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"
43 #define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master"
44 #define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem"
45 #define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service"
46 #define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context"
49 #define GET_MODEMS "GetModems"
50 #define GET_SERVICES "GetServices"
51 #define GET_CONTEXTS "GetContexts"
52 #define ACTIVATE_CONTEXT "Activate"
53 #define DEACTIVATE_CONTEXT "Deactivate"
54 #define GET_PROPERTIES "GetProperties"
55 #define SET_PROPERTY "SetProperties"
58 #define MODEM_ADDED "ModemAdded"
59 #define MODEM_REMOVED "ModemRemoved"
60 #define SERVICE_ADDED "ServiceAdded"
61 #define SERVICE_REMOVED "ServiceRemoved"
62 #define CONTEXT_ADDED "ContextAdded"
63 #define CONTEXT_REMOVED "ContextRemoved"
64 #define PROPERTY_CHANGED "PropertyChanged"
66 #define TIMEOUT 130000
68 #define STRING2BOOL(a) (!(g_strcmp0(a, "TRUE")) ? (TRUE):(FALSE))
70 static DBusConnection *connection;
71 static GHashTable *modem_hash;
72 static GHashTable *service_hash;
73 static GHashTable *network_hash;
75 struct telephony_service {
80 gboolean roaming; /* global roaming state */
81 gboolean ps_attached; /* packet service is available */
84 struct telephony_modem {
91 gboolean data_allowed;
92 gboolean roaming_allowed;
94 struct connman_device *device;
95 struct telephony_service *s_service;
98 struct telephony_network {
101 gboolean routing_only;
102 gboolean ipv6_link_only;
104 struct connman_network *network;
106 enum connman_ipconfig_method ipv4_method;
107 struct connman_ipaddress *ipv4_address;
109 enum connman_ipconfig_method ipv6_method;
110 struct connman_ipaddress *ipv6_address;
113 static int telephony_default_subscription_id = 0;
115 /* function prototype */
116 static void telephony_connect(DBusConnection *connection, void *user_data);
117 static void telephony_disconnect(DBusConnection *connection, void *user_data);
118 static void __remove_modem(gpointer data);
119 static void __remove_service(gpointer data);
120 static void __remove_network(gpointer data);
122 static int __modem_probe(struct connman_device *device);
123 static void __modem_remove(struct connman_device *device);
124 static int __modem_enable(struct connman_device *device);
125 static int __modem_disable(struct connman_device *device);
127 static int __network_probe(struct connman_network *network);
128 static void __network_remove(struct connman_network *network);
129 static int __network_connect(struct connman_network *network);
130 static int __network_disconnect(struct connman_network *network);
133 /* dbus request and reply */
134 static int __dbus_request(const char *path, const char *interface,
136 DBusPendingCallNotifyFunction notify, void *user_data,
137 DBusFreeFunction free_function, int type, ...);
139 static int __request_get_modems(void);
140 static void __response_get_modems(DBusPendingCall *call, void *user_data);
141 static int __request_get_services(const char *path);
142 static void __response_get_services(DBusPendingCall *call, void *user_data);
143 static int __request_get_contexts(struct telephony_modem *modem);
144 static void __response_get_contexts(DBusPendingCall *call, void *user_data);
145 static int __request_network_activate(struct connman_network *network);
146 static void __response_network_activate(DBusPendingCall *call, void *user_data);
147 static int __request_network_deactivate(struct connman_network *network);
149 /* telephony internal function */
150 static void __add_modem(const char *path, DBusMessageIter *prop);
151 static void __add_service(struct telephony_modem *modem,
152 const char *service_path, DBusMessageIter *prop);
153 static void __add_connman_device(const char *modem_path, const char *operator);
154 static void __remove_connman_device(struct telephony_modem *modem);
155 static void __remove_connman_networks(struct connman_device *device);
156 static int __add_context(struct connman_device *device, const char *path,
157 DBusMessageIter *prop);
160 static gboolean __changed_modem(DBusConnection *connection,
161 DBusMessage *message, void *user_data);
162 static gboolean __added_modem(DBusConnection *connection,
163 DBusMessage *message, void *user_data);
164 static gboolean __removed_modem(DBusConnection *connection,
165 DBusMessage *message, void *user_data);
166 static gboolean __changed_service(DBusConnection *connection,
167 DBusMessage *message, void *user_data);
168 static gboolean __added_service(DBusConnection *connection,
169 DBusMessage *message, void *user_data);
170 static gboolean __removed_service(DBusConnection *connection,
171 DBusMessage *message, void *user_data);
172 static gboolean __changed_context(DBusConnection *connection,
173 DBusMessage *message, void *user_data);
174 static gboolean __added_context(DBusConnection *connection,
175 DBusMessage *message, void *user_data);
176 static gboolean __removed_context(DBusConnection *connection,
177 DBusMessage *message, void *user_data);
180 static struct connman_device_driver modem_driver = {
182 .type = CONNMAN_DEVICE_TYPE_CELLULAR,
183 .probe = __modem_probe,
184 .remove = __modem_remove,
185 .enable = __modem_enable,
186 .disable = __modem_disable,
190 static struct connman_network_driver network_driver = {
192 .type = CONNMAN_NETWORK_TYPE_CELLULAR,
193 .probe = __network_probe,
194 .remove = __network_remove,
195 .connect = __network_connect,
196 .disconnect = __network_disconnect,
199 static int tech_probe(struct connman_technology *technology)
204 static void tech_remove(struct connman_technology *technology)
209 static struct connman_technology_driver tech_driver = {
211 .type = CONNMAN_SERVICE_TYPE_CELLULAR,
213 .remove = tech_remove,
217 static void telephony_connect(DBusConnection *connection, void *user_data)
219 DBG("connection %p", connection);
220 modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
221 g_free, __remove_modem);
222 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
223 g_free, __remove_service);
224 network_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
225 g_free, __remove_network);
227 __request_get_modems();
230 static void telephony_disconnect(DBusConnection *connection, void *user_data)
232 DBG("connection %p", connection);
234 if (modem_hash != NULL) {
235 g_hash_table_destroy(modem_hash);
239 if (network_hash != NULL) {
240 g_hash_table_destroy(network_hash);
245 static void __remove_modem(gpointer data)
247 struct telephony_modem *modem = data;
249 __remove_connman_device(modem);
252 g_free(modem->operator);
256 static void __remove_service(gpointer data)
258 struct telephony_service *service = data;
260 g_free(service->path);
261 g_free(service->act);
265 static void __remove_network(gpointer data)
267 struct telephony_network *info = data;
268 struct connman_device *device;
270 device = connman_network_get_device(info->network);
272 connman_device_remove_network(device, info->network);
274 connman_network_unref(info->network);
278 connman_ipaddress_free(info->ipv4_address);
279 connman_ipaddress_free(info->ipv6_address);
284 static void __set_device_powered(struct telephony_modem *modem,
287 DBG("set modem(%s) powered(%d)", modem->path, powered);
290 connman_device_set_powered(modem->device, powered);
293 static int __check_device_powered(const char *path, gboolean powered)
295 struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path);
300 DBG("check modem (%s) powered (%d)", modem->path, modem->powered);
302 if (modem->powered == powered)
308 static int __modem_probe(struct connman_device *device)
310 DBG("device %p", device);
314 static void __modem_remove(struct connman_device *device)
316 DBG("device %p", device);
319 static int __modem_enable(struct connman_device *device)
321 const char *path = connman_device_get_string(device, "Path");
322 DBG("device %p, path, %s", device, path);
324 return __check_device_powered(path, TRUE);
327 static int __modem_disable(struct connman_device *device)
329 const char *path = connman_device_get_string(device, "Path");
330 DBG("device %p, path, %s", device, path);
332 return __check_device_powered(path, FALSE);
335 static int __network_probe(struct connman_network *network)
337 DBG("network_prove network(%p)", network);
341 static int __network_connect(struct connman_network *network)
343 DBG("network %p", network);
345 return __request_network_activate(network);
348 static int __network_disconnect(struct connman_network *network)
350 DBG("network %p", network);
352 if (connman_network_get_associating(network) == TRUE)
353 connman_network_clear_associating(network);
355 connman_network_set_associating(network, FALSE);
357 return __request_network_deactivate(network);
360 static void __network_remove(struct connman_network *network)
362 char const *path = connman_network_get_string(network, "Path");
363 DBG("network %p path %s", network, path);
365 g_hash_table_remove(network_hash, path);
368 static int __dbus_request(const char *path, const char *interface,
370 DBusPendingCallNotifyFunction notify, void *user_data,
371 DBusFreeFunction free_function, int type, ...)
373 DBusMessage *message;
374 DBusPendingCall *call;
378 DBG("path %s %s.%s", path, interface, method);
383 message = dbus_message_new_method_call(PS_DBUS_SERVICE, path, interface, method);
387 dbus_message_set_auto_start(message, FALSE);
390 ok = dbus_message_append_args_valist(message, type, va);
394 dbus_message_unref(message);
398 if (dbus_connection_send_with_reply(connection, message,
399 &call, TIMEOUT) == FALSE) {
400 connman_error("Failed to call %s.%s", interface, method);
401 dbus_message_unref(message);
406 connman_error("D-Bus connection not available");
407 dbus_message_unref(message);
411 dbus_pending_call_set_notify(call, notify, user_data, free_function);
413 dbus_message_unref(message);
418 static int __request_get_modems(void)
420 DBG("request get modem");
421 /* call connect master */
422 return __dbus_request("/", PS_MASTER_INTERFACE, GET_MODEMS,
423 __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
426 static void __response_get_modems(DBusPendingCall *call, void *user_data)
430 DBusMessageIter args, dict;
434 reply = dbus_pending_call_steal_reply(call);
436 dbus_error_init(&error);
438 if (dbus_set_error_from_message(&error, reply)) {
439 connman_error("GetModems() %s %s", error.name, error.message);
440 dbus_error_free(&error);
444 DBG("message signature (%s)", dbus_message_get_signature(reply));
446 if (dbus_message_iter_init(reply, &args) == FALSE)
449 dbus_message_iter_recurse(&args, &dict);
451 /* DBG("message type (%d) dic(%d)",
452 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
455 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
456 DBusMessageIter entry, property;
457 const char *modem_path;
459 dbus_message_iter_recurse(&dict, &entry);
460 dbus_message_iter_get_basic(&entry, &modem_path);
461 DBG("modem path (%s)", modem_path);
463 dbus_message_iter_next(&entry);
464 dbus_message_iter_recurse(&entry, &property);
466 __add_modem(modem_path, &property);
468 dbus_message_iter_next(&dict);
472 dbus_message_unref(reply);
473 dbus_pending_call_unref(call);
476 static int __request_get_services(const char *path)
478 DBG("request get service");
479 return __dbus_request(path, PS_MODEM_INTERFACE, GET_SERVICES,
480 __response_get_services, g_strdup(path),
481 g_free, DBUS_TYPE_INVALID);
484 static void __response_get_services(DBusPendingCall *call, void *user_data)
488 DBusMessageIter args, dict;
490 const char *path = user_data;
491 struct telephony_modem *modem;
493 modem = g_hash_table_lookup(modem_hash, path);
497 reply = dbus_pending_call_steal_reply(call);
499 dbus_error_init(&error);
501 if (dbus_set_error_from_message(&error, reply)) {
502 connman_error("GetServices() %s %s", error.name, error.message);
503 dbus_error_free(&error);
507 if (modem == NULL || modem->device == NULL)
510 DBG("message signature (%s)", dbus_message_get_signature(reply));
512 if (dbus_message_iter_init(reply, &args) == FALSE)
515 dbus_message_iter_recurse(&args, &dict);
517 /* DBG("message type (%d) dic(%d)",
518 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
521 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
522 DBusMessageIter entry, property;
523 const char *service_path;
525 dbus_message_iter_recurse(&dict, &entry);
526 dbus_message_iter_get_basic(&entry, &service_path);
527 DBG("service path (%s)", service_path);
529 dbus_message_iter_next(&entry);
530 dbus_message_iter_recurse(&entry, &property);
532 __add_service(modem, service_path, &property);
534 dbus_message_iter_next(&dict);
538 dbus_message_unref(reply);
539 dbus_pending_call_unref(call);
542 static int __request_get_contexts(struct telephony_modem *modem)
544 DBG("request get contexts");
545 return __dbus_request(modem->s_service->path,
546 PS_SERVICE_INTERFACE, GET_CONTEXTS,
547 __response_get_contexts, g_strdup(modem->path),
548 g_free, DBUS_TYPE_INVALID);
551 static void __response_get_contexts(DBusPendingCall *call, void *user_data)
555 DBusMessageIter args, dict;
557 const char *path = user_data;
558 struct telephony_modem *modem;
562 modem = g_hash_table_lookup(modem_hash, path);
565 if (modem->s_service == NULL)
567 if (modem->device == NULL)
570 reply = dbus_pending_call_steal_reply(call);
572 dbus_error_init(&error);
574 if (dbus_set_error_from_message(&error, reply)) {
575 connman_error("GetContexts() %s %s", error.name, error.message);
576 dbus_error_free(&error);
580 DBG("message signature (%s)", dbus_message_get_signature(reply));
582 if (dbus_message_iter_init(reply, &args) == FALSE)
585 dbus_message_iter_recurse(&args, &dict);
587 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
588 DBusMessageIter entry, property;
589 const char *context_path;
591 dbus_message_iter_recurse(&dict, &entry);
592 dbus_message_iter_get_basic(&entry, &context_path);
593 DBG("context path (%s)", context_path);
595 dbus_message_iter_next(&entry);
596 dbus_message_iter_recurse(&entry, &property);
598 __add_context(modem->device, context_path, &property);
600 dbus_message_iter_next(&dict);
604 dbus_message_unref(reply);
605 dbus_pending_call_unref(call);
608 static int __request_network_activate(struct connman_network *network)
611 const char *path = NULL;
612 struct telephony_modem *modem = NULL;
614 n_modems = g_hash_table_size(modem_hash);
615 path = connman_network_get_string(network, "Path");
616 modem = connman_device_get_data(connman_network_get_device(network));
617 DBG("network %p, path %s, modem %s[%d]", network, path, modem->path,
618 telephony_default_subscription_id);
620 if (modem && n_modems > 1 && g_str_has_suffix(path, "_1") == TRUE) {
621 char *subscribe_id = g_strdup_printf("%d", telephony_default_subscription_id);
623 if (g_str_has_suffix(modem->path, subscribe_id) != TRUE) {
624 g_free(subscribe_id);
627 g_free(subscribe_id);
630 return __dbus_request(path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT,
631 __response_network_activate,
632 g_strdup(path), NULL, DBUS_TYPE_INVALID);
635 static gboolean __check_network_available(struct connman_network *network)
637 if (network == NULL || connman_network_get_device(network) == NULL)
643 static void __response_network_activate(DBusPendingCall *call, void *user_data)
645 DBG("network activation response");
650 struct telephony_network *info;
651 const char *path = user_data;
653 info = g_hash_table_lookup(network_hash, path);
654 reply = dbus_pending_call_steal_reply(call);
659 if (__check_network_available(info->network) == FALSE) {
660 g_hash_table_remove(network_hash, path);
664 dbus_error_init(&error);
665 if (dbus_set_error_from_message(&error, reply)) {
666 connman_error("connection activate() %s %s",
667 error.name, error.message);
669 if (connman_network_get_associating(info->network) == TRUE)
670 connman_network_set_error(info->network,
671 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
673 if (connman_network_get_connecting(info->network) == TRUE)
674 connman_network_set_error(info->network,
675 CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
677 if (connman_network_get_index(info->network) < 0)
678 connman_network_set_error(info->network,
679 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
681 dbus_error_free(&error);
686 dbus_message_unref(reply);
687 dbus_pending_call_unref(call);
690 static int __request_network_deactivate(struct connman_network *network)
692 const char *path = connman_network_get_string(network, "Path");
693 DBG("network %p, path %s", network, path);
695 return __dbus_request(path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT,
696 NULL, NULL, NULL, DBUS_TYPE_INVALID);
699 static void __response_get_default_subscription_id(DBusPendingCall *call,
704 DBusMessageIter args;
708 reply = dbus_pending_call_steal_reply(call);
710 dbus_error_init(&error);
711 if (dbus_set_error_from_message(&error, reply)) {
712 connman_error("GetDefaultDataSubscription() %s %s", error.name, error.message);
713 dbus_error_free(&error);
717 DBG("message signature (%s)", dbus_message_get_signature(reply));
719 if (dbus_message_iter_init(reply, &args) == FALSE)
722 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
723 DBG("default subscription: %d", telephony_default_subscription_id);
726 dbus_message_unref(reply);
727 dbus_pending_call_unref(call);
730 static int __request_get_default_subscription_id(const char *path)
733 char *telephony_modem_path = NULL;
735 telephony_modem_path = g_strdup_printf("/org/tizen/telephony%s", path);
736 DBG("request get default subscription id %s", telephony_modem_path);
738 ret = __dbus_request(telephony_modem_path,
739 "org.tizen.telephony.Network", "GetDefaultDataSubscription",
740 __response_get_default_subscription_id, NULL, NULL, DBUS_TYPE_INVALID);
742 g_free(telephony_modem_path);
746 static void __add_modem(const char *path, DBusMessageIter *prop)
748 struct telephony_modem *modem;
750 modem = g_hash_table_lookup(modem_hash, path);
754 modem = g_try_new0(struct telephony_modem, 1);
758 modem->path = g_strdup(path);
759 modem->device = NULL;
760 modem->s_service = NULL;
762 g_hash_table_insert(modem_hash, g_strdup(path), modem);
764 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
765 DBusMessageIter entry;
766 const char *key, *tmp;
768 dbus_message_iter_recurse(prop, &entry);
769 dbus_message_iter_get_basic(&entry, &key);
771 dbus_message_iter_next(&entry);
772 dbus_message_iter_get_basic(&entry, &tmp);
774 DBG("key (%s) value(%s)", key, tmp);
776 if (g_strcmp0(key, "powered") == 0) {
777 modem->powered = STRING2BOOL(tmp);
778 } else if (g_strcmp0(key, "operator") == 0) {
779 modem->operator = g_strdup(tmp);
780 } else if (g_strcmp0(key, "sim_init") == 0) {
781 modem->sim_init = STRING2BOOL(tmp);
782 } else if (g_strcmp0(key, "flight_mode") == 0) {
783 modem->flight_mode = STRING2BOOL(tmp);
784 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
785 modem->roaming_allowed = STRING2BOOL(tmp);
786 } else if (g_strcmp0(key, "data_allowed") == 0) {
787 modem->data_allowed = STRING2BOOL(tmp);
789 dbus_message_iter_next(prop);
792 __add_connman_device(path, modem->operator);
793 __set_device_powered(modem, modem->powered);
795 if (g_hash_table_size(modem_hash) > 1)
796 __request_get_default_subscription_id(modem->path);
798 if (modem->powered != TRUE) {
799 DBG("modem is not powered");
803 __request_get_services(modem->path);
806 static void __add_service(struct telephony_modem *modem,
807 const char *service_path, DBusMessageIter *prop)
809 struct telephony_service *service;
811 if (modem->s_service != NULL)
814 service = g_try_new0(struct telephony_service, 1);
818 service->path = g_strdup(service_path);
819 service->p_modem = modem;
820 g_hash_table_insert(service_hash, g_strdup(service_path), service);
822 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
823 DBusMessageIter entry;
824 const char *key, *tmp;
826 dbus_message_iter_recurse(prop, &entry);
827 dbus_message_iter_get_basic(&entry, &key);
829 dbus_message_iter_next(&entry);
830 dbus_message_iter_get_basic(&entry, &tmp);
832 DBG("key (%s) value(%s)", key, tmp);
834 if (g_strcmp0(key, "roaming") == 0) {
835 service->roaming = STRING2BOOL(tmp);
836 } else if (g_strcmp0(key, "act") == 0) {
837 service->act = g_strdup(tmp);
838 } else if (g_strcmp0(key, "ps_attached") == 0) {
839 service->ps_attached = STRING2BOOL(tmp);
842 dbus_message_iter_next(prop);
845 modem->s_service = service;
846 __request_get_contexts(modem);
849 static char *__get_ident(const char *path)
856 pos = strrchr(path, '/');
863 static void __add_connman_device(const char *modem_path, const char *operator)
866 struct telephony_modem *modem;
867 struct connman_device *device;
869 DBG("path %s operator %s", modem_path, operator);
871 if (modem_path == NULL)
874 if (operator == NULL)
877 modem = g_hash_table_lookup(modem_hash, modem_path);
882 if (!g_strcmp0(operator,
883 connman_device_get_ident(modem->device)))
886 __remove_connman_device(modem);
889 if (strlen(operator) == 0)
892 device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
896 ident = g_strdup_printf("%s_%s", __get_ident(modem_path), operator);
897 connman_device_set_ident(device, ident);
900 connman_device_set_string(device, "Path", modem_path);
901 connman_device_set_data(device, modem);
903 if (connman_device_register(device) < 0) {
904 connman_error("Failed to register cellular device");
905 connman_device_unref(device);
909 modem->device = device;
912 static void __remove_connman_device(struct telephony_modem *modem)
914 DBG("modem %p path %s device %p", modem, modem->path, modem->device);
916 if (modem->device == NULL)
919 __remove_connman_networks(modem->device);
921 connman_device_unregister(modem->device);
922 connman_device_unref(modem->device);
924 modem->device = NULL;
927 static void __remove_connman_networks(struct connman_device *device)
931 GSList *info_list = NULL;
934 if (network_hash == NULL)
937 g_hash_table_iter_init(&iter, network_hash);
939 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
940 struct telephony_network *info = value;
942 if (connman_network_get_device(info->network) != device)
945 info_list = g_slist_append(info_list, info);
948 for (list = info_list; list != NULL; list = list->next) {
949 struct telephony_network *info = list->data;
950 connman_device_remove_network(device, info->network);
953 g_slist_free(info_list);
956 static gboolean connman_ipaddress_updated(struct connman_ipaddress *ipaddress,
957 const char *address, const char *gateway)
959 if (ipaddress == NULL || address == NULL)
962 if (g_strcmp0(ipaddress->local, address) != 0)
965 if (g_strcmp0(ipaddress->gateway, gateway) != 0)
971 static void __set_network_connected(struct telephony_network *network,
974 gboolean setip = FALSE;
976 DBG("network %p connected %d", network, connected);
978 connman_network_set_index(network->network, network->if_index);
979 if (connman_network_get_connected(network->network) == connected)
982 switch (network->ipv4_method) {
983 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
984 case CONNMAN_IPCONFIG_METHOD_DHCP:
985 case CONNMAN_IPCONFIG_METHOD_AUTO:
986 case CONNMAN_IPCONFIG_METHOD_OFF:
987 connman_network_set_ipv4_method(network->network,
988 network->ipv4_method);
990 case CONNMAN_IPCONFIG_METHOD_MANUAL:
991 case CONNMAN_IPCONFIG_METHOD_FIXED:
992 connman_network_set_ipv4_method(network->network,
993 network->ipv4_method);
994 connman_network_set_ipaddress(network->network,
995 network->ipv4_address);
1000 switch (network->ipv6_method) {
1001 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1002 case CONNMAN_IPCONFIG_METHOD_OFF:
1003 case CONNMAN_IPCONFIG_METHOD_DHCP:
1005 case CONNMAN_IPCONFIG_METHOD_AUTO:
1006 connman_network_set_ipv6_method(network->network,
1007 network->ipv6_method);
1010 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1011 case CONNMAN_IPCONFIG_METHOD_FIXED:
1012 connman_network_set_ipv6_method(network->network,
1013 network->ipv6_method);
1014 connman_network_set_ipaddress(network->network,
1015 network->ipv6_address);
1021 connman_network_set_connected(network->network, connected);
1024 static gboolean __set_network_context(
1025 struct telephony_network *network,
1026 DBusMessageIter *dict)
1029 gboolean active = FALSE;
1030 gboolean routing_only = FALSE;
1031 gboolean ipv4_updated = FALSE;
1032 gboolean ipv6_updated = FALSE;
1033 gboolean ipv6_link_only = FALSE;
1034 gboolean default_internet = FALSE;
1035 gboolean active_proxy = FALSE;
1036 char **proxies = NULL;
1037 const char *dev_name = NULL;
1038 const char *proxy_addr = NULL;
1039 char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL,
1040 *ipv4_dns1 = NULL, *ipv4_dns2 = NULL;
1041 char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL,
1042 *ipv6_dns1 = NULL, *ipv6_dns2 = NULL;
1043 struct connman_service *service;
1045 while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
1046 DBusMessageIter entry;
1047 const char *key, *value;
1049 dbus_message_iter_recurse(dict, &entry);
1050 dbus_message_iter_get_basic(&entry, &key);
1052 dbus_message_iter_next(&entry);
1054 if (g_strcmp0(key, "dev_name") == 0) {
1055 dbus_message_iter_get_basic(&entry, &dev_name);
1056 DBG("dev_name (%s)", dev_name);
1057 } else if (g_strcmp0(key, "proxy") == 0) {
1058 dbus_message_iter_get_basic(&entry, &proxy_addr);
1059 DBG("proxy_addr (%s)", proxy_addr);
1060 } else if (g_strcmp0(key, "ipv4_address") == 0) {
1061 dbus_message_iter_get_basic(&entry, &ipv4_addr);
1062 DBG("ipv4_addr (%s)", ipv4_addr);
1063 } else if (g_strcmp0(key, "ipv4_gateway") == 0) {
1064 dbus_message_iter_get_basic(&entry, &ipv4_gw);
1065 DBG("ipv4_gw (%s)", ipv4_gw);
1066 } else if (g_strcmp0(key, "ipv4_netmask") == 0) {
1067 dbus_message_iter_get_basic(&entry, &ipv4_netmask);
1068 DBG("ipv4_netmask (%s)", ipv4_netmask);
1069 } else if (g_strcmp0(key, "ipv4_dns1") == 0) {
1070 dbus_message_iter_get_basic(&entry, &ipv4_dns1);
1071 DBG("ipv4_dns1 (%s)", ipv4_dns1);
1072 } else if (g_strcmp0(key, "ipv4_dns2") == 0) {
1073 dbus_message_iter_get_basic(&entry, &ipv4_dns2);
1074 DBG("ipv4_dns2 (%s)", ipv4_dns2);
1075 } else if (g_strcmp0(key, "ipv6_address") == 0) {
1076 dbus_message_iter_get_basic(&entry, &ipv6_addr);
1077 DBG("ipv6 address (%s)", ipv6_addr);
1078 } else if (g_strcmp0(key, "ipv6_gateway") == 0) {
1079 dbus_message_iter_get_basic(&entry, &ipv6_gw);
1080 DBG("ipv6_gw (%s)", ipv6_gw);
1081 } else if (g_strcmp0(key, "ipv6_netmask") == 0) {
1082 dbus_message_iter_get_basic(&entry, &ipv6_netmask);
1083 DBG("ipv6_netmask (%s)", ipv6_netmask);
1084 } else if (g_strcmp0(key, "ipv6_dns1") == 0) {
1085 dbus_message_iter_get_basic(&entry, &ipv6_dns1);
1086 DBG("ipv6_dns1 (%s)", ipv6_dns1);
1087 } else if (g_strcmp0(key, "ipv6_dns2") == 0) {
1088 dbus_message_iter_get_basic(&entry, &ipv6_dns2);
1089 DBG("ipv6_dns2 (%s)", ipv6_dns2);
1090 } else if (g_strcmp0(key, "active") == 0) {
1091 dbus_message_iter_get_basic(&entry, &value);
1092 DBG("active (%s)", value);
1093 active = STRING2BOOL(value);
1094 } else if (g_strcmp0(key, "routing_only") == 0) {
1095 dbus_message_iter_get_basic(&entry, &value);
1096 DBG("routing_only (%s)", value);
1097 routing_only = STRING2BOOL(value);
1098 network->routing_only = routing_only;
1099 } else if (g_strcmp0(key, "ipv6_link_only") == 0) {
1100 dbus_message_iter_get_basic(&entry, &value);
1101 DBG("ipv6_link_only (%s)", value);
1102 ipv6_link_only = STRING2BOOL(value);
1103 network->ipv6_link_only = ipv6_link_only;
1105 else if (g_strcmp0(key, "default_internet_conn") == 0) {
1106 dbus_message_iter_get_basic(&entry, &value);
1107 DBG("default_internet (%s)", value);
1108 default_internet = STRING2BOOL(value);
1111 dbus_message_iter_next(dict);
1115 //context active does not effect the connman service status.
1116 //it only for setting the routing path.
1117 DBG("routing_only(%d), active(%d)", routing_only, active);
1121 if (g_strcmp0(proxy_addr, ":") == 0)
1123 if (g_strcmp0(ipv4_addr, "0.0.0.0") == 0)
1125 if (g_strcmp0(ipv4_gw, "0.0.0.0") == 0)
1127 if (g_strcmp0(ipv4_netmask, "0.0.0.0") == 0)
1128 ipv4_netmask = NULL;
1129 if (g_strcmp0(ipv4_dns1, "0.0.0.0") == 0)
1131 if (g_strcmp0(ipv4_dns2, "0.0.0.0") == 0)
1133 if (g_strcmp0(ipv6_addr, "::") == 0)
1135 if (g_strcmp0(ipv6_gw, "::") == 0)
1137 if (g_strcmp0(ipv6_netmask, "::") == 0)
1138 ipv6_netmask = NULL;
1139 if (g_strcmp0(ipv6_dns1, "::") == 0)
1141 if (g_strcmp0(ipv6_dns2, "::") == 0)
1144 connman_network_set_bool(network->network, "DefaultInternet",
1145 (bool)default_internet);
1147 service = connman_service_lookup_from_network(network->network);
1148 if (service == NULL)
1151 if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
1152 /* Wi-Fi technology is always a top priority */
1153 if (active == TRUE &&
1154 connman_service_is_no_ref_user_pdn_connection(service) == TRUE &&
1155 connman_service_get_type(connman_service_get_default_connection())
1156 == CONNMAN_SERVICE_TYPE_WIFI) {
1157 __request_network_deactivate(network->network);
1163 /* interface index set */
1164 if (dev_name != NULL) {
1165 index = connman_inet_ifindex(dev_name);
1166 network->if_index = index;
1167 DBG("interface index %d", index);
1171 if (active == TRUE &&
1172 connman_network_get_connected(network->network) == TRUE)
1173 active_proxy = TRUE;
1175 proxies = connman_service_get_proxy_servers(service);
1176 if (proxies != NULL) {
1177 if (proxy_addr == NULL)
1178 connman_service_set_proxy(service, proxy_addr, active_proxy);
1179 else if (g_strcmp0(proxy_addr, proxies[0]) != 0)
1180 connman_service_set_proxy(service, proxy_addr, active_proxy);
1181 } else if (proxy_addr != NULL)
1182 connman_service_set_proxy(service, proxy_addr, active_proxy);
1184 if (proxies != NULL)
1185 g_strfreev(proxies);
1187 __connman_service_nameserver_clear(service);
1190 if (network->ipv4_address == NULL)
1191 network->ipv4_address =
1192 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
1194 if (network->ipv4_address == NULL)
1197 if (ipv4_addr == NULL && active == TRUE)
1198 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
1200 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1202 connman_network_set_ipv4_method(network->network, network->ipv4_method);
1204 ipv4_updated = connman_ipaddress_updated(network->ipv4_address,
1205 ipv4_addr, ipv4_gw);
1206 if (ipv4_updated == TRUE)
1207 connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr,
1208 ipv4_netmask, ipv4_gw);
1211 #if defined TIZEN_EXT
1212 __connman_service_nameserver_append(service, ipv4_dns1, FALSE,
1213 CONNMAN_IPCONFIG_TYPE_IPV4);
1215 __connman_service_nameserver_append(service, ipv4_dns1, FALSE);
1218 if (ipv4_dns2 && !ipv4_dns1)
1219 #if defined TIZEN_EXT
1220 __connman_service_nameserver_append(service, ipv4_dns2, FALSE,
1221 CONNMAN_IPCONFIG_TYPE_IPV4);
1223 __connman_service_nameserver_append(service, ipv4_dns2, FALSE);
1226 if (network->ipv6_address == NULL)
1227 network->ipv6_address =
1228 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
1230 if (network->ipv6_address == NULL)
1234 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO;
1236 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1238 if (ipv6_addr == NULL)
1239 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
1241 connman_network_set_ipv6_method(network->network, network->ipv6_method);
1243 ipv6_updated = connman_ipaddress_updated(network->ipv6_address,
1244 ipv6_addr, ipv6_gw);
1245 if (ipv6_updated == TRUE)
1246 connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr,
1250 #if defined TIZEN_EXT
1251 __connman_service_nameserver_append(service, ipv6_dns1, FALSE,
1252 CONNMAN_IPCONFIG_TYPE_IPV6);
1254 __connman_service_nameserver_append(service, ipv6_dns1, FALSE);
1257 if (ipv6_dns2 && !ipv6_dns1)
1258 #if defined TIZEN_EXT
1259 __connman_service_nameserver_append(service, ipv6_dns2, FALSE,
1260 CONNMAN_IPCONFIG_TYPE_IPV6);
1262 __connman_service_nameserver_append(service, ipv6_dns2, FALSE);
1265 if (active == TRUE &&
1266 connman_network_get_connected(network->network) == TRUE) {
1267 if (ipv4_updated == TRUE || ipv6_updated == TRUE) {
1268 DBG("IPv4 updated %d, IPv6 updated %d", ipv4_updated, ipv6_updated);
1270 __set_network_connected(network, FALSE);
1272 DBG("Already connected");
1279 connman_network_set_associating(network->network, TRUE);
1284 static int __add_context(struct connman_device *device, const char *path,
1285 DBusMessageIter *prop)
1288 gboolean active = FALSE;
1290 struct telephony_modem *modem = connman_device_get_data(device);
1291 struct connman_network *network;
1292 struct telephony_network *info;
1294 DBG("modem %p device %p path %s", modem, device, path);
1296 ident = __get_ident(path);
1298 network = connman_device_get_network(device, ident);
1299 if (network != NULL)
1302 info = g_hash_table_lookup(network_hash, path);
1304 DBG("path %p already exists with device %p", path,
1305 connman_network_get_device(info->network));
1307 if (connman_network_get_device(info->network))
1310 g_hash_table_remove(network_hash, path);
1313 network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
1314 if (network == NULL)
1317 info = g_try_new0(struct telephony_network, 1);
1319 connman_network_unref(network);
1323 info->path = g_strdup(path);
1325 connman_ipaddress_clear(info->ipv4_address);
1326 connman_ipaddress_clear(info->ipv6_address);
1328 info->network = network;
1330 connman_network_set_string(network, "Path", path);
1331 connman_network_set_name(network, path);
1333 connman_network_set_group(network, ident);
1335 g_hash_table_insert(network_hash, g_strdup(path), info);
1337 connman_network_set_available(network, TRUE);
1338 connman_network_set_bool(network, "Roaming", (bool)modem->s_service->roaming);
1340 if (connman_device_add_network(device, network) != 0) {
1341 g_hash_table_remove(network_hash, path);
1345 active = __set_network_context(info, prop);
1346 if(info->routing_only){
1348 struct connman_service *routing_service;
1349 struct connman_ipconfig *routing_ipconfig;
1354 routing_service = connman_service_lookup_from_network(info->network);
1355 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1356 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1358 DBG("set gateway rv(%d)", err);
1362 if (active == TRUE && (connman_network_get_associating(network) == TRUE ||
1363 connman_network_get_connecting(network) == TRUE))
1364 __set_network_connected(info, active);
1369 static gboolean __changed_modem(DBusConnection *connection,
1370 DBusMessage *message, void *user_data)
1372 gboolean old_powered;
1373 DBusMessageIter args, dict;
1374 struct telephony_modem *modem;
1375 const char *path = dbus_message_get_path(message);
1377 DBG("modem changed signal %s", path);
1379 modem = g_hash_table_lookup(modem_hash, path);
1380 if (modem == NULL) {
1381 DBG("modem object does not exists");
1385 old_powered = modem->powered;
1387 DBG("message signature (%s)", dbus_message_get_signature(message));
1389 if (dbus_message_iter_init(message, &args) == FALSE) {
1390 DBG("error to read message");
1394 dbus_message_iter_recurse(&args, &dict);
1396 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1397 DBusMessageIter entry;
1398 const char *key, *tmp;
1400 dbus_message_iter_recurse(&dict, &entry);
1401 dbus_message_iter_get_basic(&entry, &key);
1403 dbus_message_iter_next(&entry);
1404 dbus_message_iter_get_basic(&entry, &tmp);
1406 DBG("key(%s), value(%s)", key, tmp);
1408 if (g_strcmp0(key, "powered") == 0) {
1409 modem->powered = STRING2BOOL(tmp);
1410 } else if (g_strcmp0(key, "operator") == 0) {
1411 modem->operator = g_strdup(tmp);
1412 } else if (g_strcmp0(key, "sim_init") == 0) {
1413 modem->sim_init = STRING2BOOL(tmp);
1414 } else if (g_strcmp0(key, "flight_mode") == 0) {
1415 modem->flight_mode = STRING2BOOL(tmp);
1416 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
1417 modem->roaming_allowed = STRING2BOOL(tmp);
1418 } else if (g_strcmp0(key, "data_allowed") == 0) {
1419 modem->data_allowed = STRING2BOOL(tmp);
1422 dbus_message_iter_next(&dict);
1425 if (modem->device == NULL)
1426 __add_connman_device(path, modem->operator);
1428 if (old_powered != modem->powered)
1429 __set_device_powered(modem, modem->powered);
1431 if (modem->powered != TRUE) {
1432 DBG("modem is not powered");
1436 if (modem->s_service == NULL) {
1437 __request_get_services(modem->path);
1441 DBG("modem(%s) flight mode(%d) data allowed(%d)",
1442 modem->path, modem->flight_mode, modem->data_allowed);
1447 static gboolean __added_modem(DBusConnection *connection,
1448 DBusMessage *message, void *user_data)
1450 const char *modem_path = NULL;
1451 DBusMessageIter args, dict, tmp;
1453 DBG("modem added signal (%s)", dbus_message_get_signature(message));
1455 if (dbus_message_iter_init(message, &args) == FALSE) {
1456 DBG("error to read message");
1460 dbus_message_iter_recurse(&args, &dict);
1461 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1463 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1464 DBusMessageIter entry;
1465 const char *key, *value;
1467 dbus_message_iter_recurse(&tmp, &entry);
1468 dbus_message_iter_get_basic(&entry, &key);
1470 dbus_message_iter_next(&entry);
1471 dbus_message_iter_get_basic(&entry, &value);
1473 DBG("key (%s) value(%s)", key, value);
1475 if (g_strcmp0(key, "path") == 0)
1476 modem_path = g_strdup(value);
1478 dbus_message_iter_next(&tmp);
1481 if (modem_path != NULL)
1482 __add_modem(modem_path, &dict);
1487 static gboolean __removed_modem(DBusConnection *connection,
1488 DBusMessage *message, void *user_data)
1490 DBusMessageIter iter;
1491 const char *modem_path;
1493 DBG("modem removed signal");
1495 if (dbus_message_iter_init(message, &iter) == FALSE) {
1496 DBG("error to read message");
1500 dbus_message_iter_get_basic(&iter, &modem_path);
1501 g_hash_table_remove(modem_hash, modem_path);
1506 static gboolean __changed_service(DBusConnection *connection,
1507 DBusMessage *message, void *user_data)
1509 DBusMessageIter args, dict;
1510 struct telephony_modem *modem;
1511 gboolean roaming_option = TRUE;
1512 struct telephony_service *s_service;
1513 const char *service_path = dbus_message_get_path(message);
1515 DBG("service changed signal %s", service_path);
1517 s_service = g_hash_table_lookup(service_hash, service_path);
1518 if (s_service == NULL) {
1519 DBG("service object does not exists");
1523 modem = s_service->p_modem;
1524 if (modem == NULL) {
1525 DBG("modem object does not exists");
1529 DBG("message signature (%s)", dbus_message_get_signature(message));
1531 if (dbus_message_iter_init(message, &args) == FALSE) {
1532 DBG("error to read message");
1536 dbus_message_iter_recurse(&args, &dict);
1538 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1539 DBusMessageIter entry;
1540 const char *key, *tmp;
1542 dbus_message_iter_recurse(&dict, &entry);
1543 dbus_message_iter_get_basic(&entry, &key);
1545 dbus_message_iter_next(&entry);
1546 dbus_message_iter_get_basic(&entry, &tmp);
1548 DBG("key(%s), value(%s)", key, tmp);
1550 if (g_strcmp0(key, "roaming") == 0) {
1551 s_service->roaming = STRING2BOOL(tmp);
1552 } else if (g_strcmp0(key, "act") == 0) {
1553 s_service->act = g_strdup(tmp);
1554 } else if (g_strcmp0(key, "ps_attached") == 0) {
1555 s_service->ps_attached = STRING2BOOL(tmp);
1558 dbus_message_iter_next(&dict);
1561 roaming_option &= (!s_service->roaming && !modem->roaming_allowed)
1562 || modem->roaming_allowed;
1567 static gboolean __added_service(DBusConnection *connection,
1568 DBusMessage *message, void *user_data)
1570 struct telephony_modem *modem;
1571 const char *service_path = NULL;
1572 DBusMessageIter args, dict, tmp;
1573 const char *path = dbus_message_get_path(message);
1575 DBG("service added signal %s", path);
1577 modem = g_hash_table_lookup(modem_hash, path);
1578 if (modem == NULL || modem->device == NULL)
1581 DBG("message signature (%s)", dbus_message_get_signature(message));
1582 if (dbus_message_iter_init(message, &args) == FALSE) {
1583 DBG("error to read message");
1587 dbus_message_iter_recurse(&args, &dict);
1588 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1590 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1591 DBusMessageIter entry;
1592 const char *key, *value;
1594 dbus_message_iter_recurse(&tmp, &entry);
1595 dbus_message_iter_get_basic(&entry, &key);
1597 dbus_message_iter_next(&entry);
1598 dbus_message_iter_get_basic(&entry, &value);
1600 DBG("key (%s) value(%s)", key, value);
1602 if (g_strcmp0(key, "path") == 0)
1603 service_path = value;
1605 dbus_message_iter_next(&tmp);
1608 if (service_path != NULL)
1609 __add_service(modem, service_path, &dict);
1614 static gboolean __removed_service(DBusConnection *connection,
1615 DBusMessage *message, void *user_data)
1617 DBusMessageIter iter;
1618 const char *service_path;
1620 DBG("service removed signal");
1622 if (dbus_message_iter_init(message, &iter) == FALSE) {
1623 DBG("error to read message");
1627 dbus_message_iter_get_basic(&iter, &service_path);
1628 g_hash_table_remove(service_hash, service_path);
1633 static gboolean __changed_context(DBusConnection *connection,
1634 DBusMessage *message, void *user_data)
1636 gboolean active = FALSE;
1637 DBusMessageIter args, dict;
1638 struct telephony_network *info;
1639 const char *path = dbus_message_get_path(message);
1641 DBG("network changed signal %s", path);
1643 info = g_hash_table_lookup(network_hash, path);
1647 if (__check_network_available(info->network) == FALSE) {
1648 g_hash_table_remove(network_hash, path);
1652 if (dbus_message_iter_init(message, &args) == FALSE) {
1653 DBG("error to read message");
1657 dbus_message_iter_recurse(&args, &dict);
1659 active = __set_network_context(info, &dict);
1660 if(info->routing_only){
1662 struct connman_service *routing_service;
1663 struct connman_ipconfig *routing_ipconfig;
1668 routing_service = connman_service_lookup_from_network(info->network);
1669 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1670 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1672 DBG("set gateway rv(%d)", err);
1676 __set_network_connected(info, active);
1678 if (active == FALSE &&
1679 connman_network_get_connecting(info->network) == TRUE)
1680 connman_network_set_connected(info->network, FALSE);
1685 static gboolean __added_context(DBusConnection *connection,
1686 DBusMessage *message, void *user_data)
1688 const char *network_path = NULL;
1689 DBusMessageIter args, dict, tmp;
1690 struct telephony_modem *modem = NULL;
1691 struct telephony_service *service = NULL;
1692 const char *path = dbus_message_get_path(message);
1694 DBG("network added signal %s", path);
1696 service = g_hash_table_lookup(service_hash, path);
1697 if (service == NULL || service->p_modem == NULL)
1700 modem = service->p_modem;
1701 if (modem == NULL || modem->device == NULL)
1704 DBG("message signature (%s)", dbus_message_get_signature(message));
1705 if (dbus_message_iter_init(message, &args) == FALSE) {
1706 DBG("error to read message");
1710 dbus_message_iter_recurse(&args, &dict);
1711 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1713 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1714 DBusMessageIter entry;
1715 const char *key, *value;
1717 dbus_message_iter_recurse(&tmp, &entry);
1718 dbus_message_iter_get_basic(&entry, &key);
1720 dbus_message_iter_next(&entry);
1721 dbus_message_iter_get_basic(&entry, &value);
1723 DBG("key (%s) value(%s)", key, value);
1725 if (g_strcmp0(key, "path") == 0)
1726 network_path = g_strdup(value);
1728 dbus_message_iter_next(&tmp);
1731 if (network_path != NULL)
1732 __add_context(modem->device, network_path, &dict);
1737 static gboolean __removed_context(DBusConnection *connection,
1738 DBusMessage *message, void *user_data)
1740 DBusMessageIter iter;
1741 const char *network_path = NULL;
1742 struct telephony_service *service = NULL;
1743 const char *path = dbus_message_get_path(message);
1745 DBG("network removed signal %s", path);
1747 service = g_hash_table_lookup(service_hash, path);
1748 if (service == NULL || service->p_modem == NULL)
1751 if (dbus_message_iter_init(message, &iter) == FALSE) {
1752 DBG("error to read message");
1756 dbus_message_iter_get_basic(&iter, &network_path);
1757 g_hash_table_remove(network_hash, network_path);
1762 static gboolean __changed_default_subscription(DBusConnection *connection,
1763 DBusMessage *message, void *user_data)
1765 DBusMessageIter args;
1767 DBG("message signature (%s)", dbus_message_get_signature(message));
1768 if (dbus_message_iter_init(message, &args) == FALSE)
1771 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
1772 DBG("default subscription: %d", telephony_default_subscription_id);
1777 /* telephony initialization */
1778 static guint watch = 0;
1779 static guint modem_watch = 0;
1780 static guint modem_added_watch = 0;
1781 static guint modem_removed_watch = 0;
1782 static guint service_watch = 0;
1783 static guint service_added_watch = 0;
1784 static guint service_removed_watch = 0;
1785 static guint context_watch = 0;
1786 static guint context_added_watch = 0;
1787 static guint context_removed_watch = 0;
1788 static guint default_subscription_watch = 0;
1790 static int telephony_init(void)
1794 DBG("telephony plugin");
1796 connection = connman_dbus_get_connection();
1797 if (connection == NULL)
1800 /* telephony watch */
1801 watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE,
1802 telephony_connect, telephony_disconnect,
1805 modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1811 modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1812 PS_MASTER_INTERFACE,
1817 modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1818 PS_MASTER_INTERFACE,
1823 service_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1824 PS_SERVICE_INTERFACE,
1829 service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1835 service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1841 context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1842 PS_CONTEXT_INTERFACE,
1847 context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1848 PS_SERVICE_INTERFACE,
1853 context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1854 PS_SERVICE_INTERFACE,
1859 default_subscription_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1860 "org.tizen.telephony.Network",
1861 "DefaultDataSubscription",
1862 __changed_default_subscription,
1865 if (watch == 0 || modem_watch == 0 || modem_added_watch == 0
1866 || modem_removed_watch == 0 || service_watch == 0
1867 || service_added_watch == 0 || context_watch == 0
1868 || service_removed_watch == 0
1869 || context_added_watch == 0
1870 || context_removed_watch == 0
1871 || default_subscription_watch == 0) {
1876 err = connman_network_driver_register(&network_driver);
1880 err = connman_device_driver_register(&modem_driver);
1882 connman_network_driver_unregister(&network_driver);
1886 err = connman_technology_driver_register(&tech_driver);
1888 connman_device_driver_unregister(&modem_driver);
1889 connman_network_driver_unregister(&network_driver);
1896 g_dbus_remove_watch(connection, watch);
1897 g_dbus_remove_watch(connection, modem_watch);
1898 g_dbus_remove_watch(connection, modem_added_watch);
1899 g_dbus_remove_watch(connection, modem_removed_watch);
1900 g_dbus_remove_watch(connection, service_watch);
1901 g_dbus_remove_watch(connection, service_added_watch);
1902 g_dbus_remove_watch(connection, service_removed_watch);
1903 g_dbus_remove_watch(connection, context_watch);
1904 g_dbus_remove_watch(connection, context_added_watch);
1905 g_dbus_remove_watch(connection, context_removed_watch);
1906 g_dbus_remove_watch(connection, default_subscription_watch);
1908 dbus_connection_unref(connection);
1912 static void telephony_exit(void)
1914 g_dbus_remove_watch(connection, watch);
1915 g_dbus_remove_watch(connection, modem_watch);
1916 g_dbus_remove_watch(connection, modem_added_watch);
1917 g_dbus_remove_watch(connection, modem_removed_watch);
1918 g_dbus_remove_watch(connection, service_watch);
1919 g_dbus_remove_watch(connection, service_added_watch);
1920 g_dbus_remove_watch(connection, service_removed_watch);
1921 g_dbus_remove_watch(connection, context_watch);
1922 g_dbus_remove_watch(connection, context_added_watch);
1923 g_dbus_remove_watch(connection, context_removed_watch);
1924 g_dbus_remove_watch(connection, default_subscription_watch);
1926 telephony_disconnect(connection, NULL);
1928 connman_device_driver_unregister(&modem_driver);
1929 connman_network_driver_unregister(&network_driver);
1931 dbus_connection_unref(connection);
1934 CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
1935 CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)