Fix the coding style errors (bt-service)
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-obex-agent.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <dlog.h>
20 #include <string.h>
21 #include <gio/gio.h>
22
23 #include "bluetooth-api.h"
24 #include "bt-service-common.h"
25 #include "bt-service-event.h"
26 #include "bt-service-util.h"
27 #include "bt-service-obex-agent.h"
28 #include "marshal.h"
29
30 static GDBusConnection *conn = NULL;
31 static GSList *obex_agent_list = NULL;
32
33 typedef struct {
34         gchar *name;
35         gchar *path;
36
37         int openobex_id;
38         int obex_agent_id;
39
40         /* callback data */
41         gpointer authorize_data;
42         gpointer release_data;
43         gpointer request_data;
44         gpointer progress_data;
45         gpointer complete_data;
46         gpointer error_data;
47
48         /* callback function */
49         bt_obex_authorize_cb authorize_cb;
50         bt_obex_release_cb release_cb;
51         bt_obex_request_cb request_cb;
52         bt_obex_progress_cb progress_cb;
53         bt_obex_complete_cb complete_cb;
54         bt_obex_error_cb error_cb;
55 } bt_obex_agent_info;
56
57 static void __new_connection_method(GDBusConnection *connection,
58                                             const gchar *sender,
59                                             const gchar *object_path,
60                                             const gchar *interface_name,
61                                             const gchar *method_name,
62                                             GVariant *parameters,
63                                             GDBusMethodInvocation *invocation,
64                                             gpointer user_data);
65 static const GDBusInterfaceVTable method_table = {
66         __new_connection_method,
67         NULL,
68         NULL,
69 };
70
71 static const gchar obex_service_agent_xml1[] =
72 "<node name='/'>"
73 "  <interface name='org.openobex.Agent'>"
74 "    <method name='Request'>"
75 "      <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
76 "      <arg type='o' name='transfer'/>"
77 "     <arg type='s' name='name' direction='out'/>"
78 "    </method>"
79 "    <method name='Progress'>"
80 "      <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
81 "      <arg type='o' name='transfer'/>"
82 "      <arg type='t' name='transferred'/>"
83 "    </method>"
84 "    <method name='Complete'>"
85 "      <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
86 "      <arg type='o' name='transfer'/>"
87  "   </method>"
88 "    <method name='Release'>"
89 "      <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
90 "    </method>"
91 "    <method name='Error'>"
92 "      <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
93 "      <arg type='o' name='transfer'/>"
94 "      <arg type='s' name='message'/>"
95 "    </method>"
96 "    <method name='Authorize'>"
97 "       <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
98 "               <arg type='o' name='objpath'/>"
99 "               <arg type='s' name='bdaddress'/>"
100 "               <arg type='s' name='name'/>"
101 "               <arg type='s' name='type'/>"
102 "               <arg type='i' name='length'/>"
103 "               <arg type='i' name='time'/>"
104 "               <arg type='s' name='filepath' direction='out'/>"
105 "       </method>"
106 "  </interface>"
107 "</node>";
108
109 static const gchar obex_service_agent_xml2[] =
110 "<node name='/'>"
111 "  <interface name='org.bluez.obex.Agent1'>"
112 "    <method name='AuthorizePush'>"
113 "    <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>"
114 "        <arg type='o' name='objpath'/>"
115 "        <arg type='s' name='filepath' direction='out'/>"
116 "    </method>"
117 "  </interface>"
118 "</node>";
119
120 static bt_obex_agent_info *__find_obex_agent_info(char *path)
121 {
122         GSList *l;
123
124         for (l = obex_agent_list; l != NULL; l = l->next) {
125                 bt_obex_agent_info *info = l->data;
126
127                 if (g_strcmp0(info->path, path) == 0)
128                         return info;
129         }
130
131         return NULL;
132 }
133
134
135 static void __new_connection_method(GDBusConnection *connection,
136                                             const gchar *sender,
137                                             const gchar *object_path,
138                                             const gchar *interface_name,
139                                             const gchar *method_name,
140                                             GVariant *parameters,
141                                             GDBusMethodInvocation *invocation,
142                                             gpointer user_data)
143 {
144         BT_DBG("method_name %s", method_name);
145         if (g_strcmp0(method_name, "AuthorizePush") == 0) {
146                 bt_obex_agent_info *info;
147                 char *path = NULL;
148                 info = __find_obex_agent_info((char *)object_path);
149
150                 if (info == NULL)
151                         goto fail;
152
153                 if (info->authorize_cb == NULL)
154                         goto fail;
155
156                 g_variant_get(parameters, "(&o)", &path);
157
158                 info->authorize_cb(invocation, path,
159                                 info->authorize_data);
160
161                 return;
162         } else if (g_strcmp0(method_name, "Authorize") == 0) {
163                 g_dbus_method_invocation_return_value(invocation, NULL);
164         } else if (g_strcmp0(method_name, "Request") == 0) {
165                 char *sender;
166                 bt_obex_agent_info *info;
167                 GDBusProxy *proxy;
168                 char *path = NULL;
169                 char *name = NULL;
170                 GError *err = NULL;
171
172                 info = __find_obex_agent_info((char *)object_path);
173
174                 if (info == NULL)
175                         goto fail;
176
177                 if (conn == NULL)
178                         goto fail;
179
180                 sender = (char *)g_dbus_method_invocation_get_sender(invocation);
181
182                 if (info->name == NULL) {
183                         info->name = sender;
184                 } else {
185                         if (g_strcmp0(sender, info->name) != 0) {
186                                 goto fail;
187                         }
188                 }
189
190                 if (info->request_cb == NULL)
191                         goto fail;
192
193                 g_variant_get(parameters, "(&o&s)", &path, &name);
194                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
195                                         NULL,
196                                         BT_OBEX_SERVICE_NAME,
197                                         path,
198                                         BT_OBEX_TRANSFER_INTERFACE,
199                                         NULL, &err);
200
201                 if (err) {
202                         BT_ERR("Dbus Err: %s", err->message);
203                         g_clear_error(&err);
204                         goto fail;
205                 }
206
207                 info->request_cb(invocation, proxy, info->request_data);
208                 g_object_unref(proxy);
209                 return;
210
211         } else if (g_strcmp0(method_name, "Progress") == 0) {
212                 BT_DBG("+");
213
214                 bt_obex_agent_info *info;
215                 char *sender;
216                 char *path = NULL;
217                 gint64 transferred;
218                 GDBusProxy *proxy;
219                 GError *err = NULL;
220
221                 info = __find_obex_agent_info((char *)object_path);
222
223                 if (info == NULL)
224                         goto fail;
225
226                 if (conn == NULL)
227                         goto fail;
228
229                 sender = (char *)g_dbus_method_invocation_get_sender(invocation);
230
231                 if (g_strcmp0(sender, info->name) != 0) {
232                         goto fail;
233                 }
234
235                 if (info->progress_cb == NULL)
236                         goto fail;
237
238                 g_variant_get(parameters, "(&ot)", &path, &transferred);
239                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
240                                         NULL,
241                                         BT_OBEX_SERVICE_NAME,
242                                         path,
243                                         BT_OBEX_TRANSFER_INTERFACE,
244                                         NULL, &err);
245
246                 if (err) {
247                         BT_ERR("Dbus Err: %s", err->message);
248                         g_clear_error(&err);
249                         goto fail;
250                 }
251
252                 info->progress_cb(invocation, proxy, transferred, info->progress_data);
253
254                 g_object_unref(proxy);
255
256                 BT_DBG("-");
257
258                 return;
259         } else if (g_strcmp0(method_name, "Error") == 0) {
260                 bt_obex_agent_info *info;
261                 char *sender;
262                 GDBusProxy *proxy;
263                 char *path, *message;
264                 GError *err = NULL;
265
266                 info = __find_obex_agent_info((char *)object_path);
267
268                 if (info == NULL)
269                         goto fail;
270
271                 if (conn == NULL)
272                         goto fail;
273
274                 sender = (char *)g_dbus_method_invocation_get_sender(invocation);
275
276                 if (g_strcmp0(sender, info->name) != 0) {
277                         goto fail;
278                 }
279
280                 if (info->error_cb == NULL)
281                         goto fail;
282                 g_variant_get(parameters, "(&o&s)", &path, &message);
283                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
284                                         NULL,
285                                         BT_OBEX_SERVICE_NAME,
286                                         path,
287                                         BT_OBEX_TRANSFER_INTERFACE,
288                                         NULL, &err);
289                 if (err) {
290                         BT_ERR("Dbus Err: %s", err->message);
291                         g_clear_error(&err);
292                         goto fail;
293                 }
294                 info->error_cb(invocation, proxy, message, info->progress_data);
295
296                 g_object_unref(proxy);
297
298                 return;
299         } else if (g_strcmp0(method_name, "Complete") == 0) {
300                 bt_obex_agent_info *info;
301                 char *sender;
302                 GDBusProxy *proxy;
303                 char *path = NULL;
304                 GError *err = NULL;
305
306                 info = __find_obex_agent_info((char *)object_path);
307
308                 if (info == NULL)
309                         goto fail;
310
311                 if (conn == NULL)
312                         goto fail;
313
314                 sender = (char *)g_dbus_method_invocation_get_sender(invocation);
315
316                 if (g_strcmp0(sender, info->name) != 0) {
317                         goto fail;
318                 }
319
320                 if (info->complete_cb == NULL)
321                         goto fail;
322
323                 g_variant_get(parameters, "(&o)", &path);
324                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_CALL_FLAGS_NONE,
325                                         NULL,
326                                         BT_OBEX_SERVICE_NAME,
327                                         path,
328                                         BT_OBEX_TRANSFER_INTERFACE,
329                                         NULL, &err);
330                 if (err) {
331                         BT_ERR("Dbus Err: %s", err->message);
332                         g_clear_error(&err);
333                         goto fail;
334                 }
335
336                 info->complete_cb(invocation, proxy, info->complete_data);
337
338                 g_object_unref(proxy);
339
340                 return;
341         } else if (g_strcmp0(method_name, "Release") == 0) {
342                 bt_obex_agent_info *info;
343                 char *sender;
344
345                 info = __find_obex_agent_info((char *)object_path);
346
347                 if (info == NULL)
348                         goto fail;
349
350                 sender = (char *)g_dbus_method_invocation_get_sender(invocation);
351
352                 if (info->name) {
353                         /*In H2 if user denies auth,release will come without request and hence
354                         info->name will be NULL */
355                         if (g_strcmp0(sender, info->name) != 0) {
356                                 goto fail;
357                         }
358                 }
359
360                 if (info->release_cb == NULL)
361                         goto fail;
362
363                 info->release_cb(invocation, info->release_data);
364
365                 return;
366         }
367 fail:
368                 BT_ERR("Fail case");
369                 g_dbus_method_invocation_return_value(invocation, NULL);
370 }
371
372 void _bt_obex_agent_new(char *path)
373 {
374         bt_obex_agent_info *info = NULL;
375         GError *error = NULL;
376
377         if (conn == NULL) {
378                 conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
379                 if (error != NULL) {
380                         BT_ERR("Fail to get dbus: %s", error->message);
381                         g_error_free(error);
382                         return;
383                 }
384         }
385         info = (bt_obex_agent_info *)malloc(sizeof(bt_obex_agent_info));
386         if (info) {
387                 memset(info, 0, sizeof(bt_obex_agent_info));
388                 info->path = g_strdup(path);
389                 obex_agent_list = g_slist_append(obex_agent_list, info);
390         }
391 }
392
393 void _bt_obex_agent_destroy(char *path)
394 {
395         bt_obex_agent_info *info = NULL;
396         info = __find_obex_agent_info(path);
397         if (info == NULL) {
398                 BT_ERR("obex agent info not found on path %s", path);
399                 return;
400         }
401         obex_agent_list = g_slist_remove(obex_agent_list, info);
402         if (info->path)
403                 g_free(info->path);
404         if (info->name)
405                 g_free(info->name);
406         if (info->openobex_id)
407                 g_dbus_connection_unregister_object(conn,
408                         info->openobex_id);
409         if (info->obex_agent_id)
410                 g_dbus_connection_unregister_object(conn,
411                         info->obex_agent_id);
412
413         g_free(info);
414 }
415 gboolean _bt_obex_setup(const char *path)
416 {
417         bt_obex_agent_info *info;
418         GDBusProxy *proxy;
419         GDBusNodeInfo *new_conn_node;
420         GError *err = NULL;
421
422         info = __find_obex_agent_info((char *)path);
423
424         retv_if(info == NULL, FALSE);
425
426         proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
427                                 G_DBUS_PROXY_FLAGS_NONE,
428                                 NULL,
429                                 BT_OBEX_SERVICE_NAME,
430                                 BT_OBEX_CLIENT_PATH,
431                                 BT_OBEX_AGENT_INTERFACE,
432                                 NULL,
433                                 &err);
434
435         g_free(info->name);
436
437         if (proxy != NULL) {
438                 info->name = g_strdup(g_dbus_proxy_get_name(proxy));
439                 g_object_unref(proxy);
440         } else {
441                 info->name = NULL;
442         }
443
444         new_conn_node = g_dbus_node_info_new_for_xml(obex_service_agent_xml1, NULL);
445         if (new_conn_node == NULL)
446                 return FALSE;
447
448         info->openobex_id = g_dbus_connection_register_object(conn, info->path,
449                                                 new_conn_node->interfaces[0],
450                                                 &method_table,
451                                                 NULL, NULL, &err);
452         g_dbus_node_info_unref(new_conn_node);
453         if (err) {
454                 BT_INFO("Dbus Err: %s", err->message);
455                 g_clear_error(&err);
456                 return FALSE;
457         }
458         if (info->openobex_id == 0)
459                 BT_ERR("Error while registering object");
460         new_conn_node = g_dbus_node_info_new_for_xml(obex_service_agent_xml2, NULL);
461
462         info->obex_agent_id = g_dbus_connection_register_object(conn, info->path,
463                                                 new_conn_node->interfaces[0],
464                                                 &method_table,
465                                                 NULL, NULL, &err);
466         g_dbus_node_info_unref(new_conn_node);
467         if (info->obex_agent_id == 0)
468                 BT_ERR("Error while registering object");
469         if (err) {
470                 BT_INFO("Dbus Err: %s", err->message);
471                 g_clear_error(&err);
472                 return FALSE;
473         }
474         return TRUE;
475 }
476
477 void _bt_obex_set_authorize_cb(char *object_path,
478                          bt_obex_authorize_cb func, gpointer data)
479 {
480         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
481
482         if (info) {
483                 info->authorize_cb = func;
484                 info->authorize_data = data;
485         }
486 }
487
488 void _bt_obex_set_release_cb(char *object_path,
489                        bt_obex_release_cb func, gpointer data)
490 {
491         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
492
493         /* Fix : NULL_RETURNS */
494         if (info == NULL)
495                 return;
496
497         info->release_cb = func;
498         info->release_data = data;
499 }
500
501 void _bt_obex_set_request_cb(char *object_path,
502                        bt_obex_request_cb func, gpointer data)
503 {
504         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
505
506         /* Fix : NULL_RETURNS */
507         if (info == NULL)
508                 return;
509
510         info->request_cb = func;
511         info->request_data = data;
512 }
513
514 void _bt_obex_set_progress_cb(char *object_path,
515                         bt_obex_progress_cb func, gpointer data)
516 {
517         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
518
519         /* Fix : NULL_RETURNS */
520         if (info == NULL)
521                 return;
522
523         info->progress_cb = func;
524         info->progress_data = data;
525 }
526
527 void _bt_obex_set_complete_cb(char *object_path,
528                         bt_obex_complete_cb func, gpointer data)
529 {
530         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
531
532         /* Fix : NULL_RETURNS */
533         if (info == NULL)
534                 return;
535
536         info->complete_cb = func;
537         info->complete_data = data;
538 }
539
540 void _bt_obex_set_error_cb(char *object_path,
541                         bt_obex_error_cb func, gpointer data)
542 {
543         bt_obex_agent_info *info = __find_obex_agent_info(object_path);;
544
545         /* Fix : NULL_RETURNS */
546         if (info == NULL)
547                 return;
548
549         info->error_cb = func;
550         info->error_data = data;
551 }