1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2011-2012 Richard Hughes <richard@hughsie.com>
5
* Licensed under the GNU General Public License Version 2
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
#include <glib-object.h>
25
#include <glib/gi18n.h>
27
#include <nm-client.h>
28
#include <nm-device.h>
29
#include <nm-device-modem.h>
30
#include <nm-remote-connection.h>
32
#include "panel-common.h"
33
#include "network-dialogs.h"
35
#include "net-device-mobile.h"
37
#define NET_DEVICE_MOBILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobilePrivate))
39
static void nm_device_mobile_refresh_ui (NetDeviceMobile *device_mobile);
41
struct _NetDeviceMobilePrivate
44
gboolean updating_device;
53
G_DEFINE_TYPE (NetDeviceMobile, net_device_mobile, NET_TYPE_DEVICE)
56
device_mobile_proxy_add_to_notebook (NetObject *object,
57
GtkNotebook *notebook,
58
GtkSizeGroup *heading_size_group)
62
NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object);
64
/* add widgets to size group */
65
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
67
gtk_size_group_add_widget (heading_size_group, widget);
68
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
70
gtk_size_group_add_widget (heading_size_group, widget);
73
window = GTK_WINDOW (gtk_builder_get_object (device_mobile->priv->builder,
75
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
77
g_object_ref (widget);
78
gtk_container_remove (GTK_CONTAINER (window), widget);
79
gtk_notebook_append_page (notebook, widget, NULL);
80
g_object_unref (widget);
85
connection_activate_cb (NMClient *client,
86
NMActiveConnection *connection,
90
NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (user_data);
92
if (connection == NULL) {
93
/* failed to activate */
94
nm_device_mobile_refresh_ui (device_mobile);
99
mobile_connection_changed_cb (GtkComboBox *combo_box, NetDeviceMobile *device_mobile)
102
gchar *object_path = NULL;
105
NMConnection *connection;
108
NMRemoteSettings *remote_settings;
109
CcNetworkPanel *panel;
111
if (device_mobile->priv->updating_device)
114
ret = gtk_combo_box_get_active_iter (combo_box, &iter);
118
device = net_device_get_nm_device (NET_DEVICE (device_mobile));
121
client = net_object_get_client (NET_OBJECT (device_mobile));
122
remote_settings = net_object_get_remote_settings (NET_OBJECT (device_mobile));
125
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
126
gtk_tree_model_get (model, &iter,
127
COLUMN_ID, &object_path,
129
if (g_strcmp0 (object_path, NULL) == 0) {
130
panel = net_object_get_panel (NET_OBJECT (device_mobile));
131
cc_network_panel_connect_to_3g_network (panel,
138
/* activate the connection */
139
g_debug ("try to switch to connection %s", object_path);
140
connection = (NMConnection*) nm_remote_settings_get_connection_by_path (remote_settings,
142
if (connection != NULL) {
143
nm_device_disconnect (device, NULL, NULL);
144
nm_client_activate_connection (client,
147
connection_activate_cb,
152
g_free (object_path);
156
mobilebb_enabled_toggled (NMClient *client,
158
NetDeviceMobile *device_mobile)
164
device = net_device_get_nm_device (NET_DEVICE (device_mobile));
165
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_MODEM)
168
enabled = nm_client_wwan_get_enabled (client);
169
sw = GTK_SWITCH (gtk_builder_get_object (device_mobile->priv->builder,
170
"device_off_switch"));
172
device_mobile->priv->updating_device = TRUE;
173
gtk_switch_set_active (sw, enabled);
174
device_mobile->priv->updating_device = FALSE;
178
device_add_device_connections (NetDeviceMobile *device_mobile,
180
GtkListStore *liststore,
181
GtkComboBox *combobox)
183
NetDeviceMobilePrivate *priv = device_mobile->priv;
186
GtkTreeIter treeiter;
187
NMActiveConnection *active_connection;
188
NMConnection *connection;
189
NMRemoteSettings *remote_settings;
191
/* get the list of available connections for this device */
192
remote_settings = net_object_get_remote_settings (NET_OBJECT (device_mobile));
193
g_assert (remote_settings != NULL);
194
list = nm_remote_settings_list_connections (remote_settings);
195
filtered = nm_device_filter_connections (nm_device, list);
196
gtk_list_store_clear (liststore);
197
active_connection = nm_device_get_active_connection (nm_device);
198
for (l = filtered; l; l = g_slist_next (l)) {
199
connection = NM_CONNECTION (l->data);
200
gtk_list_store_append (liststore, &treeiter);
201
gtk_list_store_set (liststore,
203
COLUMN_ID, nm_connection_get_uuid (connection),
204
COLUMN_TITLE, nm_connection_get_id (connection),
207
/* is this already activated? */
208
if (active_connection != NULL &&
209
g_strcmp0 (nm_connection_get_path (connection),
210
nm_active_connection_get_connection (active_connection)) == 0) {
211
priv->updating_device = TRUE;
212
gtk_combo_box_set_active_iter (combobox, &treeiter);
213
priv->updating_device = FALSE;
217
/* add new connection entry */
218
gtk_list_store_append (liststore, &treeiter);
219
gtk_list_store_set (liststore,
222
COLUMN_TITLE, _("Add new connection"),
226
g_slist_free (filtered);
230
nm_device_mobile_refresh_ui (NetDeviceMobile *device_mobile)
233
gboolean is_connected;
235
GtkListStore *liststore;
238
NetDeviceMobilePrivate *priv = device_mobile->priv;
240
NMDeviceModemCapabilities caps;
243
/* set device kind */
244
nm_device = net_device_get_nm_device (NET_DEVICE (device_mobile));
245
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "label_device"));
246
gtk_label_set_label (GTK_LABEL (widget),
247
panel_device_to_localized_string (nm_device));
249
/* set up the device on/off switch */
250
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch"));
251
gtk_widget_show (widget);
252
client = net_object_get_client (NET_OBJECT (device_mobile));
253
mobilebb_enabled_toggled (client, NULL, device_mobile);
255
/* set device state, with status and optionally speed */
256
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "label_status"));
257
status = g_string_new (panel_device_state_to_localized_string (nm_device));
259
g_string_append (status, " - ");
260
/* Translators: network device speed */
261
g_string_append_printf (status, _("%d Mb/s"), speed);
263
gtk_label_set_label (GTK_LABEL (widget), status->str);
264
g_string_free (status, TRUE);
265
gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device));
267
/* sensitive for other connection types if the device is currently connected */
268
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
270
is_connected = net_device_get_find_connection (NET_DEVICE (device_mobile)) != NULL;
271
gtk_widget_set_sensitive (widget, is_connected);
273
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (nm_device));
274
if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
275
(caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) {
277
str = g_object_get_data (G_OBJECT (nm_device),
278
"ControlCenter::EquipmentIdentifier");
279
panel_set_device_widget_details (device_mobile->priv->builder,
284
str = g_object_get_data (G_OBJECT (nm_device),
285
"ControlCenter::OperatorName");
286
panel_set_device_widget_details (device_mobile->priv->builder,
291
/* add possible connections to device */
292
liststore = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
293
"liststore_mobile_connections"));
294
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_network"));
295
device_add_device_connections (device_mobile,
298
GTK_COMBO_BOX (widget));
301
panel_set_device_widgets (priv->builder, nm_device);
305
device_mobile_refresh (NetObject *object)
307
NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object);
308
nm_device_mobile_refresh_ui (device_mobile);
312
device_off_toggled (GtkSwitch *sw,
314
NetDeviceMobile *device_mobile)
317
const GPtrArray *acs;
320
NMActiveConnection *a;
321
NMConnection *connection;
324
if (device_mobile->priv->updating_device)
327
active = gtk_switch_get_active (sw);
329
client = net_object_get_client (NET_OBJECT (device_mobile));
330
connection = net_device_get_find_connection (NET_DEVICE (device_mobile));
331
if (connection == NULL)
333
nm_client_activate_connection (client,
335
net_device_get_nm_device (NET_DEVICE (device_mobile)),
338
connection = net_device_get_find_connection (NET_DEVICE (device_mobile));
339
if (connection == NULL)
341
path = nm_connection_get_path (connection);
342
client = net_object_get_client (NET_OBJECT (device_mobile));
343
acs = nm_client_get_active_connections (client);
344
for (i = 0; i < acs->len; i++) {
345
a = (NMActiveConnection*)acs->pdata[i];
346
if (strcmp (nm_active_connection_get_connection (a), path) == 0) {
347
nm_client_deactivate_connection (client, a);
355
edit_connection (GtkButton *button, NetDeviceMobile *device_mobile)
357
net_object_edit (NET_OBJECT (device_mobile));
361
device_mobile_device_got_modem_manager_cb (GObject *source_object,
365
GError *error = NULL;
366
GVariant *result = NULL;
368
NMDevice *device = (NMDevice *) user_data;
370
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
372
g_warning ("Error creating ModemManager proxy: %s",
374
g_error_free (error);
379
result = g_dbus_proxy_get_cached_property (proxy,
380
"EquipmentIdentifier");
383
g_object_set_data_full (G_OBJECT (device),
384
"ControlCenter::EquipmentIdentifier",
385
g_variant_dup_string (result, NULL),
389
g_variant_unref (result);
391
g_object_unref (proxy);
395
device_mobile_get_registration_info_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
397
gchar *operator_code = NULL;
398
GError *error = NULL;
399
guint registration_status;
400
GVariant *result = NULL;
401
gchar *operator_name = NULL;
402
gchar *operator_name_safe = NULL;
403
NMDevice *device = (NMDevice *) user_data;
405
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
406
if (result == NULL) {
407
g_warning ("Error getting registration info: %s\n",
409
g_error_free (error);
414
g_variant_get (result, "((uss))",
415
®istration_status,
418
if (operator_name != NULL && operator_name[0] != '\0')
419
operator_name_safe = g_strescape (operator_name, NULL);
422
g_object_set_data_full (G_OBJECT (device),
423
"ControlCenter::OperatorName",
427
g_free (operator_name);
428
g_free (operator_code);
429
g_variant_unref (result);
433
device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object,
437
GError *error = NULL;
439
NMDevice *device = (NMDevice *) user_data;
441
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
443
g_warning ("Error creating ModemManager GSM proxy: %s\n",
445
g_error_free (error);
449
g_dbus_proxy_call (proxy,
450
"GetRegistrationInfo",
452
G_DBUS_CALL_FLAGS_NONE,
455
device_mobile_get_registration_info_cb,
459
g_object_unref (proxy);
463
net_device_mobile_constructed (GObject *object)
465
GCancellable *cancellable;
466
NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object);
470
G_OBJECT_CLASS (net_device_mobile_parent_class)->constructed (object);
472
device = net_device_get_nm_device (NET_DEVICE (device_mobile));
473
cancellable = net_object_get_cancellable (NET_OBJECT (device_mobile));
474
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
475
G_DBUS_PROXY_FLAGS_NONE,
477
"org.freedesktop.ModemManager",
478
nm_device_get_udi (device),
479
"org.freedesktop.ModemManager.Modem",
481
device_mobile_device_got_modem_manager_cb,
483
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
484
G_DBUS_PROXY_FLAGS_NONE,
486
"org.freedesktop.ModemManager",
487
nm_device_get_udi (device),
488
"org.freedesktop.ModemManager.Modem.Gsm.Network",
490
device_mobile_device_got_modem_manager_gsm_cb,
493
client = net_object_get_client (NET_OBJECT (device_mobile));
494
g_signal_connect (client, "notify::wwan-enabled",
495
G_CALLBACK (mobilebb_enabled_toggled),
497
nm_device_mobile_refresh_ui (device_mobile);
501
net_device_mobile_finalize (GObject *object)
503
NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object);
504
NetDeviceMobilePrivate *priv = device_mobile->priv;
506
g_object_unref (priv->builder);
508
G_OBJECT_CLASS (net_device_mobile_parent_class)->finalize (object);
512
net_device_mobile_class_init (NetDeviceMobileClass *klass)
514
GObjectClass *object_class = G_OBJECT_CLASS (klass);
515
NetObjectClass *parent_class = NET_OBJECT_CLASS (klass);
517
object_class->finalize = net_device_mobile_finalize;
518
object_class->constructed = net_device_mobile_constructed;
519
parent_class->add_to_notebook = device_mobile_proxy_add_to_notebook;
520
parent_class->refresh = device_mobile_refresh;
521
g_type_class_add_private (klass, sizeof (NetDeviceMobilePrivate));
525
net_device_mobile_init (NetDeviceMobile *device_mobile)
527
GError *error = NULL;
529
GtkCellRenderer *renderer;
530
GtkComboBox *combobox;
532
device_mobile->priv = NET_DEVICE_MOBILE_GET_PRIVATE (device_mobile);
534
device_mobile->priv->builder = gtk_builder_new ();
535
gtk_builder_add_from_file (device_mobile->priv->builder,
536
GNOMECC_UI_DIR "/network-mobile.ui",
539
g_warning ("Could not load interface file: %s", error->message);
540
g_error_free (error);
544
/* setup mobile combobox model */
545
combobox = GTK_COMBO_BOX (gtk_builder_get_object (device_mobile->priv->builder,
546
"combobox_network"));
547
g_signal_connect (combobox, "changed",
548
G_CALLBACK (mobile_connection_changed_cb),
550
renderer = gtk_cell_renderer_text_new ();
551
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox),
554
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
555
"text", COLUMN_TITLE,
558
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
559
"device_off_switch"));
560
g_signal_connect (widget, "notify::active",
561
G_CALLBACK (device_off_toggled), device_mobile);
563
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
565
g_signal_connect (widget, "clicked",
566
G_CALLBACK (edit_connection), device_mobile);
568
widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder,
569
"device_off_switch"));
570
g_signal_connect (widget, "notify::active",
571
G_CALLBACK (device_off_toggled), device_mobile);