From f382c3c40e883640f995092c0e0ef83b6743efb4 Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Tue, 5 Jul 2016 14:30:57 -0400 Subject: [PATCH] [Adapt] Implement create and remove Bond API's This patch handles following 1/ Implement create and remove bond API's 2/ Implement bonding state machine Note: Currently bonding will not complete for the devices requiring following pairing operations. 1/ Devices requring Confirmation(numeric Comparison) 2/ Devices requesting PinCode 3/ Devices requesting DisplayPasskey etc. Pairing will be handled in subsequent patches. Change-Id: I425ac62619e8f1ed61612e1c5358e872cdf9affc Signed-off-by: Anupam Roy --- bt-oal/bluez_hal/src/bt-hal-bluetooth.c | 33 ++ bt-oal/oal-device-mgr.c | 9 +- .../services/bt-request-handler.c | 36 ++ .../services/bt-service-event-receiver.c | 5 + .../services/device/bt-service-core-device.c | 476 +++++++++++++++++++++ .../services/include/bt-service-core-device.h | 8 +- 6 files changed, 564 insertions(+), 3 deletions(-) diff --git a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c index a412b27..793e116 100644 --- a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c +++ b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c @@ -53,6 +53,7 @@ static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len); static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len); static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len); static void __bt_hal_handle_device_found_event(void *buf, uint16_t len); +static void __bt_hal_handle_bond_state_changed_event(void *buf, uint16_t len); static bool interface_ready(void) { @@ -529,6 +530,34 @@ static void __bt_hal_handle_remote_device_properties_event(void *buf, uint16_t l DBG("-"); } +static void __bt_hal_handle_bond_state_changed_event(void *buf, uint16_t len) +{ + + struct hal_ev_bond_state_changed *ev = (struct hal_ev_bond_state_changed *)buf; + bt_bdaddr_t bd_addr; + DBG("+"); + + memcpy(bd_addr.address, ev->bdaddr, 6); + /* BD address*/ + DBG("[0x%x]", bd_addr.address[0]); + DBG("[0x%x]", bd_addr.address[1]); + DBG("[0x%x]", bd_addr.address[2]); + DBG("[0x%x]", bd_addr.address[3]); + DBG("[0x%x]", bd_addr.address[4]); + DBG("[0x%x]", bd_addr.address[5]); + + DBG("Bonding State changed Status [0x%x]", ev->status); + DBG("Bonding State [0x%x]", ev->state); + + if (!bt_hal_cbacks->bond_state_changed_cb) { + ERR("HAL User bond_state_changed_callback is not set!!"); + return; + } + + bt_hal_cbacks->bond_state_changed_cb(ev->status, &bd_addr, ev->state); + DBG("-"); +} + static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len) { DBG("+"); @@ -553,6 +582,10 @@ static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len) DBG("Event: HAL_EV_REMOTE_DEVICE_PROPS"); __bt_hal_handle_remote_device_properties_event(buf, len); break; + case HAL_EV_BOND_STATE_CHANGED: + DBG("Event: HAL_EV_BOND_STATE_CHANGED:"); + __bt_hal_handle_bond_state_changed_event(buf, len); + break; default: DBG("Event Currently not handled!!"); break; diff --git a/bt-oal/oal-device-mgr.c b/bt-oal/oal-device-mgr.c index 54c910c..451a8de 100755 --- a/bt-oal/oal-device-mgr.c +++ b/bt-oal/oal-device-mgr.c @@ -99,7 +99,7 @@ oal_status_t device_create_bond(bt_address_t *addr, connection_type_e transport) API_TRACE("[%s]", bdt_bd2str(addr, &bdstr)); - res = blued_api->create_bond((bt_bdaddr_t *)addr, (unsigned char)transport); + res = blued_api->create_bond((bt_bdaddr_t *)addr, transport); if (res != BT_STATUS_SUCCESS) { BT_ERR("create_bond error: [%s]", status2string(res)); return convert_to_oal_status(res); @@ -138,11 +138,16 @@ void cb_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr, gsize size = 0; bdstr_t bdstr; + /*Below code is commented out for handling Get Bonded devices for BLuez case. + GetALl properties on a particular device interface can reyurn properties of + an unpaired or untrusted device. If We block the below event, Application + request (BT_GET_BONDED_DEVICES) will timeout on DBUS */ +#if 0 if(BT_STATUS_SUCCESS != status) { BT_ERR("[%s]status: %d", bdt_bd2str((bt_address_t*)bd_addr, &bdstr), status); return; } - +#endif BT_DBG("[%s]", bdt_bd2str((bt_address_t*)bd_addr, &bdstr)); dev_info = g_new0(remote_device_t, 1); memcpy(dev_info->address.addr, bd_addr->address, 6); diff --git a/bt-service-adaptation/services/bt-request-handler.c b/bt-service-adaptation/services/bt-request-handler.c index 3ee932c..661f2dd 100644 --- a/bt-service-adaptation/services/bt-request-handler.c +++ b/bt-service-adaptation/services/bt-request-handler.c @@ -533,6 +533,42 @@ int __bt_bluez_request(int function_name, result = _bt_set_alias(&address, local_name); break; } + case BT_BOND_DEVICE:{ + bluetooth_device_address_t address = { {0} }; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + result = _bt_bond_device(&address, BLUETOOTH_DEV_CONN_DEFAULT, out_param1); + + /* Save invocation */ + if (result == BLUETOOTH_ERROR_NONE) { + char * addr = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_addr_type_to_string(addr, address.addr); + BT_DBG("_bt_bond_device scheduled successfully! save invocation context"); + sender = (char*)g_dbus_method_invocation_get_sender(context); + _bt_save_invocation_context(context, result, sender, + function_name, (gpointer)addr); + } + break; + } + case BT_UNBOND_DEVICE: { + bluetooth_device_address_t address = { {0} }; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + result = _bt_unbond_device(&address, out_param1); + + /* Save invocation */ + if (result == BLUETOOTH_ERROR_NONE) { + char * addr = g_malloc0(BT_ADDRESS_STRING_SIZE); + _bt_convert_addr_type_to_string(addr, address.addr); + BT_DBG("_bt_unbond_device scheduled successfully! save invocation context"); + sender = (char*)g_dbus_method_invocation_get_sender(context); + _bt_save_invocation_context(context, result, sender, + function_name, (gpointer)addr); + } + break; + } default: BT_INFO("UnSupported function [%d]", function_name); result = BLUETOOTH_ERROR_NOT_SUPPORT; diff --git a/bt-service-adaptation/services/bt-service-event-receiver.c b/bt-service-adaptation/services/bt-service-event-receiver.c index bf30b5d..82067ee 100644 --- a/bt-service-adaptation/services/bt-service-event-receiver.c +++ b/bt-service-adaptation/services/bt-service-event-receiver.c @@ -94,6 +94,11 @@ void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize l if (device_cb) device_cb(event_type, event_data); break; + case OAL_EVENT_DEVICE_BONDING_SUCCESS: + case OAL_EVENT_DEVICE_BONDING_REMOVED: + case OAL_EVENT_DEVICE_BONDING_FAILED: + if (device_cb) + device_cb(event_type, event_data); default: BT_ERR("Unhandled Event: %d", event_type); break; diff --git a/bt-service-adaptation/services/device/bt-service-core-device.c b/bt-service-adaptation/services/device/bt-service-core-device.c index 21bd662..03d6828 100644 --- a/bt-service-adaptation/services/device/bt-service-core-device.c +++ b/bt-service-adaptation/services/device/bt-service-core-device.c @@ -46,11 +46,57 @@ #include #include +#define MAX_BOND_RETRY_COUNT 3 + +/* Bonding Info structure */ +typedef struct { + int result; + char *addr; + gboolean is_autopair; + unsigned short conn_type; + gboolean is_cancelled_by_user; + gboolean is_device_creating; + bluetooth_device_address_t *dev_addr; + bt_remote_dev_info_t *dev_info; +} bt_bond_data_t; + + +/* Bonding and Pairing Informations */ +bt_bond_data_t *trigger_bond_info; +bt_bond_data_t *trigger_unbond_info; + +typedef enum { + BT_DEVICE_BOND_STATE_NONE, + BT_DEVICE_BOND_STATE_CANCEL_DISCOVERY, + BT_DEVICE_BOND_STATE_DISCOVERY_CANCELLED, + BT_DEVICE_BOND_STATE_REMOVE_BONDING, + BT_DEVICE_BOND_STATE_REMOVED_BONDING, + BT_DEVICE_BOND_STATE_STARTED, + BT_DEVICE_BOND_STATE_WAIT_PROP, + BT_DEVICE_BOND_STATE_WAIT_DID +} bt_bond_state_e; + +typedef enum { + BT_DEVICE_BOND_INFO, + BT_DEVICE_UNBOND_INFO +} bt_bond_info_e; + +/* BT device bond state variable */ +static bt_bond_state_e bt_device_bond_state; +static int bond_retry_count; + /* Forward declaration */ static void __bt_device_event_handler(int event_type, gpointer event_data); static void __bt_device_remote_device_found_callback(gpointer event_data, gboolean is_ble); +static int __bt_device_handle_bond_state(void); +static void __bt_free_bond_info(uint8_t type); +static void __bt_device_handle_bond_completion_event(bt_address_t *bd_addr); +static void __bt_device_handle_bond_removal_event(bt_address_t *bd_addr); +static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_fail_event); +static void __bt_handle_ongoing_bond(bt_remote_dev_info_t *remote_dev_info); + void _bt_device_state_handle_callback_set_request(void) { _bt_service_register_event_handler_callback( @@ -73,6 +119,27 @@ void __bt_device_handle_pending_requests(int result, int service_function, continue; switch (service_function) { + case BT_BOND_DEVICE: + case BT_UNBOND_DEVICE: { + char *address = (char *)user_data; + if (strncmp((char*)req_info->user_data, address, BT_ADDRESS_STRING_SIZE)) { + BT_ERR("Unexpected: Info request pending for a different address!!"); + return; + } else { + BT_INFO("Found info request addr [%s]", (char*)req_info->user_data); + bluetooth_device_info_t dev_info; + memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t)); + _bt_convert_addr_string_to_type(dev_info.device_address.addr, + address); + out_param = g_array_new(FALSE, FALSE, sizeof(gchar)); + g_array_append_vals(out_param, &dev_info, + sizeof(bluetooth_device_info_t)); + _bt_service_method_return(req_info->context, out_param, result); + _bt_free_info_from_invocation_list(req_info); + g_array_free(out_param, TRUE); + } + break; + } case BT_GET_BONDED_DEVICE: { char rem_addr[BT_ADDRESS_STRING_SIZE]; char *address = req_info->user_data; @@ -199,6 +266,15 @@ static void __bt_device_remote_properties_callback(event_dev_properties_t *oal_d rem_info->manufacturer_data_len = 0; } + /* a. Check if bonding is on-going, if yes, we MUST update the bonding device properties */ + if (trigger_bond_info && !strcmp(trigger_bond_info->addr, rem_info->address)) { + BT_INFO("Bonding is ongoing, try update properties"); + if (!trigger_bond_info->dev_info) { + BT_INFO("Bonding device properties is NULL, Assigning rem_info"); + trigger_bond_info->dev_info = rem_info; + } + } + _bt_copy_remote_device(rem_info, &dev_info); _bt_service_print_dev_info(&dev_info); @@ -208,9 +284,203 @@ static void __bt_device_remote_properties_callback(event_dev_properties_t *oal_d __bt_device_handle_pending_requests(result, BT_GET_BONDED_DEVICE, (void *)&dev_info, sizeof(bluetooth_device_info_t)); + if (trigger_bond_info && !strcmp(trigger_bond_info->addr, rem_info->address)) { + BT_DBG("Bonding dev addr has matched with remote dev properties address [%s]", rem_info->address); + __bt_handle_ongoing_bond(trigger_bond_info->dev_info); + } + BT_DBG("-"); } +static void __bt_handle_ongoing_bond(bt_remote_dev_info_t *remote_dev_info) +{ + GVariant *param = NULL; + BT_DBG("+"); + + if (remote_dev_info->name + && remote_dev_info->address + && remote_dev_info->uuids) { + BT_INFO("All properties updated, time to send bonding finished event"); + GVariant *uuids = NULL; + GVariantBuilder *builder = NULL; + GVariant *manufacturer_data; + int i = 0; + builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + for (i=0; i < remote_dev_info->uuid_count; i++) { + g_variant_builder_add(builder, "s", + remote_dev_info->uuids[i]); + } + uuids = g_variant_new("as", builder); + g_variant_builder_unref(builder); + manufacturer_data = g_variant_new_from_data((const GVariantType *)"ay", + remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len, + TRUE, NULL, NULL); + + param = g_variant_new("(isunsbub@asn@ay)", + BLUETOOTH_ERROR_NONE, + remote_dev_info->address, + remote_dev_info->class, + remote_dev_info->rssi, + remote_dev_info->name, + remote_dev_info->paired, + remote_dev_info->connected, + remote_dev_info->trust, + uuids, + remote_dev_info->manufacturer_data_len, + manufacturer_data); + /* Send the event to application */ + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_BONDING_FINISHED, + param); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + /* TODO Free pairing Info*/ + } else { + BT_INFO("Lets wait for more remote device properties"); + } +} + +static void __bt_device_handle_bond_completion_event(bt_address_t *bd_addr) +{ + gchar address[BT_ADDRESS_STR_LEN]; + bluetooth_device_address_t dev_addr; + BT_INFO("+"); + /* Tizen does not propagate incoming bond complete event to app */ + if (trigger_bond_info == NULL) { + /* Send reply */ + BT_DBG("trigger_bond_info == NULL"); + return; + } + + _bt_convert_addr_type_to_string(address, bd_addr->addr); + if (g_strcmp0(trigger_bond_info->addr, address)) { + BT_DBG("Bonding address= [%s] is different from requested address =[%s]", + address, trigger_bond_info->addr); + return; + } + + BT_INFO("Bonding successfully completed"); + /* TODO: Bonding state will be cleaned up & BONDING FINISHED EVENT + will be sent only when Properties are fetched from stack + Till that time lets not free trigger_bond_info */ + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_NONE, BT_BOND_DEVICE, + trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE); + + _bt_convert_addr_string_to_type(dev_addr.addr, + trigger_bond_info->addr); + _bt_device_get_bonded_device_info(&dev_addr); + BT_INFO("-"); +} + +/********************************************************************************************** +* Bond removal event can be triggered for following reasons - +* a. If Bonding procedure if failed (for Auth failed, Page timeout, cancelled by user etc) +* b. If Application requests for explicitly removing the bond +* c. When application attempt to create bond,bond is removed first which triggers this event +* c. is in-line with Bluedroid bond create\emoval architecture +*********************************************************************************************/ +static void __bt_device_handle_bond_removal_event(bt_address_t *bd_addr) +{ + BT_INFO("+"); + if (trigger_unbond_info) { + BT_INFO("Bond removal request successfully handled, return DBUS and send event"); + GVariant *param = NULL; + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_NONE, BT_UNBOND_DEVICE, + trigger_unbond_info->addr, BT_ADDRESS_STRING_SIZE); + param = g_variant_new("(is)", BLUETOOTH_ERROR_NONE, trigger_unbond_info->addr); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED, + param); + __bt_free_bond_info(BT_DEVICE_UNBOND_INFO); + /* TODO Free pairing info*/ + } else if (trigger_bond_info) { + __bt_device_handle_bond_state(); + } + BT_INFO("-"); +} + +static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_fail_event) +{ + BT_INFO("+"); + oal_status_t status = bond_fail_event->status; + BT_INFO("Bonding failed, reason: %d", status); + + switch(status) { + case OAL_STATUS_RMT_DEVICE_DOWN: + { + if (trigger_bond_info) { + BT_INFO("OAL_STATUS_RMT_DEVICE_DOWN:Lets retry bonding!! retry count [%d]", + bond_retry_count); + int ret = OAL_STATUS_SUCCESS; + if (bond_retry_count < MAX_BOND_RETRY_COUNT) { + ret = device_create_bond((bt_address_t *)trigger_bond_info->dev_addr, BLUETOOTH_DEV_CONN_DEFAULT); + bond_retry_count++; + } else { + BT_ERR("Create Bond failed MAX_BOND_RETRY_COUNT TIMES!!"); + } + if (ret != OAL_STATUS_SUCCESS || bond_retry_count >= MAX_BOND_RETRY_COUNT) { + BT_ERR("Create Bond procedure could not suceed"); + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE, + trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + /* TODO Free pairing info */ + bond_retry_count = 0; + } + } + break; + } + case OAL_STATUS_AUTH_FAILED: + { + /*TODO Auto pairing status set & ignore auto pairing logics can be done at this point. + To be considered later*/ + int result = BLUETOOTH_ERROR_INTERNAL; + BT_INFO("BT_OPERATION_STATUS_AUTH_FAILED"); + if (trigger_bond_info) { + BT_ERR("Create Bond procedure could not suceed, check if cancelled by User"); + if (trigger_bond_info->is_cancelled_by_user) { + BT_ERR("Bonding is cancelled by user"); + result = BLUETOOTH_ERROR_CANCEL_BY_USER; + } + __bt_device_handle_pending_requests(result, BT_BOND_DEVICE, + trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + /* TODO Free pairing info */ + } + break; + } + case OAL_STATUS_INTERNAL_ERROR: + { + BT_INFO("OAL_STATUS_INTERNAL_ERROR"); + if (trigger_unbond_info) { + BT_INFO("Bond removal request failed, return DBUS and send event"); + GVariant *param = NULL; + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_UNBOND_DEVICE, + trigger_unbond_info->addr, BT_ADDRESS_STRING_SIZE); + param = g_variant_new("(is)", BLUETOOTH_ERROR_INTERNAL, trigger_unbond_info->addr); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED, + param); + __bt_free_bond_info(BT_DEVICE_UNBOND_INFO); + /* TODO Free pairing info */ + } else if (trigger_bond_info) { + if (__bt_device_handle_bond_state()!= BLUETOOTH_ERROR_NONE) { + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE, + trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + /* TODO Free pairing info */ + } + } + break; + } + default: + { + BT_ERR("Unknown status of Bond failed event status [%d]", status); + break; + } + + } + BT_INFO("-"); +} + static void __bt_device_event_handler(int event_type, gpointer event_data) { int eventcheck = OAL_EVENT_DEVICE_PROPERTIES; @@ -232,6 +502,21 @@ static void __bt_device_event_handler(int event_type, gpointer event_data) __bt_device_remote_properties_callback((event_dev_properties_t *)event_data); break; } + case OAL_EVENT_DEVICE_BONDING_SUCCESS: { + BT_INFO("Bonding Success event Received"); + __bt_device_handle_bond_completion_event((bt_address_t *)event_data); + break; + } + case OAL_EVENT_DEVICE_BONDING_REMOVED: { + BT_INFO("Bonding Removed event Received"); + __bt_device_handle_bond_removal_event((bt_address_t *)event_data); + break; + } + case OAL_EVENT_DEVICE_BONDING_FAILED: { + BT_INFO("Bonding Failed event Received"); + __bt_device_handle_bond_failed_event((event_dev_bond_failed_t*) event_data); + break; + } default: BT_INFO("Unhandled event.."); } @@ -309,6 +594,96 @@ static void __bt_device_remote_device_found_callback(gpointer event_data, gboole BT_DBG("-"); } +static void __bt_free_bond_info(uint8_t type) +{ + BT_INFO("+"); + if (type == BT_DEVICE_BOND_INFO) { + if (trigger_bond_info) { + if (trigger_bond_info->addr) + g_free(trigger_bond_info->addr); + if (trigger_bond_info->dev_addr) + g_free(trigger_bond_info->dev_addr); + if (trigger_bond_info->dev_info) { + if (trigger_bond_info->dev_info->address) + g_free(trigger_bond_info->dev_info->address); + if (trigger_bond_info->dev_info->name) + g_free(trigger_bond_info->dev_info->name); + if (trigger_bond_info->dev_info->manufacturer_data) + g_free(trigger_bond_info->dev_info->manufacturer_data); + g_free(trigger_bond_info->dev_info); + } + g_free(trigger_bond_info); + trigger_bond_info = NULL; + } + } else { + if (trigger_unbond_info) { + if (trigger_unbond_info->addr) + g_free(trigger_unbond_info->addr); + if (trigger_unbond_info->dev_addr) + g_free(trigger_unbond_info->dev_addr); + if (trigger_unbond_info->dev_info) { + if (trigger_unbond_info->dev_info->address) + g_free(trigger_unbond_info->dev_info->address); + if (trigger_unbond_info->dev_info->name) + g_free(trigger_unbond_info->dev_info->name); + if (trigger_unbond_info->dev_info->manufacturer_data) + g_free(trigger_unbond_info->dev_info->manufacturer_data); + g_free(trigger_unbond_info->dev_info); + } + g_free(trigger_unbond_info); + trigger_unbond_info = NULL; + } + } +} + +static int __bt_device_handle_bond_state(void) +{ + BT_INFO("Current Bond state: %d", bt_device_bond_state); + int ret = OAL_STATUS_INTERNAL_ERROR; + + switch (bt_device_bond_state) { + case BT_DEVICE_BOND_STATE_CANCEL_DISCOVERY: + /*TODO:Bonding during discovery: Unhandled!!*/ + BT_INFO("Bonding during discovery: Unhandled!!"); + break; + case BT_DEVICE_BOND_STATE_DISCOVERY_CANCELLED: + /*TODO:Bonding during discovery: Unhandled!!*/ + BT_INFO("Bonding during discovery: Unhandled!!"); + break; + case BT_DEVICE_BOND_STATE_REMOVE_BONDING: + bt_device_bond_state = BT_DEVICE_BOND_STATE_REMOVED_BONDING; + ret = device_destroy_bond((bt_address_t *)trigger_bond_info->dev_addr); + if (ret != OAL_STATUS_SUCCESS) { + ret = __bt_device_handle_bond_state(); + } + break; + case BT_DEVICE_BOND_STATE_REMOVED_BONDING: + bt_device_bond_state = BT_DEVICE_BOND_STATE_NONE; + ret = device_create_bond((bt_address_t *)trigger_bond_info->dev_addr, BLUETOOTH_DEV_CONN_DEFAULT); + /* Bonding procedure was started but unfortunately could not complete. + Basically removed bonding was success, but create bond request could not proceed + So lets cleanup the context */ + if (ret != OAL_STATUS_SUCCESS) { + BT_ERR("Create Bond procedure could not suceed"); + __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE, + trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + /* TODO: Free pairing Info */ + } + break; + case BT_DEVICE_BOND_STATE_NONE: + BT_INFO("Create Bond failed!!"); + break; + default: + break; + } + + if (ret != OAL_STATUS_SUCCESS) + return BLUETOOTH_ERROR_INTERNAL; + else + return BLUETOOTH_ERROR_NONE; +} + int _bt_device_get_bonded_device_info(bluetooth_device_address_t *addr) { int result; @@ -345,3 +720,104 @@ int _bt_set_alias(bluetooth_device_address_t *device_address, const char *alias) BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } + +int _bt_bond_device(bluetooth_device_address_t *device_address, + unsigned short conn_type, GArray **out_param1) +{ + int result = BLUETOOTH_ERROR_NONE; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + bluetooth_device_info_t dev_info; + BT_DBG("+"); + + retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + /* If bonding or discovery already going on */ + if (trigger_bond_info || _bt_is_discovering()) { + BT_ERR("Device is buzy, bonding can not proceed now.."); + result = BLUETOOTH_ERROR_DEVICE_BUSY; + goto fail; + } + + /*TODO: If unbonding with same device going on */ + _bt_convert_addr_type_to_string(address, device_address->addr); + + trigger_bond_info = g_malloc0(sizeof(bt_bond_data_t)); + trigger_bond_info->addr = g_strdup(address); + trigger_bond_info->conn_type = conn_type; + trigger_bond_info->is_device_creating = TRUE; + trigger_bond_info->dev_addr = g_memdup(device_address, sizeof(bluetooth_device_address_t)); + trigger_bond_info->dev_info = NULL; + + /* Ready to initiate bonding */ + + /* In Tizen, we will first remove bond and then attempt to create bond to keep + consistency with bluedroid. Even if remove bond fails due to device not already + bonded, then straight away create bond is triggered. This is because, remove bond + is handled differently in bluedroid and bluez. In Bluez, if device is + already removed, remove bond call fails. + However in bluedroid, remove bond on already removed device returns success. So we will + handle the cases transparently*/ + bt_device_bond_state = BT_DEVICE_BOND_STATE_REMOVE_BONDING; + bond_retry_count = 0; + result = __bt_device_handle_bond_state(); + + if (result != BLUETOOTH_ERROR_NONE) + goto fail; + + BT_DBG("-"); + return result; + +fail: + memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t)); + memcpy(dev_info.device_address.addr, device_address->addr, + BLUETOOTH_ADDRESS_LENGTH); + + g_array_append_vals(*out_param1, &dev_info, + sizeof(bluetooth_device_info_t)); + __bt_free_bond_info(BT_DEVICE_BOND_INFO); + + BT_DBG("-"); + return result; +} + +int _bt_unbond_device(bluetooth_device_address_t *device_address, + GArray **out_param1) +{ + int result = OAL_STATUS_SUCCESS; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + bluetooth_device_info_t dev_info; + BT_INFO("+"); + + retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + _bt_convert_addr_type_to_string(address, device_address->addr); + + trigger_unbond_info = g_malloc0(sizeof(bt_bond_data_t)); + trigger_unbond_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE); + trigger_unbond_info->addr = g_strdup(address); + trigger_unbond_info->dev_addr = g_memdup(device_address, sizeof(bluetooth_device_address_t)); + + /* Check if Bonding is already going on, we should not abruptly remove bonding*/ + if (trigger_bond_info && strncmp(trigger_bond_info->addr, trigger_unbond_info->addr, BT_ADDRESS_STRING_SIZE) == 0) { + BT_ERR("Bonding with same device already ongoing"); + result = BLUETOOTH_ERROR_PERMISSION_DEINED; + goto fail; + } + + result = device_destroy_bond((bt_address_t *)device_address); + if (result != OAL_STATUS_SUCCESS) + goto fail; + + return result; + +fail: + memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t)); + _bt_convert_addr_string_to_type(dev_info.device_address.addr, + trigger_unbond_info->addr); + + g_array_append_vals(*out_param1, &dev_info, + sizeof(bluetooth_device_info_t)); + __bt_free_bond_info(BT_DEVICE_UNBOND_INFO); + + return result; +} diff --git a/bt-service-adaptation/services/include/bt-service-core-device.h b/bt-service-adaptation/services/include/bt-service-core-device.h index 674a67a..f981899 100755 --- a/bt-service-adaptation/services/include/bt-service-core-device.h +++ b/bt-service-adaptation/services/include/bt-service-core-device.h @@ -32,8 +32,14 @@ int _bt_device_get_bonded_device_info(bluetooth_device_address_t *addr); int _bt_set_alias(bluetooth_device_address_t *device_address, const char *alias); +int _bt_bond_device(bluetooth_device_address_t *device_address, + unsigned short conn_type, GArray **out_param1); + +int _bt_unbond_device(bluetooth_device_address_t *device_address, + GArray **out_param1); + #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /*_BT_SERVICE_CORE_ADAPTER_H_*/ +#endif /*_BT_SERVICE_CORE_DEVICE_H_*/ -- 2.7.4