4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
28 #include "bluetooth-api.h"
29 #include "bluetooth-hid-api.h"
30 #include "bluetooth-audio-api.h"
31 #include "bt-internal-types.h"
32 #include "bluetooth-ipsp-api.h"
34 #include "bt-common.h"
35 #include "bt-request-sender.h"
36 #include "bt-event-handler.h"
37 #include "bluetooth-media-control.h"
39 /* auto generated header by bt-request-service.xml*/
40 #include "bt-request-service.h"
42 static GSList *sending_requests;
44 static GDBusProxy *service_gproxy;
46 static GDBusProxy *__bt_gdbus_init_service_proxy(void)
48 GDBusConnection *service_gconn;
54 service_gconn = _bt_gdbus_get_system_gconn();
59 proxy = g_dbus_proxy_new_sync(service_gconn,
60 G_DBUS_PROXY_FLAGS_NONE, NULL,
67 BT_ERR("Unable to create proxy: %s", err->message);
74 service_gproxy = proxy;
79 static GDBusProxy *__bt_gdbus_get_service_proxy(void)
81 return (service_gproxy) ? service_gproxy : __bt_gdbus_init_service_proxy();
84 void _bt_gdbus_deinit_proxys(void)
87 g_object_unref(service_gproxy);
88 service_gproxy = NULL;
92 static void __bt_get_event_info(int service_function, GArray *output,
93 int *event, int *event_type, void **param_data)
95 ret_if(event == NULL);
97 BT_DBG("service_function : %x", service_function);
98 switch (service_function) {
100 case BT_BOND_DEVICE_BY_TYPE:
101 *event_type = BT_ADAPTER_EVENT;
102 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
103 ret_if(output == NULL);
104 *param_data = &g_array_index(output,
105 bluetooth_device_info_t, 0);
107 case BT_UNBOND_DEVICE:
108 *event_type = BT_ADAPTER_EVENT;
109 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
110 ret_if(output == NULL);
111 *param_data = &g_array_index(output,
112 bluetooth_device_info_t, 0);
114 case BT_SEARCH_SERVICE:
115 *event_type = BT_ADAPTER_EVENT;
116 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
117 ret_if(output == NULL);
118 *param_data = &g_array_index(output,
119 bluetooth_device_info_t, 0);
122 *event_type = BT_HID_EVENT;
123 *event = BLUETOOTH_HID_CONNECTED;
124 ret_if(output == NULL);
125 *param_data = &g_array_index(output,
126 bluetooth_device_address_t, 0);
128 case BT_HID_DISCONNECT:
129 *event_type = BT_HID_EVENT;
130 *event = BLUETOOTH_HID_DISCONNECTED;
131 ret_if(output == NULL);
132 *param_data = &g_array_index(output,
133 bluetooth_device_address_t, 0);
135 case BT_AUDIO_CONNECT:
137 *event_type = BT_HEADSET_EVENT;
138 *event = BLUETOOTH_EVENT_AG_CONNECTED;
139 ret_if(output == NULL);
140 *param_data = &g_array_index(output, char, 0);
142 case BT_AUDIO_DISCONNECT:
143 case BT_AG_DISCONNECT:
144 *event_type = BT_HEADSET_EVENT;
145 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
146 ret_if(output == NULL);
147 *param_data = &g_array_index(output, char, 0);
150 *event_type = BT_HEADSET_EVENT;
151 *event = BLUETOOTH_EVENT_AV_CONNECTED;
152 ret_if(output == NULL);
153 *param_data = &g_array_index(output, char, 0);
155 case BT_AV_DISCONNECT:
156 *event_type = BT_HEADSET_EVENT;
157 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
158 ret_if(output == NULL);
159 *param_data = &g_array_index(output, char, 0);
161 case BT_AV_SOURCE_CONNECT:
162 *event_type = BT_A2DP_SOURCE_EVENT;
163 *event = BLUETOOTH_EVENT_AV_SOURCE_CONNECTED;
164 ret_if(output == NULL);
165 *param_data = &g_array_index(output, char, 0);
167 case BT_AV_SOURCE_DISCONNECT:
168 *event_type = BT_A2DP_SOURCE_EVENT;
169 *event = BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED;
170 ret_if (output == NULL);
171 *param_data = &g_array_index (output, char, 0);
174 *event_type = BT_HF_AGENT_EVENT;
175 *event = BLUETOOTH_EVENT_HF_CONNECTED;
176 ret_if(output == NULL);
177 *param_data = &g_array_index(output, char, 0);
179 case BT_HF_DISCONNECT:
180 *event_type = BT_HF_AGENT_EVENT;
181 *event = BLUETOOTH_EVENT_HF_DISCONNECTED;
182 ret_if(output == NULL);
183 *param_data = &g_array_index(output, char, 0);
185 case BT_NETWORK_CONNECT:
186 *event_type = BT_ADAPTER_EVENT;
187 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
188 ret_if(output == NULL);
189 *param_data = &g_array_index(output,
190 bluetooth_device_address_t, 0);
192 case BT_NETWORK_DISCONNECT:
193 *event_type = BT_ADAPTER_EVENT;
194 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
195 ret_if(output == NULL);
196 *param_data = &g_array_index(output,
197 bluetooth_device_address_t, 0);
199 case BT_RFCOMM_CLIENT_CONNECT:
200 *event_type = BT_RFCOMM_CLIENT_EVENT;
201 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
202 ret_if(output == NULL);
203 *param_data = &g_array_index(output,
204 bluetooth_rfcomm_connection_t, 0);
206 case BT_AVRCP_CONTROL_CONNECT:
207 *event_type = BT_AVRCP_CONTROL_EVENT;
208 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
209 ret_if(output == NULL);
210 *param_data = &g_array_index(output, char, 0);
212 case BT_AVRCP_CONTROL_DISCONNECT:
213 *event_type = BT_AVRCP_CONTROL_EVENT;
214 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
215 ret_if(output == NULL);
216 *param_data = &g_array_index(output, char, 0);
219 *event_type = BT_DEVICE_EVENT;
220 *event = BLUETOOTH_EVENT_GATT_CONNECTED;
221 ret_if(output == NULL);
222 *param_data = &g_array_index(output,
223 bluetooth_device_address_t, 0);
225 case BT_DISCONNECT_LE:
226 *event_type = BT_DEVICE_EVENT;
227 *event = BLUETOOTH_EVENT_GATT_DISCONNECTED;
228 ret_if(output == NULL);
229 *param_data = &g_array_index(output,
230 bluetooth_device_address_t, 0);
233 BT_ERR("Unknown function");
239 out param1: API result
240 out param2: return paramter
243 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
248 size = g_variant_get_size(var);
250 data = (char *)g_variant_get_data(var);
252 param = g_array_append_vals(param, data, size);
257 static void __send_request_cb(GDBusProxy *proxy,
261 bluetooth_event_param_t bt_event;
262 bt_req_info_t *cb_data = user_data;
263 int result = BLUETOOTH_ERROR_NONE;
264 int event_type = BT_ADAPTER_EVENT;
266 GError *error = NULL;
270 GArray *out_param1 = NULL;
271 // GArray *out_param2 = NULL;
274 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
276 value = g_dbus_proxy_call_finish(proxy, res, &error);
279 /* dBUS gives error cause */
280 BT_ERR("D-Bus API failure: message[%s]",
282 g_clear_error(&error);
284 result = BLUETOOTH_ERROR_TIMEOUT;
286 ret_if(cb_data == NULL);
288 __bt_get_event_info(cb_data->service_function, NULL,
289 &bt_event.event, &event_type,
290 &bt_event.param_data);
292 g_variant_get(value, "(iv)", &result, ¶m1);
293 g_variant_unref(value);
296 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
297 __bt_fill_garray_from_variant(param1, out_param1);
298 g_variant_unref(param1);
302 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
303 // __bt_fill_garray_from_variant(param2, out_param2);
304 // result = g_array_index(out_param2, int, 0);
305 // g_variant_unref(param2);
306 // g_array_free(out_param2, TRUE);
308 // result = BLUETOOTH_ERROR_INTERNAL;
311 ret_if(cb_data == NULL);
313 __bt_get_event_info(cb_data->service_function, out_param1,
314 &bt_event.event, &event_type,
315 &bt_event.param_data);
317 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
318 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
319 request_id = g_array_index(out_param1, int, 0);
320 BT_DBG("request_id : %d", request_id);
321 _bt_add_push_request_id(request_id);
329 if (cb_data->cb == NULL)
332 /* Only if fail case, call the callback function*/
333 bt_event.result = result;
334 BT_INFO("event_type[%d], result=[%d]", event_type, result);
336 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
337 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
340 } else if (event_type == BT_HID_EVENT) {
341 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
342 (hid_event_param_t *)&bt_event,
344 } else if (event_type == BT_HEADSET_EVENT) {
345 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
346 (bt_audio_event_param_t *)&bt_event,
348 } else if (event_type == BT_HF_AGENT_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_AVRCP_CONTROL_EVENT) {
353 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
354 (media_event_param_t *)&bt_event,
356 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
357 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
358 (bt_audio_event_param_t *)&bt_event,
360 } else if (event_type == BT_DEVICE_EVENT) {
361 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
365 BT_INFO("Not handled event type : %d", event_type);
369 g_array_free(out_param1, TRUE);
371 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
377 int _bt_sync_send_request(int service_type, int service_function,
378 GArray *in_param1, GArray *in_param2,
379 GArray *in_param3, GArray *in_param4,
382 int result = BLUETOOTH_ERROR_NONE;
383 GError *error = NULL;
384 GArray *in_param5 = NULL;
385 // GArray *out_param2 = NULL;
395 switch (service_type) {
396 case BT_BLUEZ_SERVICE:
397 case BT_OBEX_SERVICE:
398 case BT_AGENT_SERVICE:
399 case BT_CHECK_PRIVILEGE:
400 proxy = __bt_gdbus_get_service_proxy();
402 return BLUETOOTH_ERROR_INTERNAL;
404 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
408 param1 = g_variant_new_from_data((const GVariantType *)"ay",
409 in_param1->data, in_param1->len,
411 param2 = g_variant_new_from_data((const GVariantType *)"ay",
412 in_param2->data, in_param2->len,
414 param3 = g_variant_new_from_data((const GVariantType *)"ay",
415 in_param3->data, in_param3->len,
417 param4 = g_variant_new_from_data((const GVariantType *)"ay",
418 in_param4->data, in_param4->len,
420 param5 = g_variant_new_from_data((const GVariantType *)"ay",
421 in_param5->data, in_param5->len,
424 ret = g_dbus_proxy_call_sync(proxy, "service_request",
425 g_variant_new("(iii@ay@ay@ay@ay@ay)",
426 service_type, service_function,
430 G_DBUS_CALL_FLAGS_NONE, -1,
433 g_array_free(in_param5, TRUE);
436 /* dBUS-RPC is failed */
437 BT_ERR("dBUS-RPC is failed");
440 /* dBUS gives error cause */
441 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
442 error->code, error->message);
444 g_clear_error(&error);
446 /* dBUS does not give error cause dBUS-RPC is failed */
447 BT_ERR("error returned was NULL");
450 return BLUETOOTH_ERROR_INTERNAL;
456 g_variant_get(ret, "(iv)", &result, ¶m1);
459 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
460 __bt_fill_garray_from_variant(param1, *out_param1);
461 g_variant_unref(param1);
465 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
466 // __bt_fill_garray_from_variant(param2, out_param2);
467 // result = g_array_index(out_param2, int, 0);
468 // g_variant_unref(param2);
469 // g_array_free(out_param2, TRUE);
471 // result = BLUETOOTH_ERROR_INTERNAL;
474 g_variant_unref(ret);
477 BT_ERR("Unknown service type");
478 return BLUETOOTH_ERROR_INTERNAL;
484 int _bt_async_send_request(int service_type, int service_function,
485 GArray *in_param1, GArray *in_param2,
486 GArray *in_param3, GArray *in_param4,
487 void *callback, void *user_data)
489 GArray* in_param5 = NULL;
490 bt_req_info_t *cb_data;
500 BT_DBG("service_function : %x", service_function);
502 cb_data = g_new0(bt_req_info_t, 1);
504 cb_data->service_function = service_function;
505 cb_data->cb = callback;
506 cb_data->user_data = user_data;
508 switch (service_type) {
509 case BT_BLUEZ_SERVICE:
510 case BT_OBEX_SERVICE:
511 proxy = __bt_gdbus_get_service_proxy();
514 return BLUETOOTH_ERROR_INTERNAL;
517 /* Do not timeout the request in certain cases. Sometime the
518 * request may take undeterministic time to reponse.
519 * (for ex: pairing retry) */
520 if (service_function == BT_BOND_DEVICE ||
521 service_function == BT_BOND_DEVICE_BY_TYPE)
524 timeout = BT_DBUS_TIMEOUT_MAX;
526 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
528 param1 = g_variant_new_from_data((const GVariantType *)"ay",
529 in_param1->data, in_param1->len,
531 param2 = g_variant_new_from_data((const GVariantType *)"ay",
532 in_param2->data, in_param2->len,
534 param3 = g_variant_new_from_data((const GVariantType *)"ay",
535 in_param3->data, in_param3->len,
537 param4 = g_variant_new_from_data((const GVariantType *)"ay",
538 in_param4->data, in_param4->len,
540 param5 = g_variant_new_from_data((const GVariantType *)"ay",
541 in_param5->data, in_param5->len,
544 g_dbus_proxy_call(proxy, "service_request",
545 g_variant_new("(iii@ay@ay@ay@ay@ay)",
546 service_type, service_function,
547 BT_ASYNC_REQ, param1, param2,
548 param3, param4, param5),
549 G_DBUS_CALL_FLAGS_NONE,
551 (GAsyncReadyCallback)__send_request_cb,
553 sending_requests = g_slist_append(sending_requests, cb_data);
555 g_array_free(in_param5, TRUE);
559 return BLUETOOTH_ERROR_NONE;