From ec66ca2084d7b11d750104cc9bf8adb94525c8ea Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Mon, 4 Jul 2016 01:18:20 -0400 Subject: [PATCH] [Adapt:Bluez HAL] Implement Create and Remove Bond This patch handled Create and Remove Bond methods in Bluez HAL. Note: Adapter Agent support will be added in subsequent patch. Change-Id: I0db972dbca52360a861f1c06c6f31131a0ae1e88 Signed-off-by: Anupam Roy --- bt-oal/bluez_hal/CMakeLists.txt | 1 + bt-oal/bluez_hal/src/bt-hal-bluetooth.c | 7 +- bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c | 331 ++++++++++++++++++++++ bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h | 46 +++ 4 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c create mode 100644 bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h diff --git a/bt-oal/bluez_hal/CMakeLists.txt b/bt-oal/bluez_hal/CMakeLists.txt index 6d6f284..eb2a75d 100644 --- a/bt-oal/bluez_hal/CMakeLists.txt +++ b/bt-oal/bluez_hal/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(bluetooth.default C) SET(SRCS ./src/bt-hal-bluetooth.c ./src/bt-hal-adapter-dbus-handler.c +./src/bt-hal-device-dbus-handler.c ./src/bt-hal-dbus-common-utils.c ./src/bt-hal-event-receiver.c ./src/bt-hal-utils.c diff --git a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c index 0f5154e..ac4ca98 100644 --- a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c +++ b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c @@ -31,6 +31,7 @@ #include "bt-hal-utils.h" #include +#include #define enum_prop_to_hal(prop, hal_prop, type) do { \ static type e; \ @@ -157,7 +158,8 @@ static int cancel_discovery(void) static int create_bond(const bt_bdaddr_t *bd_addr, int transport) { - return BT_STATUS_UNSUPPORTED; + DBG("+"); + return _bt_hal_device_create_bond(bd_addr); } static int cancel_bond(const bt_bdaddr_t *bd_addr) @@ -167,7 +169,8 @@ static int cancel_bond(const bt_bdaddr_t *bd_addr) static int remove_bond(const bt_bdaddr_t *bd_addr) { - return BT_STATUS_UNSUPPORTED; + DBG("+"); + return _bt_hal_device_remove_bond(bd_addr); } static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept, diff --git a/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c b/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c new file mode 100644 index 0000000..2ab3f3f --- /dev/null +++ b/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c @@ -0,0 +1,331 @@ +/* + * BLUETOOTH HAL + * + * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved. + * + * Contact: Anupam Roy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* BT HAL Headers */ +#include "bt-hal.h" +#include "bt-hal-log.h" +#include "bt-hal-msg.h" +#include "bt-hal-internal.h" +#include "bt-hal-event-receiver.h" +#include "bt-hal-dbus-common-utils.h" + +#include "bt-hal-adapter-dbus-handler.h" +#include "bt-hal-device-dbus-handler.h" +#include "bt-hal-event-receiver.h" + +/* Forward Delcaration */ +static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data); + +static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res, + gpointer user_data); + +int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr) +{ + GDBusProxy *proxy; + char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 }; + int transport = 0; + + GDBusConnection *conn; + char *device_path = NULL; + GDBusProxy *adapter_proxy; + GError *error = NULL; + struct hal_ev_bond_state_changed ev; + memset(&ev, 0, sizeof(ev)); + DBG("+"); + + DBG("Transport [%d] Add[0x%x] [0x%x][0x%x][0x%x][0x%x][0x%x]", transport, bd_addr->address[0], bd_addr->address[1], + bd_addr->address[2], bd_addr->address[3], + bd_addr->address[4], bd_addr->address[5]); + conn = _bt_get_system_gconn(); + if (!conn) { + DBG("Could not get DBUS connection!"); + return BT_STATUS_FAIL; + } + + _bt_convert_addr_type_to_string(address, bd_addr->address); + device_path = _bt_get_device_object_path(address); + + if (device_path == NULL) { + ERR("No searched device, attempt to create device"); + GVariant *ret = NULL; + adapter_proxy = _bt_get_adapter_proxy(); + if (!adapter_proxy) { + ERR("Could not get Adapter Proxy"); + return BT_STATUS_FAIL; + } + + ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice", + g_variant_new("(s)", address), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (error != NULL) { + ERR("CreateDevice Fail: %s", error->message); + g_clear_error(&error); + } + if (ret) + g_variant_unref(ret); + device_path = _bt_get_device_object_path(address); + + if (device_path == NULL) { + ERR("Device path is still not created!!"); + return BT_STATUS_FAIL; + } else { + DBG("Device_path is created[%s]", device_path); + } + } + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_HAL_BLUEZ_NAME, + device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL); + + g_free(device_path); + if (!proxy) { + ERR("Could not get Device Proxy"); + return BT_STATUS_FAIL; + } + + g_dbus_proxy_call(proxy, "Pair", + g_variant_new("(y)", transport), + G_DBUS_CALL_FLAGS_NONE, + BT_HAL_MAX_DBUS_TIMEOUT, + NULL, + (GAsyncReadyCallback)__bt_bond_device_cb, + NULL); + + /* Prepare to send Bonding event event to HAL bluetooth */ + ev.status = BT_STATUS_SUCCESS; + ev.state = BT_BOND_STATE_BONDING; + + _bt_convert_addr_string_to_type(ev.bdaddr, address); + + handle_stack_msg event_cb = _bt_hal_get_stack_message_handler(); + if (event_cb) { + DBG("Sending HAL_EV_BOND_STATE_CHANGED event"); + event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev)); + } + + DBG("-"); + return BT_STATUS_SUCCESS; +} + +int _bt_hal_device_remove_bond(const bt_bdaddr_t *bd_addr) +{ + char *device_path = NULL; + GDBusProxy *adapter_proxy = NULL; + GDBusProxy *device_proxy = NULL; + GDBusConnection *conn; + GError *error = NULL; + GVariant *ret = NULL; + char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 }; + + DBG("Add[0x%x] [0x%x][0x%x][0x%x][0x%x][0x%x]", + bd_addr->address[0], bd_addr->address[1], + bd_addr->address[2], bd_addr->address[3], + bd_addr->address[4], bd_addr->address[5]); + + adapter_proxy = _bt_get_adapter_proxy(); + if (!adapter_proxy) { + ERR("Could not get Adapter Proxy"); + return BT_STATUS_FAIL; + } + + _bt_convert_addr_type_to_string(address, bd_addr->address); + + device_path = _bt_get_device_object_path(address); + + /* This is a special case, bluedroid always sends success to HAL even if device is already removed + whereas bluez sends BLUETOOTH_ERROR_NOT_PAIRED. However we will return Failure + in case of bluez*/ + if (device_path == NULL) { + ERR("No paired device"); + return BT_STATUS_FAIL; + } + + conn = _bt_get_system_gconn(); + if (conn == NULL) { + ERR("conn is NULL"); + return BT_STATUS_FAIL; + } + + + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_HAL_BLUEZ_NAME, + device_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL); + + if (device_proxy != NULL) { + + ret = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_HAL_DEVICE_INTERFACE, "Paired"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (error) { + ERR("Getting property failed: [%s]\n", error->message); + g_error_free(error); + return BT_STATUS_FAIL; + } else { + if (!ret) { + ERR("No paired device"); + g_object_unref(device_proxy); + return BT_STATUS_FAIL; + } + g_variant_unref(ret); + } + g_object_unref(device_proxy); + } + + g_dbus_proxy_call(adapter_proxy, "UnpairDevice", + g_variant_new("(o)", device_path), + G_DBUS_CALL_FLAGS_NONE, + BT_HAL_MAX_DBUS_TIMEOUT, + NULL, + (GAsyncReadyCallback)__bt_unbond_device_cb, + (gpointer)device_path); + + DBG("-"); + return BT_STATUS_SUCCESS; +} + +static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, + gpointer user_data) +{ + GError *err = NULL; + const char *device_path; + int result = BT_STATUS_SUCCESS; + struct hal_ev_bond_state_changed ev; + memset(&ev, 0, sizeof(ev)); + char dev_address[18]; + DBG("+"); + +#ifdef TIZEN_SYSPOPUP_SUPPORTED + /* Terminate ALL system popup */ + syspopup_destroy_all(); +#endif + + g_dbus_proxy_call_finish(proxy, res, &err); + device_path = g_dbus_proxy_get_object_path(proxy); + DBG("Device path: %s", device_path); + _bt_convert_device_path_to_address(device_path, dev_address); + DBG("Remote Device address [%s]", dev_address); + + if (err != NULL) { + g_dbus_error_strip_remote_error(err); + ERR("@@@Error occured in CreateBonding [%s]", err->message); + if (g_strrstr(err->message, "Already Exists")) { + DBG("Existing Bond, remove and retry"); + } else if (g_strrstr(err->message, "Authentication Rejected")) { + DBG("REJECTED"); + } else if (g_strrstr(err->message, "In Progress")) { + DBG("Bond in progress, cancel and retry"); + } else if (g_strrstr(err->message, "Authentication Failed")) { + DBG("Authentication Failed"); + result = BT_STATUS_AUTH_FAILURE; + } else if (g_strrstr(err->message, "Page Timeout")) { + DBG("Page Timeout"); + result = BT_STATUS_RMT_DEV_DOWN; + } else if (g_strrstr(err->message, BT_HAL_TIMEOUT_MESSAGE)) { + DBG("Timeout"); + } else if (g_strrstr(err->message, "Connection Timeout")) { + } else if (g_strrstr(err->message, "Authentication Timeout")) { + } else { + DBG("Default case: Pairing failed"); + result = BT_STATUS_AUTH_FAILURE; + } + } + + if (result == BT_STATUS_AUTH_FAILURE || + result == BT_STATUS_RMT_DEV_DOWN) { + DBG("Bonding Failed!!"); + } else { + DBG("Bonding Success!!"); + } + + /* Prepare to send event to HAL bluetooth */ + ev.status = result; + if (result == BT_STATUS_SUCCESS) + ev.state = BT_BOND_STATE_BONDED; + else + ev.state = BT_BOND_STATE_NONE; + + _bt_convert_addr_string_to_type(ev.bdaddr, dev_address); + + handle_stack_msg event_cb = _bt_hal_get_stack_message_handler(); + if (event_cb) { + DBG("Sending HAL_EV_BOND_STATE_CHANGED event"); + event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev)); + } + DBG("-"); +} + +static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res, + gpointer user_data) +{ + GError *err = NULL; + char *device_path = NULL; + char dev_address[18]; + int result = BT_STATUS_SUCCESS; + struct hal_ev_bond_state_changed ev; + memset(&ev, 0, sizeof(ev)); + DBG("+"); + + g_dbus_proxy_call_finish(proxy, res, &err); + + if (err != NULL) { + ERR("Error occured in RemoveBonding [%s]\n", err->message); + result = BT_STATUS_FAIL; + } + + g_error_free(err); + + /* Prepare to send event to HAL bluetooth */ + ev.status = result; + ev.state = BT_BOND_STATE_NONE; + + device_path = (char *)user_data; + _bt_convert_device_path_to_address(device_path, dev_address); + _bt_convert_addr_string_to_type(ev.bdaddr, dev_address); + + handle_stack_msg event_cb = _bt_hal_get_stack_message_handler(); + if (event_cb) { + DBG("Sending HAL_EV_BOND_STATE_CHANGED event"); + event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev)); + } + g_free(device_path); + DBG("-"); +} diff --git a/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h b/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h new file mode 100644 index 0000000..a619a83 --- /dev/null +++ b/bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h @@ -0,0 +1,46 @@ +/* Bluetooth-frwk + * + * Copyright (c) 20015 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Anupam Roy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#ifndef _BT_HAL_DEVICE_DBUS_HANDLER_H_ +#define _BT_HAL_DEVICE_DBUS_HANDLER_H_ + +#include +#include + +#include "bt-hal.h" +#include "bt-hal-log.h" +#include "bt-hal-msg.h" + +#include "bt-hal-event-receiver.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr); + +int _bt_hal_device_remove_bond(const bt_bdaddr_t *bd_addr); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _BT_HAL_DEVICE_DBUS_HANDLER_H_ */ -- 2.7.4