1
From 7469d3c11789a6c42f020c64214b813a925b5417 Mon Sep 17 00:00:00 2001
2
From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
3
Date: Tue, 11 Nov 2014 22:20:30 -0500
4
Subject: [PATCH] wwan: add support for using oFono as a modem manager
6
Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
9
src/devices/wwan/Makefile.am | 7
10
src/devices/wwan/nm-modem-manager.c | 191 ++++-
11
src/devices/wwan/nm-modem-ofono.c | 1329 ++++++++++++++++++++++++++++++++++++
12
src/devices/wwan/nm-modem-ofono.h | 64 +
13
5 files changed, 1590 insertions(+), 10 deletions(-)
14
create mode 100644 src/devices/wwan/nm-modem-ofono.c
15
create mode 100644 src/devices/wwan/nm-modem-ofono.h
18
===================================================================
21
@@ -593,6 +593,15 @@ else
23
AM_CONDITIONAL(WITH_MODEM_MANAGER_1, test "${with_modem_manager_1}" = "yes")
26
+AC_ARG_WITH(ofono, AS_HELP_STRING([--with-ofono], [Enable oFono support]),,[with_ofono=yes])
27
+if (test "${with_ofono}" = "yes"); then
28
+ AC_DEFINE(WITH_OFONO, 1, [Define if you have oFono support])
30
+ AC_DEFINE(WITH_OFONO, 0, [Define if you have oFono support])
32
+AM_CONDITIONAL(WITH_OFONO, test "${with_ofono}" = "yes")
35
AC_ARG_WITH([dhclient], AS_HELP_STRING([--with-dhclient=yes|no|path], [Enable dhclient 4.x support]))
36
AC_ARG_WITH([dhcpcd], AS_HELP_STRING([--with-dhcpcd=yes|no|path], [Enable dhcpcd 4.x support]))
37
Index: b/src/devices/wwan/Makefile.am
38
===================================================================
39
--- a/src/devices/wwan/Makefile.am
40
+++ b/src/devices/wwan/Makefile.am
41
@@ -49,6 +49,13 @@ libnm_wwan_la_SOURCES += \
46
+libnm_wwan_la_SOURCES += \
52
WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver
54
libnm_wwan_la_LDFLAGS = \
55
Index: b/src/devices/wwan/nm-modem-manager.c
56
===================================================================
57
--- a/src/devices/wwan/nm-modem-manager.c
58
+++ b/src/devices/wwan/nm-modem-manager.c
61
* Copyright (C) 2009 - 2014 Red Hat, Inc.
62
* Copyright (C) 2009 Novell, Inc.
63
- * Copyright (C) 2009 Canonical Ltd.
64
+ * Copyright (C) 2009 - 2013 Canonical Ltd.
69
#include "nm-modem-broadband.h"
73
+#include "nm-dbus-manager.h"
74
+#include "nm-modem-ofono.h"
77
#define MODEM_POKE_INTERVAL 120
79
G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT)
80
@@ -57,6 +62,10 @@ struct _NMModemManagerPrivate {
81
guint modem_manager_1_object_removed_id;
85
+ DBusGProxy *ofono_proxy;
91
@@ -235,6 +244,156 @@ enumerate_devices_done (DBusGProxy *prox
92
static void clear_modem_manager_1_support (NMModemManager *self);
97
+ofono_create_modem (NMModemManager *self, const char *path)
99
+ NMModem *modem = NULL;
101
+ GError *err = NULL;
102
+ GValue value = { 0, };
104
+ proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr),
105
+ OFONO_DBUS_SERVICE,
107
+ OFONO_DBUS_INTERFACE_MODEM);
109
+ /* Create a simple TRUE gvalue boolean */
110
+ g_value_init (&value, G_TYPE_BOOLEAN);
111
+ g_value_set_boolean (&value, TRUE);
113
+ /* Mark the modem as powered */
114
+ if (!dbus_g_proxy_call_with_timeout (proxy, "SetProperty", 15000, &err,
115
+ G_TYPE_STRING, "Powered",
116
+ G_TYPE_VALUE, &value,
119
+ nm_log_warn (LOGD_MB, "could not mark modem as powered: %s %s",
120
+ err ? dbus_g_error_get_name (err) : "(none)",
121
+ err ? err->message : "(unknown)");
122
+ g_clear_error (&err);
123
+ /* Don't fail the creation here, some modems are weird. */
126
+ if (g_hash_table_lookup (self->priv->modems, path)) {
127
+ nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path);
131
+ /* Create modem instance */
132
+ modem = nm_modem_ofono_new (path);
134
+ handle_new_modem (self, modem);
136
+ nm_log_warn (LOGD_MB, "Failed to create oFono modem for %s", path);
140
+ofono_modem_added (DBusGProxy *proxy, const char *path, GHashTable *props, gpointer user_data)
142
+ ofono_create_modem (NM_MODEM_MANAGER (user_data), path);
146
+ofono_modem_removed (DBusGProxy *proxy,
148
+ gpointer user_data)
150
+ NMModemManager *self = NM_MODEM_MANAGER (user_data);
153
+ modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path);
157
+ nm_modem_emit_removed (modem);
158
+ g_hash_table_remove (self->priv->modems, path);
161
+#define OFONO_DBUS_MODEM_ENTRY (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID))
162
+#define OFONO_DBUS_MODEM_ENTRIES (dbus_g_type_get_collection ("GPtrArray", OFONO_DBUS_MODEM_ENTRY))
165
+ofono_enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
167
+ NMModemManager *manager = NM_MODEM_MANAGER (data);
169
+ GError *error = NULL;
171
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error,
172
+ OFONO_DBUS_MODEM_ENTRIES, &modems,
174
+ nm_log_warn (LOGD_MB, "could not get modem list: %s", error->message);
175
+ g_error_free (error);
179
+ for (i = 0; i < modems->len; i++) {
180
+ GValueArray *item = g_ptr_array_index (modems, i);
184
+ tmp = g_value_array_get_nth (item, 0);
185
+ path = g_value_get_boxed (tmp);
187
+ ofono_create_modem (manager, path);
189
+ g_value_array_free (item);
192
+ g_ptr_array_free (modems, TRUE);
196
+ofono_appeared (NMModemManager *self)
198
+ nm_log_info (LOGD_MB, "ofono is now available");
200
+ self->priv->ofono_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr),
201
+ OFONO_DBUS_SERVICE, OFONO_DBUS_PATH, OFONO_DBUS_INTERFACE);
203
+ dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
205
+ DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
207
+ dbus_g_proxy_add_signal (self->priv->ofono_proxy, "ModemAdded",
208
+ DBUS_TYPE_G_OBJECT_PATH,
209
+ DBUS_TYPE_G_MAP_OF_VARIANT,
211
+ dbus_g_proxy_connect_signal (self->priv->ofono_proxy, "ModemAdded",
212
+ G_CALLBACK (ofono_modem_added), self,
215
+ dbus_g_proxy_add_signal (self->priv->ofono_proxy, "ModemRemoved",
216
+ DBUS_TYPE_G_OBJECT_PATH,
218
+ dbus_g_proxy_connect_signal (self->priv->ofono_proxy, "ModemRemoved",
219
+ G_CALLBACK (ofono_modem_removed), self,
222
+ dbus_g_proxy_begin_call (self->priv->ofono_proxy,
224
+ ofono_enumerate_devices_done,
225
+ self, NULL, G_TYPE_INVALID);
229
+clear_ofono_support (NMModemManager *self)
231
+ if (self->priv->ofono_proxy) {
232
+ g_object_unref (self->priv->ofono_proxy);
233
+ self->priv->ofono_proxy = NULL;
238
+init_ofono_bus (NMModemManager *self)
240
+ if (nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, OFONO_DBUS_SERVICE))
241
+ ofono_appeared (self);
246
modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices)
248
@@ -303,18 +462,22 @@ nm_modem_manager_name_owner_changed (NMD
249
gboolean old_owner_good;
250
gboolean new_owner_good;
252
- /* Can't handle the signal if its not from the modem service */
253
- if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0)
256
old_owner_good = (old_owner && strlen (old_owner));
257
new_owner_good = (new_owner && strlen (new_owner));
259
- if (!old_owner_good && new_owner_good) {
260
- modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE);
261
- } else if (old_owner_good && !new_owner_good) {
262
- nm_log_info (LOGD_MB, "the modem manager disappeared");
263
- modem_manager_disappeared (NM_MODEM_MANAGER (user_data));
264
+ if (strcmp (MM_OLD_DBUS_SERVICE, name) == 0) {
265
+ if (!old_owner_good && new_owner_good) {
266
+ modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE);
267
+ } else if (old_owner_good && !new_owner_good) {
268
+ nm_log_info (LOGD_MB, "the modem manager disappeared");
269
+ modem_manager_disappeared (NM_MODEM_MANAGER (user_data));
271
+ } else if (strcmp (OFONO_DBUS_SERVICE, name) == 0) {
272
+ if (!old_owner_good && new_owner_good) {
273
+ ofono_appeared (NM_MODEM_MANAGER (user_data));
274
+ } else if (old_owner_good && !new_owner_good) {
275
+ nm_log_info (LOGD_MB, "ofono disappeared");
280
@@ -708,6 +871,10 @@ nm_modem_manager_init (NMModemManager *s
282
modem_manager_disappeared (self);
285
+ init_ofono_bus (self);
288
#if WITH_MODEM_MANAGER_1
289
/* ModemManager >= 0.7 */
290
schedule_modem_manager_1_relaunch (self, 0);
291
@@ -722,6 +889,10 @@ dispose (GObject *object)
292
/* ModemManager < 0.7 */
293
clear_modem_manager_support (self);
296
+ clear_ofono_support (self);
299
#if WITH_MODEM_MANAGER_1
300
/* ModemManager >= 0.7 */
301
clear_modem_manager_1_support (self);
302
Index: b/src/devices/wwan/nm-modem-ofono.c
303
===================================================================
305
+++ b/src/devices/wwan/nm-modem-ofono.c
307
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
308
+/* NetworkManager -- Network link manager
310
+ * This program is free software; you can redistribute it and/or modify
311
+ * it under the terms of the GNU General Public License as published by
312
+ * the Free Software Foundation; either version 2 of the License, or
313
+ * (at your option) any later version.
315
+ * This program is distributed in the hope that it will be useful,
316
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
317
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
318
+ * GNU General Public License for more details.
320
+ * You should have received a copy of the GNU General Public License along
321
+ * with this program; if not, write to the Free Software Foundation, Inc.,
322
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
324
+ * Copyright (C) 2013 Canonical Ltd.
330
+#include <glib/gi18n.h>
332
+#include "nm-dbus-glib-types.h"
333
+#include "nm-modem-ofono.h"
334
+#include "nm-device.h"
335
+#include "nm-device-private.h"
336
+#include "nm-setting-connection.h"
337
+#include "nm-setting-gsm.h"
338
+#include "nm-settings-connection.h"
339
+#include "nm-enum-types.h"
340
+#include "nm-logging.h"
341
+#include "nm-modem.h"
342
+#include "nm-dbus-manager.h"
343
+#include "NetworkManagerUtils.h"
346
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY = 0,
347
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_GPRS,
348
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_EDGE,
349
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_UMTS,
350
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSDPA,
351
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED,
352
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED,
353
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY,
354
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY,
355
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA,
356
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA,
358
+ MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA
359
+} MMModemDeprecatedMode;
362
+ MM_MODEM_GSM_ALLOWED_MODE_ANY = 0,
363
+ MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED = 1,
364
+ MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED = 2,
365
+ MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY = 3,
366
+ MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY = 4,
367
+ MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED = 5,
368
+ MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY = 6,
370
+ MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY
371
+} MMModemGsmAllowedMode;
374
+ MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN = 0x0000,
375
+ /* bits 0..4 order match Ericsson device bitmap */
376
+ MM_MODEM_GSM_ALLOWED_AUTH_NONE = 0x0001,
377
+ MM_MODEM_GSM_ALLOWED_AUTH_PAP = 0x0002,
378
+ MM_MODEM_GSM_ALLOWED_AUTH_CHAP = 0x0004,
379
+ MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP = 0x0008,
380
+ MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2 = 0x0010,
381
+ MM_MODEM_GSM_ALLOWED_AUTH_EAP = 0x0020,
383
+ MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP
384
+} MMModemGsmAllowedAuth;
386
+G_DEFINE_TYPE (NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM)
388
+#define NM_MODEM_OFONO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OFONO, NMModemOfonoPrivate))
391
+ GHashTable *connect_properties;
393
+ NMDBusManager *dbus_mgr;
395
+ DBusGProxy *modem_proxy;
396
+ DBusGProxy *connman_proxy;
397
+ DBusGProxy *context_proxy;
398
+ DBusGProxy *simmanager_proxy;
400
+ DBusGProxyCall *call;
402
+ GError *property_error;
404
+ guint connman_iface_source;
405
+ guint connman_iface_retries;
408
+ char *context_path;
410
+ gboolean modem_online;
411
+ gboolean gprs_attached;
412
+ gboolean gprs_powered;
414
+ NMIP4Config *ip4_config;
416
+ NMModemState state;
417
+} NMModemOfonoPrivate;
419
+#define NM_OFONO_ERROR (nm_ofono_error_quark ())
422
+nm_ofono_error_quark (void)
424
+ static GQuark quark = 0;
426
+ quark = g_quark_from_static_string ("nm-ofono-error");
431
+ip_string_to_network_address (const gchar *str,
434
+ struct in_addr addr;
437
+ if (inet_pton (AF_INET, str, &addr) <= 0)
440
+ *out = (guint32)addr.s_addr;
444
+/* Disconnect stuff */
446
+ NMModemOfono *self;
448
+} SimpleDisconnectContext;
451
+simple_disconnect_context_free (SimpleDisconnectContext *ctx)
453
+ g_object_unref (ctx->self);
454
+ g_slice_free (SimpleDisconnectContext, ctx);
458
+disconnect_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
460
+ SimpleDisconnectContext *ctx = (SimpleDisconnectContext*) user_data;
461
+ NMModemOfono *self = ctx->self;
462
+ GError *error = NULL;
464
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
466
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
468
+ nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s",
469
+ nm_modem_get_uid (NM_MODEM (self)),
470
+ error && error->message ? error->message : "(unknown)");
471
+ g_clear_error (&error);
474
+ simple_disconnect_context_free (ctx);
476
+ g_object_set (NM_MODEM (self), NM_MODEM_STATE, NM_MODEM_STATE_REGISTERED, NULL);
480
+disconnect (NMModem *self,
483
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
484
+ SimpleDisconnectContext *ctx;
485
+ GValue value = G_VALUE_INIT;
487
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
489
+ ctx = g_slice_new (SimpleDisconnectContext);
490
+ ctx->self = g_object_ref (self);
493
+ g_value_init (&value, G_TYPE_BOOLEAN);
494
+ g_value_set_boolean (&value, FALSE);
496
+ dbus_g_proxy_begin_call_with_timeout (priv->context_proxy,
497
+ "SetProperty", disconnect_done,
499
+ G_TYPE_STRING, "Active",
500
+ G_TYPE_VALUE, &value,
506
+deactivate (NMModem *_self, NMDevice *device)
508
+ /* Chain up parent's */
509
+ NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate (_self, device);
513
+get_ofono_proxy (NMModemOfono *self, const char *path, const char *interface)
515
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
516
+ DBusGConnection *bus;
519
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
521
+ proxy = dbus_g_proxy_new_for_name (bus,
522
+ OFONO_DBUS_SERVICE,
529
+static void ofono_read_contexts (NMModemOfono *self);
532
+update_ofono_enabled (NMModemOfono *self,
533
+ gboolean new_enabled)
535
+ NMModemState new_state;
536
+ NMDeviceStateReason reason;
539
+ new_state = NM_MODEM_STATE_REGISTERED;
540
+ reason = NM_DEVICE_STATE_REASON_NONE;
541
+ ofono_read_contexts (self);
543
+ new_state = NM_MODEM_STATE_SEARCHING;
544
+ reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
547
+ nm_modem_set_state (NM_MODEM (self),
549
+ nm_modem_state_to_string (reason));
551
+ nm_log_info (LOGD_MB, "(%s) now in state: %s",
552
+ nm_modem_get_path (NM_MODEM (self)),
553
+ nm_modem_state_to_string(new_state));
557
+get_ofono_conn_manager_properties_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
559
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
560
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
561
+ GError *error = NULL;
562
+ GHashTable *properties = NULL;
563
+ GValue *value = NULL;
565
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
567
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error,
568
+ DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
570
+ nm_log_warn (LOGD_MB, "failed get connection manager properties: (%d) %s",
571
+ error ? error->code : -1,
572
+ error && error->message ? error->message : "(unknown)");
576
+ value = g_hash_table_lookup (properties, "Attached");
578
+ priv->gprs_attached = g_value_get_boolean (value);
580
+ nm_log_warn (LOGD_MB, "failed get GPRS state: unexpected reply type");
581
+ g_value_unset (value);
583
+ value = g_hash_table_lookup (properties, "Powered");
585
+ priv->gprs_powered = g_value_get_boolean (value);
587
+ nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type");
588
+ g_value_unset (value);
590
+ update_ofono_enabled (self, priv->modem_online
591
+ && priv->gprs_powered
592
+ && priv->gprs_attached);
596
+get_ofono_conn_manager_properties (NMModemOfono *self)
598
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
600
+ dbus_g_proxy_begin_call_with_timeout (priv->connman_proxy,
602
+ get_ofono_conn_manager_properties_done,
608
+ofono_conn_properties_changed (DBusGProxy *proxy,
611
+ gpointer user_data)
613
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
614
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
616
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
618
+ if (g_strcmp0 (key, "Powered") == 0 && G_VALUE_HOLDS_BOOLEAN (value)) {
619
+ priv->gprs_powered = g_value_get_boolean (value);
621
+ else if (g_strcmp0 (key, "Attached") == 0 && G_VALUE_HOLDS_BOOLEAN (value)) {
622
+ priv->gprs_attached = g_value_get_boolean (value);
625
+ update_ofono_enabled (self, priv->modem_online
626
+ && priv->gprs_powered
627
+ && priv->gprs_attached);
631
+ofono_read_imsi_contexts_done (DBusGProxy *proxy,
632
+ DBusGProxyCall *call_id,
633
+ gpointer user_data)
635
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
636
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
637
+ GError *error = NULL;
639
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
641
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
642
+ nm_log_warn (LOGD_MB, "failed notify settings plugin of a new context: (%d) %s",
643
+ error ? error->code : -1,
644
+ error && error->message ? error->message : "(unknown)");
650
+ofono_read_contexts (NMModemOfono *self)
652
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
653
+ DBusGConnection *bus;
654
+ DBusGProxy *settings_proxy;
655
+ GHashTable *properties;
656
+ GError *error = NULL;
659
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
660
+ nm_log_info (LOGD_MB, "(%s): trying to read IMSI contexts from oFono files",
661
+ nm_modem_get_path (NM_MODEM (self)));
663
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
665
+ dbus_g_proxy_call_with_timeout (priv->simmanager_proxy,
670
+ DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
674
+ nm_log_warn (LOGD_MB, "Could not get SIM properties: %s",
675
+ error && error->message ? error->message : "(unknown)");
676
+ g_clear_error (&error);
679
+ imsi = g_value_get_string (g_hash_table_lookup (properties, "SubscriberIdentity"));
681
+ settings_proxy = dbus_g_proxy_new_for_name (bus,
682
+ "com.canonical.NMOfono",
683
+ "/com/canonical/NMOfono",
684
+ "com.canonical.NMOfono");
686
+ if (settings_proxy)
687
+ dbus_g_proxy_begin_call_with_timeout (settings_proxy,
688
+ "ReadImsiContexts", ofono_read_imsi_contexts_done,
690
+ G_TYPE_STRING, imsi,
693
+ nm_log_warn (LOGD_MB, "could not get proxy to the oFono Settings plugin.");
697
+ofono_context_added (DBusGProxy *proxy,
700
+ gpointer user_data)
702
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
704
+ nm_log_dbg (LOGD_MB, "context %s added", path);
706
+ ofono_read_contexts (self);
710
+ofono_context_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
712
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
713
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
715
+ nm_log_dbg (LOGD_MB, "context %s removed", path);
719
+ofono_properties_changed (DBusGProxy *proxy,
722
+ gpointer user_data)
724
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
725
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
727
+ nm_log_dbg (LOGD_MB, "in %s: %s", __func__, key);
729
+ if (g_strcmp0 (key, "Online") == 0 && G_VALUE_HOLDS_BOOLEAN (value)) {
730
+ priv->modem_online = g_value_get_boolean (value);
731
+ nm_log_info (LOGD_MB, "(%s) modem is now %s",
732
+ nm_modem_get_path (NM_MODEM (self)),
733
+ priv->modem_online ? "Online" : "Offline");
734
+ update_ofono_enabled (self, priv->modem_online
735
+ && priv->gprs_powered
736
+ && priv->gprs_attached);
737
+ } else if (g_strcmp0 (key, "Interfaces") == 0 && G_VALUE_HOLDS_BOXED (value)) {
738
+ gboolean found_simmanager = FALSE;
739
+ gboolean found_conn_manager = FALSE;
742
+ priv->interfaces = (char **) g_value_get_boxed (value);
743
+ nm_log_info (LOGD_MB, "(%s) updated available interfaces", nm_modem_get_path (NM_MODEM (self)));
745
+ for (i = 0; priv->interfaces[i]; i++) {
746
+ if (g_strrstr (priv->interfaces[i], "SimManager"))
747
+ found_simmanager = TRUE;
748
+ if (g_strrstr (priv->interfaces[i], "ConnectionManager"))
749
+ found_conn_manager = TRUE;
752
+ if (found_simmanager) {
753
+ if (!priv->simmanager_proxy) {
754
+ nm_log_info (LOGD_MB, "(%s): found new SimManager interface",
755
+ nm_modem_get_path (NM_MODEM (self)));
756
+ priv->simmanager_proxy = get_ofono_proxy (self,
757
+ nm_modem_get_path (NM_MODEM (self)),
758
+ OFONO_DBUS_INTERFACE_SIM_MANAGER);
762
+ if (priv->simmanager_proxy) {
763
+ nm_log_info (LOGD_MB, "(%s): SimManager interface disappeared",
764
+ nm_modem_get_path (NM_MODEM (self)));
765
+ g_object_unref (priv->simmanager_proxy);
766
+ priv->simmanager_proxy = NULL;
770
+ if (found_conn_manager) {
771
+ if (!priv->connman_proxy) {
772
+ nm_log_info (LOGD_MB, "(%s): found new ConnectionManager interface",
773
+ nm_modem_get_path (NM_MODEM (self)));
774
+ priv->connman_proxy = get_ofono_proxy (self,
775
+ nm_modem_get_path (NM_MODEM (self)),
776
+ OFONO_DBUS_INTERFACE_CONNECTION_MANAGER);
778
+ if (priv->connman_proxy) {
779
+ get_ofono_conn_manager_properties (self);
781
+ dbus_g_proxy_add_signal (priv->connman_proxy, "PropertyChanged",
782
+ G_TYPE_STRING, G_TYPE_VALUE,
784
+ dbus_g_proxy_connect_signal (priv->connman_proxy, "PropertyChanged",
785
+ G_CALLBACK (ofono_conn_properties_changed),
789
+ dbus_g_proxy_add_signal (priv->connman_proxy, "ContextAdded",
790
+ DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
792
+ dbus_g_proxy_connect_signal (priv->connman_proxy, "ContextAdded",
793
+ G_CALLBACK (ofono_context_added),
796
+ dbus_g_proxy_add_signal (priv->connman_proxy, "ContextRemoved",
797
+ DBUS_TYPE_G_OBJECT_PATH,
799
+ dbus_g_proxy_connect_signal (priv->connman_proxy, "ContextRemoved",
800
+ G_CALLBACK (ofono_context_removed),
807
+ if (priv->connman_proxy) {
808
+ nm_log_info (LOGD_MB, "(%s): ConnectionManager interface disappeared",
809
+ nm_modem_get_path (NM_MODEM (self)));
810
+ g_object_unref (priv->connman_proxy);
811
+ priv->connman_proxy = NULL;
813
+ /* The connection manager proxy disappeared, we should
814
+ * consider the modem disabled.
816
+ update_ofono_enabled (self, FALSE);
817
+ priv->gprs_powered = FALSE;
818
+ priv->gprs_attached = FALSE;
825
+nm_modem_ofono_new (const char *path)
827
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
828
+ g_return_val_if_fail (path != NULL, NULL);
830
+ nm_log_dbg (LOGD_MB, "in %s: path %s", __func__, path);
832
+ return (NMModem *) g_object_new (NM_TYPE_MODEM_OFONO,
833
+ NM_MODEM_PATH, path,
834
+ NM_MODEM_UID, (path + 1),
835
+ NM_MODEM_CONTROL_PORT, "ofono", /* mandatory */
836
+ NM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_STATIC,
837
+ NM_MODEM_STATE, NM_MODEM_STATE_INITIALIZING,
842
+stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
844
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
845
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
846
+ GError *error = NULL;
848
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
852
+ if (priv->connect_properties) {
853
+ g_hash_table_destroy (priv->connect_properties);
854
+ priv->connect_properties = NULL;
857
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
858
+ nm_log_warn (LOGD_MB, "OFONO connection failed: (%d) %s",
859
+ error ? error->code : -1,
860
+ error && error->message ? error->message : "(unknown)");
862
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE,
863
+ NM_DEVICE_STATE_REASON_MODEM_BUSY);
865
+ g_error_free (error);
870
+ofono_context_get_ip_properties (NMModemOfono *self)
872
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
873
+ NMPlatformIP4Address addr;
874
+ NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
875
+ GHashTable *properties, *ip_settings;
876
+ GError *error = NULL;
878
+ const gchar *address_string, *gateway_string, *netmask_string, *iface;
880
+ const gchar *mms_proxy;
882
+ gboolean ret = FALSE;
883
+ guint32 address_network, gateway_network;
887
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
889
+ prop_dict = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
890
+ dbus_g_proxy_call_with_timeout (priv->context_proxy,
894
+ prop_dict, &properties,
898
+ settings = g_hash_table_lookup (properties, "Settings");
899
+ if (settings && G_VALUE_HOLDS_BOXED (settings)) {
900
+ ip_settings = (GHashTable*) g_value_get_boxed (settings);
902
+ if (nm_modem_get_state (NM_MODEM (self)) == NM_MODEM_STATE_CONNECTED
903
+ && g_hash_table_size(ip_settings) <= 0) {
904
+ g_signal_emit_by_name (self, NM_MODEM_PPP_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
908
+ nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:",
909
+ nm_modem_get_uid (NM_MODEM (self)));
911
+ iface = g_value_get_string (g_hash_table_lookup (ip_settings, "Interface"));
913
+ g_object_set (self, NM_MODEM_DATA_PORT, iface, NULL);
915
+ if (priv->ip4_config)
916
+ g_object_unref (priv->ip4_config);
917
+ priv->ip4_config = nm_ip4_config_new ();
919
+ address_string = g_value_get_string (g_hash_table_lookup (ip_settings, "Address"));
920
+ if (address_string) {
921
+ if (ip_string_to_network_address (address_string, &address_network)) {
922
+ addr.address = address_network;
923
+ addr.source = NM_PLATFORM_SOURCE_WWAN;
928
+ /* retrieve netmask and convert to prefix value */
929
+ netmask_string = g_value_get_string (g_hash_table_lookup (ip_settings, "Netmask"));
930
+ if (ip_string_to_network_address (netmask_string, &address_network)) {
931
+ prefix = nm_utils_ip4_netmask_to_prefix (address_network);
933
+ addr.plen = prefix;
937
+ nm_log_info (LOGD_MB, " address %s/%d", address_string, prefix);
938
+ nm_ip4_config_add_address (priv->ip4_config, &addr);
940
+ gateway_string = g_value_get_string (g_hash_table_lookup (ip_settings, "Gateway"));
941
+ if (gateway_string) {
942
+ if (ip_string_to_network_address (gateway_string, &gateway_network)) {
943
+ nm_log_info (LOGD_MB, " gateway %s", gateway_string);
944
+ nm_ip4_config_set_gateway (priv->ip4_config, gateway_network);
950
+ dns = (char **) g_value_get_boxed (g_hash_table_lookup (ip_settings, "DomainNameServers"));
951
+ for (i = 0; dns[i]; i++) {
952
+ if ( ip_string_to_network_address (dns[i], &address_network)
953
+ && address_network > 0) {
954
+ nm_ip4_config_add_nameserver (priv->ip4_config, address_network);
955
+ nm_log_info (LOGD_MB, " DNS %s", dns[i]);
959
+ /* Handle the case for a shared internet and MMS context */
960
+ mms_proxy = g_value_get_string (g_hash_table_lookup (properties, "MessageProxy"));
962
+ nm_log_info (LOGD_MB, " mms proxy: %s", mms_proxy);
964
+ /* If the value can't be mapped to a guint32, it's probably not
965
+ * an IP address; so we could access it via *any* internet
966
+ * connection anyway, no need for a specific host route.
968
+ if (ip_string_to_network_address (mms_proxy, &address_network)) {
969
+ NMPlatformIP4Route mms_route;
971
+ mms_route.network = address_network;
972
+ mms_route.plen = 32;
973
+ mms_route.gateway = gateway_network;
975
+ /* Setting a very low metric as MMS should go through
976
+ * the 3G connection...
978
+ mms_route.metric = 1;
980
+ nm_ip4_config_add_route (priv->ip4_config, &mms_route);
991
+ reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
992
+ g_clear_error (&error);
994
+ reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
998
+ if (nm_modem_get_state (NM_MODEM (self)) != NM_MODEM_STATE_CONNECTED)
999
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, ret, reason);
1003
+context_properties_changed (DBusGProxy *proxy,
1006
+ gpointer user_data)
1008
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
1009
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1011
+ if (g_strcmp0("Settings", key) == 0) {
1012
+ ofono_context_get_ip_properties (self);
1017
+do_context_activate (NMModemOfono *self, char *context_path)
1019
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1020
+ GValue value = G_VALUE_INIT;
1022
+ g_return_val_if_fail (self != NULL, FALSE);
1023
+ g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
1025
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1027
+ g_value_init (&value, G_TYPE_BOOLEAN);
1028
+ g_value_set_boolean (&value, TRUE);
1030
+ if (priv->context_proxy)
1031
+ g_object_unref (priv->context_proxy);
1033
+ priv->context_proxy = get_ofono_proxy (self,
1035
+ OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT);
1037
+ if (!priv->context_proxy) {
1038
+ nm_log_err (LOGD_MB, "could not bring up connection context proxy");
1039
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE,
1040
+ NM_DEVICE_STATE_REASON_MODEM_BUSY);
1044
+ if (!priv->gprs_attached) {
1045
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE,
1046
+ NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER);
1050
+ if (priv->ip4_config) {
1051
+ /* We have an old copy of the settings from a previous activation,
1052
+ * clear it so that we can gate getting the IP config from oFono
1053
+ * on whether or not we have already received them
1055
+ g_object_unref (priv->ip4_config);
1056
+ priv->ip4_config = NULL;
1059
+ dbus_g_proxy_add_signal (priv->context_proxy, "PropertyChanged",
1060
+ G_TYPE_STRING, G_TYPE_VALUE,
1062
+ dbus_g_proxy_connect_signal (priv->context_proxy, "PropertyChanged",
1063
+ G_CALLBACK (context_properties_changed),
1067
+ dbus_g_proxy_begin_call_with_timeout (priv->context_proxy,
1068
+ "SetProperty", stage1_prepare_done,
1069
+ self, NULL, 20000,
1070
+ G_TYPE_STRING, "Active",
1071
+ G_TYPE_VALUE, &value,
1077
+context_set_property (gpointer key, gpointer value, gpointer user_data)
1079
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
1080
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1081
+ GValue val = G_VALUE_INIT;
1083
+ nm_log_dbg (LOGD_MB, "%s -- setting context prop: %s == %s",
1088
+ g_value_init (&val, G_TYPE_STRING);
1089
+ g_value_set_string (&val, (char*)value);
1091
+ if (!priv->property_error) {
1092
+ dbus_g_proxy_call_with_timeout (priv->context_proxy,
1095
+ &priv->property_error,
1096
+ G_TYPE_STRING, (char*)key,
1097
+ G_TYPE_VALUE, &val,
1100
+ nm_log_warn (LOGD_MB, "could not set context property '%s': %s", (char*)key,
1101
+ priv->property_error
1102
+ && priv->property_error->message
1103
+ ? priv->property_error->message : "(unknown)");
1108
+do_context_prepare (NMModemOfono *self, char *context_path)
1110
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1112
+ g_return_val_if_fail (self != NULL, FALSE);
1113
+ g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
1115
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1117
+ if (priv->context_proxy)
1118
+ g_object_unref (priv->context_proxy);
1120
+ priv->context_proxy = get_ofono_proxy (self,
1122
+ OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT);
1124
+ if (priv->context_proxy) {
1125
+ priv->property_error = NULL;
1126
+ g_hash_table_foreach (priv->connect_properties,
1127
+ context_set_property,
1129
+ do_context_activate (self, context_path);
1134
+create_new_context_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
1136
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
1137
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1138
+ GError *error = NULL;
1139
+ char *context_path = NULL;
1140
+ gboolean ret = FALSE;
1142
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1144
+ ret = dbus_g_proxy_end_call (proxy,
1147
+ DBUS_TYPE_G_OBJECT_PATH, &context_path,
1150
+ nm_log_dbg (LOGD_MB, "%s: context path: %s", __func__, context_path);
1153
+ do_context_prepare (self, context_path);
1155
+ nm_log_warn (LOGD_MB, "Ofono modem context creation failed: (%d) %s",
1156
+ error ? error->code : -1,
1157
+ error && error->message ? error->message : "(unknown)");
1159
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
1161
+ g_error_free (error);
1166
+do_create_new_context (NMModemOfono *self)
1168
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1169
+ DBusGProxy *proxy;
1171
+ g_return_val_if_fail (self != NULL, FALSE);
1172
+ g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
1174
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1176
+ if (priv->connman_proxy) {
1177
+ dbus_g_proxy_begin_call_with_timeout (priv->connman_proxy,
1178
+ "AddContext", create_new_context_done,
1179
+ self, NULL, 20000,
1180
+ G_TYPE_STRING, "internet",
1184
+ nm_log_err (LOGD_MB, "could not bring up connection manager proxy "
1185
+ "to add a new context");
1190
+try_create_new_context (NMModemOfono *self)
1192
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1193
+ GHashTable *properties;
1194
+ char **interfaces;
1195
+ GError *error = NULL;
1196
+ gboolean found = FALSE;
1199
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1201
+ /* Only retry up to 20 times */
1202
+ if (priv->connman_iface_retries < 20) {
1203
+ dbus_g_proxy_call_with_timeout (priv->modem_proxy,
1207
+ DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
1211
+ interfaces = (char **) g_value_get_boxed (g_hash_table_lookup (properties, "Interfaces"));
1213
+ for (i = 0; interfaces[i]; i++) {
1214
+ nm_log_dbg (LOGD_MB, "%s ?? %s",
1216
+ OFONO_DBUS_INTERFACE_CONNECTION_MANAGER);
1217
+ if (!g_strcmp0 (interfaces[i],
1218
+ OFONO_DBUS_INTERFACE_CONNECTION_MANAGER)) {
1225
+ nm_log_dbg (LOGD_MB, "failed test for properties: %s",
1226
+ error && error->message ? error->message : "(unknown)");
1228
+ priv->connman_iface_retries++;
1231
+ if (priv->connman_iface_source != 0)
1232
+ g_source_remove (priv->connman_iface_source);
1234
+ priv->connman_iface_source = 0;
1235
+ priv->connman_iface_retries = 0;
1237
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, 0);
1243
+ if (priv->connman_iface_source != 0)
1244
+ g_source_remove (priv->connman_iface_source);
1246
+ priv->connman_iface_source = 0;
1247
+ priv->connman_iface_retries = 0;
1248
+ do_create_new_context (self);
1254
+static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data);
1257
+stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
1259
+ NMModemOfono *self = NM_MODEM_OFONO (user_data);
1260
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1261
+ GError *error = NULL;
1263
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1265
+ if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
1267
+ /* Try once every 5 seconds to see if we've got the right interfaces */
1268
+ priv->connman_iface_retries = 0;
1269
+ priv->connman_iface_source
1270
+ = g_timeout_add (500, (GSourceFunc) try_create_new_context, self);
1272
+ if (priv->context_path)
1273
+ do_context_activate (self, priv->context_path);
1275
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
1277
+ nm_log_warn (LOGD_MB, "OFONO modem enable failed: (%d) %s",
1278
+ error ? error->code : -1,
1279
+ error && error->message ? error->message : "(unknown)");
1281
+ g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
1283
+ g_error_free (error);
1287
+static GHashTable *
1288
+create_connect_properties (NMConnection *connection)
1290
+ NMSettingGsm *setting;
1291
+ GHashTable *properties;
1294
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1296
+ setting = nm_connection_get_setting_gsm (connection);
1297
+ properties = g_hash_table_new (g_str_hash, g_str_equal);
1299
+ str = nm_setting_gsm_get_apn (setting);
1301
+ g_hash_table_insert (properties, "AccessPointName", g_strdup (str));
1303
+ str = nm_setting_gsm_get_username (setting);
1305
+ g_hash_table_insert (properties, "Username", g_strdup (str));
1307
+ str = nm_setting_gsm_get_password (setting);
1309
+ g_hash_table_insert (properties, "Password", g_strdup (str));
1311
+ return properties;
1314
+static NMActStageReturn
1315
+act_stage1_prepare (NMModem *modem,
1316
+ NMConnection *connection,
1317
+ NMDeviceStateReason *reason)
1319
+ NMModemOfono *self = NM_MODEM_OFONO (modem);
1320
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1321
+ const char *context_id;
1322
+ char *context_path;
1325
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1327
+ context_id = nm_connection_get_id (connection);
1328
+ id = g_strsplit (context_id, "/", 0);
1331
+ nm_log_dbg (LOGD_MB, " trying %s %s", id[1], id[2]);
1333
+ if (priv->context_path)
1334
+ g_free (priv->context_path);
1336
+ priv->context_path = g_strdup_printf ("%s/%s",
1337
+ nm_modem_get_path (modem),
1341
+ if (!priv->context_path) {
1342
+ *reason = NM_DEVICE_STATE_REASON_GSM_APN_FAILED;
1343
+ return NM_ACT_STAGE_RETURN_FAILURE;
1346
+ if (priv->connect_properties)
1347
+ g_hash_table_destroy (priv->connect_properties);
1348
+ priv->connect_properties = create_connect_properties (connection);
1350
+ nm_log_info (LOGD_MB, "(%s): activating context %s",
1351
+ nm_modem_get_path (modem),
1352
+ priv->context_path);
1354
+ if (nm_modem_get_state (modem) == NM_MODEM_STATE_REGISTERED) {
1355
+ do_context_activate (self, priv->context_path);
1357
+ nm_log_warn (LOGD_MB, "(%s): could not activate context, "
1358
+ "modem is not registered.",
1359
+ nm_modem_get_path (modem));
1360
+ *reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
1361
+ return NM_ACT_STAGE_RETURN_FAILURE;
1364
+ return NM_ACT_STAGE_RETURN_POSTPONE;
1367
+static NMActStageReturn
1368
+static_stage3_ip4_config_start (NMModem *_self,
1369
+ NMActRequest *req,
1370
+ NMDeviceStateReason *reason)
1372
+ NMModemOfono *self = NM_MODEM_OFONO (_self);
1373
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1374
+ NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
1375
+ GError *error = NULL;
1377
+ if (priv->ip4_config) {
1378
+ g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, priv->ip4_config, error);
1379
+ priv->ip4_config = NULL;
1380
+ g_object_set (self, NM_MODEM_STATE, NM_MODEM_STATE_CONNECTED, NULL);
1381
+ ret = NM_ACT_STAGE_RETURN_POSTPONE;
1388
+check_connection_compatible (NMModem *modem,
1389
+ NMConnection *connection)
1391
+ NMSettingConnection *s_con;
1392
+ NMSettingGsm *s_gsm;
1395
+ s_con = nm_connection_get_setting_connection (connection);
1398
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME))
1401
+ s_gsm = nm_connection_get_setting_gsm (connection);
1405
+ id = nm_connection_get_id (connection);
1406
+ if (!g_strrstr (id, "/context"))
1413
+get_ofono_properties_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
1415
+ NMModem *self = NM_MODEM (user_data);
1416
+ GError *error = NULL;
1417
+ GHashTable *properties = NULL;
1418
+ GValue *value = NULL;
1420
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1422
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error,
1423
+ DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
1424
+ G_TYPE_INVALID)) {
1425
+ nm_log_warn (LOGD_MB, "failed get modem enabled state: (%d) %s",
1426
+ error ? error->code : -1,
1427
+ error && error->message ? error->message : "(unknown)");
1431
+ value = g_hash_table_lookup (properties, "Online");
1433
+ ofono_properties_changed (NULL, "Online", value, self);
1435
+ nm_log_warn (LOGD_MB, "failed get modem online state: unexpected reply type");
1436
+ g_value_unset (value);
1438
+ value = g_hash_table_lookup (properties, "Interfaces");
1440
+ ofono_properties_changed (NULL, "Interfaces", value, self);
1442
+ nm_log_warn (LOGD_MB, "failed get available oFono interfaces: unexpected reply type");
1443
+ g_value_unset (value);
1447
+query_ofono_properties (NMModemOfono *self)
1449
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1450
+ dbus_g_proxy_begin_call (NM_MODEM_OFONO_GET_PRIVATE (self)->modem_proxy,
1451
+ "GetProperties", get_ofono_properties_done,
1458
+set_ofono_enabled (NMModem *self, gboolean enabled)
1460
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1461
+ GValue value = G_VALUE_INIT;
1463
+ GError *error = NULL;
1465
+ g_return_if_fail (self != NULL);
1466
+ g_return_if_fail (NM_IS_MODEM_OFONO (self));
1467
+ g_return_if_fail (priv != NULL);
1468
+ g_return_if_fail (priv->connman_proxy != NULL);
1470
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1472
+ g_value_init (&value, G_TYPE_BOOLEAN);
1473
+ g_value_set_boolean (&value, enabled);
1475
+ ret = dbus_g_proxy_call_with_timeout (priv->connman_proxy,
1479
+ G_TYPE_STRING, "Powered",
1480
+ G_TYPE_VALUE, &value,
1485
+ nm_log_warn (LOGD_MB, "OFONO modem set enabled failed: (%d) %s",
1486
+ error ? error->code : -1,
1487
+ error && error->message ? error->message : "(unknown)");
1490
+ get_ofono_conn_manager_properties (self);
1495
+set_ofono_enabled (NMModem *self, gboolean enabled)
1497
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1499
+ nm_log_info (LOGD_MB, "(%s): trying to set modem to %s",
1500
+ nm_modem_get_path (self),
1501
+ enabled ? "enabled" : "disabled");
1503
+ update_ofono_enabled (NM_MODEM_OFONO (self),
1504
+ priv->modem_online
1505
+ && priv->gprs_powered
1506
+ && priv->gprs_attached);
1510
+get_capabilities (NMModem *_self,
1511
+ NMDeviceModemCapabilities *modem_caps,
1512
+ NMDeviceModemCapabilities *current_caps)
1514
+ NMModemOfono *self = NM_MODEM_OFONO (_self);
1515
+ NMDeviceModemCapabilities all_ofono_caps
1516
+ = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
1518
+ *modem_caps = all_ofono_caps;
1519
+ *current_caps = all_ofono_caps;
1523
+nm_modem_ofono_init (NMModemOfono *self)
1525
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1527
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1529
+ priv->dbus_mgr = nm_dbus_manager_get ();
1531
+ priv->modem_proxy = NULL;
1532
+ priv->connman_proxy = NULL;
1533
+ priv->context_proxy = NULL;
1534
+ priv->simmanager_proxy = NULL;
1536
+ priv->connman_iface_source = 0;
1537
+ priv->connman_iface_retries = 0;
1539
+ priv->modem_online = FALSE;
1540
+ priv->gprs_powered = FALSE;
1541
+ priv->gprs_attached = FALSE;
1543
+ priv->ip4_config = NULL;
1547
+constructor (GType type,
1548
+ guint n_construct_params,
1549
+ GObjectConstructParam *construct_params)
1552
+ NMModemOfonoPrivate *priv;
1553
+ DBusGConnection *bus;
1555
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1557
+ object = G_OBJECT_CLASS (nm_modem_ofono_parent_class)->constructor (type, n_construct_params, construct_params);
1561
+ priv = NM_MODEM_OFONO_GET_PRIVATE (object);
1562
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
1563
+ priv->modem_proxy = get_ofono_proxy (NM_MODEM_OFONO (object),
1564
+ nm_modem_get_path (NM_MODEM (object)),
1565
+ OFONO_DBUS_INTERFACE_MODEM);
1567
+ dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
1569
+ G_TYPE_STRING, G_TYPE_VALUE,
1571
+ dbus_g_proxy_add_signal (priv->modem_proxy, "PropertyChanged",
1572
+ G_TYPE_STRING, G_TYPE_VALUE,
1574
+ dbus_g_proxy_connect_signal (priv->modem_proxy, "PropertyChanged",
1575
+ G_CALLBACK (ofono_properties_changed),
1579
+ query_ofono_properties (NM_MODEM_OFONO (object));
1585
+dispose (GObject *object)
1587
+ NMModemOfono *self = NM_MODEM_OFONO (object);
1588
+ NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
1590
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1592
+ if (priv->connect_properties)
1593
+ g_hash_table_destroy (priv->connect_properties);
1595
+ if (priv->ip4_config)
1596
+ g_object_unref (priv->ip4_config);
1598
+ if (priv->modem_proxy)
1599
+ g_object_unref (priv->modem_proxy);
1600
+ if (priv->connman_proxy)
1601
+ g_object_unref (priv->connman_proxy);
1602
+ if (priv->context_proxy)
1603
+ g_object_unref (priv->context_proxy);
1605
+ G_OBJECT_CLASS (nm_modem_ofono_parent_class)->dispose (object);
1609
+nm_modem_ofono_class_init (NMModemOfonoClass *klass)
1611
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1612
+ NMModemClass *modem_class = NM_MODEM_CLASS (klass);
1614
+ nm_log_dbg (LOGD_MB, "in %s", __func__);
1616
+ g_type_class_add_private (object_class, sizeof (NMModemOfonoPrivate));
1618
+ /* Virtual methods */
1619
+ object_class->constructor = constructor;
1620
+ object_class->dispose = dispose;
1622
+ modem_class->get_capabilities = get_capabilities;
1623
+ modem_class->set_mm_enabled = set_ofono_enabled;
1624
+ modem_class->disconnect = disconnect;
1625
+ modem_class->deactivate = deactivate;
1626
+ //modem_class->get_user_pass = get_user_pass;
1627
+ //modem_class->get_setting_name = get_setting_name;
1628
+ //modem_class->complete_connection = complete_connection;
1629
+ modem_class->check_connection_compatible = check_connection_compatible;
1630
+ modem_class->act_stage1_prepare = act_stage1_prepare;
1631
+ modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start;
1633
+ //dbus_g_error_domain_register (NM_OFONO_ERROR, NULL, NM_TYPE_OFONO_ERROR);
1636
Index: b/src/devices/wwan/nm-modem-ofono.h
1637
===================================================================
1639
+++ b/src/devices/wwan/nm-modem-ofono.h
1641
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
1642
+/* NetworkManager -- Network link manager
1644
+ * This program is free software; you can redistribute it and/or modify
1645
+ * it under the terms of the GNU General Public License as published by
1646
+ * the Free Software Foundation; either version 2 of the License, or
1647
+ * (at your option) any later version.
1649
+ * This program is distributed in the hope that it will be useful,
1650
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1651
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1652
+ * GNU General Public License for more details.
1654
+ * You should have received a copy of the GNU General Public License along
1655
+ * with this program; if not, write to the Free Software Foundation, Inc.,
1656
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1658
+ * Copyright (C) 2013 - Canonical Ltd.
1661
+#ifndef NM_MODEM_OFONO_H
1662
+#define NM_MODEM_OFONO_H
1664
+#include <nm-modem.h>
1668
+#define NM_TYPE_MODEM_OFONO (nm_modem_ofono_get_type ())
1669
+#define NM_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OFONO, NMModemOfono))
1670
+#define NM_IS_MODEM_OFONO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OFONO))
1671
+#define NM_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OFONO, NMModemOfonoClass))
1672
+#define NM_IS_MODEM_OFONO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OFONO))
1673
+#define NM_MODEM_OFONO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OFONO, NMModemOfonoClass))
1674
+#define NM_MODEM_OFONO_MODEM "modem"
1676
+#define OFONO_DBUS_SERVICE "org.ofono"
1677
+#define OFONO_DBUS_PATH "/"
1678
+#define OFONO_DBUS_INTERFACE "org.ofono.Manager"
1679
+#define OFONO_DBUS_INTERFACE_MODEM "org.ofono.Modem"
1680
+#define OFONO_DBUS_INTERFACE_CONNECTION_MANAGER "org.ofono.ConnectionManager"
1681
+#define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext"
1682
+#define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager"
1685
+ NM_OFONO_ERROR_CONNECTION_NOT_OFONO = 0, /*< nick=ConnectionNotOfono >*/
1686
+ NM_OFONO_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/
1687
+ NM_OFONO_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
1695
+ NMModemClass parent;
1696
+} NMModemOfonoClass;
1698
+GType nm_modem_ofono_get_type (void);
1700
+NMModem *nm_modem_ofono_new (const char *path);
1704
+#endif /* NM_MODEM_OFONO_H */