5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
6 * Copyright (C) 2011 BWM CarIT GmbH. All rights reserved.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 static DBusConnection *connection;
32 static GHashTable *session_hash;
33 static connman_bool_t sessionmode;
35 enum connman_session_roaming_policy {
36 CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN = 0,
37 CONNMAN_SESSION_ROAMING_POLICY_DEFAULT = 1,
38 CONNMAN_SESSION_ROAMING_POLICY_ALWAYS = 2,
39 CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN = 3,
40 CONNMAN_SESSION_ROAMING_POLICY_NATIONAL = 4,
41 CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL = 5,
44 struct connman_session {
53 connman_bool_t online;
54 connman_bool_t priority;
55 GSList *allowed_bearers;
56 connman_bool_t avoid_handover;
57 connman_bool_t stay_connected;
58 unsigned int periodic_connect;
59 unsigned int idle_timeout;
61 enum connman_session_roaming_policy roaming_policy;
64 GSequence *service_list;
65 struct connman_service *service;
70 connman_bool_t match_all;
71 enum connman_service_type service_type;
74 static const char *roamingpolicy2string(enum connman_session_roaming_policy policy)
77 case CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN:
79 case CONNMAN_SESSION_ROAMING_POLICY_DEFAULT:
81 case CONNMAN_SESSION_ROAMING_POLICY_ALWAYS:
83 case CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN:
85 case CONNMAN_SESSION_ROAMING_POLICY_NATIONAL:
87 case CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL:
88 return "international";
94 static enum connman_session_roaming_policy string2roamingpolicy(const char *policy)
96 if (g_strcmp0(policy, "default") == 0)
97 return CONNMAN_SESSION_ROAMING_POLICY_DEFAULT;
98 else if (g_strcmp0(policy, "always") == 0)
99 return CONNMAN_SESSION_ROAMING_POLICY_ALWAYS;
100 else if (g_strcmp0(policy, "forbidden") == 0)
101 return CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN;
102 else if (g_strcmp0(policy, "national") == 0)
103 return CONNMAN_SESSION_ROAMING_POLICY_NATIONAL;
104 else if (g_strcmp0(policy, "international") == 0)
105 return CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL;
107 return CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN;
110 static enum connman_service_type bearer2service(const char *bearer)
113 return CONNMAN_SERVICE_TYPE_UNKNOWN;
115 if (g_strcmp0(bearer, "ethernet") == 0)
116 return CONNMAN_SERVICE_TYPE_ETHERNET;
117 else if (g_strcmp0(bearer, "wifi") == 0)
118 return CONNMAN_SERVICE_TYPE_WIFI;
119 else if (g_strcmp0(bearer, "wimax") == 0)
120 return CONNMAN_SERVICE_TYPE_WIMAX;
121 else if (g_strcmp0(bearer, "bluetooth") == 0)
122 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
123 else if (g_strcmp0(bearer, "3g") == 0)
124 return CONNMAN_SERVICE_TYPE_CELLULAR;
126 return CONNMAN_SERVICE_TYPE_UNKNOWN;
129 static char *service2bearer(enum connman_service_type type)
132 case CONNMAN_SERVICE_TYPE_ETHERNET:
134 case CONNMAN_SERVICE_TYPE_WIFI:
136 case CONNMAN_SERVICE_TYPE_WIMAX:
138 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
140 case CONNMAN_SERVICE_TYPE_CELLULAR:
142 case CONNMAN_SERVICE_TYPE_UNKNOWN:
143 case CONNMAN_SERVICE_TYPE_SYSTEM:
144 case CONNMAN_SERVICE_TYPE_GPS:
145 case CONNMAN_SERVICE_TYPE_VPN:
146 case CONNMAN_SERVICE_TYPE_GADGET:
153 static char *session2bearer(struct connman_session *session)
156 struct bearer_info *info;
157 enum connman_service_type type;
159 if (session->service == NULL)
162 type = connman_service_get_type(session->service);
164 for (list = session->allowed_bearers; list != NULL; list = list->next) {
168 return service2bearer(type);
170 if (info->service_type == CONNMAN_SERVICE_TYPE_UNKNOWN)
173 if (info->service_type == type)
174 return service2bearer(type);
181 static void cleanup_bearer_info(gpointer data, gpointer user_data)
183 struct bearer_info *info = data;
189 static GSList *session_parse_allowed_bearers(DBusMessageIter *iter)
191 struct bearer_info *info;
192 DBusMessageIter array;
195 dbus_message_iter_recurse(iter, &array);
197 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
200 dbus_message_iter_get_basic(&array, &bearer);
202 info = g_try_new0(struct bearer_info, 1);
204 g_slist_foreach(list, cleanup_bearer_info, NULL);
210 info->name = g_strdup(bearer);
211 info->service_type = bearer2service(info->name);
213 if (info->service_type == CONNMAN_SERVICE_TYPE_UNKNOWN &&
214 g_strcmp0(info->name, "*") == 0) {
215 info->match_all = TRUE;
217 info->match_all = FALSE;
220 list = g_slist_append(list, info);
222 dbus_message_iter_next(&array);
228 static GSList *session_allowed_bearers_any(void)
230 struct bearer_info *info;
233 info = g_try_new0(struct bearer_info, 1);
240 info->name = g_strdup("");
241 info->match_all = TRUE;
242 info->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
244 list = g_slist_append(list, info);
249 static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
251 struct connman_session *session = user_data;
254 for (list = session->allowed_bearers; list != NULL; list = list->next) {
255 struct bearer_info *info = list->data;
257 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
262 static void append_ipconfig_ipv4(DBusMessageIter *iter, void *user_data)
264 struct connman_service *service = user_data;
265 struct connman_ipconfig *ipconfig_ipv4;
270 ipconfig_ipv4 = __connman_service_get_ip4config(service);
271 if (ipconfig_ipv4 == NULL)
274 __connman_ipconfig_append_ipv4(ipconfig_ipv4, iter);
277 static void append_ipconfig_ipv6(DBusMessageIter *iter, void *user_data)
279 struct connman_service *service = user_data;
280 struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
285 ipconfig_ipv4 = __connman_service_get_ip4config(service);
286 ipconfig_ipv6 = __connman_service_get_ip6config(service);
287 if (ipconfig_ipv6 == NULL)
290 __connman_ipconfig_append_ipv6(ipconfig_ipv6, iter, ipconfig_ipv4);
293 static void append_service(DBusMessageIter *dict,
294 struct connman_session *session)
296 connman_dbus_dict_append_basic(dict, "Bearer",
297 DBUS_TYPE_STRING, &session->bearer);
299 connman_dbus_dict_append_basic(dict, "Online",
300 DBUS_TYPE_BOOLEAN, &session->online);
302 connman_dbus_dict_append_basic(dict, "Name",
303 DBUS_TYPE_STRING, &session->name);
305 connman_dbus_dict_append_dict(dict, "IPv4",
306 append_ipconfig_ipv4, session->service);
308 connman_dbus_dict_append_dict(dict, "IPv6",
309 append_ipconfig_ipv6, session->service);
311 connman_dbus_dict_append_basic(dict, "Interface",
312 DBUS_TYPE_STRING, &session->ifname);
316 static void append_notify_all(DBusMessageIter *dict,
317 struct connman_session *session)
321 append_service(dict, session);
323 connman_dbus_dict_append_basic(dict, "Priority",
324 DBUS_TYPE_BOOLEAN, &session->priority);
326 connman_dbus_dict_append_array(dict, "AllowedBearers",
328 append_allowed_bearers,
331 connman_dbus_dict_append_basic(dict, "AvoidHandover",
333 &session->avoid_handover);
335 connman_dbus_dict_append_basic(dict, "StayConnected",
337 &session->stay_connected);
339 connman_dbus_dict_append_basic(dict, "PeriodicConnect",
341 &session->periodic_connect);
343 connman_dbus_dict_append_basic(dict, "IdleTimeout",
345 &session->idle_timeout);
347 connman_dbus_dict_append_basic(dict, "EmergencyCall",
348 DBUS_TYPE_BOOLEAN, &session->ecall);
350 policy = roamingpolicy2string(session->roaming_policy);
351 connman_dbus_dict_append_basic(dict, "RoamingPolicy",
355 connman_dbus_dict_append_basic(dict, "SessionMarker",
356 DBUS_TYPE_UINT32, &session->marker);
359 static gboolean session_notify_all(gpointer user_data)
361 struct connman_session *session = user_data;
363 DBusMessageIter array, dict;
365 DBG("session %p owner %s notify_path %s", session,
366 session->owner, session->notify_path);
368 msg = dbus_message_new_method_call(session->owner, session->notify_path,
369 CONNMAN_NOTIFICATION_INTERFACE,
372 connman_error("Could not create notification message");
376 dbus_message_iter_init_append(msg, &array);
377 connman_dbus_dict_open(&array, &dict);
379 append_notify_all(&dict, session);
381 connman_dbus_dict_close(&array, &dict);
383 g_dbus_send_message(connection, msg);
388 static gboolean service_changed(gpointer user_data)
390 struct connman_session *session = user_data;
394 DBusMessageIter array, dict;
396 DBG("session %p owner %s notify_path %s", session,
397 session->owner, session->notify_path);
399 msg = dbus_message_new_method_call(session->owner, session->notify_path,
400 CONNMAN_NOTIFICATION_INTERFACE,
403 connman_error("Could not create notification message");
407 dbus_message_iter_init_append(msg, &array);
408 connman_dbus_dict_open(&array, &dict);
410 append_service(&dict, session);
412 connman_dbus_dict_close(&array, &dict);
414 g_dbus_send_message(connection, msg);
419 static void online_changed(struct connman_session *session)
421 connman_dbus_setting_changed_basic(session->owner, session->notify_path,
422 "Online", DBUS_TYPE_BOOLEAN,
426 static void ipconfig_ipv4_changed(struct connman_session *session)
428 connman_dbus_setting_changed_dict(session->owner, session->notify_path,
429 "IPv4", append_ipconfig_ipv4, session->service);
432 static void ipconfig_ipv6_changed(struct connman_session *session)
434 connman_dbus_setting_changed_dict(session->owner, session->notify_path,
435 "IPv6", append_ipconfig_ipv6, session->service);
438 static void update_service(struct connman_session *session)
442 if (session->service != NULL) {
443 session->bearer = session2bearer(session);
445 __connman_service_is_connected(session->service);
446 session->name = __connman_service_get_name(session->service);
447 idx = __connman_service_get_index(session->service);
448 session->ifname = connman_inet_ifname(idx);
451 session->bearer = "";
452 session->online = FALSE;
454 session->ifname = "";
458 static connman_bool_t service_match(struct connman_session *session,
459 struct connman_service *service)
463 DBG("session %p service %p", session, service);
465 for (list = session->allowed_bearers; list != NULL; list = list->next) {
466 struct bearer_info *info = list->data;
467 enum connman_service_type service_type;
469 if (info->match_all == TRUE)
472 service_type = connman_service_get_type(service);
473 if (info->service_type == service_type)
480 static connman_bool_t session_select_service(struct connman_session *session)
482 struct connman_service *service;
485 session->service_list =
486 __connman_service_get_list(session, service_match);
488 if (session->service_list == NULL)
491 iter = g_sequence_get_begin_iter(session->service_list);
493 while (g_sequence_iter_is_end(iter) == FALSE) {
494 service = g_sequence_get(iter);
496 if (__connman_service_is_connected(service) == TRUE) {
497 session->service = service;
500 iter = g_sequence_iter_next(iter);
506 static void print_name(gpointer data, gpointer user_data)
508 struct connman_service *service = data;
510 DBG("service %p name %s", service,
511 __connman_service_get_name(service));
514 static void cleanup_session(gpointer user_data)
516 struct connman_session *session = user_data;
518 DBG("remove %s", session->session_path);
520 g_sequence_free(session->service_list);
522 g_slist_foreach(session->allowed_bearers, cleanup_bearer_info, NULL);
523 g_slist_free(session->allowed_bearers);
525 g_free(session->owner);
526 g_free(session->session_path);
527 g_free(session->notify_path);
532 static void release_session(gpointer key, gpointer value, gpointer user_data)
534 struct connman_session *session = value;
535 DBusMessage *message;
537 DBG("owner %s path %s", session->owner, session->notify_path);
539 if (session->notify_watch > 0)
540 g_dbus_remove_watch(connection, session->notify_watch);
542 g_dbus_unregister_interface(connection, session->session_path,
543 CONNMAN_SESSION_INTERFACE);
545 message = dbus_message_new_method_call(session->owner,
546 session->notify_path,
547 CONNMAN_NOTIFICATION_INTERFACE,
552 dbus_message_set_no_reply(message, TRUE);
554 g_dbus_send_message(connection, message);
557 static int session_disconnect(struct connman_session *session)
559 DBG("session %p, %s", session, session->owner);
561 if (session->notify_watch > 0)
562 g_dbus_remove_watch(connection, session->notify_watch);
564 g_dbus_unregister_interface(connection, session->session_path,
565 CONNMAN_SESSION_INTERFACE);
567 g_hash_table_remove(session_hash, session->session_path);
572 static void owner_disconnect(DBusConnection *conn, void *user_data)
574 struct connman_session *session = user_data;
576 DBG("session %p, %s died", session, session->owner);
578 session_disconnect(session);
581 static DBusMessage *destroy_session(DBusConnection *conn,
582 DBusMessage *msg, void *user_data)
584 struct connman_session *session = user_data;
586 DBG("session %p", session);
588 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
591 static DBusMessage *connect_session(DBusConnection *conn,
592 DBusMessage *msg, void *user_data)
594 struct connman_session *session = user_data;
597 DBG("session %p", session);
599 if (session->service_list != NULL)
600 g_sequence_free(session->service_list);
602 session->service_list = __connman_service_get_list(session,
605 g_sequence_foreach(session->service_list, print_name, NULL);
607 err = __connman_service_session_connect(session->service_list,
610 return __connman_error_failed(msg, -err);
612 update_service(session);
613 g_timeout_add_seconds(0, service_changed, session);
615 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
618 static DBusMessage *disconnect_session(DBusConnection *conn,
619 DBusMessage *msg, void *user_data)
621 struct connman_session *session = user_data;
624 DBG("session %p", session);
626 if (session->service == NULL)
627 return __connman_error_already_disabled(msg);
629 err = __connman_service_disconnect(session->service);
631 return __connman_error_failed(msg, -err);
633 session->service = NULL;
634 update_service(session);
635 g_timeout_add_seconds(0, service_changed, session);
637 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
640 static DBusMessage *change_session(DBusConnection *conn,
641 DBusMessage *msg, void *user_data)
643 struct connman_session *session = user_data;
644 DBusMessageIter iter, value;
646 DBusMessageIter reply_array, reply_dict;
648 GSList *allowed_bearers;
650 DBG("session %p", session);
651 if (dbus_message_iter_init(msg, &iter) == FALSE)
652 return __connman_error_invalid_arguments(msg);
654 reply = dbus_message_new_method_call(session->owner,
655 session->notify_path,
656 CONNMAN_NOTIFICATION_INTERFACE,
659 return __connman_error_failed(msg, ENOMEM);
661 dbus_message_iter_init_append(reply, &reply_array);
662 connman_dbus_dict_open(&reply_array, &reply_dict);
664 dbus_message_iter_get_basic(&iter, &name);
665 dbus_message_iter_next(&iter);
666 dbus_message_iter_recurse(&iter, &value);
668 switch (dbus_message_iter_get_arg_type(&value)) {
669 case DBUS_TYPE_ARRAY:
670 if (g_str_equal(name, "AllowedBearers") == TRUE) {
671 allowed_bearers = session_parse_allowed_bearers(&value);
673 g_slist_foreach(session->allowed_bearers,
674 cleanup_bearer_info, NULL);
675 g_slist_free(session->allowed_bearers);
677 if (allowed_bearers == NULL) {
678 allowed_bearers = session_allowed_bearers_any();
680 if (allowed_bearers == NULL) {
681 dbus_message_unref(reply);
682 return __connman_error_failed(msg, ENOMEM);
686 session->allowed_bearers = allowed_bearers;
688 /* update_allowed_bearers(); */
690 connman_dbus_dict_append_array(&reply_dict,
693 append_allowed_bearers,
697 case DBUS_TYPE_BOOLEAN:
698 if (g_str_equal(name, "Priority") == TRUE) {
699 dbus_message_iter_get_basic(&value, &session->priority);
701 /* update_priority(); */
703 connman_dbus_dict_append_basic(&reply_dict, "Priority",
707 } else if (g_str_equal(name, "AvoidHandover") == TRUE) {
708 dbus_message_iter_get_basic(&value,
709 &session->avoid_handover);
711 /* update_avoid_handover(); */
713 connman_dbus_dict_append_basic(&reply_dict,
716 &session->avoid_handover);
718 } else if (g_str_equal(name, "StayConnected") == TRUE) {
719 dbus_message_iter_get_basic(&value,
720 &session->stay_connected);
722 /* update_stay_connected(); */
724 connman_dbus_dict_append_basic(&reply_dict,
727 &session->stay_connected);
729 } else if (g_str_equal(name, "EmergencyCall") == TRUE) {
730 dbus_message_iter_get_basic(&value, &session->ecall);
732 /* update_ecall(); */
734 connman_dbus_dict_append_basic(&reply_dict,
741 case DBUS_TYPE_UINT32:
742 if (g_str_equal(name, "PeriodicConnect") == TRUE) {
743 dbus_message_iter_get_basic(&value,
744 &session->periodic_connect);
746 /* update_periodic_update(); */
748 connman_dbus_dict_append_basic(&reply_dict,
751 &session->periodic_connect);
752 } else if (g_str_equal(name, "IdleTimeout") == TRUE) {
753 dbus_message_iter_get_basic(&value,
754 &session->idle_timeout);
756 /* update_idle_timeout(); */
758 connman_dbus_dict_append_basic(&reply_dict,
761 &session->idle_timeout);
764 case DBUS_TYPE_STRING:
765 if (g_str_equal(name, "RoamingPolicy") == TRUE) {
767 dbus_message_iter_get_basic(&value, &val);
768 session->roaming_policy = string2roamingpolicy(val);
770 /* update_roaming_allowed(); */
772 val = roamingpolicy2string(session->roaming_policy);
773 connman_dbus_dict_append_basic(&reply_dict,
781 connman_dbus_dict_close(&reply_array, &reply_dict);
783 g_dbus_send_message(connection, reply);
785 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
788 static GDBusMethodTable session_methods[] = {
789 { "Destroy", "", "", destroy_session },
790 { "Connect", "", "", connect_session },
791 { "Disconnect", "", "", disconnect_session },
792 { "Change", "sv", "", change_session },
796 int __connman_session_create(DBusMessage *msg)
798 const char *owner, *notify_path;
800 DBusMessageIter iter, array;
801 struct connman_session *session;
803 connman_bool_t priority = FALSE, avoid_handover = FALSE;
804 connman_bool_t stay_connected = FALSE, ecall = FALSE;
805 enum connman_session_roaming_policy roaming_policy =
806 CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN;
807 GSList *allowed_bearers = NULL;
808 unsigned int periodic_connect = 0;
809 unsigned int idle_timeout = 0;
813 owner = dbus_message_get_sender(msg);
815 DBG("owner %s", owner);
817 dbus_message_iter_init(msg, &iter);
818 dbus_message_iter_recurse(&iter, &array);
820 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
821 DBusMessageIter entry, value;
822 const char *key, *val;
824 dbus_message_iter_recurse(&array, &entry);
825 dbus_message_iter_get_basic(&entry, &key);
827 dbus_message_iter_next(&entry);
828 dbus_message_iter_recurse(&entry, &value);
830 switch (dbus_message_iter_get_arg_type(&value)) {
831 case DBUS_TYPE_ARRAY:
832 if (g_str_equal(key, "AllowedBearers") == TRUE) {
834 session_parse_allowed_bearers(&value);
837 case DBUS_TYPE_BOOLEAN:
838 if (g_str_equal(key, "Priority") == TRUE) {
839 dbus_message_iter_get_basic(&value,
841 } else if (g_str_equal(key, "AvoidHandover") == TRUE) {
842 dbus_message_iter_get_basic(&value,
844 } else if (g_str_equal(key, "StayConnected") == TRUE) {
845 dbus_message_iter_get_basic(&value,
847 } else if (g_str_equal(key, "EmergencyCall") == TRUE) {
848 dbus_message_iter_get_basic(&value,
852 case DBUS_TYPE_UINT32:
853 if (g_str_equal(key, "PeriodicConnect") == TRUE) {
854 dbus_message_iter_get_basic(&value,
856 } else if (g_str_equal(key, "IdleTimeout") == TRUE) {
857 dbus_message_iter_get_basic(&value,
861 case DBUS_TYPE_STRING:
863 if (g_str_equal(key, "RoamingPolicy") == TRUE) {
864 dbus_message_iter_get_basic(&value, &val);
865 roaming_policy = string2roamingpolicy(val);
868 dbus_message_iter_next(&array);
871 dbus_message_iter_next(&iter);
872 dbus_message_iter_get_basic(&iter, ¬ify_path);
874 if (notify_path == NULL) {
880 session_path = g_strdup_printf("/sessions%s", notify_path);
881 if (session_path == NULL) {
886 session = g_hash_table_lookup(session_hash, session_path);
887 if (session != NULL) {
892 session = g_try_new0(struct connman_session, 1);
893 if (session == NULL) {
898 session->owner = g_strdup(owner);
899 session->session_path = session_path;
900 session->notify_path = g_strdup(notify_path);
901 session->notify_watch =
902 g_dbus_add_disconnect_watch(connection, session->owner,
903 owner_disconnect, session, NULL);
905 session->bearer = "";
906 session->online = FALSE;
907 session->priority = priority;
908 session->avoid_handover = avoid_handover;
909 session->stay_connected = stay_connected;
910 session->periodic_connect = periodic_connect;
911 session->idle_timeout = idle_timeout;
912 session->ecall = ecall;
913 session->roaming_policy = roaming_policy;
915 if (session->allowed_bearers == NULL) {
916 session->allowed_bearers = session_allowed_bearers_any();
918 if (session->allowed_bearers == NULL) {
924 session->service_list = NULL;
926 update_service(session);
928 g_hash_table_replace(session_hash, session->session_path, session);
930 DBG("add %s", session->session_path);
932 if (g_dbus_register_interface(connection, session->session_path,
933 CONNMAN_SESSION_INTERFACE,
934 session_methods, NULL,
935 NULL, session, NULL) == FALSE) {
936 connman_error("Failed to register %s", session->session_path);
937 g_hash_table_remove(session_hash, session->session_path);
944 g_dbus_send_reply(connection, msg,
945 DBUS_TYPE_OBJECT_PATH, &session->session_path,
950 * Check if the session settings matches to a service which is
951 * a already connected
953 if (session_select_service(session) == TRUE)
954 update_service(session);
956 g_timeout_add_seconds(0, session_notify_all, session);
961 connman_error("Failed to create session");
962 g_free(session_path);
964 g_slist_foreach(allowed_bearers, cleanup_bearer_info, NULL);
965 g_slist_free(allowed_bearers);
970 int __connman_session_destroy(DBusMessage *msg)
972 const char *owner, *session_path;
973 struct connman_session *session;
975 owner = dbus_message_get_sender(msg);
977 DBG("owner %s", owner);
979 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &session_path,
981 if (session_path == NULL)
984 session = g_hash_table_lookup(session_hash, session_path);
988 if (g_strcmp0(owner, session->owner) != 0)
991 session_disconnect(session);
996 connman_bool_t __connman_session_mode()
1001 void __connman_session_set_mode(connman_bool_t enable)
1003 DBG("enable %d", enable);
1005 if (sessionmode == enable)
1008 sessionmode = enable;
1010 if (sessionmode == TRUE)
1011 __connman_service_disconnect_all();
1014 static void service_state_changed(struct connman_service *service,
1015 enum connman_service_state state)
1017 GHashTableIter iter;
1018 gpointer key, value;
1019 struct connman_session *session;
1020 connman_bool_t online;
1022 DBG("service %p state %d", service, state);
1024 g_hash_table_iter_init(&iter, session_hash);
1026 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1029 if (session->service == service) {
1030 online = __connman_service_is_connected(service);
1031 if (session->online != online)
1034 session->online = online;
1035 online_changed(session);
1040 static void ipconfig_changed(struct connman_service *service,
1041 struct connman_ipconfig *ipconfig)
1043 GHashTableIter iter;
1044 gpointer key, value;
1045 struct connman_session *session;
1046 enum connman_ipconfig_type type;
1048 DBG("service %p ipconfig %p", service, ipconfig);
1050 type = __connman_ipconfig_get_config_type(ipconfig);
1052 g_hash_table_iter_init(&iter, session_hash);
1054 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1057 if (session->service == service) {
1058 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1059 ipconfig_ipv4_changed(session);
1060 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1061 ipconfig_ipv6_changed(session);
1066 static struct connman_notifier session_notifier = {
1068 .service_state_changed = service_state_changed,
1069 .ipconfig_changed = ipconfig_changed,
1072 int __connman_session_init(void)
1078 connection = connman_dbus_get_connection();
1079 if (connection == NULL)
1082 err = connman_notifier_register(&session_notifier);
1084 dbus_connection_unref(connection);
1088 session_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1089 NULL, cleanup_session);
1091 sessionmode = FALSE;
1095 void __connman_session_cleanup(void)
1099 if (connection == NULL)
1102 connman_notifier_unregister(&session_notifier);
1104 g_hash_table_foreach(session_hash, release_session, NULL);
1105 g_hash_table_destroy(session_hash);
1107 dbus_connection_unref(connection);