~cyphermox/network-manager/0.9.10.0

« back to all changes in this revision

Viewing changes to debian/patches/0001-wwan-add-support-for-using-oFono-as-a-modem-manager.patch

  • Committer: Mathieu Trudel-Lapierre
  • Date: 2014-11-18 19:44:11 UTC
  • Revision ID: mathieu-tl@ubuntu.com-20141118194411-967gl49p0hkpemhu
* Merged and renamed ofono patches:
  debian/patches/provisioning_wait_ofono_properties.patch,
  debian/patches/track_ip_settings_post_connection.patch,
  debian/patches/dont-check-secrets-for-ofono.patch,
  debian/patches/ofono_mms_support.patch:
  - 0001-wwan-add-support-for-using-oFono-as-a-modem-manager.patch: add
    support for using oFono as a modem manager alongside ModemManager.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
5
 
 
6
Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
 
7
---
 
8
 configure.ac                        |    9 
 
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
 
16
 
 
17
Index: b/configure.ac
 
18
===================================================================
 
19
--- a/configure.ac
 
20
+++ b/configure.ac
 
21
@@ -593,6 +593,15 @@ else
 
22
 fi
 
23
 AM_CONDITIONAL(WITH_MODEM_MANAGER_1, test "${with_modem_manager_1}" = "yes")
 
24
 
 
25
+# OFONO
 
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])
 
29
+else
 
30
+    AC_DEFINE(WITH_OFONO, 0, [Define if you have oFono support])
 
31
+fi
 
32
+AM_CONDITIONAL(WITH_OFONO, test "${with_ofono}" = "yes")
 
33
+
 
34
 # DHCP client support
 
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 += \
 
42
        nm-modem-broadband.h
 
43
 endif
 
44
 
 
45
+if WITH_OFONO
 
46
+libnm_wwan_la_SOURCES += \
 
47
+       nm-modem-ofono.c \
 
48
+       nm-modem-ofono.h \
 
49
+       $(NULL)
 
50
+endif
 
51
+
 
52
 WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver
 
53
 
 
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
 
59
@@ -17,7 +17,7 @@
 
60
  *
 
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.
 
65
  */
 
66
 
 
67
 #include <string.h>
 
68
@@ -35,6 +35,11 @@
 
69
 #include "nm-modem-broadband.h"
 
70
 #endif
 
71
 
 
72
+#if WITH_OFONO
 
73
+#include "nm-dbus-manager.h"
 
74
+#include "nm-modem-ofono.h"
 
75
+#endif
 
76
+
 
77
 #define MODEM_POKE_INTERVAL 120
 
78
 
 
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;
 
82
 #endif
 
83
 
 
84
+#if WITH_OFONO
 
85
+       DBusGProxy *ofono_proxy;
 
86
+#endif
 
87
+
 
88
        /* Common */
 
89
        GHashTable *modems;
 
90
 };
 
91
@@ -235,6 +244,156 @@ enumerate_devices_done (DBusGProxy *prox
 
92
 static void clear_modem_manager_1_support (NMModemManager *self);
 
93
 #endif
 
94
 
 
95
+#if WITH_OFONO
 
96
+static void
 
97
+ofono_create_modem (NMModemManager *self, const char *path)
 
98
+{
 
99
+       NMModem *modem = NULL;
 
100
+       DBusGProxy *proxy;
 
101
+       GError *err = NULL;
 
102
+       GValue value = { 0, };
 
103
+
 
104
+       proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr),
 
105
+                                          OFONO_DBUS_SERVICE,
 
106
+                                          path,
 
107
+                                          OFONO_DBUS_INTERFACE_MODEM);
 
108
+
 
109
+       /* Create a simple TRUE gvalue boolean */
 
110
+       g_value_init (&value, G_TYPE_BOOLEAN);
 
111
+       g_value_set_boolean (&value, TRUE);
 
112
+
 
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,
 
117
+                                            G_TYPE_INVALID,
 
118
+                                            G_TYPE_INVALID)) {
 
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. */
 
124
+       }
 
125
+
 
126
+       if (g_hash_table_lookup (self->priv->modems, path)) {
 
127
+               nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path);
 
128
+               return;
 
129
+       }
 
130
+
 
131
+       /* Create modem instance */
 
132
+       modem = nm_modem_ofono_new (path);
 
133
+       if (modem)
 
134
+               handle_new_modem (self, modem);
 
135
+       else
 
136
+               nm_log_warn (LOGD_MB, "Failed to create oFono modem for %s", path);
 
137
+}
 
138
+
 
139
+static void
 
140
+ofono_modem_added (DBusGProxy *proxy, const char *path, GHashTable *props, gpointer user_data)
 
141
+{
 
142
+       ofono_create_modem (NM_MODEM_MANAGER (user_data), path);
 
143
+}
 
144
+
 
145
+static void
 
146
+ofono_modem_removed (DBusGProxy *proxy,
 
147
+                     const char *path,
 
148
+                     gpointer user_data)
 
149
+{
 
150
+       NMModemManager *self = NM_MODEM_MANAGER (user_data);
 
151
+       NMModem *modem;
 
152
+
 
153
+       modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path);
 
154
+       if (!modem)
 
155
+               return;
 
156
+
 
157
+       nm_modem_emit_removed (modem);
 
158
+       g_hash_table_remove (self->priv->modems, path);
 
159
+}
 
160
+
 
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))
 
163
+
 
164
+static void
 
165
+ofono_enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
 
166
+{
 
167
+       NMModemManager *manager = NM_MODEM_MANAGER (data);
 
168
+       GPtrArray *modems;
 
169
+       GError *error = NULL;
 
170
+
 
171
+       if (!dbus_g_proxy_end_call (proxy, call_id, &error,
 
172
+                                   OFONO_DBUS_MODEM_ENTRIES, &modems,
 
173
+                                   G_TYPE_INVALID)) {
 
174
+               nm_log_warn (LOGD_MB, "could not get modem list: %s", error->message);
 
175
+               g_error_free (error);
 
176
+       } else {
 
177
+               int i;
 
178
+
 
179
+               for (i = 0; i < modems->len; i++) {
 
180
+                       GValueArray *item = g_ptr_array_index (modems, i);
 
181
+                       GValue *tmp;
 
182
+                       const char *path;
 
183
+
 
184
+                       tmp = g_value_array_get_nth (item, 0);
 
185
+                       path = g_value_get_boxed (tmp);
 
186
+
 
187
+                       ofono_create_modem (manager, path);
 
188
+
 
189
+                       g_value_array_free (item);
 
190
+               }
 
191
+
 
192
+               g_ptr_array_free (modems, TRUE);
 
193
+       }
 
194
+}
 
195
+static void
 
