~ubuntu-branches/ubuntu/vivid/modemmanager/vivid-proposed

« back to all changes in this revision

Viewing changes to obsolete-patches/NetworkManager-r4359-use-modem-manager.patch

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2011-06-16 17:12:41 UTC
  • mfrom: (16.1.1 oneiric)
  • Revision ID: james.westby@ubuntu.com-20110616171241-k8vgsdmbpsvx467q
Tags: 0.4.997-1
* debian/watch: Switch to .bz2 tarballs.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
diff --git a/configure.in b/configure.in
2
 
index 8f6f425..921e0bf 100644
3
 
--- a/configure.in
4
 
+++ b/configure.in
5
 
@@ -488,6 +488,7 @@ src/dhcp-manager/Makefile
6
 
 src/supplicant-manager/Makefile
7
 
 src/ppp-manager/Makefile
8
 
 src/dnsmasq-manager/Makefile
9
 
+src/modem-manager/Makefile
10
 
 src/backends/Makefile
11
 
 libnm-util/libnm-util.pc
12
 
 libnm-util/Makefile
13
 
diff --git a/introspection/nm-device-cdma.xml b/introspection/nm-device-cdma.xml
14
 
index 2b43f8f..22a612b 100644
15
 
--- a/introspection/nm-device-cdma.xml
16
 
+++ b/introspection/nm-device-cdma.xml
17
 
@@ -2,14 +2,5 @@
18
 
 
19
 
 <node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
20
 
   <interface name="org.freedesktop.NetworkManager.Device.Cdma">
21
 
-
22
 
-    <signal name="PropertiesChanged">
23
 
-        <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
24
 
-            <tp:docstring>
25
 
-                A dictionary mapping property names to variant boxed values
26
 
-            </tp:docstring>
27
 
-        </arg>
28
 
-    </signal>
29
 
-
30
 
   </interface>
31
 
 </node>
32
 
diff --git a/introspection/nm-device-gsm.xml b/introspection/nm-device-gsm.xml
33
 
index 650d656..0bf7b08 100644
34
 
--- a/introspection/nm-device-gsm.xml
35
 
+++ b/introspection/nm-device-gsm.xml
36
 
@@ -2,14 +2,5 @@
37
 
 
38
 
 <node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
39
 
   <interface name="org.freedesktop.NetworkManager.Device.Gsm">
40
 
-
41
 
-    <signal name="PropertiesChanged">
42
 
-        <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
43
 
-            <tp:docstring>
44
 
-                A dictionary mapping property names to variant boxed values
45
 
-            </tp:docstring>
46
 
-        </arg>
47
 
-    </signal>
48
 
-
49
 
   </interface>
50
 
 </node>
51
 
diff --git a/src/Makefile.am b/src/Makefile.am
52
 
index 3c4ce75..3f24eb5 100644
53
 
--- a/src/Makefile.am
54
 
+++ b/src/Makefile.am
55
 
@@ -5,7 +5,8 @@ SUBDIRS= \
56
 
        supplicant-manager \
57
 
        ppp-manager \
58
 
        backends \
59
 
-       dnsmasq-manager
60
 
+       dnsmasq-manager \
61
 
+       modem-manager
62
 
 
63
 
 INCLUDES = -I${top_srcdir}                   \
64
 
            -I${top_srcdir}/include           \
65
 
@@ -15,6 +16,7 @@ INCLUDES = -I${top_srcdir}                   \
66
 
            -I${top_srcdir}/src/dhcp-manager  \
67
 
            -I${top_srcdir}/src/supplicant-manager  \
68
 
            -I${top_srcdir}/src/dnsmasq-manager  \
69
 
+           -I${top_srcdir}/src/modem-manager  \
70
 
            -I${top_srcdir}/libnm-util \
71
 
            -I${top_srcdir}/callouts
72
 
 
73
 
@@ -59,14 +61,6 @@ NetworkManager_SOURCES =                             \
74
 
                nm-activation-request.h         \
75
 
                nm-properties-changed-signal.c  \
76
 
                nm-properties-changed-signal.h  \
77
 
-               nm-serial-device.c              \
78
 
-               nm-serial-device.h              \
79
 
-               nm-gsm-device.c         \
80
 
-               nm-gsm-device.h         \
81
 
-               nm-cdma-device.c                \
82
 
-               nm-cdma-device.h                \
83
 
-               nm-hso-gsm-device.c \
84
 
-               nm-hso-gsm-device.h \
85
 
                wpa.c                           \
86
 
                wpa.h                           \
87
 
                nm-netlink.c                    \
88
 
@@ -89,15 +83,6 @@ nm-device-ethernet-glue.h: $(top_srcdir)/introspection/nm-device-ethernet.xml
89
 
 nm-device-wifi-glue.h: $(top_srcdir)/introspection/nm-device-wifi.xml
90
 
        dbus-binding-tool --prefix=nm_device_wifi --mode=glib-server --output=$@ $<
91
 
 
92
 
-nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml
93
 
-       dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $<
94
 
-
95
 
-nm-cdma-device-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml
96
 
-       dbus-binding-tool --prefix=nm_cdma_device --mode=glib-server --output=$@ $<
97
 
-
98
 
-nm-gsm-device-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml
99
 
-       dbus-binding-tool --prefix=nm_gsm_device --mode=glib-server --output=$@ $<
100
 
-
101
 
 nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml
102
 
        dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $<
103
 
 
104
 
@@ -113,9 +98,6 @@ BUILT_SOURCES =                                      \
105
 
        nm-device-interface-glue.h                      \
106
 
        nm-device-ethernet-glue.h                       \
107
 
        nm-device-wifi-glue.h           \
108
 
-       nm-serial-device-glue.h \
109
 
-       nm-cdma-device-glue.h \
110
 
-       nm-gsm-device-glue.h \
111
 
        nm-ip4-config-glue.h                            \
112
 
        nm-active-connection-glue.h \
113
 
        nm-dhcp4-config-glue.h
114
 
@@ -150,6 +132,7 @@ NetworkManager_LDADD =                                                      \
115
 
                        ./supplicant-manager/libsupplicant-manager.la           \
116
 
                        ./dnsmasq-manager/libdnsmasq-manager.la         \
117
 
                        ./ppp-manager/libppp-manager.la         \
118
 
+                       ./modem-manager/libmodem-manager.la             \
119
 
                        ./backends/libnmbackend.la                      \
120
 
                        $(top_builddir)/libnm-util/libnm-util.la
121
 
 
122
 
diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c
123
 
index de85d4c..a97103c 100644
124
 
--- a/src/NetworkManagerPolicy.c
125
 
+++ b/src/NetworkManagerPolicy.c
126
 
@@ -34,15 +34,13 @@
127
 
 #include "nm-device.h"
128
 
 #include "nm-device-wifi.h"
129
 
 #include "nm-device-ethernet.h"
130
 
-#include "nm-hso-gsm-device.h"
131
 
-#include "nm-gsm-device.h"
132
 
-#include "nm-cdma-device.h"
133
 
 #include "nm-dbus-manager.h"
134
 
 #include "nm-setting-ip4-config.h"
135
 
 #include "nm-setting-connection.h"
136
 
 #include "NetworkManagerSystem.h"
137
 
 #include "nm-named-manager.h"
138
 
 #include "nm-vpn-manager.h"
139
 
+#include "nm-gsm-modem-hso.h"
140
 
 
141
 
 typedef struct LookupThread LookupThread;
142
 
 
143
 
@@ -235,7 +233,7 @@ get_best_device (NMManager *manager, NMActRequest **out_req)
144
 
                }
145
 
 
146
 
                /* 'hso' devices never get a gateway from the remote end */
147
 
-               if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev))
148
 
+               if (!can_default && !NM_IS_GSM_MODEM_HSO (dev))
149
 
                        continue;
150
 
 
151
 
                prio = nm_device_get_priority (dev);
152
 
diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am
153
 
new file mode 100644
154
 
index 0000000..5331f65
155
 
--- /dev/null
156
 
+++ b/src/modem-manager/Makefile.am
157
 
@@ -0,0 +1,45 @@
158
 
+INCLUDES = \
159
 
+       -I${top_srcdir}/src \
160
 
+       -I${top_srcdir}/include \
161
 
+       -I${top_srcdir}/libnm-util \
162
 
+       -I${top_builddir}/marshallers
163
 
+
164
 
+noinst_LTLIBRARIES = libmodem-manager.la
165
 
+
166
 
+libmodem_manager_la_SOURCES = \
167
 
+       nm-cdma-modem.c \
168
 
+       nm-cdma-modem.h \
169
 
+       nm-gsm-modem.c \
170
 
+       nm-gsm-modem.h \
171
 
+       nm-gsm-modem-hso.c \
172
 
+       nm-gsm-modem-hso.h \
173
 
+       nm-gsm-modem-mbm.c \
174
 
+       nm-gsm-modem-mbm.h \
175
 
+       nm-modem-device.c \
176
 
+       nm-modem-device.h \
177
 
+       nm-modem-manager.h \
178
 
+       nm-modem-manager.c \
179
 
+       nm-modem-types.h
180
 
+
181
 
+libmodem_manager_la_CPPFLAGS = \
182
 
+       $(DBUS_CFLAGS)
183
 
+
184
 
+libmodem_manager_la_LIBADD = \
185
 
+       $(DBUS_LIBS) \
186
 
+       $(top_builddir)/marshallers/libmarshallers.la
187
 
+
188
 
+nm-cdma-device-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml
189
 
+       dbus-binding-tool --prefix=nm_cdma_device --mode=glib-server --output=$@ $<
190
 
+
191
 
+nm-gsm-device-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml
192
 
+       dbus-binding-tool --prefix=nm_gsm_device --mode=glib-server --output=$@ $<
193
 
+
194
 
+nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml
195
 
+       dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $<
196
 
+
197
 
+BUILT_SOURCES = \
198
 
+       nm-cdma-device-glue.h \
199
 
+       nm-gsm-device-glue.h \
200
 
+       nm-serial-device-glue.h
201
 
+
202
 
+CLEANFILES = $(BUILT_SOURCES)
203
 
diff --git a/src/modem-manager/nm-cdma-modem.c b/src/modem-manager/nm-cdma-modem.c
204
 
new file mode 100644
205
 
index 0000000..85532c0
206
 
--- /dev/null
207
 
+++ b/src/modem-manager/nm-cdma-modem.c
208
 
@@ -0,0 +1,264 @@
209
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
210
 
+
211
 
+#include <string.h>
212
 
+
213
 
+#include "nm-cdma-modem.h"
214
 
+#include "nm-modem-types.h"
215
 
+#include "nm-device-interface.h"
216
 
+#include "nm-device-private.h"
217
 
+#include "nm-dbus-manager.h"
218
 
+#include "nm-setting-connection.h"
219
 
+#include "nm-setting-cdma.h"
220
 
+#include "nm-utils.h"
221
 
+
222
 
+#include "nm-cdma-device-glue.h"
223
 
+
224
 
+G_DEFINE_TYPE (NMCdmaModem, nm_cdma_modem, NM_TYPE_MODEM_DEVICE)
225
 
+
226
 
+#define NM_CDMA_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CDMA_MODEM, NMCdmaModemPrivate))
227
 
+
228
 
+enum {
229
 
+       MODEM_STATE_BEGIN,
230
 
+       MODEM_STATE_ENABLE,
231
 
+       MODEM_STATE_CONNECT
232
 
+};
233
 
+
234
 
+typedef struct {
235
 
+       int modem_state;
236
 
+} NMCdmaModemPrivate;
237
 
+
238
 
+enum {
239
 
+       SIGNAL_QUALITY,
240
 
+
241
 
+       LAST_SIGNAL
242
 
+};
243
 
+
244
 
+static guint signals[LAST_SIGNAL] = { 0 };
245
 
+
246
 
+NMDevice *
247
 
+nm_cdma_modem_new (const char *path,
248
 
+                           const char *data_device,
249
 
+                           const char *driver)
250
 
+{
251
 
+       g_return_val_if_fail (path != NULL, NULL);
252
 
+       g_return_val_if_fail (data_device != NULL, NULL);
253
 
+       g_return_val_if_fail (driver != NULL, NULL);
254
 
+
255
 
+       return (NMDevice *) g_object_new (NM_TYPE_CDMA_MODEM,
256
 
+                                                           NM_DEVICE_INTERFACE_UDI, path,
257
 
+                                                           NM_DEVICE_INTERFACE_IFACE, data_device,
258
 
+                                                           NM_DEVICE_INTERFACE_DRIVER, driver,
259
 
+                                                           NM_DEVICE_INTERFACE_MANAGED, TRUE,
260
 
+                                                           NM_MODEM_DEVICE_PATH, path,
261
 
+                                                           NULL);
262
 
+}
263
 
+
264
 
+static NMSetting *
265
 
+get_setting (NMCdmaModem *device, GType setting_type)
266
 
+{
267
 
+       NMActRequest *req;
268
 
+       NMSetting *setting = NULL;
269
 
+
270
 
+       req = nm_device_get_act_request (NM_DEVICE (device));
271
 
+       if (req) {
272
 
+               NMConnection *connection;
273
 
+
274
 
+               connection = nm_act_request_get_connection (req);
275
 
+               if (connection)
276
 
+                       setting = nm_connection_get_setting (connection, setting_type);
277
 
+       }
278
 
+
279
 
+       return setting;
280
 
+}
281
 
+
282
 
+static void
283
 
+state_machine (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
284
 
+{
285
 
+       NMCdmaModem *modem = NM_CDMA_MODEM (user_data);
286
 
+       NMCdmaModemPrivate *priv = NM_CDMA_MODEM_GET_PRIVATE (modem);
287
 
+       NMSettingCdma *setting;
288
 
+       GError *error = NULL;
289
 
+
290
 
+       setting = NM_SETTING_CDMA (get_setting (modem, NM_TYPE_SETTING_CDMA));
291
 
+
292
 
+       if (call_id)
293
 
+               dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
294
 
+
295
 
+       if (error) {
296
 
+               nm_warning ("CDMA modem connection failed: %s", error->message);
297
 
+               nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
298
 
+               return;
299
 
+       }
300
 
+
301
 
+       switch (priv->modem_state) {
302
 
+       case MODEM_STATE_BEGIN:
303
 
+               priv->modem_state = MODEM_STATE_ENABLE;
304
 
+               dbus_g_proxy_begin_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (modem), NULL),
305
 
+                                                       "Enable", state_machine,
306
 
+                                                       modem, NULL,
307
 
+                                                       G_TYPE_BOOLEAN, TRUE,
308
 
+                                                       G_TYPE_INVALID);
309
 
+               break;
310
 
+       case MODEM_STATE_ENABLE:
311
 
+               priv->modem_state = MODEM_STATE_CONNECT;
312
 
+               dbus_g_proxy_begin_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (modem), NULL),
313
 
+                                                       "Connect", state_machine,
314
 
+                                                       modem, NULL,
315
 
+                                                       G_TYPE_STRING, nm_setting_cdma_get_number (setting),
316
 
+                                                       G_TYPE_INVALID);
317
 
+               break;
318
 
+       case MODEM_STATE_CONNECT:
319
 
+               nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem));
320
 
+               break;
321
 
+       default:
322
 
+               nm_warning ("Invalid modem state %d", priv->modem_state);
323
 
+               nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
324
 
+               break;
325
 
+       }
326
 
+}
327
 
+
328
 
+static NMActStageReturn
329
 
+real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
330
 
+{
331
 
+       NMCdmaModemPrivate *priv = NM_CDMA_MODEM_GET_PRIVATE (device);
332
 
+
333
 
+       priv->modem_state = MODEM_STATE_BEGIN;
334
 
+       state_machine (NULL, NULL, device);
335
 
+
336
 
+       return NM_ACT_STAGE_RETURN_POSTPONE;
337
 
+}
338
 
+
339
 
+static NMConnection *
340
 
+real_get_best_auto_connection (NMDevice *dev,
341
 
+                               GSList *connections,
342
 
+                               char **specific_object)
343
 
+{
344
 
+       GSList *iter;
345
 
+
346
 
+       for (iter = connections; iter; iter = g_slist_next (iter)) {
347
 
+               NMConnection *connection = NM_CONNECTION (iter->data);
348
 
+               NMSettingConnection *s_con;
349
 
+
350
 
+               s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
351
 
+               g_assert (s_con);
352
 
+
353
 
+               if (!nm_setting_connection_get_autoconnect (s_con))
354
 
+                       continue;
355
 
+
356
 
+               if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME))
357
 
+                       continue;
358
 
+
359
 
+               return connection;
360
 
+       }
361
 
+       return NULL;
362
 
+}
363
 
+
364
 
+static void
365
 
+real_connection_secrets_updated (NMDevice *dev,
366
 
+                                 NMConnection *connection,
367
 
+                                 GSList *updated_settings,
368
 
+                                 RequestSecretsCaller caller)
369
 
+{
370
 
+       NMActRequest *req;
371
 
+       gboolean found = FALSE;
372
 
+       GSList *iter;
373
 
+
374
 
+       if (caller == SECRETS_CALLER_PPP) {
375
 
+               NMPPPManager *ppp_manager;
376
 
+               NMSettingCdma *s_cdma = NULL;
377
 
+
378
 
+               ppp_manager = nm_modem_device_get_ppp_manager (NM_MODEM_DEVICE (dev));
379
 
+               g_return_if_fail (ppp_manager != NULL);
380
 
+
381
 
+               s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
382
 
+               if (!s_cdma) {
383
 
+                       /* Shouldn't ever happen */
384
 
+                       nm_ppp_manager_update_secrets (ppp_manager,
385
 
+                                                      nm_device_get_iface (dev),
386
 
+                                                      NULL,
387
 
+                                                      NULL,
388
 
+                                                      "missing CDMA setting; no secrets could be found.");
389
 
+               } else {
390
 
+                       const char *username = nm_setting_cdma_get_username (s_cdma);
391
 
+                       const char *password = nm_setting_cdma_get_password (s_cdma);
392
 
+
393
 
+                       nm_ppp_manager_update_secrets (ppp_manager,
394
 
+                                                      nm_device_get_iface (dev),
395
 
+                                                      username ? username : "",
396
 
+                                                      password ? password : "",
397
 
+                                                      NULL);
398
 
+               }
399
 
+               return;
400
 
+       }
401
 
+
402
 
+       g_return_if_fail (caller == SECRETS_CALLER_CDMA);
403
 
+       g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
404
 
+
405
 
+       for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
406
 
+               const char *setting_name = (const char *) iter->data;
407
 
+
408
 
+               if (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME))
409
 
+                       found = TRUE;
410
 
+               else
411
 
+                       nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
412
 
+       }
413
 
+
414
 
+       if (!found)
415
 
+               return;
416
 
+
417
 
+       req = nm_device_get_act_request (dev);
418
 
+       g_assert (req);
419
 
+
420
 
+       g_return_if_fail (nm_act_request_get_connection (req) == connection);
421
 
+
422
 
+       nm_device_activate_schedule_stage1_device_prepare (dev);
423
 
+}
424
 
+
425
 
+static const char *
426
 
+real_get_ppp_name (NMModemDevice *device, NMConnection *connection)
427
 
+{
428
 
+       NMSettingCdma *s_cdma;
429
 
+
430
 
+       s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
431
 
+       g_assert (s_cdma);
432
 
+
433
 
+       return nm_setting_cdma_get_username (s_cdma);
434
 
+}
435
 
+
436
 
+/*****************************************************************************/
437
 
+
438
 
+static void
439
 
+nm_cdma_modem_init (NMCdmaModem *self)
440
 
+{
441
 
+       nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_CDMA);
442
 
+}
443
 
+
444
 
+static void
445
 
+nm_cdma_modem_class_init (NMCdmaModemClass *klass)
446
 
+{
447
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
448
 
+       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
449
 
+       NMModemDeviceClass *modem_class = NM_MODEM_DEVICE_CLASS (klass);
450
 
+
451
 
+       g_type_class_add_private (object_class, sizeof (NMCdmaModemPrivate));
452
 
+
453
 
+       /* Virtual methods */
454
 
+       device_class->get_best_auto_connection = real_get_best_auto_connection;
455
 
+       device_class->connection_secrets_updated = real_connection_secrets_updated;
456
 
+       device_class->act_stage1_prepare = real_act_stage1_prepare;
457
 
+       modem_class->get_ppp_name = real_get_ppp_name;
458
 
+
459
 
+       /* Signals */
460
 
+       signals[SIGNAL_QUALITY] =
461
 
+               g_signal_new ("signal-quality",
462
 
+                                   G_OBJECT_CLASS_TYPE (object_class),
463
 
+                                   G_SIGNAL_RUN_FIRST,
464
 
+                                   G_STRUCT_OFFSET (NMCdmaModemClass, signal_quality),
465
 
+                                   NULL, NULL,
466
 
+                                   g_cclosure_marshal_VOID__UINT,
467
 
+                                   G_TYPE_NONE, 1,
468
 
+                                   G_TYPE_UINT);
469
 
+
470
 
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
471
 
+                                                          &dbus_glib_nm_cdma_device_object_info);
472
 
+}
473
 
diff --git a/src/modem-manager/nm-cdma-modem.h b/src/modem-manager/nm-cdma-modem.h
474
 
new file mode 100644
475
 
index 0000000..5dc3c14
476
 
--- /dev/null
477
 
+++ b/src/modem-manager/nm-cdma-modem.h
478
 
@@ -0,0 +1,36 @@
479
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
480
 
+
481
 
+#ifndef NM_CDMA_MODEM_H
482
 
+#define NM_CDMA_MODEM_H
483
 
+
484
 
+#include <nm-modem-device.h>
485
 
+
486
 
+G_BEGIN_DECLS
487
 
+
488
 
+#define NM_TYPE_CDMA_MODEM            (nm_cdma_modem_get_type ())
489
 
+#define NM_CDMA_MODEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CDMA_MODEM, NMCdmaModem))
490
 
+#define NM_CDMA_MODEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_CDMA_MODEM, NMCdmaModemClass))
491
 
+#define NM_IS_CDMA_MODEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CDMA_MODEM))
492
 
+#define NM_IS_CDMA_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_CDMA_MODEM))
493
 
+#define NM_CDMA_MODEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_CDMA_MODEM, NMCdmaModemClass))
494
 
+
495
 
+typedef struct {
496
 
+       NMModemDevice parent;
497
 
+} NMCdmaModem;
498
 
+
499
 
+typedef struct {
500
 
+       NMModemDeviceClass parent;
501
 
+
502
 
+       /* Signals */
503
 
+       void (*signal_quality) (NMCdmaModem *modem, guint32 quality);
504
 
+} NMCdmaModemClass;
505
 
+
506
 
+GType nm_cdma_modem_get_type (void);
507
 
+
508
 
+NMDevice *nm_cdma_modem_new (const char *path,
509
 
+                                           const char *data_device,
510
 
+                                           const char *driver);
511
 
+
512
 
+G_END_DECLS
513
 
+
514
 
+#endif /* NM_CDMA_MODEM_H */
515
 
diff --git a/src/modem-manager/nm-gsm-modem-hso.c b/src/modem-manager/nm-gsm-modem-hso.c
516
 
new file mode 100644
517
 
index 0000000..15b79b6
518
 
--- /dev/null
519
 
+++ b/src/modem-manager/nm-gsm-modem-hso.c
520
 
@@ -0,0 +1,348 @@
521
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
522
 
+
523
 
+#include "nm-gsm-modem-hso.h"
524
 
+#include "nm-device-private.h"
525
 
+#include "nm-device-interface.h"
526
 
+#include "NetworkManagerSystem.h"
527
 
+#include "nm-setting-connection.h"
528
 
+#include "nm-setting-gsm.h"
529
 
+#include "nm-modem-types.h"
530
 
+#include "nm-utils.h"
531
 
+
532
 
+G_DEFINE_TYPE (NMGsmModemHso, nm_gsm_modem_hso, NM_TYPE_GSM_MODEM)
533
 
+
534
 
+#define NM_GSM_MODEM_HSO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_MODEM_HSO, NMGsmModemHsoPrivate))
535
 
+
536
 
+typedef struct {
537
 
+       char *netdev_iface;
538
 
+       NMIP4Config *pending_ip4_config;
539
 
+} NMGsmModemHsoPrivate;
540
 
+
541
 
+#define HSO_SECRETS_TRIES "gsm-secrets-tries"
542
 
+
543
 
+static char *
544
 
+get_network_device (NMDevice *device)
545
 
+{
546
 
+       char *result = NULL;
547
 
+       GError *error = NULL;
548
 
+       GValue value = { 0, };
549
 
+
550
 
+       if (!dbus_g_proxy_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), "org.freedesktop.DBus.Properties"),
551
 
+                                           "Get", &error,
552
 
+                                           G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_HSO,
553
 
+                                           G_TYPE_STRING, "NetworkDevice",
554
 
+                                           G_TYPE_INVALID,
555
 
+                                           G_TYPE_VALUE, &value,
556
 
+                                           G_TYPE_INVALID)) {
557
 
+               nm_warning ("Could not get HSO device's network interface: %s", error->message);
558
 
+               g_error_free (error);
559
 
+       } else {
560
 
+               if (G_VALUE_HOLDS_STRING (&value))
561
 
+                       result = g_value_dup_string (&value);
562
 
+               else
563
 
+                       nm_warning ("Could not get HSO device's network interface: wrong type '%s'",
564
 
+                                         G_VALUE_TYPE_NAME (&value));
565
 
+
566
 
+               g_value_unset (&value);
567
 
+       }
568
 
+
569
 
+       return result;
570
 
+}
571
 
+
572
 
+NMDevice *
573
 
+nm_gsm_modem_hso_new (const char *path,
574
 
+                                 const char *data_device,
575
 
+                                 const char *driver)
576
 
+{
577
 
+       NMDevice *device;
578
 
+
579
 
+       g_return_val_if_fail (path != NULL, NULL);
580
 
+       g_return_val_if_fail (data_device != NULL, NULL);
581
 
+       g_return_val_if_fail (driver != NULL, NULL);
582
 
+
583
 
+       device = (NMDevice *) g_object_new (NM_TYPE_GSM_MODEM_HSO,
584
 
+                                                                NM_DEVICE_INTERFACE_UDI, path,
585
 
+                                                                NM_DEVICE_INTERFACE_IFACE, data_device,
586
 
+                                                                NM_DEVICE_INTERFACE_DRIVER, driver,
587
 
+                                                                NM_DEVICE_INTERFACE_MANAGED, TRUE,
588
 
+                                                                NM_MODEM_DEVICE_PATH, path,
589
 
+                                                                NULL);
590
 
+
591
 
+       if (device) {
592
 
+               NMGsmModemHsoPrivate *priv;
593
 
+
594
 
+               priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
595
 
+               priv->netdev_iface = get_network_device (device);
596
 
+               if (!priv->netdev_iface) {
597
 
+                       g_object_unref (device);
598
 
+                       device = NULL;
599
 
+               }
600
 
+       }
601
 
+
602
 
+       return device;
603
 
+}
604
 
+
605
 
+/*****************************************************************************/
606
 
+
607
 
+static NMSetting *
608
 
+get_setting (NMGsmModemHso *modem, GType setting_type)
609
 
+{
610
 
+       NMActRequest *req;
611
 
+       NMSetting *setting = NULL;
612
 
+
613
 
+       req = nm_device_get_act_request (NM_DEVICE (modem));
614
 
+       if (req) {
615
 
+               NMConnection *connection;
616
 
+
617
 
+               connection = nm_act_request_get_connection (req);
618
 
+               if (connection)
619
 
+                       setting = nm_connection_get_setting (connection, setting_type);
620
 
+       }
621
 
+
622
 
+       return setting;
623
 
+}
624
 
+
625
 
+static void
626
 
+hso_auth_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
627
 
+{
628
 
+       NMDevice *device = NM_DEVICE (user_data);
629
 
+       GError *error = NULL;
630
 
+
631
 
+       if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID))
632
 
+               nm_device_activate_schedule_stage3_ip_config_start (device);
633
 
+       else {
634
 
+               nm_warning ("Authentication failed: %s", error->message);
635
 
+               g_error_free (error);
636
 
+               nm_device_state_changed (device,
637
 
+                                                       NM_DEVICE_STATE_FAILED,
638
 
+                                                       NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED);
639
 
+       }
640
 
+}
641
 
+
642
 
+static void
643
 
+do_hso_auth (NMGsmModemHso *device)
644
 
+{
645
 
+       NMSettingGsm *s_gsm;
646
 
+       const char *username;
647
 
+       const char *password;
648
 
+
649
 
+       s_gsm = NM_SETTING_GSM (get_setting (device, NM_TYPE_SETTING_GSM));
650
 
+       username = nm_setting_gsm_get_username (s_gsm);
651
 
+       password = nm_setting_gsm_get_password (s_gsm);
652
 
+
653
 
+       dbus_g_proxy_begin_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), MM_DBUS_INTERFACE_MODEM_GSM_HSO),
654
 
+                                               "Authenticate", hso_auth_done,
655
 
+                                               device, NULL,
656
 
+                                               G_TYPE_STRING, username ? username : "",
657
 
+                                               G_TYPE_STRING, password ? password : "",
658
 
+                                               G_TYPE_INVALID);
659
 
+}
660
 
+
661
 
+static NMActStageReturn
662
 
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
663
 
+{
664
 
+       NMActRequest *req;
665
 
+       NMConnection *connection;
666
 
+       const char *setting_name;
667
 
+       GPtrArray *hints = NULL;
668
 
+       const char *hint1 = NULL, *hint2 = NULL;
669
 
+       guint32 tries;
670
 
+
671
 
+       req = nm_device_get_act_request (device);
672
 
+       g_assert (req);
673
 
+       connection = nm_act_request_get_connection (req);
674
 
+       g_assert (connection);
675
 
+
676
 
+       setting_name = nm_connection_need_secrets (connection, &hints);
677
 
+       if (!setting_name) {
678
 
+               do_hso_auth (NM_GSM_MODEM_HSO (device));
679
 
+               return NM_ACT_STAGE_RETURN_POSTPONE;
680
 
+       }
681
 
+
682
 
+       if (hints) {
683
 
+               if (hints->len > 0)
684
 
+                       hint1 = g_ptr_array_index (hints, 0);
685
 
+               if (hints->len > 1)
686
 
+                       hint2 = g_ptr_array_index (hints, 1);
687
 
+       }
688
 
+
689
 
+       nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
690
 
+
691
 
+       tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), HSO_SECRETS_TRIES));
692
 
+       nm_act_request_request_connection_secrets (req,
693
 
+                                                  setting_name,
694
 
+                                                  tries ? TRUE : FALSE,
695
 
+                                                  SECRETS_CALLER_HSO_GSM,
696
 
+                                                  hint1,
697
 
+                                                  hint2);
698
 
