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 struct connman_session {
42 static gboolean session_notify_all(gpointer user_data)
44 struct connman_session *session = user_data;
46 DBusMessageIter array, dict;
48 DBG("session %p owner %s notify_path %s", session,
49 session->owner, session->notify_path);
51 msg = dbus_message_new_method_call(session->owner, session->notify_path,
52 CONNMAN_NOTIFICATION_INTERFACE,
55 connman_error("Could not create notification message");
59 dbus_message_iter_init_append(msg, &array);
61 connman_dbus_dict_open(&array, &dict);
65 connman_dbus_dict_close(&array, &dict);
67 g_dbus_send_message(connection, msg);
72 static void cleanup_session(gpointer user_data)
74 struct connman_session *session = user_data;
76 DBG("remove %s", session->session_path);
78 g_free(session->owner);
79 g_free(session->session_path);
80 g_free(session->notify_path);
85 static void release_session(gpointer key, gpointer value, gpointer user_data)
87 struct connman_session *session = value;
90 DBG("owner %s path %s", session->owner, session->notify_path);
92 if (session->notify_watch > 0)
93 g_dbus_remove_watch(connection, session->notify_watch);
95 g_dbus_unregister_interface(connection, session->session_path,
96 CONNMAN_SESSION_INTERFACE);
98 message = dbus_message_new_method_call(session->owner,
100 CONNMAN_NOTIFICATION_INTERFACE,
105 dbus_message_set_no_reply(message, TRUE);
107 g_dbus_send_message(connection, message);
110 static int session_disconnect(struct connman_session *session)
112 DBG("session %p, %s", session, session->owner);
114 if (session->notify_watch > 0)
115 g_dbus_remove_watch(connection, session->notify_watch);
117 g_dbus_unregister_interface(connection, session->session_path,
118 CONNMAN_SESSION_INTERFACE);
120 g_hash_table_remove(session_hash, session->session_path);
125 static void owner_disconnect(DBusConnection *conn, void *user_data)
127 struct connman_session *session = user_data;
129 DBG("session %p, %s died", session, session->owner);
131 session_disconnect(session);
134 static DBusMessage *destroy_session(DBusConnection *conn,
135 DBusMessage *msg, void *user_data)
137 struct connman_session *session = user_data;
139 DBG("session %p", session);
141 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
144 static DBusMessage *connect_session(DBusConnection *conn,
145 DBusMessage *msg, void *user_data)
147 struct connman_session *session = user_data;
149 DBG("session %p", session);
151 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
154 static DBusMessage *disconnect_session(DBusConnection *conn,
155 DBusMessage *msg, void *user_data)
157 struct connman_session *session = user_data;
159 DBG("session %p", session);
161 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
164 static DBusMessage *change_session(DBusConnection *conn,
165 DBusMessage *msg, void *user_data)
167 struct connman_session *session = user_data;
169 DBG("session %p", session);
171 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
174 static GDBusMethodTable session_methods[] = {
175 { "Destroy", "", "", destroy_session },
176 { "Connect", "", "", connect_session },
177 { "Disconnect", "", "", disconnect_session },
178 { "Change", "sv", "", change_session },
182 int __connman_session_create(DBusMessage *msg)
184 const char *owner, *notify_path;
186 DBusMessageIter iter, array;
187 struct connman_session *session;
190 owner = dbus_message_get_sender(msg);
192 DBG("owner %s", owner);
194 dbus_message_iter_init(msg, &iter);
195 dbus_message_iter_recurse(&iter, &array);
197 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY)
198 dbus_message_iter_next(&array);
200 dbus_message_iter_next(&iter);
201 dbus_message_iter_get_basic(&iter, ¬ify_path);
203 if (notify_path == NULL) {
209 session_path = g_strdup_printf("/sessions%s", notify_path);
210 if (session_path == NULL) {
215 session = g_hash_table_lookup(session_hash, session_path);
216 if (session != NULL) {
221 session = g_try_new0(struct connman_session, 1);
222 if (session == NULL) {
227 session->owner = g_strdup(owner);
228 session->session_path = session_path;
229 session->notify_path = g_strdup(notify_path);
230 session->notify_watch =
231 g_dbus_add_disconnect_watch(connection, session->owner,
232 owner_disconnect, session, NULL);
234 g_hash_table_replace(session_hash, session->session_path, session);
236 DBG("add %s", session->session_path);
238 if (g_dbus_register_interface(connection, session->session_path,
239 CONNMAN_SESSION_INTERFACE,
240 session_methods, NULL,
241 NULL, session, NULL) == FALSE) {
242 connman_error("Failed to register %s", session->session_path);
243 g_hash_table_remove(session_hash, session->session_path);
250 g_dbus_send_reply(connection, msg,
251 DBUS_TYPE_OBJECT_PATH, &session->session_path,
254 g_timeout_add_seconds(0, session_notify_all, session);
259 connman_error("Failed to create session");
260 g_free(session_path);
265 int __connman_session_destroy(DBusMessage *msg)
267 const char *owner, *session_path;
268 struct connman_session *session;
270 owner = dbus_message_get_sender(msg);
272 DBG("owner %s", owner);
274 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &session_path,
276 if (session_path == NULL)
279 session = g_hash_table_lookup(session_hash, session_path);
283 if (g_strcmp0(owner, session->owner) != 0)
286 session_disconnect(session);
291 connman_bool_t __connman_session_mode()
296 void __connman_session_set_mode(connman_bool_t enable)
298 DBG("enable %d", enable);
300 if (sessionmode == enable)
303 sessionmode = enable;
305 if (sessionmode == TRUE)
306 __connman_service_disconnect_all();
309 int __connman_session_init(void)
313 connection = connman_dbus_get_connection();
314 if (connection == NULL)
317 session_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
318 NULL, cleanup_session);
324 void __connman_session_cleanup(void)
328 if (connection == NULL)
331 g_hash_table_foreach(session_hash, release_session, NULL);
332 g_hash_table_destroy(session_hash);
334 dbus_connection_unref(connection);