196
+ofono_appeared (NMModemManager *self)
 
197
+{
 
198
+       nm_log_info (LOGD_MB, "ofono is now available");
 
199
+
 
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);
 
202
+
 
203
+       dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
 
204
+                                          G_TYPE_NONE,
 
205
+                                          DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
 
206
+                                          G_TYPE_INVALID);
 
207
+       dbus_g_proxy_add_signal (self->priv->ofono_proxy, "ModemAdded",
 
208
+                                DBUS_TYPE_G_OBJECT_PATH,
 
209
+                                DBUS_TYPE_G_MAP_OF_VARIANT,
 
210
+                                G_TYPE_INVALID);
 
211
+       dbus_g_proxy_connect_signal (self->priv->ofono_proxy, "ModemAdded",
 
212
+                                    G_CALLBACK (ofono_modem_added), self,
 
213
+                                    NULL);
 
214
+
 
215
+       dbus_g_proxy_add_signal (self->priv->ofono_proxy, "ModemRemoved",
 
216
+                                DBUS_TYPE_G_OBJECT_PATH,
 
217
+                                G_TYPE_INVALID);
 
218
+       dbus_g_proxy_connect_signal (self->priv->ofono_proxy, "ModemRemoved",
 
219
+                                    G_CALLBACK (ofono_modem_removed), self,
 
220
+                                    NULL);
 
221
+
 
222
+       dbus_g_proxy_begin_call (self->priv->ofono_proxy,
 
223
+                                "GetModems",
 
224
+                                ofono_enumerate_devices_done,
 
225
+                                self, NULL, G_TYPE_INVALID);
 
226
+}
 
227
+
 
228
+static void
 
229
+clear_ofono_support (NMModemManager *self)
 
230
+{
 
231
+       if (self->priv->ofono_proxy) {
 
232
+               g_object_unref (self->priv->ofono_proxy);
 
233
+               self->priv->ofono_proxy = NULL;
 
234
+       }
 
235
+}
 
236
+
 
237
+static void
 
238
+init_ofono_bus (NMModemManager *self)
 
239
+{
 
240
+       if (nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, OFONO_DBUS_SERVICE))
 
241
+               ofono_appeared (self);
 
242
+}
 
243
+#endif
 
244
+
 
245
 static void
 
246
 modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices)
 
247
 {
 
248
@@ -303,18 +462,22 @@ nm_modem_manager_name_owner_changed (NMD
 
249
        gboolean old_owner_good;
 
250
        gboolean new_owner_good;
 
251
 
 
252
-       /* Can't handle the signal if its not from the modem service */
 
253
-       if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0)
 
254
-               return;
 
255
-
 
256
        old_owner_good = (old_owner && strlen (old_owner));
 
257
        new_owner_good = (new_owner && strlen (new_owner));
 
258
 
 
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));
 
270
+               }
 
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");
 
276
+               }
 
277
        }
 
278
 }
 
279
 
 
280
@@ -708,6 +871,10 @@ nm_modem_manager_init (NMModemManager *s
 
281
        else
 
282
                modem_manager_disappeared (self);
 
283
 
 
284
+#if WITH_OFONO
 
285
+       init_ofono_bus (self);
 
286
+#endif
 
287
+
 
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);
 
294
 
 
295
+#if WITH_OFONO
 
296
+       clear_ofono_support (self);
 
297
+#endif
 
298
+
 
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
===================================================================
 
304
--- /dev/null
 
305
+++ b/src/devices/wwan/nm-modem-ofono.c
 
306
@@ -0,0 +1,1329 @@
 
307
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
308
+/* NetworkManager -- Network link manager
 
309
+ *
 
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.
 
314
+ *
 
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.
 
319
+ *
 
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.
 
323
+ *
 
324
+ * Copyright (C) 2013 Canonical Ltd.
 
325
+ */
 
326
+
 
327
+#include "config.h"
 
328
+
 
329
+#include <string.h>
 
330
+#include <glib/gi18n.h>
 
331
+
 
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"
 
344
+
 
345
+typedef enum {
 
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,
 
357
+
 
358
+    MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA
 
359
+} MMModemDeprecatedMode;
 
360
+
 
361
+typedef enum {
 
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,
 
369
+
 
370
+    MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY
 
371
+} MMModemGsmAllowedMode;
 
372
+
 
373
+typedef enum {
 
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,
 
382
+
 
383
+    MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP
 
384
+} MMModemGsmAllowedAuth;
 
385
+
 
386
+G_DEFINE_TYPE (NMModemOfono, nm_modem_ofono, NM_TYPE_MODEM)
 
387
+
 
388
+#define NM_MODEM_OFONO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OFONO, NMModemOfonoPrivate))
 
389
+
 
390
+typedef struct {
 
391
+       GHashTable *connect_properties;
 
392
+
 
393
+       NMDBusManager *dbus_mgr;
 
394
+
 
395
+       DBusGProxy *modem_proxy;
 
396
+       DBusGProxy *connman_proxy;
 
397
+       DBusGProxy *context_proxy;
 
398
+       DBusGProxy *simmanager_proxy;
 
399
+
 
400
+       DBusGProxyCall *call;
 
401
+
 
402
+       GError *property_error;
 
403
+
 
404
+       guint connman_iface_source;
 
405
+       guint connman_iface_retries;
 
406
+
 
407
+       char **interfaces;
 
408
+       char *context_path;
 
409
+
 
410
+       gboolean modem_online;
 
411
+       gboolean gprs_attached;
 
412
+       gboolean gprs_powered;
 
413
+
 
414
+       NMIP4Config *ip4_config;
 
415
+
 
416
+       NMModemState state;
 
417
+} NMModemOfonoPrivate;
 
418
+
 
419
+#define NM_OFONO_ERROR (nm_ofono_error_quark ())
 
420
+
 
421
+static GQuark
 
422
+nm_ofono_error_quark (void)
 
423
+{
 
424
+        static GQuark quark = 0;
 
425
+        if (!quark)
 
426
+                quark = g_quark_from_static_string ("nm-ofono-error");
 
427
+        return quark;
 
428
+}
 
429
+
 
430
+static gboolean
 
431
+ip_string_to_network_address (const gchar *str,
 
432
+                              guint32 *out)
 
433
+{
 
434
+        struct in_addr addr;
 
435
+
 
436
+        /* IP address */
 
437
+        if (inet_pton (AF_INET, str, &addr) <= 0)
 
438
+                return FALSE;
 
439
+
 
440
+        *out = (guint32)addr.s_addr;
 
441
+        return TRUE;
 
442
+}
 
443
+
 
444
+/* Disconnect stuff */
 
445
+typedef struct {
 
446
+        NMModemOfono *self;
 
447
+        gboolean warn;
 
448
+} SimpleDisconnectContext;
 
