|
Packit Service |
639700 |
// SPDX-License-Identifier: GPL-2.0+
|
|
Packit |
fabffb |
/* NetworkManager Applet -- allow user control over networking
|
|
Packit |
fabffb |
*
|
|
Packit |
fabffb |
* Dan Williams <dcbw@redhat.com>
|
|
Packit |
fabffb |
*
|
|
Packit |
fabffb |
* Copyright 2010 - 2017 Red Hat, Inc.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include "nm-default.h"
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include <ctype.h>
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include <libsecret/secret.h>
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
#include "utils.h"
|
|
Packit |
fabffb |
#include "mobile-helpers.h"
|
|
Packit |
fabffb |
#include "applet-dialogs.h"
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
GdkPixbuf *
|
|
Packit |
fabffb |
mobile_helper_get_status_pixbuf (guint32 quality,
|
|
Packit |
fabffb |
gboolean quality_valid,
|
|
Packit |
fabffb |
guint32 state,
|
|
Packit |
fabffb |
guint32 access_tech,
|
|
Packit |
fabffb |
NMApplet *applet)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
GdkPixbuf *pixbuf, *qual_pixbuf, *tmp;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!quality_valid)
|
|
Packit |
fabffb |
quality = 0;
|
|
Packit |
fabffb |
qual_pixbuf = nma_icon_check_and_load (mobile_helper_get_quality_icon_name (quality), applet);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
|
Packit |
fabffb |
TRUE,
|
|
Packit |
fabffb |
qual_pixbuf ? gdk_pixbuf_get_bits_per_sample (qual_pixbuf) : 8,
|
|
Packit |
fabffb |
qual_pixbuf ? gdk_pixbuf_get_width (qual_pixbuf) : 22,
|
|
Packit |
fabffb |
qual_pixbuf ? gdk_pixbuf_get_height (qual_pixbuf) : 22);
|
|
Packit |
fabffb |
gdk_pixbuf_fill (pixbuf, 0xFFFFFF00);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Composite the tower icon into the final icon at the bottom layer */
|
|
Packit |
fabffb |
tmp = nma_icon_check_and_load ("nm-wwan-tower", applet);
|
|
Packit |
fabffb |
if (tmp) {
|
|
Packit |
fabffb |
gdk_pixbuf_composite (tmp, pixbuf,
|
|
Packit |
fabffb |
0, 0,
|
|
Packit |
fabffb |
gdk_pixbuf_get_width (tmp),
|
|
Packit |
fabffb |
gdk_pixbuf_get_height (tmp),
|
|
Packit |
fabffb |
0, 0, 1.0, 1.0,
|
|
Packit |
fabffb |
GDK_INTERP_BILINEAR, 255);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Composite the signal quality onto the icon on top of the WWAN tower */
|
|
Packit |
fabffb |
if (qual_pixbuf) {
|
|
Packit |
fabffb |
gdk_pixbuf_composite (qual_pixbuf, pixbuf,
|
|
Packit |
fabffb |
0, 0,
|
|
Packit |
fabffb |
gdk_pixbuf_get_width (qual_pixbuf),
|
|
Packit |
fabffb |
gdk_pixbuf_get_height (qual_pixbuf),
|
|
Packit |
fabffb |
0, 0, 1.0, 1.0,
|
|
Packit |
fabffb |
GDK_INTERP_BILINEAR, 255);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* And finally the roaming or technology icon */
|
|
Packit |
fabffb |
if (state == MB_STATE_ROAMING) {
|
|
Packit |
fabffb |
tmp = nma_icon_check_and_load ("nm-mb-roam", applet);
|
|
Packit |
fabffb |
if (tmp) {
|
|
Packit |
fabffb |
gdk_pixbuf_composite (tmp, pixbuf, 0, 0,
|
|
Packit |
fabffb |
gdk_pixbuf_get_width (tmp),
|
|
Packit |
fabffb |
gdk_pixbuf_get_height (tmp),
|
|
Packit |
fabffb |
0, 0, 1.0, 1.0,
|
|
Packit |
fabffb |
GDK_INTERP_BILINEAR, 255);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
const gchar *tech_icon_name;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Only try to add the access tech info icon if we get a valid
|
|
Packit |
fabffb |
* access tech reported. */
|
|
Packit |
fabffb |
tech_icon_name = mobile_helper_get_tech_icon_name (access_tech);
|
|
Packit |
fabffb |
if (tech_icon_name) {
|
|
Packit |
fabffb |
tmp = nma_icon_check_and_load (tech_icon_name, applet);
|
|
Packit |
fabffb |
if (tmp) {
|
|
Packit |
fabffb |
gdk_pixbuf_composite (tmp, pixbuf, 0, 0,
|
|
Packit |
fabffb |
gdk_pixbuf_get_width (tmp),
|
|
Packit |
fabffb |
gdk_pixbuf_get_height (tmp),
|
|
Packit |
fabffb |
0, 0, 1.0, 1.0,
|
|
Packit |
fabffb |
GDK_INTERP_BILINEAR, 255);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* 'pixbuf' will be freed by the caller */
|
|
Packit |
fabffb |
return pixbuf;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
const char *
|
|
Packit |
fabffb |
mobile_helper_get_quality_icon_name (guint32 quality)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
if (quality > 80)
|
|
Packit |
fabffb |
return "nm-signal-100";
|
|
Packit |
fabffb |
else if (quality > 55)
|
|
Packit |
fabffb |
return "nm-signal-75";
|
|
Packit |
fabffb |
else if (quality > 30)
|
|
Packit |
fabffb |
return "nm-signal-50";
|
|
Packit |
fabffb |
else if (quality > 5)
|
|
Packit |
fabffb |
return "nm-signal-25";
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
return "nm-signal-00";
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
const char *
|
|
Packit |
fabffb |
mobile_helper_get_tech_icon_name (guint32 tech)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
switch (tech) {
|
|
Packit |
fabffb |
case MB_TECH_1XRTT:
|
|
Packit |
fabffb |
return "nm-tech-cdma-1x";
|
|
Packit |
fabffb |
case MB_TECH_EVDO:
|
|
Packit |
fabffb |
return "nm-tech-evdo";
|
|
Packit |
fabffb |
case MB_TECH_GSM:
|
|
Packit |
fabffb |
case MB_TECH_GPRS:
|
|
Packit |
fabffb |
return "nm-tech-gprs";
|
|
Packit |
fabffb |
case MB_TECH_EDGE:
|
|
Packit |
fabffb |
return "nm-tech-edge";
|
|
Packit |
fabffb |
case MB_TECH_UMTS:
|
|
Packit |
fabffb |
return "nm-tech-umts";
|
|
Packit |
fabffb |
case MB_TECH_HSDPA:
|
|
Packit |
fabffb |
case MB_TECH_HSUPA:
|
|
Packit |
fabffb |
case MB_TECH_HSPA:
|
|
Packit |
fabffb |
case MB_TECH_HSPA_PLUS:
|
|
Packit |
fabffb |
return "nm-tech-hspa";
|
|
Packit |
fabffb |
case MB_TECH_LTE:
|
|
Packit |
fabffb |
return "nm-tech-lte";
|
|
Packit |
fabffb |
default:
|
|
Packit |
fabffb |
return NULL;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/********************************************************************/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
typedef struct {
|
|
Packit |
fabffb |
AppletNewAutoConnectionCallback callback;
|
|
Packit |
fabffb |
gpointer callback_data;
|
|
Packit |
fabffb |
NMDeviceModemCapabilities requested_capability;
|
|
Packit |
fabffb |
} AutoWizardInfo;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
mobile_wizard_done (NMAMobileWizard *wizard,
|
|
Packit |
fabffb |
gboolean cancelled,
|
|
Packit |
fabffb |
NMAMobileWizardAccessMethod *method,
|
|
Packit |
fabffb |
gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
AutoWizardInfo *info = user_data;
|
|
Packit |
fabffb |
NMConnection *connection = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!cancelled && method) {
|
|
Packit |
fabffb |
NMSetting *setting;
|
|
Packit |
fabffb |
char *uuid, *id;
|
|
Packit |
fabffb |
const char *setting_name;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (method->devtype != info->requested_capability) {
|
|
Packit |
fabffb |
g_warning ("Unexpected device type");
|
|
Packit |
fabffb |
cancelled = TRUE;
|
|
Packit |
fabffb |
goto done;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
connection = nm_simple_connection_new ();
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (method->devtype == NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
|
|
Packit |
fabffb |
setting_name = NM_SETTING_CDMA_SETTING_NAME;
|
|
Packit |
fabffb |
setting = nm_setting_cdma_new ();
|
|
Packit |
fabffb |
g_object_set (setting,
|
|
Packit |
fabffb |
NM_SETTING_CDMA_NUMBER, "#777",
|
|
Packit |
fabffb |
NM_SETTING_CDMA_USERNAME, method->username,
|
|
Packit |
fabffb |
NM_SETTING_CDMA_PASSWORD, method->password,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, setting);
|
|
Packit |
fabffb |
} else if (method->devtype == NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
|
|
Packit |
fabffb |
setting_name = NM_SETTING_GSM_SETTING_NAME;
|
|
Packit |
fabffb |
setting = nm_setting_gsm_new ();
|
|
Packit |
fabffb |
g_object_set (setting,
|
|
Packit |
fabffb |
NM_SETTING_GSM_NUMBER, "*99#",
|
|
Packit |
fabffb |
NM_SETTING_GSM_USERNAME, method->username,
|
|
Packit |
fabffb |
NM_SETTING_GSM_PASSWORD, method->password,
|
|
Packit |
fabffb |
NM_SETTING_GSM_APN, method->gsm_apn,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, setting);
|
|
Packit |
fabffb |
} else
|
|
Packit |
fabffb |
g_assert_not_reached ();
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Default to IPv4 & IPv6 'automatic' addressing */
|
|
Packit |
fabffb |
setting = nm_setting_ip4_config_new ();
|
|
Packit |
fabffb |
g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, setting);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
setting = nm_setting_ip6_config_new ();
|
|
Packit |
fabffb |
g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, setting);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, nm_setting_ppp_new ());
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
setting = nm_setting_connection_new ();
|
|
Packit |
fabffb |
id = utils_create_mobile_connection_id (method->provider_name, method->plan_name);
|
|
Packit |
fabffb |
uuid = nm_utils_uuid_generate ();
|
|
Packit |
fabffb |
g_object_set (setting,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_ID, id,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_TYPE, setting_name,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
|
Packit |
fabffb |
NM_SETTING_CONNECTION_UUID, uuid,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
/* Make the new connection available only for the current user */
|
|
Packit |
fabffb |
nm_setting_connection_add_permission ((NMSettingConnection *) setting,
|
|
Packit |
fabffb |
"user", g_get_user_name (), NULL);
|
|
Packit |
fabffb |
g_free (uuid);
|
|
Packit |
fabffb |
g_free (id);
|
|
Packit |
fabffb |
nm_connection_add_setting (connection, setting);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
done:
|
|
Packit |
fabffb |
(*(info->callback)) (connection, TRUE, cancelled, info->callback_data);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (wizard)
|
|
Packit |
fabffb |
nma_mobile_wizard_destroy (wizard);
|
|
Packit |
fabffb |
g_free (info);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gboolean
|
|
Packit |
fabffb |
mobile_helper_wizard (NMDeviceModemCapabilities capabilities,
|
|
Packit |
fabffb |
AppletNewAutoConnectionCallback callback,
|
|
Packit |
fabffb |
gpointer callback_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
NMAMobileWizard *wizard;
|
|
Packit |
fabffb |
AutoWizardInfo *info;
|
|
Packit |
fabffb |
NMAMobileWizardAccessMethod *method;
|
|
Packit |
fabffb |
NMDeviceModemCapabilities wizard_capability;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Convert the input capabilities mask into a single value */
|
|
Packit |
fabffb |
if (capabilities & NM_DEVICE_MODEM_CAPABILITY_LTE)
|
|
Packit |
fabffb |
/* All LTE modems treated as GSM/UMTS for the wizard */
|
|
Packit |
fabffb |
wizard_capability = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
|
|
Packit |
fabffb |
else if (capabilities & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
|
|
Packit |
fabffb |
wizard_capability = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
|
|
Packit |
fabffb |
else if (capabilities & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
|
|
Packit |
fabffb |
wizard_capability = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
|
|
Packit |
fabffb |
else {
|
|
Packit |
fabffb |
g_warning ("Unknown modem capabilities (0x%X): can't launch wizard", capabilities);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
info = g_malloc0 (sizeof (AutoWizardInfo));
|
|
Packit |
fabffb |
info->callback = callback;
|
|
Packit |
fabffb |
info->callback_data = callback_data;
|
|
Packit |
fabffb |
info->requested_capability = wizard_capability;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
wizard = nma_mobile_wizard_new (NULL,
|
|
Packit |
fabffb |
NULL,
|
|
Packit |
fabffb |
wizard_capability,
|
|
Packit |
fabffb |
FALSE,
|
|
Packit |
fabffb |
mobile_wizard_done,
|
|
Packit |
fabffb |
info);
|
|
Packit |
fabffb |
if (wizard) {
|
|
Packit |
fabffb |
nma_mobile_wizard_present (wizard);
|
|
Packit |
fabffb |
return TRUE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Fall back to something */
|
|
Packit |
fabffb |
method = g_malloc0 (sizeof (NMAMobileWizardAccessMethod));
|
|
Packit |
fabffb |
method->devtype = wizard_capability;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (wizard_capability == NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
|
|
Packit |
fabffb |
method->provider_name = _("GSM");
|
|
Packit |
fabffb |
else if (wizard_capability == NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
|
|
Packit |
fabffb |
method->provider_name = _("CDMA");
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_assert ( wizard_capability == NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS
|
|
Packit |
fabffb |
|| wizard_capability == NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
mobile_wizard_done (NULL, FALSE, method, info);
|
|
Packit |
fabffb |
g_free (method);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return TRUE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/********************************************************************/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
const SecretSchema mobile_secret_schema = {
|
|
Packit |
fabffb |
"org.freedesktop.NetworkManager.Mobile",
|
|
Packit |
fabffb |
SECRET_SCHEMA_DONT_MATCH_NAME,
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
{ "devid", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
Packit |
fabffb |
{ "simid", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
Packit |
fabffb |
{ NULL, 0 },
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
};
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
save_pin_cb (GObject *source,
|
|
Packit |
fabffb |
GAsyncResult *result,
|
|
Packit |
fabffb |
gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
GError *error = NULL;
|
|
Packit |
fabffb |
gchar *error_msg = user_data;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
secret_password_store_finish (result, &error);
|
|
Packit |
fabffb |
if (error != NULL) {
|
|
Packit |
fabffb |
g_warning ("%s: %s", error_msg, error->message);
|
|
Packit |
fabffb |
g_error_free (error);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (error_msg);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
void
|
|
Packit |
fabffb |
mobile_helper_save_pin_in_keyring (const char *devid,
|
|
Packit |
fabffb |
const char *simid,
|
|
Packit |
fabffb |
const char *pin)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
char *name;
|
|
Packit |
fabffb |
char *error_msg;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
name = g_strdup_printf (_("PIN code for SIM card “%s” on “%s”"),
|
|
Packit |
fabffb |
simid ? simid : "unknown",
|
|
Packit |
fabffb |
devid);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
error_msg = g_strdup_printf ("Saving PIN code in keyring for devid:%s simid:%s failed",
|
|
Packit |
fabffb |
devid, simid ? simid : "(unknown)");
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
secret_password_store (&mobile_secret_schema,
|
|
Packit |
fabffb |
NULL, name, pin,
|
|
Packit |
fabffb |
NULL, save_pin_cb, error_msg,
|
|
Packit |
fabffb |
"devid", devid,
|
|
Packit |
fabffb |
simid ? "simid" : NULL, simid,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (name);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
void
|
|
Packit |
fabffb |
mobile_helper_delete_pin_in_keyring (const char *devid)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
secret_password_clear (&mobile_secret_schema, NULL, NULL, NULL,
|
|
Packit |
fabffb |
"devid", devid,
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/********************************************************************/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
free_secrets_info (SecretsRequest *req)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
MobileHelperSecretsInfo *info = (MobileHelperSecretsInfo *) req;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (info->dialog) {
|
|
Packit |
fabffb |
gtk_widget_hide (info->dialog);
|
|
Packit |
fabffb |
gtk_widget_destroy (info->dialog);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_free (info->secret_name);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
get_secrets_cb (GtkDialog *dialog,
|
|
Packit |
fabffb |
gint response,
|
|
Packit |
fabffb |
gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
SecretsRequest *req = user_data;
|
|
Packit |
fabffb |
MobileHelperSecretsInfo *info = (MobileHelperSecretsInfo *) req;
|
|
Packit |
fabffb |
GError *error = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (response == GTK_RESPONSE_OK) {
|
|
Packit |
fabffb |
if (info->capability == NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
|
|
Packit |
fabffb |
NMSettingGsm *setting;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
setting = nm_connection_get_setting_gsm (req->connection);
|
|
Packit |
fabffb |
if (setting) {
|
|
Packit |
fabffb |
g_object_set (G_OBJECT (setting),
|
|
Packit |
fabffb |
info->secret_name, gtk_entry_get_text (info->secret_entry),
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): no GSM setting",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
} else if (info->capability == NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
|
|
Packit |
fabffb |
NMSettingCdma *setting;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
setting = nm_connection_get_setting_cdma (req->connection);
|
|
Packit |
fabffb |
if (setting) {
|
|
Packit |
fabffb |
g_object_set (G_OBJECT (setting),
|
|
Packit |
fabffb |
info->secret_name, gtk_entry_get_text (info->secret_entry),
|
|
Packit |
fabffb |
NULL);
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): no CDMA setting",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
} else
|
|
Packit |
fabffb |
g_assert_not_reached ();
|
|
Packit |
fabffb |
} else {
|
|
Packit |
fabffb |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_USER_CANCELED,
|
|
Packit |
fabffb |
"%s.%d (%s): canceled",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (info->capability == NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
|
|
Packit |
fabffb |
applet_secrets_request_complete_setting (req, NM_SETTING_GSM_SETTING_NAME, error);
|
|
Packit |
fabffb |
else if (info->capability == NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
|
|
Packit |
fabffb |
applet_secrets_request_complete_setting (req, NM_SETTING_CDMA_SETTING_NAME, error);
|
|
Packit |
fabffb |
else
|
|
Packit |
fabffb |
g_assert_not_reached ();
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
applet_secrets_request_free (req);
|
|
Packit |
fabffb |
g_clear_error (&error);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static void
|
|
Packit |
fabffb |
pin_entry_changed (GtkEditable *editable, gpointer user_data)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
GtkWidget *ok_button = GTK_WIDGET (user_data);
|
|
Packit |
fabffb |
const char *s;
|
|
Packit |
fabffb |
int i;
|
|
Packit |
fabffb |
gboolean valid = FALSE;
|
|
Packit |
fabffb |
guint32 len;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
s = gtk_entry_get_text (GTK_ENTRY (editable));
|
|
Packit |
fabffb |
if (s) {
|
|
Packit |
fabffb |
len = strlen (s);
|
|
Packit |
fabffb |
if ((len >= 4) && (len <= 8)) {
|
|
Packit |
fabffb |
valid = TRUE;
|
|
Packit |
fabffb |
for (i = 0; i < len; i++) {
|
|
Packit |
fabffb |
if (!g_ascii_isdigit (s[i])) {
|
|
Packit |
fabffb |
valid = FALSE;
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_widget_set_sensitive (ok_button, valid);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
static GtkWidget *
|
|
Packit |
fabffb |
ask_for_pin (GtkEntry **out_secret_entry)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
GtkDialog *dialog;
|
|
Packit |
fabffb |
GtkWidget *w = NULL, *ok_button = NULL;
|
|
Packit |
fabffb |
GtkBox *box = NULL, *vbox = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
dialog = GTK_DIALOG (gtk_dialog_new ());
|
|
Packit |
fabffb |
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
|
Packit |
fabffb |
gtk_window_set_title (GTK_WINDOW (dialog), _("PIN code required"));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_REJECT);
|
|
Packit |
fabffb |
ok_button = gtk_dialog_add_button (dialog, _("_OK"), GTK_RESPONSE_OK);
|
|
Packit |
fabffb |
gtk_window_set_default (GTK_WINDOW (dialog), ok_button);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
vbox = GTK_BOX (gtk_dialog_get_content_area (dialog));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
w = gtk_label_new (_("PIN code is needed for the mobile broadband device"));
|
|
Packit |
fabffb |
gtk_box_pack_start (vbox, w, TRUE, TRUE, 0);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
w = gtk_alignment_new (0.5, 0.5, 0, 1.0);
|
|
Packit |
fabffb |
gtk_box_pack_start (vbox, w, TRUE, TRUE, 0);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6));
|
|
Packit |
fabffb |
gtk_container_set_border_width (GTK_CONTAINER (box), 6);
|
|
Packit |
fabffb |
gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (box));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_box_pack_start (box, gtk_label_new ("PIN:"), FALSE, FALSE, 0);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
w = gtk_entry_new ();
|
|
Packit |
fabffb |
*out_secret_entry = GTK_ENTRY (w);
|
|
Packit |
fabffb |
gtk_entry_set_max_length (GTK_ENTRY (w), 8);
|
|
Packit |
fabffb |
gtk_entry_set_width_chars (GTK_ENTRY (w), 8);
|
|
Packit |
fabffb |
gtk_entry_set_activates_default (GTK_ENTRY (w), TRUE);
|
|
Packit |
fabffb |
gtk_entry_set_visibility (GTK_ENTRY (w), FALSE);
|
|
Packit |
fabffb |
gtk_box_pack_start (box, w, FALSE, FALSE, 0);
|
|
Packit |
fabffb |
g_signal_connect (w, "changed", G_CALLBACK (pin_entry_changed), ok_button);
|
|
Packit |
fabffb |
pin_entry_changed (GTK_EDITABLE (w), ok_button);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_widget_show_all (GTK_WIDGET (vbox));
|
|
Packit |
fabffb |
return GTK_WIDGET (dialog);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gboolean
|
|
Packit |
fabffb |
mobile_helper_get_secrets (NMDeviceModemCapabilities capabilities,
|
|
Packit |
fabffb |
SecretsRequest *req,
|
|
Packit |
fabffb |
GError **error)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
MobileHelperSecretsInfo *info = (MobileHelperSecretsInfo *) req;
|
|
Packit |
fabffb |
GtkWidget *widget;
|
|
Packit |
fabffb |
GtkEntry *secret_entry = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
applet_secrets_request_set_free_func (req, free_secrets_info);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!req->hints || !g_strv_length (req->hints)) {
|
|
Packit |
fabffb |
g_set_error (error,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): missing secrets hints.",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
info->secret_name = g_strdup (req->hints[0]);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Convert the input capabilities mask into a single value */
|
|
Packit |
fabffb |
if (capabilities & NM_DEVICE_MODEM_CAPABILITY_LTE)
|
|
Packit |
fabffb |
/* All LTE modems treated as GSM/UMTS for the settings */
|
|
Packit |
fabffb |
info->capability = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
|
|
Packit |
fabffb |
else if (capabilities & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
|
|
Packit |
fabffb |
info->capability = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
|
|
Packit |
fabffb |
else if (capabilities & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
|
|
Packit |
fabffb |
info->capability = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
|
|
Packit |
fabffb |
else {
|
|
Packit |
fabffb |
g_set_error (error,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): unknown modem capabilities (0x%X).",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__, capabilities);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!strcmp (info->secret_name, NM_SETTING_GSM_PIN)) {
|
|
Packit |
fabffb |
widget = ask_for_pin (&secret_entry);
|
|
Packit |
fabffb |
} else if (!strcmp (info->secret_name, NM_SETTING_GSM_PASSWORD) ||
|
|
Packit |
fabffb |
!strcmp (info->secret_name, NM_SETTING_CDMA_PASSWORD))
|
|
Packit |
fabffb |
widget = applet_mobile_password_dialog_new (req->connection, &secret_entry);
|
|
Packit |
fabffb |
else {
|
|
Packit |
fabffb |
g_set_error (error,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): unknown secrets hint '%s'.",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__, info->secret_name);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
info->dialog = widget;
|
|
Packit |
fabffb |
info->secret_entry = secret_entry;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!widget || !secret_entry) {
|
|
Packit |
fabffb |
g_set_error (error,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR,
|
|
Packit |
fabffb |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit |
fabffb |
"%s.%d (%s): error asking for mobile secrets.",
|
|
Packit |
fabffb |
__FILE__, __LINE__, __func__);
|
|
Packit |
fabffb |
return FALSE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_signal_connect (widget, "response", G_CALLBACK (get_secrets_cb), info);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ALWAYS);
|
|
Packit |
fabffb |
gtk_widget_realize (GTK_WIDGET (widget));
|
|
Packit |
fabffb |
gtk_window_present (GTK_WINDOW (widget));
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
return TRUE;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/********************************************************************/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
void
|
|
Packit |
fabffb |
mobile_helper_get_icon (NMDevice *device,
|
|
Packit |
fabffb |
NMDeviceState state,
|
|
Packit |
fabffb |
NMConnection *connection,
|
|
Packit |
fabffb |
GdkPixbuf **out_pixbuf,
|
|
Packit |
fabffb |
const char **out_icon_name,
|
|
Packit |
fabffb |
char **tip,
|
|
Packit |
fabffb |
NMApplet *applet,
|
|
Packit |
fabffb |
guint32 mb_state,
|
|
Packit |
fabffb |
guint32 mb_tech,
|
|
Packit |
fabffb |
guint32 quality,
|
|
Packit |
fabffb |
gboolean quality_valid)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
NMSettingConnection *s_con;
|
|
Packit |
fabffb |
const char *id;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_return_if_fail (out_icon_name && !*out_icon_name);
|
|
Packit |
fabffb |
g_return_if_fail (tip && !*tip);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
id = nm_device_get_iface (NM_DEVICE (device));
|
|
Packit |
fabffb |
if (connection) {
|
|
Packit |
fabffb |
s_con = nm_connection_get_setting_connection (connection);
|
|
Packit |
fabffb |
id = nm_setting_connection_get_id (s_con);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
switch (state) {
|
|
Packit |
fabffb |
case NM_DEVICE_STATE_PREPARE:
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("Preparing mobile broadband connection “%s”…"), id);
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
case NM_DEVICE_STATE_CONFIG:
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("Configuring mobile broadband connection “%s”…"), id);
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
case NM_DEVICE_STATE_NEED_AUTH:
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("User authentication required for mobile broadband connection “%s”…"), id);
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
case NM_DEVICE_STATE_IP_CONFIG:
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("Requesting a network address for “%s”…"), id);
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
case NM_DEVICE_STATE_ACTIVATED:
|
|
Packit |
fabffb |
*out_pixbuf = mobile_helper_get_status_pixbuf (quality,
|
|
Packit |
fabffb |
quality_valid,
|
|
Packit |
fabffb |
mb_state,
|
|
Packit |
fabffb |
mb_tech,
|
|
Packit |
fabffb |
applet);
|
|
Packit |
fabffb |
*out_icon_name = mobile_helper_get_quality_icon_name (quality_valid ?
|
|
Packit |
fabffb |
quality : 0);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if ((mb_state != MB_STATE_UNKNOWN) && quality_valid) {
|
|
Packit |
fabffb |
gboolean roaming = (mb_state == MB_STATE_ROAMING);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("Mobile broadband connection “%s” active: (%d%%%s%s)"),
|
|
Packit |
fabffb |
id, quality,
|
|
Packit |
fabffb |
roaming ? ", " : "",
|
|
Packit |
fabffb |
roaming ? _("roaming") : "");
|
|
Packit |
fabffb |
} else
|
|
Packit |
fabffb |
*tip = g_strdup_printf (_("Mobile broadband connection “%s” active"), id);
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
default:
|
|
Packit |
fabffb |
break;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/********************************************************************/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
char *
|
|
Packit |
fabffb |
mobile_helper_parse_3gpp_operator_name (NMAMobileProvidersDatabase **mpd, /* I/O */
|
|
Packit |
fabffb |
const char *orig,
|
|
Packit |
fabffb |
const char *op_code)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
NMAMobileProvider *provider;
|
|
Packit |
fabffb |
guint i, orig_len;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_assert (mpd != NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* Some devices return the MCC/MNC if they haven't fully initialized
|
|
Packit |
fabffb |
* or gotten all the info from the network yet. Handle that.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
orig_len = orig ? strlen (orig) : 0;
|
|
Packit |
fabffb |
if (orig_len == 0) {
|
|
Packit |
fabffb |
/* If the operator name isn't valid, maybe we can look up the MCC/MNC
|
|
Packit |
fabffb |
* from the operator code instead.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
if (op_code && strlen (op_code)) {
|
|
Packit |
fabffb |
orig = op_code;
|
|
Packit |
fabffb |
orig_len = strlen (orig);
|
|
Packit |
fabffb |
} else
|
|
Packit |
fabffb |
return NULL;
|
|
Packit |
fabffb |
} else if (orig_len < 5 || orig_len > 6)
|
|
Packit |
fabffb |
return g_strdup (orig); /* not an MCC/MNC */
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
for (i = 0; i < orig_len; i++) {
|
|
Packit |
fabffb |
if (!isdigit (orig[i]))
|
|
Packit |
fabffb |
return strdup (orig);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
/* At this point we have a 5 or 6 character all-digit string; that's
|
|
Packit |
fabffb |
* probably an MCC/MNC. Look that up.
|
|
Packit |
fabffb |
*/
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (*mpd == NULL) {
|
|
Packit |
fabffb |
GError *error = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
*mpd = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error);
|
|
Packit |
fabffb |
if (*mpd == NULL) {
|
|
Packit |
fabffb |
g_warning ("Couldn't read database: %s", error->message);
|
|
Packit |
fabffb |
g_error_free (error);
|
|
Packit |
fabffb |
return strdup (orig);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
provider = nma_mobile_providers_database_lookup_3gpp_mcc_mnc (*mpd, orig);
|
|
Packit |
fabffb |
return (provider ? g_strdup (nma_mobile_provider_get_name (provider)) : NULL);
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
char *
|
|
Packit |
fabffb |
mobile_helper_parse_3gpp2_operator_name (NMAMobileProvidersDatabase **mpd, /* I/O */
|
|
Packit |
fabffb |
guint32 sid)
|
|
Packit |
fabffb |
{
|
|
Packit |
fabffb |
NMAMobileProvider *provider;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
g_assert (mpd != NULL);
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (!sid)
|
|
Packit |
fabffb |
return NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
if (*mpd == NULL) {
|
|
Packit |
fabffb |
GError *error = NULL;
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
*mpd = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error);
|
|
Packit |
fabffb |
if (*mpd == NULL) {
|
|
Packit |
fabffb |
g_warning ("Couldn't read database: %s", error->message);
|
|
Packit |
fabffb |
g_error_free (error);
|
|
Packit |
fabffb |
return NULL;
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
}
|
|
Packit |
fabffb |
|
|
Packit |
fabffb |
provider = nma_mobile_providers_database_lookup_cdma_sid (*mpd, sid);
|
|
Packit |
fabffb |
return (provider ? g_strdup (nma_mobile_provider_get_name (provider)) : NULL);
|
|
Packit |
fabffb |
}
|