Code Sync [Tizen3.0]: Merged the tizen_2.4 Spin code to tizen.org
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-obex-agent.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23 #include <dbus/dbus-glib-lowlevel.h>
24 #include <dbus/dbus-glib.h>
25 #include <dbus/dbus.h>
26 #include <glib.h>
27 #include <dlog.h>
28 #include <string.h>
29
30 #include "bluetooth-api.h"
31 #include "bt-service-common.h"
32 #include "bt-service-event.h"
33 #include "bt-service-util.h"
34 #include "bt-service-obex-agent.h"
35 #include "marshal.h"
36 #include "bt-obex-agent-method.h"
37
38 static DBusGConnection *obex_conn = NULL;
39
40 typedef struct {
41         gchar *name;
42         gchar *path;
43
44         /* callback data */
45         gpointer authorize_data;
46         gpointer release_data;
47         gpointer request_data;
48         gpointer progress_data;
49         gpointer complete_data;
50         gpointer error_data;
51
52         /* callback function */
53         bt_obex_authorize_cb authorize_cb;
54         bt_obex_release_cb release_cb;
55         bt_obex_request_cb request_cb;
56         bt_obex_progress_cb progress_cb;
57         bt_obex_complete_cb complete_cb;
58         bt_obex_error_cb error_cb;
59 } bt_obex_agent_info;
60
61 #define BT_OBEX_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
62                                         BT_OBEX_TYPE_AGENT, bt_obex_agent_info))
63
64 G_DEFINE_TYPE(BtObexAgent, bt_obex_agent, G_TYPE_OBJECT)
65
66
67 gboolean bt_obex_agent_authorize_push(BtObexAgent *agent, const char *path,
68                              DBusGMethodInvocation *context)
69 {
70         bt_obex_agent_info *info;
71         gboolean result;
72
73         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
74
75         if (info == NULL)
76                 goto fail;
77
78         if (info->authorize_cb == NULL)
79                 goto fail;
80
81         result = info->authorize_cb(context, path,
82                                 info->authorize_data);
83
84         return result;
85 fail:
86         dbus_g_method_return(context, "");
87         return FALSE;
88 }
89
90 gboolean bt_obex_agent_authorize(BtObexAgent *agent, const char *path,
91                         const char *bdaddress, const char *name,
92                         const char *type, gint length, gint time,
93                              DBusGMethodInvocation *context)
94 {
95         bt_obex_agent_info *info;
96
97         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
98
99         if (info == NULL)
100                 goto fail;
101
102         if (info->authorize_cb == NULL)
103                 goto fail;
104
105         return TRUE;
106 fail:
107         dbus_g_method_return(context, "");
108         return FALSE;
109 }
110
111 gboolean bt_obex_agent_request(BtObexAgent *agent, const char *path,
112                                    DBusGMethodInvocation *context)
113 {
114         char *sender;
115         bt_obex_agent_info *info;
116         DBusGProxy *proxy;
117         gboolean result;
118
119         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
120
121         if (info == NULL)
122                 goto fail;
123
124         if (obex_conn == NULL)
125                 goto fail;
126
127         sender = dbus_g_method_get_sender(context);
128
129         BT_DBG("sender %s", sender);
130
131         if (info->name == NULL) {
132                 info->name = sender;
133         } else {
134                 if (g_strcmp0(sender, info->name) != 0) {
135                         g_free(sender);
136                         goto fail;
137                 }
138                 g_free(sender);
139         }
140
141         if (info->request_cb == NULL)
142                 goto fail;
143
144         proxy = dbus_g_proxy_new_for_name(obex_conn, BT_OBEX_SERVICE_NAME,
145                                           path, BT_OBEX_TRANSFER_INTERFACE);
146
147         result = info->request_cb(context, proxy, info->request_data);
148         g_object_unref(proxy);
149
150         return result;
151 fail:
152         BT_ERR("Fail case");
153         dbus_g_method_return(context, "");
154         return FALSE;
155 }
156
157 gboolean bt_obex_agent_progress(BtObexAgent *agent, const char *path,
158                     guint64 transferred, DBusGMethodInvocation *context)
159 {
160         BT_DBG("+");
161
162         bt_obex_agent_info *info;
163         char *sender;
164         gboolean result;
165         DBusGProxy *proxy;
166
167         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
168
169         if (info == NULL)
170                 goto fail;
171
172         if (obex_conn == NULL)
173                 goto fail;
174
175         sender = dbus_g_method_get_sender(context);
176
177         if (g_strcmp0(sender, info->name) != 0) {
178                 g_free(sender);
179                 goto fail;
180         }
181
182         g_free(sender);
183
184         if (info->progress_cb == NULL)
185                 goto fail;
186
187         proxy = dbus_g_proxy_new_for_name(obex_conn, BT_OBEX_SERVICE_NAME,
188                                           path, BT_OBEX_TRANSFER_INTERFACE);
189
190         result = info->progress_cb(context, proxy, transferred, info->progress_data);
191
192         g_object_unref(proxy);
193
194         BT_DBG("-");
195
196         return result;
197 fail:
198         BT_ERR("Fail case");
199         dbus_g_method_return(context, "");
200         BT_DBG("-");
201         return FALSE;
202 }
203
204 gboolean bt_obex_agent_error(BtObexAgent *agent, const char *path,
205                          const char *message, DBusGMethodInvocation *context)
206 {
207         bt_obex_agent_info *info;
208         char *sender;
209         DBusGProxy *proxy;
210         gboolean result;
211
212         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
213
214         if (info == NULL)
215                 goto fail;
216
217         if (obex_conn == NULL)
218                 goto fail;
219
220         sender = dbus_g_method_get_sender(context);
221
222         if (g_strcmp0(sender, info->name) != 0) {
223                 g_free(sender);
224                 goto fail;
225         }
226
227         g_free(sender);
228
229         if (info->error_cb == NULL)
230                 goto fail;
231
232         proxy = dbus_g_proxy_new_for_name(obex_conn, BT_OBEX_SERVICE_NAME,
233                                           path, BT_OBEX_TRANSFER_INTERFACE);
234
235         result = info->error_cb(context, proxy, message, info->progress_data);
236
237         g_object_unref(proxy);
238
239         return result;
240 fail:
241         BT_ERR("Fail case");
242         dbus_g_method_return(context, "");
243         return FALSE;
244 }
245
246 gboolean bt_obex_agent_complete(BtObexAgent *agent, const char *path,
247                                     DBusGMethodInvocation *context)
248 {
249         bt_obex_agent_info *info;
250         char *sender;
251         DBusGProxy *proxy;
252         gboolean result;
253
254         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
255
256         if (info == NULL)
257                 goto fail;
258
259         if (obex_conn == NULL)
260                 goto fail;
261
262         sender = dbus_g_method_get_sender(context);
263
264         if (g_strcmp0(sender, info->name) != 0) {
265                 g_free(sender);
266                 goto fail;
267         }
268
269         g_free(sender);
270
271         if (info->complete_cb == NULL)
272                 goto fail;
273
274         proxy = dbus_g_proxy_new_for_name(obex_conn, BT_OBEX_SERVICE_NAME,
275                                           path, BT_OBEX_TRANSFER_INTERFACE);
276
277         result = info->complete_cb(context, proxy, info->complete_data);
278
279         g_object_unref(proxy);
280
281         return result;
282 fail:
283         BT_ERR("Fail case");
284         dbus_g_method_return(context, "");
285         return FALSE;
286 }
287
288 gboolean bt_obex_agent_release(BtObexAgent *agent, DBusGMethodInvocation *context)
289 {
290         bt_obex_agent_info *info;
291         char *sender;
292         gboolean result;
293
294         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
295
296         if (info == NULL)
297                 goto fail;
298
299         sender = dbus_g_method_get_sender(context);
300
301         if (info->name) {
302                 /*In H2 if user denies auth,release will come without request and hence
303                 info->name will be NULL */
304                 if (g_strcmp0(sender, info->name) != 0) {
305                         g_free(sender);
306                         goto fail;
307                 }
308         }
309         g_free(sender);
310
311         if (info->release_cb == NULL)
312                 goto fail;
313
314         result = info->release_cb(context, info->release_data);
315
316         return result;
317 fail:
318         BT_ERR("Fail case");
319         dbus_g_method_return(context, "");
320         return FALSE;
321 }
322
323 static void bt_obex_agent_init(BtObexAgent *agent)
324 {
325         BT_DBG("agent %p", agent);
326 }
327
328 static void bt_obex_agent_finalize(GObject *agent)
329 {
330         bt_obex_agent_info *info;
331
332         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
333
334         if (info) {
335                 g_free(info->path);
336                 g_free(info->name);
337         }
338
339         G_OBJECT_CLASS(bt_obex_agent_parent_class)->finalize(agent);
340 }
341
342 static void bt_obex_agent_class_init(BtObexAgentClass *agent_class)
343 {
344         GObjectClass *object_class;
345         GError *error = NULL;
346
347         object_class = (GObjectClass *)agent_class;
348
349         g_type_class_add_private(agent_class, sizeof(bt_obex_agent_info));
350
351         object_class->finalize = bt_obex_agent_finalize;
352
353         obex_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
354
355         if (error != NULL) {
356                 BT_ERR("Fail to get dbus: %s", error->message);
357                 g_error_free(error);
358         }
359
360         dbus_g_object_type_install_info(BT_OBEX_TYPE_AGENT,
361                                 &dbus_glib_bt_obex_agent_object_info);
362 }
363
364 BtObexAgent *_bt_obex_agent_new(void)
365 {
366         BtObexAgent *agent;
367
368         agent = BT_OBEX_AGENT(g_object_new(BT_OBEX_TYPE_AGENT, NULL));
369
370         return agent;
371 }
372
373 gboolean _bt_obex_setup(BtObexAgent *agent, const char *path)
374 {
375         bt_obex_agent_info *info;
376         DBusGProxy *proxy;
377         GObject *object;
378
379         info = BT_OBEX_AGENT_GET_PRIVATE(agent);
380
381         retv_if(obex_conn == NULL, FALSE);
382         retv_if(info == NULL, FALSE);
383         retv_if(info->path != NULL, FALSE);
384
385         info->path = g_strdup(path);
386
387         proxy = dbus_g_proxy_new_for_name_owner(obex_conn, BT_OBEX_SERVICE_NAME,
388                                                 BT_OBEX_CLIENT_PATH,
389                                                 BT_OBEX_AGENT_INTERFACE, NULL);
390         g_free(info->name);
391
392         if (proxy != NULL) {
393                 info->name = g_strdup(dbus_g_proxy_get_bus_name(proxy));
394                 g_object_unref(proxy);
395         } else {
396                 info->name = NULL;
397         }
398
399         object = dbus_g_connection_lookup_g_object(obex_conn, info->path);
400         if (object != NULL)
401                 g_object_unref(object);
402
403         dbus_g_connection_register_g_object(obex_conn, info->path, G_OBJECT(agent));
404
405         dbus_g_object_register_marshaller(marshal_VOID__OBJECT_BOOLEAN,
406                                           G_TYPE_NONE, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_BOOLEAN,
407                                           G_TYPE_INVALID);
408
409         dbus_g_object_register_marshaller(marshal_VOID__INT_INT,
410                                           G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
411         return TRUE;
412 }
413
414 void _bt_obex_set_authorize_cb(BtObexAgent *agent,
415                          bt_obex_authorize_cb func, gpointer data)
416 {
417         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
418
419         info->authorize_cb = func;
420         info->authorize_data = data;
421 }
422
423 void _bt_obex_set_release_cb(BtObexAgent *agent,
424                        bt_obex_release_cb func, gpointer data)
425 {
426         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
427
428         info->release_cb = func;
429         info->release_data = data;
430 }
431
432 void _bt_obex_set_request_cb(BtObexAgent *agent,
433                        bt_obex_request_cb func, gpointer data)
434 {
435         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
436
437         info->request_cb = func;
438         info->request_data = data;
439 }
440
441 void _bt_obex_set_progress_cb(BtObexAgent *agent,
442                         bt_obex_progress_cb func, gpointer data)
443 {
444         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
445
446         info->progress_cb = func;
447         info->progress_data = data;
448 }
449
450 void _bt_obex_set_complete_cb(BtObexAgent *agent,
451                         bt_obex_complete_cb func, gpointer data)
452 {
453         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
454
455         info->complete_cb = func;
456         info->complete_data = data;
457 }
458
459 void _bt_obex_set_error_cb(BtObexAgent *agent,
460                         bt_obex_error_cb func, gpointer data)
461 {
462         bt_obex_agent_info *info = BT_OBEX_AGENT_GET_PRIVATE(agent);
463
464         info->error_cb = func;
465         info->error_data = data;
466 }