449
+
 
450
+static void
 
451
+simple_disconnect_context_free (SimpleDisconnectContext *ctx)
 
452
+{
 
453
+        g_object_unref (ctx->self);
 
454
+        g_slice_free (SimpleDisconnectContext, ctx);
 
455
+}
 
456
+
 
457
+static void
 
458
+disconnect_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
 
459
+{
 
460
+       SimpleDisconnectContext *ctx = (SimpleDisconnectContext*) user_data;
 
461
+       NMModemOfono *self = ctx->self;
 
462
+       GError *error = NULL;
 
463
+
 
464
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
465
+
 
466
+       if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
 
467
+               if (ctx->warn)
 
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);
 
472
+       }
 
473
+
 
474
+        simple_disconnect_context_free (ctx);
 
475
+
 
476
+       g_object_set (NM_MODEM (self), NM_MODEM_STATE, NM_MODEM_STATE_REGISTERED, NULL);
 
477
+}
 
478
+
 
479
+static void
 
480
+disconnect (NMModem *self,
 
481
+            gboolean warn)
 
482
+{
 
483
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
484
+        SimpleDisconnectContext *ctx;
 
485
+       GValue value = G_VALUE_INIT;
 
486
+
 
487
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
488
+
 
489
+        ctx = g_slice_new (SimpleDisconnectContext);
 
490
+        ctx->self = g_object_ref (self);
 
491
+        ctx->warn = warn;
 
492
+
 
493
+       g_value_init (&value, G_TYPE_BOOLEAN);
 
494
+       g_value_set_boolean (&value, FALSE);
 
495
+
 
496
+       dbus_g_proxy_begin_call_with_timeout (priv->context_proxy,
 
497
+                                             "SetProperty", disconnect_done,
 
498
+                                             ctx, NULL, 20000,
 
499
+                                             G_TYPE_STRING, "Active",
 
500
+                                             G_TYPE_VALUE, &value,
 
501
+                                             G_TYPE_INVALID);
 
502
+
 
503
+}
 
504
+
 
505
+static void
 
506
+deactivate (NMModem *_self, NMDevice *device)
 
507
+{
 
508
+       /* Chain up parent's */
 
509
+       NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate (_self, device);
 
510
+}
 
511
+
 
512
+DBusGProxy *
 
513
+get_ofono_proxy (NMModemOfono *self, const char *path, const char *interface)
 
514
+{
 
515
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
516
+       DBusGConnection *bus;
 
517
+       DBusGProxy *proxy;
 
518
+
 
519
+       bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
 
520
+
 
521
+       proxy = dbus_g_proxy_new_for_name (bus,
 
522
+                                          OFONO_DBUS_SERVICE,
 
523
+                                          path,
 
524
+                                          interface);
 
525
+
 
526
+       return proxy;
 
527
+}
 
528
+
 
529
+static void ofono_read_contexts (NMModemOfono *self);
 
530
+
 
531
+static void
 
532
+update_ofono_enabled (NMModemOfono *self,
 
533
+                      gboolean new_enabled)
 
534
+{
 
535
+       NMModemState new_state;
 
536
+       NMDeviceStateReason reason;
 
537
+
 
538
+       if (new_enabled) {
 
539
+               new_state = NM_MODEM_STATE_REGISTERED;
 
540
+               reason = NM_DEVICE_STATE_REASON_NONE;
 
541
+               ofono_read_contexts (self);
 
542
+       } else {
 
543
+               new_state = NM_MODEM_STATE_SEARCHING;
 
544
+               reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
 
545
+        }
 
546
+
 
547
+       nm_modem_set_state (NM_MODEM (self),
 
548
+                           new_state,
 
549
+                           nm_modem_state_to_string (reason));
 
550
+
 
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));
 
554
+}
 
555
+
 
556
+static void
 
557
+get_ofono_conn_manager_properties_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 
558
+{
 
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;
 
564
+
 
565
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
566
+
 
567
+       if (!dbus_g_proxy_end_call (proxy, call_id, &error,
 
568
+                                   DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
 
569
+                                   G_TYPE_INVALID)) {
 
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)");
 
573
+               return;
 
574
+       }
 
575
+
 
576
+       value = g_hash_table_lookup (properties, "Attached");
 
577
+       if (value)
 
578
+               priv->gprs_attached = g_value_get_boolean (value);
 
579
+       else
 
580
+               nm_log_warn (LOGD_MB, "failed get GPRS state: unexpected reply type");
 
581
+       g_value_unset (value);
 
582
+
 
583
+       value = g_hash_table_lookup (properties, "Powered");
 
584
+       if (value)
 
585
+               priv->gprs_powered = g_value_get_boolean (value);
 
586
+       else
 
587
+               nm_log_warn (LOGD_MB, "failed get modem enabled state: unexpected reply type");
 
588
+       g_value_unset (value);
 
589
+
 
590
+       update_ofono_enabled (self, priv->modem_online
 
591
+                                   && priv->gprs_powered
 
592
+                                   && priv->gprs_attached);
 
593
+}
 
594
+
 
595
+static void
 
596
+get_ofono_conn_manager_properties (NMModemOfono *self)
 
597
+{
 
598
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
599
+
 
600
+       dbus_g_proxy_begin_call_with_timeout (priv->connman_proxy,
 
601
+                                             "GetProperties",
 
602
+                                             get_ofono_conn_manager_properties_done,
 
603
+                                             self, NULL, 20000,
 
604
+                                             G_TYPE_INVALID);
 
605
+}
 
606
+
 
607
+static void
 
608
+ofono_conn_properties_changed (DBusGProxy *proxy,
 
609
+                               const char *key,
 
610
+                               GValue *value,
 
611
+                               gpointer user_data)
 
612
+{
 
613
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
614
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
615
+
 
616
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
617
+
 
618
+       if (g_strcmp0 (key, "Powered") == 0 && G_VALUE_HOLDS_BOOLEAN (value)) {
 
619
+               priv->gprs_powered = g_value_get_boolean (value);
 
620
+       }
 
621
+       else if (g_strcmp0 (key, "Attached") == 0 && G_VALUE_HOLDS_BOOLEAN (value)) {
 
622
+               priv->gprs_attached = g_value_get_boolean (value);
 
623
+       }
 
624
+
 
625
+       update_ofono_enabled (self, priv->modem_online
 
626
+                                   && priv->gprs_powered
 
627
+                                   && priv->gprs_attached);
 
628
+}
 
629
+
 
630
+static void
 
631
+ofono_read_imsi_contexts_done (DBusGProxy *proxy,
 
632
+                               DBusGProxyCall *call_id,
 
633
+                               gpointer user_data)
 
