Blame src/mobile-helpers.c

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