+       g_object_set_data (G_OBJECT (connection), HSO_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
699
 
+
700
 
+       if (hints)
701
 
+               g_ptr_array_free (hints, TRUE);
702
 
+
703
 
+       return NM_ACT_STAGE_RETURN_POSTPONE;
704
 
+}
705
 
+
706
 
+static void
707
 
+get_ip4_config_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
708
 
+{
709
 
+       NMDevice *device = NM_DEVICE (user_data);
710
 
+       guint32 ip4_address;
711
 
+       GArray *dns_array;
712
 
+       GError *error = NULL;
713
 
+
714
 
+       if (dbus_g_proxy_end_call (proxy, call_id, &error,
715
 
+                                                 G_TYPE_UINT, &ip4_address,
716
 
+                                                 DBUS_TYPE_G_UINT_ARRAY, &dns_array,
717
 
+                                                 G_TYPE_INVALID)) {
718
 
+
719
 
+               NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
720
 
+               NMIP4Address *addr;
721
 
+               int i;
722
 
+
723
 
+               addr = nm_ip4_address_new ();
724
 
+               nm_ip4_address_set_address (addr, ip4_address);
725
 
+               nm_ip4_address_set_prefix (addr, 32);
726
 
+
727
 
+               priv->pending_ip4_config = nm_ip4_config_new ();
728
 
+               nm_ip4_config_take_address (priv->pending_ip4_config, addr);
729
 
+
730
 
+               for (i = 0; i < dns_array->len; i++)
731
 
+                       nm_ip4_config_add_nameserver (priv->pending_ip4_config,
732
 
+                                                                       g_array_index (dns_array, guint32, i));
733
 
+
734
 
+               nm_device_activate_schedule_stage4_ip_config_get (device);
735
 
+       } else {
736
 
+               nm_warning ("Retrieving IP4 configuration failed: %s", error->message);
737
 
+               g_error_free (error);
738
 
+               nm_device_state_changed (device,
739
 
+                                                       NM_DEVICE_STATE_FAILED,
740
 
+                                                       NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
741
 
+       }
742
 
+}
743
 
+
744
 
+static NMActStageReturn
745
 
+real_act_stage3_ip_config_start (NMDevice *device, NMDeviceStateReason *reason)
746
 
+{
747
 
+       dbus_g_proxy_begin_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), MM_DBUS_INTERFACE_MODEM_GSM_HSO),
748
 
+                                               "GetIP4Config", get_ip4_config_done,
749
 
+                                               device, NULL,
750
 
+                                               G_TYPE_INVALID);
751
 
+
752
 
+       return NM_ACT_STAGE_RETURN_POSTPONE;
753
 
+}
754
 
+
755
 
+static NMActStageReturn
756
 
+real_act_stage4_get_ip4_config (NMDevice *device,
757
 
+                                NMIP4Config **config,
758
 
+                                NMDeviceStateReason *reason)
759
 
+{
760
 
+       NMGsmModemHso *self = NM_GSM_MODEM_HSO (device);
761
 
+       NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (self);
762
 
+       gboolean no_firmware = FALSE;
763
 
+
764
 
+       nm_device_set_ip_iface (device, priv->netdev_iface);
765
 
+       if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) {
766
 
+               if (no_firmware)
767
 
+                       *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING;
768
 
+               else
769
 
+                       *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
770
 
+               return NM_ACT_STAGE_RETURN_FAILURE;
771
 
+       }
772
 
+
773
 
+       *config = priv->pending_ip4_config;
774
 
+       priv->pending_ip4_config = NULL;
775
 
+
776
 
+       return NM_ACT_STAGE_RETURN_SUCCESS;
777
 
+}
778
 
+
779
 
+static void
780
 
+real_deactivate (NMDevice *device)
781
 
+{
782
 
+       NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
783
 
+
784
 
+       if (priv->pending_ip4_config) {
785
 
+               g_object_unref (priv->pending_ip4_config);
786
 
+               priv->pending_ip4_config = NULL;
787
 
+       }
788
 
+
789
 
+       if (priv->netdev_iface) {
790
 
+               nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface);
791
 
+               nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface);
792
 
+               nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL);
793
 
+       }
794
 
+       nm_device_set_ip_iface (device, NULL);
795
 
+
796
 
+       if (NM_DEVICE_CLASS (nm_gsm_modem_hso_parent_class)->deactivate)
797
 
+               NM_DEVICE_CLASS (nm_gsm_modem_hso_parent_class)->deactivate (device);
798
 
+}
799
 
+
800
 
+static gboolean
801
 
+real_hw_is_up (NMDevice *device)
802
 
+{
803
 
+       NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
804
 
+       NMDeviceState state;
805
 
+
806
 
+       state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
807
 
+       if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
808
 
+               return nm_system_device_is_up_with_iface (priv->netdev_iface);
809
 
+
810
 
+       return TRUE;
811
 
+}
812
 
+
813
 
+static gboolean
814
 
+real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
815
 
+{
816
 
+       NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (device);
817
 
+       NMDeviceState state;
818
 
+
819
 
+       state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
820
 
+       if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
821
 
+               return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware);
822
 
+
823
 
+       return TRUE;
824
 
+}
825
 
+
826
 
+static void
827
 
+real_connect (NMModemDevice *modem, const char *number)
828
 
+{
829
 
+       nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem));
830
 
+}
831
 
+
832
 
+/*****************************************************************************/
833
 
+
834
 
+static void
835
 
+nm_gsm_modem_hso_init (NMGsmModemHso *self)
836
 
+{
837
 
+}
838
 
+
839
 
+static void
840
 
+finalize (GObject *object)
841
 
+{
842
 
+       NMGsmModemHsoPrivate *priv = NM_GSM_MODEM_HSO_GET_PRIVATE (object);
843
 
+
844
 
+       g_free (priv->netdev_iface);
845
 
+
846
 
+       G_OBJECT_CLASS (nm_gsm_modem_hso_parent_class)->finalize (object);
847
 
+}
848
 
+
849
 
+static void
850
 
+nm_gsm_modem_hso_class_init (NMGsmModemHsoClass *klass)
851
 
+{
852
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
853
 
+       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
854
 
+       NMModemDeviceClass *modem_class = NM_MODEM_DEVICE_CLASS (klass);
855
 
+
856
 
+       g_type_class_add_private (object_class, sizeof (NMGsmModemHsoPrivate));
857
 
+
858
 
+       object_class->finalize = finalize;
859
 
+
860
 
+       device_class->act_stage2_config = real_act_stage2_config;
861
 
+       device_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start;
862
 
+       device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
863
 
+       device_class->deactivate = real_deactivate;
864
 
+       device_class->hw_is_up = real_hw_is_up;
865
 
+       device_class->hw_bring_up = real_hw_bring_up;
866
 
+
867
 
+       modem_class->connect = real_connect;
868
 
+}
869
 
diff --git a/src/modem-manager/nm-gsm-modem-hso.h b/src/modem-manager/nm-gsm-modem-hso.h
870
 
new file mode 100644
871
 
index 0000000..9b16b0b
872
 
--- /dev/null
873
 
+++ b/src/modem-manager/nm-gsm-modem-hso.h
874
 
@@ -0,0 +1,33 @@
875
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
876
 
+
877
 
+#ifndef NM_GSM_MODEM_HSO_H
878
 
+#define NM_GSM_MODEM_HSO_H
879
 
+
880
 
+#include <nm-gsm-modem.h>
881
 
+
882
 
+G_BEGIN_DECLS
883
 
+
884
 
+#define NM_TYPE_GSM_MODEM_HSO            (nm_gsm_modem_hso_get_type ())
885
 
+#define NM_GSM_MODEM_HSO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_MODEM_HSO, NMGsmModemHso))
886
 
+#define NM_GSM_MODEM_HSO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_GSM_MODEM_HSO, NMGsmModemHsoClass))
887
 
+#define NM_IS_GSM_MODEM_HSO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_MODEM_HSO))
888
 
+#define NM_IS_GSM_MODEM_HSO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_GSM_MODEM_HSO))
889
 
+#define NM_GSM_MODEM_HSO_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_GSM_MODEM_HSO, NMGsmModemHsoClass))
890
 
+
891
 
+typedef struct {
892
 
+       NMGsmModem parent;
893
 
+} NMGsmModemHso;
894
 
+
895
 
+typedef struct {
896
 
+       NMGsmModemClass parent;
897
 
+} NMGsmModemHsoClass;
898
 
+
899
 
+GType nm_gsm_modem_hso_get_type (void);
900
 
+
901
 
+NMDevice *nm_gsm_modem_hso_new (const char *path,
902
 
+                                                 const char *data_device,
903
 
+                                                 const char *driver);
904
 
+
905
 
+G_END_DECLS
906
 
+
907
 
+#endif /* NM_GSM_MODEM_HSO_H */
908
 
diff --git a/src/modem-manager/nm-gsm-modem-mbm.c b/src/modem-manager/nm-gsm-modem-mbm.c
909
 
new file mode 100644
910
 
index 0000000..37ca844
911
 
--- /dev/null
912
 
+++ b/src/modem-manager/nm-gsm-modem-mbm.c
913
 
@@ -0,0 +1,261 @@
914
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
915
 
+/*
916
 
+  Additions to NetworkManager, network-manager-applet and modemmanager
917
 
+  for supporting Ericsson modules like F3507g.
918
 
+
919
 
+  Author: Per Hallsmark <per@hallsmark.se>
920
 
+
921
 
+  This program is free software; you can redistribute it and/or modify
922
 
+  it under the terms of the GNU General Public License as published by
923
 
+  the Free Software Foundation; either version 2 of the License, or
924
 
+  (at your option) any later version.
925
 
+
926
 
+  This program is distributed in the hope that it will be useful,
927
 
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
928
 
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
929
 
+
930
 
+  GNU General Public License for more details.
931
 
+
932
 
+  You should have received a copy of the GNU General Public License
933
 
+  along with this program; if not, write to the Free Software
934
 
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
935
 
+
936
 
+*/
937
 
+
938
 
+#include "nm-gsm-modem-mbm.h"
939
 
+#include "nm-device-private.h"
940
 
+#include "nm-device-interface.h"
941
 
+#include "NetworkManagerSystem.h"
942
 
+#include "nm-setting-connection.h"
943
 
+#include "nm-setting-gsm.h"
944
 
+#include "nm-modem-types.h"
945
 
+#include "nm-utils.h"
946
 
+
947
 
+G_DEFINE_TYPE (NMGsmModemMbm, nm_gsm_modem_mbm, NM_TYPE_GSM_MODEM)
948
 
+
949
 
+#define NM_GSM_MODEM_MBM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmPrivate))
950
 
+
951
 
+typedef struct {
952
 
+       char *netdev_iface;
953
 
+       NMIP4Config *pending_ip4_config;
954
 
+} NMGsmModemMbmPrivate;
955
 
+
956
 
+#define MBM_SECRETS_TRIES "gsm-secrets-tries"
957
 
+
958
 
+static char *
959
 
+get_network_device (NMDevice *device)
960
 
+{
961
 
+       char *result = NULL;
962
 
+       GError *error = NULL;
963
 
+       GValue value = { 0, };
964
 
+
965
 
+       if (!dbus_g_proxy_call (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), "org.freedesktop.DBus.Properties"),
966
 
+                                           "Get", &error,
967
 
+                                           G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_MBM,
968
 
+                                           G_TYPE_STRING, "NetworkDevice",
969
 
+                                           G_TYPE_INVALID,
970
 
+                                           G_TYPE_VALUE, &value,
971
 
+                                           G_TYPE_INVALID)) {
972
 
+               nm_warning ("Could not get MBM device's network interface: %s", error->message);
973
 
+               g_error_free (error);
974
 
+       } else {
975
 
+               if (G_VALUE_HOLDS_STRING (&value))
976
 
+                       result = g_value_dup_string (&value);
977
 
+               else
978
 
+                       nm_warning ("Could not get MBM device's network interface: wrong type '%s'",
979
 
+                                         G_VALUE_TYPE_NAME (&value));
980
 
+
981
 
+               g_value_unset (&value);
982
 
+       }
983
 
+
984
 
+       return result;
985
 
+}
986
 
+
987
 
+NMDevice *
988
 
+nm_gsm_modem_mbm_new (const char *path,
989
 
+                                 const char *data_device,
990
 
+                                 const char *driver)
991
 
+{
992
 
+       NMDevice *device;
993
 
+
994
 
+       g_return_val_if_fail (path != NULL, NULL);
995
 
+       g_return_val_if_fail (data_device != NULL, NULL);
996
 
+       g_return_val_if_fail (driver != NULL, NULL);
997
 
+
998
 
+       device = (NMDevice *) g_object_new (NM_TYPE_GSM_MODEM_MBM,
999
 
+                                                                NM_DEVICE_INTERFACE_UDI, path,
1000
 
+                                                                NM_DEVICE_INTERFACE_IFACE, data_device,
1001
 
+                                                                NM_DEVICE_INTERFACE_DRIVER, driver,
1002
 
+                                                                NM_DEVICE_INTERFACE_MANAGED, TRUE,
1003
 
+                                                                NM_MODEM_DEVICE_PATH, path,
1004
 
+                                                                NULL);
1005
 
+
1006
 
+       if (device) {
1007
 
+               NMGsmModemMbmPrivate *priv;
1008
 
+
1009
 
+               priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
1010
 
+               priv->netdev_iface = get_network_device (device);
1011
 
+               if (!priv->netdev_iface) {
1012
 
+                       g_object_unref (device);
1013
 
+                       device = NULL;
1014
 
+               }
1015
 
+       }
1016
 
+
1017
 
+       return device;
1018
 
+}
1019
 
+
1020
 
+/*****************************************************************************/
1021
 
+
1022
 
+#if 0
1023
 
+static NMSetting *
1024
 
+get_setting (NMGsmModemMbm *modem, GType setting_type)
1025
 
+{
1026
 
+       NMActRequest *req;
1027
 
+       NMSetting *setting = NULL;
1028
 
+
1029
 
+       req = nm_device_get_act_request (NM_DEVICE (modem));
1030
 
+       if (req) {
1031
 
+               NMConnection *connection;
1032
 
+
1033
 
+               connection = nm_act_request_get_connection (req);
1034
 
+               if (connection)
1035
 
+                       setting = nm_connection_get_setting (connection, setting_type);
1036
 
+       }
1037
 
+
1038
 
+       return setting;
1039
 
+}
1040
 
+#endif
1041
 
+
1042
 
+#if 0
1043
 
+static NMActStageReturn
1044
 
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
1045
 
+{
1046
 
+       NMActRequest *req;
1047
 
+       NMConnection *connection;
1048
 
+       const char *setting_name;
1049
 
+       GPtrArray *hints = NULL;
1050
 
+       const char *hint1 = NULL, *hint2 = NULL;
1051
 
+       guint32 tries;
1052
 
+
1053
 
+       req = nm_device_get_act_request (device);
1054
 
+       g_assert (req);
1055
 
+       connection = nm_act_request_get_connection (req);
1056
 
+       g_assert (connection);
1057
 
+
1058
 
+       setting_name = nm_connection_need_secrets (connection, &hints);
1059
 
+       if (!setting_name) {
1060
 
+               //             do_mbm_auth (NM_GSM_MODEM_MBM (device));
1061
 
+               return NM_ACT_STAGE_RETURN_POSTPONE;
1062
 
+       }
1063
 
+
1064
 
+       if (hints) {
1065
 
+               if (hints->len > 0)
1066
 
+                       hint1 = g_ptr_array_index (hints, 0);
1067
 
+               if (hints->len > 1)
1068
 
+                       hint2 = g_ptr_array_index (hints, 1);
1069
 
+       }
1070
 
+
1071
 
+       nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
1072
 
+
1073
 
+       tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), MBM_SECRETS_TRIES));
1074
 
+       nm_act_request_request_connection_secrets (req,
1075
 
+                                                                          setting_name,
1076
 
+                                                                          tries ? TRUE : FALSE,
1077
 
+                                                                          SECRETS_CALLER_MBM_GSM,
1078
 
+                                                                          hint1,
1079
 
+                                                                          hint2);
1080
 
+       g_object_set_data (G_OBJECT (connection), MBM_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
1081
 
+
1082
 
+       if (hints)
1083
 
+               g_ptr_array_free (hints, TRUE);
1084
 
+
1085
 
+       return NM_ACT_STAGE_RETURN_POSTPONE;
1086
 
+}
1087
 
+#endif
1088
 
+
1089
 
+static void
1090
 
+real_deactivate (NMDevice *device)
1091
 
+{
1092
 
+       NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
1093
 
+
1094
 
+       if (priv->pending_ip4_config) {
1095
 
+               g_object_unref (priv->pending_ip4_config);
1096
 
+               priv->pending_ip4_config = NULL;
1097
 
+       }
1098
 
+
1099
 
+       if (priv->netdev_iface) {
1100
 
+               nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface);
1101
 
+               nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface);
1102
 
+               nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL);
1103
 
+       }
1104
 
+       nm_device_set_ip_iface (device, NULL);
1105
 
+
1106
 
+       if (NM_DEVICE_CLASS (nm_gsm_modem_mbm_parent_class)->deactivate)
1107
 
+               NM_DEVICE_CLASS (nm_gsm_modem_mbm_parent_class)->deactivate (device);
1108
 
+}
1109
 
+
1110
 
+static gboolean
1111
 
+real_hw_is_up (NMDevice *device)
1112
 
+{
1113
 
+       NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
1114
 
+
1115
 
+       if (priv->netdev_iface)
1116
 
+               return nm_system_device_is_up_with_iface (priv->netdev_iface);
1117
 
+
1118
 
+       return TRUE;
1119
 
+}
1120
 
+
1121
 
+static gboolean
1122
 
+real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
1123
 
+{
1124
 
+       NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (device);
1125
 
+
1126
 
+       if (priv->netdev_iface)
1127
 
+               return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware);
1128
 
+
1129
 
+       return TRUE;
1130
 
+}
1131
 
+
1132
 
+static void
1133
 
+real_connect (NMModemDevice *modem, const char *number)
1134
 
+{
1135
 
+       nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem));
1136
 
+}
1137
 
+
1138
 
+/*****************************************************************************/
1139
 
+
1140
 
+static void
1141
 
+nm_gsm_modem_mbm_init (NMGsmModemMbm *self)
1142
 
+{
1143
 
+}
1144
 
+
1145
 
+static void
1146
 
+finalize (GObject *object)
1147
 
+{
1148
 
+       NMGsmModemMbmPrivate *priv = NM_GSM_MODEM_MBM_GET_PRIVATE (object);
1149
 
+
1150
 
+       g_free (priv->netdev_iface);
1151
 
+
1152
 
+       G_OBJECT_CLASS (nm_gsm_modem_mbm_parent_class)->finalize (object);
1153
 
+}
1154
 
+
1155
 
+static void
1156
 
+nm_gsm_modem_mbm_class_init (NMGsmModemMbmClass *klass)
1157
 
+{
1158
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
1159
 
+       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
1160
 
+       NMModemDeviceClass *modem_class = NM_MODEM_DEVICE_CLASS (klass);
1161
 
+
1162
 
+       g_type_class_add_private (object_class, sizeof (NMGsmModemMbmPrivate));
1163
 
+
1164
 
+       object_class->finalize = finalize;
1165
 
+
1166
 
+#if 0
1167
 
+       device_class->act_stage2_config = real_act_stage2_config;
1168
 
+#endif
1169
 
+       device_class->deactivate = real_deactivate;
1170
 
+       device_class->hw_is_up = real_hw_is_up;
1171
 
+       device_class->hw_bring_up = real_hw_bring_up;
1172
 
+
1173
 
+       modem_class->connect = real_connect;
1174
 
+}
1175
 
diff --git a/src/modem-manager/nm-gsm-modem-mbm.h b/src/modem-manager/nm-gsm-modem-mbm.h
1176
 
new file mode 100644
1177
 
index 0000000..1f49fda
1178
 
--- /dev/null
1179
 
+++ b/src/modem-manager/nm-gsm-modem-mbm.h
1180
 
@@ -0,0 +1,54 @@
1181
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
1182
 
+/*
1183
 
+  Additions to NetworkManager, network-manager-applet and modemmanager
1184
 
+  for supporting Ericsson modules like F3507g.
1185
 
+
1186
 
+  Author: Per Hallsmark <per@hallsmark.se>
1187
 
+
1188
 
+  This program is free software; you can redistribute it and/or modify
1189
 
+  it under the terms of the GNU General Public License as published by
1190
 
+  the Free Software Foundation; either version 2 of the License, or
1191
 
+  (at your option) any later version.
1192
 
+
1193
 
+  This program is distributed in the hope that it will be useful,
1194
 
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
1195
 
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1196
 
+
1197
 
+  GNU General Public License for more details.
1198
 
+
1199
 
+  You should have received a copy of the GNU General Public License
1200
 
+  along with this program; if not, write to the Free Software
1201
 
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1202
 
+
1203
 
+*/
1204
 
+
1205
 
+#ifndef NM_GSM_MODEM_MBM_H
1206
 
+#define NM_GSM_MODEM_MBM_H
1207
 
+
1208
 
+#include <nm-gsm-modem.h>
1209
 
+
1210
 
+G_BEGIN_DECLS
1211
 
+
1212
 
+#define NM_TYPE_GSM_MODEM_MBM            (nm_gsm_modem_mbm_get_type ())
1213
 
+#define NM_GSM_MODEM_MBM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbm))
1214
 
+#define NM_GSM_MODEM_MBM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmClass))
1215
 
+#define NM_IS_GSM_MODEM_MBM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_MODEM_MBM))
1216
 
+#define NM_IS_GSM_MODEM_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_GSM_MODEM_MBM))
1217
 
+#define NM_GSM_MODEM_MBM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_GSM_MODEM_MBM, NMGsmModemMbmClass))
1218
 
+
1219
 
+typedef struct {
1220
 
+       NMGsmModem parent;
1221
 
+} NMGsmModemMbm;
1222
 
+
1223
 
+typedef struct {
1224
 
+       NMGsmModemClass parent;
1225
 
+} NMGsmModemMbmClass;
1226
 
+
1227
 
+GType nm_gsm_modem_mbm_get_type (void);
1228
 
+
1229
 
+NMDevice *nm_gsm_modem_mbm_new (const char *path, const char *data_device,
1230
 
+                                                 const char *driver);
1231
 
+
1232
 
+G_END_DECLS
1233
 
+
1234
 
+#endif /* NM_GSM_MODEM_MBM_H */
1235
 
diff --git a/src/modem-manager/nm-gsm-modem.c b/src/modem-manager/nm-gsm-modem.c
1236
 
new file mode 100644
1237
 
index 0000000..047e76c
1238
 
--- /dev/null
1239
 
+++ b/src/modem-manager/nm-gsm-modem.c
1240
 
@@ -0,0 +1,354 @@
1241
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
1242
 
+
1243
 
+#include <string.h>
1244
 
+#include "nm-gsm-modem.h"
1245
 
+#include "nm-device-private.h"
1246
 
+#include "nm-device-interface.h"
1247
 
+#include "nm-setting-connection.h"
1248
 
+#include "nm-setting-gsm.h"
1249
 
+#include "nm-modem-types.h"
1250
 
+#include "nm-utils.h"
1251
 
+
1252
 
+#include "nm-gsm-device-glue.h"
1253
 
+
1254
 
+G_DEFINE_TYPE (NMGsmModem, nm_gsm_modem, NM_TYPE_MODEM_DEVICE)
1255
 
+
1256
 
+#define NM_GSM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GSM_MODEM, NMGsmModemPrivate))
1257
 
+
1258
 
+enum {
1259
 
+       MODEM_STATE_BEGIN,
1260
 
+       MODEM_STATE_ENABLE,
1261
 
+       MODEM_STATE_SET_PIN,
1262
 
+       MODEM_STATE_SET_APN,
1263
 
+       MODEM_STATE_SET_BAND,
1264
 
+       MODEM_STATE_SET_NETWORK_MODE,
1265
 
+       MODEM_STATE_REGISTER,
1266
 
+       MODEM_STATE_FAILED,
1267
 
+};
1268
 
+
1269
 
+typedef struct {
1270
 
+       int modem_state;
1271
 
+} NMGsmModemPrivate;
1272
 
+
1273
 
+NMDevice *
1274
 
+nm_gsm_modem_new (const char *path,
1275
 
+                          const char *data_device,
1276
 
+                          const char *driver)
1277
 
+{
1278
 
+       g_return_val_if_fail (path != NULL, NULL);
1279
 
+       g_return_val_if_fail (data_device != NULL, NULL);
1280
 
+       g_return_val_if_fail (driver != NULL, NULL);
1281
 
+
1282
 
+       return (NMDevice *) g_object_new (NM_TYPE_GSM_MODEM,
1283
 
+                                                           NM_DEVICE_INTERFACE_UDI, path,
1284
 
+                                                           NM_DEVICE_INTERFACE_IFACE, data_device,
1285
 
+                                                           NM_DEVICE_INTERFACE_DRIVER, driver,
1286
 
+                                                           NM_DEVICE_INTERFACE_MANAGED, TRUE,
1287
 
+                                                           NM_MODEM_DEVICE_PATH, path,
1288
 
+                                                           NULL);
1289
 
+}
1290
 
+
1291
 
+static NMSetting *
1292
 
+get_setting (NMGsmModem *modem, GType setting_type)
1293
 
+{
1294
 
+       NMActRequest *req;
1295
 
+       NMSetting *setting = NULL;
1296
 
+
1297
 
+       req = nm_device_get_act_request (NM_DEVICE (modem));
1298
 
+       if (req) {
1299
 
+               NMConnection *connection;
1300
 
+
1301
 
+               connection = nm_act_request_get_connection (req);
1302
 
+               if (connection)
1303
 
+                       setting = nm_connection_get_setting (connection, setting_type);
1304
 
+       }
1305
 
+
1306
 
+       return setting;
1307
 
+}
1308
 
+
1309
 
+#define get_proxy(dev,iface) (nm_modem_device_get_proxy(NM_MODEM_DEVICE (dev), iface))
1310
 
+
1311
 
+static void
1312
 
+state_machine (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
1313
 
+{
1314
 
+       NMGsmModem *modem = NM_GSM_MODEM (user_data);
1315
 
+       NMGsmModemPrivate *priv = NM_GSM_MODEM_GET_PRIVATE (modem);
1316
 
+       NMSettingGsm *setting;
1317
 
+       const char *secret = NULL;
1318
 
+       const char *secret_name = NULL;
1319
 
+       const char *str;
1320
 
+       GError *error = NULL;
1321
 
+       int i;
1322
 
+       gboolean retry_secret = FALSE;
1323
 
+
1324
 
+       setting = NM_SETTING_GSM (get_setting (modem, NM_TYPE_SETTING_GSM));
1325
 
+
1326
 
+       if (call_id)
1327
 
+               dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID);
1328
 
+
1329
 
+       if (error) {
1330
 
+               g_debug ("%s", dbus_g_error_get_name (error));
1331
 
+
1332
 
+               if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) {
1333
 
+                       secret = nm_setting_gsm_get_pin (setting);
1334
 
+                       secret_name = NM_SETTING_GSM_PIN;
1335
 
+                       priv->modem_state = MODEM_STATE_SET_PIN;
1336
 
+               } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)) {
1337
 
+                       secret = nm_setting_gsm_get_puk (setting);
1338
 
+                       secret_name = NM_SETTING_GSM_PUK;
1339
 
+                       priv->modem_state = MODEM_STATE_SET_PIN;
1340
 
+               } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) {
1341
 
+                       g_object_set (setting, NM_SETTING_GSM_PIN, NULL, NULL);
1342
 
+                       secret_name = NM_SETTING_GSM_PIN;
1343
 
+                       retry_secret = TRUE;
1344
 
+                       priv->modem_state = MODEM_STATE_SET_PIN;
1345
 
+               }
1346
 
+
1347
 
+               /* FIXME: Hacks to ignore failures of setting band and network mode for now
1348
 
+                  since only Huawei module supports it. Remove when ModemManager rules.
1349
 
+               */
1350
 
+               else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED) &&
1351
 
+                           (priv->modem_state == MODEM_STATE_SET_BAND ||
1352
 
+                               priv->modem_state == MODEM_STATE_SET_NETWORK_MODE)) {
1353
 
+
1354
 
+                       nm_warning ("Modem does not support setting %s, ignoring",
1355
 
+                                         priv->modem_state == MODEM_STATE_SET_BAND ? "band" : "network mode");
1356
 
+               } else {
1357
 
+                       priv->modem_state = MODEM_STATE_FAILED;
1358
 
+                       nm_warning ("GSM modem connection failed: %s", error->message);
1359
 
+               }
1360
 
+
1361
 
+               g_error_free (error);
1362
 
+       }
1363
 
+
1364
 
+ again:
1365
 
+
1366
 
+       switch (priv->modem_state) {
1367
 
+       case MODEM_STATE_BEGIN:
1368
 
+               priv->modem_state = MODEM_STATE_ENABLE;
1369
 
+               dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM),
1370
 
+                                                       "Enable", state_machine,
1371
 
+                                                       modem, NULL,
1372
 
+                                                       G_TYPE_BOOLEAN, TRUE,
1373
 
+                                                       G_TYPE_INVALID);
1374
 
+               break;
1375
 
+
1376
 
+       case MODEM_STATE_SET_PIN:
1377
 
+               if (secret) {
1378
 
+                       priv->modem_state = MODEM_STATE_ENABLE;
1379
 
+                       dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_CARD),
1380
 
+                                                               "SendPin", state_machine,
1381
 
+                                                               modem, NULL,
1382
 
+                                                               G_TYPE_STRING, secret,
1383
 
+                                                               G_TYPE_INVALID);
1384
 
+               } else {
1385
 
+                       nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
1386
 
+                       nm_act_request_request_connection_secrets (nm_device_get_act_request (NM_DEVICE (modem)),
1387
 
+                                                                                          NM_SETTING_GSM_SETTING_NAME,
1388
 
+                                                                                          retry_secret,
1389
 
+                                                                                          SECRETS_CALLER_GSM,
1390
 
+                                                                                          secret_name,
1391
 
+                                                                                          NULL);
1392
 
+
1393
 
+               }
1394
 
+               break;
1395
 
+
1396
 
+       case MODEM_STATE_ENABLE:
1397
 
+               priv->modem_state = MODEM_STATE_SET_APN;
1398
 
+               str = nm_setting_gsm_get_apn (setting);
1399
 
+
1400
 
+               if (str)
1401
 
+                       dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
1402
 
+                                                               "SetApn", state_machine,
1403
 
+                                                               modem, NULL,
1404
 
+                                                               G_TYPE_STRING, str,
1405
 
+                                                               G_TYPE_INVALID);
1406
 
+               else
1407
 
+                       goto again;
1408
 
+
1409
 
+               break;
1410
 
