1 From f5af9712213cb0da9e5066e0a2fcf8fbedccc075 Mon Sep 17 00:00:00 2001
2 From: Arron Wang <arron.wang@intel.com>
3 Date: Wed, 10 Oct 2012 09:56:13 +0800
4 Subject: [PATCH 12/32] Tizen: Integrate telephony plugin
6 Change-Id: Ia178f5de981501296573bf3f48e329d5a1355af6
8 Makefile.plugins | 12 +
10 packaging/connman.spec | 2 +
11 plugins/telephony.c | 1757 ++++++++++++++++++++++++++++++++++++++++++++++++
12 4 files changed, 1777 insertions(+)
13 create mode 100644 plugins/telephony.c
15 diff --git a/Makefile.plugins b/Makefile.plugins
16 index e90ad19..83ad8fb 100644
17 --- a/Makefile.plugins
18 +++ b/Makefile.plugins
19 @@ -55,6 +55,18 @@ builtin_modules += dundee
20 builtin_sources += plugins/dundee.c
25 +builtin_modules += telephony
26 +builtin_sources += plugins/telephony.c
28 +plugin_LTLIBRARIES += plugins/telephony.la
29 +plugin_objects += $(plugins_telephony_la_OBJECTS)
30 +plugins_telephony_la_CFLAGS = $(plugin_cflags)
31 +plugins_telephony_la_LDFLAGS = $(plugin_ldflags)
36 builtin_modules += vpn
37 builtin_sources += plugins/vpn.c
38 diff --git a/configure.ac b/configure.ac
39 index 6f35c78..dee2dcb 100644
42 @@ -61,6 +61,12 @@ AC_ARG_ENABLE(hh2serial-gps,
43 AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no")
44 AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin")
46 +AC_ARG_ENABLE(telephony,
47 + AC_HELP_STRING([--enable-telephony], [enable Telephony support]),
48 + [enable_telephony=${enableval}], [enable_telephony="yes"])
49 +AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
50 +AM_CONDITIONAL(TELEPHONY_BUILTIN, test "${enable_telephony}" = "builtin")
52 AC_ARG_WITH(openconnect, AC_HELP_STRING([--with-openconnect=PROGRAM],
53 [specify location of openconnect binary]), [path_openconnect=${withval}])
55 diff --git a/packaging/connman.spec b/packaging/connman.spec
56 index edc1d53..f4faf92 100644
57 --- a/packaging/connman.spec
58 +++ b/packaging/connman.spec
59 @@ -152,6 +152,8 @@ systemctl daemon-reload
60 %manifest %{name}.manifest
63 +%{_libdir}/connman/plugins/*.so
65 %config %{_sysconfdir}/connman/main.conf
66 %config %{_sysconfdir}/dbus-1/system.d/*
67 %{_unitdir}/connman.service
68 diff --git a/plugins/telephony.c b/plugins/telephony.c
70 index 0000000..63e7f6e
72 +++ b/plugins/telephony.c
76 + * Connection Manager
78 + * Copyright (C) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
80 + * This program is free software; you can redistribute it and/or modify
81 + * it under the terms of the GNU General Public License version 2 as
82 + * published by the Free Software Foundation.
84 + * This program is distributed in the hope that it will be useful,
85 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
86 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87 + * GNU General Public License for more details.
89 + * You should have received a copy of the GNU General Public License
90 + * along with this program; if not, write to the Free Software
91 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
106 +#define CONNMAN_API_SUBJECT_TO_CHANGE
107 +#include <connman/plugin.h>
108 +#include <connman/device.h>
109 +#include <connman/network.h>
110 +#include <connman/ipconfig.h>
111 +#include <connman/dbus.h>
112 +#include <connman/inet.h>
113 +#include <connman/technology.h>
114 +#include <connman/log.h>
116 +#define PS_DBUS_SERVICE "com.tcore.ps"
118 +#define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master"
119 +#define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem"
120 +#define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service"
121 +#define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context"
124 +#define GET_MODEMS "GetModems"
125 +#define GET_SERVICES "GetServices"
126 +#define GET_CONTEXTS "GetContexts"
127 +#define ACTIVATE_CONTEXT "Activate"
128 +#define DEACTIVATE_CONTEXT "Deactivate"
129 +#define GET_PROPERTIES "GetProperties"
130 +#define SET_PROPERTY "SetProperties"
133 +#define MODEM_ADDED "ModemAdded"
134 +#define MODEM_REMOVED "ModemRemoved"
135 +#define SERVICE_ADDED "ServiceAdded"
136 +#define SERVICE_REMOVED "ServiceRemoved"
137 +#define CONTEXT_ADDED "ContextAdded"
138 +#define CONTEXT_REMOVED "ContextRemoved"
139 +#define PROPERTY_CHANGED "PropertyChanged"
141 +#define TIMEOUT 40000
143 +#define STRING2BOOL(a) ((g_str_equal(a, "TRUE")) ? (TRUE):(FALSE))
145 +static DBusConnection *connection;
146 +static GHashTable *modem_hash;
147 +static GHashTable *service_hash;
148 +static GHashTable *network_hash;
150 +struct telephony_service {
155 + gboolean roaming; /* global roaming state */
156 + gboolean ps_attached; /* packet service is available */
159 +struct telephony_modem {
165 + gboolean flight_mode;
166 + gboolean data_allowed;
167 + gboolean roaming_allowed;
169 + struct connman_device *device;
170 + struct telephony_service *s_service;
173 +struct telephony_network {
175 + struct connman_network *network;
177 + enum connman_ipconfig_method ipv4_method;
178 + struct connman_ipaddress *ipv4_address;
180 + enum connman_ipconfig_method ipv6_method;
181 + struct connman_ipaddress *ipv6_address;
184 +/* function prototype */
185 +static void telephony_connect(DBusConnection *connection, void *user_data);
186 +static void telephony_disconnect(DBusConnection *connection, void *user_data);
187 +static void __remove_modem(gpointer data);
188 +static void __remove_service(gpointer data);
189 +static void __remove_network(gpointer data);
191 +static int __modem_probe(struct connman_device *device);
192 +static void __modem_remove(struct connman_device *device);
193 +static int __modem_enable(struct connman_device *device);
194 +static int __modem_disable(struct connman_device *device);
196 +static int __network_probe(struct connman_network *network);
197 +static void __network_remove(struct connman_network *network);
198 +static int __network_connect(struct connman_network *network);
199 +static int __network_disconnect(struct connman_network *network);
202 +/* dbus request and reply */
203 +static int __dbus_request(const char *path, const char *interface,
204 + const char *method,
205 + DBusPendingCallNotifyFunction notify, void *user_data,
206 + DBusFreeFunction free_function, int type, ...);
208 +static int __request_get_modems(void);
209 +static void __response_get_modems(DBusPendingCall *call, void *user_data);
210 +static int __request_get_services(const char *path);
211 +static void __response_get_services(DBusPendingCall *call, void *user_data);
212 +static int __request_get_contexts(struct telephony_modem *modem);
213 +static void __response_get_contexts(DBusPendingCall *call, void *user_data);
214 +static int __request_network_activate(struct connman_network *network);
215 +static void __response_network_activate(DBusPendingCall *call, void *user_data);
216 +static int __request_network_deactivate(struct connman_network *network);
218 +/* telephony internal function */
219 +static void __add_modem(const char *path, DBusMessageIter *prop);
220 +static void __add_service(struct telephony_modem *modem,
221 + const char *service_path, DBusMessageIter *prop);
222 +static void __add_connman_device(const char *modem_path, const char *operator);
223 +static void __remove_connman_device(struct telephony_modem *modem);
224 +static void __remove_connman_networks(struct connman_device *device);
225 +static void __set_device_powered(struct telephony_modem *modem,
227 +static int __check_device_powered(const char *path, gboolean online);
228 +static gboolean __check_network_available(struct connman_network *network);
229 +static void __create_service(struct connman_network *network);
230 +static int __add_context(struct connman_device *device, const char *path,
231 + DBusMessageIter *prop);
232 +static gboolean __set_network_ipconfig(struct telephony_network *network,
233 + DBusMessageIter *dict);
234 +static void __set_network_connected(struct telephony_network *network,
235 + gboolean connected);
236 +static char *__get_ident(const char *path);
238 +/* signal handler */
239 +static gboolean __changed_modem(DBusConnection *connection,
240 + DBusMessage *message, void *user_data);
241 +static gboolean __added_modem(DBusConnection *connection,
242 + DBusMessage *message, void *user_data);
243 +static gboolean __removed_modem(DBusConnection *connection,
244 + DBusMessage *message, void *user_data);
245 +static gboolean __changed_service(DBusConnection *connection,
246 + DBusMessage *message, void *user_data);
247 +static gboolean __added_service(DBusConnection *connection,
248 + DBusMessage *message, void *user_data);
249 +static gboolean __removed_service(DBusConnection *connection,
250 + DBusMessage *message, void *user_data);
251 +static gboolean __changed_context(DBusConnection *connection,
252 + DBusMessage *message, void *user_data);
253 +static gboolean __added_context(DBusConnection *connection,
254 + DBusMessage *message, void *user_data);
255 +static gboolean __removed_context(DBusConnection *connection,
256 + DBusMessage *message, void *user_data);
259 +static struct connman_device_driver modem_driver = {
261 + .type = CONNMAN_DEVICE_TYPE_CELLULAR,
262 + .probe = __modem_probe,
263 + .remove = __modem_remove,
264 + .enable = __modem_enable,
265 + .disable = __modem_disable,
268 +/* network driver */
269 +static struct connman_network_driver network_driver = {
271 + .type = CONNMAN_NETWORK_TYPE_CELLULAR,
272 + .probe = __network_probe,
273 + .remove = __network_remove,
274 + .connect = __network_connect,
275 + .disconnect = __network_disconnect,
278 +static int tech_probe(struct connman_technology *technology)
283 +static void tech_remove(struct connman_technology *technology)
287 +static struct connman_technology_driver tech_driver = {
288 + .name = "cellular",
289 + .type = CONNMAN_SERVICE_TYPE_CELLULAR,
290 + .probe = tech_probe,
291 + .remove = tech_remove,
294 +/* local function */
295 +static void telephony_connect(DBusConnection *connection, void *user_data)
297 + DBG("connection %p", connection);
298 + modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
299 + g_free, __remove_modem);
300 + service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
301 + g_free, __remove_service);
302 + network_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
303 + g_free, __remove_network);
304 + __request_get_modems();
308 +static void telephony_disconnect(DBusConnection *connection, void *user_data)
310 + DBG("connection %p", connection);
312 + if (modem_hash != NULL) {
313 + g_hash_table_destroy(modem_hash);
317 + if (network_hash != NULL) {
318 + g_hash_table_destroy(network_hash);
319 + network_hash = NULL;
325 +static void __remove_modem(gpointer data)
327 + struct telephony_modem *modem = data;
329 + __remove_connman_device(modem);
331 + g_free(modem->path);
332 + g_free(modem->operator);
336 +static void __remove_service(gpointer data)
338 + struct telephony_service *service = data;
340 + g_free(service->path);
341 + g_free(service->act);
345 +static void __remove_network(gpointer data)
347 + struct telephony_network *info = data;
348 + struct connman_device *device;
350 + device = connman_network_get_device(info->network);
351 + if (device != NULL)
352 + connman_device_remove_network(device, info->network);
354 + connman_network_unref(info->network);
356 + g_free(info->path);
357 + connman_ipaddress_free(info->ipv4_address);
358 + connman_ipaddress_free(info->ipv6_address);
362 +static int __modem_probe(struct connman_device *device)
364 + DBG("device %p", device);
368 +static void __modem_remove(struct connman_device *device)
370 + DBG("device %p", device);
373 +static int __modem_enable(struct connman_device *device)
375 + const char *path = connman_device_get_string(device, "Path");
376 + DBG("device %p, path, %s", device, path);
378 + return __check_device_powered(path, TRUE);
381 +static int __modem_disable(struct connman_device *device)
383 + const char *path = connman_device_get_string(device, "Path");
384 + DBG("device %p, path, %s", device, path);
386 + return __check_device_powered(path, FALSE);
389 +static int __network_probe(struct connman_network *network)
391 + DBG("network_prove network(%p)", network);
395 +static int __network_connect(struct connman_network *network)
397 + struct connman_device *device;
398 + struct telephony_modem *modem;
400 + DBG("network %p", network);
402 + device = connman_network_get_device(network);
403 + if (device == NULL)
406 + modem = connman_device_get_data(device);
410 + if (modem->powered == FALSE)
413 + return __request_network_activate(network);
416 +static int __network_disconnect(struct connman_network *network)
418 + DBG("network %p", network);
420 + if (connman_network_get_index(network) < 0)
423 + connman_network_set_associating(network, FALSE);
425 + return __request_network_deactivate(network);
428 +static void __network_remove(struct connman_network *network)
430 + char const *path = connman_network_get_string(network, "Path");
431 + DBG("network %p path %s", network, path);
433 + g_hash_table_remove(network_hash, path);
437 +static int __dbus_request(const char *path, const char *interface,
438 + const char *method,
439 + DBusPendingCallNotifyFunction notify, void *user_data,
440 + DBusFreeFunction free_function, int type, ...)
442 + DBusMessage *message;
443 + DBusPendingCall *call;
447 + DBG("Telephony request path %s %s.%s", path, interface, method);
452 + message = dbus_message_new_method_call(PS_DBUS_SERVICE, path,
453 + interface, method);
454 + if (message == NULL)
457 + dbus_message_set_auto_start(message, FALSE);
459 + va_start(va, type);
460 + ok = dbus_message_append_args_valist(message, type, va);
466 + if (dbus_connection_send_with_reply(connection, message,
467 + &call, TIMEOUT) == FALSE) {
468 + connman_error("Failed to call %s.%s", interface, method);
469 + dbus_message_unref(message);
473 + if (call == NULL) {
474 + connman_error("D-Bus connection not available");
475 + dbus_message_unref(message);
479 + dbus_pending_call_set_notify(call, notify, user_data, free_function);
481 + dbus_message_unref(message);
483 + return -EINPROGRESS;
486 +static int __request_get_modems(void)
488 + DBG("request get modem");
489 + /* call connect master */
490 + return __dbus_request("/", PS_MASTER_INTERFACE, GET_MODEMS,
491 + __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
494 +static void __response_get_modems(DBusPendingCall *call, void *user_data)
496 + DBusMessage *reply;
498 + DBusMessageIter args, dict;
502 + reply = dbus_pending_call_steal_reply(call);
504 + dbus_error_init(&error);
506 + if (dbus_set_error_from_message(&error, reply)) {
507 + connman_error("GetModems() %s %s", error.name, error.message);
508 + dbus_error_free(&error);
512 + DBG("message signature (%s)", dbus_message_get_signature(reply));
514 + if (dbus_message_iter_init(reply, &args) == FALSE)
517 + dbus_message_iter_recurse(&args, &dict);
519 + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
520 + DBusMessageIter entry, property;
521 + const char *modem_path;
523 + dbus_message_iter_recurse(&dict, &entry);
524 + dbus_message_iter_get_basic(&entry, &modem_path);
525 + DBG("modem path (%s)", modem_path);
527 + dbus_message_iter_next(&entry);
528 + dbus_message_iter_recurse(&entry, &property);
530 + __add_modem(modem_path, &property);
532 + dbus_message_iter_next(&dict);
536 + dbus_message_unref(reply);
537 + dbus_pending_call_unref(call);
541 +static int __request_get_services(const char *path)
543 + DBG("request get service");
544 + return __dbus_request(path, PS_MODEM_INTERFACE, GET_SERVICES,
545 + __response_get_services, g_strdup(path),
546 + g_free, DBUS_TYPE_INVALID);
549 +static void __response_get_services(DBusPendingCall *call, void *user_data)
551 + DBusMessage *reply;
553 + DBusMessageIter args, dict;
555 + const char *path = user_data;
556 + struct telephony_modem *modem;
558 + modem = g_hash_table_lookup(modem_hash, path);
561 + if (modem->device == NULL)
566 + reply = dbus_pending_call_steal_reply(call);
568 + dbus_error_init(&error);
570 + if (dbus_set_error_from_message(&error, reply)) {
571 + connman_error("GetServices() %s %s", error.name, error.message);
572 + dbus_error_free(&error);
576 + DBG("message signature (%s)", dbus_message_get_signature(reply));
578 + if (dbus_message_iter_init(reply, &args) == FALSE)
581 + dbus_message_iter_recurse(&args, &dict);
583 + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
584 + DBusMessageIter entry, property;
585 + const char *service_path;
587 + dbus_message_iter_recurse(&dict, &entry);
588 + dbus_message_iter_get_basic(&entry, &service_path);
589 + DBG("service path (%s)", service_path);
591 + dbus_message_iter_next(&entry);
592 + dbus_message_iter_recurse(&entry, &property);
594 + __add_service(modem, service_path, &property);
596 + dbus_message_iter_next(&dict);
600 + dbus_message_unref(reply);
601 + dbus_pending_call_unref(call);
605 +static int __request_get_contexts(struct telephony_modem *modem)
607 + DBG("request get contexts");
608 + return __dbus_request(modem->s_service->path,
609 + PS_SERVICE_INTERFACE, GET_CONTEXTS,
610 + __response_get_contexts, g_strdup(modem->path),
611 + g_free, DBUS_TYPE_INVALID);
614 +static void __response_get_contexts(DBusPendingCall *call, void *user_data)
617 + DBusMessage *reply;
618 + DBusMessageIter args, dict;
620 + const char *path = user_data;
621 + struct telephony_modem *modem;
625 + modem = g_hash_table_lookup(modem_hash, path);
628 + if (modem->s_service == NULL)
630 + if (modem->device == NULL)
633 + reply = dbus_pending_call_steal_reply(call);
635 + dbus_error_init(&error);
637 + if (dbus_set_error_from_message(&error, reply)) {
638 + connman_error("GetContexts() %s %s", error.name, error.message);
639 + dbus_error_free(&error);
643 + DBG("message signature (%s)", dbus_message_get_signature(reply));
645 + if (dbus_message_iter_init(reply, &args) == FALSE)
648 + dbus_message_iter_recurse(&args, &dict);
650 + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
651 + DBusMessageIter entry, property;
652 + const char *context_path;
654 + dbus_message_iter_recurse(&dict, &entry);
655 + dbus_message_iter_get_basic(&entry, &context_path);
656 + DBG("context path (%s)", context_path);
658 + dbus_message_iter_next(&entry);
659 + dbus_message_iter_recurse(&entry, &property);
661 + __add_context(modem->device, context_path, &property);
663 + dbus_message_iter_next(&dict);
667 + dbus_message_unref(reply);
668 + dbus_pending_call_unref(call);
672 +static int __request_network_activate(struct connman_network *network)
674 + DBG("request network activate");
676 + const char *path = connman_network_get_string(network, "Path");
677 + DBG("network %p, path %s", network, path);
679 + return __dbus_request(path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT,
680 + __response_network_activate,
681 + g_strdup(path), NULL, DBUS_TYPE_INVALID);
684 +static void __response_network_activate(DBusPendingCall *call, void *user_data)
686 + DBG("network activation response");
689 + DBusMessage *reply;
691 + struct telephony_network *info;
692 + const char *path = user_data;
694 + info = g_hash_table_lookup(network_hash, path);
695 + reply = dbus_pending_call_steal_reply(call);
700 + if (!__check_network_available(info->network)) {
701 + g_hash_table_remove(network_hash, path);
705 + dbus_error_init(&error);
706 + if (dbus_set_error_from_message(&error, reply)) {
707 + connman_error("connection activate() %s %s",
708 + error.name, error.message);
710 + if (connman_network_get_index(info->network) < 0)
711 + connman_network_set_error(info->network,
712 + CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
714 + dbus_error_free(&error);
719 + dbus_message_unref(reply);
720 + dbus_pending_call_unref(call);
724 +static int __request_network_deactivate(struct connman_network *network)
726 + DBG("request network deactivate");
728 + const char *path = connman_network_get_string(network, "Path");
729 + DBG("network %p, path %s", network, path);
731 + return __dbus_request(path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT,
732 + NULL, NULL, NULL, DBUS_TYPE_INVALID);
735 +static void __add_modem(const char *path, DBusMessageIter *prop)
737 + struct telephony_modem *modem;
739 + modem = g_hash_table_lookup(modem_hash, path);
743 + modem = (struct telephony_modem *)malloc(
744 + sizeof(struct telephony_modem));
745 + memset(modem, 0, sizeof(struct telephony_modem));
747 + modem->path = g_strdup(path);
748 + modem->device = NULL;
749 + modem->s_service = NULL;
751 + g_hash_table_insert(modem_hash, g_strdup(path), modem);
753 + while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
754 + DBusMessageIter entry;
755 + const char *key, *tmp;
757 + dbus_message_iter_recurse(prop, &entry);
758 + dbus_message_iter_get_basic(&entry, &key);
760 + dbus_message_iter_next(&entry);
761 + dbus_message_iter_get_basic(&entry, &tmp);
763 + DBG("key (%s) value(%s)", key, tmp);
765 + if (g_str_equal(key, "powered") == TRUE) {
766 + modem->powered = STRING2BOOL(tmp);
767 + } else if (g_str_equal(key, "operator") == TRUE) {
768 + modem->operator = g_strdup(tmp);
769 + } else if (g_str_equal(key, "sim_init") == TRUE) {
770 + modem->sim_init = STRING2BOOL(tmp);
771 + } else if (g_str_equal(key, "flight_mode") == TRUE) {
772 + modem->flight_mode = STRING2BOOL(tmp);
773 + } else if (g_str_equal(key, "roaming_allowed") == TRUE) {
774 + modem->roaming_allowed = STRING2BOOL(tmp);
775 + } else if (g_str_equal(key, "data_allowed") == TRUE) {
776 + modem->data_allowed = STRING2BOOL(tmp);
778 + dbus_message_iter_next(prop);
781 + __add_connman_device(path, modem->operator);
782 + __set_device_powered(modem, modem->powered);
784 + if (modem->powered != TRUE) {
785 + DBG("modem is not powered");
789 + __request_get_services(modem->path);
794 +static void __add_service(struct telephony_modem *modem,
795 + const char *service_path, DBusMessageIter *prop)
797 + struct telephony_service *service;
799 + if (modem->s_service != NULL)
802 + service = (struct telephony_service *)g_try_malloc(
803 + sizeof(struct telephony_service));
804 + if (service == NULL)
807 + memset(service, 0, sizeof(struct telephony_service));
809 + service->path = g_strdup(service_path);
810 + service->p_modem = modem;
811 + g_hash_table_insert(service_hash, g_strdup(service_path), service);
813 + while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
814 + DBusMessageIter entry;
815 + const char *key, *tmp;
817 + dbus_message_iter_recurse(prop, &entry);
818 + dbus_message_iter_get_basic(&entry, &key);
820 + dbus_message_iter_next(&entry);
821 + dbus_message_iter_get_basic(&entry, &tmp);
823 + DBG("key (%s) value(%s)", key, tmp);
825 + if (g_str_equal(key, "roaming") == TRUE) {
826 + service->roaming = STRING2BOOL(tmp);
827 + } else if (g_str_equal(key, "act") == TRUE) {
828 + service->act = g_strdup(tmp);
829 + } else if (g_str_equal(key, "ps_attached") == TRUE) {
830 + service->ps_attached = STRING2BOOL(tmp);
833 + dbus_message_iter_next(prop);
836 + modem->s_service = service;
837 + __request_get_contexts(modem);
842 +static void __add_connman_device(const char *modem_path, const char *operator)
844 + struct telephony_modem *modem;
845 + struct connman_device *device;
847 + DBG("path %s operator %s", modem_path, operator);
849 + if (modem_path == NULL)
852 + if (operator == NULL)
855 + modem = g_hash_table_lookup(modem_hash, modem_path);
859 + if (modem->device) {
860 + if (!g_strcmp0(operator,
861 + connman_device_get_ident(modem->device)))
864 + __remove_connman_device(modem);
867 + if (strlen(operator) == 0)
870 + device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
871 + if (device == NULL)
874 + connman_device_set_ident(device, operator);
875 + connman_device_set_string(device, "Path", modem_path);
876 + connman_device_set_data(device, modem);
878 + if (connman_device_register(device) < 0) {
879 + connman_error("Failed to register cellular device");
880 + connman_device_unref(device);
884 + modem->device = device;
889 +static void __remove_connman_device(struct telephony_modem *modem)
891 + DBG("modem %p path %s device %p", modem, modem->path, modem->device);
893 + if (modem->device == NULL)
896 + __remove_connman_networks(modem->device);
898 + connman_device_unregister(modem->device);
899 + connman_device_unref(modem->device);
901 + modem->device = NULL;
906 +static void __remove_connman_networks(struct connman_device *device)
908 + GHashTableIter iter;
909 + gpointer key, value;
910 + GSList *info_list = NULL;
913 + if (network_hash == NULL)
916 + g_hash_table_iter_init(&iter, network_hash);
918 + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
919 + struct telephony_network *info = value;
921 + if (connman_network_get_device(info->network) != device)
924 + info_list = g_slist_append(info_list, info);
927 + for (list = info_list; list != NULL; list = list->next) {
928 + struct telephony_network *info = list->data;
929 + connman_device_remove_network(device, info->network);
932 + g_slist_free(info_list);
935 +static void __set_device_powered(struct telephony_modem *modem,
938 + DBG("set modem(%s) powered(%d)", modem->path, powered);
941 + connman_device_set_powered(modem->device, powered);
946 +static int __check_device_powered(const char *path, gboolean powered)
948 + struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path);
953 + DBG("check modem (%s) powered (%d)", modem->path, modem->powered);
955 + if (modem->powered == powered)
961 +static gboolean __check_network_available(struct connman_network *network)
963 + if (network == NULL || connman_network_get_device(network) == NULL) {
964 + DBG("Modem or network was removed");
971 +static int __add_context(struct connman_device *device, const char *path,
972 + DBusMessageIter *prop)
975 + gboolean active = FALSE;
977 + struct telephony_modem *modem = connman_device_get_data(device);
978 + struct connman_network *network;
979 + struct telephony_network *info;
981 + DBG("modem %p device %p path %s", modem, device, path);
983 + ident = __get_ident(path);
985 + network = connman_device_get_network(device, ident);
986 + if (network != NULL)
989 + info = g_hash_table_lookup(network_hash, path);
990 + if (info != NULL) {
991 + DBG("path %p already exists with device %p", path,
992 + connman_network_get_device(info->network));
994 + if (connman_network_get_device(info->network))
997 + g_hash_table_remove(network_hash, path);
1000 + network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
1001 + if (network == NULL)
1004 + info = (struct telephony_network *)g_try_malloc(
1005 + sizeof(struct telephony_network));
1006 + if (info == NULL) {
1007 + connman_network_unref(network);
1011 + memset(info, 0, sizeof(struct telephony_network));
1013 + info->path = g_strdup(path);
1015 + connman_ipaddress_clear(info->ipv4_address);
1016 + connman_ipaddress_clear(info->ipv6_address);
1017 + info->network = network;
1019 + connman_network_set_string(network, "Path", path);
1020 + connman_network_set_name(network, path);
1022 + __create_service(network);
1024 + g_hash_table_insert(network_hash, g_strdup(path), info);
1026 + connman_network_set_available(network, TRUE);
1027 + connman_network_set_index(network, -1);
1028 + connman_network_set_bool(network, "Roaming", modem->s_service->roaming);
1030 + if (connman_device_add_network(device, network) != 0) {
1031 + g_hash_table_remove(network_hash, path);
1035 + active = __set_network_ipconfig(info, prop);
1037 + if (active && (connman_network_get_connecting(network) ||
1038 + connman_network_get_associating(network)))
1039 + __set_network_connected(info, active);
1044 +static void __create_service(struct connman_network *network)
1051 + path = connman_network_get_string(network, "Path");
1053 + group = __get_ident(path);
1055 + connman_network_set_group(network, group);
1058 +static gboolean __set_network_ipconfig(struct telephony_network *network,
1059 + DBusMessageIter *dict)
1061 + DBG("set network info");
1063 + gboolean active = FALSE;
1064 + char *dev_name = NULL, *proxy_addr = NULL;
1065 + char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL,
1066 + *ipv4_dns1 = NULL, *ipv4_dns2 = NULL;
1067 + char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL,
1068 + *ipv6_dns1 = NULL, *ipv6_dns2 = NULL;
1072 + while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
1073 + DBusMessageIter entry;
1074 + const char *key, *tmp;
1076 + dbus_message_iter_recurse(dict, &entry);
1077 + dbus_message_iter_get_basic(&entry, &key);
1079 + dbus_message_iter_next(&entry);
1081 + DBG("key (%s)", key);
1083 + if (g_str_equal(key, "dev_name") == TRUE) {
1084 + dbus_message_iter_get_basic(&entry, &dev_name);
1085 + DBG("dev_name (%s)", dev_name);
1086 + } else if (g_str_equal(key, "proxy") == TRUE) {
1087 + dbus_message_iter_get_basic(&entry, &proxy_addr);
1088 + } else if (g_str_equal(key, "ipv4_address") == TRUE) {
1089 + dbus_message_iter_get_basic(&entry, &ipv4_addr);
1090 + DBG("ipv4 address (%s)", ipv4_addr);
1091 + } else if (g_str_equal(key, "ipv4_gateway") == TRUE) {
1092 + dbus_message_iter_get_basic(&entry, &ipv4_gw);
1093 + } else if (g_str_equal(key, "ipv4_netmask") == TRUE) {
1094 + dbus_message_iter_get_basic(&entry, &ipv4_netmask);
1095 + } else if (g_str_equal(key, "ipv4_dns1") == TRUE) {
1096 + dbus_message_iter_get_basic(&entry, &ipv4_dns1);
1097 + } else if (g_str_equal(key, "ipv4_dns2") == TRUE) {
1098 + dbus_message_iter_get_basic(&entry, &ipv4_dns2);
1099 + } else if (g_str_equal(key, "ipv6_address") == TRUE) {
1100 + dbus_message_iter_get_basic(&entry, &ipv6_addr);
1101 + DBG("ipv6 address (%s)", ipv6_addr);
1102 + } else if (g_str_equal(key, "ipv6_gateway") == TRUE) {
1103 + dbus_message_iter_get_basic(&entry, &ipv6_gw);
1104 + } else if (g_str_equal(key, "ipv6_netmask") == TRUE) {
1105 + dbus_message_iter_get_basic(&entry, &ipv6_netmask);
1106 + } else if (g_str_equal(key, "ipv6_dns1") == TRUE) {
1107 + dbus_message_iter_get_basic(&entry, &ipv6_dns1);
1108 + } else if (g_str_equal(key, "ipv6_dns2") == TRUE) {
1109 + dbus_message_iter_get_basic(&entry, &ipv6_dns2);
1110 + } else if (g_str_equal(key, "active") == TRUE) {
1111 + dbus_message_iter_get_basic(&entry, &tmp);
1112 + DBG("active (%s)", tmp);
1113 + active = STRING2BOOL(tmp);
1116 + dbus_message_iter_next(dict);
1119 + /* interface index set */
1120 + if (dev_name == NULL)
1123 + if (!g_str_equal(dev_name, "")) {
1124 + index = connman_inet_ifindex(dev_name);
1125 + DBG("interface %s, index %d", dev_name, index);
1126 + connman_network_set_index(network->network, index);
1130 + if (proxy_addr == NULL)
1133 + DBG("proxy (%s) is set", proxy_addr);
1134 + connman_network_set_proxy(network->network, proxy_addr);
1137 + if (ipv4_addr == NULL)
1138 + ipv4_addr = "0.0.0.0";
1140 + if (g_str_equal(ipv4_addr, "0.0.0.0")) {
1141 + network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
1143 + network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1144 + network->ipv4_address =
1145 + connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
1146 + if (network->ipv4_address == NULL)
1149 + connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr,
1150 + ipv4_netmask, ipv4_gw);
1152 + if (ipv4_dns1 == NULL)
1153 + ipv4_dns1 = "0.0.0.0";
1154 + if (ipv4_dns2 == NULL)
1155 + ipv4_dns2 = "0.0.0.0";
1157 + if (g_str_equal(ipv4_dns1, "0.0.0.0"))
1160 + if (g_str_equal(ipv4_dns2, "0.0.0.0"))
1163 + gchar *nameservers = NULL;
1165 + switch (dns_flag) {
1167 + nameservers = g_strdup_printf("%s %s", ipv4_dns1,
1171 + nameservers = g_strdup_printf("%s", ipv4_dns2);
1174 + nameservers = g_strdup_printf("%s", ipv4_dns1);
1177 + connman_network_set_nameservers(network->network, nameservers);
1178 + g_free(nameservers);
1182 + if (ipv6_addr == NULL)
1185 + if (g_str_equal(ipv6_addr, "::")) {
1186 + network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
1188 + network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
1189 + unsigned char prefix_length = 64;
1190 + network->ipv6_address =
1191 + connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
1192 + if (network->ipv6_address == NULL)
1195 + connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr,
1196 + prefix_length, ipv6_gw);
1200 + if (ipv6_dns1 == NULL)
1202 + if (ipv6_dns2 == NULL)
1205 + if (g_str_equal(ipv6_dns1, "::"))
1208 + if (g_str_equal(ipv6_dns2, "::"))
1211 + gchar *nameservers = NULL;
1213 + switch (dns_flag) {
1215 + nameservers = g_strdup_printf("%s %s", ipv6_dns1,
1219 + nameservers = g_strdup_printf("%s", ipv6_dns2);
1222 + nameservers = g_strdup_printf("%s", ipv6_dns1);
1225 + connman_network_set_nameservers(network->network, nameservers);
1226 + g_free(nameservers);
1230 + connman_network_set_associating(network->network, TRUE);
1235 +static void __set_network_connected(struct telephony_network *network,
1236 + gboolean connected)
1238 + gboolean setip = FALSE;
1240 + DBG("network %p connected %d", network, connected);
1242 + switch (network->ipv4_method) {
1243 + case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1244 + case CONNMAN_IPCONFIG_METHOD_OFF:
1245 + case CONNMAN_IPCONFIG_METHOD_MANUAL:
1246 + case CONNMAN_IPCONFIG_METHOD_AUTO:
1250 + case CONNMAN_IPCONFIG_METHOD_FIXED:
1251 + connman_network_set_ipv4_method(network->network,
1252 + network->ipv4_method);
1253 + connman_network_set_ipaddress(network->network,
1254 + network->ipv4_address);
1258 + case CONNMAN_IPCONFIG_METHOD_DHCP:
1259 + connman_network_set_ipv4_method(network->network,
1260 + network->ipv4_method);
1265 + switch (network->ipv6_method) {
1266 + case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1267 + case CONNMAN_IPCONFIG_METHOD_OFF:
1268 + case CONNMAN_IPCONFIG_METHOD_MANUAL:
1269 + case CONNMAN_IPCONFIG_METHOD_DHCP:
1270 + case CONNMAN_IPCONFIG_METHOD_AUTO:
1271 + DBG("ipv6 not supported");
1274 + case CONNMAN_IPCONFIG_METHOD_FIXED:
1275 + connman_network_set_ipv6_method(network->network,
1276 + network->ipv6_method);
1277 + connman_network_set_ipaddress(network->network,
1278 + network->ipv6_address);
1283 + if (setip == TRUE)
1284 + connman_network_set_connected(network->network, connected);
1289 +static char *__get_ident(const char *path)
1296 + pos = strrchr(path, '/');
1303 +static gboolean __changed_modem(DBusConnection *connection,
1304 + DBusMessage *message, void *user_data)
1306 + DBG("modem changed signal");
1308 + DBusMessageIter args, dict;
1309 + const char *path = dbus_message_get_path(message);
1310 + struct telephony_modem *modem;
1312 + DBG("modem path %s", path);
1314 + modem = g_hash_table_lookup(modem_hash, path);
1315 + if (modem == NULL) {
1316 + DBG("modem object does not exists");
1320 + DBG("message signature (%s)", dbus_message_get_signature(message));
1322 + if (dbus_message_iter_init(message, &args) == FALSE) {
1323 + DBG("error to read message");
1327 + dbus_message_iter_recurse(&args, &dict);
1329 + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1330 + DBusMessageIter entry;
1331 + const char *key, *tmp;
1333 + dbus_message_iter_recurse(&dict, &entry);
1334 + dbus_message_iter_get_basic(&entry, &key);
1336 + dbus_message_iter_next(&entry);
1337 + dbus_message_iter_get_basic(&entry, &tmp);
1339 + DBG("key(%s), value(%s)", key, tmp);
1341 + if (g_str_equal(key, "powered") == TRUE) {
1342 + modem->powered = STRING2BOOL(tmp);
1343 + } else if (g_str_equal(key, "operator") == TRUE) {
1344 + modem->operator = g_strdup(tmp);
1345 + } else if (g_str_equal(key, "sim_init") == TRUE) {
1346 + modem->sim_init = STRING2BOOL(tmp);
1347 + } else if (g_str_equal(key, "flight_mode") == TRUE) {
1348 + modem->flight_mode = STRING2BOOL(tmp);
1349 + } else if (g_str_equal(key, "roaming_allowed") == TRUE) {
1350 + modem->roaming_allowed = STRING2BOOL(tmp);
1351 + } else if (g_str_equal(key, "data_allowed") == TRUE) {
1352 + modem->data_allowed = STRING2BOOL(tmp);
1355 + dbus_message_iter_next(&dict);
1358 + if (modem->device == NULL)
1359 + __add_connman_device(path, modem->operator);
1361 + __set_device_powered(modem, modem->powered);
1363 + if (modem->powered != TRUE) {
1364 + DBG("modem is not powered");
1368 + if (!modem->s_service) {
1369 + __request_get_services(modem->path);
1373 + if (modem->flight_mode || !modem->data_allowed) {
1374 + DBG("modem(%s) flight mode(%d) data allowed(%d)",
1375 + modem->path, modem->flight_mode, modem->data_allowed);
1382 +static gboolean __added_modem(DBusConnection *connection,
1383 + DBusMessage *message, void *user_data)
1385 + DBG("modem added signal");
1387 + const char *modem_path = NULL;
1388 + DBusMessageIter args, dict, tmp;
1390 + DBG("message signature (%s)", dbus_message_get_signature(message));
1391 + if (dbus_message_iter_init(message, &args) == FALSE) {
1392 + DBG("error to read message");
1396 + dbus_message_iter_recurse(&args, &dict);
1397 + memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1399 + while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1400 + DBusMessageIter entry;
1401 + const char *key, *value;
1403 + dbus_message_iter_recurse(&tmp, &entry);
1404 + dbus_message_iter_get_basic(&entry, &key);
1406 + dbus_message_iter_next(&entry);
1407 + dbus_message_iter_get_basic(&entry, &value);
1409 + DBG("key (%s) value(%s)", key, value);
1411 + if (g_str_equal(key, "path") == TRUE)
1412 + modem_path = g_strdup(value);
1414 + dbus_message_iter_next(&tmp);
1417 + if (modem_path != NULL)
1418 + __add_modem(modem_path, &dict);
1423 +static gboolean __removed_modem(DBusConnection *connection,
1424 + DBusMessage *message, void *user_data)
1426 + DBG("modem removed signal");
1428 + DBusMessageIter iter;
1429 + const char *modem_path;
1431 + if (dbus_message_iter_init(message, &iter) == FALSE) {
1432 + DBG("error to read message");
1436 + dbus_message_iter_get_basic(&iter, &modem_path);
1437 + g_hash_table_remove(modem_hash, modem_path);
1442 +static gboolean __changed_service(DBusConnection *connection,
1443 + DBusMessage *message, void *user_data)
1445 + DBG("service changed signal");
1447 + DBusMessageIter args, dict;
1448 + const char *service_path = dbus_message_get_path(message);
1449 + struct telephony_modem *modem;
1450 + struct telephony_service *s_service;
1451 + gboolean roaming_option = TRUE;
1453 + DBG("service path %s", service_path);
1455 + s_service = g_hash_table_lookup(service_hash, service_path);
1456 + if (s_service == NULL) {
1457 + DBG("service object does not exists");
1461 + modem = s_service->p_modem;
1462 + if (modem == NULL) {
1463 + DBG("modem object does not exists");
1467 + DBG("message signature (%s)", dbus_message_get_signature(message));
1469 + if (dbus_message_iter_init(message, &args) == FALSE) {
1470 + DBG("error to read message");
1474 + dbus_message_iter_recurse(&args, &dict);
1476 + while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
1477 + DBusMessageIter entry;
1478 + const char *key, *tmp;
1480 + dbus_message_iter_recurse(&dict, &entry);
1481 + dbus_message_iter_get_basic(&entry, &key);
1483 + dbus_message_iter_next(&entry);
1484 + dbus_message_iter_get_basic(&entry, &tmp);
1486 + DBG("key(%s), value(%s)", key, tmp);
1488 + if (g_str_equal(key, "roaming") == TRUE) {
1489 + s_service->roaming = STRING2BOOL(tmp);
1490 + } else if (g_str_equal(key, "act") == TRUE) {
1491 + s_service->act = g_strdup(tmp);
1492 + } else if (g_str_equal(key, "ps_attached") == TRUE) {
1493 + s_service->ps_attached = STRING2BOOL(tmp);
1496 + dbus_message_iter_next(&dict);
1499 + roaming_option &= (!s_service->roaming && !modem->roaming_allowed)
1500 + || modem->roaming_allowed;
1506 +static gboolean __added_service(DBusConnection *connection,
1507 + DBusMessage *message, void *user_data)
1509 + DBG("service added signal");
1511 + const char *path = dbus_message_get_path(message);
1512 + const char *service_path = NULL;
1513 + DBusMessageIter args, dict, tmp;
1514 + struct telephony_modem *modem;
1516 + modem = g_hash_table_lookup(modem_hash, path);
1517 + if (modem == NULL || modem->device == NULL)
1520 + DBG("message signature (%s)", dbus_message_get_signature(message));
1521 + if (dbus_message_iter_init(message, &args) == FALSE) {
1522 + DBG("error to read message");
1526 + dbus_message_iter_recurse(&args, &dict);
1527 + memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1529 + while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1530 + DBusMessageIter entry;
1531 + const char *key, *value;
1533 + dbus_message_iter_recurse(&tmp, &entry);
1534 + dbus_message_iter_get_basic(&entry, &key);
1536 + dbus_message_iter_next(&entry);
1537 + dbus_message_iter_get_basic(&entry, &value);
1539 + DBG("key (%s) value(%s)", key, value);
1541 + if (g_str_equal(key, "path") == TRUE) {
1542 + service_path = g_strdup(value);
1545 + dbus_message_iter_next(&tmp);
1548 + if (service_path != NULL)
1549 + __add_service(modem, service_path, &dict);
1554 +static gboolean __removed_service(DBusConnection *connection,
1555 + DBusMessage *message, void *user_data)
1557 + DBG("service removed signal");
1559 + DBusMessageIter iter;
1560 + const char *service_path;
1562 + if (dbus_message_iter_init(message, &iter) == FALSE) {
1563 + DBG("error to read message");
1567 + dbus_message_iter_get_basic(&iter, &service_path);
1568 + g_hash_table_remove(service_hash, service_path);
1573 +static gboolean __changed_context(DBusConnection *connection,
1574 + DBusMessage *message, void *user_data)
1576 + DBG("network changed signal");
1578 + gboolean active = FALSE;
1579 + const char *path = dbus_message_get_path(message);
1580 + struct telephony_network *info;
1581 + DBusMessageIter args, dict;
1583 + DBG("path %s", path);
1584 + info = g_hash_table_lookup(network_hash, path);
1588 + if (!__check_network_available(info->network)) {
1589 + g_hash_table_remove(network_hash, path);
1593 + if (dbus_message_iter_init(message, &args) == FALSE) {
1594 + DBG("error to read message");
1598 + dbus_message_iter_recurse(&args, &dict);
1600 + active = __set_network_ipconfig(info, &dict);
1602 + if (active == FALSE)
1603 + __set_network_connected(info, active);
1604 + else if ((connman_network_get_connecting(info->network) ||
1605 + connman_network_get_associating(info->network)))
1606 + __set_network_connected(info, active);
1611 +static gboolean __added_context(DBusConnection *connection,
1612 + DBusMessage *message, void *user_data)
1614 + DBG("network added signal");
1616 + DBusMessageIter args, dict, tmp;
1617 + const char *path = dbus_message_get_path(message);
1618 + const char *network_path = NULL;
1619 + struct telephony_service *service = NULL;
1620 + struct telephony_modem *modem = NULL;
1622 + service = g_hash_table_lookup(service_hash, path);
1623 + if (service == NULL || service->p_modem == NULL)
1626 + modem = service->p_modem;
1627 + if (modem == NULL || modem->device == NULL)
1630 + DBG("message signature (%s)", dbus_message_get_signature(message));
1631 + if (dbus_message_iter_init(message, &args) == FALSE) {
1632 + DBG("error to read message");
1636 + dbus_message_iter_recurse(&args, &dict);
1637 + memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
1639 + while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
1640 + DBusMessageIter entry;
1641 + const char *key, *value;
1643 + dbus_message_iter_recurse(&tmp, &entry);
1644 + dbus_message_iter_get_basic(&entry, &key);
1646 + dbus_message_iter_next(&entry);
1647 + dbus_message_iter_get_basic(&entry, &value);
1649 + DBG("key (%s) value(%s)", key, value);
1651 + if (g_str_equal(key, "path") == TRUE)
1652 + network_path = g_strdup(value);
1654 + dbus_message_iter_next(&tmp);
1657 + if (network_path != NULL)
1658 + __add_context(modem->device, network_path, &dict);
1663 +static gboolean __removed_context(DBusConnection *connection,
1664 + DBusMessage *message, void *user_data)
1666 + DBG("network removed signal");
1668 + DBusMessageIter iter;
1669 + const char *path = dbus_message_get_path(message);
1670 + const char *network_path = NULL;
1671 + struct telephony_service *service = NULL;
1673 + service = g_hash_table_lookup(service_hash, path);
1674 + if (service == NULL || service->p_modem == NULL)
1677 + if (dbus_message_iter_init(message, &iter) == FALSE) {
1678 + DBG("error to read message");
1682 + dbus_message_iter_get_basic(&iter, &network_path);
1683 + g_hash_table_remove(network_hash, network_path);
1688 +/* telephony initialization */
1689 +static guint watch;
1690 +static guint modem_watch;
1691 +static guint modem_added_watch;
1692 +static guint modem_removed_watch;
1693 +static guint service_watch;
1694 +static guint service_added_watch;
1695 +static guint service_removed_watch;
1696 +static guint context_watch;
1697 +static guint context_added_watch;
1698 +static guint context_removed_watch;
1700 +static int telephony_init(void)
1702 + DBG("telephony plugin");
1705 + connection = connman_dbus_get_connection();
1706 + if (connection == NULL)
1709 + /* telephony watch */
1710 + watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE,
1711 + telephony_connect, telephony_disconnect,
1714 + modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1715 + PS_MODEM_INTERFACE,
1717 + __changed_modem, NULL, NULL);
1719 + modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1720 + PS_MASTER_INTERFACE,
1721 + MODEM_ADDED, __added_modem,
1724 + modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1725 + PS_MASTER_INTERFACE,
1726 + MODEM_REMOVED, __removed_modem,
1729 + service_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1730 + PS_SERVICE_INTERFACE,
1732 + __changed_service,
1735 + service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1736 + PS_MODEM_INTERFACE,
1737 + SERVICE_ADDED, __added_service,
1740 + service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1741 + PS_MODEM_INTERFACE,
1743 + __removed_service,
1746 + context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1747 + PS_CONTEXT_INTERFACE,
1749 + __changed_context,
1752 + context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1753 + PS_SERVICE_INTERFACE,
1754 + CONTEXT_ADDED, __added_context,
1757 + context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
1758 + PS_SERVICE_INTERFACE,
1760 + __removed_context,
1763 + if (watch == 0 || modem_watch == 0 || modem_added_watch == 0
1764 + || modem_removed_watch == 0 || service_watch == 0
1765 + || service_added_watch == 0 || context_watch == 0
1766 + || service_removed_watch == 0
1767 + || context_added_watch == 0
1768 + || context_removed_watch == 0) {
1773 + err = connman_network_driver_register(&network_driver);
1777 + err = connman_device_driver_register(&modem_driver);
1779 + connman_network_driver_unregister(&network_driver);
1783 + err = connman_technology_driver_register(&tech_driver);
1785 + connman_device_driver_unregister(&modem_driver);
1786 + connman_network_driver_unregister(&network_driver);
1793 + g_dbus_remove_watch(connection, watch);
1794 + g_dbus_remove_watch(connection, modem_watch);
1795 + g_dbus_remove_watch(connection, modem_added_watch);
1796 + g_dbus_remove_watch(connection, modem_removed_watch);
1797 + g_dbus_remove_watch(connection, service_watch);
1798 + g_dbus_remove_watch(connection, service_added_watch);
1799 + g_dbus_remove_watch(connection, service_removed_watch);
1800 + g_dbus_remove_watch(connection, context_watch);
1801 + g_dbus_remove_watch(connection, context_added_watch);
1802 + g_dbus_remove_watch(connection, context_removed_watch);
1804 + dbus_connection_unref(connection);
1808 +static void telephony_exit(void)
1810 + g_dbus_remove_watch(connection, watch);
1811 + g_dbus_remove_watch(connection, modem_watch);
1812 + g_dbus_remove_watch(connection, modem_added_watch);
1813 + g_dbus_remove_watch(connection, modem_removed_watch);
1814 + g_dbus_remove_watch(connection, service_watch);
1815 + g_dbus_remove_watch(connection, service_added_watch);
1816 + g_dbus_remove_watch(connection, service_removed_watch);
1817 + g_dbus_remove_watch(connection, context_watch);
1818 + g_dbus_remove_watch(connection, context_added_watch);
1819 + g_dbus_remove_watch(connection, context_removed_watch);
1821 + telephony_disconnect(connection, NULL);
1823 + connman_device_driver_unregister(&modem_driver);
1824 + connman_network_driver_unregister(&network_driver);
1826 + dbus_connection_unref(connection);
1829 +CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
1830 + CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)