BT_EVENT_MAP_CLIENT_GET_MESSAGE, /**< MAP - getMessage event*/
BT_EVENT_MAP_CLIENT_PUSH_MESSAGE, /**< MAP - pushMessage event*/
BT_EVENT_TDS_ACTIVATION_REQUESTED, /**< TDS - transport activation requested event */
+ BT_EVENT_TDS_PROVIDER_FOUND_RESULT, /**< TDS - CUSTOM Provider */
BT_EVENT_MAX
} bt_event_e;
BT_ADAPTER_LE_ADVERTISING_DATA_128_BIT_SERVICE_SOLICITATION_UUIDS = 0x15, /**< List of 128-bit Service Solicitation UUIDs*/
BT_ADAPTER_LE_ADVERTISING_DATA_SERVICE_DATA = 0x16, /**< Service data */
BT_ADAPTER_LE_ADVERTISING_DATA_APPEARANCE = 0x19, /**< Appearance*/
+ BT_ADAPTER_LE_ADVERTISING_DATA_TRANSPORT_DISCOVERY = 0x26, /**< Transport Discovery*/
BT_ADAPTER_LE_ADVERTISING_DATA_MANUFACTURER_SPECIFIC_DATA = 0xff, /**< Manufacturer data */
} bt_adapter_le_advertising_data_type_e;
int _bt_get_bt_device_info_s(bt_device_info_s **dest_dev, bluetooth_device_info_t *source_dev);
+/**
+ * @internal
+ * @brief Filter Advertising data based on AD type.
+ */
+int _bt_get_ad_data_by_type(char *in_data, int in_len,
+ char in_type, char **data, int *data_len);
+
/**
* @internal
* @brief Free bt_device_info_s.
*/
int _bt_proximity_connection_set_state_changed(int result, const char *remote_address, bool connected);
+/**
+ * @internal
+ * @brief Send GATT connection state changed status with remote TDS provider.
+ */
+void _bt_tds_update_seeker_connection_state_changed(int result, const char *remote_address, bool connected);
+
+/**
+ * @internal
+ * @brief Parses TDS AD Type data recived in scan, to extract meaningful transport specific data.
+ */
+int _bt_tds_parse_transport_blocks(bt_tds_transport_block_list_s **info, char *data, int data_len);
+
+/**
+ * @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);
+
#ifdef __cplusplus
}
#endif
*/
int bt_tds_unset_transport_activation_requested_cb(void);
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to start seeking Remote TDS providers only
+ */
+int bt_tds_start_seeking_providers(bt_tds_provider_scan_result_cb cb, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to stop seeking Remote TDS providers
+ */
+int bt_tds_stop_seeking_providers(void);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to create Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_create(const char *remote_address, bt_tds_seeker_h *seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to destroy Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_destroy(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to set connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_set_connection_state_changed_cb(bt_tds_seeker_h seeker,
+ bt_tds_seeker_connection_state_changed_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to unset connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_unset_connection_state_changed_cb(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to connect to Remote TDS provider
+ */
+int bt_tds_seeker_connect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to disconnect to Remote TDS provider
+ */
+int bt_tds_seeker_disconnect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to read complete TDS block data which is stored in Remote TDS provider's GATT database
+ */
+int bt_tds_seeker_get_complete_transport_blocks(bt_tds_seeker_h seeker,
+ bt_tds_seeker_complete_transport_data_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to Activate ALternate transport supported by Remote TDS provider
+ */
+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);
/**
* @}
*/
* @since_tizen 3.0
*/
typedef enum {
- BT_TDS_TRANSPORT_STATE_OFF,
- BT_TDS_TRANSPORT_STATE_ON,
- BT_TDS_TRANSPORT_STATE_UNAVAILABLE,
+ BT_TDS_TRANSPORT_STATE_OFF, /**< Transport is currently in OFF state */
+ BT_TDS_TRANSPORT_STATE_ON, /**< Transport is currently in ON state */
+ BT_TDS_TRANSPORT_STATE_UNAVAILABLE, /**< Transport is temporarily unavailable */
} bt_tds_transport_state_e;
/**
BT_TDS_TRANSPORT_INVALID
} bt_tds_transport_e;
+/**
+ * @internal
+ * @brief The structure type of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ bt_tds_transport_e transport;
+ bt_tds_transport_state_e state;
+ bool is_data_complete;
+ char *data;
+ int length;
+} tds_transport_data_s;
+
+/**
+ * @internal
+ * @brief The structure type of list of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ int num_transport_block; /**< Number of Transport Data Blocks */
+ tds_transport_data_s **data; /**< Array of Transport Data Block */
+} bt_tds_transport_block_list_s;
+
/**
* @internal
* @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
*/
typedef void (*bt_tds_activation_requested_cb)(char *remote_bd_addr,
bt_tds_transport_e transport, unsigned char *buf, int len, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief The handle of a TDS Seeker client which is associated with a remote TDS provider
+ * @since_tizen 3.0
+ */
+typedef void *bt_tds_seeker_h;
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Scan result callback containing filtered TDS service information and
+ * complete LE discovery informations
+ */
+typedef void (*bt_tds_provider_scan_result_cb)(int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, bt_adapter_le_device_scan_result_info_s *scan_info,
+ void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Connection State changed callback which is associated with a remote TDS provider
+ */
+typedef void (*bt_tds_seeker_connection_state_changed_cb)
+ (int result, const char *remote_address, bt_tds_seeker_h seeker, bool connected, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile complete TDS data block read callback from remote TDS provider
+ */
+typedef void (*bt_tds_seeker_complete_transport_data_cb)
+ (int result, const char *remote_address, bt_tds_transport_block_list_s *info, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile TDS Control Point Activation request callback which is associated with remote TDS provider
+ */
+typedef void (*bt_tds_control_point_activation_indication_cb)
+ (int result, const char *remote_address, unsigned char *data, int data_length, void *user_data);
/**
* @}
*/
*/
int bt_tds_unset_transport_activation_requested_cb(void);
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to start seeking Remote TDS providers only
+ */
+int bt_tds_start_seeking_providers(bt_tds_provider_scan_result_cb cb, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to stop seeking Remote TDS providers
+ */
+int bt_tds_stop_seeking_providers(void);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to create Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_create(const char *remote_address, bt_tds_seeker_h *seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to destroy Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_destroy(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to set connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_set_connection_state_changed_cb(bt_tds_seeker_h seeker,
+ bt_tds_seeker_connection_state_changed_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to unset connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_unset_connection_state_changed_cb(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to connect to Remote TDS provider
+ */
+int bt_tds_seeker_connect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to disconnect to Remote TDS provider
+ */
+int bt_tds_seeker_disconnect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to read complete TDS block data which is stored in Remote TDS provider's GATT database
+ */
+int bt_tds_seeker_get_complete_transport_blocks(bt_tds_seeker_h seeker,
+ bt_tds_seeker_complete_transport_data_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to Activate ALternate transport supported by Remote TDS provider
+ */
+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);
/**
* @}
*/
* @since_tizen 3.0
*/
typedef enum {
- BT_TDS_TRANSPORT_STATE_OFF,
- BT_TDS_TRANSPORT_STATE_ON,
- BT_TDS_TRANSPORT_STATE_UNAVAILABLE,
+ BT_TDS_TRANSPORT_STATE_OFF, /**< Transport is currently in OFF state */
+ BT_TDS_TRANSPORT_STATE_ON, /**< Transport is currently in ON state */
+ BT_TDS_TRANSPORT_STATE_UNAVAILABLE, /**< Transport is temporarily unavailable */
} bt_tds_transport_state_e;
/**
BT_TDS_TRANSPORT_INVALID
} bt_tds_transport_e;
+/**
+ * @internal
+ * @brief The structure type of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ bt_tds_transport_e transport;
+ bt_tds_transport_state_e state;
+ bool is_data_complete;
+ char *data;
+ int length;
+} tds_transport_data_s;
+
+/**
+ * @internal
+ * @brief The structure type of list of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ int num_transport_block; /**< Number of Transport Data Blocks */
+ tds_transport_data_s **data; /**< Array of Transport Data Block */
+} bt_tds_transport_block_list_s;
+
/**
* @internal
* @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
*/
typedef void (*bt_tds_activation_requested_cb)(char *remote_bd_addr,
bt_tds_transport_e transport, unsigned char *buf, int len, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief The handle of a TDS Seeker client which is associated with a remote TDS provider
+ * @since_tizen 3.0
+ */
+typedef void *bt_tds_seeker_h;
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Scan result callback containing filtered TDS service information and
+ * complete LE discovery informations
+ */
+typedef void (*bt_tds_provider_scan_result_cb)(int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, bt_adapter_le_device_scan_result_info_s *scan_info,
+ void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Connection State changed callback which is associated with a remote TDS provider
+ */
+typedef void (*bt_tds_seeker_connection_state_changed_cb)
+ (int result, const char *remote_address,
+ bt_tds_seeker_h seeker, bool connected, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile complete TDS data block read callback from remote TDS provider
+ */
+typedef void (*bt_tds_seeker_complete_transport_data_cb)
+ (int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile TDS Control Point Activation request callback which is associated with remote TDS provider
+ */
+typedef void (*bt_tds_control_point_activation_indication_cb)
+ (int result, const char *remote_address,
+ unsigned char *data, int data_length, void *user_data);
/**
* @}
*/
*/
int bt_tds_unset_transport_activation_requested_cb(void);
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to start seeking Remote TDS providers only
+ */
+int bt_tds_start_seeking_providers(bt_tds_provider_scan_result_cb cb, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to stop seeking Remote TDS providers
+ */
+int bt_tds_stop_seeking_providers(void);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to create Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_create(const char *remote_address, bt_tds_seeker_h *seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to destroy Seeker Role associated with Remote TDS provider
+ */
+int bt_tds_seeker_destroy(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to set connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_set_connection_state_changed_cb(bt_tds_seeker_h seeker,
+ bt_tds_seeker_connection_state_changed_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to unset connection state changed event associated with Remote TDS provider
+ */
+int bt_tds_seeker_unset_connection_state_changed_cb(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to connect to Remote TDS provider
+ */
+int bt_tds_seeker_connect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to disconnect to Remote TDS provider
+ */
+int bt_tds_seeker_disconnect(bt_tds_seeker_h seeker);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to read complete TDS block data which is stored in Remote TDS provider's GATT database
+ */
+int bt_tds_seeker_get_complete_transport_blocks(bt_tds_seeker_h seeker,
+ bt_tds_seeker_complete_transport_data_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief TDS Seeker Profile API to Activate ALternate transport supported by Remote TDS provider
+ */
+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);
/**
* @}
*/
* @since_tizen 3.0
*/
typedef enum {
- BT_TDS_TRANSPORT_STATE_OFF,
- BT_TDS_TRANSPORT_STATE_ON,
- BT_TDS_TRANSPORT_STATE_UNAVAILABLE,
+ BT_TDS_TRANSPORT_STATE_OFF, /**< Transport is currently in OFF state */
+ BT_TDS_TRANSPORT_STATE_ON, /**< Transport is currently in ON state */
+ BT_TDS_TRANSPORT_STATE_UNAVAILABLE, /**< Transport is temporarily unavailable */
} bt_tds_transport_state_e;
/**
BT_TDS_TRANSPORT_INVALID
} bt_tds_transport_e;
+/**
+ * @internal
+ * @brief The structure type of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ bt_tds_transport_e transport;
+ bt_tds_transport_state_e state;
+ bool is_data_complete;
+ char *data;
+ int length;
+} tds_transport_data_s;
+
+/**
+ * @internal
+ * @brief The structure type of list of TDS transport data block
+ * @since_tizen 3.0
+ */
+typedef struct {
+ int num_transport_block; /**< Number of Transport Data Blocks */
+ tds_transport_data_s **data; /**< Array of Transport Data Block */
+} bt_tds_transport_block_list_s;
+
/**
* @internal
* @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
*/
typedef void (*bt_tds_activation_requested_cb)(char *remote_bd_addr,
bt_tds_transport_e transport, unsigned char *buf, int len, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief The handle of a TDS Seeker client which is associated with a remote TDS provider
+ * @since_tizen 3.0
+ */
+typedef void *bt_tds_seeker_h;
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Scan result callback containing filtered TDS service information and
+ * complete LE discovery informations
+ */
+typedef void (*bt_tds_provider_scan_result_cb)(int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, bt_adapter_le_device_scan_result_info_s *scan_info,
+ void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile Connection State changed callback which is associated with a remote TDS provider
+ */
+typedef void (*bt_tds_seeker_connection_state_changed_cb)
+ (int result, const char *remote_address,
+ bt_tds_seeker_h seeker, bool connected, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile complete TDS data block read callback from remote TDS provider
+ */
+typedef void (*bt_tds_seeker_complete_transport_data_cb)
+ (int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 3.0
+ * @brief TDS Seeker profile TDS Control Point Activation request callback which is associated with remote TDS provider
+ */
+typedef void (*bt_tds_control_point_activation_indication_cb)
+ (int result, const char *remote_address,
+ unsigned char *data, int data_length, void *user_data);
/**
* @}
*/
static int __bt_get_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan_result_info_s **scan_info, bluetooth_le_device_info_t *source_info);
static void __bt_free_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan_result_info_s *scan_info);
+/* TDS Forward declarations */
+static void __bt_free_tds_scan_result_info_s(bt_tds_transport_block_list_s *discovery_info);
+
#if !defined(TIZEN_PROFILE_WEARABLE) && !defined(TIZEN_PROFILE_IVI)
static int __bt_get_bt_adapter_le_device_discovery_info_s(bt_adapter_le_device_discovery_info_s **le_discovery_info, bluetooth_le_device_info_t *source_info);
static void __bt_free_bt_adapter_le_device_discovery_info_s(bt_adapter_le_device_discovery_info_s *discovery_info);
}
/* LCOV_EXCL_STOP */
+int _bt_get_ad_data_by_type(char *in_data, int in_len,
+ char in_type, char **data, int *data_len)
+{
+ if (in_data == NULL || data == NULL || data_len == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ if (in_len < 0)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ int i;
+ int len = 0;
+ int type = 0;
+
+ for (i = 0; i < in_len; i++) {
+ len = in_data[i];
+ if (len <= 0 || i + 1 >= in_len) {
+ BT_ERR("Invalid advertising data");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ type = in_data[i + 1];
+ if (type == in_type) {
+ i = i + 2;
+ len--;
+ break;
+ }
+
+ i += len;
+ len = 0;
+ }
+
+ if (i + len > in_len) {
+ BT_ERR("Invalid advertising data");
+ return BLUETOOTH_ERROR_INTERNAL;
+ } else if (len == 0) {
+ BT_DBG("AD Type 0x%02x data is not set", in_type);
+ *data = NULL;
+ *data_len = 0;
+ return BLUETOOTH_ERROR_NONE;
+ }
+
+ *data = g_memdup(&in_data[i], len);
+ if (*data == NULL)
+ return BLUETOOTH_ERROR_OUT_OF_MEMORY;
+ *data_len = len;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
int _bt_convert_address_to_string(char **addr_str, bluetooth_device_address_t *addr_hex)
{
char address[18] = { 0, };
case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED:
case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED:
case BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED:
+ case BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED:
+ case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT:
+ case BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED:
+ case BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION:
return true;
default:
break;
if (is_pxp_initialized)
_bt_proximity_connection_set_state_changed(param->result, device_addr, TRUE);
+ /* TDS Seeker */
+ _bt_tds_update_seeker_connection_state_changed(param->result, device_addr, TRUE);
+
g_free(device_addr);
device_addr = NULL;
break;
if (is_pxp_initialized)
_bt_proximity_connection_set_state_changed(param->result, device_addr, FALSE);
+ /* TDS Seeker */
+ _bt_tds_update_seeker_connection_state_changed(param->result, device_addr, FALSE);
+
g_free(device_addr);
device_addr = NULL;
break;
_bt_convert_address_to_string(&device_addr,
&service_change->device_addr);
+ /* Check if TDS Service removed */
+ _bt_tds_check_service_changed(device_addr, service_change);
+
client = _bt_gatt_get_client(device_addr);
g_free(device_addr);
device_addr = NULL;
free(device_addr); /* LCOV_EXCL_STOP */
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); /* LCOV_EXCL_STOP */
+ 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); /* LCOV_EXCL_STOP */
+ 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); /* LCOV_EXCL_STOP */
+ 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); /* LCOV_EXCL_STOP */
+ break;
+ }
default:
BT_INFO("Unknown function");
break;
if (__bt_get_bt_adapter_le_device_scan_info_s(&scan_info, (bluetooth_le_device_info_t *)(param->param_data)) == BT_ERROR_NONE) {
((bt_adapter_le_scan_result_cb)bt_event_slot_container[event_index].callback)
(_bt_get_error_code(param->result), scan_info, bt_event_slot_container[event_index].user_data);
- __bt_free_bt_adapter_le_device_scan_info_s(scan_info);
} else {
((bt_adapter_le_scan_result_cb)bt_event_slot_container[event_index].callback)
(_bt_get_error_code(param->result), NULL, bt_event_slot_container[event_index].user_data);
}
}
#endif
- break;
+ /* TDS Provider Search: Uses Scan Info */
+ if (bt_event_slot_container[BT_EVENT_TDS_PROVIDER_FOUND_RESULT].callback != NULL) {
+ char *data = NULL;
+ int data_len = 0;
+ if (!scan_info) {
+ /* Get Scan Info */
+ if (__bt_get_bt_adapter_le_device_scan_info_s(&scan_info,
+ (bluetooth_le_device_info_t *)(param->param_data)) != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */
+ break;
+ }
+ }
+ _bt_get_ad_data_by_type((char*)scan_info->adv_data, scan_info->adv_data_len,
+ BT_ADAPTER_LE_ADVERTISING_DATA_TRANSPORT_DISCOVERY,
+ &data, &data_len);
+ if (data != NULL) {
+ BT_DBG("TDS Service available Data length[%d]", data_len);
+ 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_provider_scan_result_cb)bt_event_slot_container[BT_EVENT_TDS_PROVIDER_FOUND_RESULT].callback) /* LCOV_EXCL_LINE */
+ (_bt_get_error_code(param->result),
+ scan_info->remote_address, info,
+ scan_info,
+ bt_event_slot_container[BT_EVENT_TDS_PROVIDER_FOUND_RESULT].user_data);
+ }
+ __bt_free_tds_scan_result_info_s(info);
+
+ if (data) {
+ g_free(data);
+ data = NULL;
+ }
+ }
+ }
+ if (scan_info)
+ __bt_free_bt_adapter_le_device_scan_info_s(scan_info);
+ break;
default:
break;
}
scan_info = NULL;
} /* LCOV_EXCL_STOP */
+static void __bt_free_tds_scan_result_info_s(bt_tds_transport_block_list_s *discovery_info)
+{
+ int k;
+
+ if (discovery_info == NULL)
+ return;
+
+ for (k = 0; k < discovery_info->num_transport_block; k++) {
+ g_free(discovery_info->data[k]->data);
+ g_free(discovery_info->data[k]);
+ }
+
+ g_free(discovery_info);
+ discovery_info = NULL;
+
+}
+
/* LCOV_EXCL_START */
#if !defined(TIZEN_PROFILE_WEARABLE) && !defined(TIZEN_PROFILE_IVI)
static int __bt_get_bt_adapter_le_device_discovery_info_s(
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"
+
typedef struct {
unsigned int tds_handle;
bluetooth_tds_transport_t transport;
bluetooth_tds_transport_state_t state;
} bt_tds_provider_s;
+typedef struct bt_tds_transport_slot_s {
+ bool is_seek_ongoing;
+} bt_tds_transport_slot_s;
+
+typedef struct {
+ char *remote_address;
+ bool connected;
+
+ const void *connection_callback;
+ void *conn_cb_user_data;
+
+ 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;
+} bt_tds_seeker_s;
+
gboolean tds_provider_registered = FALSE;
GSList *providers_list;
+GSList *tds_seeker_list;
+
+static int __bt_update_tds_transport_data(bluetooth_device_address_t *address, bt_tds_seeker_s *seeker_s);
+static void __bt_tds_reset_seeker_data(bt_tds_seeker_s *seeker);
int bt_tds_set_transport_activation_requested_cb(
bt_tds_activation_requested_cb callback, void *user_data)
return error_code;
}
+
+static bt_tds_seeker_s *_bt_tds_seeker_find(const char *remote_address)
+{
+ GSList *l;
+
+ for (l = tds_seeker_list; l; l = g_slist_next(l)) {
+
+ if (!g_ascii_strcasecmp(((bt_tds_seeker_s *)l->data)->remote_address, remote_address))
+ return ((bt_tds_seeker_s *)l->data);
+ }
+ return NULL;
+}
+
+static void __bt_tds_free_transport_data(bt_tds_transport_block_list_s *info)
+{
+ int k;
+
+ if (info == NULL)
+ return;
+
+ for (k = 0; k < info->num_transport_block; k++) {
+ g_free(info->data[k]->data);
+ g_free(info->data[k]);
+ }
+
+ g_free(info);
+}
+
+void _bt_tds_check_service_changed(char *address, bt_gatt_service_change_t *service_change)
+{
+ bt_tds_seeker_s *seeker_s = NULL;
+ int error_code = BLUETOOTH_ERROR_NONE;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ if (!address) {
+ BT_ERR("Abnormal Result!!");
+ return;
+ }
+ seeker_s = _bt_tds_seeker_find(address);
+ BT_DBG("GATT Service state changed [%d]", service_change->change_type);
+ 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) {
+ BT_ERR("TDS Primary Service removed abnormally from Remote Provider [%s]", address);
+ __bt_tds_reset_seeker_data(seeker_s);
+ }
+ } else {
+ _bt_convert_address_to_hex(&addr_hex, address);
+
+ /* Attempt to update TDS Service data if service added is TDS service */
+ if (__bt_update_tds_transport_data(&addr_hex, seeker_s) == BLUETOOTH_ERROR_NONE) {
+ BT_INFO("TDS Primary Service added in Remote Provider [%s]", address);
+ /* Set Service changed Watcher */
+ error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
+ if (error_code != BLUETOOTH_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ }
+ }
+ }
+ 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]", 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);
+ if (seeker_s->activation_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);
+ if (seeker_s->activation_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);
+
+ if (seeker_s->activation_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)
+{
+ int numblocks = 0;
+ int index = 2;
+ uint8_t flags;
+ int k;
+ GSList *info_list = NULL;
+ GSList *l = NULL;
+
+ if (data_len < 3) {
+ BT_ERR("Invalid TDS data, can not process!!");
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ tds_transport_data_s *td;
+
+ while (index < data_len) {
+
+ /* Check if Provider Role is supported by Remote */
+ flags = data[index-1];
+
+ if (!(flags & 0x02)) {
+ /* Move to Next Block */
+ index = index + data[index] + 3;
+ BT_ERR("TDS Block is not Provider Role");
+ continue;
+ }
+
+ td = g_malloc(sizeof(tds_transport_data_s));
+ td->length = data[index];
+
+ td->data = g_malloc0(td->length);
+
+ /* Fill Transport Block Data excluding Flag and Org ID */
+ for (k = 0; k < td->length; k++)
+ td->data[k] = data[k+index+1];
+
+ /* Get Transport Name */
+ td->transport = data[index -2];
+
+ /* Get Transport Data Block Incomplete status */
+ if (flags & 0x04)
+ td->is_data_complete = false;
+ else
+ td->is_data_complete = true;
+
+ /* Get Transport's current state */
+ if (flags & 0x08)
+ td->state = BT_TDS_TRANSPORT_STATE_ON;
+ else if (flags & 0x10)
+ td->state = BT_TDS_TRANSPORT_STATE_UNAVAILABLE;
+ else
+ td->state = BT_TDS_TRANSPORT_STATE_OFF;
+
+ /* Move to Next Block */
+ index = index + data[index] + 3;
+ info_list = g_slist_append(info_list, td);
+
+ (*info)->num_transport_block = ++numblocks;
+ BT_DBG("Transport Block data length [%d] Flags [0x%x] Transport Name [0x%x] Block Num [%d]",
+ td->length, flags, td->transport, numblocks);
+
+ }
+
+ if (info_list != NULL) {
+ (*info)->data = (tds_transport_data_s**)g_malloc0(g_slist_length(info_list) * sizeof(tds_transport_data_s));
+ for (l = info_list, k = 0; l; l = g_slist_next(l), k++)
+ (*info)->data[k] = (tds_transport_data_s*)l->data;
+ return BT_ERROR_NONE;
+ }
+ return BT_ERROR_NO_DATA;
+}
+
+static void __bt_tds_reset_seeker_data(bt_tds_seeker_s *seeker)
+{
+ if ((seeker)->tds_control_point) {
+ g_free((seeker)->tds_control_point);
+ (seeker)->tds_control_point = NULL;
+ }
+
+ if ((seeker)->tds_control_point_cccd) {
+ g_free((seeker)->tds_control_point_cccd);
+ (seeker)->tds_control_point_cccd = NULL;
+ }
+
+ if ((seeker)->tds_user_data_desciptor) {
+ g_free((seeker)->tds_user_data_desciptor);
+ (seeker)->tds_user_data_desciptor = NULL;
+ }
+
+ if ((seeker)->tds_service_handle) {
+ g_free((seeker)->tds_service_handle);
+ (seeker)->tds_service_handle = NULL;
+ }
+
+ if ((seeker)->activation_data) {
+ g_free((seeker)->activation_data);
+ (seeker)->activation_data = NULL;
+ }
+
+ /* Reset CCCD */
+ (seeker)->cccd_enabled = false;
+}
+
+void _bt_tds_update_seeker_connection_state_changed(int result,
+ const char *remote_address, bool connected)
+{
+ int error_code = BLUETOOTH_ERROR_NONE;
+ bt_tds_seeker_s *seeker_s = NULL;
+ BT_DBG("TDS Seeker Connection state changed result [%d] connected [%d]", result, connected ? TRUE : FALSE);
+
+ /* GATT Connect Request failed */
+ seeker_s = _bt_tds_seeker_find(remote_address);
+ if (seeker_s) {
+ BT_DBG("Seeker found against address [%s]", remote_address);
+
+ bluetooth_device_address_t addr_hex = { {0,} };
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ if (result != BT_ERROR_NONE) {
+ BT_ERR("GATT Connect Request failed Address [%s]", remote_address);
+ __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);
+ return;
+ }
+ /* Update TDS Control point values */
+ if (connected) {
+ BT_DBG("Remote Provider connected successfully");
+ /* Attempt to update TDS Service data */
+ error_code = __bt_update_tds_transport_data(&addr_hex, seeker_s);
+ if (error_code != BLUETOOTH_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+
+ /* Set Service changed Watcher */
+ error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
+ if (error_code != BLUETOOTH_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ } else {
+ BT_DBG("Remote Provider disconnected successfully");
+ /* Disconnected */
+ __bt_tds_reset_seeker_data(seeker_s);
+ bluetooth_gatt_set_service_change_watcher(&addr_hex, false);
+ }
+ (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);
+ } else {
+ BT_DBG("TDS Seeker not found!");
+ }
+}
+
+int bt_tds_start_seeking_providers(bt_tds_provider_scan_result_cb cb, void *user_data)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(cb);
+ BT_DBG("+");
+
+ /* LE Event handler registered */
+ if (_bt_le_adapter_init() != BLUETOOTH_ERROR_NONE)
+ return BT_ERROR_OPERATION_FAILED;
+
+ /* Start LE discovery with default scan params if already not started */
+ if (bluetooth_is_le_scanning() == false)
+ error_code = _bt_get_error_code(bluetooth_start_le_discovery());
+
+ if (error_code != BT_ERROR_NONE &&
+ error_code != BT_ERROR_NOW_IN_PROGRESS) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ } else {
+ BT_DBG("LE Discovery ON..Wait for TDS Configuration Service from Remote Providers");
+ _bt_set_cb(BT_EVENT_TDS_PROVIDER_FOUND_RESULT, cb, user_data);
+ }
+
+ return error_code;
+}
+
+int bt_tds_stop_seeking_providers(void)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_DBG("+");
+
+ if (bluetooth_is_le_scanning() == true)
+ error_code = _bt_get_error_code(bluetooth_stop_le_discovery());
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
+ error_code);
+ }
+
+ _bt_unset_cb(BT_EVENT_TDS_PROVIDER_FOUND_RESULT);
+ return BT_ERROR_NONE;
+}
+
+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);
+ 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);
+
+ 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;
+ }
+ if ((seeker_s)->tds_control_point)
+ g_free((seeker_s)->tds_control_point);
+ (seeker_s)->tds_control_point = g_strdup(characteristic.handle);
+
+ if ((seeker_s)->tds_control_point_cccd)
+ 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");
+ if ((seeker_s)->tds_user_data_desciptor)
+ 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 */
+
+ if ((seeker_s)->tds_service_handle)
+ 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;
+}
+
+int bt_tds_seeker_set_connection_state_changed_cb(bt_tds_seeker_h seeker,
+ bt_tds_seeker_connection_state_changed_cb callback, void *user_data)
+{
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ BT_DBG("Set TDS Seeker Connection State changed callback");
+ /* register the callback */
+ seeker_s->connection_callback = callback;
+ seeker_s->conn_cb_user_data = user_data;
+
+ return BT_ERROR_NONE;
+}
+
+int bt_tds_seeker_unset_connection_state_changed_cb(bt_tds_seeker_h seeker)
+{
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ BT_DBG("UnSet TDS Seeker Connection State changed callback");
+ /* unregister the callback */
+ seeker_s->connection_callback = NULL;
+ seeker_s->conn_cb_user_data = NULL;
+
+ return BT_ERROR_NONE;
+}
+
+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)
+{
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int ret = BT_ERROR_NONE;
+ unsigned char *buf;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+ BT_CHECK_INPUT_PARAMETER(buffer);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ if (len > 255)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (seeker_s->connected == false)
+ return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
+
+ if (seeker_s->tds_activation_ongoing == true)
+ return BT_ERROR_NOW_IN_PROGRESS;
+
+ /* 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))
+ return BT_ERROR_OPERATION_FAILED;
+
+ BT_DBG("Activate Control Point [%s] transport [%d] current CCCD state [%d]",
+ seeker_s->remote_address, transport, seeker_s->cccd_enabled);
+
+ _bt_convert_address_to_hex(&addr_hex, seeker_s->remote_address);
+
+ /* Activate Control Point */
+ buf = g_malloc0(len+2);
+
+ buf[0] = 0x01; /* Activate control point Opcode */
+ buf[1] = transport; /* Activate control point Opcode */
+ memcpy(buf+2, buffer, len);
+
+ /* Check if TDS control Point is already enabled or not */
+ 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));
+ 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;
+
+ /* Save actvation data and trigger when CCCD is actually enabled */
+ seeker_s->activation_data = buf;
+ seeker_s->data_len = len;
+
+ BT_DBG("-");
+ return ret;
+}
+
+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();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (seeker_s->connected == false)
+ return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
+
+ if (!seeker_s->tds_user_data_desciptor)
+ 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));
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+ /* register the callback */
+ seeker_s->complete_data_callback = callback;
+ seeker_s->complete_data_cb_user_data = user_data;
+
+ return ret;
+}
+
+int bt_tds_seeker_create(const char *remote_address, bt_tds_seeker_h *seeker)
+{
+ int error_code = BT_ERROR_NONE;
+ bt_tds_seeker_s *seeker_s = NULL;
+ bool connected = false;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ GSList *l;
+ BT_INFO("+");
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+ BT_CHECK_INPUT_PARAMETER(seeker);
+
+ for (l = tds_seeker_list; l; l = g_slist_next(l)) {
+ bt_tds_seeker_s *c = (bt_tds_seeker_s *)l->data;
+
+ if (!g_ascii_strcasecmp(c->remote_address, remote_address)) {
+ BT_ERR("TDS Seeker for Remote Provider [%s] is already created",
+ remote_address);
+ *seeker = (bt_tds_seeker_h)c;
+ return BT_ERROR_ALREADY_DONE;
+ }
+ }
+
+ seeker_s = g_malloc0(sizeof(*seeker_s));
+ if (seeker_s == NULL) {
+ error_code = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ return error_code;
+ }
+
+ if (bt_device_is_profile_connected(remote_address, BT_PROFILE_GATT,
+ &connected) != BT_ERROR_NONE)
+ BT_ERR("bt_device_is_profile_connected is failed");
+ seeker_s->connected = connected;
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ if (seeker_s->connected == true) {
+ error_code = __bt_update_tds_transport_data(&addr_hex, seeker_s);
+ if (error_code != BLUETOOTH_ERROR_NONE) {
+ g_free(seeker_s);
+ return BT_ERROR_OPERATION_FAILED;
+ }
+ error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
+ if (error_code != BLUETOOTH_ERROR_NONE) {
+ g_free(seeker_s);
+ return BT_ERROR_OPERATION_FAILED;
+ }
+ }
+
+ seeker_s->remote_address = g_strdup(remote_address);
+ if (seeker_s->remote_address == NULL) {
+ free(seeker_s);
+ error_code = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ return error_code;
+ }
+
+ seeker_s->cccd_enabled = FALSE;
+ seeker_s->activation_data = NULL;
+
+ tds_seeker_list = g_slist_append(tds_seeker_list, seeker_s);
+ *seeker = (bt_tds_seeker_h)seeker_s;
+
+ BT_DBG("TDS Seeker Created");
+ return BT_ERROR_NONE;
+}
+
+int bt_tds_seeker_destroy(bt_tds_seeker_h seeker)
+{
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ BT_DBG("TDS Seeker destroy Remote Provider [%s]", seeker_s->remote_address);
+ __bt_tds_reset_seeker_data(seeker_s);
+
+ tds_seeker_list = g_slist_remove(tds_seeker_list, seeker_s);
+ g_free(seeker_s);
+ seeker_s = NULL;
+
+ return BT_ERROR_NONE;
+}
+
+int bt_tds_seeker_connect(bt_tds_seeker_h seeker)
+{
+ int error_code;
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (seeker_s->connected)
+ return BT_ERROR_NONE;
+
+ 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);
+
+ return error_code;
+}
+
+int bt_tds_seeker_disconnect(bt_tds_seeker_h seeker)
+{
+ int error_code;
+ bt_tds_seeker_s *seeker_s = (bt_tds_seeker_s *)seeker;
+
+ BT_CHECK_TDS_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(seeker_s);
+
+ if (_bt_tds_seeker_find(seeker_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ if (seeker_s->connected == false) {
+ BT_ERR("Remote Provider [%s] is not conencted", seeker_s->remote_address);
+ return BT_ERROR_OPERATION_FAILED;
+ }
+
+ 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);
+
+ return error_code;
+}
bt_tds_provider_h provider;
char *tds_act_address;
+bt_tds_seeker_h seeker;
#ifdef TIZEN_FEATURE_ENABLE_LEGACY_GATT_CLIENT
bt_gatt_attribute_h service_clone[MAX_SERVICES];
#endif
{"etc.(Automated test, AppControl)"
, BT_UNIT_TEST_TABLE_ETC},
- {"TDS"
- , BT_UNIT_TEST_TABLE_TDS},
+ {"TDS Provider"
+ , BT_UNIT_TEST_TABLE_TDS_PROVIDER},
+ {"TDS Seeker"
+ , BT_UNIT_TEST_TABLE_TDS_SEEKER},
{"Initialize All"
, BT_UNIT_TEST_FUNCTION_INITIALIZE_ALL},
{"FINISH"
};
#endif
-tc_table_t tc_tds[] = {
- /* TDS functions */
+tc_table_t tc_tds_provider[] = {
+ /* TDS provider functions */
{"BACK"
, BT_UNIT_TEST_FUNCTION_BACK},
{"TDS Provider(Register)"
{NULL , 0x0000},
};
+tc_table_t tc_tds_seeker[] = {
+ /* TDS Seeker functions */
+ {"BACK"
+ , BT_UNIT_TEST_FUNCTION_BACK},
+ {"TDS Seeker Start Discovering Provider"
+ , BT_UNIT_TEST_FUNCTION_TDS_START_DISCOVERING_PROVIDER},
+ {"TDS Seeker Stop Discovering Provider"
+ , BT_UNIT_TEST_FUNCTION_TDS_STOP_DISCOVERING_PROVIDER},
+ {"TDS Seeker(Create)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CREATE},
+ {"TDS Seeker(Destroy)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DESTROY},
+ {"TDS Set Seeker Connection cb"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_SET_CONNECTION_CALLBACK},
+ {"TDS Seeker Connect(remote)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CONNECT},
+ {"TDS Seeker DisConnect(remote)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DISCONNECT},
+ {"TDS UnSet Seeker Connection cb"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_UNSET_CONNECTION_CALLBACK},
+ {"TDS Read Complete Transport Data (remote)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_GET_COMPLETE_DATA},
+ {"TDS Activate Control Point (remote)"
+ , BT_UNIT_TEST_FUNCTION_TDS_SEEKER_ACTIVATE_CONTROL_POINT},
+ {NULL , 0x0000},
+};
+
+
tc_table_t tc_automated_test[] = {
/* Automated test Functions*/
{"BACK" , BT_UNIT_TEST_FUNCTION_BACK},
__bt_initialize_all();
TC_PRT("Key 0 : usage BACK");
return;
- case BT_UNIT_TEST_TABLE_TDS:
- tc_table = tc_tds;
+ case BT_UNIT_TEST_TABLE_TDS_PROVIDER:
+ tc_table = tc_tds_provider;
+ break;
+ case BT_UNIT_TEST_TABLE_TDS_SEEKER:
+ tc_table = tc_tds_seeker;
break;
case BT_UNIT_TEST_TABLE_MAIN:
default:
bt_onoff_cnt++;
}
+/* TDS Seeker Callbacks */
+static void __bt_tds_provider_scan_result_cb(int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, bt_adapter_le_device_scan_result_info_s *scan_info,
+ void *user_data)
+{
+ int k;
+ int l;
+ TC_PRT("__bt_tds_provider_scan_result_cb");
+ TC_PRT("result: %s", __bt_get_error_message(result));
+
+ TC_PRT("Result: %s", __bt_get_error_message(result));
+ TC_PRT("Remote addr [%s]", remote_address);
+ TC_PRT("Number of Transport Block [%d]", info->num_transport_block);
+
+ if (result == BT_ERROR_NONE) {
+ for (k = 0; k < info->num_transport_block; k++) {
+ TC_PRT("Block Num[%d] Transport Name [%d]", k+1, info->data[k]->transport);
+ TC_PRT("Block Num[%d] Transport state [%d]", k+1, info->data[k]->state);
+ TC_PRT("Block Num[%d] Is Data complete [%d]", k+1, info->data[k]->is_data_complete);
+ TC_PRT("Block Num[%d] Length of TDS Block data [%d]", k+1, info->data[k]->length);
+
+ for (l = 0; l < info->data[k]->length; l++)
+ TC_PRT("Transport Specific data [%d] = [0x%x]", l, info->data[k]->data[l]);
+ }
+ }
+}
+
+static void __bt_tds_seeker_connection_state_changed_cb(int result, const char *remote_address,
+ bt_tds_seeker_h seeker, bool connected, void *user_data)
+{
+ TC_PRT("Result: %s", __bt_get_error_message(result));
+ if (result == BT_ERROR_NONE) {
+ if (connected)
+ TC_PRT("TDS Seeker connected(address = %s)", remote_address);
+ else
+ TC_PRT("TDS Seeker Disconnected (address = %s)", remote_address);
+ } else
+ BT_ERR("TDS Connection failed!");
+}
+
+static void __bt_tds_seeker_complete_transport_data_cb(int result, const char *remote_address,
+ bt_tds_transport_block_list_s *info, void *user_data)
+{
+ int k;
+ int l;
+ TC_PRT("__bt_tds_seeker_complete_transport_data_cb");
+ TC_PRT("Result: %s", __bt_get_error_message(result));
+ TC_PRT("Remote addr [%s]", remote_address);
+
+ if (result == BT_ERROR_NONE) {
+ TC_PRT("Number of Transport Block [%d]", info->num_transport_block);
+ for (k = 0; k < info->num_transport_block; k++) {
+ TC_PRT("Block Num[%d] Transport Name [%d]", k+1, info->data[k]->transport);
+ TC_PRT("Block Num[%d] Transport state [%d]", k+1, info->data[k]->state);
+ TC_PRT("Block Num[%d] Is Data complete [%d]", k+1, info->data[k]->is_data_complete);
+ TC_PRT("Block Num[%d] Length of TDS Block data [%d]", k+1, info->data[k]->length);
+
+ for (l = 0; l < info->data[k]->length; l++)
+ TC_PRT("Transport Specific data [%d] = [0x%x]", l, info->data[k]->data[l]);
+ }
+ } else
+ BT_ERR("TDS Data receive request failed!");
+}
+
+static void __bt_tds_control_point_activation_result_cb(int result, const char *remote_address,
+ unsigned char *data, int length, void *user_data)
+{
+ int k;
+ TC_PRT("__bt_tds_control_point_activation_result_cb");
+ TC_PRT("Result [%d]", result);
+ TC_PRT("Address[%s]", remote_address);
+
+ if (result == BT_ERROR_NONE) {
+ TC_PRT("Data length [%d]", length);
+ for (k = 0; k < length; k++)
+ TC_PRT("Data[%d] [0x%x]", k, data[k]);
+ }
+}
+
static void __bt_initialize_all(void)
{
int ret;
break;
}
#endif
- case BT_UNIT_TEST_TABLE_TDS: {
+ case BT_UNIT_TEST_TABLE_TDS_PROVIDER: {
switch (test_id) {
case BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_REGISTER: {
ret = bt_tds_provider_register();
}
break;
}
+ case BT_UNIT_TEST_TABLE_TDS_SEEKER: {
+ switch (test_id) {
+ case BT_UNIT_TEST_FUNCTION_TDS_START_DISCOVERING_PROVIDER: {
+ ret = bt_tds_start_seeking_providers(__bt_tds_provider_scan_result_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_STOP_DISCOVERING_PROVIDER: {
+ ret = bt_tds_stop_seeking_providers();
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CREATE: {
+ if (seeker)
+ seeker = NULL;
+ ret = bt_tds_seeker_create(remote_addr, &seeker);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DESTROY: {
+ if (seeker) {
+ ret = bt_tds_seeker_destroy(seeker);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_SET_CONNECTION_CALLBACK: {
+ if (seeker) {
+ ret = bt_tds_seeker_set_connection_state_changed_cb(seeker,
+ __bt_tds_seeker_connection_state_changed_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CONNECT: {
+ if (seeker) {
+ ret = bt_tds_seeker_connect(seeker);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DISCONNECT: {
+ if (seeker) {
+ ret = bt_tds_seeker_disconnect(seeker);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_UNSET_CONNECTION_CALLBACK: {
+ if (seeker) {
+ ret = bt_tds_seeker_unset_connection_state_changed_cb(seeker);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_GET_COMPLETE_DATA: {
+ if (seeker) {
+ ret = bt_tds_seeker_get_complete_transport_blocks(seeker,
+ __bt_tds_seeker_complete_transport_data_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_TDS_SEEKER_ACTIVATE_CONTROL_POINT: {
+ if (seeker) {
+ unsigned char buf[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, /* Mac */
+ 0x0A, 0x0B}; /* Channel Info */
+ bt_tds_transport_e transport = BT_TDS_TRANSPORT_CUSTOM;
+ ret = bt_tds_seeker_activate_control_point(seeker, transport, buf, sizeof(buf),
+ __bt_tds_control_point_activation_result_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
case BT_UNIT_TEST_TABLE_ETC: {
static unsigned int delay = 0;
bt_onoff_cnt = 0;
#endif
BT_UNIT_TEST_TABLE_ETC,
BT_UNIT_TEST_FUNCTION_INITIALIZE_ALL,
- BT_UNIT_TEST_TABLE_TDS,
+ BT_UNIT_TEST_TABLE_TDS_PROVIDER,
+ BT_UNIT_TEST_TABLE_TDS_SEEKER,
BT_UNIT_TEST_TABLE_FINISH = 0xFF,
} bt_unit_test_table_e;
BT_UNIT_TEST_FUNCTION_PXP_MONITOR_READ_IMMEDIATE_ALERT,
BT_UNIT_TEST_FUNCTION_PXP_MONITOR_READ_SIGNAL_LEVEL,
+ /* TDS Provider */
BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_REGISTER = 1,
BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_UNREGISTER,
BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_SET_ACT_REQ_CB,
BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_TRANSPORT_DATA,
BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_MANUF_DATA,
BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SEND_ACTIVATION_RESP,
+
+ /* TDS Seeker */
+ BT_UNIT_TEST_FUNCTION_TDS_START_DISCOVERING_PROVIDER = 1,
+ BT_UNIT_TEST_FUNCTION_TDS_STOP_DISCOVERING_PROVIDER,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CREATE,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DESTROY,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_SET_CONNECTION_CALLBACK,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_CONNECT,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_DISCONNECT,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_UNSET_CONNECTION_CALLBACK,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_GET_COMPLETE_DATA,
+ BT_UNIT_TEST_FUNCTION_TDS_SEEKER_ACTIVATE_CONTROL_POINT,
+
BT_UNIT_TEST_FUNCTION_ACTIVATE_FLAG_TO_SET_PARAMETERS = 0XFF,
} bt_unit_test_function_e;