5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
6 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
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.
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.
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
34 #define CONNMAN_API_SUBJECT_TO_CHANGE
35 #include <connman/plugin.h>
36 #include <connman/device.h>
37 #include <connman/network.h>
38 #include <connman/dbus.h>
39 #include <connman/log.h>
41 #define uninitialized_var(x) x = x
43 #define OFONO_SERVICE "org.ofono"
45 #define OFONO_MANAGER_INTERFACE OFONO_SERVICE ".Manager"
46 #define OFONO_MODEM_INTERFACE OFONO_SERVICE ".Modem"
47 #define OFONO_SIM_INTERFACE OFONO_SERVICE ".SimManager"
48 #define OFONO_NETREG_INTERFACE OFONO_SERVICE ".NetworkRegistration"
49 #define OFONO_CM_INTERFACE OFONO_SERVICE ".ConnectionManager"
50 #define OFONO_CONTEXT_INTERFACE OFONO_SERVICE ".ConnectionContext"
52 #define MODEM_ADDED "ModemAdded"
53 #define MODEM_REMOVED "ModemRemoved"
54 #define PROPERTY_CHANGED "PropertyChanged"
55 #define CONTEXT_ADDED "ContextAdded"
56 #define CONTEXT_REMOVED "ContextRemoved"
58 #define GET_PROPERTIES "GetProperties"
59 #define SET_PROPERTY "SetProperty"
60 #define GET_MODEMS "GetModems"
66 OFONO_API_NETREG = 0x2,
70 static DBusConnection *connection;
72 static GHashTable *modem_hash;
77 struct connman_device *device;
81 connman_bool_t powered;
82 connman_bool_t online;
85 connman_bool_t set_powered;
86 connman_bool_t set_online;
88 /* ConnectionManager Interface */
89 connman_bool_t attached;
90 connman_bool_t cm_powered;
92 connman_bool_t set_cm_powered;
94 /* SimManager Interface */
98 DBusPendingCall *call_set_property;
99 DBusPendingCall *call_get_properties;
102 typedef void (*set_property_cb)(struct modem_data *data,
103 connman_bool_t success);
104 typedef void (*get_properties_cb)(struct modem_data *data,
105 DBusMessageIter *dict);
107 struct property_info {
108 struct modem_data *modem;
110 const char *interface;
111 const char *property;
112 set_property_cb set_property_cb;
113 get_properties_cb get_properties_cb;
116 static void set_property_reply(DBusPendingCall *call, void *user_data)
118 struct property_info *info = user_data;
121 connman_bool_t success = TRUE;
123 DBG("%s path %s %s.%s", info->modem->path,
124 info->path, info->interface, info->property);
126 info->modem->call_set_property = NULL;
128 dbus_error_init(&error);
130 reply = dbus_pending_call_steal_reply(call);
132 if (dbus_set_error_from_message(&error, reply)) {
133 connman_error("Failed to change property: %s %s.%s: %s %s",
134 info->path, info->interface, info->property,
135 error.name, error.message);
136 dbus_error_free(&error);
140 if (info->set_property_cb != NULL)
141 (*info->set_property_cb)(info->modem, success);
143 dbus_message_unref(reply);
145 dbus_pending_call_unref(call);
148 static int set_property(struct modem_data *modem,
149 const char *path, const char *interface,
150 const char *property, int type, void *value,
151 set_property_cb notify)
153 DBusMessage *message;
154 DBusMessageIter iter;
155 struct property_info *info;
157 DBG("%s path %s %s.%s", modem->path, path, interface, property);
159 if (modem->call_set_property != NULL) {
160 connman_error("Pending SetProperty");
164 message = dbus_message_new_method_call(OFONO_SERVICE, path,
165 interface, SET_PROPERTY);
169 dbus_message_iter_init_append(message, &iter);
170 connman_dbus_property_append_basic(&iter, property, type, value);
172 if (dbus_connection_send_with_reply(connection, message,
173 &modem->call_set_property, TIMEOUT) == FALSE) {
174 connman_error("Failed to change property: %s %s.%s",
175 path, interface, property);
176 dbus_message_unref(message);
180 if (modem->call_set_property == NULL) {
181 connman_error("D-Bus connection not available");
182 dbus_message_unref(message);
186 info = g_try_new0(struct property_info, 1);
188 dbus_message_unref(message);
194 info->interface = interface;
195 info->property = property;
196 info->set_property_cb = notify;
198 dbus_pending_call_set_notify(modem->call_set_property,
199 set_property_reply, info, g_free);
201 dbus_message_unref(message);
206 static void get_properties_reply(DBusPendingCall *call, void *user_data)
208 struct property_info *info = user_data;
209 DBusMessageIter array, dict;
213 DBG("%s path %s %s", info->modem->path, info->path, info->interface);
215 info->modem->call_get_properties = NULL;
217 dbus_error_init(&error);
219 reply = dbus_pending_call_steal_reply(call);
221 if (dbus_set_error_from_message(&error, reply)) {
222 connman_error("Failed to get properties: %s %s: %s %s",
223 info->path, info->interface,
224 error.name, error.message);
225 dbus_error_free(&error);
230 if (dbus_message_iter_init(reply, &array) == FALSE)
233 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
236 dbus_message_iter_recurse(&array, &dict);
238 if (info->get_properties_cb != NULL)
239 (*info->get_properties_cb)(info->modem, &dict);
243 dbus_message_unref(reply);
245 dbus_pending_call_unref(call);
248 static int get_properties(const char *path, const char *interface,
249 get_properties_cb notify,
250 struct modem_data *modem)
252 DBusMessage *message;
253 struct property_info *info;
255 DBG("%s path %s %s", modem->path, path, interface);
257 if (modem->call_get_properties != NULL) {
258 connman_error("Pending GetProperties");
262 message = dbus_message_new_method_call(OFONO_SERVICE, path,
263 interface, GET_PROPERTIES);
267 if (dbus_connection_send_with_reply(connection, message,
268 &modem->call_get_properties, TIMEOUT) == FALSE) {
269 connman_error("Failed to call %s.GetProperties()", interface);
270 dbus_message_unref(message);
274 if (modem->call_get_properties == NULL) {
275 connman_error("D-Bus connection not available");
276 dbus_message_unref(message);
280 info = g_try_new0(struct property_info, 1);
282 dbus_message_unref(message);
288 info->interface = interface;
289 info->get_properties_cb = notify;
291 dbus_pending_call_set_notify(modem->call_get_properties,
292 get_properties_reply, info, g_free);
294 dbus_message_unref(message);
299 static void modem_set_online_reply(struct modem_data *modem,
300 connman_bool_t success)
302 DBG("%s", modem->path);
304 if (success == TRUE) {
306 * Don't handle do anything on success here. oFono will send
307 * the change via PropertyChanged singal.
312 modem->set_online = FALSE;
315 static int modem_set_online(struct modem_data *modem)
317 DBG("%s", modem->path);
319 modem->set_online = TRUE;
321 return set_property(modem, modem->path,
322 OFONO_MODEM_INTERFACE,
323 "Online", DBUS_TYPE_BOOLEAN,
325 modem_set_online_reply);
328 static void cm_set_powered_reply(struct modem_data *modem,
329 connman_bool_t success)
331 DBG("%s", modem->path);
333 if (success == TRUE) {
335 * Don't handle do anything on success here. oFono will send
336 * the change via PropertyChanged singal.
341 modem->set_cm_powered = FALSE;
344 static int cm_set_powered(struct modem_data *modem)
346 DBG("%s", modem->path);
348 modem->set_cm_powered = TRUE;
350 return set_property(modem, modem->path,
352 "Powered", DBUS_TYPE_BOOLEAN,
353 &modem->set_cm_powered,
354 cm_set_powered_reply);
357 static int modem_set_powered(struct modem_data *modem)
359 DBG("%s", modem->path);
361 modem->set_powered = TRUE;
363 return set_property(modem, modem->path,
364 OFONO_MODEM_INTERFACE,
365 "Powered", DBUS_TYPE_BOOLEAN,
370 static connman_bool_t has_interface(uint8_t interfaces,
373 if ((interfaces & api) == api)
379 static uint8_t extract_interfaces(DBusMessageIter *array)
381 DBusMessageIter entry;
382 uint8_t interfaces = 0;
384 dbus_message_iter_recurse(array, &entry);
386 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
389 dbus_message_iter_get_basic(&entry, &name);
391 if (g_str_equal(name, OFONO_SIM_INTERFACE) == TRUE)
392 interfaces |= OFONO_API_SIM;
393 else if (g_str_equal(name, OFONO_NETREG_INTERFACE) == TRUE)
394 interfaces |= OFONO_API_NETREG;
395 else if (g_str_equal(name, OFONO_CM_INTERFACE) == TRUE)
396 interfaces |= OFONO_API_CM;
398 dbus_message_iter_next(&entry);
404 static connman_bool_t ready_to_create_device(struct modem_data *modem)
407 * There are three different modem types which behave slightly
409 * - GSM modems will expose the SIM interface then the
411 * - DUN modems will expose first a unique serial number (BDADDR)
412 * and then the CM interface.
413 * - CDMA modems will expose CM first and sometime later
414 * a unique serial number.
416 * This functions tests if we have the necessary information gathered
417 * before we are able to create a device.
420 if (modem->device != NULL)
423 if (modem->imsi != NULL || modem->serial != NULL)
429 static void create_device(struct modem_data *modem)
431 struct connman_device *device;
432 char *uninitialized_var(ident);
434 DBG("%s", modem->path);
436 if (modem->imsi != NULL)
438 else if (modem->serial != NULL)
439 ident = modem->serial;
441 if (connman_dbus_validate_ident(ident) == FALSE)
442 ident = connman_dbus_encode_string(ident);
444 ident = g_strdup(ident);
446 device = connman_device_create(ident, CONNMAN_DEVICE_TYPE_CELLULAR);
450 DBG("device %p", device);
452 connman_device_set_ident(device, ident);
454 connman_device_set_string(device, "Path", modem->path);
456 connman_device_set_data(device, modem);
458 if (connman_device_register(device) < 0) {
459 connman_error("Failed to register cellular device");
460 connman_device_unref(device);
464 modem->device = device;
470 static void destroy_device(struct modem_data *modem)
472 DBG("%s", modem->path);
474 connman_device_set_powered(modem->device, FALSE);
476 connman_device_unregister(modem->device);
477 connman_device_unref(modem->device);
479 modem->device = NULL;
482 static gboolean context_changed(DBusConnection *connection,
483 DBusMessage *message,
489 static gboolean cm_context_added(DBusConnection *connection,
490 DBusMessage *message,
496 static gboolean cm_context_removed(DBusConnection *connection,
497 DBusMessage *message,
503 static gboolean netreg_changed(DBusConnection *connection, DBusMessage *message,
509 static gboolean cm_changed(DBusConnection *connection, DBusMessage *message,
512 const char *path = dbus_message_get_path(message);
513 struct modem_data *modem;
514 DBusMessageIter iter, value;
517 modem = g_hash_table_lookup(modem_hash, path);
521 if (dbus_message_iter_init(message, &iter) == FALSE)
524 dbus_message_iter_get_basic(&iter, &key);
526 dbus_message_iter_next(&iter);
527 dbus_message_iter_recurse(&iter, &value);
529 if (g_str_equal(key, "Attached") == TRUE) {
530 dbus_message_iter_get_basic(&value, &modem->attached);
532 DBG("%s Attached %d", modem->path, modem->attached);
533 } else if (g_str_equal(key, "Powered") == TRUE) {
534 dbus_message_iter_get_basic(&value, &modem->cm_powered);
536 DBG("%s ConnnectionManager Powered %d", modem->path,
539 if (modem->cm_powered == FALSE)
540 cm_set_powered(modem);
546 static void cm_properties_reply(struct modem_data *modem, DBusMessageIter *dict)
548 DBG("%s", modem->path);
550 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
551 DBusMessageIter entry, value;
554 dbus_message_iter_recurse(dict, &entry);
555 dbus_message_iter_get_basic(&entry, &key);
557 dbus_message_iter_next(&entry);
558 dbus_message_iter_recurse(&entry, &value);
560 if (g_str_equal(key, "Attached") == TRUE) {
561 dbus_message_iter_get_basic(&value, &modem->attached);
563 DBG("%s Attached %d", modem->path,
565 } else if (g_str_equal(key, "Powered") == TRUE) {
566 dbus_message_iter_get_basic(&value, &modem->cm_powered);
568 DBG("%s ConnnectionManager Powered %d", modem->path,
571 if (modem->cm_powered == FALSE)
572 cm_set_powered(modem);
575 dbus_message_iter_next(dict);
579 static int cm_get_properties(struct modem_data *modem)
581 return get_properties(modem->path, OFONO_CM_INTERFACE,
582 cm_properties_reply, modem);
585 static void update_sim_imsi(struct modem_data *modem,
588 DBG("%s imsi %s", modem->path, imsi);
590 if (g_strcmp0(modem->imsi, imsi) == 0)
594 modem->imsi = g_strdup(imsi);
597 static gboolean sim_changed(DBusConnection *connection, DBusMessage *message,
600 const char *path = dbus_message_get_path(message);
601 struct modem_data *modem;
602 DBusMessageIter iter, value;
605 modem = g_hash_table_lookup(modem_hash, path);
609 if (dbus_message_iter_init(message, &iter) == FALSE)
612 dbus_message_iter_get_basic(&iter, &key);
614 dbus_message_iter_next(&iter);
615 dbus_message_iter_recurse(&iter, &value);
617 if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
620 dbus_message_iter_get_basic(&value, &imsi);
622 update_sim_imsi(modem, imsi);
624 if (modem->online == FALSE) {
625 modem_set_online(modem);
626 } else if (has_interface(modem->interfaces,
627 OFONO_API_CM) == TRUE) {
628 if (ready_to_create_device(modem) == TRUE)
629 create_device(modem);
636 static void sim_properties_reply(struct modem_data *modem,
637 DBusMessageIter *dict)
639 DBG("%s", modem->path);
641 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
642 DBusMessageIter entry, value;
645 dbus_message_iter_recurse(dict, &entry);
646 dbus_message_iter_get_basic(&entry, &key);
648 dbus_message_iter_next(&entry);
649 dbus_message_iter_recurse(&entry, &value);
651 if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
654 dbus_message_iter_get_basic(&value, &imsi);
656 update_sim_imsi(modem, imsi);
658 if (modem->online == FALSE) {
659 modem_set_online(modem);
663 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
664 if (ready_to_create_device(modem) == TRUE)
665 create_device(modem);
666 if (modem->device != NULL)
667 cm_get_properties(modem);
672 dbus_message_iter_next(dict);
676 static int sim_get_properties(struct modem_data *modem)
678 return get_properties(modem->path, OFONO_SIM_INTERFACE,
679 sim_properties_reply, modem);
682 static gboolean modem_changed(DBusConnection *connection, DBusMessage *message,
685 const char *path = dbus_message_get_path(message);
686 struct modem_data *modem;
687 DBusMessageIter iter, value;
690 modem = g_hash_table_lookup(modem_hash, path);
694 if (dbus_message_iter_init(message, &iter) == FALSE)
697 dbus_message_iter_get_basic(&iter, &key);
699 dbus_message_iter_next(&iter);
700 dbus_message_iter_recurse(&iter, &value);
702 if (g_str_equal(key, "Powered") == TRUE) {
703 dbus_message_iter_get_basic(&value, &modem->powered);
705 DBG("%s Powered %d", modem->path, modem->powered);
707 if (modem->powered == FALSE)
708 modem_set_powered(modem);
709 } else if (g_str_equal(key, "Online") == TRUE) {
710 dbus_message_iter_get_basic(&value, &modem->online);
712 DBG("%s Online %d", modem->path, modem->online);
714 if (modem->online == FALSE)
717 if (has_interface(modem->interfaces, OFONO_API_CM) == FALSE)
719 if (ready_to_create_device(modem) == TRUE)
720 create_device(modem);
721 if (modem->device != NULL)
722 cm_get_properties(modem);
723 } else if (g_str_equal(key, "Interfaces") == TRUE) {
724 modem->interfaces = extract_interfaces(&value);
726 DBG("%s Interfaces 0x%02x", modem->path,
729 if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE) {
730 if (modem->imsi == NULL &&
731 modem->set_powered == FALSE) {
733 * Only use do GetProperties() when
734 * device has not been powered up.
736 sim_get_properties(modem);
741 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
742 if (ready_to_create_device(modem) == TRUE)
743 create_device(modem);
744 if (modem->device != NULL)
745 cm_get_properties(modem);
747 if (modem->device != NULL)
748 destroy_device(modem);
750 } else if (g_str_equal(key, "Serial") == TRUE) {
753 dbus_message_iter_get_basic(&value, &serial);
755 g_free(modem->serial);
756 modem->serial = g_strdup(serial);
758 DBG("%s Serial %s", modem->path, modem->serial);
760 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
761 if (ready_to_create_device(modem) == TRUE)
762 create_device(modem);
763 if (modem->device != NULL)
764 cm_get_properties(modem);
771 static void add_modem(const char *path, DBusMessageIter *prop)
773 struct modem_data *modem;
777 modem = g_hash_table_lookup(modem_hash, path);
780 * When oFono powers up we ask for the modems and oFono is
781 * reporting with modem_added signal the modems. Only
787 modem = g_try_new0(struct modem_data, 1);
791 modem->path = g_strdup(path);
793 g_hash_table_insert(modem_hash, g_strdup(path), modem);
795 while (dbus_message_iter_get_arg_type(prop) == DBUS_TYPE_DICT_ENTRY) {
796 DBusMessageIter entry, value;
799 dbus_message_iter_recurse(prop, &entry);
800 dbus_message_iter_get_basic(&entry, &key);
802 dbus_message_iter_next(&entry);
803 dbus_message_iter_recurse(&entry, &value);
805 if (g_str_equal(key, "Powered") == TRUE) {
806 dbus_message_iter_get_basic(&value, &modem->powered);
808 DBG("%s Powered %d", modem->path, modem->powered);
809 } else if (g_str_equal(key, "Online") == TRUE) {
810 dbus_message_iter_get_basic(&value, &modem->online);
812 DBG("%s Online %d", modem->path, modem->online);
813 } else if (g_str_equal(key, "Interfaces") == TRUE) {
814 modem->interfaces = extract_interfaces(&value);
816 DBG("%s Interfaces 0x%02x", modem->path,
818 } else if (g_str_equal(key, "Serial") == TRUE) {
821 dbus_message_iter_get_basic(&value, &serial);
822 modem->serial = g_strdup(serial);
824 DBG("%s Serial %s", modem->path, modem->serial);
827 dbus_message_iter_next(prop);
830 if (modem->powered == FALSE) {
831 modem_set_powered(modem);
832 } else if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE) {
833 sim_get_properties(modem);
834 } else if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
835 if (ready_to_create_device(modem) == TRUE)
836 create_device(modem);
837 if (modem->device != NULL)
838 cm_get_properties(modem);
842 static void remove_modem(gpointer data)
844 struct modem_data *modem = data;
846 DBG("%s", modem->path);
848 if (modem->call_set_property != NULL)
849 dbus_pending_call_cancel(modem->call_set_property);
851 if (modem->call_get_properties != NULL)
852 dbus_pending_call_cancel(modem->call_get_properties);
854 if (modem->device != NULL)
855 destroy_device(modem);
857 g_free(modem->serial);
864 static gboolean modem_added(DBusConnection *connection,
865 DBusMessage *message, void *user_data)
867 DBusMessageIter iter, properties;
872 if (dbus_message_iter_init(message, &iter) == FALSE)
875 dbus_message_iter_get_basic(&iter, &path);
877 dbus_message_iter_next(&iter);
878 dbus_message_iter_recurse(&iter, &properties);
880 add_modem(path, &properties);
885 static gboolean modem_removed(DBusConnection *connection,
886 DBusMessage *message, void *user_data)
888 DBusMessageIter iter;
893 if (dbus_message_iter_init(message, &iter) == FALSE)
896 dbus_message_iter_get_basic(&iter, &path);
898 g_hash_table_remove(modem_hash, path);
903 static void manager_get_modems_reply(DBusPendingCall *call, void *user_data)
907 DBusMessageIter array, dict;
911 reply = dbus_pending_call_steal_reply(call);
913 dbus_error_init(&error);
915 if (dbus_set_error_from_message(&error, reply) == TRUE) {
916 connman_error("%s", error.message);
917 dbus_error_free(&error);
921 if (dbus_message_iter_init(reply, &array) == FALSE)
924 dbus_message_iter_recurse(&array, &dict);
926 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
927 DBusMessageIter value, properties;
930 dbus_message_iter_recurse(&dict, &value);
931 dbus_message_iter_get_basic(&value, &path);
933 dbus_message_iter_next(&value);
934 dbus_message_iter_recurse(&value, &properties);
936 add_modem(path, &properties);
938 dbus_message_iter_next(&dict);
942 dbus_message_unref(reply);
944 dbus_pending_call_unref(call);
947 static int manager_get_modems(void)
949 DBusMessage *message;
950 DBusPendingCall *call;
954 message = dbus_message_new_method_call(OFONO_SERVICE, "/",
955 OFONO_MANAGER_INTERFACE, GET_MODEMS);
959 if (dbus_connection_send_with_reply(connection, message,
960 &call, TIMEOUT) == FALSE) {
961 connman_error("Failed to call GetModems()");
962 dbus_message_unref(message);
967 connman_error("D-Bus connection not available");
968 dbus_message_unref(message);
972 dbus_pending_call_set_notify(call, manager_get_modems_reply,
975 dbus_message_unref(message);
980 static void ofono_connect(DBusConnection *conn, void *user_data)
984 modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
985 g_free, remove_modem);
986 if (modem_hash == NULL)
989 manager_get_modems();
992 static void ofono_disconnect(DBusConnection *conn, void *user_data)
996 if (modem_hash == NULL)
999 g_hash_table_destroy(modem_hash);
1003 static int network_probe(struct connman_network *network)
1005 DBG("network %p", network);
1010 static void network_remove(struct connman_network *network)
1012 DBG("network %p", network);
1015 static int network_connect(struct connman_network *network)
1017 DBG("network %p", network);
1022 static int network_disconnect(struct connman_network *network)
1024 DBG("network %p", network);
1029 static struct connman_network_driver network_driver = {
1031 .type = CONNMAN_NETWORK_TYPE_CELLULAR,
1032 .probe = network_probe,
1033 .remove = network_remove,
1034 .connect = network_connect,
1035 .disconnect = network_disconnect,
1038 static int modem_probe(struct connman_device *device)
1040 struct modem_data *modem = connman_device_get_data(device);
1042 DBG("%s device %p", modem->path, device);
1047 static void modem_remove(struct connman_device *device)
1049 struct modem_data *modem = connman_device_get_data(device);
1051 DBG("%s device %p", modem->path, device);
1054 static int modem_enable(struct connman_device *device)
1056 struct modem_data *modem = connman_device_get_data(device);
1058 DBG("%s device %p", modem->path, device);
1063 static int modem_disable(struct connman_device *device)
1065 struct modem_data *modem = connman_device_get_data(device);
1067 DBG("%s device %p", modem->path, device);
1072 static struct connman_device_driver modem_driver = {
1074 .type = CONNMAN_DEVICE_TYPE_CELLULAR,
1075 .probe = modem_probe,
1076 .remove = modem_remove,
1077 .enable = modem_enable,
1078 .disable = modem_disable,
1082 static guint modem_added_watch;
1083 static guint modem_removed_watch;
1084 static guint modem_watch;
1085 static guint cm_watch;
1086 static guint sim_watch;
1087 static guint context_added_watch;
1088 static guint context_removed_watch;
1089 static guint netreg_watch;
1090 static guint context_watch;
1092 static int ofono_init(void)
1098 connection = connman_dbus_get_connection();
1099 if (connection == NULL)
1102 watch = g_dbus_add_service_watch(connection,
1103 OFONO_SERVICE, ofono_connect,
1104 ofono_disconnect, NULL, NULL);
1106 modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1107 OFONO_MANAGER_INTERFACE,
1112 modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1113 OFONO_MANAGER_INTERFACE,
1118 modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1119 OFONO_MODEM_INTERFACE,
1124 cm_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1130 sim_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1131 OFONO_SIM_INTERFACE,
1136 context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1142 context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1148 context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1149 OFONO_CONTEXT_INTERFACE,
1154 netreg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1155 OFONO_NETREG_INTERFACE,
1161 if (watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0 ||
1162 modem_watch == 0 || cm_watch == 0 || sim_watch == 0 ||
1163 context_added_watch == 0 ||
1164 context_removed_watch == 0 ||
1165 context_watch == 0 || netreg_watch == 0) {
1170 err = connman_network_driver_register(&network_driver);
1174 err = connman_device_driver_register(&modem_driver);
1176 connman_network_driver_unregister(&network_driver);
1183 g_dbus_remove_watch(connection, netreg_watch);
1184 g_dbus_remove_watch(connection, context_watch);
1185 g_dbus_remove_watch(connection, context_removed_watch);
1186 g_dbus_remove_watch(connection, context_added_watch);
1187 g_dbus_remove_watch(connection, sim_watch);
1188 g_dbus_remove_watch(connection, cm_watch);
1189 g_dbus_remove_watch(connection, modem_watch);
1190 g_dbus_remove_watch(connection, modem_removed_watch);
1191 g_dbus_remove_watch(connection, modem_added_watch);
1192 g_dbus_remove_watch(connection, watch);
1193 dbus_connection_unref(connection);
1198 static void ofono_exit(void)
1202 if (modem_hash != NULL) {
1203 g_hash_table_destroy(modem_hash);
1207 connman_device_driver_unregister(&modem_driver);
1208 connman_network_driver_unregister(&network_driver);
1210 g_dbus_remove_watch(connection, netreg_watch);
1211 g_dbus_remove_watch(connection, context_watch);
1212 g_dbus_remove_watch(connection, context_removed_watch);
1213 g_dbus_remove_watch(connection, context_added_watch);
1214 g_dbus_remove_watch(connection, sim_watch);
1215 g_dbus_remove_watch(connection, cm_watch);
1216 g_dbus_remove_watch(connection, modem_watch);
1217 g_dbus_remove_watch(connection, modem_added_watch);
1218 g_dbus_remove_watch(connection, modem_removed_watch);
1219 g_dbus_remove_watch(connection, watch);
1221 dbus_connection_unref(connection);
1224 CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
1225 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ofono_init, ofono_exit)