+       case MODEM_STATE_SET_APN:
1411
 
+               priv->modem_state = MODEM_STATE_SET_BAND;
1412
 
+               i = nm_setting_gsm_get_band (setting);
1413
 
+
1414
 
+               if (i)
1415
 
+                       dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
1416
 
+                                                               "SetBand", state_machine,
1417
 
+                                                               modem, NULL,
1418
 
+                                                               G_TYPE_UINT, (guint32) i,
1419
 
+                                                               G_TYPE_INVALID);
1420
 
+               else
1421
 
+                       goto again;
1422
 
+
1423
 
+               break;
1424
 
+
1425
 
+       case MODEM_STATE_SET_BAND:
1426
 
+               priv->modem_state = MODEM_STATE_SET_NETWORK_MODE;
1427
 
+               i = nm_setting_gsm_get_network_type (setting);
1428
 
+
1429
 
+               if (i)
1430
 
+                       dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
1431
 
+                                                               "SetNetworkMode", state_machine,
1432
 
+                                                               modem, NULL,
1433
 
+                                                               G_TYPE_UINT, (guint32) i,
1434
 
+                                                               G_TYPE_INVALID);
1435
 
+               else
1436
 
+                       goto again;
1437
 
+
1438
 
+               break;
1439
 
+
1440
 
+       case MODEM_STATE_SET_NETWORK_MODE:
1441
 
+               priv->modem_state = MODEM_STATE_REGISTER;
1442
 
+
1443
 
+               str = nm_setting_gsm_get_network_id (setting);
1444
 
+               dbus_g_proxy_begin_call_with_timeout (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK),
1445
 
+                                                                          "Register", state_machine,
1446
 
+                                                                          modem, NULL, 120000,
1447
 
+                                                                          G_TYPE_STRING, str ? str : "",
1448
 
+                                                                          G_TYPE_INVALID);
1449
 
+               break;
1450
 
+
1451
 
+       case MODEM_STATE_REGISTER:
1452
 
+               nm_modem_device_connect (NM_MODEM_DEVICE (modem), nm_setting_gsm_get_number (setting));
1453
 
+               break;
1454
 
+       case MODEM_STATE_FAILED:
1455
 
+       default:
1456
 
+               nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
1457
 
+               break;
1458
 
+       }
1459
 
+}
1460
 
+
1461
 
+static NMActStageReturn
1462
 
+real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
1463
 
+{
1464
 
+       NMGsmModemPrivate *priv = NM_GSM_MODEM_GET_PRIVATE (device);
1465
 
+
1466
 
+       priv->modem_state = MODEM_STATE_BEGIN;
1467
 
+       state_machine (NULL, NULL, device);
1468
 
+
1469
 
+       return NM_ACT_STAGE_RETURN_POSTPONE;
1470
 
+}
1471
 
+
1472
 
+static NMConnection *
1473
 
+real_get_best_auto_connection (NMDevice *dev,
1474
 
+                               GSList *connections,
1475
 
+                               char **specific_object)
1476
 
+{
1477
 
+       GSList *iter;
1478
 
+
1479
 
+       for (iter = connections; iter; iter = g_slist_next (iter)) {
1480
 
+               NMConnection *connection = NM_CONNECTION (iter->data);
1481
 
+               NMSettingConnection *s_con;
1482
 
+
1483
 
+               s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
1484
 
+               g_assert (s_con);
1485
 
+
1486
 
+               if (!nm_setting_connection_get_autoconnect (s_con))
1487
 
+                       continue;
1488
 
+
1489
 
+               if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME))
1490
 
+                       continue;
1491
 
+
1492
 
+               return connection;
1493
 
+       }
1494
 
+       return NULL;
1495
 
+}
1496
 
+
1497
 
+static void
1498
 
+real_connection_secrets_updated (NMDevice *dev,
1499
 
+                                 NMConnection *connection,
1500
 
+                                 GSList *updated_settings,
1501
 
+                                 RequestSecretsCaller caller)
1502
 
+{
1503
 
+       NMActRequest *req;
1504
 
+       gboolean found = FALSE;
1505
 
+       GSList *iter;
1506
 
+
1507
 
+       if (caller == SECRETS_CALLER_PPP) {
1508
 
+               NMPPPManager *ppp_manager;
1509
 
+               NMSettingGsm *s_gsm = NULL;
1510
 
+
1511
 
+               ppp_manager = nm_modem_device_get_ppp_manager (NM_MODEM_DEVICE (dev));
1512
 
+               g_return_if_fail (ppp_manager != NULL);
1513
 
+
1514
 
+               s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
1515
 
+               if (!s_gsm) {
1516
 
+                       /* Shouldn't ever happen */
1517
 
+                       nm_ppp_manager_update_secrets (ppp_manager,
1518
 
+                                                      nm_device_get_iface (dev),
1519
 
+                                                      NULL,
1520
 
+                                                      NULL,
1521
 
+                                                      "missing GSM setting; no secrets could be found.");
1522
 
+               } else {
1523
 
+                       const char *username = nm_setting_gsm_get_username (s_gsm);
1524
 
+                       const char *password = nm_setting_gsm_get_password (s_gsm);
1525
 
+
1526
 
+                       nm_ppp_manager_update_secrets (ppp_manager,
1527
 
+                                                      nm_device_get_iface (dev),
1528
 
+                                                      username ? username : "",
1529
 
+                                                      password ? password : "",
1530
 
+                                                      NULL);
1531
 
+               }
1532
 
+               return;
1533
 
+       }
1534
 
+
1535
 
+       g_return_if_fail (caller == SECRETS_CALLER_GSM);
1536
 
+       g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
1537
 
+
1538
 
+       for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
1539
 
+               const char *setting_name = (const char *) iter->data;
1540
 
+
1541
 
+               if (!strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME))
1542
 
+                       found = TRUE;
1543
 
+               else
1544
 
+                       nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
1545
 
+       }
1546
 
+
1547
 
+       if (!found)
1548
 
+               return;
1549
 
+
1550
 
+       req = nm_device_get_act_request (dev);
1551
 
+       g_assert (req);
1552
 
+
1553
 
+       g_return_if_fail (nm_act_request_get_connection (req) == connection);
1554
 
+
1555
 
+       nm_device_activate_schedule_stage1_device_prepare (dev);
1556
 
+}
1557
 
+
1558
 
+static const char *
1559
 
+real_get_ppp_name (NMModemDevice *device, NMConnection *connection)
1560
 
+{
1561
 
+       NMSettingGsm *s_gsm;
1562
 
+
1563
 
+       s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
1564
 
+       g_assert (s_gsm);
1565
 
+
1566
 
+       return nm_setting_gsm_get_username (s_gsm);
1567
 
+}
1568
 
+
1569
 
+/*****************************************************************************/
1570
 
+
1571
 
+static void
1572
 
+nm_gsm_modem_init (NMGsmModem *self)
1573
 
+{
1574
 
+       nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_GSM);
1575
 
+}
1576
 
+
1577
 
+static void
1578
 
+nm_gsm_modem_class_init (NMGsmModemClass *klass)
1579
 
+{
1580
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
1581
 
+       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
1582
 
+       NMModemDeviceClass *modem_class = NM_MODEM_DEVICE_CLASS (klass);
1583
 
+
1584
 
+       g_type_class_add_private (object_class, sizeof (NMGsmModemPrivate));
1585
 
+
1586
 
+       /* Virtual methods */
1587
 
+       device_class->get_best_auto_connection = real_get_best_auto_connection;
1588
 
+       device_class->connection_secrets_updated = real_connection_secrets_updated;
1589
 
+       device_class->act_stage1_prepare = real_act_stage1_prepare;
1590
 
+       modem_class->get_ppp_name = real_get_ppp_name;
1591
 
+
1592
 
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
1593
 
+                                                          &dbus_glib_nm_gsm_device_object_info);
1594
 
+}
1595
 
diff --git a/src/modem-manager/nm-gsm-modem.h b/src/modem-manager/nm-gsm-modem.h
1596
 
new file mode 100644
1597
 
index 0000000..8df8265
1598
 
--- /dev/null
1599
 
+++ b/src/modem-manager/nm-gsm-modem.h
1600
 
@@ -0,0 +1,36 @@
1601
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
1602
 
+
1603
 
+#ifndef NM_GSM_MODEM_H
1604
 
+#define NM_GSM_MODEM_H
1605
 
+
1606
 
+#include <nm-modem-device.h>
1607
 
+
1608
 
+G_BEGIN_DECLS
1609
 
+
1610
 
+#define NM_TYPE_GSM_MODEM            (nm_gsm_modem_get_type ())
1611
 
+#define NM_GSM_MODEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_MODEM, NMGsmModem))
1612
 
+#define NM_GSM_MODEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_GSM_MODEM, NMGsmModemClass))
1613
 
+#define NM_IS_GSM_MODEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_MODEM))
1614
 
+#define NM_IS_GSM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_GSM_MODEM))
1615
 
+#define NM_GSM_MODEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_GSM_MODEM, NMGsmModemClass))
1616
 
+
1617
 
+typedef struct {
1618
 
+       NMModemDevice parent;
1619
 
+} NMGsmModem;
1620
 
+
1621
 
+typedef struct {
1622
 
+       NMModemDeviceClass parent;
1623
 
+
1624
 
+       /* Signals */
1625
 
+       void (*signal_quality) (NMGsmModem *modem, guint32 quality);
1626
 
+} NMGsmModemClass;
1627
 
+
1628
 
+GType nm_gsm_modem_get_type (void);
1629
 
+
1630
 
+NMDevice *nm_gsm_modem_new (const char *path,
1631
 
+                                          const char *data_device,
1632
 
+                                          const char *driver);
1633
 
+
1634
 
+G_END_DECLS
1635
 
+
1636
 
+#endif /* NM_GSM_MODEM_H */
1637
 
diff --git a/src/modem-manager/nm-modem-device.c b/src/modem-manager/nm-modem-device.c
1638
 
new file mode 100644
1639
 
index 0000000..1f49acc
1640
 
--- /dev/null
1641
 
+++ b/src/modem-manager/nm-modem-device.c
1642
 
@@ -0,0 +1,457 @@
1643
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
1644
 
+
1645
 
+#include <string.h>
1646
 
+#include "nm-modem-device.h"
1647
 
+#include "nm-device-private.h"
1648
 
+#include "nm-device-interface.h"
1649
 
+#include "nm-dbus-manager.h"
1650
 
+#include "nm-setting-connection.h"
1651
 
+#include "nm-setting-gsm.h"
1652
 
+#include "nm-setting-cdma.h"
1653
 
+#include "nm-marshal.h"
1654
 
+#include "nm-properties-changed-signal.h"
1655
 
+#include "nm-modem-types.h"
1656
 
+#include "nm-utils.h"
1657
 
+#include "nm-serial-device-glue.h"
1658
 
+
1659
 
+G_DEFINE_TYPE (NMModemDevice, nm_modem_device, NM_TYPE_DEVICE)
1660
 
+
1661
 
+#define NM_MODEM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_DEVICE, NMModemDevicePrivate))
1662
 
+
1663
 
+enum {
1664
 
+       PROP_0,
1665
 
+       PROP_PATH,
1666
 
+
1667
 
+       LAST_PROP
1668
 
+};
1669
 
+
1670
 
+typedef struct {
1671
 
+       NMDBusManager *dbus_mgr;
1672
 
+       char *path;
1673
 
+       DBusGProxy *proxy;
1674
 
+       NMPPPManager *ppp_manager;
1675
 
+       NMIP4Config  *pending_ip4_config;
1676
 
+
1677
 
+       guint state_to_disconnected_id;
1678
 
+
1679
 
+       /* PPP stats */
1680
 
+       guint32 in_bytes;
1681
 
+       guint32 out_bytes;
1682
 
+} NMModemDevicePrivate;
1683
 
+
1684
 
+enum {
1685
 
+       PPP_STATS,
1686
 
+       PROPERTIES_CHANGED,
1687
 
+
1688
 
+       LAST_SIGNAL
1689
 
+};
1690
 
+
1691
 
+static guint signals[LAST_SIGNAL] = { 0 };
1692
 
+
1693
 
+NMPPPManager *
1694
 
+nm_modem_device_get_ppp_manager (NMModemDevice *device)
1695
 
+{
1696
 
+       g_return_val_if_fail (NM_IS_MODEM_DEVICE (device), NULL);
1697
 
+
1698
 
+       return NM_MODEM_DEVICE_GET_PRIVATE (device)->ppp_manager;
1699
 
+}
1700
 
+
1701
 
+DBusGProxy *
1702
 
+nm_modem_device_get_proxy (NMModemDevice *device,
1703
 
+                                         const char *interface)
1704
 
+{
1705
 
+
1706
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
1707
 
+       const char *current_iface;
1708
 
+
1709
 
+       g_return_val_if_fail (NM_IS_MODEM_DEVICE (device), NULL);
1710
 
+
1711
 
+       /* Default to the default interface. */
1712
 
+       if (interface == NULL)
1713
 
+               interface = MM_DBUS_INTERFACE_MODEM;
1714
 
+
1715
 
+       current_iface = dbus_g_proxy_get_interface (priv->proxy);
1716
 
+       if (!current_iface || strcmp (current_iface, interface))
1717
 
+               dbus_g_proxy_set_interface (priv->proxy, interface);
1718
 
+
1719
 
+       return priv->proxy;
1720
 
+}
1721
 
+
1722
 
+void
1723
 
+nm_modem_device_connect (NMModemDevice *device,
1724
 
+                                       const char *number)
1725
 
+{
1726
 
+       g_return_if_fail (NM_IS_MODEM_DEVICE (device));
1727
 
+
1728
 
+       NM_MODEM_DEVICE_GET_CLASS (device)->connect (device, number);
1729
 
+}
1730
 
+
1731
 
+const char *
1732
 
+nm_modem_device_get_ppp_name (NMModemDevice *device,
1733
 
+                                               NMConnection *connection)
1734
 
+{
1735
 
+       g_return_val_if_fail (NM_IS_MODEM_DEVICE (device), NULL);
1736
 
+       g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
1737
 
+
1738
 
+       if (NM_MODEM_DEVICE_GET_CLASS (device)->get_ppp_name)
1739
 
+               return NM_MODEM_DEVICE_GET_CLASS (device)->get_ppp_name (device, connection);
1740
 
+
1741
 
+       return NULL;
1742
 
+}
1743
 
+
1744
 
+static void
1745
 
+ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data)
1746
 
+{
1747
 
+       NMDevice *device = NM_DEVICE (user_data);
1748
 
+
1749
 
+       switch (status) {
1750
 
+       case NM_PPP_STATUS_NETWORK:
1751
 
+               nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
1752
 
+               break;
1753
 
+       case NM_PPP_STATUS_DISCONNECT:
1754
 
+               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
1755
 
+               break;
1756
 
+       case NM_PPP_STATUS_DEAD:
1757
 
+               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
1758
 
+               break;
1759
 
+       case NM_PPP_STATUS_AUTHENTICATE:
1760
 
+               nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
1761
 
+               break;
1762
 
+       default:
1763
 
+               break;
1764
 
+       }
1765
 
+}
1766
 
+
1767
 
+static void
1768
 
+ppp_ip4_config (NMPPPManager *ppp_manager,
1769
 
+                        const char *iface,
1770
 
+                        NMIP4Config *config,
1771
 
+                        gpointer user_data)
1772
 
+{
1773
 
+       NMDevice *device = NM_DEVICE (user_data);
1774
 
+
1775
 
+       nm_device_set_ip_iface (device, iface);
1776
 
+       NM_MODEM_DEVICE_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config);
1777
 
+       nm_device_activate_schedule_stage4_ip_config_get (device);
1778
 
+}
1779
 
+
1780
 
+static void
1781
 
+ppp_stats (NMPPPManager *ppp_manager,
1782
 
+                guint32 in_bytes,
1783
 
+                guint32 out_bytes,
1784
 
+                gpointer user_data)
1785
 
+{
1786
 
+       NMModemDevice *device = NM_MODEM_DEVICE (user_data);
1787
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
1788
 
+
1789
 
+       if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) {
1790
 
+               priv->in_bytes = in_bytes;
1791
 
+               priv->out_bytes = out_bytes;
1792
 
+
1793
 
+               g_signal_emit (device, signals[PPP_STATS], 0, in_bytes, out_bytes);
1794
 
+       }
1795
 
+}
1796
 
+
1797
 
+static NMActStageReturn
1798
 
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
1799
 
+{
1800
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
1801
 
+       NMActRequest *req;
1802
 
+       const char *ppp_name = NULL;
1803
 
+       GError *err = NULL;
1804
 
+       NMActStageReturn ret;
1805
 
+
1806
 
+       req = nm_device_get_act_request (device);
1807
 
+       g_assert (req);
1808
 
+
1809
 
+       ppp_name = nm_modem_device_get_ppp_name (NM_MODEM_DEVICE (device),
1810
 
+                                                                        nm_act_request_get_connection (req));
1811
 
+
1812
 
+       priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (device));
1813
 
+       if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, &err)) {
1814
 
+               g_signal_connect (priv->ppp_manager, "state-changed",
1815
 
+                                          G_CALLBACK (ppp_state_changed),
1816
 
+                                          device);
1817
 
+               g_signal_connect (priv->ppp_manager, "ip4-config",
1818
 
+                                          G_CALLBACK (ppp_ip4_config),
1819
 
+                                          device);
1820
 
+               g_signal_connect (priv->ppp_manager, "stats",
1821
 
+                                          G_CALLBACK (ppp_stats),
1822
 
+                                          device);
1823
 
+
1824
 
+               ret = NM_ACT_STAGE_RETURN_POSTPONE;
1825
 
+       } else {
1826
 
+               nm_warning ("%s", err->message);
1827
 
+               g_error_free (err);
1828
 
+
1829
 
+               g_object_unref (priv->ppp_manager);
1830
 
+               priv->ppp_manager = NULL;
1831
 
+
1832
 
+               *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
1833
 
+               ret = NM_ACT_STAGE_RETURN_FAILURE;
1834
 
+       }
1835
 
+
1836
 
+       return ret;
1837
 
+}
1838
 
+
1839
 
+static NMActStageReturn
1840
 
+real_act_stage4_get_ip4_config (NMDevice *device,
1841
 
+                                NMIP4Config **config,
1842
 
+                                NMDeviceStateReason *reason)
1843
 
+{
1844
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
1845
 
+
1846
 
+       *config = priv->pending_ip4_config;
1847
 
+       priv->pending_ip4_config = NULL;
1848
 
+
1849
 
+       return NM_ACT_STAGE_RETURN_SUCCESS;
1850
 
+}
1851
 
+
1852
 
+static void
1853
 
+real_deactivate_quickly (NMDevice *device)
1854
 
+{
1855
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (device);
1856
 
+
1857
 
+       nm_device_set_ip_iface (device, NULL);
1858
 
+
1859
 
+       if (priv->pending_ip4_config) {
1860
 
+               g_object_unref (priv->pending_ip4_config);
1861
 
+               priv->pending_ip4_config = NULL;
1862
 
+       }
1863
 
+
1864
 
+       priv->in_bytes = priv->out_bytes = 0;
1865
 
+
1866
 
+       if (priv->ppp_manager) {
1867
 
+               g_object_unref (priv->ppp_manager);
1868
 
+               priv->ppp_manager = NULL;
1869
 
+       }
1870
 
+
1871
 
+       dbus_g_proxy_call_no_reply (nm_modem_device_get_proxy (NM_MODEM_DEVICE (device), NULL),
1872
 
+                                                  "Enable", G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID);
1873
 
+}
1874
 
+
1875
 
+static guint32
1876
 
+real_get_generic_capabilities (NMDevice *dev)
1877
 
+{
1878
 
+       return NM_DEVICE_CAP_NM_SUPPORTED;
1879
 
+}
1880
 
+
1881
 
+
1882
 
+static void
1883
 
+connect_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
1884
 
+{
1885
 
+       NMDevice *device = NM_DEVICE (user_data);
1886
 
+       GError *error = NULL;
1887
 
+
1888
 
+       if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID))
1889
 
+               nm_device_activate_schedule_stage2_device_config (device);
1890
 
+       else {
1891
 
+               nm_warning ("Connect failed: %s", error->message);
1892
 
+               g_error_free (error);
1893
 
+               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED);
1894
 
+       }
1895
 
+}
1896
 
+
1897
 
+static void
1898
 
+real_connect (NMModemDevice *modem, const char *number)
1899
 
+{
1900
 
+       dbus_g_proxy_begin_call_with_timeout (nm_modem_device_get_proxy (modem, MM_DBUS_INTERFACE_MODEM),
1901
 
+                                                                  "Connect", connect_done,
1902
 
+                                                                  modem, NULL, 60000,
1903
 
+                                                                  G_TYPE_STRING, number ? number : "",
1904
 
+                                                                  G_TYPE_INVALID);
1905
 
+}
1906
 
+
1907
 
+static gboolean
1908
 
+unavailable_to_disconnected (gpointer user_data)
1909
 
+{
1910
 
+       nm_device_state_changed (NM_DEVICE (user_data),
1911
 
+                                NM_DEVICE_STATE_DISCONNECTED,
1912
 
+                                NM_DEVICE_STATE_REASON_NONE);
1913
 
+       return FALSE;
1914
 
+}
1915
 
+
1916
 
+static void
1917
 
+device_state_changed (NMDeviceInterface *device,
1918
 
+                      NMDeviceState new_state,
1919
 
+                      NMDeviceState old_state,
1920
 
+                      NMDeviceStateReason reason,
1921
 
+                      gpointer user_data)
1922
 
+{
1923
 
+       NMModemDevice *self = NM_MODEM_DEVICE (user_data);
1924
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (self);
1925
 
+
1926
 
+       /* Remove any previous delayed transition to disconnected */
1927
 
+       if (priv->state_to_disconnected_id) {
1928
 
+               g_source_remove (priv->state_to_disconnected_id);
1929
 
+               priv->state_to_disconnected_id = 0;
1930
 
+       }
1931
 
+
1932
 
+       /* If transitioning to UNAVAILBLE and we have a carrier, transition to
1933
 
+        * DISCONNECTED because the device is ready to use.  Otherwise the carrier-on
1934
 
+        * handler will handle the transition to DISCONNECTED when the carrier is detected.
1935
 
+        */
1936
 
+       if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
1937
 
+               priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, user_data);
1938
 
+
1939
 
+       /* Make sure we don't leave the serial device open */
1940
 
+       switch (new_state) {
1941
 
+       case NM_DEVICE_STATE_NEED_AUTH:
1942
 
+               if (priv->ppp_manager)
1943
 
+                       break;
1944
 
+               /* else fall through */
1945
 
+       case NM_DEVICE_STATE_UNMANAGED:
1946
 
+       case NM_DEVICE_STATE_UNAVAILABLE:
1947
 
+       case NM_DEVICE_STATE_FAILED:
1948
 
+       case NM_DEVICE_STATE_DISCONNECTED:
1949
 
+               dbus_g_proxy_call_no_reply (nm_modem_device_get_proxy (self, NULL),
1950
 
+                                                          "Disconnect", G_TYPE_INVALID);
1951
 
+               break;
1952
 
+       default:
1953
 
+               break;
1954
 
+       }
1955
 
+}
1956
 
+
1957
 
+/*****************************************************************************/
1958
 
+
1959
 
+static void
1960
 
+nm_modem_device_init (NMModemDevice *self)
1961
 
+{
1962
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (self);
1963
 
+
1964
 
+       priv->dbus_mgr = nm_dbus_manager_get ();
1965
 
+}
1966
 
+
1967
 
+static GObject*
1968
 
+constructor (GType type,
1969
 
+                  guint n_construct_params,
1970
 
+                  GObjectConstructParam *construct_params)
1971
 
+{
1972
 
+       GObject *object;
1973
 
+       NMModemDevicePrivate *priv;
1974
 
+
1975
 
+       object = G_OBJECT_CLASS (nm_modem_device_parent_class)->constructor (type,
1976
 
+                                                                                                                   n_construct_params,
1977
 
+                                                                                                                   construct_params);
1978
 
+       if (!object)
1979
 
+               return NULL;
1980
 
+
1981
 
+       priv = NM_MODEM_DEVICE_GET_PRIVATE (object);
1982
 
+
1983
 
+       if (!priv->path) {
1984
 
+               g_warning ("DBus path not provided");
1985
 
+               goto err;
1986
 
+       }
1987
 
+
1988
 
+       priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
1989
 
+                                                                        MM_DBUS_SERVICE, priv->path, MM_DBUS_INTERFACE_MODEM);
1990
 
+
1991
 
+       g_signal_connect (object, "state-changed", G_CALLBACK (device_state_changed), object);
1992
 
+
1993
 
+       return object;
1994
 
+
1995
 
+ err:
1996
 
+       g_object_unref (object);
1997
 
+       return NULL;
1998
 
+}
1999
 
+
2000
 
+static void
2001
 
+get_property (GObject *object, guint prop_id,
2002
 
+                   GValue *value, GParamSpec *pspec)
2003
 
+{
2004
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (object);
2005
 
+
2006
 
+       switch (prop_id) {
2007
 
+       case PROP_PATH:
2008
 
+               g_value_set_string (value, priv->path);
2009
 
+               break;
2010
 
+       default:
2011
 
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2012
 
+               break;
2013
 
+       }
2014
 
+
2015
 
+}
2016
 
+
2017
 
+static void
2018
 
+set_property (GObject *object, guint prop_id,
2019
 
+                   const GValue *value, GParamSpec *pspec)
2020
 
+{
2021
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (object);
2022
 
+
2023
 
+       switch (prop_id) {
2024
 
+       case PROP_PATH:
2025
 
+               /* Construct only */
2026
 
+               priv->path = g_value_dup_string (value);
2027
 
+               break;
2028
 
+       default:
2029
 
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2030
 
+               break;
2031
 
+       }
2032
 
+}
2033
 
+
2034
 
+static void
2035
 
+finalize (GObject *object)
2036
 
+{
2037
 
+       NMModemDevicePrivate *priv = NM_MODEM_DEVICE_GET_PRIVATE (object);
2038
 
+
2039
 
+       if (priv->state_to_disconnected_id) {
2040
 
+               g_source_remove (priv->state_to_disconnected_id);
2041
 
+               priv->state_to_disconnected_id = 0;
2042
 
+       }
2043
 
+
2044
 
+       if (priv->proxy)
2045
 
+               g_object_unref (priv->proxy);
2046
 
+
2047
 
+       g_object_unref (priv->dbus_mgr);
2048
 
+
2049
 
+       G_OBJECT_CLASS (nm_modem_device_parent_class)->finalize (object);
2050
 
+}
2051
 
+
2052
 
+static void
2053
 
+nm_modem_device_class_init (NMModemDeviceClass *klass)
2054
 
+{
2055
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
2056
 
+       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
2057
 
+
2058
 
+       g_type_class_add_private (object_class, sizeof (NMModemDevicePrivate));
2059
 
+
2060
 
+       /* Virtual methods */
2061
 
+       object_class->constructor = constructor;
2062
 
+       object_class->set_property = set_property;
2063
 
+       object_class->get_property = get_property;
2064
 
+       object_class->finalize = finalize;
2065
 
+
2066
 
+       device_class->get_generic_capabilities = real_get_generic_capabilities;
2067
 
+       device_class->act_stage2_config = real_act_stage2_config;
2068
 
+       device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
2069
 
+       device_class->deactivate_quickly = real_deactivate_quickly;
2070
 
+
2071
 
+       klass->connect = real_connect;
2072
 
+
2073
 
+       /* Properties */
2074
 
+       g_object_class_install_property
2075
 
+               (object_class, PROP_PATH,
2076
 
+                g_param_spec_string (NM_MODEM_DEVICE_PATH,
2077
 
+                                                 "DBus path",
2078
 
+                                                 "DBus path",
2079
 
+                                                 NULL,
2080
 
+                                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2081
 
+
2082
 
+       /* Signals */
2083
 
+       signals[PPP_STATS] =
2084
 
+               g_signal_new ("ppp-stats",
2085
 
+                                   G_OBJECT_CLASS_TYPE (object_class),
2086
 
+                                   G_SIGNAL_RUN_FIRST,
2087
 
+                                   G_STRUCT_OFFSET (NMModemDeviceClass, ppp_stats),
2088
 
+                                   NULL, NULL,
2089
 
+                                   _nm_marshal_VOID__UINT_UINT,
2090
 
+                                   G_TYPE_NONE, 2,
2091
 
+                                   G_TYPE_UINT, G_TYPE_UINT);
2092
 
+
2093
 
+       signals[PROPERTIES_CHANGED] = 
2094
 
+               nm_properties_changed_signal_new (object_class,
2095
 
+                                                                   G_STRUCT_OFFSET (NMModemDeviceClass, properties_changed));
2096
 
+
2097
 
+       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
2098
 
+                                                          &dbus_glib_nm_serial_device_object_info);
2099
 
+}
2100
 
diff --git a/src/modem-manager/nm-modem-device.h b/src/modem-manager/nm-modem-device.h
2101
 
new file mode 100644
2102
 
index 0000000..fae6d74
2103
 
--- /dev/null
2104
 
+++ b/src/modem-manager/nm-modem-device.h
2105
 
@@ -0,0 +1,55 @@
2106
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
2107
 
+
2108
 
+#ifndef NM_MODEM_DEVICE_H
2109
 
+#define NM_MODEM_DEVICE_H
2110
 
+
2111
 
+#include <dbus/dbus-glib.h>
2112
 
+#include <nm-device.h>
2113
 
+#include "ppp-manager/nm-ppp-manager.h"
2114
 
+
2115
 
+G_BEGIN_DECLS
2116
 
+
2117
 
+#define NM_TYPE_MODEM_DEVICE                   (nm_modem_device_get_type ())
2118
 
+#define NM_MODEM_DEVICE(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_DEVICE, NMModemDevice))
2119
 
+#define NM_MODEM_DEVICE_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_MODEM_DEVICE, NMModemDeviceClass))
2120
 
+#define NM_IS_MODEM_DEVICE(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_DEVICE))
2121
 
+#define NM_IS_MODEM_DEVICE_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_MODEM_DEVICE))
2122
 
+#define NM_MODEM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_MODEM_DEVICE, NMModemDeviceClass))
2123
 
+
2124
 
+#define NM_MODEM_DEVICE_PATH "path"
2125
 
+
2126
 
+typedef struct {
2127
 
+       NMDevice parent;
2128
 
+} NMModemDevice;
2129
 
+
2130
 
+typedef struct {
2131
 
+       NMDeviceClass parent;
2132
 
+
2133
 
+       void (*connect) (NMModemDevice *device,
2134
 
+                                 const char *number);
2135
 
+
2136
 
+       const char *(*get_ppp_name) (NMModemDevice *device,
2137
 
+                                                   NMConnection *connection);
2138
 
+
2139
 
+       /* Signals */
2140
 
+       void (*ppp_stats) (NMModemDevice *device, guint32 in_bytes, guint32 out_bytes);
2141
 
+       void (*properties_changed) (NMModemDevice *device, GHashTable *properties);
2142
 
+} NMModemDeviceClass;
2143
 
+
2144
 
+GType nm_modem_device_get_type (void);
2145
 
+
2146
 
+/* Protected */
2147
 
+
2148
 
+NMPPPManager *nm_modem_device_get_ppp_manager (NMModemDevice *device);
2149
 
+DBusGProxy   *nm_modem_device_get_proxy       (NMModemDevice *device,
2150
 
+                                                                         const char *interface);
2151
 
+
2152
 
+void          nm_modem_device_connect         (NMModemDevice *device,
2153
 
+                                                                         const char *number);
2154
 
+
2155
 
+const char   *nm_modem_device_get_ppp_name    (NMModemDevice *device,
2156
 
+                                                                         NMConnection *connection);
2157
 
+
2158
 
+G_END_DECLS
2159
 
+
2160
 
+#endif /* NM_MODEM_DEVICE_H */
2161
 
diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c
2162
 
new file mode 100644
2163
 
index 0000000..be0ca7a
2164
 
--- /dev/null
2165
 
+++ b/src/modem-manager/nm-modem-manager.c
2166
 
@@ -0,0 +1,395 @@
2167
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
2168
 
+
2169
 
+#include <string.h>
2170
 
+#include "nm-modem-manager.h"
2171
 
+#include "nm-modem-device.h"
2172
 
+#include "nm-gsm-modem.h"
2173
 
+#include "nm-gsm-modem-hso.h"
2174
 
+#include "nm-gsm-modem-mbm.h"
2175
 
+#include "nm-cdma-modem.h"
2176
 
+#include "nm-dbus-manager.h"
2177
 
+#include "nm-utils.h"
2178
 
+#include "nm-modem-types.h"
2179
 
+
2180
 
+#define MODEM_POKE_INTERVAL 120000
2181
 
+
2182
 
+G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT)
2183
 
