bidirectional messages implemented, updated the example code
[profile/ivi/message-port.git] / daemon / dbus-manager.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * Copyright (C) 2013 Intel Corporation.
5  *
6  * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include "dbus-manager.h"
25 #include "common/dbus-manager-glue.h"
26 #include "common/dbus-service-glue.h"
27 #include "common/log.h"
28 #include "dbus-service.h"
29 #include "dbus-server.h"
30 #include "manager.h"
31
32 G_DEFINE_TYPE (MsgPortDbusManager, msgport_dbus_manager, G_TYPE_OBJECT)
33
34 #define MSGPORT_DBUS_MANAGER_GET_PRIV(obj) \
35     G_TYPE_INSTANCE_GET_PRIVATE ((obj), MSGPORT_TYPE_DBUS_MANAGER, MsgPortDbusManagerPrivate)
36
37 struct _MsgPortDbusManagerPrivate {
38     MsgPortDbusGlueManager *dbus_skeleton;
39     GDBusConnection        *connection;
40     MsgPortManager         *manager;
41     MsgPortDbusServer      *server;
42     gchar                  *app_id;
43 };
44
45
46 static void
47 _dbus_manager_finalize (GObject *self)
48 {
49     //MsgPortDbusManager *manager = MSGPORT_DBUS_MANAGER (self);
50
51     G_OBJECT_CLASS (msgport_dbus_manager_parent_class)->finalize (self);
52 }
53
54 static void
55 _dbus_manager_dispose (GObject *self)
56 {
57     MsgPortDbusManager *dbus_mgr = MSGPORT_DBUS_MANAGER (self);
58
59     DBG ("Unexporting dbus manager %p on connection %p", dbus_mgr, dbus_mgr->priv->connection);
60     if (dbus_mgr->priv->dbus_skeleton) {
61         g_dbus_interface_skeleton_unexport (
62                 G_DBUS_INTERFACE_SKELETON (dbus_mgr->priv->dbus_skeleton));
63         g_clear_object (&dbus_mgr->priv->dbus_skeleton);
64     }
65
66     g_clear_object (&dbus_mgr->priv->connection);
67
68     /* unregister all services owned by this connection */
69     msgport_manager_unregister_services (dbus_mgr->priv->manager, dbus_mgr);
70
71     g_clear_object (&dbus_mgr->priv->manager);
72
73     G_OBJECT_CLASS (msgport_dbus_manager_parent_class)->dispose (self);
74 }
75
76
77 static gboolean
78 _dbus_manager_handle_register_service (
79     MsgPortDbusManager    *dbus_mgr,
80     GDBusMethodInvocation *invocation,
81     const gchar           *port_name,
82     gboolean               is_trusted,
83     gpointer               userdata)
84 {
85     GError *error = NULL;
86     MsgPortDbusService *dbus_service = NULL;
87     g_return_val_if_fail (dbus_mgr &&  MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE);
88
89     DBG ("register service request from %p for port %s", dbus_mgr, port_name);
90
91     dbus_service = msgport_manager_register_service (
92             dbus_mgr->priv->manager, dbus_mgr, 
93             port_name, is_trusted, &error);
94
95     if (error) {
96         g_dbus_method_invocation_take_error (invocation, error);
97     }
98     else {
99         msgport_dbus_glue_manager_complete_register_service (
100                 dbus_mgr->priv->dbus_skeleton, invocation, 
101                 msgport_dbus_service_get_object_path(dbus_service));
102     }
103
104     return TRUE;
105 }
106
107 static gboolean
108 _dbus_manager_handle_check_for_remote_service (
109     MsgPortDbusManager    *dbus_mgr,
110     GDBusMethodInvocation *invocation,
111     const gchar    *remote_app_id,
112     const gchar    *remote_port_name,
113     gboolean        is_trusted,
114     gpointer        userdata)
115 {
116     GError *error = NULL;
117     MsgPortDbusService *dbus_service = NULL;
118     MsgPortDbusManager *remote_dbus_manager = NULL;
119
120     g_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE);
121
122     DBG ("check remote service request from %p for %s %s", dbus_mgr, remote_app_id, remote_port_name);
123
124     remote_dbus_manager = msgport_dbus_server_get_dbus_manager_by_app_id (
125                 dbus_mgr->priv->server, remote_app_id);
126
127     dbus_service = msgport_manager_get_service (dbus_mgr->priv->manager, 
128             remote_dbus_manager, remote_port_name, is_trusted);
129
130     if (error) {
131         g_dbus_method_invocation_take_error (invocation, error);
132     }
133     else {
134         DBG ("Found service id : %d", msgport_dbus_service_get_id (dbus_service));
135         msgport_dbus_glue_manager_complete_check_for_remote_service (
136                 dbus_mgr->priv->dbus_skeleton, invocation, 
137                 msgport_dbus_service_get_id (dbus_service));
138     }
139
140     return TRUE;
141 }
142
143 static gboolean
144 _dbus_manager_handle_send_message (
145     MsgPortDbusManager    *dbus_mgr,
146     GDBusMethodInvocation *invocation,
147     guint                  service_id,
148     GVariant              *data,
149     gpointer               userdata)
150 {
151     GError *error = NULL;
152     MsgPortDbusService *dbus_service = 0;
153
154     g_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE);
155
156     DBG ("send_message from %p : %d ", dbus_mgr, service_id);
157
158     dbus_service = msgport_manager_get_service_by_id (
159             dbus_mgr->priv->manager, service_id);
160
161     if (dbus_service){
162         msgport_dbus_service_send_message (dbus_service, data, "", "", FALSE);
163         msgport_dbus_glue_manager_complete_send_message (
164                 dbus_mgr->priv->dbus_skeleton, invocation);
165     }
166     else {
167         /* FIXME : fill error */
168         g_dbus_method_invocation_take_error (invocation, error);
169     }
170
171     return TRUE;
172 }
173
174 static void
175 msgport_dbus_manager_init (MsgPortDbusManager *self)
176 {
177     MsgPortDbusManagerPrivate *priv = MSGPORT_DBUS_MANAGER_GET_PRIV (self);
178
179     priv->dbus_skeleton = msgport_dbus_glue_manager_skeleton_new ();
180     priv->manager = msgport_manager_new ();
181
182     g_signal_connect_swapped (priv->dbus_skeleton, "handle-register-service",
183                 G_CALLBACK (_dbus_manager_handle_register_service), (gpointer)self);
184     g_signal_connect_swapped (priv->dbus_skeleton, "handle-check-for-remote-service",
185                 G_CALLBACK (_dbus_manager_handle_check_for_remote_service), (gpointer)self);
186     g_signal_connect_swapped (priv->dbus_skeleton, "handle-send-message",
187                 G_CALLBACK (_dbus_manager_handle_send_message), (gpointer)self);
188
189     self->priv = priv;
190 }
191
192 static void
193 msgport_dbus_manager_class_init (MsgPortDbusManagerClass *klass)
194 {
195     GObjectClass *gklass = G_OBJECT_CLASS(klass);
196
197     g_type_class_add_private (klass, sizeof(MsgPortDbusManagerPrivate));
198
199     gklass->finalize = _dbus_manager_finalize;
200     gklass->dispose = _dbus_manager_dispose;
201 }
202
203 static gchar *
204 _get_app_id_from_connection (GDBusConnection *connection)
205 {
206     gchar *str_cred = NULL;
207     GCredentials *cred = g_dbus_connection_get_peer_credentials (connection);
208
209     g_return_val_if_fail (cred != NULL, NULL);
210
211     str_cred = g_credentials_to_string (cred);
212     DBG ("Client Credentials : %s", str_cred);
213     g_free (str_cred);
214
215     return g_strdup_printf ("%d", g_credentials_get_unix_pid(cred, NULL));
216 }
217
218 MsgPortDbusManager *
219 msgport_dbus_manager_new (
220     GDBusConnection *connection,
221     MsgPortDbusServer *server,
222     MsgPortManager *manager)
223 {
224     MsgPortDbusManager *dbus_mgr = NULL;
225     GError *error = NULL;
226
227     dbus_mgr = MSGPORT_DBUS_MANAGER (g_object_new (MSGPORT_TYPE_DBUS_MANAGER, NULL));
228     if (!dbus_mgr) return NULL;
229
230     if (!g_dbus_interface_skeleton_export (
231             G_DBUS_INTERFACE_SKELETON (dbus_mgr->priv->dbus_skeleton),
232             connection,
233             "/",
234             &error)) {
235         g_print ("Failed to export dbus object on connection %p : %s",
236                     connection, error->message);
237         g_error_free (error);
238         g_object_unref (dbus_mgr);
239         return NULL;
240     }
241     dbus_mgr->priv->connection = g_object_ref (connection);
242     dbus_mgr->priv->manager = g_object_ref (manager);
243     dbus_mgr->priv->server = server;
244     dbus_mgr->priv->app_id =  _get_app_id_from_connection (connection);
245
246     return dbus_mgr;
247 }
248
249 MsgPortManager *
250 msgport_dbus_manager_get_manager (MsgPortDbusManager *dbus_manager)
251 {
252     g_return_val_if_fail (dbus_manager && MSGPORT_IS_DBUS_MANAGER (dbus_manager), NULL);
253
254     return dbus_manager->priv->manager;
255 }
256
257 GDBusConnection *
258 msgport_dbus_manager_get_connection (MsgPortDbusManager *dbus_manager)
259 {
260     g_return_val_if_fail (dbus_manager && MSGPORT_IS_DBUS_MANAGER (dbus_manager), NULL);
261
262     return dbus_manager->priv->connection;
263 }
264
265 const gchar *
266 msgport_dbus_manager_get_app_id (MsgPortDbusManager *dbus_manager)
267 {
268     g_return_val_if_fail (dbus_manager && MSGPORT_IS_DBUS_MANAGER (dbus_manager), NULL);
269
270     return (const gchar *)dbus_manager->priv->app_id;
271 }
272