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 /* auto generated header by bt-request-service.xml*/
34 #include "bt-request-service.h"
36 static GSList *sending_requests;
38 static GDBusProxy *service_gproxy;
40 static GDBusProxy *__bt_gdbus_init_service_proxy(void)
42 GDBusConnection *service_gconn;
46 service_gconn = _bt_gdbus_get_system_gconn();
51 proxy = g_dbus_proxy_new_sync(service_gconn,
52 G_DBUS_PROXY_FLAGS_NONE, NULL,
59 BT_ERR("Unable to create proxy: %s", err->message);
66 service_gproxy = proxy;
71 static GDBusProxy *__bt_gdbus_get_service_proxy(void)
73 return (service_gproxy) ? service_gproxy : __bt_gdbus_init_service_proxy();
76 void _bt_gdbus_deinit_proxys(void)
79 g_object_unref(service_gproxy);
80 service_gproxy = NULL;
84 static void __bt_get_event_info(int service_function, GArray *output,
85 int *event, int *event_type, void **param_data)
87 ret_if(event == NULL);
89 BT_DBG("service_function : %x", service_function);
90 switch (service_function) {
92 case BT_BOND_DEVICE_BY_TYPE:
93 *event_type = BT_ADAPTER_EVENT;
94 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
95 ret_if(output == NULL);
96 *param_data = &g_array_index(output,
97 bluetooth_device_info_t, 0);
99 case BT_UNBOND_DEVICE:
100 *event_type = BT_ADAPTER_EVENT;
101 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
102 ret_if(output == NULL);
103 *param_data = &g_array_index(output,
104 bluetooth_device_info_t, 0);
106 case BT_SEARCH_SERVICE:
107 *event_type = BT_ADAPTER_EVENT;
108 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
109 ret_if(output == NULL);
110 *param_data = &g_array_index(output,
111 bluetooth_device_info_t, 0);
114 *event_type = BT_HID_EVENT;
115 *event = BLUETOOTH_HID_CONNECTED;
116 ret_if(output == NULL);
117 *param_data = &g_array_index(output,
118 bluetooth_device_address_t, 0);
120 case BT_HID_DISCONNECT:
121 *event_type = BT_HID_EVENT;
122 *event = BLUETOOTH_HID_DISCONNECTED;
123 ret_if(output == NULL);
124 *param_data = &g_array_index(output,
125 bluetooth_device_address_t, 0);
127 case BT_AUDIO_CONNECT:
129 *event_type = BT_HEADSET_EVENT;
130 *event = BLUETOOTH_EVENT_AG_CONNECTED;
131 ret_if(output == NULL);
132 *param_data = &g_array_index(output, char, 0);
134 case BT_AUDIO_DISCONNECT:
135 case BT_AG_DISCONNECT:
136 *event_type = BT_HEADSET_EVENT;
137 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
138 ret_if(output == NULL);
139 *param_data = &g_array_index(output, char, 0);
142 *event_type = BT_HEADSET_EVENT;
143 *event = BLUETOOTH_EVENT_AV_CONNECTED;
144 ret_if(output == NULL);
145 *param_data = &g_array_index(output, char, 0);
147 case BT_AV_DISCONNECT:
148 *event_type = BT_HEADSET_EVENT;
149 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
150 ret_if(output == NULL);
151 *param_data = &g_array_index(output, char, 0);
153 case BT_AV_SOURCE_CONNECT:
154 *event_type = BT_A2DP_SOURCE_EVENT;
155 *event = BLUETOOTH_EVENT_AV_SOURCE_CONNECTED;
156 ret_if(output == NULL);
157 *param_data = &g_array_index(output, char, 0);
159 case BT_AV_SOURCE_DISCONNECT:
160 *event_type = BT_A2DP_SOURCE_EVENT;
161 *event = BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED;
162 ret_if (output == NULL);
163 *param_data = &g_array_index (output, char, 0);
166 *event_type = BT_HF_AGENT_EVENT;
167 *event = BLUETOOTH_EVENT_HF_CONNECTED;
168 ret_if(output == NULL);
169 *param_data = &g_array_index(output, char, 0);
171 case BT_HF_DISCONNECT:
172 *event_type = BT_HF_AGENT_EVENT;
173 *event = BLUETOOTH_EVENT_HF_DISCONNECTED;
174 ret_if(output == NULL);
175 *param_data = &g_array_index(output, char, 0);
177 case BT_NETWORK_CONNECT:
178 *event_type = BT_ADAPTER_EVENT;
179 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
180 ret_if(output == NULL);
181 *param_data = &g_array_index(output,
182 bluetooth_device_address_t, 0);
184 case BT_NETWORK_DISCONNECT:
185 *event_type = BT_ADAPTER_EVENT;
186 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
187 ret_if(output == NULL);
188 *param_data = &g_array_index(output,
189 bluetooth_device_address_t, 0);
191 case BT_RFCOMM_CLIENT_CONNECT:
192 *event_type = BT_RFCOMM_CLIENT_EVENT;
193 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
194 ret_if(output == NULL);
195 *param_data = &g_array_index(output,
196 bluetooth_rfcomm_connection_t, 0);
198 case BT_AVRCP_CONTROL_CONNECT:
199 *event_type = BT_AVRCP_CONTROL_EVENT;
200 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
201 ret_if(output == NULL);
202 *param_data = &g_array_index(output, char, 0);
204 case BT_AVRCP_CONTROL_DISCONNECT:
205 *event_type = BT_AVRCP_CONTROL_EVENT;
206 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
207 ret_if(output == NULL);
208 *param_data = &g_array_index(output, char, 0);
211 *event_type = BT_DEVICE_EVENT;
212 *event = BLUETOOTH_EVENT_GATT_CONNECTED;
213 ret_if(output == NULL);
214 *param_data = &g_array_index(output,
215 bluetooth_device_address_t, 0);
217 case BT_DISCONNECT_LE:
218 *event_type = BT_DEVICE_EVENT;
219 *event = BLUETOOTH_EVENT_GATT_DISCONNECTED;
220 ret_if(output == NULL);
221 *param_data = &g_array_index(output,
222 bluetooth_device_address_t, 0);
225 BT_ERR("Unknown function");
231 out param1: API result
232 out param2: return paramter
235 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
240 size = g_variant_get_size(var);
242 data = (char *)g_variant_get_data(var);
244 param = g_array_append_vals(param, data, size);
249 static void __send_request_cb(GDBusProxy *proxy,
253 bluetooth_event_param_t bt_event;
254 bt_req_info_t *cb_data = user_data;
255 int result = BLUETOOTH_ERROR_NONE;
256 int event_type = BT_ADAPTER_EVENT;
258 GError *error = NULL;
262 GArray *out_param1 = NULL;
263 // GArray *out_param2 = NULL;
266 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
268 value = g_dbus_proxy_call_finish(proxy, res, &error);
271 /* dBUS gives error cause */
272 BT_ERR("D-Bus API failure: message[%s]",
274 g_clear_error(&error);
276 result = BLUETOOTH_ERROR_TIMEOUT;
278 ret_if(cb_data == NULL);
280 __bt_get_event_info(cb_data->service_function, NULL,
281 &bt_event.event, &event_type,
282 &bt_event.param_data);
284 g_variant_get(value, "(iv)", &result, ¶m1);
285 g_variant_unref(value);
288 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
289 __bt_fill_garray_from_variant(param1, out_param1);
290 g_variant_unref(param1);
294 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
295 // __bt_fill_garray_from_variant(param2, out_param2);
296 // result = g_array_index(out_param2, int, 0);
297 // g_variant_unref(param2);
298 // g_array_free(out_param2, TRUE);
300 // result = BLUETOOTH_ERROR_INTERNAL;
303 ret_if(cb_data == NULL);
305 __bt_get_event_info(cb_data->service_function, out_param1,
306 &bt_event.event, &event_type,
307 &bt_event.param_data);
309 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
310 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
311 request_id = g_array_index(out_param1, int, 0);
312 BT_DBG("request_id : %d", request_id);
313 _bt_add_push_request_id(request_id);
321 if (cb_data->cb == NULL)
324 /* Only if fail case, call the callback function*/
325 bt_event.result = result;
326 BT_INFO("event_type[%d], result=[%d]", event_type, result);
328 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
329 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
332 } else if (event_type == BT_HID_EVENT) {
333 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
334 (hid_event_param_t *)&bt_event,
336 } else if (event_type == BT_HEADSET_EVENT) {
337 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
338 (bt_audio_event_param_t *)&bt_event,
340 } else if (event_type == BT_HF_AGENT_EVENT) {
341 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
342 (bt_audio_event_param_t *)&bt_event,
344 } else if (event_type == BT_AVRCP_CONTROL_EVENT) {
345 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
346 (media_event_param_t *)&bt_event,
348 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
349 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
350 (bt_audio_event_param_t *)&bt_event,
352 } else if (event_type == BT_DEVICE_EVENT) {
353 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
357 BT_INFO("Not handled event type : %d", event_type);
361 g_array_free(out_param1, TRUE);
363 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
369 int _bt_sync_send_request(int service_type, int service_function,
370 GArray *in_param1, GArray *in_param2,
371 GArray *in_param3, GArray *in_param4,
374 int result = BLUETOOTH_ERROR_NONE;
375 GError *error = NULL;
376 GArray *in_param5 = NULL;
377 // GArray *out_param2 = NULL;
387 switch (service_type) {
388 case BT_BLUEZ_SERVICE:
389 case BT_OBEX_SERVICE:
390 case BT_AGENT_SERVICE:
391 case BT_CHECK_PRIVILEGE:
392 proxy = __bt_gdbus_get_service_proxy();
394 return BLUETOOTH_ERROR_INTERNAL;
396 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
400 param1 = g_variant_new_from_data((const GVariantType *)"ay",
401 in_param1->data, in_param1->len,
403 param2 = g_variant_new_from_data((const GVariantType *)"ay",
404 in_param2->data, in_param2->len,
406 param3 = g_variant_new_from_data((const GVariantType *)"ay",
407 in_param3->data, in_param3->len,
409 param4 = g_variant_new_from_data((const GVariantType *)"ay",
410 in_param4->data, in_param4->len,
412 param5 = g_variant_new_from_data((const GVariantType *)"ay",
413 in_param5->data, in_param5->len,
416 ret = g_dbus_proxy_call_sync(proxy, "service_request",
417 g_variant_new("(iii@ay@ay@ay@ay@ay)",
418 service_type, service_function,
422 G_DBUS_CALL_FLAGS_NONE, -1,
425 g_array_free(in_param5, TRUE);
428 /* dBUS-RPC is failed */
429 BT_ERR("dBUS-RPC is failed");
432 /* dBUS gives error cause */
433 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
434 error->code, error->message);
436 g_clear_error(&error);
438 /* dBUS does not give error cause dBUS-RPC is failed */
439 BT_ERR("error returned was NULL");
442 return BLUETOOTH_ERROR_INTERNAL;
448 g_variant_get(ret, "(iv)", &result, ¶m1);
451 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
452 __bt_fill_garray_from_variant(param1, *out_param1);
453 g_variant_unref(param1);
457 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
458 // __bt_fill_garray_from_variant(param2, out_param2);
459 // result = g_array_index(out_param2, int, 0);
460 // g_variant_unref(param2);
461 // g_array_free(out_param2, TRUE);
463 // result = BLUETOOTH_ERROR_INTERNAL;
466 g_variant_unref(ret);
469 BT_ERR("Unknown service type");
470 return BLUETOOTH_ERROR_INTERNAL;
476 int _bt_async_send_request(int service_type, int service_function,
477 GArray *in_param1, GArray *in_param2,
478 GArray *in_param3, GArray *in_param4,
479 void *callback, void *user_data)
481 GArray* in_param5 = NULL;
482 bt_req_info_t *cb_data;
492 BT_DBG("service_function : %x", service_function);
494 cb_data = g_new0(bt_req_info_t, 1);
496 cb_data->service_function = service_function;
497 cb_data->cb = callback;
498 cb_data->user_data = user_data;
500 switch (service_type) {
501 case BT_BLUEZ_SERVICE:
502 case BT_OBEX_SERVICE:
503 proxy = __bt_gdbus_get_service_proxy();
506 return BLUETOOTH_ERROR_INTERNAL;
509 /* Do not timeout the request in certain cases. Sometime the
510 * request may take undeterministic time to reponse.
511 * (for ex: pairing retry) */
512 if (service_function == BT_BOND_DEVICE ||
513 service_function == BT_BOND_DEVICE_BY_TYPE)
516 timeout = BT_DBUS_TIMEOUT_MAX;
518 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
520 param1 = g_variant_new_from_data((const GVariantType *)"ay",
521 in_param1->data, in_param1->len,
523 param2 = g_variant_new_from_data((const GVariantType *)"ay",
524 in_param2->data, in_param2->len,
526 param3 = g_variant_new_from_data((const GVariantType *)"ay",
527 in_param3->data, in_param3->len,
529 param4 = g_variant_new_from_data((const GVariantType *)"ay",
530 in_param4->data, in_param4->len,
532 param5 = g_variant_new_from_data((const GVariantType *)"ay",
533 in_param5->data, in_param5->len,
536 g_dbus_proxy_call(proxy, "service_request",
537 g_variant_new("(iii@ay@ay@ay@ay@ay)",
538 service_type, service_function,
539 BT_ASYNC_REQ, param1, param2,
540 param3, param4, param5),
541 G_DBUS_CALL_FLAGS_NONE,
543 (GAsyncReadyCallback)__send_request_cb,
545 sending_requests = g_slist_append(sending_requests, cb_data);
547 g_array_free(in_param5, TRUE);
551 return BLUETOOTH_ERROR_NONE;