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 <syspopup_caller.h>
24 #include <bundle_internal.h>
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-device.h"
31 #include "bt-service-util.h"
32 #include "bt-service-event.h"
33 #include "bt-service-otp.h"
35 #define BT_OTP_SERVICE_NAME "org.projectx.otp"
36 #define BT_OTP_OBJECT_PATH "/org/projectx/otp"
37 #define BT_OTP_INTERFACE_NAME "org.projectx.otp_service"
39 #define BT_OTP_BASE_DIR_PATH "/home/owner/media/otp/"
41 #define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1"
43 #define GATT_DEFAULT_TIMEOUT (6 * 1000) /* Dependent on supervision timeout 6 sec */
44 #define BT_INDICATION_TIMEOUT_MAX 30000 /* Timeout for Indication from OTP Server in msec */
46 /* OTP Notification Request structure */
50 unsigned int notification_timeout_id;
52 } bt_otp_notification_info;
54 /* OTP transport specific data read Request info structure */
59 } bt_otp_read_req_info;
61 static GSList *otp_read_req_info_list = NULL;
63 static GSList *otp_notification_info_list = NULL;
65 static GDBusProxy *otp_gproxy;
67 static GDBusProxy *_bt_core_gdbus_init_otp_proxy(void)
71 GDBusConnection *conn;
75 conn = _bt_gdbus_get_system_gconn();
79 proxy = g_dbus_proxy_new_sync(conn,
80 G_DBUS_PROXY_FLAGS_NONE, NULL,
83 BT_OTP_INTERFACE_NAME,
87 BT_ERR("Unable to create proxy: %s", err->message);
98 GDBusProxy *_bt_core_gdbus_get_otp_proxy(void)
100 return (otp_gproxy) ? otp_gproxy : _bt_core_gdbus_init_otp_proxy();
103 void server_init_cb(GObject *object, GAsyncResult *res,
106 BT_INFO("Server Init completed");
107 GError *error = NULL;
108 GVariant *result, *out_param, *param;
109 request_info_t *req_info = NULL;
110 int status = BLUETOOTH_ERROR_NONE;
111 bool server_state = false;
113 result = g_dbus_proxy_call_finish(otp_gproxy, res, &error);
115 if (result == NULL) {
116 BT_ERR("Dbus-RPC is failed\n");
118 BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
119 error->code, error->message);
120 g_clear_error(&error);
121 status = BLUETOOTH_ERROR_INTERNAL;
126 g_variant_get(result, "(i)", &status);
129 BT_DBG("Status [%d]", status);
131 if (status == BLUETOOTH_ERROR_NONE)
134 param = g_variant_new("(ib)", status, server_state);
136 req_info = _bt_get_request_info(GPOINTER_TO_INT(user_data));
138 /* Send the event to application */
139 _bt_send_event(BT_OTP_EVENT,
140 BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
143 out_param = g_variant_new_from_data((const GVariantType*)"i",
144 result, sizeof(int), TRUE, NULL, NULL);
147 g_dbus_method_invocation_return_value(req_info->context,
148 g_variant_new("(iv)", status, out_param));
150 _bt_delete_request_list(req_info->req_id);
153 g_variant_unref(result);
156 int bt_otp_server_init(int request_id, const char *directory)
158 BT_INFO("relative_path: [%s]", directory);
159 char *base_dir = g_strconcat(BT_OTP_BASE_DIR_PATH, directory, NULL);
163 otp_gproxy = _bt_core_gdbus_get_otp_proxy();
165 BT_DBG("Couldn't get service proxy");
167 return BLUETOOTH_ERROR_INTERNAL;
170 g_dbus_proxy_call(otp_gproxy,
174 G_DBUS_CALL_FLAGS_NONE, -1,
176 (GAsyncReadyCallback) server_init_cb,
177 GINT_TO_POINTER(request_id));
181 return BLUETOOTH_ERROR_NONE;
184 void server_deinit_cb(GObject *object, GAsyncResult *res,
187 BT_INFO("Server Deinit completed");
188 GError *error = NULL;
189 GVariant *result, *out_param, *param;
190 request_info_t *req_info = NULL;
191 int status = BLUETOOTH_ERROR_NONE;
192 bool server_state = false;
194 result = g_dbus_proxy_call_finish(otp_gproxy, res, &error);
196 if (result == NULL) {
197 BT_ERR("Dbus-RPC is failed\n");
199 BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
200 error->code, error->message);
201 g_clear_error(&error);
202 status = BLUETOOTH_ERROR_INTERNAL;
207 g_variant_get(result, "(i)", &status);
210 BT_DBG("Status [%d]", status);
212 param = g_variant_new("(ib)", status, server_state);
214 req_info = _bt_get_request_info(GPOINTER_TO_INT(user_data));
216 /* Send the event to application */
217 _bt_send_event(BT_OTP_EVENT,
218 BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
222 out_param = g_variant_new_from_data((const GVariantType*)"i",
223 result, sizeof(int), TRUE, NULL, NULL);
225 g_dbus_method_invocation_return_value(req_info->context,
226 g_variant_new("(iv)", status, out_param));
228 _bt_delete_request_list(req_info->req_id);
231 g_variant_unref(result);
234 g_object_unref(otp_gproxy);
239 int bt_otp_server_deinit(int request_id)
243 otp_gproxy = _bt_core_gdbus_get_otp_proxy();
245 BT_DBG("Couldn't get service proxy");
246 return BLUETOOTH_ERROR_INTERNAL;
249 g_dbus_proxy_call(otp_gproxy,
251 NULL, G_DBUS_CALL_FLAGS_NONE,
253 (GAsyncReadyCallback) server_deinit_cb,
254 GINT_TO_POINTER(request_id));
257 return BLUETOOTH_ERROR_NONE;
260 int __get_handle_length(char *handle)
263 while (handle && (handle[i] != '\0')) {
269 static bt_otp_read_req_info *__bt_otp_get_read_info(char *handle)
272 bt_otp_read_req_info *info = NULL;
273 BT_INFO("Found waiting for OTP Read from charc handle[%s]", handle);
274 for (l = otp_read_req_info_list; l != NULL; l = g_slist_next(l)) {
275 info = (bt_otp_read_req_info *)l->data;
279 if (!g_strcmp0(info->handle, handle)) {
280 BT_INFO("Found waiting for OTP Read from remote addr[%s]",
288 static void __bt_otp_remove_read_info(bt_otp_read_req_info *info)
290 BT_DBG("Removing Read Req Info [%s]", info->handle);
292 otp_read_req_info_list = g_slist_remove(otp_read_req_info_list, info);
294 g_free(info->handle);
296 g_free(info->sender);
300 static int __bluetooth_get_att_error_code(GError *error)
306 BT_ERR("Error : %s", error->message);
307 str = g_strrstr(error->message, "ATT error: 0x");
310 att_ecode = g_ascii_xdigit_value(str[len-2]) << 4;
311 att_ecode += g_ascii_xdigit_value(str[len-1]);
313 return BLUETOOTH_ATT_ERROR_INTERNAL;
318 static void __bt_otp_read_char_cb(GObject *source_object,
319 GAsyncResult *res, gpointer user_data)
321 bt_gatt_char_descriptor_property_t att_value = { 0, };
322 GDBusConnection *system_gconn = NULL;
323 GVariant *var_data, *param = NULL;
324 int result = BLUETOOTH_ATT_ERROR_NONE;
325 bt_otp_read_req_info *info = NULL;
326 GByteArray *gp_byte_array = NULL;
327 request_info_t *req_info = NULL;
328 GVariantIter *iter = NULL;
329 GVariant *value = NULL;
330 char *otp_data = NULL;
331 GVariant *out_param1;
332 GError *error = NULL;
337 system_gconn = _bt_gdbus_get_system_gconn();
339 handle = (char *)user_data;
340 info = __bt_otp_get_read_info(handle);
342 value = g_dbus_connection_call_finish(system_gconn, res, &error);
345 result = __bluetooth_get_att_error_code(error);
346 att_value.val_len = 0;
350 g_variant_get(value, "(ay)", &iter);
352 gp_byte_array = g_byte_array_new();
354 while (g_variant_iter_loop(iter, "y", &g_byte))
355 g_byte_array_append(gp_byte_array, &g_byte, 1);
357 if (gp_byte_array->len != 0) {
358 att_value.val_len = (unsigned int)gp_byte_array->len;
359 att_value.val = (unsigned char *)gp_byte_array->data;
362 otp_data = (char *)g_memdup(att_value.val, att_value.val_len);
365 var_data = g_variant_new_from_data((const GVariantType*)"ay",
366 otp_data, att_value.val_len, TRUE, NULL, NULL);
369 param = g_variant_new("(isn@ay)", result, handle, att_value.val_len, var_data);
370 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
371 BLUETOOTH_EVENT_OTP_READ_CHAR_VAL,
375 req_info = _bt_get_request_info(info->req_id);
376 __bt_otp_remove_read_info(info);
378 if (req_info == NULL) {
379 BT_ERR("OTP data read Request not found!!");
383 if (req_info->context == NULL)
386 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
387 handle, __get_handle_length(handle), TRUE, NULL, NULL);
388 g_dbus_method_invocation_return_value(req_info->context,
389 g_variant_new("(iv)", result, out_param1));
391 _bt_delete_request_list(req_info->req_id);
396 g_clear_error(&error);
398 g_byte_array_free(gp_byte_array, TRUE);
402 g_variant_unref(value);
404 g_variant_iter_free(iter);
410 int _bt_otp_read_characteristic_value(int request_id, char *sender, char *handle)
412 GDBusConnection *conn;
413 bt_otp_read_req_info *info = NULL;
414 char *charc_handle = g_strdup(handle);
415 GVariantBuilder *builder = NULL;
418 BT_CHECK_PARAMETER(handle, return);
419 BT_CHECK_PARAMETER(sender, return);
421 conn = _bt_gdbus_get_system_gconn();
422 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
424 BT_DBG("Read OTP Characteristic from server handle [%s]", handle);
426 /* If OTP data read already pending on same Server, then return In progress */
427 if (__bt_otp_get_read_info(handle) != NULL) {
428 BT_ERR("Read Req is ongoing in remote server [%s]", charc_handle);
429 g_free(charc_handle);
430 return BLUETOOTH_ERROR_IN_PROGRESS;
433 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
435 g_variant_builder_add(builder, "{sv}", "offset",
436 g_variant_new("q", offset));
438 g_dbus_connection_call(conn,
443 g_variant_new("(a{sv})", builder),
444 G_VARIANT_TYPE("(ay)"),
445 G_DBUS_CALL_FLAGS_NONE,
448 (GAsyncReadyCallback)__bt_otp_read_char_cb,
449 (gpointer)charc_handle);
451 /* Save Info in pending list */
452 info = g_malloc0(sizeof(bt_otp_read_req_info));
453 info->handle = g_strdup(handle);
454 BT_INFO("Found waiting for OTP Read from charc handle[%s] [%s]", info->handle, handle);
455 info->sender = g_strdup(sender);
456 info->req_id = request_id;
457 otp_read_req_info_list = g_slist_append(otp_read_req_info_list, info);
460 return BLUETOOTH_ERROR_NONE;
463 static bt_otp_notification_info *__bt_otp_get_notification_info(char *handle)
466 bt_otp_notification_info *info = NULL;
468 for (l = otp_notification_info_list; l != NULL; l = g_slist_next(l)) {
469 info = (bt_otp_notification_info *)l->data;
473 if (!g_strcmp0(info->handle, handle)) {
474 BT_INFO("Found waiting for Ind from Server addr[%s]",
482 static void __bt_otp_remove_notification_info(bt_otp_notification_info *info)
484 BT_DBG("Removing Notification Info [%s]", info->handle);
486 otp_notification_info_list = g_slist_remove(otp_notification_info_list, info);
488 g_free(info->handle);
490 g_free(info->sender);
491 if (info->notification_timeout_id > 0) {
492 g_source_remove(info->notification_timeout_id);
493 info->notification_timeout_id = 0;
498 static void __bt_otp_notification_enable_request_cb(GObject *source_object,
499 GAsyncResult *res, gpointer user_data)
501 GError *error = NULL;
502 GDBusConnection *system_gconn = NULL;
503 GVariant *value = NULL;
504 GVariant *param = NULL;
505 GVariant *out_param1 = NULL;
506 int result = BLUETOOTH_ERROR_NONE;
508 bt_otp_notification_info *info = NULL;
509 request_info_t *req_info = NULL;
512 system_gconn = _bt_gdbus_get_system_gconn();
513 value = g_dbus_connection_call_finish(system_gconn, res, &error);
516 BT_ERR("Error : %s \n", error->message);
517 if (g_strrstr(error->message, "Already notifying"))
518 result = BLUETOOTH_ERROR_NONE;
519 else if (g_strrstr(error->message, "In Progress"))
520 result = BLUETOOTH_ERROR_IN_PROGRESS;
521 else if (g_strrstr(error->message, "Operation is not supported"))
522 result = BLUETOOTH_ERROR_NOT_SUPPORT;
523 else if (g_strrstr(error->message, "Write not permitted") ||
524 g_strrstr(error->message, "Operation Not Authorized"))
525 result = BLUETOOTH_ERROR_PERMISSION_DEINED;
526 else if (g_strrstr(error->message, "Not paired"))
527 result = BLUETOOTH_ERROR_NOT_PAIRED;
529 result = BLUETOOTH_ERROR_INTERNAL;
531 BT_DBG("OTP CCCD enable request successful, send event to BT App");
534 handle = (char *)user_data;
535 info = __bt_otp_get_notification_info(handle);
538 req_info = _bt_get_request_info(info->req_id);
540 /* If CCCD Enable request failed for any reason, reset timer */
541 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
542 BT_ERR("Activation Request failed");
544 if (info->notification_timeout_id > 0) {
545 g_source_remove(info->notification_timeout_id);
546 info->notification_timeout_id = 0;
549 /* Remove Indication Info */
550 __bt_otp_remove_notification_info(info);
552 /* CCCD Enable Request successful */
554 param = g_variant_new("(is)", result, handle);
555 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
556 BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED,
561 if (req_info == NULL) {
562 BT_ERR("OTP Control Point CCCD Enable Request is not found!!");
566 if (req_info->context == NULL)
569 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
570 handle, __get_handle_length(handle), TRUE, NULL, NULL);
571 g_dbus_method_invocation_return_value(req_info->context,
572 g_variant_new("(iv)", result, out_param1));
574 _bt_delete_request_list(req_info->req_id);
578 g_variant_unref(value);
580 g_clear_error(&error);
588 int _bt_otp_enable_notification(int request_id, char *sender, char *handle)
590 bt_otp_notification_info *info = NULL;
591 char *charc_handle = g_strdup(handle);
592 GDBusConnection *conn;
594 BT_CHECK_PARAMETER(handle, return);
595 BT_CHECK_PARAMETER(sender, return);
597 conn = _bt_gdbus_get_system_gconn();
598 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
600 BT_DBG("OTP Control point CCCD Handle [%s]", handle);
602 if (__bt_otp_get_notification_info(handle) != NULL) {
603 BT_ERR("Activation is already ongoing for same remote server");
604 g_free(charc_handle);
605 return BLUETOOTH_ERROR_IN_PROGRESS;
608 BT_INFO("Start Notify to Bluez");
609 g_dbus_connection_call(conn,
616 G_DBUS_CALL_FLAGS_NONE,
617 GATT_DEFAULT_TIMEOUT, NULL,
618 (GAsyncReadyCallback)__bt_otp_notification_enable_request_cb,
619 (gpointer)charc_handle);
621 info = g_malloc0(sizeof(bt_otp_notification_info));
622 info->handle = g_strdup(handle);
623 info->sender = g_strdup(sender);
624 info->req_id = request_id;
625 otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
628 return BLUETOOTH_ERROR_NONE;
631 static void __bt_otp_write_request_cb(GObject *source_object,
632 GAsyncResult *res, gpointer user_data)
634 GError *error = NULL;
635 GDBusConnection *system_gconn = NULL;
636 GVariant *value = NULL;
637 GVariant *param = NULL;
638 GVariant *out_param1 = NULL;
639 int result = BLUETOOTH_ATT_ERROR_NONE;
641 bt_otp_notification_info *info = NULL;
642 request_info_t *req_info = NULL;
645 system_gconn = _bt_gdbus_get_system_gconn();
646 value = g_dbus_connection_call_finish(system_gconn, res, &error);
649 result = __bluetooth_get_att_error_code(error);
651 handle = (char *)user_data;
652 info = __bt_otp_get_notification_info(handle);
654 req_info = _bt_get_request_info(info->req_id);
656 /* Is Activation request failed for any reason, reset timer */
657 if (result != BLUETOOTH_ATT_ERROR_NONE && info != NULL) {
658 BT_ERR("Activation Request failed");
659 /* Remove Indication Info */
660 __bt_otp_remove_notification_info(info);
663 /* Activation Request successful */
665 param = g_variant_new("(is)", result, handle);
666 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
667 BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL,
671 if (req_info == NULL) {
672 BT_ERR("OTP Write Request is not found!!");
676 if (req_info->context == NULL)
679 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
680 handle, __get_handle_length(handle), TRUE, NULL, NULL);
681 g_dbus_method_invocation_return_value(req_info->context,
682 g_variant_new("(iv)", result, out_param1));
684 _bt_delete_request_list(req_info->req_id);
688 g_variant_unref(value);
690 g_clear_error(&error);
698 static void __bt_otp_send_indication_event(bt_otp_notification_info *info,
699 unsigned char *buffer, int len, int result)
704 otp_data = g_variant_new_from_data((const GVariantType*)"ay",
705 buffer, len, TRUE, NULL, NULL);
707 BT_DBG("Send Indication event to sender");
708 param = g_variant_new("(is@ay)", result, info->handle, otp_data);
709 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
710 BLUETOOTH_EVENT_OTP_INDICATION,
713 /* Remove info from list */
714 __bt_otp_remove_notification_info(info);
717 static bool __bt_otp_indication_timeout_cb(gpointer user_data)
720 handle = (char *) user_data;
721 bt_otp_notification_info *info = NULL;
723 info = __bt_otp_get_notification_info(handle);
725 BT_DBG("Activation timer Expired [Server] [%s]", info->handle);
726 __bt_otp_send_indication_event(info, NULL, 0, BLUETOOTH_ERROR_INTERNAL);
732 int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle,
733 unsigned char *param, int length)
735 GVariantBuilder *builder1;
738 GVariantBuilder *builder2;
740 bt_otp_notification_info *info = NULL;
741 GDBusConnection *conn;
742 char *charc_handle = g_strdup(handle);
747 BT_CHECK_PARAMETER(handle, return);
748 BT_CHECK_PARAMETER(sender, return);
749 BT_CHECK_PARAMETER(param, return);
751 conn = _bt_gdbus_get_system_gconn();
752 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
754 BT_DBG("OTP Write Characteristic value handle [%s] data length [%d]", handle, length);
755 /* Check if activation is ongoing for the same Remote Server */
757 info = __bt_otp_get_notification_info(handle);
758 if (info && info->notification_timeout_id > 0) {
759 BT_ERR("Write Request is already ongoing in remote server");
760 g_free(charc_handle);
761 return BLUETOOTH_ERROR_IN_PROGRESS;
764 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
766 for (i = 0; i < length; i++) {
767 g_variant_builder_add(builder1, "y", param[i]);
770 val = g_variant_new("ay", builder1);
771 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
773 g_variant_builder_add(builder2, "{sv}", "offset",
774 g_variant_new_uint16(offset));
776 options = g_variant_new("a{sv}", builder2);
778 /* Activate Control Point */
779 g_dbus_connection_call(conn,
784 g_variant_new("(@ay@a{sv})",
787 G_DBUS_CALL_FLAGS_NONE,
789 (GAsyncReadyCallback)__bt_otp_write_request_cb,
790 (gpointer)charc_handle);
792 g_variant_builder_unref(builder1);
793 g_variant_builder_unref(builder2);
796 info = g_malloc0(sizeof(bt_otp_notification_info));
797 info->handle = g_strdup(handle);
798 info->sender = g_strdup(sender);
799 otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
801 info->req_id = request_id;
802 /* Set timeout only for cp charc */
803 info->notification_timeout_id = g_timeout_add(BT_INDICATION_TIMEOUT_MAX,
804 (GSourceFunc)__bt_otp_indication_timeout_cb, (gpointer)info->handle);
807 return BLUETOOTH_ERROR_NONE;
810 void _bt_otp_check_indication(const char *path, GVariant *msg)
812 bt_otp_notification_info *info = NULL;
813 unsigned char *buffer = NULL;
816 GVariant *value = NULL;
819 info = __bt_otp_get_notification_info((char *)path);
822 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
823 len = g_variant_get_size(value);
824 BT_DBG("Indication data from Server len[%d]", len);
826 buffer = (unsigned char *)g_variant_get_data(value);
828 for (i = 0; i < len; i++)
829 BT_DBG("%.2x", buffer[i]);
833 if (info->notification_timeout_id > 0)
834 g_source_remove(info->notification_timeout_id);
836 /* Send Indication & info removed internally */
837 __bt_otp_send_indication_event(info, buffer, len, BLUETOOTH_ERROR_NONE);
840 g_variant_unref(value);
845 int _bt_otp_connect_otc(int req_id, const bluetooth_device_address_t *bd_addr)
847 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
848 gchar *device_path = NULL;
849 GDBusProxy *device_proxy = NULL;
850 GDBusConnection *conn;
851 int ret = BLUETOOTH_ERROR_NONE;
852 GVariant *result = NULL;
855 BT_CHECK_PARAMETER(bd_addr, return);
857 _bt_convert_addr_type_to_string(device_address,
858 (unsigned char *)bd_addr->addr);
860 conn = _bt_gdbus_get_system_gconn();
861 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
863 device_path = _bt_get_device_object_path(device_address);
864 if (device_path == NULL) {
865 BT_DBG("device_path NULL");
866 ret = BLUETOOTH_ERROR_INTERNAL;
870 retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
872 device_proxy = g_dbus_proxy_new_sync(conn,
873 G_DBUS_PROXY_FLAGS_NONE,
875 device_path, BT_DEVICE_INTERFACE,
878 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
880 result = g_dbus_proxy_call_sync(device_proxy, "ConnectOtc",
882 G_DBUS_CALL_FLAGS_NONE,
887 if (result == NULL) {
889 g_dbus_error_strip_remote_error(err);
890 BT_ERR("OTC Connect Error: %s\n", err->message);
891 if (g_strcmp0(err->message, "Already Exists") == 0)
892 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
894 ret = BLUETOOTH_ERROR_INTERNAL;
898 g_variant_unref(result);
901 g_object_unref(device_proxy);
905 int _bt_otp_disconnect_otc(const bluetooth_device_address_t *bd_addr)
907 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
908 gchar *device_path = NULL;
909 GError *error = NULL;
910 GDBusProxy *device_proxy = NULL;
911 GDBusProxy *adapter_proxy;
912 GDBusConnection *conn;
913 int ret = BLUETOOTH_ERROR_NONE;
915 BT_CHECK_PARAMETER(bd_addr, return);
917 _bt_convert_addr_type_to_string(device_address,
918 (unsigned char *)bd_addr->addr);
920 conn = _bt_gdbus_get_system_gconn();
921 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
923 adapter_proxy = _bt_get_adapter_proxy();
924 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
926 device_path = _bt_get_device_object_path(device_address);
927 if (device_path == NULL) {
928 BT_DBG("device_path NULL");
929 return BLUETOOTH_ERROR_INTERNAL;
932 retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
934 device_proxy = g_dbus_proxy_new_sync(conn,
935 G_DBUS_PROXY_FLAGS_NONE,
941 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
943 g_dbus_proxy_call_sync(device_proxy, "DisconnectOtc",
945 G_DBUS_CALL_FLAGS_NONE,
951 BT_ERR("DisconnectOtc Call Error %s[%s]",
952 error->message, device_address);
954 g_object_unref(device_proxy);
955 return BLUETOOTH_ERROR_INTERNAL;
959 g_object_unref(device_proxy);