Commit ea96ccc9 authored by Dan Williams's avatar Dan Williams
Browse files

Add a mobile broadband connection setup wizard

Interaction design by Máirín Duffy <duffy@redhat.com>
parent 6da80cd0
......@@ -68,13 +68,13 @@ AC_C_BIGENDIAN
PKG_CHECK_MODULES(GOBJECT, gobject-2.0)
PKG_CHECK_MODULES(NMA,
[dbus-glib-1 >= 0.72
[dbus-glib-1 >= 0.74
glib-2.0 >= 2.10
NetworkManager >= 0.7.0
libnm_glib >= 0.7.0
libnm-util >= 0.7.0
libnm_glib_vpn >= 0.7.0
gtk+-2.0 >= 2.10
NetworkManager >= 0.7.1
libnm_glib >= 0.7.1
libnm-util >= 0.7.1
libnm_glib_vpn >= 0.7.1
gtk+-2.0 >= 2.14
libglade-2.0
gmodule-export-2.0
gconf-2.0
......
......@@ -23,7 +23,6 @@ src/connection-editor/ce-page-wireless.glade
src/connection-editor/ce-page-wireless-security.glade
src/connection-editor/ce-vpn-wizard.glade
src/connection-editor/ip4-routes-dialog.c
src/connection-editor/mobile-wizard.c
src/connection-editor/page-dsl.c
src/connection-editor/page-ip4.c
src/connection-editor/page-mobile.c
......@@ -40,6 +39,8 @@ src/connection-editor/nm-connection-list.c
src/connection-editor/vpn-helpers.c
src/keyring.png
src/main.c
src/utils/mobile-wizard.c
src/utils/nmn-mobile-providers.c
src/vpn-password-dialog.c
src/vpn-password-dialog.h
src/wired-dialog.c
......
......@@ -38,6 +38,7 @@
#include "applet.h"
#include "applet-device-cdma.h"
#include "utils.h"
#include "mobile-wizard.h"
typedef struct {
NMApplet *applet;
......@@ -51,53 +52,105 @@ cdma_menu_item_info_destroy (gpointer data)
g_slice_free (CdmaMenuItemInfo, data);
}
#define DEFAULT_CDMA_NAME _("Auto Mobile Broadband (CDMA) connection")
typedef struct {
AppletNewAutoConnectionCallback callback;
gpointer callback_data;
} AutoCdmaWizardInfo;
static void
mobile_wizard_done (MobileWizard *wizard,
gboolean canceled,
MobileWizardAccessMethod *method,
gpointer user_data)
{
AutoCdmaWizardInfo *info = user_data;
NMConnection *connection = NULL;
if (!canceled && method) {
NMSetting *setting;
char *uuid, *id;
if (method->devtype != NM_DEVICE_TYPE_CDMA) {
g_warning ("Unexpected device type (not CDMA).");
canceled = TRUE;
goto done;
}
connection = nm_connection_new ();
setting = nm_setting_cdma_new ();
g_object_set (setting,
NM_SETTING_CDMA_NUMBER, "#777",
NM_SETTING_CDMA_USERNAME, method->username,
NM_SETTING_CDMA_PASSWORD, method->password,
NULL);
nm_connection_add_setting (connection, setting);
/* Serial setting */
setting = nm_setting_serial_new ();
g_object_set (setting,
NM_SETTING_SERIAL_BAUD, 115200,
NM_SETTING_SERIAL_BITS, 8,
NM_SETTING_SERIAL_PARITY, 'n',
NM_SETTING_SERIAL_STOPBITS, 1,
NULL);
nm_connection_add_setting (connection, setting);
nm_connection_add_setting (connection, nm_setting_ppp_new ());
setting = nm_setting_connection_new ();
if (method->plan_name)
id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name);
else
id = g_strdup_printf ("%s connection", method->provider_name);
uuid = nm_utils_uuid_generate ();
g_object_set (setting,
NM_SETTING_CONNECTION_ID, id,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_CDMA_SETTING_NAME,
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
NM_SETTING_CONNECTION_UUID, uuid,
NULL);
g_free (uuid);
g_free (id);
nm_connection_add_setting (connection, setting);
}
done:
(*(info->callback)) (connection, TRUE, canceled, info->callback_data);
static NMConnection *
if (wizard)
mobile_wizard_destroy (wizard);
g_free (info);
}
static gboolean
cdma_new_auto_connection (NMDevice *device,
NMApplet *applet,
gpointer user_data)
gpointer dclass_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data)
{
NMConnection *connection;
NMSettingCdma *s_cdma;
NMSettingSerial *s_serial;
NMSettingPPP *s_ppp;
NMSettingConnection *s_con;
char *uuid;
connection = nm_connection_new ();
s_cdma = NM_SETTING_CDMA (nm_setting_cdma_new ());
/* De-facto standard for CDMA */
g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL);
nm_connection_add_setting (connection, NM_SETTING (s_cdma));
/* Serial setting */
s_serial = (NMSettingSerial *) nm_setting_serial_new ();
g_object_set (s_serial,
NM_SETTING_SERIAL_BAUD, 115200,
NM_SETTING_SERIAL_BITS, 8,
NM_SETTING_SERIAL_PARITY, 'n',
NM_SETTING_SERIAL_STOPBITS, 1,
NULL);
nm_connection_add_setting (connection, NM_SETTING (s_serial));
s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ppp));
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, DEFAULT_CDMA_NAME,
NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (NM_SETTING (s_cdma)),
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
NM_SETTING_CONNECTION_UUID, uuid,
NULL);
g_free (uuid);
nm_connection_add_setting (connection, NM_SETTING (s_con));
return connection;
MobileWizard *wizard;
AutoCdmaWizardInfo *info;
MobileWizardAccessMethod *method;
info = g_malloc0 (sizeof (AutoCdmaWizardInfo));
info->callback = callback;
info->callback_data = callback_data;
wizard = mobile_wizard_new (NULL, device, mobile_wizard_done, info);
if (wizard) {
mobile_wizard_present (wizard);
return TRUE;
}
/* Fall back to something */
method = g_malloc0 (sizeof (MobileWizardAccessMethod));
method->devtype = NM_DEVICE_TYPE_CDMA;
method->provider_name = _("CDMA");
mobile_wizard_done (NULL, FALSE, method, info);
g_free (method);
return TRUE;
}
static void
......@@ -156,7 +209,7 @@ add_default_connection_item (NMDevice *device,
CdmaMenuItemInfo *info;
GtkWidget *item;
item = gtk_check_menu_item_new_with_label (DEFAULT_CDMA_NAME);
item = gtk_check_menu_item_new_with_label (_("New Mobile Broadband (CDMA) connection..."));
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE);
info = g_slice_new0 (CdmaMenuItemInfo);
......
......@@ -39,6 +39,7 @@
#include "applet.h"
#include "applet-device-gsm.h"
#include "utils.h"
#include "mobile-wizard.h"
typedef struct {
NMApplet *applet;
......@@ -52,53 +53,106 @@ gsm_menu_item_info_destroy (gpointer data)
g_slice_free (GSMMenuItemInfo, data);
}
#define DEFAULT_GSM_NAME _("Auto Mobile Broadband (GSM) connection")
typedef struct {
AppletNewAutoConnectionCallback callback;
gpointer callback_data;
} AutoGsmWizardInfo;
static void
mobile_wizard_done (MobileWizard *wizard,
gboolean canceled,
MobileWizardAccessMethod *method,
gpointer user_data)
{
AutoGsmWizardInfo *info = user_data;
NMConnection *connection = NULL;
if (!canceled && method) {
NMSetting *setting;
char *uuid, *id;
if (method->devtype != NM_DEVICE_TYPE_GSM) {
g_warning ("Unexpected device type (not GSM).");
canceled = TRUE;
goto done;
}
connection = nm_connection_new ();
setting = nm_setting_gsm_new ();
g_object_set (setting,
NM_SETTING_GSM_NUMBER, "*99#",
NM_SETTING_GSM_USERNAME, method->username,
NM_SETTING_GSM_PASSWORD, method->password,
NM_SETTING_GSM_APN, method->gsm_apn,
NULL);
nm_connection_add_setting (connection, setting);
/* Serial setting */
setting = nm_setting_serial_new ();
g_object_set (setting,
NM_SETTING_SERIAL_BAUD, 115200,
NM_SETTING_SERIAL_BITS, 8,
NM_SETTING_SERIAL_PARITY, 'n',
NM_SETTING_SERIAL_STOPBITS, 1,
NULL);
nm_connection_add_setting (connection, setting);
nm_connection_add_setting (connection, nm_setting_ppp_new ());
setting = nm_setting_connection_new ();
if (method->plan_name)
id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name);
else
id = g_strdup_printf ("%s connection", method->provider_name);
uuid = nm_utils_uuid_generate ();
g_object_set (setting,
NM_SETTING_CONNECTION_ID, id,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME,
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
NM_SETTING_CONNECTION_UUID, uuid,
NULL);
g_free (uuid);
g_free (id);
nm_connection_add_setting (connection, setting);
}
done:
(*(info->callback)) (connection, TRUE, canceled, info->callback_data);
static NMConnection *
if (wizard)
mobile_wizard_destroy (wizard);
g_free (info);
}
static gboolean
gsm_new_auto_connection (NMDevice *device,
NMApplet *applet,
gpointer user_data)
gpointer dclass_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data)
{
NMConnection *connection;
NMSettingGsm *s_gsm;
NMSettingSerial *s_serial;
NMSettingPPP *s_ppp;
NMSettingConnection *s_con;
char *uuid;
connection = nm_connection_new ();
s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ());
/* This should be a sensible default as it's seems to be quite standard */
g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
nm_connection_add_setting (connection, NM_SETTING (s_gsm));
/* Serial setting */
s_serial = (NMSettingSerial *) nm_setting_serial_new ();
g_object_set (s_serial,
NM_SETTING_SERIAL_BAUD, 115200,
NM_SETTING_SERIAL_BITS, 8,
NM_SETTING_SERIAL_PARITY, 'n',
NM_SETTING_SERIAL_STOPBITS, 1,
NULL);
nm_connection_add_setting (connection, NM_SETTING (s_serial));
s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ppp));
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, DEFAULT_GSM_NAME,
NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (NM_SETTING (s_gsm)),
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
NM_SETTING_CONNECTION_UUID, uuid,
NULL);
g_free (uuid);
nm_connection_add_setting (connection, NM_SETTING (s_con));
return connection;
MobileWizard *wizard;
AutoGsmWizardInfo *info;
MobileWizardAccessMethod *method;
info = g_malloc0 (sizeof (AutoGsmWizardInfo));
info->callback = callback;
info->callback_data = callback_data;
wizard = mobile_wizard_new (NULL, device, mobile_wizard_done, info);
if (wizard) {
mobile_wizard_present (wizard);
return TRUE;
}
/* Fall back to something */
method = g_malloc0 (sizeof (MobileWizardAccessMethod));
method->devtype = NM_DEVICE_TYPE_GSM;
method->provider_name = _("GSM");
mobile_wizard_done (NULL, FALSE, method, info);
g_free (method);
return TRUE;
}
static void
......@@ -157,7 +211,7 @@ add_default_connection_item (NMDevice *device,
GSMMenuItemInfo *info;
GtkWidget *item;
item = gtk_check_menu_item_new_with_label (DEFAULT_GSM_NAME);
item = gtk_check_menu_item_new_with_label (_("New Mobile Broadband (GSM) connection..."));
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), TRUE);
info = g_slice_new0 (GSMMenuItemInfo);
......
......@@ -316,12 +316,13 @@ none:
return NULL;
}
static NMConnection *
static gboolean
wireless_new_auto_connection (NMDevice *device,
NMApplet *applet,
gpointer user_data)
gpointer dclass_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data)
{
WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) user_data;
WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) dclass_data;
NMConnection *connection = NULL;
NMSettingConnection *s_con = NULL;
NMSettingWireless *s_wireless = NULL;
......@@ -337,7 +338,7 @@ wireless_new_auto_connection (NMDevice *device,
if (!info->ap) {
g_warning ("%s: AP not set", __func__);
return NULL;
return FALSE;
}
s_wireless = (NMSettingWireless *) nm_setting_wireless_new ();
......@@ -357,7 +358,7 @@ wireless_new_auto_connection (NMDevice *device,
s_wireless_sec = get_security_for_ap (info->ap, dev_caps, &supported, &s_8021x);
if (!supported) {
g_object_unref (s_wireless);
goto out;
goto done;
} else if (s_wireless_sec)
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
......@@ -387,8 +388,9 @@ wireless_new_auto_connection (NMDevice *device,
nm_connection_add_setting (connection, NM_SETTING (s_con));
out:
return connection;
done:
(*callback) (connection, TRUE, FALSE, callback_data);
return TRUE;
}
static void
......
......@@ -62,10 +62,11 @@ wired_menu_item_info_destroy (gpointer data)
#define DEFAULT_WIRED_NAME _("Auto Ethernet")
static NMConnection *
static gboolean
wired_new_auto_connection (NMDevice *device,
NMApplet *applet,
gpointer user_data)
gpointer dclass_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data)
{
NMConnection *connection;
NMSettingWired *s_wired = NULL;
......@@ -89,7 +90,8 @@ wired_new_auto_connection (NMDevice *device,
nm_connection_add_setting (connection, NM_SETTING (s_con));
return connection;
(*callback) (connection, TRUE, FALSE, callback_data);
return TRUE;
}
static void
......
......@@ -296,44 +296,62 @@ activate_connection_cb (gpointer user_data, const char *path, GError *error)
applet_schedule_update_icon (NM_APPLET (user_data));
}
void
applet_menu_item_activate_helper (NMDevice *device,
NMConnection *connection,
const char *specific_object,
NMApplet *applet,
gpointer user_data)
typedef struct {
NMApplet *applet;
NMDevice *device;
char *specific_object;
gpointer dclass_data;
} AppletItemActivateInfo;
static void
applet_item_activate_info_destroy (AppletItemActivateInfo *info)
{
NMAGConfConnection *exported;
g_return_if_fail (info != NULL);
if (info->device)
g_object_unref (info->device);
g_free (info->specific_object);
memset (info, 0, sizeof (AppletItemActivateInfo));
g_free (info);
}
static void
applet_menu_item_activate_helper_part2 (NMConnection *connection,
gboolean auto_created,
gboolean canceled,
gpointer user_data)
{
AppletItemActivateInfo *info = user_data;
const char *con_path;
gboolean is_system = FALSE;
g_return_if_fail (NM_IS_DEVICE (device));
if (canceled) {
applet_item_activate_info_destroy (info);
return;
}
if (connection) {
is_system = is_system_connection (connection);
} else {
NMADeviceClass *dclass = get_device_class (device, applet);
g_assert (connection);
/* If no connection was given, create a new default connection for this
* device type.
*/
g_assert (dclass);
connection = dclass->new_auto_connection (device, applet, user_data);
if (!connection) {
nm_warning ("Couldn't create default connection.");
return;
}
if (!auto_created)
is_system = is_system_connection (connection);
else {
NMAGConfConnection *exported;
exported = nma_gconf_settings_add_connection (applet->gconf_settings, connection);
exported = nma_gconf_settings_add_connection (info->applet->gconf_settings, connection);
if (!exported) {
NMADeviceClass *dclass = get_device_class (info->device, info->applet);
/* If the setting isn't valid, because it needs more authentication
* or something, ask the user for it.
*/
g_assert (dclass);
nm_warning ("Invalid connection; asking for more information.");
if (dclass->get_more_info)
dclass->get_more_info (device, connection, applet, user_data);
dclass->get_more_info (info->device, connection, info->applet, info->dclass_data);
g_object_unref (connection);
applet_item_activate_info_destroy (info);
return;
}
g_object_unref (connection);
......@@ -344,13 +362,52 @@ applet_menu_item_activate_helper (NMDevice *device,
g_assert (con_path);
/* Finally, tell NM to activate the connection */
nm_client_activate_connection (applet->nm_client,
nm_client_activate_connection (info->applet->nm_client,
is_system ? NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS,
con_path,
device,
specific_object,
info->device,
info->specific_object,
activate_connection_cb,
applet);
info->applet);
applet_item_activate_info_destroy (info);
}
void
applet_menu_item_activate_helper (NMDevice *device,
NMConnection *connection,
const char *specific_object,
NMApplet *applet,
gpointer dclass_data)
{
AppletItemActivateInfo *info;
NMADeviceClass *dclass;
g_return_if_fail (NM_IS_DEVICE (device));
info = g_malloc0 (sizeof (AppletItemActivateInfo));
info->applet = applet;
info->specific_object = g_strdup (specific_object);
info->device = g_object_ref (device);
info->dclass_data = dclass_data;
if (connection) {
applet_menu_item_activate_helper_part2 (connection, FALSE, FALSE, info);
return;
}
dclass = get_device_class (device, applet);
/* If no connection was passed in, ask the device class to create a new
* default connection for this device type. This could be a wizard,
* and thus take a while.
*/
g_assert (dclass);
if (!dclass->new_auto_connection (device, dclass_data,
applet_menu_item_activate_helper_part2,
info)) {
nm_warning ("Couldn't create default connection.");
applet_item_activate_info_destroy (info);
}
}
static void
......
......@@ -146,11 +146,16 @@ typedef struct
gboolean notify_with_actions;
} NMApplet;
typedef void (*AppletNewAutoConnectionCallback) (NMConnection *connection,
gboolean created,
gboolean canceled,
gpointer user_data);
struct NMADeviceClass {
NMConnection * (*new_auto_connection) (NMDevice *device,
NMApplet *applet,
gpointer user_data);
gboolean (*new_auto_connection) (NMDevice *device,
gpointer user_data,
AppletNewAutoConnectionCallback callback,
gpointer callback_data);
void (*add_menu_item) (NMDevice *device,
guint32 num_devices,
......@@ -204,7 +209,7 @@ void applet_menu_item_activate_helper (NMDevice *device,
NMConnection *connection,
const char *specific_object,
NMApplet *applet,
gpointer user_data);
gpointer dclass_data);
NMAGConfConnection *applet_get_exported_connection_for_device (NMDevice *device, NMApplet *applet);
......