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;
124 g_variant_get(result, "(i)", &status);
125 g_variant_unref(result);
128 BT_DBG("Status [%d]", status);
130 if (status == BLUETOOTH_ERROR_NONE)
133 param = g_variant_new("(ib)", status, server_state);
135 req_info = _bt_get_request_info(GPOINTER_TO_INT(user_data));
137 /* Send the event to application */
138 _bt_send_event(BT_OTP_EVENT,
139 BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
142 out_param = g_variant_new_from_data((const GVariantType*)"i",
143 &status, sizeof(int), TRUE, NULL, NULL);
146 g_dbus_method_invocation_return_value(req_info->context,
147 g_variant_new("(iv)", status, out_param));
149 _bt_delete_request_list(req_info->req_id);
153 int bt_otp_server_init(int request_id, const char *directory)
155 BT_INFO("relative_path: [%s]", directory);
156 char *base_dir = g_strconcat(BT_OTP_BASE_DIR_PATH, directory, NULL);
160 otp_gproxy = _bt_core_gdbus_get_otp_proxy();
162 BT_DBG("Couldn't get service proxy");
164 return BLUETOOTH_ERROR_INTERNAL;
167 g_dbus_proxy_call(otp_gproxy,
171 G_DBUS_CALL_FLAGS_NONE, -1,
173 (GAsyncReadyCallback) server_init_cb,
174 GINT_TO_POINTER(request_id));
178 return BLUETOOTH_ERROR_NONE;
181 void server_deinit_cb(GObject *object, GAsyncResult *res,
184 BT_INFO("Server Deinit completed");
185 GError *error = NULL;
186 GVariant *result, *out_param, *param;
187 request_info_t *req_info = NULL;
188 int status = BLUETOOTH_ERROR_NONE;
189 bool server_state = false;
191 result = g_dbus_proxy_call_finish(otp_gproxy, res, &error);
193 if (result == NULL) {
194 BT_ERR("Dbus-RPC is failed\n");
196 BT_ERR("D-Bus API failure: errCode[%x], message[%s]\n",
197 error->code, error->message);
198 g_clear_error(&error);
199 status = BLUETOOTH_ERROR_INTERNAL;
202 g_variant_get(result, "(i)", &status);
203 g_variant_unref(result);
206 BT_DBG("Status [%d]", status);
208 param = g_variant_new("(ib)", status, server_state);
210 req_info = _bt_get_request_info(GPOINTER_TO_INT(user_data));
212 /* Send the event to application */
213 _bt_send_event(BT_OTP_EVENT,
214 BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
218 out_param = g_variant_new_from_data((const GVariantType*)"i",
219 &status, sizeof(int), TRUE, NULL, NULL);
221 g_dbus_method_invocation_return_value(req_info->context,
222 g_variant_new("(iv)", status, out_param));
224 _bt_delete_request_list(req_info->req_id);
228 g_object_unref(otp_gproxy);
233 int bt_otp_server_deinit(int request_id)
237 otp_gproxy = _bt_core_gdbus_get_otp_proxy();
239 BT_DBG("Couldn't get service proxy");
240 return BLUETOOTH_ERROR_INTERNAL;
243 g_dbus_proxy_call(otp_gproxy,
245 NULL, G_DBUS_CALL_FLAGS_NONE,
247 (GAsyncReadyCallback) server_deinit_cb,
248 GINT_TO_POINTER(request_id));
251 return BLUETOOTH_ERROR_NONE;
254 int __get_handle_length(char *handle)
258 while (handle && (handle[i] != '\0'))
264 static bt_otp_read_req_info *__bt_otp_get_read_info(char *handle)
267 bt_otp_read_req_info *info = NULL;
268 BT_INFO("Found waiting for OTP Read from charc handle[%s]", handle);
269 for (l = otp_read_req_info_list; l != NULL; l = g_slist_next(l)) {
270 info = (bt_otp_read_req_info *)l->data;
274 if (!g_strcmp0(info->handle, handle)) {
275 BT_INFO("Found waiting for OTP Read from remote addr[%s]",
283 static void __bt_otp_remove_read_info(bt_otp_read_req_info *info)
285 BT_DBG("Removing Read Req Info [%s]", info->handle);
287 otp_read_req_info_list = g_slist_remove(otp_read_req_info_list, info);
289 g_free(info->handle);
291 g_free(info->sender);
295 static int __bluetooth_get_att_error_code(GError *error)
301 BT_ERR("Error : %s", error->message);
302 str = g_strrstr(error->message, "ATT error: 0x");
305 att_ecode = g_ascii_xdigit_value(str[len-2]) << 4;
306 att_ecode += g_ascii_xdigit_value(str[len-1]);
308 return BLUETOOTH_ATT_ERROR_INTERNAL;
313 static void __bt_otp_read_char_cb(GObject *source_object,
314 GAsyncResult *res, gpointer user_data)
316 bt_gatt_char_descriptor_property_t att_value = { 0, };
317 GDBusConnection *system_gconn = NULL;
318 GVariant *var_data, *param = NULL;
319 int result = BLUETOOTH_ATT_ERROR_NONE;
320 bt_otp_read_req_info *info = NULL;
321 GByteArray *gp_byte_array = NULL;
322 request_info_t *req_info = NULL;
323 GVariantIter *iter = NULL;
324 GVariant *value = NULL;
325 char *otp_data = NULL;
326 GVariant *out_param1;
327 GError *error = NULL;
332 system_gconn = _bt_gdbus_get_system_gconn();
334 handle = (char *)user_data;
335 info = __bt_otp_get_read_info(handle);
337 value = g_dbus_connection_call_finish(system_gconn, res, &error);
340 result = __bluetooth_get_att_error_code(error);
341 att_value.val_len = 0;
345 g_variant_get(value, "(ay)", &iter);
347 gp_byte_array = g_byte_array_new();
349 while (g_variant_iter_loop(iter, "y", &g_byte))
350 g_byte_array_append(gp_byte_array, &g_byte, 1);
352 if (gp_byte_array->len != 0) {
353 att_value.val_len = (unsigned int)gp_byte_array->len;
354 att_value.val = (unsigned char *)gp_byte_array->data;
357 otp_data = (char *)g_memdup(att_value.val, att_value.val_len);
360 var_data = g_variant_new_from_data((const GVariantType*)"ay",
361 otp_data, att_value.val_len, TRUE, NULL, NULL);
364 param = g_variant_new("(isn@ay)", result, handle, att_value.val_len, var_data);
365 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
366 BLUETOOTH_EVENT_OTP_READ_CHAR_VAL,
368 req_info = _bt_get_request_info(info->req_id);
369 __bt_otp_remove_read_info(info);
372 if (req_info == NULL) {
373 BT_ERR("OTP data read Request not found!!");
377 if (req_info->context == NULL)
380 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
381 handle, __get_handle_length(handle), TRUE, NULL, NULL);
382 g_dbus_method_invocation_return_value(req_info->context,
383 g_variant_new("(iv)", result, out_param1));
385 _bt_delete_request_list(req_info->req_id);
390 g_clear_error(&error);
392 g_byte_array_free(gp_byte_array, TRUE);
396 g_variant_unref(value);
398 g_variant_iter_free(iter);
404 int _bt_otp_read_characteristic_value(int request_id, char *sender, char *handle)
406 GDBusConnection *conn;
407 bt_otp_read_req_info *info = NULL;
408 char *charc_handle = NULL;
409 GVariantBuilder *builder = NULL;
412 BT_CHECK_PARAMETER(handle, return);
413 BT_CHECK_PARAMETER(sender, return);
415 conn = _bt_gdbus_get_system_gconn();
416 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
418 BT_DBG("Read OTP Characteristic from server handle [%s]", handle);
420 /* If OTP data read already pending on same Server, then return In progress */
421 if (__bt_otp_get_read_info(handle) != NULL) {
422 BT_ERR("Read Req is ongoing in remote server [%s]", handle);
423 return BLUETOOTH_ERROR_IN_PROGRESS;
426 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
428 g_variant_builder_add(builder, "{sv}", "offset",
429 g_variant_new("q", offset));
431 charc_handle = g_strdup(handle);
433 g_dbus_connection_call(conn,
438 g_variant_new("(a{sv})", builder),
439 G_VARIANT_TYPE("(ay)"),
440 G_DBUS_CALL_FLAGS_NONE,
443 (GAsyncReadyCallback)__bt_otp_read_char_cb,
444 (gpointer)charc_handle);
446 /* Save Info in pending list */
447 info = g_malloc0(sizeof(bt_otp_read_req_info));
448 info->handle = g_strdup(handle);
449 BT_INFO("Found waiting for OTP Read from charc handle[%s] [%s]", info->handle, handle);
450 info->sender = g_strdup(sender);
451 info->req_id = request_id;
452 otp_read_req_info_list = g_slist_append(otp_read_req_info_list, info);
455 return BLUETOOTH_ERROR_NONE;
458 static bt_otp_notification_info *__bt_otp_get_notification_info(char *handle)
461 bt_otp_notification_info *info = NULL;
463 for (l = otp_notification_info_list; l != NULL; l = g_slist_next(l)) {
464 info = (bt_otp_notification_info *)l->data;
468 if (!g_strcmp0(info->handle, handle)) {
469 BT_INFO("Found waiting for Ind from Server addr[%s]",
477 static void __bt_otp_remove_notification_info(bt_otp_notification_info *info)
479 BT_DBG("Removing Notification Info [%s]", info->handle);
481 otp_notification_info_list = g_slist_remove(otp_notification_info_list, info);
483 g_free(info->handle);
485 g_free(info->sender);
486 if (info->notification_timeout_id > 0) {
487 g_source_remove(info->notification_timeout_id);
488 info->notification_timeout_id = 0;
493 static void __bt_otp_notification_enable_request_cb(GObject *source_object,
494 GAsyncResult *res, gpointer user_data)
496 GError *error = NULL;
497 GDBusConnection *system_gconn = NULL;
498 GVariant *value = NULL;
499 GVariant *param = NULL;
500 GVariant *out_param1 = NULL;
501 int result = BLUETOOTH_ERROR_NONE;
503 bt_otp_notification_info *info = NULL;
504 request_info_t *req_info = NULL;
507 system_gconn = _bt_gdbus_get_system_gconn();
508 value = g_dbus_connection_call_finish(system_gconn, res, &error);
511 BT_ERR("Error : %s \n", error->message);
512 if (g_strrstr(error->message, "Already notifying"))
513 result = BLUETOOTH_ERROR_NONE;
514 else if (g_strrstr(error->message, "In Progress"))
515 result = BLUETOOTH_ERROR_IN_PROGRESS;
516 else if (g_strrstr(error->message, "Operation is not supported"))
517 result = BLUETOOTH_ERROR_NOT_SUPPORT;
518 else if (g_strrstr(error->message, "Write not permitted") ||
519 g_strrstr(error->message, "Operation Not Authorized"))
520 result = BLUETOOTH_ERROR_PERMISSION_DEINED;
521 else if (g_strrstr(error->message, "Not paired"))
522 result = BLUETOOTH_ERROR_NOT_PAIRED;
524 result = BLUETOOTH_ERROR_INTERNAL;
526 BT_DBG("OTP CCCD enable request successful, send event to BT App");
529 handle = (char *)user_data;
530 info = __bt_otp_get_notification_info(handle);
533 req_info = _bt_get_request_info(info->req_id);
535 /* If CCCD Enable request failed for any reason, reset timer */
536 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
537 BT_ERR("Activation Request failed");
539 if (info->notification_timeout_id > 0) {
540 g_source_remove(info->notification_timeout_id);
541 info->notification_timeout_id = 0;
544 /* Remove Indication Info */
545 __bt_otp_remove_notification_info(info);
547 /* CCCD Enable Request successful */
549 param = g_variant_new("(is)", result, handle);
550 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
551 BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED,
556 if (req_info == NULL) {
557 BT_ERR("OTP Control Point CCCD Enable Request is not found!!");
561 if (req_info->context == NULL)
564 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
565 handle, __get_handle_length(handle), TRUE, NULL, NULL);
566 g_dbus_method_invocation_return_value(req_info->context,
567 g_variant_new("(iv)", result, out_param1));
569 _bt_delete_request_list(req_info->req_id);
573 g_variant_unref(value);
575 g_clear_error(&error);
583 int _bt_otp_enable_notification(int request_id, char *sender, char *handle)
585 bt_otp_notification_info *info = NULL;
586 char *charc_handle = NULL;
587 GDBusConnection *conn;
589 BT_CHECK_PARAMETER(handle, return);
590 BT_CHECK_PARAMETER(sender, return);
592 conn = _bt_gdbus_get_system_gconn();
593 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
595 BT_DBG("OTP Control point CCCD Handle [%s]", handle);
597 if (__bt_otp_get_notification_info(handle) != NULL) {
598 BT_ERR("Activation is already ongoing for same remote server");
599 return BLUETOOTH_ERROR_IN_PROGRESS;
602 charc_handle = g_strdup(handle);
604 BT_INFO("Start Notify to Bluez");
605 g_dbus_connection_call(conn,
612 G_DBUS_CALL_FLAGS_NONE,
613 GATT_DEFAULT_TIMEOUT, NULL,
614 (GAsyncReadyCallback)__bt_otp_notification_enable_request_cb,
615 (gpointer)charc_handle);
617 info = g_malloc0(sizeof(bt_otp_notification_info));
618 info->handle = g_strdup(handle);
619 info->sender = g_strdup(sender);
620 info->req_id = request_id;
621 otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
624 return BLUETOOTH_ERROR_NONE;
627 static void __bt_otp_write_request_cb(GObject *source_object,
628 GAsyncResult *res, gpointer user_data)
630 GError *error = NULL;
631 GDBusConnection *system_gconn = NULL;
632 GVariant *value = NULL;
633 GVariant *param = NULL;
634 GVariant *out_param1 = NULL;
635 int result = BLUETOOTH_ATT_ERROR_NONE;
637 bt_otp_notification_info *info = NULL;
638 request_info_t *req_info = NULL;
641 system_gconn = _bt_gdbus_get_system_gconn();
642 value = g_dbus_connection_call_finish(system_gconn, res, &error);
645 result = __bluetooth_get_att_error_code(error);
647 handle = (char *)user_data;
648 info = __bt_otp_get_notification_info(handle);
650 req_info = _bt_get_request_info(info->req_id);
652 /* Is Activation request failed for any reason, reset timer */
653 if (result != BLUETOOTH_ATT_ERROR_NONE && info != NULL) {
654 BT_ERR("Activation Request failed");
655 /* Remove Indication Info */
656 __bt_otp_remove_notification_info(info);
659 /* Activation Request successful */
661 param = g_variant_new("(is)", result, handle);
662 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
663 BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL,
667 if (req_info == NULL) {
668 BT_ERR("OTP Write Request is not found!!");
672 if (req_info->context == NULL)
675 out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
676 handle, __get_handle_length(handle), TRUE, NULL, NULL);
677 g_dbus_method_invocation_return_value(req_info->context,
678 g_variant_new("(iv)", result, out_param1));
680 _bt_delete_request_list(req_info->req_id);
684 g_variant_unref(value);
686 g_clear_error(&error);
694 static void __bt_otp_send_indication_event(bt_otp_notification_info *info,
695 unsigned char *buffer, int len, int result)
700 otp_data = g_variant_new_from_data((const GVariantType*)"ay",
701 buffer, len, TRUE, NULL, NULL);
703 BT_DBG("Send Indication event to sender");
704 param = g_variant_new("(is@ay)", result, info->handle, otp_data);
705 _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
706 BLUETOOTH_EVENT_OTP_INDICATION,
709 /* Remove info from list */
710 __bt_otp_remove_notification_info(info);
713 static bool __bt_otp_indication_timeout_cb(gpointer user_data)
716 handle = (char *) user_data;
717 bt_otp_notification_info *info = NULL;
719 info = __bt_otp_get_notification_info(handle);
721 BT_DBG("Activation timer Expired [Server] [%s]", info->handle);
722 __bt_otp_send_indication_event(info, NULL, 0, BLUETOOTH_ERROR_INTERNAL);
728 int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle,
729 unsigned char *param, int length)
731 GVariantBuilder *builder1;
734 GVariantBuilder *builder2;
736 bt_otp_notification_info *info = NULL;
737 GDBusConnection *conn;
738 char *charc_handle = NULL;
743 BT_CHECK_PARAMETER(handle, return);
744 BT_CHECK_PARAMETER(sender, return);
745 BT_CHECK_PARAMETER(param, return);
747 conn = _bt_gdbus_get_system_gconn();
748 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
750 BT_DBG("OTP Write Characteristic value handle [%s] data length [%d]", handle, length);
751 /* Check if activation is ongoing for the same Remote Server */
753 info = __bt_otp_get_notification_info(handle);
754 if (info && info->notification_timeout_id > 0) {
755 BT_ERR("Write Request is already ongoing in remote server");
756 return BLUETOOTH_ERROR_IN_PROGRESS;
759 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
761 for (i = 0; i < length; i++)
762 g_variant_builder_add(builder1, "y", param[i]);
764 val = g_variant_new("ay", builder1);
765 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
767 g_variant_builder_add(builder2, "{sv}", "offset",
768 g_variant_new_uint16(offset));
770 options = g_variant_new("a{sv}", builder2);
772 charc_handle = g_strdup(handle);
774 /* Activate Control Point */
775 g_dbus_connection_call(conn,
780 g_variant_new("(@ay@a{sv})",
783 G_DBUS_CALL_FLAGS_NONE,
785 (GAsyncReadyCallback)__bt_otp_write_request_cb,
786 (gpointer)charc_handle);
788 g_variant_builder_unref(builder1);
789 g_variant_builder_unref(builder2);
792 info = g_malloc0(sizeof(bt_otp_notification_info));
793 info->handle = g_strdup(handle);
794 info->sender = g_strdup(sender);
795 otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
797 info->req_id = request_id;
798 /* Set timeout only for cp charc */
799 info->notification_timeout_id = g_timeout_add(BT_INDICATION_TIMEOUT_MAX,
800 (GSourceFunc)__bt_otp_indication_timeout_cb, (gpointer)info->handle);
803 return BLUETOOTH_ERROR_NONE;
806 void _bt_otp_check_indication(const char *path, GVariant *msg)
808 bt_otp_notification_info *info = NULL;
809 unsigned char *buffer = NULL;
812 GVariant *value = NULL;
815 info = __bt_otp_get_notification_info((char *)path);
819 if (info->notification_timeout_id > 0)
820 g_source_remove(info->notification_timeout_id);
822 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
825 len = g_variant_get_size(value);
826 BT_DBG("Indication data from Server len[%d]", len);
828 buffer = (unsigned char *)g_variant_get_data(value);
830 for (i = 0; i < len; i++)
831 BT_DBG("%.2x", buffer[i]);
834 /* Send Indication & info removed internally */
835 __bt_otp_send_indication_event(info, buffer, len, BLUETOOTH_ERROR_NONE);
837 g_variant_unref(value);
839 BT_ERR("No Indication data from Server");
840 /* Send Error Indication & info removed internally */
841 __bt_otp_send_indication_event(info, NULL, 0, BLUETOOTH_ERROR_INTERNAL);
847 int _bt_otp_connect_otc(int req_id, const bluetooth_device_address_t *bd_addr)
849 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
850 gchar *device_path = NULL;
851 GDBusProxy *device_proxy = NULL;
852 GDBusConnection *conn;
853 int ret = BLUETOOTH_ERROR_NONE;
854 GVariant *result = NULL;
857 BT_CHECK_PARAMETER(bd_addr, return);
859 _bt_convert_addr_type_to_string(device_address,
860 (unsigned char *)bd_addr->addr);
862 conn = _bt_gdbus_get_system_gconn();
863 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
865 device_path = _bt_get_device_object_path(device_address);
866 if (device_path == NULL) {
867 BT_DBG("device_path NULL");
868 ret = BLUETOOTH_ERROR_INTERNAL;
872 retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
874 device_proxy = g_dbus_proxy_new_sync(conn,
875 G_DBUS_PROXY_FLAGS_NONE,
877 device_path, BT_DEVICE_INTERFACE,
880 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
882 result = g_dbus_proxy_call_sync(device_proxy, "ConnectOtc",
884 G_DBUS_CALL_FLAGS_NONE,
889 if (result == NULL) {
891 g_dbus_error_strip_remote_error(err);
892 BT_ERR("OTC Connect Error: %s\n", err->message);
893 if (g_strcmp0(err->message, "Already Exists") == 0)
894 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
896 ret = BLUETOOTH_ERROR_INTERNAL;
900 g_variant_unref(result);
903 g_object_unref(device_proxy);
907 int _bt_otp_disconnect_otc(const bluetooth_device_address_t *bd_addr)
909 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
910 gchar *device_path = NULL;
911 GError *error = NULL;
912 GDBusProxy *device_proxy = NULL;
913 GDBusProxy *adapter_proxy;
914 GDBusConnection *conn;
915 int ret = BLUETOOTH_ERROR_NONE;
917 BT_CHECK_PARAMETER(bd_addr, return);
919 _bt_convert_addr_type_to_string(device_address,
920 (unsigned char *)bd_addr->addr);
922 conn = _bt_gdbus_get_system_gconn();
923 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
925 adapter_proxy = _bt_get_adapter_proxy();
926 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
928 device_path = _bt_get_device_object_path(device_address);
929 if (device_path == NULL) {
930 BT_DBG("device_path NULL");
931 return BLUETOOTH_ERROR_INTERNAL;
934 retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
936 device_proxy = g_dbus_proxy_new_sync(conn,
937 G_DBUS_PROXY_FLAGS_NONE,
943 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
945 g_dbus_proxy_call_sync(device_proxy, "DisconnectOtc",
947 G_DBUS_CALL_FLAGS_NONE,
953 BT_ERR("DisconnectOtc Call Error %s[%s]",
954 error->message, device_address);
956 g_object_unref(device_proxy);
957 return BLUETOOTH_ERROR_INTERNAL;
961 g_object_unref(device_proxy);