summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoHyun Pyun <dh79.pyun@samsung.com>2016-08-24 17:21:33 -0700
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>2016-08-24 17:21:33 -0700
commit468bac4ff2b9552dc67959be1ff9cbc2848de855 (patch)
tree6873b03589b93e720d1d4ba4cb9c7a006c4b19cf
parent5ec51d797985d00bff7009ce8b1c5ea369cdbee1 (diff)
parente46c73af5755926004e4a6dc5a3eb5399fffdb1c (diff)
downloadbluetooth-468bac4ff2b9552dc67959be1ff9cbc2848de855.tar.gz
bluetooth-468bac4ff2b9552dc67959be1ff9cbc2848de855.tar.bz2
bluetooth-468bac4ff2b9552dc67959be1ff9cbc2848de855.zip
Merge "Merge the code from private" into tizen
-rw-r--r--include/bluetooth_private.h313
-rw-r--r--include/mobile/bluetooth_type_internal.h46
-rw-r--r--include/wearable/bluetooth_type_internal.h45
-rw-r--r--src/bluetooth-adapter.c478
-rw-r--r--src/bluetooth-audio.c104
-rw-r--r--src/bluetooth-avrcp.c38
-rw-r--r--src/bluetooth-common.c634
-rw-r--r--src/bluetooth-device.c294
-rw-r--r--src/bluetooth-gatt.c645
-rw-r--r--src/bluetooth-hid.c27
-rw-r--r--src/bluetooth-socket.c13
-rw-r--r--test/bt_unit_test.c28
12 files changed, 2304 insertions, 361 deletions
diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h
index b0686b1..473291e 100644
--- a/include/bluetooth_private.h
+++ b/include/bluetooth_private.h
@@ -99,7 +99,9 @@ typedef enum {
BT_EVENT_HID_DEVICE_DATA_RECEIVED, /**< HID Device Data received callback */
BT_EVENT_DEVICE_CONNECTION_STATUS, /**< Device connection status callback */
BT_EVENT_GATT_CONNECTION_STATUS, /** < GATT connection status callback */
+ BT_EVENT_GATT_ATT_MTU_CHANGE_STATUS, /** < GATT Attribute MTU change status callback */
BT_EVENT_GATT_CLIENT_SERVICE_DISCOVERED, /** GATT services discovered callback */
+ BT_EVENT_GATT_CLIENT_SERVICE_CHANGED, /** GATT services changed callback */
BT_EVENT_GATT_CLIENT_VALUE_CHANGED, /**< GATT characteristic value changed callback */
BT_EVENT_GATT_CLIENT_READ_CHARACTERISTIC, /**< GATT characteristic value read callback */
BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC, /**< GATT characteristic value write callback */
@@ -118,10 +120,13 @@ typedef enum {
BT_EVENT_LE_DATA_LENGTH_CHANGED, /** LE data length changed callback */
BT_EVENT_ADVERTISING_STATE_CHANGED, /**< Advertising state changed callback */
BT_EVENT_MANUFACTURER_DATA_CHANGED, /**< Manufacturer data changed callback */
+ BT_EVENT_PASSKEY_NOTIFICATION_EVENT, /**< Display passkey callback */
BT_EVENT_CONNECTABLE_CHANGED_EVENT, /**< Adapter connectable changed callback */
BT_EVENT_RSSI_ENABLED_EVENT, /**< RSSI Enabled callback */
BT_EVENT_RSSI_ALERT_EVENT, /**< RSSI Alert callback */
BT_EVENT_GET_RSSI_EVENT, /**< Get RSSI Strength callback */
+ BT_EVENT_LE_READ_MAXIMUM_DATA_LENGTH, /**< Read maximun LE data length callback */
+ BT_EVENT_SUPPORTED_TRUSTED_PROFILE_EVENT, /**< Trusted Profile callback */
#ifdef TIZEN_WEARABLE
BT_EVENT_PBAP_CONNECTION_STATUS, /**< PBAP connection status callback */
BT_EVENT_PBAP_PHONEBOOK_SIZE, /**< PBAP Phonebook Size status callback */
@@ -135,6 +140,8 @@ typedef enum {
BT_EVENT_HF_VENDOR_DEP_CMD_EVENT, /**< Audio - HF Vendor Command callback */
BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT, /**< Audio - HF 3-way call event callback */
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 */
#endif
BT_EVENT_MAX
} bt_event_e;
@@ -194,6 +201,90 @@ typedef enum {
/**
* @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
+ * @brief Called when trying to be displayed the passkey.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address The address of remote device
+ * @param[in] passkey The passkey to be paired with remote device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @pre This function will be invoked when trying to be displayed the passkey
+ * if callback is registered using bt_adapter_set_passkey_notification().
+ * @see bt_adapter_set_passkey_notification()
+ * @see bt_adapter_unset_passkey_notification()
+ */
+typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, const char *passkey, void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
+ * @brief Registers a callback function to be invoked
+ * when trying to be displayed the passkey.
+ * @since_tizen 3.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/bluetooth.admin
+ *
+ * @param[in] callback The callback function to register
+ * @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_INITIALIZED Not initialized
+ * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #BT_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #BT_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @post bt_adapter_passkey_notification_cb() will be invoked.
+ *
+ * @see bt_initialize()
+ */
+int bt_adapter_set_passkey_notification(bt_adapter_passkey_notification_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
+ * @brief Unregisters the callback function.
+ * @since_tizen 3.0
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/bluetooth.admin
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #BT_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #BT_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ *
+ * @see bt_initialize()
+ * @see bt_adapter_set_passkey_notification()
+ */
+int bt_adapter_unset_passkey_notification(void);
+
+typedef enum {
+ BT_GATT_CLIENT_SERVICE_ADDED,
+ BT_GATT_CLIENT_SERVICE_REMOVED,
+} bt_gatt_client_service_change_type_e;
+
+typedef void (*bt_gatt_client_service_changed_cb) (bt_gatt_client_h client,
+ bt_gatt_client_service_change_type_e change_type,
+ const char* service_uuid, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Enumerations of the Bluetooth device's LE connection mode.
+ * @since_tizen 3.0
+ */
+typedef enum
+{
+ BT_DEVICE_LE_CONNECTION_MODE_BALANCED, /**< Balanced mode of power consumption and connection latency */
+ BT_DEVICE_LE_CONNECTION_MODE_LOW_LATENCY, /**< Low connection latency but high power consumption */
+ BT_DEVICE_LE_CONNECTION_MODE_LOW_ENERGY, /**< Low power consumption but high connection latency */
+} bt_device_le_connection_mode_e;
+
+/**
+ * @internal
*/
typedef struct {
bt_adapter_le_advertising_mode_e mode;
@@ -252,6 +343,10 @@ typedef struct {
GSList *services;
char *remote_address;
bool services_discovered;
+ bool connected;
+
+ bt_gatt_client_service_changed_cb service_changed_cb;
+ void *service_changed_user_data;
} bt_gatt_client_s;
typedef struct {
@@ -275,6 +370,9 @@ typedef struct {
GSList *included_services;
GSList *characteristics;
+
+ char **include_handles;
+ char **char_handles;
} bt_gatt_service_s;
typedef struct {
@@ -290,6 +388,8 @@ typedef struct {
GSList *descriptors;
+ char **desc_handles;
+
bt_gatt_client_characteristic_value_changed_cb value_changed_cb;
void *value_changed_user_data;
@@ -340,9 +440,156 @@ typedef struct {
bt_gatt_client_request_completed_cb cb;
} bt_gatt_client_cb_data_s;
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Attribute protocol MTU change information structure.
+ * @since_tizen 3.0
+ *
+ * @see bt_device_att_mtu_changed_cb()
+ */
+typedef struct {
+ char *remote_address; /**< The address of remote device */
+ unsigned int mtu; /** < MTU value */
+ unsigned int status; /** < request status*/
+} bt_device_att_mtu_info_s;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when the connection state is changed.
+ * @since_tizen 2.3.1
+ *
+ * @param[in] connected The connection status: (@c true = connected, @c false = disconnected)
+ * @param[in] conn_info The connection information
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_set_connection_state_changed_cb()
+ * @see bt_device_unset_connection_state_changed_cb()
+ */
+typedef void (*bt_device_att_mtu_changed_cb)(int result, bt_device_att_mtu_info_s *mtu_info, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when RSSI monitoring is enabled.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address Remote Device address
+ * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link).
+ * @param[in] rssi_enabled RSSI monitoring status (@c 1 = enabled, @c 0 = disabled)
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_enable_rssi_monitor()
+ * @see bt_device_disable_rssi_monitor()
+ */
+typedef void (*bt_rssi_monitor_enabled_cb)(const char *remote_address,
+ bt_device_connection_link_type_e link_type,
+ int rssi_enabled, void *user_data);
+
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when RSSI Alert is received.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address Remote Device address
+ * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link).
+ * @param[in] rssi_alert_type RSSI Alert type (@c 1 = High Alert (In-Range Alert), @c 2 = Low Alert)
+ * @param[in] rssi_alert_dbm RSSI Alert signal strength value
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_enable_rssi_monitor()
+ * @see bt_device_disable_rssi_monitor()
+ */
+typedef void (*bt_rssi_alert_cb)(char *bt_address,
+ bt_device_connection_link_type_e link_type,
+ int rssi_alert_type, int rssi_alert_dbm, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when Raw RSSI signal strength is received.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address Remote Device address
+ * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link).
+ * @param[in] rssi_dbm Raw RSSI signal strength value
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_get_rssi_strength()
+ */
+typedef void (*bt_rssi_strength_cb)(char *bt_address,
+ bt_device_connection_link_type_e link_type,
+ int rssi_dbm, void *user_data);
+
+
typedef void (*_bt_gatt_client_value_changed_cb)(char *char_path,
unsigned char *value, int value_length, void *user_data);
+/**
+ * @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
+ *
+ * @param[in] remote_address The address of remote device
+ * @param[in] passkey The passkey to be paired with remote device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @pre This function will be invoked when trying to be displayed the passkey
+ * if callback is registered using bt_adapter_set_passkey_notification().
+ * @see bt_adapter_set_passkey_notification()
+ * @see bt_adapter_unset_passkey_notification()
+ */
+typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, const char *passkey, void *user_data);
+
+
#define BT_CHECK_INPUT_PARAMETER(arg) \
if (arg == NULL) { \
LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, BT_ERROR_INVALID_PARAMETER); \
@@ -486,6 +733,12 @@ char *_bt_convert_error_to_string(int error);
/**
* @internal
+ * @brief Convert uuid to uuid128
+ */
+char* _bt_convert_uuid_to_uuid128(const char *uuid);
+
+/**
+ * @internal
* @brief Convert the visibility mode
*/
bt_adapter_visibility_mode_e _bt_get_bt_visibility_mode_e(bluetooth_discoverable_mode_t mode);
@@ -498,6 +751,32 @@ void _bt_audio_event_proxy(int event, bt_audio_event_param_t *param, void *user_
#ifdef TIZEN_WEARABLE
/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE
+ * @brief Enumerations for the device state event from Audio-Gateway device
+ * @since_tizen 3.0
+ */
+typedef enum {
+ BT_HF_REMOTE_DEVICE_STATE_BATTERY_LEVEL = 0x00, /**< Battery charge level of AG (ranges from 0 to 5) */
+ BT_HF_REMOTE_DEVICE_STATE_SIGNAL_STRENGTH, /**< Signal strength level of AG (ranges from 0 to 5) */
+ BT_HF_REMOTE_DEVICE_STATE_NETWORK_SERVICE, /**< Network service availability (0:no service , 1:available) */
+ BT_HF_REMOTE_DEVICE_STATE_VOICE_RECOGNITON, /**< Voice Recognition State (0:disabled , 1:enabled) */
+} bt_hf_remote_device_state_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
+ *
+ * @param[in] event The device state chagned event from remote Audio-Gateway device
+ * @param[in] value The new values to be changed.
+ * @param[in] user_data The user data passed from the callback registration function
+ *
+ * @see bt_hf_set_remote_device_state_changed_cb()
+ * @see bt_hf_unset_remote_device_state_changed_cb()
+ */
+typedef void (*bt_hf_remote_device_state_changed_cb) (bt_hf_remote_device_state_e state, int value, void *user_data);
+
+/**
* @internal
* @brief Since the HF call back and event proxy call backs have different prototype it is wrapper function.
*/
@@ -528,11 +807,39 @@ void _bt_adapter_le_invoke_advertising_state_cb(int handle, int result, bt_adapt
bool _bt_gatt_is_legacy_client_mode(void);
#endif
-const GSList *_bt_gatt_get_client_list(void);
-const GSList *_bt_gatt_get_server_list(void);
+/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_MODULE
+ * @brief Gets the specification name from the UUID
+ * @since_tizen 3.0
+ *
+ * @remarks @a name must be released with free() by you.
+ *
+ * @param[in] uuid The UUID
+ * @param[out] name The specification name which defined from www.bluetooth.org
+ * @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_SUPPORTED Not supported
+ *
+ * @see bt_gatt_get_uuid()
+ */
+int bt_get_uuid_name(const char *uuid, char **name);
+
+bt_gatt_client_h _bt_gatt_get_client(const char *remote_addr);
+
+const GSList* _bt_gatt_get_server_list(void);
+
+bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client, const char *path);
+
+int _bt_gatt_client_update_services(bt_gatt_client_h client);
+
+int _bt_gatt_client_update_include_services(bt_gatt_h service);
+
+int _bt_gatt_client_update_characteristics(bt_gatt_h service);
-int _bt_gatt_client_update_all(bt_gatt_client_h client);
+int _bt_gatt_client_update_descriptors(bt_gatt_h characteristic);
/**
* @ingroup CAPI_NETWORK_BLUETOOTH_LE_MODULE
diff --git a/include/mobile/bluetooth_type_internal.h b/include/mobile/bluetooth_type_internal.h
index 1a09f63..55b7555 100644
--- a/include/mobile/bluetooth_type_internal.h
+++ b/include/mobile/bluetooth_type_internal.h
@@ -155,6 +155,21 @@ typedef void (*bt_adapter_manufacturer_data_changed_cb) (char *data,
int len, void *user_data);
/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
+ * @brief Called repeatedly when you get the devices connected with specific profile.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address The address of remote device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * \n @c false to break out of the loop.
+ * @pre bt_adapter_foreach_profile_connected_devices() will invoke this function.
+ * @see bt_adapter_foreach_profile_connected_devices()
+ */
+typedef bool (*bt_adapter_profile_connected_devices_cb)(const char *remote_address, void *user_data);
+
+/**
* @ingroup CAPI_NETWORK_BLUETOOTH_DPM_MODULE
* @brief DPM BT allowance state
* @since_tizen 3.0
@@ -363,6 +378,37 @@ typedef void (*bt_hid_device_connection_state_changed_cb) (int result,
typedef void (*bt_hid_device_data_received_cb)(const bt_hid_device_received_data_s *data, void *user_data);
/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Trusted Profile enumeration.
+ * @since_tizen 3.0
+ *
+ * @see bt_device_set_profile_trusted()
+ * @see bt_device_get_profile_trusted()
+ */
+typedef enum {
+ BT_TRUSTED_PROFILE_PBAP = 1,
+ BT_TRUSTED_PROFILE_MAP,
+ BT_TRUSTED_PROFILE_SAP,
+ BT_TRUSTED_PROFILE_ALL = 0xFFFFFFFF,
+} bt_trusted_profile_t;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when Trusted Profiles is changed.
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of supported profile callback
+ * @param[in] remote_address Address of remote device
+ * @param[in] trusted_profiles Trusted profile FLAG
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_set_trusted_profile_cb()
+ * @see bt_device_unset_trusted_profile_cb()
+ */
+typedef void (*bt_device_trusted_profiles_cb)
+ (int result, char *remote_address, int trusted_profile, bool supported, bool trusted,void *user_data);
+
+
+/**
* @internal
* @ingroup
* @brief IPSP Init state changed callback
diff --git a/include/wearable/bluetooth_type_internal.h b/include/wearable/bluetooth_type_internal.h
index ac4fe1a..a8a68f6 100644
--- a/include/wearable/bluetooth_type_internal.h
+++ b/include/wearable/bluetooth_type_internal.h
@@ -226,6 +226,21 @@ typedef void (*bt_adapter_manufacturer_data_changed_cb) (char *data,
int len, void *user_data);
/**
+ * @internal
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
+ * @brief Called repeatedly when you get the devices connected with specific profile.
+ * @since_tizen 3.0
+ *
+ * @param[in] remote_address The address of remote device
+ * @param[in] user_data The user data passed from the callback registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * \n @c false to break out of the loop.
+ * @pre bt_adapter_foreach_profile_connected_devices() will invoke this function.
+ * @see bt_adapter_foreach_profile_connected_devices()
+ */
+typedef bool (*bt_adapter_profile_connected_devices_cb)(const char *remote_address, void *user_data);
+
+/**
* @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_HF_MODULE
* @brief Called when the SCO(Synchronous Connection Oriented link) state is changed.
* @since_tizen 2.3
@@ -380,6 +395,36 @@ typedef struct {
} bt_dpm_uuids_list_s;
/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Trusted Profile enumeration.
+ * @since_tizen 3.0
+ *
+ * @see bt_device_set_profile_trusted()
+ * @see bt_device_get_profile_trusted()
+ */
+typedef enum {
+ BT_TRUSTED_PROFILE_PBAP = 1,
+ BT_TRUSTED_PROFILE_MAP,
+ BT_TRUSTED_PROFILE_SAP,
+ BT_TRUSTED_PROFILE_ALL = 0xFFFFFFFF,
+} bt_trusted_profile_t;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE
+ * @brief Called when Trusted Profiles is changed.
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of supported profile callback
+ * @param[in] remote_address Address of remote device
+ * @param[in] trusted_profiles Trusted profile FLAG
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_device_set_trusted_profile_cb()
+ * @see bt_device_unset_trusted_profile_cb()
+ */
+typedef void (*bt_device_trusted_profiles_cb)
+ (int result, char *remote_address, int trusted_profile, bool supported, bool trusted,void *user_data);
+
+/**
* @internal
* @brief IPSP Init state changed callback
*/
diff --git a/src/bluetooth-adapter.c b/src/bluetooth-adapter.c
index e467359..1246f4f 100644
--- a/src/bluetooth-adapter.c
+++ b/src/bluetooth-adapter.c
@@ -285,6 +285,11 @@ int bt_adapter_get_local_info(char **chipset, char **firmware,
goto ERROR;
}
info_size = info_end - info_start - 1;
+ if (info_size < 0) {
+ BT_ERR("info_size is invalid(%d)", info_size);
+ ret = BT_ERROR_OPERATION_FAILED;
+ goto ERROR;
+ }
local_firmware = (char *)malloc(sizeof(char) *(info_size + 1));
if (local_firmware == NULL) {
@@ -733,6 +738,69 @@ int bt_adapter_is_service_used(const char *service_uuid, bool *used)
return ret;
}
+int bt_adapter_foreach_profile_connected_devices(const char *profile_uuid,
+ bt_adapter_profile_connected_devices_cb callback, void *user_data)
+{
+ char *uuid128;
+ GPtrArray *addr_list = NULL;
+ bluetooth_device_address_t *remote_addr = NULL;
+ char *remote_address = NULL;
+ int ret = BT_ERROR_NONE;
+ int i = 0;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(profile_uuid);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ uuid128 = _bt_convert_uuid_to_uuid128(profile_uuid);
+ if (uuid128 == NULL) {
+ BT_ERR("Wrong type of uuid : %s", profile_uuid);
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ addr_list = g_ptr_array_new();
+ if (addr_list == NULL) {
+ BT_ERR("OUT_OF_MEMORY(0x%08x)", BT_ERROR_OUT_OF_MEMORY);
+ return BT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = _bt_get_error_code(
+ bluetooth_get_profile_connected_device_list(uuid128, &addr_list));
+ g_free(uuid128);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x) : Failed to get profile connected device list",
+ _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ for (i = 0; i < addr_list->len; i++) {
+ remote_addr = g_ptr_array_index(addr_list, i);
+ if (remote_addr != NULL) {
+ ret = _bt_convert_address_to_string(&remote_address, remote_addr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ if (!callback(remote_address, user_data)) {
+ g_free(remote_address);
+ break;
+ }
+ g_free(remote_address);
+ } else {
+ BT_ERR("OPERATION_FAILED(0x%08x)", BT_ERROR_OPERATION_FAILED);
+ ret = BT_ERROR_OPERATION_FAILED;
+ break;
+ }
+ }
+
+ g_ptr_array_foreach(addr_list, (GFunc)g_free, NULL);
+ g_ptr_array_free(addr_list, TRUE);
+
+ return ret;
+}
+
int bt_adapter_set_state_changed_cb(bt_adapter_state_changed_cb callback,
void *user_data)
{
@@ -1034,11 +1102,11 @@ int bt_adapter_get_local_oob_data(unsigned char **hash,
ret = _bt_get_error_code(bluetooth_oob_read_local_data(&oob_data));
if (BT_ERROR_NONE == ret) {
- *hash = g_memdup(oob_data.hash, BLUETOOTH_OOB_DATA_LENGTH);
+ *hash = g_memdup(oob_data.hash, oob_data.hash_len);
*randomizer = g_memdup(oob_data.randomizer,
- BLUETOOTH_OOB_DATA_LENGTH);
- *hash_len = BLUETOOTH_OOB_DATA_LENGTH;
- *randomizer_len = BLUETOOTH_OOB_DATA_LENGTH;
+ oob_data.randomizer_len);
+ *hash_len = oob_data.hash_len;
+ *randomizer_len = oob_data.randomizer_len;
} else {
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret),
ret); /* LCOV_EXCL_LINE */
@@ -1053,6 +1121,7 @@ int bt_adapter_set_remote_oob_data(const char *remote_address,
int ret = BT_ERROR_NONE;
bluetooth_device_address_t addr_hex = { {0,} };
bt_oob_data_t oob_data = { {0},};
+ int len;
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
BT_CHECK_INIT_STATUS();
@@ -1060,11 +1129,18 @@ int bt_adapter_set_remote_oob_data(const char *remote_address,
_bt_convert_address_to_hex(&addr_hex, remote_address);
- if (hash != NULL && randomizer != NULL) {
- memcpy(oob_data.hash, hash, hash_len);
- memcpy(oob_data.randomizer, randomizer, randomizer_len);
- oob_data.hash_len = hash_len;
- oob_data.randomizer_len = randomizer_len;
+ if (hash && randomizer) {
+ len = hash_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ hash_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.hash, hash, len);
+ oob_data.hash_len = len;
+
+ len = randomizer_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ randomizer_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.randomizer, randomizer, len);
+ oob_data.randomizer_len = len;
+ } else {
+ return BT_ERROR_INVALID_PARAMETER;
}
ret = _bt_get_error_code(bluetooth_oob_add_remote_data(&addr_hex,
@@ -1076,6 +1152,110 @@ int bt_adapter_set_remote_oob_data(const char *remote_address,
return ret;
}
+int bt_adapter_get_local_oob_ext_data(unsigned char **hash192, unsigned char **randomizer192,
+ int *hash192_len, int *randomizer192_len,
+ unsigned char **hash256, unsigned char **randomizer256,
+ int *hash256_len, int *randomizer256_len)
+{
+ int ret = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(hash192);
+ BT_CHECK_INPUT_PARAMETER(randomizer192);
+ BT_CHECK_INPUT_PARAMETER(hash192_len);
+ BT_CHECK_INPUT_PARAMETER(randomizer192_len);
+ BT_CHECK_INPUT_PARAMETER(hash256);
+ BT_CHECK_INPUT_PARAMETER(randomizer256);
+ BT_CHECK_INPUT_PARAMETER(hash256_len);
+ BT_CHECK_INPUT_PARAMETER(randomizer256_len);
+
+ bt_oob_data_t oob_data;
+
+ ret = _bt_get_error_code(bluetooth_oob_read_local_data(&oob_data));
+ if (BT_ERROR_NONE == ret) {
+ *hash192 = *randomizer192 = NULL;
+ *hash192_len = *randomizer192_len = 0;
+
+ *hash256 = *randomizer256 = NULL;
+ *hash256_len = *randomizer256_len = 0;
+
+ if (oob_data.hash_len && oob_data.randomizer_len) {
+ *hash192 = g_memdup(oob_data.hash, oob_data.hash_len);
+ *randomizer192 = g_memdup(oob_data.randomizer,
+ oob_data.randomizer_len);
+
+ *hash192_len = oob_data.hash_len;
+ *randomizer192_len = oob_data.randomizer_len;
+ }
+
+ if (oob_data.hash256_len && oob_data.randomizer256_len) {
+ *hash256 = g_memdup(oob_data.hash256, oob_data.hash256_len);
+ *randomizer256 = g_memdup(oob_data.randomizer256,
+ oob_data.randomizer256_len);
+
+ *hash256_len = oob_data.hash256_len;
+ *randomizer256_len = oob_data.randomizer256_len;
+ }
+ } else {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+
+ return ret;
+}
+
+int bt_adapter_set_remote_oob_ext_data(const char *remote_address,
+ const unsigned char *hash192, const unsigned char *randomizer192,
+ int hash192_len, int randomizer192_len,
+ const unsigned char *hash256, const unsigned char *randomizer256,
+ int hash256_len, int randomizer256_len)
+{
+ int ret = BT_ERROR_NONE;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ bt_oob_data_t oob_data = { {0},};
+ int len;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ if ((!hash192 || !randomizer192) && (!hash256 || !randomizer256))
+ return BT_ERROR_INVALID_PARAMETER;
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ if (hash192 && randomizer192) {
+ len = hash192_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ hash192_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.hash, hash192, len);
+ oob_data.hash_len = len;
+
+ len = randomizer192_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ randomizer192_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.randomizer, randomizer192, len);
+ oob_data.randomizer_len = len;
+ }
+
+ if (hash256 && randomizer256) {
+ len = hash256_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ hash256_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.hash256, hash256, len);
+ oob_data.hash256_len = len;
+
+ len = randomizer256_len < BLUETOOTH_OOB_DATA_LENGTH ?
+ randomizer256_len : BLUETOOTH_OOB_DATA_LENGTH;
+ memcpy(oob_data.randomizer256, randomizer256, len);
+ oob_data.randomizer256_len = len;
+ }
+
+ ret = _bt_get_error_code(bluetooth_oob_add_remote_data(&addr_hex, &oob_data));
+ if (BT_ERROR_NONE != ret) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+
+ return ret;
+}
+
int bt_adapter_remove_remote_oob_data(const char *remote_address)
{
int ret = BT_ERROR_NONE;
@@ -1126,6 +1306,101 @@ int bt_adapter_set_manufacturer_data(char *data, int len)
return ret;
}
+int bt_adapter_parse_manufacturer_data(bt_manufacturer_data *data, char *manufacturer_data, int manufacturer_data_len)
+{
+
+ int cursor, name_len;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(data);
+ BT_CHECK_INPUT_PARAMETER(manufacturer_data);
+
+ if (manufacturer_data_len < 30) {
+ BT_DBG("minimum Size of the smasung specific manufacturer data is greater than 30 ");
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+ if (manufacturer_data[0] != 0x00 || manufacturer_data[1] != 0x75) {
+ BT_DBG("This is not a samsung specific manufaturer data");
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ cursor = 2;
+
+/* control and version */
+ data->version = manufacturer_data[cursor++];
+
+/* service ID */
+ data->service_id = manufacturer_data[cursor++];
+
+/* Samsung discovery version */
+ data->discovery_version = manufacturer_data[cursor++];
+
+/* associated service ID */
+ data->associated_service_id = manufacturer_data[cursor++];
+
+/* Proxamity and locality */
+ /* type */
+ data->proximity_locality_type = manufacturer_data[cursor++];
+
+ /* info */
+ data->proximity_locality_info = manufacturer_data[cursor++];
+
+/* Device */
+ /* type */
+ data->device_type = manufacturer_data[cursor++];
+
+ /* icon */
+ data->device_icon = manufacturer_data[cursor++];
+
+ /* Authentication info */
+ memcpy(data->auth_info, &(manufacturer_data[cursor]), 5);
+ cursor = cursor + 5;
+
+/* Connectivity */
+ /* address type */
+ data->addr_type = manufacturer_data[cursor++];
+
+ /* addr1 */
+ memcpy(data->addr1, &(manufacturer_data[cursor]), 6);
+ cursor = cursor + 6;
+
+ /* addr2 */
+ memcpy(data->addr2, &(manufacturer_data[cursor]), 6);
+ cursor = cursor + 6;
+
+ /* channel info */
+ data->channel_info = manufacturer_data[cursor++];
+
+
+/* Associated service data */
+ data->associated_service_data_len = manufacturer_data[cursor++];
+ if (data->associated_service_data_len) {
+ data->associated_service_data_val = g_malloc0(data->associated_service_data_len);
+ memcpy(data->associated_service_data_val, &(manufacturer_data[cursor]),
+ data->associated_service_data_len);
+
+ cursor = cursor + data->associated_service_data_len;
+ }
+
+/* name : include the null termination */
+ name_len = manufacturer_data_len - cursor;
+ if (name_len > 0) {
+ data->name= g_malloc0(name_len + 1);
+ memcpy(data->name, &(manufacturer_data[cursor]), name_len);
+ data->name[name_len] = '\0';
+ }
+ return BT_ERROR_NONE;
+}
+
+int bt_adapter_free_manufacturer_data(bt_manufacturer_data *data)
+{
+ BT_CHECK_INPUT_PARAMETER(data);
+ g_free(data->associated_service_data_val);
+ g_free(data->name);
+ return BT_ERROR_NONE;
+}
+
int bt_adapter_set_manufacturer_data_changed_cb(
bt_adapter_manufacturer_data_changed_cb callback,
void *user_data)
@@ -1153,6 +1428,43 @@ int bt_adapter_unset_manufacturer_data_changed_cb(void)
return BT_ERROR_NONE;
}
+int bt_adapter_set_passkey_notification(
+ bt_adapter_passkey_notification_cb callback, void *user_data)
+{
+ int ret = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ ret = _bt_get_error_code(bluetooth_set_passkey_notification(TRUE));
+ if (ret == BT_ERROR_NONE) {
+ _bt_set_cb(BT_EVENT_PASSKEY_NOTIFICATION_EVENT,
+ callback, user_data);
+ } else {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+
+ return ret;
+}
+
+int bt_adapter_unset_passkey_notification(void)
+{
+ int ret = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+
+ ret = _bt_get_error_code(bluetooth_set_passkey_notification(FALSE));
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+
+ _bt_unset_cb(BT_EVENT_PASSKEY_NOTIFICATION_EVENT);
+
+ return BT_ERROR_NONE;
+}
+
int bt_adapter_le_add_white_list(const char *address,
bt_device_address_type_e address_type)
{
@@ -1243,6 +1555,24 @@ int bt_adapter_le_set_scan_mode(bt_adapter_le_scan_mode_e scan_mode)
}
/* LCOV_EXCL_STOP */
+int bt_adapter_le_set_customized_scan_mode(float scan_interval, float scan_window)
+{
+ int ret = BT_ERROR_NONE;
+ bluetooth_le_scan_params_t scan_params;
+
+ BT_CHECK_INIT_STATUS();
+
+ scan_params.type = BT_ADAPTER_LE_ACTIVE_SCAN;
+ scan_params.interval = scan_interval;
+ scan_params.window = scan_window;
+
+ ret = _bt_get_error_code(bluetooth_set_scan_parameters(&scan_params));
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ return ret;
+}
+
int bt_adapter_le_create_advertiser(bt_advertiser_h *advertiser)
{
bt_advertiser_s *__adv = NULL;
@@ -1326,12 +1656,9 @@ static int __bt_remove_ad_data_by_type(char *in_data, unsigned int in_len,
if (i + len > in_len) {
BT_ERR("Invalid advertising data"); /* LCOV_EXCL_LINE */
return BT_ERROR_OPERATION_FAILED; /* LCOV_EXCL_LINE */
- } else if (len == 0 &&
- in_type != BT_ADAPTER_LE_ADVERTISING_DATA_LOCAL_NAME &&
- in_type != BT_ADAPTER_LE_ADVERTISING_DATA_TX_POWER_LEVEL) {
- BT_INFO("AD Type 0x%02x data is not set",
- in_type); /* LCOV_EXCL_LINE */
- return BT_ERROR_OPERATION_FAILED; /* LCOV_EXCL_LINE */
+ } else if (len == 0) {
+ BT_INFO("AD Type 0x%02x data is not set", in_type);
+ return BT_ERROR_OPERATION_FAILED;
}
p = (char *)malloc(sizeof(char) *(in_len - len));
@@ -1790,7 +2117,7 @@ int bt_adapter_le_add_advertising_service_data(bt_advertiser_h advertiser,
char *adv_data = NULL;
int uuid_bit;
char *uuid_ptr;
- int byte_len;
+ int byte_len = 0;
char *converted_uuid = NULL;
BT_CHECK_LE_SUPPORT();
@@ -2294,12 +2621,28 @@ int bt_adapter_le_enable_privacy(bool enable_privacy)
return error_code;
}
+int bt_adapter_le_set_static_random_address(bool enable)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_LE_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+
+ error_code = _bt_get_error_code(bluetooth_set_le_static_random_address(enable));
+
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ }
+ return error_code;
+}
+
static void __bt_adapter_le_convert_scan_filter(
bluetooth_le_scan_filter_t *dest,
bt_le_scan_filter_s *src)
{
int bit;
char *data;
+ char *converted_uuid = NULL;
memset(dest, 0x00, sizeof(bluetooth_le_scan_filter_t));
@@ -2324,17 +2667,30 @@ static void __bt_adapter_le_convert_scan_filter(
dest->service_uuid.data_len = 2;
else
dest->service_uuid.data_len = 16;
- memcpy(dest->service_uuid.data.data, data,
+
+ if (__bt_convert_byte_ordering(data, dest->service_uuid.data_len,
+ &converted_uuid) == BT_ERROR_NONE) {
+ memcpy(dest->service_uuid.data.data, converted_uuid,
dest->service_uuid.data_len);
+ g_free(converted_uuid);
+ converted_uuid = NULL;
+ }
g_free(data);
+ data = NULL;
dest->service_uuid_mask.data_len = dest->service_uuid.data_len;
if (src->service_uuid_mask) {
- __bt_convert_string_to_uuid(
- src->service_uuid_mask, &data, &bit);
- memcpy(dest->service_uuid_mask.data.data, data,
- dest->service_uuid_mask.data_len);
+ __bt_convert_string_to_uuid(src->service_uuid_mask, &data, &bit);
+
+ if (__bt_convert_byte_ordering(data, dest->service_uuid_mask.data_len,
+ &converted_uuid) == BT_ERROR_NONE) {
+ memcpy(dest->service_uuid_mask.data.data, converted_uuid,
+ dest->service_uuid_mask.data_len);
+ g_free(converted_uuid);
+ converted_uuid = NULL;
+ }
g_free(data);
+ data = NULL;
} else {
memset(dest->service_uuid_mask.data.data, 0xFF,
dest->service_uuid_mask.data_len);
@@ -2351,17 +2707,30 @@ static void __bt_adapter_le_convert_scan_filter(
dest->service_solicitation_uuid.data_len = 2;
else
dest->service_solicitation_uuid.data_len = 16;
- memcpy(dest->service_solicitation_uuid.data.data, data,
- dest->service_solicitation_uuid.data_len);
+
+ if (__bt_convert_byte_ordering(data, dest->service_solicitation_uuid.data_len,
+ &converted_uuid) == BT_ERROR_NONE) {
+ memcpy(dest->service_solicitation_uuid.data.data,
+ converted_uuid, dest->service_solicitation_uuid.data_len);
+ g_free(converted_uuid);
+ converted_uuid = NULL;
+ }
g_free(data);
+ data = NULL;
dest->service_solicitation_uuid_mask.data_len = dest->service_solicitation_uuid.data_len;
if (src->service_solicitation_uuid_mask) {
- __bt_convert_string_to_uuid(
- src->service_solicitation_uuid_mask,
- &data, &bit);
- memcpy(dest->service_solicitation_uuid_mask.data.data, data, dest->service_solicitation_uuid_mask.data_len);
+ __bt_convert_string_to_uuid(src->service_solicitation_uuid_mask, &data, &bit);
+
+ if (__bt_convert_byte_ordering(data, dest->service_solicitation_uuid_mask.data_len,
+ &converted_uuid) == BT_ERROR_NONE) {
+ memcpy(dest->service_solicitation_uuid_mask.data.data,
+ converted_uuid, dest->service_solicitation_uuid_mask.data_len);
+ g_free(converted_uuid);
+ converted_uuid = NULL;
+ }
g_free(data);
+ data = NULL;
} else {
memset(dest->service_solicitation_uuid_mask.data.data, 0xFF, dest->service_solicitation_uuid_mask.data_len);
}
@@ -2369,27 +2738,28 @@ static void __bt_adapter_le_convert_scan_filter(
}
if (src->service_data_uuid) {
- char *service_uuid;
int uuid_len;
- if (__bt_convert_string_to_uuid(src->service_data_uuid,
- &service_uuid, &bit) == BT_ERROR_NONE) {
+ if (__bt_convert_string_to_uuid(src->service_data_uuid, &data, &bit) == BT_ERROR_NONE) {
dest->added_features |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
if (bit == 16)
uuid_len = 2;
else
uuid_len = 16;
- memcpy(dest->service_data.data.data, service_uuid, uuid_len);
- g_free(service_uuid);
- memcpy(dest->service_data.data.data + uuid_len,
- src->service_data, src->service_data_len);
- dest->service_data.data_len = uuid_len
- + src->service_data_len;
-
- dest->service_data_mask.data_len = uuid_len
- + src->service_data_len;
- memset(dest->service_data_mask.data.data,
- 0xFF, uuid_len);
+ if (__bt_convert_byte_ordering(data, uuid_len, &converted_uuid)
+ == BT_ERROR_NONE) {
+ memcpy(dest->service_data.data.data, converted_uuid, uuid_len);
+ g_free(converted_uuid);
+ converted_uuid = NULL;
+ }
+ g_free(data);
+ data = NULL;
+
+ memcpy(dest->service_data.data.data + uuid_len, src->service_data, src->service_data_len);
+ dest->service_data.data_len = uuid_len + src->service_data_len;
+
+ dest->service_data_mask.data_len = dest->service_data.data_len;
+ memset(dest->service_data_mask.data.data, 0xFF, uuid_len);
if (src->service_data_mask)
memcpy(dest->service_data_mask.data.data + uuid_len, src->service_data_mask, src->service_data_len);
else
@@ -2934,6 +3304,11 @@ int bt_adapter_le_create_scan_filter(bt_scan_filter_h *scan_filter)
bt_le_scan_filter_s *__filter = NULL;
BT_CHECK_LE_SUPPORT();
+ if (bluetooth_is_scan_filter_supported() == FALSE) {
+ BT_ERR("BT_ERROR_NOT_SUPPORTED(0x%08x)", BT_ERROR_NOT_SUPPORTED);
+ return BT_ERROR_NOT_SUPPORTED;
+ }
+
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(scan_filter);
@@ -3293,6 +3668,11 @@ int bt_adapter_le_unregister_all_scan_filters(void)
int error_code = BT_ERROR_NONE;
BT_CHECK_LE_SUPPORT();
+ if (bluetooth_is_scan_filter_supported() == FALSE) {
+ BT_ERR("BT_ERROR_NOT_SUPPORTED(0x%08x)", BT_ERROR_NOT_SUPPORTED);
+ return BT_ERROR_NOT_SUPPORTED;
+ }
+
BT_CHECK_INIT_STATUS();
if (bluetooth_is_le_scanning() == TRUE) {
BT_ERR("NOW_IN_PROGRESS(0x%08x)",
@@ -3309,6 +3689,7 @@ int bt_adapter_le_unregister_all_scan_filters(void)
return BT_ERROR_NONE;
}
+
int bt_adapter_le_read_maximum_data_length(
int *max_tx_octets, int *max_tx_time,
int *max_rx_octets, int *max_rx_time)
@@ -3391,6 +3772,21 @@ int bt_adapter_le_read_suggested_default_data_length(
return ret;
}
+int bt_adapter_force_hcidump(int timeout)
+{
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_LE_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+
+ error_code = _bt_get_error_code(bluetooth_force_hcidump(timeout));
+
+ 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_adapter_set_authentication_req_cb(bt_adapter_authentication_req_cb callback,
void *user_data)
{
diff --git a/src/bluetooth-audio.c b/src/bluetooth-audio.c
index 852d06c..7feebe6 100644
--- a/src/bluetooth-audio.c
+++ b/src/bluetooth-audio.c
@@ -565,11 +565,17 @@ int bt_ag_notify_call_event(bt_ag_call_event_e event, unsigned int call_id, cons
case BT_AG_CALL_EVENT_ALERTING:
error = bluetooth_telephony_call_remote_ringing(call_id);
break;
- case BT_AG_CALL_EVENT_INCOMING:
- BT_CHECK_INPUT_PARAMETER(phone_number);
- error = bluetooth_telephony_indicate_incoming_call(phone_number,
+ case BT_AG_CALL_EVENT_INCOMING: {
+ const char *ph_number;
+ if (phone_number) {
+ ph_number = phone_number;
+ } else {
+ ph_number = "";
+ }
+ error = bluetooth_telephony_indicate_incoming_call(ph_number,
call_id);
break;
+ }
default:
error = BLUETOOTH_TELEPHONY_ERROR_INVALID_PARAM;
}
@@ -601,6 +607,23 @@ int bt_ag_notify_call_list(bt_call_list_h list)
}
/* LCOV_EXCL_STOP */
+int bt_ag_notify_vendor_cmd(const char *command)
+{
+ int error;
+
+ BT_CHECK_HFP_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_AG_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(command);
+
+ error = bluetooth_telephony_send_vendor_cmd(command);
+ error = _bt_convert_telephony_error_code(error);
+ if (error != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
+ }
+ return error;
+}
+
int bt_ag_notify_voice_recognition_state(bool state)
{
int error;
@@ -787,7 +810,11 @@ int bt_call_list_add(bt_call_list_h list, unsigned int call_id, bt_ag_call_state
return BT_ERROR_OUT_OF_MEMORY;
call_status->call_id = call_id;
call_status->call_status = state;
- call_status->phone_number = g_strdup(phone_number);
+ if (phone_number) {
+ call_status->phone_number = g_strdup(phone_number);
+ } else {
+ call_status->phone_number = g_strdup("");
+ }
handle->list = g_list_append(handle->list, (gpointer)call_status);
return BT_ERROR_NONE;
@@ -1092,6 +1119,33 @@ int bt_hf_get_call_status_info_list(GSList **call_list)
return error;
}
+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_INPUT_PARAMETER(supported);
+
+ error = bluetooth_hf_is_ibr_supported(&is_supported);
+ error = _bt_get_error_code(error);
+ if (error != BT_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error), error);
+
+ if (is_supported)
+ *supported = TRUE;
+ else
+ *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)
{
bt_hf_call_status_info_s *call_info = (bt_hf_call_status_info_s *)data;
@@ -1172,4 +1226,44 @@ int bt_hf_unset_multi_call_handling_event_cb(void)
_bt_unset_cb(BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT);
return BT_ERROR_NONE;
}
-#endif
+
+int bt_hf_set_remote_call_event_cb(
+ bt_hf_remote_call_event_cb callback,
+ void *user_data)
+{
+ BT_CHECK_HF_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_HF_REMOTE_CALL_EVENT, callback, user_data);
+ return BT_ERROR_NONE;
+}
+
+int bt_hf_unset_remote_call_event_cb(void)
+{
+ BT_CHECK_HF_SUPPORT();
+ BT_CHECK_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;
+}
+
+int bt_hf_set_remote_device_state_changed_cb(
+ bt_hf_remote_device_state_changed_cb callback,
+ void *user_data)
+{
+ BT_CHECK_HF_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED, callback, user_data);
+ return BT_ERROR_NONE;
+}
+
+int bt_hf_unset_remote_device_state_changed_cb(void)
+{
+ BT_CHECK_HF_SUPPORT();
+ BT_CHECK_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;
+}
+#endif \ No newline at end of file
diff --git a/src/bluetooth-avrcp.c b/src/bluetooth-avrcp.c
index 8d659f8..25fe672 100644
--- a/src/bluetooth-avrcp.c
+++ b/src/bluetooth-avrcp.c
@@ -108,6 +108,44 @@ int bt_avrcp_target_initialize(bt_avrcp_target_connection_state_changed_cb callb
return BT_ERROR_NONE;
}
+int bt_avrcp_target_connect(const char *remote_address)
+{
+ int error;
+ bluetooth_device_address_t addr_hex = { {0,} };
+
+ BT_CHECK_AVRCP_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_AVRCP_TARGET_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ error = bluetooth_media_target_connect(&addr_hex);
+ 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_avrcp_target_disconnect(const char *remote_address)
+{
+ int error;
+ bluetooth_device_address_t addr_hex = { {0,} };
+
+ BT_CHECK_AVRCP_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_AVRCP_TARGET_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ error = bluetooth_media_target_disconnect(&addr_hex);
+ 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_avrcp_target_deinitialize(void)
{
int error;
diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c
index 8e58ead..28deedc 100644
--- a/src/bluetooth-common.c
+++ b/src/bluetooth-common.c
@@ -42,7 +42,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
static void __bt_le_event_proxy(int event, bluetooth_event_param_t *param, void *user_data);
static int __bt_get_cb_index(int event);
static void __bt_convert_lower_to_upper(char *origin);
-static int __bt_get_bt_device_sdp_info_s(bt_device_sdp_info_s **dest, bt_sdp_info_t *source);
+static int __bt_get_bt_device_sdp_info_s(bt_device_sdp_info_s **dest, bt_sdp_info_t *source, int error);
static void __bt_free_bt_device_sdp_info_s(bt_device_sdp_info_s *sdp_info);
static int __bt_get_bt_device_connection_info_s(bt_device_connection_info_s **dest, bt_connection_info_t *source);
static void __bt_free_bt_device_connection_info_s(bt_device_connection_info_s *conn_info);
@@ -63,9 +63,12 @@ static int __bt_gatt_client_update_descriptors(bt_gatt_handle_info_t desc_handle
int bt_initialize(void)
{
+ int ret;
+
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
if (is_initialized != true) {
- if (bluetooth_register_callback(&__bt_event_proxy, NULL) != BLUETOOTH_ERROR_NONE) {
+ ret = bluetooth_register_callback(&__bt_event_proxy, NULL);
+ if (ret != BLUETOOTH_ERROR_NONE && ret != BLUETOOTH_ERROR_ALREADY_INITIALIZED) {
BT_ERR("OPERATION_FAILED(0x%08x)", BT_ERROR_OPERATION_FAILED); /* LCOV_EXCL_LINE */
return BT_ERROR_OPERATION_FAILED; /* LCOV_EXCL_LINE */
}
@@ -88,6 +91,177 @@ int bt_deinitialize(void)
return BT_ERROR_NONE;
}
+int bt_get_uuid_name(const char *uuid, char **name)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INPUT_PARAMETER(uuid);
+ BT_CHECK_INPUT_PARAMETER(name);
+
+ int i;
+ int offset = 0;
+ int uuid_len = 4;
+ static struct {
+ const char *uuid;
+ const char *specification_name;
+ } bt_uuid_name[] = {
+ /* BT Classic Services */
+ {"1101", "Serial Port Service"},
+ {"1102", "LAN Access Using PPP Service"},
+ {"1103", "Dialup Netwworking Service"},
+ {"1104", "IrMCSync Service"},
+ {"1105", "OBEX Object Push Service"},
+ {"1106", "OBEX File Transfer Service"},
+ {"1107", "IrMC Sync Command Service"},
+ {"1108", "Headset Service"},
+ {"1109", "Cordless Telephony Service"},
+ {"110A", "Audio Source Service"},
+ {"110B", "Audio Sink Service"},
+ {"110C", "AV Remote Control Target Service"},
+ {"110D", "Advanced Audio Distribution Profile"},
+ {"110E", "AV Remote Control Service"},
+ {"110F", "Video Conferencing Service"},
+ {"1110", "Intercom Service"},
+ {"1111", "Fax Service"},
+ {"1112", "Headset Audio Gateway Service"},
+ {"1113", "WAP Service"},
+ {"1114", "WAP Client Service"},
+ {"1115", "PANU Service"},
+ {"1116", "NAP Service"},
+ {"1117", "GN Service"},
+ {"1118", "Direct Printing Service"},
+ {"1119", "Reference Printing Service"},
+ {"111A", "Basic Imaging Profile"},
+ {"111B", "Imaging Responder Service"},
+ {"111C", "Imaging Automatic Archive Service"},
+ {"111D", "Imaging Reference Objects Service"},
+ {"111E", "Handsfree Service"},
+ {"111F", "Handsfree Audio Gateway Service"},
+ {"1120", "Direct Printing Reference Objects Service"},
+ {"1121", "Reflected UI Service"},
+ {"1122", "Basic Printing Profile"},
+ {"1123", "Printing Status Service"},
+ {"1124", "Human Interface Device Service"},
+ {"1125", "Hardcopy Cable Replacement Profile"},
+ {"1126", "HCR Print Service"},
+ {"1127", "HCR Scan Service"},
+ {"112D", "SIM Access Service"},
+ {"112E", "Phonebook Access PCE Service"},
+ {"112F", "Phonebook Access PSE Service"},
+ {"1130", "Phonebook Access Profile"},
+ {"1132", "Message Access Server Service"},
+ {"1133", "Message Notification Server Service"},
+ {"1134", "Message Access Profile"},
+ {"1200", "PnP Information Service"},
+ {"1201", "Generic Networking Service"},
+ {"1202", "Generic File Transfer Service"},
+ {"1203", "Generic Audio Service"},
+ {"1204", "Generic Telephony Service"},
+ {"1205", "UPnP Service"},
+ {"1206", "UPnP Ip Service"},
+ {"1400", "Health Device Profile"},
+
+ /* GATT Services */
+ {"1800", "Generic Access"},
+ {"1801", "Generic Attribute"},
+ {"1802", "Immediate Alert"},
+ {"1803", "Link Loss"},
+ {"1804", "Tx Power"},
+ {"1805", "Current Time Service"},
+ {"1806", "Reference Time Update Service"},
+ {"1807", "Next DST Change Service"},
+ {"1808", "Glucose"},
+ {"1809", "Health Thermometer"},
+ {"180A", "Device Information"},
+ {"180D", "Heart Rate"},
+ {"180F", "Battery Service"},
+ {"1810", "Blood Pressure"},
+ {"1811", "Alert Notification Service"},
+ {"1812", "Human Interface Device"},
+
+ /* GATT Declarations */
+ {"2800", "Primary Service Declaration"},
+ {"2801", "Secondary Service Declaration"},
+ {"2802", "Include Declaration"},
+ {"2803", "Characteristic Declaration"},
+
+ /* GATT Descriptors */
+ {"2900", "Characteristic Extended Properties"},
+ {"2901", "Characteristic User Description"},
+ {"2902", "Client Characteristic Configuration"},
+ {"2903", "Server Characteristic Configuration"},
+ {"2904", "Characteristic Format"},
+ {"2905", "Characteristic Aggregate Formate"},
+ {"2906", "Valid Range"},
+ {"2907", "External Report Reference"},
+ {"2908", "Report Reference"},
+
+ /* GATT Characteristics */
+ {"2A00", "Device Name"},
+ {"2A01", "Appearance"},
+ {"2A02", "Peripheral Privacy Flag"},
+ {"2A03", "Reconnection Address"},
+ {"2A04", "Peripheral Preferred Connection Parameters"},
+ {"2A05", "Service Changed"},
+ {"2A06", "Alert Level"},
+ {"2A07", "Tx Power Level"},
+ {"2A08", "Date Time"},
+ {"2A09", "Day of Week"},
+ {"2A0A", "Day Date Time"},
+ {"2A19", "Battery Level"},
+ {"2A1E", "Intermediate Temperature"},
+ {"2A23", "System ID"},
+ {"2A24", "Model Number String"},
+ {"2A25", "Serial Number String"},
+ {"2A26", "Firmware Revision String"},
+ {"2A27", "Hardware Revision String"},
+ {"2A28", "Software Revision String"},
+ {"2A29", "Manufacturer Name String"},
+ {"2A2A", "IEEE 11073-20601 Regulatory Certification Data List"},
+ {"2A2B", "Current Time"},
+ {"2A37", "Heart Rate Measurement"},
+ {"2A38", "Body Sensor Location"},
+ {"2A3F", "Alert Status"},
+ {"2A46", "New Alert"},
+ {"2A4A", "HID Information"},
+ {"2A4C", "HID Control Point"},
+ {"2A50", "PnP ID"},
+
+ /* Custom uuids */
+ {"7905F431-B5CE-4E99-A40F-4B1E122D00D0", "Apple Notification Center Service"},
+ {"9FBF120D-6301-42D9-8C58-25E699A21DBD", "Notifications Source"},
+ {"69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9", "Control Point"},
+ {"22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB", "Data Source"},
+ {"89D3502B-0F36-433A-8EF4-C502AD55F8DC", "Apple Media Service"},
+ {"9B3C81D8-57B1-4A8A-B8DF-0E56F7CA51C2", "Remote Command"},
+ {"2F7CABCE-808D-411F-9A0C-BB92BA96C102", "Entity Update"},
+ {"C6B2F38C-23AB-46D8-A6AB-A3A870BBD5D7", "Entity Attribute"},
+ {"9A3F68E0-86CE-11E5-A309-0002A5D5C51B", "Samsung Gear Manager Service"},
+ {"c2f2cc0f-c085-4dd4-be5a-aca3074bbc72", "Control Point"},
+ {"cece518b-28d7-4171-92d5-76a1e249a3b9", "Notifications Source"},
+ {NULL, NULL}
+ };
+
+ if (strlen(uuid) == 36) {
+ if (!g_ascii_strncasecmp(uuid + 9, "0000-1000-8000-00805F9B34FB", 27))
+ offset = 4;
+ else {
+ offset = 0;
+ uuid_len = 36;
+ }
+ } else if (strlen(uuid) >= 8)
+ offset = 4;
+
+ for (i = 0; bt_uuid_name[i].uuid; i++) {
+ if (!g_ascii_strncasecmp(uuid + offset, bt_uuid_name[i].uuid, uuid_len)) {
+ *name = g_strdup(bt_uuid_name[i].specification_name);
+ return BT_ERROR_NONE;
+ }
+ }
+
+ *name = g_strdup("Unknown");
+ return BT_ERROR_NONE;
+}
+
/*
* Common Functions
*/
@@ -160,8 +334,9 @@ int _bt_get_error_code(int origin_error)
return BT_ERROR_NONE;
case BLUETOOTH_ERROR_INVALID_DATA:
case BLUETOOTH_ERROR_INVALID_PARAM:
- case BLUETOOTH_ERROR_NOT_CONNECTED:
return BT_ERROR_INVALID_PARAMETER;
+ case BLUETOOTH_ERROR_NOT_CONNECTED:
+ return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
case BLUETOOTH_ERROR_NOT_SUPPORT:
return BT_ERROR_NOT_SUPPORTED;
case BLUETOOTH_ERROR_MEMORY_ALLOCATION:
@@ -175,6 +350,7 @@ int _bt_get_error_code(int origin_error)
case BLUETOOTH_ERROR_ALREADY_INITIALIZED:
case BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST:
case BLUETOOTH_ERROR_ALREADY_DEACTIVATED:
+ case BLUETOOTH_ERROR_ALREADY_CONNECT:
return BT_ERROR_ALREADY_DONE;
case BLUETOOTH_ERROR_NOT_PAIRED:
return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
@@ -199,12 +375,14 @@ int _bt_get_error_code(int origin_error)
return BT_ERROR_SERVICE_NOT_FOUND;
case BLUETOOTH_ERROR_NOT_INITIALIZED:
return BT_ERROR_NOT_INITIALIZED;
+ case BLUETOOTH_ERROR_NO_RESOURCES:
+ return BT_ERROR_QUOTA_EXCEEDED;
+ case BLUETOOTH_ERROR_AUTHENTICATION_REJECTED:
+ return BT_ERROR_AUTH_REJECTED;
case BLUETOOTH_ERROR_DEVICE_POLICY_RESTRICTION:
return BT_ERROR_DEVICE_POLICY_RESTRICTION;
case BLUETOOTH_ERROR_PARING_FAILED:
case BLUETOOTH_ERROR_MAX_CONNECTION:
- case BLUETOOTH_ERROR_ALREADY_CONNECT:
- case BLUETOOTH_ERROR_NO_RESOURCES:
case BLUETOOTH_ERROR_REGISTRATION_FAILED:
case BLUETOOTH_ERROR_CONNECTION_BUSY:
case BLUETOOTH_ERROR_MAX_CLIENT:
@@ -235,6 +413,11 @@ int _bt_get_bt_device_info_s(bt_device_info_s **dest_dev, bluetooth_device_info_
else
(*dest_dev)->remote_name = NULL;
+#if 0
+ (*dest_dev)->is_alias_set = source_dev->is_alias_set;
+ BT_DBG("is_alias_set: [%s]", (*dest_dev)->is_alias_set ? "TRUE" : "FALSE");
+#endif
+
_bt_convert_address_to_string(&((*dest_dev)->remote_address), &(source_dev->device_address));
(*dest_dev)->bt_class.major_device_class = source_dev->device_class.major_class;
@@ -374,6 +557,12 @@ char *_bt_convert_error_to_string(int error)
return "SERVICE_NOT_FOUND"; /* LCOV_EXCL_LINE */
case BT_ERROR_NOT_SUPPORTED:
return "NOT_SUPPORTD"; /* LCOV_EXCL_LINE */
+ case BT_ERROR_NO_DATA:
+ return "NO_DATA";
+ case BT_ERROR_QUOTA_EXCEEDED:
+ return "QUOTA EXCEEDED";
+ case BT_ERROR_AGAIN:
+ return "AGAIN";
case BT_ERROR_DEVICE_POLICY_RESTRICTION:
return "DEVICE_POLICY_RESTRICTION";
default:
@@ -381,6 +570,33 @@ char *_bt_convert_error_to_string(int error)
}
}
+char *_bt_convert_uuid_to_uuid128(const char *uuid)
+{
+ int len;
+ char *uuid128;
+
+ len = strlen(uuid);
+
+ switch (len) {
+ case 4: /* UUID 16bits */
+ uuid128 = g_strdup_printf("0000%s-0000-1000-8000-00805f9b34fb", uuid);
+ break;
+
+ case 8: /* UUID 32bits */
+ uuid128 = g_strdup_printf("%s-0000-1000-8000-00805f9b34fb", uuid);
+ break;
+
+ case 36: /* UUID 128bits */
+ uuid128 = strdup(uuid);
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return uuid128;
+}
+
bt_adapter_visibility_mode_e _bt_get_bt_visibility_mode_e(bluetooth_discoverable_mode_t mode)
{
switch (mode) {
@@ -398,7 +614,7 @@ bt_adapter_visibility_mode_e _bt_get_bt_visibility_mode_e(bluetooth_discoverable
*/
/* LCOV_EXCL_START */
-static int __bt_get_bt_device_sdp_info_s(bt_device_sdp_info_s **dest, bt_sdp_info_t *source)
+static int __bt_get_bt_device_sdp_info_s(bt_device_sdp_info_s **dest, bt_sdp_info_t *source, int error)
{
int i = 0;
@@ -412,6 +628,10 @@ static int __bt_get_bt_device_sdp_info_s(bt_device_sdp_info_s **dest, bt_sdp_inf
__bt_free_bt_device_sdp_info_s(*dest);
return BT_ERROR_OUT_OF_MEMORY;
}
+ if(error != BT_ERROR_NONE) {
+ BT_DBG("In error case, ignore other fields of service search");
+ return BT_ERROR_NONE;
+ }
if (source->service_index > 0) {
(*dest)->service_uuid = (char **)malloc(sizeof(char *) *source->service_index);
@@ -458,6 +678,25 @@ static void __bt_free_bt_device_sdp_info_s(bt_device_sdp_info_s *sdp_info)
sdp_info = NULL;
}
+static int __bt_get_bt_device_att_mtu_info_s(bt_device_att_mtu_info_s **dest, bluetooth_le_att_mtu_info_t *source)
+{
+ *dest = (bt_device_att_mtu_info_s *)g_malloc0(sizeof(bt_device_att_mtu_info_s));
+ if (*dest == NULL)
+ return BT_ERROR_OUT_OF_MEMORY;
+
+ if (_bt_convert_address_to_string(&((*dest)->remote_address), &(source->device_address)) != BT_ERROR_NONE) {
+ g_free(*dest);
+ *dest = NULL;
+
+ return BT_ERROR_OUT_OF_MEMORY;
+ }
+
+ (*dest)->mtu = source->mtu;
+ (*dest)->status = source->status;
+
+ return BT_ERROR_NONE;
+}
+
static int __bt_get_bt_device_connection_info_s(bt_device_connection_info_s **dest, bt_connection_info_t *source)
{
*dest = (bt_device_connection_info_s *)g_malloc0(sizeof(bt_device_connection_info_s));
@@ -490,7 +729,7 @@ static int __bt_get_bt_device_connection_info_s(bt_device_connection_info_s **de
}
static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
- bt_gatt_h service, bt_gatt_h attribute, void **user_data)
+ bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
{
gchar *svc_path = (gchar *)service;
gchar *att_path = (gchar *)attribute;
@@ -516,6 +755,7 @@ static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
if (g_strcmp0(chr->path, att_path) == 0) {
if (chr->read_requested_cb) {
*user_data = chr->read_requested_user_data;
+ *gatt_handle = chr;
return chr->read_requested_cb;
} else
return NULL;
@@ -526,6 +766,7 @@ static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
if (desc && g_strcmp0(desc->path, att_path) == 0) {
if (desc->read_requested_cb) {
*user_data = desc->read_requested_user_data;
+ *gatt_handle = desc;
return desc->read_requested_cb;
} else
return NULL;
@@ -541,7 +782,7 @@ static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
}
static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_change_cb(
- bt_gatt_h service, bt_gatt_h attribute, void **user_data)
+ bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
{
gchar *svc_path = (gchar *)service;
gchar *att_path = (gchar *)attribute;
@@ -567,6 +808,7 @@ static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_cha
if (g_strcmp0(chr->path, att_path) == 0) {
if (chr->write_value_requested_cb) {
*user_data = chr->write_value_requested_user_data;
+ *gatt_handle = chr;
return chr->write_value_requested_cb;
} else
return NULL;
@@ -577,6 +819,7 @@ static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_cha
if (desc && g_strcmp0(desc->path, att_path) == 0) {
if (desc->write_value_requested_cb) {
*user_data = desc->write_value_requested_user_data;
+ *gatt_handle = desc;
return desc->write_value_requested_cb;
} else
return NULL;
@@ -591,8 +834,9 @@ static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_cha
return NULL;
}
-static bt_gatt_server_characteristic_notification_state_changed_cb __bt_gatt_attribute_get_notification_change_cb(
- bt_gatt_h service, bt_gatt_h attribute, void **user_data)
+static bt_gatt_server_characteristic_notification_state_changed_cb
+ __bt_gatt_attribute_get_notification_change_cb(
+ bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
{
gchar *svc_path = (gchar *)service;
gchar *att_path = (gchar *)attribute;
@@ -617,6 +861,7 @@ static bt_gatt_server_characteristic_notification_state_changed_cb __bt_gatt_att
if (chr && g_strcmp0(chr->path, att_path) == 0) {
if (chr->notification_changed_cb) {
*user_data = chr->notification_changed_user_data;
+ *gatt_handle = chr;
return chr->notification_changed_cb;
} else
return NULL;
@@ -730,6 +975,31 @@ void _bt_hid_event_proxy(int event, hid_event_param_t *param, void *user_data)
}
/* LCOV_EXCL_STOP */
+static bool __bt_need_to_handle(int event)
+{
+ int event_index = -1;
+
+ switch (event) {
+ case BLUETOOTH_EVENT_ADVERTISING_STARTED:
+ case BLUETOOTH_EVENT_ADVERTISING_STOPPED:
+ case BLUETOOTH_EVENT_GATT_CONNECTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED:
+ case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED:
+ case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED:
+ case BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED:
+ return true;
+ default:
+ break;
+ }
+
+ event_index = __bt_get_cb_index(event);
+ if (event_index != -1 && bt_event_slot_container[event_index].callback)
+ return true;
+
+ return false;
+}
+
static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *user_data)
{
int call_id;
@@ -766,44 +1036,10 @@ 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;
- event_index = __bt_get_cb_index(event);
-
- if (event == BLUETOOTH_EVENT_GATT_CONNECTED) {
- const GSList *clients = NULL; /* LCOV_EXCL_START */
- const GSList *l = NULL;
- int ret;
-
- _bt_convert_address_to_string(&device_addr,
- (bluetooth_device_address_t *)(param->param_data));
-
- clients = _bt_gatt_get_client_list();
- for (l = clients; l; l = g_slist_next(l)) {
- bt_gatt_client_s *client_s = l->data;
-
- if (!g_strcmp0(client_s->remote_address, device_addr)) {
- if (client_s->services_discovered == false) {
- BT_INFO("Matched GATT Client is found");
- ret = _bt_gatt_client_update_all((bt_gatt_client_h)l->data);
- if (ret != BT_ERROR_NONE)
- BT_ERR("bluetooth_gatt_get_primary_services is failed");
- else
- client_s->services_discovered = true;
- }
- break;
- }
- }
- g_free(device_addr);
- device_addr = NULL; /* LCOV_EXCL_STOP */
- }
-
- if (event == BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED || event == BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED ||
- event == BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED || event == BLUETOOTH_EVENT_ADVERTISING_STARTED ||
- event == BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED || event == BLUETOOTH_EVENT_ADVERTISING_STOPPED)
- BT_INFO("NOT use bt_event_slot_container");
- else if (event_index == -1 || bt_event_slot_container[event_index].callback == NULL)
+ if (!__bt_need_to_handle(event))
return;
- memset(&rfcomm_connection, 0x00, sizeof(bt_socket_connection_s));
+ event_index = __bt_get_cb_index(event);
switch (event) {
case BLUETOOTH_EVENT_ENABLED:
@@ -838,6 +1074,13 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
((bt_adapter_connectable_changed_cb)bt_event_slot_container[event_index].callback)
(_bt_get_error_code(param->result), *(bool *)(param->param_data), bt_event_slot_container[event_index].user_data);
break;
+ case BLUETOOTH_EVENT_SUPPORTED_PROFILE_TRUSTED: {
+ BT_INFO("bt_device_trusted_profile_cb() will be called");
+ bt_supported_profile_trusted_t *parameter = param->param_data;
+ ((bt_device_trusted_profiles_cb)bt_event_slot_container[event_index].callback)
+ (_bt_get_error_code(param->result), parameter->address, parameter->profile, parameter->supported, parameter->trusted, bt_event_slot_container[event_index].user_data);
+ break;
+ }
case BLUETOOTH_EVENT_DISCOVERY_STARTED:
BT_INFO("bt_adapter_device_discovery_state_changed_cb() will be called with BT_ADAPTER_DEVICE_DISCOVERY_STARTED");
((bt_adapter_device_discovery_state_changed_cb) bt_event_slot_container[event_index].callback)
@@ -961,11 +1204,13 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
break;
case BLUETOOTH_EVENT_SERVICE_SEARCHED:
BT_INFO("bt_device_service_searched_cb() will be called");
- __bt_get_bt_device_sdp_info_s(&sdp_info, (bt_sdp_info_t *)(param->param_data));
error_code = _bt_get_error_code(param->result);
/* In service search, BT_ERROR_SERVICE_SEARCH_FAILED is returned instead of BT_ERROR_OPERATION_FAILED. */
if (error_code == BT_ERROR_OPERATION_FAILED)
error_code = BT_ERROR_SERVICE_SEARCH_FAILED;
+
+ __bt_get_bt_device_sdp_info_s(&sdp_info, (bt_sdp_info_t *)(param->param_data), error_code);
+
((bt_device_service_searched_cb)bt_event_slot_container[event_index].callback)
(error_code, sdp_info, bt_event_slot_container[event_index].user_data);
__bt_free_bt_device_sdp_info_s(sdp_info);
@@ -1510,25 +1755,47 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
((bt_hid_device_received_data_s *)(param->param_data), bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_GATT_CONNECTED: {
+ bt_gatt_client_s *client_s;
+ bt_gatt_connection_state_changed_cb cb = NULL;
BT_INFO("BLUETOOTH_EVENT_GATT_CONNECTED");
- gboolean connected = TRUE;
- bd_addr = (bluetooth_device_address_t *)(param->param_data);
- _bt_convert_address_to_string(&device_addr, bd_addr);
- if (_bt_get_error_code(param->result) != BT_ERROR_NONE)
- connected = FALSE;
- ((bt_gatt_connection_state_changed_cb)bt_event_slot_container[event_index].callback)
- (_bt_get_error_code(param->result), connected, device_addr,
- bt_event_slot_container[event_index].user_data);
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (client_s && !client_s->services_discovered) {
+ if (_bt_gatt_client_update_services(client_s) != BT_ERROR_NONE)
+ BT_ERR("_bt_gatt_client_update_services failed");
+ else
+ client_s->services_discovered = true;
}
+ if (client_s)
+ client_s->connected = true;
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), TRUE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
break;
- case BLUETOOTH_EVENT_GATT_DISCONNECTED:
+ }
+ case BLUETOOTH_EVENT_GATT_DISCONNECTED: {
+ bt_gatt_client_s *client_s;
+ bt_gatt_connection_state_changed_cb cb = NULL;
BT_INFO("BLUETOOTH_EVENT_GATT_DISCONNECTED");
- bd_addr = (bluetooth_device_address_t *)(param->param_data);
- _bt_convert_address_to_string(&device_addr, bd_addr);
- ((bt_gatt_connection_state_changed_cb)bt_event_slot_container[event_index].callback)
- (_bt_get_error_code(param->result), FALSE, device_addr,
- bt_event_slot_container[event_index].user_data);
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (client_s)
+ client_s->connected = false;
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), FALSE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
break;
+ }
#ifdef BT_ENABLE_LEGACY_GATT_CLIENT
case BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED: {
BT_INFO("BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED");
@@ -1619,7 +1886,18 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
}
#endif
_bt_unset_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC);
- ret = _bt_get_error_code(param->result);
+
+ /* Send actual ATT error code to Application
+ * if param->result is not BLUETOOTH_ERROR_INTERNAL.
+ */
+ if (param->result == BLUETOOTH_ERROR_INTERNAL)
+ ret = _bt_get_error_code(param->result);
+ else
+ ret = param->result;
+
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("BLUETOOTH_EVENT_GATT_WRITE_CHAR - ret [%d]", ret);
+
cb(ret, cb_data->gatt_handle, cb_data->user_data);
g_free(cb_data);
@@ -1663,8 +1941,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_gatt_read_req_t *read_req = param->param_data;
bt_gatt_server_read_value_requested_cb cb;
void *user_data = NULL;
+ bt_gatt_h gatt_handle = NULL;
cb = __bt_gatt_attribute_get_read_cb(read_req->service_handle,
- read_req->att_handle, &user_data);
+ read_req->att_handle, &gatt_handle, &user_data);
BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED");
if (cb == NULL) {
@@ -1675,7 +1954,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
}
cb(read_req->address, read_req->req_id, read_req->service_handle,
- read_req->att_handle, read_req->offset,
+ gatt_handle, read_req->offset,
user_data);
break;
}
@@ -1683,8 +1962,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_gatt_value_change_t *value_change = param->param_data;
bt_gatt_server_write_value_requested_cb cb;
void *user_data = NULL;
+ bt_gatt_h gatt_handle = NULL;
cb = __bt_gatt_attribute_get_value_change_cb(value_change->service_handle,
- value_change->att_handle, &user_data);
+ value_change->att_handle, &gatt_handle, &user_data);
BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGE");
if (cb == NULL) {
@@ -1695,7 +1975,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,
- value_change->att_handle, value_change->offset,
+ gatt_handle, value_change->offset,
(char *)value_change->att_value, value_change->val_len, user_data);
break;
}
@@ -1703,15 +1983,16 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_gatt_char_notify_change_t *value_change = param->param_data;
bt_gatt_server_characteristic_notification_state_changed_cb cb;
void *user_data = NULL;
+ bt_gatt_h gatt_handle = NULL;
cb = __bt_gatt_attribute_get_notification_change_cb(value_change->service_handle,
- value_change->att_handle, &user_data);
+ value_change->att_handle, &gatt_handle, &user_data);
BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED");
if (cb == NULL)
return;
cb(value_change->att_notify, value_change->service_handle,
- value_change->att_handle, user_data);
+ gatt_handle, user_data);
break;
}
case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED: {
@@ -1785,6 +2066,81 @@ 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);
+ const GSList *l = NULL;
+ bt_gatt_client_s *client = NULL;
+ bt_gatt_service_s *svc = NULL;
+
+ BT_INFO("BLUETOOTH_EVENT_GATT_CLIENT_SERVICE_CHANGED");
+
+ if (service_change == NULL) {
+ BT_ERR("service_change is NULL");
+ return;
+ }
+
+ _bt_convert_address_to_string(&device_addr,
+ &service_change->device_addr);
+
+ client = _bt_gatt_get_client(device_addr);
+ g_free(device_addr);
+ device_addr = NULL;
+
+ if (client == NULL) {
+ BT_ERR("There is NO matched client");
+ break;
+ }
+
+ if (service_change->change_type
+ == BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_ADD) {
+ for (l = client->services; l; l = g_slist_next(l)) {
+ svc = l->data;
+ if (!g_strcmp0(svc->path, service_change->svc_path))
+ break;
+ }
+ if (l) {
+ BT_INFO("already added service : %s", svc->path);
+ break;
+ }
+
+ svc = _bt_gatt_client_add_service(client,
+ service_change->svc_path);
+ if (svc == NULL) {
+ BT_ERR("_bt_gatt_client_add_service is failed");
+ break;
+ }
+
+ if (client->connected && client->service_changed_cb)
+ client->service_changed_cb(client,
+ BT_GATT_CLIENT_SERVICE_ADDED,
+ svc->uuid,
+ client->service_changed_user_data);
+ } else {
+ char *removed_uuid = NULL;
+
+ for (l = client->services; l; l = g_slist_next(l)) {
+ svc = l->data;
+ if (!g_strcmp0(svc->path, service_change->svc_path))
+ break;
+ }
+ if (!l) {
+ BT_ERR("There is NO matched service");
+ break;
+ }
+
+ removed_uuid = g_strdup(svc->uuid);
+ bt_gatt_service_destroy((bt_gatt_h)svc);
+
+ if (client->connected && client->service_changed_cb)
+ client->service_changed_cb(client,
+ BT_GATT_CLIENT_SERVICE_REMOVED,
+ removed_uuid,
+ client->service_changed_user_data);
+ g_free(removed_uuid);
+ }
+ break;
+ }
case BLUETOOTH_EVENT_ADVERTISING_STARTED:
BT_INFO("BLUETOOTH_EVENT_ADVERTISING_STARTED");
adv_handle = (int *)(param->param_data);
@@ -1821,6 +2177,21 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_event_slot_container[event_index].user_data);
break;
+
+ case BLUETOOTH_EVENT_PASSKEY_NOTIFICATION: {
+ const char *address = NULL;
+ const char *passkey = NULL;
+ const char **passkey_info = param->param_data;
+ BT_INFO("BLUETOOTH_EVENT_PASSKEY_NOTIFICATION");
+
+ address = passkey_info[0];
+ passkey = passkey_info[1];
+
+ ((bt_adapter_passkey_notification_cb)bt_event_slot_container[event_index].callback)
+ (address, passkey, bt_event_slot_container[event_index].user_data);
+
+ break;
+ }
case BLUETOOTH_EVENT_IPSP_CONNECTED:
BT_INFO("BLUETOOTH_EVENT_IPSP_CONNECTED");
bt_ipsp_iface_info = (bt_ipsp_connection_info_t *)(param->param_data);
@@ -1837,6 +2208,15 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
(_bt_get_error_code(param->result), FALSE, device_addr, bt_ipsp_iface_info->if_name,
bt_event_slot_container[event_index].user_data);
break;
+ case BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED: {
+ bt_device_att_mtu_info_s *mtu_info = NULL;
+
+ BT_INFO("BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED");
+ __bt_get_bt_device_att_mtu_info_s(&mtu_info, (bluetooth_le_att_mtu_info_t *)(param->param_data));
+ ((bt_device_att_mtu_changed_cb)bt_event_slot_container[event_index].callback)
+ (_bt_get_error_code(param->result), mtu_info, bt_event_slot_container[event_index].user_data);
+ break;
+ }
case BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED:
BT_INFO("__bt_le_set_data_length_changed_cb() will be called");
data_length_info = (bt_le_data_length_params_t *)(param->param_data);
@@ -2019,63 +2399,93 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
case BLUETOOTH_EVENT_HF_RING_INDICATOR:
BT_INFO("BLUETOOTH_EVENT_HF_RING_INDICATOR");
phone_number = (char *)(param->param_data);
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_RING, phone_number,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_RINGING, phone_number,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_TERMINATED:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_TERMINATED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_RELEASE, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_CALL_TERMINATED, NULL,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_HF_CALL_FAILED_TO_DIAL:
+ BT_INFO("BLUETOOTH_EVENT_HF_CALL_FAILED_TO_DIAL");
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_FAILED_TO_DIALING, NULL,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_HF_CALL_IDLE:
+ BT_INFO("BLUETOOTH_EVENT_HF_CALL_IDLE");
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_IDLE, NULL,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_HF_CALLSETUP_INCOMING:
+ BT_INFO("BLUETOOTH_EVENT_HF_CALLSETUP_INCOMING");
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_INCOMING, NULL,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_HF_CALLSETUP_DIALING:
+ BT_INFO("BLUETOOTH_EVENT_HF_CALLSETUP_DIALING");
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_DIALING, NULL,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ case BLUETOOTH_EVENT_HF_CALLSETUP_ALERTING:
+ BT_INFO("BLUETOOTH_EVENT_HF_CALLSETUP_ALERTING");
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_ALERTING, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_STARTED:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_STARTED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_CALL_STARTED, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_CALL_STARTED, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_ENDED:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_ENDED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_CALL_ENDED, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_CALL_ENDED, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_ENABLED:
BT_INFO("BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_ENABLED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_VOICE_RECOGNITION_ENABLED, NULL,
+ ((bt_hf_remote_device_state_changed_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_DEVICE_STATE_VOICE_RECOGNITON, TRUE,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_DISABLED:
BT_INFO("BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_DISABLED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_VOICE_RECOGNITION_DISABLED, NULL,
+ ((bt_hf_remote_device_state_changed_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_DEVICE_STATE_VOICE_RECOGNITON, FALSE,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_WAITING:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_WAITING");
phone_number = (char *)(param->param_data);
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_WAITING, phone_number,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_WAITING, phone_number,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_ON_HOLD:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_ON_HOLD");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_HELD, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_HELD, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_UNHOLD:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_UNHOLD");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_UNHELD, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_UNHELD, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_CALL_SWAPPED:
BT_INFO("BLUETOOTH_EVENT_HF_CALL_SWAPPED");
- ((bt_hf_call_handling_event_cb)bt_event_slot_container[event_index].callback)
- (BT_HF_CALL_HANDLING_EVENT_SWAPPED, NULL,
+ ((bt_hf_remote_call_event_cb)bt_event_slot_container[event_index].callback)
+ (BT_HF_REMOTE_CALL_EVENT_SWAPPED, NULL,
bt_event_slot_container[event_index].user_data);
break;
case BLUETOOTH_EVENT_HF_VOLUME_SPEAKER: {
@@ -2108,6 +2518,17 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
(call_list, bt_event_slot_container[event_index].user_data);
break;
}
+ case BLUETOOTH_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED: {
+ bluetooth_hf_ciev_device_event_t *device_event = (bluetooth_hf_ciev_device_event_t *)(param->param_data);
+
+ BT_INFO("BLUETOOTH_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED (status %d)(value %d)",
+ device_event->event, device_event->value);
+
+ ((bt_hf_remote_device_state_changed_cb)bt_event_slot_container[event_index].callback)
+ ((bt_hf_remote_device_state_e) device_event->event, device_event->value,
+ bt_event_slot_container[event_index].user_data);
+ break;
+ }
#endif
case BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED: {
BT_DBG("BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED"); /* LCOV_EXCL_LINE */
@@ -2121,7 +2542,6 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
}
}
-
static void __bt_le_event_proxy(int event, bluetooth_event_param_t *param, void *user_data)
{
bt_adapter_le_device_scan_result_info_s *scan_info = NULL;
@@ -2581,16 +3001,22 @@ static int __bt_get_cb_index(int event)
case BLUETOOTH_EVENT_GATT_WRITE_DESC:
return BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR;
/* LCOV_EXCL_STOP */
+ case BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED:
+ return BT_EVENT_GATT_ATT_MTU_CHANGE_STATUS;
case BLUETOOTH_EVENT_ADVERTISING_STARTED:
case BLUETOOTH_EVENT_ADVERTISING_STOPPED:
return BT_EVENT_ADVERTISING_STATE_CHANGED;
case BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED:
return BT_EVENT_MANUFACTURER_DATA_CHANGED; /* LCOV_EXCL_LINE */
+ case BLUETOOTH_EVENT_PASSKEY_NOTIFICATION:
+ return BT_EVENT_PASSKEY_NOTIFICATION_EVENT;
case BLUETOOTH_EVENT_CONNECTABLE_CHANGED:
return BT_EVENT_CONNECTABLE_CHANGED_EVENT; /* LCOV_EXCL_LINE */
case BLUETOOTH_EVENT_IPSP_CONNECTED:
case BLUETOOTH_EVENT_IPSP_DISCONNECTED:
return BT_EVENT_IPSP_CONNECTION_STATUS; /* LCOV_EXCL_LINE */
+ case BLUETOOTH_EVENT_SUPPORTED_PROFILE_TRUSTED:
+ return BT_EVENT_SUPPORTED_TRUSTED_PROFILE_EVENT;
case BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED:
return BT_EVENT_LE_DATA_LENGTH_CHANGED; /* LCOV_EXCL_LINE */
#ifdef TIZEN_WEARABLE
@@ -2619,17 +3045,26 @@ static int __bt_get_cb_index(int event)
case BLUETOOTH_EVENT_HF_CALL_TERMINATED:
case BLUETOOTH_EVENT_HF_CALL_STARTED:
case BLUETOOTH_EVENT_HF_CALL_ENDED:
- case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_ENABLED:
- case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_DISABLED:
case BLUETOOTH_EVENT_HF_CALL_WAITING:
case BLUETOOTH_EVENT_HF_CALL_ON_HOLD:
case BLUETOOTH_EVENT_HF_CALL_UNHOLD:
case BLUETOOTH_EVENT_HF_CALL_SWAPPED:
- return BT_EVENT_HF_CALL_HANDLING_EVENT;
+ case BLUETOOTH_EVENT_HF_CALL_FAILED_TO_DIAL:
+ case BLUETOOTH_EVENT_HF_CALL_IDLE:
+ case BLUETOOTH_EVENT_HF_CALLSETUP_INCOMING:
+ case BLUETOOTH_EVENT_HF_CALLSETUP_DIALING:
+ case BLUETOOTH_EVENT_HF_CALLSETUP_ALERTING:
+ return BT_EVENT_HF_REMOTE_CALL_EVENT;
+ case BLUETOOTH_EVENT_HF_VENDOR_DEP_CMD:
+ return BT_EVENT_HF_VENDOR_DEP_CMD_EVENT;
case BLUETOOTH_EVENT_HF_VOLUME_SPEAKER:
return BT_EVENT_HF_SPEAKER_GAIN_CHANGE;
case BLUETOOTH_EVENT_HF_CALL_STATUS:
return BT_EVENT_HF_CALL_STATUS_UPDATED_EVENT;
+ case BLUETOOTH_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED:
+ case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_ENABLED:
+ case BLUETOOTH_EVENT_HF_VOICE_RECOGNITION_DISABLED:
+ return BT_EVENT_HF_CIEV_DEVICE_STATUS_CHANGED;
#endif
case BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED:
return BT_EVENT_IPSP_INIT_STATE_CHANGED;
@@ -2651,8 +3086,19 @@ static void __bt_convert_lower_to_upper(char *origin)
static void bt_gatt_client_handle_destroy(bt_gatt_h gatt_handle)
{
- if (gatt_handle)
- bt_gatt_destroy(gatt_handle);
+ bt_gatt_common_s *handle = (bt_gatt_common_s *)gatt_handle;
+
+ if (handle) {
+ if (handle->type == BT_GATT_TYPE_SERVICE)
+ bt_gatt_service_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
+ bt_gatt_characteristic_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
+ bt_gatt_descriptor_destroy(gatt_handle);
+ else {
+ BT_ERR("Type is invalid(type:%d)", handle->type);
+ }
+ }
}
int _bt_gatt_client_update_all(bt_gatt_client_h client)
diff --git a/src/bluetooth-device.c b/src/bluetooth-device.c
index 35d4d9d..c042977 100644
--- a/src/bluetooth-device.c
+++ b/src/bluetooth-device.c
@@ -297,6 +297,11 @@ int bt_device_get_connection_state(const char *remote_address,
return ret;
}
+ if (connected_link == BLUETOOTH_CONNECTED_LINK_NONE) {
+ *connected = false;
+ return BT_ERROR_NONE;
+ }
+
if (connected_link == BLUETOOTH_CONNECTED_LINK_BREDR_LE) {
*connected = true;
return BT_ERROR_NONE;
@@ -327,6 +332,16 @@ int bt_device_set_connection_state_changed_cb(bt_device_connection_state_changed
return BT_ERROR_NONE;
}
+int bt_device_set_att_mtu_changed_cb(bt_device_att_mtu_changed_cb callback, void *user_data)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_GATT_ATT_MTU_CHANGE_STATUS, callback, user_data);
+
+ return BT_ERROR_NONE;
+}
+
int bt_device_unset_bond_created_cb(void)
{
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
@@ -372,6 +387,92 @@ int bt_device_unset_connection_state_changed_cb(void)
_bt_unset_cb(BT_EVENT_DEVICE_CONNECTION_STATUS);
return BT_ERROR_NONE;
}
+
+int bt_device_unset_att_mtu_changed_cb(void)
+{
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ _bt_unset_cb(BT_EVENT_DEVICE_CONNECTION_STATUS);
+ return BT_ERROR_NONE;
+}
+
+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,
+ bt_rssi_monitor_enabled_cb cb_enable,
+ void *user_data_enable,
+ bt_rssi_alert_cb cb_alert,
+ void *user_data_alert)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int error_code = BT_ERROR_NONE;
+ bt_rssi_threshold_t rssi_threshold = { 0, };
+ BT_DBG("Enable RSSI");
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+ rssi_threshold.high_threshold = 127;
+ rssi_threshold.low_threshold = low_threshold;
+ rssi_threshold.in_range_threshold = in_range_threshold;
+
+ error_code = _bt_get_error_code(bluetooth_enable_rssi(&addr_hex, link_type, &rssi_threshold));
+ 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_RSSI_ENABLED_EVENT, cb_enable, user_data_enable);
+ _bt_set_cb(BT_EVENT_RSSI_ALERT_EVENT, cb_alert, user_data_alert);
+ }
+
+ return error_code;
+}
+
+int bt_device_disable_rssi_monitor(const char *remote_address,
+ bt_device_connection_link_type_e link_type,
+ bt_rssi_monitor_enabled_cb cb_disable,
+ void *user_data_disable)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int error_code = BT_ERROR_NONE;
+ bt_rssi_threshold_t rssi_threshold = { 0, };
+ BT_DBG("Enable RSSI");
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+ error_code = _bt_get_error_code(bluetooth_enable_rssi(&addr_hex, link_type, &rssi_threshold));
+ 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_RSSI_ENABLED_EVENT, cb_disable, user_data_disable);
+
+ return error_code;
+}
+
+int bt_device_get_rssi_strength(const char *remote_address,
+ bt_device_connection_link_type_e link_type,
+ bt_rssi_strength_cb callback, void *user_data)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int error_code = BT_ERROR_NONE;
+ BT_DBG("Get RSSI Strength");
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+ error_code = _bt_get_error_code(bluetooth_get_rssi_strength(&addr_hex, link_type));
+ 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_GET_RSSI_EVENT, callback, user_data);
+
+ return error_code;
+}
+
+
/* LCOV_EXCL_START */
int bt_device_le_conn_update(const char *device_address,
const bt_le_conn_update_s *parameters)
@@ -605,6 +706,199 @@ int bt_passkey_confirmation_reply(bool confirmation_reply)
return error_code;
}
+
+int bt_device_set_pin_code(const char *remote_address, const char *pin_code)
+{
+ int error_code = BT_ERROR_NONE;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ bluetooth_device_pin_code_t pin = { {0} };
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+ BT_CHECK_INPUT_PARAMETER(pin_code);
+ if (strlen(pin_code) > BLUETOOTH_PIN_CODE_MAX_LENGTH) {
+ BT_ERR("INVALID_PARAMETER(0x%08x)", BT_ERROR_INVALID_PARAMETER);
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+ strncpy(pin.pin_code, pin_code, BLUETOOTH_PIN_CODE_MAX_LENGTH);
+ pin.pin_code[BLUETOOTH_PIN_CODE_MAX_LENGTH] = '\0';
+
+ error_code = _bt_get_error_code(bluetooth_set_pin_code(&addr_hex, &pin));
+ 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_device_unset_pin_code(const char *remote_address)
+{
+ int error_code = BT_ERROR_NONE;
+ bluetooth_device_address_t addr_hex = { {0,} };
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ error_code = _bt_get_error_code(bluetooth_unset_pin_code(&addr_hex));
+ 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_device_update_le_connection_mode(const char *remote_address, bt_device_le_connection_mode_e mode)
+{
+ int ret;
+ bluetooth_device_address_t addr_hex = { {0,} };
+
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ if (mode < BT_DEVICE_LE_CONNECTION_MODE_BALANCED ||
+ mode > BT_DEVICE_LE_CONNECTION_MODE_LOW_ENERGY) {
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ ret = _bt_get_error_code(bluetooth_update_le_connection_mode(&addr_hex, mode));
+ if (BT_ERROR_NONE != ret)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ return ret;
+}
+
+int bt_device_request_att_mtu(const char *remote_address, unsigned int mtu)
+{
+ int ret;
+ bluetooth_device_address_t addr_hex = { {0,} };
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ ret = _bt_get_error_code(bluetooth_request_att_mtu(&addr_hex, mtu));
+ if (BT_ERROR_NONE != ret)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ return ret;
+}
+
+int bt_device_get_att_mtu(const char *remote_address, unsigned int *mtu)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int ret;
+ unsigned int mtu_value = 0;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ ret = _bt_get_error_code(bluetooth_get_att_mtu(&addr_hex, &mtu_value));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ *mtu = mtu_value;
+
+ return ret;
+
+}
+
+int bt_device_get_ida(const char *remote_rpa, char **id_address)
+{
+ bluetooth_device_address_t id_addr = { {0} };
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int ret = BT_ERROR_NONE;
+
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_rpa);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_rpa);
+
+ ret = bluetooth_get_device_ida(&addr_hex, &id_addr);
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ ret = _bt_convert_address_to_string(id_address, &id_addr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+int bt_device_set_profile_trusted(const char *device_address,
+ bt_trusted_profile_t profile, bool trust)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(device_address);
+
+ _bt_convert_address_to_hex(&addr_hex, device_address);
+ error_code = _bt_get_error_code(bluetooth_set_profile_trusted(&addr_hex,
+ profile, trust));
+ 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_device_get_profile_trusted(const char *device_address,
+ bt_trusted_profile_t profile, int *trust)
+{
+ bluetooth_device_address_t addr_hex = { {0,} };
+ int profile_trusted;
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(device_address);
+
+ _bt_convert_address_to_hex(&addr_hex, device_address);
+ error_code = _bt_get_error_code(bluetooth_get_profile_trusted(&addr_hex,
+ profile, &profile_trusted));
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ }
+ if (trust)
+ *trust = profile_trusted;
+ return error_code;
+}
+
+int bt_device_set_trusted_profile_cb(bt_device_trusted_profiles_cb callback, void *user_data)
+{
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_SUPPORTED_TRUSTED_PROFILE_EVENT, callback, user_data);
+
+ return BT_ERROR_NONE;
+}
+
+int bt_device_unset_trusted_profile_cb(void)
+{
+ BT_CHECK_INIT_STATUS();
+ _bt_unset_cb(BT_EVENT_SUPPORTED_TRUSTED_PROFILE_EVENT);
+ return BT_ERROR_NONE;
+}
+
int bt_device_le_set_data_length(const char *remote_address,
unsigned int max_tx_Octets, unsigned int max_tx_Time)
{
diff --git a/src/bluetooth-gatt.c b/src/bluetooth-gatt.c
index 6114158..cfe372d 100644
--- a/src/bluetooth-gatt.c
+++ b/src/bluetooth-gatt.c
@@ -32,6 +32,9 @@ static GSList *gatt_server_list = NULL;
static bool is_gatt_server_initialized = false;
static bool is_gatt_server_started = false;
+bt_gatt_service_s* __bt_gatt_service_create(const char *uuid,
+ bt_gatt_service_type_e type);
+
#define BT_CHECK_GATT_SUPPORT() \
{ \
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
@@ -57,35 +60,6 @@ int __bt_check_gatt_server_init_status(void)
return BT_ERROR_NONE;
}
-static char *__convert_uuid_to_uuid128(const char *uuid)
-{
- int len;
- char *uuid128;
-
- len = strlen(uuid);
-
- switch (len) {
- case 4: /* UUID 16bits */
- uuid128 = g_strdup_printf("0000%s-0000-1000-8000-00805F9B34FB",
- uuid);
- break;
-
- case 8: /* UUID 32bits */
- uuid128 = g_strdup_printf("%s-0000-1000-8000-00805F9B34FB",
- uuid);
- break;
-
- case 36: /* UUID 128bits */
- uuid128 = strdup(uuid);
- break;
-
- default:
- return NULL;
- }
-
- return uuid128;
-}
-
static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
bt_gatt_h *gatt_handle)
{
@@ -93,7 +67,7 @@ static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
char *uuid128_a;
char *uuid128_b;
- uuid128_a = __convert_uuid_to_uuid128(uuid);
+ uuid128_a = _bt_convert_uuid_to_uuid128(uuid);
if (uuid128_a == NULL) {
BT_ERR("Wrong type of uuid : %s", uuid);
return BT_ERROR_INVALID_PARAMETER;
@@ -102,7 +76,7 @@ static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
for (l = list; l; l = g_slist_next(l)) {
bt_gatt_common_s *common = (bt_gatt_common_s *)l->data;
- uuid128_b = __convert_uuid_to_uuid128(common->uuid);
+ uuid128_b = _bt_convert_uuid_to_uuid128(common->uuid);
if (g_ascii_strcasecmp(uuid128_a, uuid128_b) == 0) {
g_free(uuid128_b);
break;
@@ -110,6 +84,7 @@ static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
g_free(uuid128_b);
}
+ g_free(uuid128_a);
if (!l)
return BT_ERROR_NO_DATA;
@@ -119,16 +94,299 @@ static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
return BT_ERROR_NONE;
}
-const GSList *_bt_gatt_get_client_list(void)
+bt_gatt_client_h _bt_gatt_get_client(const char *remote_addr)
{
- return gatt_client_list;
+ GSList *l;
+
+ for (l = gatt_client_list; l; l = g_slist_next(l)) {
+ bt_gatt_client_s *client_s = l->data;
+
+ if (client_s == NULL)
+ continue;
+
+ if (!g_strcmp0(client_s->remote_address, remote_addr))
+ return (bt_gatt_client_h)client_s;
+ }
+
+ return NULL;
}
-const GSList *_bt_gatt_get_server_list(void)
+const GSList* _bt_gatt_get_server_list(void)
{
return gatt_server_list;
}
+static void __bt_gatt_client_handle_destroy(bt_gatt_h gatt_handle)
+{
+ bt_gatt_common_s *handle = (bt_gatt_common_s*)gatt_handle;
+
+ if (handle->type == BT_GATT_TYPE_SERVICE)
+ bt_gatt_service_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
+ bt_gatt_characteristic_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
+ bt_gatt_descriptor_destroy(gatt_handle);
+}
+
+bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client, const char *path)
+{
+ int ret;
+ bt_gatt_client_s *client_s = client;
+ bt_gatt_service_s *svc = NULL;
+ bt_gatt_service_property_t property;
+
+ if (client == NULL || path == NULL) {
+ BT_ERR("Invalid parameter");
+ return NULL;
+ }
+
+ memset(&property, 0x00, sizeof(property));
+
+ ret = bluetooth_gatt_get_service_property(path, &property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_service_property is failed");
+ return NULL;
+ }
+
+ svc = __bt_gatt_service_create(property.uuid,
+ BT_GATT_SERVICE_TYPE_PRIMARY);
+ if (svc == NULL) {
+ BT_ERR("svc is NULL");
+ return NULL;
+ }
+ svc->role = BT_GATT_ROLE_CLIENT;
+ svc->parent = (void *)client_s;
+ svc->is_included_service = false;
+ svc->path = g_strdup(path);
+
+ svc->include_handles = property.include_handles.handle;
+ property.include_handles.handle = NULL;
+
+ svc->char_handles = property.char_handle.handle;
+ property.char_handle.handle = NULL;
+
+ bluetooth_gatt_free_service_property(&property);
+
+ client_s->services = g_slist_append(client_s->services, svc);
+
+ return svc;
+}
+
+int _bt_gatt_client_update_services(bt_gatt_client_h client)
+{
+ bt_gatt_client_s *client_s = client;
+ bluetooth_device_address_t addr_hex = { {0, } };
+ bt_gatt_handle_info_t prim_svc;
+ int ret;
+ int i;
+
+ _bt_convert_address_to_hex(&addr_hex, client_s->remote_address);
+
+ ret = bluetooth_gatt_get_primary_services(&addr_hex, &prim_svc);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_primary_services is failed");
+ return ret;
+ }
+
+ g_slist_free_full(client_s->services,
+ __bt_gatt_client_handle_destroy);
+ client_s->services = NULL;
+
+ if (prim_svc.count == 0) {
+ BT_INFO("There is no service");
+ return BT_ERROR_NONE;
+ }
+
+ for (i = 0; i < prim_svc.count; i++) {
+ BT_INFO("Service handle[%d] %s", i, prim_svc.handle[i]);
+
+ if (!_bt_gatt_client_add_service(client, prim_svc.handle[i]))
+ BT_ERR("_bt_gatt_client_add_service is failed [%s]",
+ prim_svc.handle[i]);
+ }
+ g_strfreev(prim_svc.handle);
+
+ return BT_ERROR_NONE;
+}
+
+int _bt_gatt_client_update_include_services(bt_gatt_h service)
+{
+ bt_gatt_service_s *svc = service;
+ GSList *include_list = NULL;
+ int i;
+
+ if (svc == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ if (svc->include_handles == NULL)
+ return BT_ERROR_NONE;
+
+ for (i = 0; svc->include_handles[i]; i++) {
+ bt_gatt_service_s *sec_svc = NULL;
+ bt_gatt_service_property_t sec_property;
+ int ret;
+
+ memset(&sec_property, 0x00, sizeof(sec_property));
+
+ ret = bluetooth_gatt_get_service_property(
+ svc->include_handles[i], &sec_property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_service_property is failed");
+ continue;
+ }
+
+ sec_svc = __bt_gatt_service_create(sec_property.uuid,
+ BT_GATT_SERVICE_TYPE_SECONDARY);
+ if (sec_svc == NULL) {
+ BT_ERR("svc is NULL");
+ goto next;
+ }
+ sec_svc->role = BT_GATT_ROLE_CLIENT;
+ sec_svc->parent = (void *)svc;
+ sec_svc->is_included_service = true;
+ sec_svc->path = g_strdup(svc->include_handles[i]);
+
+ sec_svc->char_handles = sec_property.char_handle.handle;
+ sec_property.char_handle.handle = NULL;
+
+ include_list = g_slist_append(include_list, sec_svc);
+next:
+ bluetooth_gatt_free_service_property(&sec_property);
+ }
+
+ g_strfreev(svc->include_handles);
+ svc->include_handles = NULL;
+
+ g_slist_free_full(svc->included_services,
+ __bt_gatt_client_handle_destroy);
+
+ svc->included_services = include_list;
+
+ return BT_ERROR_NONE;
+}
+
+int _bt_gatt_client_update_characteristics(bt_gatt_h service)
+{
+ bt_gatt_service_s *svc = service;
+ GSList *chr_list = NULL;
+ int i;
+
+ if (svc == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ if (svc->char_handles == NULL)
+ return BT_ERROR_NONE;
+
+ for (i = 0; svc->char_handles[i]; i++) {
+ bt_gatt_characteristic_s *chr = NULL;
+ bt_gatt_char_property_t char_property;
+ int ret;
+
+ memset(&char_property, 0x00, sizeof(char_property));
+
+ ret = bluetooth_gatt_get_characteristics_property(
+ svc->char_handles[i], &char_property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_characteristics_property is failed");
+ continue;
+ }
+
+ ret = bt_gatt_characteristic_create(char_property.uuid, 0,
+ char_property.permission,
+ (char *)char_property.val,
+ (int)char_property.val_len, (bt_gatt_h *)&chr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_characteristic_create is failed");
+ goto next;
+ }
+
+ if (char_property.permission & BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE)
+ chr->write_type = BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE;
+ else if (char_property.permission & BT_GATT_PROPERTY_WRITE)
+ chr->write_type = BT_GATT_WRITE_TYPE_WRITE;
+
+ chr->path = g_strdup(svc->char_handles[i]);
+ chr->parent = (void *)svc;
+ chr->role = BT_GATT_ROLE_CLIENT;
+ chr->desc_handles = char_property.char_desc_handle.handle;
+ char_property.char_desc_handle.handle = NULL;
+
+ chr_list = g_slist_append(chr_list, chr);
+next:
+ bluetooth_gatt_free_char_property(&char_property);
+ }
+
+ g_strfreev(svc->char_handles);
+ svc->char_handles = NULL;
+
+ g_slist_free_full(svc->characteristics,
+ __bt_gatt_client_handle_destroy);
+
+ svc->characteristics = chr_list;
+
+ return BT_ERROR_NONE;
+}
+
+int _bt_gatt_client_update_descriptors(bt_gatt_h characteristic)
+{
+ bt_gatt_characteristic_s *chr = characteristic;
+ GSList *desc_list = NULL;
+ int i;
+
+ if (chr == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ if (chr->desc_handles == NULL)
+ return BT_ERROR_NONE;
+
+ for (i = 0; chr->desc_handles[i]; i++) {
+ bt_gatt_descriptor_s *desc = NULL;
+ bt_gatt_char_descriptor_property_t desc_property;
+ int ret;
+
+ memset(&desc_property, 0x00, sizeof(desc_property));
+
+ ret = bluetooth_gatt_get_char_descriptor_property(
+ chr->desc_handles[i], &desc_property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_char_descriptor_property is failed");
+ continue;
+ }
+
+ ret = bt_gatt_descriptor_create(desc_property.uuid, 0,
+ (char*)desc_property.val,
+ (int)desc_property.val_len,
+ (bt_gatt_h *)&desc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_characteristic_create is failed");
+ goto next;
+ }
+
+ desc->path = g_strdup(chr->desc_handles[i]);
+ desc->parent = (void *)characteristic;
+ desc->role = BT_GATT_ROLE_CLIENT;
+
+ desc_list = g_slist_append(desc_list, desc);
+next:
+ bluetooth_gatt_free_desc_property(&desc_property);
+ }
+
+ g_strfreev(chr->desc_handles);
+ chr->desc_handles = NULL;
+
+ g_slist_free_full(chr->descriptors,
+ __bt_gatt_client_handle_destroy);
+
+ chr->descriptors = desc_list;
+
+ return BT_ERROR_NONE;
+}
+
#ifdef BT_ENABLE_LEGACY_GATT_CLIENT
bool _bt_gatt_is_legacy_client_mode(void)
{
@@ -599,102 +857,6 @@ int bt_gatt_unset_connection_state_changed_cb(void)
_bt_unset_cb(BT_EVENT_GATT_CONNECTION_STATUS);
return BT_ERROR_NONE;
}
-/* LCOV_EXCL_START */
-int bt_gatt_get_uuid_specification_name(const char *uuid, char **name)
-{
- BT_CHECK_GATT_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(uuid);
- BT_CHECK_INPUT_PARAMETER(name);
-
- int i;
- int offset = 0;
- static struct {
- const char *uuid;
- const char *specification_name;
- } bt_uuid_name[] = {
- /* GATT Services */
- {"1800", "Generic Access"},
- {"1801", "Generic Attribute"},
- {"1802", "Immediate Alert"},
- {"1803", "Link Loss"},
- {"1804", "Tx Power"},
- {"1805", "Current Time Service"},
- {"1806", "Reference Time Update Service"},
- {"1807", "Next DST Change Service"},
- {"1808", "Glucose"},
- {"1809", "Health Thermometer"},
- {"180A", "Device Information"},
- {"180D", "Heart Rate"},
- {"180F", "Battery Service"},
- {"1810", "Blood Pressure"},
- {"1811", "Alert Notification Service"},
- {"1812", "Human Interface Device"},
-
- /* GATT Declarations */
- {"2800", "Primary Service Declaration"},
- {"2801", "Secondary Service Declaration"},
- {"2802", "Include Declaration"},
- {"2803", "Characteristic Declaration"},
-
- /* GATT Descriptors */
- {"2900", "Characteristic Extended Properties"},
- {"2901", "Characteristic User Description"},
- {"2902", "Client Characteristic Configuration"},
- {"2903", "Server Characteristic Configuration"},
- {"2904", "Characteristic Format"},
- {"2905", "Characteristic Aggregate Formate"},
- {"2906", "Valid Range"},
- {"2907", "External Report Reference"},
- {"2908", "Report Reference"},
-
- /* GATT Characteristics */
- {"2A00", "Device Name"},
- {"2A01", "Appearance"},
- {"2A02", "Peripheral Privacy Flag"},
- {"2A03", "Reconnection Address"},
- {"2A04", "Peripheral Preferred Connection Parameters"},
- {"2A05", "Service Changed"},
- {"2A06", "Alert Level"},
- {"2A07", "Tx Power Level"},
- {"2A08", "Date Time"},
- {"2A09", "Day of Week"},
- {"2A0A", "Day Date Time"},
- {"2A19", "Battery Level"},
- {"2A1E", "Intermediate Temperature"},
- {"2A23", "System ID"},
- {"2A24", "Model Number String"},
- {"2A25", "Serial Number String"},
- {"2A26", "Firmware Revision String"},
- {"2A27", "Hardware Revision String"},
- {"2A28", "Software Revision String"},
- {"2A29", "Manufacturer Name String"},
- {"2A2A", "IEEE 11073-20601 Regulatory Certification Data List"},
- {"2A2B", "Current Time"},
- {"2A37", "Heart Rate Measurement"},
- {"2A38", "Body Sensor Location"},
- {"2A3F", "Alert Status"},
- {"2A46", "New Alert"},
- {"2A4A", "HID Information"},
- {"2A4C", "HID Control Point"},
- {"2A50", "PnP ID"},
- {NULL, NULL}
- };
-
- if (strlen(uuid) >= 8)
- offset = 4;
-
- for (i = 0; bt_uuid_name[i].uuid; i++) {
- if (!g_ascii_strncasecmp(uuid + offset,
- bt_uuid_name[i].uuid, 4)) {
- *name = g_strdup(bt_uuid_name[i].specification_name);
- return BT_ERROR_NONE;
- }
- }
-
- *name = g_strdup("Unknown");
- return BT_ERROR_NONE;
-}
static void __bt_gatt_free_descriptor(bt_gatt_h gatt_handle)
{
@@ -708,10 +870,23 @@ static void __bt_gatt_free_descriptor(bt_gatt_h gatt_handle)
static void __bt_gatt_free_characteristic(bt_gatt_h gatt_handle)
{
- bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+ int ret;
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s*)gatt_handle;
+
+ if (chr->role == BT_GATT_ROLE_CLIENT && chr->value_changed_cb &&
+ chr->properties &
+ (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
+ BT_DBG("Unwatch characteristic");
+ ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics(
+ chr->path));
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
g_slist_free_full(chr->descriptors, __bt_gatt_free_descriptor);
+ g_strfreev(chr->desc_handles);
+
g_free(chr->path);
g_free(chr->uuid);
g_free(chr->value);
@@ -733,6 +908,9 @@ static void __bt_gatt_free_service(bt_gatt_h gatt_handle)
_bt_convert_error_to_string(ret), ret);
}
+ g_strfreev(svc->include_handles);
+ g_strfreev(svc->char_handles);
+
g_free(svc->path);
g_free(svc->uuid);
g_free(svc);
@@ -890,28 +1068,6 @@ static int __get_data_type_int_size(bt_data_type_int_e format)
}
}
-int bt_gatt_destroy(bt_gatt_h gatt_handle)
-{
- bt_gatt_common_s *handle = (bt_gatt_common_s *)gatt_handle;
-
- BT_CHECK_GATT_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(gatt_handle);
-
- if (handle->type == BT_GATT_TYPE_SERVICE)
- __bt_gatt_destroy_service(gatt_handle);
- else if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
- __bt_gatt_destroy_characteristic(gatt_handle);
- else if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
- __bt_gatt_destroy_descriptor(gatt_handle);
- else {
- BT_ERR("Type is invalid(type:%d)", handle->type);
- return BT_ERROR_INVALID_PARAMETER;
- }
-
- return BT_ERROR_NONE;
-}
-
int bt_gatt_service_destroy(bt_gatt_h gatt_handle)
{
bt_gatt_common_s *handle = (bt_gatt_common_s *)gatt_handle;
@@ -1474,6 +1630,33 @@ int bt_gatt_get_type(bt_gatt_h gatt_handle, bt_gatt_type_e *gatt_type)
return BT_ERROR_NONE; /* LCOV_EXCL_LINE */
}
+
+bt_gatt_service_s* __bt_gatt_service_create(const char *uuid,
+ bt_gatt_service_type_e type)
+{
+ bt_gatt_service_s *svc;
+
+ if (uuid == NULL)
+ return NULL;
+
+ svc = (bt_gatt_service_s*)g_malloc0(sizeof(bt_gatt_service_s));
+ if (svc == NULL)
+ return NULL;
+
+ svc->type = BT_GATT_TYPE_SERVICE;
+ if (strlen(uuid) == 8)
+ svc->uuid = _bt_convert_uuid_to_uuid128(uuid);
+ else
+ svc->uuid = strdup(uuid);
+ if (svc->uuid == NULL) {
+ g_free(svc);
+ return NULL;
+ }
+ svc->service_type = type;
+
+ return svc;
+}
+
/* LCOV_EXCL_START */
int bt_gatt_service_create(const char *uuid, bt_gatt_service_type_e type,
bt_gatt_h *service)
@@ -1486,27 +1669,16 @@ int bt_gatt_service_create(const char *uuid, bt_gatt_service_type_e type,
BT_CHECK_INPUT_PARAMETER(uuid);
BT_CHECK_INPUT_PARAMETER(service);
- svc = (bt_gatt_service_s *)g_malloc0(sizeof(bt_gatt_service_s));
- if (svc == NULL)
- return BT_ERROR_OUT_OF_MEMORY;
- svc->type = BT_GATT_TYPE_SERVICE;
- svc->role = BT_GATT_ROLE_SERVER;
-
if (is_gatt_server_started) {
BT_ERR("Already Server started");
return BT_ERROR_OPERATION_FAILED;
}
- if (strlen(uuid) == 8)
- svc->uuid = __convert_uuid_to_uuid128(uuid);
- else
- svc->uuid = strdup(uuid);
- if (svc->uuid == NULL) {
- g_free(svc);
+ svc = __bt_gatt_service_create(uuid, type);
+ if (svc == NULL)
return BT_ERROR_OUT_OF_MEMORY;
- }
+ svc->role = BT_GATT_ROLE_SERVER;
svc->is_included_service = false;
- svc->service_type = type;
*service = (bt_gatt_h)svc;
@@ -1622,8 +1794,15 @@ int bt_gatt_service_get_characteristic(bt_gatt_h service, const char *uuid,
BT_CHECK_INPUT_PARAMETER(uuid); /* LCOV_EXCL_START */
BT_CHECK_INPUT_PARAMETER(characteristic);
- ret = __get_gatt_handle_by_uuid(svc->characteristics,
- uuid, &gatt_handle);
+ if (svc->char_handles) {
+ ret = _bt_gatt_client_update_characteristics(svc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_characteristics failed");
+ return ret;
+ }
+ }
+
+ ret = __get_gatt_handle_by_uuid(svc->characteristics, uuid, &gatt_handle);
if (ret == BT_ERROR_NONE && gatt_handle != NULL) {
*characteristic = gatt_handle;
return BT_ERROR_NONE;
@@ -1649,6 +1828,16 @@ int bt_gatt_service_foreach_characteristics(bt_gatt_h service,
BT_CHECK_INPUT_PARAMETER(service);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
+ if (svc->char_handles) {
+ int ret;
+
+ ret = _bt_gatt_client_update_characteristics(svc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_characteristics is failed");
+ return ret;
+ }
+ }
+
total = g_slist_length(svc->characteristics);
for (l = svc->characteristics; l; l = g_slist_next(l)) {
@@ -1674,8 +1863,15 @@ int bt_gatt_service_get_included_service(bt_gatt_h service, const char *uuid,
BT_CHECK_INPUT_PARAMETER(uuid); /* LCOV_EXCL_START */
BT_CHECK_INPUT_PARAMETER(included_service);
- ret = __get_gatt_handle_by_uuid(svc->included_services,
- uuid, &gatt_handle);
+ if (svc->include_handles) {
+ ret = _bt_gatt_client_update_include_services(svc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_include_services failed");
+ return ret;
+ }
+ }
+
+ ret = __get_gatt_handle_by_uuid(svc->included_services, uuid, &gatt_handle);
if (ret == BT_ERROR_NONE && gatt_handle != NULL) {
*included_service = gatt_handle;
return BT_ERROR_NONE;
@@ -1701,6 +1897,16 @@ int bt_gatt_service_foreach_included_services(bt_gatt_h service,
BT_CHECK_INPUT_PARAMETER(service);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_LINE */
+ if (svc->include_handles) {
+ int ret;
+
+ ret = _bt_gatt_client_update_include_services(svc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_include_services failed");
+ return ret;
+ }
+ }
+
total = g_slist_length(svc->included_services); /* LCOV_EXCL_LINE */
for (l = svc->included_services; l; l = g_slist_next(l)) {
@@ -1737,7 +1943,7 @@ int bt_gatt_characteristic_create(const char *uuid, int permissions,
chr->type = BT_GATT_TYPE_CHARACTERISTIC;
chr->role = BT_GATT_ROLE_SERVER;
if (strlen(uuid) == 8)
- chr->uuid = __convert_uuid_to_uuid128(uuid);
+ chr->uuid = _bt_convert_uuid_to_uuid128(uuid);
else
chr->uuid = g_strdup(uuid);
if (chr->uuid == NULL) {
@@ -1879,6 +2085,7 @@ int bt_gatt_characteristic_set_write_type(bt_gatt_h characteristic,
bt_gatt_write_type_e write_type)
{
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)characteristic;
+ int property;
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
@@ -1890,8 +2097,27 @@ int bt_gatt_characteristic_set_write_type(bt_gatt_h characteristic,
return BT_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */
}
- chr->write_type = write_type;
+ switch (write_type) {
+ case BT_GATT_WRITE_TYPE_WRITE:
+ property = BT_GATT_PROPERTY_WRITE;
+ break;
+ case BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
+ property = BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
+ break;
+/* After ACR for BT_GATT_WRITE_TYPE_SIGNED_WRITE, will enable this code */
+#if 0
+ case BT_GATT_WRITE_TYPE_SIGNED_WRITE:
+ property = BT_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES;
+ break;
+#endif
+ default:
+ return BT_ERROR_NOT_SUPPORTED;
+ }
+
+ if(!(chr->properties & property))
+ return BT_ERROR_NOT_SUPPORTED;
+ chr->write_type = write_type;
return BT_ERROR_NONE;
}
@@ -1909,6 +2135,19 @@ int bt_gatt_characteristic_get_descriptor(bt_gatt_h characteristic,
BT_CHECK_INPUT_PARAMETER(uuid); /* LCOV_EXCL_START */
BT_CHECK_INPUT_PARAMETER(descriptor);
+ if (chr->type != BT_GATT_TYPE_CHARACTERISTIC) {
+ BT_ERR("Wrong type of GATT handle : %d", chr->type);
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (chr->desc_handles) {
+ ret = _bt_gatt_client_update_descriptors(chr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_descriptors is failed");
+ return ret;
+ }
+ }
+
ret = __get_gatt_handle_by_uuid(chr->descriptors, uuid, &gatt_handle);
if (ret == BT_ERROR_NONE && gatt_handle != NULL) {
*descriptor = gatt_handle;
@@ -1938,6 +2177,16 @@ int bt_gatt_characteristic_foreach_descriptors(bt_gatt_h characteristic,
return BT_ERROR_INVALID_PARAMETER;
}
+ if (chr->desc_handles) {
+ int ret;
+
+ ret = _bt_gatt_client_update_descriptors(chr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("_bt_gatt_client_update_descriptors is failed");
+ return ret;
+ }
+ }
+
total = g_slist_length(chr->descriptors);
i = 1;
@@ -1973,13 +2222,14 @@ int bt_gatt_descriptor_create(const char *uuid, int permissions,
desc->type = BT_GATT_TYPE_DESCRIPTOR;
desc->role = BT_GATT_ROLE_SERVER;
if (strlen(uuid) == 8)
- desc->uuid = __convert_uuid_to_uuid128(uuid);
+ desc->uuid = _bt_convert_uuid_to_uuid128(uuid);
else
desc->uuid = g_strdup(uuid);
if (desc->uuid == NULL) {
ret = BT_ERROR_OUT_OF_MEMORY;
goto fail;
}
+
desc->permissions = permissions;
desc->value_length = value_length;
if (value_length > 0) {
@@ -2278,16 +2528,17 @@ int bt_gatt_server_unregister_service(bt_gatt_server_h server,
return BT_ERROR_SERVICE_NOT_FOUND;
}
- __bt_gatt_destroy_service(svc);
+ bt_gatt_service_destroy(svc);
return BT_ERROR_NONE;
}
int bt_gatt_server_unregister_all_services(bt_gatt_server_h server)
{
- bt_gatt_server_s *serv = (bt_gatt_server_s *)server;
int ret = BT_ERROR_NONE;
+ bt_gatt_server_s *serv = (bt_gatt_server_s*)server;
+
BT_CHECK_INIT_STATUS();
BT_CHECK_GATT_SERVER_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(server);
@@ -2332,8 +2583,13 @@ int bt_gatt_server_send_response(int request_id, bluetooth_gatt_att_request_type
int ret = BT_ERROR_NONE;
BT_CHECK_INIT_STATUS();
- if (value_length < 0)
- return BT_ERROR_INVALID_PARAMETER;
+ if (request_type == BLUETOOTH_GATT_REQUEST_TYPE_READ &&
+ resp_status == BT_ERROR_NONE) {
+ BT_CHECK_INPUT_PARAMETER(value);
+
+ if (value_length < 0)
+ return BT_ERROR_INVALID_PARAMETER;
+ }
ret = _bt_get_error_code(bluetooth_gatt_send_response(request_id,
request_type, resp_status,
@@ -2470,6 +2726,7 @@ int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
{
int ret = BT_ERROR_NONE;
bt_gatt_client_s *client_s;
+ bool connected = false;
GSList *l;
BT_CHECK_GATT_SUPPORT();
@@ -2492,7 +2749,6 @@ int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
return ret;
}
- memset(client_s, 0x00, sizeof(*client_s));
client_s->remote_address = g_strdup(remote_address);
if (client_s->remote_address == NULL) {
@@ -2501,14 +2757,20 @@ int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
return ret;
}
- client_s->services_discovered = false;
*client = (bt_gatt_client_h)client_s;
gatt_client_list = g_slist_append(gatt_client_list, client_s);
+ if (bt_device_is_profile_connected(remote_address, BT_PROFILE_GATT,
+ &connected) != BT_ERROR_NONE)
+ BT_ERR("bt_device_is_profile_connected is failed");
+ else
+ client_s->connected = connected;
+
+ if (_bt_gatt_client_update_services(*client) == BT_ERROR_NONE)
+ client_s->services_discovered = true;
- if (_bt_gatt_client_update_all(*client) == BT_ERROR_NONE)
- client_s->services_discovered = true;
+ BT_INFO("GATT Client Handle is created");
return ret; /* LCOV_EXCL_STOP */
}
@@ -2657,17 +2919,24 @@ int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
chr->path, (guint8 *)chr->value,
chr->value_length,
BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE));
+/* After ACR for BT_GATT_WRITE_TYPE_SIGNED_WRITE, will enable this code */
+#if 0
+
+ else if (chr->write_type == BT_GATT_WRITE_TYPE_SIGNED_WRITE)
+ ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
+ chr->path, (guint8 *)chr->value, chr->value_length,
+ BT_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES));
+#endif
else {
BT_ERR("Unknow write type : %d", chr->write_type);
+ BT_ERR("path : %s", chr->path);
ret = BT_ERROR_OPERATION_FAILED;
}
if (ret != BT_ERROR_NONE) {
g_free(cb_data);
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
} else {
- if (chr->write_type != BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE)
- _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC,
- callback, cb_data);
+ _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC, callback, cb_data);
}
} else if (c->type == BT_GATT_TYPE_DESCRIPTOR) {
bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
@@ -2678,11 +2947,9 @@ int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
desc->value_length));
if (ret != BT_ERROR_NONE) {
g_free(cb_data);
- BT_ERR("%s(0x%08x)",
- _bt_convert_error_to_string(ret), ret);
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
} else {
- _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR,
- callback, cb_data);
+ _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR, callback, cb_data);
}
} else {
BT_ERR("Invalid handle type for write ");
diff --git a/src/bluetooth-hid.c b/src/bluetooth-hid.c
index fd38b0a..0b8a11f 100644
--- a/src/bluetooth-hid.c
+++ b/src/bluetooth-hid.c
@@ -318,18 +318,21 @@ int bt_hid_device_send_rc_key_event(const char *remote_address,
if (ret <= 0) {
if (ret == -1) {
/* write fail case */
- if (errno == EACCES || errno == EPERM)
+ if (errno == EACCES || errno == EPERM) {
set_last_result(BT_ERROR_PERMISSION_DENIED);
- else if (errno == EAGAIN || errno == EWOULDBLOCK)
+ BT_ERR("PERMISSION_DENIED, errno = %d", errno);
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
set_last_result(BT_ERROR_AGAIN);
- else
+ BT_ERR("BT_ERROR_AGAIN, errno = %d", errno);
+ } else {
set_last_result(BT_ERROR_OPERATION_FAILED);
+ BT_ERR("BT_ERROR_OPERATION_FAILED, errno = %d", errno);
+ }
} else {
ret = _bt_get_error_code(ret);
set_last_result(ret);
+ BT_ERR("Write failed, ret = %d", ret);
}
-
- BT_ERR("Write failed, ret = %d", ret);
}
return ret;
@@ -345,24 +348,28 @@ int bt_hid_device_reply_to_report(const char *remote_address,
BT_CHECK_HID_DEVICE_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(remote_address);
+ BT_CHECK_INPUT_PARAMETER(data);
ret = bluetooth_hid_device_reply_to_report(remote_address, header_type,
param_type, data, data_len);
if (ret <= 0) {
if (ret == -1) {
/* write fail case */
- if (errno == EACCES || errno == EPERM)
+ if (errno == EACCES || errno == EPERM) {
set_last_result(BT_ERROR_PERMISSION_DENIED);
- else if (errno == EAGAIN || errno == EWOULDBLOCK)
+ BT_ERR("PERMISSION_DENIED, errno = %d", errno);
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
set_last_result(BT_ERROR_AGAIN);
- else
+ BT_ERR("BT_ERROR_AGAIN, errno = %d", errno);
+ } else {
set_last_result(BT_ERROR_OPERATION_FAILED);
+ BT_ERR("BT_ERROR_OPERATION_FAILED, errno = %d", errno);
+ }
} else {
ret = _bt_get_error_code(ret);
set_last_result(ret);
+ BT_ERR("Write failed, ret = %d", ret);
}
-
- BT_ERR("Write failed, ret = %d", ret);
}
return ret;
diff --git a/src/bluetooth-socket.c b/src/bluetooth-socket.c
index bd5d86d..c141dc3 100644
--- a/src/bluetooth-socket.c
+++ b/src/bluetooth-socket.c
@@ -237,18 +237,21 @@ int bt_socket_send_data(int socket_fd, const char *data, int length)
if (ret <= 0) {
if (ret == -1) {
/* write fail case */
- if (errno == EACCES || errno == EPERM)
+ if (errno == EACCES || errno == EPERM) {
set_last_result(BT_ERROR_PERMISSION_DENIED);
- else if (errno == EAGAIN || errno == EWOULDBLOCK)
+ BT_ERR("PERMISSION_DENIED, errno = %d", errno);
+ } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
set_last_result(BT_ERROR_AGAIN);
- else
+ BT_ERR("BT_ERROR_AGAIN, errno = %d", errno);
+ } else {
set_last_result(BT_ERROR_OPERATION_FAILED);
+ BT_ERR("BT_ERROR_OPERATION_FAILED, errno = %d", errno);
+ }
} else {
ret = _bt_get_error_code(ret);
set_last_result(ret);
+ BT_ERR("Write failed, ret = %d", ret);
}
-
- BT_ERR("Write failed, ret = %d", ret);
}
return ret; /* LCOV_EXCL_STOP */
diff --git a/test/bt_unit_test.c b/test/bt_unit_test.c
index d3c1a32..ac374b5 100644
--- a/test/bt_unit_test.c
+++ b/test/bt_unit_test.c
@@ -2090,7 +2090,7 @@ bool __bt_gatt_print_info_cb(int total,
char *str = NULL;
bt_gatt_get_uuid(gatt_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("[%d / %d] %s (%s)",
index, total,
@@ -2109,7 +2109,7 @@ void __bt_gatt_client_write_complete_cb(int result,
char *str = NULL;
bt_gatt_get_uuid(gatt_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("Write %s for %s (%s)",
result == BT_ERROR_NONE ? "Success" : "Fail",
@@ -2128,7 +2128,7 @@ void __bt_gatt_client_read_complete_cb(int result,
char *str = NULL;
bt_gatt_get_uuid(gatt_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("Read %s for %s (%s)",
result == BT_ERROR_NONE ? "Success" : "Fail",
@@ -2152,7 +2152,7 @@ bool __bt_gatt_client_foreach_desc_cb(int total,
char *str = NULL;
bt_gatt_get_uuid(desc_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("\t\t[%d / %d] %s (%s)",
index, total,
@@ -2171,13 +2171,13 @@ bool __bt_gatt_client_foreach_chr_cb(int total,
int ret;
char *uuid = NULL;
char *str = NULL;
+ int properties = 0;
bt_gatt_get_uuid(chr_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
+ bt_gatt_characteristic_get_properties(chr_handle, &properties);
- TC_PRT("\t[%d / %d] %s (%s)",
- index, total,
- str ? str : "Unknown", uuid);
+ TC_PRT("\t[%d / %d] %s (%s) (0x%X)", index, total, str ? str : "Unknown", uuid, properties);
__bt_gatt_client_print_value(chr_handle);
g_free(str);
@@ -2204,7 +2204,7 @@ bool __bt_gatt_client_foreach_svc_cb(int total,
char *str = NULL;
bt_gatt_get_uuid(svc_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("[%d / %d] %s (%s)",
index, total,
@@ -2241,7 +2241,7 @@ bool __bt_hps_client_svc_cb(int total,
char *str = NULL;
bt_gatt_get_uuid(svc_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
if (!g_strcmp0(uuid, HPS_UUID)) {
@@ -2400,7 +2400,7 @@ bool __bt_gatt_server_foreach_svc_cb(int total,
char *str = NULL;
bt_gatt_get_uuid(svc_handle, &uuid);
- bt_gatt_get_uuid_specification_name(uuid, &str);
+ bt_get_uuid_name(uuid, &str);
TC_PRT("[%d / %d] %s (%s)", index, total, str ? str : "Unknown", uuid);
@@ -2468,7 +2468,7 @@ bool __bt_gatt_included_service_cb(bt_gatt_attribute_h service,
bt_gatt_get_characteristic_declaration(service, &uuid,
&value, &value_length);
- bt_gatt_get_uuid_specification_name(uuid, &name);
+ bt_get_uuid_name(uuid, &name);
TC_PRT("uuid: %s [%s]", uuid, name);
g_free(uuid);
@@ -6588,7 +6588,7 @@ int test_input_callback(void *data)
if (ret < BT_ERROR_NONE) {
TC_PRT("returns %s\n", __bt_get_error_message(ret));
} else {
- bt_gatt_get_uuid_specification_name(uuid, &name);
+ bt_get_uuid_name(uuid, &name);
TC_PRT("uuid: %s [%s]", uuid, name);
g_free(name);
g_free(uuid);
@@ -6639,7 +6639,7 @@ int test_input_callback(void *data)
if (ret < BT_ERROR_NONE) {
TC_PRT("returns %s\n", __bt_get_error_message(ret));
} else {
- bt_gatt_get_uuid_specification_name(uuid, &name);
+ bt_get_uuid_name(uuid, &name);
TC_PRT("uuid: %s [%s]", uuid, name);
for (i = 0; i < value_length; i++)