+
2184
 
+#define NM_MODEM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_MANAGER, NMModemManagerPrivate))
2185
 
+
2186
 
+typedef struct {
2187
 
+       NMDBusManager *dbus_mgr;
2188
 
+       DBusGProxy *proxy;
2189
 
+       GHashTable *modems;
2190
 
+       gboolean disposed;
2191
 
+       guint poke_id;
2192
 
+} NMModemManagerPrivate;
2193
 
+
2194
 
+enum {
2195
 
+       DEVICE_ADDED,
2196
 
+       DEVICE_REMOVED,
2197
 
+
2198
 
+       LAST_SIGNAL
2199
 
+};
2200
 
+
2201
 
+static guint signals[LAST_SIGNAL] = { 0 };
2202
 
+
2203
 
+
2204
 
+NMModemManager *
2205
 
+nm_modem_manager_get (void)
2206
 
+{
2207
 
+       static NMModemManager *singleton = NULL;
2208
 
+
2209
 
+       if (!singleton)
2210
 
+               singleton = NM_MODEM_MANAGER (g_object_new (NM_TYPE_MODEM_MANAGER, NULL));
2211
 
+       else
2212
 
+               g_object_ref (singleton);
2213
 
+
2214
 
+       g_assert (singleton);
2215
 
+       return singleton;
2216
 
+}
2217
 
+
2218
 
+static gboolean
2219
 
+get_modem_properties (DBusGConnection *connection,
2220
 
+                                 const char *path,
2221
 
+                                 char **data_device,
2222
 
+                                 char **driver,
2223
 
+                                 guint32 *type)
2224
 
+{
2225
 
+       DBusGProxy *proxy;
2226
 
+       GValue value = { 0 };
2227
 
+       GError *err = NULL;
2228
 
+
2229
 
+       proxy = dbus_g_proxy_new_for_name (connection,
2230
 
+                                                               MM_DBUS_SERVICE,
2231
 
+                                                               path,
2232
 
+                                                               "org.freedesktop.DBus.Properties");
2233
 
+
2234
 
+       if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err,
2235
 
+                                                                G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
2236
 
+                                                                G_TYPE_STRING, "Type",
2237
 
+                                                                G_TYPE_INVALID,
2238
 
+                                                                G_TYPE_VALUE, &value,
2239
 
+                                                                G_TYPE_INVALID)) {
2240
 
+               *type = g_value_get_uint (&value);
2241
 
+               g_value_unset (&value);
2242
 
+       } else {
2243
 
+               g_warning ("Could not get device type: %s", err->message);
2244
 
+               goto out;
2245
 
+       }
2246
 
+
2247
 
+       if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err,
2248
 
+                                                                G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
2249
 
+                                                                G_TYPE_STRING, "DataDevice",
2250
 
+                                                                G_TYPE_INVALID,
2251
 
+                                                                G_TYPE_VALUE, &value,
2252
 
+                                                                G_TYPE_INVALID)) {
2253
 
+               *data_device = g_value_dup_string (&value);
2254
 
+               g_value_unset (&value);
2255
 
+       } else {
2256
 
+               g_warning ("Could not get modem data device: %s", err->message);
2257
 
+               goto out;
2258
 
+       }
2259
 
+
2260
 
+       if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err,
2261
 
+                                                                G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
2262
 
+                                                                G_TYPE_STRING, "Driver",
2263
 
+                                                                G_TYPE_INVALID,
2264
 
+                                                                G_TYPE_VALUE, &value,
2265
 
+                                                                G_TYPE_INVALID)) {
2266
 
+               *driver = g_value_dup_string (&value);
2267
 
+               g_value_unset (&value);
2268
 
+       } else {
2269
 
+               g_warning ("Could not get modem driver: %s", err->message);
2270
 
+               goto out;
2271
 
+       }
2272
 
+
2273
 
+ out:
2274
 
+       if (err)
2275
 
+               g_error_free (err);
2276
 
+
2277
 
+       g_object_unref (proxy);
2278
 
+
2279
 
+       return *data_device && *driver;
2280
 
+}
2281
 
+
2282
 
+static void
2283
 
+create_modem (NMModemManager *manager, const char *path)
2284
 
+{
2285
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (manager);
2286
 
+       NMDevice *device;
2287
 
+       char *data_device = NULL;
2288
 
+       char *driver = NULL;
2289
 
+       uint modem_type = MM_MODEM_TYPE_UNKNOWN;
2290
 
+
2291
 
+       if (g_hash_table_lookup (priv->modems, path)) {
2292
 
+               nm_warning ("Modem with path %s already exists, ignoring", path);
2293
 
+               return;
2294
 
+       }
2295
 
+
2296
 
+       if (!get_modem_properties (nm_dbus_manager_get_connection (priv->dbus_mgr), path,
2297
 
+                                                 &data_device, &driver, &modem_type))
2298
 
+               return;
2299
 
+
2300
 
+       if (modem_type == MM_MODEM_TYPE_UNKNOWN) {
2301
 
+               nm_warning ("Modem with path %s has unknown type, ignoring", path);
2302
 
+               return;
2303
 
+       }
2304
 
+
2305
 
+       if (!driver || !strlen (driver)) {
2306
 
+               nm_warning ("Modem with path %s has unknown driver, ignoring", path);
2307
 
+               return;
2308
 
+       }
2309
 
+
2310
 
+       if (!data_device || !strlen (data_device)) {
2311
 
+               nm_warning ("Modem with path %s has unknown data device, ignoring", path);
2312
 
+               return;
2313
 
+       }
2314
 
+
2315
 
+       if (modem_type == MM_MODEM_TYPE_GSM) {
2316
 
+               if (!strcmp (driver, "hso"))
2317
 
+                       device = nm_gsm_modem_hso_new (path, data_device, driver);
2318
 
+               else if (!strcmp (driver, "mbm"))
2319
 
+                       device = nm_gsm_modem_mbm_new (path, data_device, driver);
2320
 
+               else
2321
 
+                       device = nm_gsm_modem_new (path, data_device, driver);
2322
 
+       } else if (modem_type == MM_MODEM_TYPE_CDMA)
2323
 
+               device = nm_cdma_modem_new (path, data_device, driver);
2324
 
+       else
2325
 
+               g_error ("Invalid modem type");
2326
 
+
2327
 
+       g_free (data_device);
2328
 
+       g_free (driver);
2329
 
+
2330
 
+       if (device) {
2331
 
+               g_hash_table_insert (priv->modems, g_strdup (path), device);
2332
 
+               g_signal_emit (manager, signals[DEVICE_ADDED], 0, device);
2333
 
+       }
2334
 
+}
2335
 
+
2336
 
+static void
2337
 
+modem_added (DBusGProxy *proxy, const char *path, gpointer user_data)
2338
 
+{
2339
 
+       create_modem (NM_MODEM_MANAGER (user_data), path);
2340
 
+}
2341
 
+
2342
 
+static void
2343
 
+modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
2344
 
+{
2345
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (user_data);
2346
 
+       NMModemDevice *modem;
2347
 
+
2348
 
+       modem = (NMModemDevice *) g_hash_table_lookup (priv->modems, path);
2349
 
+       if (modem) {
2350
 
+               g_signal_emit (user_data, signals[DEVICE_REMOVED], 0, modem);
2351
 
+               g_hash_table_remove (priv->modems, path);
2352
 
+       }
2353
 
+}
2354
 
+
2355
 
+static gboolean
2356
 
+poke_modem_cb (gpointer user_data)
2357
 
+{
2358
 
+       NMModemManager *self = NM_MODEM_MANAGER (user_data);
2359
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
2360
 
+       DBusGConnection *g_connection;
2361
 
+       DBusGProxy *proxy;
2362
 
+
2363
 
+       g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
2364
 
+       proxy = dbus_g_proxy_new_for_name (g_connection,
2365
 
+                                          MM_DBUS_SERVICE,
2366
 
+                                          MM_DBUS_PATH,
2367
 
+                                          MM_DBUS_INTERFACE);
2368
 
+
2369
 
+       nm_info ("Trying to start the modem-manager...");
2370
 
+       dbus_g_proxy_call_no_reply (proxy, "EnumerateDevices", G_TYPE_INVALID);
2371
 
+       g_object_unref (proxy);
2372
 
+
2373
 
+       return TRUE;
2374
 
+}
2375
 
+
2376
 
+static void
2377
 
+enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
2378
 
+{
2379
 
+       NMModemManager *manager = NM_MODEM_MANAGER (data);
2380
 
+       GPtrArray *modems;
2381
 
+       GError *error = NULL;
2382
 
+
2383
 
+       if (!dbus_g_proxy_end_call (proxy, call_id, &error,
2384
 
+                                                  dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems,
2385
 
+                                                  G_TYPE_INVALID)) {
2386
 
+               nm_warning ("Could not get modem list: %s", error->message);
2387
 
+               g_error_free (error);
2388
 
+       } else {
2389
 
+               int i;
2390
 
+
2391
 
+               for (i = 0; i < modems->len; i++) {
2392
 
+                       char *path = (char *) g_ptr_array_index (modems, i);
2393
 
+
2394
 
+                       create_modem (manager, path);
2395
 
+                       g_free (path);
2396
 
+               }
2397
 
+
2398
 
+               g_ptr_array_free (modems, TRUE);
2399
 
+       }
2400
 
+}
2401
 
+
2402
 
+static void
2403
 
+modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices)
2404
 
+{
2405
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
2406
 
+
2407
 
+       if (priv->poke_id) {
2408
 
+               g_source_remove (priv->poke_id);
2409
 
+               priv->poke_id = 0;
2410
 
+       }
2411
 
+
2412
 
+       priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
2413
 
+                                                                        MM_DBUS_SERVICE, MM_DBUS_PATH, MM_DBUS_INTERFACE);
2414
 
+
2415
 
+       dbus_g_proxy_add_signal (priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID);
2416
 
+       dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded",
2417
 
+                                                   G_CALLBACK (modem_added), self,
2418
 
+                                                   NULL);
2419
 
+
2420
 
+       dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
2421
 
+       dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved",
2422
 
+                                                   G_CALLBACK (modem_removed), self,
2423
 
+                                                   NULL);
2424
 
+
2425
 
+       if (enumerate_devices)
2426
 
+               dbus_g_proxy_begin_call (priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID);
2427
 
+}
2428
 
+
2429
 
+static gboolean
2430
 
+remove_one_modem (gpointer key, gpointer value, gpointer user_data)
2431
 
+{
2432
 
+       g_signal_emit (user_data, signals[DEVICE_REMOVED], 0, value);
2433
 
+
2434
 
+       return TRUE;
2435
 
+}
2436
 
+
2437
 
+static void
2438
 
+modem_manager_disappeared (NMModemManager *self)
2439
 
+{
2440
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
2441
 
+
2442
 
+       g_hash_table_foreach_remove (priv->modems, remove_one_modem, self);
2443
 
+
2444
 
+       if (priv->proxy) {
2445
 
+               g_object_unref (priv->proxy);
2446
 
+               priv->proxy = NULL;
2447
 
+       }
2448
 
+
2449
 
+       /* Try to activate the modem-manager */
2450
 
+       poke_modem_cb (self);
2451
 
+       priv->poke_id = g_timeout_add (MODEM_POKE_INTERVAL, poke_modem_cb, self);
2452
 
+}
2453
 
+
2454
 
+static void
2455
 
+nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr,
2456
 
+                                                         const char *name,
2457
 
+                                                         const char *old_owner,
2458
 
+                                                         const char *new_owner,
2459
 
+                                                         gpointer user_data)
2460
 
+{
2461
 
+       gboolean old_owner_good;
2462
 
+       gboolean new_owner_good;
2463
 
+
2464
 
+       /* Can't handle the signal if its not from the modem service */
2465
 
+       if (strcmp (MM_DBUS_SERVICE, name) != 0)
2466
 
+               return;
2467
 
+
2468
 
+       old_owner_good = (old_owner && strlen (old_owner));
2469
 
+       new_owner_good = (new_owner && strlen (new_owner));
2470
 
+
2471
 
+       if (!old_owner_good && new_owner_good) {
2472
 
+               nm_info ("modem manager appeared");
2473
 
+               modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE);
2474
 
+       } else if (old_owner_good && !new_owner_good) {
2475
 
+               nm_info ("modem manager disappeared");
2476
 
+               modem_manager_disappeared (NM_MODEM_MANAGER (user_data));
2477
 
+       }
2478
 
+}
2479
 
+
2480
 
+/*******************************************************/
2481
 
+
2482
 
+static void
2483
 
+nm_modem_manager_init (NMModemManager *self)
2484
 
+{
2485
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self);
2486
 
+
2487
 
+       priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
2488
 
+       priv->dbus_mgr = nm_dbus_manager_get ();
2489
 
+
2490
 
+       g_signal_connect (priv->dbus_mgr, "name-owner-changed",
2491
 
+                         G_CALLBACK (nm_modem_manager_name_owner_changed),
2492
 
+                         self);
2493
 
+
2494
 
+       if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE))
2495
 
+               modem_manager_appeared (self, TRUE);
2496
 
+       else
2497
 
+               modem_manager_disappeared (self);
2498
 
+}
2499
 
+
2500
 
+static void
2501
 
+dispose (GObject *object)
2502
 
+{
2503
 
+       NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (object);
2504
 
+
2505
 
+       if (priv->disposed)
2506
 
+               return;
2507
 
+
2508
 
+       priv->disposed = TRUE;
2509
 
+
2510
 
+       if (priv->poke_id) {
2511
 
+               g_source_remove (priv->poke_id);
2512
 
+               priv->poke_id = 0;
2513
 
+       }
2514
 
+
2515
 
+       g_hash_table_foreach_remove (priv->modems, remove_one_modem, object);
2516
 
+       g_hash_table_destroy (priv->modems);
2517
 
+
2518
 
+       if (priv->proxy) {
2519
 
+               g_object_unref (priv->proxy);
2520
 
+               priv->proxy = NULL;
2521
 
+       }
2522
 
+
2523
 
+       if (priv->dbus_mgr) {
2524
 
+               g_object_unref (priv->dbus_mgr);
2525
 
+               priv->dbus_mgr = NULL;
2526
 
+       }
2527
 
+
2528
 
+       /* Chain up to the parent class */
2529
 
+       G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object);
2530
 
+}
2531
 
+
2532
 
+static void
2533
 
+nm_modem_manager_class_init (NMModemManagerClass *klass)
2534
 
+{
2535
 
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
2536
 
+
2537
 
+       g_type_class_add_private (object_class, sizeof (NMModemManagerPrivate));
2538
 
+
2539
 
+       object_class->dispose = dispose;
2540
 
+
2541
 
+       /* signals */
2542
 
+       signals[DEVICE_ADDED] =
2543
 
+               g_signal_new ("device-added",
2544
 
+                                   G_OBJECT_CLASS_TYPE (object_class),
2545
 
+                                   G_SIGNAL_RUN_FIRST,
2546
 
+                                   G_STRUCT_OFFSET (NMModemManagerClass, device_added),
2547
 
+                                   NULL, NULL,
2548
 
+                                   g_cclosure_marshal_VOID__OBJECT,
2549
 
+                                   G_TYPE_NONE, 1,
2550
 
+                                   G_TYPE_OBJECT);
2551
 
+
2552
 
+       signals[DEVICE_REMOVED] =
2553
 
+               g_signal_new ("device-removed",
2554
 
+                                   G_OBJECT_CLASS_TYPE (object_class),
2555
 
+                                   G_SIGNAL_RUN_FIRST,
2556
 
+                                   G_STRUCT_OFFSET (NMModemManagerClass, device_removed),
2557
 
+                                   NULL, NULL,
2558
 
+                                   g_cclosure_marshal_VOID__OBJECT,
2559
 
+                                   G_TYPE_NONE, 1,
2560
 
+                                   G_TYPE_OBJECT);
2561
 
+}
2562
 
diff --git a/src/modem-manager/nm-modem-manager.h b/src/modem-manager/nm-modem-manager.h
2563
 
new file mode 100644
2564
 
index 0000000..ec62f84
2565
 
--- /dev/null
2566
 
+++ b/src/modem-manager/nm-modem-manager.h
2567
 
@@ -0,0 +1,35 @@
2568
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
2569
 
+
2570
 
+#ifndef NM_MODEM_MANAGER_H
2571
 
+#define NM_MODEM_MANAGER_H
2572
 
+
2573
 
+#include <glib-object.h>
2574
 
+#include "nm-device.h"
2575
 
+
2576
 
+#define NM_TYPE_MODEM_MANAGER                          (nm_modem_manager_get_type ())
2577
 
+#define NM_MODEM_MANAGER(obj)                          (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_MANAGER, NMModemManager))
2578
 
+#define NM_MODEM_MANAGER_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_MODEM_MANAGER, NMModemManagerClass))
2579
 
+#define NM_IS_MODEM_MANAGER(obj)                       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_MANAGER))
2580
 
+#define NM_IS_MODEM_MANAGER_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_MODEM_MANAGER))
2581
 
+#define NM_MODEM_MANAGER_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_MODEM_MANAGER, NMModemManagerClass))
2582
 
+
2583
 
+typedef struct {
2584
 
+       GObject parent;
2585
 
+} NMModemManager;
2586
 
+
2587
 
+typedef struct {
2588
 
+       GObjectClass parent;
2589
 
+
2590
 
+       /* Signals */
2591
 
+       void (*device_added) (NMModemManager *manager,
2592
 
+                                         NMDevice *device);
2593
 
+
2594
 
+       void (*device_removed) (NMModemManager *manager,
2595
 
+                                           NMDevice *device);
2596
 
+} NMModemManagerClass;
2597
 
+
2598
 
+GType nm_modem_manager_get_type (void);
2599
 
+
2600
 
+NMModemManager *nm_modem_manager_get (void);
2601
 
+
2602
 
+#endif /* NM_MODEM_MANAGER_H */
2603
 
diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h
2604
 
new file mode 100644
2605
 
index 0000000..de1d2de
2606
 
--- /dev/null
2607
 
+++ b/src/modem-manager/nm-modem-types.h
2608
 
@@ -0,0 +1,90 @@
2609
 
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
2610
 
+
2611
 
+#ifndef NM_MODEM_TYPES_H
2612
 
+#define NM_MODEM_TYPES_H
2613
 
+
2614
 
+#define MM_DBUS_SERVICE              "org.freedesktop.ModemManager"
2615
 
+#define MM_DBUS_PATH                 "/org/freedesktop/ModemManager"
2616
 
+#define MM_DBUS_INTERFACE            "org.freedesktop.ModemManager"
2617
 
+#define MM_DBUS_INTERFACE_MODEM      "org.freedesktop.ModemManager.Modem"
2618
 
+#define MM_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma"
2619
 
+
2620
 
+#define MM_DBUS_INTERFACE_MODEM_GSM_CARD    "org.freedesktop.ModemManager.Modem.Gsm.Card"
2621
 
+#define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network"
2622
 
+#define MM_DBUS_INTERFACE_MODEM_GSM_HSO     "org.freedesktop.ModemManager.Modem.Gsm.Hso"
2623
 
+#define MM_DBUS_INTERFACE_MODEM_GSM_MBM     "org.freedesktop.ModemManager.Modem.Gsm.Mbm"
2624
 
+
2625
 
+#define MM_MODEM_TYPE_UNKNOWN  0
2626
 
+#define MM_MODEM_TYPE_GSM      1
2627
 
+#define MM_MODEM_TYPE_CDMA     2
2628
 
+
2629
 
+/* Errors */
2630
 
+
2631
 
+#define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed"
2632
 
+#define MM_SERIAL_SEND_FAILED MM_DBUS_INTERFACE_MODEM ".SerialSendFailed"
2633
 
+#define MM_SERIAL_RESPONSE_TIMEOUT MM_DBUS_INTERFACE_MODEM ".SerialResponseTimeout"
2634
 
+
2635
 
+#define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".General"
2636
 
+#define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_DBUS_INTERFACE_MODEM ".OperationNotSupported"
2637
 
+
2638
 
+#define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_DBUS_INTERFACE_MODEM ".NoCarrier"
2639
 
+#define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_DBUS_INTERFACE_MODEM ".NoDialtone"
2640
 
+#define MM_MODEM_CONNECT_ERROR_BUSY MM_DBUS_INTERFACE_MODEM ".Busy"
2641
 
+#define MM_MODEM_CONNECT_ERROR_NO_ANSWER MM_DBUS_INTERFACE_MODEM ".NoAnswer"
2642
 
+
2643
 
+#define MM_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm"
2644
 
+
2645
 
+#define MM_MODEM_ERROR_PHONE_FAILURE MM_MODEM_ERROR ".PhoneFailure"
2646
 
+#define MM_MODEM_ERROR_NO_CONNECTION MM_MODEM_ERROR ".NoConnection"
2647
 
+#define MM_MODEM_ERROR_LINK_RESERVED MM_MODEM_ERROR ".LinkReserved"
2648
 
+#define MM_MODEM_ERROR_NOT_ALLOWED MM_MODEM_ERROR ".OperationNotAllowed"
2649
 
+#define MM_MODEM_ERROR_NOT_SUPPORTED MM_MODEM_ERROR ".OperationNotSupported"
2650
 
+#define MM_MODEM_ERROR_PH_SIM_PIN MM_MODEM_ERROR ".PhSimPinRequired"
2651
 
+#define MM_MODEM_ERROR_PH_FSIM_PIN MM_MODEM_ERROR ".PhFSimPinRequired"
2652
 
+#define MM_MODEM_ERROR_PH_FSIM_PUK MM_MODEM_ERROR ".PhFPukRequired"
2653
 
+#define MM_MODEM_ERROR_SIM_NOT_INSERTED MM_MODEM_ERROR ".SimNotInserted"
2654
 
+#define MM_MODEM_ERROR_SIM_PIN MM_MODEM_ERROR ".SimPinRequired"
2655
 
+#define MM_MODEM_ERROR_SIM_PUK MM_MODEM_ERROR ".SimPukRequired"
2656
 
+#define MM_MODEM_ERROR_SIM_FAILURE MM_MODEM_ERROR ".SimFailure"
2657
 
+#define MM_MODEM_ERROR_SIM_BUSY MM_MODEM_ERROR ".SimBusy"
2658
 
+#define MM_MODEM_ERROR_SIM_WRONG MM_MODEM_ERROR ".SimWrong"
2659
 
+#define MM_MODEM_ERROR_WRONG_PASSWORD MM_MODEM_ERROR ".IncorrectPassword"
2660
 
+#define MM_MODEM_ERROR_SIM_PIN2 MM_MODEM_ERROR ".SimPin2Required"
2661
 
+#define MM_MODEM_ERROR_SIM_PUK2 MM_MODEM_ERROR ".SimPuk2Required"
2662
 
+#define MM_MODEM_ERROR_MEMORY_FULL MM_MODEM_ERROR ".MemoryFull"
2663
 
+#define MM_MODEM_ERROR_INVALID_INDEX MM_MODEM_ERROR ".InvalidIndex"
2664
 
+#define MM_MODEM_ERROR_NOT_FOUND MM_MODEM_ERROR ".NotFound"
2665
 
+#define MM_MODEM_ERROR_MEMORY_FAILURE MM_MODEM_ERROR ".MemoryFailure"
2666
 
+#define MM_MODEM_ERROR_TEXT_TOO_LONG MM_MODEM_ERROR ".TextTooLong"
2667
 
+#define MM_MODEM_ERROR_INVALID_CHARS MM_MODEM_ERROR ".InvalidChars"
2668
 
+#define MM_MODEM_ERROR_DIAL_STRING_TOO_LONG MM_MODEM_ERROR ".DialStringTooLong"
2669
 
+#define MM_MODEM_ERROR_DIAL_STRING_INVALID MM_MODEM_ERROR ".InvalidDialString"
2670
 
+#define MM_MODEM_ERROR_NO_NETWORK MM_MODEM_ERROR ".NoNetwork"
2671
 
+#define MM_MODEM_ERROR_NETWORK_TIMEOUT MM_MODEM_ERROR ".NetworkTimeout"
2672
 
+#define MM_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_MODEM_ERROR ".NetworkNotAllowed"
2673
 
+#define MM_MODEM_ERROR_NETWORK_PIN MM_MODEM_ERROR ".NetworkPinRequired"
2674
 
+#define MM_MODEM_ERROR_NETWORK_PUK MM_MODEM_ERROR ".NetworkPukRequired"
2675
 
+#define MM_MODEM_ERROR_NETWORK_SUBSET_PIN MM_MODEM_ERROR ".NetworkSubsetPinRequired"
2676
 
+#define MM_MODEM_ERROR_NETWORK_SUBSET_PUK MM_MODEM_ERROR ".NetworkSubsetPukRequired"
2677
 
+#define MM_MODEM_ERROR_SERVICE_PIN MM_MODEM_ERROR ".ServicePinRequired"
2678
 
+#define MM_MODEM_ERROR_SERVICE_PUK MM_MODEM_ERROR ".ServicePukRequired"
2679
 
+#define MM_MODEM_ERROR_CORP_PIN MM_MODEM_ERROR ".CorporatePinRequired"
2680
 
+#define MM_MODEM_ERROR_CORP_PUK MM_MODEM_ERROR ".CorporatePukRequired"
2681
 
+#define MM_MODEM_ERROR_HIDDEN_KEY MM_MODEM_ERROR ".HiddenKeyRequired"
2682
 
+#define MM_MODEM_ERROR_EAP_NOT_SUPPORTED MM_MODEM_ERROR ".EapMethodNotSupported"
2683
 
+#define MM_MODEM_ERROR_INCORRECT_PARAMS MM_MODEM_ERROR ".IncorrectParams"
2684
 
+#define MM_MODEM_ERROR_UNKNOWN MM_MODEM_ERROR ".Unknown"
2685
 
+#define MM_MODEM_ERROR_GPRS_ILLEGAL_MS MM_MODEM_ERROR ".GprsIllegalMs"
2686
 
+#define MM_MODEM_ERROR_GPRS_ILLEGAL_ME MM_MODEM_ERROR ".GprsIllegalMe"
2687
 
+#define MM_MODEM_ERROR_GPRS_SERVICE_NOT_ALLOWED  MM_MODEM_ERROR ".GprsServiceNotAllowed"
2688
 
+#define MM_MODEM_ERROR_GPRS_PLMN_NOT_ALLOWED MM_MODEM_ERROR ".GprsPlmnNotAllowed"
2689
 
+#define MM_MODEM_ERROR_GPRS_LOCATION_NOT_ALLOWED MM_MODEM_ERROR ".GprsLocationNotAllowed"
2690
 
+#define MM_MODEM_ERROR_GPRS_ROAMING_NOT_ALLOWED MM_MODEM_ERROR ".GprsRoamingNotAllowed"
2691
 
+#define MM_MODEM_ERROR_GPRS_OPTION_NOT_SUPPORTED MM_MODEM_ERROR ".GprsOptionNotSupported"
2692
 
+#define MM_MODEM_ERROR_GPRS_NOT_SUBSCRIBED MM_MODEM_ERROR ".GprsNotSubscribed"
2693
 
+#define MM_MODEM_ERROR_GPRS_OUT_OF_ORDER MM_MODEM_ERROR ".GprsOutOfOrder"
2694
 
+#define MM_MODEM_ERROR_GPRS_PDP_AUTH_FAILURE MM_MODEM_ERROR ".GprsPdpAuthFailure"
2695
 
+#define MM_MODEM_ERROR_GPRS_UNKNOWN MM_MODEM_ERROR ".GprsUnspecified"
2696
 
+#define MM_MODEM_ERROR_GPRS_INVALID_CLASS MM_MODEM_ERROR ".GprsInvalidClass"
2697
 
+
2698
 
+#endif /* NM_MODEM_TYPES_H */
2699
 
diff --git a/src/nm-cdma-device.c b/src/nm-cdma-device.c
2700
 
deleted file mode 100644
2701
 
index c1c9b06..0000000
2702
 
--- a/src/nm-cdma-device.c
2703
 
+++ /dev/null
2704
 
@@ -1,593 +0,0 @@
2705
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2706
 
-/* NetworkManager -- Network link manager
2707
 
- *
2708
 
- * This program is free software; you can redistribute it and/or modify
2709
 
- * it under the terms of the GNU General Public License as published by
2710
 
- * the Free Software Foundation; either version 2 of the License, or
2711
 
- * (at your option) any later version.
2712
 
- *
2713
 
- * This program is distributed in the hope that it will be useful,
2714
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2715
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2716
 
- * GNU General Public License for more details.
2717
 
- *
2718
 
- * You should have received a copy of the GNU General Public License along
2719
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
2720
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2721
 
- *
2722
 
- * Copyright (C) 2008 Red Hat, Inc.
2723
 
- * Copyright (C) 2008 Novell, Inc.
2724
 
- */
2725
 
