1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of tlm
6 * Copyright (C) 2014 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 #include "common/tlm-log.h"
27 #include "common/tlm-error.h"
28 #include "common/tlm-pipe-stream.h"
29 #include "common/dbus/tlm-dbus-session-gen.h"
30 #include "common/dbus/tlm-dbus-utils.h"
31 #include "common/dbus/tlm-dbus.h"
32 #include "tlm-session-daemon.h"
33 #include "tlm-session.h"
35 struct _TlmSessionDaemonPrivate
37 GDBusConnection *connection;
38 TlmDbusSession *dbus_session;
42 G_DEFINE_TYPE (TlmSessionDaemon, tlm_session_daemon, G_TYPE_OBJECT)
45 #define TLM_SESSION_DAEMON_GET_PRIV(obj) \
46 G_TYPE_INSTANCE_GET_PRIVATE ((obj), TLM_TYPE_SESSION_DAEMON,\
47 TlmSessionDaemonPrivate)
50 _dispose (GObject *object)
52 TlmSessionDaemon *self = TLM_SESSION_DAEMON (object);
53 if (self->priv->dbus_session) {
54 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
55 self->priv->dbus_session));
56 g_object_unref (self->priv->dbus_session);
57 self->priv->dbus_session = NULL;
60 if (self->priv->connection) {
61 g_object_unref (self->priv->connection);
62 self->priv->connection = NULL;
65 if (self->priv->session) {
66 g_object_unref (self->priv->session);
67 self->priv->session = NULL;
70 G_OBJECT_CLASS (tlm_session_daemon_parent_class)->dispose (object);
74 _finalize (GObject *object)
76 G_OBJECT_CLASS (tlm_session_daemon_parent_class)->finalize (object);
80 tlm_session_daemon_class_init (
81 TlmSessionDaemonClass *klass)
83 GObjectClass* object_class = G_OBJECT_CLASS (klass);
85 g_type_class_add_private (object_class, sizeof (
86 TlmSessionDaemonPrivate));
88 object_class->dispose = _dispose;
89 object_class->finalize = _finalize;
94 tlm_session_daemon_init (
95 TlmSessionDaemon *self)
97 self->priv = TLM_SESSION_DAEMON_GET_PRIV(self);
98 self->priv->connection = NULL;
99 self->priv->dbus_session = NULL;
100 self->priv->session = NULL;
104 _on_connection_closed (
105 GDBusConnection *connection,
106 gboolean remote_peer_vanished,
110 TlmSessionDaemon *daemon = TLM_SESSION_DAEMON (user_data);
112 g_signal_handlers_disconnect_by_func (connection, _on_connection_closed,
114 DBG("dbus connection(%p) closed (peer vanished : %d)", connection,
115 remote_peer_vanished);
117 DBG("...reason : %s", error->message);
119 g_object_unref (daemon);
123 _handle_session_create_from_dbus (
124 TlmSessionDaemon *self,
125 GDBusMethodInvocation *invocation,
126 const gchar *password,
127 GVariant *environment,
130 g_return_val_if_fail (self && TLM_IS_SESSION_DAEMON (self), FALSE);
131 gchar *seatid = NULL;
132 gchar *service = NULL;
133 gchar *username = NULL;
134 GHashTable *data = NULL;
136 tlm_dbus_session_complete_session_create (
137 self->priv->dbus_session, invocation);
139 gchar *data_str = g_variant_print(environment, TRUE);
143 data = tlm_dbus_utils_hash_table_from_variant (environment);
144 g_object_get (self->priv->dbus_session, "seatid", &seatid,
145 "username", &username, "service", &service, NULL);
147 tlm_session_start (self->priv->session, seatid, service, username,
150 g_hash_table_unref (data);
158 _handle_session_terminate_from_dbus (
159 TlmSessionDaemon *self,
160 GDBusMethodInvocation *invocation,
163 g_return_val_if_fail (self && TLM_IS_SESSION_DAEMON (self), FALSE);
165 tlm_dbus_session_complete_session_terminate (self->priv->dbus_session,
168 tlm_session_terminate (self->priv->session);
173 _handle_session_created_from_session (
174 TlmSessionDaemon *self,
175 const gchar *sessionid,
178 g_return_if_fail (self && TLM_IS_SESSION_DAEMON (self));
180 DBG ("sessionid: %s", sessionid);
182 g_object_set (G_OBJECT (self->priv->dbus_session), "sessionid", sessionid,
184 tlm_dbus_session_emit_session_created (self->priv->dbus_session, sessionid);
188 _handle_session_terminated_from_session (
189 TlmSessionDaemon *self,
192 g_return_if_fail (self && TLM_IS_SESSION_DAEMON (self));
194 tlm_dbus_session_emit_session_terminated (self->priv->dbus_session);
198 _handle_authenticated_from_session (
199 TlmSessionDaemon *self,
202 g_return_if_fail (self && TLM_IS_SESSION_DAEMON (self));
204 tlm_dbus_session_emit_authenticated (self->priv->dbus_session);
208 _handle_error_from_session (
209 TlmSessionDaemon *self,
213 g_return_if_fail (self && TLM_IS_SESSION_DAEMON (self));
215 GVariant *error = tlm_error_to_variant (gerror);
216 gchar *data_str = g_variant_print (error, TRUE);
220 tlm_dbus_session_emit_error (self->priv->dbus_session, error);
224 tlm_session_daemon_new (
228 GError *error = NULL;
229 TlmPipeStream *stream = NULL;
231 TlmSessionDaemon *daemon = TLM_SESSION_DAEMON (g_object_new (
232 TLM_TYPE_SESSION_DAEMON, NULL));
235 daemon->priv->session = tlm_session_new ();
236 if (!daemon->priv->session) {
237 DBG ("failed to create session object");
238 g_object_unref (daemon);
241 tlm_log_init(G_LOG_DOMAIN);
242 /* Create dbus connection */
243 stream = tlm_pipe_stream_new (in_fd, out_fd, TRUE);
244 daemon->priv->connection = g_dbus_connection_new_sync (G_IO_STREAM (stream),
245 NULL, G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, NULL, NULL,
247 g_object_unref (stream);
249 /* Create dbus object */
250 daemon->priv->dbus_session =
251 tlm_dbus_session_skeleton_new ();
253 /* Connect dbus remote session signals to handlers */
254 g_signal_connect_swapped (daemon->priv->dbus_session,
255 "handle-session-create", G_CALLBACK (
256 _handle_session_create_from_dbus), daemon);
257 g_signal_connect_swapped (daemon->priv->dbus_session,
258 "handle-session-terminate", G_CALLBACK(
259 _handle_session_terminate_from_dbus), daemon);
261 /* Connect session signals to handlers */
262 g_signal_connect_swapped (daemon->priv->session, "session-created",
263 G_CALLBACK (_handle_session_created_from_session), daemon);
264 g_signal_connect_swapped (daemon->priv->session, "session-terminated",
265 G_CALLBACK(_handle_session_terminated_from_session), daemon);
266 g_signal_connect_swapped (daemon->priv->session, "authenticated",
267 G_CALLBACK(_handle_authenticated_from_session), daemon);
268 g_signal_connect_swapped (daemon->priv->session, "session-error",
269 G_CALLBACK(_handle_error_from_session), daemon);
271 g_signal_connect (daemon->priv->connection, "closed",
272 G_CALLBACK(_on_connection_closed), daemon);
274 g_dbus_interface_skeleton_export (
275 G_DBUS_INTERFACE_SKELETON(daemon->priv->dbus_session),
276 daemon->priv->connection, TLM_SESSION_OBJECTPATH, &error);
278 DBG ("failed to register object: %s", error->message);
279 g_error_free (error);
280 g_object_unref (daemon);
283 DBG("Started session daemon '%p' at path '%s' on connection '%p'",
284 daemon, TLM_SESSION_OBJECTPATH, daemon->priv->connection);
286 g_dbus_connection_start_message_processing (daemon->priv->connection);