diff options
author | DoHyun Pyun <dh79.pyun@samsung.com> | 2017-02-07 14:17:16 +0900 |
---|---|---|
committer | DoHyun Pyun <dh79.pyun@samsung.com> | 2017-02-07 14:17:16 +0900 |
commit | 0949556a08b04798fcf8a8a47aa95e7d352b314d (patch) | |
tree | 6ba70b0597a16dbbf604d1a1cd337521a63a3cc1 | |
parent | 37954d63b5a599cfc93efdd6afc682a7ea7b5599 (diff) | |
download | bluetooth-0949556a08b04798fcf8a8a47aa95e7d352b314d.tar.gz bluetooth-0949556a08b04798fcf8a8a47aa95e7d352b314d.tar.bz2 bluetooth-0949556a08b04798fcf8a8a47aa95e7d352b314d.zip |
Merge latest tizen_3.0 bug fix codes
--------------------------------------------------
commit f426f42dde18b4629190022eb301e53ea215ab72
Author: Lee Hyuk <hyuk0512.lee@samsung.com>
Date: Mon Feb 6 09:02:04 2017 +0900
Revert "Fix the build fail for TV profile"
--------------------------------------------------
Change-Id: I0661eb19f7d88167caa7dfaadc207bcd0ef75e3f
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | include/bluetooth_internal.h | 355 | ||||
-rw-r--r-- | include/bluetooth_private.h | 166 | ||||
-rw-r--r-- | include/bluetooth_type.h | 3 | ||||
-rw-r--r-- | include/bluetooth_type_internal.h | 299 | ||||
-rw-r--r-- | src/bluetooth-adapter.c | 59 | ||||
-rw-r--r-- | src/bluetooth-audio.c | 141 | ||||
-rw-r--r-- | src/bluetooth-avrcp.c | 7 | ||||
-rw-r--r-- | src/bluetooth-common.c | 315 | ||||
-rw-r--r-- | src/bluetooth-device.c | 9 | ||||
-rw-r--r-- | src/bluetooth-gatt.c | 2 | ||||
-rw-r--r-- | src/bluetooth-map-client.c | 399 | ||||
-rw-r--r-- | src/bluetooth-proximity.c | 65 | ||||
-rw-r--r-- | src/bluetooth-tds.c | 1179 | ||||
-rw-r--r-- | test/bt_unit_test.c | 389 | ||||
-rw-r--r-- | test/bt_unit_test.h | 26 |
16 files changed, 3156 insertions, 260 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cac390..377965c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ src/bluetooth-device.c src/bluetooth-socket.c src/bluetooth-opp-server.c src/bluetooth-opp-client.c +src/bluetooth-map-client.c src/bluetooth-pan.c src/bluetooth-hdp.c src/bluetooth-hid.c @@ -47,6 +48,7 @@ src/bluetooth-gatt.c src/bluetooth-ipsp.c src/bluetooth-dpm.c src/bluetooth-proximity.c +src/bluetooth-tds.c ) LIST(APPEND SOURCES src/bluetooth-proximity.c) diff --git a/include/bluetooth_internal.h b/include/bluetooth_internal.h index ecc73e4..8091fda 100644 --- a/include/bluetooth_internal.h +++ b/include/bluetooth_internal.h @@ -714,9 +714,9 @@ int bt_adapter_le_enable_privacy(bool enable_privacy); * * @pre The Bluetooth service must be initialized with bt_initialize(). * - * @see bt_adapter_le_destroy_scan_filter() + * @see bt_adapter_le_scan_filter_destroy() */ -int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter); +int bt_adapter_le_scan_filter_create(bt_scan_filter_h *scan_filter); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE @@ -733,9 +733,9 @@ int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter); * * @pre The Bluetooth service must be initialized with bt_initialize(). * - * @see bt_adapter_le_create_scan_filter() + * @see bt_adapter_le_scan_filter_create() */ -int bt_adapter_le_destroy_scan_filter(bt_scan_filter_h scan_filter); +int bt_adapter_le_scan_filter_destroy(bt_scan_filter_h scan_filter); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE @@ -767,8 +767,8 @@ int bt_adapter_le_scan_filter_set_device_address(bt_scan_filter_h scan_filter, c * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -786,8 +786,8 @@ int bt_adapter_le_scan_filter_set_device_name(bt_scan_filter_h scan_filter, cons * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -808,8 +808,8 @@ int bt_adapter_le_scan_filter_set_service_uuid(bt_scan_filter_h scan_filter, con * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -828,8 +828,8 @@ int bt_adapter_le_scan_filter_set_service_uuid_with_mask(bt_scan_filter_h scan_f * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -850,8 +850,8 @@ int bt_adapter_le_scan_filter_set_service_solicitation_uuid(bt_scan_filter_h sca * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -872,8 +872,8 @@ int bt_adapter_le_scan_filter_set_service_solicitation_uuid_with_mask(bt_scan_fi * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -898,8 +898,8 @@ int bt_adapter_le_scan_filter_set_service_data(bt_scan_filter_h scan_filter, * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -920,8 +920,8 @@ int bt_adapter_le_scan_filter_set_service_data_with_mask(bt_scan_filter_h scan_f * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -946,8 +946,8 @@ int bt_adapter_le_scan_filter_set_manufacturer_data(bt_scan_filter_h scan_filter * @return 0 on success, otherwise a negative error value. * @retval #BT_ERROR_NONE Successful * @retval #BT_ERROR_NOT_INITIALIZED Not initialized - * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported * * @pre The Bluetooth service must be initialized with bt_initialize(). * @@ -974,7 +974,7 @@ int bt_adapter_le_scan_filter_set_manufacturer_data_with_mask(bt_scan_filter_h s * @pre The Bluetooth service must be initialized with bt_initialize(). * */ -int bt_adapter_le_register_scan_filter(bt_scan_filter_h scan_filter); +int bt_adapter_le_scan_filter_register(bt_scan_filter_h scan_filter); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE @@ -993,7 +993,7 @@ int bt_adapter_le_register_scan_filter(bt_scan_filter_h scan_filter); * @pre The Bluetooth service must be initialized with bt_initialize(). * */ -int bt_adapter_le_unregister_scan_filter(bt_scan_filter_h scan_filter); +int bt_adapter_le_scan_filter_unregister(bt_scan_filter_h scan_filter); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE @@ -1009,7 +1009,7 @@ int bt_adapter_le_unregister_scan_filter(bt_scan_filter_h scan_filter); * @pre The Bluetooth service must be initialized with bt_initialize(). * */ -int bt_adapter_le_unregister_all_scan_filters(void); +int bt_adapter_le_scan_filter_unregister_all(void); /** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE @@ -1777,6 +1777,23 @@ int bt_ag_is_wbs_mode(bool *wbs_mode); int bt_ag_is_connected(bool *connected); /** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Switch between the connected headsets for AG role. + * @since_tizen 3.0 + * @param[out] + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Not connected + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_ag_switch_headset(const char *remote_addr); + +/** * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE * @brief Registers a callback function that will be invoked when the SCO(Synchronous Connection Oriented link) state is changed. * @since_tizen @if MOBILE @elseif WEARABLE 2.3.1 @endif @@ -3741,6 +3758,294 @@ int bt_adapter_le_scan_filter_set_proximity_uuid(bt_scan_filter_h scan_filter); int bt_adapter_le_scan_filter_unset_proximity_uuid(bt_scan_filter_h scan_filter); /** + * @internal + * @brief API to register TDS provider. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] None + * @param[out] None + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_tds_provider_unregister() + */ +int bt_tds_provider_register(void); + +/** + * @internal + * @brief API to unregister TDS provider. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] None + * @param[out] None + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + */ +int bt_tds_provider_unregister(void); + +/** + * @internal + * @brief API to create TDS provider. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] transport Transport to be discovered over BLE. + * @param[out] provider The handle associated with the newly created provider. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + * @see bt_tds_provider_unregister() + * @see bt_tds_provider_destroy() + */ +int bt_tds_provider_create(bt_tds_provider_h *provider, bt_tds_transport_e transport); + +/** + * @internal + * @brief API to destroy TDS provider. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] provider The handle associated with the provider + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * @pre TDS provider must be created with bt_tds_provider_create(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + * @see bt_tds_provider_create() + */ +int bt_tds_provider_destroy(bt_tds_provider_h provider); + +/** + * @internal + * @brief API to set transport block data for transport provider. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] provider The handle associated with the provider + * @param[in] transport_state State of transport + * @param[in] buf transport block data + * @param[in] length transport block data length + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * @pre TDS provider must be created with bt_tds_provider_create(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + * @see bt_tds_provider_create() + */ +int bt_tds_provider_set_transport_data(bt_tds_provider_h provider, + bt_tds_transport_state_e transport_state, unsigned char *buf, int length); + +/** + * @internal + * @brief API to set TDS provider manufacturer specific data. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] buf manufacturer specific data + * @param[in] length manufacturer data length + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + * @see bt_tds_provider_create() + */ +int bt_tds_provider_set_manufacturer_data(unsigned char *buf, int length); + +/** + * @internal + * @brief API to send activation response to TDS seeker. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] address Remote device bluetooth address + * @param[in] result Result of activation request + * BT_ERROR_NONE: success + * BT_ERROR_INVALID_PARAMETER: Invalid data in activation request + * BT_ERROR_OPERATION_FAILED: Operation failed + * @param[in] provider The handle associated with the provider + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre TDS provider must be registered with bt_tds_provider_register(). + * + * @see bt_initialize() + * @see bt_tds_provider_register() + * @see bt_tds_activation_requested_cb() + * @see bt_tds_set_transport_activation_requested_cb() + * @see bt_tds_unset_transport_activation_requested_cb() + */ +int bt_tds_provider_send_activation_resp(char *address, int result, bt_tds_provider_h provider); + +/** + * @internal + * @brief API to set activation requeste callback. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_tds_activation_requested_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_tds_activation_requested_cb() + * @see bt_tds_unset_transport_activation_requested_cb() + */ +int bt_tds_set_transport_activation_requested_cb( + bt_tds_activation_requested_cb callback, void *user_data); + +/** + * @internal + * @brief API to unset activation requeste callback. + * @since_tizen @if WEARABLE 3.0 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] None + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @see bt_initialize() + * @see bt_tds_set_transport_activation_requested_cb() + */ +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); +/** * @} */ diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h index 2ce25d9..5e911f8 100644 --- a/include/bluetooth_private.h +++ b/include/bluetooth_private.h @@ -43,6 +43,7 @@ extern "C" { #define BT_ERR(fmt, args...) SLOGE(fmt, ##args) #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" +#define MAP_UUID "00001134-0000-1000-8000-00805f9b34fb" /* Manufacture ID for Apple iBeacons */ #define COMPANY_ID_APPLE 0x004C @@ -80,6 +81,8 @@ typedef enum { BT_EVENT_OPP_CLIENT_PUSH_RESPONSED, /**< OPP client connection is responsed */ BT_EVENT_OPP_CLIENT_PUSH_PROGRESS, /**< OPP client push progress */ BT_EVENT_OPP_CLIENT_PUSH_FINISHED, /**< OPP client push is finished */ + BT_EVENT_MAP_CONNECTION_REQUESTED, /**< MAP connection is requested */ + BT_EVENT_MAP_CLIENT_OP_COMPLETE, /**< MAP client operation is complete */ BT_EVENT_PAN_CONNECTION_STATE_CHANGED, /**< PAN connection change */ BT_EVENT_NAP_CONNECTION_STATE_CHANGED, /**< NAP connection change */ BT_EVENT_HDP_CONNECTED, /**< HDP connection change */ @@ -148,6 +151,13 @@ typedef enum { BT_EVENT_HF_CALL_STATUS_UPDATED_EVENT, /**< Audio - HF call status updated callback */ BT_EVENT_HF_REMOTE_CALL_EVENT, /**< Audio - HF : call state event callback */ BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED, /**< Audio - HF : device state changed callback */ + BT_EVENT_MAP_CLIENT_LIST_FOLDERS, /**< MAP client - listFolders event*/ + BT_EVENT_MAP_CLIENT_LIST_FILTER_FIELDS, /**< MAP - get filter field list callback */ + BT_EVENT_MAP_CLIENT_LIST_MESSAGES, /**< MAP - listMessages event*/ + 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; @@ -172,6 +182,7 @@ typedef enum { 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; @@ -451,60 +462,6 @@ typedef void (*_bt_gatt_client_value_changed_cb)(char *char_path, /** * @internal * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE - * @brief Enumaration for the address type field in manufactrer specific data - * @since_tizen 3.0 - */ -typedef enum { - ADDRESS_NONE_TYPE = 0x00, - WI_FI_P2P_ADDRESS = 0x01, - BLUETOOTH_ADDRESS = 0x02, - INDICATION_ADDRESS = 0x04, - IPV4_ADDRESS = 0x08, - IPV6_ADDRESS = 0x10, - UNKNOWN_ADDRESS = 0xff -} connectivity_address_t; - -/** - * @internal - * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE - * @brief Enumaration for the proximity locality type field in manufactrer specific data - * @since_tizen 3.0 - */ -typedef enum { - NONE_TYPE = 0x00, - PROXIMITY = 0x01, - CO_PRESENCE = 0x02, - UNKNOWN_TYPE = 0xff -} bt_proximity_locality_t; - -/** - * @internal - * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE - * @brief Structure of samsung specific manufacturer data - * @since_tizen 3.0 - */ -typedef struct { - unsigned char version; - unsigned char service_id; - unsigned char discovery_version; - unsigned char associated_service_id; - bt_proximity_locality_t proximity_locality_type; - unsigned char proximity_locality_info; - unsigned char device_type; - unsigned char device_icon; - unsigned char auth_info[5]; - connectivity_address_t addr_type; - unsigned char addr1[6]; - unsigned char addr2[6]; - unsigned char channel_info; - unsigned char associated_service_data_len; - unsigned char *associated_service_data_val; - char *name; -} bt_manufacturer_data; - -/** - * @internal - * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE * @brief Called when trying to be displayed the passkey. * @since_tizen 3.0 * @@ -521,7 +478,19 @@ typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, c #define BT_CHECK_INPUT_PARAMETER(arg) \ if (arg == NULL) { \ - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, BT_ERROR_INVALID_PARAMETER); \ + LOGE("[%s] INVALID_PARAMETER(0%s=NULL)", __FUNCTION__, #arg); \ + return BT_ERROR_INVALID_PARAMETER; \ + } + +#define BT_CHECK_INPUT_PARAMETER_UINT(arg) \ + if (arg < -1) { \ + LOGE("[%s] INVALID_PARAMETER_UINT(%s=%d)", __FUNCTION__, #arg, arg); \ + return BT_ERROR_INVALID_PARAMETER; \ + } + +#define BT_CHECK_INPUT_PARAMETER_BOOL(arg) \ + if (arg < -1 || arg > 1) { \ + LOGE("[%s] INVALID_PARAMETER_BOOL(%s=%d)", __FUNCTION__, #arg, arg); \ return BT_ERROR_INVALID_PARAMETER; \ } @@ -534,6 +503,7 @@ typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, c #define BT_FEATURE_HID_HOST "tizen.org/feature/network.bluetooth.hid" #define BT_FEATURE_HID_DEVICE "tizen.org/feature/network.bluetooth.hid_device" #define BT_FEATURE_OPP "tizen.org/feature/network.bluetooth.opp" +#define BT_FEATURE_MAP "tizen.org/feature/network.bluetooth.map" #define BT_FEATURE_TETHERING "tizen.org/feature/network.tethering.bluetooth" #define BT_FEATURE_PBAP_CLIENT "tizen.org/feature/network.bluetooth.phonebook.client" @@ -638,6 +608,13 @@ int _bt_get_bt_device_info_s(bt_device_info_s **dest_dev, bluetooth_device_info_ /** * @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. */ void _bt_free_bt_device_info_s(bt_device_info_s *device_info); @@ -694,27 +671,6 @@ typedef enum { /** * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE - * @brief Enumerations for the call event from Audio-Gateway device - * @since_tizen 3.0 - */ -typedef enum { - BT_HF_REMOTE_CALL_EVENT_IDLE = 0x00, /**< Idle. Neither setup call nor active call exist */ - BT_HF_REMOTE_CALL_EVENT_INCOMING, /**< (Call-setup event) Received an incoming call on AG */ - BT_HF_REMOTE_CALL_EVENT_DIALING, /**< (Call-setup event) Dialing an outgoing call on AG */ - BT_HF_REMOTE_CALL_EVENT_ALERTING, /**< (Call-setup event) Remote party being alerted in an outgoing call of AG */ - BT_HF_REMOTE_CALL_EVENT_CALL_TERMINATED, /**< (Call-setup event) Setup call is terminated without activating */ - BT_HF_REMOTE_CALL_EVENT_CALL_STARTED, /**< (Active call state event) Call is started on AG */ - BT_HF_REMOTE_CALL_EVENT_CALL_ENDED, /**< (Active call state event) Active call is terminated on AG */ - BT_HF_REMOTE_CALL_EVENT_UNHELD, /**< (Call held event) No calls on hold */ - BT_HF_REMOTE_CALL_EVENT_SWAPPED, /**< (Call held event) Call is placed on hold or active/held calls swapped */ - BT_HF_REMOTE_CALL_EVENT_HELD, /**< (Call held event) Calls on hold, no active call */ - BT_HF_REMOTE_CALL_EVENT_RINGING, /**< Incoming call is ringing event with number. This event is optional event. */ - BT_HF_REMOTE_CALL_EVENT_WAITING, /**< Call Waiting notification in 3-way call scenario */ - BT_HF_REMOTE_CALL_EVENT_FAILED_TO_DIALING, /**< Failed to dialing a outgoing call on AG */ -} bt_hf_remote_call_event_e; - -/** - * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE * @brief Called when a device status changed event happend from Audio-Gateway device * @since_tizen 3.0 * @@ -727,20 +683,6 @@ typedef enum { */ typedef void (*bt_hf_remote_device_state_changed_cb) (bt_hf_remote_device_state_e state, int value, void *user_data); - -/** - * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE - * @brief Called when a call event happend from Audio-Gateway device - * @since_tizen 3.0 - * - * @param[in] event The call state chagned event from remote Audio-Gateway device - * @param[in] user_data The user data passed from the callback registration function - * - * @see bt_hf_set_remote_call_event_cb() - * @see bt_hf_unset_remote_call_event_cb() - */ -typedef void (*bt_hf_remote_call_event_cb) (bt_hf_remote_call_event_e event, char *phone_number, void *user_data); - /** * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE * @brief Called when a vendor command event happened from Hands-Free. @@ -877,6 +819,48 @@ int _bt_check_proximity_is_initialized(bool *is_initialized); */ 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); + typedef enum { _PROFILE_UNKNOWN = 0, _PROFILE_MOBILE = 0x1, @@ -888,7 +872,7 @@ typedef enum { extern tizen_profile_t _get_tizen_profile(); extern tizen_profile_t profile; -#define TIZEN_PROFILE_(x) (( (__builtin_expect(profile != _PROFILE_UNKNOWN, 1)) ? \ +#define TIZEN_PROFILE_(x) (((__builtin_expect(profile != _PROFILE_UNKNOWN, 1)) ? \ (profile) : _get_tizen_profile()) \ & (x)) diff --git a/include/bluetooth_type.h b/include/bluetooth_type.h index 8c547fe..c0f091d 100644 --- a/include/bluetooth_type.h +++ b/include/bluetooth_type.h @@ -1912,6 +1912,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected, * @param[in] request_id The identification of this request. It will be used to send a response. * @param[in] server The GATT server handle * @param[in] gatt_handle The characteristic or descriptor's GATT handle which has an old value + * @param[in] response_needed Indicates whether a response is required by the remote device - @c true if required, @c false if not * @param[in] offset The requested offset from where the @a gatt_handle value will be updated * @param[in] value The new value * @param[in] len The length of @a value @@ -1922,7 +1923,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected, */ typedef void (*bt_gatt_server_write_value_requested_cb) (const char *remote_address, int request_id, bt_gatt_server_h server, - bt_gatt_h gatt_handle, int offset, + bt_gatt_h gatt_handle, bool response_needed, int offset, const char *value, int len, void *user_data); /** diff --git a/include/bluetooth_type_internal.h b/include/bluetooth_type_internal.h index c3c2343..fc9c903 100644 --- a/include/bluetooth_type_internal.h +++ b/include/bluetooth_type_internal.h @@ -23,6 +23,9 @@ extern "C" { #endif /* __cplusplus */ +/* This variable will be added into bt_service_class_t in tizen 4.0 */ +#define BT_SC_MAP_SERVICE_MASK 0x00800000 /**< MAP service class */ + /** * @file bluetooth_type_internal.h */ @@ -84,6 +87,27 @@ typedef enum { } bt_ag_call_state_e; /** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE + * @brief Enumerations for the call event from Audio-Gateway device + * @since_tizen @if WEARABLE 3.0 @endif + */ +typedef enum { + BT_HF_REMOTE_CALL_EVENT_IDLE = 0x00, /**< Idle. Neither setup call nor active call exist */ + BT_HF_REMOTE_CALL_EVENT_INCOMING, /**< (Call-setup event) Received an incoming call on AG */ + BT_HF_REMOTE_CALL_EVENT_DIALING, /**< (Call-setup event) Dialing an outgoing call on AG */ + BT_HF_REMOTE_CALL_EVENT_ALERTING, /**< (Call-setup event) Remote party being alerted in an outgoing call of AG */ + BT_HF_REMOTE_CALL_EVENT_CALL_TERMINATED, /**< (Call-setup event) Setup call is terminated without activating */ + BT_HF_REMOTE_CALL_EVENT_CALL_STARTED, /**< (Active call state event) Call is started on AG */ + BT_HF_REMOTE_CALL_EVENT_CALL_ENDED, /**< (Active call state event) Active call is terminated on AG */ + BT_HF_REMOTE_CALL_EVENT_UNHELD, /**< (Call held event) No calls on hold */ + BT_HF_REMOTE_CALL_EVENT_SWAPPED, /**< (Call held event) Call is placed on hold or active/held calls swapped */ + BT_HF_REMOTE_CALL_EVENT_HELD, /**< (Call held event) Calls on hold, no active call */ + BT_HF_REMOTE_CALL_EVENT_RINGING, /**< Incoming call is ringing event with number. This event is optional event. */ + BT_HF_REMOTE_CALL_EVENT_WAITING, /**< Call Waiting notification in 3-way call scenario */ + BT_HF_REMOTE_CALL_EVENT_FAILED_TO_DIALING, /**< Failed to dialing a outgoing call on AG */ +} bt_hf_remote_call_event_e; + +/** * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_MODULE * @brief Enumerations for the transfer type * @since_tizen 3.0 @@ -94,6 +118,102 @@ typedef enum { } bt_opp_transfer_type_t; /** + * @ingroup CAPI_NETWORK_BLUETOOTH_MAP_CLIENT_MODULE + * @brief + * @since_tizen 3.0 + */ +typedef void* bt_map_client_session_info_h; + +typedef void* bt_map_client_message_object_h; + +typedef struct { + int16_t offset; + int16_t max_count; +} bt_map_client_list_folders_filter_s; + +typedef struct { + int16_t offset; + int16_t max_count; + int8_t subject_length; + char *fields; + char *types; + char *period_begin; + char *period_end; + int is_read; + char *recipient; + char *sender; + int is_priority; +} bt_map_client_list_messages_filter_s; + +typedef struct { + bt_map_client_message_object_h message_object; + char *folder; + char *subject; + char *timestamp; + char *sender; + char *sender_address; + char *reply_to; + char *recipient; + char *recipient_address; + char *type; + int64_t size; + int is_text; + char *status; + int64_t attachment_size; + int is_priority; + int is_read; + int is_sent; + int is_protected; +} bt_map_client_message_item_s; + +typedef struct { + int is_transparent; + int is_retry; + char *charset; +} bt_map_client_push_message_args_s; + +typedef struct { + char *file_path; +// TODO: maybe some additional fields could be supported +// char *folder; +// char *subject; +// char *timestamp; +// char *sender; +// char *sender_address; +// char *reply_to; +// char *recipient; +// char *recipient_address; +// char *type; +// int64_t size; +// char *status; +// int is_priority; +// int is_read; +// int is_deleted; +// int is_sent; +// int is_protected; +} bt_map_client_message_s; + +typedef bt_map_client_list_folders_filter_s *bt_map_client_list_folders_filter_h; + +typedef bt_map_client_list_messages_filter_s *bt_map_client_list_messages_filter_h; + +typedef bt_map_client_message_item_s *bt_map_client_message_item_h; + +typedef bt_map_client_push_message_args_s *bt_map_client_push_message_args_h; + +typedef bt_map_client_message_s *bt_map_client_message_h; + +typedef void (*bt_map_client_list_folders_cb)(int result, char **folders, int count, void *user_data); + +typedef void (*bt_map_client_list_filter_fields_cb)(int result, char **filter_fields, int count, void *user_data); + +typedef void (*bt_map_client_list_messages_cb)(int result, bt_map_client_message_item_s *messages, int count, void *user_data); + +typedef void (*bt_map_client_push_message_cb)(int result, void *user_data); + +typedef void (*bt_map_client_get_message_cb)(int result, bt_map_client_message_h message, void *user_data); + +/** * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE * @brief Called when the connectable state changes. * @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif @@ -391,6 +511,60 @@ typedef struct { } bt_dpm_uuids_list_s; /** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enumaration for the address type field in manufactrer specific data + * @since_tizen 3.0 + */ +typedef enum { + ADDRESS_NONE_TYPE = 0x00, + WI_FI_P2P_ADDRESS = 0x01, + BLUETOOTH_ADDRESS = 0x02, + INDICATION_ADDRESS = 0x04, + IPV4_ADDRESS = 0x08, + IPV6_ADDRESS = 0x10, + UNKNOWN_ADDRESS = 0xff +} connectivity_address_t; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enumaration for the proximity locality type field in manufactrer specific data + * @since_tizen 3.0 + */ +typedef enum { + NONE_TYPE = 0x00, + PROXIMITY = 0x01, + CO_PRESENCE = 0x02, + UNKNOWN_TYPE = 0xff +} bt_proximity_locality_t; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Structure of samsung specific manufacturer data + * @since_tizen 3.0 + */ +typedef struct { + unsigned char version; + unsigned char service_id; + unsigned char discovery_version; + unsigned char associated_service_id; + bt_proximity_locality_t proximity_locality_type; + unsigned char proximity_locality_info; + unsigned char device_type; + unsigned char device_icon; + unsigned char auth_info[5]; + connectivity_address_t addr_type; + unsigned char addr1[6]; + unsigned char addr2[6]; + unsigned char channel_info; + unsigned char associated_service_data_len; + unsigned char *associated_service_data_val; + char *name; +} bt_manufacturer_data; + +/** * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE * @brief Trusted Profile enumeration. * @since_tizen 3.0 @@ -551,6 +725,52 @@ typedef void (*bt_proximity_reporter_connection_state_changed_cb) /** * @internal + * @brief Various TDS transport states. + * @since_tizen 3.0 + */ +typedef enum { + 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; + +/** + * @internal + * @brief Various TDS transports. + * @since_tizen 3.0 + */ +typedef enum { + BT_TDS_TRANSPORT_BT = 0x01, /* Transport BR-EDR */ + BT_TDS_TRANSPORT_CUSTOM, /* Transport custom */ + /* ... */ + 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 * @brief Called when remote device requests authentication. * @since_tizen 3.0 @@ -586,11 +806,24 @@ typedef void (*bt_adapter_authentication_req_cb)(int result, bt_authentication_t * @since_tizen 2.3.2 */ typedef struct { - int app_id; /**< The application ID */ - char *message; /**< Command message */ + int app_id; /**< The application ID */ + char *message; /**< Command message */ } bt_hf_vendor_dep_at_cmd_s; /** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE + * @brief Called when a call event happend from Audio-Gateway device + * @since_tizen @if WEARABLE 3.0 @endif + * + * @param[in] event The call state chagned event from remote Audio-Gateway device + * @param[in] user_data The user data passed from the callback registration function + * + * @see bt_hf_set_remote_call_event_cb() + * @see bt_hf_unset_remote_call_event_cb() + */ +typedef void (*bt_hf_remote_call_event_cb) (bt_hf_remote_call_event_e event, char *phone_number, void *user_data); + +/** * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE * @brief Called when a XSAT vendor command is transmitted from Hands-Free. * @since_tizen 2.3 @@ -603,6 +836,68 @@ typedef struct { typedef void (*bt_ag_vendor_cmd_cb) (char *command, void *user_data); /** + * @internal + * @brief The handle of a Transport Discover Service Provider. + * @since_tizen 3.0 + */ +typedef void *bt_tds_provider_h; + +/** + * @internal + * @brief Called when remote device requests transport activation + * @since_tizen 3.0 + * @param[in] remote_bd_addr Remote device address + * @param[in] transport transport to be activated + * @param[in] buf transport activation request data buffer + * @param[in] len transport activation request data buffer length + * @param[in] user_data The user data passed from the callback registration function + * + * @see bt_tds_set_transport_activation_requested_cb() + */ +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); +/** * @} */ diff --git a/src/bluetooth-adapter.c b/src/bluetooth-adapter.c index 2ed50a4..b8a71c1 100644 --- a/src/bluetooth-adapter.c +++ b/src/bluetooth-adapter.c @@ -160,14 +160,14 @@ int bt_adapter_get_address(char **address) error_code = _bt_get_error_code(bluetooth_get_local_address(&loc_address)); if (error_code != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */ - BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */ error_code); /* LCOV_EXCL_LINE */ return error_code; /* LCOV_EXCL_LINE */ } error_code = _bt_convert_address_to_string(address, &loc_address); if (error_code != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */ - BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */ error_code); /* LCOV_EXCL_LINE */ return error_code; /* LCOV_EXCL_LINE */ } @@ -441,14 +441,14 @@ int bt_adapter_get_name(char **name) ret = _bt_get_error_code(bluetooth_get_local_name(&loc_name)); if (ret != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */ - BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), /* LCOV_EXCL_LINE */ ret); /* LCOV_EXCL_LINE */ return ret; /* LCOV_EXCL_LINE */ } *name = strdup(loc_name.name); if (*name == NULL) { - BT_ERR("OUT_OF_MEMORY(0x%08x)", + BT_ERR("OUT_OF_MEMORY(0x%08x)", /* LCOV_EXCL_LINE */ BT_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */ return BT_ERROR_OUT_OF_MEMORY; } @@ -470,7 +470,7 @@ int bt_adapter_set_name(const char *name) ret = _bt_get_error_code(bluetooth_set_local_name(&loc_name)); if (ret != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */ - BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), /* LCOV_EXCL_LINE */ ret); /* LCOV_EXCL_LINE */ } /* LCOV_EXCL_LINE */ @@ -617,14 +617,14 @@ int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb foreach_cb, dev_list = g_ptr_array_new(); if (dev_list == NULL) { - BT_ERR("OUT_OF_MEMORY(0x%08x)", + BT_ERR("OUT_OF_MEMORY(0x%08x)", /* LCOV_EXCL_LINE */ BT_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */ return BT_ERROR_OUT_OF_MEMORY; } ret = _bt_get_error_code(bluetooth_get_bonded_device_list(&dev_list)); if (ret != BT_ERROR_NONE) { - BT_ERR("%s(0x%08x) : Failed to get bonded device list", + BT_ERR("%s(0x%08x) : Failed to get bonded device list", /* LCOV_EXCL_LINE */ _bt_convert_error_to_string(ret), ret); /* LCOV_EXCL_LINE */ return ret; } @@ -635,7 +635,7 @@ int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb foreach_cb, ret = _bt_get_bt_device_info_s(&dev_info, (bluetooth_device_info_t *)ptr); if (ret != BT_ERROR_NONE) { - BT_ERR("%s(0x%08x) : Failed to get device info", + BT_ERR("%s(0x%08x) : Failed to get device info", /* LCOV_EXCL_LINE */ _bt_convert_error_to_string(ret), ret); /* LCOV_EXCL_LINE */ break; @@ -647,7 +647,7 @@ int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb foreach_cb, } _bt_free_bt_device_info_s(dev_info); /* LCOV_EXCL_LINE */ } else { - BT_ERR("OPERATION_FAILED(0x%08x)", + BT_ERR("OPERATION_FAILED(0x%08x)", /* LCOV_EXCL_LINE */ BT_ERROR_OPERATION_FAILED); /* LCOV_EXCL_LINE */ ret = BT_ERROR_OPERATION_FAILED; break; @@ -725,6 +725,7 @@ int bt_adapter_is_service_used(const char *service_uuid, bool *used) &is_used)); *used = is_used ? true : false; /* LCOV_EXCL_LINE */ } + /* TODO: MAP? see above */ if (ret != BT_ERROR_NONE) { /* LCOV_EXCL_LINE */ BT_ERR("%s(0x%08x) : Failed to run function", @@ -735,6 +736,7 @@ int bt_adapter_is_service_used(const char *service_uuid, bool *used) return ret; } +/* LCOV_EXCL_START */ int bt_adapter_foreach_profile_connected_devices(const char *profile_uuid, bt_adapter_profile_connected_devices_cb callback, void *user_data) { @@ -796,7 +798,7 @@ int bt_adapter_foreach_profile_connected_devices(const char *profile_uuid, g_ptr_array_free(addr_list, TRUE); return ret; -} +} /* LCOV_EXCL_STOP */ int bt_adapter_set_state_changed_cb(bt_adapter_state_changed_cb callback, void *user_data) @@ -1511,7 +1513,6 @@ int bt_adapter_le_set_scan_mode(bt_adapter_le_scan_mode_e scan_mode) } /* LCOV_EXCL_LINE */ return ret; } -/* LCOV_EXCL_STOP */ int bt_adapter_le_set_customized_scan_mode(float scan_interval, float scan_window) { @@ -1529,7 +1530,7 @@ int bt_adapter_le_set_customized_scan_mode(float scan_interval, float scan_windo BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret); return ret; -} +} /* LCOV_EXCL_STOP */ int bt_adapter_le_create_advertiser(bt_advertiser_h *advertiser) { @@ -3330,7 +3331,7 @@ int bt_adapter_le_get_scan_result_ibeacon_report(const bt_adapter_le_device_scan /* LCOV_EXCL_START */ -int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter) +int bt_adapter_le_scan_filter_create(bt_scan_filter_h *scan_filter) { bt_le_scan_filter_s *__filter = NULL; @@ -3351,7 +3352,7 @@ int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter) return BT_ERROR_NONE; } -int bt_adapter_le_destroy_scan_filter(bt_scan_filter_h scan_filter) +int bt_adapter_le_scan_filter_destroy(bt_scan_filter_h scan_filter) { bt_le_scan_filter_s *__filter = (bt_le_scan_filter_s *)scan_filter; @@ -3639,7 +3640,7 @@ int bt_adapter_le_scan_filter_set_manufacturer_data_with_mask(bt_scan_filter_h s return BT_ERROR_NONE; } -int bt_adapter_le_register_scan_filter(bt_scan_filter_h scan_filter) +int bt_adapter_le_scan_filter_register(bt_scan_filter_h scan_filter) { int error_code = BT_ERROR_NONE; bt_le_scan_filter_s *__filter = (bt_le_scan_filter_s *)scan_filter; @@ -3666,7 +3667,7 @@ int bt_adapter_le_register_scan_filter(bt_scan_filter_h scan_filter) return error_code; } -int bt_adapter_le_unregister_scan_filter(bt_scan_filter_h scan_filter) +int bt_adapter_le_scan_filter_unregister(bt_scan_filter_h scan_filter) { int error_code = BT_ERROR_NONE; bt_le_scan_filter_s *__filter = (bt_le_scan_filter_s *)scan_filter; @@ -3689,7 +3690,7 @@ int bt_adapter_le_unregister_scan_filter(bt_scan_filter_h scan_filter) return error_code; } -int bt_adapter_le_unregister_all_scan_filters(void) +int bt_adapter_le_scan_filter_unregister_all(void) { int error_code = BT_ERROR_NONE; @@ -3855,14 +3856,14 @@ int bt_adapter_le_scan_filter_set_proximity_uuid(bt_scan_filter_h scan_filter) BT_CHECK_INPUT_PARAMETER(scan_filter); /* register Linkloss alert scan filter */ - ret = bt_adapter_le_create_scan_filter(&pxp_linkloss_alert_filter); + ret = bt_adapter_le_scan_filter_create(&pxp_linkloss_alert_filter); if (ret == BT_ERROR_NONE) { ret = bt_adapter_le_scan_filter_set_service_uuid(pxp_linkloss_alert_filter, PXP_LINK_LOSS_SVC_UUID); if (ret == BT_ERROR_NONE) - ret = bt_adapter_le_register_scan_filter(pxp_linkloss_alert_filter); + ret = bt_adapter_le_scan_filter_register(pxp_linkloss_alert_filter); if (ret != BT_ERROR_NONE) { - bt_adapter_le_unregister_scan_filter(pxp_linkloss_alert_filter); + bt_adapter_le_scan_filter_unregister(pxp_linkloss_alert_filter); pxp_linkloss_alert_filter = NULL; } } else { @@ -3870,14 +3871,14 @@ int bt_adapter_le_scan_filter_set_proximity_uuid(bt_scan_filter_h scan_filter) } /* register Immediate alert scan filter */ - ret = bt_adapter_le_create_scan_filter(&pxp_immediate_alert_filter); + ret = bt_adapter_le_scan_filter_create(&pxp_immediate_alert_filter); if (ret == BT_ERROR_NONE) { ret = bt_adapter_le_scan_filter_set_service_uuid(pxp_immediate_alert_filter, PXP_IMMEDIATE_ALERT_SVC_UUID); if (ret == BT_ERROR_NONE) - ret = bt_adapter_le_register_scan_filter(pxp_immediate_alert_filter); + ret = bt_adapter_le_scan_filter_register(pxp_immediate_alert_filter); if (ret != BT_ERROR_NONE) { - bt_adapter_le_unregister_scan_filter(pxp_immediate_alert_filter); + bt_adapter_le_scan_filter_unregister(pxp_immediate_alert_filter); pxp_immediate_alert_filter = NULL; } } else { @@ -3885,14 +3886,14 @@ int bt_adapter_le_scan_filter_set_proximity_uuid(bt_scan_filter_h scan_filter) } /* register Signal loss scan filter */ - ret = bt_adapter_le_create_scan_filter(&pxp_signal_loss_filter); + ret = bt_adapter_le_scan_filter_create(&pxp_signal_loss_filter); if (ret == BT_ERROR_NONE) { ret = bt_adapter_le_scan_filter_set_service_uuid(pxp_signal_loss_filter, PXP_TX_POWER_SVC_UUID); if (ret == BT_ERROR_NONE) - ret = bt_adapter_le_register_scan_filter(pxp_signal_loss_filter); + ret = bt_adapter_le_scan_filter_register(pxp_signal_loss_filter); if (ret != BT_ERROR_NONE) { - bt_adapter_le_unregister_scan_filter(pxp_signal_loss_filter); + bt_adapter_le_scan_filter_unregister(pxp_signal_loss_filter); pxp_signal_loss_filter = NULL; } } else { @@ -3911,19 +3912,19 @@ int bt_adapter_le_scan_filter_unset_proximity_uuid(bt_scan_filter_h scan_filter) /* unregister Linkloss alert scan filter */ if (pxp_linkloss_alert_filter) { - ret = bt_adapter_le_unregister_scan_filter(pxp_linkloss_alert_filter); + ret = bt_adapter_le_scan_filter_unregister(pxp_linkloss_alert_filter); pxp_linkloss_alert_filter = NULL; } /* unregister Immediate alert scan filter */ if (pxp_immediate_alert_filter) { - ret = bt_adapter_le_unregister_scan_filter(pxp_immediate_alert_filter); + ret = bt_adapter_le_scan_filter_unregister(pxp_immediate_alert_filter); pxp_immediate_alert_filter = NULL; } /* unregister Signal loss scan filter */ if (pxp_signal_loss_filter) { - ret = bt_adapter_le_unregister_scan_filter(pxp_signal_loss_filter); + ret = bt_adapter_le_scan_filter_unregister(pxp_signal_loss_filter); pxp_signal_loss_filter = NULL; } diff --git a/src/bluetooth-audio.c b/src/bluetooth-audio.c index 222afd7..623cc77 100644 --- a/src/bluetooth-audio.c +++ b/src/bluetooth-audio.c @@ -595,7 +595,6 @@ int bt_ag_notify_call_list(bt_call_list_h list) return error; } -/* LCOV_EXCL_STOP */ int bt_ag_notify_vendor_cmd(const char *command) { @@ -611,7 +610,7 @@ int bt_ag_notify_vendor_cmd(const char *command) if (error != BT_ERROR_NONE) BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error); return error; -} +} /* LCOV_EXCL_STOP */ int bt_ag_notify_voice_recognition_state(bool state) { @@ -675,6 +674,27 @@ int bt_ag_unset_multi_call_handling_event_cb(void) return BT_ERROR_NONE; } +int bt_ag_set_vendor_cmd_cb(bt_ag_vendor_cmd_cb callback, + void *user_data) +{ + BT_CHECK_HFP_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_AG_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(callback); + _bt_set_cb(BT_EVENT_AG_VENDOR_CMD, callback, user_data); + return BT_ERROR_NONE; +} + +int bt_ag_unset_vendor_cmd_cb(void) +{ + BT_CHECK_HFP_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_AG_INIT_STATUS(); + if (_bt_check_cb(BT_EVENT_AG_VENDOR_CMD) == true) + _bt_unset_cb(BT_EVENT_AG_VENDOR_CMD); + return BT_ERROR_NONE; +} + int bt_ag_set_dtmf_transmitted_cb(bt_ag_dtmf_transmitted_cb callback, void *user_data) { @@ -719,6 +739,27 @@ int bt_ag_is_connected(bool *connected) return error; } +int bt_ag_switch_headset(const char *remote_addr) +{ + int error; + + BT_CHECK_HFP_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_AG_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(remote_addr); + + char *addr = g_strdup(remote_addr); + BT_INFO("Remote address = %s", addr); + + error = bluetooth_telephony_set_active_headset(addr); + error = _bt_get_error_code(error); + + if (error != BT_ERROR_NONE) + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error); + + return error; +} + int bt_call_list_create(bt_call_list_h *list) { call_list_s *handle; @@ -827,42 +868,47 @@ int bt_a2dp_set_content_protection(bool status) int bt_hf_initialize(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; - BT_CHECK_INIT_STATUS(); error = bluetooth_hf_init(_bt_hf_event_proxy, NULL); error = _bt_get_error_code(error); if (BT_ERROR_NONE != error) { BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error); return error; } + + is_audio_hf_initialized = true; + return error; } int bt_hf_deinitialize(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; - BT_CHECK_INIT_STATUS(); error = bluetooth_hf_deinit(); error = _bt_get_error_code(error); - if (BT_ERROR_NONE != error) { + if (BT_ERROR_NONE != error) BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error); - return error; - } - return error; + + is_audio_hf_initialized = false; + + return BT_ERROR_NONE; } int bt_hf_notify_call_event(bt_hf_call_event_e event, char *phone_number) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error = BT_ERROR_NONE; @@ -911,8 +957,9 @@ int bt_hf_notify_call_event(bt_hf_call_event_e event, char *phone_number) int bt_hf_notify_speaker_gain(int gain) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; @@ -926,8 +973,9 @@ int bt_hf_notify_speaker_gain(int gain) int bt_hf_set_speaker_gain_changed_cb(bt_hf_speaker_gain_changed_cb callback, void *user_data) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_SPEAKER_GAIN_CHANGE, callback, user_data); @@ -936,8 +984,9 @@ int bt_hf_set_speaker_gain_changed_cb(bt_hf_speaker_gain_changed_cb callback, vo int bt_hf_unset_speaker_gain_changed_cb(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_SPEAKER_GAIN_CHANGE) == true) _bt_unset_cb(BT_EVENT_HF_SPEAKER_GAIN_CHANGE); @@ -946,8 +995,9 @@ int bt_hf_unset_speaker_gain_changed_cb(void) int bt_hf_notify_voice_recognition_state(bool state) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; @@ -961,8 +1011,9 @@ int bt_hf_notify_voice_recognition_state(bool state) int bt_hf_set_call_status_updated_event_cb(bt_hf_call_status_updated_event_cb callback, void *user_data) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_CALL_STATUS_UPDATED_EVENT, callback, user_data); @@ -971,8 +1022,9 @@ int bt_hf_set_call_status_updated_event_cb(bt_hf_call_status_updated_event_cb ca int bt_hf_unset_call_status_updated_event_cb(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_CALL_STATUS_UPDATED_EVENT) == true) _bt_unset_cb(BT_EVENT_HF_CALL_STATUS_UPDATED_EVENT); @@ -981,8 +1033,9 @@ int bt_hf_unset_call_status_updated_event_cb(void) int bt_hf_close_sco(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; @@ -996,8 +1049,9 @@ int bt_hf_close_sco(void) int bt_hf_send_dtmf(char *dtmf) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); int error; @@ -1011,8 +1065,9 @@ int bt_hf_send_dtmf(char *dtmf) int bt_hf_is_connected(bool *connected) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(connected); int error; @@ -1033,8 +1088,9 @@ int bt_hf_is_connected(bool *connected) int bt_hf_is_sco_opened(bool *opened) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(opened); int error; @@ -1055,8 +1111,9 @@ int bt_hf_is_sco_opened(bool *opened) int bt_hf_get_codec_id(unsigned int *codec_id) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(codec_id); int error; @@ -1071,8 +1128,9 @@ int bt_hf_get_codec_id(unsigned int *codec_id) int bt_hf_get_call_status_info_list(GSList **call_list) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(call_list); int error; @@ -1107,14 +1165,14 @@ int bt_hf_get_call_status_info_list(GSList **call_list) int bt_hf_is_inband_ringtone_supported(bool *supported) { -#ifdef TIZEN_BT_HFP_HF_ENABLE - int error; - gboolean is_supported = FALSE; - BT_CHECK_HF_SUPPORT(); BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(supported); + int error; + gboolean is_supported = FALSE; + error = bluetooth_hf_is_ibr_supported(&is_supported); error = _bt_get_error_code(error); if (error != BT_ERROR_NONE) @@ -1126,10 +1184,6 @@ int bt_hf_is_inband_ringtone_supported(bool *supported) *supported = FALSE; return error; -#else - BT_ERR("NOT_SUPPORTED(0x%08x)", BT_ERROR_NOT_SUPPORTED); - return BT_ERROR_NOT_SUPPORTED; -#endif } static void __bt_hf_free_call_status_info(void *data) @@ -1141,8 +1195,9 @@ static void __bt_hf_free_call_status_info(void *data) int bt_hf_free_call_status_info_list(GSList *call_list) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(call_list); g_slist_free_full(call_list, __bt_hf_free_call_status_info); @@ -1153,8 +1208,9 @@ int bt_hf_free_call_status_info_list(GSList *call_list) int bt_hf_set_sco_state_changed_cb(bt_hf_sco_state_changed_cb callback, void *user_data) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_SCO_CONNECTION_STATUS, callback, user_data); return BT_ERROR_NONE; @@ -1162,8 +1218,9 @@ int bt_hf_set_sco_state_changed_cb(bt_hf_sco_state_changed_cb callback, int bt_hf_unset_sco_state_changed_cb(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_SCO_CONNECTION_STATUS) == true) _bt_unset_cb(BT_EVENT_HF_SCO_CONNECTION_STATUS); @@ -1173,8 +1230,9 @@ int bt_hf_unset_sco_state_changed_cb(void) int bt_hf_set_call_handling_event_cb(bt_hf_call_handling_event_cb callback, void *user_data) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_CALL_HANDLING_EVENT, callback, user_data); @@ -1183,8 +1241,9 @@ int bt_hf_set_call_handling_event_cb(bt_hf_call_handling_event_cb callback, int bt_hf_unset_call_handling_event_cb(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_CALL_HANDLING_EVENT) == true) _bt_unset_cb(BT_EVENT_HF_CALL_HANDLING_EVENT); @@ -1195,8 +1254,9 @@ int bt_hf_set_multi_call_handling_event_cb( bt_hf_multi_call_handling_event_cb callback, void *user_data) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT, callback, user_data); @@ -1205,8 +1265,9 @@ int bt_hf_set_multi_call_handling_event_cb( int bt_hf_unset_multi_call_handling_event_cb(void) { - BT_CHECK_INIT_STATUS(); BT_CHECK_HF_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT) == true) _bt_unset_cb(BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT); @@ -1219,6 +1280,7 @@ int bt_hf_set_remote_call_event_cb( { BT_CHECK_HF_SUPPORT(); BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_REMOTE_CALL_EVENT, callback, user_data); return BT_ERROR_NONE; @@ -1228,6 +1290,7 @@ int bt_hf_unset_remote_call_event_cb(void) { BT_CHECK_HF_SUPPORT(); BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_REMOTE_CALL_EVENT) == true) _bt_unset_cb(BT_EVENT_HF_REMOTE_CALL_EVENT); return BT_ERROR_NONE; @@ -1239,6 +1302,7 @@ int bt_hf_set_remote_device_state_changed_cb( { BT_CHECK_HF_SUPPORT(); BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(callback); _bt_set_cb(BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED, callback, user_data); return BT_ERROR_NONE; @@ -1248,6 +1312,7 @@ int bt_hf_unset_remote_device_state_changed_cb(void) { BT_CHECK_HF_SUPPORT(); BT_CHECK_INIT_STATUS(); + BT_CHECK_HF_INIT_STATUS(); if (_bt_check_cb(BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED) == true) _bt_unset_cb(BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED); return BT_ERROR_NONE; diff --git a/src/bluetooth-avrcp.c b/src/bluetooth-avrcp.c index 9da615c..6a73b44 100644 --- a/src/bluetooth-avrcp.c +++ b/src/bluetooth-avrcp.c @@ -59,15 +59,17 @@ int __bt_check_avrcp_target_init_status(void) return BT_ERROR_NOT_INITIALIZED; \ } +/* LCOV_EXCL_START */ int __bt_check_avrcp_control_init_status(void) { - if (is_avrcp_control_initialized != true) { + if (is_avrcp_control_initialized != true) { /* LCOV_EXCL_LINE */ BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED); /* LCOV_EXCL_LINE */ return BT_ERROR_NOT_INITIALIZED; /* LCOV_EXCL_LINE */ } return BT_ERROR_NONE; } +/* LCOV_EXCL_STOP */ /*The below API is just to conver the error from Audio API's to CAPI error codes, * this is temporary change and changes to proper error code will be done in @@ -108,6 +110,7 @@ int bt_avrcp_target_initialize(bt_avrcp_target_connection_state_changed_cb callb return BT_ERROR_NONE; } +/* LCOV_EXCL_START */ int bt_avrcp_target_connect(const char *remote_address) { int error; @@ -144,7 +147,7 @@ int bt_avrcp_target_disconnect(const char *remote_address) BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error); return error; -} +} /* LCOV_EXCL_STOP */ int bt_avrcp_target_deinitialize(void) { diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c index c3859ff..ade64d4 100644 --- a/src/bluetooth-common.c +++ b/src/bluetooth-common.c @@ -52,6 +52,9 @@ static void __bt_free_bt_adapter_device_discovery_info_s(bt_adapter_device_disco 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); + 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); static int __bt_gatt_client_update_characteristics(bt_gatt_handle_info_t char_handles, bt_gatt_service_s *service); @@ -107,7 +110,7 @@ int bt_get_uuid_name(const char *uuid, char **name) /* BT Classic Services */ {"1101", "Serial Port Service"}, {"1102", "LAN Access Using PPP Service"}, - {"1103", "Dialup Netwworking Service"}, + {"1103", "Dialup Networking Service"}, {"1104", "IrMCSync Service"}, {"1105", "OBEX Object Push Service"}, {"1106", "OBEX File Transfer Service"}, @@ -147,7 +150,7 @@ int bt_get_uuid_name(const char *uuid, char **name) {"112D", "SIM Access Service"}, {"112E", "Phonebook Access PCE Service"}, {"112F", "Phonebook Access PSE Service"}, - {"1130", "Phonebook Access Profile"}, + {"1130", "Phonebook Access Profile"}, {"1132", "Message Access Server Service"}, {"1133", "Message Notification Server Service"}, {"1134", "Message Access Profile"}, @@ -158,7 +161,12 @@ int bt_get_uuid_name(const char *uuid, char **name) {"1204", "Generic Telephony Service"}, {"1205", "UPnP Service"}, {"1206", "UPnP Ip Service"}, + {"1303", "Video Source Service"}, + {"1304", "Video Sink Service"}, + {"1305", "Video Distribution Profile"}, {"1400", "Health Device Profile"}, + {"1401", "HDP Source Service"}, + {"1402", "HDP Sink Service"}, /* GATT Services */ {"1800", "Generic Access"}, @@ -238,6 +246,9 @@ int bt_get_uuid_name(const char *uuid, char **name) {"9A3F68E0-86CE-11E5-A309-0002A5D5C51B", "Samsung Gear Manager Service"}, {"c2f2cc0f-c085-4dd4-be5a-aca3074bbc72", "Control Point"}, {"cece518b-28d7-4171-92d5-76a1e249a3b9", "Notifications Source"}, + {"32D1955A-E5AA-4A96-9A49-08538DA8B8F6", "Samsung Gear Fit Manager Service"}, + {"FE53FF98-B259-4337-B56A-0EC9F82C6BAD", "Control Point"}, + {"C2051EE0-804D-4D50-A12C-15E243852100", "Notifications Source"}, {NULL, NULL} }; @@ -478,6 +489,55 @@ void _bt_free_bt_device_info_s(bt_device_info_s *device_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, }; @@ -988,6 +1048,10 @@ static bool __bt_need_to_handle(int event) 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; @@ -996,12 +1060,16 @@ static bool __bt_need_to_handle(int event) event_index = __bt_get_cb_index(event); if (event_index != -1 && bt_event_slot_container[event_index].callback) return true; + else + BT_DBG("Event [%d] would not handled, not found in bt_event_slot_container", event); return false; } static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *user_data) { + BT_DBG("Entered for event: %d", event); + int call_id; int *avrcp_mode; int *discoverable_timeout; @@ -1034,6 +1102,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us bt_le_data_length_params_t *data_length_info = NULL; bt_ipsp_connection_info_t *bt_ipsp_iface_info = NULL; bt_pxp_property_changed_params_t *bt_pxp_property_info = NULL; + bluetooth_tds_activation_req_t *tds_act_req_info = NULL; if (!__bt_need_to_handle(event)) return; @@ -1429,6 +1498,88 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us /* This event don't be used in CAPI */ break; + case BLUETOOTH_EVENT_MAP_CONNECTED: + BT_INFO("bt_map_client_??????????_cb() will be called"); + bd_addr = (bluetooth_device_address_t *)(param->param_data); + _bt_convert_address_to_string(&device_addr, bd_addr); + + /* TODO: MAP, see above */ + + if (device_addr != NULL) + free(device_addr); + break; + + case BLUETOOTH_EVENT_MAP_DISCONNECTED: + BT_INFO("bt_map_client_??????????_cb() will be called"); + bd_addr = (bluetooth_device_address_t *)(param->param_data); + _bt_convert_address_to_string(&device_addr, bd_addr); + + /* TODO: MAP, see above */ + + if (device_addr != NULL) + free(device_addr); + break; + case BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE: + BT_INFO("BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE event"); + //do not need to release memory, it is managed by bluetooth-frwk + bt_map_client_folders_s* folders_struct = (bt_map_client_folders_s*) param->param_data; + ((bt_map_client_list_folders_cb)bt_event_slot_container[event_index].callback) + (param->result, folders_struct->names, folders_struct->size, + bt_event_slot_container[event_index].user_data); + + if (device_addr != NULL) + free(device_addr); + break; + + case BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE: + { + BT_INFO(" BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE event"); + bt_map_list_filter_fields_info_t* fields_info = (bt_map_list_filter_fields_info_t*)(param->param_data); + + ((bt_map_client_list_filter_fields_cb)bt_event_slot_container[event_index].callback) + (param->result, fields_info->fields, fields_info->size, + bt_event_slot_container[event_index].user_data); + + if (device_addr != NULL) + free(device_addr); + } + break; + + case BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE: + BT_INFO("BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE event"); + bt_map_client_message_items_s* messages_struct = (bt_map_client_message_items_s*) param->param_data; + ((bt_map_client_list_messages_cb)bt_event_slot_container[event_index].callback)( + param->result, + (bt_map_client_message_item_s*)(messages_struct->message_items), + messages_struct->size, + bt_event_slot_container[event_index].user_data); + if (device_addr != NULL) + free(device_addr); + break; + + case BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE: + BT_INFO("BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE event"); + + bt_get_message_callback_data *data = bt_event_slot_container[event_index].user_data; + char *target_file = (char*) data->target_file; + void *user_data = data->user_data; + free(data); + + bt_map_client_message_s* res = malloc(sizeof(*res)); + res->file_path = target_file; + + ((bt_map_client_get_message_cb)bt_event_slot_container[event_index].callback)( + param->result, res, user_data); + break; + + case BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE: + BT_INFO("BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE event"); + + ((bt_map_client_push_message_cb)bt_event_slot_container[event_index].callback)( + param->result, + bt_event_slot_container[event_index].user_data); + break; + case BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED: BT_INFO("BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED"); dev_info = (bluetooth_network_device_info_t *)(param->param_data); @@ -1837,6 +1988,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us 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; @@ -1861,6 +2015,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us 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; @@ -2032,6 +2189,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGE"); if (cb == NULL) { + if (value_change->response_needed == FALSE) + return; + bluetooth_gatt_send_response(value_change->req_id, BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE, BLUETOOTH_ERROR_INTERNAL, 0, NULL, 0); @@ -2039,7 +2199,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us } cb(value_change->address, value_change->req_id, value_change->service_handle, - gatt_handle, value_change->offset, + gatt_handle, value_change->offset, value_change->response_needed, (char *)value_change->att_value, value_change->val_len, user_data); break; } @@ -2113,7 +2273,8 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us for (char_list = svc->characteristics; char_list; char_list = g_slist_next(char_list)) { bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)char_list->data; - if (chr->path && strcmp(char_val->char_handle, chr->path) == 0) { + + if (chr && g_strcmp0(char_val->char_handle, chr->path) == 0) { g_free(chr->value); chr->value = NULL; if (char_val->val_len > 0) @@ -2122,7 +2283,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us /* TODO : Fix build error temporary */ if (chr->write_value_requested_cb) chr->write_value_requested_cb(NULL, 0, (bt_gatt_server_h)serv, (bt_gatt_h)chr, - 0, (char*)char_val->char_value, char_val->val_len, + 0, TRUE, (char*)char_val->char_value, char_val->val_len, chr->write_value_requested_user_data); } } @@ -2130,7 +2291,6 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us } break; } -/* LCOV_EXCL_STOP */ case BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED: { bt_gatt_service_change_t *service_change = (bt_gatt_service_change_t *)(param->param_data); @@ -2148,6 +2308,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us _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; @@ -2206,6 +2369,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us } break; } +/* LCOV_EXCL_STOP */ case BLUETOOTH_EVENT_ADVERTISING_STARTED: BT_INFO("BLUETOOTH_EVENT_ADVERTISING_STARTED"); adv_handle = (int *)(param->param_data); @@ -2672,7 +2836,78 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us free(device_addr); /* LCOV_EXCL_STOP */ break; } + case BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED: { + BT_DBG("BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED"); /* LCOV_EXCL_LINE */ + tds_act_req_info = (bluetooth_tds_activation_req_t *)(param->param_data); + _bt_convert_address_to_string(&device_addr, &tds_act_req_info->rem_addr); + + ((bt_tds_activation_requested_cb)bt_event_slot_container[event_index].callback) /* LCOV_EXCL_LINE */ + (device_addr, tds_act_req_info->transport, tds_act_req_info->tds_data.data, + tds_act_req_info->tds_data.length, bt_event_slot_container[event_index].user_data); + + if (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; } } @@ -2745,8 +2980,43 @@ static void __bt_le_event_proxy(int event, bluetooth_event_param_t *param, void } } } - 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; } @@ -2832,7 +3102,7 @@ static void __bt_free_bt_adapter_device_discovery_info_s(bt_adapter_device_disco free(discovery_info); discovery_info = NULL; } -/* LCOV_EXCL_STOP */ + 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) @@ -2886,6 +3156,23 @@ static void __bt_free_bt_adapter_le_device_scan_info_s(bt_adapter_le_device_scan free(scan_info); 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 */ @@ -3033,6 +3320,16 @@ static int __bt_get_cb_index(int event) return BT_EVENT_OPP_CLIENT_PUSH_PROGRESS; case BLUETOOTH_EVENT_OPC_DISCONNECTED: return BT_EVENT_OPP_CLIENT_PUSH_FINISHED; + case BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE: + return BT_EVENT_MAP_CLIENT_LIST_FOLDERS; + case BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE: + return BT_EVENT_MAP_CLIENT_LIST_FILTER_FIELDS; + case BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE: + return BT_EVENT_MAP_CLIENT_LIST_MESSAGES; + case BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE: + return BT_EVENT_MAP_CLIENT_GET_MESSAGE; + case BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE: + return BT_EVENT_MAP_CLIENT_PUSH_MESSAGE; case BLUETOOTH_EVENT_NETWORK_SERVER_CONNECTED: case BLUETOOTH_EVENT_NETWORK_SERVER_DISCONNECTED: return BT_EVENT_NAP_CONNECTION_STATE_CHANGED; @@ -3244,6 +3541,8 @@ static int __bt_get_cb_index(int event) return BT_EVENT_IPSP_INIT_STATE_CHANGED; case BLUETOOTH_EVENT_PXP_PROPERTY_CHANGED: return BT_EVENT_PROXIMITY_REPORTER_PROPERTY_CHANGED; + case BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED: + return BT_EVENT_TDS_ACTIVATION_REQUESTED; default: return -1; } diff --git a/src/bluetooth-device.c b/src/bluetooth-device.c index 315f836..94fc700 100644 --- a/src/bluetooth-device.c +++ b/src/bluetooth-device.c @@ -388,13 +388,14 @@ int bt_device_unset_connection_state_changed_cb(void) return BT_ERROR_NONE; } +/* LCOV_EXCL_START */ int bt_device_unset_rssi_alert_cb(void) { BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); BT_CHECK_INIT_STATUS(); _bt_unset_cb(BT_EVENT_RSSI_ALERT_EVENT); return BT_ERROR_NONE; -} +} /* LCOV_EXCL_STOP */ int bt_device_unset_att_mtu_changed_cb(void) { @@ -404,6 +405,7 @@ int bt_device_unset_att_mtu_changed_cb(void) return BT_ERROR_NONE; } +/* LCOV_EXCL_START */ int bt_device_enable_rssi_monitor(const char *remote_address, bt_device_connection_link_type_e link_type, int low_threshold, int in_range_threshold, @@ -481,7 +483,6 @@ int bt_device_get_rssi_strength(const char *remote_address, } -/* LCOV_EXCL_START */ int bt_device_le_conn_update(const char *device_address, const bt_le_conn_update_s *parameters) { @@ -557,6 +558,10 @@ int bt_device_get_service_mask_from_uuid_list(char **uuids, service_mask |= BT_SC_OPP_SERVICE_MASK; break; + case BLUETOOTH_OBEX_MESSAGE_ACCESS_SERVICE_UUID: + service_mask |= BT_SC_MAP_SERVICE_MASK; + break; + case BLUETOOTH_OBEX_FILE_TRANSFER_UUID: service_mask |= BT_SC_FTP_SERVICE_MASK; break; diff --git a/src/bluetooth-gatt.c b/src/bluetooth-gatt.c index 2a50411..1863192 100644 --- a/src/bluetooth-gatt.c +++ b/src/bluetooth-gatt.c @@ -967,6 +967,7 @@ static void __bt_gatt_destroy_service(bt_gatt_h gatt_handle) __bt_gatt_free_service(gatt_handle); } +/* LCOV_EXCL_START */ static int __convert_int_to_signed_bits(int i, int size) { if (i < 0) @@ -1065,6 +1066,7 @@ static int __get_data_type_int_size(bt_data_type_int_e format) return 0; } } +/* LCOV_EXCL_STOP */ int bt_gatt_destroy(bt_gatt_h gatt_handle) { diff --git a/src/bluetooth-map-client.c b/src/bluetooth-map-client.c new file mode 100644 index 0000000..536f91e --- /dev/null +++ b/src/bluetooth-map-client.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <glib.h> +#include <dlog.h> +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include <bluetooth-api.h> + +#include "bluetooth.h" +#include "bluetooth_private.h" + +static bool is_map_client_initialized = false; + +#define BT_CHECK_MAP_CLIENT_SUPPORT() \ +{ \ + BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \ + BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_MAP); \ +} + +#define BT_CHECK_MAP_CLIENT_INIT_STATUS() \ + if (__bt_check_map_client_init_status() == BT_ERROR_NOT_INITIALIZED) { \ + BT_ERR("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \ + return BT_ERROR_NOT_INITIALIZED; \ + } + +int __bt_check_map_client_init_status(void) +{ + if (is_map_client_initialized != true) { + BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED); + return BT_ERROR_NOT_INITIALIZED; + } + + return BT_ERROR_NONE; +} + +int bt_map_client_initialize(void) +{ + BT_DBG("bt_map_client_initialize"); + + int error_code = BT_ERROR_NONE; + + // TODO: MAP: it is not supported on TM1 + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + + error_code = _bt_get_error_code(bluetooth_map_client_init()); + + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */ + error_code); /* LCOV_EXCL_LINE */ + return error_code; /* LCOV_EXCL_LINE */ + } + + is_map_client_initialized = true; + return error_code; +} + +int bt_map_client_deinitialize(void) +{ + BT_DBG("bt_map_client_deinitialize"); + + int error_code = BT_ERROR_NONE; + + // TODO: MAP: it is not supported on TM1 + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + + error_code = _bt_get_error_code(bluetooth_map_client_deinit()); + + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), /* LCOV_EXCL_LINE */ + error_code); /* LCOV_EXCL_LINE */ + return error_code; /* LCOV_EXCL_LINE */ + } + + is_map_client_initialized = false; + return error_code; +} + +int bt_map_client_create_session(const char* remote_address, + bt_map_client_session_info_h* handle) +{ + BT_DBG("bt_map_client_create_session"); + int error_code = BT_ERROR_NONE; + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(remote_address); + + bt_map_client_session_info_s* session = + malloc(sizeof(bt_map_client_session_info_s)); + session->remote_address = strdup(remote_address); + + error_code = _bt_get_error_code(bluetooth_map_client_create_session(session)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), + error_code); + free(session->remote_address); + free(session); + } else { + BT_DBG("Successfully created session"); + *handle = session; + } + return error_code; + +} + +int bt_map_client_destroy_session(bt_map_client_session_info_h handle) +{ + BT_DBG("bt_map_client_destroy_session"); + int error_code = BT_ERROR_NONE; + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*)handle; + + error_code = _bt_get_error_code(bluetooth_map_client_destroy_session(session)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), + error_code); + } else { + BT_DBG("Successfully destroyed session"); + } + return error_code; +} + +int bt_map_client_set_folder(bt_map_client_session_info_h handle, const char *name) +{ + int error_code = BT_ERROR_NONE; + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + BT_CHECK_INPUT_PARAMETER(name); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*)handle; + + error_code = _bt_get_error_code(bluetooth_map_client_set_folder(session, name)); + + 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_map_client_list_folders(bt_map_client_session_info_h handle, + bt_map_client_list_folders_filter_h filter, + bt_map_client_list_folders_cb callback, + void* user_data) +{ + BT_DBG("bt_map_client_list_folders"); + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + BT_CHECK_INPUT_PARAMETER(filter); + BT_CHECK_INPUT_PARAMETER_UINT(filter->offset); + BT_CHECK_INPUT_PARAMETER_UINT(filter->max_count); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*) handle; + + int error_code = _bt_get_error_code( + bluetooth_map_client_list_folders( + session, + (bt_map_client_list_folders_filter_t*) filter + ) + ); + if (error_code != BT_ERROR_NONE) { + BT_ERR("bt_map_client_list_folders %s(0x%08x)", _bt_convert_error_to_string(error_code), + error_code); + } else { + _bt_set_cb(BT_EVENT_MAP_CLIENT_LIST_FOLDERS, callback, user_data); + } + + return error_code; /* LCOV_EXCL_STOP */ +} + +int bt_map_client_list_filter_fields(bt_map_client_session_info_h handle, + bt_map_client_list_filter_fields_cb callback, + void *user_data) +{ + int error_code = BT_ERROR_NONE; + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*) handle; + + error_code = _bt_get_error_code(bluetooth_map_client_list_filter_fields(session)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), + error_code); + } else { + _bt_set_cb(BT_EVENT_MAP_CLIENT_LIST_FILTER_FIELDS, callback, user_data); + } + + return error_code; +} + +int bt_map_client_list_messages(bt_map_client_session_info_h handle, + const char* folder, + bt_map_client_list_messages_filter_h filter, + bt_map_client_list_messages_cb callback, + void *user_data) +{ + BT_DBG("bt_map_client_list_messages"); + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + BT_CHECK_INPUT_PARAMETER(filter); + BT_CHECK_INPUT_PARAMETER_UINT(filter->offset); + BT_CHECK_INPUT_PARAMETER_UINT(filter->max_count); + BT_CHECK_INPUT_PARAMETER_UINT(filter->subject_length); + BT_CHECK_INPUT_PARAMETER_BOOL(filter->is_read); + BT_CHECK_INPUT_PARAMETER_BOOL(filter->is_priority); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*) handle; + + int error_code = _bt_get_error_code( + bluetooth_map_client_list_messages( + session, + folder, + (bt_map_client_list_messages_filter_t*) filter + ) + ); + if (error_code != BT_ERROR_NONE) { + BT_ERR("bluetooth_map_client_list_messages %s(0x%08x)", + _bt_convert_error_to_string(error_code), error_code); + } else { + _bt_set_cb(BT_EVENT_MAP_CLIENT_LIST_MESSAGES, callback, user_data); + } + + return error_code; +} + +int bt_map_client_update_inbox(bt_map_client_session_info_h handle) +{ + int error_code = BT_ERROR_NONE; + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*)handle; + + error_code = _bt_get_error_code(bluetooth_map_client_update_inbox(session)); + + 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_map_client_push_message(bt_map_client_session_info_h handle, + const char* source_file, + const char* folder, + bt_map_client_push_message_args_h args, + bt_map_client_push_message_cb callback, + void *user_data) +{ + BT_DBG("Entered bt_map_client_get_message"); + + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + BT_CHECK_INPUT_PARAMETER(source_file); + BT_CHECK_INPUT_PARAMETER(folder); + BT_CHECK_INPUT_PARAMETER(args); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*)handle; + + int error_code = _bt_get_error_code( + bluetooth_map_client_push_message( + session, + source_file, + folder, + (bt_map_client_push_message_args_t*) args + ) + ); + if (error_code != BT_ERROR_NONE) { + BT_ERR("bluetooth_map_client_push_message %s(0x%08x)", + _bt_convert_error_to_string(error_code), error_code); + } else { + _bt_set_cb(BT_EVENT_MAP_CLIENT_PUSH_MESSAGE, callback, user_data); + } + + return error_code; +} + +int bt_map_client_get_message(bt_map_client_session_info_h handle, + const bt_map_client_message_object_h message_object, + const char* target_file, + bool attachment, + bt_map_client_get_message_cb callback, + void* user_data) +{ + BT_DBG("Entered bt_map_client_get_message"); + //BT_CHECK_MAP_CLIENT_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_MAP_CLIENT_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(handle); + BT_CHECK_INPUT_PARAMETER(message_object); + BT_CHECK_INPUT_PARAMETER(target_file); + + bt_map_client_session_info_s* session = (bt_map_client_session_info_s*) handle; + + bt_get_message_callback_data *data = malloc(sizeof(*data)); + data->target_file = target_file; + data->user_data = user_data; + + int error_code = _bt_get_error_code(bluetooth_map_client_get_message(session, + message_object, target_file, attachment)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("bt_map_client_get_message %s(0x%08x)", _bt_convert_error_to_string(error_code), + error_code); + } else { + _bt_set_cb(BT_EVENT_MAP_CLIENT_GET_MESSAGE, callback, data); + } + + return error_code; /* LCOV_EXCL_STOP */ +} + +void bt_map_client_list_folders_filter_create(bt_map_client_list_folders_filter_h *filter) +{ + (*filter) = malloc(sizeof(bt_map_client_list_folders_filter_s)); + (*filter)->offset = -1; + (*filter)->max_count = -1; +} + +void bt_map_client_list_folders_filter_destroy(bt_map_client_list_folders_filter_h *filter) +{ + free(*filter); + *filter = NULL; +} + +void bt_map_client_list_messages_filter_create(bt_map_client_list_messages_filter_h *filter) +{ + (*filter) = malloc(sizeof(bt_map_client_list_messages_filter_s)); + (*filter)->offset = -1; + (*filter)->max_count = -1; + (*filter)->subject_length = -1; + (*filter)->fields = NULL; + (*filter)->types = NULL; + (*filter)->period_begin = NULL; + (*filter)->period_end = NULL; + (*filter)->is_read = -1; + (*filter)->recipient = NULL; + (*filter)->sender = NULL; + (*filter)->is_priority = -1; +} + +void bt_map_client_list_messages_filter_destroy(bt_map_client_list_messages_filter_h *filter) +{ + free(*filter); + *filter = NULL; +} + +void bt_map_client_push_message_args_create(bt_map_client_push_message_args_h *args) +{ + (*args) = malloc(sizeof(bt_map_client_push_message_args_s)); + (*args)->is_transparent = -1; + (*args)->is_retry = -1; + (*args)->charset = NULL; +} + +void bt_map_client_push_message_args_destroy(bt_map_client_push_message_args_h *args) +{ + free(*args); + *args = NULL; +} diff --git a/src/bluetooth-proximity.c b/src/bluetooth-proximity.c index b1bb44c..8e88796 100644 --- a/src/bluetooth-proximity.c +++ b/src/bluetooth-proximity.c @@ -138,7 +138,7 @@ int bt_proximity_reporter_destroy(bt_proximity_reporter_h reporter) return error_code; } - +/* LCOV_EXCL_START */ int _bt_check_proximity_is_initialized(bool *is_initialized) { BT_CHECK_GATT_PXP_SUPPORT(); @@ -152,7 +152,7 @@ int _bt_check_proximity_is_initialized(bool *is_initialized) return BT_ERROR_NONE; } - +/* LCOV_EXCL_STOP */ static bt_proximity_monitor_s *_bt_proximity_minotr_find(const char *remote_address) { GSList *l; @@ -165,16 +165,7 @@ static bt_proximity_monitor_s *_bt_proximity_minotr_find(const char *remote_addr } return NULL; } - -static int _bt_proximity_monitor_addr_info_cmp(gconstpointer a1, gconstpointer a2) -{ - const bt_proximity_monitor_s *c = a1; - const bt_proximity_monitor_s *b = a2; - - return g_ascii_strcasecmp(c->remote_address, b->remote_address); -} - - +/* LCOV_EXCL_START */ int _bt_proximity_connection_set_state_changed(int result, const char *remote_address, bool connected) { int service_type = 0; @@ -195,8 +186,6 @@ int _bt_proximity_connection_set_state_changed(int result, const char *remote_ad monitor_s->connected = connected; monitor_s->services_discovered = service_type; pxp_monitor_supported_services = service_type; - proximity_monitor_list = g_slist_insert_sorted(proximity_monitor_list, - monitor_s, _bt_proximity_monitor_addr_info_cmp); if (monitor_s->connection_callback) ((bt_proximity_monitor_connection_state_changed_cb)monitor_s->connection_callback) (result, remote_address, monitor_s, connected, service_type, monitor_s->user_data); @@ -213,7 +202,7 @@ int _bt_proximity_connection_set_state_changed(int result, const char *remote_ad } return error_code; } - +/* LCOV_EXCL_STOP */ int bt_proximity_monitor_create(const char *remote_address, bt_proximity_monitor_h *monitor) { int error_code = BT_ERROR_NONE; @@ -283,7 +272,7 @@ int bt_proximity_monitor_destroy(bt_proximity_monitor_h monitor) BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_START */ - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (monitor_s->connection_callback) { @@ -307,8 +296,8 @@ int bt_proximity_monitor_connect(bt_proximity_monitor_h monitor) BT_CHECK_GATT_PXP_SUPPORT(); BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor_s); - - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) +/* LCOV_EXCL_START */ + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; error_code = bt_gatt_connect(monitor_s->remote_address, FALSE); @@ -318,7 +307,7 @@ int bt_proximity_monitor_connect(bt_proximity_monitor_h monitor) return error_code; } - +/* LCOV_EXCL_STOP */ int bt_proximity_monitor_disconnect(bt_proximity_monitor_h monitor) { int error_code; @@ -327,8 +316,8 @@ int bt_proximity_monitor_disconnect(bt_proximity_monitor_h monitor) BT_CHECK_GATT_PXP_SUPPORT(); BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor_s); - - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) +/* LCOV_EXCL_START */ + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; error_code = bt_gatt_disconnect(monitor_s->remote_address); @@ -338,7 +327,7 @@ int bt_proximity_monitor_disconnect(bt_proximity_monitor_h monitor) return error_code; } - +/* LCOV_EXCL_STOP */ int bt_proximity_monitor_set_connection_state_changed_cb(bt_proximity_monitor_h monitor, bt_proximity_monitor_connection_state_changed_cb callback, void *user_data) { @@ -349,16 +338,13 @@ int bt_proximity_monitor_set_connection_state_changed_cb(bt_proximity_monitor_h BT_CHECK_INPUT_PARAMETER(monitor_s); BT_CHECK_INPUT_PARAMETER(callback); - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; /* register the callback */ monitor_s->connection_callback = callback; monitor_s->user_data = user_data; - proximity_monitor_list = g_slist_insert_sorted(proximity_monitor_list, - monitor_s, _bt_proximity_monitor_addr_info_cmp); - return BT_ERROR_NONE; } @@ -370,16 +356,13 @@ int bt_proximity_monitor_unset_connection_state_changed_cb(bt_proximity_monitor_ BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor_s); - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; /* unregister the callback */ monitor_s->connection_callback = NULL; monitor_s->user_data = NULL; - proximity_monitor_list = g_slist_insert_sorted(proximity_monitor_list, - monitor_s, _bt_proximity_monitor_addr_info_cmp); - return BT_ERROR_NONE; } @@ -454,14 +437,14 @@ int bt_proximity_monitor_set_linkloss_alert(bt_proximity_monitor_h monitor, int BT_CHECK_GATT_PXP_SUPPORT(); BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_LINE */ - - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) +/* LCOV_EXCL_START */ + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (!(pxp_monitor_supported_services & BT_PROXIMITY_LINKLOSS_ALERT)) return BT_ERROR_NOT_SUPPORTED; - _bt_convert_address_to_hex(&addr_hex, monitor_s->remote_address); /* LCOV_EXCL_LINE */ + _bt_convert_address_to_hex(&addr_hex, monitor_s->remote_address); error_code = _bt_get_error_code(bluetooth_proximity_monitor_set_property(&addr_hex, BT_PROXIMITY_LINKLOSS_ALERT, value)); @@ -470,7 +453,7 @@ int bt_proximity_monitor_set_linkloss_alert(bt_proximity_monitor_h monitor, int return error_code; } - +/* LCOV_EXCL_STOP */ int bt_proximity_monitor_set_immediate_alert(bt_proximity_monitor_h monitor, int value) { int error_code = BT_ERROR_NONE; @@ -480,14 +463,14 @@ int bt_proximity_monitor_set_immediate_alert(bt_proximity_monitor_h monitor, int BT_CHECK_GATT_PXP_SUPPORT(); BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_LINE */ - - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) +/* LCOV_EXCL_START */ + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (!(pxp_monitor_supported_services & BT_PROXIMITY_IMMEDIATE_ALERT)) return BT_ERROR_NOT_SUPPORTED; - _bt_convert_address_to_hex(&addr_hex, monitor_s->remote_address); /* LCOV_EXCL_LINE */ + _bt_convert_address_to_hex(&addr_hex, monitor_s->remote_address); error_code = _bt_get_error_code(bluetooth_proximity_monitor_set_property(&addr_hex, BT_PROXIMITY_IMMEDIATE_ALERT, value)); @@ -496,7 +479,7 @@ int bt_proximity_monitor_set_immediate_alert(bt_proximity_monitor_h monitor, int return error_code; } - +/* LCOV_EXCL_STOP */ int bt_proximity_monitor_get_linkloss_alert(bt_proximity_monitor_h monitor, int *value) { int error_code = BT_ERROR_NONE; @@ -507,7 +490,7 @@ int bt_proximity_monitor_get_linkloss_alert(bt_proximity_monitor_h monitor, int BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_LINE */ - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (!(pxp_monitor_supported_services & BT_PROXIMITY_LINKLOSS_ALERT)) @@ -534,7 +517,7 @@ int bt_proximity_monitor_get_immediate_alert(bt_proximity_monitor_h monitor, int BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_LINE */ - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (!(pxp_monitor_supported_services & BT_PROXIMITY_IMMEDIATE_ALERT)) @@ -561,7 +544,7 @@ int bt_proximity_monitor_get_signal_level(bt_proximity_monitor_h monitor, int *v BT_CHECK_INIT_STATUS(); BT_CHECK_INPUT_PARAMETER(monitor); /* LCOV_EXCL_LINE */ - if(_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) + if (_bt_proximity_minotr_find(monitor_s->remote_address) == NULL) return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED; if (!(pxp_monitor_supported_services & BT_PROXIMITY_TX_POWER)) diff --git a/src/bluetooth-tds.c b/src/bluetooth-tds.c new file mode 100644 index 0000000..5445053 --- /dev/null +++ b/src/bluetooth-tds.c @@ -0,0 +1,1179 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <glib.h> +#include <dlog.h> +#include <string.h> +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include <bluetooth-api.h> + +#include "bluetooth.h" +#include "bluetooth_internal.h" +#include "bluetooth_private.h" + +#define BT_CHECK_TDS_SUPPORT() \ +{ \ + BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \ + 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) +{ + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(callback); + _bt_set_cb(BT_EVENT_TDS_ACTIVATION_REQUESTED, callback, user_data); + return BT_ERROR_NONE; +} + +int bt_tds_unset_transport_activation_requested_cb(void) +{ + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + _bt_unset_cb(BT_EVENT_TDS_ACTIVATION_REQUESTED); + return BT_ERROR_NONE; +} + +int bt_tds_provider_register(void) +{ + int error_code = BT_ERROR_NONE; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + + if (tds_provider_registered) + return BT_ERROR_ALREADY_DONE; + + /* register TDS provider role here */ + error_code = _bt_get_error_code(bluetooth_tds_provider_register()); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + tds_provider_registered = TRUE; + return error_code; +} + +int bt_tds_provider_unregister(void) +{ + int error_code = BT_ERROR_NONE; + GSList *l; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + /* register TDS provider role here */ + error_code = _bt_get_error_code(bluetooth_tds_provider_unregister()); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + for (l = providers_list; l != NULL; l = g_slist_next(l)) { + bt_tds_provider_s *tds_provider = l->data; + g_free(tds_provider); + } + providers_list = NULL; + + tds_provider_registered = FALSE; + return error_code; +} + +int bt_tds_provider_create(bt_tds_provider_h *provider, bt_tds_transport_e transport) +{ + bluetooth_tds_transport_t tds_transport; + int error_code = BT_ERROR_NONE; + bt_tds_provider_s *tds_provider; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + switch (transport) { + case BT_TDS_TRANSPORT_BT: + error_code = BT_ERROR_NOT_SUPPORTED; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + case BT_TDS_TRANSPORT_CUSTOM: + tds_transport = BLUETOOTH_TDS_TRANSPORT_CUSTOM; + break; + default: + error_code = BT_ERROR_INVALID_PARAMETER; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + tds_provider = g_malloc0(sizeof(bt_tds_provider_s)); + if (!tds_provider) { + error_code = BT_ERROR_OUT_OF_MEMORY; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + tds_provider->tds_handle = GPOINTER_TO_INT(tds_provider); + + /* register TDS provider role here */ + error_code = _bt_get_error_code(bluetooth_tds_provider_create(tds_transport, tds_provider->tds_handle)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + g_free(tds_provider); + return error_code; + } + + tds_provider->transport = tds_transport; + tds_provider->state = BLUETOOTH_TDS_TRANSPORT_STATE_OFF; + *provider = (bt_tds_provider_h *)tds_provider; + providers_list = g_slist_append(providers_list, tds_provider); + return error_code; +} + +int bt_tds_provider_destroy(bt_tds_provider_h provider) +{ + bt_tds_provider_s *tds_provider; + int error_code = BT_ERROR_NONE; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(provider); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + if (NULL == g_slist_find(providers_list, provider)) { + BT_ERR("g_slist_find returned NULL"); + return BT_ERROR_NOT_INITIALIZED; + } + + tds_provider = (bt_tds_provider_s *)provider; + /* Unregister TDS provider role Here */ + error_code = _bt_get_error_code(bluetooth_tds_provider_destroy(tds_provider->tds_handle)); + if (error_code != BT_ERROR_NONE) { + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + providers_list = g_slist_remove(providers_list, tds_provider); + g_free(tds_provider); + return error_code; +} + +int bt_tds_provider_set_transport_data(bt_tds_provider_h provider, + bt_tds_transport_state_e transport_state, unsigned char *buf, int length) +{ + bluetooth_tds_transport_state_t state; + bt_tds_provider_s *tds_provider; + int error_code = BT_ERROR_NONE; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(buf); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + if (255 < length) { + error_code = BT_ERROR_INVALID_PARAMETER; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + switch (transport_state) { + case BT_TDS_TRANSPORT_STATE_OFF: + state = BLUETOOTH_TDS_TRANSPORT_STATE_OFF; + break; + case BT_TDS_TRANSPORT_STATE_ON: + state = BLUETOOTH_TDS_TRANSPORT_STATE_ON; + break; + case BT_TDS_TRANSPORT_STATE_UNAVAILABLE: + state = BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE; + break; + default: + error_code = BT_ERROR_INVALID_PARAMETER; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + if (NULL == g_slist_find(providers_list, provider)) { + BT_ERR("g_slist_find returned NULL"); + return BT_ERROR_NOT_INITIALIZED; + } + + tds_provider = (bt_tds_provider_s *)provider; + tds_provider->state = state; + + /* TDS provider: set transport data here */ + error_code = _bt_get_error_code( + bluetooth_set_tds_provider_transport_data(tds_provider->tds_handle, state, buf, length)); + if (error_code != BT_ERROR_NONE) + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + + return error_code; +} + +/* TODO: Add more parameters if needed */ +int bt_tds_provider_send_activation_resp(char *address, int result, bt_tds_provider_h provider) +{ + bluetooth_device_address_t dev_address; + bt_tds_provider_s *tds_provider; + int error_code = BT_ERROR_NONE; + unsigned char *buf = NULL; + int length = 0; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(provider); + BT_CHECK_INPUT_PARAMETER(address); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + if (NULL == g_slist_find(providers_list, provider)) { + BT_ERR("g_slist_find returned NULL"); + return BT_ERROR_NOT_INITIALIZED; + } + + _bt_convert_address_to_hex(&dev_address, address); + tds_provider = (bt_tds_provider_s *)provider; + + /* TODO: If needed, fill buf with additional params */ + + /* TDS provider: send tds activation response */ + error_code = _bt_get_error_code(bluetooth_send_tds_activation_response( + &dev_address, tds_provider->tds_handle, result, buf, length)); + if (error_code != BT_ERROR_NONE) + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + + return error_code; +} + +int bt_tds_provider_set_manufacturer_data(unsigned char *buf, int length) +{ + int error_code = BT_ERROR_NONE; + + BT_CHECK_TDS_SUPPORT(); + BT_CHECK_INIT_STATUS(); + BT_CHECK_INPUT_PARAMETER(buf); + + if (!tds_provider_registered) + return BT_ERROR_NOT_INITIALIZED; + + if (29 < length) { + error_code = BT_ERROR_INVALID_PARAMETER; + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + return error_code; + } + + /* TDS provider: set manufacturer data here */ + error_code = _bt_get_error_code( + bluetooth_set_tds_provider_manuf_data(buf, length)); + if (error_code != BT_ERROR_NONE) + BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code); + + 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; +} diff --git a/test/bt_unit_test.c b/test/bt_unit_test.c index d65a13c..5a69058 100644 --- a/test/bt_unit_test.c +++ b/test/bt_unit_test.c @@ -121,6 +121,10 @@ bt_proximity_reporter_h reporter; bt_proximity_monitor_h monitor; bt_scan_filter_h pxp_scan_filter; +bt_tds_provider_h provider; +char *tds_act_address; +bt_tds_seeker_h seeker; + bt_gatt_attribute_h service_clone[MAX_SERVICES]; bt_gatt_attribute_h characteristics[MAX_SERVICES]; bt_gatt_attribute_h characteristics_services[MAX_SERVICES]; @@ -177,6 +181,10 @@ tc_table_t tc_main[] = { , BT_UNIT_TEST_TABLE_PBAP_CLIENT}, {"etc.(Automated test, AppControl)" , BT_UNIT_TEST_TABLE_ETC}, + {"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" @@ -509,6 +517,8 @@ tc_table_t tc_audio[] = { , BT_UNIT_TEST_FUNCTION_AG_SET_CALL_HANDLING_EVENT_CB}, {"bt_ag_is_nrec_enabled" , BT_UNIT_TEST_FUNCTION_AG_IS_NREC_ENABLED}, + {"bt_ag_switch_headset" + , BT_UNIT_TEST_FUNCTION_AG_SWITCH_HEADSET}, /* A2DP SCMS-T functions */ {"Select this menu to set parameters and then select the function again." @@ -1073,6 +1083,59 @@ tc_table_t tc_pbap_client[] = { {NULL , 0x0000}, }; +tc_table_t tc_tds_provider[] = { + /* TDS provider functions */ + {"BACK" + , BT_UNIT_TEST_FUNCTION_BACK}, + {"TDS Provider(Register)" + , BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_REGISTER}, + {"TDS Provider(Unregister)" + , BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_UNREGISTER}, + {"TDS Provider set activation req callback" + , BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_SET_ACT_REQ_CB}, + {"TDS Provider unset activation req callback" + , BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_UNSET_ACT_REQ_CB}, + {"TDS CUSTOM Provider(Create)" + , BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_CREATE}, + {"TDS CUSTOM Provider(Destroy)" + , BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_DESTROY}, + {"TDS CUSTOM Provider(Set transport Data)" + , BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_TRANSPORT_DATA}, + {"TDS CUSTOM Provider(Set manuf Data)" + , BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_MANUF_DATA}, + {"TDS CUSTOM Provider(Send Activation Response)" + , BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SEND_ACTIVATION_RESP}, + {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}, @@ -2528,6 +2591,21 @@ void __bt_proximity_reporter_connection_state_changed_cb(int result, const char } } +void __tds_activation_req_cb(char *rem_bd_addr, + bt_tds_transport_e transport, unsigned char *buf, int len, void *user_data) +{ + int i; + + TC_PRT("remote_address : %s", rem_bd_addr); + TC_PRT("transport : %d", transport); + for (i = 0; i < len; i++) + TC_PRT("Act req data[%d] : %.2x", i, buf[i]); + + if (tds_act_address) + g_free(tds_act_address); + tds_act_address = g_strdup(rem_bd_addr); +} + void __bt_gatt_server_notification_sent_cb(int result, const char *remote_address, bt_gatt_server_h server, bt_gatt_h characteristic, bool completed, void *user_data) @@ -2540,11 +2618,12 @@ void __bt_gatt_server_notification_sent_cb(int result, void __bt_gatt_server_write_value_requested_cb(const char *remote_address, int request_id, bt_gatt_server_h server, - bt_gatt_h gatt_handle, int offset, + bt_gatt_h gatt_handle, bool response_needed, int offset, const char *value, int len, void *user_data) { int i, resp_status = BT_ERROR_NONE; TC_PRT("remote_address : %s", remote_address); + TC_PRT("Response needed : %d", response_needed); TC_PRT("offset : %d", offset); TC_PRT("len [%d] : ", len); for (i = 0; i < len; i++) @@ -3001,6 +3080,85 @@ void __bt_repeat_test_adapter_state_changed_cb(int result, 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; @@ -3371,7 +3529,7 @@ int test_set_params(int test_id, char *param) g_test_param.params[param_index - 1] = g_malloc0(len + 1); /* Remove new line character */ param[len - 1] = '\0'; - strcpy(g_test_param.params[param_index - 1], param); + strncpy(g_test_param.params[param_index - 1], param, strlen(param)); } if (param_index == g_test_param.param_count) { @@ -3401,7 +3559,7 @@ int test_set_params(int test_id, char *param) g_test_param.params[param_index - 1] = g_malloc0(len + 1); /* Remove new line character */ param[len - 1] = '\0'; - strcpy(g_test_param.params[param_index - 1], param); + strncpy(g_test_param.params[param_index - 1], param, strlen(param)); } if (param_index == g_test_param.param_count) { @@ -3614,6 +3772,35 @@ int test_set_params(int test_id, char *param) break; } + case BT_UNIT_TEST_FUNCTION_AG_SWITCH_HEADSET: { + if (param_index == 0) { + g_test_param.param_count = 1; + g_test_param.params = g_malloc0(sizeof(char *) *g_test_param.param_count); + param_type = BT_UNIT_TEST_PARAM_TYPE_STRING; + } + + if (param_index > 0) { + g_test_param.params[param_index - 1] = g_malloc0(strlen(param) + 1); + strncpy(g_test_param.params[param_index - 1], param, strlen(param)); + } + + if (param_index == g_test_param.param_count) { + need_to_set_params = false; +#ifdef ARCH64 + test_input_callback((void *)(uintptr_t)test_id); +#else + test_input_callback((void *)test_id); +#endif + param_index = 0; + return 0; + } + + TC_PRT("Input param(%d) type:%s", + param_index + 1, param_type); + param_index++; + + break; + } default: TC_PRT("There is no param to set\n"); @@ -4473,7 +4660,7 @@ int test_set_params(int test_id, char *param) g_test_param.params[param_index - 1] = g_malloc0(len + 1); /* Remove new line character */ param[len - 1] = '\0'; - strcpy(g_test_param.params[param_index - 1], param); + strncpy(g_test_param.params[param_index - 1], param, strlen(param)); } if (param_index == g_test_param.param_count) { @@ -5348,7 +5535,7 @@ int test_input_callback(void *data) case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_DEVICE_ADDRESS: { bt_scan_filter_h scan_filter; - ret = bt_adapter_le_create_scan_filter(&scan_filter); + ret = bt_adapter_le_scan_filter_create(&scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5356,11 +5543,11 @@ int test_input_callback(void *data) if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_register_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_register(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_destroy_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_destroy(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5370,7 +5557,7 @@ int test_input_callback(void *data) case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_UUID: { bt_scan_filter_h scan_filter; - ret = bt_adapter_le_create_scan_filter(&scan_filter); + ret = bt_adapter_le_scan_filter_create(&scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5378,11 +5565,11 @@ int test_input_callback(void *data) if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_register_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_register(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_destroy_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_destroy(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5392,7 +5579,7 @@ int test_input_callback(void *data) case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_SERVICE_SOLICITATION_UUID: { bt_scan_filter_h scan_filter; - ret = bt_adapter_le_create_scan_filter(&scan_filter); + ret = bt_adapter_le_scan_filter_create(&scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5400,11 +5587,11 @@ int test_input_callback(void *data) if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_register_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_register(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_destroy_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_destroy(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5414,7 +5601,7 @@ int test_input_callback(void *data) case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_REGISTER_SCAN_FILTER_IBEACON_DATA: { bt_scan_filter_h scan_filter; - ret = bt_adapter_le_create_scan_filter(&scan_filter); + ret = bt_adapter_le_scan_filter_create(&scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5422,7 +5609,7 @@ int test_input_callback(void *data) if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); - ret = bt_adapter_le_register_scan_filter(scan_filter); + ret = bt_adapter_le_scan_filter_register(scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -5430,7 +5617,7 @@ int test_input_callback(void *data) } case BT_UNIT_TEST_FUNCTION_ADAPTER_LE_UNREGISTER_ALL_SCAN_FILTERS: { - ret = bt_adapter_le_unregister_all_scan_filters(); + ret = bt_adapter_le_scan_filter_unregister_all(); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -6134,6 +6321,19 @@ int test_input_callback(void *data) TC_PRT("returns %s\n", __bt_get_error_message(ret)); break; } + case BT_UNIT_TEST_FUNCTION_AG_SWITCH_HEADSET: { + if (g_test_param.param_count < 0) { + TC_PRT("Input parameters first"); + break; + } + + ret = bt_ag_switch_headset(g_test_param.params[0]); + __bt_free_test_param(&g_test_param); + + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_ACTIVATE_FLAG_TO_SET_PARAMETERS: need_to_set_params = true; TC_PRT("Select the function again"); @@ -7117,7 +7317,7 @@ int test_input_callback(void *data) break; } else { break; /* goto default */ - } + } case BT_UNIT_TEST_FUNCTION_GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS: if (TIZEN_FEATURE_ENABLE_LEGACY_GATT_CLIENT) { ret = bt_gatt_discover_characteristic_descriptor( @@ -9128,17 +9328,17 @@ int test_input_callback(void *data) ret = bt_adapter_le_scan_filter_unset_proximity_uuid(pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); - ret = bt_adapter_le_destroy_scan_filter(pxp_scan_filter); + ret = bt_adapter_le_scan_filter_destroy(pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); pxp_scan_filter = NULL; } - ret = bt_adapter_le_create_scan_filter(&pxp_scan_filter); + ret = bt_adapter_le_scan_filter_create(&pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); ret = bt_adapter_le_scan_filter_set_proximity_uuid(pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); - ret = bt_adapter_le_register_scan_filter(pxp_scan_filter); + ret = bt_adapter_le_scan_filter_register(pxp_scan_filter); if (ret != BT_ERROR_NONE) TC_PRT("failed with [0x%04x]", ret); @@ -9148,7 +9348,7 @@ int test_input_callback(void *data) ret = bt_adapter_le_scan_filter_unset_proximity_uuid(pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); - ret = bt_adapter_le_destroy_scan_filter(pxp_scan_filter); + ret = bt_adapter_le_scan_filter_destroy(pxp_scan_filter); TC_PRT("returns %s\n", __bt_get_error_message(ret)); pxp_scan_filter = NULL; @@ -9556,6 +9756,153 @@ int test_input_callback(void *data) break; } + case BT_UNIT_TEST_TABLE_TDS_PROVIDER: { + switch (test_id) { + case BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_REGISTER: { + ret = bt_tds_provider_register(); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_UNREGISTER: { + ret = bt_tds_provider_unregister(); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + provider = NULL; + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_SET_ACT_REQ_CB: { + ret = bt_tds_set_transport_activation_requested_cb(__tds_activation_req_cb, NULL); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_PROVIDER_UNSET_ACT_REQ_CB: { + ret = bt_tds_unset_transport_activation_requested_cb(); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_CREATE: { + if (provider) { + ret = bt_tds_provider_destroy(provider); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + + provider = NULL; + } + ret = bt_tds_provider_create(&provider, BT_TDS_TRANSPORT_CUSTOM); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_DESTROY: { + ret = bt_tds_provider_destroy(provider); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + provider = NULL; + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_TRANSPORT_DATA: { + unsigned char buf[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, /* Mac */ + 0x20, 0xFA, /* Operating Channel */ + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; /* Hash */ + + ret = bt_tds_provider_set_transport_data(provider, + BT_TDS_TRANSPORT_STATE_OFF, buf, sizeof(buf)); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SET_MANUF_DATA: { + unsigned char buf[] = {0x00, 0x75, 0x4E, 0x24, 0x36, 0x28, 0x01, 0x13}; + + ret = bt_tds_provider_set_manufacturer_data(buf, sizeof(buf)); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + case BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_SEND_ACTIVATION_RESP: { + ret = bt_tds_provider_send_activation_resp( + tds_act_address, BLUETOOTH_ERROR_NONE, provider); + TC_PRT("returns %s\n", __bt_get_error_message(ret)); + break; + } + default: + break; + } + 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; diff --git a/test/bt_unit_test.h b/test/bt_unit_test.h index fe10cf0..5737491 100644 --- a/test/bt_unit_test.h +++ b/test/bt_unit_test.h @@ -51,6 +51,8 @@ typedef enum { BT_UNIT_TEST_TABLE_PBAP_CLIENT, BT_UNIT_TEST_TABLE_ETC, BT_UNIT_TEST_FUNCTION_INITIALIZE_ALL, + BT_UNIT_TEST_TABLE_TDS_PROVIDER, + BT_UNIT_TEST_TABLE_TDS_SEEKER, BT_UNIT_TEST_TABLE_FINISH = 0xFF, } bt_unit_test_table_e; @@ -201,6 +203,7 @@ typedef enum { BT_UNIT_TEST_FUNCTION_AG_NOTIFY_CALL_LIST, BT_UNIT_TEST_FUNCTION_AG_SET_CALL_HANDLING_EVENT_CB, BT_UNIT_TEST_FUNCTION_AG_IS_NREC_ENABLED, + BT_UNIT_TEST_FUNCTION_AG_SWITCH_HEADSET, BT_UNIT_TEST_FUNCTION_AG_IS_WBS_MODE, BT_UNIT_TEST_FUNCTION_AG_SET_VENDOR_CMD_CB, BT_UNIT_TEST_FUNCTION_AG_UNSET_VENDOR_CMD_CB, @@ -448,6 +451,29 @@ typedef enum { 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_PROVIDER_UNSET_ACT_REQ_CB, + BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_CREATE, + BT_UNIT_TEST_FUNCTION_TDS_CUSTOM_PROVIDER_DESTROY, + 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; |