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.
24 #include <dbus/dbus-glib.h>
29 #include "bluetooth-api.h"
30 #include "bluetooth-hid-api.h"
31 #include "bluetooth-audio-api.h"
32 #include "bt-internal-types.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 DBusGConnection *service_conn;
45 DBusGConnection *system_conn;
46 DBusGProxy *service_proxy;
48 static GDBusConnection *service_gconn;
49 static GDBusProxy *service_gproxy;
51 static GDBusProxy *__bt_gdbus_init_service_proxy(void)
58 if (service_gconn == NULL)
59 service_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
63 BT_ERR("Unable to connect to dbus: %s", err->message);
69 proxy = g_dbus_proxy_new_sync(service_gconn,
70 G_DBUS_PROXY_FLAGS_NONE, NULL,
77 BT_ERR("Unable to create proxy: %s", err->message);
81 g_object_unref(service_gconn);
86 service_gproxy = proxy;
91 static GDBusProxy *__bt_gdbus_get_service_proxy(void)
93 return (service_gproxy) ? service_gproxy : __bt_gdbus_init_service_proxy();
96 void _bt_gdbus_deinit_proxys(void)
99 g_object_unref(service_proxy);
100 service_proxy = NULL;
104 g_object_unref(service_gconn);
105 service_gconn = NULL;
109 static void __bt_get_event_info(int service_function, GArray *output,
110 int *event, int *event_type, void **param_data)
112 ret_if(event == NULL);
114 BT_DBG("service_function : %x", service_function);
115 switch (service_function) {
117 case BT_BOND_DEVICE_BY_TYPE:
118 *event_type = BT_ADAPTER_EVENT;
119 *event = BLUETOOTH_EVENT_BONDING_FINISHED;
120 ret_if(output == NULL);
121 *param_data = &g_array_index(output,
122 bluetooth_device_info_t, 0);
124 case BT_UNBOND_DEVICE:
125 *event_type = BT_ADAPTER_EVENT;
126 *event = BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED;
127 ret_if(output == NULL);
128 *param_data = &g_array_index(output,
129 bluetooth_device_info_t, 0);
131 case BT_SEARCH_SERVICE:
132 *event_type = BT_ADAPTER_EVENT;
133 *event = BLUETOOTH_EVENT_SERVICE_SEARCHED;
134 ret_if(output == NULL);
135 *param_data = &g_array_index(output,
136 bluetooth_device_info_t, 0);
139 *event_type = BT_HID_EVENT;
140 *event = BLUETOOTH_HID_CONNECTED;
141 ret_if(output == NULL);
142 *param_data = &g_array_index(output,
143 bluetooth_device_address_t, 0);
145 case BT_HID_DISCONNECT:
146 *event_type = BT_HID_EVENT;
147 *event = BLUETOOTH_HID_DISCONNECTED;
148 ret_if(output == NULL);
149 *param_data = &g_array_index(output,
150 bluetooth_device_address_t, 0);
152 case BT_AUDIO_CONNECT:
154 *event_type = BT_HEADSET_EVENT;
155 *event = BLUETOOTH_EVENT_AG_CONNECTED;
156 ret_if(output == NULL);
157 *param_data = &g_array_index(output, char, 0);
159 case BT_AUDIO_DISCONNECT:
160 case BT_AG_DISCONNECT:
161 *event_type = BT_HEADSET_EVENT;
162 *event = BLUETOOTH_EVENT_AG_DISCONNECTED;
163 ret_if(output == NULL);
164 *param_data = &g_array_index(output, char, 0);
167 *event_type = BT_HEADSET_EVENT;
168 *event = BLUETOOTH_EVENT_AV_CONNECTED;
169 ret_if(output == NULL);
170 *param_data = &g_array_index(output, char, 0);
172 case BT_AV_DISCONNECT:
173 *event_type = BT_HEADSET_EVENT;
174 *event = BLUETOOTH_EVENT_AV_DISCONNECTED;
175 ret_if(output == NULL);
176 *param_data = &g_array_index(output, char, 0);
178 case BT_AV_SOURCE_CONNECT:
179 *event_type = BT_A2DP_SOURCE_EVENT;
180 *event = BLUETOOTH_EVENT_AV_SOURCE_CONNECTED;
181 ret_if(output == NULL);
182 *param_data = &g_array_index(output, char, 0);
184 case BT_AV_SOURCE_DISCONNECT:
185 *event_type = BT_A2DP_SOURCE_EVENT;
186 *event = BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED;
187 ret_if (output == NULL);
188 *param_data = &g_array_index (output, char, 0);
191 *event_type = BT_HF_AGENT_EVENT;
192 *event = BLUETOOTH_EVENT_HF_CONNECTED;
193 ret_if(output == NULL);
194 *param_data = &g_array_index(output, char, 0);
196 case BT_HF_DISCONNECT:
197 *event_type = BT_HF_AGENT_EVENT;
198 *event = BLUETOOTH_EVENT_HF_DISCONNECTED;
199 ret_if(output == NULL);
200 *param_data = &g_array_index(output, char, 0);
202 case BT_NETWORK_CONNECT:
203 *event_type = BT_ADAPTER_EVENT;
204 *event = BLUETOOTH_EVENT_NETWORK_CONNECTED;
205 ret_if(output == NULL);
206 *param_data = &g_array_index(output,
207 bluetooth_device_address_t, 0);
209 case BT_NETWORK_DISCONNECT:
210 *event_type = BT_ADAPTER_EVENT;
211 *event = BLUETOOTH_EVENT_NETWORK_DISCONNECTED;
212 ret_if(output == NULL);
213 *param_data = &g_array_index(output,
214 bluetooth_device_address_t, 0);
216 case BT_RFCOMM_CLIENT_CONNECT:
217 *event_type = BT_RFCOMM_CLIENT_EVENT;
218 *event = BLUETOOTH_EVENT_RFCOMM_CONNECTED;
219 ret_if(output == NULL);
220 *param_data = &g_array_index(output,
221 bluetooth_rfcomm_connection_t, 0);
223 case BT_AVRCP_CONTROL_CONNECT:
224 *event_type = BT_AVRCP_CONTROL_EVENT;
225 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
226 ret_if(output == NULL);
227 *param_data = &g_array_index(output, char, 0);
229 case BT_AVRCP_CONTROL_DISCONNECT:
230 *event_type = BT_AVRCP_CONTROL_EVENT;
231 *event = BLUETOOTH_EVENT_AVRCP_CONTROL_DISCONNECTED;
232 ret_if(output == NULL);
233 *param_data = &g_array_index(output, char, 0);
236 BT_ERR("Unknown function");
242 out param1: API result
243 out param2: return paramter
246 static void __bt_fill_garray_from_variant(GVariant *var, GArray *param)
251 size = g_variant_get_size(var);
253 data = (char *)g_variant_get_data(var);
255 param = g_array_append_vals(param, data, size);
260 static void __send_request_cb(GDBusProxy *proxy,
264 bluetooth_event_param_t bt_event;
265 bt_req_info_t *cb_data = user_data;
266 int result = BLUETOOTH_ERROR_NONE;
267 int event_type = BT_ADAPTER_EVENT;
269 GError *error = NULL;
273 GArray *out_param1 = NULL;
274 // GArray *out_param2 = NULL;
277 memset(&bt_event, 0x00, sizeof(bluetooth_event_param_t));
279 value = g_dbus_proxy_call_finish(proxy, res, &error);
282 /* dBUS gives error cause */
283 BT_ERR("D-Bus API failure: message[%s]",
285 g_clear_error(&error);
287 result = BLUETOOTH_ERROR_TIMEOUT;
289 ret_if(cb_data == NULL);
291 __bt_get_event_info(cb_data->service_function, NULL,
292 &bt_event.event, &event_type,
293 &bt_event.param_data);
295 g_variant_get(value, "(iv)", &result, ¶m1);
296 g_variant_unref(value);
299 out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
300 __bt_fill_garray_from_variant(param1, out_param1);
301 g_variant_unref(param1);
305 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
306 // __bt_fill_garray_from_variant(param2, out_param2);
307 // result = g_array_index(out_param2, int, 0);
308 // g_variant_unref(param2);
309 // g_array_free(out_param2, TRUE);
311 // result = BLUETOOTH_ERROR_INTERNAL;
314 ret_if(cb_data == NULL);
316 __bt_get_event_info(cb_data->service_function, out_param1,
317 &bt_event.event, &event_type,
318 &bt_event.param_data);
320 if (result == BLUETOOTH_ERROR_NONE && out_param1) {
321 if (cb_data->service_function == BT_OPP_PUSH_FILES) {
322 request_id = g_array_index(out_param1, int, 0);
323 BT_DBG("request_id : %d", request_id);
324 _bt_add_push_request_id(request_id);
332 if (cb_data->cb == NULL)
335 /* Only if fail case, call the callback function*/
336 bt_event.result = result;
337 BT_INFO("event_type[%d], result=[%d]", event_type, result);
339 if (event_type == BT_ADAPTER_EVENT || event_type == BT_RFCOMM_CLIENT_EVENT) {
340 ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
343 } else if (event_type == BT_HID_EVENT) {
344 ((hid_cb_func_ptr)cb_data->cb)(bt_event.event,
345 (hid_event_param_t *)&bt_event,
347 } else if (event_type == BT_HEADSET_EVENT) {
348 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
349 (bt_audio_event_param_t *)&bt_event,
351 } else if (event_type == BT_HF_AGENT_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_AVRCP_CONTROL_EVENT) {
356 ((media_cb_func_ptr)cb_data->cb)(bt_event.event,
357 (media_event_param_t *)&bt_event,
359 } else if (event_type == BT_A2DP_SOURCE_EVENT) {
360 ((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
361 (bt_audio_event_param_t *)&bt_event,
364 BT_INFO("Not handled event type : %d", event_type);
368 g_array_free(out_param1, TRUE);
370 sending_requests = g_slist_remove(sending_requests, (void *)cb_data);
376 int _bt_sync_send_request(int service_type, int service_function,
377 GArray *in_param1, GArray *in_param2,
378 GArray *in_param3, GArray *in_param4,
381 int result = BLUETOOTH_ERROR_NONE;
382 GError *error = NULL;
383 GArray *in_param5 = NULL;
384 // GArray *out_param2 = NULL;
394 switch (service_type) {
395 case BT_BLUEZ_SERVICE:
396 case BT_OBEX_SERVICE:
397 case BT_AGENT_SERVICE:
398 case BT_CHECK_PRIVILEGE:
399 proxy = __bt_gdbus_get_service_proxy();
401 return BLUETOOTH_ERROR_INTERNAL;
403 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
405 param1 = g_variant_new_from_data((const GVariantType *)"ay",
406 in_param1->data, in_param1->len,
408 param2 = g_variant_new_from_data((const GVariantType *)"ay",
409 in_param2->data, in_param2->len,
411 param3 = g_variant_new_from_data((const GVariantType *)"ay",
412 in_param3->data, in_param3->len,
414 param4 = g_variant_new_from_data((const GVariantType *)"ay",
415 in_param4->data, in_param4->len,
417 param5 = g_variant_new_from_data((const GVariantType *)"ay",
418 in_param5->data, in_param5->len,
421 ret = g_dbus_proxy_call_sync(proxy, "service_request",
422 g_variant_new("(iii@ay@ay@ay@ay@ay)",
423 service_type, service_function,
427 G_DBUS_CALL_FLAGS_NONE, -1,
430 g_array_free(in_param5, TRUE);
433 /* dBUS-RPC is failed */
434 BT_ERR("dBUS-RPC is failed");
437 /* dBUS gives error cause */
438 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
439 error->code, error->message);
441 g_clear_error(&error);
443 /* dBUS does not give error cause dBUS-RPC is failed */
444 BT_ERR("error returned was NULL");
447 return BLUETOOTH_ERROR_INTERNAL;
453 g_variant_get(ret, "(iv)", &result, ¶m1);
456 *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
457 __bt_fill_garray_from_variant(param1, *out_param1);
458 g_variant_unref(param1);
462 // out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
463 // __bt_fill_garray_from_variant(param2, out_param2);
464 // result = g_array_index(out_param2, int, 0);
465 // g_variant_unref(param2);
466 // g_array_free(out_param2, TRUE);
468 // result = BLUETOOTH_ERROR_INTERNAL;
471 g_variant_unref(ret);
474 BT_ERR("Unknown service type");
475 return BLUETOOTH_ERROR_INTERNAL;
481 int _bt_async_send_request(int service_type, int service_function,
482 GArray *in_param1, GArray *in_param2,
483 GArray *in_param3, GArray *in_param4,
484 void *callback, void *user_data)
486 GArray* in_param5 = NULL;
487 bt_req_info_t *cb_data;
497 BT_DBG("service_function : %x", service_function);
499 cb_data = g_new0(bt_req_info_t, 1);
501 cb_data->service_function = service_function;
502 cb_data->cb = callback;
503 cb_data->user_data = user_data;
505 switch (service_type) {
506 case BT_BLUEZ_SERVICE:
507 case BT_OBEX_SERVICE:
508 proxy = __bt_gdbus_get_service_proxy();
511 return BLUETOOTH_ERROR_INTERNAL;
514 /* Do not timeout the request in certain cases. Sometime the
515 * request may take undeterministic time to reponse.
516 * (for ex: pairing retry) */
517 if (service_function == BT_BOND_DEVICE ||
518 service_function == BT_BOND_DEVICE_BY_TYPE)
521 timeout = BT_DBUS_TIMEOUT_MAX;
523 in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar));
525 param1 = g_variant_new_from_data((const GVariantType *)"ay",
526 in_param1->data, in_param1->len,
528 param2 = g_variant_new_from_data((const GVariantType *)"ay",
529 in_param2->data, in_param2->len,
531 param3 = g_variant_new_from_data((const GVariantType *)"ay",
532 in_param3->data, in_param3->len,
534 param4 = g_variant_new_from_data((const GVariantType *)"ay",
535 in_param4->data, in_param4->len,
537 param5 = g_variant_new_from_data((const GVariantType *)"ay",
538 in_param5->data, in_param5->len,
541 g_dbus_proxy_call(proxy, "service_request",
542 g_variant_new("(iii@ay@ay@ay@ay@ay)",
543 service_type, service_function,
544 BT_ASYNC_REQ, param1, param2,
545 param3, param4, param5),
546 G_DBUS_CALL_FLAGS_NONE,
548 (GAsyncReadyCallback)__send_request_cb,
550 sending_requests = g_slist_append(sending_requests, cb_data);
552 g_array_free(in_param5, TRUE);
556 return BLUETOOTH_ERROR_NONE;