-
2726
 
-#include <stdio.h>
2727
 
-#include <string.h>
2728
 
-#include "nm-cdma-device.h"
2729
 
-#include "nm-device-interface.h"
2730
 
-#include "nm-device-private.h"
2731
 
-#include "nm-setting-cdma.h"
2732
 
-#include "nm-utils.h"
2733
 
-#include "nm-properties-changed-signal.h"
2734
 
-#include "nm-cdma-device-glue.h"
2735
 
-#include "nm-setting-connection.h"
2736
 
-
2737
 
-G_DEFINE_TYPE (NMCdmaDevice, nm_cdma_device, NM_TYPE_SERIAL_DEVICE)
2738
 
-
2739
 
-#define NM_CDMA_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CDMA_DEVICE, NMCdmaDevicePrivate))
2740
 
-
2741
 
-typedef struct {
2742
 
-       char *monitor_iface;
2743
 
-       NMSerialDevice *monitor_device;
2744
 
-
2745
 
-       guint state_to_disconnected_id;
2746
 
-} NMCdmaDevicePrivate;
2747
 
-
2748
 
-enum {
2749
 
-       PROP_0,
2750
 
-       PROP_MONITOR_IFACE,
2751
 
-
2752
 
-       LAST_PROP
2753
 
-};
2754
 
-
2755
 
-enum {
2756
 
-       PROPERTIES_CHANGED,
2757
 
-
2758
 
-       LAST_SIGNAL
2759
 
-};
2760
 
-
2761
 
-static guint signals[LAST_SIGNAL] = { 0 };
2762
 
-
2763
 
-
2764
 
-NMCdmaDevice *
2765
 
-nm_cdma_device_new (const char *udi,
2766
 
-                    const char *data_iface,
2767
 
-                    const char *monitor_iface,
2768
 
-                    const char *driver,
2769
 
-                    gboolean managed)
2770
 
-{
2771
 
-       g_return_val_if_fail (udi != NULL, NULL);
2772
 
-       g_return_val_if_fail (data_iface != NULL, NULL);
2773
 
-       g_return_val_if_fail (driver != NULL, NULL);
2774
 
-
2775
 
-       return (NMCdmaDevice *) g_object_new (NM_TYPE_CDMA_DEVICE,
2776
 
-                                             NM_DEVICE_INTERFACE_UDI, udi,
2777
 
-                                             NM_DEVICE_INTERFACE_IFACE, data_iface,
2778
 
-                                             NM_DEVICE_INTERFACE_DRIVER, driver,
2779
 
-                                             NM_CDMA_DEVICE_MONITOR_IFACE, monitor_iface,
2780
 
-                                                                                 NM_DEVICE_INTERFACE_MANAGED, managed,
2781
 
-                                             NULL);
2782
 
-}
2783
 
-
2784
 
-static NMSetting *
2785
 
-cdma_device_get_setting (NMCdmaDevice *device, GType setting_type)
2786
 
-{
2787
 
-       NMActRequest *req;
2788
 
-       NMSetting *setting = NULL;
2789
 
-
2790
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
2791
 
-       if (req) {
2792
 
-               NMConnection *connection;
2793
 
-
2794
 
-               connection = nm_act_request_get_connection (req);
2795
 
-               if (connection)
2796
 
-                       setting = nm_connection_get_setting (connection, setting_type);
2797
 
-       }
2798
 
-
2799
 
-       return setting;
2800
 
-}
2801
 
-
2802
 
-static void
2803
 
-dial_done (NMSerialDevice *device,
2804
 
-           int reply_index,
2805
 
-           const char *reply,
2806
 
-           gpointer user_data)
2807
 
-{
2808
 
-       NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
2809
 
-       gboolean success = FALSE;
2810
 
-
2811
 
-       switch (reply_index) {
2812
 
-       case 0:
2813
 
-               nm_info ("Connected, Woo!");
2814
 
-               success = TRUE;
2815
 
-               break;
2816
 
-       case 1:
2817
 
-               nm_info ("Busy");
2818
 
-               reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
2819
 
-               break;
2820
 
-       case 2:
2821
 
-               nm_warning ("No dial tone");
2822
 
-               reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
2823
 
-               break;
2824
 
-       case 3:
2825
 
-               nm_warning ("No carrier");
2826
 
-               reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
2827
 
-               break;
2828
 
-       case -1:
2829
 
-               nm_warning ("Dialing timed out");
2830
 
-               reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
2831
 
-               break;
2832
 
-       default:
2833
 
-               nm_warning ("Dialing failed");
2834
 
-               break;
2835
 
-       }
2836
 
-
2837
 
-       if (success)
2838
 
-               nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
2839
 
-       else
2840
 
-               nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, reason);
2841
 
-}
2842
 
-
2843
 
-static void
2844
 
-do_dial (NMSerialDevice *device)
2845
 
-{
2846
 
-       NMSettingCdma *setting;
2847
 
-       char *command;
2848
 
-       guint id = 0;
2849
 
-       const char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL };
2850
 
-
2851
 
-       setting = NM_SETTING_CDMA (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_CDMA));
2852
 
-
2853
 
-       command = g_strconcat ("ATDT", nm_setting_cdma_get_number (setting), NULL);
2854
 
-       if (nm_serial_device_send_command_string (device, command))
2855
 
-               id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL);
2856
 
-       g_free (command);
2857
 
-
2858
 
-       if (id == 0)
2859
 
-               nm_device_state_changed (NM_DEVICE (device),
2860
 
-                                        NM_DEVICE_STATE_FAILED,
2861
 
-                                        NM_DEVICE_STATE_REASON_UNKNOWN);
2862
 
-}
2863
 
-
2864
 
-static void
2865
 
-power_up_response (NMSerialDevice *device,
2866
 
-                   int reply_index,
2867
 
-                   const char *reply,
2868
 
-                   gpointer user_data)
2869
 
-{
2870
 
-       /* Ignore errors */
2871
 
-       do_dial (device);
2872
 
-}
2873
 
-
2874
 
-static void
2875
 
-power_up (NMSerialDevice *device)
2876
 
-{
2877
 
-       const char *responses[] = { "OK", "ERROR", "ERR", NULL };
2878
 
-       guint id = 0;
2879
 
-
2880
 
-       /* Only works on Sierra cards */
2881
 
-       nm_info ("(%s): powering up...", nm_device_get_iface (NM_DEVICE (device)));             
2882
 
-       if (nm_serial_device_send_command_string (device, "at!pcstate=1"))
2883
 
-               id = nm_serial_device_wait_for_reply (device, 10, responses, responses, power_up_response, NULL);
2884
 
-
2885
 
-       /* Ignore errors */
2886
 
-       if (id == 0)
2887
 
-               do_dial (device);
2888
 
-}
2889
 
-
2890
 
-static void
2891
 
-init_done (NMSerialDevice *device,
2892
 
-           int reply_index,
2893
 
-           const char *reply,
2894
 
-           gpointer user_data)
2895
 
-{
2896
 
-       switch (reply_index) {
2897
 
-       case 0:
2898
 
-               power_up (device);
2899
 
-               break;
2900
 
-       case -1:
2901
 
-               nm_warning ("Modem initialization timed out");
2902
 
-               nm_device_state_changed (NM_DEVICE (device),
2903
 
-                                        NM_DEVICE_STATE_FAILED,
2904
 
-                                        NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
2905
 
-               break;
2906
 
-       default:
2907
 
-               nm_warning ("Modem initialization failed");
2908
 
-               nm_device_state_changed (NM_DEVICE (device),
2909
 
-                                        NM_DEVICE_STATE_FAILED,
2910
 
-                                        NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
2911
 
-               return;
2912
 
-       }
2913
 
-}
2914
 
-
2915
 
-static void
2916
 
-init_modem (NMSerialDevice *device, gpointer user_data)
2917
 
-{
2918
 
-       guint id = 0;
2919
 
-       const char *responses[] = { "OK", "ERROR", "ERR", NULL };
2920
 
-
2921
 
-       if (nm_serial_device_send_command_string (device, "ATZ E0"))
2922
 
-               id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
2923
 
-
2924
 
-       if (id == 0)
2925
 
-               nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
2926
 
-}
2927
 
-
2928
 
-static NMActStageReturn
2929
 
-real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
2930
 
-{
2931
 
-       NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
2932
 
-       NMSettingSerial *setting;
2933
 
-       guint id;
2934
 
-
2935
 
-       setting = NM_SETTING_SERIAL (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_SERIAL));
2936
 
-
2937
 
-       if (!nm_serial_device_open (serial_device, setting)) {
2938
 
-               *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
2939
 
-               return NM_ACT_STAGE_RETURN_FAILURE;
2940
 
-       }
2941
 
-
2942
 
-       id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
2943
 
-       if (!id)
2944
 
-               *reason = NM_DEVICE_STATE_REASON_UNKNOWN;
2945
 
-
2946
 
-       return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
2947
 
-}
2948
 
-
2949
 
-static NMConnection *
2950
 
-real_get_best_auto_connection (NMDevice *dev,
2951
 
-                               GSList *connections,
2952
 
-                               char **specific_object)
2953
 
-{
2954
 
-       GSList *iter;
2955
 
-
2956
 
-       for (iter = connections; iter; iter = g_slist_next (iter)) {
2957
 
-               NMConnection *connection = NM_CONNECTION (iter->data);
2958
 
-               NMSettingConnection *s_con;
2959
 
-
2960
 
-               s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
2961
 
-               g_assert (s_con);
2962
 
-
2963
 
-               if (!nm_setting_connection_get_autoconnect (s_con))
2964
 
-                       continue;
2965
 
-
2966
 
-               if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME))
2967
 
-                       continue;
2968
 
-
2969
 
-               return connection;
2970
 
-       }
2971
 
-       return NULL;
2972
 
-}
2973
 
-
2974
 
-static guint32
2975
 
-real_get_generic_capabilities (NMDevice *dev)
2976
 
-{
2977
 
-       return NM_DEVICE_CAP_NM_SUPPORTED;
2978
 
-}
2979
 
-
2980
 
-static void
2981
 
-real_connection_secrets_updated (NMDevice *dev,
2982
 
-                                 NMConnection *connection,
2983
 
-                                 GSList *updated_settings,
2984
 
-                                 RequestSecretsCaller caller)
2985
 
-{
2986
 
-       NMActRequest *req;
2987
 
-       gboolean found = FALSE;
2988
 
-       GSList *iter;
2989
 
-
2990
 
-       if (caller == SECRETS_CALLER_PPP) {
2991
 
-               NMPPPManager *ppp_manager;
2992
 
-               NMSettingCdma *s_cdma = NULL;
2993
 
-
2994
 
-               ppp_manager = nm_serial_device_get_ppp_manager (NM_SERIAL_DEVICE (dev));
2995
 
-               g_return_if_fail (ppp_manager != NULL);
2996
 
-
2997
 
-               s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
2998
 
-               if (!s_cdma) {
2999
 
-                       /* Shouldn't ever happen */
3000
 
-                       nm_ppp_manager_update_secrets (ppp_manager,
3001
 
-                                                      nm_device_get_iface (dev),
3002
 
-                                                      NULL,
3003
 
-                                                      NULL,
3004
 
-                                                      "missing CDMA setting; no secrets could be found.");
3005
 
-               } else {
3006
 
-                       const char *cdma_username = nm_setting_cdma_get_username (s_cdma);
3007
 
-                       const char *cdma_password = nm_setting_cdma_get_password (s_cdma);
3008
 
-
3009
 
-                       nm_ppp_manager_update_secrets (ppp_manager,
3010
 
-                                                      nm_device_get_iface (dev),
3011
 
-                                                      cdma_username ? cdma_username : "",
3012
 
-                                                      cdma_password ? cdma_password : "",
3013
 
-                                                      NULL);
3014
 
-               }
3015
 
-               return;
3016
 
-       }
3017
 
-
3018
 
-       g_return_if_fail (caller == SECRETS_CALLER_CDMA);
3019
 
-       g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
3020
 
-
3021
 
-       for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
3022
 
-               const char *setting_name = (const char *) iter->data;
3023
 
-
3024
 
-               if (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME))
3025
 
-                       found = TRUE;
3026
 
-               else
3027
 
-                       nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name);
3028
 
-       }
3029
 
-
3030
 
-       if (!found)
3031
 
-               return;
3032
 
-
3033
 
-       req = nm_device_get_act_request (dev);
3034
 
-       g_assert (req);
3035
 
-
3036
 
-       g_return_if_fail (nm_act_request_get_connection (req) == connection);
3037
 
-
3038
 
-       nm_device_activate_schedule_stage1_device_prepare (dev);
3039
 
-}
3040
 
-
3041
 
-static const char *
3042
 
-real_get_ppp_name (NMSerialDevice *device, NMActRequest *req)
3043
 
-{
3044
 
-       NMConnection *connection;
3045
 
-       NMSettingCdma *s_cdma;
3046
 
-
3047
 
-       connection = nm_act_request_get_connection (req);
3048
 
-       g_assert (connection);
3049
 
-
3050
 
-       s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
3051
 
-       g_assert (s_cdma);
3052
 
-
3053
 
-       return nm_setting_cdma_get_username (s_cdma);
3054
 
-}
3055
 
-
3056
 
-/*****************************************************************************/
3057
 
-/* Monitor device handling */
3058
 
-
3059
 
-static gboolean
3060
 
-monitor_device_got_data (GIOChannel *source,
3061
 
-                                       GIOCondition condition,
3062
 
-                                       gpointer data)
3063
 
-{
3064
 
-       gsize bytes_read;
3065
 
-       char buf[4096];
3066
 
-       GIOStatus status;
3067
 
-
3068
 
-       if (condition & G_IO_IN) {
3069
 
-               do {
3070
 
-                       status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL);
3071
 
-
3072
 
-                       if (bytes_read) {
3073
 
-                               buf[bytes_read] = '\0';
3074
 
-                               /* Do nothing with the data for now */
3075
 
-                               nm_debug ("Monitor got unhandled data: '%s'", buf);
3076
 
-                       }
3077
 
-               } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN);
3078
 
-       }
3079
 
-
3080
 
-       if (condition & G_IO_HUP || condition & G_IO_ERR) {
3081
 
-               return FALSE;
3082
 
-       }
3083
 
-
3084
 
-       return TRUE;
3085
 
-}
3086
 
-
3087
 
-static gboolean
3088
 
-setup_monitor_device (NMCdmaDevice *device)
3089
 
-{
3090
 
-       NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (device);
3091
 
-       GIOChannel *channel;
3092
 
-       NMSettingSerial *setting;
3093
 
-
3094
 
-       if (!priv->monitor_iface) {
3095
 
-               nm_debug ("No monitoring udi provided");
3096
 
-               return FALSE;
3097
 
-       }
3098
 
-
3099
 
-       priv->monitor_device = g_object_new (NM_TYPE_SERIAL_DEVICE,
3100
 
-                                            NM_DEVICE_INTERFACE_UDI, nm_device_get_udi (NM_DEVICE (device)),
3101
 
-                                            NM_DEVICE_INTERFACE_IFACE, priv->monitor_iface,
3102
 
-                                            NULL);
3103
 
-
3104
 
-       if (!priv->monitor_device) {
3105
 
-               nm_warning ("Creation of the monitoring device failed");
3106
 
-               return FALSE;
3107
 
-       }
3108
 
-
3109
 
-       setting = NM_SETTING_SERIAL (nm_setting_serial_new ());
3110
 
-       if (!nm_serial_device_open (priv->monitor_device, setting)) {
3111
 
-               nm_warning ("Monitoring device open failed");
3112
 
-               g_object_unref (setting);
3113
 
-               g_object_unref (priv->monitor_device);
3114
 
-               return FALSE;
3115
 
-       }
3116
 
-
3117
 
-       g_object_unref (setting);
3118
 
-
3119
 
-       channel = nm_serial_device_get_io_channel (priv->monitor_device);
3120
 
-       g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
3121
 
-                                monitor_device_got_data, device);
3122
 
-
3123
 
-       g_io_channel_unref (channel);
3124
 
-
3125
 
-       return TRUE;
3126
 
-}
3127
 
-
3128
 
-/*****************************************************************************/
3129
 
-
3130
 
-static void
3131
 
-nm_cdma_device_init (NMCdmaDevice *self)
3132
 
-{
3133
 
-       nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_CDMA);
3134
 
-}
3135
 
-
3136
 
-static gboolean
3137
 
-unavailable_to_disconnected (gpointer user_data)
3138
 
-{
3139
 
-       nm_device_state_changed (NM_DEVICE (user_data),
3140
 
-                                NM_DEVICE_STATE_DISCONNECTED,
3141
 
-                                NM_DEVICE_STATE_REASON_NONE);
3142
 
-       return FALSE;
3143
 
-}
3144
 
-
3145
 
-static void
3146
 
-device_state_changed (NMDeviceInterface *device,
3147
 
-                      NMDeviceState new_state,
3148
 
-                      NMDeviceState old_state,
3149
 
-                      NMDeviceStateReason reason,
3150
 
-                      gpointer user_data)
3151
 
-{
3152
 
-       NMCdmaDevice *self = NM_CDMA_DEVICE (user_data);
3153
 
-       NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (self);
3154
 
-
3155
 
-       /* Remove any previous delayed transition to disconnected */
3156
 
-       if (priv->state_to_disconnected_id) {
3157
 
-               g_source_remove (priv->state_to_disconnected_id);
3158
 
-               priv->state_to_disconnected_id = 0;
3159
 
-       }
3160
 
-
3161
 
-       /* If transitioning to UNAVAILBLE and we have a carrier, transition to
3162
 
-        * DISCONNECTED because the device is ready to use.  Otherwise the carrier-on
3163
 
-        * handler will handle the transition to DISCONNECTED when the carrier is detected.
3164
 
-        */
3165
 
-       if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
3166
 
-               priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self);
3167
 
-
3168
 
-       /* Make sure we don't leave the serial device open */
3169
 
-       switch (new_state) {
3170
 
-       case NM_DEVICE_STATE_UNMANAGED:
3171
 
-       case NM_DEVICE_STATE_UNAVAILABLE:
3172
 
-       case NM_DEVICE_STATE_FAILED:
3173
 
-       case NM_DEVICE_STATE_DISCONNECTED:
3174
 
-               nm_serial_device_close (NM_SERIAL_DEVICE (self));
3175
 
-               break;
3176
 
-       default:
3177
 
-               break;
3178
 
-       }
3179
 
-}
3180
 
-
3181
 
-static GObject*
3182
 
-constructor (GType type,
3183
 
-             guint n_construct_params,
3184
 
-             GObjectConstructParam *construct_params)
3185
 
-{
3186
 
-       GObject *object;
3187
 
-
3188
 
-       object = G_OBJECT_CLASS (nm_cdma_device_parent_class)->constructor (type,
3189
 
-                                                                                                                 n_construct_params,
3190
 
-                                                                                                                 construct_params);
3191
 
-       if (!object)
3192
 
-               return NULL;
3193
 
-
3194
 
-       /* FIXME: Make the monitor device not required for now */
3195
 
-       setup_monitor_device (NM_CDMA_DEVICE (object));
3196
 
-#if 0
3197
 
-       if (!setup_monitor_device (NM_CDMA_DEVICE (object))) {
3198
 
-               g_object_unref (object);
3199
 
-               object = NULL;
3200
 
-       }
3201
 
-#endif
3202
 
-
3203
 
-       g_signal_connect (NM_DEVICE (object), "state-changed",
3204
 
-                         G_CALLBACK (device_state_changed), NM_CDMA_DEVICE (object));
3205
 
-
3206
 
-       return object;
3207
 
-}
3208
 
-
3209
 
-static void
3210
 
-set_property (GObject *object, guint prop_id,
3211
 
-                   const GValue *value, GParamSpec *pspec)
3212
 
-{
3213
 
-       NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object);
3214
 
-
3215
 
-       switch (prop_id) {
3216
 
-       case PROP_MONITOR_IFACE:
3217
 
-               /* Construct only */
3218
 
-               priv->monitor_iface = g_value_dup_string (value);
3219
 
-               break;
3220
 
-       default:
3221
 
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3222
 
-               break;
3223
 
-       }
3224
 
-}
3225
 
-
3226
 
-static void
3227
 
-get_property (GObject *object, guint prop_id,
3228
 
-                   GValue *value, GParamSpec *pspec)
3229
 
-{
3230
 
-       NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object);
3231
 
-
3232
 
-       switch (prop_id) {
3233
 
-       case PROP_MONITOR_IFACE:
3234
 
-               g_value_set_string (value, priv->monitor_iface);
3235
 
-               break;
3236
 
-       default:
3237
 
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3238
 
-               break;
3239
 
-       }
3240
 
-}
3241
 
-
3242
 
-static void
3243
 
-finalize (GObject *object)
3244
 
-{
3245
 
-       NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object);
3246
 
-
3247
 
-       if (priv->monitor_device)
3248
 
-               g_object_unref (priv->monitor_device);
3249
 
-
3250
 
-       g_free (priv->monitor_iface);
3251
 
-
3252
 
-       if (priv->state_to_disconnected_id) {
3253
 
-               g_source_remove (priv->state_to_disconnected_id);
3254
 
-               priv->state_to_disconnected_id = 0;
3255
 
-       }
3256
 
-
3257
 
-       G_OBJECT_CLASS (nm_cdma_device_parent_class)->finalize (object);
3258
 
-}
3259
 
-
3260
 
-static void
3261
 
-nm_cdma_device_class_init (NMCdmaDeviceClass *klass)
3262
 
-{
3263
 
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
3264
 
-       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
3265
 
-       NMSerialDeviceClass *serial_class = NM_SERIAL_DEVICE_CLASS (klass);
3266
 
-
3267
 
-       g_type_class_add_private (object_class, sizeof (NMCdmaDevicePrivate));
3268
 
-
3269
 
-       object_class->constructor = constructor;
3270
 
-       object_class->get_property = get_property;
3271
 
-       object_class->set_property = set_property;
3272
 
-       object_class->finalize = finalize;
3273
 
-
3274
 
-       device_class->get_best_auto_connection = real_get_best_auto_connection;
3275
 
-       device_class->get_generic_capabilities = real_get_generic_capabilities;
3276
 
-       device_class->act_stage1_prepare = real_act_stage1_prepare;
3277
 
-       device_class->connection_secrets_updated = real_connection_secrets_updated;
3278
 
-
3279
 
-       serial_class->get_ppp_name = real_get_ppp_name;
3280
 
-
3281
 
-       /* Properties */
3282
 
-       g_object_class_install_property
3283
 
-               (object_class, PROP_MONITOR_IFACE,
3284
 
-                g_param_spec_string (NM_CDMA_DEVICE_MONITOR_IFACE,
3285
 
-                                                 "Monitoring interface",
3286
 
-                                                 "Monitoring interface",
3287
 
-                                                 NULL,
3288
 
-                                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
3289
 
-
3290
 
-       /* Signals */
3291
 
-       signals[PROPERTIES_CHANGED] = 
3292
 
-               nm_properties_changed_signal_new (object_class,
3293
 
-                                                                   G_STRUCT_OFFSET (NMCdmaDeviceClass, properties_changed));
3294
 
-
3295
 
-       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
3296
 
-                                                                        &dbus_glib_nm_cdma_device_object_info);
3297
 
-}
3298
 
diff --git a/src/nm-cdma-device.h b/src/nm-cdma-device.h
3299
 
deleted file mode 100644
3300
 
index 50c44a3..0000000
3301
 
--- a/src/nm-cdma-device.h
3302
 
+++ /dev/null
3303
 
@@ -1,59 +0,0 @@
3304
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3305
 
-/* NetworkManager -- Network link manager
3306
 
- *
3307
 
- * This program is free software; you can redistribute it and/or modify
3308
 
- * it under the terms of the GNU General Public License as published by
3309
 
- * the Free Software Foundation; either version 2 of the License, or
3310
 
- * (at your option) any later version.
3311
 
- *
3312
 
- * This program is distributed in the hope that it will be useful,
3313
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3314
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3315
 
- * GNU General Public License for more details.
3316
 
- *
3317
 
- * You should have received a copy of the GNU General Public License along
3318
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
3319
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3320
 
- *
3321
 
- * Copyright (C) 2008 Red Hat, Inc.
3322
 
- * Copyright (C) 2008 Novell, Inc.
3323
 
- */
3324
 
-
3325
 
-#ifndef NM_CDMA_DEVICE_H
3326
 
-#define NM_CDMA_DEVICE_H
3327
 
-
3328
 
-#include <nm-serial-device.h>
3329
 
-
3330
 
-G_BEGIN_DECLS
3331
 
-
3332
 
-#define NM_TYPE_CDMA_DEVICE                    (nm_cdma_device_get_type ())
3333
 
-#define NM_CDMA_DEVICE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CDMA_DEVICE, NMCdmaDevice))
3334
 
-#define NM_CDMA_DEVICE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_CDMA_DEVICE, NMCdmaDeviceClass))
3335
 
-#define NM_IS_CDMA_DEVICE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CDMA_DEVICE))
3336
 
-#define NM_IS_CDMA_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_CDMA_DEVICE))
3337
 
-#define NM_CDMA_DEVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_CDMA_DEVICE, NMCdmaDeviceClass))
3338
 
-
3339
 
-#define NM_CDMA_DEVICE_MONITOR_IFACE "monitor-iface"
3340
 
-
3341
 
-typedef struct {
3342
 
-       NMSerialDevice parent;
3343
 
-} NMCdmaDevice;
3344
 
-
3345
 
-typedef struct {
3346
 
-       NMSerialDeviceClass parent;
3347
 
-
3348
 
-       /* Signals */
3349
 
-       void (*properties_changed) (NMCdmaDevice *device, GHashTable *properties);
3350
 
-} NMCdmaDeviceClass;
3351
 
-
3352
 
-GType nm_cdma_device_get_type (void);
3353
 
-
3354
 
-NMCdmaDevice *nm_cdma_device_new (const char *udi,
3355
 
-                                  const char *data_iface,
3356
 
-                                  const char *monitor_iface,
3357
 
-                                  const char *driver,
3358
 
-                                  gboolean managed);
3359
 
-
3360
 
-G_END_DECLS
3361
 
-
3362
 
-#endif /* NM_CDMA_DEVICE_H */
3363
 
diff --git a/src/nm-hal-manager.c b/src/nm-hal-manager.c
3364
 
index 2a97e59..b1f97ff 100644
3365
 
--- a/src/nm-hal-manager.c
3366
 
+++ b/src/nm-hal-manager.c
3367
 
@@ -32,9 +32,6 @@
3368
 
 #include "nm-utils.h"
3369
 
 #include "nm-device-wifi.h"
3370
 
 #include "nm-device-ethernet.h"
3371
 
-#include "nm-gsm-device.h"
3372
 
-#include "nm-hso-gsm-device.h"
3373
 
-#include "nm-cdma-device.h"
3374
 
 
3375
 
 /* Killswitch poll frequency in seconds */
3376
 
 #define RFKILL_POLL_FREQUENCY 6
3377
 
@@ -219,145 +216,6 @@ wireless_device_creator (NMHalManager *self, const char *udi, gboolean managed)
3378
 
        return device;
3379
 
 }
3380
 
 
3381
 
-/* Modem device creator */
3382
 
-
3383
 
-static gboolean
3384
 
-is_modem_device (NMHalManager *self, const char *udi)
3385
 
-{
3386
 
-       NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
3387
 
-       gboolean is_modem = FALSE;
3388
 
-
3389
 
-       if (libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) {
3390
 
-               char *category;
3391
 
-
3392
 
-               category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL);
3393
 
-               if (category) {
3394
 
-                       is_modem = strcmp (category, "serial") == 0;
3395
 
-                       libhal_free_string (category);
3396
 
-               }
3397
 
-       }
3398
 
-
3399
 
-       return is_modem;
3400
 
-}
3401
 
-
3402
 
-static char *
3403
 
-get_hso_netdev (LibHalContext *ctx, const char *udi)
3404
 
-{
3405
 
-       char *serial_parent, *netdev = NULL;
3406
 
-       char **netdevs;
3407
 
-       int num, i;
3408
 
-
3409
 
-       /* Get the serial interface's originating device UDI, used to find the
3410
 
-        * originating device's netdev.
3411
 
-        */
3412
 
-       serial_parent = libhal_device_get_property_string (ctx, udi, "serial.originating_device", NULL);
3413
 
-       if (!serial_parent)
3414
 
-               serial_parent = libhal_device_get_property_string (ctx, udi, "info.parent", NULL);
3415
 
-       if (!serial_parent)
3416
 
-               return NULL;
3417
 
-
3418
 
-       /* Look for the originating device's netdev */
3419
 
-       netdevs = libhal_find_device_by_capability (ctx, "net", &num, NULL);
3420
 
-       for (i = 0; netdevs && !netdev && (i < num); i++) {
3421
 
-               char *netdev_parent, *tmp;
3422
 
-
3423
 
-               netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.originating_device", NULL);
3424
 
-               if (!netdev_parent)
3425
 
-                       netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.physical_device", NULL);
3426
 
-               if (!netdev_parent)
3427
 
-                       continue;
3428
 
-
3429
 
-               if (!strcmp (netdev_parent, serial_parent)) {
3430
 
-                       /* We found it */
3431
 
-                       tmp = libhal_device_get_property_string (ctx, netdevs[i], "net.interface", NULL);
3432
 
-                       if (tmp) {
3433
 
-                               netdev = g_strdup (tmp);
3434
 
-                               libhal_free_string (tmp);
3435
 
-                       }
3436
 
-               }
3437
 
-
3438
 
-               libhal_free_string (netdev_parent);
3439
 
-       }
3440
 
-       libhal_free_string_array (netdevs);
3441
 
-       libhal_free_string (serial_parent);
3442
 
-
3443
 
-       return netdev;
3444
 
-}
3445
 
-
3446
 
-static GObject *
3447
 
-modem_device_creator (NMHalManager *self, const char *udi, gboolean managed)
3448
 
-{
3449
 
-       NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self);
3450
 
-       char *serial_device;
3451
 
-       char *parent_udi;
3452
 
-       char *driver_name = NULL;
3453
 
-       GObject *device = NULL;
3454
 
-       char **capabilities, **iter;
3455
 
-       gboolean type_gsm = FALSE;
3456
 
-       gboolean type_cdma = FALSE;
3457
 
-       char *netdev = NULL;
3458
 
-
3459
 
-       serial_device = libhal_device_get_property_string (priv->hal_ctx, udi, "serial.device", NULL);
3460
 
-
3461
 
-       /* Get the driver */
3462
 
-       parent_udi = libhal_device_get_property_string (priv->hal_ctx, udi, "info.parent", NULL);
3463
 
-       if (parent_udi) {
3464
 
-               driver_name = libhal_device_get_property_string (priv->hal_ctx, parent_udi, "info.linux.driver", NULL);
3465
 
-               libhal_free_string (parent_udi);
3466
 
-       }
3467
 
