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