ofono: Get all modems when oFono connects
[platform/upstream/connman.git] / plugins / ofono.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
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 version 2 as
10  *  published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <stdlib.h>
29
30 #include <gdbus.h>
31 #include <string.h>
32
33 #define CONNMAN_API_SUBJECT_TO_CHANGE
34 #include <connman/plugin.h>
35 #include <connman/device.h>
36 #include <connman/network.h>
37 #include <connman/dbus.h>
38 #include <connman/log.h>
39
40 #define OFONO_SERVICE                   "org.ofono"
41
42 #define OFONO_MANAGER_INTERFACE         OFONO_SERVICE ".Manager"
43 #define OFONO_MODEM_INTERFACE           OFONO_SERVICE ".Modem"
44 #define OFONO_SIM_INTERFACE             OFONO_SERVICE ".SimManager"
45 #define OFONO_NETREG_INTERFACE          OFONO_SERVICE ".NetworkRegistration"
46 #define OFONO_CM_INTERFACE              OFONO_SERVICE ".ConnectionManager"
47 #define OFONO_CONTEXT_INTERFACE         OFONO_SERVICE ".ConnectionContext"
48
49 #define MODEM_ADDED                     "ModemAdded"
50 #define MODEM_REMOVED                   "ModemRemoved"
51 #define PROPERTY_CHANGED                "PropertyChanged"
52 #define CONTEXT_ADDED                   "ContextAdded"
53 #define CONTEXT_REMOVED                 "ContextRemoved"
54
55 #define GET_MODEMS                      "GetModems"
56
57 #define TIMEOUT 40000
58
59 static DBusConnection *connection;
60
61 static gboolean context_changed(DBusConnection *connection,
62                                 DBusMessage *message,
63                                 void *user_data)
64 {
65         return TRUE;
66 }
67
68 static gboolean cm_context_added(DBusConnection *connection,
69                                         DBusMessage *message,
70                                         void *user_data)
71 {
72         return TRUE;
73 }
74
75 static gboolean cm_context_removed(DBusConnection *connection,
76                                         DBusMessage *message,
77                                         void *user_data)
78 {
79         return TRUE;
80 }
81
82 static gboolean netreg_changed(DBusConnection *connection, DBusMessage *message,
83                                 void *user_data)
84 {
85         return TRUE;
86 }
87
88 static gboolean cm_changed(DBusConnection *connection, DBusMessage *message,
89                                 void *user_data)
90 {
91         return TRUE;
92 }
93
94 static gboolean sim_changed(DBusConnection *connection, DBusMessage *message,
95                                 void *user_data)
96 {
97         return TRUE;
98 }
99
100 static gboolean modem_changed(DBusConnection *connection, DBusMessage *message,
101                                 void *user_data)
102 {
103         return TRUE;
104 }
105
106 static gboolean modem_added(DBusConnection *connection,
107                                 DBusMessage *message, void *user_data)
108 {
109         return TRUE;
110 }
111
112 static gboolean modem_removed(DBusConnection *connection,
113                                 DBusMessage *message, void *user_data)
114 {
115         return TRUE;
116 }
117
118 static void manager_get_modems_reply(DBusPendingCall *call, void *user_data)
119 {
120         DBusMessage *reply;
121         DBusError error;
122         DBusMessageIter array, dict;
123
124         DBG("");
125
126         reply = dbus_pending_call_steal_reply(call);
127
128         dbus_error_init(&error);
129
130         if (dbus_set_error_from_message(&error, reply) == TRUE) {
131                 connman_error("%s", error.message);
132                 dbus_error_free(&error);
133                 goto done;
134         }
135
136         if (dbus_message_iter_init(reply, &array) == FALSE)
137                 goto done;
138
139         dbus_message_iter_recurse(&array, &dict);
140
141         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
142                 DBusMessageIter value, properties;
143                 const char *path;
144
145                 dbus_message_iter_recurse(&dict, &value);
146                 dbus_message_iter_get_basic(&value, &path);
147
148                 dbus_message_iter_next(&value);
149                 dbus_message_iter_recurse(&value, &properties);
150
151                 dbus_message_iter_next(&dict);
152         }
153
154 done:
155         dbus_message_unref(reply);
156
157         dbus_pending_call_unref(call);
158 }
159
160 static int manager_get_modems(void)
161 {
162         DBusMessage *message;
163         DBusPendingCall *call;
164
165         DBG("");
166
167         message = dbus_message_new_method_call(OFONO_SERVICE, "/",
168                                         OFONO_MANAGER_INTERFACE, GET_MODEMS);
169         if (message == NULL)
170                 return -ENOMEM;
171
172         if (dbus_connection_send_with_reply(connection, message,
173                                                &call, TIMEOUT) == FALSE) {
174                 connman_error("Failed to call GetModems()");
175                 dbus_message_unref(message);
176                 return -EINVAL;
177         }
178
179         if (call == NULL) {
180                 connman_error("D-Bus connection not available");
181                 dbus_message_unref(message);
182                 return -EINVAL;
183         }
184
185         dbus_pending_call_set_notify(call, manager_get_modems_reply,
186                                         NULL, NULL);
187
188         dbus_message_unref(message);
189
190         return -EINPROGRESS;
191 }
192
193 static void ofono_connect(DBusConnection *conn, void *user_data)
194 {
195         DBG("");
196
197         manager_get_modems();
198 }
199
200 static void ofono_disconnect(DBusConnection *conn, void *user_data)
201 {
202 }
203
204 static int network_probe(struct connman_network *network)
205 {
206         DBG("network %p", network);
207
208         return 0;
209 }
210
211 static void network_remove(struct connman_network *network)
212 {
213         DBG("network %p", network);
214 }
215
216 static int network_connect(struct connman_network *network)
217 {
218         DBG("network %p", network);
219
220         return 0;
221 }
222
223 static int network_disconnect(struct connman_network *network)
224 {
225         DBG("network %p", network);
226
227         return 0;
228 }
229
230 static struct connman_network_driver network_driver = {
231         .name           = "network",
232         .type           = CONNMAN_NETWORK_TYPE_CELLULAR,
233         .probe          = network_probe,
234         .remove         = network_remove,
235         .connect        = network_connect,
236         .disconnect     = network_disconnect,
237 };
238
239 static int modem_probe(struct connman_device *device)
240 {
241         DBG("device %p", device);
242
243         return 0;
244 }
245
246 static void modem_remove(struct connman_device *device)
247 {
248         DBG("device %p", device);
249 }
250
251 static int modem_enable(struct connman_device *device)
252 {
253         DBG("device %p", device);
254
255         return 0;
256 }
257
258 static int modem_disable(struct connman_device *device)
259 {
260         DBG("device %p", device);
261
262         return 0;
263 }
264
265 static struct connman_device_driver modem_driver = {
266         .name           = "modem",
267         .type           = CONNMAN_DEVICE_TYPE_CELLULAR,
268         .probe          = modem_probe,
269         .remove         = modem_remove,
270         .enable         = modem_enable,
271         .disable        = modem_disable,
272 };
273
274 static guint watch;
275 static guint modem_added_watch;
276 static guint modem_removed_watch;
277 static guint modem_watch;
278 static guint cm_watch;
279 static guint sim_watch;
280 static guint context_added_watch;
281 static guint context_removed_watch;
282 static guint netreg_watch;
283 static guint context_watch;
284
285 static int ofono_init(void)
286 {
287         int err;
288
289         DBG("");
290
291         connection = connman_dbus_get_connection();
292         if (connection == NULL)
293                 return -EIO;
294
295         watch = g_dbus_add_service_watch(connection,
296                                         OFONO_SERVICE, ofono_connect,
297                                         ofono_disconnect, NULL, NULL);
298
299         modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
300                                                 OFONO_MANAGER_INTERFACE,
301                                                 MODEM_ADDED,
302                                                 modem_added,
303                                                 NULL, NULL);
304
305         modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
306                                                 OFONO_MANAGER_INTERFACE,
307                                                 MODEM_REMOVED,
308                                                 modem_removed,
309                                                 NULL, NULL);
310
311         modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
312                                                 OFONO_MODEM_INTERFACE,
313                                                 PROPERTY_CHANGED,
314                                                 modem_changed,
315                                                 NULL, NULL);
316
317         cm_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
318                                                 OFONO_CM_INTERFACE,
319                                                 PROPERTY_CHANGED,
320                                                 cm_changed,
321                                                 NULL, NULL);
322
323         sim_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
324                                                 OFONO_SIM_INTERFACE,
325                                                 PROPERTY_CHANGED,
326                                                 sim_changed,
327                                                 NULL, NULL);
328
329         context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
330                                                 OFONO_CM_INTERFACE,
331                                                 CONTEXT_ADDED,
332                                                 cm_context_added,
333                                                 NULL, NULL);
334
335         context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
336                                                 OFONO_CM_INTERFACE,
337                                                 CONTEXT_REMOVED,
338                                                 cm_context_removed,
339                                                 NULL, NULL);
340
341         context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
342                                                 OFONO_CONTEXT_INTERFACE,
343                                                 PROPERTY_CHANGED,
344                                                 context_changed,
345                                                 NULL, NULL);
346
347         netreg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
348                                                 OFONO_NETREG_INTERFACE,
349                                                 PROPERTY_CHANGED,
350                                                 netreg_changed,
351                                                 NULL, NULL);
352
353
354         if (watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0 ||
355                         modem_watch == 0 || cm_watch == 0 || sim_watch == 0 ||
356                         context_added_watch == 0 ||
357                         context_removed_watch == 0 ||
358                         context_watch == 0 || netreg_watch == 0) {
359                 err = -EIO;
360                 goto remove;
361         }
362
363         err = connman_network_driver_register(&network_driver);
364         if (err < 0)
365                 goto remove;
366
367         err = connman_device_driver_register(&modem_driver);
368         if (err < 0) {
369                 connman_network_driver_unregister(&network_driver);
370                 goto remove;
371         }
372
373         return 0;
374
375 remove:
376         g_dbus_remove_watch(connection, netreg_watch);
377         g_dbus_remove_watch(connection, context_watch);
378         g_dbus_remove_watch(connection, context_removed_watch);
379         g_dbus_remove_watch(connection, context_added_watch);
380         g_dbus_remove_watch(connection, sim_watch);
381         g_dbus_remove_watch(connection, cm_watch);
382         g_dbus_remove_watch(connection, modem_watch);
383         g_dbus_remove_watch(connection, modem_removed_watch);
384         g_dbus_remove_watch(connection, modem_added_watch);
385         g_dbus_remove_watch(connection, watch);
386         dbus_connection_unref(connection);
387
388         return err;
389 }
390
391 static void ofono_exit(void)
392 {
393         DBG("");
394
395         connman_device_driver_unregister(&modem_driver);
396         connman_network_driver_unregister(&network_driver);
397
398         g_dbus_remove_watch(connection, netreg_watch);
399         g_dbus_remove_watch(connection, context_watch);
400         g_dbus_remove_watch(connection, context_removed_watch);
401         g_dbus_remove_watch(connection, context_added_watch);
402         g_dbus_remove_watch(connection, sim_watch);
403         g_dbus_remove_watch(connection, cm_watch);
404         g_dbus_remove_watch(connection, modem_watch);
405         g_dbus_remove_watch(connection, modem_added_watch);
406         g_dbus_remove_watch(connection, modem_removed_watch);
407         g_dbus_remove_watch(connection, watch);
408
409         dbus_connection_unref(connection);
410 }
411
412 CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
413                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ofono_init, ofono_exit)