-
3468
 
-       if (!serial_device || !driver_name)
3469
 
-               goto out;
3470
 
-
3471
 
-       capabilities = libhal_device_get_property_strlist (priv->hal_ctx, udi, "modem.command_sets", NULL);
3472
 
-       /* 'capabilites' may be NULL */
3473
 
-       for (iter = capabilities; iter && *iter; iter++) {
3474
 
-               if (!strcmp (*iter, "GSM-07.07")) {
3475
 
-                       type_gsm = TRUE;
3476
 
-                       break;
3477
 
-               }
3478
 
-               if (!strcmp (*iter, "IS-707-A")) {
3479
 
-                       type_cdma = TRUE;
3480
 
-                       break;
3481
 
-               }
3482
 
-       }
3483
 
-       g_strfreev (capabilities);
3484
 
-
3485
 
-       /* Compatiblity with the pre-specification bits */
3486
 
-       if (!type_gsm && !type_cdma) {
3487
 
-               capabilities = libhal_device_get_property_strlist (priv->hal_ctx, udi, "info.capabilities", NULL);
3488
 
-               for (iter = capabilities; *iter; iter++) {
3489
 
-                       if (!strcmp (*iter, "gsm")) {
3490
 
-                               type_gsm = TRUE;
3491
 
-                               break;
3492
 
-                       }
3493
 
-                       if (!strcmp (*iter, "cdma")) {
3494
 
-                               type_cdma = TRUE;
3495
 
-                               break;
3496
 
-                       }
3497
 
-               }
3498
 
-               g_strfreev (capabilities);
3499
 
-       }
3500
 
-
3501
 
-       /* Special handling of 'hso' cards (until punted out to a modem manager) */
3502
 
-       if (type_gsm && !strcmp (driver_name, "hso"))
3503
 
-               netdev = get_hso_netdev (priv->hal_ctx, udi);
3504
 
-
3505
 
-       if (type_gsm) {
3506
 
-               if (netdev)
3507
 
-                       device = (GObject *) nm_hso_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, netdev, driver_name, managed);
3508
 
-               else
3509
 
-                       device = (GObject *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed);
3510
 
-       } else if (type_cdma)
3511
 
-               device = (GObject *) nm_cdma_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed);
3512
 
-
3513
 
-out:
3514
 
-       libhal_free_string (serial_device);
3515
 
-       libhal_free_string (driver_name);
3516
 
-
3517
 
-       return device;
3518
 
-}
3519
 
-
3520
 
 static void
3521
 
 register_built_in_creators (NMHalManager *self)
3522
 
 {
3523
 
@@ -379,14 +237,6 @@ register_built_in_creators (NMHalManager *self)
3524
 
        creator->is_device_fn = is_wireless_device;
3525
 
        creator->creator_fn = wireless_device_creator;
3526
 
        priv->device_creators = g_slist_append (priv->device_creators, creator);
3527
 
-
3528
 
-       /* Modem */
3529
 
-       creator = g_slice_new0 (DeviceCreator);
3530
 
-       creator->device_type_name = g_strdup ("Modem");
3531
 
-       creator->capability_str = g_strdup ("modem");
3532
 
-       creator->is_device_fn = is_modem_device;
3533
 
-       creator->creator_fn = modem_device_creator;
3534
 
-       priv->device_creators = g_slist_append (priv->device_creators, creator);
3535
 
 }
3536
 
 
3537
 
 static void
3538
 
diff --git a/src/nm-hso-gsm-device.c b/src/nm-hso-gsm-device.c
3539
 
deleted file mode 100644
3540
 
index 15032a3..0000000
3541
 
--- a/src/nm-hso-gsm-device.c
3542
 
+++ /dev/null
3543
 
@@ -1,593 +0,0 @@
3544
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3545
 
-/* NetworkManager -- Network link manager
3546
 
- *
3547
 
- * This program is free software; you can redistribute it and/or modify
3548
 
- * it under the terms of the GNU General Public License as published by
3549
 
- * the Free Software Foundation; either version 2 of the License, or
3550
 
- * (at your option) any later version.
3551
 
- *
3552
 
- * This program is distributed in the hope that it will be useful,
3553
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3554
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3555
 
- * GNU General Public License for more details.
3556
 
- *
3557
 
- * You should have received a copy of the GNU General Public License along
3558
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
3559
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3560
 
- *
3561
 
- * Copyright (C) 2008 Red Hat, Inc.
3562
 
- */
3563
 
-
3564
 
-#include <stdio.h>
3565
 
-#include <string.h>
3566
 
-#include <errno.h>
3567
 
-#include <stdlib.h>
3568
 
-#include <arpa/inet.h>
3569
 
-#include <dbus/dbus-glib.h>
3570
 
-
3571
 
-#include "nm-device.h"
3572
 
-#include "nm-hso-gsm-device.h"
3573
 
-#include "nm-gsm-device.h"
3574
 
-#include "nm-device-interface.h"
3575
 
-#include "nm-device-private.h"
3576
 
-#include "nm-setting-gsm.h"
3577
 
-#include "nm-utils.h"
3578
 
-#include "nm-properties-changed-signal.h"
3579
 
-#include "nm-setting-connection.h"
3580
 
-#include "NetworkManagerSystem.h"
3581
 
-
3582
 
-G_DEFINE_TYPE (NMHsoGsmDevice, nm_hso_gsm_device, NM_TYPE_GSM_DEVICE)
3583
 
-
3584
 
-#define NM_HSO_GSM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDevicePrivate))
3585
 
-
3586
 
-extern const DBusGObjectInfo dbus_glib_nm_gsm_device_object_info;
3587
 
-
3588
 
-#define GSM_CID "gsm-cid"
3589
 
-#define HSO_SECRETS_TRIES "gsm-secrets-tries"
3590
 
-
3591
 
-typedef struct {
3592
 
-       char *netdev_iface;
3593
 
-       NMIP4Config *pending_ip4_config;
3594
 
-} NMHsoGsmDevicePrivate;
3595
 
-
3596
 
-enum {
3597
 
-       PROP_0,
3598
 
-       PROP_NETDEV_IFACE,
3599
 
-
3600
 
-       LAST_PROP
3601
 
-};
3602
 
-
3603
 
-NMHsoGsmDevice *
3604
 
-nm_hso_gsm_device_new (const char *udi,
3605
 
-                       const char *data_iface,
3606
 
-                       const char *monitor_iface,
3607
 
-                       const char *netdev_iface,
3608
 
-                       const char *driver,
3609
 
-                       gboolean managed)
3610
 
-{
3611
 
-       g_return_val_if_fail (udi != NULL, NULL);
3612
 
-       g_return_val_if_fail (data_iface != NULL, NULL);
3613
 
-       g_return_val_if_fail (driver != NULL, NULL);
3614
 
-       g_return_val_if_fail (netdev_iface != NULL, NULL);
3615
 
-
3616
 
-       return (NMHsoGsmDevice *) g_object_new (NM_TYPE_HSO_GSM_DEVICE,
3617
 
-                                                                 NM_DEVICE_INTERFACE_UDI, udi,
3618
 
-                                                                 NM_DEVICE_INTERFACE_IFACE, data_iface,
3619
 
-                                                                 NM_DEVICE_INTERFACE_DRIVER, driver,
3620
 
-                                                                 NM_GSM_DEVICE_MONITOR_IFACE, monitor_iface,
3621
 
-                                                                 NM_HSO_GSM_DEVICE_NETDEV_IFACE, netdev_iface,
3622
 
-                                                                 NM_DEVICE_INTERFACE_MANAGED, managed,
3623
 
-                                                                 NULL);
3624
 
-}
3625
 
-
3626
 
-static void
3627
 
-modem_wait_for_reply (NMGsmDevice *self,
3628
 
-                      const char *command,
3629
 
-                      guint timeout,
3630
 
-                      const char **responses,
3631
 
-                      const char **terminators,
3632
 
-                      NMSerialWaitForReplyFn callback,
3633
 
-                      gpointer user_data)
3634
 
-{
3635
 
-       NMSerialDevice *serial = NM_SERIAL_DEVICE (self);
3636
 
-       guint id = 0;
3637
 
-
3638
 
-       if (nm_serial_device_send_command_string (serial, command))
3639
 
-               id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, user_data);
3640
 
-
3641
 
-       if (id == 0)
3642
 
-               nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
3643
 
-}
3644
 
-
3645
 
-static NMSetting *
3646
 
-gsm_device_get_setting (NMGsmDevice *device, GType setting_type)
3647
 
-{
3648
 
-       NMActRequest *req;
3649
 
-       NMSetting *setting = NULL;
3650
 
-
3651
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
3652
 
-       if (req) {
3653
 
-               NMConnection *connection;
3654
 
-
3655
 
-               connection = nm_act_request_get_connection (req);
3656
 
-               if (connection)
3657
 
-                       setting = nm_connection_get_setting (connection, setting_type);
3658
 
-       }
3659
 
-
3660
 
-       return setting;
3661
 
-}
3662
 
-
3663
 
-static void
3664
 
-hso_call_done (NMSerialDevice *device,
3665
 
-               int reply_index,
3666
 
-               const char *reply,
3667
 
-               gpointer user_data)
3668
 
-{
3669
 
-       gboolean success = FALSE;
3670
 
-
3671
 
-       switch (reply_index) {
3672
 
-       case 0:
3673
 
-               nm_info ("Connected, Woo!");
3674
 
-               success = TRUE;
3675
 
-               break;
3676
 
-       default:
3677
 
-               nm_warning ("Connect request failed");
3678
 
-               break;
3679
 
-       }
3680
 
-
3681
 
-       if (success)
3682
 
-               nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (device));
3683
 
-       else
3684
 
-               nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED);
3685
 
-}
3686
 
-
3687
 
-static void
3688
 
-hso_clear_done (NMSerialDevice *device,
3689
 
-                int reply_index,
3690
 
-                const char *reply,
3691
 
-                gpointer user_data)
3692
 
-{
3693
 
-       const char *responses[] = { "_OWANCALL: ", "ERROR", NULL };
3694
 
-       guint cid = GPOINTER_TO_UINT (user_data);
3695
 
-       char *command;
3696
 
-
3697
 
-       /* Try to connect */
3698
 
-       command = g_strdup_printf ("AT_OWANCALL=%d,1,1", cid);
3699
 
-       modem_wait_for_reply (NM_GSM_DEVICE (device), command, 10, responses, responses, hso_call_done, NULL);
3700
 
-       g_free (command);
3701
 
-}
3702
 
-
3703
 
-static void
3704
 
-hso_auth_done (NMSerialDevice *device,
3705
 
-               int reply_index,
3706
 
-               const char *reply,
3707
 
-               gpointer user_data)
3708
 
-{
3709
 
-       gboolean success = FALSE;
3710
 
-       const char *responses[] = { "_OWANCALL: ", "ERROR", "NO CARRIER", NULL };
3711
 
-       guint cid = GPOINTER_TO_UINT (user_data);
3712
 
-       char *command;
3713
 
-
3714
 
-       switch (reply_index) {
3715
 
-       case 0:
3716
 
-               nm_info ("Authentication successful!");
3717
 
-               success = TRUE;
3718
 
-               break;
3719
 
-       default:
3720
 
-               nm_warning ("Authentication failed");
3721
 
-               break;
3722
 
-       }
3723
 
-
3724
 
-       if (!success) {
3725
 
-               nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED);
3726
 
-               return;
3727
 
-       }
3728
 
-
3729
 
-       /* Kill any existing connection */
3730
 
-       command = g_strdup_printf ("AT_OWANCALL=%d,0,1", cid);
3731
 
-       modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, responses, hso_clear_done, GUINT_TO_POINTER (cid));
3732
 
-       g_free (command);
3733
 
-}
3734
 
-
3735
 
-static void
3736
 
-do_hso_auth (NMHsoGsmDevice *device)
3737
 
-{
3738
 
-       NMSettingGsm *s_gsm;
3739
 
-       NMActRequest *req;
3740
 
-       const char *responses[] = { "OK", "ERROR", "ERR", NULL };
3741
 
-       char *command;
3742
 
-       const char *gsm_username;
3743
 
-       const char *gsm_password;
3744
 
-       guint cid;
3745
 
-
3746
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
3747
 
-       g_assert (req);
3748
 
-
3749
 
-       cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID));
3750
 
-
3751
 
-       s_gsm = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM));
3752
 
-
3753
 
-       gsm_username = nm_setting_gsm_get_username (s_gsm);
3754
 
-       gsm_password = nm_setting_gsm_get_password (s_gsm);
3755
 
-
3756
 
-       command = g_strdup_printf ("AT$QCPDPP=%d,1,\"%s\",\"%s\"",
3757
 
-                                  cid,
3758
 
-                                  gsm_password ? gsm_password : "",
3759
 
-                                  gsm_username ? gsm_username : "");
3760
 
-       modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, responses, hso_auth_done, GUINT_TO_POINTER (cid));
3761
 
-       g_free (command);
3762
 
-}
3763
 
-
3764
 
-static NMActStageReturn
3765
 
-real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
3766
 
-{
3767
 
-       NMActRequest *req;
3768
 
-       NMConnection *connection;
3769
 
-       const char *setting_name;
3770
 
-       GPtrArray *hints = NULL;
3771
 
-       const char *hint1 = NULL, *hint2 = NULL;
3772
 
-       guint32 tries;
3773
 
-
3774
 
-       req = nm_device_get_act_request (device);
3775
 
-       g_assert (req);
3776
 
-       connection = nm_act_request_get_connection (req);
3777
 
-       g_assert (connection);
3778
 
-
3779
 
-       setting_name = nm_connection_need_secrets (connection, &hints);
3780
 
-       if (!setting_name) {
3781
 
-               do_hso_auth (NM_HSO_GSM_DEVICE (device));
3782
 
-               return NM_ACT_STAGE_RETURN_POSTPONE;
3783
 
-       }
3784
 
-
3785
 
-       if (hints) {
3786
 
-               if (hints->len > 0)
3787
 
-                       hint1 = g_ptr_array_index (hints, 0);
3788
 
-               if (hints->len > 1)
3789
 
-                       hint2 = g_ptr_array_index (hints, 1);
3790
 
-       }
3791
 
-
3792
 
-       nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
3793
 
-
3794
 
-       tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), HSO_SECRETS_TRIES));
3795
 
-       nm_act_request_request_connection_secrets (req,
3796
 
-                                                  setting_name,
3797
 
-                                                  tries ? TRUE : FALSE,
3798
 
-                                                  SECRETS_CALLER_HSO_GSM,
3799
 
-                                                  hint1,
3800
 
-                                                  hint2);
3801
 
-       g_object_set_data (G_OBJECT (connection), HSO_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
3802
 
-
3803
 
-       if (hints)
3804
 
-               g_ptr_array_free (hints, TRUE);
3805
 
-
3806
 
-       return NM_ACT_STAGE_RETURN_POSTPONE;
3807
 
-}
3808
 
-
3809
 
-static void
3810
 
-real_do_dial (NMGsmDevice *device, guint cid)
3811
 
-{
3812
 
-       NMActRequest *req;
3813
 
-
3814
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
3815
 
-       g_assert (req);
3816
 
-       g_object_set_data (G_OBJECT (req), GSM_CID, GUINT_TO_POINTER (cid));
3817
 
-
3818
 
-       nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
3819
 
-}
3820
 
-
3821
 
-#define OWANDATA_TAG "_OWANDATA: "
3822
 
-
3823
 
-static void
3824
 
-hso_ip4_config_response (NMSerialDevice *device,
3825
 
-                         int reply_index,
3826
 
-                         const char *response,
3827
 
-                         gpointer user_data)
3828
 
-{
3829
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
3830
 
-       NMActRequest *req;
3831
 
-       char **items, **iter;
3832
 
-       guint cid, i;
3833
 
-       guint32 dns1 = 0, dns2 = 0, ip4_address = 0;
3834
 
-
3835
 
-       if (   (reply_index < 0)
3836
 
-           || !response
3837
 
-           || strncmp (response, OWANDATA_TAG, strlen (OWANDATA_TAG))) {
3838
 
-               nm_device_activate_schedule_stage4_ip_config_timeout (NM_DEVICE (device));
3839
 
-               return;
3840
 
-       }
3841
 
-
3842
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
3843
 
-       g_assert (req);
3844
 
-       cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID));
3845
 
-
3846
 
-       items = g_strsplit (response + strlen (OWANDATA_TAG), ", ", 0);
3847
 
-       for (iter = items, i = 0; *iter; iter++, i++) {
3848
 
-               if (i == 0) { /* CID */
3849
 
-                       long int tmp;
3850
 
-
3851
 
-                       errno = 0;
3852
 
-                       tmp = strtol (*iter, NULL, 10);
3853
 
-                       if (errno != 0 || tmp < 0 || (guint) tmp != cid) {
3854
 
-                               nm_warning ("%s: unknown CID in OWANDATA response (got %d, expected %d)",
3855
 
-                                           nm_device_get_iface (NM_DEVICE (device)),
3856
 
-                                           (guint) tmp, cid);
3857
 
-                               goto out;
3858
 
-                       }
3859
 
-               } else if (i == 1) { /* IP address */
3860
 
-                       if (inet_pton (AF_INET, *iter, &ip4_address) <= 0)
3861
 
-                               ip4_address = 0;
3862
 
-               } else if (i == 3) { /* DNS 1 */
3863
 
-                       if (inet_pton (AF_INET, *iter, &dns1) <= 0)
3864
 
-                               dns1 = 0;
3865
 
-               } else if (i == 4) { /* DNS 2 */
3866
 
-                       if (inet_pton (AF_INET, *iter, &dns2) <= 0)
3867
 
-                               dns2 = 0;
3868
 
-               }
3869
 
-       }
3870
 
-
3871
 
-out:
3872
 
-       g_strfreev (items);
3873
 
-
3874
 
-       if (ip4_address) {
3875
 
-               NMIP4Address *addr;
3876
 
-
3877
 
-               priv->pending_ip4_config = nm_ip4_config_new ();
3878
 
-
3879
 
-               addr = nm_ip4_address_new ();
3880
 
-               nm_ip4_address_set_address (addr, ip4_address);
3881
 
-               nm_ip4_address_set_prefix (addr, 32);
3882
 
-
3883
 
-               nm_ip4_config_take_address (priv->pending_ip4_config, addr);
3884
 
-
3885
 
-               if (dns1)
3886
 
-                       nm_ip4_config_add_nameserver (priv->pending_ip4_config, dns1);
3887
 
-               if (dns2)
3888
 
-                       nm_ip4_config_add_nameserver (priv->pending_ip4_config, dns2);
3889
 
-
3890
 
-               nm_device_activate_schedule_stage4_ip_config_get (NM_DEVICE (device));
3891
 
-       } else {
3892
 
-               nm_device_state_changed (NM_DEVICE (device),
3893
 
-                                        NM_DEVICE_STATE_FAILED,
3894
 
-                                        NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
3895
 
-       }
3896
 
-}
3897
 
-
3898
 
-static NMActStageReturn
3899
 
-real_act_stage3_ip_config_start (NMDevice *device, NMDeviceStateReason *reason)
3900
 
-{
3901
 
-       NMActRequest *req;
3902
 
-       char *command;
3903
 
-       gint cid;
3904
 
-       const char *responses[] = { "_OWANDATA: ", NULL };
3905
 
-       const char *terminators[] = { "OK", "ERROR", "ERR", NULL };
3906
 
-
3907
 
-       req = nm_device_get_act_request (device);
3908
 
-       g_assert (req);
3909
 
-
3910
 
-       cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID));
3911
 
-       command = g_strdup_printf ("AT_OWANDATA=%d", cid);
3912
 
-       modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, terminators, hso_ip4_config_response, NULL);
3913
 
-       g_free (command);
3914
 
-
3915
 
-       return NM_ACT_STAGE_RETURN_POSTPONE;
3916
 
-}
3917
 
-
3918
 
-static NMActStageReturn
3919
 
-real_act_stage4_get_ip4_config (NMDevice *device,
3920
 
-                                NMIP4Config **config,
3921
 
-                                NMDeviceStateReason *reason)
3922
 
-{
3923
 
-       NMHsoGsmDevice *self = NM_HSO_GSM_DEVICE (device);
3924
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (self);
3925
 
-       gboolean no_firmware = FALSE;
3926
 
-
3927
 
-       g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
3928
 
-       g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
3929
 
-
3930
 
-       nm_device_set_ip_iface (device, priv->netdev_iface);
3931
 
-       if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) {
3932
 
-               if (no_firmware)
3933
 
-                       *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING;
3934
 
-               else
3935
 
-                       *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
3936
 
-               return NM_ACT_STAGE_RETURN_FAILURE;
3937
 
-       }
3938
 
-
3939
 
-       *config = priv->pending_ip4_config;
3940
 
-       priv->pending_ip4_config = NULL;
3941
 
-       return NM_ACT_STAGE_RETURN_SUCCESS;
3942
 
-}
3943
 
-
3944
 
-static void
3945
 
-real_connection_secrets_updated (NMDevice *device,
3946
 
-                                 NMConnection *connection,
3947
 
-                                 GSList *updated_settings,
3948
 
-                                 RequestSecretsCaller caller)
3949
 
-{
3950
 
-       g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
3951
 
-
3952
 
-       if (caller == SECRETS_CALLER_HSO_GSM)  { /* HSO PPP auth */
3953
 
-               nm_device_activate_schedule_stage2_device_config (device);
3954
 
-               return;
3955
 
-       }
3956
 
-
3957
 
-       /* Let parent handle other auth like PIN/PUK */
3958
 
-       NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->connection_secrets_updated (device, connection, updated_settings, caller);
3959
 
-}
3960
 
-
3961
 
-static void
3962
 
-real_deactivate_quickly (NMDevice *device)
3963
 
-{
3964
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
3965
 
-       NMActRequest *req;
3966
 
-       guint cid;
3967
 
-       char *command;
3968
 
-
3969
 
-       if (priv->pending_ip4_config) {
3970
 
-               g_object_unref (priv->pending_ip4_config);
3971
 
-               priv->pending_ip4_config = NULL;
3972
 
-       }
3973
 
-
3974
 
-       /* Don't leave the modem connected */
3975
 
-       req = nm_device_get_act_request (device);
3976
 
-       if (req) {
3977
 
-               cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID));
3978
 
-               if (cid) {
3979
 
-                       const char *responses[] = { "OK", "ERROR", "ERR", NULL };
3980
 
-                       int reply;
3981
 
-
3982
 
-                       /* Disconnect and disable asynchonous notification to keep serial
3983
 
-                        * buffer empty after the OK.
3984
 
-                        */
3985
 
-                       command = g_strdup_printf ("AT_OWANCALL=%d,0,0", cid);
3986
 
-                       nm_serial_device_send_command_string (NM_SERIAL_DEVICE (device), command);
3987
 
-                       reply = nm_serial_device_wait_reply_blocking (NM_SERIAL_DEVICE (device), 5, responses, responses);
3988
 
-                       g_free (command);
3989
 
-               }
3990
 
-       }
3991
 
-
3992
 
-       if (NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate_quickly)
3993
 
-               NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate_quickly (device);
3994
 
-}
3995
 
-
3996
 
-static void
3997
 
-real_deactivate (NMDevice *device)
3998
 
-{
3999
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
4000
 
-
4001
 
-       if (priv->netdev_iface) {
4002
 
-               nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface);
4003
 
-               nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface);
4004
 
-               nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL);
4005
 
-       }
4006
 
-       nm_device_set_ip_iface (device, NULL);
4007
 
-
4008
 
-       if (NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate)
4009
 
-               NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate (device);
4010
 
-}
4011
 
-
4012
 
-static gboolean
4013
 
-real_hw_is_up (NMDevice *device)
4014
 
-{
4015
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
4016
 
-       NMDeviceState state;
4017
 
-
4018
 
-       state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
4019
 
-
4020
 
-       if (   priv->pending_ip4_config
4021
 
-           || (state == NM_DEVICE_STATE_IP_CONFIG)
4022
 
-           || (state == NM_DEVICE_STATE_ACTIVATED))
4023
 
-               return nm_system_device_is_up_with_iface (priv->netdev_iface);
4024
 
-
4025
 
-       return TRUE;
4026
 
-}
4027
 
-
4028
 
-static gboolean
4029
 
-real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
4030
 
-{
4031
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
4032
 
-       NMDeviceState state;
4033
 
-
4034
 
-       state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
4035
 
-
4036
 
-       if (   priv->pending_ip4_config
4037
 
-           || (state == NM_DEVICE_STATE_IP_CONFIG)
4038
 
-           || (state == NM_DEVICE_STATE_ACTIVATED))
4039
 
-               return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware);
4040
 
-
4041
 
-       return TRUE;
4042
 
-}
4043
 
-
4044
 
-static void
4045
 
-nm_hso_gsm_device_init (NMHsoGsmDevice *self)
4046
 
-{
4047
 
-}
4048
 
-
4049
 
-static GObject*
4050
 
-constructor (GType type,
4051
 
-             guint n_params,
4052
 
-             GObjectConstructParam *params)
4053
 
-{
4054
 
-       return G_OBJECT_CLASS (nm_hso_gsm_device_parent_class)->constructor (type, n_params, params);
4055
 
-}
4056
 
-
4057
 
-static void
4058
 
-set_property (GObject *object, guint prop_id,
4059
 
-                   const GValue *value, GParamSpec *pspec)
4060
 
-{
4061
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object);
4062
 
-
4063
 
-       switch (prop_id) {
4064
 
-       case PROP_NETDEV_IFACE:
4065
 
-               /* Construct only */
4066
 
-               priv->netdev_iface = g_value_dup_string (value);
4067
 
-               break;
4068
 
-       default:
4069
 
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4070
 
-               break;
4071
 
-       }
4072
 
-}
4073
 
-
4074
 
-static void
4075
 
-get_property (GObject *object, guint prop_id,
4076
 
-                   GValue *value, GParamSpec *pspec)
4077
 
-{
4078
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object);
4079
 
-
4080
 
-       switch (prop_id) {
4081
 
-       case PROP_NETDEV_IFACE:
4082
 
-               g_value_set_string (value, priv->netdev_iface);
4083
 
-               break;
4084
 
-       default:
4085
 
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4086
 
-               break;
4087
 
-       }
4088
 
-}
4089
 
-
4090
 
-static void
4091
 
-finalize (GObject *object)
4092
 
-{
4093
 
-       NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object);
4094
 
-
4095
 
-       g_free (priv->netdev_iface);
4096
 
-
4097
 
-       G_OBJECT_CLASS (nm_hso_gsm_device_parent_class)->finalize (object);
4098
 
-}
4099
 
-
4100
 
-static void
4101
 
-nm_hso_gsm_device_class_init (NMHsoGsmDeviceClass *klass)
4102
 
