Svace fix: WGID-319844 'characteristic.handle' doubble free
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-request-sender.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
22 #include "bluetooth-api.h"
23 #include "bluetooth-hid-api.h"
24 #include "bluetooth-audio-api.h"
25 #include "bt-internal-types.h"
26 #include "bluetooth-ipsp-api.h"
27
28 #include "bt-common.h"
29 #include "bt-request-sender.h"
30 #include "bt-event-handler.h"
31 #include "bluetooth-media-control.h"
32
33 static GSList *sending_requests;
34
35 static GDBusProxy *service_gproxy;
36
37 static GDBusProxy *__bt_gdbus_init_service_proxy(void)
38 {
39         GDBusConnection *service_gconn;
40         GDBusProxy *proxy;
41         GError *err = NULL;
42
43         service_gconn = _bt_gdbus_get_system_gconn();
44
45         if (!service_gconn)
46                 return NULL;
47
48         proxy =  g_dbus_proxy_new_sync(service_gconn,
49                         G_DBUS_PROXY_FLAGS_NONE, NULL,
50                         BT_DBUS_NAME,
51                         BT_SERVICE_PATH,
52                         BT_DBUS_NAME,
53                         NULL, &err);
54         if (!proxy) {
55                 if (err) {
56                          BT_ERR("Unable to create proxy: %s", err->message);
57                          g_clear_error(&err);
58                 }
59
60                 return NULL;
61         }
62
63         service_gproxy = proxy;
64
65         return proxy;
66 }
67
68 static GDBusProxy *__bt_gdbus_get_service_proxy(void)
69 {
70         return (service_gproxy) ? service_gproxy : __bt_gdbus_init_service_proxy();
71 }
72
73 void _bt_gdbus_deinit_proxys(void)
74 {
75         if (service_gproxy) {
76                 g_object_unref(service_gproxy);
77                 service_gproxy = NULL;
78         }
79 }
80
81 static void __bt_get_event_info(int service_function, GArray *output,
82                         int *event, int *event_type, void **param_data)
83 {
84         ret_if(event == NULL);
85
86         BT_DBG("service_function : %s (0x%x)",
87                 _bt_convert_service_function_to_string(service_function),
88                 service_function);
89         switch (service_function) {
90         case BT_BOND_DEVICE:
91         case BT_BOND_DEVICE_BY_TYPE:
92                 *event_type = BT_ADAPTER_EVENT;
93                 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
94                 ret_if(output == NULL);
95                 *param_data = &g_array_index(output,
96                                 bluetooth_device_info_t, 0);
97                 break;
98         case BT_UNBOND_DEVICE:
99                 *event_type = BT_ADAPTER_EVENT;
100                 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
101                 ret_if(output == NULL);
102                 *param_data = &g_array_index(output,
103                                 bluetooth_device_address_t, 0);
104                 break;
105         case BT_SEARCH_SERVICE:
106                 *event_type = BT_ADAPTER_EVENT;
107                 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
108                 ret_if(output == NULL);
109                 *param_data = &g_array_index(output,
110                                 bt_sdp_info_t, 0);
111                 break;
112         case BT_HID_CONNECT:
113                 *event_type = BT_HID_EVENT;
114                 *event = BLUETOOTH_HID_CONNECTED;
115                 ret_if(output == NULL);
116                 *param_data = &g_array_index(output,
117                                 bluetooth_device_address_t, 0);
118                 break;
119         case BT_HID_DISCONNECT:
120                 *event_type = BT_HID_EVENT;
121                 *event = BLUETOOTH_HID_DISCONNECTED;
122                 ret_if(output == NULL);
123                 *param_data = &g_array_index(output,
124                                 bluetooth_device_address_t, 0);
125                 break;
126         case BT_AUDIO_CONNECT:
127         case BT_AG_CONNECT:
128                 *event_type = BT_HEADSET_EVENT;
129                 *event = BLUETOOTH_EVENT_AG_CONNECTED;
130                 ret_if(output == NULL);
131                 *param_data = &g_array_index(output, char, 0);
132                 break;
133         case BT_AUDIO_DISCONNECT:
134         case BT_AG_DISCONNECT:
135                 *event_type = BT_HEADSET_EVENT;
136                 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
137                 ret_if(output == NULL);
138                 *param_data = &g_array_index(output, char, 0);
139                 break;
140         case BT_AV_CONNECT:
141                 *event_type = BT_HEADSET_EVENT;
142                 *event = BLUETOOTH_EVENT_AV_CONNECTED;
143                 ret_if(output == NULL);
144                 *param_data = &g_array_index(output, char, 0);
145                 break;
146         case BT_AV_DISCONNECT:
147                 *event_type = BT_HEADSET_EVENT;
148                 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
149                 ret_if(output == NULL);
150                 *param_data = &g_array_index(output, char, 0);
151                 break;
152         case BT_AV_SOURCE_CONNECT:
153                 *event_type = BT_A2DP_SOURCE_EVENT;
154                 *event = BLUETOOTH_EVENT_AV_SOURCE_CONNECTED;
155                 ret_if(output == NULL);
156                 *param_data = &g_array_index(output, char, 0);
157                 break;
158         case BT_AV_SOURCE_DISCONNECT:
159                 *event_type = BT_A2DP_SOURCE_EVENT;
160                 *event = BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED;
161                 ret_if(output == NULL);
162                 *param_data = &g_array_index(output, char, 0);
163                 break;
164         case BT_HF_CONNECT:
165                 *event_type = BT_HF_AGENT_EVENT;
166                 *event = BLUETOOTH_EVENT_HF_CONNECTED;
167                 ret_if(output == NULL);
168                 *param_data = &g_array_index(output, char, 0);
169                 break;
170         case BT_HF_DISCONNECT:
171                 *event_type = BT_HF_AGENT_EVENT;
172                 *event = BLUETOOTH_EVENT_HF_DISCONNECTED;
173                 ret_if(output == NULL);
174                 *param_data = &g_array_index(output, char, 0);
175                 break;
176         case BT_NETWORK_CONNECT:
177                 *event_type = BT_ADAPTER_EVENT;
178                 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
179                 ret_if(output == NULL);
180                 *param_data = &g_array_index(output,
181                                 bluetooth_device_address_t, 0);
182                 break;
183         case BT_NETWORK_DISCONNECT:
184                 *event_type = BT_ADAPTER_EVENT;
185                 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
186                 ret_if(output == NULL);
187                 *param_data = &g_array_index(output,
188                                 bluetooth_device_address_t, 0);
189                 break;
190         case BT_RFCOMM_CLIENT_CONNECT:
191                 *event_type = BT_RFCOMM_CLIENT_EVENT;
192                 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
193                 ret_if(output == NULL);
194                 *param_data = &g_array_index(output,
195                                 bluetooth_rfcomm_connection_t, 0);
196                 break;
197         case BT_AVRCP_TARGET_CONNECT:
198                 *event_type = BT_AVRCP_EVENT;
199                 *event = BLUETOOTH_EVENT_AVRCP_CONNECTED;
200                 ret_if(output == NULL);
201                 *param_data = &g_array_index(output, char, 0);
202                 break;
203         case BT_AVRCP_TARGET_DISCONNECT:
204                 *event_type = BT_AVRCP_EVENT;
205                 *event = BLUETOOTH_EVENT_AVRCP_DISCONNECTED;
206                 ret_if(output == NULL);
207                 *param_data = &g_array_index(output, char, 0);
208                 break;
209         case BT_AVRCP_CONTROL_CONNECT:
210                 *event_type = BT_AVRCP_CONTROL_EVENT;
211                 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
212                 ret_if(output == NULL);
213                 *param_data = &g_array_index(output, char, 0);
214                 break;
215         case BT_AVRCP_CONTROL_DISCONNECT:
216                 *event_type = BT_AVRCP_CONTROL_EVENT;
217                 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
218                 ret_if(output == NULL);
219                 *param_data = &g_array_index(output, char, 0);
220                 break;
221         case BT_REQ_ATT_MTU:
222                 *event_type = BT_DEVICE_EVENT;
223                 *event = BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED;
224                 ret_if(output == NULL);
225                 *param_data = &g_array_index(output,
226                                 bluetooth_device_address_t, 0);
227                 break;
228         case BT_CONNECT_LE:
229                 *event_type = BT_DEVICE_EVENT;
230                 *event = BLUETOOTH_EVENT_GATT_CONNECTED;
231                 ret_if(output == NULL);
232                 *param_data = &g_array_index(output,
233                                 bluetooth_device_address_t, 0);
234                 break;
235         case BT_DISCONNECT_LE:
236                 *event_type = BT_DEVICE_EVENT;
237                 *event = BLUETOOTH_EVENT_GATT_DISCONNECTED;
238                 ret_if(output == NULL);
239                 *param_data = &g_array_index(output,
240                                 bluetooth_device_address_t, 0);
241                 break;
242         case BT_TDS_READ_TRANSPORT_DATA:
243                 *event_type = BT_TDS_EVENT;
244                 *event = BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED;
245                 ret_if(output == NULL);
246                 *param_data = &g_array_index(output,
247                         bluetooth_device_address_t, 0);
248                 break;
249         case BT_TDS_ENABLE_CONTROL_POINT:
250                 *event_type = BT_TDS_EVENT;
251                 *event = BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED;
252                 ret_if(output == NULL);
253                 *param_data = &g_array_index(output,
254                         bluetooth_device_address_t, 0);
255                 break;
256         case BT_TDS_ACTIVATE_CONTROL_POINT:
257                 *event_type = BT_TDS_EVENT;
258                 *event = BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT;
259                 ret_if(output == NULL);
260                 *param_data = &g_array_index(output,
261                         bluetooth_device_address_t, 0);
262                 break;
263         case BT_HDP_CONNECT:
264                 *event_type = BT_HDP_EVENT;
265                 *event = BLUETOOTH_EVENT_HDP_CONNECTED;
266                 ret_if(output == NULL);
267                 *param_data = &g_array_index(output,
268                                 bt_hdp_connected_t, 0);
269                 break;
270         case BT_HDP_DISCONNECT:
271                 *event_type = BT_HDP_EVENT;
272                 *event = BLUETOOTH_EVENT_HDP_DISCONNECTED;
273                 ret_if(output == NULL);
274                 *param_data = &g_array_index(output,
275                                 bt_hdp_disconnected_t, 0);
276                 break;
277         default:
278                 BT_ERR("Unknown function");
279                 return;
280         }
281 }
282
283 /*
284 out param1: API result
285 out param2: return paramter
286 out param3:
287 */
288 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
289 {
290         char *data;
291         int size;
292
293         size = g_variant_get_size(var);
294         if (size > 0) {
295                 data = (char *)g_variant_get_data(var);
296                 if (data)
297                         param = g_array_append_vals(param, data, size);
298
299         }
300 }
301
302 static void __send_request_cb(GDBusProxy *proxy,
303                                 GAsyncResult *res,
304                                 gpointer user_data)
305 {
306         bluetooth_event_param_t bt_event;
307         bt_req_info_t *cb_data = user_data;
308         int result = BLUETOOTH_ERROR_NONE;
309         int event_type = BT_ADAPTER_EVENT;
310         int request_id;
311         GError *error = NULL;
312         GVariant *value;
313         GVariant *param1;
314 //      GVariant *param2;
315         GArray *out_param1 = NULL;
316 //      GArray *out_param2 = NULL;
317
318         BT_DBG("+");
319         memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
320
321         value = g_dbus_proxy_call_finish(proxy, res, &error);
322         if (value == NULL) {
323                 if (error) {
324                         /* dBUS gives error cause */
325                         BT_ERR("D-Bus API failure: message[%s]",
326                                                         error->message);
327                         g_clear_error(&error);
328                 }
329                 result = BLUETOOTH_ERROR_TIMEOUT;
330
331                 ret_if(cb_data == NULL);
332
333                 __bt_get_event_info(cb_data->service_function, NULL,
334                                 &bt_event.event, &event_type,
335                                 &bt_event.param_data);
336         } else {
337                 g_variant_get(value, "(iv)", &result, &param1);
338                 g_variant_unref(value);
339
340                 if (param1) {
341                         out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
342                         __bt_fill_garray_from_variant(param1, out_param1);
343                         g_variant_unref(param1);
344                 }
345
346 //              if (param2) {
347 //                      out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
348 //                      __bt_fill_garray_from_variant(param2, out_param2);
349 //                      result = g_array_index(out_param2, int, 0);
350 //                      g_variant_unref(param2);
351 //                      g_array_free(out_param2, TRUE);
352 //              } else {
353 //                      result = BLUETOOTH_ERROR_INTERNAL;
354 //              }
355
356                 ret_if(cb_data == NULL);
357
358                 __bt_get_event_info(cb_data->service_function, out_param1,
359                                 &bt_event.event, &event_type,
360                                 &bt_event.param_data);
361
362                 BT_DBG("service_function [%d]", cb_data->service_function);
363                 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
364                         if (cb_data->service_function == BT_OPP_PUSH_FILES) {
365                                 request_id = g_array_index(out_param1, int, 0);
366                                 BT_DBG("request_id : %d", request_id);
367                                 _bt_add_push_request_id(request_id);
368                         } else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) {
369                                 request_id = g_array_index(out_param1, int, 0);
370                                 BT_DBG("request_id : %d", request_id);
371                                 _bt_add_push_request_id(request_id);
372                         } else if (cb_data->service_function == BT_MAP_LIST_FILTER_FIELDS) {
373                                 request_id = g_array_index(out_param1, int, 0);
374                                 BT_DBG("request_id : %d", request_id);
375                                 _bt_add_push_request_id(request_id);
376                         } else if (cb_data->service_function == BT_MAP_LIST_MESSAGES) {
377                                 request_id = g_array_index(out_param1, int, 0);
378                                 BT_DBG("request_id : %d", request_id);
379                                 _bt_add_push_request_id(request_id);
380                         } else if (cb_data->service_function == BT_MAP_GET_MESSAGE) {
381                                 request_id = g_array_index(out_param1, int, 0);
382                                 BT_DBG("request_id : %d", request_id);
383                                 _bt_add_push_request_id(request_id);
384                         } else if (cb_data->service_function == BT_MAP_PUSH_MESSAGE) {
385                                 request_id = g_array_index(out_param1, int, 0);
386                                 BT_DBG("request_id : %d", request_id);
387                                 _bt_add_push_request_id(request_id);
388                         }
389
390                         goto done;
391                 }
392         }
393
394         if (cb_data->cb == NULL)
395                 goto done;
396
397         /* Only if fail case, call the callback function*/
398         bt_event.result = result;
399         BT_INFO("event_type[%d], result= %s [0x%x]", event_type,
400                 _bt_convert_error_to_string(result), result);
401
402         if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
403                 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
404                                 &bt_event,
405                                 cb_data->user_data);
406         } else if (event_type == BT_HID_EVENT) {
407                 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
408                                 (hid_event_param_t *)&bt_event,
409                                 cb_data->user_data);
410         } else if (event_type == BT_HEADSET_EVENT) {
411                 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
412                                 (bt_audio_event_param_t *)&bt_event,
413                                 cb_data->user_data);
414         } else if (event_type == BT_HF_AGENT_EVENT) {
415                 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
416                                 (bt_audio_event_param_t *)&bt_event,
417                                 cb_data->user_data);
418         } else if (event_type == BT_AVRCP_CONTROL_EVENT) {
419                 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
420                                 (media_event_param_t *)&bt_event,
421                                 cb_data->user_data);
422         } else if (event_type == BT_A2DP_SOURCE_EVENT) {
423                 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
424                                 (bt_audio_event_param_t *)&bt_event,
425                                 cb_data->user_data);
426         } else if (event_type == BT_DEVICE_EVENT) {
427                 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
428                                 &bt_event,
429                                 cb_data->user_data);
430         } else if (event_type == BT_TDS_EVENT) {
431                 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
432                                 &bt_event,
433                                 cb_data->user_data);
434         } else if (event_type == BT_HDP_EVENT) {
435                 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
436                         &bt_event, cb_data->user_data);
437         } else if (event_type == BT_AVRCP_EVENT) {
438                 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
439                         &bt_event, cb_data->user_data);
440         } else {
441                 BT_INFO("Not handled event type : %d", event_type);
442         }
443 done:
444         if (out_param1)
445                 g_array_free(out_param1, TRUE);
446
447         sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
448
449         g_free(cb_data);
450         BT_DBG("-");
451 }
452
453 int _bt_sync_send_request(int service_type, int service_function,
454                         GArray *in_param1, GArray *in_param2,
455                         GArray *in_param3, GArray *in_param4,
456                         GArray **out_param1)
457 {
458         int result = BLUETOOTH_ERROR_NONE;
459         GError *error = NULL;
460         GArray *in_param5 = NULL;
461 //      GArray *out_param2 = NULL;
462
463         GDBusProxy  *proxy;
464         GVariant *ret;
465         GVariant *param1;
466         GVariant *param2;
467         GVariant *param3;
468         GVariant *param4;
469         GVariant *param5;
470
471         switch (service_type) {
472         case BT_BLUEZ_SERVICE:
473         case BT_OBEX_SERVICE:
474         case BT_AGENT_SERVICE:
475         case BT_CHECK_PRIVILEGE:
476                 proxy = __bt_gdbus_get_service_proxy();
477                 if (!proxy)
478                         return BLUETOOTH_ERROR_INTERNAL;
479
480                 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
481
482
483
484                 param1 = g_variant_new_from_data((const GVariantType *)"ay",
485                                         in_param1->data, in_param1->len,
486                                         TRUE, NULL, NULL);
487                 param2 = g_variant_new_from_data((const GVariantType *)"ay",
488                                         in_param2->data, in_param2->len,
489                                         TRUE, NULL, NULL);
490                 param3 = g_variant_new_from_data((const GVariantType *)"ay",
491                                         in_param3->data, in_param3->len,
492                                         TRUE, NULL, NULL);
493                 param4 = g_variant_new_from_data((const GVariantType *)"ay",
494                                         in_param4->data, in_param4->len,
495                                         TRUE, NULL, NULL);
496                 param5 = g_variant_new_from_data((const GVariantType *)"ay",
497                                         in_param5->data, in_param5->len,
498                                         TRUE, NULL, NULL);
499
500                 ret = g_dbus_proxy_call_sync(proxy, "service_request",
501                                         g_variant_new("(iii@ay@ay@ay@ay@ay)",
502                                                 service_type, service_function,
503                                                 BT_SYNC_REQ, param1,
504                                                 param2, param3,
505                                                 param4, param5),
506                                         G_DBUS_CALL_FLAGS_NONE, -1,
507                                         NULL, &error);
508
509                 g_array_free(in_param5, TRUE);
510
511                 if (ret == NULL) {
512                         /* dBUS-RPC is failed */
513                         BT_ERR("dBUS-RPC is failed");
514
515                         if (error != NULL) {
516                                 /* dBUS gives error cause */
517                                 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
518                                        error->code, error->message);
519
520                                 g_clear_error(&error);
521                         } else {
522                                 /* dBUS does not give error cause dBUS-RPC is failed */
523                                 BT_ERR("error returned was NULL");
524                         }
525
526                         return BLUETOOTH_ERROR_INTERNAL;
527                 }
528
529                 param1 = NULL;
530 //              param2 = NULL;
531
532                 g_variant_get(ret, "(iv)", &result, &param1);
533
534                 if (param1) {
535                         *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
536                         __bt_fill_garray_from_variant(param1, *out_param1);
537                         g_variant_unref(param1);
538                 }
539
540 //              if (param2) {
541 //                      out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
542 //                      __bt_fill_garray_from_variant(param2, out_param2);
543 //                      result = g_array_index(out_param2, int, 0);
544 //                      g_variant_unref(param2);
545 //                      g_array_free(out_param2, TRUE);
546 //              } else {
547 //                      result = BLUETOOTH_ERROR_INTERNAL;
548 //              }
549
550                 g_variant_unref(ret);
551                 break;
552         default:
553                 BT_ERR("Unknown service type");
554                 return BLUETOOTH_ERROR_INTERNAL;
555         }
556
557         return result;
558 }
559
560 int _bt_async_send_request(int service_type, int service_function,
561                         GArray *in_param1, GArray *in_param2,
562                         GArray *in_param3, GArray *in_param4,
563                         void *callback, void *user_data)
564 {
565         GArray* in_param5 = NULL;
566         bt_req_info_t *cb_data;
567
568         GDBusProxy *proxy;
569         int timeout;
570         GVariant *param1;
571         GVariant *param2;
572         GVariant *param3;
573         GVariant *param4;
574         GVariant *param5;
575
576         BT_DBG("service_function : %s (0x%x)",
577                         _bt_convert_service_function_to_string(service_function),
578                         service_function);
579
580         cb_data = g_new0(bt_req_info_t, 1);
581
582         cb_data->service_function = service_function;
583         cb_data->cb = callback;
584         cb_data->user_data = user_data;
585
586         switch (service_type) {
587         case BT_BLUEZ_SERVICE:
588         case BT_OBEX_SERVICE:
589                 proxy =  __bt_gdbus_get_service_proxy();
590                 if (!proxy) {
591                         g_free(cb_data);
592                         return BLUETOOTH_ERROR_INTERNAL;
593                 }
594
595                 /* Do not timeout the request in certain cases. Sometime the
596                  * request may take undeterministic time to reponse.
597                  * (for ex: pairing retry) */
598                 if (service_function == BT_BOND_DEVICE ||
599                         service_function == BT_BOND_DEVICE_BY_TYPE)
600                         timeout = INT_MAX;
601                 else
602                         timeout = BT_DBUS_TIMEOUT_MAX;
603
604                 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
605
606                 param1 = g_variant_new_from_data((const GVariantType *)"ay",
607                                         in_param1->data, in_param1->len,
608                                         TRUE, NULL, NULL);
609                 param2 = g_variant_new_from_data((const GVariantType *)"ay",
610                                         in_param2->data, in_param2->len,
611                                         TRUE, NULL, NULL);
612                 param3 = g_variant_new_from_data((const GVariantType *)"ay",
613                                         in_param3->data, in_param3->len,
614                                         TRUE, NULL, NULL);
615                 param4 = g_variant_new_from_data((const GVariantType *)"ay",
616                                         in_param4->data, in_param4->len,
617                                         TRUE, NULL, NULL);
618                 param5 = g_variant_new_from_data((const GVariantType *)"ay",
619                                         in_param5->data, in_param5->len,
620                                         TRUE, NULL, NULL);
621
622                 g_dbus_proxy_call(proxy, "service_request",
623                                         g_variant_new("(iii@ay@ay@ay@ay@ay)",
624                                                 service_type, service_function,
625                                                 BT_ASYNC_REQ, param1, param2,
626                                                 param3, param4, param5),
627                                         G_DBUS_CALL_FLAGS_NONE,
628                                         timeout, NULL,
629                                         (GAsyncReadyCallback)__send_request_cb,
630                                         (gpointer)cb_data);
631                 sending_requests = g_slist_append(sending_requests, cb_data);
632
633                 g_array_free(in_param5, TRUE);
634                 break;
635         default:
636                 g_free(cb_data);
637                 break;
638         }
639
640         return BLUETOOTH_ERROR_NONE;
641 }
642
643 int _bt_async_send_request_with_unix_fd_list(int service_type, int service_function,
644                         GArray *in_param1, GArray *in_param2,
645                         GArray *in_param3, GArray *in_param4,
646                         void *callback, void *user_data,
647                         GUnixFDList *fd_list, GAsyncReadyCallback __async_req_cb)
648 {
649         GArray* in_param5 = NULL;
650         bt_req_info_t *cb_data;
651
652         GDBusProxy *proxy;
653         int timeout;
654         GVariant *param1;
655         GVariant *param2;
656         GVariant *param3;
657         GVariant *param4;
658         GVariant *param5;
659
660         BT_DBG("service_function : %d", service_function);
661
662         cb_data = g_new0(bt_req_info_t, 1);
663         cb_data->service_function = service_function;
664         cb_data->cb = callback;
665         cb_data->user_data = user_data;
666
667         switch (service_type) {
668         case BT_BLUEZ_SERVICE:
669         case BT_OBEX_SERVICE:
670                 proxy =  __bt_gdbus_get_service_proxy();
671                 if (!proxy) {
672                         g_free(cb_data);
673                         return BLUETOOTH_ERROR_INTERNAL;
674                 }
675
676                 /* Do not timeout the request in certain cases. Sometime the
677                  * request may take undeterministic time to reponse.
678                  * (for ex: pairing retry) */
679                 if (service_function == BT_BOND_DEVICE ||
680                                 service_function == BT_BOND_DEVICE_BY_TYPE)
681                         timeout = INT_MAX;
682                 else
683                         timeout = BT_DBUS_TIMEOUT_MAX;
684
685                 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
686
687                 param1 = g_variant_new_from_data((const GVariantType *)"ay",
688                                 in_param1->data, in_param1->len,
689                                 TRUE, NULL, NULL);
690                 param2 = g_variant_new_from_data((const GVariantType *)"ay",
691                                 in_param2->data, in_param2->len,
692                                 TRUE, NULL, NULL);
693                 param3 = g_variant_new_from_data((const GVariantType *)"ay",
694                                 in_param3->data, in_param3->len,
695                                 TRUE, NULL, NULL);
696                 param4 = g_variant_new_from_data((const GVariantType *)"ay",
697                                 in_param4->data, in_param4->len,
698                                 TRUE, NULL, NULL);
699                 param5 = g_variant_new_from_data((const GVariantType *)"ay",
700                                 in_param5->data, in_param5->len,
701                                 TRUE, NULL, NULL);
702
703                 g_dbus_proxy_call_with_unix_fd_list(proxy, "service_request",
704                                 g_variant_new("(iii@ay@ay@ay@ay@ay)",
705                                         service_type, service_function,
706                                         BT_ASYNC_REQ, param1, param2,
707                                         param3, param4, param5),
708                                 G_DBUS_CALL_FLAGS_NONE,
709                                 timeout, fd_list, NULL,
710                                 __async_req_cb, (gpointer)cb_data);
711                 sending_requests = g_slist_append(sending_requests, cb_data);
712
713                 g_array_free(in_param5, TRUE);
714                 break;
715         default:
716                 g_free(cb_data);
717                 break;
718         }
719
720         return BLUETOOTH_ERROR_NONE;
721 }
722
723 int _bt_sync_send_request_with_unix_fd_list(
724                 int service_type, int service_function,
725                 GArray *in_param1, GArray *in_param2,
726                 GArray *in_param3, GArray *in_param4,
727                 GUnixFDList *fd_list, GArray **out_param1,
728                 GUnixFDList **out_fd_list)
729 {
730         int result = BLUETOOTH_ERROR_NONE;
731         GError *error = NULL;
732         GArray *in_param5 = NULL;
733
734         GDBusProxy  *proxy;
735         GVariant *ret;
736         GVariant *param1;
737         GVariant *param2;
738         GVariant *param3;
739         GVariant *param4;
740         GVariant *param5;
741
742         switch (service_type) {
743         case BT_BLUEZ_SERVICE:
744         case BT_OBEX_SERVICE:
745         case BT_AGENT_SERVICE:
746         case BT_CHECK_PRIVILEGE:
747                 proxy = __bt_gdbus_get_service_proxy();
748                 if (!proxy)
749                         return BLUETOOTH_ERROR_INTERNAL;
750
751                 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
752
753                 param1 = g_variant_new_from_data((const GVariantType *)"ay",
754                                         in_param1->data, in_param1->len,
755                                         TRUE, NULL, NULL);
756                 param2 = g_variant_new_from_data((const GVariantType *)"ay",
757                                         in_param2->data, in_param2->len,
758                                         TRUE, NULL, NULL);
759                 param3 = g_variant_new_from_data((const GVariantType *)"ay",
760                                         in_param3->data, in_param3->len,
761                                         TRUE, NULL, NULL);
762                 param4 = g_variant_new_from_data((const GVariantType *)"ay",
763                                         in_param4->data, in_param4->len,
764                                         TRUE, NULL, NULL);
765                 param5 = g_variant_new_from_data((const GVariantType *)"ay",
766                                         in_param5->data, in_param5->len,
767                                         TRUE, NULL, NULL);
768
769                 ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, "service_request",
770                                 g_variant_new("(iii@ay@ay@ay@ay@ay)",
771                                         service_type, service_function,
772                                         BT_SYNC_REQ, param1, param2,
773                                         param3, param4, param5),
774                                 G_DBUS_CALL_FLAGS_NONE, -1,
775                                 fd_list, out_fd_list, NULL, &error);
776                 g_array_free(in_param5, TRUE);
777
778                 if (ret == NULL) {
779                         /* dBUS-RPC is failed */
780                         BT_ERR("dBUS-RPC is failed");
781
782                         if (error != NULL) {
783                                 /* dBUS gives error cause */
784                                 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
785                                        error->code, error->message);
786
787                                 g_clear_error(&error);
788                         } else {
789                                 /* dBUS does not give error cause dBUS-RPC is failed */
790                                 BT_ERR("error returned was NULL");
791                         }
792
793                         return BLUETOOTH_ERROR_INTERNAL;
794                 }
795
796                 param1 = NULL;
797                 g_variant_get(ret, "(iv)", &result, &param1);
798
799                 if (param1) {
800                         *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
801                         __bt_fill_garray_from_variant(param1, *out_param1);
802                         g_variant_unref(param1);
803                 }
804
805                 g_variant_unref(ret);
806                 break;
807         default:
808                 BT_ERR("Unknown service type");
809                 return BLUETOOTH_ERROR_INTERNAL;
810         }
811
812         return result;
813 }