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 : %x", service_function);
87 switch (service_function) {
89 case BT_BOND_DEVICE_BY_TYPE:
90 *event_type = BT_ADAPTER_EVENT;
91 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
92 ret_if(output == NULL);
93 *param_data = &g_array_index(output,
94 bluetooth_device_info_t, 0);
96 case BT_UNBOND_DEVICE:
97 *event_type = BT_ADAPTER_EVENT;
98 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
99 ret_if(output == NULL);
100 *param_data = &g_array_index(output,
101 bluetooth_device_info_t, 0);
103 case BT_SEARCH_SERVICE:
104 *event_type = BT_ADAPTER_EVENT;
105 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
106 ret_if(output == NULL);
107 *param_data = &g_array_index(output,
108 bluetooth_device_info_t, 0);
111 *event_type = BT_HID_EVENT;
112 *event = BLUETOOTH_HID_CONNECTED;
113 ret_if(output == NULL);
114 *param_data = &g_array_index(output,
115 bluetooth_device_address_t, 0);
117 case BT_HID_DISCONNECT:
118 *event_type = BT_HID_EVENT;
119 *event = BLUETOOTH_HID_DISCONNECTED;
120 ret_if(output == NULL);
121 *param_data = &g_array_index(output,
122 bluetooth_device_address_t, 0);
124 case BT_AUDIO_CONNECT:
126 *event_type = BT_HEADSET_EVENT;
127 *event = BLUETOOTH_EVENT_AG_CONNECTED;
128 ret_if(output == NULL);
129 *param_data = &g_array_index(output, char, 0);
131 case BT_AUDIO_DISCONNECT:
132 case BT_AG_DISCONNECT:
133 *event_type = BT_HEADSET_EVENT;
134 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
135 ret_if(output == NULL);
136 *param_data = &g_array_index(output, char, 0);
139 *event_type = BT_HEADSET_EVENT;
140 *event = BLUETOOTH_EVENT_AV_CONNECTED;
141 ret_if(output == NULL);
142 *param_data = &g_array_index(output, char, 0);
144 case BT_AV_DISCONNECT:
145 *event_type = BT_HEADSET_EVENT;
146 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
147 ret_if(output == NULL);
148 *param_data = &g_array_index(output, char, 0);
150 case BT_AV_SOURCE_CONNECT:
151 *event_type = BT_A2DP_SOURCE_EVENT;
152 *event = BLUETOOTH_EVENT_AV_SOURCE_CONNECTED;
153 ret_if(output == NULL);
154 *param_data = &g_array_index(output, char, 0);
156 case BT_AV_SOURCE_DISCONNECT:
157 *event_type = BT_A2DP_SOURCE_EVENT;
158 *event = BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED;
159 ret_if(output == NULL);
160 *param_data = &g_array_index(output, char, 0);
163 *event_type = BT_HF_AGENT_EVENT;
164 *event = BLUETOOTH_EVENT_HF_CONNECTED;
165 ret_if(output == NULL);
166 *param_data = &g_array_index(output, char, 0);
168 case BT_HF_DISCONNECT:
169 *event_type = BT_HF_AGENT_EVENT;
170 *event = BLUETOOTH_EVENT_HF_DISCONNECTED;
171 ret_if(output == NULL);
172 *param_data = &g_array_index(output, char, 0);
174 case BT_NETWORK_CONNECT:
175 *event_type = BT_ADAPTER_EVENT;
176 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
177 ret_if(output == NULL);
178 *param_data = &g_array_index(output,
179 bluetooth_device_address_t, 0);
181 case BT_NETWORK_DISCONNECT:
182 *event_type = BT_ADAPTER_EVENT;
183 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
184 ret_if(output == NULL);
185 *param_data = &g_array_index(output,
186 bluetooth_device_address_t, 0);
188 case BT_RFCOMM_CLIENT_CONNECT:
189 *event_type = BT_RFCOMM_CLIENT_EVENT;
190 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
191 ret_if(output == NULL);
192 *param_data = &g_array_index(output,
193 bluetooth_rfcomm_connection_t, 0);
195 case BT_AVRCP_CONTROL_CONNECT:
196 *event_type = BT_AVRCP_CONTROL_EVENT;
197 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
198 ret_if(output == NULL);
199 *param_data = &g_array_index(output, char, 0);
201 case BT_AVRCP_CONTROL_DISCONNECT:
202 *event_type = BT_AVRCP_CONTROL_EVENT;
203 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
204 ret_if(output == NULL);
205 *param_data = &g_array_index(output, char, 0);
208 *event_type = BT_DEVICE_EVENT;
209 *event = BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED;
210 ret_if(output == NULL);
211 *param_data = &g_array_index(output,
212 bluetooth_device_address_t, 0);
215 *event_type = BT_DEVICE_EVENT;
216 *event = BLUETOOTH_EVENT_GATT_CONNECTED;
217 ret_if(output == NULL);
218 *param_data = &g_array_index(output,
219 bluetooth_device_address_t, 0);
221 case BT_DISCONNECT_LE:
222 *event_type = BT_DEVICE_EVENT;
223 *event = BLUETOOTH_EVENT_GATT_DISCONNECTED;
224 ret_if(output == NULL);
225 *param_data = &g_array_index(output,
226 bluetooth_device_address_t, 0);
229 BT_ERR("Unknown function");
235 out param1: API result
236 out param2: return paramter
239 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
244 size = g_variant_get_size(var);
246 data = (char *)g_variant_get_data(var);
248 param = g_array_append_vals(param, data, size);
253 static void __send_request_cb(GDBusProxy *proxy,
257 bluetooth_event_param_t bt_event;
258 bt_req_info_t *cb_data = user_data;
259 int result = BLUETOOTH_ERROR_NONE;
260 int event_type = BT_ADAPTER_EVENT;
262 GError *error = NULL;
266 GArray *out_param1 = NULL;
267 // GArray *out_param2 = NULL;
270 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
272 value = g_dbus_proxy_call_finish(proxy, res, &error);
275 /* dBUS gives error cause */
276 BT_ERR("D-Bus API failure: message[%s]",
278 g_clear_error(&error);
280 result = BLUETOOTH_ERROR_TIMEOUT;
282 ret_if(cb_data == NULL);
284 __bt_get_event_info(cb_data->service_function, NULL,
285 &bt_event.event, &event_type,
286 &bt_event.param_data);
288 g_variant_get(value, "(iv)", &result, ¶m1);
289 g_variant_unref(value);
292 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
293 __bt_fill_garray_from_variant(param1, out_param1);
294 g_variant_unref(param1);
298 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
299 // __bt_fill_garray_from_variant(param2, out_param2);
300 // result = g_array_index(out_param2, int, 0);
301 // g_variant_unref(param2);
302 // g_array_free(out_param2, TRUE);
304 // result = BLUETOOTH_ERROR_INTERNAL;
307 ret_if(cb_data == NULL);
309 __bt_get_event_info(cb_data->service_function, out_param1,
310 &bt_event.event, &event_type,
311 &bt_event.param_data);
313 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
314 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
315 request_id = g_array_index(out_param1, int, 0);
316 BT_DBG("request_id : %d", request_id);
317 _bt_add_push_request_id(request_id);
324 if (cb_data->cb == NULL)
327 /* Only if fail case, call the callback function*/
328 bt_event.result = result;
329 BT_INFO("event_type[%d], result=[%d]", event_type, result);
331 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
332 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
335 } else if (event_type == BT_HID_EVENT) {
336 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
337 (hid_event_param_t *)&bt_event,
339 } else if (event_type == BT_HEADSET_EVENT) {
340 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
341 (bt_audio_event_param_t *)&bt_event,
343 } else if (event_type == BT_HF_AGENT_EVENT) {
344 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
345 (bt_audio_event_param_t *)&bt_event,
347 } else if (event_type == BT_AVRCP_CONTROL_EVENT) {
348 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
349 (media_event_param_t *)&bt_event,
351 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
352 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
353 (bt_audio_event_param_t *)&bt_event,
355 } else if (event_type == BT_DEVICE_EVENT) {
356 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
360 BT_INFO("Not handled event type : %d", event_type);
364 g_array_free(out_param1, TRUE);
366 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
372 int _bt_sync_send_request(int service_type, int service_function,
373 GArray *in_param1, GArray *in_param2,
374 GArray *in_param3, GArray *in_param4,
377 int result = BLUETOOTH_ERROR_NONE;
378 GError *error = NULL;
379 GArray *in_param5 = NULL;
380 // GArray *out_param2 = NULL;
390 switch (service_type) {
391 case BT_BLUEZ_SERVICE:
392 case BT_OBEX_SERVICE:
393 case BT_AGENT_SERVICE:
394 case BT_CHECK_PRIVILEGE:
395 proxy = __bt_gdbus_get_service_proxy();
397 return BLUETOOTH_ERROR_INTERNAL;
399 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
403 param1 = g_variant_new_from_data((const GVariantType *)"ay",
404 in_param1->data, in_param1->len,
406 param2 = g_variant_new_from_data((const GVariantType *)"ay",
407 in_param2->data, in_param2->len,
409 param3 = g_variant_new_from_data((const GVariantType *)"ay",
410 in_param3->data, in_param3->len,
412 param4 = g_variant_new_from_data((const GVariantType *)"ay",
413 in_param4->data, in_param4->len,
415 param5 = g_variant_new_from_data((const GVariantType *)"ay",
416 in_param5->data, in_param5->len,
419 ret = g_dbus_proxy_call_sync(proxy, "service_request",
420 g_variant_new("(iii@ay@ay@ay@ay@ay)",
421 service_type, service_function,
425 G_DBUS_CALL_FLAGS_NONE, -1,
428 g_array_free(in_param5, TRUE);
431 /* dBUS-RPC is failed */
432 BT_ERR("dBUS-RPC is failed");
435 /* dBUS gives error cause */
436 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
437 error->code, error->message);
439 g_clear_error(&error);
441 /* dBUS does not give error cause dBUS-RPC is failed */
442 BT_ERR("error returned was NULL");
445 return BLUETOOTH_ERROR_INTERNAL;
451 g_variant_get(ret, "(iv)", &result, ¶m1);
454 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
455 __bt_fill_garray_from_variant(param1, *out_param1);
456 g_variant_unref(param1);
460 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
461 // __bt_fill_garray_from_variant(param2, out_param2);
462 // result = g_array_index(out_param2, int, 0);
463 // g_variant_unref(param2);
464 // g_array_free(out_param2, TRUE);
466 // result = BLUETOOTH_ERROR_INTERNAL;
469 g_variant_unref(ret);
472 BT_ERR("Unknown service type");
473 return BLUETOOTH_ERROR_INTERNAL;
479 int _bt_async_send_request(int service_type, int service_function,
480 GArray *in_param1, GArray *in_param2,
481 GArray *in_param3, GArray *in_param4,
482 void *callback, void *user_data)
484 GArray* in_param5 = NULL;
485 bt_req_info_t *cb_data;
495 BT_DBG("service_function : %x", service_function);
497 cb_data = g_new0(bt_req_info_t, 1);
499 cb_data->service_function = service_function;
500 cb_data->cb = callback;
501 cb_data->user_data = user_data;
503 switch (service_type) {
504 case BT_BLUEZ_SERVICE:
505 case BT_OBEX_SERVICE:
506 proxy = __bt_gdbus_get_service_proxy();
509 return BLUETOOTH_ERROR_INTERNAL;
512 /* Do not timeout the request in certain cases. Sometime the
513 * request may take undeterministic time to reponse.
514 * (for ex: pairing retry) */
515 if (service_function == BT_BOND_DEVICE ||
516 service_function == BT_BOND_DEVICE_BY_TYPE)
519 timeout = BT_DBUS_TIMEOUT_MAX;
521 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
523 param1 = g_variant_new_from_data((const GVariantType *)"ay",
524 in_param1->data, in_param1->len,
526 param2 = g_variant_new_from_data((const GVariantType *)"ay",
527 in_param2->data, in_param2->len,
529 param3 = g_variant_new_from_data((const GVariantType *)"ay",
530 in_param3->data, in_param3->len,
532 param4 = g_variant_new_from_data((const GVariantType *)"ay",
533 in_param4->data, in_param4->len,
535 param5 = g_variant_new_from_data((const GVariantType *)"ay",
536 in_param5->data, in_param5->len,
539 g_dbus_proxy_call(proxy, "service_request",
540 g_variant_new("(iii@ay@ay@ay@ay@ay)",
541 service_type, service_function,
542 BT_ASYNC_REQ, param1, param2,
543 param3, param4, param5),
544 G_DBUS_CALL_FLAGS_NONE,
546 (GAsyncReadyCallback)__send_request_cb,
548 sending_requests = g_slist_append(sending_requests, cb_data);
550 g_array_free(in_param5, TRUE);
557 return BLUETOOTH_ERROR_NONE;