-{
4103
 
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
4104
 
-       NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
4105
 
-       NMGsmDeviceClass *gsm_class = NM_GSM_DEVICE_CLASS (klass);
4106
 
-
4107
 
-       g_type_class_add_private (object_class, sizeof (NMHsoGsmDevicePrivate));
4108
 
-
4109
 
-       object_class->constructor = constructor;
4110
 
-       object_class->get_property = get_property;
4111
 
-       object_class->set_property = set_property;
4112
 
-       object_class->finalize = finalize;
4113
 
-
4114
 
-       device_class->act_stage2_config = real_act_stage2_config;
4115
 
-       device_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start;
4116
 
-       device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
4117
 
-       device_class->connection_secrets_updated = real_connection_secrets_updated;
4118
 
-       device_class->deactivate_quickly = real_deactivate_quickly;
4119
 
-       device_class->deactivate = real_deactivate;
4120
 
-       device_class->hw_is_up = real_hw_is_up;
4121
 
-       device_class->hw_bring_up = real_hw_bring_up;
4122
 
-
4123
 
-       gsm_class->do_dial = real_do_dial;
4124
 
-
4125
 
-       /* Properties */
4126
 
-       g_object_class_install_property
4127
 
-               (object_class, PROP_NETDEV_IFACE,
4128
 
-                g_param_spec_string (NM_HSO_GSM_DEVICE_NETDEV_IFACE,
4129
 
-                                                 "Network interface",
4130
 
-                                                 "Network interface",
4131
 
-                                                 NULL,
4132
 
-                                                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
4133
 
-
4134
 
-       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
4135
 
-                                                                        &dbus_glib_nm_gsm_device_object_info);
4136
 
-}
4137
 
diff --git a/src/nm-hso-gsm-device.h b/src/nm-hso-gsm-device.h
4138
 
deleted file mode 100644
4139
 
index 5b6b48a..0000000
4140
 
--- a/src/nm-hso-gsm-device.h
4141
 
+++ /dev/null
4142
 
@@ -1,56 +0,0 @@
4143
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4144
 
-/* NetworkManager -- Network link manager
4145
 
- *
4146
 
- * This program is free software; you can redistribute it and/or modify
4147
 
- * it under the terms of the GNU General Public License as published by
4148
 
- * the Free Software Foundation; either version 2 of the License, or
4149
 
- * (at your option) any later version.
4150
 
- *
4151
 
- * This program is distributed in the hope that it will be useful,
4152
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4153
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4154
 
- * GNU General Public License for more details.
4155
 
- *
4156
 
- * You should have received a copy of the GNU General Public License along
4157
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
4158
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4159
 
- *
4160
 
- * Copyright (C) 2008 Red Hat, Inc.
4161
 
- */
4162
 
-
4163
 
-#ifndef NM_HSO_GSM_DEVICE_H
4164
 
-#define NM_HSO_GSM_DEVICE_H
4165
 
-
4166
 
-#include <nm-gsm-device.h>
4167
 
-
4168
 
-G_BEGIN_DECLS
4169
 
-
4170
 
-#define NM_TYPE_HSO_GSM_DEVICE                         (nm_hso_gsm_device_get_type ())
4171
 
-#define NM_HSO_GSM_DEVICE(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDevice))
4172
 
-#define NM_HSO_GSM_DEVICE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDeviceClass))
4173
 
-#define NM_IS_HSO_GSM_DEVICE(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HSO_GSM_DEVICE))
4174
 
-#define NM_IS_HSO_GSM_DEVICE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_HSO_GSM_DEVICE))
4175
 
-#define NM_HSO_GSM_DEVICE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDeviceClass))
4176
 
-
4177
 
-#define NM_HSO_GSM_DEVICE_NETDEV_IFACE "netdev-iface"
4178
 
-
4179
 
-typedef struct {
4180
 
-       NMGsmDevice parent;
4181
 
-} NMHsoGsmDevice;
4182
 
-
4183
 
-typedef struct {
4184
 
-       NMGsmDeviceClass parent;
4185
 
-} NMHsoGsmDeviceClass;
4186
 
-
4187
 
-GType nm_hso_gsm_device_get_type (void);
4188
 
-
4189
 
-NMHsoGsmDevice *nm_hso_gsm_device_new (const char *udi,
4190
 
-                                       const char *data_iface,
4191
 
-                                       const char *monitor_iface,
4192
 
-                                       const char *netdev_iface,
4193
 
-                                       const char *driver,
4194
 
-                                       gboolean managed);
4195
 
-
4196
 
-G_END_DECLS
4197
 
-
4198
 
-#endif /* NM_HSO_GSM_DEVICE_H */
4199
 
diff --git a/src/nm-manager.c b/src/nm-manager.c
4200
 
index e5ebdb2..d323ceb 100644
4201
 
--- a/src/nm-manager.c
4202
 
+++ b/src/nm-manager.c
4203
 
@@ -28,6 +28,7 @@
4204
 
 #include "nm-utils.h"
4205
 
 #include "nm-dbus-manager.h"
4206
 
 #include "nm-vpn-manager.h"
4207
 
+#include "nm-modem-manager.h"
4208
 
 #include "nm-device-interface.h"
4209
 
 #include "nm-device-private.h"
4210
 
 #include "nm-device-wifi.h"
4211
 
@@ -95,6 +96,10 @@ static void system_settings_properties_changed_cb (DBusGProxy *proxy,
4212
 
                                                    GHashTable *properties,
4213
 
                                                    gpointer user_data);
4214
 
 
4215
 
+static void add_device (NMManager *self, NMDevice *device, const char *type_name);
4216
 
+static void remove_one_device (NMManager *manager, NMDevice *device);
4217
 
+
4218
 
+
4219
 
 #define SSD_POKE_INTERVAL 120000
4220
 
 
4221
 
 typedef struct {
4222
 
@@ -133,6 +138,10 @@ typedef struct {
4223
 
        NMVPNManager *vpn_manager;
4224
 
        guint vpn_manager_id;
4225
 
 
4226
 
+       NMModemManager *modem_manager;
4227
 
+       guint modem_added_id;
4228
 
+       guint modem_removed_id;
4229
 
+
4230
 
        DBusGProxy *aipd_proxy;
4231
 
 
4232
 
        gboolean disposed;
4233
 
@@ -241,6 +250,36 @@ vpn_manager_connection_deactivated_cb (NMVPNManager *manager,
4234
 
 }
4235
 
 
4236
 
 static void
4237
 
+modem_added (NMModemManager *modem_manager,
4238
 
+                  NMDevice *modem,
4239
 
+                  gpointer user_data)
4240
 
+{
4241
 
+       NMDeviceType type;
4242
 
+       const char *type_name;
4243
 
+
4244
 
+       type = nm_device_get_device_type (NM_DEVICE (modem));
4245
 
+       if (type == NM_DEVICE_TYPE_GSM)
4246
 
+               type_name = "GSM modem";
4247
 
+       else if (type == NM_DEVICE_TYPE_CDMA)
4248
 
+               type_name = "CDMA modem";
4249
 
+       else
4250
 
+               type_name = "Unknown modem";
4251
 
+
4252
 
+       add_device (NM_MANAGER (user_data), NM_DEVICE (g_object_ref (modem)), type_name);
4253
 
+}
4254
 
+
4255
 
+static void
4256
 
+modem_removed (NMModemManager *modem_manager,
4257
 
+                       NMDevice *modem,
4258
 
+                       gpointer user_data)
4259
 
+{
4260
 
+       NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data);
4261
 
+
4262
 
+       remove_one_device (NM_MANAGER (user_data), modem);
4263
 
+       priv->devices = g_slist_remove (priv->devices, modem);
4264
 
+}
4265
 
+
4266
 
+static void
4267
 
 aipd_handle_event (DBusGProxy *proxy,
4268
 
                    const char *event,
4269
 
                    const char *iface,
4270
 
@@ -303,6 +342,12 @@ nm_manager_init (NMManager *manager)
4271
 
                                                        g_free,
4272
 
                                                        g_object_unref);
4273
 
 
4274
 
+       priv->modem_manager = nm_modem_manager_get ();
4275
 
+       priv->modem_added_id = g_signal_connect (priv->modem_manager, "device-added",
4276
 
+                                                                        G_CALLBACK (modem_added), manager);
4277
 
+       priv->modem_removed_id = g_signal_connect (priv->modem_manager, "device-removed",
4278
 
+                                                                          G_CALLBACK (modem_removed), manager);
4279
 
+
4280
 
        priv->vpn_manager = nm_vpn_manager_get ();
4281
 
        id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated",
4282
 
                               G_CALLBACK (vpn_manager_connection_deactivated_cb), manager);
4283
 
@@ -502,6 +547,16 @@ dispose (GObject *object)
4284
 
        }
4285
 
        g_object_unref (priv->vpn_manager);
4286
 
 
4287
 
+       if (priv->modem_added_id) {
4288
 
+               g_source_remove (priv->modem_added_id);
4289
 
+               priv->modem_added_id = 0;
4290
 
+       }
4291
 
+       if (priv->modem_removed_id) {
4292
 
+               g_source_remove (priv->modem_removed_id);
4293
 
+               priv->modem_removed_id = 0;
4294
 
+       }
4295
 
+       g_object_unref (priv->modem_manager);
4296
 
+
4297
 
        g_object_unref (priv->dbus_mgr);
4298
 
        g_object_unref (priv->hal_mgr);
4299
 
 
4300
 
@@ -1644,58 +1699,66 @@ next:
4301
 
 }
4302
 
 
4303
 
 static void
4304
 
-hal_manager_udi_added_cb (NMHalManager *hal_mgr,
4305
 
-                          const char *udi,
4306
 
-                          const char *type_name,
4307
 
-                          NMDeviceCreatorFn creator_fn,
4308
 
-                          gpointer user_data)
4309
 
+add_device (NMManager *self, NMDevice *device, const char *type_name)
4310
 
 {
4311
 
-       NMManager *self = NM_MANAGER (user_data);
4312
 
        NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4313
 
-       GObject *device;
4314
 
        const char *iface;
4315
 
 
4316
 
-       if (priv->sleeping)
4317
 
-               return;
4318
 
-
4319
 
-       /* Make sure the device is not already in the device list */
4320
 
-       if (nm_manager_get_device_by_udi (self, udi))
4321
 
-               return;
4322
 
-
4323
 
-       device = creator_fn (hal_mgr, udi, nm_manager_udi_is_managed (self, udi));
4324
 
-       if (!device)
4325
 
-               return;
4326
 
-
4327
 
        priv->devices = g_slist_append (priv->devices, device);
4328
 
 
4329
 
        g_signal_connect (device, "state-changed",
4330
 
-                                         G_CALLBACK (manager_device_state_changed),
4331
 
-                                         self);
4332
 
+                                  G_CALLBACK (manager_device_state_changed),
4333
 
+                                  self);
4334
 
 
4335
 
        /* Attach to the access-point-added signal so that the manager can fill
4336
 
         * non-SSID-broadcasting APs with an SSID.
4337
 
         */
4338
 
        if (NM_IS_DEVICE_WIFI (device)) {
4339
 
                g_signal_connect (device, "hidden-ap-found",
4340
 
-                                                 G_CALLBACK (manager_hidden_ap_found),
4341
 
-                                                 self);
4342
 
+                                          G_CALLBACK (manager_hidden_ap_found),
4343
 
+                                          self);
4344
 
 
4345
 
                /* Set initial rfkill state */
4346
 
                nm_device_wifi_set_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
4347
 
        }
4348
 
 
4349
 
-       iface = nm_device_get_iface (NM_DEVICE (device));
4350
 
+       iface = nm_device_get_iface (device);
4351
 
        nm_info ("Found new %s device '%s'.", type_name, iface);
4352
 
 
4353
 
        dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr),
4354
 
                                                                  nm_device_get_udi (NM_DEVICE (device)),
4355
 
-                                                                 device);
4356
 
-       nm_info ("(%s): exported as %s", iface, udi);
4357
 
+                                                                 G_OBJECT (device));
4358
 
+       nm_info ("(%s): exported as %s", iface, nm_device_get_udi (device));
4359
 
 
4360
 
        g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
4361
 
 }
4362
 
 
4363
 
 static void
4364
 
+hal_manager_udi_added_cb (NMHalManager *hal_mgr,
4365
 
+                          const char *udi,
4366
 
+                          const char *type_name,
4367
 
+                          NMDeviceCreatorFn creator_fn,
4368
 
+                          gpointer user_data)
4369
 
+{
4370
 
+       NMManager *self = NM_MANAGER (user_data);
4371
 
+       NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
4372
 
+       GObject *device;
4373
 
+
4374
 
+       if (priv->sleeping)
4375
 
+               return;
4376
 
+
4377
 
+       /* Make sure the device is not already in the device list */
4378
 
+       if (nm_manager_get_device_by_udi (self, udi))
4379
 
+               return;
4380
 
+
4381
 
+       device = creator_fn (hal_mgr, udi, nm_manager_udi_is_managed (self, udi));
4382
 
+       if (!device)
4383
 
+               return;
4384
 
+
4385
 
+       add_device (self, NM_DEVICE (device), type_name);
4386
 
+}
4387
 
+
4388
 
+static void
4389
 
 hal_manager_udi_removed_cb (NMHalManager *manager,
4390
 
                             const char *udi,
4391
 
                             gpointer user_data)
4392
 
diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c
4393
 
deleted file mode 100644
4394
 
index 184c67c..0000000
4395
 
--- a/src/nm-serial-device.c
4396
 
+++ /dev/null
4397
 
@@ -1,1178 +0,0 @@
4398
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4399
 
-/* NetworkManager -- Network link manager
4400
 
- *
4401
 
- * This program is free software; you can redistribute it and/or modify
4402
 
- * it under the terms of the GNU General Public License as published by
4403
 
- * the Free Software Foundation; either version 2 of the License, or
4404
 
- * (at your option) any later version.
4405
 
- *
4406
 
- * This program is distributed in the hope that it will be useful,
4407
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4408
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4409
 
- * GNU General Public License for more details.
4410
 
- *
4411
 
- * You should have received a copy of the GNU General Public License along
4412
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
4413
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4414
 
- *
4415
 
- * Copyright (C) 2007 - 2008 Novell, Inc.
4416
 
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
4417
 
- */
4418
 
-
4419
 
-#define _GNU_SOURCE  /* for strcasestr() */
4420
 
-
4421
 
-#include <termio.h>
4422
 
-#include <unistd.h>
4423
 
-#include <sys/types.h>
4424
 
-#include <sys/stat.h>
4425
 
-#include <fcntl.h>
4426
 
-#include <errno.h>
4427
 
-#include <sys/ioctl.h>
4428
 
-#include <string.h>
4429
 
-#include <stdlib.h>
4430
 
-#include <glib.h>
4431
 
-
4432
 
-#include "nm-serial-device.h"
4433
 
-#include "nm-device-interface.h"
4434
 
-#include "nm-device-private.h"
4435
 
-#include "ppp-manager/nm-ppp-manager.h"
4436
 
-#include "nm-setting-ppp.h"
4437
 
-#include "nm-marshal.h"
4438
 
-#include "nm-utils.h"
4439
 
-#include "nm-serial-device-glue.h"
4440
 
-#include "NetworkManagerUtils.h"
4441
 
-
4442
 
-static gboolean serial_debug = FALSE;
4443
 
-
4444
 
-#define SERIAL_BUF_SIZE 2048
4445
 
-
4446
 
-G_DEFINE_TYPE (NMSerialDevice, nm_serial_device, NM_TYPE_DEVICE)
4447
 
-
4448
 
-#define NM_SERIAL_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SERIAL_DEVICE, NMSerialDevicePrivate))
4449
 
-
4450
 
-typedef struct {
4451
 
-       int fd;
4452
 
-       GIOChannel *channel;
4453
 
-       NMPPPManager *ppp_manager;
4454
 
-       NMIP4Config  *pending_ip4_config;
4455
 
-       struct termios old_t;
4456
 
-
4457
 
-       guint pending_id;
4458
 
-       guint timeout_id;
4459
 
-
4460
 
-       /* PPP stats */
4461
 
-       guint32 in_bytes;
4462
 
-       guint32 out_bytes;
4463
 
-} NMSerialDevicePrivate;
4464
 
-
4465
 
-enum {
4466
 
-       PPP_STATS,
4467
 
-
4468
 
-       LAST_SIGNAL
4469
 
-};
4470
 
-
4471
 
-static guint signals[LAST_SIGNAL] = { 0 };
4472
 
-
4473
 
-static int
4474
 
-parse_baudrate (guint i)
4475
 
-{
4476
 
-       int speed;
4477
 
-
4478
 
-       switch (i) {
4479
 
-       case 0:
4480
 
-               speed = B0;
4481
 
-               break;
4482
 
-       case 50:
4483
 
-               speed = B50;
4484
 
-               break;
4485
 
-       case 75:
4486
 
-               speed = B75;
4487
 
-               break;
4488
 
-       case 110:
4489
 
-               speed = B110;
4490
 
-               break;
4491
 
-       case 150:
4492
 
-               speed = B150;
4493
 
-               break;
4494
 
-       case 300:
4495
 
-               speed = B300;
4496
 
-               break;
4497
 
-       case 600:
4498
 
-               speed = B600;
4499
 
-               break;
4500
 
-       case 1200:
4501
 
-               speed = B1200;
4502
 
-               break;
4503
 
-       case 2400:
4504
 
-               speed = B2400;
4505
 
-               break;
4506
 
-       case 4800:
4507
 
-               speed = B4800;
4508
 
-               break;
4509
 
-       case 9600:
4510
 
-               speed = B9600;
4511
 
-               break;
4512
 
-       case 19200:
4513
 
-               speed = B19200;
4514
 
-               break;
4515
 
-       case 38400:
4516
 
-               speed = B38400;
4517
 
-               break;
4518
 
-       case 57600:
4519
 
-               speed = B57600;
4520
 
-               break;
4521
 
-       case 115200:
4522
 
-               speed = B115200;
4523
 
-               break;
4524
 
-       case 460800:
4525
 
-               speed = B460800;
4526
 
-               break;
4527
 
-       default:
4528
 
-               g_warning ("Invalid baudrate '%d'", i);
4529
 
-               speed = B9600;
4530
 
-       }
4531
 
-
4532
 
-       return speed;
4533
 
-}
4534
 
-
4535
 
-static int
4536
 
-parse_bits (guint i)
4537
 
-{
4538
 
-       int bits;
4539
 
-
4540
 
-       switch (i) {
4541
 
-       case 5:
4542
 
-               bits = CS5;
4543
 
-               break;
4544
 
-       case 6:
4545
 
-               bits = CS6;
4546
 
-               break;
4547
 
-       case 7:
4548
 
-               bits = CS7;
4549
 
-               break;
4550
 
-       case 8:
4551
 
-               bits = CS8;
4552
 
-               break;
4553
 
-       default:
4554
 
-               g_warning ("Invalid bits (%d). Valid values are 5, 6, 7, 8.", i);
4555
 
-               bits = CS8;
4556
 
-       }
4557
 
-
4558
 
-       return bits;
4559
 
-}
4560
 
-
4561
 
-static int
4562
 
-parse_parity (char c)
4563
 
-{
4564
 
-       int parity;
4565
 
-
4566
 
-       switch (c) {
4567
 
-       case 'n':
4568
 
-       case 'N':
4569
 
-               parity = 0;
4570
 
-               break;
4571
 
-       case 'e':
4572
 
-       case 'E':
4573
 
-               parity = PARENB;
4574
 
-               break;
4575
 
-       case 'o':
4576
 
-       case 'O':
4577
 
-               parity = PARENB | PARODD;
4578
 
-               break;
4579
 
-       default:
4580
 
-               g_warning ("Invalid parity (%c). Valid values are n, e, o", c);
4581
 
-               parity = 0;
4582
 
-       }
4583
 
-
4584
 
-       return parity;
4585
 
-}
4586
 
-
4587
 
-static int
4588
 
-parse_stopbits (guint i)
4589
 
-{
4590
 
-       int stopbits;
4591
 
-
4592
 
-       switch (i) {
4593
 
-       case 1:
4594
 
-               stopbits = 0;
4595
 
-               break;
4596
 
-       case 2:
4597
 
-               stopbits = CSTOPB;
4598
 
-               break;
4599
 
-       default:
4600
 
-               g_warning ("Invalid stop bits (%d). Valid values are 1 and 2)", i);
4601
 
-               stopbits = 0;
4602
 
-       }
4603
 
-
4604
 
-       return stopbits;
4605
 
-}
4606
 
-
4607
 
-static inline void
4608
 
-nm_serial_debug (const char *prefix, const char *data, int len)
4609
 
-{
4610
 
-       GString *str;
4611
 
-       int i;
4612
 
-
4613
 
-       if (!serial_debug)
4614
 
-               return;
4615
 
-
4616
 
-       str = g_string_sized_new (len);
4617
 
-       for (i = 0; i < len; i++) {
4618
 
-               if (data[i] == '\0')
4619
 
-                       g_string_append_c (str, ' ');
4620
 
-               else if (data[i] == '\r')
4621
 
-                       g_string_append_c (str, '\n');
4622
 
-               else
4623
 
-                       g_string_append_c (str, data[i]);
4624
 
-       }
4625
 
-
4626
 
-       nm_debug ("%s '%s'", prefix, str->str);
4627
 
-       g_string_free (str, TRUE);
4628
 
-}
4629
 
-
4630
 
-static NMSetting *
4631
 
-serial_device_get_setting (NMSerialDevice *device, GType setting_type)
4632
 
-{
4633
 
-       NMActRequest *req;
4634
 
-       NMSetting *setting = NULL;
4635
 
-
4636
 
-       req = nm_device_get_act_request (NM_DEVICE (device));
4637
 
-       if (req) {
4638
 
-               NMConnection *connection;
4639
 
-
4640
 
-               connection = nm_act_request_get_connection (req);
4641
 
-               if (connection)
4642
 
-                       setting = nm_connection_get_setting (connection, setting_type);
4643
 
-       }
4644
 
-
4645
 
-       return setting;
4646
 
-}
4647
 
-
4648
 
-/* Timeout handling */
4649
 
-
4650
 
-static void
4651
 
-nm_serial_device_timeout_removed (gpointer data)
4652
 
-{
4653
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data);
4654
 
-
4655
 
-       priv->timeout_id = 0;
4656
 
-}
4657
 
-
4658
 
-static gboolean
4659
 
-nm_serial_device_timed_out (gpointer data)
4660
 
-{
4661
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data);
4662
 
-
4663
 
-       /* Cancel data reading */
4664
 
-       if (priv->pending_id)
4665
 
-               g_source_remove (priv->pending_id);
4666
 
-       else
4667
 
-               nm_warning ("Timeout reached, but there's nothing to time out");
4668
 
-
4669
 
-       return FALSE;
4670
 
-}
4671
 
-
4672
 
-static void
4673
 
-nm_serial_device_add_timeout (NMSerialDevice *self, guint timeout)
4674
 
-{
4675
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self);
4676
 
-
4677
 
-       if (priv->pending_id == 0)
4678
 
-               nm_warning ("Adding a time out while not waiting for any data");
4679
 
-
4680
 
-       if (priv->timeout_id) {
4681
 
-               nm_warning ("Trying to add a new time out while the old one still exists");
4682
 
-               g_source_remove (priv->timeout_id);
4683
 
-       }
4684
 
-
4685
 
-       priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
4686
 
-                                                                   timeout * 1000,
4687
 
-                                                                   nm_serial_device_timed_out,
4688
 
-                                                                   self,
4689
 
-                                                                   nm_serial_device_timeout_removed);
4690
 
-       if (G_UNLIKELY (priv->timeout_id == 0))
4691
 
-               nm_warning ("Registering serial device time out failed.");
4692
 
-}
4693
 
-
4694
 
-static void
4695
 
-nm_serial_device_remove_timeout (NMSerialDevice *self)
4696
 
-{
4697
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self);
4698
 
-
4699
 
-       if (priv->timeout_id)
4700
 
-               g_source_remove (priv->timeout_id);
4701
 
-}
4702
 
-
4703
 
-/* Pending data reading */
4704
 
-
4705
 
-static guint
4706
 
-nm_serial_device_set_pending (NMSerialDevice *device,
4707
 
-                                               guint timeout,
4708
 
-                                               GIOFunc callback,
4709
 
-                                               gpointer user_data,
4710
 
-                                               GDestroyNotify notify)
4711
 
-{
4712
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
4713
 
-
4714
 
-       if (G_UNLIKELY (priv->pending_id)) {
4715
 
-               /* FIXME: Probably should queue up pending calls instead? */
4716
 
-               /* Multiple pending calls on the same GIOChannel doesn't work, so let's cancel the previous one. */
4717
 
-               nm_warning ("Adding new pending call while previous one isn't finished.");
4718
 
-               nm_warning ("Cancelling the previous pending call.");
4719
 
-               g_source_remove (priv->pending_id);
4720
 
-       }
4721
 
-
4722
 
-       priv->pending_id = g_io_add_watch_full (priv->channel,
4723
 
-                                                                       G_PRIORITY_DEFAULT,
4724
 
-                                                                       G_IO_IN | G_IO_ERR | G_IO_HUP,
4725
 
-                                                                       callback, user_data, notify);
4726
 
-
4727
 
-       nm_serial_device_add_timeout (device, timeout);
4728
 
-
4729
 
-       return priv->pending_id;
4730
 
-}
4731
 
-
4732
 
-static void
4733
 
-nm_serial_device_pending_done (NMSerialDevice *self)
4734
 
-{
4735
 
-       NM_SERIAL_DEVICE_GET_PRIVATE (self)->pending_id = 0;
4736
 
-       nm_serial_device_remove_timeout (self);
4737
 
-}
4738
 
-
4739
 
-/****/
4740
 
-
4741
 
-static gboolean
4742
 
-config_fd (NMSerialDevice *device, NMSettingSerial *setting)
4743
 
-{
4744
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
4745
 
-       struct termio stbuf;
4746
 
-       int speed;
4747
 
-       int bits;
4748
 
-       int parity;
4749
 
-       int stopbits;
4750
 
-
4751
 
-       speed = parse_baudrate (nm_setting_serial_get_baud (setting));
4752
 
-       bits = parse_bits (nm_setting_serial_get_bits (setting));
4753
 
-       parity = parse_parity (nm_setting_serial_get_parity (setting));
4754
 
-       stopbits = parse_stopbits (nm_setting_serial_get_stopbits (setting));
4755
 
-
4756
 
-       ioctl (priv->fd, TCGETA, &stbuf);
4757
 
-
4758
 
-       stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR );
4759
 
-       stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
4760
 
-       stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
4761
 
-       stbuf.c_lflag &= ~(ECHO | ECHOE);
4762
 
-       stbuf.c_cc[VMIN] = 1;
4763
 
-       stbuf.c_cc[VTIME] = 0;
4764
 
-       stbuf.c_cc[VEOF] = 1;
4765
 
-
4766
 
-       stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
4767
 
-       stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity | stopbits);
4768
 
-
4769
 
-       if (ioctl (priv->fd, TCSETA, &stbuf) < 0) {
4770
 
-               nm_warning ("(%s) cannot control device (errno %d)",
4771
 
-                           nm_device_get_iface (NM_DEVICE (device)), errno);
4772
 
-               return FALSE;
4773
 
-       }
4774
 
-
4775
 
-       return TRUE;
4776
 
-}
4777
 
-
4778
 
-gboolean
4779
 
-nm_serial_device_open (NMSerialDevice *device,
4780
 
-                       NMSettingSerial *setting)
4781
 
-{
4782
 
-       NMSerialDevicePrivate *priv;
4783
 
-       const char *iface;
4784
 
-       char *path;
4785
 
-
4786
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE);
4787
 
-       g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), FALSE);
4788
 
-
4789
 
-       priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
4790
 
-       iface = nm_device_get_iface (NM_DEVICE (device));
4791
 
-
4792
 
-       nm_debug ("(%s) opening device...", iface);
4793
 
-
4794
 
-       path = g_build_filename ("/dev", iface, NULL);
4795
 
-       priv->fd = open (path, O_RDWR | O_EXCL | O_NONBLOCK | O_NOCTTY);
4796
 
-       g_free (path);
4797
 
-
4798
 
-       if (priv->fd < 0) {
4799
 
-               nm_warning ("(%s) cannot open device (errno %d)", iface, errno);
4800
 
-               return FALSE;
4801
 
-       }
4802
 
-
4803
 
-       if (ioctl (priv->fd, TCGETA, &priv->old_t) < 0) {
4804
 
-               nm_warning ("(%s) cannot control device (errno %d)", iface, errno);
4805
 
-               close (priv->fd);
4806
 
-               return FALSE;
4807
 
-       }
4808
 
-
4809
 
-       if (!config_fd (device, setting)) {
4810
 
-               close (priv->fd);
4811
 
-               return FALSE;
4812
 
-       }
4813
 
-
4814
 
-       priv->channel = g_io_channel_unix_new (priv->fd);
4815
 
-
4816
 
-       return TRUE;
4817
 
-}
4818
 
-
4819
 
-void
4820
 
-nm_serial_device_close (NMSerialDevice *device)
4821
 
-{
4822
 
-       NMSerialDevicePrivate *priv;
4823
 
-
4824
 
-       g_return_if_fail (NM_IS_SERIAL_DEVICE (device));
4825
 
-
4826
 
-       priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
4827
 
-
4828
 
-       if (priv->pending_id)
4829
 
-               g_source_remove (priv->pending_id);
4830
 
-
4831
 
-       if (priv->ppp_manager) {
4832
 
-               nm_ppp_manager_stop (priv->ppp_manager);
4833
 
-               g_object_unref (priv->ppp_manager);
4834
 
-               priv->ppp_manager = NULL;
4835
 
-       }
4836
 
-
4837
 
-       if (priv->fd) {
4838
 
-               nm_debug ("Closing device '%s'", nm_device_get_iface (NM_DEVICE (device)));
4839
 
-
4840
 
-               if (priv->channel) {
4841
 
-                       g_io_channel_unref (priv->channel);
4842
 
-                       priv->channel = NULL;
4843
 
-               }
4844
 
-
4845
 
-               ioctl (priv->fd, TCSETA, &priv->old_t);
4846
 
-               close (priv->fd);
4847
 
-               priv->fd = 0;
4848
 
-       }
4849
 
-}
4850
 
-
4851
 
-gboolean
4852
 
-nm_serial_device_send_command (NMSerialDevice *device, GByteArray *command)
4853
 
-{
4854
 
-       int fd;
4855
 
-       NMSettingSerial *setting;
4856
 
-       int i, eagain_count = 1000;
4857
 
-       ssize_t written;
4858
 
-       guint32 send_delay = 0;
4859
 
-
4860
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE);
4861
 
-       g_return_val_if_fail (command != NULL, FALSE);
4862
 
-
4863
 
-       fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd;
4864
 
-       setting = NM_SETTING_SERIAL (serial_device_get_setting (device, NM_TYPE_SETTING_SERIAL));
4865
 
-       if (setting)
4866
 
-               send_delay = nm_setting_serial_get_send_delay (setting);
4867
 
-       if (send_delay == 0)
4868
 
-               send_delay = G_USEC_PER_SEC / 1000;
4869
 
-
4870
 
-       nm_serial_debug ("Sending:", (char *) command->data, command->len);
4871
 
-
4872
 
-       for (i = 0; i < command->len && eagain_count > 0;) {
4873
 
-               written = write (fd, command->data + i, 1);
4874
 
-
4875
 
-               if (written > 0)
4876
 
-                       i += written;
4877
 
-               else {
4878
 
-                       /* Treat written == 0 as EAGAIN to ensure we break out of the
4879
 
-                        * for() loop eventually.
4880
 
-                        */
4881
 
-                       if ((written < 0) && (errno != EAGAIN)) {
4882
 
-                               g_warning ("Error in writing (errno %d)", errno);
4883
 
-                               return FALSE;
4884
 
-                       }
4885
 
-                       eagain_count--;
4886
 
-               }
4887
 
-               g_usleep (send_delay);
4888
 
-       }
4889
 
-
4890
 
-       if (eagain_count <= 0)
4891
 
-               nm_serial_debug ("Error: too many retries sending:", (char *) command->data, command->len);
4892
 
-
4893
 
-       return TRUE;
4894
 
-}
4895
 
-
4896
 
-gboolean
4897
 
-nm_serial_device_send_command_string (NMSerialDevice *device, const char *str)
4898
 
-{
4899
 
-       GByteArray *command;
4900
 
-       gboolean ret;
4901
 
-
4902
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE);
4903
 
-       g_return_val_if_fail (str != NULL, FALSE);
4904
 
-
4905
 
-       command = g_byte_array_new ();
4906
 
-       g_byte_array_append (command, (guint8 *) str, strlen (str));
4907
 
-       g_byte_array_append (command, (guint8 *) "\r", 1);
4908
 
-
4909
 
-       ret = nm_serial_device_send_command (device, command);
4910
 
-       g_byte_array_free (command, TRUE);
4911
 
-
4912
 
-       return ret;
4913
 
-}
4914
 
-
4915
 
-static gboolean
4916
 
-find_terminator (const char *line, const char **terminators)
4917
 
-{
4918
 
-       int i;
4919
 
-
4920
 
-       for (i = 0; terminators[i]; i++) {
4921
 
-               if (!strncasecmp (line, terminators[i], strlen (terminators[i])))
4922
 
-                       return TRUE;
4923
 
-       }
4924
 
-       return FALSE;
4925
 
-}
4926
 
-
4927
 
-static const char *
4928
 
-find_response (const char *line, const char **responses, gint *idx)
4929
 
-{
4930
 
-       int i;
4931
 
-
4932
 
-       /* Don't look for a result again if we got one previously */
4933
 
-       for (i = 0; responses[i]; i++) {
4934
 
-               if (strcasestr (line, responses[i])) {
4935
 
-                       *idx = i;
4936
 
-                       return line;
4937
 
-               }
4938
 
-       }
4939
 
-       return NULL;
4940
 
-}
4941
 
-
4942
 
-#define RESPONSE_LINE_MAX 128
4943
 
-
4944
 
-int
4945
 
-nm_serial_device_wait_reply_blocking (NMSerialDevice *device,
4946
 
-                                      guint32 timeout_secs,
4947
 
-                                      const char **needles,
4948
 
-                                      const char **terminators)
4949
 
-{
4950
 
-       char buf[SERIAL_BUF_SIZE + 1];
4951
 
-       int fd, reply_index = -1, bytes_read;
4952
 
-       GString *result = NULL;
4953
 
-       time_t end;
4954
 
-       const char *response = NULL;
4955
 
-       gboolean done = FALSE;
4956
 
-
4957
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), -1);
4958
 
-       g_return_val_if_fail (timeout_secs <= 60, -1);
4959
 