634
+{
 
635
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
636
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
637
+       GError *error = NULL;
 
638
+
 
639
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
640
+
 
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)");
 
645
+               return;
 
646
+       }
 
647
+}
 
648
+
 
649
+static void
 
650
+ofono_read_contexts (NMModemOfono *self)
 
651
+{
 
652
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
653
+       DBusGConnection *bus;
 
654
+       DBusGProxy *settings_proxy;
 
655
+       GHashTable *properties;
 
656
+       GError *error = NULL;
 
657
+       const char *imsi;
 
658
+
 
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)));
 
662
+
 
663
+       bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
 
664
+
 
665
+       dbus_g_proxy_call_with_timeout (priv->simmanager_proxy,
 
666
+                                       "GetProperties",
 
667
+                                       20000,
 
668
+                                       &error,
 
669
+                                       G_TYPE_INVALID,
 
670
+                                       DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
 
671
+                                       G_TYPE_INVALID);
 
672
+
 
673
+       if (error) {
 
674
+               nm_log_warn (LOGD_MB, "Could not get SIM properties: %s",
 
675
+                            error && error->message ? error->message : "(unknown)");
 
676
+               g_clear_error (&error);
 
677
+       }
 
678
+
 
679
+       imsi = g_value_get_string (g_hash_table_lookup (properties, "SubscriberIdentity"));
 
680
+
 
681
+       settings_proxy = dbus_g_proxy_new_for_name (bus,
 
682
+                                                   "com.canonical.NMOfono",
 
683
+                                                   "/com/canonical/NMOfono",
 
684
+                                                   "com.canonical.NMOfono");
 
685
+
 
686
+       if (settings_proxy)
 
687
+               dbus_g_proxy_begin_call_with_timeout (settings_proxy,
 
688
+                                                     "ReadImsiContexts", ofono_read_imsi_contexts_done,
 
689
+                                                     self, NULL, 20000,
 
690
+                                                     G_TYPE_STRING, imsi,
 
691
+                                                     G_TYPE_INVALID);
 
692
+       else
 
693
+               nm_log_warn (LOGD_MB, "could not get proxy to the oFono Settings plugin.");
 
694
+}
 
695
+
 
696
+static void
 
697
+ofono_context_added (DBusGProxy *proxy,
 
698
+                     const char *path,
 
699
+                     GValue *prop,
 
700
+                     gpointer user_data)
 
701
+{
 
702
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
703
+
 
704
+       nm_log_dbg (LOGD_MB, "context %s added", path);
 
705
+
 
706
+       ofono_read_contexts (self);
 
707
+}
 
708
+
 
709
+static void
 
710
+ofono_context_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
 
711
+{
 
712
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
713
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
714
+
 
715
+       nm_log_dbg (LOGD_MB, "context %s removed", path);
 
716
+}
 
717
+
 
718
+static void
 
719
+ofono_properties_changed (DBusGProxy *proxy,
 
720
+                          const char *key,
 
721
+                          GValue *value,
 
722
+                          gpointer user_data)
 
723
+{
 
724
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
725
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
726
+
 
727
+       nm_log_dbg (LOGD_MB, "in %s: %s", __func__, key);
 
728
+
 
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;
 
740
+               int i;
 
741
+
 
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)));
 
744
+
 
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;
 
750
+               }
 
751
+
 
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);
 
759
+                       }
 
760
+               }
 
761
+               else {
 
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;
 
767
+                       }
 
768
+               }
 
769
+
 
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);
 
777
+
 
778
+                               if (priv->connman_proxy) {
 
779
+                                       get_ofono_conn_manager_properties (self);
 
780
+
 
781
+                                       dbus_g_proxy_add_signal (priv->connman_proxy, "PropertyChanged",
 
782
+                                                               G_TYPE_STRING, G_TYPE_VALUE,
 
783
+                                                               G_TYPE_INVALID);
 
784
+                                       dbus_g_proxy_connect_signal (priv->connman_proxy, "PropertyChanged",
 
785
+                                                               G_CALLBACK (ofono_conn_properties_changed),
 
786
+                                                               self,
 
787
+                                                               NULL);
 
788
+
 
789
+                                       dbus_g_proxy_add_signal (priv->connman_proxy, "ContextAdded",
 
790
+                                                               DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
 
791
+                                                               G_TYPE_INVALID);
 
792
+                                       dbus_g_proxy_connect_signal (priv->connman_proxy, "ContextAdded",
 
793
+                                                               G_CALLBACK (ofono_context_added),
 
794
+                                                               self,
 
795
+                                                               NULL);
 
796
+                                       dbus_g_proxy_add_signal (priv->connman_proxy, "ContextRemoved",
 
797
+                                                               DBUS_TYPE_G_OBJECT_PATH,
 
798
+                                                               G_TYPE_INVALID);
 
799
+                                       dbus_g_proxy_connect_signal (priv->connman_proxy, "ContextRemoved",
 
800
+                                                               G_CALLBACK (ofono_context_removed),
 
801
+                                                               self,
 
802
+                                                               NULL);
 
803
+                               }
 
804
+                       }
 
805
+               }
 
806
+               else {
 
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;
 
812
+
 
813
+                               /* The connection manager proxy disappeared, we should
 
814
+                                * consider the modem disabled.
 
815
+                                */
 
816
+                               update_ofono_enabled (self, FALSE);
 
817
+                               priv->gprs_powered = FALSE;
 
818
+                               priv->gprs_attached = FALSE;
 
819
+                       }
 
820
+               }
 
821
+       }
 
822
+}
 
823
+
 
824
+NMModem *
 
825
+nm_modem_ofono_new (const char *path)
 
826
+{
 
827
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
828
+       g_return_val_if_fail (path != NULL, NULL);
 
829
+
 
830
+       nm_log_dbg (LOGD_MB, "in %s: path %s", __func__, path);
 
831
+
 
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,
 
838
+                                        NULL);
 
839
+}
 
840
+
 
841
+static void
 
842
+stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
 
843
+{
 
844
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
845
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
846
+       GError *error = NULL;
 
847
+
 
848
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
849
+
 
850
+       priv->call = NULL;
 
851
+
 
852
+       if (priv->connect_properties) {
 
853
+               g_hash_table_destroy (priv->connect_properties);
 
854
+               priv->connect_properties = NULL;
 
855
+       }
 
856
+
 
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)");
 
861
+
 
862
+               g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE,
 
863
+                                      NM_DEVICE_STATE_REASON_MODEM_BUSY);
 
864
+
 
865
+               g_error_free (error);
 
866
+       }
 
867
+}
 
868
+
 
869
+static void
 
870
+ofono_context_get_ip_properties (NMModemOfono *self)
 
