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 bluetooth_event_param_t bt_event;
281 bt_req_info_t *cb_data = user_data;
282 int result = BLUETOOTH_ERROR_NONE;
283 int event_type = BT_ADAPTER_EVENT;
285 GError *error = NULL;
289 GArray *out_param1 = NULL;
290 // GArray *out_param2 = NULL;
293 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
295 value = g_dbus_proxy_call_finish(proxy, res, &error);
298 /* dBUS gives error cause */
299 BT_ERR("D-Bus API failure: message[%s]",
301 g_clear_error(&error);
303 result = BLUETOOTH_ERROR_TIMEOUT;
305 ret_if(cb_data == NULL);
307 __bt_get_event_info(cb_data->service_function, NULL,
308 &bt_event.event, &event_type,
309 &bt_event.param_data);
311 g_variant_get(value, "(iv)", &result, ¶m1);
312 g_variant_unref(value);
315 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
316 __bt_fill_garray_from_variant(param1, out_param1);
317 g_variant_unref(param1);
321 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
322 // __bt_fill_garray_from_variant(param2, out_param2);
323 // result = g_array_index(out_param2, int, 0);
324 // g_variant_unref(param2);
325 // g_array_free(out_param2, TRUE);
327 // result = BLUETOOTH_ERROR_INTERNAL;
330 ret_if(cb_data == NULL);
332 __bt_get_event_info(cb_data->service_function, out_param1,
333 &bt_event.event, &event_type,
334 &bt_event.param_data);
336 BT_DBG("service_function [%d]", cb_data->service_function);
337 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
338 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
339 request_id = g_array_index(out_param1, int, 0);
340 BT_DBG("request_id : %d", request_id);
341 _bt_add_push_request_id(request_id);
342 } else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) {
343 request_id = g_array_index(out_param1, int, 0);
344 BT_DBG("request_id : %d", request_id);
345 _bt_add_push_request_id(request_id);
346 } else if (cb_data->service_function == BT_MAP_LIST_FILTER_FIELDS) {
347 request_id = g_array_index(out_param1, int, 0);
348 BT_DBG("request_id : %d", request_id);
349 _bt_add_push_request_id(request_id);
350 } else if (cb_data->service_function == BT_MAP_LIST_MESSAGES) {
351 request_id = g_array_index(out_param1, int, 0);
352 BT_DBG("request_id : %d", request_id);
353 _bt_add_push_request_id(request_id);
354 } else if (cb_data->service_function == BT_MAP_GET_MESSAGE) {
355 request_id = g_array_index(out_param1, int, 0);
356 BT_DBG("request_id : %d", request_id);
357 _bt_add_push_request_id(request_id);
358 } else if (cb_data->service_function == BT_MAP_PUSH_MESSAGE) {
359 request_id = g_array_index(out_param1, int, 0);
360 BT_DBG("request_id : %d", request_id);
361 _bt_add_push_request_id(request_id);
368 if (cb_data->cb == NULL)
371 /* Only if fail case, call the callback function*/
372 bt_event.result = result;
373 BT_INFO("event_type[%d], result= %s [0x%x]", event_type,
374 _bt_convert_error_to_string(result), result);
376 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
377 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
380 } else if (event_type == BT_HID_EVENT) {
381 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
382 (hid_event_param_t *)&bt_event,
384 } else if (event_type == BT_HEADSET_EVENT) {
385 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
386 (bt_audio_event_param_t *)&bt_event,
388 } else if (event_type == BT_HF_AGENT_EVENT) {
389 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
390 (bt_audio_event_param_t *)&bt_event,
392 } else if (event_type == BT_AVRCP_CONTROL_EVENT) {
393 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
394 (media_event_param_t *)&bt_event,
396 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
397 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
398 (bt_audio_event_param_t *)&bt_event,
400 } else if (event_type == BT_DEVICE_EVENT) {
401 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
404 } else if (event_type == BT_TDS_EVENT) {
405 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
409 BT_INFO("Not handled event type : %d", event_type);
413 g_array_free(out_param1, TRUE);
415 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
421 int _bt_sync_send_request(int service_type, int service_function,
422 GArray *in_param1, GArray *in_param2,
423 GArray *in_param3, GArray *in_param4,
426 int result = BLUETOOTH_ERROR_NONE;
427 GError *error = NULL;
428 GArray *in_param5 = NULL;
429 // GArray *out_param2 = NULL;
439 switch (service_type) {
440 case BT_BLUEZ_SERVICE:
441 case BT_OBEX_SERVICE:
442 case BT_AGENT_SERVICE:
443 case BT_CHECK_PRIVILEGE:
444 proxy = __bt_gdbus_get_service_proxy();
446 return BLUETOOTH_ERROR_INTERNAL;
448 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
452 param1 = g_variant_new_from_data((const GVariantType *)"ay",
453 in_param1->data, in_param1->len,
455 param2 = g_variant_new_from_data((const GVariantType *)"ay",
456 in_param2->data, in_param2->len,
458 param3 = g_variant_new_from_data((const GVariantType *)"ay",
459 in_param3->data, in_param3->len,
461 param4 = g_variant_new_from_data((const GVariantType *)"ay",
462 in_param4->data, in_param4->len,
464 param5 = g_variant_new_from_data((const GVariantType *)"ay",
465 in_param5->data, in_param5->len,
468 ret = g_dbus_proxy_call_sync(proxy, "service_request",
469 g_variant_new("(iii@ay@ay@ay@ay@ay)",
470 service_type, service_function,
474 G_DBUS_CALL_FLAGS_NONE, -1,
477 g_array_free(in_param5, TRUE);
480 /* dBUS-RPC is failed */
481 BT_ERR("dBUS-RPC is failed");
484 /* dBUS gives error cause */
485 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
486 error->code, error->message);
488 g_clear_error(&error);
490 /* dBUS does not give error cause dBUS-RPC is failed */
491 BT_ERR("error returned was NULL");
494 return BLUETOOTH_ERROR_INTERNAL;
500 g_variant_get(ret, "(iv)", &result, ¶m1);
503 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
504 __bt_fill_garray_from_variant(param1, *out_param1);
505 g_variant_unref(param1);
509 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
510 // __bt_fill_garray_from_variant(param2, out_param2);
511 // result = g_array_index(out_param2, int, 0);
512 // g_variant_unref(param2);
513 // g_array_free(out_param2, TRUE);
515 // result = BLUETOOTH_ERROR_INTERNAL;
518 g_variant_unref(ret);
521 BT_ERR("Unknown service type");
522 return BLUETOOTH_ERROR_INTERNAL;
528 int _bt_async_send_request(int service_type, int service_function,
529 GArray *in_param1, GArray *in_param2,
530 GArray *in_param3, GArray *in_param4,
531 void *callback, void *user_data)
533 GArray* in_param5 = NULL;
534 bt_req_info_t *cb_data;
544 BT_DBG("service_function : %s (0x%x)",
545 _bt_convert_service_function_to_string(service_function),
548 cb_data = g_new0(bt_req_info_t, 1);
550 cb_data->service_function = service_function;
551 cb_data->cb = callback;
552 cb_data->user_data = user_data;
554 switch (service_type) {
555 case BT_BLUEZ_SERVICE:
556 case BT_OBEX_SERVICE:
557 proxy = __bt_gdbus_get_service_proxy();
560 return BLUETOOTH_ERROR_INTERNAL;
563 /* Do not timeout the request in certain cases. Sometime the
564 * request may take undeterministic time to reponse.
565 * (for ex: pairing retry) */
566 if (service_function == BT_BOND_DEVICE ||
567 service_function == BT_BOND_DEVICE_BY_TYPE)
570 timeout = BT_DBUS_TIMEOUT_MAX;
572 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
574 param1 = g_variant_new_from_data((const GVariantType *)"ay",
575 in_param1->data, in_param1->len,
577 param2 = g_variant_new_from_data((const GVariantType *)"ay",
578 in_param2->data, in_param2->len,
580 param3 = g_variant_new_from_data((const GVariantType *)"ay",
581 in_param3->data, in_param3->len,
583 param4 = g_variant_new_from_data((const GVariantType *)"ay",
584 in_param4->data, in_param4->len,
586 param5 = g_variant_new_from_data((const GVariantType *)"ay",
587 in_param5->data, in_param5->len,
590 g_dbus_proxy_call(proxy, "service_request",
591 g_variant_new("(iii@ay@ay@ay@ay@ay)",
592 service_type, service_function,
593 BT_ASYNC_REQ, param1, param2,
594 param3, param4, param5),
595 G_DBUS_CALL_FLAGS_NONE,
597 (GAsyncReadyCallback)__send_request_cb,
599 sending_requests = g_slist_append(sending_requests, cb_data);
601 g_array_free(in_param5, TRUE);
608 return BLUETOOTH_ERROR_NONE;