-       g_return_val_if_fail (needles != NULL, -1);
4960
 
-
4961
 
-       fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd;
4962
 
-       if (fd < 0)
4963
 
-               return -1;
4964
 
-
4965
 
-       end = time (NULL) + timeout_secs;
4966
 
-       result = g_string_sized_new (20);
4967
 
-       do {
4968
 
-               bytes_read = read (fd, buf, SERIAL_BUF_SIZE);
4969
 
-               if (bytes_read < 0 && errno != EAGAIN) {
4970
 
-                       nm_warning ("%s: read error: %d (%s)",
4971
 
-                                   nm_device_get_iface (NM_DEVICE (device)),
4972
 
-                                   errno,
4973
 
-                                   strerror (errno));
4974
 
-                       return -1;
4975
 
-               }
4976
 
-
4977
 
-               if (bytes_read == 0)
4978
 
-                       break; /* EOF */
4979
 
-               else if (bytes_read > 0) {
4980
 
-                       buf[bytes_read] = 0;
4981
 
-                       g_string_append (result, buf);
4982
 
-
4983
 
-                       nm_serial_debug ("Got:", result->str, result->len);
4984
 
-               }
4985
 
-
4986
 
-               /* Look for needles and terminators */
4987
 
-               if ((bytes_read > 0) && result->str) {
4988
 
-                       char *p = result->str;
4989
 
-
4990
 
-                       /* Break the response up into lines and process each one */
4991
 
-                       while ((p < result->str + strlen (result->str)) && !done) {
4992
 
-                               char line[RESPONSE_LINE_MAX] = { '\0', };
4993
 
-                               char *tmp;
4994
 
-                               int i;
4995
 
-                               gboolean got_something = FALSE;
4996
 
-
4997
 
-                               for (i = 0; *p && (i < RESPONSE_LINE_MAX - 1); p++) {
4998
 
-                                       /* Ignore front CR/LF */
4999
 
-                                       if ((*p == '\n') || (*p == '\r')) {
5000
 
-                                               if (got_something)
5001
 
-                                                       break;
5002
 
-                                       } else {
5003
 
-                                               line[i++] = *p;
5004
 
-                                               got_something = TRUE;
5005
 
-                                       }
5006
 
-                               }
5007
 
-                               line[i] = '\0';
5008
 
-
5009
 
-                               tmp = g_strstrip (line);
5010
 
-                               if (tmp && strlen (tmp)) {
5011
 
-                                       done = find_terminator (tmp, terminators);
5012
 
-                                       if (reply_index == -1)
5013
 
-                                               response = find_response (tmp, needles, &reply_index);
5014
 
-                               }
5015
 
-                       }
5016
 
-               }
5017
 
-
5018
 
-               /* Limit the size of the buffer */
5019
 
-               if (result->len > SERIAL_BUF_SIZE) {
5020
 
-                       g_warning ("%s (%s): response buffer filled before repsonse received",
5021
 
-                                  __func__, nm_device_get_iface (NM_DEVICE (device)));
5022
 
-                       break;
5023
 
-               }
5024
 
-
5025
 
-               if (!done)
5026
 
-                       g_usleep (100);
5027
 
-       } while (!done && (time (NULL) < end));
5028
 
-
5029
 
-       return reply_index;
5030
 
-}
5031
 
-
5032
 
-typedef struct {
5033
 
-       NMSerialDevice *device;
5034
 
-       char **str_needles;
5035
 
-       char **terminators;
5036
 
-       GString *result;
5037
 
-       NMSerialWaitForReplyFn callback;
5038
 
-       gpointer user_data;
5039
 
-       int reply_index;
5040
 
-       char *reply_line;
5041
 
-       time_t end;
5042
 
-} WaitForReplyInfo;
5043
 
-
5044
 
-static void
5045
 
-wait_for_reply_done (gpointer data)
5046
 
-{
5047
 
-       WaitForReplyInfo *info = (WaitForReplyInfo *) data;
5048
 
-
5049
 
-       nm_serial_device_pending_done (info->device);
5050
 
-
5051
 
-       /* Call the callback */
5052
 
-       info->callback (info->device, info->reply_index, info->reply_line, info->user_data);
5053
 
-
5054
 
-       /* Free info */
5055
 
-       if (info->result)
5056
 
-               g_string_free (info->result, TRUE);
5057
 
-
5058
 
-       g_free (info->reply_line);
5059
 
-
5060
 
-       g_strfreev (info->str_needles);
5061
 
-       g_strfreev (info->terminators);
5062
 
-       g_slice_free (WaitForReplyInfo, info);
5063
 
-}
5064
 
-
5065
 
-static gboolean
5066
 
-wait_for_reply_got_data (GIOChannel *source,
5067
 
-                                       GIOCondition condition,
5068
 
-                                       gpointer data)
5069
 
-{
5070
 
-       WaitForReplyInfo *info = (WaitForReplyInfo *) data;
5071
 
-       gchar buf[SERIAL_BUF_SIZE + 1];
5072
 
-       gsize bytes_read;
5073
 
-       GIOStatus status;
5074
 
-       gboolean done = FALSE;
5075
 
-
5076
 
-       if (condition & G_IO_HUP || condition & G_IO_ERR)
5077
 
-               return FALSE;
5078
 
-
5079
 
-       do {
5080
 
-               GError *err = NULL;
5081
 
-
5082
 
-               status = g_io_channel_read_chars (source, buf, SERIAL_BUF_SIZE, &bytes_read, &err);
5083
 
-               if (status == G_IO_STATUS_ERROR) {
5084
 
-                       g_warning ("%s", err->message);
5085
 
-                       g_error_free (err);
5086
 
-                       err = NULL;
5087
 
-               }
5088
 
-
5089
 
-               if (bytes_read > 0) {
5090
 
-                       buf[bytes_read] = 0;
5091
 
-                       g_string_append (info->result, buf);
5092
 
-
5093
 
-                       nm_serial_debug ("Got:", info->result->str, info->result->len);
5094
 
-               }
5095
 
-
5096
 
-               /* Look for needles and terminators */
5097
 
-               if ((bytes_read > 0) && info->result->str) {
5098
 
-                       char *p = info->result->str;
5099
 
-
5100
 
-                       /* Break the response up into lines and process each one */
5101
 
-                       while ((p < info->result->str + strlen (info->result->str)) && !done) {
5102
 
-                               char line[RESPONSE_LINE_MAX] = { '\0', };
5103
 
-                               char *tmp;
5104
 
-                               int i;
5105
 
-                               gboolean got_something = FALSE;
5106
 
-
5107
 
-                               for (i = 0; *p && (i < RESPONSE_LINE_MAX - 1); p++) {
5108
 
-                                       /* Ignore front CR/LF */
5109
 
-                                       if ((*p == '\n') || (*p == '\r')) {
5110
 
-                                               if (got_something)
5111
 
-                                                       break;
5112
 
-                                       } else {
5113
 
-                                               line[i++] = *p;
5114
 
-                                               got_something = TRUE;
5115
 
-                                       }
5116
 
-                               }
5117
 
-                               line[i] = '\0';
5118
 
-
5119
 
-                               tmp = g_strstrip (line);
5120
 
-                               if (tmp && strlen (tmp)) {
5121
 
-                                       done = find_terminator (tmp, (const char **) info->terminators);
5122
 
-                                       if (info->reply_index == -1) {
5123
 
-                                               if (find_response (tmp, (const char **) info->str_needles, &(info->reply_index)))
5124
 
-                                                       info->reply_line = g_strdup (tmp);
5125
 
-                                       }
5126
 
-                               }
5127
 
-                       }
5128
 
-               }
5129
 
-
5130
 
-               /* Limit the size of the buffer */
5131
 
-               if (info->result->len > SERIAL_BUF_SIZE) {
5132
 
-                       nm_warning ("(%s): response buffer filled before repsonse received",
5133
 
-                                   nm_device_get_iface (NM_DEVICE (info->device)));
5134
 
-                       done = TRUE;
5135
 
-                       break;
5136
 
-               }
5137
 
-
5138
 
-               /* Make sure we don't go over the timeout, in addition to the timeout
5139
 
-                * handler that's been scheduled.  If for some reason this loop doesn't
5140
 
-                * terminate (terminator not found, whatever) then this should make
5141
 
-                * sure that NM doesn't spin the CPU forever.
5142
 
-                */
5143
 
-               if (time (NULL) > info->end) {
5144
 
-                       done = TRUE;
5145
 
-                       break;
5146
 
-               } else if (!done)
5147
 
-                       g_usleep (50);
5148
 
-       } while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN);
5149
 
-
5150
 
-       return !done;
5151
 
-}
5152
 
-
5153
 
-guint
5154
 
-nm_serial_device_wait_for_reply (NMSerialDevice *device,
5155
 
-                                 guint timeout,
5156
 
-                                 const char **responses,
5157
 
-                                 const char **terminators,
5158
 
-                                 NMSerialWaitForReplyFn callback,
5159
 
-                                 gpointer user_data)
5160
 
-{
5161
 
-       WaitForReplyInfo *info;
5162
 
-
5163
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
5164
 
-       g_return_val_if_fail (responses != NULL, 0);
5165
 
-       g_return_val_if_fail (callback != NULL, 0);
5166
 
-
5167
 
-       info = g_slice_new0 (WaitForReplyInfo);
5168
 
-       info->device = device;
5169
 
-       info->str_needles = g_strdupv ((char **) responses);
5170
 
-       info->terminators = g_strdupv ((char **) terminators);
5171
 
-       info->result = g_string_new (NULL);
5172
 
-       info->callback = callback;
5173
 
-       info->user_data = user_data;
5174
 
-       info->reply_index = -1;
5175
 
-       info->end = time (NULL) + timeout;
5176
 
-
5177
 
-       return nm_serial_device_set_pending (device, timeout, wait_for_reply_got_data, info, wait_for_reply_done);
5178
 
-}
5179
 
-
5180
 
-#if 0
5181
 
-typedef struct {
5182
 
-       NMSerialDevice *device;
5183
 
-       gboolean timed_out;
5184
 
-       NMSerialWaitQuietFn callback;
5185
 
-       gpointer user_data;
5186
 
-} WaitQuietInfo;
5187
 
-
5188
 
-static void
5189
 
-wait_quiet_done (gpointer data)
5190
 
-{
5191
 
-       WaitQuietInfo *info = (WaitQuietInfo *) data;
5192
 
-
5193
 
-       nm_serial_device_pending_done (info->device);
5194
 
-
5195
 
-       /* Call the callback */
5196
 
-       info->callback (info->device, info->timed_out, info->user_data);
5197
 
-
5198
 
-       /* Free info */
5199
 
-       g_slice_free (WaitQuietInfo, info);
5200
 
-}
5201
 
-
5202
 
-static gboolean
5203
 
-wait_quiet_quiettime (gpointer data)
5204
 
-{
5205
 
-       WaitQuietInfo *info = (WaitQuietInfo *) data;
5206
 
-
5207
 
-       info->timed_out = FALSE;
5208
 
-       g_source_remove (NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending);
5209
 
-
5210
 
-       return FALSE;
5211
 
-}
5212
 
-
5213
 
-static gboolean
5214
 
-wait_quiet_got_data (GIOChannel *source,
5215
 
-                                GIOCondition condition,
5216
 
-                                gpointer data)
5217
 
-{
5218
 
-       WaitQuietInfo *info = (WaitQuietInfo *) data;
5219
 
-       gsize bytes_read;
5220
 
-       char buf[4096];
5221
 
-       GIOStatus status;
5222
 
-
5223
 
-       if (condition & G_IO_HUP || condition & G_IO_ERR)
5224
 
-               return FALSE;
5225
 
-
5226
 
-       if (condition & G_IO_IN) {
5227
 
-               do {
5228
 
-                       status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL);
5229
 
-
5230
 
-                       if (bytes_read) {
5231
 
-                               /* Reset the quiet time timeout */
5232
 
-                               g_source_remove (info->quiet_id);
5233
 
-                               info->quiet_id = g_timeout_add (info->quiet_time, wait_quiet_quiettime, info);
5234
 
-                       }
5235
 
-               } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN);
5236
 
-       }
5237
 
-
5238
 
-       return TRUE;
5239
 
-}
5240
 
-
5241
 
-void
5242
 
-nm_serial_device_wait_quiet (NMSerialDevice *device,
5243
 
-                                           guint timeout, 
5244
 
-                                           guint quiet_time,
5245
 
-                                           NMSerialWaitQuietFn callback,
5246
 
-                                           gpointer user_data)
5247
 
-{
5248
 
-       WaitQuietInfo *info;
5249
 
-
5250
 
-       g_return_if_fail (NM_IS_SERIAL_DEVICE (device));
5251
 
-       g_return_if_fail (callback != NULL);
5252
 
-
5253
 
-       info = g_slice_new0 (WaitQuietInfo);
5254
 
-       info->device = device;
5255
 
-       info->timed_out = TRUE;
5256
 
-       info->callback = callback;
5257
 
-       info->user_data = user_data;
5258
 
-       info->quiet_id = g_timeout_add (quiet_time,
5259
 
-                                                         wait_quiet_timeout,
5260
 
-                                                         info);
5261
 
-
5262
 
-       return nm_serial_device_set_pending (device, timeout, wait_quiet_got_data, info, wait_quiet_done);
5263
 
-}
5264
 
-
5265
 
-#endif
5266
 
-
5267
 
-typedef struct {
5268
 
-       NMSerialDevice *device;
5269
 
-       speed_t current_speed;
5270
 
-       NMSerialFlashFn callback;
5271
 
-       gpointer user_data;
5272
 
-} FlashInfo;
5273
 
-
5274
 
-static speed_t
5275
 
-get_speed (NMSerialDevice *device)
5276
 
-{
5277
 
-       struct termios options;
5278
 
-
5279
 
-       tcgetattr (NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd, &options);
5280
 
-
5281
 
-       return cfgetospeed (&options);
5282
 
-}
5283
 
-
5284
 
-static void
5285
 
-set_speed (NMSerialDevice *device, speed_t speed)
5286
 
-{
5287
 
-       struct termios options;
5288
 
-       int fd;
5289
 
-
5290
 
-       fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd;
5291
 
-       tcgetattr (fd, &options);
5292
 
-
5293
 
-       cfsetispeed (&options, speed);
5294
 
-       cfsetospeed (&options, speed);
5295
 
-
5296
 
-       options.c_cflag |= (CLOCAL | CREAD);
5297
 
-       tcsetattr (fd, TCSANOW, &options);
5298
 
-}
5299
 
-
5300
 
-static void
5301
 
-flash_done (gpointer data)
5302
 
-{
5303
 
-       FlashInfo *info = (FlashInfo *) data;
5304
 
-
5305
 
-       NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending_id = 0;
5306
 
-
5307
 
-       info->callback (info->device, info->user_data);
5308
 
-
5309
 
-       g_slice_free (FlashInfo, info);
5310
 
-}
5311
 
-
5312
 
-static gboolean
5313
 
-flash_do (gpointer data)
5314
 
-{
5315
 
-       FlashInfo *info = (FlashInfo *) data;
5316
 
-
5317
 
-       set_speed (info->device, info->current_speed);
5318
 
-
5319
 
-       return FALSE;
5320
 
-}
5321
 
-
5322
 
-guint
5323
 
-nm_serial_device_flash (NMSerialDevice *device,
5324
 
-                                   guint32 flash_time,
5325
 
-                                   NMSerialFlashFn callback,
5326
 
-                                   gpointer user_data)
5327
 
-{
5328
 
-       FlashInfo *info;
5329
 
-       guint id;
5330
 
-
5331
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
5332
 
-       g_return_val_if_fail (callback != NULL, 0);
5333
 
-
5334
 
-       info = g_slice_new0 (FlashInfo);
5335
 
-       info->device = device;
5336
 
-       info->current_speed = get_speed (device);
5337
 
-       info->callback = callback;
5338
 
-       info->user_data = user_data;
5339
 
-
5340
 
-       set_speed (device, B0);
5341
 
-
5342
 
-       id = g_timeout_add_full (G_PRIORITY_DEFAULT,
5343
 
-                                               flash_time,
5344
 
-                                               flash_do,
5345
 
-                                               info,
5346
 
-                                               flash_done);
5347
 
-
5348
 
-       NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_id = id;
5349
 
-
5350
 
-       return id;
5351
 
-}
5352
 
-
5353
 
-GIOChannel *
5354
 
-nm_serial_device_get_io_channel (NMSerialDevice *device)
5355
 
-{
5356
 
-       NMSerialDevicePrivate *priv;
5357
 
-
5358
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0);
5359
 
-
5360
 
-       priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
5361
 
-       if (priv->channel)
5362
 
-               return g_io_channel_ref (priv->channel);
5363
 
-
5364
 
-       return NULL;
5365
 
-}
5366
 
-
5367
 
-NMPPPManager *
5368
 
-nm_serial_device_get_ppp_manager (NMSerialDevice *device)
5369
 
-{
5370
 
-       g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), NULL);
5371
 
-
5372
 
-       return NM_SERIAL_DEVICE_GET_PRIVATE (device)->ppp_manager;
5373
 
-}
5374
 
-
5375
 
-static void
5376
 
-ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data)
5377
 
-{
5378
 
-       NMDevice *device = NM_DEVICE (user_data);
5379
 
-
5380
 
-       switch (status) {
5381
 
-       case NM_PPP_STATUS_NETWORK:
5382
 
-               nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
5383
 
-               break;
5384
 
-       case NM_PPP_STATUS_DISCONNECT:
5385
 
-               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
5386
 
-               break;
5387
 
-       case NM_PPP_STATUS_DEAD:
5388
 
-               nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
5389
 
-               break;
5390
 
-       case NM_PPP_STATUS_AUTHENTICATE:
5391
 
-               nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
5392
 
-               break;
5393
 
-       default:
5394
 
-               break;
5395
 
-       }
5396
 
-}
5397
 
-
5398
 
-static void
5399
 
-ppp_ip4_config (NMPPPManager *ppp_manager,
5400
 
-                        const char *iface,
5401
 
-                        NMIP4Config *config,
5402
 
-                        gpointer user_data)
5403
 
-{
5404
 
-       NMDevice *device = NM_DEVICE (user_data);
5405
 
-
5406
 
-       nm_device_set_ip_iface (device, iface);
5407
 
-       NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config);
5408
 
-       nm_device_activate_schedule_stage4_ip_config_get (device);
5409
 
-}
5410
 
-
5411
 
-static void
5412
 
-ppp_stats (NMPPPManager *ppp_manager,
5413
 
-                guint32 in_bytes,
5414
 
-                guint32 out_bytes,
5415
 
-                gpointer user_data)
5416
 
-{
5417
 
-       NMSerialDevice *device = NM_SERIAL_DEVICE (user_data);
5418
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
5419
 
-
5420
 
-       if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) {
5421
 
-               priv->in_bytes = in_bytes;
5422
 
-               priv->out_bytes = out_bytes;
5423
 
-
5424
 
-               g_signal_emit (device, signals[PPP_STATS], 0, in_bytes, out_bytes);
5425
 
-       }
5426
 
-}
5427
 
-
5428
 
-static NMActStageReturn
5429
 
-real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
5430
 
-{
5431
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
5432
 
-       NMSerialDeviceClass *serial_class = NM_SERIAL_DEVICE_GET_CLASS (device);
5433
 
-       NMActRequest *req;
5434
 
-       GError *err = NULL;
5435
 
-       NMActStageReturn ret;
5436
 
-       const char *ppp_name = NULL;
5437
 
-
5438
 
-       req = nm_device_get_act_request (device);
5439
 
-       g_assert (req);
5440
 
-
5441
 
-       if (serial_class->get_ppp_name)
5442
 
-               ppp_name = serial_class->get_ppp_name (NM_SERIAL_DEVICE (device), req);
5443
 
-
5444
 
-       priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (device));
5445
 
-       if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, &err)) {
5446
 
-               g_signal_connect (priv->ppp_manager, "state-changed",
5447
 
-                                          G_CALLBACK (ppp_state_changed),
5448
 
-                                          device);
5449
 
-               g_signal_connect (priv->ppp_manager, "ip4-config",
5450
 
-                                          G_CALLBACK (ppp_ip4_config),
5451
 
-                                          device);
5452
 
-               g_signal_connect (priv->ppp_manager, "stats",
5453
 
-                                          G_CALLBACK (ppp_stats),
5454
 
-                                          device);
5455
 
-
5456
 
-               ret = NM_ACT_STAGE_RETURN_POSTPONE;
5457
 
-       } else {
5458
 
-               nm_warning ("%s", err->message);
5459
 
-               g_error_free (err);
5460
 
-
5461
 
-               g_object_unref (priv->ppp_manager);
5462
 
-               priv->ppp_manager = NULL;
5463
 
-
5464
 
-               *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
5465
 
-               ret = NM_ACT_STAGE_RETURN_FAILURE;
5466
 
-       }
5467
 
-
5468
 
-       return ret;
5469
 
-}
5470
 
-
5471
 
-static NMActStageReturn
5472
 
-real_act_stage4_get_ip4_config (NMDevice *device,
5473
 
-                                NMIP4Config **config,
5474
 
-                                NMDeviceStateReason *reason)
5475
 
-{
5476
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
5477
 
-       NMConnection *connection;
5478
 
-       NMSettingIP4Config *s_ip4;
5479
 
-
5480
 
-       g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
5481
 
-       g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
5482
 
-       g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
5483
 
-
5484
 
-       connection = nm_act_request_get_connection (nm_device_get_act_request (device));
5485
 
-       g_assert (connection);
5486
 
-
5487
 
-       s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
5488
 
-
5489
 
-       *config = priv->pending_ip4_config;
5490
 
-       priv->pending_ip4_config = NULL;
5491
 
-       nm_utils_merge_ip4_config (*config, s_ip4);
5492
 
-
5493
 
-       return NM_ACT_STAGE_RETURN_SUCCESS;
5494
 
-}
5495
 
-
5496
 
-static void
5497
 
-cleanup_device (NMSerialDevice *device)
5498
 
-{
5499
 
-       NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
5500
 
-
5501
 
-       nm_device_set_ip_iface (NM_DEVICE (device), NULL);
5502
 
-
5503
 
-       if (priv->pending_ip4_config) {
5504
 
-               g_object_unref (priv->pending_ip4_config);
5505
 
-               priv->pending_ip4_config = NULL;
5506
 
-       }
5507
 
-
5508
 
-       priv->in_bytes = priv->out_bytes = 0;
5509
 
-}
5510
 
-
5511
 
-static void
5512
 
-real_deactivate_quickly (NMDevice *device)
5513
 
-{
5514
 
-       NMSerialDevice *self = NM_SERIAL_DEVICE (device);
5515
 
-
5516
 
-       cleanup_device (self);
5517
 
-       nm_serial_device_close (self);
5518
 
-}
5519
 
-
5520
 
-static guint32
5521
 
-real_get_generic_capabilities (NMDevice *dev)
5522
 
-{
5523
 
-       return NM_DEVICE_CAP_NM_SUPPORTED;
5524
 
-}
5525
 
-
5526
 
-/*****************************************************************************/
5527
 
-
5528
 
-static void
5529
 
-nm_serial_device_init (NMSerialDevice *self)
5530
 
-{
5531
 
-       if (getenv ("NM_SERIAL_DEBUG"))
5532
 
-               serial_debug = TRUE;
5533
 
-}
5534
 
-
5535
 
-static void
5536
 
-finalize (GObject *object)
5537
 
-{
5538
 
-       NMSerialDevice *self = NM_SERIAL_DEVICE (object);
5539
 
-
5540
 
-       cleanup_device (self);
5541
 
-       nm_serial_device_close (self);
5542
 
-
5543
 
-       G_OBJECT_CLASS (nm_serial_device_parent_class)->finalize (object);
5544
 
-}
5545
 
-
5546
 
-static void
5547
 
-nm_serial_device_class_init (NMSerialDeviceClass *klass)
5548
 
-{
5549
 
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
5550
 
-       NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
5551
 
-
5552
 
-       g_type_class_add_private (object_class, sizeof (NMSerialDevicePrivate));
5553
 
-
5554
 
-       /* Virtual methods */
5555
 
-       object_class->finalize = finalize;
5556
 
-
5557
 
-       parent_class->get_generic_capabilities = real_get_generic_capabilities;
5558
 
-       parent_class->act_stage2_config = real_act_stage2_config;
5559
 
-       parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
5560
 
-       parent_class->deactivate_quickly = real_deactivate_quickly;
5561
 
-
5562
 
-       /* Signals */
5563
 
-       signals[PPP_STATS] =
5564
 
-               g_signal_new ("ppp-stats",
5565
 
-                                   G_OBJECT_CLASS_TYPE (object_class),
5566
 
-                                   G_SIGNAL_RUN_FIRST,
5567
 
-                                   G_STRUCT_OFFSET (NMSerialDeviceClass, ppp_stats),
5568
 
-                                   NULL, NULL,
5569
 
-                                   _nm_marshal_VOID__UINT_UINT,
5570
 
-                                   G_TYPE_NONE, 2,
5571
 
-                                   G_TYPE_UINT, G_TYPE_UINT);
5572
 
-
5573
 
-       dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
5574
 
-                                                          &dbus_glib_nm_serial_device_object_info);
5575
 
-}
5576
 
diff --git a/src/nm-serial-device.h b/src/nm-serial-device.h
5577
 
deleted file mode 100644
5578
 
index 6e9b53b..0000000
5579
 
--- a/src/nm-serial-device.h
5580
 
+++ /dev/null
5581
 
@@ -1,110 +0,0 @@
5582
 
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
5583
 
-/* NetworkManager -- Network link manager
5584
 
- *
5585
 
- * This program is free software; you can redistribute it and/or modify
5586
 
- * it under the terms of the GNU General Public License as published by
5587
 
- * the Free Software Foundation; either version 2 of the License, or
5588
 
- * (at your option) any later version.
5589
 
- *
5590
 
- * This program is distributed in the hope that it will be useful,
5591
 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
5592
 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5593
 
- * GNU General Public License for more details.
5594
 
- *
5595
 
- * You should have received a copy of the GNU General Public License along
5596
 
- * with this program; if not, write to the Free Software Foundation, Inc.,
5597
 
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5598
 
- *
5599
 
- * Copyright (C) 2007 - 2008 Novell, Inc.
5600
 
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
5601
 
- */
5602
 
-
5603
 
-#ifndef NM_SERIAL_DEVICE_H
5604
 
-#define NM_SERIAL_DEVICE_H
5605
 
-
5606
 
-#include <nm-device.h>
5607
 
-#include <nm-setting-serial.h>
5608
 
-#include "ppp-manager/nm-ppp-manager.h"
5609
 
-
5610
 
-G_BEGIN_DECLS
5611
 
-
5612
 
-#define NM_TYPE_SERIAL_DEVICE                  (nm_serial_device_get_type ())
5613
 
-#define NM_SERIAL_DEVICE(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SERIAL_DEVICE, NMSerialDevice))
5614
 
-#define NM_SERIAL_DEVICE_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass))
5615
 
-#define NM_IS_SERIAL_DEVICE(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SERIAL_DEVICE))
5616
 
-#define NM_IS_SERIAL_DEVICE_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_SERIAL_DEVICE))
5617
 
-#define NM_SERIAL_DEVICE_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass))
5618
 
-
5619
 
-typedef struct {
5620
 
-       NMDevice parent;
5621
 
-} NMSerialDevice;
5622
 
-
5623
 
-typedef struct {
5624
 
-       NMDeviceClass parent;
5625
 
-
5626
 
-       const char * (*get_ppp_name) (NMSerialDevice *device, NMActRequest *req);
5627
 
-
5628
 
-       /* Signals */
5629
 
-       void (*ppp_stats) (NMSerialDevice *device, guint32 in_bytes, guint32 out_bytes);
5630
 
-} NMSerialDeviceClass;
5631
 
-
5632
 
-GType nm_serial_device_get_type (void);
5633
 
-
5634
 
-typedef void (*NMSerialGetReplyFn)     (NMSerialDevice *device,
5635
 
-                                                               const char *reply,
5636
 
-                                                               gpointer user_data);
5637
 
-
5638
 
-typedef void (*NMSerialWaitForReplyFn) (NMSerialDevice *device,
5639
 
-                                        int reply_index,
5640
 
-                                        const char *reply,
5641
 
-                                        gpointer user_data);
5642
 
-
5643
 
-typedef void (*NMSerialWaitQuietFn)    (NMSerialDevice *device,
5644
 
-                                                               gboolean timed_out,
5645
 
-                                                               gpointer user_data);
5646
 
-
5647
 
-typedef void (*NMSerialFlashFn)        (NMSerialDevice *device,
5648
 
-                                                               gpointer user_data);
5649
 
-
5650
 
-
5651
 
-
5652
 
-gboolean nm_serial_device_open                (NMSerialDevice *device, 
5653
 
-                                                                         NMSettingSerial *setting);
5654
 
-
5655
 
-void     nm_serial_device_close               (NMSerialDevice *device);
5656
 
-gboolean nm_serial_device_send_command        (NMSerialDevice *device,
5657
 
-                                                                         GByteArray *command);
5658
 
-
5659
 
-gboolean nm_serial_device_send_command_string (NMSerialDevice *device,
5660
 
-                                                                         const char *str);
5661
 
-
5662
 
-int nm_serial_device_wait_reply_blocking (NMSerialDevice *device,
5663
 
-                                          guint32 timeout_secs,
5664
 
-                                          const char **needles,
5665
 
-                                          const char **terminators);
5666
 
-
5667
 
-guint    nm_serial_device_wait_for_reply      (NMSerialDevice *device,
5668
 
-                                                                         guint timeout,
5669
 
-                                                                         const char **responses,
5670
 
-                                                                         const char **terminators,
5671
 
-                                                                         NMSerialWaitForReplyFn callback,
5672
 
-                                                                         gpointer user_data);
5673
 
-
5674
 
-void     nm_serial_device_wait_quiet          (NMSerialDevice *device,
5675
 
-                                                                         guint timeout, 
5676
 
-                                                                         guint quiet_time,
5677
 
-                                                                         NMSerialWaitQuietFn callback,
5678
 
-                                                                         gpointer user_data);
5679
 
-
5680
 
-guint    nm_serial_device_flash               (NMSerialDevice *device,
5681
 
-                                                                         guint32 flash_time,
5682
 
-                                                                         NMSerialFlashFn callback,
5683
 
-                                                                         gpointer user_data);
5684
 
-
5685
 
-GIOChannel *nm_serial_device_get_io_channel   (NMSerialDevice *device);
5686
 
-
5687
 
-NMPPPManager *nm_serial_device_get_ppp_manager (NMSerialDevice *device);
5688
 
-
5689
 
-G_END_DECLS
5690
 
-
5691
 
-#endif /* NM_SERIAL_DEVICE_H */