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,
699 case DBUS_TYPE_BOOLEAN:
700 if (g_str_equal(name, "Priority") == TRUE) {
701 dbus_message_iter_get_basic(&value, &session->priority);
703 /* update_priority(); */
705 connman_dbus_dict_append_basic(&reply_dict, "Priority",
709 } else if (g_str_equal(name, "AvoidHandover") == TRUE) {
710 dbus_message_iter_get_basic(&value,
711 &session->avoid_handover);
713 /* update_avoid_handover(); */
715 connman_dbus_dict_append_basic(&reply_dict,
718 &session->avoid_handover);
720 } else if (g_str_equal(name, "StayConnected") == TRUE) {
721 dbus_message_iter_get_basic(&value,
722 &session->stay_connected);
724 /* update_stay_connected(); */
726 connman_dbus_dict_append_basic(&reply_dict,
729 &session->stay_connected);
731 } else if (g_str_equal(name, "EmergencyCall") == TRUE) {
732 dbus_message_iter_get_basic(&value, &session->ecall);
734 /* update_ecall(); */
736 connman_dbus_dict_append_basic(&reply_dict,
745 case DBUS_TYPE_UINT32:
746 if (g_str_equal(name, "PeriodicConnect") == TRUE) {
747 dbus_message_iter_get_basic(&value,
748 &session->periodic_connect);
750 /* update_periodic_update(); */
752 connman_dbus_dict_append_basic(&reply_dict,
755 &session->periodic_connect);
756 } else if (g_str_equal(name, "IdleTimeout") == TRUE) {
757 dbus_message_iter_get_basic(&value,
758 &session->idle_timeout);
760 /* update_idle_timeout(); */
762 connman_dbus_dict_append_basic(&reply_dict,
765 &session->idle_timeout);
770 case DBUS_TYPE_STRING:
771 if (g_str_equal(name, "RoamingPolicy") == TRUE) {
773 dbus_message_iter_get_basic(&value, &val);
774 session->roaming_policy = string2roamingpolicy(val);
776 /* update_roaming_allowed(); */
778 val = roamingpolicy2string(session->roaming_policy);
779 connman_dbus_dict_append_basic(&reply_dict,
789 connman_dbus_dict_close(&reply_array, &reply_dict);
791 g_dbus_send_message(connection, reply);
793 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
796 dbus_message_unref(reply);
797 return __connman_error_invalid_arguments(msg);
800 static GDBusMethodTable session_methods[] = {
801 { "Destroy", "", "", destroy_session },
802 { "Connect", "", "", connect_session },
803 { "Disconnect", "", "", disconnect_session },
804 { "Change", "sv", "", change_session },
808 int __connman_session_create(DBusMessage *msg)
810 const char *owner, *notify_path;
812 DBusMessageIter iter, array;
813 struct connman_session *session;
815 connman_bool_t priority = FALSE, avoid_handover = FALSE;
816 connman_bool_t stay_connected = FALSE, ecall = FALSE;
817 enum connman_session_roaming_policy roaming_policy =
818 CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN;
819 GSList *allowed_bearers = NULL;
820 unsigned int periodic_connect = 0;
821 unsigned int idle_timeout = 0;
825 owner = dbus_message_get_sender(msg);
827 DBG("owner %s", owner);
829 dbus_message_iter_init(msg, &iter);
830 dbus_message_iter_recurse(&iter, &array);
832 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
833 DBusMessageIter entry, value;
834 const char *key, *val;
836 dbus_message_iter_recurse(&array, &entry);
837 dbus_message_iter_get_basic(&entry, &key);
839 dbus_message_iter_next(&entry);
840 dbus_message_iter_recurse(&entry, &value);
842 switch (dbus_message_iter_get_arg_type(&value)) {
843 case DBUS_TYPE_ARRAY:
844 if (g_str_equal(key, "AllowedBearers") == TRUE) {
846 session_parse_allowed_bearers(&value);
851 case DBUS_TYPE_BOOLEAN:
852 if (g_str_equal(key, "Priority") == TRUE) {
853 dbus_message_iter_get_basic(&value,
855 } else if (g_str_equal(key, "AvoidHandover") == TRUE) {
856 dbus_message_iter_get_basic(&value,
858 } else if (g_str_equal(key, "StayConnected") == TRUE) {
859 dbus_message_iter_get_basic(&value,
861 } else if (g_str_equal(key, "EmergencyCall") == TRUE) {
862 dbus_message_iter_get_basic(&value,
868 case DBUS_TYPE_UINT32:
869 if (g_str_equal(key, "PeriodicConnect") == TRUE) {
870 dbus_message_iter_get_basic(&value,
872 } else if (g_str_equal(key, "IdleTimeout") == TRUE) {
873 dbus_message_iter_get_basic(&value,
879 case DBUS_TYPE_STRING:
880 if (g_str_equal(key, "RoamingPolicy") == TRUE) {
881 dbus_message_iter_get_basic(&value, &val);
882 roaming_policy = string2roamingpolicy(val);
887 dbus_message_iter_next(&array);
890 dbus_message_iter_next(&iter);
891 dbus_message_iter_get_basic(&iter, ¬ify_path);
893 if (notify_path == NULL) {
899 session_path = g_strdup_printf("/sessions%s", notify_path);
900 if (session_path == NULL) {
905 session = g_hash_table_lookup(session_hash, session_path);
906 if (session != NULL) {
911 session = g_try_new0(struct connman_session, 1);
912 if (session == NULL) {
917 session->owner = g_strdup(owner);
918 session->session_path = session_path;
919 session->notify_path = g_strdup(notify_path);
920 session->notify_watch =
921 g_dbus_add_disconnect_watch(connection, session->owner,
922 owner_disconnect, session, NULL);
924 session->bearer = "";
925 session->online = FALSE;
926 session->priority = priority;
927 session->avoid_handover = avoid_handover;
928 session->stay_connected = stay_connected;
929 session->periodic_connect = periodic_connect;
930 session->idle_timeout = idle_timeout;
931 session->ecall = ecall;
932 session->roaming_policy = roaming_policy;
934 if (session->allowed_bearers == NULL) {
935 session->allowed_bearers = session_allowed_bearers_any();
937 if (session->allowed_bearers == NULL) {
943 session->service_list = NULL;
945 update_service(session);
947 g_hash_table_replace(session_hash, session->session_path, session);
949 DBG("add %s", session->session_path);
951 if (g_dbus_register_interface(connection, session->session_path,
952 CONNMAN_SESSION_INTERFACE,
953 session_methods, NULL,
954 NULL, session, NULL) == FALSE) {
955 connman_error("Failed to register %s", session->session_path);
956 g_hash_table_remove(session_hash, session->session_path);
963 g_dbus_send_reply(connection, msg,
964 DBUS_TYPE_OBJECT_PATH, &session->session_path,
969 * Check if the session settings matches to a service which is
970 * a already connected
972 if (session_select_service(session) == TRUE)
973 update_service(session);
975 g_timeout_add_seconds(0, session_notify_all, session);
980 connman_error("Failed to create session");
981 g_free(session_path);
983 g_slist_foreach(allowed_bearers, cleanup_bearer_info, NULL);
984 g_slist_free(allowed_bearers);
989 int __connman_session_destroy(DBusMessage *msg)
991 const char *owner, *session_path;
992 struct connman_session *session;
994 owner = dbus_message_get_sender(msg);
996 DBG("owner %s", owner);
998 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &session_path,
1000 if (session_path == NULL)
1003 session = g_hash_table_lookup(session_hash, session_path);
1004 if (session == NULL)
1007 if (g_strcmp0(owner, session->owner) != 0)
1010 session_disconnect(session);
1015 connman_bool_t __connman_session_mode()
1020 void __connman_session_set_mode(connman_bool_t enable)
1022 DBG("enable %d", enable);
1024 if (sessionmode == enable)
1027 sessionmode = enable;
1029 if (sessionmode == TRUE)
1030 __connman_service_disconnect_all();
1033 static void service_state_changed(struct connman_service *service,
1034 enum connman_service_state state)
1036 GHashTableIter iter;
1037 gpointer key, value;
1038 struct connman_session *session;
1039 connman_bool_t online;
1041 DBG("service %p state %d", service, state);
1043 g_hash_table_iter_init(&iter, session_hash);
1045 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1048 if (session->service == service) {
1049 online = __connman_service_is_connected(service);
1050 if (session->online != online)
1053 session->online = online;
1054 online_changed(session);
1059 static void ipconfig_changed(struct connman_service *service,
1060 struct connman_ipconfig *ipconfig)
1062 GHashTableIter iter;
1063 gpointer key, value;
1064 struct connman_session *session;
1065 enum connman_ipconfig_type type;
1067 DBG("service %p ipconfig %p", service, ipconfig);
1069 type = __connman_ipconfig_get_config_type(ipconfig);
1071 g_hash_table_iter_init(&iter, session_hash);
1073 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1076 if (session->service == service) {
1077 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1078 ipconfig_ipv4_changed(session);
1079 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1080 ipconfig_ipv6_changed(session);
1085 static struct connman_notifier session_notifier = {
1087 .service_state_changed = service_state_changed,
1088 .ipconfig_changed = ipconfig_changed,
1091 int __connman_session_init(void)
1097 connection = connman_dbus_get_connection();
1098 if (connection == NULL)
1101 err = connman_notifier_register(&session_notifier);
1103 dbus_connection_unref(connection);
1107 session_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1108 NULL, cleanup_session);
1110 sessionmode = FALSE;
1114 void __connman_session_cleanup(void)
1118 if (connection == NULL)
1121 connman_notifier_unregister(&session_notifier);
1123 g_hash_table_foreach(session_hash, release_session, NULL);
1124 g_hash_table_destroy(session_hash);
1126 dbus_connection_unref(connection);