871
+{
 
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;
 
877
+       GType prop_dict;
 
878
+       const gchar *address_string, *gateway_string, *netmask_string, *iface;
 
879
+       gchar **dns;
 
880
+       const gchar *mms_proxy;
 
881
+       gpointer settings;
 
882
+       gboolean ret = FALSE;
 
883
+       guint32 address_network, gateway_network;
 
884
+       guint i;
 
885
+       guint prefix = 0;
 
886
+
 
887
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
888
+
 
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,
 
891
+                                       "GetProperties",
 
892
+                                       20000, &error,
 
893
+                                       G_TYPE_INVALID,
 
894
+                                       prop_dict, &properties,
 
895
+                                       G_TYPE_INVALID);
 
896
+
 
897
+       if (!error) {
 
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);
 
901
+
 
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);
 
905
+                               return;
 
906
+                       }
 
907
+
 
908
+                       nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:",
 
909
+                                    nm_modem_get_uid (NM_MODEM (self)));
 
910
+
 
911
+                       iface = g_value_get_string (g_hash_table_lookup (ip_settings, "Interface"));
 
912
+                       if (iface)
 
913
+                               g_object_set (self, NM_MODEM_DATA_PORT, iface, NULL);
 
914
+
 
915
+                       if (priv->ip4_config)
 
916
+                               g_object_unref (priv->ip4_config);
 
917
+                       priv->ip4_config = nm_ip4_config_new ();
 
918
+
 
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;
 
924
+                               }
 
925
+                       } else
 
926
+                               goto out;
 
927
+
 
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);
 
932
+                               if (prefix > 0)
 
933
+                                       addr.plen = prefix;
 
934
+                       } else
 
935
+                               goto out;
 
936
+
 
937
+                       nm_log_info (LOGD_MB, "  address %s/%d", address_string, prefix);
 
938
+                       nm_ip4_config_add_address (priv->ip4_config, &addr);
 
939
+
 
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);
 
945
+                               }
 
946
+                       } else
 
947
+                               goto out;
 
948
+
 
949
+                       /* DNS servers */
 
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]);
 
956
+                               }
 
957
+                       }
 
958
+
 
959
+                       /* Handle the case for a shared internet and MMS context */
 
960
+                       mms_proxy = g_value_get_string (g_hash_table_lookup (properties, "MessageProxy"));
 
961
+                       if (mms_proxy) {
 
962
+                               nm_log_info (LOGD_MB, "  mms proxy: %s", mms_proxy);
 
963
+
 
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.
 
967
+                                */
 
968
+                               if (ip_string_to_network_address (mms_proxy, &address_network)) {
 
969
+                                       NMPlatformIP4Route mms_route;
 
970
+
 
971
+                                       mms_route.network = address_network;
 
972
+                                       mms_route.plen = 32;
 
973
+                                       mms_route.gateway = gateway_network;
 
974
+
 
975
+                                       /* Setting a very low metric as MMS should go through
 
976
+                                        * the 3G connection...
 
977
+                                        */
 
978
+                                       mms_route.metric = 1;
 
979
+
 
980
+                                       nm_ip4_config_add_route (priv->ip4_config, &mms_route);
 
981
+                               }
 
982
+                       }
 
983
+
 
984
+                       ret = TRUE;
 
985
+               }
 
986
+       }
 
987
+
 
988
+out:
 
989
+       if (!ret) {
 
990
+               if (error) {
 
991
+                       reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
 
992
+                       g_clear_error (&error);
 
993
+               } else {
 
994
+                       reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
 
995
+               }
 
996
+       }
 
997
+
 
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);
 
1000
+}
 
1001
+
 
1002
+static void
 
1003
+context_properties_changed (DBusGProxy *proxy,
 
1004
+                            const char *key,
 
1005
+                            GValue *value,
 
1006
+                            gpointer user_data)
 
1007
+{
 
1008
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
1009
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1010
+
 
1011
+       if (g_strcmp0("Settings", key) == 0) {
 
1012
+               ofono_context_get_ip_properties (self);
 
1013
+       }
 
1014
+}
 
1015
+
 
1016
+static void
 
1017
+do_context_activate (NMModemOfono *self, char *context_path)
 
1018
+{
 
1019
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1020
+       GValue value = G_VALUE_INIT;
 
1021
+
 
1022
+       g_return_val_if_fail (self != NULL, FALSE);
 
1023
+       g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
 
1024
+
 
1025
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1026
+
 
1027
+       g_value_init (&value, G_TYPE_BOOLEAN);
 
1028
+       g_value_set_boolean (&value, TRUE);
 
1029
+
 
1030
+       if (priv->context_proxy)
 
1031
+               g_object_unref (priv->context_proxy);
 
1032
+
 
1033
+       priv->context_proxy = get_ofono_proxy (self,
 
1034
+                                              context_path,
 
1035
+                                              OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT);
 
1036
+
 
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);
 
1041
+               return;
 
1042
+       }
 
1043
+
 
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);
 
1047
+               return;
 
1048
+       }
 
1049
+
 
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
 
1054
+                */
 
1055
+               g_object_unref (priv->ip4_config);
 
1056
+               priv->ip4_config = NULL;
 
1057
+       }
 
1058
+
 
1059
+       dbus_g_proxy_add_signal (priv->context_proxy, "PropertyChanged",
 
1060
+                                G_TYPE_STRING, G_TYPE_VALUE,
 
1061
+                                G_TYPE_INVALID);
 
1062
+       dbus_g_proxy_connect_signal (priv->context_proxy, "PropertyChanged",
 
1063
+                                    G_CALLBACK (context_properties_changed),
 
1064
+                                    self,
 
1065
+                                    NULL);
 
1066
+
 
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,
 
1072
+                                             G_TYPE_INVALID);
 
1073
+
 
1074
+}
 
1075
+
 
1076
+static void
 
1077
+context_set_property (gpointer key, gpointer value, gpointer user_data)
 
1078
+{
 
1079
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
1080
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1081
+       GValue val = G_VALUE_INIT;
 
1082
+
 
1083
+       nm_log_dbg (LOGD_MB, "%s -- setting context prop: %s == %s",
 
1084
+                   __func__,
 
1085
+                   (char*)key,
 
1086
+                   (char*)value);
 
1087
+
 
1088
+       g_value_init (&val, G_TYPE_STRING);
 
1089
+       g_value_set_string (&val, (char*)value);
 
1090
+
 
1091
+       if (!priv->property_error) {
 
1092
+               dbus_g_proxy_call_with_timeout (priv->context_proxy,
 
1093
+                                               "SetProperty",
 
1094
+                                               20000,
 
1095
+                                               &priv->property_error,
 
1096
+                                               G_TYPE_STRING, (char*)key,
 
1097
+                                               G_TYPE_VALUE, &val,
 
1098
+                                               G_TYPE_INVALID);
 
1099
+       } else {
 
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)");
 
1104
+       }
 
