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/inet.h>
39 #include <connman/dbus.h>
40 #include <connman/log.h>
42 #define uninitialized_var(x) x = x
44 #define OFONO_SERVICE "org.ofono"
46 #define OFONO_MANAGER_INTERFACE OFONO_SERVICE ".Manager"
47 #define OFONO_MODEM_INTERFACE OFONO_SERVICE ".Modem"
48 #define OFONO_SIM_INTERFACE OFONO_SERVICE ".SimManager"
49 #define OFONO_NETREG_INTERFACE OFONO_SERVICE ".NetworkRegistration"
50 #define OFONO_CM_INTERFACE OFONO_SERVICE ".ConnectionManager"
51 #define OFONO_CONTEXT_INTERFACE OFONO_SERVICE ".ConnectionContext"
53 #define MODEM_ADDED "ModemAdded"
54 #define MODEM_REMOVED "ModemRemoved"
55 #define PROPERTY_CHANGED "PropertyChanged"
56 #define CONTEXT_ADDED "ContextAdded"
57 #define CONTEXT_REMOVED "ContextRemoved"
59 #define GET_PROPERTIES "GetProperties"
60 #define SET_PROPERTY "SetProperty"
61 #define GET_MODEMS "GetModems"
62 #define GET_CONTEXTS "GetContexts"
68 OFONO_API_NETREG = 0x2,
72 static DBusConnection *connection;
74 static GHashTable *modem_hash;
75 static GHashTable *context_hash;
77 struct network_context {
81 enum connman_ipconfig_method ipv4_method;
82 struct connman_ipaddress *ipv4_address;
83 char *ipv4_nameservers;
85 enum connman_ipconfig_method ipv6_method;
86 struct connman_ipaddress *ipv6_address;
87 char *ipv6_nameservers;
93 struct connman_device *device;
94 struct connman_network *network;
96 struct network_context *context;
100 connman_bool_t powered;
101 connman_bool_t online;
104 connman_bool_t set_powered;
105 connman_bool_t set_online;
107 /* ConnectionManager Interface */
108 connman_bool_t attached;
109 connman_bool_t cm_powered;
111 connman_bool_t set_cm_powered;
113 /* ConnectionContext Interface */
114 connman_bool_t active;
115 connman_bool_t set_active;
117 /* SimManager Interface */
120 /* Netreg Interface */
125 DBusPendingCall *call_set_property;
126 DBusPendingCall *call_get_properties;
127 DBusPendingCall *call_get_contexts;
130 static char *get_ident(const char *path)
137 pos = strrchr(path, '/');
144 static struct network_context *network_context_alloc(const char *path)
146 struct network_context *context;
148 context = g_try_new0(struct network_context, 1);
152 context->path = g_strdup(path);
155 context->ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
156 context->ipv4_address = NULL;
157 context->ipv4_nameservers = NULL;
159 context->ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
160 context->ipv6_address = NULL;
161 context->ipv6_nameservers = NULL;
166 static void network_context_free(struct network_context *context)
168 g_free(context->path);
170 connman_ipaddress_free(context->ipv4_address);
171 g_free(context->ipv4_nameservers);
173 connman_ipaddress_free(context->ipv6_address);
174 g_free(context->ipv6_nameservers);
179 static void set_connected(struct modem_data *modem)
181 connman_bool_t setip = FALSE;
183 DBG("%s", modem->path);
185 connman_network_set_index(modem->network, modem->context->index);
187 switch (modem->context->ipv4_method) {
188 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
189 case CONNMAN_IPCONFIG_METHOD_OFF:
190 case CONNMAN_IPCONFIG_METHOD_MANUAL:
191 case CONNMAN_IPCONFIG_METHOD_AUTO:
194 case CONNMAN_IPCONFIG_METHOD_FIXED:
195 connman_network_set_ipv4_method(modem->network,
196 modem->context->ipv4_method);
197 connman_network_set_ipaddress(modem->network,
198 modem->context->ipv4_address);
199 connman_network_set_nameservers(modem->network,
200 modem->context->ipv4_nameservers);
204 case CONNMAN_IPCONFIG_METHOD_DHCP:
205 connman_network_set_ipv4_method(modem->network,
206 modem->context->ipv4_method);
211 switch (modem->context->ipv6_method) {
212 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
213 case CONNMAN_IPCONFIG_METHOD_OFF:
214 case CONNMAN_IPCONFIG_METHOD_MANUAL:
215 case CONNMAN_IPCONFIG_METHOD_DHCP:
216 case CONNMAN_IPCONFIG_METHOD_AUTO:
219 case CONNMAN_IPCONFIG_METHOD_FIXED:
220 connman_network_set_ipv6_method(modem->network,
221 modem->context->ipv6_method);
222 connman_network_set_ipaddress(modem->network,
223 modem->context->ipv6_address);
229 connman_network_set_connected(modem->network, TRUE);
232 static void set_disconnected(struct modem_data *modem)
234 DBG("%s", modem->path);
236 connman_network_set_connected(modem->network, FALSE);
239 typedef void (*set_property_cb)(struct modem_data *data,
240 connman_bool_t success);
241 typedef void (*get_properties_cb)(struct modem_data *data,
242 DBusMessageIter *dict);
244 struct property_info {
245 struct modem_data *modem;
247 const char *interface;
248 const char *property;
249 set_property_cb set_property_cb;
250 get_properties_cb get_properties_cb;
253 static void set_property_reply(DBusPendingCall *call, void *user_data)
255 struct property_info *info = user_data;
258 connman_bool_t success = TRUE;
260 DBG("%s path %s %s.%s", info->modem->path,
261 info->path, info->interface, info->property);
263 info->modem->call_set_property = NULL;
265 dbus_error_init(&error);
267 reply = dbus_pending_call_steal_reply(call);
269 if (dbus_set_error_from_message(&error, reply)) {
270 connman_error("Failed to change property: %s %s.%s: %s %s",
271 info->path, info->interface, info->property,
272 error.name, error.message);
273 dbus_error_free(&error);
277 if (info->set_property_cb != NULL)
278 (*info->set_property_cb)(info->modem, success);
280 dbus_message_unref(reply);
282 dbus_pending_call_unref(call);
285 static int set_property(struct modem_data *modem,
286 const char *path, const char *interface,
287 const char *property, int type, void *value,
288 set_property_cb notify)
290 DBusMessage *message;
291 DBusMessageIter iter;
292 struct property_info *info;
294 DBG("%s path %s %s.%s", modem->path, path, interface, property);
296 if (modem->call_set_property != NULL) {
297 connman_error("Pending SetProperty");
301 message = dbus_message_new_method_call(OFONO_SERVICE, path,
302 interface, SET_PROPERTY);
306 dbus_message_iter_init_append(message, &iter);
307 connman_dbus_property_append_basic(&iter, property, type, value);
309 if (dbus_connection_send_with_reply(connection, message,
310 &modem->call_set_property, TIMEOUT) == FALSE) {
311 connman_error("Failed to change property: %s %s.%s",
312 path, interface, property);
313 dbus_message_unref(message);
317 if (modem->call_set_property == NULL) {
318 connman_error("D-Bus connection not available");
319 dbus_message_unref(message);
323 info = g_try_new0(struct property_info, 1);
325 dbus_message_unref(message);
331 info->interface = interface;
332 info->property = property;
333 info->set_property_cb = notify;
335 dbus_pending_call_set_notify(modem->call_set_property,
336 set_property_reply, info, g_free);
338 dbus_message_unref(message);
343 static void get_properties_reply(DBusPendingCall *call, void *user_data)
345 struct property_info *info = user_data;
346 DBusMessageIter array, dict;
350 DBG("%s path %s %s", info->modem->path, info->path, info->interface);
352 info->modem->call_get_properties = NULL;
354 dbus_error_init(&error);
356 reply = dbus_pending_call_steal_reply(call);
358 if (dbus_set_error_from_message(&error, reply)) {
359 connman_error("Failed to get properties: %s %s: %s %s",
360 info->path, info->interface,
361 error.name, error.message);
362 dbus_error_free(&error);
367 if (dbus_message_iter_init(reply, &array) == FALSE)
370 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
373 dbus_message_iter_recurse(&array, &dict);
375 if (info->get_properties_cb != NULL)
376 (*info->get_properties_cb)(info->modem, &dict);
380 dbus_message_unref(reply);
382 dbus_pending_call_unref(call);
385 static int get_properties(const char *path, const char *interface,
386 get_properties_cb notify,
387 struct modem_data *modem)
389 DBusMessage *message;
390 struct property_info *info;
392 DBG("%s path %s %s", modem->path, path, interface);
394 if (modem->call_get_properties != NULL) {
395 connman_error("Pending GetProperties");
399 message = dbus_message_new_method_call(OFONO_SERVICE, path,
400 interface, GET_PROPERTIES);
404 if (dbus_connection_send_with_reply(connection, message,
405 &modem->call_get_properties, TIMEOUT) == FALSE) {
406 connman_error("Failed to call %s.GetProperties()", interface);
407 dbus_message_unref(message);
411 if (modem->call_get_properties == NULL) {
412 connman_error("D-Bus connection not available");
413 dbus_message_unref(message);
417 info = g_try_new0(struct property_info, 1);
419 dbus_message_unref(message);
425 info->interface = interface;
426 info->get_properties_cb = notify;
428 dbus_pending_call_set_notify(modem->call_get_properties,
429 get_properties_reply, info, g_free);
431 dbus_message_unref(message);
436 static void context_set_active_reply(struct modem_data *modem,
437 connman_bool_t success)
439 DBG("%s", modem->path);
441 if (success == TRUE) {
443 * Don't handle do anything on success here. oFono will send
444 * the change via PropertyChanged singal.
450 * Active = True might fail due a timeout. That means oFono
451 * still tries to go online. If we retry to set Active = True,
452 * we just get a InProgress error message. Should we power
453 * cycle the modem in such cases?
456 connman_network_set_error(modem->network,
457 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
460 static int context_set_active(struct modem_data *modem)
462 dbus_bool_t active = TRUE;
464 DBG("%s", modem->path);
466 return set_property(modem, modem->context->path,
467 OFONO_CONTEXT_INTERFACE,
468 "Active", DBUS_TYPE_BOOLEAN,
470 context_set_active_reply);
473 static int context_set_inactive(struct modem_data *modem)
475 dbus_bool_t active = FALSE;
478 DBG("%s", modem->path);
480 err = set_property(modem, modem->context->path,
481 OFONO_CONTEXT_INTERFACE,
482 "Active", DBUS_TYPE_BOOLEAN,
485 if (err == -EINPROGRESS)
491 static void modem_set_online_reply(struct modem_data *modem,
492 connman_bool_t success)
494 DBG("%s", modem->path);
496 if (success == TRUE) {
498 * Don't handle do anything on success here. oFono will send
499 * the change via PropertyChanged singal.
504 modem->set_online = FALSE;
507 static int modem_set_online(struct modem_data *modem)
509 DBG("%s", modem->path);
511 modem->set_online = TRUE;
513 return set_property(modem, modem->path,
514 OFONO_MODEM_INTERFACE,
515 "Online", DBUS_TYPE_BOOLEAN,
517 modem_set_online_reply);
520 static void cm_set_powered_reply(struct modem_data *modem,
521 connman_bool_t success)
523 DBG("%s", modem->path);
525 if (success == TRUE) {
527 * Don't handle do anything on success here. oFono will send
528 * the change via PropertyChanged singal.
533 modem->set_cm_powered = FALSE;
536 static int cm_set_powered(struct modem_data *modem)
538 DBG("%s", modem->path);
540 modem->set_cm_powered = TRUE;
542 return set_property(modem, modem->path,
544 "Powered", DBUS_TYPE_BOOLEAN,
545 &modem->set_cm_powered,
546 cm_set_powered_reply);
549 static int modem_set_powered(struct modem_data *modem)
551 DBG("%s", modem->path);
553 modem->set_powered = TRUE;
555 return set_property(modem, modem->path,
556 OFONO_MODEM_INTERFACE,
557 "Powered", DBUS_TYPE_BOOLEAN,
562 static connman_bool_t has_interface(uint8_t interfaces,
565 if ((interfaces & api) == api)
571 static uint8_t extract_interfaces(DBusMessageIter *array)
573 DBusMessageIter entry;
574 uint8_t interfaces = 0;
576 dbus_message_iter_recurse(array, &entry);
578 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
581 dbus_message_iter_get_basic(&entry, &name);
583 if (g_str_equal(name, OFONO_SIM_INTERFACE) == TRUE)
584 interfaces |= OFONO_API_SIM;
585 else if (g_str_equal(name, OFONO_NETREG_INTERFACE) == TRUE)
586 interfaces |= OFONO_API_NETREG;
587 else if (g_str_equal(name, OFONO_CM_INTERFACE) == TRUE)
588 interfaces |= OFONO_API_CM;
590 dbus_message_iter_next(&entry);
596 static char *extract_nameservers(DBusMessageIter *array)
598 DBusMessageIter entry;
599 char *nameservers = NULL;
602 dbus_message_iter_recurse(array, &entry);
604 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
605 const char *nameserver;
607 dbus_message_iter_get_basic(&entry, &nameserver);
609 if (nameservers == NULL) {
610 nameservers = g_strdup(nameserver);
613 nameservers = g_strdup_printf("%s %s", tmp, nameserver);
617 dbus_message_iter_next(&entry);
623 static void extract_ipv4_settings(DBusMessageIter *array,
624 struct network_context *context)
626 DBusMessageIter dict;
627 char *address = NULL, *netmask = NULL, *gateway = NULL;
628 char *nameservers = NULL;
629 const char *interface = NULL;
632 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
635 dbus_message_iter_recurse(array, &dict);
637 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
638 DBusMessageIter entry, value;
639 const char *key, *val;
641 dbus_message_iter_recurse(&dict, &entry);
642 dbus_message_iter_get_basic(&entry, &key);
644 dbus_message_iter_next(&entry);
645 dbus_message_iter_recurse(&entry, &value);
647 if (g_str_equal(key, "Interface") == TRUE) {
648 dbus_message_iter_get_basic(&value, &interface);
650 DBG("Interface %s", interface);
652 index = connman_inet_ifindex(interface);
654 DBG("index %d", index);
655 } else if (g_str_equal(key, "Method") == TRUE) {
656 dbus_message_iter_get_basic(&value, &val);
658 DBG("Method %s", val);
660 if (g_strcmp0(val, "static") == 0) {
661 context->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
662 } else if (g_strcmp0(val, "dhcp") == 0) {
663 context->ipv4_method = CONNMAN_IPCONFIG_METHOD_DHCP;
666 } else if (g_str_equal(key, "Address") == TRUE) {
667 dbus_message_iter_get_basic(&value, &val);
669 address = g_strdup(val);
671 DBG("Address %s", address);
672 } else if (g_str_equal(key, "Netmask") == TRUE) {
673 dbus_message_iter_get_basic(&value, &val);
675 netmask = g_strdup(val);
677 DBG("Netmask %s", netmask);
678 } else if (g_str_equal(key, "DomainNameServers") == TRUE) {
679 nameservers = extract_nameservers(&value);
681 DBG("Nameservers %s", nameservers);
682 } else if (g_str_equal(key, "Gateway") == TRUE) {
683 dbus_message_iter_get_basic(&value, &val);
685 gateway = g_strdup(val);
687 DBG("Gateway %s", gateway);
690 dbus_message_iter_next(&dict);
696 if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_FIXED)
699 context->ipv4_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
700 if (context->ipv4_address == NULL)
703 context->index = index;
704 connman_ipaddress_set_ipv4(context->ipv4_address, address,
707 context->ipv4_nameservers = nameservers;
710 if (context->ipv4_nameservers != nameservers)
718 static void extract_ipv6_settings(DBusMessageIter *array,
719 struct network_context *context)
721 DBusMessageIter dict;
722 char *address = NULL, *gateway = NULL;
723 unsigned char prefix_length;
724 char *nameservers = NULL;
725 const char *interface = NULL;
728 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
731 dbus_message_iter_recurse(array, &dict);
733 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
734 DBusMessageIter entry, value;
735 const char *key, *val;
737 dbus_message_iter_recurse(&dict, &entry);
738 dbus_message_iter_get_basic(&entry, &key);
740 dbus_message_iter_next(&entry);
741 dbus_message_iter_recurse(&entry, &value);
743 if (g_str_equal(key, "Interface") == TRUE) {
744 dbus_message_iter_get_basic(&value, &interface);
746 DBG("Interface %s", interface);
748 index = connman_inet_ifindex(interface);
750 DBG("index %d", index);
751 } else if (g_str_equal(key, "Address") == TRUE) {
752 dbus_message_iter_get_basic(&value, &val);
754 address = g_strdup(val);
756 DBG("Address %s", address);
757 } else if (g_str_equal(key, "PrefixLength") == TRUE) {
758 dbus_message_iter_get_basic(&value, &prefix_length);
760 DBG("prefix length %d", prefix_length);
761 } else if (g_str_equal(key, "DomainNameServers") == TRUE) {
762 nameservers = extract_nameservers(&value);
764 DBG("Nameservers %s", nameservers);
765 } else if (g_str_equal(key, "Gateway") == TRUE) {
766 dbus_message_iter_get_basic(&value, &val);
768 gateway = g_strdup(val);
770 DBG("Gateway %s", gateway);
773 dbus_message_iter_next(&dict);
779 context->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
781 context->ipv6_address =
782 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
783 if (context->ipv6_address == NULL)
786 context->index = index;
787 connman_ipaddress_set_ipv6(context->ipv6_address, address,
788 prefix_length, gateway);
790 context->ipv6_nameservers = nameservers;
793 if (context->ipv6_nameservers != nameservers)
800 static connman_bool_t ready_to_create_device(struct modem_data *modem)
803 * There are three different modem types which behave slightly
805 * - GSM modems will expose the SIM interface then the
807 * - DUN modems will expose first a unique serial number (BDADDR)
808 * and then the CM interface.
809 * - CDMA modems will expose CM first and sometime later
810 * a unique serial number.
812 * This functions tests if we have the necessary information gathered
813 * before we are able to create a device.
816 if (modem->device != NULL)
819 if (modem->imsi != NULL || modem->serial != NULL)
825 static void create_device(struct modem_data *modem)
827 struct connman_device *device;
828 char *uninitialized_var(ident);
830 DBG("%s", modem->path);
832 if (modem->imsi != NULL)
834 else if (modem->serial != NULL)
835 ident = modem->serial;
837 if (connman_dbus_validate_ident(ident) == FALSE)
838 ident = connman_dbus_encode_string(ident);
840 ident = g_strdup(ident);
842 device = connman_device_create(ident, CONNMAN_DEVICE_TYPE_CELLULAR);
846 DBG("device %p", device);
848 connman_device_set_ident(device, ident);
850 connman_device_set_string(device, "Path", modem->path);
852 connman_device_set_data(device, modem);
854 if (connman_device_register(device) < 0) {
855 connman_error("Failed to register cellular device");
856 connman_device_unref(device);
860 modem->device = device;
866 static void destroy_device(struct modem_data *modem)
868 DBG("%s", modem->path);
870 connman_device_set_powered(modem->device, FALSE);
872 if (modem->network != NULL) {
873 connman_device_remove_network(modem->device, modem->network);
874 connman_network_unref(modem->network);
875 modem->network = NULL;
878 connman_device_unregister(modem->device);
879 connman_device_unref(modem->device);
881 modem->device = NULL;
884 static void add_network(struct modem_data *modem)
888 DBG("%s", modem->path);
890 if (modem->network != NULL)
893 modem->network = connman_network_create(modem->context->path,
894 CONNMAN_NETWORK_TYPE_CELLULAR);
895 if (modem->network == NULL)
898 DBG("network %p", modem->network);
900 connman_network_set_data(modem->network, modem);
902 connman_network_set_string(modem->network, "Path",
903 modem->context->path);
905 connman_network_set_index(modem->network, modem->context->index);
907 if (modem->name != NULL)
908 connman_network_set_name(modem->network, modem->name);
910 connman_network_set_name(modem->network, "");
912 connman_network_set_strength(modem->network, modem->strength);
914 group = get_ident(modem->context->path);
915 connman_network_set_group(modem->network, group);
917 connman_network_set_available(modem->network, TRUE);
919 if (connman_device_add_network(modem->device, modem->network) < 0) {
920 connman_network_unref(modem->network);
921 modem->network = NULL;
926 static int add_cm_context(struct modem_data *modem, const char *context_path,
927 DBusMessageIter *dict)
929 const char *context_type;
930 struct network_context *context = NULL;
931 connman_bool_t active = FALSE;
933 DBG("%s context path %s", modem->path, context_path);
935 if (modem->context != NULL) {
937 * We have already assigned a context to this modem
938 * and we do only support one Internet context.
943 context = network_context_alloc(context_path);
947 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
948 DBusMessageIter entry, value;
951 dbus_message_iter_recurse(dict, &entry);
952 dbus_message_iter_get_basic(&entry, &key);
954 dbus_message_iter_next(&entry);
955 dbus_message_iter_recurse(&entry, &value);
957 if (g_str_equal(key, "Type") == TRUE) {
958 dbus_message_iter_get_basic(&value, &context_type);
960 DBG("%s context %s type %s", modem->path,
961 context_path, context_type);
962 } else if (g_str_equal(key, "Settings") == TRUE) {
963 DBG("%s Settings", modem->path);
965 extract_ipv4_settings(&value, context);
966 } else if (g_str_equal(key, "IPv6.Settings") == TRUE) {
967 DBG("%s IPv6.Settings", modem->path);
969 extract_ipv6_settings(&value, context);
970 } else if (g_str_equal(key, "Active") == TRUE) {
971 dbus_message_iter_get_basic(&value, &active);
973 DBG("%s Active %d", modem->path, active);
976 dbus_message_iter_next(dict);
979 if (g_strcmp0(context_type, "internet") != 0) {
980 network_context_free(context);
984 modem->context = context;
985 modem->active = active;
987 g_hash_table_replace(context_hash, g_strdup(context_path), modem);
992 static void remove_cm_context(struct modem_data *modem,
993 const char *context_path)
995 if (modem->context == NULL)
998 g_hash_table_remove(context_hash, context_path);
1000 network_context_free(modem->context);
1001 modem->context = NULL;
1004 static gboolean context_changed(DBusConnection *connection,
1005 DBusMessage *message,
1008 const char *context_path = dbus_message_get_path(message);
1009 struct modem_data *modem = NULL;
1010 DBusMessageIter iter, value;
1013 DBG("context_path %s", context_path);
1015 modem = g_hash_table_lookup(context_hash, context_path);
1019 if (dbus_message_iter_init(message, &iter) == FALSE)
1022 dbus_message_iter_get_basic(&iter, &key);
1024 dbus_message_iter_next(&iter);
1025 dbus_message_iter_recurse(&iter, &value);
1028 * oFono guarantees the ordering of Settings and
1029 * Active. Settings will always be send before Active = True.
1030 * That means we don't have to order here.
1032 if (g_str_equal(key, "Settings") == TRUE) {
1033 DBG("%s Settings", modem->path);
1035 extract_ipv4_settings(&value, modem->context);
1036 } else if (g_str_equal(key, "IPv6.Settings") == TRUE) {
1037 DBG("%s IPv6.Settings", modem->path);
1039 extract_ipv6_settings(&value, modem->context);
1040 } else if (g_str_equal(key, "Active") == TRUE) {
1041 dbus_message_iter_get_basic(&value, &modem->active);
1043 DBG("%s Active %d", modem->path, modem->active);
1045 if (modem->active == TRUE)
1046 set_connected(modem);
1048 set_disconnected(modem);
1054 static void cm_get_contexts_reply(DBusPendingCall *call, void *user_data)
1056 struct modem_data *modem = user_data;
1057 DBusMessageIter array, dict, entry, value;
1061 DBG("%s", modem->path);
1063 modem->call_get_contexts = NULL;
1065 reply = dbus_pending_call_steal_reply(call);
1067 dbus_error_init(&error);
1069 if (dbus_set_error_from_message(&error, reply) == TRUE) {
1070 connman_error("%s", error.message);
1071 dbus_error_free(&error);
1075 if (dbus_message_iter_init(reply, &array) == FALSE)
1078 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
1081 dbus_message_iter_recurse(&array, &dict);
1083 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
1084 const char *context_path;
1086 dbus_message_iter_recurse(&dict, &entry);
1087 dbus_message_iter_get_basic(&entry, &context_path);
1089 dbus_message_iter_next(&entry);
1090 dbus_message_iter_recurse(&entry, &value);
1092 if (add_cm_context(modem, context_path, &value) == 0)
1095 dbus_message_iter_next(&dict);
1099 dbus_message_unref(reply);
1101 dbus_pending_call_unref(call);
1104 static int cm_get_contexts(struct modem_data *modem)
1106 DBusMessage *message;
1108 DBG("%s", modem->path);
1110 if (modem->call_get_contexts != NULL)
1113 message = dbus_message_new_method_call(OFONO_SERVICE, modem->path,
1114 OFONO_CM_INTERFACE, GET_CONTEXTS);
1115 if (message == NULL)
1118 if (dbus_connection_send_with_reply(connection, message,
1119 &modem->call_get_contexts, TIMEOUT) == FALSE) {
1120 connman_error("Failed to call GetContexts()");
1121 dbus_message_unref(message);
1125 if (modem->call_get_contexts == NULL) {
1126 connman_error("D-Bus connection not available");
1127 dbus_message_unref(message);
1131 dbus_pending_call_set_notify(modem->call_get_contexts,
1132 cm_get_contexts_reply,
1135 dbus_message_unref(message);
1137 return -EINPROGRESS;
1140 static gboolean cm_context_added(DBusConnection *connection,
1141 DBusMessage *message,
1144 const char *path = dbus_message_get_path(message);
1146 struct modem_data *modem;
1147 DBusMessageIter iter, properties;
1151 modem = g_hash_table_lookup(modem_hash, context_path);
1155 if (dbus_message_iter_init(message, &iter) == FALSE)
1158 dbus_message_iter_get_basic(&iter, &context_path);
1160 dbus_message_iter_next(&iter);
1161 dbus_message_iter_recurse(&iter, &properties);
1163 if (add_cm_context(modem, context_path, &properties) != 0)
1169 static gboolean cm_context_removed(DBusConnection *connection,
1170 DBusMessage *message,
1173 const char *path = dbus_message_get_path(message);
1174 const char *context_path;
1175 struct modem_data *modem;
1176 DBusMessageIter iter;
1178 DBG("context path %s", path);
1180 if (dbus_message_iter_init(message, &iter) == FALSE)
1183 dbus_message_iter_get_basic(&iter, &context_path);
1185 modem = g_hash_table_lookup(context_hash, context_path);
1189 remove_cm_context(modem, context_path);
1194 static gboolean netreg_changed(DBusConnection *connection, DBusMessage *message,
1197 const char *path = dbus_message_get_path(message);
1198 struct modem_data *modem;
1199 DBusMessageIter iter, value;
1202 modem = g_hash_table_lookup(modem_hash, path);
1206 if (dbus_message_iter_init(message, &iter) == FALSE)
1209 dbus_message_iter_get_basic(&iter, &key);
1211 dbus_message_iter_next(&iter);
1212 dbus_message_iter_recurse(&iter, &value);
1214 if (g_str_equal(key, "Name") == TRUE) {
1217 dbus_message_iter_get_basic(&value, &name);
1219 DBG("%s Name %s", modem->path, name);
1221 g_free(modem->name);
1222 modem->name = g_strdup(name);
1224 if (modem->network == NULL)
1227 connman_network_set_name(modem->network, modem->name);
1228 connman_network_update(modem->network);
1229 } else if (g_str_equal(key, "Strength") == TRUE) {
1230 dbus_message_iter_get_basic(&value, &modem->strength);
1232 DBG("%s Strength %d", modem->path, modem->strength);
1234 if (modem->network == NULL)
1237 connman_network_set_strength(modem->network, modem->strength);
1238 connman_network_update(modem->network);
1244 static void netreg_properties_reply(struct modem_data *modem,
1245 DBusMessageIter *dict)
1247 DBG("%s", modem->path);
1249 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
1250 DBusMessageIter entry, value;
1253 dbus_message_iter_recurse(dict, &entry);
1254 dbus_message_iter_get_basic(&entry, &key);
1256 dbus_message_iter_next(&entry);
1257 dbus_message_iter_recurse(&entry, &value);
1259 if (g_str_equal(key, "Name") == TRUE) {
1262 dbus_message_iter_get_basic(&value, &name);
1264 DBG("%s Name %s", modem->path, name);
1266 g_free(modem->name);
1267 modem->name = g_strdup(name);
1269 if (modem->network != NULL) {
1270 connman_network_set_name(modem->network,
1272 connman_network_update(modem->network);
1274 } else if (g_str_equal(key, "Strength") == TRUE) {
1275 dbus_message_iter_get_basic(&value, &modem->strength);
1277 DBG("%s Strength %d", modem->path,
1280 if (modem->network != NULL) {
1281 connman_network_set_strength(modem->network,
1283 connman_network_update(modem->network);
1287 dbus_message_iter_next(dict);
1290 if (modem->context == NULL) {
1292 * netgreg_get_properties() was issued after we got
1293 * cm_get_contexts_reply() where we create the
1294 * context. Though before we got the
1295 * netreg_properties_reply the context was removed
1296 * again. Therefore we have to skip the network
1304 if (modem->active == TRUE)
1305 set_connected(modem);
1308 static int netreg_get_properties(struct modem_data *modem)
1310 return get_properties(modem->path, OFONO_NETREG_INTERFACE,
1311 netreg_properties_reply, modem);
1314 static gboolean cm_changed(DBusConnection *connection, DBusMessage *message,
1317 const char *path = dbus_message_get_path(message);
1318 struct modem_data *modem;
1319 DBusMessageIter iter, value;
1322 modem = g_hash_table_lookup(modem_hash, path);
1326 if (dbus_message_iter_init(message, &iter) == FALSE)
1329 dbus_message_iter_get_basic(&iter, &key);
1331 dbus_message_iter_next(&iter);
1332 dbus_message_iter_recurse(&iter, &value);
1334 if (g_str_equal(key, "Attached") == TRUE) {
1335 dbus_message_iter_get_basic(&value, &modem->attached);
1337 DBG("%s Attached %d", modem->path, modem->attached);
1339 if (modem->attached == TRUE) {
1340 if (has_interface(modem->interfaces,
1341 OFONO_API_NETREG) == TRUE) {
1342 netreg_get_properties(modem);
1345 } else if (g_str_equal(key, "Powered") == TRUE) {
1346 dbus_message_iter_get_basic(&value, &modem->cm_powered);
1348 DBG("%s ConnnectionManager Powered %d", modem->path,
1351 if (modem->cm_powered == FALSE)
1352 cm_set_powered(modem);
1358 static void cm_properties_reply(struct modem_data *modem, DBusMessageIter *dict)
1360 DBG("%s", modem->path);
1362 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
1363 DBusMessageIter entry, value;
1366 dbus_message_iter_recurse(dict, &entry);
1367 dbus_message_iter_get_basic(&entry, &key);
1369 dbus_message_iter_next(&entry);
1370 dbus_message_iter_recurse(&entry, &value);
1372 if (g_str_equal(key, "Attached") == TRUE) {
1373 dbus_message_iter_get_basic(&value, &modem->attached);
1375 DBG("%s Attached %d", modem->path,
1378 if (modem->attached == TRUE) {
1379 if (has_interface(modem->interfaces,
1380 OFONO_API_NETREG) == TRUE) {
1381 netreg_get_properties(modem);
1384 } else if (g_str_equal(key, "Powered") == TRUE) {
1385 dbus_message_iter_get_basic(&value, &modem->cm_powered);
1387 DBG("%s ConnnectionManager Powered %d", modem->path,
1390 if (modem->cm_powered == FALSE)
1391 cm_set_powered(modem);
1394 dbus_message_iter_next(dict);
1398 static int cm_get_properties(struct modem_data *modem)
1400 return get_properties(modem->path, OFONO_CM_INTERFACE,
1401 cm_properties_reply, modem);
1404 static void update_sim_imsi(struct modem_data *modem,
1407 DBG("%s imsi %s", modem->path, imsi);
1409 if (g_strcmp0(modem->imsi, imsi) == 0)
1412 g_free(modem->imsi);
1413 modem->imsi = g_strdup(imsi);
1416 static gboolean sim_changed(DBusConnection *connection, DBusMessage *message,
1419 const char *path = dbus_message_get_path(message);
1420 struct modem_data *modem;
1421 DBusMessageIter iter, value;
1424 modem = g_hash_table_lookup(modem_hash, path);
1428 if (dbus_message_iter_init(message, &iter) == FALSE)
1431 dbus_message_iter_get_basic(&iter, &key);
1433 dbus_message_iter_next(&iter);
1434 dbus_message_iter_recurse(&iter, &value);
1436 if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
1439 dbus_message_iter_get_basic(&value, &imsi);
1441 update_sim_imsi(modem, imsi);
1443 if (modem->online == FALSE) {
1444 modem_set_online(modem);
1445 } else if (has_interface(modem->interfaces,
1446 OFONO_API_CM) == TRUE) {
1447 if (ready_to_create_device(modem) == TRUE)
1448 create_device(modem);
1455 static void sim_properties_reply(struct modem_data *modem,
1456 DBusMessageIter *dict)
1458 DBG("%s", modem->path);
1460 while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
1461 DBusMessageIter entry, value;
1464 dbus_message_iter_recurse(dict, &entry);
1465 dbus_message_iter_get_basic(&entry, &key);
1467 dbus_message_iter_next(&entry);
1468 dbus_message_iter_recurse(&entry, &value);
1470 if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
1473 dbus_message_iter_get_basic(&value, &imsi);
1475 update_sim_imsi(modem, imsi);
1477 if (modem->online == FALSE) {
1478 modem_set_online(modem);
1482 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
1483 if (ready_to_create_device(modem) == TRUE)
1484 create_device(modem);
1485 if (modem->device != NULL) {
1486 cm_get_properties(modem);
1487 cm_get_contexts(modem);
1493 dbus_message_iter_next(dict);
1497 static int sim_get_properties(struct modem_data *modem)
1499 return get_properties(modem->path, OFONO_SIM_INTERFACE,
1500 sim_properties_reply, modem);
1503 static gboolean modem_changed(DBusConnection *connection, DBusMessage *message,
1506 const char *path = dbus_message_get_path(message);
1507 struct modem_data *modem;
1508 DBusMessageIter iter, value;
1511 modem = g_hash_table_lookup(modem_hash, path);
1515 if (dbus_message_iter_init(message, &iter) == FALSE)
1518 dbus_message_iter_get_basic(&iter, &key);
1520 dbus_message_iter_next(&iter);
1521 dbus_message_iter_recurse(&iter, &value);
1523 if (g_str_equal(key, "Powered") == TRUE) {
1524 dbus_message_iter_get_basic(&value, &modem->powered);
1526 DBG("%s Powered %d", modem->path, modem->powered);
1528 if (modem->powered == FALSE)
1529 modem_set_powered(modem);
1530 } else if (g_str_equal(key, "Online") == TRUE) {
1531 dbus_message_iter_get_basic(&value, &modem->online);
1533 DBG("%s Online %d", modem->path, modem->online);
1535 if (modem->online == FALSE)
1538 if (has_interface(modem->interfaces, OFONO_API_CM) == FALSE)
1540 if (ready_to_create_device(modem) == TRUE)
1541 create_device(modem);
1542 if (modem->device != NULL) {
1543 cm_get_properties(modem);
1544 cm_get_contexts(modem);
1546 } else if (g_str_equal(key, "Interfaces") == TRUE) {
1547 modem->interfaces = extract_interfaces(&value);
1549 DBG("%s Interfaces 0x%02x", modem->path,
1552 if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE) {
1553 if (modem->imsi == NULL &&
1554 modem->set_powered == FALSE) {
1556 * Only use do GetProperties() when
1557 * device has not been powered up.
1559 sim_get_properties(modem);
1564 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
1565 if (ready_to_create_device(modem) == TRUE)
1566 create_device(modem);
1567 if (modem->device != NULL) {
1568 cm_get_properties(modem);
1569 cm_get_contexts(modem);
1573 if (modem->context != NULL) {
1574 remove_cm_context(modem,
1575 modem->context->path);
1578 if (modem->device != NULL)
1579 destroy_device(modem);
1584 if (has_interface(modem->interfaces, OFONO_API_NETREG) == TRUE) {
1585 if (modem->attached == TRUE)
1586 netreg_get_properties(modem);
1588 } else if (g_str_equal(key, "Serial") == TRUE) {
1591 dbus_message_iter_get_basic(&value, &serial);
1593 g_free(modem->serial);
1594 modem->serial = g_strdup(serial);
1596 DBG("%s Serial %s", modem->path, modem->serial);
1598 if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
1599 if (ready_to_create_device(modem) == TRUE)
1600 create_device(modem);
1601 if (modem->device != NULL) {
1602 cm_get_properties(modem);
1603 cm_get_contexts(modem);
1611 static void add_modem(const char *path, DBusMessageIter *prop)
1613 struct modem_data *modem;
1617 modem = g_hash_table_lookup(modem_hash, path);
1618 if (modem != NULL) {
1620 * When oFono powers up we ask for the modems and oFono is
1621 * reporting with modem_added signal the modems. Only
1627 modem = g_try_new0(struct modem_data, 1);
1631 modem->path = g_strdup(path);
1633 g_hash_table_insert(modem_hash, g_strdup(path), modem);
1635 while (dbus_message_iter_get_arg_type(prop) == DBUS_TYPE_DICT_ENTRY) {
1636 DBusMessageIter entry, value;
1639 dbus_message_iter_recurse(prop, &entry);
1640 dbus_message_iter_get_basic(&entry, &key);
1642 dbus_message_iter_next(&entry);
1643 dbus_message_iter_recurse(&entry, &value);
1645 if (g_str_equal(key, "Powered") == TRUE) {
1646 dbus_message_iter_get_basic(&value, &modem->powered);
1648 DBG("%s Powered %d", modem->path, modem->powered);
1649 } else if (g_str_equal(key, "Online") == TRUE) {
1650 dbus_message_iter_get_basic(&value, &modem->online);
1652 DBG("%s Online %d", modem->path, modem->online);
1653 } else if (g_str_equal(key, "Interfaces") == TRUE) {
1654 modem->interfaces = extract_interfaces(&value);
1656 DBG("%s Interfaces 0x%02x", modem->path,
1658 } else if (g_str_equal(key, "Serial") == TRUE) {
1661 dbus_message_iter_get_basic(&value, &serial);
1662 modem->serial = g_strdup(serial);
1664 DBG("%s Serial %s", modem->path, modem->serial);
1667 dbus_message_iter_next(prop);
1670 if (modem->powered == FALSE) {
1671 modem_set_powered(modem);
1672 } else if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE) {
1673 sim_get_properties(modem);
1674 } else if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
1675 if (ready_to_create_device(modem) == TRUE)
1676 create_device(modem);
1677 if (modem->device != NULL) {
1678 cm_get_properties(modem);
1679 cm_get_contexts(modem);
1684 static void remove_modem(gpointer data)
1686 struct modem_data *modem = data;
1688 DBG("%s", modem->path);
1690 if (modem->call_set_property != NULL)
1691 dbus_pending_call_cancel(modem->call_set_property);
1693 if (modem->call_get_properties != NULL)
1694 dbus_pending_call_cancel(modem->call_get_properties);
1696 if (modem->call_get_contexts != NULL)
1697 dbus_pending_call_cancel(modem->call_get_contexts);
1699 if (modem->device != NULL)
1700 destroy_device(modem);
1702 if (modem->context != NULL)
1703 remove_cm_context(modem, modem->context->path);
1705 g_free(modem->serial);
1706 g_free(modem->name);
1707 g_free(modem->imsi);
1708 g_free(modem->path);
1713 static gboolean modem_added(DBusConnection *connection,
1714 DBusMessage *message, void *user_data)
1716 DBusMessageIter iter, properties;
1721 if (dbus_message_iter_init(message, &iter) == FALSE)
1724 dbus_message_iter_get_basic(&iter, &path);
1726 dbus_message_iter_next(&iter);
1727 dbus_message_iter_recurse(&iter, &properties);
1729 add_modem(path, &properties);
1734 static gboolean modem_removed(DBusConnection *connection,
1735 DBusMessage *message, void *user_data)
1737 DBusMessageIter iter;
1742 if (dbus_message_iter_init(message, &iter) == FALSE)
1745 dbus_message_iter_get_basic(&iter, &path);
1747 g_hash_table_remove(modem_hash, path);
1752 static void manager_get_modems_reply(DBusPendingCall *call, void *user_data)
1756 DBusMessageIter array, dict;
1760 reply = dbus_pending_call_steal_reply(call);
1762 dbus_error_init(&error);
1764 if (dbus_set_error_from_message(&error, reply) == TRUE) {
1765 connman_error("%s", error.message);
1766 dbus_error_free(&error);
1770 if (dbus_message_iter_init(reply, &array) == FALSE)
1773 dbus_message_iter_recurse(&array, &dict);
1775 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
1776 DBusMessageIter value, properties;
1779 dbus_message_iter_recurse(&dict, &value);
1780 dbus_message_iter_get_basic(&value, &path);
1782 dbus_message_iter_next(&value);
1783 dbus_message_iter_recurse(&value, &properties);
1785 add_modem(path, &properties);
1787 dbus_message_iter_next(&dict);
1791 dbus_message_unref(reply);
1793 dbus_pending_call_unref(call);
1796 static int manager_get_modems(void)
1798 DBusMessage *message;
1799 DBusPendingCall *call;
1803 message = dbus_message_new_method_call(OFONO_SERVICE, "/",
1804 OFONO_MANAGER_INTERFACE, GET_MODEMS);
1805 if (message == NULL)
1808 if (dbus_connection_send_with_reply(connection, message,
1809 &call, TIMEOUT) == FALSE) {
1810 connman_error("Failed to call GetModems()");
1811 dbus_message_unref(message);
1816 connman_error("D-Bus connection not available");
1817 dbus_message_unref(message);
1821 dbus_pending_call_set_notify(call, manager_get_modems_reply,
1824 dbus_message_unref(message);
1826 return -EINPROGRESS;
1829 static void ofono_connect(DBusConnection *conn, void *user_data)
1833 modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1834 g_free, remove_modem);
1835 if (modem_hash == NULL)
1838 context_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1840 if (context_hash == NULL) {
1841 g_hash_table_destroy(modem_hash);
1845 manager_get_modems();
1848 static void ofono_disconnect(DBusConnection *conn, void *user_data)
1852 if (modem_hash == NULL || context_hash == NULL)
1855 g_hash_table_destroy(modem_hash);
1858 g_hash_table_destroy(context_hash);
1859 context_hash = NULL;
1862 static int network_probe(struct connman_network *network)
1864 struct modem_data *modem = connman_network_get_data(network);
1866 DBG("%s network %p", modem->path, network);
1871 static void network_remove(struct connman_network *network)
1873 struct modem_data *modem = connman_network_get_data(network);
1875 DBG("%s network %p", modem->path, network);
1878 static int network_connect(struct connman_network *network)
1880 struct modem_data *modem = connman_network_get_data(network);
1882 DBG("%s network %p", modem->path, network);
1884 return context_set_active(modem);
1887 static int network_disconnect(struct connman_network *network)
1889 struct modem_data *modem = connman_network_get_data(network);
1891 DBG("%s network %p", modem->path, network);
1893 return context_set_inactive(modem);
1896 static struct connman_network_driver network_driver = {
1898 .type = CONNMAN_NETWORK_TYPE_CELLULAR,
1899 .probe = network_probe,
1900 .remove = network_remove,
1901 .connect = network_connect,
1902 .disconnect = network_disconnect,
1905 static int modem_probe(struct connman_device *device)
1907 struct modem_data *modem = connman_device_get_data(device);
1909 DBG("%s device %p", modem->path, device);
1914 static void modem_remove(struct connman_device *device)
1916 struct modem_data *modem = connman_device_get_data(device);
1918 DBG("%s device %p", modem->path, device);
1921 static int modem_enable(struct connman_device *device)
1923 struct modem_data *modem = connman_device_get_data(device);
1925 DBG("%s device %p", modem->path, device);
1930 static int modem_disable(struct connman_device *device)
1932 struct modem_data *modem = connman_device_get_data(device);
1934 DBG("%s device %p", modem->path, device);
1939 static struct connman_device_driver modem_driver = {
1941 .type = CONNMAN_DEVICE_TYPE_CELLULAR,
1942 .probe = modem_probe,
1943 .remove = modem_remove,
1944 .enable = modem_enable,
1945 .disable = modem_disable,
1949 static guint modem_added_watch;
1950 static guint modem_removed_watch;
1951 static guint modem_watch;
1952 static guint cm_watch;
1953 static guint sim_watch;
1954 static guint context_added_watch;
1955 static guint context_removed_watch;
1956 static guint netreg_watch;
1957 static guint context_watch;
1959 static int ofono_init(void)
1965 connection = connman_dbus_get_connection();
1966 if (connection == NULL)
1969 watch = g_dbus_add_service_watch(connection,
1970 OFONO_SERVICE, ofono_connect,
1971 ofono_disconnect, NULL, NULL);
1973 modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1974 OFONO_MANAGER_INTERFACE,
1979 modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1980 OFONO_MANAGER_INTERFACE,
1985 modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1986 OFONO_MODEM_INTERFACE,
1991 cm_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1997 sim_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1998 OFONO_SIM_INTERFACE,
2003 context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
2009 context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
2015 context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
2016 OFONO_CONTEXT_INTERFACE,
2021 netreg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
2022 OFONO_NETREG_INTERFACE,
2028 if (watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0 ||
2029 modem_watch == 0 || cm_watch == 0 || sim_watch == 0 ||
2030 context_added_watch == 0 ||
2031 context_removed_watch == 0 ||
2032 context_watch == 0 || netreg_watch == 0) {
2037 err = connman_network_driver_register(&network_driver);
2041 err = connman_device_driver_register(&modem_driver);
2043 connman_network_driver_unregister(&network_driver);
2050 g_dbus_remove_watch(connection, netreg_watch);
2051 g_dbus_remove_watch(connection, context_watch);
2052 g_dbus_remove_watch(connection, context_removed_watch);
2053 g_dbus_remove_watch(connection, context_added_watch);
2054 g_dbus_remove_watch(connection, sim_watch);
2055 g_dbus_remove_watch(connection, cm_watch);
2056 g_dbus_remove_watch(connection, modem_watch);
2057 g_dbus_remove_watch(connection, modem_removed_watch);
2058 g_dbus_remove_watch(connection, modem_added_watch);
2059 g_dbus_remove_watch(connection, watch);
2060 dbus_connection_unref(connection);
2065 static void ofono_exit(void)
2069 if (modem_hash != NULL) {
2070 g_hash_table_destroy(modem_hash);
2074 if (context_hash != NULL) {
2075 g_hash_table_destroy(context_hash);
2076 context_hash = NULL;
2079 connman_device_driver_unregister(&modem_driver);
2080 connman_network_driver_unregister(&network_driver);
2082 g_dbus_remove_watch(connection, netreg_watch);
2083 g_dbus_remove_watch(connection, context_watch);
2084 g_dbus_remove_watch(connection, context_removed_watch);
2085 g_dbus_remove_watch(connection, context_added_watch);
2086 g_dbus_remove_watch(connection, sim_watch);
2087 g_dbus_remove_watch(connection, cm_watch);
2088 g_dbus_remove_watch(connection, modem_watch);
2089 g_dbus_remove_watch(connection, modem_added_watch);
2090 g_dbus_remove_watch(connection, modem_removed_watch);
2091 g_dbus_remove_watch(connection, watch);
2093 dbus_connection_unref(connection);
2096 CONNMAN_PLUGIN_DEFINE(ofono, "oFono telephony plugin", VERSION,
2097 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ofono_init, ofono_exit)