diff options
author | Tambet Ingo <tambet@gmail.com> | 2009-01-19 11:01:00 +0200 |
---|---|---|
committer | Tambet Ingo <tambet@gmail.com> | 2009-02-09 11:01:35 +0200 |
commit | e4398a88c8e09a6576625e6084c1a8d263949b76 (patch) | |
tree | af4096cdeca881ea9193b3e44f8c0b1d3ec69eea | |
parent | a734c836a56f3170202f0555f1a03c9b2835775c (diff) |
Use ModemManager.
25 files changed, 2562 insertions, 2795 deletions
diff --git a/configure.in b/configure.in index a235e227c5..7e82d4d0a2 100644 --- a/configure.in +++ b/configure.in | |||
@@ -504,6 +504,7 @@ src/dhcp-manager/Makefile | |||
504 | src/supplicant-manager/Makefile | 504 | src/supplicant-manager/Makefile |
505 | src/ppp-manager/Makefile | 505 | src/ppp-manager/Makefile |
506 | src/dnsmasq-manager/Makefile | 506 | src/dnsmasq-manager/Makefile |
507 | src/modem-manager/Makefile | ||
507 | src/backends/Makefile | 508 | src/backends/Makefile |
508 | libnm-util/libnm-util.pc | 509 | libnm-util/libnm-util.pc |
509 | libnm-util/Makefile | 510 | libnm-util/Makefile |
diff --git a/src/Makefile.am b/src/Makefile.am index 68ed5e8ded..3e134758a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -6,6 +6,7 @@ SUBDIRS= \ | |||
6 | ppp-manager \ | 6 | ppp-manager \ |
7 | backends \ | 7 | backends \ |
8 | dnsmasq-manager \ | 8 | dnsmasq-manager \ |
9 | modem-manager \ | ||
9 | . \ | 10 | . \ |
10 | tests | 11 | tests |
11 | 12 | ||
@@ -17,6 +18,7 @@ INCLUDES = -I${top_srcdir} \ | |||
17 | -I${top_srcdir}/src/dhcp-manager \ | 18 | -I${top_srcdir}/src/dhcp-manager \ |
18 | -I${top_srcdir}/src/supplicant-manager \ | 19 | -I${top_srcdir}/src/supplicant-manager \ |
19 | -I${top_srcdir}/src/dnsmasq-manager \ | 20 | -I${top_srcdir}/src/dnsmasq-manager \ |
21 | -I${top_srcdir}/src/modem-manager \ | ||
20 | -I${top_srcdir}/libnm-util \ | 22 | -I${top_srcdir}/libnm-util \ |
21 | -I${top_srcdir}/callouts | 23 | -I${top_srcdir}/callouts |
22 | 24 | ||
@@ -87,14 +89,6 @@ NetworkManager_SOURCES = \ | |||
87 | nm-activation-request.h \ | 89 | nm-activation-request.h \ |
88 | nm-properties-changed-signal.c \ | 90 | nm-properties-changed-signal.c \ |
89 | nm-properties-changed-signal.h \ | 91 | nm-properties-changed-signal.h \ |
90 | nm-serial-device.c \ | ||
91 | nm-serial-device.h \ | ||
92 | nm-gsm-device.c \ | ||
93 | nm-gsm-device.h \ | ||
94 | nm-cdma-device.c \ | ||
95 | nm-cdma-device.h \ | ||
96 | nm-hso-gsm-device.c \ | ||
97 | nm-hso-gsm-device.h \ | ||
98 | wpa.c \ | 92 | wpa.c \ |
99 | wpa.h \ | 93 | wpa.h \ |
100 | nm-netlink.c \ | 94 | nm-netlink.c \ |
@@ -117,15 +111,6 @@ nm-device-ethernet-glue.h: $(top_srcdir)/introspection/nm-device-ethernet.xml | |||
117 | nm-device-wifi-glue.h: $(top_srcdir)/introspection/nm-device-wifi.xml | 111 | nm-device-wifi-glue.h: $(top_srcdir)/introspection/nm-device-wifi.xml |
118 | dbus-binding-tool --prefix=nm_device_wifi --mode=glib-server --output=$@ $< | 112 | dbus-binding-tool --prefix=nm_device_wifi --mode=glib-server --output=$@ $< |
119 | 113 | ||
120 | nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml | ||
121 | dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $< | ||
122 | |||
123 | nm-cdma-device-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml | ||
124 | dbus-binding-tool --prefix=nm_cdma_device --mode=glib-server --output=$@ $< | ||
125 | |||
126 | nm-gsm-device-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml | ||
127 | dbus-binding-tool --prefix=nm_gsm_device --mode=glib-server --output=$@ $< | ||
128 | |||
129 | nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml | 114 | nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml |
130 | dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $< | 115 | dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=$@ $< |
131 | 116 | ||
@@ -141,9 +126,6 @@ BUILT_SOURCES = \ | |||
141 | nm-device-interface-glue.h \ | 126 | nm-device-interface-glue.h \ |
142 | nm-device-ethernet-glue.h \ | 127 | nm-device-ethernet-glue.h \ |
143 | nm-device-wifi-glue.h \ | 128 | nm-device-wifi-glue.h \ |
144 | nm-serial-device-glue.h \ | ||
145 | nm-cdma-device-glue.h \ | ||
146 | nm-gsm-device-glue.h \ | ||
147 | nm-ip4-config-glue.h \ | 129 | nm-ip4-config-glue.h \ |
148 | nm-active-connection-glue.h \ | 130 | nm-active-connection-glue.h \ |
149 | nm-dhcp4-config-glue.h | 131 | nm-dhcp4-config-glue.h |
@@ -175,11 +157,12 @@ NetworkManager_LDADD = \ | |||
175 | ./named-manager/libnamed-manager.la \ | 157 | ./named-manager/libnamed-manager.la \ |
176 | ./vpn-manager/libvpn-manager.la \ | 158 | ./vpn-manager/libvpn-manager.la \ |
177 | ./dhcp-manager/libdhcp-manager.la \ | 159 | ./dhcp-manager/libdhcp-manager.la \ |
178 | ./supplicant-manager/libsupplicant-manager.la \ | 160 | ./supplicant-manager/libsupplicant-manager.la \ |
179 | ./dnsmasq-manager/libdnsmasq-manager.la \ | 161 | ./dnsmasq-manager/libdnsmasq-manager.la \ |
180 | ./ppp-manager/libppp-manager.la \ | 162 | ./ppp-manager/libppp-manager.la \ |
181 | ./backends/libnmbackend.la \ | 163 | ./modem-manager/libmodem-manager.la \ |
182 | $(top_builddir)/libnm-util/libnm-util.la | 164 | ./backends/libnmbackend.la \ |
165 | $(top_builddir)/libnm-util/libnm-util.la | ||
183 | 166 | ||
184 | NetworkManager_LDFLAGS = -rdynamic | 167 | NetworkManager_LDFLAGS = -rdynamic |
185 | 168 | ||
diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 6bba92f2b1..941109ab78 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c | |||
@@ -34,15 +34,13 @@ | |||
34 | #include "nm-device.h" | 34 | #include "nm-device.h" |
35 | #include "nm-device-wifi.h" | 35 | #include "nm-device-wifi.h" |
36 | #include "nm-device-ethernet.h" | 36 | #include "nm-device-ethernet.h" |
37 | #include "nm-hso-gsm-device.h" | ||
38 | #include "nm-gsm-device.h" | ||
39 | #include "nm-cdma-device.h" | ||
40 | #include "nm-dbus-manager.h" | 37 | #include "nm-dbus-manager.h" |
41 | #include "nm-setting-ip4-config.h" | 38 | #include "nm-setting-ip4-config.h" |
42 | #include "nm-setting-connection.h" | 39 | #include "nm-setting-connection.h" |
43 | #include "NetworkManagerSystem.h" | 40 | #include "NetworkManagerSystem.h" |
44 | #include "nm-named-manager.h" | 41 | #include "nm-named-manager.h" |
45 | #include "nm-vpn-manager.h" | 42 | #include "nm-vpn-manager.h" |
43 | #include "nm-modem-gsm-hso.h" | ||
46 | 44 | ||
47 | typedef struct LookupThread LookupThread; | 45 | typedef struct LookupThread LookupThread; |
48 | 46 | ||
@@ -235,7 +233,7 @@ get_best_device (NMManager *manager, NMActRequest **out_req) | |||
235 | } | 233 | } |
236 | 234 | ||
237 | /* 'hso' devices never get a gateway from the remote end */ | 235 | /* 'hso' devices never get a gateway from the remote end */ |
238 | if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev)) | 236 | if (!can_default && !NM_IS_MODEM_GSM_HSO (dev)) |
239 | continue; | 237 | continue; |
240 | 238 | ||
241 | /* 'never-default' devices can't ever be the default */ | 239 | /* 'never-default' devices can't ever be the default */ |
diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am new file mode 100644 index 0000000000..75ab97e041 --- /dev/null +++ b/src/modem-manager/Makefile.am | |||
@@ -0,0 +1,45 @@ | |||
1 | INCLUDES = \ | ||
2 | -I${top_srcdir}/src \ | ||
3 | -I${top_srcdir}/include \ | ||
4 | -I${top_srcdir}/libnm-util \ | ||
5 | -I${top_builddir}/marshallers | ||
6 | |||
7 | noinst_LTLIBRARIES = libmodem-manager.la | ||
8 | |||
9 | libmodem_manager_la_SOURCES = \ | ||
10 | nm-modem-cdma.c \ | ||
11 | nm-modem-cdma.h \ | ||
12 | nm-modem-gsm.c \ | ||
13 | nm-modem-gsm.h \ | ||
14 | nm-modem-gsm-hso.c \ | ||
15 | nm-modem-gsm-hso.h \ | ||
16 | nm-modem-gsm-mbm.c \ | ||
17 | nm-modem-gsm-mbm.h \ | ||
18 | nm-modem.c \ | ||
19 | nm-modem.h \ | ||
20 | nm-modem-manager.h \ | ||
21 | nm-modem-manager.c \ | ||
22 | nm-modem-types.h | ||
23 | |||
24 | libmodem_manager_la_CPPFLAGS = \ | ||
25 | $(DBUS_CFLAGS) | ||
26 | |||
27 | libmodem_manager_la_LIBADD = \ | ||
28 | $(DBUS_LIBS) \ | ||
29 | $(top_builddir)/marshallers/libmarshallers.la | ||
30 | |||
31 | nm-device-cdma-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml | ||
32 | dbus-binding-tool --prefix=nm_device_cdma --mode=glib-server --output=$@ $< | ||
33 | |||
34 | nm-device-gsm-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml | ||
35 | dbus-binding-tool --prefix=nm_device_gsm --mode=glib-server --output=$@ $< | ||
36 | |||
37 | nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml | ||
38 | dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $< | ||
39 | |||
40 | BUILT_SOURCES = \ | ||
41 | nm-device-cdma-glue.h \ | ||
42 | nm-device-gsm-glue.h \ | ||
43 | nm-serial-device-glue.h | ||
44 | |||
45 | CLEANFILES = $(BUILT_SOURCES) | ||
diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c new file mode 100644 index 0000000000..1d426962d0 --- /dev/null +++ b/src/modem-manager/nm-modem-cdma.c | |||
@@ -0,0 +1,264 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #include <string.h> | ||
4 | |||
5 | #include "nm-modem-cdma.h" | ||
6 | #include "nm-modem-types.h" | ||
7 | #include "nm-device-interface.h" | ||
8 | #include "nm-device-private.h" | ||
9 | #include "nm-dbus-manager.h" | ||
10 | #include "nm-setting-connection.h" | ||
11 | #include "nm-setting-cdma.h" | ||
12 | #include "nm-utils.h" | ||
13 | |||
14 | #include "nm-device-cdma-glue.h" | ||
15 | |||
16 | G_DEFINE_TYPE (NMModemCdma, nm_modem_cdma, NM_TYPE_MODEM) | ||
17 | |||
18 | #define NM_MODEM_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_CDMA, NMModemCdmaPrivate)) | ||
19 | |||
20 | enum { | ||
21 | MODEM_STATE_BEGIN, | ||
22 | MODEM_STATE_ENABLE, | ||
23 | MODEM_STATE_CONNECT | ||
24 | }; | ||
25 | |||
26 | typedef struct { | ||
27 | int modem_state; | ||
28 | } NMModemCdmaPrivate; | ||
29 | |||
30 | enum { | ||
31 | SIGNAL_QUALITY, | ||
32 | |||
33 | LAST_SIGNAL | ||
34 | }; | ||
35 | |||
36 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
37 | |||
38 | NMDevice * | ||
39 | nm_modem_cdma_new (const char *path, | ||
40 | const char *data_device, | ||
41 | const char *driver) | ||
42 | { | ||
43 | g_return_val_if_fail (path != NULL, NULL); | ||
44 | g_return_val_if_fail (data_device != NULL, NULL); | ||
45 | g_return_val_if_fail (driver != NULL, NULL); | ||
46 | |||
47 | return (NMDevice *) g_object_new (NM_TYPE_MODEM_CDMA, | ||
48 | NM_DEVICE_INTERFACE_UDI, path, | ||
49 | NM_DEVICE_INTERFACE_IFACE, data_device, | ||
50 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
51 | NM_DEVICE_INTERFACE_MANAGED, TRUE, | ||
52 | NM_MODEM_PATH, path, | ||
53 | NULL); | ||
54 | } | ||
55 | |||
56 | static NMSetting * | ||
57 | get_setting (NMModemCdma *self, GType setting_type) | ||
58 | { | ||
59 | NMActRequest *req; | ||
60 | NMSetting *setting = NULL; | ||
61 | |||
62 | req = nm_device_get_act_request (NM_DEVICE (self)); | ||
63 | if (req) { | ||
64 | NMConnection *connection; | ||
65 | |||
66 | connection = nm_act_request_get_connection (req); | ||
67 | if (connection) | ||
68 | setting = nm_connection_get_setting (connection, setting_type); | ||
69 | } | ||
70 | |||
71 | return setting; | ||
72 | } | ||
73 | |||
74 | static void | ||
75 | state_machine (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) | ||
76 | { | ||
77 | NMModemCdma *modem = NM_MODEM_CDMA (user_data); | ||
78 | NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (modem); | ||
79 | NMSettingCdma *setting; | ||
80 | GError *error = NULL; | ||
81 | |||
82 | setting = NM_SETTING_CDMA (get_setting (modem, NM_TYPE_SETTING_CDMA)); | ||
83 | |||
84 | if (call_id) | ||
85 | dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID); | ||
86 | |||
87 | if (error) { | ||
88 | nm_warning ("CDMA modem connection failed: %s", error->message); | ||
89 | nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); | ||
90 | return; | ||
91 | } | ||
92 | |||
93 | switch (priv->modem_state) { | ||
94 | case MODEM_STATE_BEGIN: | ||
95 | priv->modem_state = MODEM_STATE_ENABLE; | ||
96 | dbus_g_proxy_begin_call (nm_modem_get_proxy (NM_MODEM (modem), NULL), | ||
97 | "Enable", state_machine, | ||
98 | modem, NULL, | ||
99 | G_TYPE_BOOLEAN, TRUE, | ||
100 | G_TYPE_INVALID); | ||
101 | break; | ||
102 | case MODEM_STATE_ENABLE: | ||
103 | priv->modem_state = MODEM_STATE_CONNECT; | ||
104 | dbus_g_proxy_begin_call (nm_modem_get_proxy (NM_MODEM (modem), NULL), | ||
105 | "Connect", state_machine, | ||
106 | modem, NULL, | ||
107 | G_TYPE_STRING, nm_setting_cdma_get_number (setting), | ||
108 | G_TYPE_INVALID); | ||
109 | break; | ||
110 | case MODEM_STATE_CONNECT: | ||
111 | nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem)); | ||
112 | break; | ||
113 | default: | ||
114 | nm_warning ("Invalid modem state %d", priv->modem_state); | ||
115 | nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static NMActStageReturn | ||
121 | real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) | ||
122 | { | ||
123 | NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (device); | ||
124 | |||
125 | priv->modem_state = MODEM_STATE_BEGIN; | ||
126 | state_machine (NULL, NULL, device); | ||
127 | |||
128 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
129 | } | ||
130 | |||
131 | static NMConnection * | ||
132 | real_get_best_auto_connection (NMDevice *dev, | ||
133 | GSList *connections, | ||
134 | char **specific_object) | ||
135 | { | ||
136 | GSList *iter; | ||
137 | |||
138 | for (iter = connections; iter; iter = g_slist_next (iter)) { | ||
139 | NMConnection *connection = NM_CONNECTION (iter->data); | ||
140 | NMSettingConnection *s_con; | ||
141 | |||
142 | s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); | ||
143 | g_assert (s_con); | ||
144 | |||
145 | if (!nm_setting_connection_get_autoconnect (s_con)) | ||
146 | continue; | ||
147 | |||
148 | if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME)) | ||
149 | continue; | ||
150 | |||
151 | return connection; | ||
152 | } | ||
153 | return NULL; | ||
154 | } | ||
155 | |||
156 | static void | ||
157 | real_connection_secrets_updated (NMDevice *dev, | ||
158 | NMConnection *connection, | ||
159 | GSList *updated_settings, | ||
160 | RequestSecretsCaller caller) | ||
161 | { | ||
162 | NMActRequest *req; | ||
163 | gboolean found = FALSE; | ||
164 | GSList *iter; | ||
165 | |||
166 | if (caller == SECRETS_CALLER_PPP) { | ||
167 | NMPPPManager *ppp_manager; | ||
168 | NMSettingCdma *s_cdma = NULL; | ||
169 | |||
170 | ppp_manager = nm_modem_get_ppp_manager (NM_MODEM (dev)); | ||
171 | g_return_if_fail (ppp_manager != NULL); | ||
172 | |||
173 | s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); | ||
174 | if (!s_cdma) { | ||
175 | /* Shouldn't ever happen */ | ||
176 | nm_ppp_manager_update_secrets (ppp_manager, | ||
177 | nm_device_get_iface (dev), | ||
178 | NULL, | ||
179 | NULL, | ||
180 | "missing CDMA setting; no secrets could be found."); | ||
181 | } else { | ||
182 | const char *username = nm_setting_cdma_get_username (s_cdma); | ||
183 | const char *password = nm_setting_cdma_get_password (s_cdma); | ||
184 | |||
185 | nm_ppp_manager_update_secrets (ppp_manager, | ||
186 | nm_device_get_iface (dev), | ||
187 | username ? username : "", | ||
188 | password ? password : "", | ||
189 | NULL); | ||
190 | } | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | g_return_if_fail (caller == SECRETS_CALLER_CDMA); | ||
195 | g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); | ||
196 | |||
197 | for (iter = updated_settings; iter; iter = g_slist_next (iter)) { | ||
198 | const char *setting_name = (const char *) iter->data; | ||
199 | |||
200 | if (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME)) | ||
201 | found = TRUE; | ||
202 | else | ||
203 | nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); | ||
204 | } | ||
205 | |||
206 | if (!found) | ||
207 | return; | ||
208 | |||
209 | req = nm_device_get_act_request (dev); | ||
210 | g_assert (req); | ||
211 | |||
212 | g_return_if_fail (nm_act_request_get_connection (req) == connection); | ||
213 | |||
214 | nm_device_activate_schedule_stage1_device_prepare (dev); | ||
215 | } | ||
216 | |||
217 | static const char * | ||
218 | real_get_ppp_name (NMModem *device, NMConnection *connection) | ||
219 | { | ||
220 | NMSettingCdma *s_cdma; | ||
221 | |||
222 | s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); | ||
223 | g_assert (s_cdma); | ||
224 | |||
225 | return nm_setting_cdma_get_username (s_cdma); | ||
226 | } | ||
227 | |||
228 | /*****************************************************************************/ | ||
229 | |||
230 | static void | ||
231 | nm_modem_cdma_init (NMModemCdma *self) | ||
232 | { | ||
233 | nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_CDMA); | ||
234 | } | ||
235 | |||
236 | static void | ||
237 | nm_modem_cdma_class_init (NMModemCdmaClass *klass) | ||
238 | { | ||
239 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
240 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
241 | NMModemClass *modem_class = NM_MODEM_CLASS (klass); | ||
242 | |||
243 | g_type_class_add_private (object_class, sizeof (NMModemCdmaPrivate)); | ||
244 | |||
245 | /* Virtual methods */ | ||
246 | device_class->get_best_auto_connection = real_get_best_auto_connection; | ||
247 | device_class->connection_secrets_updated = real_connection_secrets_updated; | ||
248 | device_class->act_stage1_prepare = real_act_stage1_prepare; | ||
249 | modem_class->get_ppp_name = real_get_ppp_name; | ||
250 | |||
251 | /* Signals */ | ||
252 | signals[SIGNAL_QUALITY] = | ||
253 | g_signal_new ("signal-quality", | ||
254 | G_OBJECT_CLASS_TYPE (object_class), | ||
255 | G_SIGNAL_RUN_FIRST, | ||
256 | G_STRUCT_OFFSET (NMModemCdmaClass, signal_quality), | ||
257 | NULL, NULL, | ||
258 | g_cclosure_marshal_VOID__UINT, | ||
259 | G_TYPE_NONE, 1, | ||
260 | G_TYPE_UINT); | ||
261 | |||
262 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
263 | &dbus_glib_nm_device_cdma_object_info); | ||
264 | } | ||
diff --git a/src/modem-manager/nm-modem-cdma.h b/src/modem-manager/nm-modem-cdma.h new file mode 100644 index 0000000000..a1f3bf5459 --- /dev/null +++ b/src/modem-manager/nm-modem-cdma.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_CDMA_H | ||
4 | #define NM_MODEM_CDMA_H | ||
5 | |||
6 | #include <nm-modem.h> | ||
7 | |||
8 | G_BEGIN_DECLS | ||
9 | |||
10 | #define NM_TYPE_MODEM_CDMA (nm_modem_cdma_get_type ()) | ||
11 | #define NM_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_CDMA, NMModemCdma)) | ||
12 | #define NM_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) | ||
13 | #define NM_IS_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_CDMA)) | ||
14 | #define NM_IS_MODEM_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_CDMA)) | ||
15 | #define NM_MODEM_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_CDMA, NMModemCdmaClass)) | ||
16 | |||
17 | typedef struct { | ||
18 | NMModem parent; | ||
19 | } NMModemCdma; | ||
20 | |||
21 | typedef struct { | ||
22 | NMModemClass parent; | ||
23 | |||
24 | /* Signals */ | ||
25 | void (*signal_quality) (NMModemCdma *self, guint32 quality); | ||
26 | } NMModemCdmaClass; | ||
27 | |||
28 | GType nm_modem_cdma_get_type (void); | ||
29 | |||
30 | NMDevice *nm_modem_cdma_new (const char *path, | ||
31 | const char *data_device, | ||
32 | const char *driver); | ||
33 | |||
34 | G_END_DECLS | ||
35 | |||
36 | #endif /* NM_MODEM_CDMA_H */ | ||
diff --git a/src/modem-manager/nm-modem-gsm-hso.c b/src/modem-manager/nm-modem-gsm-hso.c new file mode 100644 index 0000000000..343bfa3f24 --- /dev/null +++ b/src/modem-manager/nm-modem-gsm-hso.c | |||
@@ -0,0 +1,348 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #include "nm-modem-gsm-hso.h" | ||
4 | #include "nm-device-private.h" | ||
5 | #include "nm-device-interface.h" | ||
6 | #include "NetworkManagerSystem.h" | ||
7 | #include "nm-setting-connection.h" | ||
8 | #include "nm-setting-gsm.h" | ||
9 | #include "nm-modem-types.h" | ||
10 | #include "nm-utils.h" | ||
11 | |||
12 | G_DEFINE_TYPE (NMModemGsmHso, nm_modem_gsm_hso, NM_TYPE_MODEM_GSM) | ||
13 | |||
14 | #define NM_MODEM_GSM_HSO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GSM_HSO, NMModemGsmHsoPrivate)) | ||
15 | |||
16 | typedef struct { | ||
17 | char *netdev_iface; | ||
18 | NMIP4Config *pending_ip4_config; | ||
19 | } NMModemGsmHsoPrivate; | ||
20 | |||
21 | #define HSO_SECRETS_TRIES "gsm-secrets-tries" | ||
22 | |||
23 | static char * | ||
24 | get_network_device (NMDevice *device) | ||
25 | { | ||
26 | char *result = NULL; | ||
27 | GError *error = NULL; | ||
28 | GValue value = { 0, }; | ||
29 | |||
30 | if (!dbus_g_proxy_call (nm_modem_get_proxy (NM_MODEM (device), "org.freedesktop.DBus.Properties"), | ||
31 | "Get", &error, | ||
32 | G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_HSO, | ||
33 | G_TYPE_STRING, "NetworkDevice", | ||
34 | G_TYPE_INVALID, | ||
35 | G_TYPE_VALUE, &value, | ||
36 | G_TYPE_INVALID)) { | ||
37 | nm_warning ("Could not get HSO device's network interface: %s", error->message); | ||
38 | g_error_free (error); | ||
39 | } else { | ||
40 | if (G_VALUE_HOLDS_STRING (&value)) | ||
41 | result = g_value_dup_string (&value); | ||
42 | else | ||
43 | nm_warning ("Could not get HSO device's network interface: wrong type '%s'", | ||
44 | G_VALUE_TYPE_NAME (&value)); | ||
45 | |||
46 | g_value_unset (&value); | ||
47 | } | ||
48 | |||
49 | return result; | ||
50 | } | ||
51 | |||
52 | NMDevice * | ||
53 | nm_modem_gsm_hso_new (const char *path, | ||
54 | const char *data_device, | ||
55 | const char *driver) | ||
56 | { | ||
57 | NMDevice *device; | ||
58 | |||
59 | g_return_val_if_fail (path != NULL, NULL); | ||
60 | g_return_val_if_fail (data_device != NULL, NULL); | ||
61 | g_return_val_if_fail (driver != NULL, NULL); | ||
62 | |||
63 | device = (NMDevice *) g_object_new (NM_TYPE_MODEM_GSM_HSO, | ||
64 | NM_DEVICE_INTERFACE_UDI, path, | ||
65 | NM_DEVICE_INTERFACE_IFACE, data_device, | ||
66 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
67 | NM_DEVICE_INTERFACE_MANAGED, TRUE, | ||
68 | NM_MODEM_PATH, path, | ||
69 | NULL); | ||
70 | |||
71 | if (device) { | ||
72 | NMModemGsmHsoPrivate *priv; | ||
73 | |||
74 | priv = NM_MODEM_GSM_HSO_GET_PRIVATE (device); | ||
75 | priv->netdev_iface = get_network_device (device); | ||
76 | if (!priv->netdev_iface) { | ||
77 | g_object_unref (device); | ||
78 | device = NULL; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | return device; | ||
83 | } | ||
84 | |||
85 | /*****************************************************************************/ | ||
86 | |||
87 | static NMSetting * | ||
88 | get_setting (NMModemGsmHso *modem, GType setting_type) | ||
89 | { | ||
90 | NMActRequest *req; | ||
91 | NMSetting *setting = NULL; | ||
92 | |||
93 | req = nm_device_get_act_request (NM_DEVICE (modem)); | ||
94 | if (req) { | ||
95 | NMConnection *connection; | ||
96 | |||
97 | connection = nm_act_request_get_connection (req); | ||
98 | if (connection) | ||
99 | setting = nm_connection_get_setting (connection, setting_type); | ||
100 | } | ||
101 | |||
102 | return setting; | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | hso_auth_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) | ||
107 | { | ||
108 | NMDevice *device = NM_DEVICE (user_data); | ||
109 | GError *error = NULL; | ||
110 | |||
111 | if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) | ||
112 | nm_device_activate_schedule_stage3_ip_config_start (device); | ||
113 | else { | ||
114 | nm_warning ("Authentication failed: %s", error->message); | ||
115 | g_error_free (error); | ||
116 | nm_device_state_changed (device, | ||
117 | NM_DEVICE_STATE_FAILED, | ||
118 | NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | static void | ||
123 | do_hso_auth (NMModemGsmHso *device) | ||
124 | { | ||
125 | NMSettingGsm *s_gsm; | ||
126 | const char *username; | ||
127 | const char *password; | ||
128 | |||
129 | s_gsm = NM_SETTING_GSM (get_setting (device, NM_TYPE_SETTING_GSM)); | ||
130 | username = nm_setting_gsm_get_username (s_gsm); | ||
131 | password = nm_setting_gsm_get_password (s_gsm); | ||
132 | |||
133 | dbus_g_proxy_begin_call (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_GSM_HSO), | ||
134 | "Authenticate", hso_auth_done, | ||
135 | device, NULL, | ||
136 | G_TYPE_STRING, username ? username : "", | ||
137 | G_TYPE_STRING, password ? password : "", | ||
138 | G_TYPE_INVALID); | ||
139 | } | ||
140 | |||
141 | static NMActStageReturn | ||
142 | real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) | ||
143 | { | ||
144 | NMActRequest *req; | ||
145 | NMConnection *connection; | ||
146 | const char *setting_name; | ||
147 | GPtrArray *hints = NULL; | ||
148 | const char *hint1 = NULL, *hint2 = NULL; | ||
149 | guint32 tries; | ||
150 | |||
151 | req = nm_device_get_act_request (device); | ||
152 | g_assert (req); | ||
153 | connection = nm_act_request_get_connection (req); | ||
154 | g_assert (connection); | ||
155 | |||
156 | setting_name = nm_connection_need_secrets (connection, &hints); | ||
157 | if (!setting_name) { | ||
158 | do_hso_auth (NM_MODEM_GSM_HSO (device)); | ||
159 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
160 | } | ||
161 | |||
162 | if (hints) { | ||
163 | if (hints->len > 0) | ||
164 | hint1 = g_ptr_array_index (hints, 0); | ||
165 | if (hints->len > 1) | ||
166 | hint2 = g_ptr_array_index (hints, 1); | ||
167 | } | ||
168 | |||
169 | nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
170 | |||
171 | tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), HSO_SECRETS_TRIES)); | ||
172 | nm_act_request_request_connection_secrets (req, | ||
173 | setting_name, | ||
174 | tries ? TRUE : FALSE, | ||
175 | SECRETS_CALLER_HSO_GSM, | ||
176 | hint1, | ||
177 | hint2); | ||
178 | g_object_set_data (G_OBJECT (connection), HSO_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); | ||
179 | |||
180 | if (hints) | ||
181 | g_ptr_array_free (hints, TRUE); | ||
182 | |||
183 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
184 | } | ||
185 | |||
186 | static void | ||
187 | get_ip4_config_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) | ||
188 | { | ||
189 | NMDevice *device = NM_DEVICE (user_data); | ||
190 | guint32 ip4_address; | ||
191 | GArray *dns_array; | ||
192 | GError *error = NULL; | ||
193 | |||
194 | if (dbus_g_proxy_end_call (proxy, call_id, &error, | ||
195 | G_TYPE_UINT, &ip4_address, | ||
196 | DBUS_TYPE_G_UINT_ARRAY, &dns_array, | ||
197 | G_TYPE_INVALID)) { | ||
198 | |||
199 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (device); | ||
200 | NMIP4Address *addr; | ||
201 | int i; | ||
202 | |||
203 | addr = nm_ip4_address_new (); | ||
204 | nm_ip4_address_set_address (addr, ip4_address); | ||
205 | nm_ip4_address_set_prefix (addr, 32); | ||
206 | |||
207 | priv->pending_ip4_config = nm_ip4_config_new (); | ||
208 | nm_ip4_config_take_address (priv->pending_ip4_config, addr); | ||
209 | |||
210 | for (i = 0; i < dns_array->len; i++) | ||
211 | nm_ip4_config_add_nameserver (priv->pending_ip4_config, | ||
212 | g_array_index (dns_array, guint32, i)); | ||
213 | |||
214 | nm_device_activate_schedule_stage4_ip_config_get (device); | ||
215 | } else { | ||
216 | nm_warning ("Retrieving IP4 configuration failed: %s", error->message); | ||
217 | g_error_free (error); | ||
218 | nm_device_state_changed (device, | ||
219 | NM_DEVICE_STATE_FAILED, | ||
220 | NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static NMActStageReturn | ||
225 | real_act_stage3_ip_config_start (NMDevice *device, NMDeviceStateReason *reason) | ||
226 | { | ||
227 | dbus_g_proxy_begin_call (nm_modem_get_proxy (NM_MODEM (device), MM_DBUS_INTERFACE_MODEM_GSM_HSO), | ||
228 | "GetIP4Config", get_ip4_config_done, | ||
229 | device, NULL, | ||
230 | G_TYPE_INVALID); | ||
231 | |||
232 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
233 | } | ||
234 | |||
235 | static NMActStageReturn | ||
236 | real_act_stage4_get_ip4_config (NMDevice *device, | ||
237 | NMIP4Config **config, | ||
238 | NMDeviceStateReason *reason) | ||
239 | { | ||
240 | NMModemGsmHso *self = NM_MODEM_GSM_HSO (device); | ||
241 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (self); | ||
242 | gboolean no_firmware = FALSE; | ||
243 | |||
244 | nm_device_set_ip_iface (device, priv->netdev_iface); | ||
245 | if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) { | ||
246 | if (no_firmware) | ||
247 | *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING; | ||
248 | else | ||
249 | *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; | ||
250 | return NM_ACT_STAGE_RETURN_FAILURE; | ||
251 | } | ||
252 | |||
253 | *config = priv->pending_ip4_config; | ||
254 | priv->pending_ip4_config = NULL; | ||
255 | |||
256 | return NM_ACT_STAGE_RETURN_SUCCESS; | ||
257 | } | ||
258 | |||
259 | static void | ||
260 | real_deactivate (NMDevice *device) | ||
261 | { | ||
262 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (device); | ||
263 | |||
264 | if (priv->pending_ip4_config) { | ||
265 | g_object_unref (priv->pending_ip4_config); | ||
266 | priv->pending_ip4_config = NULL; | ||
267 | } | ||
268 | |||
269 | if (priv->netdev_iface) { | ||
270 | nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface); | ||
271 | nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface); | ||
272 | nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL); | ||
273 | } | ||
274 | nm_device_set_ip_iface (device, NULL); | ||
275 | |||
276 | if (NM_DEVICE_CLASS (nm_modem_gsm_hso_parent_class)->deactivate) | ||
277 | NM_DEVICE_CLASS (nm_modem_gsm_hso_parent_class)->deactivate (device); | ||
278 | } | ||
279 | |||
280 | static gboolean | ||
281 | real_hw_is_up (NMDevice *device) | ||
282 | { | ||
283 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (device); | ||
284 | NMDeviceState state; | ||
285 | |||
286 | state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); | ||
287 | if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED) | ||
288 | return nm_system_device_is_up_with_iface (priv->netdev_iface); | ||
289 | |||
290 | return TRUE; | ||
291 | } | ||
292 | |||
293 | static gboolean | ||
294 | real_hw_bring_up (NMDevice *device, gboolean *no_firmware) | ||
295 | { | ||
296 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (device); | ||
297 | NMDeviceState state; | ||
298 | |||
299 | state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); | ||
300 | if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED) | ||
301 | return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware); | ||
302 | |||
303 | return TRUE; | ||
304 | } | ||
305 | |||
306 | static void | ||
307 | real_connect (NMModem *modem, const char *number) | ||
308 | { | ||
309 | nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem)); | ||
310 | } | ||
311 | |||
312 | /*****************************************************************************/ | ||
313 | |||
314 | static void | ||
315 | nm_modem_gsm_hso_init (NMModemGsmHso *self) | ||
316 | { | ||
317 | } | ||
318 | |||
319 | static void | ||
320 | finalize (GObject *object) | ||
321 | { | ||
322 | NMModemGsmHsoPrivate *priv = NM_MODEM_GSM_HSO_GET_PRIVATE (object); | ||
323 | |||
324 | g_free (priv->netdev_iface); | ||
325 | |||
326 | G_OBJECT_CLASS (nm_modem_gsm_hso_parent_class)->finalize (object); | ||
327 | } | ||
328 | |||
329 | static void | ||
330 | nm_modem_gsm_hso_class_init (NMModemGsmHsoClass *klass) | ||
331 | { | ||
332 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
333 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
334 | NMModemClass *modem_class = NM_MODEM_CLASS (klass); | ||
335 | |||
336 | g_type_class_add_private (object_class, sizeof (NMModemGsmHsoPrivate)); | ||
337 | |||
338 | object_class->finalize = finalize; | ||
339 | |||
340 | device_class->act_stage2_config = real_act_stage2_config; | ||
341 | device_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start; | ||
342 | device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; | ||
343 | device_class->deactivate = real_deactivate; | ||
344 | device_class->hw_is_up = real_hw_is_up; | ||
345 | device_class->hw_bring_up = real_hw_bring_up; | ||
346 | |||
347 | modem_class->connect = real_connect; | ||
348 | } | ||
diff --git a/src/modem-manager/nm-modem-gsm-hso.h b/src/modem-manager/nm-modem-gsm-hso.h new file mode 100644 index 0000000000..9b67bee921 --- /dev/null +++ b/src/modem-manager/nm-modem-gsm-hso.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_GSM_HSO_H | ||
4 | #define NM_MODEM_GSM_HSO_H | ||
5 | |||
6 | #include <nm-modem-gsm.h> | ||
7 | |||
8 | G_BEGIN_DECLS | ||
9 | |||
10 | #define NM_TYPE_MODEM_GSM_HSO (nm_modem_gsm_hso_get_type ()) | ||
11 | #define NM_MODEM_GSM_HSO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GSM_HSO, NMModemGsmHso)) | ||
12 | #define NM_MODEM_GSM_HSO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GSM_HSO, NMModemGsmHsoClass)) | ||
13 | #define NM_IS_MODEM_GSM_HSO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GSM_HSO)) | ||
14 | #define NM_IS_MODEM_GSM_HSO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GSM_HSO)) | ||
15 | #define NM_MODEM_GSM_HSO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM_HSO, NMModemGsmHsoClass)) | ||
16 | |||
17 | typedef struct { | ||
18 | NMModemGsm parent; | ||
19 | } NMModemGsmHso; | ||
20 | |||
21 | typedef struct { | ||
22 | NMModemGsmClass parent; | ||
23 | } NMModemGsmHsoClass; | ||
24 | |||
25 | GType nm_modem_gsm_hso_get_type (void); | ||
26 | |||
27 | NMDevice *nm_modem_gsm_hso_new (const char *path, | ||
28 | const char *data_device, | ||
29 | const char *driver); | ||
30 | |||
31 | G_END_DECLS | ||
32 | |||
33 | #endif /* NM_MODEM_GSM_HSO_H */ | ||
diff --git a/src/modem-manager/nm-modem-gsm-mbm.c b/src/modem-manager/nm-modem-gsm-mbm.c new file mode 100644 index 0000000000..adac6f7552 --- /dev/null +++ b/src/modem-manager/nm-modem-gsm-mbm.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* | ||
3 | Additions to NetworkManager, network-manager-applet and modemmanager | ||
4 | for supporting Ericsson modules like F3507g. | ||
5 | |||
6 | Author: Per Hallsmark <per@hallsmark.se> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | |||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include "nm-modem-gsm-mbm.h" | ||
26 | #include "nm-device-private.h" | ||
27 | #include "nm-device-interface.h" | ||
28 | #include "NetworkManagerSystem.h" | ||
29 | #include "nm-setting-connection.h" | ||
30 | #include "nm-setting-gsm.h" | ||
31 | #include "nm-modem-types.h" | ||
32 | #include "nm-utils.h" | ||
33 | |||
34 | G_DEFINE_TYPE (NMModemGsmMbm, nm_modem_gsm_mbm, NM_TYPE_MODEM_GSM) | ||
35 | |||
36 | #define NM_MODEM_GSM_MBM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GSM_MBM, NMModemGsmMbmPrivate)) | ||
37 | |||
38 | typedef struct { | ||
39 | char *netdev_iface; | ||
40 | NMIP4Config *pending_ip4_config; | ||
41 | } NMModemGsmMbmPrivate; | ||
42 | |||
43 | #define MBM_SECRETS_TRIES "gsm-secrets-tries" | ||
44 | |||
45 | static char * | ||
46 | get_network_device (NMDevice *device) | ||
47 | { | ||
48 | char *result = NULL; | ||
49 | GError *error = NULL; | ||
50 | GValue value = { 0, }; | ||
51 | |||
52 | if (!dbus_g_proxy_call (nm_modem_get_proxy (NM_MODEM (device), "org.freedesktop.DBus.Properties"), | ||
53 | "Get", &error, | ||
54 | G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM_GSM_MBM, | ||
55 | G_TYPE_STRING, "NetworkDevice", | ||
56 | G_TYPE_INVALID, | ||
57 | G_TYPE_VALUE, &value, | ||
58 | G_TYPE_INVALID)) { | ||
59 | nm_warning ("Could not get MBM device's network interface: %s", error->message); | ||
60 | g_error_free (error); | ||
61 | } else { | ||
62 | if (G_VALUE_HOLDS_STRING (&value)) | ||
63 | result = g_value_dup_string (&value); | ||
64 | else | ||
65 | nm_warning ("Could not get MBM device's network interface: wrong type '%s'", | ||
66 | G_VALUE_TYPE_NAME (&value)); | ||
67 | |||
68 | g_value_unset (&value); | ||
69 | } | ||
70 | |||
71 | return result; | ||
72 | } | ||
73 | |||
74 | NMDevice * | ||
75 | nm_modem_gsm_mbm_new (const char *path, | ||
76 | const char *data_device, | ||
77 | const char *driver) | ||
78 | { | ||
79 | NMDevice *device; | ||
80 | |||
81 | g_return_val_if_fail (path != NULL, NULL); | ||
82 | g_return_val_if_fail (data_device != NULL, NULL); | ||
83 | g_return_val_if_fail (driver != NULL, NULL); | ||
84 | |||
85 | device = (NMDevice *) g_object_new (NM_TYPE_MODEM_GSM_MBM, | ||
86 | NM_DEVICE_INTERFACE_UDI, path, | ||
87 | NM_DEVICE_INTERFACE_IFACE, data_device, | ||
88 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
89 | NM_DEVICE_INTERFACE_MANAGED, TRUE, | ||
90 | NM_MODEM_PATH, path, | ||
91 | NULL); | ||
92 | |||
93 | if (device) { | ||
94 | NMModemGsmMbmPrivate *priv; | ||
95 | |||
96 | priv = NM_MODEM_GSM_MBM_GET_PRIVATE (device); | ||
97 | priv->netdev_iface = get_network_device (device); | ||
98 | if (!priv->netdev_iface) { | ||
99 | g_object_unref (device); | ||
100 | device = NULL; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | return device; | ||
105 | } | ||
106 | |||
107 | /*****************************************************************************/ | ||
108 | |||
109 | #if 0 | ||
110 | static NMSetting * | ||
111 | get_setting (NMModemGsmMbm *modem, GType setting_type) | ||
112 | { | ||
113 | NMActRequest *req; | ||
114 | NMSetting *setting = NULL; | ||
115 | |||
116 | req = nm_device_get_act_request (NM_DEVICE (modem)); | ||
117 | if (req) { | ||
118 | NMConnection *connection; | ||
119 | |||
120 | connection = nm_act_request_get_connection (req); | ||
121 | if (connection) | ||
122 | setting = nm_connection_get_setting (connection, setting_type); | ||
123 | } | ||
124 | |||
125 | return setting; | ||
126 | } | ||
127 | #endif | ||
128 | |||
129 | #if 0 | ||
130 | static NMActStageReturn | ||
131 | real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) | ||
132 | { | ||
133 | NMActRequest *req; | ||
134 | NMConnection *connection; | ||
135 | const char *setting_name; | ||
136 | GPtrArray *hints = NULL; | ||
137 | const char *hint1 = NULL, *hint2 = NULL; | ||
138 | guint32 tries; | ||
139 | |||
140 | req = nm_device_get_act_request (device); | ||
141 | g_assert (req); | ||
142 | connection = nm_act_request_get_connection (req); | ||
143 | g_assert (connection); | ||
144 | |||
145 | setting_name = nm_connection_need_secrets (connection, &hints); | ||
146 | if (!setting_name) { | ||
147 | // do_mbm_auth (NM_MODEM_GSM_MBM (device)); | ||
148 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
149 | } | ||
150 | |||
151 | if (hints) { | ||
152 | if (hints->len > 0) | ||
153 | hint1 = g_ptr_array_index (hints, 0); | ||
154 | if (hints->len > 1) | ||
155 | hint2 = g_ptr_array_index (hints, 1); | ||
156 | } | ||
157 | |||
158 | nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
159 | |||
160 | tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), MBM_SECRETS_TRIES)); | ||
161 | nm_act_request_request_connection_secrets (req, | ||
162 | setting_name, | ||
163 | tries ? TRUE : FALSE, | ||
164 | SECRETS_CALLER_MBM_GSM, | ||
165 | hint1, | ||
166 | hint2); | ||
167 | g_object_set_data (G_OBJECT (connection), MBM_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); | ||
168 | |||
169 | if (hints) | ||
170 | g_ptr_array_free (hints, TRUE); | ||
171 | |||
172 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | static void | ||
177 | real_deactivate (NMDevice *device) | ||
178 | { | ||
179 | NMModemGsmMbmPrivate *priv = NM_MODEM_GSM_MBM_GET_PRIVATE (device); | ||
180 | |||
181 | if (priv->pending_ip4_config) { | ||
182 | g_object_unref (priv->pending_ip4_config); | ||
183 | priv->pending_ip4_config = NULL; | ||
184 | } | ||
185 | |||
186 | if (priv->netdev_iface) { | ||
187 | nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface); | ||
188 | nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface); | ||
189 | nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL); | ||
190 | } | ||
191 | nm_device_set_ip_iface (device, NULL); | ||
192 | |||
193 | if (NM_DEVICE_CLASS (nm_modem_gsm_mbm_parent_class)->deactivate) | ||
194 | NM_DEVICE_CLASS (nm_modem_gsm_mbm_parent_class)->deactivate (device); | ||
195 | } | ||
196 | |||
197 | static gboolean | ||
198 | real_hw_is_up (NMDevice *device) | ||
199 | { | ||
200 | NMModemGsmMbmPrivate *priv = NM_MODEM_GSM_MBM_GET_PRIVATE (device); | ||
201 | |||
202 | if (priv->netdev_iface) | ||
203 | return nm_system_device_is_up_with_iface (priv->netdev_iface); | ||
204 | |||
205 | return TRUE; | ||
206 | } | ||
207 | |||
208 | static gboolean | ||
209 | real_hw_bring_up (NMDevice *device, gboolean *no_firmware) | ||
210 | { | ||
211 | NMModemGsmMbmPrivate *priv = NM_MODEM_GSM_MBM_GET_PRIVATE (device); | ||
212 | |||
213 | if (priv->netdev_iface) | ||
214 | return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware); | ||
215 | |||
216 | return TRUE; | ||
217 | } | ||
218 | |||
219 | static void | ||
220 | real_connect (NMModem *modem, const char *number) | ||
221 | { | ||
222 | nm_device_activate_schedule_stage2_device_config (NM_DEVICE (modem)); | ||
223 | } | ||
224 | |||
225 | /*****************************************************************************/ | ||
226 | |||
227 | static void | ||
228 | nm_modem_gsm_mbm_init (NMModemGsmMbm *self) | ||
229 | { | ||
230 | } | ||
231 | |||
232 | static void | ||
233 | finalize (GObject *object) | ||
234 | { | ||
235 | NMModemGsmMbmPrivate *priv = NM_MODEM_GSM_MBM_GET_PRIVATE (object); | ||
236 | |||
237 | g_free (priv->netdev_iface); | ||
238 | |||
239 | G_OBJECT_CLASS (nm_modem_gsm_mbm_parent_class)->finalize (object); | ||
240 | } | ||
241 | |||
242 | static void | ||
243 | nm_modem_gsm_mbm_class_init (NMModemGsmMbmClass *klass) | ||
244 | { | ||
245 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
246 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
247 | NMModemClass *modem_class = NM_MODEM_CLASS (klass); | ||
248 | |||
249 | g_type_class_add_private (object_class, sizeof (NMModemGsmMbmPrivate)); | ||
250 | |||
251 | object_class->finalize = finalize; | ||
252 | |||
253 | #if 0 | ||
254 | device_class->act_stage2_config = real_act_stage2_config; | ||
255 | #endif | ||
256 | device_class->deactivate = real_deactivate; | ||
257 | device_class->hw_is_up = real_hw_is_up; | ||
258 | device_class->hw_bring_up = real_hw_bring_up; | ||
259 | |||
260 | modem_class->connect = real_connect; | ||
261 | } | ||
diff --git a/src/modem-manager/nm-modem-gsm-mbm.h b/src/modem-manager/nm-modem-gsm-mbm.h new file mode 100644 index 0000000000..9bd4b3a7da --- /dev/null +++ b/src/modem-manager/nm-modem-gsm-mbm.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* | ||
3 | Additions to NetworkManager, network-manager-applet and modemmanager | ||
4 | for supporting Ericsson modules like F3507g. | ||
5 | |||
6 | Author: Per Hallsmark <per@hallsmark.se> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | |||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #ifndef NM_MODEM_GSM_MBM_H | ||
26 | #define NM_MODEM_GSM_MBM_H | ||
27 | |||
28 | #include <nm-modem-gsm.h> | ||
29 | |||
30 | G_BEGIN_DECLS | ||
31 | |||
32 | #define NM_TYPE_MODEM_GSM_MBM (nm_modem_gsm_mbm_get_type ()) | ||
33 | #define NM_MODEM_GSM_MBM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GSM_MBM, NMModemGsmMbm)) | ||
34 | #define NM_MODEM_GSM_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GSM_MBM, NMModemGsmMbmClass)) | ||
35 | #define NM_IS_MODEM_GSM_MBM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GSM_MBM)) | ||
36 | #define NM_IS_MODEM_GSM_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GSM_MBM)) | ||
37 | #define NM_MODEM_GSM_MBM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM_MBM, NMModemGsmMbmClass)) | ||
38 | |||
39 | typedef struct { | ||
40 | NMModemGsm parent; | ||
41 | } NMModemGsmMbm; | ||
42 | |||
43 | typedef struct { | ||
44 | NMModemGsmClass parent; | ||
45 | } NMModemGsmMbmClass; | ||
46 | |||
47 | GType nm_modem_gsm_mbm_get_type (void); | ||
48 | |||
49 | NMDevice *nm_modem_gsm_mbm_new (const char *path, | ||
50 | const char *data_device, | ||
51 | const char *driver); | ||
52 | |||
53 | G_END_DECLS | ||
54 | |||
55 | #endif /* NM_MODEM_GSM_MBM_H */ | ||
diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c new file mode 100644 index 0000000000..15231797e6 --- /dev/null +++ b/src/modem-manager/nm-modem-gsm.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #include <string.h> | ||
4 | #include "nm-modem-gsm.h" | ||
5 | #include "nm-device-private.h" | ||
6 | #include "nm-device-interface.h" | ||
7 | #include "nm-setting-connection.h" | ||
8 | #include "nm-setting-gsm.h" | ||
9 | #include "nm-modem-types.h" | ||
10 | #include "nm-utils.h" | ||
11 | |||
12 | #include "nm-device-gsm-glue.h" | ||
13 | |||
14 | G_DEFINE_TYPE (NMModemGsm, nm_modem_gsm, NM_TYPE_MODEM) | ||
15 | |||
16 | #define NM_MODEM_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_GSM, NMModemGsmPrivate)) | ||
17 | |||
18 | enum { | ||
19 | MODEM_STATE_BEGIN, | ||
20 | MODEM_STATE_ENABLE, | ||
21 | MODEM_STATE_SET_PIN, | ||
22 | MODEM_STATE_SET_APN, | ||
23 | MODEM_STATE_SET_BAND, | ||
24 | MODEM_STATE_SET_NETWORK_MODE, | ||
25 | MODEM_STATE_REGISTER, | ||
26 | MODEM_STATE_FAILED, | ||
27 | }; | ||
28 | |||
29 | typedef struct { | ||
30 | int modem_state; | ||
31 | } NMModemGsmPrivate; | ||
32 | |||
33 | NMDevice * | ||
34 | nm_modem_gsm_new (const char *path, | ||
35 | const char *data_device, | ||
36 | const char *driver) | ||
37 | { | ||
38 | g_return_val_if_fail (path != NULL, NULL); | ||
39 | g_return_val_if_fail (data_device != NULL, NULL); | ||
40 | g_return_val_if_fail (driver != NULL, NULL); | ||
41 | |||
42 | return (NMDevice *) g_object_new (NM_TYPE_MODEM_GSM, | ||
43 | NM_DEVICE_INTERFACE_UDI, path, | ||
44 | NM_DEVICE_INTERFACE_IFACE, data_device, | ||
45 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
46 | NM_DEVICE_INTERFACE_MANAGED, TRUE, | ||
47 | NM_MODEM_PATH, path, | ||
48 | NULL); | ||
49 | } | ||
50 | |||
51 | static NMSetting * | ||
52 | get_setting (NMModemGsm *modem, GType setting_type) | ||
53 | { | ||
54 | NMActRequest *req; | ||
55 | NMSetting *setting = NULL; | ||
56 | |||
57 | req = nm_device_get_act_request (NM_DEVICE (modem)); | ||
58 | if (req) { | ||
59 | NMConnection *connection; | ||
60 | |||
61 | connection = nm_act_request_get_connection (req); | ||
62 | if (connection) | ||
63 | setting = nm_connection_get_setting (connection, setting_type); | ||
64 | } | ||
65 | |||
66 | return setting; | ||
67 | } | ||
68 | |||
69 | #define get_proxy(dev,iface) (nm_modem_get_proxy(NM_MODEM (dev), iface)) | ||
70 | |||
71 | static void | ||
72 | state_machine (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) | ||
73 | { | ||
74 | NMModemGsm *modem = NM_MODEM_GSM (user_data); | ||
75 | NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (modem); | ||
76 | NMSettingGsm *setting; | ||
77 | const char *secret = NULL; | ||
78 | const char *secret_name = NULL; | ||
79 | const char *str; | ||
80 | GError *error = NULL; | ||
81 | int i; | ||
82 | gboolean retry_secret = FALSE; | ||
83 | |||
84 | setting = NM_SETTING_GSM (get_setting (modem, NM_TYPE_SETTING_GSM)); | ||
85 | |||
86 | if (call_id) | ||
87 | dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID); | ||
88 | |||
89 | if (error) { | ||
90 | g_debug ("%s", dbus_g_error_get_name (error)); | ||
91 | |||
92 | if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PIN)) { | ||
93 | secret = nm_setting_gsm_get_pin (setting); | ||
94 | secret_name = NM_SETTING_GSM_PIN; | ||
95 | priv->modem_state = MODEM_STATE_SET_PIN; | ||
96 | } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_PUK)) { | ||
97 | secret = nm_setting_gsm_get_puk (setting); | ||
98 | secret_name = NM_SETTING_GSM_PUK; | ||
99 | priv->modem_state = MODEM_STATE_SET_PIN; | ||
100 | } else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_SIM_WRONG)) { | ||
101 | g_object_set (setting, NM_SETTING_GSM_PIN, NULL, NULL); | ||
102 | secret_name = NM_SETTING_GSM_PIN; | ||
103 | retry_secret = TRUE; | ||
104 | priv->modem_state = MODEM_STATE_SET_PIN; | ||
105 | } | ||
106 | |||
107 | /* FIXME: Hacks to ignore failures of setting band and network mode for now | ||
108 | since only Huawei module supports it. Remove when ModemManager rules. | ||
109 | */ | ||
110 | else if (dbus_g_error_has_name (error, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED) && | ||
111 | (priv->modem_state == MODEM_STATE_SET_BAND || | ||
112 | priv->modem_state == MODEM_STATE_SET_NETWORK_MODE)) { | ||
113 | |||
114 | nm_warning ("Modem does not support setting %s, ignoring", | ||
115 | priv->modem_state == MODEM_STATE_SET_BAND ? "band" : "network mode"); | ||
116 | } else { | ||
117 | priv->modem_state = MODEM_STATE_FAILED; | ||
118 | nm_warning ("GSM modem connection failed: %s", error->message); | ||
119 | } | ||
120 | |||
121 | g_error_free (error); | ||
122 | } | ||
123 | |||
124 | again: | ||
125 | |||
126 | switch (priv->modem_state) { | ||
127 | case MODEM_STATE_BEGIN: | ||
128 | priv->modem_state = MODEM_STATE_ENABLE; | ||
129 | dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM), | ||
130 | "Enable", state_machine, | ||
131 | modem, NULL, | ||
132 | G_TYPE_BOOLEAN, TRUE, | ||
133 | G_TYPE_INVALID); | ||
134 | break; | ||
135 | |||
136 | case MODEM_STATE_SET_PIN: | ||
137 | if (secret) { | ||
138 | priv->modem_state = MODEM_STATE_ENABLE; | ||
139 | dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_CARD), | ||
140 | "SendPin", state_machine, | ||
141 | modem, NULL, | ||
142 | G_TYPE_STRING, secret, | ||
143 | G_TYPE_INVALID); | ||
144 | } else { | ||
145 | nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
146 | nm_act_request_request_connection_secrets (nm_device_get_act_request (NM_DEVICE (modem)), | ||
147 | NM_SETTING_GSM_SETTING_NAME, | ||
148 | retry_secret, | ||
149 | SECRETS_CALLER_GSM, | ||
150 | secret_name, | ||
151 | NULL); | ||
152 | |||
153 | } | ||
154 | break; | ||
155 | |||
156 | case MODEM_STATE_ENABLE: | ||
157 | priv->modem_state = MODEM_STATE_SET_APN; | ||
158 | str = nm_setting_gsm_get_apn (setting); | ||
159 | |||
160 | if (str) | ||
161 | dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK), | ||
162 | "SetApn", state_machine, | ||
163 | modem, NULL, | ||
164 | G_TYPE_STRING, str, | ||
165 | G_TYPE_INVALID); | ||
166 | else | ||
167 | goto again; | ||
168 | |||
169 | break; | ||
170 | case MODEM_STATE_SET_APN: | ||
171 | priv->modem_state = MODEM_STATE_SET_BAND; | ||
172 | i = nm_setting_gsm_get_band (setting); | ||
173 | |||
174 | if (i) | ||
175 | dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK), | ||
176 | "SetBand", state_machine, | ||
177 | modem, NULL, | ||
178 | G_TYPE_UINT, (guint32) i, | ||
179 | G_TYPE_INVALID); | ||
180 | else | ||
181 | goto again; | ||
182 | |||
183 | break; | ||
184 | |||
185 | case MODEM_STATE_SET_BAND: | ||
186 | priv->modem_state = MODEM_STATE_SET_NETWORK_MODE; | ||
187 | i = nm_setting_gsm_get_network_type (setting); | ||
188 | |||
189 | if (i) | ||
190 | dbus_g_proxy_begin_call (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK), | ||
191 | "SetNetworkMode", state_machine, | ||
192 | modem, NULL, | ||
193 | G_TYPE_UINT, (guint32) i, | ||
194 | G_TYPE_INVALID); | ||
195 | else | ||
196 | goto again; | ||
197 | |||
198 | break; | ||
199 | |||
200 | case MODEM_STATE_SET_NETWORK_MODE: | ||
201 | priv->modem_state = MODEM_STATE_REGISTER; | ||
202 | |||
203 | str = nm_setting_gsm_get_network_id (setting); | ||
204 | dbus_g_proxy_begin_call_with_timeout (get_proxy (modem, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK), | ||
205 | "Register", state_machine, | ||
206 | modem, NULL, 120000, | ||
207 | G_TYPE_STRING, str ? str : "", | ||
208 | G_TYPE_INVALID); | ||
209 | break; | ||
210 | |||
211 | case MODEM_STATE_REGISTER: | ||
212 | nm_modem_connect (NM_MODEM (modem), nm_setting_gsm_get_number (setting)); | ||
213 | break; | ||
214 | case MODEM_STATE_FAILED: | ||
215 | default: | ||
216 | nm_device_state_changed (NM_DEVICE (modem), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static NMActStageReturn | ||
222 | real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) | ||
223 | { | ||
224 | NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (device); | ||
225 | |||
226 | priv->modem_state = MODEM_STATE_BEGIN; | ||
227 | state_machine (NULL, NULL, device); | ||
228 | |||
229 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
230 | } | ||
231 | |||
232 | static NMConnection * | ||
233 | real_get_best_auto_connection (NMDevice *dev, | ||
234 | GSList *connections, | ||
235 | char **specific_object) | ||
236 | { | ||
237 | GSList *iter; | ||
238 | |||
239 | for (iter = connections; iter; iter = g_slist_next (iter)) { | ||
240 | NMConnection *connection = NM_CONNECTION (iter->data); | ||
241 | NMSettingConnection *s_con; | ||
242 | |||
243 | s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); | ||
244 | g_assert (s_con); | ||
245 | |||
246 | if (!nm_setting_connection_get_autoconnect (s_con)) | ||
247 | continue; | ||
248 | |||
249 | if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME)) | ||
250 | continue; | ||
251 | |||
252 | return connection; | ||
253 | } | ||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | static void | ||
258 | real_connection_secrets_updated (NMDevice *dev, | ||
259 | NMConnection *connection, | ||
260 | GSList *updated_settings, | ||
261 | RequestSecretsCaller caller) | ||
262 | { | ||
263 | NMActRequest *req; | ||
264 | gboolean found = FALSE; | ||
265 | GSList *iter; | ||
266 | |||
267 | if (caller == SECRETS_CALLER_PPP) { | ||
268 | NMPPPManager *ppp_manager; | ||
269 | NMSettingGsm *s_gsm = NULL; | ||
270 | |||
271 | ppp_manager = nm_modem_get_ppp_manager (NM_MODEM (dev)); | ||
272 | g_return_if_fail (ppp_manager != NULL); | ||
273 | |||
274 | s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); | ||
275 | if (!s_gsm) { | ||
276 | /* Shouldn't ever happen */ | ||
277 | nm_ppp_manager_update_secrets (ppp_manager, | ||
278 | nm_device_get_iface (dev), | ||
279 | NULL, | ||
280 | NULL, | ||
281 | "missing GSM setting; no secrets could be found."); | ||
282 | } else { | ||
283 | const char *username = nm_setting_gsm_get_username (s_gsm); | ||
284 | const char *password = nm_setting_gsm_get_password (s_gsm); | ||
285 | |||
286 | nm_ppp_manager_update_secrets (ppp_manager, | ||
287 | nm_device_get_iface (dev), | ||
288 | username ? username : "", | ||
289 | password ? password : "", | ||
290 | NULL); | ||
291 | } | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | g_return_if_fail (caller == SECRETS_CALLER_GSM); | ||
296 | g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); | ||
297 | |||
298 | for (iter = updated_settings; iter; iter = g_slist_next (iter)) { | ||
299 | const char *setting_name = (const char *) iter->data; | ||
300 | |||
301 | if (!strcmp (setting_name, NM_SETTING_GSM_SETTING_NAME)) | ||
302 | found = TRUE; | ||
303 | else | ||
304 | nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); | ||
305 | } | ||
306 | |||
307 | if (!found) | ||
308 | return; | ||
309 | |||
310 | req = nm_device_get_act_request (dev); | ||
311 | g_assert (req); | ||
312 | |||
313 | g_return_if_fail (nm_act_request_get_connection (req) == connection); | ||
314 | |||
315 | nm_device_activate_schedule_stage1_device_prepare (dev); | ||
316 | } | ||
317 | |||
318 | static const char * | ||
319 | real_get_ppp_name (NMModem *device, NMConnection *connection) | ||
320 | { | ||
321 | NMSettingGsm *s_gsm; | ||
322 | |||
323 | s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); | ||
324 | g_assert (s_gsm); | ||
325 | |||
326 | return nm_setting_gsm_get_username (s_gsm); | ||
327 | } | ||
328 | |||
329 | /*****************************************************************************/ | ||
330 | |||
331 | static void | ||
332 | nm_modem_gsm_init (NMModemGsm *self) | ||
333 | { | ||
334 | nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_GSM); | ||
335 | } | ||
336 | |||
337 | static void | ||
338 | nm_modem_gsm_class_init (NMModemGsmClass *klass) | ||
339 | { | ||
340 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
341 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
342 | NMModemClass *modem_class = NM_MODEM_CLASS (klass); | ||
343 | |||
344 | g_type_class_add_private (object_class, sizeof (NMModemGsmPrivate)); | ||
345 | |||
346 | /* Virtual methods */ | ||
347 | device_class->get_best_auto_connection = real_get_best_auto_connection; | ||
348 | device_class->connection_secrets_updated = real_connection_secrets_updated; | ||
349 | device_class->act_stage1_prepare = real_act_stage1_prepare; | ||
350 | modem_class->get_ppp_name = real_get_ppp_name; | ||
351 | |||
352 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
353 | &dbus_glib_nm_device_gsm_object_info); | ||
354 | } | ||
diff --git a/src/modem-manager/nm-modem-gsm.h b/src/modem-manager/nm-modem-gsm.h new file mode 100644 index 0000000000..50f08548e7 --- /dev/null +++ b/src/modem-manager/nm-modem-gsm.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_GSM_H | ||
4 | #define NM_MODEM_GSM_H | ||
5 | |||
6 | #include <nm-modem.h> | ||
7 | |||
8 | G_BEGIN_DECLS | ||
9 | |||
10 | #define NM_TYPE_MODEM_GSM (nm_modem_gsm_get_type ()) | ||
11 | #define NM_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_GSM, NMModemGsm)) | ||
12 | #define NM_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_GSM, NMModemGsmClass)) | ||
13 | #define NM_IS_MODEM_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_GSM)) | ||
14 | #define NM_IS_MODEM_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_GSM)) | ||
15 | #define NM_MODEM_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_GSM, NMModemGsmClass)) | ||
16 | |||
17 | typedef struct { | ||
18 | NMModem parent; | ||
19 | } NMModemGsm; | ||
20 | |||
21 | typedef struct { | ||
22 | NMModemClass parent; | ||
23 | |||
24 | /* Signals */ | ||
25 | void (*signal_quality) (NMModemGsm *self, guint32 quality); | ||
26 | } NMModemGsmClass; | ||
27 | |||
28 | GType nm_modem_gsm_get_type (void); | ||
29 | |||
30 | NMDevice *nm_modem_gsm_new (const char *path, | ||
31 | const char *data_device, | ||
32 | const char *driver); | ||
33 | |||
34 | G_END_DECLS | ||
35 | |||
36 | #endif /* NM_MODEM_GSM_H */ | ||
diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c new file mode 100644 index 0000000000..85aaf713c4 --- /dev/null +++ b/src/modem-manager/nm-modem-manager.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #include <string.h> | ||
4 | #include "nm-modem-manager.h" | ||
5 | #include "nm-modem.h" | ||
6 | #include "nm-modem-gsm.h" | ||
7 | #include "nm-modem-gsm-hso.h" | ||
8 | #include "nm-modem-gsm-mbm.h" | ||
9 | #include "nm-modem-cdma.h" | ||
10 | #include "nm-dbus-manager.h" | ||
11 | #include "nm-utils.h" | ||
12 | #include "nm-modem-types.h" | ||
13 | |||
14 | #define MODEM_POKE_INTERVAL 120000 | ||
15 | |||
16 | G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) | ||
17 | |||
18 | #define NM_MODEM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_MANAGER, NMModemManagerPrivate)) | ||
19 | |||
20 | typedef struct { | ||
21 | NMDBusManager *dbus_mgr; | ||
22 | DBusGProxy *proxy; | ||
23 | GHashTable *modems; | ||
24 | gboolean disposed; | ||
25 | guint poke_id; | ||
26 | } NMModemManagerPrivate; | ||
27 | |||
28 | enum { | ||
29 | DEVICE_ADDED, | ||
30 | DEVICE_REMOVED, | ||
31 | |||
32 | LAST_SIGNAL | ||
33 | }; | ||
34 | |||
35 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
36 | |||
37 | |||
38 | NMModemManager * | ||
39 | nm_modem_manager_get (void) | ||
40 | { | ||
41 | static NMModemManager *singleton = NULL; | ||
42 | |||
43 | if (!singleton) | ||
44 | singleton = NM_MODEM_MANAGER (g_object_new (NM_TYPE_MODEM_MANAGER, NULL)); | ||
45 | else | ||
46 | g_object_ref (singleton); | ||
47 | |||
48 | g_assert (singleton); | ||
49 | return singleton; | ||
50 | } | ||
51 | |||
52 | static gboolean | ||
53 | get_modem_properties (DBusGConnection *connection, | ||
54 | const char *path, | ||
55 | char **data_device, | ||
56 | char **driver, | ||
57 | guint32 *type) | ||
58 | { | ||
59 | DBusGProxy *proxy; | ||
60 | GValue value = { 0 }; | ||
61 | GError *err = NULL; | ||
62 | |||
63 | proxy = dbus_g_proxy_new_for_name (connection, | ||
64 | MM_DBUS_SERVICE, | ||
65 | path, | ||
66 | "org.freedesktop.DBus.Properties"); | ||
67 | |||
68 | if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, | ||
69 | G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, | ||
70 | G_TYPE_STRING, "Type", | ||
71 | G_TYPE_INVALID, | ||
72 | G_TYPE_VALUE, &value, | ||
73 | G_TYPE_INVALID)) { | ||
74 | *type = g_value_get_uint (&value); | ||
75 | g_value_unset (&value); | ||
76 | } else { | ||
77 | g_warning ("Could not get device type: %s", err->message); | ||
78 | goto out; | ||
79 | } | ||
80 | |||
81 | if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, | ||
82 | G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, | ||
83 | G_TYPE_STRING, "DataDevice", | ||
84 | G_TYPE_INVALID, | ||
85 | G_TYPE_VALUE, &value, | ||
86 | G_TYPE_INVALID)) { | ||
87 | *data_device = g_value_dup_string (&value); | ||
88 | g_value_unset (&value); | ||
89 | } else { | ||
90 | g_warning ("Could not get modem data device: %s", err->message); | ||
91 | goto out; | ||
92 | } | ||
93 | |||
94 | if (dbus_g_proxy_call_with_timeout (proxy, "Get", 15000, &err, | ||
95 | G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM, | ||
96 | G_TYPE_STRING, "Driver", | ||
97 | G_TYPE_INVALID, | ||
98 | G_TYPE_VALUE, &value, | ||
99 | G_TYPE_INVALID)) { | ||
100 | *driver = g_value_dup_string (&value); | ||
101 | g_value_unset (&value); | ||
102 | } else { | ||
103 | g_warning ("Could not get modem driver: %s", err->message); | ||
104 | goto out; | ||
105 | } | ||
106 | |||
107 | out: | ||
108 | if (err) | ||
109 | g_error_free (err); | ||
110 | |||
111 | g_object_unref (proxy); | ||
112 | |||
113 | return *data_device && *driver; | ||
114 | } | ||
115 | |||
116 | static void | ||
117 | create_modem (NMModemManager *manager, const char *path) | ||
118 | { | ||
119 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (manager); | ||
120 | NMDevice *device; | ||
121 | char *data_device = NULL; | ||
122 | char *driver = NULL; | ||
123 | uint modem_type = MM_MODEM_TYPE_UNKNOWN; | ||
124 | |||
125 | if (g_hash_table_lookup (priv->modems, path)) { | ||
126 | nm_warning ("Modem with path %s already exists, ignoring", path); | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | if (!get_modem_properties (nm_dbus_manager_get_connection (priv->dbus_mgr), path, | ||
131 | &data_device, &driver, &modem_type)) | ||
132 | return; | ||
133 | |||
134 | if (modem_type == MM_MODEM_TYPE_UNKNOWN) { | ||
135 | nm_warning ("Modem with path %s has unknown type, ignoring", path); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | if (!driver || !strlen (driver)) { | ||
140 | nm_warning ("Modem with path %s has unknown driver, ignoring", path); | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | if (!data_device || !strlen (data_device)) { | ||
145 | nm_warning ("Modem with path %s has unknown data device, ignoring", path); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | if (modem_type == MM_MODEM_TYPE_GSM) { | ||
150 | if (!strcmp (driver, "hso")) | ||
151 | device = nm_modem_gsm_hso_new (path, data_device, driver); | ||
152 | else if (!strcmp (driver, "mbm")) | ||
153 | device = nm_modem_gsm_mbm_new (path, data_device, driver); | ||
154 | else | ||
155 | device = nm_modem_gsm_new (path, data_device, driver); | ||
156 | } else if (modem_type == MM_MODEM_TYPE_CDMA) | ||
157 | device = nm_modem_cdma_new (path, data_device, driver); | ||
158 | else | ||
159 | g_error ("Invalid modem type"); | ||
160 | |||
161 | g_free (data_device); | ||
162 | g_free (driver); | ||
163 | |||
164 | if (device) { | ||
165 | g_hash_table_insert (priv->modems, g_strdup (path), device); | ||
166 | g_signal_emit (manager, signals[DEVICE_ADDED], 0, device); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | modem_added (DBusGProxy *proxy, const char *path, gpointer user_data) | ||
172 | { | ||
173 | create_modem (NM_MODEM_MANAGER (user_data), path); | ||
174 | } | ||
175 | |||
176 | static void | ||
177 | modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) | ||
178 | { | ||
179 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (user_data); | ||
180 | NMModem *modem; | ||
181 | |||
182 | modem = (NMModem *) g_hash_table_lookup (priv->modems, path); | ||
183 | if (modem) { | ||
184 | g_signal_emit (user_data, signals[DEVICE_REMOVED], 0, modem); | ||
185 | g_hash_table_remove (priv->modems, path); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static gboolean | ||
190 | poke_modem_cb (gpointer user_data) | ||
191 | { | ||
192 | NMModemManager *self = NM_MODEM_MANAGER (user_data); | ||
193 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); | ||
194 | DBusGConnection *g_connection; | ||
195 | DBusGProxy *proxy; | ||
196 | |||
197 | g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); | ||
198 | proxy = dbus_g_proxy_new_for_name (g_connection, | ||
199 | MM_DBUS_SERVICE, | ||
200 | MM_DBUS_PATH, | ||
201 | MM_DBUS_INTERFACE); | ||
202 | |||
203 | nm_info ("Trying to start the modem-manager..."); | ||
204 | dbus_g_proxy_call_no_reply (proxy, "EnumerateDevices", G_TYPE_INVALID); | ||
205 | g_object_unref (proxy); | ||
206 | |||
207 | return TRUE; | ||
208 | } | ||
209 | |||
210 | static void | ||
211 | enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data) | ||
212 | { | ||
213 | NMModemManager *manager = NM_MODEM_MANAGER (data); | ||
214 | GPtrArray *modems; | ||
215 | GError *error = NULL; | ||
216 | |||
217 | if (!dbus_g_proxy_end_call (proxy, call_id, &error, | ||
218 | dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems, | ||
219 | G_TYPE_INVALID)) { | ||
220 | nm_warning ("Could not get modem list: %s", error->message); | ||
221 | g_error_free (error); | ||
222 | } else { | ||
223 | int i; | ||
224 | |||
225 | for (i = 0; i < modems->len; i++) { | ||
226 | char *path = (char *) g_ptr_array_index (modems, i); | ||
227 | |||
228 | create_modem (manager, path); | ||
229 | g_free (path); | ||
230 | } | ||
231 | |||
232 | g_ptr_array_free (modems, TRUE); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static void | ||
237 | modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices) | ||
238 | { | ||
239 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); | ||
240 | |||
241 | if (priv->poke_id) { | ||
242 | g_source_remove (priv->poke_id); | ||
243 | priv->poke_id = 0; | ||
244 | } | ||
245 | |||
246 | priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), | ||
247 | MM_DBUS_SERVICE, MM_DBUS_PATH, MM_DBUS_INTERFACE); | ||
248 | |||
249 | dbus_g_proxy_add_signal (priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID); | ||
250 | dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded", | ||
251 | G_CALLBACK (modem_added), self, | ||
252 | NULL); | ||
253 | |||
254 | dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID); | ||
255 | dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved", | ||
256 | G_CALLBACK (modem_removed), self, | ||
257 | NULL); | ||
258 | |||
259 | if (enumerate_devices) | ||
260 | dbus_g_proxy_begin_call (priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); | ||
261 | } | ||
262 | |||
263 | static gboolean | ||
264 | remove_one_modem (gpointer key, gpointer value, gpointer user_data) | ||
265 | { | ||
266 | g_signal_emit (user_data, signals[DEVICE_REMOVED], 0, value); | ||
267 | |||
268 | return TRUE; | ||
269 | } | ||
270 | |||
271 | static void | ||
272 | modem_manager_disappeared (NMModemManager *self) | ||
273 | { | ||
274 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); | ||
275 | |||
276 | g_hash_table_foreach_remove (priv->modems, remove_one_modem, self); | ||
277 | |||
278 | if (priv->proxy) { | ||
279 | g_object_unref (priv->proxy); | ||
280 | priv->proxy = NULL; | ||
281 | } | ||
282 | |||
283 | /* Try to activate the modem-manager */ | ||
284 | poke_modem_cb (self); | ||
285 | priv->poke_id = g_timeout_add (MODEM_POKE_INTERVAL, poke_modem_cb, self); | ||
286 | } | ||
287 | |||
288 | static void | ||
289 | nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, | ||
290 | const char *name, | ||
291 | const char *old_owner, | ||
292 | const char *new_owner, | ||
293 | gpointer user_data) | ||
294 | { | ||
295 | gboolean old_owner_good; | ||
296 | gboolean new_owner_good; | ||
297 | |||
298 | /* Can't handle the signal if its not from the modem service */ | ||
299 | if (strcmp (MM_DBUS_SERVICE, name) != 0) | ||
300 | return; | ||
301 | |||
302 | old_owner_good = (old_owner && strlen (old_owner)); | ||
303 | new_owner_good = (new_owner && strlen (new_owner)); | ||
304 | |||
305 | if (!old_owner_good && new_owner_good) { | ||
306 | nm_info ("modem manager appeared"); | ||
307 | modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE); | ||
308 | } else if (old_owner_good && !new_owner_good) { | ||
309 | nm_info ("modem manager disappeared"); | ||
310 | modem_manager_disappeared (NM_MODEM_MANAGER (user_data)); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /*******************************************************/ | ||
315 | |||
316 | static void | ||
317 | nm_modem_manager_init (NMModemManager *self) | ||
318 | { | ||
319 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); | ||
320 | |||
321 | priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); | ||
322 | priv->dbus_mgr = nm_dbus_manager_get (); | ||
323 | |||
324 | g_signal_connect (priv->dbus_mgr, "name-owner-changed", | ||
325 | G_CALLBACK (nm_modem_manager_name_owner_changed), | ||
326 | self); | ||
327 | |||
328 | if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE)) | ||
329 | modem_manager_appeared (self, TRUE); | ||
330 | else | ||
331 | modem_manager_disappeared (self); | ||
332 | } | ||
333 | |||
334 | static void | ||
335 | dispose (GObject *object) | ||
336 | { | ||
337 | NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (object); | ||
338 | |||
339 | if (priv->disposed) | ||
340 | return; | ||
341 | |||
342 | priv->disposed = TRUE; | ||
343 | |||
344 | if (priv->poke_id) { | ||
345 | g_source_remove (priv->poke_id); | ||
346 | priv->poke_id = 0; | ||
347 | } | ||
348 | |||
349 | g_hash_table_foreach_remove (priv->modems, remove_one_modem, object); | ||
350 | g_hash_table_destroy (priv->modems); | ||
351 | |||
352 | if (priv->proxy) { | ||
353 | g_object_unref (priv->proxy); | ||
354 | priv->proxy = NULL; | ||
355 | } | ||
356 | |||
357 | if (priv->dbus_mgr) { | ||
358 | g_object_unref (priv->dbus_mgr); | ||
359 | priv->dbus_mgr = NULL; | ||
360 | } | ||
361 | |||
362 | /* Chain up to the parent class */ | ||
363 | G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object); | ||
364 | } | ||
365 | |||
366 | static void | ||
367 | nm_modem_manager_class_init (NMModemManagerClass *klass) | ||
368 | { | ||
369 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
370 | |||
371 | g_type_class_add_private (object_class, sizeof (NMModemManagerPrivate)); | ||
372 | |||
373 | object_class->dispose = dispose; | ||
374 | |||
375 | /* signals */ | ||
376 | signals[DEVICE_ADDED] = | ||
377 | g_signal_new ("device-added", | ||
378 | G_OBJECT_CLASS_TYPE (object_class), | ||
379 | G_SIGNAL_RUN_FIRST, | ||
380 | G_STRUCT_OFFSET (NMModemManagerClass, device_added), | ||
381 | NULL, NULL, | ||
382 | g_cclosure_marshal_VOID__OBJECT, | ||
383 | G_TYPE_NONE, 1, | ||
384 | G_TYPE_OBJECT); | ||
385 | |||
386 | signals[DEVICE_REMOVED] = | ||
387 | g_signal_new ("device-removed", | ||
388 | G_OBJECT_CLASS_TYPE (object_class), | ||
389 | G_SIGNAL_RUN_FIRST, | ||
390 | G_STRUCT_OFFSET (NMModemManagerClass, device_removed), | ||
391 | NULL, NULL, | ||
392 | g_cclosure_marshal_VOID__OBJECT, | ||
393 | G_TYPE_NONE, 1, | ||
394 | G_TYPE_OBJECT); | ||
395 | } | ||
diff --git a/src/modem-manager/nm-modem-manager.h b/src/modem-manager/nm-modem-manager.h new file mode 100644 index 0000000000..fb51f73988 --- /dev/null +++ b/src/modem-manager/nm-modem-manager.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_MANAGER_H | ||
4 | #define NM_MODEM_MANAGER_H | ||
5 | |||
6 | #include <glib-object.h> | ||
7 | #include "nm-device.h" | ||
8 | |||
9 | #define NM_TYPE_MODEM_MANAGER (nm_modem_manager_get_type ()) | ||
10 | #define NM_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_MANAGER, NMModemManager)) | ||
11 | #define NM_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) | ||
12 | #define NM_IS_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_MANAGER)) | ||
13 | #define NM_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_MANAGER)) | ||
14 | #define NM_MODEM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_MANAGER, NMModemManagerClass)) | ||
15 | |||
16 | typedef struct { | ||
17 | GObject parent; | ||
18 | } NMModemManager; | ||
19 | |||
20 | typedef struct { | ||
21 | GObjectClass parent; | ||
22 | |||
23 | /* Signals */ | ||
24 | void (*device_added) (NMModemManager *manager, | ||
25 | NMDevice *device); | ||
26 | |||
27 | void (*device_removed) (NMModemManager *manager, | ||
28 | NMDevice *device); | ||
29 | } NMModemManagerClass; | ||
30 | |||
31 | GType nm_modem_manager_get_type (void); | ||
32 | |||
33 | NMModemManager *nm_modem_manager_get (void); | ||
34 | |||
35 | #endif /* NM_MODEM_MANAGER_H */ | ||
diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h new file mode 100644 index 0000000000..4a5dad42ec --- /dev/null +++ b/src/modem-manager/nm-modem-types.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_TYPES_H | ||
4 | #define NM_MODEM_TYPES_H | ||
5 | |||
6 | #define MM_DBUS_SERVICE "org.freedesktop.ModemManager" | ||
7 | #define MM_DBUS_PATH "/org/freedesktop/ModemManager" | ||
8 | #define MM_DBUS_INTERFACE "org.freedesktop.ModemManager" | ||
9 | #define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" | ||
10 | #define MM_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma" | ||
11 | |||
12 | #define MM_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" | ||
13 | #define MM_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" | ||
14 | #define MM_DBUS_INTERFACE_MODEM_GSM_HSO "org.freedesktop.ModemManager.Modem.Gsm.Hso" | ||
15 | #define MM_DBUS_INTERFACE_MODEM_GSM_MBM "org.freedesktop.ModemManager.Modem.Gsm.Mbm" | ||
16 | |||
17 | #define MM_MODEM_TYPE_UNKNOWN 0 | ||
18 | #define MM_MODEM_TYPE_GSM 1 | ||
19 | #define MM_MODEM_TYPE_CDMA 2 | ||
20 | |||
21 | /* Errors */ | ||
22 | |||
23 | #define MM_SERIAL_OPEN_FAILED MM_DBUS_INTERFACE_MODEM ".SerialOpenFailed" | ||
24 | #define MM_SERIAL_SEND_FAILED MM_DBUS_INTERFACE_MODEM ".SerialSendFailed" | ||
25 | #define MM_SERIAL_RESPONSE_TIMEOUT MM_DBUS_INTERFACE_MODEM ".SerialResponseTimeout" | ||
26 | |||
27 | #define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".General" | ||
28 | #define MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED MM_DBUS_INTERFACE_MODEM ".OperationNotSupported" | ||
29 | |||
30 | #define MM_MODEM_CONNECT_ERROR_NO_CARRIER MM_DBUS_INTERFACE_MODEM ".NoCarrier" | ||
31 | #define MM_MODEM_CONNECT_ERROR_NO_DIALTONE MM_DBUS_INTERFACE_MODEM ".NoDialtone" | ||
32 | #define MM_MODEM_CONNECT_ERROR_BUSY MM_DBUS_INTERFACE_MODEM ".Busy" | ||
33 | #define MM_MODEM_CONNECT_ERROR_NO_ANSWER MM_DBUS_INTERFACE_MODEM ".NoAnswer" | ||
34 | |||
35 | #define MM_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" | ||
36 | |||
37 | #define MM_MODEM_ERROR_PHONE_FAILURE MM_MODEM_ERROR ".PhoneFailure" | ||
38 | #define MM_MODEM_ERROR_NO_CONNECTION MM_MODEM_ERROR ".NoConnection" | ||
39 | #define MM_MODEM_ERROR_LINK_RESERVED MM_MODEM_ERROR ".LinkReserved" | ||
40 | #define MM_MODEM_ERROR_NOT_ALLOWED MM_MODEM_ERROR ".OperationNotAllowed" | ||
41 | #define MM_MODEM_ERROR_NOT_SUPPORTED MM_MODEM_ERROR ".OperationNotSupported" | ||
42 | #define MM_MODEM_ERROR_PH_SIM_PIN MM_MODEM_ERROR ".PhSimPinRequired" | ||
43 | #define MM_MODEM_ERROR_PH_FSIM_PIN MM_MODEM_ERROR ".PhFSimPinRequired" | ||
44 | #define MM_MODEM_ERROR_PH_FSIM_PUK MM_MODEM_ERROR ".PhFPukRequired" | ||
45 | #define MM_MODEM_ERROR_SIM_NOT_INSERTED MM_MODEM_ERROR ".SimNotInserted" | ||
46 | #define MM_MODEM_ERROR_SIM_PIN MM_MODEM_ERROR ".SimPinRequired" | ||
47 | #define MM_MODEM_ERROR_SIM_PUK MM_MODEM_ERROR ".SimPukRequired" | ||
48 | #define MM_MODEM_ERROR_SIM_FAILURE MM_MODEM_ERROR ".SimFailure" | ||
49 | #define MM_MODEM_ERROR_SIM_BUSY MM_MODEM_ERROR ".SimBusy" | ||
50 | #define MM_MODEM_ERROR_SIM_WRONG MM_MODEM_ERROR ".SimWrong" | ||
51 | #define MM_MODEM_ERROR_WRONG_PASSWORD MM_MODEM_ERROR ".IncorrectPassword" | ||
52 | #define MM_MODEM_ERROR_SIM_PIN2 MM_MODEM_ERROR ".SimPin2Required" | ||
53 | #define MM_MODEM_ERROR_SIM_PUK2 MM_MODEM_ERROR ".SimPuk2Required" | ||
54 | #define MM_MODEM_ERROR_MEMORY_FULL MM_MODEM_ERROR ".MemoryFull" | ||
55 | #define MM_MODEM_ERROR_INVALID_INDEX MM_MODEM_ERROR ".InvalidIndex" | ||
56 | #define MM_MODEM_ERROR_NOT_FOUND MM_MODEM_ERROR ".NotFound" | ||
57 | #define MM_MODEM_ERROR_MEMORY_FAILURE MM_MODEM_ERROR ".MemoryFailure" | ||
58 | #define MM_MODEM_ERROR_TEXT_TOO_LONG MM_MODEM_ERROR ".TextTooLong" | ||
59 | #define MM_MODEM_ERROR_INVALID_CHARS MM_MODEM_ERROR ".InvalidChars" | ||
60 | #define MM_MODEM_ERROR_DIAL_STRING_TOO_LONG MM_MODEM_ERROR ".DialStringTooLong" | ||
61 | #define MM_MODEM_ERROR_DIAL_STRING_INVALID MM_MODEM_ERROR ".InvalidDialString" | ||
62 | #define MM_MODEM_ERROR_NO_NETWORK MM_MODEM_ERROR ".NoNetwork" | ||
63 | #define MM_MODEM_ERROR_NETWORK_TIMEOUT MM_MODEM_ERROR ".NetworkTimeout" | ||
64 | #define MM_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_MODEM_ERROR ".NetworkNotAllowed" | ||
65 | #define MM_MODEM_ERROR_NETWORK_PIN MM_MODEM_ERROR ".NetworkPinRequired" | ||
66 | #define MM_MODEM_ERROR_NETWORK_PUK MM_MODEM_ERROR ".NetworkPukRequired" | ||
67 | #define MM_MODEM_ERROR_NETWORK_SUBSET_PIN MM_MODEM_ERROR ".NetworkSubsetPinRequired" | ||
68 | #define MM_MODEM_ERROR_NETWORK_SUBSET_PUK MM_MODEM_ERROR ".NetworkSubsetPukRequired" | ||
69 | #define MM_MODEM_ERROR_SERVICE_PIN MM_MODEM_ERROR ".ServicePinRequired" | ||
70 | #define MM_MODEM_ERROR_SERVICE_PUK MM_MODEM_ERROR ".ServicePukRequired" | ||
71 | #define MM_MODEM_ERROR_CORP_PIN MM_MODEM_ERROR ".CorporatePinRequired" | ||
72 | #define MM_MODEM_ERROR_CORP_PUK MM_MODEM_ERROR ".CorporatePukRequired" | ||
73 | #define MM_MODEM_ERROR_HIDDEN_KEY MM_MODEM_ERROR ".HiddenKeyRequired" | ||
74 | #define MM_MODEM_ERROR_EAP_NOT_SUPPORTED MM_MODEM_ERROR ".EapMethodNotSupported" | ||
75 | #define MM_MODEM_ERROR_INCORRECT_PARAMS MM_MODEM_ERROR ".IncorrectParams" | ||
76 | #define MM_MODEM_ERROR_UNKNOWN MM_MODEM_ERROR ".Unknown" | ||
77 | #define MM_MODEM_ERROR_GPRS_ILLEGAL_MS MM_MODEM_ERROR ".GprsIllegalMs" | ||
78 | #define MM_MODEM_ERROR_GPRS_ILLEGAL_ME MM_MODEM_ERROR ".GprsIllegalMe" | ||
79 | #define MM_MODEM_ERROR_GPRS_SERVICE_NOT_ALLOWED MM_MODEM_ERROR ".GprsServiceNotAllowed" | ||
80 | #define MM_MODEM_ERROR_GPRS_PLMN_NOT_ALLOWED MM_MODEM_ERROR ".GprsPlmnNotAllowed" | ||
81 | #define MM_MODEM_ERROR_GPRS_LOCATION_NOT_ALLOWED MM_MODEM_ERROR ".GprsLocationNotAllowed" | ||
82 | #define MM_MODEM_ERROR_GPRS_ROAMING_NOT_ALLOWED MM_MODEM_ERROR ".GprsRoamingNotAllowed" | ||
83 | #define MM_MODEM_ERROR_GPRS_OPTION_NOT_SUPPORTED MM_MODEM_ERROR ".GprsOptionNotSupported" | ||
84 | #define MM_MODEM_ERROR_GPRS_NOT_SUBSCRIBED MM_MODEM_ERROR ".GprsNotSubscribed" | ||
85 | #define MM_MODEM_ERROR_GPRS_OUT_OF_ORDER MM_MODEM_ERROR ".GprsOutOfOrder" | ||
86 | #define MM_MODEM_ERROR_GPRS_PDP_AUTH_FAILURE MM_MODEM_ERROR ".GprsPdpAuthFailure" | ||
87 | #define MM_MODEM_ERROR_GPRS_UNKNOWN MM_MODEM_ERROR ".GprsUnspecified" | ||
88 | #define MM_MODEM_ERROR_GPRS_INVALID_CLASS MM_MODEM_ERROR ".GprsInvalidClass" | ||
89 | |||
90 | #endif /* NM_MODEM_TYPES_H */ | ||
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c new file mode 100644 index 0000000000..fddfd059fd --- /dev/null +++ b/src/modem-manager/nm-modem.c | |||
@@ -0,0 +1,457 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #include <string.h> | ||
4 | #include "nm-modem.h" | ||
5 | #include "nm-device-private.h" | ||
6 | #include "nm-device-interface.h" | ||
7 | #include "nm-dbus-manager.h" | ||
8 | #include "nm-setting-connection.h" | ||
9 | #include "nm-setting-gsm.h" | ||
10 | #include "nm-setting-cdma.h" | ||
11 | #include "nm-marshal.h" | ||
12 | #include "nm-properties-changed-signal.h" | ||
13 | #include "nm-modem-types.h" | ||
14 | #include "nm-utils.h" | ||
15 | #include "nm-serial-device-glue.h" | ||
16 | |||
17 | G_DEFINE_TYPE (NMModem, nm_modem, NM_TYPE_DEVICE) | ||
18 | |||
19 | #define NM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM, NMModemPrivate)) | ||
20 | |||
21 | enum { | ||
22 | PROP_0, | ||
23 | PROP_PATH, | ||
24 | |||
25 | LAST_PROP | ||
26 | }; | ||
27 | |||
28 | typedef struct { | ||
29 | NMDBusManager *dbus_mgr; | ||
30 | char *path; | ||
31 | DBusGProxy *proxy; | ||
32 | NMPPPManager *ppp_manager; | ||
33 | NMIP4Config *pending_ip4_config; | ||
34 | |||
35 | guint state_to_disconnected_id; | ||
36 | |||
37 | /* PPP stats */ | ||
38 | guint32 in_bytes; | ||
39 | guint32 out_bytes; | ||
40 | } NMModemPrivate; | ||
41 | |||
42 | enum { | ||
43 | PPP_STATS, | ||
44 | PROPERTIES_CHANGED, | ||
45 | |||
46 | LAST_SIGNAL | ||
47 | }; | ||
48 | |||
49 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
50 | |||
51 | NMPPPManager * | ||
52 | nm_modem_get_ppp_manager (NMModem *self) | ||
53 | { | ||
54 | g_return_val_if_fail (NM_IS_MODEM (self), NULL); | ||
55 | |||
56 | return NM_MODEM_GET_PRIVATE (self)->ppp_manager; | ||
57 | } | ||
58 | |||
59 | DBusGProxy * | ||
60 | nm_modem_get_proxy (NMModem *self, | ||
61 | const char *interface) | ||
62 | { | ||
63 | |||
64 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); | ||
65 | const char *current_iface; | ||
66 | |||
67 | g_return_val_if_fail (NM_IS_MODEM (self), NULL); | ||
68 | |||
69 | /* Default to the default interface. */ | ||
70 | if (interface == NULL) | ||
71 | interface = MM_DBUS_INTERFACE_MODEM; | ||
72 | |||
73 | current_iface = dbus_g_proxy_get_interface (priv->proxy); | ||
74 | if (!current_iface || strcmp (current_iface, interface)) | ||
75 | dbus_g_proxy_set_interface (priv->proxy, interface); | ||
76 | |||
77 | return priv->proxy; | ||
78 | } | ||
79 | |||
80 | void | ||
81 | nm_modem_connect (NMModem *self, | ||
82 | const char *number) | ||
83 | { | ||
84 | g_return_if_fail (NM_IS_MODEM (self)); | ||
85 | |||
86 | NM_MODEM_GET_CLASS (self)->connect (self, number); | ||
87 | } | ||
88 | |||
89 | const char * | ||
90 | nm_modem_get_ppp_name (NMModem *self, | ||
91 | NMConnection *connection) | ||
92 | { | ||
93 | g_return_val_if_fail (NM_IS_MODEM (self), NULL); | ||
94 | g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); | ||
95 | |||
96 | if (NM_MODEM_GET_CLASS (self)->get_ppp_name) | ||
97 | return NM_MODEM_GET_CLASS (self)->get_ppp_name (self, connection); | ||
98 | |||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | static void | ||
103 | ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) | ||
104 | { | ||
105 | NMDevice *device = NM_DEVICE (user_data); | ||
106 | |||
107 | switch (status) { | ||
108 | case NM_PPP_STATUS_NETWORK: | ||
109 | nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); | ||
110 | break; | ||
111 | case NM_PPP_STATUS_DISCONNECT: | ||
112 | nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); | ||
113 | break; | ||
114 | case NM_PPP_STATUS_DEAD: | ||
115 | nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); | ||
116 | break; | ||
117 | case NM_PPP_STATUS_AUTHENTICATE: | ||
118 | nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
119 | break; | ||
120 | default: | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static void | ||
126 | ppp_ip4_config (NMPPPManager *ppp_manager, | ||
127 | const char *iface, | ||
128 | NMIP4Config *config, | ||
129 | gpointer user_data) | ||
130 | { | ||
131 | NMDevice *device = NM_DEVICE (user_data); | ||
132 | |||
133 | nm_device_set_ip_iface (device, iface); | ||
134 | NM_MODEM_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config); | ||
135 | nm_device_activate_schedule_stage4_ip_config_get (device); | ||
136 | } | ||
137 | |||
138 | static void | ||
139 | ppp_stats (NMPPPManager *ppp_manager, | ||
140 | guint32 in_bytes, | ||
141 | guint32 out_bytes, | ||
142 | gpointer user_data) | ||
143 | { | ||
144 | NMModem *self = NM_MODEM (user_data); | ||
145 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); | ||
146 | |||
147 | if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { | ||
148 | priv->in_bytes = in_bytes; | ||
149 | priv->out_bytes = out_bytes; | ||
150 | |||
151 | g_signal_emit (self, signals[PPP_STATS], 0, in_bytes, out_bytes); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | static NMActStageReturn | ||
156 | real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) | ||
157 | { | ||
158 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (device); | ||
159 | NMActRequest *req; | ||
160 | const char *ppp_name = NULL; | ||
161 | GError *err = NULL; | ||
162 | NMActStageReturn ret; | ||
163 | |||
164 | req = nm_device_get_act_request (device); | ||
165 | g_assert (req); | ||
166 | |||
167 | ppp_name = nm_modem_get_ppp_name (NM_MODEM (device), | ||
168 | nm_act_request_get_connection (req)); | ||
169 | |||
170 | priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (device)); | ||
171 | if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, &err)) { | ||
172 | g_signal_connect (priv->ppp_manager, "state-changed", | ||
173 | G_CALLBACK (ppp_state_changed), | ||
174 | device); | ||
175 | g_signal_connect (priv->ppp_manager, "ip4-config", | ||
176 | G_CALLBACK (ppp_ip4_config), | ||
177 | device); | ||
178 | g_signal_connect (priv->ppp_manager, "stats", | ||
179 | G_CALLBACK (ppp_stats), | ||
180 | device); | ||
181 | |||
182 | ret = NM_ACT_STAGE_RETURN_POSTPONE; | ||
183 | } else { | ||
184 | nm_warning ("%s", err->message); | ||
185 | g_error_free (err); | ||
186 | |||
187 | g_object_unref (priv->ppp_manager); | ||
188 | priv->ppp_manager = NULL; | ||
189 | |||
190 | *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED; | ||
191 | ret = NM_ACT_STAGE_RETURN_FAILURE; | ||
192 | } | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static NMActStageReturn | ||
198 | real_act_stage4_get_ip4_config (NMDevice *device, | ||
199 | NMIP4Config **config, | ||
200 | NMDeviceStateReason *reason) | ||
201 | { | ||
202 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (device); | ||
203 | |||
204 | *config = priv->pending_ip4_config; | ||
205 | priv->pending_ip4_config = NULL; | ||
206 | |||
207 | return NM_ACT_STAGE_RETURN_SUCCESS; | ||
208 | } | ||
209 | |||
210 | static void | ||
211 | real_deactivate_quickly (NMDevice *device) | ||
212 | { | ||
213 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (device); | ||
214 | |||
215 | nm_device_set_ip_iface (device, NULL); | ||
216 | |||
217 | if (priv->pending_ip4_config) { | ||
218 | g_object_unref (priv->pending_ip4_config); | ||
219 | priv->pending_ip4_config = NULL; | ||
220 | } | ||
221 | |||
222 | priv->in_bytes = priv->out_bytes = 0; | ||
223 | |||
224 | if (priv->ppp_manager) { | ||
225 | g_object_unref (priv->ppp_manager); | ||
226 | priv->ppp_manager = NULL; | ||
227 | } | ||
228 | |||
229 | dbus_g_proxy_call_no_reply (nm_modem_get_proxy (NM_MODEM (device), NULL), | ||
230 | "Enable", G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID); | ||
231 | } | ||
232 | |||
233 | static guint32 | ||
234 | real_get_generic_capabilities (NMDevice *dev) | ||
235 | { | ||
236 | return NM_DEVICE_CAP_NM_SUPPORTED; | ||
237 | } | ||
238 | |||
239 | |||
240 | static void | ||
241 | connect_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) | ||
242 | { | ||
243 | NMDevice *device = NM_DEVICE (user_data); | ||
244 | GError *error = NULL; | ||
245 | |||
246 | if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) | ||
247 | nm_device_activate_schedule_stage2_device_config (device); | ||
248 | else { | ||
249 | nm_warning ("Connect failed: %s", error->message); | ||
250 | g_error_free (error); | ||
251 | nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | static void | ||
256 | real_connect (NMModem *modem, const char *number) | ||
257 | { | ||
258 | dbus_g_proxy_begin_call_with_timeout (nm_modem_get_proxy (modem, MM_DBUS_INTERFACE_MODEM), | ||
259 | "Connect", connect_done, | ||
260 | modem, NULL, 60000, | ||
261 | G_TYPE_STRING, number ? number : "", | ||
262 | G_TYPE_INVALID); | ||
263 | } | ||
264 | |||
265 | static gboolean | ||
266 | unavailable_to_disconnected (gpointer user_data) | ||
267 | { | ||
268 | nm_device_state_changed (NM_DEVICE (user_data), | ||
269 | NM_DEVICE_STATE_DISCONNECTED, | ||
270 | NM_DEVICE_STATE_REASON_NONE); | ||
271 | return FALSE; | ||
272 | } | ||
273 | |||
274 | static void | ||
275 | device_state_changed (NMDeviceInterface *device, | ||
276 | NMDeviceState new_state, | ||
277 | NMDeviceState old_state, | ||
278 | NMDeviceStateReason reason, | ||
279 | gpointer user_data) | ||
280 | { | ||
281 | NMModem *self = NM_MODEM (user_data); | ||
282 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); | ||
283 | |||
284 | /* Remove any previous delayed transition to disconnected */ | ||
285 | if (priv->state_to_disconnected_id) { | ||
286 | g_source_remove (priv->state_to_disconnected_id); | ||
287 | priv->state_to_disconnected_id = 0; | ||
288 | } | ||
289 | |||
290 | /* If transitioning to UNAVAILBLE and we have a carrier, transition to | ||
291 | * DISCONNECTED because the device is ready to use. Otherwise the carrier-on | ||
292 | * handler will handle the transition to DISCONNECTED when the carrier is detected. | ||
293 | */ | ||
294 | if (new_state == NM_DEVICE_STATE_UNAVAILABLE) | ||
295 | priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, user_data); | ||
296 | |||
297 | /* Make sure we don't leave the serial device open */ | ||
298 | switch (new_state) { | ||
299 | case NM_DEVICE_STATE_NEED_AUTH: | ||
300 | if (priv->ppp_manager) | ||
301 | break; | ||
302 | /* else fall through */ | ||
303 | case NM_DEVICE_STATE_UNMANAGED: | ||
304 | case NM_DEVICE_STATE_UNAVAILABLE: | ||
305 | case NM_DEVICE_STATE_FAILED: | ||
306 | case NM_DEVICE_STATE_DISCONNECTED: | ||
307 | dbus_g_proxy_call_no_reply (nm_modem_get_proxy (self, NULL), | ||
308 | "Disconnect", G_TYPE_INVALID); | ||
309 | break; | ||
310 | default: | ||
311 | break; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /*****************************************************************************/ | ||
316 | |||
317 | static void | ||
318 | nm_modem_init (NMModem *self) | ||
319 | { | ||
320 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); | ||
321 | |||
322 | priv->dbus_mgr = nm_dbus_manager_get (); | ||
323 | } | ||
324 | |||
325 | static GObject* | ||
326 | constructor (GType type, | ||
327 | guint n_construct_params, | ||
328 | GObjectConstructParam *construct_params) | ||
329 | { | ||
330 | GObject *object; | ||
331 | NMModemPrivate *priv; | ||
332 | |||
333 | object = G_OBJECT_CLASS (nm_modem_parent_class)->constructor (type, | ||
334 | n_construct_params, | ||
335 | construct_params); | ||
336 | if (!object) | ||
337 | return NULL; | ||
338 | |||
339 | priv = NM_MODEM_GET_PRIVATE (object); | ||
340 | |||
341 | if (!priv->path) { | ||
342 | g_warning ("DBus path not provided"); | ||
343 | goto err; | ||
344 | } | ||
345 | |||
346 | priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), | ||
347 | MM_DBUS_SERVICE, priv->path, MM_DBUS_INTERFACE_MODEM); | ||
348 | |||
349 | g_signal_connect (object, "state-changed", G_CALLBACK (device_state_changed), object); | ||
350 | |||
351 | return object; | ||
352 | |||
353 | err: | ||
354 | g_object_unref (object); | ||
355 | return NULL; | ||
356 | } | ||
357 | |||
358 | static void | ||
359 | get_property (GObject *object, guint prop_id, | ||
360 | GValue *value, GParamSpec *pspec) | ||
361 | { | ||
362 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); | ||
363 | |||
364 | switch (prop_id) { | ||
365 | case PROP_PATH: | ||
366 | g_value_set_string (value, priv->path); | ||
367 | break; | ||
368 | default: | ||
369 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | } | ||
374 | |||
375 | static void | ||
376 | set_property (GObject *object, guint prop_id, | ||
377 | const GValue *value, GParamSpec *pspec) | ||
378 | { | ||
379 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); | ||
380 | |||
381 | switch (prop_id) { | ||
382 | case PROP_PATH: | ||
383 | /* Construct only */ | ||
384 | priv->path = g_value_dup_string (value); | ||
385 | break; | ||
386 | default: | ||
387 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | static void | ||
393 | finalize (GObject *object) | ||
394 | { | ||
395 | NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); | ||
396 | |||
397 | if (priv->state_to_disconnected_id) { | ||
398 | g_source_remove (priv->state_to_disconnected_id); | ||
399 | priv->state_to_disconnected_id = 0; | ||
400 | } | ||
401 | |||
402 | if (priv->proxy) | ||
403 | g_object_unref (priv->proxy); | ||
404 | |||
405 | g_object_unref (priv->dbus_mgr); | ||
406 | |||
407 | G_OBJECT_CLASS (nm_modem_parent_class)->finalize (object); | ||
408 | } | ||
409 | |||
410 | static void | ||
411 | nm_modem_class_init (NMModemClass *klass) | ||
412 | { | ||
413 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
414 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
415 | |||
416 | g_type_class_add_private (object_class, sizeof (NMModemPrivate)); | ||
417 | |||
418 | /* Virtual methods */ | ||
419 | object_class->constructor = constructor; | ||
420 | object_class->set_property = set_property; | ||
421 | object_class->get_property = get_property; | ||
422 | object_class->finalize = finalize; | ||
423 | |||
424 | device_class->get_generic_capabilities = real_get_generic_capabilities; | ||
425 | device_class->act_stage2_config = real_act_stage2_config; | ||
426 | device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; | ||
427 | device_class->deactivate_quickly = real_deactivate_quickly; | ||
428 | |||
429 | klass->connect = real_connect; | ||
430 | |||
431 | /* Properties */ | ||
432 | g_object_class_install_property | ||
433 | (object_class, PROP_PATH, | ||
434 | g_param_spec_string (NM_MODEM_PATH, | ||
435 | "DBus path", | ||
436 | "DBus path", | ||
437 | NULL, | ||
438 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); | ||
439 | |||
440 | /* Signals */ | ||
441 | signals[PPP_STATS] = | ||
442 | g_signal_new ("ppp-stats", | ||
443 | G_OBJECT_CLASS_TYPE (object_class), | ||
444 | G_SIGNAL_RUN_FIRST, | ||
445 | G_STRUCT_OFFSET (NMModemClass, ppp_stats), | ||
446 | NULL, NULL, | ||
447 | _nm_marshal_VOID__UINT_UINT, | ||
448 | G_TYPE_NONE, 2, | ||
449 | G_TYPE_UINT, G_TYPE_UINT); | ||
450 | |||
451 | signals[PROPERTIES_CHANGED] = | ||
452 | nm_properties_changed_signal_new (object_class, | ||
453 | G_STRUCT_OFFSET (NMModemClass, properties_changed)); | ||
454 | |||
455 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
456 | &dbus_glib_nm_serial_device_object_info); | ||
457 | } | ||
diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h new file mode 100644 index 0000000000..36b9bd8202 --- /dev/null +++ b/src/modem-manager/nm-modem.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | |||
3 | #ifndef NM_MODEM_H | ||
4 | #define NM_MODEM_H | ||
5 | |||
6 | #include <dbus/dbus-glib.h> | ||
7 | #include <nm-device.h> | ||
8 | #include "ppp-manager/nm-ppp-manager.h" | ||
9 | |||
10 | G_BEGIN_DECLS | ||
11 | |||
12 | #define NM_TYPE_MODEM (nm_modem_get_type ()) | ||
13 | #define NM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM, NMModem)) | ||
14 | #define NM_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM, NMModemClass)) | ||
15 | #define NM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM)) | ||
16 | #define NM_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM)) | ||
17 | #define NM_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM, NMModemClass)) | ||
18 | |||
19 | #define NM_MODEM_PATH "path" | ||
20 | |||
21 | typedef struct { | ||
22 | NMDevice parent; | ||
23 | } NMModem; | ||
24 | |||
25 | typedef struct { | ||
26 | NMDeviceClass parent; | ||
27 | |||
28 | void (*connect) (NMModem *self, | ||
29 | const char *number); | ||
30 | |||
31 | const char *(*get_ppp_name) (NMModem *self, | ||
32 | NMConnection *connection); | ||
33 | |||
34 | /* Signals */ | ||
35 | void (*ppp_stats) (NMModem *self, guint32 in_bytes, guint32 out_bytes); | ||
36 | void (*properties_changed) (NMModem *self, GHashTable *properties); | ||
37 | } NMModemClass; | ||
38 | |||
39 | GType nm_modem_get_type (void); | ||
40 | |||
41 | /* Protected */ | ||
42 | |||
43 | NMPPPManager *nm_modem_get_ppp_manager (NMModem *self); | ||
44 | DBusGProxy *nm_modem_get_proxy (NMModem *self, | ||
45 | const char *interface); | ||
46 | |||
47 | void nm_modem_connect (NMModem *self, | ||
48 | const char *number); | ||
49 | |||
50 | const char *nm_modem_get_ppp_name (NMModem *self, | ||
51 | NMConnection *connection); | ||
52 | |||
53 | G_END_DECLS | ||
54 | |||
55 | #endif /* NM_MODEM_H */ | ||
diff --git a/src/nm-cdma-device.c b/src/nm-cdma-device.c deleted file mode 100644 index c1c9b06b77..0000000000 --- a/src/nm-cdma-device.c +++ /dev/null | |||
@@ -1,593 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2008 Red Hat, Inc. | ||
19 | * Copyright (C) 2008 Novell, Inc. | ||
20 | */ | ||
21 | |||
22 | #include <stdio.h> | ||
23 | #include <string.h> | ||
24 | #include "nm-cdma-device.h" | ||
25 | #include "nm-device-interface.h" | ||
26 | #include "nm-device-private.h" | ||
27 | #include "nm-setting-cdma.h" | ||
28 | #include "nm-utils.h" | ||
29 | #include "nm-properties-changed-signal.h" | ||
30 | #include "nm-cdma-device-glue.h" | ||
31 | #include "nm-setting-connection.h" | ||
32 | |||
33 | G_DEFINE_TYPE (NMCdmaDevice, nm_cdma_device, NM_TYPE_SERIAL_DEVICE) | ||
34 | |||
35 | #define NM_CDMA_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CDMA_DEVICE, NMCdmaDevicePrivate)) | ||
36 | |||
37 | typedef struct { | ||
38 | char *monitor_iface; | ||
39 | NMSerialDevice *monitor_device; | ||
40 | |||
41 | guint state_to_disconnected_id; | ||
42 | } NMCdmaDevicePrivate; | ||
43 | |||
44 | enum { | ||
45 | PROP_0, | ||
46 | PROP_MONITOR_IFACE, | ||
47 | |||
48 | LAST_PROP | ||
49 | }; | ||
50 | |||
51 | enum { | ||
52 | PROPERTIES_CHANGED, | ||
53 | |||
54 | LAST_SIGNAL | ||
55 | }; | ||
56 | |||
57 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
58 | |||
59 | |||
60 | NMCdmaDevice * | ||
61 | nm_cdma_device_new (const char *udi, | ||
62 | const char *data_iface, | ||
63 | const char *monitor_iface, | ||
64 | const char *driver, | ||
65 | gboolean managed) | ||
66 | { | ||
67 | g_return_val_if_fail (udi != NULL, NULL); | ||
68 | g_return_val_if_fail (data_iface != NULL, NULL); | ||
69 | g_return_val_if_fail (driver != NULL, NULL); | ||
70 | |||
71 | return (NMCdmaDevice *) g_object_new (NM_TYPE_CDMA_DEVICE, | ||
72 | NM_DEVICE_INTERFACE_UDI, udi, | ||
73 | NM_DEVICE_INTERFACE_IFACE, data_iface, | ||
74 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
75 | NM_CDMA_DEVICE_MONITOR_IFACE, monitor_iface, | ||
76 | NM_DEVICE_INTERFACE_MANAGED, managed, | ||
77 | NULL); | ||
78 | } | ||
79 | |||
80 | static NMSetting * | ||
81 | cdma_device_get_setting (NMCdmaDevice *device, GType setting_type) | ||
82 | { | ||
83 | NMActRequest *req; | ||
84 | NMSetting *setting = NULL; | ||
85 | |||
86 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
87 | if (req) { | ||
88 | NMConnection *connection; | ||
89 | |||
90 | connection = nm_act_request_get_connection (req); | ||
91 | if (connection) | ||
92 | setting = nm_connection_get_setting (connection, setting_type); | ||
93 | } | ||
94 | |||
95 | return setting; | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | dial_done (NMSerialDevice *device, | ||
100 | int reply_index, | ||
101 | const char *reply, | ||
102 | gpointer user_data) | ||
103 | { | ||
104 | NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN; | ||
105 | gboolean success = FALSE; | ||
106 | |||
107 | switch (reply_index) { | ||
108 | case 0: | ||
109 | nm_info ("Connected, Woo!"); | ||
110 | success = TRUE; | ||
111 | break; | ||
112 | case 1: | ||
113 | nm_info ("Busy"); | ||
114 | reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; | ||
115 | break; | ||
116 | case 2: | ||
117 | nm_warning ("No dial tone"); | ||
118 | reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; | ||
119 | break; | ||
120 | case 3: | ||
121 | nm_warning ("No carrier"); | ||
122 | reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; | ||
123 | break; | ||
124 | case -1: | ||
125 | nm_warning ("Dialing timed out"); | ||
126 | reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; | ||
127 | break; | ||
128 | default: | ||
129 | nm_warning ("Dialing failed"); | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | if (success) | ||
134 | nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device)); | ||
135 | else | ||
136 | nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, reason); | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | do_dial (NMSerialDevice *device) | ||
141 | { | ||
142 | NMSettingCdma *setting; | ||
143 | char *command; | ||
144 | guint id = 0; | ||
145 | const char *responses[] = { "CONNECT", "BUSY", "NO DIAL TONE", "NO CARRIER", NULL }; | ||
146 | |||
147 | setting = NM_SETTING_CDMA (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_CDMA)); | ||
148 | |||
149 | command = g_strconcat ("ATDT", nm_setting_cdma_get_number (setting), NULL); | ||
150 | if (nm_serial_device_send_command_string (device, command)) | ||
151 | id = nm_serial_device_wait_for_reply (device, 60, responses, responses, dial_done, NULL); | ||
152 | g_free (command); | ||
153 | |||
154 | if (id == 0) | ||
155 | nm_device_state_changed (NM_DEVICE (device), | ||
156 | NM_DEVICE_STATE_FAILED, | ||
157 | NM_DEVICE_STATE_REASON_UNKNOWN); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | power_up_response (NMSerialDevice *device, | ||
162 | int reply_index, | ||
163 | const char *reply, | ||
164 | gpointer user_data) | ||
165 | { | ||
166 | /* Ignore errors */ | ||
167 | do_dial (device); | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | power_up (NMSerialDevice *device) | ||
172 | { | ||
173 | const char *responses[] = { "OK", "ERROR", "ERR", NULL }; | ||
174 | guint id = 0; | ||
175 | |||
176 | /* Only works on Sierra cards */ | ||
177 | nm_info ("(%s): powering up...", nm_device_get_iface (NM_DEVICE (device))); | ||
178 | if (nm_serial_device_send_command_string (device, "at!pcstate=1")) | ||
179 | id = nm_serial_device_wait_for_reply (device, 10, responses, responses, power_up_response, NULL); | ||
180 | |||
181 | /* Ignore errors */ | ||
182 | if (id == 0) | ||
183 | do_dial (device); | ||
184 | } | ||
185 | |||
186 | static void | ||
187 | init_done (NMSerialDevice *device, | ||
188 | int reply_index, | ||
189 | const char *reply, | ||
190 | gpointer user_data) | ||
191 | { | ||
192 | switch (reply_index) { | ||
193 | case 0: | ||
194 | power_up (device); | ||
195 | break; | ||
196 | case -1: | ||
197 | nm_warning ("Modem initialization timed out"); | ||
198 | nm_device_state_changed (NM_DEVICE (device), | ||
199 | NM_DEVICE_STATE_FAILED, | ||
200 | NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); | ||
201 | break; | ||
202 | default: | ||
203 | nm_warning ("Modem initialization failed"); | ||
204 | nm_device_state_changed (NM_DEVICE (device), | ||
205 | NM_DEVICE_STATE_FAILED, | ||
206 | NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED); | ||
207 | return; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | static void | ||
212 | init_modem (NMSerialDevice *device, gpointer user_data) | ||
213 | { | ||
214 | guint id = 0; | ||
215 | const char *responses[] = { "OK", "ERROR", "ERR", NULL }; | ||
216 | |||
217 | if (nm_serial_device_send_command_string (device, "ATZ E0")) | ||
218 | id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL); | ||
219 | |||
220 | if (id == 0) | ||
221 | nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); | ||
222 | } | ||
223 | |||
224 | static NMActStageReturn | ||
225 | real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) | ||
226 | { | ||
227 | NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); | ||
228 | NMSettingSerial *setting; | ||
229 | guint id; | ||
230 | |||
231 | setting = NM_SETTING_SERIAL (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_SERIAL)); | ||
232 | |||
233 | if (!nm_serial_device_open (serial_device, setting)) { | ||
234 | *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; | ||
235 | return NM_ACT_STAGE_RETURN_FAILURE; | ||
236 | } | ||
237 | |||
238 | id = nm_serial_device_flash (serial_device, 100, init_modem, NULL); | ||
239 | if (!id) | ||
240 | *reason = NM_DEVICE_STATE_REASON_UNKNOWN; | ||
241 | |||
242 | return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; | ||
243 | } | ||
244 | |||
245 | static NMConnection * | ||
246 | real_get_best_auto_connection (NMDevice *dev, | ||
247 | GSList *connections, | ||
248 | char **specific_object) | ||
249 | { | ||
250 | GSList *iter; | ||
251 | |||
252 | for (iter = connections; iter; iter = g_slist_next (iter)) { | ||
253 | NMConnection *connection = NM_CONNECTION (iter->data); | ||
254 | NMSettingConnection *s_con; | ||
255 | |||
256 | s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); | ||
257 | g_assert (s_con); | ||
258 | |||
259 | if (!nm_setting_connection_get_autoconnect (s_con)) | ||
260 | continue; | ||
261 | |||
262 | if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME)) | ||
263 | continue; | ||
264 | |||
265 | return connection; | ||
266 | } | ||
267 | return NULL; | ||
268 | } | ||
269 | |||
270 | static guint32 | ||
271 | real_get_generic_capabilities (NMDevice *dev) | ||
272 | { | ||
273 | return NM_DEVICE_CAP_NM_SUPPORTED; | ||
274 | } | ||
275 | |||
276 | static void | ||
277 | real_connection_secrets_updated (NMDevice *dev, | ||
278 | NMConnection *connection, | ||
279 | GSList *updated_settings, | ||
280 | RequestSecretsCaller caller) | ||
281 | { | ||
282 | NMActRequest *req; | ||
283 | gboolean found = FALSE; | ||
284 | GSList *iter; | ||
285 | |||
286 | if (caller == SECRETS_CALLER_PPP) { | ||
287 | NMPPPManager *ppp_manager; | ||
288 | NMSettingCdma *s_cdma = NULL; | ||
289 | |||
290 | ppp_manager = nm_serial_device_get_ppp_manager (NM_SERIAL_DEVICE (dev)); | ||
291 | g_return_if_fail (ppp_manager != NULL); | ||
292 | |||
293 | s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); | ||
294 | if (!s_cdma) { | ||
295 | /* Shouldn't ever happen */ | ||
296 | nm_ppp_manager_update_secrets (ppp_manager, | ||
297 | nm_device_get_iface (dev), | ||
298 | NULL, | ||
299 | NULL, | ||
300 | "missing CDMA setting; no secrets could be found."); | ||
301 | } else { | ||
302 | const char *cdma_username = nm_setting_cdma_get_username (s_cdma); | ||
303 | const char *cdma_password = nm_setting_cdma_get_password (s_cdma); | ||
304 | |||
305 | nm_ppp_manager_update_secrets (ppp_manager, | ||
306 | nm_device_get_iface (dev), | ||
307 | cdma_username ? cdma_username : "", | ||
308 | cdma_password ? cdma_password : "", | ||
309 | NULL); | ||
310 | } | ||
311 | return; | ||
312 | } | ||
313 | |||
314 | g_return_if_fail (caller == SECRETS_CALLER_CDMA); | ||
315 | g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); | ||
316 | |||
317 | for (iter = updated_settings; iter; iter = g_slist_next (iter)) { | ||
318 | const char *setting_name = (const char *) iter->data; | ||
319 | |||
320 | if (!strcmp (setting_name, NM_SETTING_CDMA_SETTING_NAME)) | ||
321 | found = TRUE; | ||
322 | else | ||
323 | nm_warning ("Ignoring updated secrets for setting '%s'.", setting_name); | ||
324 | } | ||
325 | |||
326 | if (!found) | ||
327 | return; | ||
328 | |||
329 | req = nm_device_get_act_request (dev); | ||
330 | g_assert (req); | ||
331 | |||
332 | g_return_if_fail (nm_act_request_get_connection (req) == connection); | ||
333 | |||
334 | nm_device_activate_schedule_stage1_device_prepare (dev); | ||
335 | } | ||
336 | |||
337 | static const char * | ||
338 | real_get_ppp_name (NMSerialDevice *device, NMActRequest *req) | ||
339 | { | ||
340 | NMConnection *connection; | ||
341 | NMSettingCdma *s_cdma; | ||
342 | |||
343 | connection = nm_act_request_get_connection (req); | ||
344 | g_assert (connection); | ||
345 | |||
346 | s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); | ||
347 | g_assert (s_cdma); | ||
348 | |||
349 | return nm_setting_cdma_get_username (s_cdma); | ||
350 | } | ||
351 | |||
352 | /*****************************************************************************/ | ||
353 | /* Monitor device handling */ | ||
354 | |||
355 | static gboolean | ||
356 | monitor_device_got_data (GIOChannel *source, | ||
357 | GIOCondition condition, | ||
358 | gpointer data) | ||
359 | { | ||
360 | gsize bytes_read; | ||
361 | char buf[4096]; | ||
362 | GIOStatus status; | ||
363 | |||
364 | if (condition & G_IO_IN) { | ||
365 | do { | ||
366 | status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL); | ||
367 | |||
368 | if (bytes_read) { | ||
369 | buf[bytes_read] = '\0'; | ||
370 | /* Do nothing with the data for now */ | ||
371 | nm_debug ("Monitor got unhandled data: '%s'", buf); | ||
372 | } | ||
373 | } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN); | ||
374 | } | ||
375 | |||
376 | if (condition & G_IO_HUP || condition & G_IO_ERR) { | ||
377 | return FALSE; | ||
378 | } | ||
379 | |||
380 | return TRUE; | ||
381 | } | ||
382 | |||
383 | static gboolean | ||
384 | setup_monitor_device (NMCdmaDevice *device) | ||
385 | { | ||
386 | NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (device); | ||
387 | GIOChannel *channel; | ||
388 | NMSettingSerial *setting; | ||
389 | |||
390 | if (!priv->monitor_iface) { | ||
391 | nm_debug ("No monitoring udi provided"); | ||
392 | return FALSE; | ||
393 | } | ||
394 | |||
395 | priv->monitor_device = g_object_new (NM_TYPE_SERIAL_DEVICE, | ||
396 | NM_DEVICE_INTERFACE_UDI, nm_device_get_udi (NM_DEVICE (device)), | ||
397 | NM_DEVICE_INTERFACE_IFACE, priv->monitor_iface, | ||
398 | NULL); | ||
399 | |||
400 | if (!priv->monitor_device) { | ||
401 | nm_warning ("Creation of the monitoring device failed"); | ||
402 | return FALSE; | ||
403 | } | ||
404 | |||
405 | setting = NM_SETTING_SERIAL (nm_setting_serial_new ()); | ||
406 | if (!nm_serial_device_open (priv->monitor_device, setting)) { | ||
407 | nm_warning ("Monitoring device open failed"); | ||
408 | g_object_unref (setting); | ||
409 | g_object_unref (priv->monitor_device); | ||
410 | return FALSE; | ||
411 | } | ||
412 | |||
413 | g_object_unref (setting); | ||
414 | |||
415 | channel = nm_serial_device_get_io_channel (priv->monitor_device); | ||
416 | g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP, | ||
417 | monitor_device_got_data, device); | ||
418 | |||
419 | g_io_channel_unref (channel); | ||
420 | |||
421 | return TRUE; | ||
422 | } | ||
423 | |||
424 | /*****************************************************************************/ | ||
425 | |||
426 | static void | ||
427 | nm_cdma_device_init (NMCdmaDevice *self) | ||
428 | { | ||
429 | nm_device_set_device_type (NM_DEVICE (self), NM_DEVICE_TYPE_CDMA); | ||
430 | } | ||
431 | |||
432 | static gboolean | ||
433 | unavailable_to_disconnected (gpointer user_data) | ||
434 | { | ||
435 | nm_device_state_changed (NM_DEVICE (user_data), | ||
436 | NM_DEVICE_STATE_DISCONNECTED, | ||
437 | NM_DEVICE_STATE_REASON_NONE); | ||
438 | return FALSE; | ||
439 | } | ||
440 | |||
441 | static void | ||
442 | device_state_changed (NMDeviceInterface *device, | ||
443 | NMDeviceState new_state, | ||
444 | NMDeviceState old_state, | ||
445 | NMDeviceStateReason reason, | ||
446 | gpointer user_data) | ||
447 | { | ||
448 | NMCdmaDevice *self = NM_CDMA_DEVICE (user_data); | ||
449 | NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (self); | ||
450 | |||
451 | /* Remove any previous delayed transition to disconnected */ | ||
452 | if (priv->state_to_disconnected_id) { | ||
453 | g_source_remove (priv->state_to_disconnected_id); | ||
454 | priv->state_to_disconnected_id = 0; | ||
455 | } | ||
456 | |||
457 | /* If transitioning to UNAVAILBLE and we have a carrier, transition to | ||
458 | * DISCONNECTED because the device is ready to use. Otherwise the carrier-on | ||
459 | * handler will handle the transition to DISCONNECTED when the carrier is detected. | ||
460 | */ | ||
461 | if (new_state == NM_DEVICE_STATE_UNAVAILABLE) | ||
462 | priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); | ||
463 | |||
464 | /* Make sure we don't leave the serial device open */ | ||
465 | switch (new_state) { | ||
466 | case NM_DEVICE_STATE_UNMANAGED: | ||
467 | case NM_DEVICE_STATE_UNAVAILABLE: | ||
468 | case NM_DEVICE_STATE_FAILED: | ||
469 | case NM_DEVICE_STATE_DISCONNECTED: | ||
470 | nm_serial_device_close (NM_SERIAL_DEVICE (self)); | ||
471 | break; | ||
472 | default: | ||
473 | break; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | static GObject* | ||
478 | constructor (GType type, | ||
479 | guint n_construct_params, | ||
480 | GObjectConstructParam *construct_params) | ||
481 | { | ||
482 | GObject *object; | ||
483 | |||
484 | object = G_OBJECT_CLASS (nm_cdma_device_parent_class)->constructor (type, | ||
485 | n_construct_params, | ||
486 | construct_params); | ||
487 | if (!object) | ||
488 | return NULL; | ||
489 | |||
490 | /* FIXME: Make the monitor device not required for now */ | ||
491 | setup_monitor_device (NM_CDMA_DEVICE (object)); | ||
492 | #if 0 | ||
493 | if (!setup_monitor_device (NM_CDMA_DEVICE (object))) { | ||
494 | g_object_unref (object); | ||
495 | object = NULL; | ||
496 | } | ||
497 | #endif | ||
498 | |||
499 | g_signal_connect (NM_DEVICE (object), "state-changed", | ||
500 | G_CALLBACK (device_state_changed), NM_CDMA_DEVICE (object)); | ||
501 | |||
502 | return object; | ||
503 | } | ||
504 | |||
505 | static void | ||
506 | set_property (GObject *object, guint prop_id, | ||
507 | const GValue *value, GParamSpec *pspec) | ||
508 | { | ||
509 | NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object); | ||
510 | |||
511 | switch (prop_id) { | ||
512 | case PROP_MONITOR_IFACE: | ||
513 | /* Construct only */ | ||
514 | priv->monitor_iface = g_value_dup_string (value); | ||
515 | break; | ||
516 | default: | ||
517 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
518 | break; | ||
519 | } | ||
520 | } | ||
521 | |||
522 | static void | ||
523 | get_property (GObject *object, guint prop_id, | ||
524 | GValue *value, GParamSpec *pspec) | ||
525 | { | ||
526 | NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object); | ||
527 | |||
528 | switch (prop_id) { | ||
529 | case PROP_MONITOR_IFACE: | ||
530 | g_value_set_string (value, priv->monitor_iface); | ||
531 | break; | ||
532 | default: | ||
533 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
534 | break; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | static void | ||
539 | finalize (GObject *object) | ||
540 | { | ||
541 | NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (object); | ||
542 | |||
543 | if (priv->monitor_device) | ||
544 | g_object_unref (priv->monitor_device); | ||
545 | |||
546 | g_free (priv->monitor_iface); | ||
547 | |||
548 | if (priv->state_to_disconnected_id) { | ||
549 | g_source_remove (priv->state_to_disconnected_id); | ||
550 | priv->state_to_disconnected_id = 0; | ||
551 | } | ||
552 | |||
553 | G_OBJECT_CLASS (nm_cdma_device_parent_class)->finalize (object); | ||
554 | } | ||
555 | |||
556 | static void | ||
557 | nm_cdma_device_class_init (NMCdmaDeviceClass *klass) | ||
558 | { | ||
559 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
560 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
561 | NMSerialDeviceClass *serial_class = NM_SERIAL_DEVICE_CLASS (klass); | ||
562 | |||
563 | g_type_class_add_private (object_class, sizeof (NMCdmaDevicePrivate)); | ||
564 | |||
565 | object_class->constructor = constructor; | ||
566 | object_class->get_property = get_property; | ||
567 | object_class->set_property = set_property; | ||
568 | object_class->finalize = finalize; | ||
569 | |||
570 | device_class->get_best_auto_connection = real_get_best_auto_connection; | ||
571 | device_class->get_generic_capabilities = real_get_generic_capabilities; | ||
572 | device_class->act_stage1_prepare = real_act_stage1_prepare; | ||
573 | device_class->connection_secrets_updated = real_connection_secrets_updated; | ||
574 | |||
575 | serial_class->get_ppp_name = real_get_ppp_name; | ||
576 | |||
577 | /* Properties */ | ||
578 | g_object_class_install_property | ||
579 | (object_class, PROP_MONITOR_IFACE, | ||
580 | g_param_spec_string (NM_CDMA_DEVICE_MONITOR_IFACE, | ||
581 | "Monitoring interface", | ||
582 | "Monitoring interface", | ||
583 | NULL, | ||
584 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); | ||
585 | |||
586 | /* Signals */ | ||
587 | signals[PROPERTIES_CHANGED] = | ||
588 | nm_properties_changed_signal_new (object_class, | ||
589 | G_STRUCT_OFFSET (NMCdmaDeviceClass, properties_changed)); | ||
590 | |||
591 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
592 | &dbus_glib_nm_cdma_device_object_info); | ||
593 | } | ||
diff --git a/src/nm-cdma-device.h b/src/nm-cdma-device.h deleted file mode 100644 index 50c44a3ed8..0000000000 --- a/src/nm-cdma-device.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2008 Red Hat, Inc. | ||
19 | * Copyright (C) 2008 Novell, Inc. | ||
20 | */ | ||
21 | |||
22 | #ifndef NM_CDMA_DEVICE_H | ||
23 | #define NM_CDMA_DEVICE_H | ||
24 | |||
25 | #include <nm-serial-device.h> | ||
26 | |||
27 | G_BEGIN_DECLS | ||
28 | |||
29 | #define NM_TYPE_CDMA_DEVICE (nm_cdma_device_get_type ()) | ||
30 | #define NM_CDMA_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CDMA_DEVICE, NMCdmaDevice)) | ||
31 | #define NM_CDMA_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CDMA_DEVICE, NMCdmaDeviceClass)) | ||
32 | #define NM_IS_CDMA_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CDMA_DEVICE)) | ||
33 | #define NM_IS_CDMA_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CDMA_DEVICE)) | ||
34 | #define NM_CDMA_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CDMA_DEVICE, NMCdmaDeviceClass)) | ||
35 | |||
36 | #define NM_CDMA_DEVICE_MONITOR_IFACE "monitor-iface" | ||
37 | |||
38 | typedef struct { | ||
39 | NMSerialDevice parent; | ||
40 | } NMCdmaDevice; | ||
41 | |||
42 | typedef struct { | ||
43 | NMSerialDeviceClass parent; | ||
44 | |||
45 | /* Signals */ | ||
46 | void (*properties_changed) (NMCdmaDevice *device, GHashTable *properties); | ||
47 | } NMCdmaDeviceClass; | ||
48 | |||
49 | GType nm_cdma_device_get_type (void); | ||
50 | |||
51 | NMCdmaDevice *nm_cdma_device_new (const char *udi, | ||
52 | const char *data_iface, | ||
53 | const char *monitor_iface, | ||
54 | const char *driver, | ||
55 | gboolean managed); | ||
56 | |||
57 | G_END_DECLS | ||
58 | |||
59 | #endif /* NM_CDMA_DEVICE_H */ | ||
diff --git a/src/nm-hal-manager.c b/src/nm-hal-manager.c index e7179c028f..ff308e8f4b 100644 --- a/src/nm-hal-manager.c +++ b/src/nm-hal-manager.c | |||
@@ -33,9 +33,6 @@ | |||
33 | #include "nm-utils.h" | 33 | #include "nm-utils.h" |
34 | #include "nm-device-wifi.h" | 34 | #include "nm-device-wifi.h" |
35 | #include "nm-device-ethernet.h" | 35 | #include "nm-device-ethernet.h" |
36 | #include "nm-gsm-device.h" | ||
37 | #include "nm-hso-gsm-device.h" | ||
38 | #include "nm-cdma-device.h" | ||
39 | 36 | ||
40 | /* Killswitch poll frequency in seconds */ | 37 | /* Killswitch poll frequency in seconds */ |
41 | #define RFKILL_POLL_FREQUENCY 6 | 38 | #define RFKILL_POLL_FREQUENCY 6 |
@@ -220,145 +217,6 @@ wireless_device_creator (NMHalManager *self, const char *udi, gboolean managed) | |||
220 | return device; | 217 | return device; |
221 | } | 218 | } |
222 | 219 | ||
223 | /* Modem device creator */ | ||
224 | |||
225 | static gboolean | ||
226 | is_modem_device (NMHalManager *self, const char *udi) | ||
227 | { | ||
228 | NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); | ||
229 | gboolean is_modem = FALSE; | ||
230 | |||
231 | if (libhal_device_property_exists (priv->hal_ctx, udi, "info.category", NULL)) { | ||
232 | char *category; | ||
233 | |||
234 | category = libhal_device_get_property_string (priv->hal_ctx, udi, "info.category", NULL); | ||
235 | if (category) { | ||
236 | is_modem = strcmp (category, "serial") == 0; | ||
237 | libhal_free_string (category); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | return is_modem; | ||
242 | } | ||
243 | |||
244 | static char * | ||
245 | get_hso_netdev (LibHalContext *ctx, const char *udi) | ||
246 | { | ||
247 | char *serial_parent, *netdev = NULL; | ||
248 | char **netdevs; | ||
249 | int num, i; | ||
250 | |||
251 | /* Get the serial interface's originating device UDI, used to find the | ||
252 | * originating device's netdev. | ||
253 | */ | ||
254 | serial_parent = libhal_device_get_property_string (ctx, udi, "serial.originating_device", NULL); | ||
255 | if (!serial_parent) | ||
256 | serial_parent = libhal_device_get_property_string (ctx, udi, "info.parent", NULL); | ||
257 | if (!serial_parent) | ||
258 | return NULL; | ||
259 | |||
260 | /* Look for the originating device's netdev */ | ||
261 | netdevs = libhal_find_device_by_capability (ctx, "net", &num, NULL); | ||
262 | for (i = 0; netdevs && !netdev && (i < num); i++) { | ||
263 | char *netdev_parent, *tmp; | ||
264 | |||
265 | netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.originating_device", NULL); | ||
266 | if (!netdev_parent) | ||
267 | netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "net.physical_device", NULL); | ||
268 | if (!netdev_parent) | ||
269 | continue; | ||
270 | |||
271 | if (!strcmp (netdev_parent, serial_parent)) { | ||
272 | /* We found it */ | ||
273 | tmp = libhal_device_get_property_string (ctx, netdevs[i], "net.interface", NULL); | ||
274 | if (tmp) { | ||
275 | netdev = g_strdup (tmp); | ||
276 | libhal_free_string (tmp); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | libhal_free_string (netdev_parent); | ||
281 | } | ||
282 | libhal_free_string_array (netdevs); | ||
283 | libhal_free_string (serial_parent); | ||
284 | |||
285 | return netdev; | ||
286 | } | ||
287 | |||
288 | static GObject * | ||
289 | modem_device_creator (NMHalManager *self, const char *udi, gboolean managed) | ||
290 | { | ||
291 | NMHalManagerPrivate *priv = NM_HAL_MANAGER_GET_PRIVATE (self); | ||
292 | char *serial_device; | ||
293 | char *parent_udi; | ||
294 | char *driver_name = NULL; | ||
295 | GObject *device = NULL; | ||
296 | char **capabilities, **iter; | ||
297 | gboolean type_gsm = FALSE; | ||
298 | gboolean type_cdma = FALSE; | ||
299 | char *netdev = NULL; | ||
300 | |||
301 | serial_device = libhal_device_get_property_string (priv->hal_ctx, udi, "serial.device", NULL); | ||
302 | |||
303 | /* Get the driver */ | ||
304 | parent_udi = libhal_device_get_property_string (priv->hal_ctx, udi, "info.parent", NULL); | ||
305 | if (parent_udi) { | ||
306 | driver_name = libhal_device_get_property_string (priv->hal_ctx, parent_udi, "info.linux.driver", NULL); | ||
307 | libhal_free_string (parent_udi); | ||
308 | } | ||
309 | |||
310 | if (!serial_device || !driver_name) | ||
311 | goto out; | ||
312 | |||
313 | capabilities = libhal_device_get_property_strlist (priv->hal_ctx, udi, "modem.command_sets", NULL); | ||
314 | /* 'capabilites' may be NULL */ | ||
315 | for (iter = capabilities; iter && *iter; iter++) { | ||
316 | if (!strcmp (*iter, "GSM-07.07")) { | ||
317 | type_gsm = TRUE; | ||
318 | break; | ||
319 | } | ||
320 | if (!strcmp (*iter, "IS-707-A")) { | ||
321 | type_cdma = TRUE; | ||
322 | break; | ||
323 | } | ||
324 | } | ||
325 | g_strfreev (capabilities); | ||
326 | |||
327 | /* Compatiblity with the pre-specification bits */ | ||
328 | if (!type_gsm && !type_cdma) { | ||
329 | capabilities = libhal_device_get_property_strlist (priv->hal_ctx, udi, "info.capabilities", NULL); | ||
330 | for (iter = capabilities; *iter; iter++) { | ||
331 | if (!strcmp (*iter, "gsm")) { | ||
332 | type_gsm = TRUE; | ||
333 | break; | ||
334 | } | ||
335 | if (!strcmp (*iter, "cdma")) { | ||
336 | type_cdma = TRUE; | ||
337 | break; | ||
338 | } | ||
339 | } | ||
340 | g_strfreev (capabilities); | ||
341 | } | ||
342 | |||
343 | /* Special handling of 'hso' cards (until punted out to a modem manager) */ | ||
344 | if (type_gsm && !strcmp (driver_name, "hso")) | ||
345 | netdev = get_hso_netdev (priv->hal_ctx, udi); | ||
346 | |||
347 | if (type_gsm) { | ||
348 | if (netdev) | ||
349 | device = (GObject *) nm_hso_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, netdev, driver_name, managed); | ||
350 | else | ||
351 | device = (GObject *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed); | ||
352 | } else if (type_cdma) | ||
353 | device = (GObject *) nm_cdma_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed); | ||
354 | |||
355 | out: | ||
356 | libhal_free_string (serial_device); | ||
357 | libhal_free_string (driver_name); | ||
358 | |||
359 | return device; | ||
360 | } | ||
361 | |||
362 | static void | 220 | static void |
363 | register_built_in_creators (NMHalManager *self) | 221 | register_built_in_creators (NMHalManager *self) |
364 | { | 222 | { |
@@ -380,14 +238,6 @@ register_built_in_creators (NMHalManager *self) | |||
380 | creator->is_device_fn = is_wireless_device; | 238 | creator->is_device_fn = is_wireless_device; |
381 | creator->creator_fn = wireless_device_creator; | 239 | creator->creator_fn = wireless_device_creator; |
382 | priv->device_creators = g_slist_append (priv->device_creators, creator); | 240 | priv->device_creators = g_slist_append (priv->device_creators, creator); |
383 | |||
384 | /* Modem */ | ||
385 | creator = g_slice_new0 (DeviceCreator); | ||
386 | creator->device_type_name = g_strdup ("Modem"); | ||
387 | creator->capability_str = g_strdup ("modem"); | ||
388 | creator->is_device_fn = is_modem_device; | ||
389 | creator->creator_fn = modem_device_creator; | ||
390 | priv->device_creators = g_slist_append (priv->device_creators, creator); | ||
391 | } | 241 | } |
392 | 242 | ||
393 | static void | 243 | static void |
diff --git a/src/nm-hso-gsm-device.c b/src/nm-hso-gsm-device.c deleted file mode 100644 index 15032a3c15..0000000000 --- a/src/nm-hso-gsm-device.c +++ /dev/null | |||
@@ -1,593 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2008 Red Hat, Inc. | ||
19 | */ | ||
20 | |||
21 | #include <stdio.h> | ||
22 | #include <string.h> | ||
23 | #include <errno.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <arpa/inet.h> | ||
26 | #include <dbus/dbus-glib.h> | ||
27 | |||
28 | #include "nm-device.h" | ||
29 | #include "nm-hso-gsm-device.h" | ||
30 | #include "nm-gsm-device.h" | ||
31 | #include "nm-device-interface.h" | ||
32 | #include "nm-device-private.h" | ||
33 | #include "nm-setting-gsm.h" | ||
34 | #include "nm-utils.h" | ||
35 | #include "nm-properties-changed-signal.h" | ||
36 | #include "nm-setting-connection.h" | ||
37 | #include "NetworkManagerSystem.h" | ||
38 | |||
39 | G_DEFINE_TYPE (NMHsoGsmDevice, nm_hso_gsm_device, NM_TYPE_GSM_DEVICE) | ||
40 | |||
41 | #define NM_HSO_GSM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDevicePrivate)) | ||
42 | |||
43 | extern const DBusGObjectInfo dbus_glib_nm_gsm_device_object_info; | ||
44 | |||
45 | #define GSM_CID "gsm-cid" | ||
46 | #define HSO_SECRETS_TRIES "gsm-secrets-tries" | ||
47 | |||
48 | typedef struct { | ||
49 | char *netdev_iface; | ||
50 | NMIP4Config *pending_ip4_config; | ||
51 | } NMHsoGsmDevicePrivate; | ||
52 | |||
53 | enum { | ||
54 | PROP_0, | ||
55 | PROP_NETDEV_IFACE, | ||
56 | |||
57 | LAST_PROP | ||
58 | }; | ||
59 | |||
60 | NMHsoGsmDevice * | ||
61 | nm_hso_gsm_device_new (const char *udi, | ||
62 | const char *data_iface, | ||
63 | const char *monitor_iface, | ||
64 | const char *netdev_iface, | ||
65 | const char *driver, | ||
66 | gboolean managed) | ||
67 | { | ||
68 | g_return_val_if_fail (udi != NULL, NULL); | ||
69 | g_return_val_if_fail (data_iface != NULL, NULL); | ||
70 | g_return_val_if_fail (driver != NULL, NULL); | ||
71 | g_return_val_if_fail (netdev_iface != NULL, NULL); | ||
72 | |||
73 | return (NMHsoGsmDevice *) g_object_new (NM_TYPE_HSO_GSM_DEVICE, | ||
74 | NM_DEVICE_INTERFACE_UDI, udi, | ||
75 | NM_DEVICE_INTERFACE_IFACE, data_iface, | ||
76 | NM_DEVICE_INTERFACE_DRIVER, driver, | ||
77 | NM_GSM_DEVICE_MONITOR_IFACE, monitor_iface, | ||
78 | NM_HSO_GSM_DEVICE_NETDEV_IFACE, netdev_iface, | ||
79 | NM_DEVICE_INTERFACE_MANAGED, managed, | ||
80 | NULL); | ||
81 | } | ||
82 | |||
83 | static void | ||
84 | modem_wait_for_reply (NMGsmDevice *self, | ||
85 | const char *command, | ||
86 | guint timeout, | ||
87 | const char **responses, | ||
88 | const char **terminators, | ||
89 | NMSerialWaitForReplyFn callback, | ||
90 | gpointer user_data) | ||
91 | { | ||
92 | NMSerialDevice *serial = NM_SERIAL_DEVICE (self); | ||
93 | guint id = 0; | ||
94 | |||
95 | if (nm_serial_device_send_command_string (serial, command)) | ||
96 | id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, user_data); | ||
97 | |||
98 | if (id == 0) | ||
99 | nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN); | ||
100 | } | ||
101 | |||
102 | static NMSetting * | ||
103 | gsm_device_get_setting (NMGsmDevice *device, GType setting_type) | ||
104 | { | ||
105 | NMActRequest *req; | ||
106 | NMSetting *setting = NULL; | ||
107 | |||
108 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
109 | if (req) { | ||
110 | NMConnection *connection; | ||
111 | |||
112 | connection = nm_act_request_get_connection (req); | ||
113 | if (connection) | ||
114 | setting = nm_connection_get_setting (connection, setting_type); | ||
115 | } | ||
116 | |||
117 | return setting; | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | hso_call_done (NMSerialDevice *device, | ||
122 | int reply_index, | ||
123 | const char *reply, | ||
124 | gpointer user_data) | ||
125 | { | ||
126 | gboolean success = FALSE; | ||
127 | |||
128 | switch (reply_index) { | ||
129 | case 0: | ||
130 | nm_info ("Connected, Woo!"); | ||
131 | success = TRUE; | ||
132 | break; | ||
133 | default: | ||
134 | nm_warning ("Connect request failed"); | ||
135 | break; | ||
136 | } | ||
137 | |||
138 | if (success) | ||
139 | nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (device)); | ||
140 | else | ||
141 | nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED); | ||
142 | } | ||
143 | |||
144 | static void | ||
145 | hso_clear_done (NMSerialDevice *device, | ||
146 | int reply_index, | ||
147 | const char *reply, | ||
148 | gpointer user_data) | ||
149 | { | ||
150 | const char *responses[] = { "_OWANCALL: ", "ERROR", NULL }; | ||
151 | guint cid = GPOINTER_TO_UINT (user_data); | ||
152 | char *command; | ||
153 | |||
154 | /* Try to connect */ | ||
155 | command = g_strdup_printf ("AT_OWANCALL=%d,1,1", cid); | ||
156 | modem_wait_for_reply (NM_GSM_DEVICE (device), command, 10, responses, responses, hso_call_done, NULL); | ||
157 | g_free (command); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | hso_auth_done (NMSerialDevice *device, | ||
162 | int reply_index, | ||
163 | const char *reply, | ||
164 | gpointer user_data) | ||
165 | { | ||
166 | gboolean success = FALSE; | ||
167 | const char *responses[] = { "_OWANCALL: ", "ERROR", "NO CARRIER", NULL }; | ||
168 | guint cid = GPOINTER_TO_UINT (user_data); | ||
169 | char *command; | ||
170 | |||
171 | switch (reply_index) { | ||
172 | case 0: | ||
173 | nm_info ("Authentication successful!"); | ||
174 | success = TRUE; | ||
175 | break; | ||
176 | default: | ||
177 | nm_warning ("Authentication failed"); | ||
178 | break; | ||
179 | } | ||
180 | |||
181 | if (!success) { | ||
182 | nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED); | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | /* Kill any existing connection */ | ||
187 | command = g_strdup_printf ("AT_OWANCALL=%d,0,1", cid); | ||
188 | modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, responses, hso_clear_done, GUINT_TO_POINTER (cid)); | ||
189 | g_free (command); | ||
190 | } | ||
191 | |||
192 | static void | ||
193 | do_hso_auth (NMHsoGsmDevice *device) | ||
194 | { | ||
195 | NMSettingGsm *s_gsm; | ||
196 | NMActRequest *req; | ||
197 | const char *responses[] = { "OK", "ERROR", "ERR", NULL }; | ||
198 | char *command; | ||
199 | const char *gsm_username; | ||
200 | const char *gsm_password; | ||
201 | guint cid; | ||
202 | |||
203 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
204 | g_assert (req); | ||
205 | |||
206 | cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID)); | ||
207 | |||
208 | s_gsm = NM_SETTING_GSM (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_GSM)); | ||
209 | |||
210 | gsm_username = nm_setting_gsm_get_username (s_gsm); | ||
211 | gsm_password = nm_setting_gsm_get_password (s_gsm); | ||
212 | |||
213 | command = g_strdup_printf ("AT$QCPDPP=%d,1,\"%s\",\"%s\"", | ||
214 | cid, | ||
215 | gsm_password ? gsm_password : "", | ||
216 | gsm_username ? gsm_username : ""); | ||
217 | modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, responses, hso_auth_done, GUINT_TO_POINTER (cid)); | ||
218 | g_free (command); | ||
219 | } | ||
220 | |||
221 | static NMActStageReturn | ||
222 | real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) | ||
223 | { | ||
224 | NMActRequest *req; | ||
225 | NMConnection *connection; | ||
226 | const char *setting_name; | ||
227 | GPtrArray *hints = NULL; | ||
228 | const char *hint1 = NULL, *hint2 = NULL; | ||
229 | guint32 tries; | ||
230 | |||
231 | req = nm_device_get_act_request (device); | ||
232 | g_assert (req); | ||
233 | connection = nm_act_request_get_connection (req); | ||
234 | g_assert (connection); | ||
235 | |||
236 | setting_name = nm_connection_need_secrets (connection, &hints); | ||
237 | if (!setting_name) { | ||
238 | do_hso_auth (NM_HSO_GSM_DEVICE (device)); | ||
239 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
240 | } | ||
241 | |||
242 | if (hints) { | ||
243 | if (hints->len > 0) | ||
244 | hint1 = g_ptr_array_index (hints, 0); | ||
245 | if (hints->len > 1) | ||
246 | hint2 = g_ptr_array_index (hints, 1); | ||
247 | } | ||
248 | |||
249 | nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
250 | |||
251 | tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), HSO_SECRETS_TRIES)); | ||
252 | nm_act_request_request_connection_secrets (req, | ||
253 | setting_name, | ||
254 | tries ? TRUE : FALSE, | ||
255 | SECRETS_CALLER_HSO_GSM, | ||
256 | hint1, | ||
257 | hint2); | ||
258 | g_object_set_data (G_OBJECT (connection), HSO_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); | ||
259 | |||
260 | if (hints) | ||
261 | g_ptr_array_free (hints, TRUE); | ||
262 | |||
263 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
264 | } | ||
265 | |||
266 | static void | ||
267 | real_do_dial (NMGsmDevice *device, guint cid) | ||
268 | { | ||
269 | NMActRequest *req; | ||
270 | |||
271 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
272 | g_assert (req); | ||
273 | g_object_set_data (G_OBJECT (req), GSM_CID, GUINT_TO_POINTER (cid)); | ||
274 | |||
275 | nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device)); | ||
276 | } | ||
277 | |||
278 | #define OWANDATA_TAG "_OWANDATA: " | ||
279 | |||
280 | static void | ||
281 | hso_ip4_config_response (NMSerialDevice *device, | ||
282 | int reply_index, | ||
283 | const char *response, | ||
284 | gpointer user_data) | ||
285 | { | ||
286 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device); | ||
287 | NMActRequest *req; | ||
288 | char **items, **iter; | ||
289 | guint cid, i; | ||
290 | guint32 dns1 = 0, dns2 = 0, ip4_address = 0; | ||
291 | |||
292 | if ( (reply_index < 0) | ||
293 | || !response | ||
294 | || strncmp (response, OWANDATA_TAG, strlen (OWANDATA_TAG))) { | ||
295 | nm_device_activate_schedule_stage4_ip_config_timeout (NM_DEVICE (device)); | ||
296 | return; | ||
297 | } | ||
298 | |||
299 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
300 | g_assert (req); | ||
301 | cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID)); | ||
302 | |||
303 | items = g_strsplit (response + strlen (OWANDATA_TAG), ", ", 0); | ||
304 | for (iter = items, i = 0; *iter; iter++, i++) { | ||
305 | if (i == 0) { /* CID */ | ||
306 | long int tmp; | ||
307 | |||
308 | errno = 0; | ||
309 | tmp = strtol (*iter, NULL, 10); | ||
310 | if (errno != 0 || tmp < 0 || (guint) tmp != cid) { | ||
311 | nm_warning ("%s: unknown CID in OWANDATA response (got %d, expected %d)", | ||
312 | nm_device_get_iface (NM_DEVICE (device)), | ||
313 | (guint) tmp, cid); | ||
314 | goto out; | ||
315 | } | ||
316 | } else if (i == 1) { /* IP address */ | ||
317 | if (inet_pton (AF_INET, *iter, &ip4_address) <= 0) | ||
318 | ip4_address = 0; | ||
319 | } else if (i == 3) { /* DNS 1 */ | ||
320 | if (inet_pton (AF_INET, *iter, &dns1) <= 0) | ||
321 | dns1 = 0; | ||
322 | } else if (i == 4) { /* DNS 2 */ | ||
323 | if (inet_pton (AF_INET, *iter, &dns2) <= 0) | ||
324 | dns2 = 0; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | out: | ||
329 | g_strfreev (items); | ||
330 | |||
331 | if (ip4_address) { | ||
332 | NMIP4Address *addr; | ||
333 | |||
334 | priv->pending_ip4_config = nm_ip4_config_new (); | ||
335 | |||
336 | addr = nm_ip4_address_new (); | ||
337 | nm_ip4_address_set_address (addr, ip4_address); | ||
338 | nm_ip4_address_set_prefix (addr, 32); | ||
339 | |||
340 | nm_ip4_config_take_address (priv->pending_ip4_config, addr); | ||
341 | |||
342 | if (dns1) | ||
343 | nm_ip4_config_add_nameserver (priv->pending_ip4_config, dns1); | ||
344 | if (dns2) | ||
345 | nm_ip4_config_add_nameserver (priv->pending_ip4_config, dns2); | ||
346 | |||
347 | nm_device_activate_schedule_stage4_ip_config_get (NM_DEVICE (device)); | ||
348 | } else { | ||
349 | nm_device_state_changed (NM_DEVICE (device), | ||
350 | NM_DEVICE_STATE_FAILED, | ||
351 | NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | static NMActStageReturn | ||
356 | real_act_stage3_ip_config_start (NMDevice *device, NMDeviceStateReason *reason) | ||
357 | { | ||
358 | NMActRequest *req; | ||
359 | char *command; | ||
360 | gint cid; | ||
361 | const char *responses[] = { "_OWANDATA: ", NULL }; | ||
362 | const char *terminators[] = { "OK", "ERROR", "ERR", NULL }; | ||
363 | |||
364 | req = nm_device_get_act_request (device); | ||
365 | g_assert (req); | ||
366 | |||
367 | cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID)); | ||
368 | command = g_strdup_printf ("AT_OWANDATA=%d", cid); | ||
369 | modem_wait_for_reply (NM_GSM_DEVICE (device), command, 5, responses, terminators, hso_ip4_config_response, NULL); | ||
370 | g_free (command); | ||
371 | |||
372 | return NM_ACT_STAGE_RETURN_POSTPONE; | ||
373 | } | ||
374 | |||
375 | static NMActStageReturn | ||
376 | real_act_stage4_get_ip4_config (NMDevice *device, | ||
377 | NMIP4Config **config, | ||
378 | NMDeviceStateReason *reason) | ||
379 | { | ||
380 | NMHsoGsmDevice *self = NM_HSO_GSM_DEVICE (device); | ||
381 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (self); | ||
382 | gboolean no_firmware = FALSE; | ||
383 | |||
384 | g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); | ||
385 | g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); | ||
386 | |||
387 | nm_device_set_ip_iface (device, priv->netdev_iface); | ||
388 | if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) { | ||
389 | if (no_firmware) | ||
390 | *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING; | ||
391 | else | ||
392 | *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; | ||
393 | return NM_ACT_STAGE_RETURN_FAILURE; | ||
394 | } | ||
395 | |||
396 | *config = priv->pending_ip4_config; | ||
397 | priv->pending_ip4_config = NULL; | ||
398 | return NM_ACT_STAGE_RETURN_SUCCESS; | ||
399 | } | ||
400 | |||
401 | static void | ||
402 | real_connection_secrets_updated (NMDevice *device, | ||
403 | NMConnection *connection, | ||
404 | GSList *updated_settings, | ||
405 | RequestSecretsCaller caller) | ||
406 | { | ||
407 | g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); | ||
408 | |||
409 | if (caller == SECRETS_CALLER_HSO_GSM) { /* HSO PPP auth */ | ||
410 | nm_device_activate_schedule_stage2_device_config (device); | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | /* Let parent handle other auth like PIN/PUK */ | ||
415 | NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->connection_secrets_updated (device, connection, updated_settings, caller); | ||
416 | } | ||
417 | |||
418 | static void | ||
419 | real_deactivate_quickly (NMDevice *device) | ||
420 | { | ||
421 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device); | ||
422 | NMActRequest *req; | ||
423 | guint cid; | ||
424 | char *command; | ||
425 | |||
426 | if (priv->pending_ip4_config) { | ||
427 | g_object_unref (priv->pending_ip4_config); | ||
428 | priv->pending_ip4_config = NULL; | ||
429 | } | ||
430 | |||
431 | /* Don't leave the modem connected */ | ||
432 | req = nm_device_get_act_request (device); | ||
433 | if (req) { | ||
434 | cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), GSM_CID)); | ||
435 | if (cid) { | ||
436 | const char *responses[] = { "OK", "ERROR", "ERR", NULL }; | ||
437 | int reply; | ||
438 | |||
439 | /* Disconnect and disable asynchonous notification to keep serial | ||
440 | * buffer empty after the OK. | ||
441 | */ | ||
442 | command = g_strdup_printf ("AT_OWANCALL=%d,0,0", cid); | ||
443 | nm_serial_device_send_command_string (NM_SERIAL_DEVICE (device), command); | ||
444 | reply = nm_serial_device_wait_reply_blocking (NM_SERIAL_DEVICE (device), 5, responses, responses); | ||
445 | g_free (command); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | if (NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate_quickly) | ||
450 | NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate_quickly (device); | ||
451 | } | ||
452 | |||
453 | static void | ||
454 | real_deactivate (NMDevice *device) | ||
455 | { | ||
456 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device); | ||
457 | |||
458 | if (priv->netdev_iface) { | ||
459 | nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface); | ||
460 | nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface); | ||
461 | nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL); | ||
462 | } | ||
463 | nm_device_set_ip_iface (device, NULL); | ||
464 | |||
465 | if (NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate) | ||
466 | NM_DEVICE_CLASS (nm_hso_gsm_device_parent_class)->deactivate (device); | ||
467 | } | ||
468 | |||
469 | static gboolean | ||
470 | real_hw_is_up (NMDevice *device) | ||
471 | { | ||
472 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device); | ||
473 | NMDeviceState state; | ||
474 | |||
475 | state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); | ||
476 | |||
477 | if ( priv->pending_ip4_config | ||
478 | || (state == NM_DEVICE_STATE_IP_CONFIG) | ||
479 | || (state == NM_DEVICE_STATE_ACTIVATED)) | ||
480 | return nm_system_device_is_up_with_iface (priv->netdev_iface); | ||
481 | |||
482 | return TRUE; | ||
483 | } | ||
484 | |||
485 | static gboolean | ||
486 | real_hw_bring_up (NMDevice *device, gboolean *no_firmware) | ||
487 | { | ||
488 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device); | ||
489 | NMDeviceState state; | ||
490 | |||
491 | state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); | ||
492 | |||
493 | if ( priv->pending_ip4_config | ||
494 | || (state == NM_DEVICE_STATE_IP_CONFIG) | ||
495 | || (state == NM_DEVICE_STATE_ACTIVATED)) | ||
496 | return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware); | ||
497 | |||
498 | return TRUE; | ||
499 | } | ||
500 | |||
501 | static void | ||
502 | nm_hso_gsm_device_init (NMHsoGsmDevice *self) | ||
503 | { | ||
504 | } | ||
505 | |||
506 | static GObject* | ||
507 | constructor (GType type, | ||
508 | guint n_params, | ||
509 | GObjectConstructParam *params) | ||
510 | { | ||
511 | return G_OBJECT_CLASS (nm_hso_gsm_device_parent_class)->constructor (type, n_params, params); | ||
512 | } | ||
513 | |||
514 | static void | ||
515 | set_property (GObject *object, guint prop_id, | ||
516 | const GValue *value, GParamSpec *pspec) | ||
517 | { | ||
518 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object); | ||
519 | |||
520 | switch (prop_id) { | ||
521 | case PROP_NETDEV_IFACE: | ||
522 | /* Construct only */ | ||
523 | priv->netdev_iface = g_value_dup_string (value); | ||
524 | break; | ||
525 | default: | ||
526 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | static void | ||
532 | get_property (GObject *object, guint prop_id, | ||
533 | GValue *value, GParamSpec *pspec) | ||
534 | { | ||
535 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object); | ||
536 | |||
537 | switch (prop_id) { | ||
538 | case PROP_NETDEV_IFACE: | ||
539 | g_value_set_string (value, priv->netdev_iface); | ||
540 | break; | ||
541 | default: | ||
542 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||
543 | break; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | static void | ||
548 | finalize (GObject *object) | ||
549 | { | ||
550 | NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (object); | ||
551 | |||
552 | g_free (priv->netdev_iface); | ||
553 | |||
554 | G_OBJECT_CLASS (nm_hso_gsm_device_parent_class)->finalize (object); | ||
555 | } | ||
556 | |||
557 | static void | ||
558 | nm_hso_gsm_device_class_init (NMHsoGsmDeviceClass *klass) | ||
559 | { | ||
560 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
561 | NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); | ||
562 | NMGsmDeviceClass *gsm_class = NM_GSM_DEVICE_CLASS (klass); | ||
563 | |||
564 | g_type_class_add_private (object_class, sizeof (NMHsoGsmDevicePrivate)); | ||
565 | |||
566 | object_class->constructor = constructor; | ||
567 | object_class->get_property = get_property; | ||
568 | object_class->set_property = set_property; | ||
569 | object_class->finalize = finalize; | ||
570 | |||
571 | device_class->act_stage2_config = real_act_stage2_config; | ||
572 | device_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start; | ||
573 | device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; | ||
574 | device_class->connection_secrets_updated = real_connection_secrets_updated; | ||
575 | device_class->deactivate_quickly = real_deactivate_quickly; | ||
576 | device_class->deactivate = real_deactivate; | ||
577 | device_class->hw_is_up = real_hw_is_up; | ||
578 | device_class->hw_bring_up = real_hw_bring_up; | ||
579 | |||
580 | gsm_class->do_dial = real_do_dial; | ||
581 | |||
582 | /* Properties */ | ||
583 | g_object_class_install_property | ||
584 | (object_class, PROP_NETDEV_IFACE, | ||
585 | g_param_spec_string (NM_HSO_GSM_DEVICE_NETDEV_IFACE, | ||
586 | "Network interface", | ||
587 | "Network interface", | ||
588 | NULL, | ||
589 | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT)); | ||
590 | |||
591 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
592 | &dbus_glib_nm_gsm_device_object_info); | ||
593 | } | ||
diff --git a/src/nm-hso-gsm-device.h b/src/nm-hso-gsm-device.h deleted file mode 100644 index 5b6b48ac66..0000000000 --- a/src/nm-hso-gsm-device.h +++ /dev/null | |||
@@ -1,56 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2008 Red Hat, Inc. | ||
19 | */ | ||
20 | |||
21 | #ifndef NM_HSO_GSM_DEVICE_H | ||
22 | #define NM_HSO_GSM_DEVICE_H | ||
23 | |||
24 | #include <nm-gsm-device.h> | ||
25 | |||
26 | G_BEGIN_DECLS | ||
27 | |||
28 | #define NM_TYPE_HSO_GSM_DEVICE (nm_hso_gsm_device_get_type ()) | ||
29 | #define NM_HSO_GSM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDevice)) | ||
30 | #define NM_HSO_GSM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDeviceClass)) | ||
31 | #define NM_IS_HSO_GSM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HSO_GSM_DEVICE)) | ||
32 | #define NM_IS_HSO_GSM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_HSO_GSM_DEVICE)) | ||
33 | #define NM_HSO_GSM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_HSO_GSM_DEVICE, NMHsoGsmDeviceClass)) | ||
34 | |||
35 | #define NM_HSO_GSM_DEVICE_NETDEV_IFACE "netdev-iface" | ||
36 | |||
37 | typedef struct { | ||
38 | NMGsmDevice parent; | ||
39 | } NMHsoGsmDevice; | ||
40 | |||
41 | typedef struct { | ||
42 | NMGsmDeviceClass parent; | ||
43 | } NMHsoGsmDeviceClass; | ||
44 | |||
45 | GType nm_hso_gsm_device_get_type (void); | ||
46 | |||
47 | NMHsoGsmDevice *nm_hso_gsm_device_new (const char *udi, | ||
48 | const char *data_iface, | ||
49 | const char *monitor_iface, | ||
50 | const char *netdev_iface, | ||
51 | const char *driver, | ||
52 | gboolean managed); | ||
53 | |||
54 | G_END_DECLS | ||
55 | |||
56 | #endif /* NM_HSO_GSM_DEVICE_H */ | ||
diff --git a/src/nm-manager.c b/src/nm-manager.c index 1b40834432..e0d8f71e68 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "nm-utils.h" | 29 | #include "nm-utils.h" |
30 | #include "nm-dbus-manager.h" | 30 | #include "nm-dbus-manager.h" |
31 | #include "nm-vpn-manager.h" | 31 | #include "nm-vpn-manager.h" |
32 | #include "nm-modem-manager.h" | ||
32 | #include "nm-device-interface.h" | 33 | #include "nm-device-interface.h" |
33 | #include "nm-device-private.h" | 34 | #include "nm-device-private.h" |
34 | #include "nm-device-wifi.h" | 35 | #include "nm-device-wifi.h" |
@@ -96,6 +97,9 @@ static void system_settings_properties_changed_cb (DBusGProxy *proxy, | |||
96 | GHashTable *properties, | 97 | GHashTable *properties, |
97 | gpointer user_data); | 98 | gpointer user_data); |
98 | 99 | ||
100 | static void add_device (NMManager *self, NMDevice *device, const char *type_name); | ||
101 | static void remove_one_device (NMManager *manager, NMDevice *device); | ||
102 | |||
99 | #define SSD_POKE_INTERVAL 120 | 103 | #define SSD_POKE_INTERVAL 120 |
100 | 104 | ||
101 | typedef struct { | 105 | typedef struct { |
@@ -134,6 +138,10 @@ typedef struct { | |||
134 | NMVPNManager *vpn_manager; | 138 | NMVPNManager *vpn_manager; |
135 | guint vpn_manager_id; | 139 | guint vpn_manager_id; |
136 | 140 | ||
141 | NMModemManager *modem_manager; | ||
142 | guint modem_added_id; | ||
143 | guint modem_removed_id; | ||
144 | |||
137 | DBusGProxy *aipd_proxy; | 145 | DBusGProxy *aipd_proxy; |
138 | 146 | ||
139 | gboolean disposed; | 147 | gboolean disposed; |
@@ -242,6 +250,36 @@ vpn_manager_connection_deactivated_cb (NMVPNManager *manager, | |||
242 | } | 250 | } |
243 | 251 | ||
244 | static void | 252 | static void |
253 | modem_added (NMModemManager *modem_manager, | ||
254 | NMDevice *modem, | ||
255 | gpointer user_data) | ||
256 | { | ||
257 | NMDeviceType type; | ||
258 | const char *type_name; | ||
259 | |||
260 | type = nm_device_get_device_type (NM_DEVICE (modem)); | ||
261 | if (type == NM_DEVICE_TYPE_GSM) | ||
262 | type_name = "GSM modem"; | ||
263 | else if (type == NM_DEVICE_TYPE_CDMA) | ||
264 | type_name = "CDMA modem"; | ||
265 | else | ||
266 | type_name = "Unknown modem"; | ||
267 | |||
268 | add_device (NM_MANAGER (user_data), NM_DEVICE (g_object_ref (modem)), type_name); | ||
269 | } | ||
270 | |||
271 | static void | ||
272 | modem_removed (NMModemManager *modem_manager, | ||
273 | NMDevice *modem, | ||
274 | gpointer user_data) | ||
275 | { | ||
276 | NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data); | ||
277 | |||
278 | remove_one_device (NM_MANAGER (user_data), modem); | ||
279 | priv->devices = g_slist_remove (priv->devices, modem); | ||
280 | } | ||
281 | |||
282 | static void | ||
245 | aipd_handle_event (DBusGProxy *proxy, | 283 | aipd_handle_event (DBusGProxy *proxy, |
246 | const char *event, | 284 | const char *event, |
247 | const char *iface, | 285 | const char *iface, |
@@ -304,6 +342,12 @@ nm_manager_init (NMManager *manager) | |||
304 | g_free, | 342 | g_free, |
305 | g_object_unref); | 343 | g_object_unref); |
306 | 344 | ||
345 | priv->modem_manager = nm_modem_manager_get (); | ||
346 | priv->modem_added_id = g_signal_connect (priv->modem_manager, "device-added", | ||
347 | G_CALLBACK (modem_added), manager); | ||
348 | priv->modem_removed_id = g_signal_connect (priv->modem_manager, "device-removed", | ||
349 | G_CALLBACK (modem_removed), manager); | ||
350 | |||
307 | priv->vpn_manager = nm_vpn_manager_get (); | 351 | priv->vpn_manager = nm_vpn_manager_get (); |
308 | id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated", | 352 | id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated", |
309 | G_CALLBACK (vpn_manager_connection_deactivated_cb), manager); | 353 | G_CALLBACK (vpn_manager_connection_deactivated_cb), manager); |
@@ -503,6 +547,16 @@ dispose (GObject *object) | |||
503 | } | 547 | } |
504 | g_object_unref (priv->vpn_manager); | 548 | g_object_unref (priv->vpn_manager); |
505 | 549 | ||
550 | if (priv->modem_added_id) { | ||
551 | g_source_remove (priv->modem_added_id); | ||
552 | priv->modem_added_id = 0; | ||
553 | } | ||
554 | if (priv->modem_removed_id) { | ||
555 | g_source_remove (priv->modem_removed_id); | ||
556 | priv->modem_removed_id = 0; | ||
557 | } | ||
558 | g_object_unref (priv->modem_manager); | ||
559 | |||
506 | g_object_unref (priv->dbus_mgr); | 560 | g_object_unref (priv->dbus_mgr); |
507 | g_object_unref (priv->hal_mgr); | 561 | g_object_unref (priv->hal_mgr); |
508 | 562 | ||
@@ -1645,58 +1699,66 @@ next: | |||
1645 | } | 1699 | } |
1646 | 1700 | ||
1647 | static void | 1701 | static void |
1648 | hal_manager_udi_added_cb (NMHalManager *hal_mgr, | 1702 | add_device (NMManager *self, NMDevice *device, const char *type_name) |
1649 | const char *udi, | ||
1650 | const char *type_name, | ||
1651 | NMDeviceCreatorFn creator_fn, | ||
1652 | gpointer user_data) | ||
1653 | { | 1703 | { |
1654 | NMManager *self = NM_MANAGER (user_data); | ||
1655 | NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); | 1704 | NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); |
1656 | GObject *device; | ||
1657 | const char *iface; | 1705 | const char *iface; |
1658 | 1706 | ||
1659 | if (priv->sleeping) | ||
1660 | return; | ||
1661 | |||
1662 | /* Make sure the device is not already in the device list */ | ||
1663 | if (nm_manager_get_device_by_udi (self, udi)) | ||
1664 | return; | ||
1665 | |||
1666 | device = creator_fn (hal_mgr, udi, nm_manager_udi_is_managed (self, udi)); | ||
1667 | if (!device) | ||
1668 | return; | ||
1669 | |||
1670 | priv->devices = g_slist_append (priv->devices, device); | 1707 | priv->devices = g_slist_append (priv->devices, device); |
1671 | 1708 | ||
1672 | g_signal_connect (device, "state-changed", | 1709 | g_signal_connect (device, "state-changed", |
1673 | G_CALLBACK (manager_device_state_changed), | 1710 | G_CALLBACK (manager_device_state_changed), |
1674 | self); | 1711 | self); |
1675 | 1712 | ||
1676 | /* Attach to the access-point-added signal so that the manager can fill | 1713 | /* Attach to the access-point-added signal so that the manager can fill |
1677 | * non-SSID-broadcasting APs with an SSID. | 1714 | * non-SSID-broadcasting APs with an SSID. |
1678 | */ | 1715 | */ |
1679 | if (NM_IS_DEVICE_WIFI (device)) { | 1716 | if (NM_IS_DEVICE_WIFI (device)) { |
1680 | g_signal_connect (device, "hidden-ap-found", | 1717 | g_signal_connect (device, "hidden-ap-found", |
1681 | G_CALLBACK (manager_hidden_ap_found), | 1718 | G_CALLBACK (manager_hidden_ap_found), |
1682 | self); | 1719 | self); |
1683 | 1720 | ||
1684 | /* Set initial rfkill state */ | 1721 | /* Set initial rfkill state */ |
1685 | nm_device_wifi_set_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled); | 1722 | nm_device_wifi_set_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled); |
1686 | } | 1723 | } |
1687 | 1724 | ||
1688 | iface = nm_device_get_iface (NM_DEVICE (device)); | 1725 | iface = nm_device_get_iface (device); |
1689 | nm_info ("Found new %s device '%s'.", type_name, iface); | 1726 | nm_info ("Found new %s device '%s'.", type_name, iface); |
1690 | 1727 | ||
1691 | dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), | 1728 | dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), |
1692 | nm_device_get_udi (NM_DEVICE (device)), | 1729 | nm_device_get_udi (NM_DEVICE (device)), |
1693 | device); | 1730 | G_OBJECT (device)); |
1694 | nm_info ("(%s): exported as %s", iface, udi); | 1731 | nm_info ("(%s): exported as %s", iface, nm_device_get_udi (device)); |
1695 | 1732 | ||
1696 | g_signal_emit (self, signals[DEVICE_ADDED], 0, device); | 1733 | g_signal_emit (self, signals[DEVICE_ADDED], 0, device); |
1697 | } | 1734 | } |
1698 | 1735 | ||
1699 | static void | 1736 | static void |
1737 | hal_manager_udi_added_cb (NMHalManager *hal_mgr, | ||
1738 | const char *udi, | ||
1739 | const char *type_name, | ||
1740 | NMDeviceCreatorFn creator_fn, | ||
1741 | gpointer user_data) | ||
1742 | { | ||
1743 | NMManager *self = NM_MANAGER (user_data); | ||
1744 | NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); | ||
1745 | GObject *device; | ||
1746 | |||
1747 | if (priv->sleeping) | ||
1748 | return; | ||
1749 | |||
1750 | /* Make sure the device is not already in the device list */ | ||
1751 | if (nm_manager_get_device_by_udi (self, udi)) | ||
1752 | return; | ||
1753 | |||
1754 | device = creator_fn (hal_mgr, udi, nm_manager_udi_is_managed (self, udi)); | ||
1755 | if (!device) | ||
1756 | return; | ||
1757 | |||
1758 | add_device (self, NM_DEVICE (device), type_name); | ||
1759 | } | ||
1760 | |||
1761 | static void | ||
1700 | hal_manager_udi_removed_cb (NMHalManager *manager, | 1762 | hal_manager_udi_removed_cb (NMHalManager *manager, |
1701 | const char *udi, | 1763 | const char *udi, |
1702 | gpointer user_data) | 1764 | gpointer user_data) |
diff --git a/src/nm-serial-device.c b/src/nm-serial-device.c deleted file mode 100644 index 18cd2d8d13..0000000000 --- a/src/nm-serial-device.c +++ /dev/null | |||
@@ -1,1180 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2007 - 2008 Novell, Inc. | ||
19 | * Copyright (C) 2007 - 2008 Red Hat, Inc. | ||
20 | */ | ||
21 | |||
22 | #define _GNU_SOURCE /* for strcasestr() */ | ||
23 | |||
24 | #include <termio.h> | ||
25 | #include <unistd.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <sys/stat.h> | ||
28 | #include <fcntl.h> | ||
29 | #include <errno.h> | ||
30 | #include <sys/ioctl.h> | ||
31 | #include <string.h> | ||
32 | #include <stdlib.h> | ||
33 | #include <glib.h> | ||
34 | |||
35 | #include "nm-glib-compat.h" | ||
36 | #include "nm-serial-device.h" | ||
37 | #include "nm-device-interface.h" | ||
38 | #include "nm-device-private.h" | ||
39 | #include "ppp-manager/nm-ppp-manager.h" | ||
40 | #include "nm-setting-ppp.h" | ||
41 | #include "nm-marshal.h" | ||
42 | #include "nm-utils.h" | ||
43 | #include "nm-serial-device-glue.h" | ||
44 | #include "NetworkManagerUtils.h" | ||
45 | |||
46 | static gboolean serial_debug = FALSE; | ||
47 | |||
48 | #define SERIAL_BUF_SIZE 2048 | ||
49 | |||
50 | G_DEFINE_TYPE (NMSerialDevice, nm_serial_device, NM_TYPE_DEVICE) | ||
51 | |||
52 | #define NM_SERIAL_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SERIAL_DEVICE, NMSerialDevicePrivate)) | ||
53 | |||
54 | typedef struct { | ||
55 | int fd; | ||
56 | GIOChannel *channel; | ||
57 | NMPPPManager *ppp_manager; | ||
58 | NMIP4Config *pending_ip4_config; | ||
59 | struct termios old_t; | ||
60 | |||
61 | guint pending_id; | ||
62 | guint timeout_id; | ||
63 | |||
64 | /* PPP stats */ | ||
65 | guint32 in_bytes; | ||
66 | guint32 out_bytes; | ||
67 | } NMSerialDevicePrivate; | ||
68 | |||
69 | enum { | ||
70 | PPP_STATS, | ||
71 | |||
72 | LAST_SIGNAL | ||
73 | }; | ||
74 | |||
75 | static guint signals[LAST_SIGNAL] = { 0 }; | ||
76 | |||
77 | static int | ||
78 | parse_baudrate (guint i) | ||
79 | { | ||
80 | int speed; | ||
81 | |||
82 | switch (i) { | ||
83 | case 0: | ||
84 | speed = B0; | ||
85 | break; | ||
86 | case 50: | ||
87 | speed = B50; | ||
88 | break; | ||
89 | case 75: | ||
90 | speed = B75; | ||
91 | break; | ||
92 | case 110: | ||
93 | speed = B110; | ||
94 | break; | ||
95 | case 150: | ||
96 | speed = B150; | ||
97 | break; | ||
98 | case 300: | ||
99 | speed = B300; | ||
100 | break; | ||
101 | case 600: | ||
102 | speed = B600; | ||
103 | break; | ||
104 | case 1200: | ||
105 | speed = B1200; | ||
106 | break; | ||
107 | case 2400: | ||
108 | speed = B2400; | ||
109 | break; | ||
110 | case 4800: | ||
111 | speed = B4800; | ||
112 | break; | ||
113 | case 9600: | ||
114 | speed = B9600; | ||
115 | break; | ||
116 | case 19200: | ||
117 | speed = B19200; | ||
118 | break; | ||
119 | case 38400: | ||
120 | speed = B38400; | ||
121 | break; | ||
122 | case 57600: | ||
123 | speed = B57600; | ||
124 | break; | ||
125 | case 115200: | ||
126 | speed = B115200; | ||
127 | break; | ||
128 | case 460800: | ||
129 | speed = B460800; | ||
130 | break; | ||
131 | default: | ||
132 | g_warning ("Invalid baudrate '%d'", i); | ||
133 | speed = B9600; | ||
134 | } | ||
135 | |||
136 | return speed; | ||
137 | } | ||
138 | |||
139 | static int | ||
140 | parse_bits (guint i) | ||
141 | { | ||
142 | int bits; | ||
143 | |||
144 | switch (i) { | ||
145 | case 5: | ||
146 | bits = CS5; | ||
147 | break; | ||
148 | case 6: | ||
149 | bits = CS6; | ||
150 | break; | ||
151 | case 7: | ||
152 | bits = CS7; | ||
153 | break; | ||
154 | case 8: | ||
155 | bits = CS8; | ||
156 | break; | ||
157 | default: | ||
158 | g_warning ("Invalid bits (%d). Valid values are 5, 6, 7, 8.", i); | ||
159 | bits = CS8; | ||
160 | } | ||
161 | |||
162 | return bits; | ||
163 | } | ||
164 | |||
165 | static int | ||
166 | parse_parity (char c) | ||
167 | { | ||
168 | int parity; | ||
169 | |||
170 | switch (c) { | ||
171 | case 'n': | ||
172 | case 'N': | ||
173 | parity = 0; | ||
174 | break; | ||
175 | case 'e': | ||
176 | case 'E': | ||
177 | parity = PARENB; | ||
178 | break; | ||
179 | case 'o': | ||
180 | case 'O': | ||
181 | parity = PARENB | PARODD; | ||
182 | break; | ||
183 | default: | ||
184 | g_warning ("Invalid parity (%c). Valid values are n, e, o", c); | ||
185 | parity = 0; | ||
186 | } | ||
187 | |||
188 | return parity; | ||
189 | } | ||
190 | |||
191 | static int | ||
192 | parse_stopbits (guint i) | ||
193 | { | ||
194 | int stopbits; | ||
195 | |||
196 | switch (i) { | ||
197 | case 1: | ||
198 | stopbits = 0; | ||
199 | break; | ||
200 | case 2: | ||
201 | stopbits = CSTOPB; | ||
202 | break; | ||
203 | default: | ||
204 | g_warning ("Invalid stop bits (%d). Valid values are 1 and 2)", i); | ||
205 | stopbits = 0; | ||
206 | } | ||
207 | |||
208 | return stopbits; | ||
209 | } | ||
210 | |||
211 | static inline void | ||
212 | nm_serial_debug (const char *prefix, const char *data, int len) | ||
213 | { | ||
214 | GString *str; | ||
215 | int i; | ||
216 | |||
217 | if (!serial_debug) | ||
218 | return; | ||
219 | |||
220 | str = g_string_sized_new (len); | ||
221 | for (i = 0; i < len; i++) { | ||
222 | if (data[i] == '\0') | ||
223 | g_string_append_c (str, ' '); | ||
224 | else if (data[i] == '\r') | ||
225 | g_string_append_c (str, '\n'); | ||
226 | else | ||
227 | g_string_append_c (str, data[i]); | ||
228 | } | ||
229 | |||
230 | nm_debug ("%s '%s'", prefix, str->str); | ||
231 | g_string_free (str, TRUE); | ||
232 | } | ||
233 | |||
234 | static NMSetting * | ||
235 | serial_device_get_setting (NMSerialDevice *device, GType setting_type) | ||
236 | { | ||
237 | NMActRequest *req; | ||
238 | NMSetting *setting = NULL; | ||
239 | |||
240 | req = nm_device_get_act_request (NM_DEVICE (device)); | ||
241 | if (req) { | ||
242 | NMConnection *connection; | ||
243 | |||
244 | connection = nm_act_request_get_connection (req); | ||
245 | if (connection) | ||
246 | setting = nm_connection_get_setting (connection, setting_type); | ||
247 | } | ||
248 | |||
249 | return setting; | ||
250 | } | ||
251 | |||
252 | /* Timeout handling */ | ||
253 | |||
254 | static void | ||
255 | nm_serial_device_timeout_removed (gpointer data) | ||
256 | { | ||
257 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data); | ||
258 | |||
259 | priv->timeout_id = 0; | ||
260 | } | ||
261 | |||
262 | static gboolean | ||
263 | nm_serial_device_timed_out (gpointer data) | ||
264 | { | ||
265 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (data); | ||
266 | |||
267 | /* Cancel data reading */ | ||
268 | if (priv->pending_id) | ||
269 | g_source_remove (priv->pending_id); | ||
270 | else | ||
271 | nm_warning ("Timeout reached, but there's nothing to time out"); | ||
272 | |||
273 | return FALSE; | ||
274 | } | ||
275 | |||
276 | static void | ||
277 | nm_serial_device_add_timeout (NMSerialDevice *self, guint timeout) | ||
278 | { | ||
279 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self); | ||
280 | |||
281 | if (priv->pending_id == 0) | ||
282 | nm_warning ("Adding a time out while not waiting for any data"); | ||
283 | |||
284 | if (priv->timeout_id) { | ||
285 | nm_warning ("Trying to add a new time out while the old one still exists"); | ||
286 | g_source_remove (priv->timeout_id); | ||
287 | } | ||
288 | |||
289 | priv->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, | ||
290 | timeout, | ||
291 | nm_serial_device_timed_out, | ||
292 | self, | ||
293 | nm_serial_device_timeout_removed); | ||
294 | if (G_UNLIKELY (priv->timeout_id == 0)) | ||
295 | nm_warning ("Registering serial device time out failed."); | ||
296 | } | ||
297 | |||
298 | static void | ||
299 | nm_serial_device_remove_timeout (NMSerialDevice *self) | ||
300 | { | ||
301 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (self); | ||
302 | |||
303 | if (priv->timeout_id) | ||
304 | g_source_remove (priv->timeout_id); | ||
305 | } | ||
306 | |||
307 | /* Pending data reading */ | ||
308 | |||
309 | static guint | ||
310 | nm_serial_device_set_pending (NMSerialDevice *device, | ||
311 | guint timeout, | ||
312 | GIOFunc callback, | ||
313 | gpointer user_data, | ||
314 | GDestroyNotify notify) | ||
315 | { | ||
316 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
317 | |||
318 | if (G_UNLIKELY (priv->pending_id)) { | ||
319 | /* FIXME: Probably should queue up pending calls instead? */ | ||
320 | /* Multiple pending calls on the same GIOChannel doesn't work, so let's cancel the previous one. */ | ||
321 | nm_warning ("Adding new pending call while previous one isn't finished."); | ||
322 | nm_warning ("Cancelling the previous pending call."); | ||
323 | g_source_remove (priv->pending_id); | ||
324 | } | ||
325 | |||
326 | priv->pending_id = g_io_add_watch_full (priv->channel, | ||
327 | G_PRIORITY_DEFAULT, | ||
328 | G_IO_IN | G_IO_ERR | G_IO_HUP, | ||
329 | callback, user_data, notify); | ||
330 | |||
331 | nm_serial_device_add_timeout (device, timeout); | ||
332 | |||
333 | return priv->pending_id; | ||
334 | } | ||
335 | |||
336 | static void | ||
337 | nm_serial_device_pending_done (NMSerialDevice *self) | ||
338 | { | ||
339 | NM_SERIAL_DEVICE_GET_PRIVATE (self)->pending_id = 0; | ||
340 | nm_serial_device_remove_timeout (self); | ||
341 | } | ||
342 | |||
343 | /****/ | ||
344 | |||
345 | static gboolean | ||
346 | config_fd (NMSerialDevice *device, NMSettingSerial *setting) | ||
347 | { | ||
348 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
349 | struct termio stbuf; | ||
350 | int speed; | ||
351 | int bits; | ||
352 | int parity; | ||
353 | int stopbits; | ||
354 | |||
355 | speed = parse_baudrate (nm_setting_serial_get_baud (setting)); | ||
356 | bits = parse_bits (nm_setting_serial_get_bits (setting)); | ||
357 | parity = parse_parity (nm_setting_serial_get_parity (setting)); | ||
358 | stopbits = parse_stopbits (nm_setting_serial_get_stopbits (setting)); | ||
359 | |||
360 | ioctl (priv->fd, TCGETA, &stbuf); | ||
361 | |||
362 | stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR ); | ||
363 | stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET); | ||
364 | stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL); | ||
365 | stbuf.c_lflag &= ~(ECHO | ECHOE); | ||
366 | stbuf.c_cc[VMIN] = 1; | ||
367 | stbuf.c_cc[VTIME] = 0; | ||
368 | stbuf.c_cc[VEOF] = 1; | ||
369 | |||
370 | stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB); | ||
371 | stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity | stopbits); | ||
372 | |||
373 | if (ioctl (priv->fd, TCSETA, &stbuf) < 0) { | ||
374 | nm_warning ("(%s) cannot control device (errno %d)", | ||
375 | nm_device_get_iface (NM_DEVICE (device)), errno); | ||
376 | return FALSE; | ||
377 | } | ||
378 | |||
379 | return TRUE; | ||
380 | } | ||
381 | |||
382 | gboolean | ||
383 | nm_serial_device_open (NMSerialDevice *device, | ||
384 | NMSettingSerial *setting) | ||
385 | { | ||
386 | NMSerialDevicePrivate *priv; | ||
387 | const char *iface; | ||
388 | char *path; | ||
389 | |||
390 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); | ||
391 | g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), FALSE); | ||
392 | |||
393 | priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
394 | iface = nm_device_get_iface (NM_DEVICE (device)); | ||
395 | |||
396 | nm_debug ("(%s) opening device...", iface); | ||
397 | |||
398 | path = g_build_filename ("/dev", iface, NULL); | ||
399 | priv->fd = open (path, O_RDWR | O_EXCL | O_NONBLOCK | O_NOCTTY); | ||
400 | g_free (path); | ||
401 | |||
402 | if (priv->fd < 0) { | ||
403 | nm_warning ("(%s) cannot open device (errno %d)", iface, errno); | ||
404 | return FALSE; | ||
405 | } | ||
406 | |||
407 | if (ioctl (priv->fd, TCGETA, &priv->old_t) < 0) { | ||
408 | nm_warning ("(%s) cannot control device (errno %d)", iface, errno); | ||
409 | close (priv->fd); | ||
410 | return FALSE; | ||
411 | } | ||
412 | |||
413 | if (!config_fd (device, setting)) { | ||
414 | close (priv->fd); | ||
415 | return FALSE; | ||
416 | } | ||
417 | |||
418 | priv->channel = g_io_channel_unix_new (priv->fd); | ||
419 | g_io_channel_set_encoding (priv->channel, NULL, NULL); | ||
420 | |||
421 | return TRUE; | ||
422 | } | ||
423 | |||
424 | void | ||
425 | nm_serial_device_close (NMSerialDevice *device) | ||
426 | { | ||
427 | NMSerialDevicePrivate *priv; | ||
428 | |||
429 | g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); | ||
430 | |||
431 | priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
432 | |||
433 | if (priv->pending_id) | ||
434 | g_source_remove (priv->pending_id); | ||
435 | |||
436 | if (priv->ppp_manager) { | ||
437 | nm_ppp_manager_stop (priv->ppp_manager); | ||
438 | g_object_unref (priv->ppp_manager); | ||
439 | priv->ppp_manager = NULL; | ||
440 | } | ||
441 | |||
442 | if (priv->fd) { | ||
443 | nm_debug ("Closing device '%s'", nm_device_get_iface (NM_DEVICE (device))); | ||
444 | |||
445 | if (priv->channel) { | ||
446 | g_io_channel_unref (priv->channel); | ||
447 | priv->channel = NULL; | ||
448 | } | ||
449 | |||
450 | ioctl (priv->fd, TCSETA, &priv->old_t); | ||
451 | close (priv->fd); | ||
452 | priv->fd = 0; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | gboolean | ||
457 | nm_serial_device_send_command (NMSerialDevice *device, GByteArray *command) | ||
458 | { | ||
459 | int fd; | ||
460 | NMSettingSerial *setting; | ||
461 | int i, eagain_count = 1000; | ||
462 | ssize_t written; | ||
463 | guint32 send_delay = 0; | ||
464 | |||
465 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); | ||
466 | g_return_val_if_fail (command != NULL, FALSE); | ||
467 | |||
468 | fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd; | ||
469 | setting = NM_SETTING_SERIAL (serial_device_get_setting (device, NM_TYPE_SETTING_SERIAL)); | ||
470 | if (setting) | ||
471 | send_delay = nm_setting_serial_get_send_delay (setting); | ||
472 | if (send_delay == 0) | ||
473 | send_delay = G_USEC_PER_SEC / 1000; | ||
474 | |||
475 | nm_serial_debug ("Sending:", (char *) command->data, command->len); | ||
476 | |||
477 | for (i = 0; i < command->len && eagain_count > 0;) { | ||
478 | written = write (fd, command->data + i, 1); | ||
479 | |||
480 | if (written > 0) | ||
481 | i += written; | ||
482 | else { | ||
483 | /* Treat written == 0 as EAGAIN to ensure we break out of the | ||
484 | * for() loop eventually. | ||
485 | */ | ||
486 | if ((written < 0) && (errno != EAGAIN)) { | ||
487 | g_warning ("Error in writing (errno %d)", errno); | ||
488 | return FALSE; | ||
489 | } | ||
490 | eagain_count--; | ||
491 | } | ||
492 | g_usleep (send_delay); | ||
493 | } | ||
494 | |||
495 | if (eagain_count <= 0) | ||
496 | nm_serial_debug ("Error: too many retries sending:", (char *) command->data, command->len); | ||
497 | |||
498 | return TRUE; | ||
499 | } | ||
500 | |||
501 | gboolean | ||
502 | nm_serial_device_send_command_string (NMSerialDevice *device, const char *str) | ||
503 | { | ||
504 | GByteArray *command; | ||
505 | gboolean ret; | ||
506 | |||
507 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), FALSE); | ||
508 | g_return_val_if_fail (str != NULL, FALSE); | ||
509 | |||
510 | command = g_byte_array_new (); | ||
511 | g_byte_array_append (command, (guint8 *) str, strlen (str)); | ||
512 | g_byte_array_append (command, (guint8 *) "\r", 1); | ||
513 | |||
514 | ret = nm_serial_device_send_command (device, command); | ||
515 | g_byte_array_free (command, TRUE); | ||
516 | |||
517 | return ret; | ||
518 | } | ||
519 | |||
520 | static gboolean | ||
521 | find_terminator (const char *line, const char **terminators) | ||
522 | { | ||
523 | int i; | ||
524 | |||
525 | for (i = 0; terminators[i]; i++) { | ||
526 | if (!strncasecmp (line, terminators[i], strlen (terminators[i]))) | ||
527 | return TRUE; | ||
528 | } | ||
529 | return FALSE; | ||
530 | } | ||
531 | |||
532 | static const char * | ||
533 | find_response (const char *line, const char **responses, gint *idx) | ||
534 | { | ||
535 | int i; | ||
536 | |||
537 | /* Don't look for a result again if we got one previously */ | ||
538 | for (i = 0; responses[i]; i++) { | ||
539 | if (strcasestr (line, responses[i])) { | ||
540 | *idx = i; | ||
541 | return line; | ||
542 | } | ||
543 | } | ||
544 | return NULL; | ||
545 | } | ||
546 | |||
547 | #define RESPONSE_LINE_MAX 128 | ||
548 | |||
549 | int | ||
550 | nm_serial_device_wait_reply_blocking (NMSerialDevice *device, | ||
551 | guint32 timeout_secs, | ||
552 | const char **needles, | ||
553 | const char **terminators) | ||
554 | { | ||
555 | char buf[SERIAL_BUF_SIZE + 1]; | ||
556 | int fd, reply_index = -1, bytes_read; | ||
557 | GString *result = NULL; | ||
558 | time_t end; | ||
559 | const char *response = NULL; | ||
560 | gboolean done = FALSE; | ||
561 | |||
562 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), -1); | ||
563 | g_return_val_if_fail (timeout_secs <= 60, -1); | ||
564 | g_return_val_if_fail (needles != NULL, -1); | ||
565 | |||
566 | fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd; | ||
567 | if (fd < 0) | ||
568 | return -1; | ||
569 | |||
570 | end = time (NULL) + timeout_secs; | ||
571 | result = g_string_sized_new (20); | ||
572 | do { | ||
573 | bytes_read = read (fd, buf, SERIAL_BUF_SIZE); | ||
574 | if (bytes_read < 0 && errno != EAGAIN) { | ||
575 | nm_warning ("%s: read error: %d (%s)", | ||
576 | nm_device_get_iface (NM_DEVICE (device)), | ||
577 | errno, | ||
578 | strerror (errno)); | ||
579 | return -1; | ||
580 | } | ||
581 | |||
582 | if (bytes_read == 0) | ||
583 | break; /* EOF */ | ||
584 | else if (bytes_read > 0) { | ||
585 | buf[bytes_read] = 0; | ||
586 | g_string_append (result, buf); | ||
587 | |||
588 | nm_serial_debug ("Got:", result->str, result->len); | ||
589 | } | ||
590 | |||
591 | /* Look for needles and terminators */ | ||
592 | if ((bytes_read > 0) && result->str) { | ||
593 | char *p = result->str; | ||
594 | |||
595 | /* Break the response up into lines and process each one */ | ||
596 | while ((p < result->str + strlen (result->str)) && !done) { | ||
597 | char line[RESPONSE_LINE_MAX] = { '\0', }; | ||
598 | char *tmp; | ||
599 | int i; | ||
600 | gboolean got_something = FALSE; | ||
601 | |||
602 | for (i = 0; *p && (i < RESPONSE_LINE_MAX - 1); p++) { | ||
603 | /* Ignore front CR/LF */ | ||
604 | if ((*p == '\n') || (*p == '\r')) { | ||
605 | if (got_something) | ||
606 | break; | ||
607 | } else { | ||
608 | line[i++] = *p; | ||
609 | got_something = TRUE; | ||
610 | } | ||
611 | } | ||
612 | line[i] = '\0'; | ||
613 | |||
614 | tmp = g_strstrip (line); | ||
615 | if (tmp && strlen (tmp)) { | ||
616 | done = find_terminator (tmp, terminators); | ||
617 | if (reply_index == -1) | ||
618 | response = find_response (tmp, needles, &reply_index); | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | |||
623 | /* Limit the size of the buffer */ | ||
624 | if (result->len > SERIAL_BUF_SIZE) { | ||
625 | g_warning ("%s (%s): response buffer filled before repsonse received", | ||
626 | __func__, nm_device_get_iface (NM_DEVICE (device))); | ||
627 | break; | ||
628 | } | ||
629 | |||
630 | if (!done) | ||
631 | g_usleep (100); | ||
632 | } while (!done && (time (NULL) < end)); | ||
633 | |||
634 | return reply_index; | ||
635 | } | ||
636 | |||
637 | typedef struct { | ||
638 | NMSerialDevice *device; | ||
639 | char **str_needles; | ||
640 | char **terminators; | ||
641 | GString *result; | ||
642 | NMSerialWaitForReplyFn callback; | ||
643 | gpointer user_data; | ||
644 | int reply_index; | ||
645 | char *reply_line; | ||
646 | time_t end; | ||
647 | } WaitForReplyInfo; | ||
648 | |||
649 | static void | ||
650 | wait_for_reply_done (gpointer data) | ||
651 | { | ||
652 | WaitForReplyInfo *info = (WaitForReplyInfo *) data; | ||
653 | |||
654 | nm_serial_device_pending_done (info->device); | ||
655 | |||
656 | /* Call the callback */ | ||
657 | info->callback (info->device, info->reply_index, info->reply_line, info->user_data); | ||
658 | |||
659 | /* Free info */ | ||
660 | if (info->result) | ||
661 | g_string_free (info->result, TRUE); | ||
662 | |||
663 | g_free (info->reply_line); | ||
664 | |||
665 | g_strfreev (info->str_needles); | ||
666 | g_strfreev (info->terminators); | ||
667 | g_slice_free (WaitForReplyInfo, info); | ||
668 | } | ||
669 | |||
670 | static gboolean | ||
671 | wait_for_reply_got_data (GIOChannel *source, | ||
672 | GIOCondition condition, | ||
673 | gpointer data) | ||
674 | { | ||
675 | WaitForReplyInfo *info = (WaitForReplyInfo *) data; | ||
676 | gchar buf[SERIAL_BUF_SIZE + 1]; | ||
677 | gsize bytes_read; | ||
678 | GIOStatus status; | ||
679 | gboolean done = FALSE; | ||
680 | |||
681 | if (condition & G_IO_HUP || condition & G_IO_ERR) | ||
682 | return FALSE; | ||
683 | |||
684 | do { | ||
685 | GError *err = NULL; | ||
686 | |||
687 | status = g_io_channel_read_chars (source, buf, SERIAL_BUF_SIZE, &bytes_read, &err); | ||
688 | if (status == G_IO_STATUS_ERROR) { | ||
689 | g_warning ("%s", err->message); | ||
690 | g_error_free (err); | ||
691 | err = NULL; | ||
692 | } | ||
693 | |||
694 | if (bytes_read > 0) { | ||
695 | buf[bytes_read] = 0; | ||
696 | g_string_append (info->result, buf); | ||
697 | |||
698 | nm_serial_debug ("Got:", info->result->str, info->result->len); | ||
699 | } | ||
700 | |||
701 | /* Look for needles and terminators */ | ||
702 | if ((bytes_read > 0) && info->result->str) { | ||
703 | char *p = info->result->str; | ||
704 | |||
705 | /* Break the response up into lines and process each one */ | ||
706 | while ((p < info->result->str + strlen (info->result->str)) && !done) { | ||
707 | char line[RESPONSE_LINE_MAX] = { '\0', }; | ||
708 | char *tmp; | ||
709 | int i; | ||
710 | gboolean got_something = FALSE; | ||
711 | |||
712 | for (i = 0; *p && (i < RESPONSE_LINE_MAX - 1); p++) { | ||
713 | /* Ignore front CR/LF */ | ||
714 | if ((*p == '\n') || (*p == '\r')) { | ||
715 | if (got_something) | ||
716 | break; | ||
717 | } else { | ||
718 | line[i++] = *p; | ||
719 | got_something = TRUE; | ||
720 | } | ||
721 | } | ||
722 | line[i] = '\0'; | ||
723 | |||
724 | tmp = g_strstrip (line); | ||
725 | if (tmp && strlen (tmp)) { | ||
726 | done = find_terminator (tmp, (const char **) info->terminators); | ||
727 | if (info->reply_index == -1) { | ||
728 | if (find_response (tmp, (const char **) info->str_needles, &(info->reply_index))) | ||
729 | info->reply_line = g_strdup (tmp); | ||
730 | } | ||
731 | } | ||
732 | } | ||
733 | } | ||
734 | |||
735 | /* Limit the size of the buffer */ | ||
736 | if (info->result->len > SERIAL_BUF_SIZE) { | ||
737 | nm_warning ("(%s): response buffer filled before repsonse received", | ||
738 | nm_device_get_iface (NM_DEVICE (info->device))); | ||
739 | done = TRUE; | ||
740 | break; | ||
741 | } | ||
742 | |||
743 | /* Make sure we don't go over the timeout, in addition to the timeout | ||
744 | * handler that's been scheduled. If for some reason this loop doesn't | ||
745 | * terminate (terminator not found, whatever) then this should make | ||
746 | * sure that NM doesn't spin the CPU forever. | ||
747 | */ | ||
748 | if (time (NULL) > info->end) { | ||
749 | done = TRUE; | ||
750 | break; | ||
751 | } else if (!done) | ||
752 | g_usleep (50); | ||
753 | } while (!done || bytes_read == SERIAL_BUF_SIZE || status == G_IO_STATUS_AGAIN); | ||
754 | |||
755 | return !done; | ||
756 | } | ||
757 | |||
758 | guint | ||
759 | nm_serial_device_wait_for_reply (NMSerialDevice *device, | ||
760 | guint timeout, | ||
761 | const char **responses, | ||
762 | const char **terminators, | ||
763 | NMSerialWaitForReplyFn callback, | ||
764 | gpointer user_data) | ||
765 | { | ||
766 | WaitForReplyInfo *info; | ||
767 | |||
768 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0); | ||
769 | g_return_val_if_fail (responses != NULL, 0); | ||
770 | g_return_val_if_fail (callback != NULL, 0); | ||
771 | |||
772 | info = g_slice_new0 (WaitForReplyInfo); | ||
773 | info->device = device; | ||
774 | info->str_needles = g_strdupv ((char **) responses); | ||
775 | info->terminators = g_strdupv ((char **) terminators); | ||
776 | info->result = g_string_new (NULL); | ||
777 | info->callback = callback; | ||
778 | info->user_data = user_data; | ||
779 | info->reply_index = -1; | ||
780 | info->end = time (NULL) + timeout; | ||
781 | |||
782 | return nm_serial_device_set_pending (device, timeout, wait_for_reply_got_data, info, wait_for_reply_done); | ||
783 | } | ||
784 | |||
785 | #if 0 | ||
786 | typedef struct { | ||
787 | NMSerialDevice *device; | ||
788 | gboolean timed_out; | ||
789 | NMSerialWaitQuietFn callback; | ||
790 | gpointer user_data; | ||
791 | } WaitQuietInfo; | ||
792 | |||
793 | static void | ||
794 | wait_quiet_done (gpointer data) | ||
795 | { | ||
796 | WaitQuietInfo *info = (WaitQuietInfo *) data; | ||
797 | |||
798 | nm_serial_device_pending_done (info->device); | ||
799 | |||
800 | /* Call the callback */ | ||
801 | info->callback (info->device, info->timed_out, info->user_data); | ||
802 | |||
803 | /* Free info */ | ||
804 | g_slice_free (WaitQuietInfo, info); | ||
805 | } | ||
806 | |||
807 | static gboolean | ||
808 | wait_quiet_quiettime (gpointer data) | ||
809 | { | ||
810 | WaitQuietInfo *info = (WaitQuietInfo *) data; | ||
811 | |||
812 | info->timed_out = FALSE; | ||
813 | g_source_remove (NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending); | ||
814 | |||
815 | return FALSE; | ||
816 | } | ||
817 | |||
818 | static gboolean | ||
819 | wait_quiet_got_data (GIOChannel *source, | ||
820 | GIOCondition condition, | ||
821 | gpointer data) | ||
822 | { | ||
823 | WaitQuietInfo *info = (WaitQuietInfo *) data; | ||
824 | gsize bytes_read; | ||
825 | char buf[4096]; | ||
826 | GIOStatus status; | ||
827 | |||
828 | if (condition & G_IO_HUP || condition & G_IO_ERR) | ||
829 | return FALSE; | ||
830 | |||
831 | if (condition & G_IO_IN) { | ||
832 | do { | ||
833 | status = g_io_channel_read_chars (source, buf, 4096, &bytes_read, NULL); | ||
834 | |||
835 | if (bytes_read) { | ||
836 | /* Reset the quiet time timeout */ | ||
837 | g_source_remove (info->quiet_id); | ||
838 | info->quiet_id = g_timeout_add (info->quiet_time, wait_quiet_quiettime, info); | ||
839 | } | ||
840 | } while (bytes_read == 4096 || status == G_IO_STATUS_AGAIN); | ||
841 | } | ||
842 | |||
843 | return TRUE; | ||
844 | } | ||
845 | |||
846 | void | ||
847 | nm_serial_device_wait_quiet (NMSerialDevice *device, | ||
848 | guint timeout, | ||
849 | guint quiet_time, | ||
850 | NMSerialWaitQuietFn callback, | ||
851 | gpointer user_data) | ||
852 | { | ||
853 | WaitQuietInfo *info; | ||
854 | |||
855 | g_return_if_fail (NM_IS_SERIAL_DEVICE (device)); | ||
856 | g_return_if_fail (callback != NULL); | ||
857 | |||
858 | info = g_slice_new0 (WaitQuietInfo); | ||
859 | info->device = device; | ||
860 | info->timed_out = TRUE; | ||
861 | info->callback = callback; | ||
862 | info->user_data = user_data; | ||
863 | info->quiet_id = g_timeout_add (quiet_time, | ||
864 | wait_quiet_timeout, | ||
865 | info); | ||
866 | |||
867 | return nm_serial_device_set_pending (device, timeout, wait_quiet_got_data, info, wait_quiet_done); | ||
868 | } | ||
869 | |||
870 | #endif | ||
871 | |||
872 | typedef struct { | ||
873 | NMSerialDevice *device; | ||
874 | speed_t current_speed; | ||
875 | NMSerialFlashFn callback; | ||
876 | gpointer user_data; | ||
877 | } FlashInfo; | ||
878 | |||
879 | static speed_t | ||
880 | get_speed (NMSerialDevice *device) | ||
881 | { | ||
882 | struct termios options; | ||
883 | |||
884 | tcgetattr (NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd, &options); | ||
885 | |||
886 | return cfgetospeed (&options); | ||
887 | } | ||
888 | |||
889 | static void | ||
890 | set_speed (NMSerialDevice *device, speed_t speed) | ||
891 | { | ||
892 | struct termios options; | ||
893 | int fd; | ||
894 | |||
895 | fd = NM_SERIAL_DEVICE_GET_PRIVATE (device)->fd; | ||
896 | tcgetattr (fd, &options); | ||
897 | |||
898 | cfsetispeed (&options, speed); | ||
899 | cfsetospeed (&options, speed); | ||
900 | |||
901 | options.c_cflag |= (CLOCAL | CREAD); | ||
902 | tcsetattr (fd, TCSANOW, &options); | ||
903 | } | ||
904 | |||
905 | static void | ||
906 | flash_done (gpointer data) | ||
907 | { | ||
908 | FlashInfo *info = (FlashInfo *) data; | ||
909 | |||
910 | NM_SERIAL_DEVICE_GET_PRIVATE (info->device)->pending_id = 0; | ||
911 | |||
912 | info->callback (info->device, info->user_data); | ||
913 | |||
914 | g_slice_free (FlashInfo, info); | ||
915 | } | ||
916 | |||
917 | static gboolean | ||
918 | flash_do (gpointer data) | ||
919 | { | ||
920 | FlashInfo *info = (FlashInfo *) data; | ||
921 | |||
922 | set_speed (info->device, info->current_speed); | ||
923 | |||
924 | return FALSE; | ||
925 | } | ||
926 | |||
927 | guint | ||
928 | nm_serial_device_flash (NMSerialDevice *device, | ||
929 | guint32 flash_time, | ||
930 | NMSerialFlashFn callback, | ||
931 | gpointer user_data) | ||
932 | { | ||
933 | FlashInfo *info; | ||
934 | guint id; | ||
935 | |||
936 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0); | ||
937 | g_return_val_if_fail (callback != NULL, 0); | ||
938 | |||
939 | info = g_slice_new0 (FlashInfo); | ||
940 | info->device = device; | ||
941 | info->current_speed = get_speed (device); | ||
942 | info->callback = callback; | ||
943 | info->user_data = user_data; | ||
944 | |||
945 | set_speed (device, B0); | ||
946 | |||
947 | id = g_timeout_add_full (G_PRIORITY_DEFAULT, | ||
948 | flash_time, | ||
949 | flash_do, | ||
950 | info, | ||
951 | flash_done); | ||
952 | |||
953 | NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_id = id; | ||
954 | |||
955 | return id; | ||
956 | } | ||
957 | |||
958 | GIOChannel * | ||
959 | nm_serial_device_get_io_channel (NMSerialDevice *device) | ||
960 | { | ||
961 | NMSerialDevicePrivate *priv; | ||
962 | |||
963 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), 0); | ||
964 | |||
965 | priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
966 | if (priv->channel) | ||
967 | return g_io_channel_ref (priv->channel); | ||
968 | |||
969 | return NULL; | ||
970 | } | ||
971 | |||
972 | NMPPPManager * | ||
973 | nm_serial_device_get_ppp_manager (NMSerialDevice *device) | ||
974 | { | ||
975 | g_return_val_if_fail (NM_IS_SERIAL_DEVICE (device), NULL); | ||
976 | |||
977 | return NM_SERIAL_DEVICE_GET_PRIVATE (device)->ppp_manager; | ||
978 | } | ||
979 | |||
980 | static void | ||
981 | ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_data) | ||
982 | { | ||
983 | NMDevice *device = NM_DEVICE (user_data); | ||
984 | |||
985 | switch (status) { | ||
986 | case NM_PPP_STATUS_NETWORK: | ||
987 | nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); | ||
988 | break; | ||
989 | case NM_PPP_STATUS_DISCONNECT: | ||
990 | nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT); | ||
991 | break; | ||
992 | case NM_PPP_STATUS_DEAD: | ||
993 | nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED); | ||
994 | break; | ||
995 | case NM_PPP_STATUS_AUTHENTICATE: | ||
996 | nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); | ||
997 | break; | ||
998 | default: | ||
999 | break; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | static void | ||
1004 | ppp_ip4_config (NMPPPManager *ppp_manager, | ||
1005 | const char *iface, | ||
1006 | NMIP4Config *config, | ||
1007 | gpointer user_data) | ||
1008 | { | ||
1009 | NMDevice *device = NM_DEVICE (user_data); | ||
1010 | |||
1011 | nm_device_set_ip_iface (device, iface); | ||
1012 | NM_SERIAL_DEVICE_GET_PRIVATE (device)->pending_ip4_config = g_object_ref (config); | ||
1013 | nm_device_activate_schedule_stage4_ip_config_get (device); | ||
1014 | } | ||
1015 | |||
1016 | static void | ||
1017 | ppp_stats (NMPPPManager *ppp_manager, | ||
1018 | guint32 in_bytes, | ||
1019 | guint32 out_bytes, | ||
1020 | gpointer user_data) | ||
1021 | { | ||
1022 | NMSerialDevice *device = NM_SERIAL_DEVICE (user_data); | ||
1023 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
1024 | |||
1025 | if (priv->in_bytes != in_bytes || priv->out_bytes != out_bytes) { | ||
1026 | priv->in_bytes = in_bytes; | ||
1027 | priv->out_bytes = out_bytes; | ||
1028 | |||
1029 | g_signal_emit (device, signals[PPP_STATS], 0, in_bytes, out_bytes); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | static NMActStageReturn | ||
1034 | real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) | ||
1035 | { | ||
1036 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
1037 | NMSerialDeviceClass *serial_class = NM_SERIAL_DEVICE_GET_CLASS (device); | ||
1038 | NMActRequest *req; | ||
1039 | GError *err = NULL; | ||
1040 | NMActStageReturn ret; | ||
1041 | const char *ppp_name = NULL; | ||
1042 | |||
1043 | req = nm_device_get_act_request (device); | ||
1044 | g_assert (req); | ||
1045 | |||
1046 | if (serial_class->get_ppp_name) | ||
1047 | ppp_name = serial_class->get_ppp_name (NM_SERIAL_DEVICE (device), req); | ||
1048 | |||
1049 | priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (device)); | ||
1050 | if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, &err)) { | ||
1051 | g_signal_connect (priv->ppp_manager, "state-changed", | ||
1052 | G_CALLBACK (ppp_state_changed), | ||
1053 | device); | ||
1054 | g_signal_connect (priv->ppp_manager, "ip4-config", | ||
1055 | G_CALLBACK (ppp_ip4_config), | ||
1056 | device); | ||
1057 | g_signal_connect (priv->ppp_manager, "stats", | ||
1058 | G_CALLBACK (ppp_stats), | ||
1059 | device); | ||
1060 | |||
1061 | ret = NM_ACT_STAGE_RETURN_POSTPONE; | ||
1062 | } else { | ||
1063 | nm_warning ("%s", err->message); | ||
1064 | g_error_free (err); | ||
1065 | |||
1066 | g_object_unref (priv->ppp_manager); | ||
1067 | priv->ppp_manager = NULL; | ||
1068 | |||
1069 | *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED; | ||
1070 | ret = NM_ACT_STAGE_RETURN_FAILURE; | ||
1071 | } | ||
1072 | |||
1073 | return ret; | ||
1074 | } | ||
1075 | |||
1076 | static NMActStageReturn | ||
1077 | real_act_stage4_get_ip4_config (NMDevice *device, | ||
1078 | NMIP4Config **config, | ||
1079 | NMDeviceStateReason *reason) | ||
1080 | { | ||
1081 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
1082 | NMConnection *connection; | ||
1083 | NMSettingIP4Config *s_ip4; | ||
1084 | |||
1085 | g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); | ||
1086 | g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); | ||
1087 | g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); | ||
1088 | |||
1089 | connection = nm_act_request_get_connection (nm_device_get_act_request (device)); | ||
1090 | g_assert (connection); | ||
1091 | |||
1092 | s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); | ||
1093 | |||
1094 | *config = priv->pending_ip4_config; | ||
1095 | priv->pending_ip4_config = NULL; | ||
1096 | nm_utils_merge_ip4_config (*config, s_ip4); | ||
1097 | |||
1098 | return NM_ACT_STAGE_RETURN_SUCCESS; | ||
1099 | } | ||
1100 | |||
1101 | static void | ||
1102 | cleanup_device (NMSerialDevice *device) | ||
1103 | { | ||
1104 | NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); | ||
1105 | |||
1106 | nm_device_set_ip_iface (NM_DEVICE (device), NULL); | ||
1107 | |||
1108 | if (priv->pending_ip4_config) { | ||
1109 | g_object_unref (priv->pending_ip4_config); | ||
1110 | priv->pending_ip4_config = NULL; | ||
1111 | } | ||
1112 | |||
1113 | priv->in_bytes = priv->out_bytes = 0; | ||
1114 | } | ||
1115 | |||
1116 | static void | ||
1117 | real_deactivate_quickly (NMDevice *device) | ||
1118 | { | ||
1119 | NMSerialDevice *self = NM_SERIAL_DEVICE (device); | ||
1120 | |||
1121 | cleanup_device (self); | ||
1122 | nm_serial_device_close (self); | ||
1123 | } | ||
1124 | |||
1125 | static guint32 | ||
1126 | real_get_generic_capabilities (NMDevice *dev) | ||
1127 | { | ||
1128 | return NM_DEVICE_CAP_NM_SUPPORTED; | ||
1129 | } | ||
1130 | |||
1131 | /*****************************************************************************/ | ||
1132 | |||
1133 | static void | ||
1134 | nm_serial_device_init (NMSerialDevice *self) | ||
1135 | { | ||
1136 | if (getenv ("NM_SERIAL_DEBUG")) | ||
1137 | serial_debug = TRUE; | ||
1138 | } | ||
1139 | |||
1140 | static void | ||
1141 | finalize (GObject *object) | ||
1142 | { | ||
1143 | NMSerialDevice *self = NM_SERIAL_DEVICE (object); | ||
1144 | |||
1145 | cleanup_device (self); | ||
1146 | nm_serial_device_close (self); | ||
1147 | |||
1148 | G_OBJECT_CLASS (nm_serial_device_parent_class)->finalize (object); | ||
1149 | } | ||
1150 | |||
1151 | static void | ||
1152 | nm_serial_device_class_init (NMSerialDeviceClass *klass) | ||
1153 | { | ||
1154 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
1155 | NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); | ||
1156 | |||
1157 | g_type_class_add_private (object_class, sizeof (NMSerialDevicePrivate)); | ||
1158 | |||
1159 | /* Virtual methods */ | ||
1160 | object_class->finalize = finalize; | ||
1161 | |||
1162 | parent_class->get_generic_capabilities = real_get_generic_capabilities; | ||
1163 | parent_class->act_stage2_config = real_act_stage2_config; | ||
1164 | parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; | ||
1165 | parent_class->deactivate_quickly = real_deactivate_quickly; | ||
1166 | |||
1167 | /* Signals */ | ||
1168 | signals[PPP_STATS] = | ||
1169 | g_signal_new ("ppp-stats", | ||
1170 | G_OBJECT_CLASS_TYPE (object_class), | ||
1171 | G_SIGNAL_RUN_FIRST, | ||
1172 | G_STRUCT_OFFSET (NMSerialDeviceClass, ppp_stats), | ||
1173 | NULL, NULL, | ||
1174 | _nm_marshal_VOID__UINT_UINT, | ||
1175 | G_TYPE_NONE, 2, | ||
1176 | G_TYPE_UINT, G_TYPE_UINT); | ||
1177 | |||
1178 | dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), | ||
1179 | &dbus_glib_nm_serial_device_object_info); | ||
1180 | } | ||
diff --git a/src/nm-serial-device.h b/src/nm-serial-device.h deleted file mode 100644 index 6e9b53bef0..0000000000 --- a/src/nm-serial-device.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ | ||
2 | /* NetworkManager -- Network link manager | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | * Copyright (C) 2007 - 2008 Novell, Inc. | ||
19 | * Copyright (C) 2007 - 2008 Red Hat, Inc. | ||
20 | */ | ||
21 | |||
22 | #ifndef NM_SERIAL_DEVICE_H | ||
23 | #define NM_SERIAL_DEVICE_H | ||
24 | |||
25 | #include <nm-device.h> | ||
26 | #include <nm-setting-serial.h> | ||
27 | #include "ppp-manager/nm-ppp-manager.h" | ||
28 | |||
29 | G_BEGIN_DECLS | ||
30 | |||
31 | #define NM_TYPE_SERIAL_DEVICE (nm_serial_device_get_type ()) | ||
32 | #define NM_SERIAL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SERIAL_DEVICE, NMSerialDevice)) | ||
33 | #define NM_SERIAL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass)) | ||
34 | #define NM_IS_SERIAL_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SERIAL_DEVICE)) | ||
35 | #define NM_IS_SERIAL_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SERIAL_DEVICE)) | ||
36 | #define NM_SERIAL_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SERIAL_DEVICE, NMSerialDeviceClass)) | ||
37 | |||
38 | typedef struct { | ||
39 | NMDevice parent; | ||
40 | } NMSerialDevice; | ||
41 | |||
42 | typedef struct { | ||
43 | NMDeviceClass parent; | ||
44 | |||
45 | const char * (*get_ppp_name) (NMSerialDevice *device, NMActRequest *req); | ||
46 | |||
47 | /* Signals */ | ||
48 | void (*ppp_stats) (NMSerialDevice *device, guint32 in_bytes, guint32 out_bytes); | ||
49 | } NMSerialDeviceClass; | ||
50 | |||
51 | GType nm_serial_device_get_type (void); | ||
52 | |||
53 | typedef void (*NMSerialGetReplyFn) (NMSerialDevice *device, | ||
54 | const char *reply, | ||
55 | gpointer user_data); | ||
56 | |||
57 | typedef void (*NMSerialWaitForReplyFn) (NMSerialDevice *device, | ||
58 | int reply_index, | ||
59 | const char *reply, | ||
60 | gpointer user_data); | ||
61 | |||
62 | typedef void (*NMSerialWaitQuietFn) (NMSerialDevice *device, | ||
63 | gboolean timed_out, | ||
64 | gpointer user_data); | ||
65 | |||
66 | typedef void (*NMSerialFlashFn) (NMSerialDevice *device, | ||
67 | gpointer user_data); | ||
68 | |||
69 | |||
70 | |||
71 | gboolean nm_serial_device_open (NMSerialDevice *device, | ||
72 | NMSettingSerial *setting); | ||
73 | |||
74 | void nm_serial_device_close (NMSerialDevice *device); | ||
75 | gboolean nm_serial_device_send_command (NMSerialDevice *device, | ||
76 | GByteArray *command); | ||
77 | |||
78 | gboolean nm_serial_device_send_command_string (NMSerialDevice *device, | ||
79 | const char *str); | ||
80 | |||
81 | int nm_serial_device_wait_reply_blocking (NMSerialDevice *device, | ||
82 | guint32 timeout_secs, | ||
83 | const char **needles, | ||
84 | const char **terminators); | ||
85 | |||
86 | guint nm_serial_device_wait_for_reply (NMSerialDevice *device, | ||
87 | guint timeout, | ||
88 | const char **responses, | ||
89 | const char **terminators, | ||
90 | NMSerialWaitForReplyFn callback, | ||
91 | gpointer user_data); | ||
92 | |||
93 | void nm_serial_device_wait_quiet (NMSerialDevice *device, | ||
94 | guint timeout, | ||
95 | guint quiet_time, | ||
96 | NMSerialWaitQuietFn callback, | ||
97 | gpointer user_data); | ||
98 | |||
99 | guint nm_serial_device_flash (NMSerialDevice *device, | ||
100 | guint32 flash_time, | ||
101 | NMSerialFlashFn callback, | ||
102 | gpointer user_data); | ||
103 | |||
104 | GIOChannel *nm_serial_device_get_io_channel (NMSerialDevice *device); | ||
105 | |||
106 | NMPPPManager *nm_serial_device_get_ppp_manager (NMSerialDevice *device); | ||
107 | |||
108 | G_END_DECLS | ||
109 | |||
110 | #endif /* NM_SERIAL_DEVICE_H */ | ||