1105
+}
 
1106
+
 
1107
+static void
 
1108
+do_context_prepare (NMModemOfono *self, char *context_path)
 
1109
+{
 
1110
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1111
+
 
1112
+       g_return_val_if_fail (self != NULL, FALSE);
 
1113
+       g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
 
1114
+
 
1115
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1116
+
 
1117
+       if (priv->context_proxy)
 
1118
+               g_object_unref (priv->context_proxy);
 
1119
+
 
1120
+       priv->context_proxy = get_ofono_proxy (self,
 
1121
+                                              context_path,
 
1122
+                                              OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT);
 
1123
+
 
1124
+       if (priv->context_proxy) {
 
1125
+               priv->property_error = NULL;
 
1126
+               g_hash_table_foreach (priv->connect_properties,
 
1127
+                                     context_set_property,
 
1128
+                                     (gpointer) self);
 
1129
+               do_context_activate (self, context_path);
 
1130
+       }
 
1131
+}
 
1132
+
 
1133
+static void
 
1134
+create_new_context_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 
1135
+{
 
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;
 
1141
+
 
1142
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1143
+
 
1144
+        ret = dbus_g_proxy_end_call (proxy,
 
1145
+                                     call_id,
 
1146
+                                    &error,
 
1147
+                                    DBUS_TYPE_G_OBJECT_PATH, &context_path,
 
1148
+                                    G_TYPE_INVALID);
 
1149
+
 
1150
+       nm_log_dbg (LOGD_MB, "%s: context path: %s", __func__, context_path);
 
1151
+
 
1152
+       if (ret)
 
1153
+                do_context_prepare (self, context_path);
 
1154
+        else {
 
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)");
 
1158
+
 
1159
+               g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
 
1160
+
 
1161
+               g_error_free (error);
 
1162
+        }
 
1163
+}
 
1164
+
 
1165
+static void
 
1166
+do_create_new_context (NMModemOfono *self)
 
1167
+{
 
1168
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1169
+       DBusGProxy *proxy;
 
1170
+
 
1171
+       g_return_val_if_fail (self != NULL, FALSE);
 
1172
+       g_return_val_if_fail (NM_IS_MODEM_OFONO (self), FALSE);
 
1173
+
 
1174
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1175
+
 
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",
 
1181
+                                                     G_TYPE_INVALID);
 
1182
+       }
 
1183
+       else {
 
1184
+               nm_log_err (LOGD_MB, "could not bring up connection manager proxy "
 
1185
+                                    "to add a new context");
 
1186
+       }
 
1187
+}
 
1188
+
 
1189
+static gboolean
 
1190
+try_create_new_context (NMModemOfono *self)
 
1191
+{
 
1192
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1193
+       GHashTable *properties;
 
1194
+       char **interfaces;
 
1195
+       GError *error = NULL;
 
1196
+       gboolean found = FALSE;
 
1197
+       int i;
 
1198
+
 
1199
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1200
+
 
1201
+       /* Only retry up to 20 times */
 
1202
+       if (priv->connman_iface_retries < 20) {
 
1203
+               dbus_g_proxy_call_with_timeout (priv->modem_proxy,
 
1204
+                                               "GetProperties",
 
1205
+                                               250, &error,
 
1206
+                                               G_TYPE_INVALID,
 
1207
+                                               DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
 
1208
+                                               G_TYPE_INVALID);
 
1209
+
 
1210
+               if (!error) {
 
1211
+                       interfaces = (char **) g_value_get_boxed (g_hash_table_lookup (properties, "Interfaces"));
 
1212
+
 
1213
+                       for (i = 0; interfaces[i]; i++) {
 
1214
+                               nm_log_dbg (LOGD_MB, "%s ?? %s",
 
1215
+                                           interfaces[i],
 
1216
+                                           OFONO_DBUS_INTERFACE_CONNECTION_MANAGER);
 
1217
+                               if (!g_strcmp0 (interfaces[i],
 
1218
+                                               OFONO_DBUS_INTERFACE_CONNECTION_MANAGER)) {
 
1219
+                                       found = TRUE;
 
1220
+                                       break;
 
1221
+                               }
 
1222
+                       }
 
1223
+               }
 
1224
+               else {
 
1225
+                       nm_log_dbg (LOGD_MB, "failed test for properties: %s",
 
1226
+                                   error && error->message ? error->message : "(unknown)");
 
1227
+               }
 
1228
+               priv->connman_iface_retries++;
 
1229
+       }
 
1230
+       else {
 
1231
+               if (priv->connman_iface_source != 0)
 
1232
+                       g_source_remove (priv->connman_iface_source);
 
1233
+
 
1234
+               priv->connman_iface_source = 0;
 
1235
+               priv->connman_iface_retries = 0;
 
1236
+
 
1237
+               g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, 0);
 
1238
+
 
1239
+               return FALSE;
 
1240
+       }
 
1241
+
 
1242
+       if (found) {
 
1243
+               if (priv->connman_iface_source != 0)
 
1244
+                       g_source_remove (priv->connman_iface_source);
 
1245
+
 
1246
+               priv->connman_iface_source = 0;
 
1247
+               priv->connman_iface_retries = 0;
 
1248
+               do_create_new_context (self);
 
1249
+       }
 
1250
+
 
1251
+       return !found;
 
1252
+}
 
1253
+
 
1254
+static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data);
 
1255
+
 
1256
+static void
 
1257
+stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 
1258
+{
 
1259
+       NMModemOfono *self = NM_MODEM_OFONO (user_data);
 
1260
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1261
+       GError *error = NULL;
 
1262
+
 
1263
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1264
+
 
1265
+       if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
 
1266
+#if 0
 
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);
 
1271
+#endif
 
1272
+               if (priv->context_path)
 
1273
+                       do_context_activate (self, priv->context_path);
 
1274
+               else
 
1275
+                       g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
 
1276
+       } else {
 
1277
+               nm_log_warn (LOGD_MB, "OFONO modem enable failed: (%d) %s",
 
1278
+                            error ? error->code : -1,
 
1279
+                            error && error->message ? error->message : "(unknown)");
 
1280
+
 
1281
+               g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
 
1282
+
 
1283
+               g_error_free (error);
 
1284
+       }
 
1285
+}
 
1286
+
 
1287
+static GHashTable *
 
1288
+create_connect_properties (NMConnection *connection)
 
