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 gboolean session_do_connect(gpointer user_data)
593 struct connman_session *session = user_data;
595 __connman_service_connect(session->service);
597 service_changed(session);
601 static DBusMessage *connect_session(DBusConnection *conn,
602 DBusMessage *msg, void *user_data)
604 struct connman_session *session = user_data;
605 struct connman_service *service = NULL;
606 GSourceFunc callback;
609 DBG("session %p", session);
611 if (session->service_list != NULL)
612 g_sequence_free(session->service_list);
614 session->service_list = __connman_service_get_list(session,
617 g_sequence_foreach(session->service_list, print_name, NULL);
620 iter = g_sequence_get_begin_iter(session->service_list);
622 while (g_sequence_iter_is_end(iter) == FALSE) {
623 service = g_sequence_get(iter);
625 if (__connman_service_is_connecting(service) == TRUE ||
626 __connman_service_is_connected(service) == TRUE) {
627 callback = service_changed;
631 if (__connman_service_is_idle(service) == TRUE) {
632 callback = session_do_connect;
636 iter = g_sequence_iter_next(iter);
639 if (session != NULL) {
640 session->service = service;
641 update_service(session);
642 g_timeout_add_seconds(0, callback, session);
645 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
648 static gboolean session_do_disconnect(gpointer user_data)
650 struct connman_session *session = user_data;
652 if (__connman_service_disconnect(session->service) < 0)
655 session->service = NULL;
656 update_service(session);
657 service_changed(session);
662 static DBusMessage *disconnect_session(DBusConnection *conn,
663 DBusMessage *msg, void *user_data)
665 struct connman_session *session = user_data;
667 DBG("session %p", session);
669 if (session->service == NULL)
670 return __connman_error_already_disabled(msg);
672 g_timeout_add_seconds(0, session_do_disconnect, session);
674 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
677 static DBusMessage *change_session(DBusConnection *conn,
678 DBusMessage *msg, void *user_data)
680 struct connman_session *session = user_data;
681 DBusMessageIter iter, value;
683 DBusMessageIter reply_array, reply_dict;
685 GSList *allowed_bearers;
687 DBG("session %p", session);
688 if (dbus_message_iter_init(msg, &iter) == FALSE)
689 return __connman_error_invalid_arguments(msg);
691 reply = dbus_message_new_method_call(session->owner,
692 session->notify_path,
693 CONNMAN_NOTIFICATION_INTERFACE,
696 return __connman_error_failed(msg, ENOMEM);
698 dbus_message_iter_init_append(reply, &reply_array);
699 connman_dbus_dict_open(&reply_array, &reply_dict);
701 dbus_message_iter_get_basic(&iter, &name);
702 dbus_message_iter_next(&iter);
703 dbus_message_iter_recurse(&iter, &value);
705 switch (dbus_message_iter_get_arg_type(&value)) {
706 case DBUS_TYPE_ARRAY:
707 if (g_str_equal(name, "AllowedBearers") == TRUE) {
708 allowed_bearers = session_parse_allowed_bearers(&value);
710 g_slist_foreach(session->allowed_bearers,
711 cleanup_bearer_info, NULL);
712 g_slist_free(session->allowed_bearers);
714 if (allowed_bearers == NULL) {
715 allowed_bearers = session_allowed_bearers_any();
717 if (allowed_bearers == NULL) {
718 dbus_message_unref(reply);
719 return __connman_error_failed(msg, ENOMEM);
723 session->allowed_bearers = allowed_bearers;
725 /* update_allowed_bearers(); */
727 connman_dbus_dict_append_array(&reply_dict,
730 append_allowed_bearers,
736 case DBUS_TYPE_BOOLEAN:
737 if (g_str_equal(name, "Priority") == TRUE) {
738 dbus_message_iter_get_basic(&value, &session->priority);
740 /* update_priority(); */
742 connman_dbus_dict_append_basic(&reply_dict, "Priority",
746 } else if (g_str_equal(name, "AvoidHandover") == TRUE) {
747 dbus_message_iter_get_basic(&value,
748 &session->avoid_handover);
750 /* update_avoid_handover(); */
752 connman_dbus_dict_append_basic(&reply_dict,
755 &session->avoid_handover);
757 } else if (g_str_equal(name, "StayConnected") == TRUE) {
758 dbus_message_iter_get_basic(&value,
759 &session->stay_connected);
761 /* update_stay_connected(); */
763 connman_dbus_dict_append_basic(&reply_dict,
766 &session->stay_connected);
768 } else if (g_str_equal(name, "EmergencyCall") == TRUE) {
769 dbus_message_iter_get_basic(&value, &session->ecall);
771 /* update_ecall(); */
773 connman_dbus_dict_append_basic(&reply_dict,
782 case DBUS_TYPE_UINT32:
783 if (g_str_equal(name, "PeriodicConnect") == TRUE) {
784 dbus_message_iter_get_basic(&value,
785 &session->periodic_connect);
787 /* update_periodic_update(); */
789 connman_dbus_dict_append_basic(&reply_dict,
792 &session->periodic_connect);
793 } else if (g_str_equal(name, "IdleTimeout") == TRUE) {
794 dbus_message_iter_get_basic(&value,
795 &session->idle_timeout);
797 /* update_idle_timeout(); */
799 connman_dbus_dict_append_basic(&reply_dict,
802 &session->idle_timeout);
807 case DBUS_TYPE_STRING:
808 if (g_str_equal(name, "RoamingPolicy") == TRUE) {
810 dbus_message_iter_get_basic(&value, &val);
811 session->roaming_policy = string2roamingpolicy(val);
813 /* update_roaming_allowed(); */
815 val = roamingpolicy2string(session->roaming_policy);
816 connman_dbus_dict_append_basic(&reply_dict,
826 connman_dbus_dict_close(&reply_array, &reply_dict);
828 g_dbus_send_message(connection, reply);
830 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
833 dbus_message_unref(reply);
834 return __connman_error_invalid_arguments(msg);
837 static GDBusMethodTable session_methods[] = {
838 { "Destroy", "", "", destroy_session },
839 { "Connect", "", "", connect_session },
840 { "Disconnect", "", "", disconnect_session },
841 { "Change", "sv", "", change_session },
845 int __connman_session_create(DBusMessage *msg)
847 const char *owner, *notify_path;
849 DBusMessageIter iter, array;
850 struct connman_session *session;
852 connman_bool_t priority = FALSE, avoid_handover = FALSE;
853 connman_bool_t stay_connected = FALSE, ecall = FALSE;
854 enum connman_session_roaming_policy roaming_policy =
855 CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN;
856 GSList *allowed_bearers = NULL;
857 unsigned int periodic_connect = 0;
858 unsigned int idle_timeout = 0;
862 owner = dbus_message_get_sender(msg);
864 DBG("owner %s", owner);
866 dbus_message_iter_init(msg, &iter);
867 dbus_message_iter_recurse(&iter, &array);
869 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
870 DBusMessageIter entry, value;
871 const char *key, *val;
873 dbus_message_iter_recurse(&array, &entry);
874 dbus_message_iter_get_basic(&entry, &key);
876 dbus_message_iter_next(&entry);
877 dbus_message_iter_recurse(&entry, &value);
879 switch (dbus_message_iter_get_arg_type(&value)) {
880 case DBUS_TYPE_ARRAY:
881 if (g_str_equal(key, "AllowedBearers") == TRUE) {
883 session_parse_allowed_bearers(&value);
888 case DBUS_TYPE_BOOLEAN:
889 if (g_str_equal(key, "Priority") == TRUE) {
890 dbus_message_iter_get_basic(&value,
892 } else if (g_str_equal(key, "AvoidHandover") == TRUE) {
893 dbus_message_iter_get_basic(&value,
895 } else if (g_str_equal(key, "StayConnected") == TRUE) {
896 dbus_message_iter_get_basic(&value,
898 } else if (g_str_equal(key, "EmergencyCall") == TRUE) {
899 dbus_message_iter_get_basic(&value,
905 case DBUS_TYPE_UINT32:
906 if (g_str_equal(key, "PeriodicConnect") == TRUE) {
907 dbus_message_iter_get_basic(&value,
909 } else if (g_str_equal(key, "IdleTimeout") == TRUE) {
910 dbus_message_iter_get_basic(&value,
916 case DBUS_TYPE_STRING:
917 if (g_str_equal(key, "RoamingPolicy") == TRUE) {
918 dbus_message_iter_get_basic(&value, &val);
919 roaming_policy = string2roamingpolicy(val);
924 dbus_message_iter_next(&array);
927 dbus_message_iter_next(&iter);
928 dbus_message_iter_get_basic(&iter, ¬ify_path);
930 if (notify_path == NULL) {
936 session_path = g_strdup_printf("/sessions%s", notify_path);
937 if (session_path == NULL) {
942 session = g_hash_table_lookup(session_hash, session_path);
943 if (session != NULL) {
948 session = g_try_new0(struct connman_session, 1);
949 if (session == NULL) {
954 session->owner = g_strdup(owner);
955 session->session_path = session_path;
956 session->notify_path = g_strdup(notify_path);
957 session->notify_watch =
958 g_dbus_add_disconnect_watch(connection, session->owner,
959 owner_disconnect, session, NULL);
961 session->bearer = "";
962 session->online = FALSE;
963 session->priority = priority;
964 session->avoid_handover = avoid_handover;
965 session->stay_connected = stay_connected;
966 session->periodic_connect = periodic_connect;
967 session->idle_timeout = idle_timeout;
968 session->ecall = ecall;
969 session->roaming_policy = roaming_policy;
971 if (session->allowed_bearers == NULL) {
972 session->allowed_bearers = session_allowed_bearers_any();
974 if (session->allowed_bearers == NULL) {
980 session->service_list = NULL;
982 update_service(session);
984 g_hash_table_replace(session_hash, session->session_path, session);
986 DBG("add %s", session->session_path);
988 if (g_dbus_register_interface(connection, session->session_path,
989 CONNMAN_SESSION_INTERFACE,
990 session_methods, NULL,
991 NULL, session, NULL) == FALSE) {
992 connman_error("Failed to register %s", session->session_path);
993 g_hash_table_remove(session_hash, session->session_path);
1000 g_dbus_send_reply(connection, msg,
1001 DBUS_TYPE_OBJECT_PATH, &session->session_path,
1006 * Check if the session settings matches to a service which is
1007 * a already connected
1009 if (session_select_service(session) == TRUE)
1010 update_service(session);
1012 g_timeout_add_seconds(0, session_notify_all, session);
1017 connman_error("Failed to create session");
1018 g_free(session_path);
1020 g_slist_foreach(allowed_bearers, cleanup_bearer_info, NULL);
1021 g_slist_free(allowed_bearers);
1026 int __connman_session_destroy(DBusMessage *msg)
1028 const char *owner, *session_path;
1029 struct connman_session *session;
1031 owner = dbus_message_get_sender(msg);
1033 DBG("owner %s", owner);
1035 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &session_path,
1037 if (session_path == NULL)
1040 session = g_hash_table_lookup(session_hash, session_path);
1041 if (session == NULL)
1044 if (g_strcmp0(owner, session->owner) != 0)
1047 session_disconnect(session);
1052 connman_bool_t __connman_session_mode()
1057 void __connman_session_set_mode(connman_bool_t enable)
1059 DBG("enable %d", enable);
1061 if (sessionmode == enable)
1064 sessionmode = enable;
1066 if (sessionmode == TRUE)
1067 __connman_service_disconnect_all();
1070 static void service_state_changed(struct connman_service *service,
1071 enum connman_service_state state)
1073 GHashTableIter iter;
1074 gpointer key, value;
1075 struct connman_session *session;
1076 connman_bool_t online;
1078 DBG("service %p state %d", service, state);
1080 g_hash_table_iter_init(&iter, session_hash);
1082 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1085 if (session->service == service) {
1086 online = __connman_service_is_connected(service);
1087 if (session->online == online)
1090 session->online = online;
1091 online_changed(session);
1096 static void ipconfig_changed(struct connman_service *service,
1097 struct connman_ipconfig *ipconfig)
1099 GHashTableIter iter;
1100 gpointer key, value;
1101 struct connman_session *session;
1102 enum connman_ipconfig_type type;
1104 DBG("service %p ipconfig %p", service, ipconfig);
1106 type = __connman_ipconfig_get_config_type(ipconfig);
1108 g_hash_table_iter_init(&iter, session_hash);
1110 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1113 if (session->service == service) {
1114 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1115 ipconfig_ipv4_changed(session);
1116 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1117 ipconfig_ipv6_changed(session);
1122 static struct connman_notifier session_notifier = {
1124 .service_state_changed = service_state_changed,
1125 .ipconfig_changed = ipconfig_changed,
1128 int __connman_session_init(void)
1134 connection = connman_dbus_get_connection();
1135 if (connection == NULL)
1138 err = connman_notifier_register(&session_notifier);
1140 dbus_connection_unref(connection);
1144 session_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1145 NULL, cleanup_session);
1147 sessionmode = FALSE;
1151 void __connman_session_cleanup(void)
1155 if (connection == NULL)
1158 connman_notifier_unregister(&session_notifier);
1160 g_hash_table_foreach(session_hash, release_session, NULL);
1161 g_hash_table_destroy(session_hash);
1163 dbus_connection_unref(connection);