2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
28 #include "bt-common.h"
29 #include "bt-request-sender.h"
30 #include "bt-event-handler.h"
31 #include "bluetooth-media-control.h"
33 static GSList *sending_requests;
35 static GDBusProxy *service_gproxy;
37 static GDBusProxy *__bt_gdbus_init_service_proxy(void)
39 GDBusConnection *service_gconn;
43 service_gconn = _bt_gdbus_get_system_gconn();
48 proxy = g_dbus_proxy_new_sync(service_gconn,
49 G_DBUS_PROXY_FLAGS_NONE, NULL,
56 BT_ERR("Unable to create proxy: %s", err->message);
63 service_gproxy = proxy;
68 static GDBusProxy *__bt_gdbus_get_service_proxy(void)
70 return (service_gproxy) ? service_gproxy : __bt_gdbus_init_service_proxy();
73 void _bt_gdbus_deinit_proxys(void)
76 g_object_unref(service_gproxy);
77 service_gproxy = NULL;
81 static void __bt_get_event_info(int service_function, GArray *output,
82 int *event, int *event_type, void **param_data)
84 ret_if(event == NULL);
86 BT_DBG("service_function : %s (0x%x)",
87 _bt_convert_service_function_to_string(service_function),
89 switch (service_function) {
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);
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_info_t, 0);
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 bluetooth_device_info_t, 0);
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);
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);
126 case BT_AUDIO_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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
197 case BT_AVRCP_CONTROL_CONNECT:
198 *event_type = BT_AVRCP_CONTROL_EVENT;
199 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
200 ret_if(output == NULL);
201 *param_data = &g_array_index(output, char, 0);
203 case BT_AVRCP_CONTROL_DISCONNECT:
204 *event_type = BT_AVRCP_CONTROL_EVENT;
205 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
206 ret_if(output == NULL);
207 *param_data = &g_array_index(output, char, 0);
210 *event_type = BT_DEVICE_EVENT;
211 *event = BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED;
212 ret_if(output == NULL);
213 *param_data = &g_array_index(output,
214 bluetooth_device_address_t, 0);
217 *event_type = BT_DEVICE_EVENT;
218 *event = BLUETOOTH_EVENT_GATT_CONNECTED;
219 ret_if(output == NULL);
220 *param_data = &g_array_index(output,
221 bluetooth_device_address_t, 0);
223 case BT_DISCONNECT_LE:
224 *event_type = BT_DEVICE_EVENT;
225 *event = BLUETOOTH_EVENT_GATT_DISCONNECTED;
226 ret_if(output == NULL);
227 *param_data = &g_array_index(output,
228 bluetooth_device_address_t, 0);
230 case BT_TDS_READ_TRANSPORT_DATA:
231 *event_type = BT_TDS_EVENT;
232 *event = BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED;
233 ret_if(output == NULL);
234 *param_data = &g_array_index(output,
235 bluetooth_device_address_t, 0);
237 case BT_TDS_ENABLE_CONTROL_POINT:
238 *event_type = BT_TDS_EVENT;
239 *event = BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED;
240 ret_if(output == NULL);
241 *param_data = &g_array_index(output,
242 bluetooth_device_address_t, 0);
244 case BT_TDS_ACTIVATE_CONTROL_POINT:
245 *event_type = BT_TDS_EVENT;
246 *event = BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION;
247 ret_if(output == NULL);
248 *param_data = &g_array_index(output,
249 bluetooth_device_address_t, 0);
252 BT_ERR("Unknown function");
258 out param1: API result
259 out param2: return paramter
262 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
267 size = g_variant_get_size(var);
269 data = (char *)g_variant_get_data(var);
271 param = g_array_append_vals(param, data, size);
276 static void __send_request_cb(GDBusProxy *proxy,
280 BT_DBG("Entered __send_request_cb");
281 bluetooth_event_param_t bt_event;
282 bt_req_info_t *cb_data = user_data;
283 int result = BLUETOOTH_ERROR_NONE;
284 int event_type = BT_ADAPTER_EVENT;
286 GError *error = NULL;
290 GArray *out_param1 = NULL;
291 // GArray *out_param2 = NULL;
294 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
296 value = g_dbus_proxy_call_finish(proxy, res, &error);
299 /* dBUS gives error cause */
300 BT_ERR("D-Bus API failure: message[%s]",
302 g_clear_error(&error);
304 result = BLUETOOTH_ERROR_TIMEOUT;
306 ret_if(cb_data == NULL);
308 __bt_get_event_info(cb_data->service_function, NULL,
309 &bt_event.event, &event_type,
310 &bt_event.param_data);
312 g_variant_get(value, "(iv)", &result, ¶m1);
313 g_variant_unref(value);
316 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
317 __bt_fill_garray_from_variant(param1, out_param1);
318 g_variant_unref(param1);
322 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
323 // __bt_fill_garray_from_variant(param2, out_param2);
324 // result = g_array_index(out_param2, int, 0);
325 // g_variant_unref(param2);
326 // g_array_free(out_param2, TRUE);
328 // result = BLUETOOTH_ERROR_INTERNAL;
331 ret_if(cb_data == NULL);
333 __bt_get_event_info(cb_data->service_function, out_param1,
334 &bt_event.event, &event_type,
335 &bt_event.param_data);
337 BT_DBG("service_function [%d]", cb_data->service_function);
338 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
339 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
340 request_id = g_array_index(out_param1, int, 0);
341 BT_DBG("request_id : %d", request_id);
342 _bt_add_push_request_id(request_id);
343 } else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) {
344 request_id = g_array_index(out_param1, int, 0);
345 BT_DBG("request_id : %d", request_id);
346 _bt_add_push_request_id(request_id);
347 } else if (cb_data->service_function == BT_MAP_LIST_FILTER_FIELDS) {
348 request_id = g_array_index(out_param1, int, 0);
349 BT_DBG("request_id : %d", request_id);
350 _bt_add_push_request_id(request_id);
351 } else if (cb_data->service_function == BT_MAP_LIST_MESSAGES) {
352 request_id = g_array_index(out_param1, int, 0);
353 BT_DBG("request_id : %d", request_id);
354 _bt_add_push_request_id(request_id);
355 } else if (cb_data->service_function == BT_MAP_GET_MESSAGE) {
356 request_id = g_array_index(out_param1, int, 0);
357 BT_DBG("request_id : %d", request_id);
358 _bt_add_push_request_id(request_id);
359 } else if (cb_data->service_function == BT_MAP_PUSH_MESSAGE) {
360 request_id = g_array_index(out_param1, int, 0);
361 BT_DBG("request_id : %d", request_id);
362 _bt_add_push_request_id(request_id);
369 if (cb_data->cb == NULL)
372 /* Only if fail case, call the callback function*/
373 bt_event.result = result;
374 BT_INFO("event_type[%d], result= %s [0x%x]", event_type,
375 _bt_convert_error_to_string(result), result);
377 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
378 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
381 } else if (event_type == BT_HID_EVENT) {
382 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
383 (hid_event_param_t *)&bt_event,
385 } else if (event_type == BT_HEADSET_EVENT) {
386 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
387 (bt_audio_event_param_t *)&bt_event,
389 } else if (event_type == BT_HF_AGENT_EVENT) {
390 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
391 (bt_audio_event_param_t *)&bt_event,
393 } else if (event_type == BT_AVRCP_CONTROL_EVENT) {
394 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
395 (media_event_param_t *)&bt_event,
397 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
398 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
399 (bt_audio_event_param_t *)&bt_event,
401 } else if (event_type == BT_DEVICE_EVENT) {
402 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
405 } else if (event_type == BT_TDS_EVENT) {
406 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
410 BT_INFO("Not handled event type : %d", event_type);
414 g_array_free(out_param1, TRUE);
416 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
422 int _bt_sync_send_request(int service_type, int service_function,
423 GArray *in_param1, GArray *in_param2,
424 GArray *in_param3, GArray *in_param4,
427 int result = BLUETOOTH_ERROR_NONE;
428 GError *error = NULL;
429 GArray *in_param5 = NULL;
430 // GArray *out_param2 = NULL;
440 switch (service_type) {
441 case BT_BLUEZ_SERVICE:
442 case BT_OBEX_SERVICE:
443 case BT_AGENT_SERVICE:
444 case BT_CHECK_PRIVILEGE:
445 proxy = __bt_gdbus_get_service_proxy();
447 return BLUETOOTH_ERROR_INTERNAL;
449 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
453 param1 = g_variant_new_from_data((const GVariantType *)"ay",
454 in_param1->data, in_param1->len,
456 param2 = g_variant_new_from_data((const GVariantType *)"ay",
457 in_param2->data, in_param2->len,
459 param3 = g_variant_new_from_data((const GVariantType *)"ay",
460 in_param3->data, in_param3->len,
462 param4 = g_variant_new_from_data((const GVariantType *)"ay",
463 in_param4->data, in_param4->len,
465 param5 = g_variant_new_from_data((const GVariantType *)"ay",
466 in_param5->data, in_param5->len,
469 ret = g_dbus_proxy_call_sync(proxy, "service_request",
470 g_variant_new("(iii@ay@ay@ay@ay@ay)",
471 service_type, service_function,
475 G_DBUS_CALL_FLAGS_NONE, -1,
478 g_array_free(in_param5, TRUE);
481 /* dBUS-RPC is failed */
482 BT_ERR("dBUS-RPC is failed");
485 /* dBUS gives error cause */
486 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
487 error->code, error->message);
489 g_clear_error(&error);
491 /* dBUS does not give error cause dBUS-RPC is failed */
492 BT_ERR("error returned was NULL");
495 return BLUETOOTH_ERROR_INTERNAL;
501 g_variant_get(ret, "(iv)", &result, ¶m1);
504 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
505 __bt_fill_garray_from_variant(param1, *out_param1);
506 g_variant_unref(param1);
510 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
511 // __bt_fill_garray_from_variant(param2, out_param2);
512 // result = g_array_index(out_param2, int, 0);
513 // g_variant_unref(param2);
514 // g_array_free(out_param2, TRUE);
516 // result = BLUETOOTH_ERROR_INTERNAL;
519 g_variant_unref(ret);
522 BT_ERR("Unknown service type");
523 return BLUETOOTH_ERROR_INTERNAL;
529 int _bt_async_send_request(int service_type, int service_function,
530 GArray *in_param1, GArray *in_param2,
531 GArray *in_param3, GArray *in_param4,
532 void *callback, void *user_data)
534 GArray* in_param5 = NULL;
535 bt_req_info_t *cb_data;
545 BT_DBG("service_function : %s (0x%x)",
546 _bt_convert_service_function_to_string(service_function),
549 cb_data = g_new0(bt_req_info_t, 1);
551 cb_data->service_function = service_function;
552 cb_data->cb = callback;
553 cb_data->user_data = user_data;
555 switch (service_type) {
556 case BT_BLUEZ_SERVICE:
557 case BT_OBEX_SERVICE:
558 proxy = __bt_gdbus_get_service_proxy();
561 return BLUETOOTH_ERROR_INTERNAL;
564 /* Do not timeout the request in certain cases. Sometime the
565 * request may take undeterministic time to reponse.
566 * (for ex: pairing retry) */
567 if (service_function == BT_BOND_DEVICE ||
568 service_function == BT_BOND_DEVICE_BY_TYPE)
571 timeout = BT_DBUS_TIMEOUT_MAX;
573 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
575 param1 = g_variant_new_from_data((const GVariantType *)"ay",
576 in_param1->data, in_param1->len,
578 param2 = g_variant_new_from_data((const GVariantType *)"ay",
579 in_param2->data, in_param2->len,
581 param3 = g_variant_new_from_data((const GVariantType *)"ay",
582 in_param3->data, in_param3->len,
584 param4 = g_variant_new_from_data((const GVariantType *)"ay",
585 in_param4->data, in_param4->len,
587 param5 = g_variant_new_from_data((const GVariantType *)"ay",
588 in_param5->data, in_param5->len,
591 g_dbus_proxy_call(proxy, "service_request",
592 g_variant_new("(iii@ay@ay@ay@ay@ay)",
593 service_type, service_function,
594 BT_ASYNC_REQ, param1, param2,
595 param3, param4, param5),
596 G_DBUS_CALL_FLAGS_NONE,
598 (GAsyncReadyCallback)__send_request_cb,
600 sending_requests = g_slist_append(sending_requests, cb_data);
602 g_array_free(in_param5, TRUE);
609 return BLUETOOTH_ERROR_NONE;