1289
+{
 
1290
+       NMSettingGsm *setting;
 
1291
+       GHashTable *properties;
 
1292
+       const char *str;
 
1293
+
 
1294
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1295
+
 
1296
+       setting = nm_connection_get_setting_gsm (connection);
 
1297
+       properties = g_hash_table_new (g_str_hash, g_str_equal);
 
1298
+
 
1299
+       str = nm_setting_gsm_get_apn (setting);
 
1300
+       if (str)
 
1301
+               g_hash_table_insert (properties, "AccessPointName", g_strdup (str));
 
1302
+
 
1303
+       str = nm_setting_gsm_get_username (setting);
 
1304
+       if (str)
 
1305
+               g_hash_table_insert (properties, "Username", g_strdup (str));
 
1306
+
 
1307
+       str = nm_setting_gsm_get_password (setting);
 
1308
+       if (str)
 
1309
+               g_hash_table_insert (properties, "Password", g_strdup (str));
 
1310
+
 
1311
+       return properties;
 
1312
+}
 
1313
+
 
1314
+static NMActStageReturn
 
1315
+act_stage1_prepare (NMModem *modem,
 
1316
+                    NMConnection *connection,
 
1317
+                    NMDeviceStateReason *reason)
 
1318
+{
 
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;
 
1323
+       char **id = NULL;
 
1324
+
 
1325
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1326
+
 
1327
+       context_id = nm_connection_get_id (connection);
 
1328
+       id = g_strsplit (context_id, "/", 0);
 
1329
+       g_assert (id[2]);
 
1330
+
 
1331
+       nm_log_dbg (LOGD_MB, " trying %s %s", id[1], id[2]);
 
1332
+
 
1333
+       if (priv->context_path)
 
1334
+               g_free (priv->context_path);
 
1335
+
 
1336
+       priv->context_path = g_strdup_printf ("%s/%s",
 
1337
+                                             nm_modem_get_path (modem),
 
1338
+                                             id[2]);
 
1339
+       g_strfreev (id);
 
1340
+
 
1341
+       if (!priv->context_path) {
 
1342
+               *reason = NM_DEVICE_STATE_REASON_GSM_APN_FAILED;
 
1343
+               return NM_ACT_STAGE_RETURN_FAILURE;
 
1344
+       }
 
1345
+
 
1346
+       if (priv->connect_properties)
 
1347
+               g_hash_table_destroy (priv->connect_properties);
 
1348
+       priv->connect_properties = create_connect_properties (connection);
 
1349
+
 
1350
+       nm_log_info (LOGD_MB, "(%s): activating context %s",
 
1351
+                    nm_modem_get_path (modem),
 
1352
+                    priv->context_path);
 
1353
+
 
1354
+       if (nm_modem_get_state (modem) == NM_MODEM_STATE_REGISTERED) {
 
1355
+               do_context_activate (self, priv->context_path);
 
1356
+       } else {
 
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;
 
1362
+       }
 
1363
+
 
1364
+       return NM_ACT_STAGE_RETURN_POSTPONE;
 
1365
+}
 
1366
+
 
1367
+static NMActStageReturn
 
1368
+static_stage3_ip4_config_start (NMModem *_self,
 
1369
+                                NMActRequest *req,
 
1370
+                                NMDeviceStateReason *reason)
 
1371
+{
 
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;
 
1376
+
 
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;
 
1382
+       }
 
1383
+
 
1384
+       return ret;
 
1385
+}
 
1386
+
 
1387
+static gboolean
 
1388
+check_connection_compatible (NMModem *modem,
 
1389
+                             NMConnection *connection)
 
1390
+{
 
1391
+       NMSettingConnection *s_con;
 
1392
+       NMSettingGsm *s_gsm;
 
1393
+       const char *id;
 
1394
+
 
1395
+       s_con = nm_connection_get_setting_connection (connection);
 
1396
+       g_assert (s_con);
 
1397
+
 
1398
+       if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME))
 
1399
+               return FALSE;
 
1400
+
 
1401
+       s_gsm = nm_connection_get_setting_gsm (connection);
 
1402
+       if (!s_gsm)
 
1403
+               return FALSE;
 
1404
+
 
1405
+       id = nm_connection_get_id (connection);
 
1406
+       if (!g_strrstr (id, "/context"))
 
1407
+               return FALSE;
 
1408
+
 
1409
+       return TRUE;
 
1410
+}
 
1411
+
 
1412
+static void
 
1413
+get_ofono_properties_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 
1414
+{
 
1415
+       NMModem *self = NM_MODEM (user_data);
 
1416
+       GError *error = NULL;
 
1417
+       GHashTable *properties = NULL;
 
1418
+       GValue *value = NULL;
 
1419
+
 
1420
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1421
+
 
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)");
 
1428
+               return;
 
1429
+       }
 
1430
+
 
1431
+       value = g_hash_table_lookup (properties, "Online");
 
1432
+       if (value)
 
1433
+               ofono_properties_changed (NULL, "Online", value, self);
 
1434
+       else
 
1435
+               nm_log_warn (LOGD_MB, "failed get modem online state: unexpected reply type");
 
1436
+       g_value_unset (value);
 
1437
+
 
1438
+       value = g_hash_table_lookup (properties, "Interfaces");
 
1439
+       if (value)
 
1440
+               ofono_properties_changed (NULL, "Interfaces", value, self);
 
1441
+       else
 
1442
+               nm_log_warn (LOGD_MB, "failed get available oFono interfaces: unexpected reply type");
 
1443
+       g_value_unset (value);
 
1444
+}
 
1445
+
 
1446
+static void
 
1447
+query_ofono_properties (NMModemOfono *self)
 
1448
+{
 
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,
 
1452
+                                self, NULL,
 
1453
+                                G_TYPE_INVALID);
 
1454
+}
 
1455
+
 
1456
+#if 0
 
1457
+static void
 
1458
+set_ofono_enabled (NMModem *self, gboolean enabled)
 
1459
+{
 
1460
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1461
+       GValue value = G_VALUE_INIT;
 
1462
+       gboolean ret;
 
1463
+       GError *error = NULL;
 
1464
+
 
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);
 
1469
+
 
1470
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1471
+
 
1472
+       g_value_init (&value, G_TYPE_BOOLEAN);
 
1473
+       g_value_set_boolean (&value, enabled);
 
1474
+
 
1475
+       ret = dbus_g_proxy_call_with_timeout (priv->connman_proxy,
 
1476
+                                             "SetProperty",
 
1477
+                                             20000,
 
1478
+                                             &error,
 
1479
+                                             G_TYPE_STRING, "Powered",
 
1480
+                                             G_TYPE_VALUE, &value,
 
1481
+                                             G_TYPE_INVALID,
 
1482
+                                             G_TYPE_INVALID);
 
1483
+
 
1484
+       if (!ret) {
 
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)");
 
1488
+       }
 
1489
+       else {
 
1490
+               get_ofono_conn_manager_properties (self);
 
1491
+       }
 
1492
+}
 
1493
+#endif
 
