5 * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #define CONNMAN_API_SUBJECT_TO_CHANGE
32 #include <connman/dbus.h>
33 #include <connman/inet.h>
34 #include <connman/plugin.h>
35 #include <connman/network.h>
36 #include <connman/setting.h>
37 #include <connman/technology.h>
41 #define PS_DBUS_SERVICE "com.tcore.ps"
42 #define TELEPHONY_DBUS_SERVICE "org.tizen.telephony"
44 #define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master"
45 #define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem"
46 #define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service"
47 #define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context"
50 #define GET_MODEMS "GetModems"
51 #define GET_SERVICES "GetServices"
52 #define GET_CONTEXTS "GetContexts"
53 #define ACTIVATE_CONTEXT "Activate"
54 #define DEACTIVATE_CONTEXT "Deactivate"
55 #define GET_PROPERTIES "GetProperties"
56 #define SET_PROPERTY "SetProperties"
59 #define MODEM_ADDED "ModemAdded"
60 #define MODEM_REMOVED "ModemRemoved"
61 #define SERVICE_ADDED "ServiceAdded"
62 #define SERVICE_REMOVED "ServiceRemoved"
63 #define CONTEXT_ADDED "ContextAdded"
64 #define CONTEXT_REMOVED "ContextRemoved"
65 #define PROPERTY_CHANGED "PropertyChanged"
67 #define TIMEOUT 130000
69 #define STRING2BOOL(a) (!(g_strcmp0(a, "TRUE")) ? (TRUE):(FALSE))
71 static DBusConnection *connection;
72 static GHashTable *modem_hash;
73 static GHashTable *service_hash;
74 static GHashTable *network_hash;
76 struct telephony_service {
81 gboolean roaming; /* global roaming state */
82 gboolean ps_attached; /* packet service is available */
85 struct telephony_modem {
92 gboolean data_allowed;
93 gboolean roaming_allowed;
95 struct connman_device *device;
96 struct telephony_service *s_service;
99 struct telephony_network {
102 gboolean routing_only;
103 gboolean ipv6_link_only;
105 struct connman_network *network;
107 enum connman_ipconfig_method ipv4_method;
108 struct connman_ipaddress *ipv4_address;
110 enum connman_ipconfig_method ipv6_method;
111 struct connman_ipaddress *ipv6_address;
114 static int telephony_default_subscription_id = 0;
116 /* function prototype */
117 static void telephony_connect(DBusConnection *connection, void *user_data);
118 static void telephony_disconnect(DBusConnection *connection, void *user_data);
119 static void __remove_modem(gpointer data);
120 static void __remove_service(gpointer data);
121 static void __remove_network(gpointer data);
123 static int __modem_probe(struct connman_device *device);
124 static void __modem_remove(struct connman_device *device);
125 static int __modem_enable(struct connman_device *device);
126 static int __modem_disable(struct connman_device *device);
128 static int __network_probe(struct connman_network *network);
129 static void __network_remove(struct connman_network *network);
130 static int __network_connect(struct connman_network *network);
131 static int __network_disconnect(struct connman_network *network);
134 /* dbus request and reply */
135 static int __dbus_request(const char *service, const char *path, const char *interface,
137 DBusPendingCallNotifyFunction notify, void *user_data,
138 DBusFreeFunction free_function, int type, ...);
140 static int __request_get_modems(void);
141 static void __response_get_modems(DBusPendingCall *call, void *user_data);
142 static int __request_get_services(const char *path);
143 static void __response_get_services(DBusPendingCall *call, void *user_data);
144 static int __request_get_contexts(struct telephony_modem *modem);
145 static void __response_get_contexts(DBusPendingCall *call, void *user_data);
146 static int __request_network_activate(struct connman_network *network);
147 static void __response_network_activate(DBusPendingCall *call, void *user_data);
148 static int __request_network_deactivate(struct connman_network *network);
150 /* telephony internal function */
151 static void __add_modem(const char *path, DBusMessageIter *prop);
152 static void __add_service(struct telephony_modem *modem,
153 const char *service_path, DBusMessageIter *prop);
154 static void __add_connman_device(const char *modem_path, const char *operator);
155 static void __remove_connman_device(struct telephony_modem *modem);
156 static void __remove_connman_networks(struct connman_device *device);
157 static int __add_context(struct connman_device *device, const char *path,
158 DBusMessageIter *prop);
161 static gboolean __changed_modem(DBusConnection *connection,
162 DBusMessage *message, void *user_data);
163 static gboolean __added_modem(DBusConnection *connection,
164 DBusMessage *message, void *user_data);
165 static gboolean __removed_modem(DBusConnection *connection,
166 DBusMessage *message, void *user_data);
167 static gboolean __changed_service(DBusConnection *connection,
168 DBusMessage *message, void *user_data);
169 static gboolean __added_service(DBusConnection *connection,
170 DBusMessage *message, void *user_data);
171 static gboolean __removed_service(DBusConnection *connection,
172 DBusMessage *message, void *user_data);
173 static gboolean __changed_context(DBusConnection *connection,
174 DBusMessage *message, void *user_data);
175 static gboolean __added_context(DBusConnection *connection,
176 DBusMessage *message, void *user_data);
177 static gboolean __removed_context(DBusConnection *connection,
178 DBusMessage *message, void *user_data);
181 static struct connman_device_driver modem_driver = {
183 .type = CONNMAN_DEVICE_TYPE_CELLULAR,
184 .probe = __modem_probe,
185 .remove = __modem_remove,
186 .enable = __modem_enable,
187 .disable = __modem_disable,
191 static struct connman_network_driver network_driver = {
193 .type = CONNMAN_NETWORK_TYPE_CELLULAR,
194 .probe = __network_probe,
195 .remove = __network_remove,
196 .connect = __network_connect,
197 .disconnect = __network_disconnect,
200 static int tech_probe(struct connman_technology *technology)
205 static void tech_remove(struct connman_technology *technology)
210 static struct connman_technology_driver tech_driver = {
212 .type = CONNMAN_SERVICE_TYPE_CELLULAR,
214 .remove = tech_remove,
218 static void telephony_connect(DBusConnection *connection, void *user_data)
220 DBG("connection %p", connection);
221 modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
222 g_free, __remove_modem);
223 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
224 g_free, __remove_service);
225 network_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
226 g_free, __remove_network);
228 __request_get_modems();
231 static void telephony_disconnect(DBusConnection *connection, void *user_data)
233 DBG("connection %p", connection);
235 if (modem_hash != NULL) {
236 g_hash_table_destroy(modem_hash);
240 if (network_hash != NULL) {
241 g_hash_table_destroy(network_hash);
246 static void __remove_modem(gpointer data)
248 struct telephony_modem *modem = data;
250 __remove_connman_device(modem);
253 g_free(modem->operator);
257 static void __remove_service(gpointer data)
259 struct telephony_service *service = data;
261 g_free(service->path);
262 g_free(service->act);
266 static void __remove_network(gpointer data)
268 struct telephony_network *info = data;
269 struct connman_device *device;
271 device = connman_network_get_device(info->network);
273 connman_device_remove_network(device, info->network);
275 connman_network_unref(info->network);
279 connman_ipaddress_free(info->ipv4_address);
280 connman_ipaddress_free(info->ipv6_address);
285 static void __set_device_powered(struct telephony_modem *modem,
288 DBG("set modem(%s) powered(%d)", modem->path, powered);
291 connman_device_set_powered(modem->device, powered);
294 static int __check_device_powered(const char *path, gboolean powered)
296 struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path);
301 DBG("check modem (%s) powered (%d)", modem->path, modem->powered);
303 if (modem->powered == powered)
309 static int __modem_probe(struct connman_device *device)
311 DBG("device %p", device);
315 static void __modem_remove(struct connman_device *device)
317 DBG("device %p", device);
320 static int __modem_enable(struct connman_device *device)
322 const char *path = connman_device_get_string(device, "Path");
323 DBG("device %p, path, %s", device, path);
325 return __check_device_powered(path, TRUE);
328 static int __modem_disable(struct connman_device *device)
330 const char *path = connman_device_get_string(device, "Path");
331 DBG("device %p, path, %s", device, path);
333 return __check_device_powered(path, FALSE);
336 static int __network_probe(struct connman_network *network)
338 DBG("network_prove network(%p)", network);
342 static int __network_connect(struct connman_network *network)
344 DBG("network %p", network);
346 return __request_network_activate(network);
349 static int __network_disconnect(struct connman_network *network)
351 DBG("network %p", network);
353 if (connman_network_get_associating(network) == TRUE)
354 connman_network_clear_associating(network);
356 connman_network_set_associating(network, FALSE);
358 return __request_network_deactivate(network);
361 static void __network_remove(struct connman_network *network)
363 char const *path = connman_network_get_string(network, "Path");
364 DBG("network %p path %s", network, path);
366 g_hash_table_remove(network_hash, path);
369 static int __dbus_request(const char *service, const char *path, const char *interface,
371 DBusPendingCallNotifyFunction notify, void *user_data,
372 DBusFreeFunction free_function, int type, ...)
374 DBusMessage *message;
375 DBusPendingCall *call;
379 DBG("path %s %s.%s", path, interface, method);
384 message = dbus_message_new_method_call(service, path, interface, method);
388 dbus_message_set_auto_start(message, FALSE);
391 ok = dbus_message_append_args_valist(message, type, va);
395 dbus_message_unref(message);
399 if (dbus_connection_send_with_reply(connection, message,
400 &call, TIMEOUT) == FALSE) {
401 connman_error("Failed to call %s.%s", interface, method);
402 dbus_message_unref(message);
407 connman_error("D-Bus connection not available");
408 dbus_message_unref(message);
412 dbus_pending_call_set_notify(call, notify, user_data, free_function);
414 dbus_message_unref(message);
419 static int __request_get_modems(void)
421 DBG("request get modem");
422 /* call connect master */
423 return __dbus_request(PS_DBUS_SERVICE, "/", PS_MASTER_INTERFACE, GET_MODEMS,
424 __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
427 static void __response_get_modems(DBusPendingCall *call, void *user_data)
431 DBusMessageIter args, dict;
435 reply = dbus_pending_call_steal_reply(call);
437 dbus_error_init(&error);
439 if (dbus_set_error_from_message(&error, reply)) {
440 connman_error("GetModems() %s %s", error.name, error.message);
441 dbus_error_free(&error);
445 DBG("message signature (%s)", dbus_message_get_signature(reply));
447 if (dbus_message_iter_init(reply, &args) == FALSE)
450 dbus_message_iter_recurse(&args, &dict);
452 /* DBG("message type (%d) dic(%d)",
453 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
456 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
457 DBusMessageIter entry, property;
458 const char *modem_path;
460 dbus_message_iter_recurse(&dict, &entry);
461 dbus_message_iter_get_basic(&entry, &modem_path);
462 DBG("modem path (%s)", modem_path);
464 dbus_message_iter_next(&entry);
465 dbus_message_iter_recurse(&entry, &property);
467 __add_modem(modem_path, &property);
469 dbus_message_iter_next(&dict);
473 dbus_message_unref(reply);
474 dbus_pending_call_unref(call);
477 static int __request_get_services(const char *path)
479 DBG("request get service");
480 return __dbus_request(PS_DBUS_SERVICE, path, PS_MODEM_INTERFACE, GET_SERVICES,
481 __response_get_services, g_strdup(path),
482 g_free, DBUS_TYPE_INVALID);
485 static void __response_get_services(DBusPendingCall *call, void *user_data)
489 DBusMessageIter args, dict;
491 const char *path = user_data;
492 struct telephony_modem *modem;
494 modem = g_hash_table_lookup(modem_hash, path);
498 reply = dbus_pending_call_steal_reply(call);
500 dbus_error_init(&error);
502 if (dbus_set_error_from_message(&error, reply)) {
503 connman_error("GetServices() %s %s", error.name, error.message);
504 dbus_error_free(&error);
508 if (modem == NULL || modem->device == NULL)
511 DBG("message signature (%s)", dbus_message_get_signature(reply));
513 if (dbus_message_iter_init(reply, &args) == FALSE)
516 dbus_message_iter_recurse(&args, &dict);
518 /* DBG("message type (%d) dic(%d)",
519 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
522 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
523 DBusMessageIter entry, property;
524 const char *service_path;
526 dbus_message_iter_recurse(&dict, &entry);
527 dbus_message_iter_get_basic(&entry, &service_path);
528 DBG("service path (%s)", service_path);
530 dbus_message_iter_next(&entry);
531 dbus_message_iter_recurse(&entry, &property);
533 __add_service(modem, service_path, &property);
535 dbus_message_iter_next(&dict);
539 dbus_message_unref(reply);
540 dbus_pending_call_unref(call);
543 static int __request_get_contexts(struct telephony_modem *modem)
545 DBG("request get contexts");
546 return __dbus_request(PS_DBUS_SERVICE, modem->s_service->path,
547 PS_SERVICE_INTERFACE, GET_CONTEXTS,
548 __response_get_contexts, g_strdup(modem->path),
549 g_free, DBUS_TYPE_INVALID);
552 static void __response_get_contexts(DBusPendingCall *call, void *user_data)
556 DBusMessageIter args, dict;
558 const char *path = user_data;
559 struct telephony_modem *modem;
563 modem = g_hash_table_lookup(modem_hash, path);
566 if (modem->s_service == NULL)
568 if (modem->device == NULL)
571 reply = dbus_pending_call_steal_reply(call);
573 dbus_error_init(&error);
575 if (dbus_set_error_from_message(&error, reply)) {
576 connman_error("GetContexts() %s %s", error.name, error.message);
577 dbus_error_free(&error);
581 DBG("message signature (%s)", dbus_message_get_signature(reply));
583 if (dbus_message_iter_init(reply, &args) == FALSE)
586 dbus_message_iter_recurse(&args, &dict);
588 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
589 DBusMessageIter entry, property;
590 const char *context_path;
592 dbus_message_iter_recurse(&dict, &entry);
593 dbus_message_iter_get_basic(&entry, &context_path);
594 DBG("context path (%s)", context_path);
596 dbus_message_iter_next(&entry);
597 dbus_message_iter_recurse(&entry, &property);
599 __add_context(modem->device, context_path, &property);
601 dbus_message_iter_next(&dict);
605 dbus_message_unref(reply);
606 dbus_pending_call_unref(call);
609 static int __request_network_activate(struct connman_network *network)
612 const char *path = NULL;
613 struct telephony_modem *modem = NULL;
615 n_modems = g_hash_table_size(modem_hash);
616 path = connman_network_get_string(network, "Path");
617 modem = connman_device_get_data(connman_network_get_device(network));
618 DBG("network %p, path %s, modem %s[%d]", network, path, modem->path,
619 telephony_default_subscription_id);
621 if (modem && n_modems > 1 && g_str_has_suffix(path, "_1") == TRUE) {
622 char *subscribe_id = g_strdup_printf("%d", telephony_default_subscription_id);
624 if (g_str_has_suffix(modem->path, subscribe_id) != TRUE) {
625 g_free(subscribe_id);
628 g_free(subscribe_id);
631 return __dbus_request(PS_DBUS_SERVICE, path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT,
632 __response_network_activate,
633 g_strdup(path), NULL, DBUS_TYPE_INVALID);
636 static gboolean __check_network_available(struct connman_network *network)
638 if (network == NULL || connman_network_get_device(network) == NULL)
644 static void __response_network_activate(DBusPendingCall *call, void *user_data)
646 DBG("network activation response");
651 struct telephony_network *info;
652 const char *path = user_data;
654 info = g_hash_table_lookup(network_hash, path);
655 reply = dbus_pending_call_steal_reply(call);
660 if (__check_network_available(info->network) == FALSE) {
661 g_hash_table_remove(network_hash, path);
665 dbus_error_init(&error);
666 if (dbus_set_error_from_message(&error, reply)) {
667 connman_error("connection activate() %s %s",
668 error.name, error.message);
670 if (connman_network_get_associating(info->network) == TRUE)
671 connman_network_set_error(info->network,
672 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
674 if (connman_network_get_connecting(info->network) == TRUE)
675 connman_network_set_error(info->network,
676 CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
678 if (connman_network_get_index(info->network) < 0)
679 connman_network_set_error(info->network,
680 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
682 dbus_error_free(&error);
687 dbus_message_unref(reply);
688 dbus_pending_call_unref(call);
691 static int __request_network_deactivate(struct connman_network *network)
693 const char *path = connman_network_get_string(network, "Path");
694 DBG("network %p, path %s", network, path);
696 return __dbus_request(PS_DBUS_SERVICE, path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT,
697 NULL, NULL, NULL, DBUS_TYPE_INVALID);
700 static void __response_get_default_subscription_id(DBusPendingCall *call,
705 DBusMessageIter args;
709 reply = dbus_pending_call_steal_reply(call);
711 dbus_error_init(&error);
712 if (dbus_set_error_from_message(&error, reply)) {
713 connman_error("GetDefaultDataSubscription() %s %s", error.name, error.message);
714 dbus_error_free(&error);
718 DBG("message signature (%s)", dbus_message_get_signature(reply));
720 if (dbus_message_iter_init(reply, &args) == FALSE)
723 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
724 DBG("default subscription: %d", telephony_default_subscription_id);
727 dbus_message_unref(reply);
728 dbus_pending_call_unref(call);
731 static int __request_get_default_subscription_id(const char *path)
734 char *telephony_modem_path = NULL;
736 telephony_modem_path = g_strdup_printf("/org/tizen/telephony%s", path);
737 DBG("request get default subscription id %s", telephony_modem_path);
739 ret = __dbus_request(TELEPHONY_DBUS_SERVICE, telephony_modem_path,
740 "org.tizen.telephony.Network", "GetDefaultDataSubscription",
741 __response_get_default_subscription_id, NULL, NULL, DBUS_TYPE_INVALID);
743 g_free(telephony_modem_path);
747 static void __add_modem(const char *path, DBusMessageIter *prop)
749 struct telephony_modem *modem;
751 modem = g_hash_table_lookup(modem_hash, path);
755 modem = g_try_new0(struct telephony_modem, 1);
759 modem->path = g_strdup(path);
760 modem->device = NULL;
761 modem->s_service = NULL;
763 g_hash_table_insert(modem_hash, g_strdup(path), modem);
765 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
766 DBusMessageIter entry;
767 const char *key, *tmp;
769 dbus_message_iter_recurse(prop, &entry);
770 dbus_message_iter_get_basic(&entry, &key);
772 dbus_message_iter_next(&entry);
773 dbus_message_iter_get_basic(&entry, &tmp);
775 DBG("key (%s) value(%s)", key, tmp);
777 if (g_strcmp0(key, "powered") == 0) {
778 modem->powered = STRING2BOOL(tmp);
779 } else if (g_strcmp0(key, "operator") == 0) {
780 modem->operator = g_strdup(tmp);
781 } else if (g_strcmp0(key, "sim_init") == 0) {
782 modem->sim_init = STRING2BOOL(tmp);
783 } else if (g_strcmp0(key, "flight_mode") == 0) {
784 modem->flight_mode = STRING2BOOL(tmp);
785 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
786 modem->roaming_allowed = STRING2BOOL(tmp);
787 } else if (g_strcmp0(key, "data_allowed") == 0) {
788 modem->data_allowed = STRING2BOOL(tmp);
790 dbus_message_iter_next(prop);
793 __add_connman_device(path, modem->operator);
794 __set_device_powered(modem, modem->powered);
796 if (g_hash_table_size(modem_hash) > 1)
797 __request_get_default_subscription_id(modem->path);
799 if (modem->powered != TRUE) {
800 DBG("modem is not powered");
804 __request_get_services(modem->path);
807 static void __add_service(struct telephony_modem *modem,
808 const char *service_path, DBusMessageIter *prop)
810 struct telephony_service *service;
812 if (modem->s_service != NULL)
815 service = g_try_new0(struct telephony_service, 1);
819 service->path = g_strdup(service_path);
820 service->p_modem = modem;
821 g_hash_table_insert(service_hash, g_strdup(service_path), service);
823 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
824 DBusMessageIter entry;
825 const char *key, *tmp;
827 dbus_message_iter_recurse(prop, &entry);
828 dbus_message_iter_get_basic(&entry, &key);
830 dbus_message_iter_next(&entry);
831 dbus_message_iter_get_basic(&entry, &tmp);
833 DBG("key (%s) value(%s)", key, tmp);
835 if (g_strcmp0(key, "roaming") == 0) {
836 service->roaming = STRING2BOOL(tmp);
837 } else if (g_strcmp0(key, "act") == 0) {
838 service->act = g_strdup(tmp);
839 } else if (g_strcmp0(key, "ps_attached") == 0) {
840 service->ps_attached = STRING2BOOL(tmp);
843 dbus_message_iter_next(prop);
846 modem->s_service = service;
847 __request_get_contexts(modem);
850 static char *__get_ident(const char *path)
857 pos = strrchr(path, '/');
864 static void __add_connman_device(const char *modem_path, const char *operator)
867 struct telephony_modem *modem;
868 struct connman_device *device;
870 DBG("path %s operator %s", modem_path, operator);
872 if (modem_path == NULL)
875 if (operator == NULL)
878 modem = g_hash_table_lookup(modem_hash, modem_path);
883 if (!g_strcmp0(operator,
884 connman_device_get_ident(modem->device)))
887 __remove_connman_device(modem);
890 if (strlen(operator) == 0)
893 device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
897 ident = g_strdup_printf("%s_%s", __get_ident(modem_path), operator);
898 connman_device_set_ident(device, ident);
901 connman_device_set_string(device, "Path", modem_path);
902 connman_device_set_data(device, modem);
904 if (connman_device_register(device) < 0) {
905 connman_error("Failed to register cellular device");
906 connman_device_unref(device);
910 modem->device = device;
913 static void __remove_connman_device(struct telephony_modem *modem)
915 DBG("modem %p path %s device %p", modem, modem->path, modem->device);
917 if (modem->device == NULL)
920 __remove_connman_networks(modem->device);
922 connman_device_unregister(modem->device);
923 connman_device_unref(modem->device);
925 modem->device = NULL;
928 static void __remove_connman_networks(struct connman_device *device)
932 GSList *info_list = NULL;
935 if (network_hash == NULL)
938 g_hash_table_iter_init(&iter, network_hash);
940 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
941 struct telephony_network *info = value;
943 if (connman_network_get_device(info->network) != device)
946 info_list = g_slist_append(info_list, info);
949 for (list = info_list; list != NULL; list = list->next) {
950 struct telephony_network *info = list->data;
951 connman_device_remove_network(device, info->network);
954 g_slist_free(info_list);
957 static gboolean connman_ipaddress_updated(struct connman_ipaddress *ipaddress,
958 const char *address, const char *gateway)
960 if (ipaddress == NULL || address == NULL)
963 if (g_strcmp0(ipaddress->local, address) != 0)
966 if (g_strcmp0(ipaddress->gateway, gateway) != 0)
972 static void __set_network_connected(struct telephony_network *network,
975 gboolean setip = FALSE;
977 DBG("network %p connected %d", network, connected);
979 connman_network_set_index(network->network, network->if_index);
980 if (connman_network_get_connected(network->network) == connected)
983 switch (network->ipv4_method) {
984 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
985 case CONNMAN_IPCONFIG_METHOD_DHCP:
986 case CONNMAN_IPCONFIG_METHOD_AUTO:
987 case CONNMAN_IPCONFIG_METHOD_OFF:
988 connman_network_set_ipv4_method(network->network,
989 network->ipv4_method);
991 case CONNMAN_IPCONFIG_METHOD_MANUAL:
992 case CONNMAN_IPCONFIG_METHOD_FIXED:
993 connman_network_set_ipv4_method(network->network,
994 network->ipv4_method);
995 connman_network_set_ipaddress(network->network,
996 network->ipv4_address);
1001 switch (network->ipv6_method) {
1002 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1003 case CONNMAN_IPCONFIG_METHOD_OFF:
1004 case CONNMAN_IPCONFIG_METHOD_DHCP:
1006 case CONNMAN_IPCONFIG_METHOD_AUTO:
1007 connman_network_set_ipv6_method(network->network,
1008 network->ipv6_method);
1011 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1012 case CONNMAN_IPCONFIG_METHOD_FIXED:
1013 connman_network_set_ipv6_method(network->network,
1014 network->ipv6_method);
1015 connman_network_set_ipaddress(network->network,
1016 network->ipv6_address);
1022 connman_network_set_connected(network->network, connected);
1025 static gboolean __set_network_context(
1026 struct telephony_network *network,
1027 DBusMessageIter *dict)
1030 gboolean active = FALSE;
1031 gboolean routing_only = FALSE;
1032 gboolean ipv4_updated = FALSE;
1033 gboolean ipv6_updated = FALSE;
1034 gboolean ipv6_link_only = FALSE;
1035 gboolean default_internet = FALSE;
1036 gboolean active_proxy = FALSE;
1037 char **proxies = NULL;
1038 const char *dev_name = NULL;
1039 const char *proxy_addr = NULL;
1040 char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL,
1041 *ipv4_dns1 = NULL, *ipv4_dns2 = NULL;
1042 char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL,
1043 *ipv6_dns1 = NULL, *ipv6_dns2 = NULL;
1044 struct connman_service *service;
1046 while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
1047 DBusMessageIter entry;
1048 const char *key, *value;
1050 dbus_message_iter_recurse(dict, &entry);
1051 dbus_message_iter_get_basic(&entry, &key);
1053 dbus_message_iter_next(&entry);
1055 if (g_strcmp0(key, "dev_name") == 0) {
1056 dbus_message_iter_get_basic(&entry, &dev_name);
1057 DBG("dev_name (%s)", dev_name);
1058 } else if (g_strcmp0(key, "proxy") == 0) {
1059 dbus_message_iter_get_basic(&entry, &proxy_addr);
1060 DBG("proxy_addr (%s)", proxy_addr);
1061 } else if (g_strcmp0(key, "ipv4_address") == 0) {
1062 dbus_message_iter_get_basic(&entry, &ipv4_addr);
1063 DBG("ipv4_addr (%s)", ipv4_addr);
1064 } else if (g_strcmp0(key, "ipv4_gateway") == 0) {
1065 dbus_message_iter_get_basic(&entry, &ipv4_gw);
1066 DBG("ipv4_gw (%s)", ipv4_gw);
1067 } else if (g_strcmp0(key, "ipv4_netmask") == 0) {
1068 dbus_message_iter_get_basic(&entry, &ipv4_netmask);
1069 DBG("ipv4_netmask (%s)", ipv4_netmask);
1070 } else if (g_strcmp0(key, "ipv4_dns1") == 0) {
1071 dbus_message_iter_get_basic(&entry, &ipv4_dns1);
1072 DBG("ipv4_dns1 (%s)", ipv4_dns1);
1073 } else if (g_strcmp0(key, "ipv4_dns2") == 0) {
1074 dbus_message_iter_get_basic(&entry, &ipv4_dns2);
1075 DBG("ipv4_dns2 (%s)", ipv4_dns2);
1076 } else if (g_strcmp0(key, "ipv6_address") == 0) {
1077 dbus_message_iter_get_basic(&entry, &ipv6_addr);
1078 DBG("ipv6 address (%s)", ipv6_addr);
1079 } else if (g_strcmp0(key, "ipv6_gateway") == 0) {
1080 dbus_message_iter_get_basic(&entry, &ipv6_gw);
1081 DBG("ipv6_gw (%s)", ipv6_gw);
1082 } else if (g_strcmp0(key, "ipv6_netmask") == 0) {
1083 dbus_message_iter_get_basic(&entry, &ipv6_netmask);
1084 DBG("ipv6_netmask (%s)", ipv6_netmask);
1085 } else if (g_strcmp0(key, "ipv6_dns1") == 0) {
1086 dbus_message_iter_get_basic(&entry, &ipv6_dns1);
1087 DBG("ipv6_dns1 (%s)", ipv6_dns1);
1088 } else if (g_strcmp0(key, "ipv6_dns2") == 0) {
1089 dbus_message_iter_get_basic(&entry, &ipv6_dns2);
1090 DBG("ipv6_dns2 (%s)", ipv6_dns2);
1091 } else if (g_strcmp0(key, "active") == 0) {
1092 dbus_message_iter_get_basic(&entry, &value);
1093 DBG("active (%s)", value);
1094 active = STRING2BOOL(value);
1095 } else if (g_strcmp0(key, "routing_only") == 0) {
1096 dbus_message_iter_get_basic(&entry, &value);
1097 DBG("routing_only (%s)", value);
1098 routing_only = STRING2BOOL(value);
1099 network->routing_only = routing_only;
1100 } else if (g_strcmp0(key, "ipv6_link_only") == 0) {
1101 dbus_message_iter_get_basic(&entry, &value);
1102 DBG("ipv6_link_only (%s)", value);
1103 ipv6_link_only = STRING2BOOL(value);
1104 network->ipv6_link_only = ipv6_link_only;
1106 else if (g_strcmp0(key, "default_internet_conn") == 0) {
1107 dbus_message_iter_get_basic(&entry, &value);
1108 DBG("default_internet (%s)", value);
1109 default_internet = STRING2BOOL(value);
1112 dbus_message_iter_next(dict);
1116 //context active does not effect the connman service status.
1117 //it only for setting the routing path.
1118 DBG("routing_only(%d), active(%d)", routing_only, active);
1122 if (g_strcmp0(proxy_addr, ":") == 0)
1124 if (g_strcmp0(ipv4_addr, "0.0.0.0") == 0)
1126 if (g_strcmp0(ipv4_gw, "0.0.0.0") == 0)
1128 if (g_strcmp0(ipv4_netmask, "0.0.0.0") == 0)
1129 ipv4_netmask = NULL;
1130 if (g_strcmp0(ipv4_dns1, "0.0.0.0") == 0)
1132 if (g_strcmp0(ipv4_dns2, "0.0.0.0") == 0)
1134 if (g_strcmp0(ipv6_addr, "::") == 0)
1136 if (g_strcmp0(ipv6_gw, "::") == 0)
1138 if (g_strcmp0(ipv6_netmask, "::") == 0)
1139 ipv6_netmask = NULL;
1140 if (g_strcmp0(ipv6_dns1, "::") == 0)
1142 if (g_strcmp0(ipv6_dns2, "::") == 0)
1145 connman_network_set_bool(network->network, "DefaultInternet",
1146 (bool)default_internet);
1148 service = connman_service_lookup_from_network(network->network);
1149 if (service == NULL)
1152 if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
1153 /* Wi-Fi technology is always a top priority */
1154 if (active == TRUE &&
1155 connman_service_is_no_ref_user_pdn_connection(service) == TRUE &&
1156 connman_service_get_type(connman_service_get_default_connection())
1157 == CONNMAN_SERVICE_TYPE_WIFI) {
1158 __request_network_deactivate(network->network);
1164 /* interface index set */
1165 if (dev_name != NULL) {
1166 index = connman_inet_ifindex(dev_name);
1167 network->if_index = index;
1168 DBG("interface index %d", index);
1172 if (active == TRUE &&
1173 connman_network_get_connected(network->network) == TRUE)
1174 active_proxy = TRUE;
1176 proxies = connman_service_get_proxy_servers(service);
1177 if (proxies != NULL) {
1178 if (proxy_addr == NULL)
1179 connman_service_set_proxy(service, proxy_addr, active_proxy);
1180 else if (g_strcmp0(proxy_addr, proxies[0]) != 0)
1181 connman_service_set_proxy(service, proxy_addr, active_proxy);
1182 } else if (proxy_addr != NULL)
1183 connman_service_set_proxy(service, proxy_addr, active_proxy);
1185 if (proxies != NULL)
1186 g_strfreev(proxies);
1188 __connman_service_nameserver_clear(service);
1191 if (network->ipv4_address == NULL)
1192 network->ipv4_address =
1193 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
1195 if (network->ipv4_address == NULL)
1198 if (ipv4_addr == NULL && active == TRUE)
1199 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
1201 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1203 connman_network_set_ipv4_method(network->network, network->ipv4_method);
1205 ipv4_updated = connman_ipaddress_updated(network->ipv4_address,
1206 ipv4_addr, ipv4_gw);
1207 if (ipv4_updated == TRUE)
1208 connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr,
1209 ipv4_netmask, ipv4_gw);
1212 #if defined TIZEN_EXT
1213 __connman_service_nameserver_append(service, ipv4_dns1, FALSE,
1214 CONNMAN_IPCONFIG_TYPE_IPV4);
1216 __connman_service_nameserver_append(service, ipv4_dns1, FALSE);
1219 if (ipv4_dns2 && !ipv4_dns1)
1220 #if defined TIZEN_EXT
1221 __connman_service_nameserver_append(service, ipv4_dns2, FALSE,
1222 CONNMAN_IPCONFIG_TYPE_IPV4);
1224 __connman_service_nameserver_append(service, ipv4_dns2, FALSE);
1227 if (network->ipv6_address == NULL)
1228 network->ipv6_address =
1229 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
1231 if (network->ipv6_address == NULL)
1235 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO;
1237 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1239 if (ipv6_addr == NULL)
1240 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
1242 connman_network_set_ipv6_method(network->network, network->ipv6_method);
1244 ipv6_updated = connman_ipaddress_updated(network->ipv6_address,
1245 ipv6_addr, ipv6_gw);
1246 if (ipv6_updated == TRUE)
1247 connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr,
1251 #if defined TIZEN_EXT
1252 __connman_service_nameserver_append(service, ipv6_dns1, FALSE,
1253 CONNMAN_IPCONFIG_TYPE_IPV6);
1255 __connman_service_nameserver_append(service, ipv6_dns1, FALSE);
1258 if (ipv6_dns2 && !ipv6_dns1)
1259 #if defined TIZEN_EXT
1260 __connman_service_nameserver_append(service, ipv6_dns2, FALSE,
1261 CONNMAN_IPCONFIG_TYPE_IPV6);
1263 __connman_service_nameserver_append(service, ipv6_dns2, FALSE);
1266 if (active == TRUE &&
1267 connman_network_get_connected(network->network) == TRUE) {
1268 if (ipv4_updated == TRUE || ipv6_updated == TRUE) {
1269 DBG("IPv4 updated %d, IPv6 updated %d", ipv4_updated, ipv6_updated);
1271 __set_network_connected(network, FALSE);
1273 DBG("Already connected");
1280 connman_network_set_associating(network->network, TRUE);
1285 static int __add_context(struct connman_device *device, const char *path,
1286 DBusMessageIter *prop)
1289 gboolean active = FALSE;
1291 struct telephony_modem *modem = connman_device_get_data(device);
1292 struct connman_network *network;
1293 struct telephony_network *info;
1295 DBG("modem %p device %p path %s", modem, device, path);
1297 ident = __get_ident(path);
1299 network = connman_device_get_network(device, ident);
1300 if (network != NULL)
1303 info = g_hash_table_lookup(network_hash, path);
1305 DBG("path %p already exists with device %p", path,
1306 connman_network_get_device(info->network));
1308 if (connman_network_get_device(info->network))
1311 g_hash_table_remove(network_hash, path);
1314 network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
1315 if (network == NULL)
1318 info = g_try_new0(struct telephony_network, 1);
1320 connman_network_unref(network);
1324 info->path = g_strdup(path);
1326 connman_ipaddress_clear(info->ipv4_address);
1327 connman_ipaddress_clear(info->ipv6_address);
1329 info->network = network;
1331 connman_network_set_string(network, "Path", path);
1332 connman_network_set_name(network, path);
1334 connman_network_set_group(network, ident);
1336 g_hash_table_insert(network_hash, g_strdup(path), info);
1338 connman_network_set_available(network, TRUE);
1339 connman_network_set_bool(network, "Roaming", (bool)modem->s_service->roaming);
1341 if (connman_device_add_network(device, network) != 0) {
1342 g_hash_table_remove(network_hash, path);
1346 active = __set_network_context(info, prop);
1347 if(info->routing_only){
1349 struct connman_service *routing_service;
1350 struct connman_ipconfig *routing_ipconfig;
1355 routing_service = connman_service_lookup_from_network(info->network);
1356 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1357 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1359 DBG("set gateway rv(%d)", err);
1363 if (active == TRUE && (connman_network_get_associating(network) == TRUE ||
1364 connman_network_get_connecting(network) == TRUE))
1365 __set_network_connected(info, active);
1370 static gboolean __changed_modem(DBusConnection *connection,
1371 DBusMessage *message, void *user_data)
1373 gboolean old_powered;
1374 DBusMessageIter args, dict;
1375 struct telephony_modem *modem;
1376 const char *path = dbus_message_get_path(message);
1378 DBG("modem changed signal %s", path);
1380 modem = g_hash_table_lookup(modem_hash, path);
1381 if (modem == NULL) {
1382 DBG("modem object does not exists");
1386 old_powered = modem->powered;
1388 DBG("message signature (%s)", dbus_message_get_signature(message));
1390 if (dbus_message_iter_init(message, &args) == FALSE) {
1391 DBG("error to read message");
1395 dbus_message_iter_recurse(&args, &dict);
1397 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1398 DBusMessageIter entry;
1399 const char *key, *tmp;
1401 dbus_message_iter_recurse(&dict, &entry);
1402 dbus_message_iter_get_basic(&entry, &key);
1404 dbus_message_iter_next(&entry);
1405 dbus_message_iter_get_basic(&entry, &tmp);
1407 DBG("key(%s), value(%s)", key, tmp);
1409 if (g_strcmp0(key, "powered") == 0) {
1410 modem->powered = STRING2BOOL(tmp);
1411 } else if (g_strcmp0(key, "operator") == 0) {
1412 modem->operator = g_strdup(tmp);
1413 } else if (g_strcmp0(key, "sim_init") == 0) {
1414 modem->sim_init = STRING2BOOL(tmp);
1415 } else if (g_strcmp0(key, "flight_mode") == 0) {
1416 modem->flight_mode = STRING2BOOL(tmp);
1417 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
1418 modem->roaming_allowed = STRING2BOOL(tmp);
1419 } else if (g_strcmp0(key, "data_allowed") == 0) {
1420 modem->data_allowed = STRING2BOOL(tmp);
1423 dbus_message_iter_next(&dict);
1426 if (modem->device == NULL)
1427 __add_connman_device(path, modem->operator);
1429 if (old_powered != modem->powered)
1430 __set_device_powered(modem, modem->powered);
1432 if (modem->powered != TRUE) {
1433 DBG("modem is not powered");
1437 if (modem->s_service == NULL) {
1438 __request_get_services(modem->path);
1442 DBG("modem(%s) flight mode(%d) data allowed(%d)",
1443 modem->path, modem->flight_mode, modem->data_allowed);
1448 static gboolean __added_modem(DBusConnection *connection,
1449 DBusMessage *message, void *user_data)
1451 const char *modem_path = NULL;
1452 DBusMessageIter args, dict, tmp;
1454 DBG("modem added signal (%s)", dbus_message_get_signature(message));
1456 if (dbus_message_iter_init(message, &args) == FALSE) {
1457 DBG("error to read message");
1461 dbus_message_iter_recurse(&args, &dict);
1462 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1464 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1465 DBusMessageIter entry;
1466 const char *key, *value;
1468 dbus_message_iter_recurse(&tmp, &entry);
1469 dbus_message_iter_get_basic(&entry, &key);
1471 dbus_message_iter_next(&entry);
1472 dbus_message_iter_get_basic(&entry, &value);
1474 DBG("key (%s) value(%s)", key, value);
1476 if (g_strcmp0(key, "path") == 0)
1477 modem_path = g_strdup(value);
1479 dbus_message_iter_next(&tmp);
1482 if (modem_path != NULL)
1483 __add_modem(modem_path, &dict);
1488 static gboolean __removed_modem(DBusConnection *connection,
1489 DBusMessage *message, void *user_data)
1491 DBusMessageIter iter;
1492 const char *modem_path;
1494 DBG("modem removed signal");
1496 if (dbus_message_iter_init(message, &iter) == FALSE) {
1497 DBG("error to read message");
1501 dbus_message_iter_get_basic(&iter, &modem_path);
1502 g_hash_table_remove(modem_hash, modem_path);
1507 static gboolean __changed_service(DBusConnection *connection,
1508 DBusMessage *message, void *user_data)
1510 DBusMessageIter args, dict;
1511 struct telephony_modem *modem;
1512 gboolean roaming_option = TRUE;
1513 struct telephony_service *s_service;
1514 const char *service_path = dbus_message_get_path(message);
1516 DBG("service changed signal %s", service_path);
1518 s_service = g_hash_table_lookup(service_hash, service_path);
1519 if (s_service == NULL) {
1520 DBG("service object does not exists");
1524 modem = s_service->p_modem;
1525 if (modem == NULL) {
1526 DBG("modem object does not exists");
1530 DBG("message signature (%s)", dbus_message_get_signature(message));
1532 if (dbus_message_iter_init(message, &args) == FALSE) {
1533 DBG("error to read message");
1537 dbus_message_iter_recurse(&args, &dict);
1539 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1540 DBusMessageIter entry;
1541 const char *key, *tmp;
1543 dbus_message_iter_recurse(&dict, &entry);
1544 dbus_message_iter_get_basic(&entry, &key);
1546 dbus_message_iter_next(&entry);
1547 dbus_message_iter_get_basic(&entry, &tmp);
1549 DBG("key(%s), value(%s)", key, tmp);
1551 if (g_strcmp0(key, "roaming") == 0) {
1552 s_service->roaming = STRING2BOOL(tmp);
1553 } else if (g_strcmp0(key, "act") == 0) {
1554 s_service->act = g_strdup(tmp);
1555 } else if (g_strcmp0(key, "ps_attached") == 0) {
1556 s_service->ps_attached = STRING2BOOL(tmp);
1559 dbus_message_iter_next(&dict);
1562 roaming_option &= (!s_service->roaming && !modem->roaming_allowed)
1563 || modem->roaming_allowed;
1568 static gboolean __added_service(DBusConnection *connection,
1569 DBusMessage *message, void *user_data)
1571 struct telephony_modem *modem;
1572 const char *service_path = NULL;
1573 DBusMessageIter args, dict, tmp;
1574 const char *path = dbus_message_get_path(message);
1576 DBG("service added signal %s", path);
1578 modem = g_hash_table_lookup(modem_hash, path);
1579 if (modem == NULL || modem->device == NULL)
1582 DBG("message signature (%s)", dbus_message_get_signature(message));
1583 if (dbus_message_iter_init(message, &args) == FALSE) {
1584 DBG("error to read message");
1588 dbus_message_iter_recurse(&args, &dict);
1589 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1591 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1592 DBusMessageIter entry;
1593 const char *key, *value;
1595 dbus_message_iter_recurse(&tmp, &entry);
1596 dbus_message_iter_get_basic(&entry, &key);
1598 dbus_message_iter_next(&entry);
1599 dbus_message_iter_get_basic(&entry, &value);
1601 DBG("key (%s) value(%s)", key, value);
1603 if (g_strcmp0(key, "path") == 0)
1604 service_path = value;
1606 dbus_message_iter_next(&tmp);
1609 if (service_path != NULL)
1610 __add_service(modem, service_path, &dict);
1615 static gboolean __removed_service(DBusConnection *connection,
1616 DBusMessage *message, void *user_data)
1618 DBusMessageIter iter;
1619 const char *service_path;
1621 DBG("service removed signal");
1623 if (dbus_message_iter_init(message, &iter) == FALSE) {
1624 DBG("error to read message");
1628 dbus_message_iter_get_basic(&iter, &service_path);
1629 g_hash_table_remove(service_hash, service_path);
1634 static gboolean __changed_context(DBusConnection *connection,
1635 DBusMessage *message, void *user_data)
1637 gboolean active = FALSE;
1638 DBusMessageIter args, dict;
1639 struct telephony_network *info;
1640 const char *path = dbus_message_get_path(message);
1642 DBG("network changed signal %s", path);
1644 info = g_hash_table_lookup(network_hash, path);
1648 if (__check_network_available(info->network) == FALSE) {
1649 g_hash_table_remove(network_hash, path);
1653 if (dbus_message_iter_init(message, &args) == FALSE) {
1654 DBG("error to read message");
1658 dbus_message_iter_recurse(&args, &dict);
1660 active = __set_network_context(info, &dict);
1661 if(info->routing_only){
1663 struct connman_service *routing_service;
1664 struct connman_ipconfig *routing_ipconfig;
1669 routing_service = connman_service_lookup_from_network(info->network);
1670 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1671 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1673 DBG("set gateway rv(%d)", err);
1677 __set_network_connected(info, active);
1679 if (active == FALSE &&
1680 connman_network_get_connecting(info->network) == TRUE)
1681 connman_network_set_connected(info->network, FALSE);
1686 static gboolean __added_context(DBusConnection *connection,
1687 DBusMessage *message, void *user_data)
1689 const char *network_path = NULL;
1690 DBusMessageIter args, dict, tmp;
1691 struct telephony_modem *modem = NULL;
1692 struct telephony_service *service = NULL;
1693 const char *path = dbus_message_get_path(message);
1695 DBG("network added signal %s", path);
1697 service = g_hash_table_lookup(service_hash, path);
1698 if (service == NULL || service->p_modem == NULL)
1701 modem = service->p_modem;
1702 if (modem == NULL || modem->device == NULL)
1705 DBG("message signature (%s)", dbus_message_get_signature(message));
1706 if (dbus_message_iter_init(message, &args) == FALSE) {
1707 DBG("error to read message");
1711 dbus_message_iter_recurse(&args, &dict);
1712 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1714 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1715 DBusMessageIter entry;
1716 const char *key, *value;
1718 dbus_message_iter_recurse(&tmp, &entry);
1719 dbus_message_iter_get_basic(&entry, &key);
1721 dbus_message_iter_next(&entry);
1722 dbus_message_iter_get_basic(&entry, &value);
1724 DBG("key (%s) value(%s)", key, value);
1726 if (g_strcmp0(key, "path") == 0)
1727 network_path = g_strdup(value);
1729 dbus_message_iter_next(&tmp);
1732 if (network_path != NULL)
1733 __add_context(modem->device, network_path, &dict);
1738 static gboolean __removed_context(DBusConnection *connection,
1739 DBusMessage *message, void *user_data)
1741 DBusMessageIter iter;
1742 const char *network_path = NULL;
1743 struct telephony_service *service = NULL;
1744 const char *path = dbus_message_get_path(message);
1746 DBG("network removed signal %s", path);
1748 service = g_hash_table_lookup(service_hash, path);
1749 if (service == NULL || service->p_modem == NULL)
1752 if (dbus_message_iter_init(message, &iter) == FALSE) {
1753 DBG("error to read message");
1757 dbus_message_iter_get_basic(&iter, &network_path);
1758 g_hash_table_remove(network_hash, network_path);
1763 static gboolean __changed_default_subscription(DBusConnection *connection,
1764 DBusMessage *message, void *user_data)
1766 DBusMessageIter args;
1768 DBG("message signature (%s)", dbus_message_get_signature(message));
1769 if (dbus_message_iter_init(message, &args) == FALSE)
1772 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
1773 DBG("default subscription: %d", telephony_default_subscription_id);
1778 /* telephony initialization */
1779 static guint watch = 0;
1780 static guint modem_watch = 0;
1781 static guint modem_added_watch = 0;
1782 static guint modem_removed_watch = 0;
1783 static guint service_watch = 0;
1784 static guint service_added_watch = 0;
1785 static guint service_removed_watch = 0;
1786 static guint context_watch = 0;
1787 static guint context_added_watch = 0;
1788 static guint context_removed_watch = 0;
1789 static guint default_subscription_watch = 0;
1791 static int telephony_init(void)
1795 DBG("telephony plugin");
1797 connection = connman_dbus_get_connection();
1798 if (connection == NULL)
1801 /* telephony watch */
1802 watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE,
1803 telephony_connect, telephony_disconnect,
1806 modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1812 modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1813 PS_MASTER_INTERFACE,
1818 modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1819 PS_MASTER_INTERFACE,
1824 service_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1825 PS_SERVICE_INTERFACE,
1830 service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1836 service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1842 context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1843 PS_CONTEXT_INTERFACE,
1848 context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1849 PS_SERVICE_INTERFACE,
1854 context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1855 PS_SERVICE_INTERFACE,
1860 default_subscription_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1861 "org.tizen.telephony.Network",
1862 "DefaultDataSubscription",
1863 __changed_default_subscription,
1866 if (watch == 0 || modem_watch == 0 || modem_added_watch == 0
1867 || modem_removed_watch == 0 || service_watch == 0
1868 || service_added_watch == 0 || context_watch == 0
1869 || service_removed_watch == 0
1870 || context_added_watch == 0
1871 || context_removed_watch == 0
1872 || default_subscription_watch == 0) {
1877 err = connman_network_driver_register(&network_driver);
1881 err = connman_device_driver_register(&modem_driver);
1883 connman_network_driver_unregister(&network_driver);
1887 err = connman_technology_driver_register(&tech_driver);
1889 connman_device_driver_unregister(&modem_driver);
1890 connman_network_driver_unregister(&network_driver);
1897 g_dbus_remove_watch(connection, watch);
1898 g_dbus_remove_watch(connection, modem_watch);
1899 g_dbus_remove_watch(connection, modem_added_watch);
1900 g_dbus_remove_watch(connection, modem_removed_watch);
1901 g_dbus_remove_watch(connection, service_watch);
1902 g_dbus_remove_watch(connection, service_added_watch);
1903 g_dbus_remove_watch(connection, service_removed_watch);
1904 g_dbus_remove_watch(connection, context_watch);
1905 g_dbus_remove_watch(connection, context_added_watch);
1906 g_dbus_remove_watch(connection, context_removed_watch);
1907 g_dbus_remove_watch(connection, default_subscription_watch);
1909 dbus_connection_unref(connection);
1913 static void telephony_exit(void)
1915 g_dbus_remove_watch(connection, watch);
1916 g_dbus_remove_watch(connection, modem_watch);
1917 g_dbus_remove_watch(connection, modem_added_watch);
1918 g_dbus_remove_watch(connection, modem_removed_watch);
1919 g_dbus_remove_watch(connection, service_watch);
1920 g_dbus_remove_watch(connection, service_added_watch);
1921 g_dbus_remove_watch(connection, service_removed_watch);
1922 g_dbus_remove_watch(connection, context_watch);
1923 g_dbus_remove_watch(connection, context_added_watch);
1924 g_dbus_remove_watch(connection, context_removed_watch);
1925 g_dbus_remove_watch(connection, default_subscription_watch);
1927 telephony_disconnect(connection, NULL);
1929 connman_device_driver_unregister(&modem_driver);
1930 connman_network_driver_unregister(&network_driver);
1932 dbus_connection_unref(connection);
1935 CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
1936 CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)