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);
396 if (dbus_connection_send_with_reply(connection, message,
397 &call, TIMEOUT) == FALSE) {
398 connman_error("Failed to call %s.%s", interface, method);
399 dbus_message_unref(message);
404 connman_error("D-Bus connection not available");
405 dbus_message_unref(message);
409 dbus_pending_call_set_notify(call, notify, user_data, free_function);
411 dbus_message_unref(message);
416 static int __request_get_modems(void)
418 DBG("request get modem");
419 /* call connect master */
420 return __dbus_request("/", PS_MASTER_INTERFACE, GET_MODEMS,
421 __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
424 static void __response_get_modems(DBusPendingCall *call, void *user_data)
428 DBusMessageIter args, dict;
432 reply = dbus_pending_call_steal_reply(call);
434 dbus_error_init(&error);
436 if (dbus_set_error_from_message(&error, reply)) {
437 connman_error("GetModems() %s %s", error.name, error.message);
438 dbus_error_free(&error);
442 DBG("message signature (%s)", dbus_message_get_signature(reply));
444 if (dbus_message_iter_init(reply, &args) == FALSE)
447 dbus_message_iter_recurse(&args, &dict);
449 /* DBG("message type (%d) dic(%d)",
450 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
453 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
454 DBusMessageIter entry, property;
455 const char *modem_path;
457 dbus_message_iter_recurse(&dict, &entry);
458 dbus_message_iter_get_basic(&entry, &modem_path);
459 DBG("modem path (%s)", modem_path);
461 dbus_message_iter_next(&entry);
462 dbus_message_iter_recurse(&entry, &property);
464 __add_modem(modem_path, &property);
466 dbus_message_iter_next(&dict);
470 dbus_message_unref(reply);
471 dbus_pending_call_unref(call);
474 static int __request_get_services(const char *path)
476 DBG("request get service");
477 return __dbus_request(path, PS_MODEM_INTERFACE, GET_SERVICES,
478 __response_get_services, g_strdup(path),
479 g_free, DBUS_TYPE_INVALID);
482 static void __response_get_services(DBusPendingCall *call, void *user_data)
486 DBusMessageIter args, dict;
488 const char *path = user_data;
489 struct telephony_modem *modem;
491 modem = g_hash_table_lookup(modem_hash, path);
494 if (modem->device == NULL)
499 reply = dbus_pending_call_steal_reply(call);
501 dbus_error_init(&error);
503 if (dbus_set_error_from_message(&error, reply)) {
504 connman_error("GetServices() %s %s", error.name, error.message);
505 dbus_error_free(&error);
509 DBG("message signature (%s)", dbus_message_get_signature(reply));
511 if (dbus_message_iter_init(reply, &args) == FALSE)
514 dbus_message_iter_recurse(&args, &dict);
516 /* DBG("message type (%d) dic(%d)",
517 * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
520 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
521 DBusMessageIter entry, property;
522 const char *service_path;
524 dbus_message_iter_recurse(&dict, &entry);
525 dbus_message_iter_get_basic(&entry, &service_path);
526 DBG("service path (%s)", service_path);
528 dbus_message_iter_next(&entry);
529 dbus_message_iter_recurse(&entry, &property);
531 __add_service(modem, service_path, &property);
533 dbus_message_iter_next(&dict);
537 dbus_message_unref(reply);
538 dbus_pending_call_unref(call);
541 static int __request_get_contexts(struct telephony_modem *modem)
543 DBG("request get contexts");
544 return __dbus_request(modem->s_service->path,
545 PS_SERVICE_INTERFACE, GET_CONTEXTS,
546 __response_get_contexts, g_strdup(modem->path),
547 g_free, DBUS_TYPE_INVALID);
550 static void __response_get_contexts(DBusPendingCall *call, void *user_data)
554 DBusMessageIter args, dict;
556 const char *path = user_data;
557 struct telephony_modem *modem;
561 modem = g_hash_table_lookup(modem_hash, path);
564 if (modem->s_service == NULL)
566 if (modem->device == NULL)
569 reply = dbus_pending_call_steal_reply(call);
571 dbus_error_init(&error);
573 if (dbus_set_error_from_message(&error, reply)) {
574 connman_error("GetContexts() %s %s", error.name, error.message);
575 dbus_error_free(&error);
579 DBG("message signature (%s)", dbus_message_get_signature(reply));
581 if (dbus_message_iter_init(reply, &args) == FALSE)
584 dbus_message_iter_recurse(&args, &dict);
586 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
587 DBusMessageIter entry, property;
588 const char *context_path;
590 dbus_message_iter_recurse(&dict, &entry);
591 dbus_message_iter_get_basic(&entry, &context_path);
592 DBG("context path (%s)", context_path);
594 dbus_message_iter_next(&entry);
595 dbus_message_iter_recurse(&entry, &property);
597 __add_context(modem->device, context_path, &property);
599 dbus_message_iter_next(&dict);
603 dbus_message_unref(reply);
604 dbus_pending_call_unref(call);
607 static int __request_network_activate(struct connman_network *network)
610 const char *path = NULL;
611 struct telephony_modem *modem = NULL;
613 n_modems = g_hash_table_size(modem_hash);
614 path = connman_network_get_string(network, "Path");
615 modem = connman_device_get_data(connman_network_get_device(network));
616 DBG("network %p, path %s, modem %s[%d]", network, path, modem->path,
617 telephony_default_subscription_id);
619 if (modem && n_modems > 1 && g_str_has_suffix(path, "_1") == TRUE) {
620 char *subscribe_id = g_strdup_printf("%d", telephony_default_subscription_id);
622 if (g_str_has_suffix(modem->path, subscribe_id) != TRUE) {
623 g_free(subscribe_id);
626 g_free(subscribe_id);
629 return __dbus_request(path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT,
630 __response_network_activate,
631 g_strdup(path), NULL, DBUS_TYPE_INVALID);
634 static gboolean __check_network_available(struct connman_network *network)
636 if (network == NULL || connman_network_get_device(network) == NULL)
642 static void __response_network_activate(DBusPendingCall *call, void *user_data)
644 DBG("network activation response");
649 struct telephony_network *info;
650 const char *path = user_data;
652 info = g_hash_table_lookup(network_hash, path);
653 reply = dbus_pending_call_steal_reply(call);
658 if (__check_network_available(info->network) == FALSE) {
659 g_hash_table_remove(network_hash, path);
663 dbus_error_init(&error);
664 if (dbus_set_error_from_message(&error, reply)) {
665 connman_error("connection activate() %s %s",
666 error.name, error.message);
668 if (connman_network_get_associating(info->network) == TRUE)
669 connman_network_set_error(info->network,
670 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
672 if (connman_network_get_connecting(info->network) == TRUE)
673 connman_network_set_error(info->network,
674 CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
676 if (connman_network_get_index(info->network) < 0)
677 connman_network_set_error(info->network,
678 CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
680 dbus_error_free(&error);
685 dbus_message_unref(reply);
686 dbus_pending_call_unref(call);
689 static int __request_network_deactivate(struct connman_network *network)
691 const char *path = connman_network_get_string(network, "Path");
692 DBG("network %p, path %s", network, path);
694 return __dbus_request(path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT,
695 NULL, NULL, NULL, DBUS_TYPE_INVALID);
698 static void __response_get_default_subscription_id(DBusPendingCall *call,
703 DBusMessageIter args;
707 reply = dbus_pending_call_steal_reply(call);
709 dbus_error_init(&error);
710 if (dbus_set_error_from_message(&error, reply)) {
711 connman_error("GetDefaultDataSubscription() %s %s", error.name, error.message);
712 dbus_error_free(&error);
716 DBG("message signature (%s)", dbus_message_get_signature(reply));
718 if (dbus_message_iter_init(reply, &args) == FALSE)
721 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
722 DBG("default subscription: %d", telephony_default_subscription_id);
725 dbus_message_unref(reply);
726 dbus_pending_call_unref(call);
729 static int __request_get_default_subscription_id(const char *path)
732 char *telephony_modem_path = NULL;
734 telephony_modem_path = g_strdup_printf("/org/tizen/telephony%s", path);
735 DBG("request get default subscription id %s", telephony_modem_path);
737 ret = __dbus_request(telephony_modem_path,
738 "org.tizen.telephony.Network", "GetDefaultDataSubscription",
739 __response_get_default_subscription_id, NULL, NULL, DBUS_TYPE_INVALID);
741 g_free(telephony_modem_path);
745 static void __add_modem(const char *path, DBusMessageIter *prop)
747 struct telephony_modem *modem;
749 modem = g_hash_table_lookup(modem_hash, path);
753 modem = g_try_new0(struct telephony_modem, 1);
757 modem->path = g_strdup(path);
758 modem->device = NULL;
759 modem->s_service = NULL;
761 g_hash_table_insert(modem_hash, g_strdup(path), modem);
763 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
764 DBusMessageIter entry;
765 const char *key, *tmp;
767 dbus_message_iter_recurse(prop, &entry);
768 dbus_message_iter_get_basic(&entry, &key);
770 dbus_message_iter_next(&entry);
771 dbus_message_iter_get_basic(&entry, &tmp);
773 DBG("key (%s) value(%s)", key, tmp);
775 if (g_strcmp0(key, "powered") == 0) {
776 modem->powered = STRING2BOOL(tmp);
777 } else if (g_strcmp0(key, "operator") == 0) {
778 modem->operator = g_strdup(tmp);
779 } else if (g_strcmp0(key, "sim_init") == 0) {
780 modem->sim_init = STRING2BOOL(tmp);
781 } else if (g_strcmp0(key, "flight_mode") == 0) {
782 modem->flight_mode = STRING2BOOL(tmp);
783 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
784 modem->roaming_allowed = STRING2BOOL(tmp);
785 } else if (g_strcmp0(key, "data_allowed") == 0) {
786 modem->data_allowed = STRING2BOOL(tmp);
788 dbus_message_iter_next(prop);
791 __add_connman_device(path, modem->operator);
792 __set_device_powered(modem, modem->powered);
794 if (g_hash_table_size(modem_hash) > 1)
795 __request_get_default_subscription_id(modem->path);
797 if (modem->powered != TRUE) {
798 DBG("modem is not powered");
802 __request_get_services(modem->path);
805 static void __add_service(struct telephony_modem *modem,
806 const char *service_path, DBusMessageIter *prop)
808 struct telephony_service *service;
810 if (modem->s_service != NULL)
813 service = g_try_new0(struct telephony_service, 1);
817 service->path = g_strdup(service_path);
818 service->p_modem = modem;
819 g_hash_table_insert(service_hash, g_strdup(service_path), service);
821 while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
822 DBusMessageIter entry;
823 const char *key, *tmp;
825 dbus_message_iter_recurse(prop, &entry);
826 dbus_message_iter_get_basic(&entry, &key);
828 dbus_message_iter_next(&entry);
829 dbus_message_iter_get_basic(&entry, &tmp);
831 DBG("key (%s) value(%s)", key, tmp);
833 if (g_strcmp0(key, "roaming") == 0) {
834 service->roaming = STRING2BOOL(tmp);
835 } else if (g_strcmp0(key, "act") == 0) {
836 service->act = g_strdup(tmp);
837 } else if (g_strcmp0(key, "ps_attached") == 0) {
838 service->ps_attached = STRING2BOOL(tmp);
841 dbus_message_iter_next(prop);
844 modem->s_service = service;
845 __request_get_contexts(modem);
848 static char *__get_ident(const char *path)
855 pos = strrchr(path, '/');
862 static void __add_connman_device(const char *modem_path, const char *operator)
865 struct telephony_modem *modem;
866 struct connman_device *device;
868 DBG("path %s operator %s", modem_path, operator);
870 if (modem_path == NULL)
873 if (operator == NULL)
876 modem = g_hash_table_lookup(modem_hash, modem_path);
881 if (!g_strcmp0(operator,
882 connman_device_get_ident(modem->device)))
885 __remove_connman_device(modem);
888 if (strlen(operator) == 0)
891 device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
895 ident = g_strdup_printf("%s_%s", __get_ident(modem_path), operator);
896 connman_device_set_ident(device, ident);
899 connman_device_set_string(device, "Path", modem_path);
900 connman_device_set_data(device, modem);
902 if (connman_device_register(device) < 0) {
903 connman_error("Failed to register cellular device");
904 connman_device_unref(device);
908 modem->device = device;
911 static void __remove_connman_device(struct telephony_modem *modem)
913 DBG("modem %p path %s device %p", modem, modem->path, modem->device);
915 if (modem->device == NULL)
918 __remove_connman_networks(modem->device);
920 connman_device_unregister(modem->device);
921 connman_device_unref(modem->device);
923 modem->device = NULL;
926 static void __remove_connman_networks(struct connman_device *device)
930 GSList *info_list = NULL;
933 if (network_hash == NULL)
936 g_hash_table_iter_init(&iter, network_hash);
938 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
939 struct telephony_network *info = value;
941 if (connman_network_get_device(info->network) != device)
944 info_list = g_slist_append(info_list, info);
947 for (list = info_list; list != NULL; list = list->next) {
948 struct telephony_network *info = list->data;
949 connman_device_remove_network(device, info->network);
952 g_slist_free(info_list);
955 static gboolean connman_ipaddress_updated(struct connman_ipaddress *ipaddress,
956 const char *address, const char *gateway)
958 if (ipaddress == NULL || address == NULL)
961 if (g_strcmp0(ipaddress->local, address) != 0)
964 if (g_strcmp0(ipaddress->gateway, gateway) != 0)
970 static void __set_network_connected(struct telephony_network *network,
973 gboolean setip = FALSE;
975 DBG("network %p connected %d", network, connected);
977 connman_network_set_index(network->network, network->if_index);
978 if (connman_network_get_connected(network->network) == connected)
981 switch (network->ipv4_method) {
982 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
983 case CONNMAN_IPCONFIG_METHOD_DHCP:
984 case CONNMAN_IPCONFIG_METHOD_AUTO:
985 case CONNMAN_IPCONFIG_METHOD_OFF:
986 connman_network_set_ipv4_method(network->network,
987 network->ipv4_method);
989 case CONNMAN_IPCONFIG_METHOD_MANUAL:
990 case CONNMAN_IPCONFIG_METHOD_FIXED:
991 connman_network_set_ipv4_method(network->network,
992 network->ipv4_method);
993 connman_network_set_ipaddress(network->network,
994 network->ipv4_address);
999 switch (network->ipv6_method) {
1000 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1001 case CONNMAN_IPCONFIG_METHOD_OFF:
1002 case CONNMAN_IPCONFIG_METHOD_DHCP:
1004 case CONNMAN_IPCONFIG_METHOD_AUTO:
1005 connman_network_set_ipv6_method(network->network,
1006 network->ipv6_method);
1009 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1010 case CONNMAN_IPCONFIG_METHOD_FIXED:
1011 connman_network_set_ipv6_method(network->network,
1012 network->ipv6_method);
1013 connman_network_set_ipaddress(network->network,
1014 network->ipv6_address);
1020 connman_network_set_connected(network->network, connected);
1023 static gboolean __set_network_context(
1024 struct telephony_network *network,
1025 DBusMessageIter *dict)
1028 gboolean active = FALSE;
1029 gboolean routing_only = FALSE;
1030 gboolean ipv4_updated = FALSE;
1031 gboolean ipv6_updated = FALSE;
1032 gboolean ipv6_link_only = FALSE;
1033 gboolean default_internet = FALSE;
1034 gboolean active_proxy = FALSE;
1035 char **proxies = NULL;
1036 const char *dev_name = NULL;
1037 const char *proxy_addr = NULL;
1038 char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL,
1039 *ipv4_dns1 = NULL, *ipv4_dns2 = NULL;
1040 char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL,
1041 *ipv6_dns1 = NULL, *ipv6_dns2 = NULL;
1042 struct connman_service *service;
1044 while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
1045 DBusMessageIter entry;
1046 const char *key, *value;
1048 dbus_message_iter_recurse(dict, &entry);
1049 dbus_message_iter_get_basic(&entry, &key);
1051 dbus_message_iter_next(&entry);
1053 if (g_strcmp0(key, "dev_name") == 0) {
1054 dbus_message_iter_get_basic(&entry, &dev_name);
1055 DBG("dev_name (%s)", dev_name);
1056 } else if (g_strcmp0(key, "proxy") == 0) {
1057 dbus_message_iter_get_basic(&entry, &proxy_addr);
1058 DBG("proxy_addr (%s)", proxy_addr);
1059 } else if (g_strcmp0(key, "ipv4_address") == 0) {
1060 dbus_message_iter_get_basic(&entry, &ipv4_addr);
1061 DBG("ipv4_addr (%s)", ipv4_addr);
1062 } else if (g_strcmp0(key, "ipv4_gateway") == 0) {
1063 dbus_message_iter_get_basic(&entry, &ipv4_gw);
1064 DBG("ipv4_gw (%s)", ipv4_gw);
1065 } else if (g_strcmp0(key, "ipv4_netmask") == 0) {
1066 dbus_message_iter_get_basic(&entry, &ipv4_netmask);
1067 DBG("ipv4_netmask (%s)", ipv4_netmask);
1068 } else if (g_strcmp0(key, "ipv4_dns1") == 0) {
1069 dbus_message_iter_get_basic(&entry, &ipv4_dns1);
1070 DBG("ipv4_dns1 (%s)", ipv4_dns1);
1071 } else if (g_strcmp0(key, "ipv4_dns2") == 0) {
1072 dbus_message_iter_get_basic(&entry, &ipv4_dns2);
1073 DBG("ipv4_dns2 (%s)", ipv4_dns2);
1074 } else if (g_strcmp0(key, "ipv6_address") == 0) {
1075 dbus_message_iter_get_basic(&entry, &ipv6_addr);
1076 DBG("ipv6 address (%s)", ipv6_addr);
1077 } else if (g_strcmp0(key, "ipv6_gateway") == 0) {
1078 dbus_message_iter_get_basic(&entry, &ipv6_gw);
1079 DBG("ipv6_gw (%s)", ipv6_gw);
1080 } else if (g_strcmp0(key, "ipv6_netmask") == 0) {
1081 dbus_message_iter_get_basic(&entry, &ipv6_netmask);
1082 DBG("ipv6_netmask (%s)", ipv6_netmask);
1083 } else if (g_strcmp0(key, "ipv6_dns1") == 0) {
1084 dbus_message_iter_get_basic(&entry, &ipv6_dns1);
1085 DBG("ipv6_dns1 (%s)", ipv6_dns1);
1086 } else if (g_strcmp0(key, "ipv6_dns2") == 0) {
1087 dbus_message_iter_get_basic(&entry, &ipv6_dns2);
1088 DBG("ipv6_dns2 (%s)", ipv6_dns2);
1089 } else if (g_strcmp0(key, "active") == 0) {
1090 dbus_message_iter_get_basic(&entry, &value);
1091 DBG("active (%s)", value);
1092 active = STRING2BOOL(value);
1093 } else if (g_strcmp0(key, "routing_only") == 0) {
1094 dbus_message_iter_get_basic(&entry, &value);
1095 DBG("routing_only (%s)", value);
1096 routing_only = STRING2BOOL(value);
1097 network->routing_only = routing_only;
1098 } else if (g_strcmp0(key, "ipv6_link_only") == 0) {
1099 dbus_message_iter_get_basic(&entry, &value);
1100 DBG("ipv6_link_only (%s)", value);
1101 ipv6_link_only = STRING2BOOL(value);
1102 network->ipv6_link_only = ipv6_link_only;
1104 else if (g_strcmp0(key, "default_internet_conn") == 0) {
1105 dbus_message_iter_get_basic(&entry, &value);
1106 DBG("default_internet (%s)", value);
1107 default_internet = STRING2BOOL(value);
1110 dbus_message_iter_next(dict);
1114 //context active does not effect the connman service status.
1115 //it only for setting the routing path.
1116 DBG("routing_only(%d), active(%d)", routing_only, active);
1120 if (g_strcmp0(proxy_addr, ":") == 0)
1122 if (g_strcmp0(ipv4_addr, "0.0.0.0") == 0)
1124 if (g_strcmp0(ipv4_gw, "0.0.0.0") == 0)
1126 if (g_strcmp0(ipv4_netmask, "0.0.0.0") == 0)
1127 ipv4_netmask = NULL;
1128 if (g_strcmp0(ipv4_dns1, "0.0.0.0") == 0)
1130 if (g_strcmp0(ipv4_dns2, "0.0.0.0") == 0)
1132 if (g_strcmp0(ipv6_addr, "::") == 0)
1134 if (g_strcmp0(ipv6_gw, "::") == 0)
1136 if (g_strcmp0(ipv6_netmask, "::") == 0)
1137 ipv6_netmask = NULL;
1138 if (g_strcmp0(ipv6_dns1, "::") == 0)
1140 if (g_strcmp0(ipv6_dns2, "::") == 0)
1143 connman_network_set_bool(network->network, "DefaultInternet",
1144 (bool)default_internet);
1146 service = connman_service_lookup_from_network(network->network);
1147 if (service == NULL)
1150 if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
1151 /* Wi-Fi technology is always a top priority */
1152 if (active == TRUE &&
1153 connman_service_is_no_ref_user_pdn_connection(service) == TRUE &&
1154 connman_service_get_type(connman_service_get_default_connection())
1155 == CONNMAN_SERVICE_TYPE_WIFI) {
1156 __request_network_deactivate(network->network);
1162 /* interface index set */
1163 if (dev_name != NULL) {
1164 index = connman_inet_ifindex(dev_name);
1165 network->if_index = index;
1166 DBG("interface index %d", index);
1170 if (active == TRUE &&
1171 connman_network_get_connected(network->network) == TRUE)
1172 active_proxy = TRUE;
1174 proxies = connman_service_get_proxy_servers(service);
1175 if (proxies != NULL) {
1176 if (proxy_addr == NULL)
1177 connman_service_set_proxy(service, proxy_addr, active_proxy);
1178 else if (g_strcmp0(proxy_addr, proxies[0]) != 0)
1179 connman_service_set_proxy(service, proxy_addr, active_proxy);
1180 } else if (proxy_addr != NULL)
1181 connman_service_set_proxy(service, proxy_addr, active_proxy);
1183 if (proxies != NULL)
1184 g_strfreev(proxies);
1186 __connman_service_nameserver_clear(service);
1189 if (network->ipv4_address == NULL)
1190 network->ipv4_address =
1191 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
1193 if (network->ipv4_address == NULL)
1196 if (ipv4_addr == NULL && active == TRUE)
1197 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
1199 network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1201 connman_network_set_ipv4_method(network->network, network->ipv4_method);
1203 ipv4_updated = connman_ipaddress_updated(network->ipv4_address,
1204 ipv4_addr, ipv4_gw);
1205 if (ipv4_updated == TRUE)
1206 connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr,
1207 ipv4_netmask, ipv4_gw);
1210 __connman_service_nameserver_append(service, ipv4_dns1, FALSE);
1212 if (ipv4_dns2 && !ipv4_dns1)
1213 __connman_service_nameserver_append(service, ipv4_dns2, FALSE);
1216 if (network->ipv6_address == NULL)
1217 network->ipv6_address =
1218 connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
1220 if (network->ipv6_address == NULL)
1224 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO;
1226 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1228 if (ipv6_addr == NULL)
1229 network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
1231 connman_network_set_ipv6_method(network->network, network->ipv6_method);
1233 ipv6_updated = connman_ipaddress_updated(network->ipv6_address,
1234 ipv6_addr, ipv6_gw);
1235 if (ipv6_updated == TRUE)
1236 connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr,
1240 __connman_service_nameserver_append(service, ipv6_dns1, FALSE);
1242 if (ipv6_dns2 && !ipv6_dns1)
1243 __connman_service_nameserver_append(service, ipv6_dns2, FALSE);
1245 if (active == TRUE &&
1246 connman_network_get_connected(network->network) == TRUE) {
1247 if (ipv4_updated == TRUE || ipv6_updated == TRUE) {
1248 DBG("IPv4 updated %d, IPv6 updated %d", ipv4_updated, ipv6_updated);
1250 __set_network_connected(network, FALSE);
1252 DBG("Already connected");
1259 connman_network_set_associating(network->network, TRUE);
1264 static int __add_context(struct connman_device *device, const char *path,
1265 DBusMessageIter *prop)
1268 gboolean active = FALSE;
1270 struct telephony_modem *modem = connman_device_get_data(device);
1271 struct connman_network *network;
1272 struct telephony_network *info;
1274 DBG("modem %p device %p path %s", modem, device, path);
1276 ident = __get_ident(path);
1278 network = connman_device_get_network(device, ident);
1279 if (network != NULL)
1282 info = g_hash_table_lookup(network_hash, path);
1284 DBG("path %p already exists with device %p", path,
1285 connman_network_get_device(info->network));
1287 if (connman_network_get_device(info->network))
1290 g_hash_table_remove(network_hash, path);
1293 network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
1294 if (network == NULL)
1297 info = g_try_new0(struct telephony_network, 1);
1299 connman_network_unref(network);
1303 info->path = g_strdup(path);
1305 connman_ipaddress_clear(info->ipv4_address);
1306 connman_ipaddress_clear(info->ipv6_address);
1308 info->network = network;
1310 connman_network_set_string(network, "Path", path);
1311 connman_network_set_name(network, path);
1313 connman_network_set_group(network, ident);
1315 g_hash_table_insert(network_hash, g_strdup(path), info);
1317 connman_network_set_available(network, TRUE);
1318 connman_network_set_bool(network, "Roaming", (bool)modem->s_service->roaming);
1320 if (connman_device_add_network(device, network) != 0) {
1321 g_hash_table_remove(network_hash, path);
1325 active = __set_network_context(info, prop);
1326 if(info->routing_only){
1328 struct connman_service *routing_service;
1329 struct connman_ipconfig *routing_ipconfig;
1334 routing_service = connman_service_lookup_from_network(info->network);
1335 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1336 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1338 DBG("set gateway rv(%d)", err);
1342 if (active == TRUE && (connman_network_get_associating(network) == TRUE ||
1343 connman_network_get_connecting(network) == TRUE))
1344 __set_network_connected(info, active);
1349 static gboolean __changed_modem(DBusConnection *connection,
1350 DBusMessage *message, void *user_data)
1352 gboolean old_powered;
1353 DBusMessageIter args, dict;
1354 struct telephony_modem *modem;
1355 const char *path = dbus_message_get_path(message);
1357 DBG("modem changed signal %s", path);
1359 modem = g_hash_table_lookup(modem_hash, path);
1360 if (modem == NULL) {
1361 DBG("modem object does not exists");
1365 old_powered = modem->powered;
1367 DBG("message signature (%s)", dbus_message_get_signature(message));
1369 if (dbus_message_iter_init(message, &args) == FALSE) {
1370 DBG("error to read message");
1374 dbus_message_iter_recurse(&args, &dict);
1376 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1377 DBusMessageIter entry;
1378 const char *key, *tmp;
1380 dbus_message_iter_recurse(&dict, &entry);
1381 dbus_message_iter_get_basic(&entry, &key);
1383 dbus_message_iter_next(&entry);
1384 dbus_message_iter_get_basic(&entry, &tmp);
1386 DBG("key(%s), value(%s)", key, tmp);
1388 if (g_strcmp0(key, "powered") == 0) {
1389 modem->powered = STRING2BOOL(tmp);
1390 } else if (g_strcmp0(key, "operator") == 0) {
1391 modem->operator = g_strdup(tmp);
1392 } else if (g_strcmp0(key, "sim_init") == 0) {
1393 modem->sim_init = STRING2BOOL(tmp);
1394 } else if (g_strcmp0(key, "flight_mode") == 0) {
1395 modem->flight_mode = STRING2BOOL(tmp);
1396 } else if (g_strcmp0(key, "roaming_allowed") == 0) {
1397 modem->roaming_allowed = STRING2BOOL(tmp);
1398 } else if (g_strcmp0(key, "data_allowed") == 0) {
1399 modem->data_allowed = STRING2BOOL(tmp);
1402 dbus_message_iter_next(&dict);
1405 if (modem->device == NULL)
1406 __add_connman_device(path, modem->operator);
1408 if (old_powered != modem->powered)
1409 __set_device_powered(modem, modem->powered);
1411 if (modem->powered != TRUE) {
1412 DBG("modem is not powered");
1416 if (modem->s_service == NULL) {
1417 __request_get_services(modem->path);
1421 DBG("modem(%s) flight mode(%d) data allowed(%d)",
1422 modem->path, modem->flight_mode, modem->data_allowed);
1427 static gboolean __added_modem(DBusConnection *connection,
1428 DBusMessage *message, void *user_data)
1430 const char *modem_path = NULL;
1431 DBusMessageIter args, dict, tmp;
1433 DBG("modem added signal (%s)", dbus_message_get_signature(message));
1435 if (dbus_message_iter_init(message, &args) == FALSE) {
1436 DBG("error to read message");
1440 dbus_message_iter_recurse(&args, &dict);
1441 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1443 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1444 DBusMessageIter entry;
1445 const char *key, *value;
1447 dbus_message_iter_recurse(&tmp, &entry);
1448 dbus_message_iter_get_basic(&entry, &key);
1450 dbus_message_iter_next(&entry);
1451 dbus_message_iter_get_basic(&entry, &value);
1453 DBG("key (%s) value(%s)", key, value);
1455 if (g_strcmp0(key, "path") == 0)
1456 modem_path = g_strdup(value);
1458 dbus_message_iter_next(&tmp);
1461 if (modem_path != NULL)
1462 __add_modem(modem_path, &dict);
1467 static gboolean __removed_modem(DBusConnection *connection,
1468 DBusMessage *message, void *user_data)
1470 DBusMessageIter iter;
1471 const char *modem_path;
1473 DBG("modem removed signal");
1475 if (dbus_message_iter_init(message, &iter) == FALSE) {
1476 DBG("error to read message");
1480 dbus_message_iter_get_basic(&iter, &modem_path);
1481 g_hash_table_remove(modem_hash, modem_path);
1486 static gboolean __changed_service(DBusConnection *connection,
1487 DBusMessage *message, void *user_data)
1489 DBusMessageIter args, dict;
1490 struct telephony_modem *modem;
1491 gboolean roaming_option = TRUE;
1492 struct telephony_service *s_service;
1493 const char *service_path = dbus_message_get_path(message);
1495 DBG("service changed signal %s", service_path);
1497 s_service = g_hash_table_lookup(service_hash, service_path);
1498 if (s_service == NULL) {
1499 DBG("service object does not exists");
1503 modem = s_service->p_modem;
1504 if (modem == NULL) {
1505 DBG("modem object does not exists");
1509 DBG("message signature (%s)", dbus_message_get_signature(message));
1511 if (dbus_message_iter_init(message, &args) == FALSE) {
1512 DBG("error to read message");
1516 dbus_message_iter_recurse(&args, &dict);
1518 while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1519 DBusMessageIter entry;
1520 const char *key, *tmp;
1522 dbus_message_iter_recurse(&dict, &entry);
1523 dbus_message_iter_get_basic(&entry, &key);
1525 dbus_message_iter_next(&entry);
1526 dbus_message_iter_get_basic(&entry, &tmp);
1528 DBG("key(%s), value(%s)", key, tmp);
1530 if (g_strcmp0(key, "roaming") == 0) {
1531 s_service->roaming = STRING2BOOL(tmp);
1532 } else if (g_strcmp0(key, "act") == 0) {
1533 s_service->act = g_strdup(tmp);
1534 } else if (g_strcmp0(key, "ps_attached") == 0) {
1535 s_service->ps_attached = STRING2BOOL(tmp);
1538 dbus_message_iter_next(&dict);
1541 roaming_option &= (!s_service->roaming && !modem->roaming_allowed)
1542 || modem->roaming_allowed;
1547 static gboolean __added_service(DBusConnection *connection,
1548 DBusMessage *message, void *user_data)
1550 struct telephony_modem *modem;
1551 const char *service_path = NULL;
1552 DBusMessageIter args, dict, tmp;
1553 const char *path = dbus_message_get_path(message);
1555 DBG("service added signal %s", path);
1557 modem = g_hash_table_lookup(modem_hash, path);
1558 if (modem == NULL || modem->device == NULL)
1561 DBG("message signature (%s)", dbus_message_get_signature(message));
1562 if (dbus_message_iter_init(message, &args) == FALSE) {
1563 DBG("error to read message");
1567 dbus_message_iter_recurse(&args, &dict);
1568 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1570 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1571 DBusMessageIter entry;
1572 const char *key, *value;
1574 dbus_message_iter_recurse(&tmp, &entry);
1575 dbus_message_iter_get_basic(&entry, &key);
1577 dbus_message_iter_next(&entry);
1578 dbus_message_iter_get_basic(&entry, &value);
1580 DBG("key (%s) value(%s)", key, value);
1582 if (g_strcmp0(key, "path") == 0)
1583 service_path = value;
1585 dbus_message_iter_next(&tmp);
1588 if (service_path != NULL)
1589 __add_service(modem, service_path, &dict);
1594 static gboolean __removed_service(DBusConnection *connection,
1595 DBusMessage *message, void *user_data)
1597 DBusMessageIter iter;
1598 const char *service_path;
1600 DBG("service removed signal");
1602 if (dbus_message_iter_init(message, &iter) == FALSE) {
1603 DBG("error to read message");
1607 dbus_message_iter_get_basic(&iter, &service_path);
1608 g_hash_table_remove(service_hash, service_path);
1613 static gboolean __changed_context(DBusConnection *connection,
1614 DBusMessage *message, void *user_data)
1616 gboolean active = FALSE;
1617 DBusMessageIter args, dict;
1618 struct telephony_network *info;
1619 const char *path = dbus_message_get_path(message);
1621 DBG("network changed signal %s", path);
1623 info = g_hash_table_lookup(network_hash, path);
1627 if (__check_network_available(info->network) == FALSE) {
1628 g_hash_table_remove(network_hash, path);
1632 if (dbus_message_iter_init(message, &args) == FALSE) {
1633 DBG("error to read message");
1637 dbus_message_iter_recurse(&args, &dict);
1639 active = __set_network_context(info, &dict);
1640 if(info->routing_only){
1642 struct connman_service *routing_service;
1643 struct connman_ipconfig *routing_ipconfig;
1648 routing_service = connman_service_lookup_from_network(info->network);
1649 routing_ipconfig = __connman_service_get_ip4config(routing_service);
1650 err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
1652 DBG("set gateway rv(%d)", err);
1656 __set_network_connected(info, active);
1658 if (active == FALSE &&
1659 connman_network_get_connecting(info->network) == TRUE)
1660 connman_network_set_connected(info->network, FALSE);
1665 static gboolean __added_context(DBusConnection *connection,
1666 DBusMessage *message, void *user_data)
1668 const char *network_path = NULL;
1669 DBusMessageIter args, dict, tmp;
1670 struct telephony_modem *modem = NULL;
1671 struct telephony_service *service = NULL;
1672 const char *path = dbus_message_get_path(message);
1674 DBG("network added signal %s", path);
1676 service = g_hash_table_lookup(service_hash, path);
1677 if (service == NULL || service->p_modem == NULL)
1680 modem = service->p_modem;
1681 if (modem == NULL || modem->device == NULL)
1684 DBG("message signature (%s)", dbus_message_get_signature(message));
1685 if (dbus_message_iter_init(message, &args) == FALSE) {
1686 DBG("error to read message");
1690 dbus_message_iter_recurse(&args, &dict);
1691 memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1693 while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1694 DBusMessageIter entry;
1695 const char *key, *value;
1697 dbus_message_iter_recurse(&tmp, &entry);
1698 dbus_message_iter_get_basic(&entry, &key);
1700 dbus_message_iter_next(&entry);
1701 dbus_message_iter_get_basic(&entry, &value);
1703 DBG("key (%s) value(%s)", key, value);
1705 if (g_strcmp0(key, "path") == 0)
1706 network_path = g_strdup(value);
1708 dbus_message_iter_next(&tmp);
1711 if (network_path != NULL)
1712 __add_context(modem->device, network_path, &dict);
1717 static gboolean __removed_context(DBusConnection *connection,
1718 DBusMessage *message, void *user_data)
1720 DBusMessageIter iter;
1721 const char *network_path = NULL;
1722 struct telephony_service *service = NULL;
1723 const char *path = dbus_message_get_path(message);
1725 DBG("network removed signal %s", path);
1727 service = g_hash_table_lookup(service_hash, path);
1728 if (service == NULL || service->p_modem == NULL)
1731 if (dbus_message_iter_init(message, &iter) == FALSE) {
1732 DBG("error to read message");
1736 dbus_message_iter_get_basic(&iter, &network_path);
1737 g_hash_table_remove(network_hash, network_path);
1742 static gboolean __changed_default_subscription(DBusConnection *connection,
1743 DBusMessage *message, void *user_data)
1745 DBusMessageIter args;
1747 DBG("message signature (%s)", dbus_message_get_signature(message));
1748 if (dbus_message_iter_init(message, &args) == FALSE)
1751 dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
1752 DBG("default subscription: %d", telephony_default_subscription_id);
1757 /* telephony initialization */
1758 static guint watch = 0;
1759 static guint modem_watch = 0;
1760 static guint modem_added_watch = 0;
1761 static guint modem_removed_watch = 0;
1762 static guint service_watch = 0;
1763 static guint service_added_watch = 0;
1764 static guint service_removed_watch = 0;
1765 static guint context_watch = 0;
1766 static guint context_added_watch = 0;
1767 static guint context_removed_watch = 0;
1768 static guint default_subscription_watch = 0;
1770 static int telephony_init(void)
1774 DBG("telephony plugin");
1776 connection = connman_dbus_get_connection();
1777 if (connection == NULL)
1780 /* telephony watch */
1781 watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE,
1782 telephony_connect, telephony_disconnect,
1785 modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1791 modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1792 PS_MASTER_INTERFACE,
1797 modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1798 PS_MASTER_INTERFACE,
1803 service_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1804 PS_SERVICE_INTERFACE,
1809 service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1815 service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1821 context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1822 PS_CONTEXT_INTERFACE,
1827 context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1828 PS_SERVICE_INTERFACE,
1833 context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1834 PS_SERVICE_INTERFACE,
1839 default_subscription_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1840 "org.tizen.telephony.Network",
1841 "DefaultDataSubscription",
1842 __changed_default_subscription,
1845 if (watch == 0 || modem_watch == 0 || modem_added_watch == 0
1846 || modem_removed_watch == 0 || service_watch == 0
1847 || service_added_watch == 0 || context_watch == 0
1848 || service_removed_watch == 0
1849 || context_added_watch == 0
1850 || context_removed_watch == 0
1851 || default_subscription_watch == 0) {
1856 err = connman_network_driver_register(&network_driver);
1860 err = connman_device_driver_register(&modem_driver);
1862 connman_network_driver_unregister(&network_driver);
1866 err = connman_technology_driver_register(&tech_driver);
1868 connman_device_driver_unregister(&modem_driver);
1869 connman_network_driver_unregister(&network_driver);
1876 g_dbus_remove_watch(connection, watch);
1877 g_dbus_remove_watch(connection, modem_watch);
1878 g_dbus_remove_watch(connection, modem_added_watch);
1879 g_dbus_remove_watch(connection, modem_removed_watch);
1880 g_dbus_remove_watch(connection, service_watch);
1881 g_dbus_remove_watch(connection, service_added_watch);
1882 g_dbus_remove_watch(connection, service_removed_watch);
1883 g_dbus_remove_watch(connection, context_watch);
1884 g_dbus_remove_watch(connection, context_added_watch);
1885 g_dbus_remove_watch(connection, context_removed_watch);
1886 g_dbus_remove_watch(connection, default_subscription_watch);
1888 dbus_connection_unref(connection);
1892 static void telephony_exit(void)
1894 g_dbus_remove_watch(connection, watch);
1895 g_dbus_remove_watch(connection, modem_watch);
1896 g_dbus_remove_watch(connection, modem_added_watch);
1897 g_dbus_remove_watch(connection, modem_removed_watch);
1898 g_dbus_remove_watch(connection, service_watch);
1899 g_dbus_remove_watch(connection, service_added_watch);
1900 g_dbus_remove_watch(connection, service_removed_watch);
1901 g_dbus_remove_watch(connection, context_watch);
1902 g_dbus_remove_watch(connection, context_added_watch);
1903 g_dbus_remove_watch(connection, context_removed_watch);
1904 g_dbus_remove_watch(connection, default_subscription_watch);
1906 telephony_disconnect(connection, NULL);
1908 connman_device_driver_unregister(&modem_driver);
1909 connman_network_driver_unregister(&network_driver);
1911 dbus_connection_unref(connection);
1914 CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
1915 CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)