1494
+static void
 
1495
+set_ofono_enabled (NMModem *self, gboolean enabled)
 
1496
+{
 
1497
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1498
+
 
1499
+       nm_log_info (LOGD_MB, "(%s): trying to set modem to %s",
 
1500
+                    nm_modem_get_path (self),
 
1501
+                     enabled ? "enabled" : "disabled");
 
1502
+
 
1503
+       update_ofono_enabled (NM_MODEM_OFONO (self),
 
1504
+                             priv->modem_online
 
1505
+                             && priv->gprs_powered
 
1506
+                             && priv->gprs_attached);
 
1507
+}
 
1508
+
 
1509
+static void
 
1510
+get_capabilities (NMModem *_self,
 
1511
+                  NMDeviceModemCapabilities *modem_caps,
 
1512
+                  NMDeviceModemCapabilities *current_caps)
 
1513
+{
 
1514
+       NMModemOfono *self = NM_MODEM_OFONO (_self);
 
1515
+       NMDeviceModemCapabilities all_ofono_caps
 
1516
+           = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
 
1517
+
 
1518
+       *modem_caps = all_ofono_caps;
 
1519
+       *current_caps = all_ofono_caps;
 
1520
+}
 
1521
+
 
1522
+static void
 
1523
+nm_modem_ofono_init (NMModemOfono *self)
 
1524
+{
 
1525
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1526
+
 
1527
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1528
+
 
1529
+       priv->dbus_mgr = nm_dbus_manager_get ();
 
1530
+
 
1531
+       priv->modem_proxy = NULL;
 
1532
+       priv->connman_proxy = NULL;
 
1533
+       priv->context_proxy = NULL;
 
1534
+       priv->simmanager_proxy = NULL;
 
1535
+
 
1536
+       priv->connman_iface_source = 0;
 
1537
+       priv->connman_iface_retries = 0;
 
1538
+
 
1539
+       priv->modem_online = FALSE;
 
1540
+       priv->gprs_powered = FALSE;
 
1541
+       priv->gprs_attached = FALSE;
 
1542
+
 
1543
+       priv->ip4_config = NULL;
 
1544
+}
 
1545
+
 
1546
+static GObject*
 
1547
+constructor (GType type,
 
1548
+                        guint n_construct_params,
 
1549
+                        GObjectConstructParam *construct_params)
 
1550
+{
 
1551
+       GObject *object;
 
1552
+       NMModemOfonoPrivate *priv;
 
1553
+       DBusGConnection *bus;
 
1554
+
 
1555
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1556
+
 
1557
+       object = G_OBJECT_CLASS (nm_modem_ofono_parent_class)->constructor (type, n_construct_params, construct_params);
 
1558
+       if (!object)
 
1559
+               return NULL;
 
1560
+
 
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);
 
1566
+
 
1567
+       dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
 
1568
+                                          G_TYPE_NONE,
 
1569
+                                          G_TYPE_STRING, G_TYPE_VALUE,
 
1570
+                                          G_TYPE_INVALID);
 
1571
+       dbus_g_proxy_add_signal (priv->modem_proxy, "PropertyChanged",
 
1572
+                                G_TYPE_STRING, G_TYPE_VALUE,
 
1573
+                                G_TYPE_INVALID);
 
1574
+       dbus_g_proxy_connect_signal (priv->modem_proxy, "PropertyChanged",
 
1575
+                                    G_CALLBACK (ofono_properties_changed),
 
1576
+                                    object,
 
1577
+                                    NULL);
 
1578
+
 
1579
+       query_ofono_properties (NM_MODEM_OFONO (object));
 
1580
+
 
1581
+       return object;
 
1582
+}
 
1583
+
 
1584
+static void
 
1585
+dispose (GObject *object)
 
1586
+{
 
1587
+       NMModemOfono *self = NM_MODEM_OFONO (object);
 
1588
+       NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
 
1589
+
 
1590
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1591
+
 
1592
+       if (priv->connect_properties)
 
1593
+               g_hash_table_destroy (priv->connect_properties);
 
1594
+
 
1595
+       if (priv->ip4_config)
 
1596
+               g_object_unref (priv->ip4_config);
 
1597
+
 
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);
 
1604
+
 
1605
+       G_OBJECT_CLASS (nm_modem_ofono_parent_class)->dispose (object);
 
1606
+}
 
1607
+
 
1608
+static void
 
1609
+nm_modem_ofono_class_init (NMModemOfonoClass *klass)
 
1610
+{
 
1611
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
1612
+       NMModemClass *modem_class = NM_MODEM_CLASS (klass);
 
1613
+
 
1614
+       nm_log_dbg (LOGD_MB, "in %s", __func__);
 
1615
+
 
1616
+       g_type_class_add_private (object_class, sizeof (NMModemOfonoPrivate));
 
1617
+
 
1618
+       /* Virtual methods */
 
1619
+       object_class->constructor = constructor;
 
1620
+       object_class->dispose = dispose;
 
1621
+
 
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;
 
1632
+
 
1633
+       //dbus_g_error_domain_register (NM_OFONO_ERROR, NULL, NM_TYPE_OFONO_ERROR);
 
1634
+}
 
1635
+
 
1636
Index: b/src/devices/wwan/nm-modem-ofono.h
 
1637
===================================================================
 
1638
--- /dev/null
 
1639
+++ b/src/devices/wwan/nm-modem-ofono.h
 
1640
@@ -0,0 +1,64 @@
 
1641
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
1642
+/* NetworkManager -- Network link manager
 
1643
+ *
 
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.
 
1648
+ *
 
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.
 
1653
+ *
 
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.
 
1657
+ *
 
1658
+ * Copyright (C) 2013 - Canonical Ltd.
 
1659
+ */
 
1660
+
 
1661
+#ifndef NM_MODEM_OFONO_H
 
1662
+#define NM_MODEM_OFONO_H
 
1663
+
 
1664
+#include <nm-modem.h>
 
1665
+
 
1666
+G_BEGIN_DECLS
 
1667
+
 
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"
 
1675
+
 
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"
 
1683
+
 
1684
+typedef enum {
 
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 >*/
 
1688
+} NMOfonoError;
 
1689
+
 
1690
+typedef struct {
 
1691
+       NMModem parent;
 
1692
+} NMModemOfono;
 
1693
+
 
1694
+typedef struct {
 
1695
+       NMModemClass parent;
 
1696
+} NMModemOfonoClass;
 
1697
+
 
1698
+GType nm_modem_ofono_get_type (void);
 
1699
+
 
1700
+NMModem *nm_modem_ofono_new (const char *path);
 
1701
+
 
1702
+G_END_DECLS
 
1703
+
 
1704
+#endif /* NM_MODEM_OFONO_H */