bidirectional messages implemented, updated the example code
[profile/ivi/message-port.git] / daemon / dbus-service.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-service.h"
25 #include "common/dbus-service-glue.h"
26 #include "common/log.h"
27 #include "manager.h"
28
29 G_DEFINE_TYPE (MsgPortDbusService, msgport_dbus_service, G_TYPE_OBJECT)
30
31 #define MSGPORT_DBUS_SERVICE_GET_PRIV(obj) \
32     G_TYPE_INSTANCE_GET_PRIVATE ((obj), MSGPORT_TYPE_DBUS_SERVICE, MsgPortDbusServicePrivate)
33
34 struct _MsgPortDbusServicePrivate {
35     MsgPortDbusManager *owner;
36     MsgPortDbusGlueService *dbus_skeleton;
37     MsgPortService *service;
38     gchar *object_path;
39     guint id;
40 };
41
42
43 static void
44 _dbus_service_finalize (GObject *self)
45 {
46     MsgPortDbusService *dbus_service = MSGPORT_DBUS_SERVICE (self);
47
48     if (dbus_service->priv->object_path) {
49         g_free (dbus_service->priv->object_path);
50         dbus_service->priv->object_path = NULL;
51     }
52
53     G_OBJECT_CLASS (msgport_dbus_service_parent_class)->finalize (self);
54 }
55
56 static void
57 _dbus_service_dispose (GObject *self)
58 {
59     MsgPortDbusService *dbus_service = MSGPORT_DBUS_SERVICE (self);
60     DBG ("Unregistering service '%s'", 
61         msgport_service_get_port_name (dbus_service->priv->service));
62     if (dbus_service->priv->dbus_skeleton) {
63         g_dbus_interface_skeleton_unexport (
64                 G_DBUS_INTERFACE_SKELETON (dbus_service->priv->dbus_skeleton));
65         g_clear_object (&dbus_service->priv->dbus_skeleton);
66     }
67
68     g_clear_object (&dbus_service->priv->service);
69
70 //    g_clear_object (&dbus_service->priv->owner);
71
72     G_OBJECT_CLASS (msgport_dbus_service_parent_class)->dispose (self);
73 }
74
75
76 static gboolean
77 _dbus_service_handle_send_message (
78     MsgPortDbusService    *dbus_service,
79     GDBusMethodInvocation *invocation,
80     guint                   remote_service_id,
81     GVariant              *data,
82     gpointer               userdata)
83 {
84     MsgPortDbusService *peer_dbus_service = NULL;
85     MsgPortManager *manager = NULL;
86     GError *error;
87     g_return_val_if_fail (dbus_service &&  MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE);
88
89     DBG ("Send Message rquest on service %p to remote service id : %d", dbus_service, remote_service_id);
90     manager = msgport_dbus_manager_get_manager (dbus_service->priv->owner);
91     peer_dbus_service = msgport_manager_get_service_by_id (manager, remote_service_id);
92     if (!peer_dbus_service) {
93         /* FIXME: return ENOTFOUND error */
94         g_dbus_method_invocation_take_error (invocation, error);
95     }
96     else {
97         msgport_dbus_service_send_message (peer_dbus_service, data,
98                 msgport_dbus_service_get_app_id (dbus_service),
99                 msgport_dbus_service_get_port_name (dbus_service),
100                 msgport_dbus_service_get_is_trusted (dbus_service));
101         msgport_dbus_glue_service_complete_send_message (
102                 dbus_service->priv->dbus_skeleton, invocation);
103     }
104
105     return TRUE;
106 }
107
108 static gboolean
109 _dbus_service_handle_unregister (
110     MsgPortDbusService    *dbus_service,
111     GDBusMethodInvocation *invocation,
112     gpointer               userdata)
113 {
114     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE);
115
116     /* FIXME unregister */
117     return TRUE;
118 }
119
120 static gboolean
121 _dbus_service_handle_get_properties (
122     MsgPortDbusService    *dbus_service,
123     GDBusMethodInvocation *invocation,
124     gpointer               userdata)
125 {
126     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE);
127
128     msgport_dbus_glue_service_complete_get_properties (
129             dbus_service->priv->dbus_skeleton,
130             invocation,
131             msgport_service_to_variant (dbus_service->priv->service));
132
133     return TRUE;
134 }
135
136 static void
137 msgport_dbus_service_init (MsgPortDbusService *self)
138 {
139     MsgPortDbusServicePrivate *priv = MSGPORT_DBUS_SERVICE_GET_PRIV (self);
140
141     priv->dbus_skeleton = msgport_dbus_glue_service_skeleton_new ();
142     priv->service = NULL;
143     priv->owner = NULL;
144
145     g_signal_connect_swapped (priv->dbus_skeleton, "handle-send-message",
146                 G_CALLBACK (_dbus_service_handle_send_message), (gpointer)self);
147     g_signal_connect_swapped (priv->dbus_skeleton, "handle-unregister",
148                 G_CALLBACK (_dbus_service_handle_unregister), (gpointer)self);
149     g_signal_connect_swapped (priv->dbus_skeleton, "handle-get-properties",
150                 G_CALLBACK (_dbus_service_handle_get_properties), (gpointer)self);
151
152     self->priv = priv;
153 }
154
155 static void
156 msgport_dbus_service_class_init (MsgPortDbusServiceClass *klass)
157 {
158     GObjectClass *gklass = G_OBJECT_CLASS(klass);
159
160     g_type_class_add_private (klass, sizeof(MsgPortDbusServicePrivate));
161
162     gklass->finalize = _dbus_service_finalize;
163     gklass->dispose = _dbus_service_dispose;
164 }
165
166 MsgPortDbusService *
167 msgport_dbus_service_new (MsgPortDbusManager *owner, const gchar *name, gboolean is_trusted)
168 {
169     static guint object_conter = 0;
170
171     MsgPortDbusService *dbus_service = NULL;
172     GDBusConnection *connection = NULL;
173     gchar *object_path = 0;
174     GError *error = NULL;
175
176     connection = msgport_dbus_manager_get_connection (owner),
177     dbus_service = MSGPORT_DBUS_SERVICE (g_object_new (MSGPORT_TYPE_DBUS_SERVICE, NULL));
178     if (!dbus_service) return NULL;
179
180     /* FIXME: better way of path creation */
181     object_path = g_strdup_printf ("/%u", ++object_conter); 
182     if (!g_dbus_interface_skeleton_export (
183             G_DBUS_INTERFACE_SKELETON (dbus_service->priv->dbus_skeleton),
184             connection,
185             object_path,
186             &error)) {
187         g_print ("Failed to export dbus object on connection %p : %s",
188                     connection, error->message);
189         g_error_free (error);
190         g_object_unref (dbus_service);
191         g_free (object_path);
192         return NULL;
193     }
194     dbus_service->priv->id = object_conter;
195     dbus_service->priv->owner = /*g_object_ref*/ (owner);
196     dbus_service->priv->object_path = object_path;
197     dbus_service->priv->service = msgport_service_new (
198             msgport_dbus_manager_get_app_id (owner), name, is_trusted);
199
200     g_assert (dbus_service->priv->service);
201     g_assert (MSGPORT_IS_SERVICE (dbus_service->priv->service));
202
203     return dbus_service;
204 }
205
206 guint
207 msgport_dbus_service_get_id (MsgPortDbusService *dbus_service)
208 {
209     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), 0);
210
211     return dbus_service->priv->id;
212 }
213
214 const gchar *
215 msgport_dbus_service_get_object_path (MsgPortDbusService *dbus_service)
216 {
217     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
218
219     return (const gchar *)dbus_service->priv->object_path ;
220 }
221
222 GDBusConnection *
223 msgport_dbus_service_get_connection (MsgPortDbusService *dbus_service)
224 {
225     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
226
227     return msgport_dbus_manager_get_connection (dbus_service->priv->owner);
228 }
229
230 MsgPortService *
231 msgport_dbus_service_get_service (MsgPortDbusService *dbus_service)
232 {
233     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
234
235     return dbus_service->priv->service;
236 }
237
238 MsgPortDbusManager *
239 msgport_dbus_service_get_owner (MsgPortDbusService *dbus_service)
240 {
241     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
242
243     return dbus_service->priv->owner;
244 }
245
246 const gchar *
247 msgport_dbus_service_get_port_name (MsgPortDbusService *dbus_service)
248 {
249     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
250
251     return msgport_service_get_port_name (dbus_service->priv->service);
252 }
253
254 const gchar *
255 msgport_dbus_service_get_app_id (MsgPortDbusService *dbus_service)
256 {
257     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), NULL);
258
259     return msgport_dbus_manager_get_app_id (dbus_service->priv->owner);
260 }
261
262 gboolean
263 msgport_dbus_service_get_is_trusted (MsgPortDbusService *dbus_service)
264 {
265     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE);
266
267     return msgport_service_get_is_trusted (dbus_service->priv->service);
268 }
269
270 gboolean
271 msgport_dbus_service_send_message (MsgPortDbusService *dbus_service, GVariant *data, const gchar *r_app_id, const gchar *r_port, gboolean r_is_trusted)
272 {
273     g_return_val_if_fail (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE);
274
275     DBG ("Sending message to %p from '%s:%s'", dbus_service, r_app_id, r_port);
276     msgport_dbus_glue_service_emit_on_message (dbus_service->priv->dbus_skeleton, data, r_app_id, r_port, r_is_trusted);
277     
278     return TRUE;
279 }
280