diff options
author | Wootak Jung <wootak.jung@samsung.com> | 2020-10-28 09:01:10 +0900 |
---|---|---|
committer | Wootak Jung <wootak.jung@samsung.com> | 2020-10-29 13:47:27 +0900 |
commit | 61a32f92188ca46d506a9a8a5af95edd7ce4802b (patch) | |
tree | 06b75966454440186b995fd4dd63336eda2ba22a | |
parent | 7c2b9f1dca77a2648b029a79d832242b40c556af (diff) | |
download | bluetooth-61a32f92188ca46d506a9a8a5af95edd7ce4802b.tar.gz bluetooth-61a32f92188ca46d506a9a8a5af95edd7ce4802b.tar.bz2 bluetooth-61a32f92188ca46d506a9a8a5af95edd7ce4802b.zip |
Apply GATT function for TDS API
Change-Id: I065886e5aab498b0b0a64c53f0e11f7d25d3869f
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
-rw-r--r-- | include/bluetooth_private.h | 24 | ||||
-rw-r--r-- | src/bluetooth-common.c | 66 | ||||
-rw-r--r-- | src/bluetooth-tds.c | 467 |
3 files changed, 171 insertions, 386 deletions
diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h index c0bf50b..4192ee6 100644 --- a/include/bluetooth_private.h +++ b/include/bluetooth_private.h @@ -1061,30 +1061,6 @@ int _bt_tds_parse_transport_blocks(bt_tds_transport_block_list_s **info, char *d /** * @internal - * @brief Handles complete TDS specific data to be sent to application. - */ -void _bt_tds_send_complete_transport_data(int result, const char *address, char *data, int data_len); - -/** - * @internal - * @brief Send Result of TDS specific CCCD enabled event of Remote TDS provider. - */ -void _bt_tds_control_point_enabled_update(int result, const char *remote_address); - -/** - * @internal - * @brief Send Result of TDS control point activate ACK event. - */ -void _bt_tds_control_point_activation_result_update(int result, const char *remote_address); - -/** - * @internal - * @brief Send TDS Indication response from remote TDS provider. - */ -void _bt_tds_control_point_indication_response_update(const char *address, bluetooth_tds_indication_res_t *info); - -/** - * @internal * @brief Sends GATT primary service status changed of Remote Provider. */ void _bt_tds_check_service_changed(char *address, bt_gatt_service_change_t *service_change); diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c index 2764d7e..0a45a48 100644 --- a/src/bluetooth-common.c +++ b/src/bluetooth-common.c @@ -1441,9 +1441,6 @@ static bool __bt_need_to_handle(int event) case BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED: case BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED: case BLUETOOTH_EVENT_GATT_SERVER_ATT_MTU_CHANGED: - case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT: - case BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED: - case BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION: case BLUETOOTH_EVENT_OTP_READ_CHAR_VAL: case BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED: case BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL: @@ -2531,6 +2528,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us /*HRP Server*/ __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, TRUE); + /* TDS Seeker */ + _bt_tds_update_seeker_connection_state_changed(param->result, device_addr, TRUE); + if (event_index >= 0) cb = bt_event_slot_container[event_index].callback; if (cb) @@ -2561,6 +2561,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us /*HRP Server*/ __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, FALSE); + /* TDS Seeker */ + _bt_tds_update_seeker_connection_state_changed(param->result, device_addr, FALSE); + if (event_index >= 0) cb = bt_event_slot_container[event_index].callback; if (cb) @@ -3560,63 +3563,6 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us free(device_addr); break; } - case BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED: { - BT_DBG("BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED"); /* LCOV_EXCL_LINE */ - bluetooth_tds_transport_data_info_t *info = NULL; - bluetooth_device_address_t *addr = NULL; - - if (_bt_get_error_code(param->result) == BT_ERROR_NONE) { - info = (bluetooth_tds_transport_data_info_t *)(param->param_data); - _bt_convert_address_to_string(&device_addr, &info->device_address); - _bt_tds_send_complete_transport_data(_bt_get_error_code(param->result), device_addr, - info->data, info->data_length); - } else { - BT_ERR("TDS Complete data Read request failed!!!"); - addr = (bluetooth_device_address_t *)(param->param_data); - _bt_convert_address_to_string(&device_addr, addr); - _bt_tds_send_complete_transport_data(_bt_get_error_code(param->result), device_addr, - NULL, 0); - } - BT_DBG("TDS Complete data blocks received: Remote provider address [%s]", device_addr); - if (device_addr != NULL) - free(device_addr); - break; - } - case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT: { - BT_DBG("BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT"); /* LCOV_EXCL_LINE */ - _bt_convert_address_to_string(&device_addr, - (bluetooth_device_address_t *)(param->param_data)); - - _bt_tds_control_point_activation_result_update(_bt_get_error_code(param->result), device_addr); - - if (device_addr != NULL) - free(device_addr); - break; - } - case BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED: { - BT_DBG("BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED"); /* LCOV_EXCL_LINE */ - _bt_convert_address_to_string(&device_addr, - (bluetooth_device_address_t *)(param->param_data)); - - _bt_tds_control_point_enabled_update(_bt_get_error_code(param->result), device_addr); - - if (device_addr != NULL) - free(device_addr); - break; - } case BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION: { - BT_DBG("BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION"); /* LCOV_EXCL_LINE */ - bluetooth_tds_indication_res_t *tds_act_ind_res = NULL; - tds_act_ind_res = (bluetooth_tds_indication_res_t *)(param->param_data); - - _bt_convert_address_to_string(&device_addr, &tds_act_ind_res->rem_addr); - - BT_ERR("Address [%s]", device_addr); - _bt_tds_control_point_indication_response_update(device_addr, tds_act_ind_res); - - if (device_addr != NULL) - free(device_addr); - break; - } case BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED: { bt_otp_server_state_changed_cb cb = bt_event_slot_container[event_index].callback; bool *status = (bool *)(param->param_data); diff --git a/src/bluetooth-tds.c b/src/bluetooth-tds.c index e31a3c4..2a665a6 100644 --- a/src/bluetooth-tds.c +++ b/src/bluetooth-tds.c @@ -32,9 +32,11 @@ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \ } -#define BT_TDS_SERVICE_UUID "00001824-0000-1000-8000-00805f9b34fb" -#define BT_TDS_CONTROL_POINT_UUID "00002abc-0000-1000-8000-00805f9b34fb" -#define BT_TDS_USER_DATA_DESCRIPTOR "00002a56-0000-1000-8000-00805f9b34fb" +#define BT_TDS_SERVICE_UUID "1824" +#define BT_TDS_CONTROL_POINT_UUID "2abc" +#define BT_TDS_CONTROL_POINT_CFG_UUID "2902" +#define BT_TDS_USER_CHARACTERISTIC_UUID "2af6" +#define BT_TDS_USER_CHARACTERISTIC_DESC_UUID "2a56" typedef struct { unsigned int tds_handle; @@ -56,19 +58,20 @@ typedef struct { const void *complete_data_callback; /* Callback for receiving complete TDS data block */ void *complete_data_cb_user_data; /* User data for complete TDS data block callback */ - char *tds_service_handle; /* TDS Primary Service Handle */ - char *tds_control_point; /* TDS Control Point characteristic handle */ - char *tds_control_point_cccd; /* TDS Control Point CCCD handle */ - char *tds_user_data_desciptor; /* TDS User descriptor handle: This will store the Entire TDS block data in GATT Server */ - bool cccd_enabled; /* TDS Control Point CCCD is enabled or not */ - bool tds_activation_ongoing; /* TDS Actvation is ongoing or not */ + void *control_point_act_cb; /* TDS Control Point Activation Response callback */ void *control_point_act_user_data; /* User data for TDS Control Point Activation Response callback*/ - unsigned char *activation_data; /* TDS Activation data */ - int data_len; + int data_len; /* TDS Activation data length */ + + bt_gatt_client_h client; /* GATT Client */ + bt_gatt_h tds_svc; /* GATT TDS service */ + bt_gatt_h control_point_chr; /* GATT Control Point characterisitic */ + bt_gatt_h control_point_chr_cccd; /* GATT Control Point characteristic CCCD */ + bt_gatt_h user_chr; /* GATT User characterisitic */ + bt_gatt_h user_chr_desc; /* GATT User characterisitic descriptor */ } bt_tds_seeker_s; gboolean tds_provider_registered = FALSE; @@ -385,8 +388,7 @@ void _bt_tds_check_service_changed(char *address, bt_gatt_service_change_t *serv BT_DBG("GATT Service [%s]", service_change->svc_path); if (seeker_s) { if (service_change->change_type == BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_REMOVE) { - if (seeker_s->tds_service_handle && - g_strcmp0(seeker_s->tds_service_handle, service_change->svc_path) == 0) { + if (seeker_s->tds_svc && g_strcmp0(service_change->svc_path, BT_TDS_SERVICE_UUID) == 0) { BT_ERR("TDS Primary Service removed abnormally from Remote Provider [%s]", address); __bt_tds_reset_seeker_data(seeker_s); } @@ -406,165 +408,6 @@ void _bt_tds_check_service_changed(char *address, bt_gatt_service_change_t *serv BT_DBG("-"); } -void _bt_tds_send_complete_transport_data(int result, const char *address, char *data, int data_len) -{ - bt_tds_seeker_s *seeker_s = NULL; - - if (!address) { - BT_ERR("Abnormal Result!!"); - return; - } - - seeker_s = _bt_tds_seeker_find(address); - - if (seeker_s && (seeker_s)->complete_data_callback) { - BT_DBG("Complete TDS Data recv callback is set by app"); - - if (result == BT_ERROR_NONE) { - bt_tds_transport_block_list_s *info = g_malloc0(sizeof(bt_tds_transport_block_list_s)); - - if (_bt_tds_parse_transport_blocks(&info, data, data_len) == BT_ERROR_NONE) { - ((bt_tds_seeker_complete_transport_data_cb)((seeker_s)->complete_data_callback))(result, - address, info, - (seeker_s)->complete_data_cb_user_data); - } else { - BT_ERR("Error parsing data blocks"); - ((bt_tds_seeker_complete_transport_data_cb)((seeker_s)->complete_data_callback))(result, - address, NULL, - (seeker_s)->complete_data_cb_user_data); - } - __bt_tds_free_transport_data(info); - } else { - BT_ERR("TDS Data read failed!!"); - ((bt_tds_seeker_complete_transport_data_cb)((seeker_s)->complete_data_callback))(result, - address, NULL, - (seeker_s)->complete_data_cb_user_data); - } - } -} - -void _bt_tds_control_point_indication_response_update(const char *address, bluetooth_tds_indication_res_t *info) -{ - bt_tds_seeker_s *seeker_s = NULL; - - if (!address) { - BT_ERR("Abnormal Result!!"); - return; - } - - seeker_s = _bt_tds_seeker_find(address); - int result = BT_ERROR_NONE; - int k; - - if (seeker_s) { - BT_DBG("TDS Control point Activation Indication Response"); - BT_DBG("Data length [%d]", info->tds_data.length); - BT_DBG("Address[%s]", address); - - /* DEBUG */ - for (k = 0; k < info->tds_data.length; k++) - BT_DBG("Data[%d] [0x%x]", k, info->tds_data.data[k]); - - if (seeker_s->tds_activation_ongoing == true) { - (seeker_s)->tds_activation_ongoing = false; - - if (info->tds_data.length < 2) - result = BT_ERROR_OPERATION_FAILED; - else { - if (info->tds_data.data[1] == 0x00) { - BT_DBG("Provider has enabled transport"); - result = BT_ERROR_NONE; - } else - result = BT_ERROR_OPERATION_FAILED; - } - - if ((seeker_s)->control_point_act_cb) - ((bt_tds_control_point_activation_indication_cb)((seeker_s)->control_point_act_cb))(result, - address, info->tds_data.data, info->tds_data.length, (seeker_s)->control_point_act_user_data); - g_free(seeker_s->activation_data); - seeker_s->activation_data = NULL; - } - } -} - -void _bt_tds_control_point_activation_result_update(int result, const char *remote_address) -{ - bt_tds_seeker_s *seeker_s = NULL; - if (!remote_address) { - BT_ERR("Abnormal Result!!"); - return; - } - seeker_s = _bt_tds_seeker_find(remote_address); - - if (seeker_s) { - BT_DBG("TDS Control point Activation response [%d] address [%s]", result, remote_address); - - if ((seeker_s)->tds_activation_ongoing == true) { - /* Send Pending Activation Request callback with error */ - if (result != BT_ERROR_NONE) { - (seeker_s)->tds_activation_ongoing = false; - if ((seeker_s)->control_point_act_cb) - ((bt_tds_control_point_activation_indication_cb)((seeker_s)->control_point_act_cb))(BT_ERROR_OPERATION_FAILED, - remote_address, NULL, 0, (seeker_s)->control_point_act_user_data); - g_free(seeker_s->activation_data); - seeker_s->activation_data = NULL; - return; - } else - BT_DBG("TDS Activation request successfully accepted by Provider, wait for Indication"); - } else - BT_DBG("TDS Control point activation request is not ongoing"); - } -} - -void _bt_tds_control_point_enabled_update(int result, const char *remote_address) -{ - bt_tds_seeker_s *seeker_s = NULL; - if (!remote_address) { - BT_ERR("Abnormal Result!!"); - return; - } - seeker_s = _bt_tds_seeker_find(remote_address); - int ret = BT_ERROR_NONE; - bluetooth_device_address_t addr_hex = { {0,} }; - _bt_convert_address_to_hex(&addr_hex, remote_address); - - if (seeker_s) { - BT_DBG("TDS Control point Enable result [%d] address [%s]", result, remote_address); - - /* Send Pending Activation Request callback with error */ - if (result != BT_ERROR_NONE) { - (seeker_s)->tds_activation_ongoing = false; - - if ((seeker_s)->control_point_act_cb) - ((bt_tds_control_point_activation_indication_cb)((seeker_s)->control_point_act_cb))(BT_ERROR_OPERATION_FAILED, - remote_address, NULL, 0, (seeker_s)->control_point_act_user_data); - - g_free(seeker_s->activation_data); - seeker_s->activation_data = NULL; - return; - } else { - BT_DBG("TDS Control Point enabled successfully!!"); - seeker_s->cccd_enabled = true; - ret = _bt_get_error_code(bluetooth_tds_activate_control_point(&addr_hex, - seeker_s->tds_control_point, seeker_s->activation_data, - seeker_s->data_len)); - if (ret != BT_ERROR_NONE) { - (seeker_s)->tds_activation_ongoing = false; - - if ((seeker_s)->control_point_act_cb) - ((bt_tds_control_point_activation_indication_cb)((seeker_s)->control_point_act_cb))(BT_ERROR_OPERATION_FAILED, - remote_address, NULL, 0, (seeker_s)->control_point_act_user_data); - - if (seeker_s->activation_data) { - g_free(seeker_s->activation_data); - seeker_s->activation_data = NULL; - } - } - BT_DBG("Activation request sent, wait for response and Indication"); - } - } -} - int _bt_tds_parse_transport_blocks(bt_tds_transport_block_list_s **info, char *data, int data_len) { @@ -645,19 +488,6 @@ int _bt_tds_parse_transport_blocks(bt_tds_transport_block_list_s **info, static void __bt_tds_reset_seeker_data(bt_tds_seeker_s *seeker) { - - g_free((seeker)->tds_control_point); - (seeker)->tds_control_point = NULL; - - g_free((seeker)->tds_control_point_cccd); - (seeker)->tds_control_point_cccd = NULL; - - g_free((seeker)->tds_user_data_desciptor); - (seeker)->tds_user_data_desciptor = NULL; - - g_free((seeker)->tds_service_handle); - (seeker)->tds_service_handle = NULL; - g_free((seeker)->activation_data); (seeker)->activation_data = NULL; @@ -685,9 +515,9 @@ void _bt_tds_update_seeker_connection_state_changed(int result, __bt_tds_reset_seeker_data(seeker_s); bluetooth_gatt_set_service_change_watcher(&addr_hex, false); - if ((seeker_s)->connection_callback) - ((bt_tds_seeker_connection_state_changed_cb)(seeker_s)->connection_callback) - (result, remote_address, seeker_s, connected, (seeker_s)->conn_cb_user_data); + if (seeker_s->connection_callback) + ((bt_tds_seeker_connection_state_changed_cb)seeker_s->connection_callback) + (result, remote_address, seeker_s, connected, seeker_s->conn_cb_user_data); return; } /* Update TDS Control point values */ @@ -708,11 +538,11 @@ void _bt_tds_update_seeker_connection_state_changed(int result, __bt_tds_reset_seeker_data(seeker_s); bluetooth_gatt_set_service_change_watcher(&addr_hex, false); } - (seeker_s)->connected = connected; + seeker_s->connected = connected; - if ((seeker_s)->connection_callback) - ((bt_tds_seeker_connection_state_changed_cb)(seeker_s)->connection_callback) - (result, remote_address, seeker_s, connected, (seeker_s)->conn_cb_user_data); + if (seeker_s->connection_callback) + ((bt_tds_seeker_connection_state_changed_cb)seeker_s->connection_callback) + (result, remote_address, seeker_s, connected, seeker_s->conn_cb_user_data); } else { BT_DBG("TDS Seeker not found!"); } @@ -769,106 +599,34 @@ int bt_tds_stop_seeking_providers(void) static int __bt_update_tds_transport_data(bluetooth_device_address_t *address, bt_tds_seeker_s *seeker_s) { int ret = BLUETOOTH_ERROR_INTERNAL; - bt_gatt_service_property_t service; - int count; - ret = bluetooth_gatt_get_service_from_uuid(address, BT_TDS_SERVICE_UUID, &service); + ret = bt_gatt_client_get_service(seeker_s->client, BT_TDS_SERVICE_UUID, &seeker_s->tds_svc); if (ret != BLUETOOTH_ERROR_NONE) { BT_ERR("Failed to find TDS configuration service"); return ret; } - /* Find all characteristics of TDS service and their properties */ - for (count = 0; count < service.char_handle.count; count++) { - bt_gatt_char_property_t characteristic; - memset(&characteristic, 0x00, sizeof(characteristic)); - - BT_DBG("Get properties for Char [%s]", service.char_handle.handle[count]); - - ret = bluetooth_gatt_get_characteristics_property(service.char_handle.handle[count], - &characteristic); + ret = bt_gatt_service_get_characteristic(seeker_s->tds_svc, BT_TDS_CONTROL_POINT_UUID, &seeker_s->control_point_chr); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to find TDS configuration service"); + } else { + ret = bt_gatt_characteristic_get_descriptor(seeker_s->control_point_chr, BT_TDS_CONTROL_POINT_CFG_UUID, &seeker_s->control_point_chr_cccd); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to find TDS configuration service"); + } + } + ret = bt_gatt_service_get_characteristic(seeker_s->tds_svc, BT_TDS_USER_CHARACTERISTIC_UUID, &seeker_s->user_chr); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to find TDS configuration service"); + } else { + ret = bt_gatt_characteristic_get_descriptor(seeker_s->user_chr, BT_TDS_USER_CHARACTERISTIC_DESC_UUID, &seeker_s->user_chr_desc); if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Get characteristic property failed(0x%08x)", ret); - bluetooth_gatt_free_service_property(&service); - bluetooth_gatt_free_char_property(&characteristic); - goto fail; - } else { - if (g_strstr_len(characteristic.uuid, -1, BT_TDS_CONTROL_POINT_UUID)) { - BT_DBG("TDS Control point discovered "); - bt_gatt_char_descriptor_property_t desc_property; - memset(&desc_property, 0x00, sizeof(desc_property)); - - - /* Get CCCD for Control Point */ - ret = bluetooth_gatt_get_char_descriptor_property( - characteristic.char_desc_handle.handle[0], &desc_property); - - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Failed to discover CCCD for TDS Control point"); - bluetooth_gatt_free_service_property(&service); - bluetooth_gatt_free_char_property(&characteristic); - bluetooth_gatt_free_desc_property(&desc_property); - goto fail; - } - g_free((seeker_s)->tds_control_point); - (seeker_s)->tds_control_point = g_strdup(characteristic.handle); - - g_free((seeker_s)->tds_control_point_cccd); - (seeker_s)->tds_control_point_cccd = g_strdup(desc_property.handle); - - BT_DBG("TDS Control point handle [%s]", (seeker_s)->tds_control_point); - BT_DBG("TDS Control point CCCD handle [%s]", (seeker_s)->tds_control_point_cccd); - } else { - /* Fetch Descriptors for the discovered characteristic */ - int c; - int p; - - for (c = 0; c < characteristic.char_desc_handle.count; c++) { - - bt_gatt_char_descriptor_property_t desc_property; - memset(&desc_property, 0x00, sizeof(desc_property)); - - ret = bluetooth_gatt_get_char_descriptor_property( - characteristic.char_desc_handle.handle[c], &desc_property); - - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Failed to discover Descriptor Property for characteristic [%s]", - characteristic.handle); - bluetooth_gatt_free_service_property(&service); - bluetooth_gatt_free_char_property(&characteristic); - bluetooth_gatt_free_desc_property(&desc_property); - goto fail; - } else { - /* Descriptor property discovered */ - BT_DBG("Descriptor handle [%s]", desc_property.handle); - BT_DBG("Descriptor UUID [%s]", desc_property.uuid); - BT_DBG("Descriptor val len [%d]", desc_property.val_len); - - if (g_strstr_len(desc_property.uuid, -1, BT_TDS_USER_DATA_DESCRIPTOR)) { - BT_DBG("User data descriptor handle discovered"); - g_free((seeker_s)->tds_user_data_desciptor); - (seeker_s)->tds_user_data_desciptor = g_strdup(desc_property.handle); - } - - for (p = 0; p < desc_property.val_len; p++) - BT_DBG("Descriptor data[%d] = [0x%x]", p, desc_property.val[p]); - } /* Descriptor property get successful */ - bluetooth_gatt_free_desc_property(&desc_property); - } /* Next Descriptor */ - } /* Control Point characteristic */ - } /* Characteristic property get successful */ - bluetooth_gatt_free_char_property(&characteristic); - } /* Next Charatceristic */ - - g_free((seeker_s)->tds_service_handle); - - (seeker_s)->tds_service_handle = g_strdup(service.handle); - bluetooth_gatt_free_service_property(&service); - return ret; -fail: - __bt_tds_reset_seeker_data(seeker_s); - return ret; + BT_ERR("Failed to find TDS configuration service"); + } + } + + return BLUETOOTH_ERROR_NONE; } int bt_tds_seeker_set_connection_state_changed_cb(bt_tds_seeker_h seeker, @@ -911,6 +669,68 @@ int bt_tds_seeker_unset_connection_state_changed_cb(bt_tds_seeker_h seeker) return BT_ERROR_NONE; } +static void __write_value_cb(int result, bt_gatt_h request_handle, void *user_data) +{ + bt_tds_seeker_s *seeker_s = user_data; + + BT_DBG("TDS Control point Activation result [%d] address [%s]", result, seeker_s->remote_address); + + if (seeker_s->tds_activation_ongoing == true) { + /* Send Pending Activation Request callback with error */ + if (result != BT_ERROR_NONE) { + seeker_s->tds_activation_ongoing = false; + if (seeker_s->control_point_act_cb) + ((bt_tds_control_point_activation_indication_cb)(seeker_s->control_point_act_cb))(BT_ERROR_OPERATION_FAILED, + seeker_s->remote_address, NULL, 0, seeker_s->control_point_act_user_data); + g_free(seeker_s->activation_data); + seeker_s->activation_data = NULL; + return; + } else { + BT_DBG("TDS Activation request successfully accepted by Provider, wait for Indication"); + } + } else { + BT_DBG("TDS Control point activation request is not ongoing"); + } +} + +static void __set_characteristic_value_changed_cb(bt_gatt_h characteristic, char *value, int len, void *user_data) +{ + bt_tds_seeker_s *seeker_s = user_data; + int result = BT_ERROR_NONE; + int k; + + BT_DBG("TDS Control point Activation Indication Response"); + BT_DBG("Data length [%d]", len); + BT_DBG("Address[%s]", seeker_s->remote_address); + + /* DEBUG */ + for (k = 0; k < len; k++) + BT_DBG("Data[%d] [0x%x]", k, value[k]); + + if (seeker_s->tds_activation_ongoing == true) { + seeker_s->tds_activation_ongoing = false; + + if (len < 2) + result = BT_ERROR_OPERATION_FAILED; + else { + if (value[1] == 0x00) { + BT_DBG("Provider has enabled transport"); + result = BT_ERROR_NONE; + } else { + BT_ERR("Operation failed[0x%x]", value[1]); /* TODO: handle error code */ + result = BT_ERROR_OPERATION_FAILED; + } + } + + if (seeker_s->control_point_act_cb) + ((bt_tds_control_point_activation_indication_cb)(seeker_s->control_point_act_cb))(result, + seeker_s->remote_address, + (unsigned char *)value, len, seeker_s->control_point_act_user_data); + g_free(seeker_s->activation_data); + seeker_s->activation_data = NULL; + } +} + int bt_tds_seeker_activate_control_point(bt_tds_seeker_h seeker, bt_tds_transport_e transport, unsigned char *buffer, int len, bt_tds_control_point_activation_indication_cb callback, void *user_data) @@ -937,10 +757,10 @@ int bt_tds_seeker_activate_control_point(bt_tds_seeker_h seeker, if (seeker_s->tds_activation_ongoing == true) return BT_ERROR_NOW_IN_PROGRESS; + seeker_s->tds_activation_ongoing = true; /* Check if both TDS Control Point char & Control Point CCCD are valid or discovered */ - if (!(seeker_s->tds_control_point) || - !(seeker_s->tds_control_point_cccd)) + if (!seeker_s->control_point_chr || !seeker_s->control_point_chr_cccd) return BT_ERROR_OPERATION_FAILED; BT_DBG("Activate Control Point [%s] transport [%d] current CCCD state [%d]", @@ -959,24 +779,26 @@ int bt_tds_seeker_activate_control_point(bt_tds_seeker_h seeker, if (seeker_s->cccd_enabled == FALSE) { /* Enable TDS Control point CCCD to enable */ BT_DBG("TDS Control point is disabled, enable it"); - ret = _bt_get_error_code(bluetooth_tds_enable_control_point(&addr_hex, seeker_s->tds_control_point)); - if (ret != BT_ERROR_NONE) { - BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); - g_free(buf); - return ret; - } - } else { - BT_DBG("TDS Control point is already enabled"); - ret = _bt_get_error_code(bluetooth_tds_activate_control_point(&addr_hex, seeker_s->tds_control_point, buf, len)); + ret = _bt_get_error_code(bt_gatt_client_set_characteristic_value_changed_cb(seeker_s->control_point_chr, + __set_characteristic_value_changed_cb, seeker_s)); if (ret != BT_ERROR_NONE) { BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); g_free(buf); return ret; } } + seeker_s->cccd_enabled = TRUE; + + BT_DBG("TDS Control point is enabled"); + ret = bt_gatt_set_value(seeker_s->control_point_chr, (const char *)buf, len); + ret = _bt_get_error_code(bt_gatt_client_write_value(seeker_s->control_point_chr, __write_value_cb, seeker_s)); + if (ret != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); + g_free(buf); + return ret; + } /* Register the callback */ - seeker_s->tds_activation_ongoing = true; seeker_s->control_point_act_cb = callback; seeker_s->control_point_act_user_data = user_data; @@ -988,11 +810,46 @@ int bt_tds_seeker_activate_control_point(bt_tds_seeker_h seeker, return ret; } +static void __read_value_cb(int result, bt_gatt_h gatt_handle, void *user_data) +{ + bt_tds_seeker_s *seeker_s = user_data; + char *data = NULL; + int data_len = 0; + + BT_DBG("Complete TDS Data recv callback is set by app"); + + if (result != BT_ERROR_NONE) { + BT_ERR("TDS Data read failed!!"); + ((bt_tds_seeker_complete_transport_data_cb)(seeker_s->complete_data_callback))(result, + seeker_s->remote_address, NULL, seeker_s->complete_data_cb_user_data); + return; + } + + result = bt_gatt_get_value(gatt_handle, &data, &data_len); + if (result != BT_ERROR_NONE) { + BT_ERR("Error getting data blocks"); + ((bt_tds_seeker_complete_transport_data_cb)(seeker_s->complete_data_callback))(result, + seeker_s->remote_address, NULL, seeker_s->complete_data_cb_user_data); + return; + } + + bt_tds_transport_block_list_s *info = g_malloc0(sizeof(bt_tds_transport_block_list_s)); + if (_bt_tds_parse_transport_blocks(&info, data, data_len) == BT_ERROR_NONE) { + ((bt_tds_seeker_complete_transport_data_cb)(seeker_s->complete_data_callback))(result, + seeker_s->remote_address, info, seeker_s->complete_data_cb_user_data); + } else { + BT_ERR("Error parsing data blocks"); + ((bt_tds_seeker_complete_transport_data_cb)(seeker_s->complete_data_callback))(BT_ERROR_OPERATION_FAILED, + seeker_s->remote_address, NULL, seeker_s->complete_data_cb_user_data); + } + __bt_tds_free_transport_data(info); + g_free(data); +} + int bt_tds_seeker_get_complete_transport_blocks(bt_tds_seeker_h seeker, bt_tds_seeker_complete_transport_data_cb callback, void *user_data) { bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker; - bluetooth_device_address_t addr_hex = { {0,} }; int ret = BT_ERROR_NONE; BT_CHECK_TDS_SUPPORT(); @@ -1006,14 +863,15 @@ int bt_tds_seeker_get_complete_transport_blocks(bt_tds_seeker_h seeker, if (seeker_s->connected == false) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; - if (!seeker_s->tds_user_data_desciptor) + if (!seeker_s->user_chr_desc) { + BT_ERR("No transport blocks on the remote provider"); return BT_ERROR_OPERATION_FAILED; + } BT_DBG("Set TDS Seeker Get complete callback"); - _bt_convert_address_to_hex(&addr_hex, seeker_s->remote_address); /* Read Data from Transport Data block desciptor */ - ret = _bt_get_error_code(bluetooth_tds_read_transport_data(&addr_hex, seeker_s->tds_user_data_desciptor)); + ret = bt_gatt_client_read_value(seeker_s->user_chr_desc, __read_value_cb, seeker_s); if (ret != BT_ERROR_NONE) { BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); return ret; @@ -1060,6 +918,12 @@ int bt_tds_seeker_create(const char *remote_address, bt_tds_seeker_h *seeker) return error_code; } + error_code = bt_gatt_client_create(remote_address, &seeker_s->client); + if (error_code != BLUETOOTH_ERROR_NONE) { + g_free(seeker_s); + return BT_ERROR_OPERATION_FAILED; + } + if (bt_device_is_profile_connected(remote_address, BT_PROFILE_GATT, &connected) != BT_ERROR_NONE) BT_ERR("bt_device_is_profile_connected is failed"); @@ -1114,6 +978,7 @@ int bt_tds_seeker_destroy(bt_tds_seeker_h seeker) BT_DBG("TDS Seeker destroy Remote Provider [%s]", seeker_s->remote_address); __bt_tds_reset_seeker_data(seeker_s); + bt_gatt_client_destroy(seeker_s->client); tds_seeker_list = g_slist_remove(tds_seeker_list, seeker_s); g_free(seeker_s); @@ -1139,7 +1004,6 @@ int bt_tds_seeker_connect(bt_tds_seeker_h seeker) BT_DBG("TDS Seeker connect Remote Provider [%s]", seeker_s->remote_address); error_code = bt_gatt_connect(seeker_s->remote_address, FALSE); - if (error_code != BT_ERROR_NONE) BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); @@ -1165,7 +1029,6 @@ int bt_tds_seeker_disconnect(bt_tds_seeker_h seeker) BT_DBG("TDS Seeker Disconnect Remote Provider [%s]", seeker_s->remote_address); error_code = bt_gatt_disconnect(seeker_s->remote_address); - if (error_code != BT_ERROR_NONE) BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); |