summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/bluetooth_internal.h70
-rw-r--r--include/bluetooth_private.h2
-rw-r--r--include/bluetooth_type.h1
-rw-r--r--include/bluetooth_type_internal.h64
-rw-r--r--src/bluetooth-hrp.c439
-rw-r--r--test/bt_unit_test.c161
-rw-r--r--test/bt_unit_test.h14
7 files changed, 721 insertions, 30 deletions
diff --git a/include/bluetooth_internal.h b/include/bluetooth_internal.h
index 67c05ba..e1e369b 100644
--- a/include/bluetooth_internal.h
+++ b/include/bluetooth_internal.h
@@ -4333,6 +4333,76 @@ int bt_hrp_sensor_update_heartrate_value(int heartrate);
int bt_hrp_sensor_destroy();
+/**
+ * @internal
+ * @brief HRP collector API to create collector .
+ */
+
+int bt_hrp_collector_create(const char *remote_address,
+ bt_hrp_collector_h *collector);
+
+/**
+ * @internal
+ * @brief HRP collector API to destory collector.
+ */
+void bt_hrp_collector_destory(bt_hrp_collector_h collector);
+
+/**
+ * @internal
+ * @brief HRP collector API to start scan .
+ */
+int bt_hrp_collector_start_scan();
+
+/**
+ * @internal
+ * @brief HRP collector API to stop scan.
+ */
+int bt_hrp_collector_stop_scan();
+
+/**
+ * @internal
+ * @brief HRP collector API to connect to remote sensor .
+ */
+int bt_hrp_collector_connect(const char *address, bool auto_connect);
+
+/**
+ * @internal
+ * @brief HRP collector API to disconnect to remote sensor .
+ */
+int bt_hrp_collector_disconnect(const char *address);
+
+/**
+ * @internal
+ * @brief HRP collector API to set notification on / off.
+ */
+int bt_hrp_collector_set_notification(bt_hrp_collector_h collector,
+ bt_hrp_collector_heart_rate_value_changed_cb callback,
+ bool isNotify);
+
+/**
+ * @internal
+ * @brief HRP collector API to read Body Sensor location , fills body sensor location in bsl_location
+ */
+
+bt_body_sensor_location_e bt_hrp_get_body_sensor_location(bt_hrp_collector_h collector,
+ bt_hrp_collector_bsl_read_completed_cb bsl_read_cb);
+
+
+/**
+ * @internal
+ * @brief HRP collector API to set connection state callback
+ */
+
+int bt_hrp_collector_set_connection_state_changed_cb(bt_hrp_collector_h collector,
+ bt_hrp_collector_connection_state_changed_cb callback,
+ void *user_data);
+
+/**
+ * @internal
+ * @brief HRP collector API to unset connection state callback
+ */
+
+int bt_hrp_collector_unset_connection_state_changed_cb(bt_hrp_collector_h collector);
/**
* @}
diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h
index 4fadc08..4e1181e 100644
--- a/include/bluetooth_private.h
+++ b/include/bluetooth_private.h
@@ -587,6 +587,7 @@ typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, c
#define BT_FEATURE_GATT_SERVER "tizen.org/feature/network.bluetooth.le.gatt.server"
#define BT_FEATURE_GATT_CLIENT "tizen.org/feature/network.bluetooth.le.gatt.client"
#define BT_FEATURE_HRS "tizen.org/feature/network.bluetooth.le.hrp.sensor"
+#define BT_FEATURE_HRC "tizen.org/feature/network.bluetooth.le.hrp.collector"
#define BT_CHECK_SUPPORTED_FEATURE(feature_name) \
@@ -935,7 +936,6 @@ void _bt_tds_update_seeker_connection_state_changed(int result, const char *remo
*/
void __bt_hrp_le_connection_state_changed_cb(int result, const char *remote_address, bool connected);
-
/**
* @internal
* @brief Parses TDS AD Type data recived in scan, to extract meaningful transport specific data.
diff --git a/include/bluetooth_type.h b/include/bluetooth_type.h
index 8f037d5..107a6ba 100644
--- a/include/bluetooth_type.h
+++ b/include/bluetooth_type.h
@@ -1708,6 +1708,7 @@ typedef void (*bt_gatt_client_request_completed_cb) (int result,
*/
typedef void (*bt_gatt_client_characteristic_value_changed_cb) (bt_gatt_h characteristic,
char *value, int len, void *user_data);
+
/**
* @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE
* @brief Called when the connection state is changed.
diff --git a/include/bluetooth_type_internal.h b/include/bluetooth_type_internal.h
index 6f3c27e..790034f 100644
--- a/include/bluetooth_type_internal.h
+++ b/include/bluetooth_type_internal.h
@@ -1125,6 +1125,70 @@ typedef enum {
BT_BSL_FOOT,
} bt_body_sensor_location_e;
+/**
+ * @internal
+ * @brief The handle of a HRP Collector client which is associated with a remote HRP sensor
+ * @since_tizen 4.0
+ */
+typedef void *bt_hrp_collector_h;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_CLIENT_MODULE
+ * @brief Called when a value of a watched characteristic's GATT handle has been changed in HRP.
+ * @since_tizen 2.3.1
+ *
+ * @remarks After this function is returned, a changed value is automatically \n
+ * applied to @a characteristic. Before that, @a characteristic has an old value.
+ *
+ * @param[in] characteristic The characteristic's GATT handle of which value change is informed. It has an old value.
+ * @param[in] value The new value
+ * @param[in] len The length of @a value
+ * @param[in] user_data The user data passed from the registering function
+ *
+ * @see bt_gatt_client_set_characteristic_value_changed_cb()
+ */
+typedef void (*bt_hrp_collector_heart_rate_value_changed_cb) (bt_gatt_client_h characteristic,
+ unsigned short hr_value, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_CLIENT_MODULE
+ * @brief type information structure ,define what type of reequest is made.
+ * @since_tizen 4.0
+ *
+ * @see bt_gatt_client_att_mtu_changed_cb()
+ */
+
+typedef enum {
+ HEART_RATE = 1,
+ BODY_SENSOR_LOCATION,
+ HEART_CONTROL_POINT,
+} bt_serv_char_type_t;
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_CLIENT_MODULE
+ * @brief Called when the client request read operation on body sensor location has been completed.
+ * @since_tizen 4
+ *
+ * @param[in] result The result of a request
+ * @param[in] request_handle The requesting GATT handle
+ * @param[in] type : Heart Rate Value , Body Sensor Location or Heart Control Point
+ * @param[in] value : Int value corresponding to the type recieved .
+ * @param[in] user_data The user data passed from the requesting function
+ *
+ */
+typedef void (*bt_hrp_collector_bsl_read_completed_cb) (int result,
+ bt_hrp_collector_h request_handle, bt_body_sensor_location_e location, void *user_data);
+
+/**
+ * @internal
+ * @since_tizen 4.0
+ * @brief HRP Collector profile Connection State changed callback which is associated with
+ * a remote HRP sensor.
+ */
+typedef void (*bt_hrp_collector_connection_state_changed_cb)
+ (int result, const char *remote_address, bt_hrp_collector_h collector,
+ bool connected, void *user_data);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/bluetooth-hrp.c b/src/bluetooth-hrp.c
index 45eb899..749c43c 100644
--- a/src/bluetooth-hrp.c
+++ b/src/bluetooth-hrp.c
@@ -39,6 +39,13 @@
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_HRS); \
}
+#define BT_CHECK_HRC_SUPPORT() \
+{ \
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
+ BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_HRC); \
+}
+
/*======================================================================================================
Heart Rate Server - Structures
========================================================================================================*/
@@ -90,6 +97,27 @@ static guint adv_timer_id;
GSList *sensor_list;
static bt_hrp_server_info_s hrp_server_info_s;
+//Collector Structures
+
+typedef struct {
+ char *remote_address; //remote sensor
+ bool connected; //is connected to sensor or not
+ int heart_rate_measurement;
+ bt_gatt_h bsl_char_handle;
+ bt_hrp_collector_connection_state_changed_cb connection_callback; //GATT connection state changes callback
+ void *conn_cb_user_data; //
+ char *hrs_service_handle; /* HRS Primary Service Handle */
+ char *dis_service_handle; /* DIS Primary Service Handle */
+ bool cccd_enabled; /* TDS Control Point CCCD is enabled or not */
+ bt_hrp_collector_heart_rate_value_changed_cb char_update_cb;
+ bt_hrp_collector_bsl_read_completed_cb bsl_read_cb;
+} bt_hrp_collector_s;
+
+GSList *hrp_collector_list;
+static bt_adapter_le_scan_result_cb scan_cb; //le scan application callback
+static bt_hrp_collector_s *_bt_hrp_collector_find(const char *remote_address);
+
+
/*======================================================================================================
Heart Rate Server - Utility
========================================================================================================*/
@@ -471,37 +499,51 @@ void __bt_hrp_le_connection_state_changed_cb(int result,
BT_INFO("[HR]Remote Address : %s", remote_address);
bool isappend = true;
int error_code = BT_ERROR_NOT_INITIALIZED;
+ /*To do Check for if it for sensor or collector */
+
+ /*If Sensor */
+ if (hrp_server_info_s.hrp_sensor == NULL) {
+
+ GSList *iter = hrp_server_info_s.hrs_collector_connected_list;
+
+ for (; iter; iter = g_slist_next(iter)) {
+ if ((iter) && (iter->data != NULL) &&
+ (((bt_hrp_collector_notify_info_s *)iter->data)->remote_address != NULL)) {
+ if (!g_ascii_strcasecmp(((bt_hrp_collector_notify_info_s *)iter->data)->remote_address,
+ remote_address)) {
+ ((bt_hrp_collector_notify_info_s *)iter->data)->isconnected = connected;
+ isappend = false;
+ break;
+ }
+ }
+ }
- GSList *iter = hrp_server_info_s.hrs_collector_connected_list;
+ if (isappend) {
+ bt_hrp_collector_notify_info_s *client_s = g_malloc(sizeof(bt_hrp_collector_notify_info_s));
+ client_s->isconnected = connected;
+ client_s->remote_address = g_strdup(remote_address);
+ hrp_server_info_s.hrs_collector_connected_list =
+ g_slist_append(hrp_server_info_s.hrs_collector_connected_list, (gpointer)client_s);
+ }
- for (; iter; iter = g_slist_next(iter)) {
- if ((iter) && (iter->data != NULL) &&
- (((bt_hrp_collector_notify_info_s *)iter->data)->remote_address != NULL)) {
- if (!g_ascii_strcasecmp(((bt_hrp_collector_notify_info_s *)iter->data)->remote_address,
- remote_address)) {
- ((bt_hrp_collector_notify_info_s *)iter->data)->isconnected = connected;
- isappend = false;
- break;
- }
+ if (connected == true && hrp_server_info_s.is_notify_cb_set == false) {
+ error_code = bt_gatt_server_notify_characteristic_changed_value(hrp_server_info_s.hrs_characteristic,
+ __bt_hrp_notification_send_cb, NULL, NULL);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("bt_gatt_server_notify_characteristic_changed_value : %s\n", _bt_convert_error_to_string(error_code));
+ hrp_server_info_s.is_notify_cb_set = true;
}
- }
- if (isappend) {
- bt_hrp_collector_notify_info_s *client_s = g_malloc(sizeof(bt_hrp_collector_notify_info_s));
- client_s->isconnected = connected;
- client_s->remote_address = g_strdup(remote_address);
- hrp_server_info_s.hrs_collector_connected_list =
- g_slist_append(hrp_server_info_s.hrs_collector_connected_list, (gpointer)client_s);
- }
+ } else {
+ /*If Collector*/
+ bt_hrp_collector_s *collector_s = _bt_hrp_collector_find(remote_address);
- if (connected == true && hrp_server_info_s.is_notify_cb_set == false) {
- error_code = bt_gatt_server_notify_characteristic_changed_value(hrp_server_info_s.hrs_characteristic,
- __bt_hrp_notification_send_cb, NULL, NULL);
- if (error_code != BT_ERROR_NONE)
- BT_ERR("bt_gatt_server_notify_characteristic_changed_value : %s\n", _bt_convert_error_to_string(error_code));
- hrp_server_info_s.is_notify_cb_set = true;
+ if (collector_s && collector_s->connection_callback)
+ collector_s->connection_callback(result, remote_address,
+ (bt_hrp_collector_h)collector_s, connected, NULL);
}
+
}
/*Application Interfaces*/
@@ -848,3 +890,352 @@ int bt_hrp_sensor_destroy()
}
+/*======================================================================================================
+ Hear Rate Collector
+ =======================================================================================================*/
+static void _bt_hrp_collector_characteristic_value_changed_cb(bt_hrp_collector_h characteristic,
+ char *value, int len, void *user_data)
+{
+
+ BT_INFO("_bt_hrp_collector_characteristic_value_changed_cb Called with value %s", value);
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)characteristic;
+
+ /*To do :Extract value in to uint and send*/
+ unsigned short hr_value = 1;
+
+ if (collector_s->char_update_cb)
+ collector_s->char_update_cb(characteristic, hr_value, user_data);
+
+}
+static void _bt_hrp_collector_bsl_read_completed_cb (int result, bt_hrp_collector_h collector, void *user_data)
+{
+ BT_INFO();
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+ char *value = NULL;
+ int len = 0;
+
+ int error_code = bt_gatt_get_value(collector_s->bsl_char_handle, &value, &len);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_get_value is failed : %d", error_code);
+ return;
+ }
+
+ if (collector_s->bsl_read_cb)
+ collector_s->bsl_read_cb(result, collector, (bt_body_sensor_location_e) *value, user_data);
+
+}
+
+static bt_hrp_collector_s *_bt_hrp_collector_find(const char *remote_address)
+{
+ GSList *l;
+
+ for (l = hrp_collector_list; l; l = g_slist_next(l)) {
+
+ if ((l == NULL) || (l->data == NULL) ||
+ (((bt_hrp_collector_s *)l->data)->remote_address == NULL)) {
+ BT_ERR("_bt_hrp_collector_find Error Parameter are NULL..\n");
+ continue;
+ } else if (!g_ascii_strcasecmp(
+ ((bt_hrp_collector_s *)l->data)->remote_address, remote_address)) {
+ return ((bt_hrp_collector_s *)l->data);
+ }
+ }
+ return NULL;
+}
+
+static void __bt_hrp_reset_collector_data(bt_hrp_collector_s *collector)
+{
+
+ g_free((collector)->remote_address);
+ (collector)->remote_address = NULL;
+
+ (collector)->connected = false;
+
+ (collector)->connection_callback = NULL;
+
+ (collector)->conn_cb_user_data = NULL;
+
+ g_free(collector->hrs_service_handle);
+ collector->hrs_service_handle = NULL;
+
+ collector->cccd_enabled = false;
+}
+
+int bt_hrp_collector_create(const char *remote_address, bt_hrp_collector_h *collector)
+{
+ int error_code = BT_ERROR_NONE;
+ bt_hrp_collector_s *collector_s = NULL;
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address); /* LCOV_EXCL_START */
+
+ if (_bt_hrp_collector_find(remote_address) != NULL)
+ return BT_ERROR_ALREADY_DONE;
+
+ error_code = bt_gatt_client_create(remote_address, collector);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ return error_code;
+ }
+
+ collector_s = g_malloc0(sizeof(*collector_s));
+ if (collector_s == NULL) {
+ error_code = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ return error_code;
+ }
+
+ __bt_hrp_reset_collector_data(collector_s);
+
+ collector_s->remote_address = g_strdup(remote_address);
+ if (collector_s->remote_address == NULL) {
+ g_free(collector_s);
+ error_code = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
+ return error_code;
+ }
+
+ hrp_collector_list = g_slist_append(hrp_collector_list, collector_s);
+ BT_INFO("bt_hrp_collector_create Exit");
+
+ return error_code;
+}
+
+void bt_hrp_collector_destory(bt_hrp_collector_h collector)
+{
+
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+
+ if (collector_s) {
+ BT_DBG("bt_hrp_collector_destory destroy Remote Provider [%s]", collector_s->remote_address);
+ __bt_hrp_reset_collector_data(collector_s);
+
+ hrp_collector_list = g_slist_remove(hrp_collector_list, collector_s);
+ g_free(collector_s);
+ }
+
+}
+
+static void __bt_hrp_le_scan_result_cb(int result,
+ bt_adapter_le_device_scan_result_info_s *info,
+ void *user_data)
+{
+
+ BT_INFO("__bt_hrp_le_scan_result_cb \n");
+ BT_INFO("%s Adv %d Scan resp %d RSSI %d Addr_type %d",
+ info->remote_address, info->adv_data_len,
+ info->scan_data_len, info->rssi,
+ info->address_type);
+
+ if (scan_cb)
+ scan_cb(result, info, user_data);
+
+}
+
+int bt_hrp_collector_set_connection_state_changed_cb(bt_hrp_collector_h collector,
+ bt_hrp_collector_connection_state_changed_cb callback,
+ void *user_data)
+{
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(collector_s);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ if (_bt_hrp_collector_find(collector_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ BT_DBG("Set HRP collectorr Connection State changed callback");
+ /* register the callback */
+ collector_s->connection_callback = callback;
+ collector_s->conn_cb_user_data = user_data;
+
+ return BT_ERROR_NONE;
+}
+
+int bt_hrp_collector_unset_connection_state_changed_cb(bt_hrp_collector_h collector)
+{
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(collector_s);
+
+ if (_bt_hrp_collector_find(collector_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ BT_DBG("Set HRP collectorr Connection State changed callback");
+ /* register the callback */
+ collector_s->connection_callback = NULL;
+ collector_s->conn_cb_user_data = NULL;
+
+ return BT_ERROR_NONE;
+}
+
+int bt_hrp_collector_start_scan(bt_adapter_le_scan_result_cb cb)
+{
+
+ bt_scan_filter_h scan_filter = NULL;
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+
+ scan_cb = cb; //le scan application callback
+ /*ToDo error code handling*/
+ error_code = bt_adapter_le_scan_filter_create(&scan_filter);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("failed with [0x%04x]", error_code);
+
+ error_code = bt_adapter_le_scan_filter_set_service_uuid(scan_filter, HEART_RATE_UUID);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("failed with [0x%04x]", error_code);
+
+ error_code = bt_adapter_le_scan_filter_register(scan_filter);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("failed with [0x%04x]", error_code);
+
+ error_code = bt_adapter_le_start_scan(
+ __bt_hrp_le_scan_result_cb, NULL);
+ BT_ERR("returns %s\n", _bt_convert_error_to_string(error_code));
+
+ error_code = bt_adapter_le_scan_filter_destroy(scan_filter);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("failed with [0x%04x]", error_code);
+
+ return error_code;
+
+}
+
+int bt_hrp_collector_stop_scan()
+{
+ int error_code = BT_ERROR_NONE;
+
+ error_code = bt_adapter_le_stop_scan();
+ BT_ERR("returns %s\n", _bt_convert_error_to_string(error_code));
+
+ scan_cb = NULL;
+
+ return error_code;
+
+}
+
+int bt_hrp_collector_connect(const char *address, bool auto_connect)
+{
+
+ int error_code = BT_ERROR_NONE;
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+
+ error_code = bt_gatt_connect(address, auto_connect);
+
+ 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_hrp_collector_disconnect(const char *address)
+{
+ int error_code = BT_ERROR_NONE;
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ error_code = bt_gatt_disconnect(address);
+
+ 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_hrp_collector_set_notification(bt_hrp_collector_h collector,
+ bt_hrp_collector_heart_rate_value_changed_cb callback,
+ bool isNotify)
+{
+ int error_code = BT_ERROR_NONE;
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+ bt_gatt_h svc = NULL;
+ bt_gatt_h chr = NULL;
+
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(collector_s);
+
+ if (_bt_hrp_collector_find(collector_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+
+ error_code = bt_gatt_client_get_service(collector, HEART_RATE_MEASUREMENT_UUID, &svc);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_client_get_service is failed : %d", error_code);
+ return error_code;
+ }
+
+ error_code = bt_gatt_service_get_characteristic(svc, HEART_RATE_CHARAC_CFG_UUID, &chr);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_service_get_characteristic is failed : %d", error_code);
+ return error_code;
+ }
+
+ collector_s->char_update_cb = callback;
+
+ if (isNotify == true) {
+ error_code = bt_gatt_client_set_characteristic_value_changed_cb(chr, _bt_hrp_collector_characteristic_value_changed_cb, NULL);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("bt_gatt_client_set_characteristic_value_changed_cb is failed : %d", error_code);
+ } else {
+ error_code = bt_gatt_client_unset_characteristic_value_changed_cb(chr);
+ if (error_code != BT_ERROR_NONE)
+ BT_ERR("bt_gatt_client_set_characteristic_value_changed_cb is failed : %d", error_code);
+ }
+
+ return error_code;
+}
+
+bt_body_sensor_location_e bt_hrp_get_body_sensor_location(bt_hrp_collector_h collector,
+ bt_hrp_collector_bsl_read_completed_cb bsl_read_cb)
+{
+ int error_code = BT_ERROR_NONE;
+ bt_gatt_h svc = NULL;
+ bt_gatt_h chr = NULL;
+
+ bt_hrp_collector_s *collector_s = (bt_hrp_collector_s *)collector;
+
+ BT_CHECK_HRC_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(collector_s);
+
+ if (_bt_hrp_collector_find(collector_s->remote_address) == NULL)
+ return BT_ERROR_NOT_INITIALIZED;
+
+ error_code = bt_gatt_client_get_service(collector, HEART_RATE_UUID, &svc);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_client_get_service is failed : %d", error_code);
+ return error_code;
+ }
+
+ error_code = bt_gatt_service_get_characteristic(svc, BODY_SENSOR_LOCATION_UUID, &chr);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_service_get_characteristic is failed : %d", error_code);
+ return error_code;
+ }
+
+ collector_s->bsl_read_cb = bsl_read_cb;
+ collector_s->bsl_char_handle = chr;
+
+ //read bsl char
+ error_code = bt_gatt_client_read_value(chr, _bt_hrp_collector_bsl_read_completed_cb, NULL);
+ if (error_code != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_client_read_value is failed : %d", error_code);
+ return error_code;
+ }
+
+ return error_code;
+}
+
diff --git a/test/bt_unit_test.c b/test/bt_unit_test.c
index 51c4a69..88043bd 100644
--- a/test/bt_unit_test.c
+++ b/test/bt_unit_test.c
@@ -123,6 +123,9 @@ char *tds_act_address;
bt_tds_seeker_h seeker;
bt_otp_client_h otp_client;
+bt_hrp_collector_h collector;
+bool set_notif = true;
+
static unsigned char *hash = NULL;
static unsigned char *randomizer = NULL;
@@ -183,7 +186,9 @@ tc_table_t tc_main[] = {
{"OTP"
, BT_UNIT_TEST_TABLE_OTP},
{"HRS"
- , BT_UNIT_TEST_TABLE_HR_SENSOR},
+ , BT_UNIT_TEST_TABLE_HRP_SENSOR},
+ {"HRC"
+ , BT_UNIT_TEST_TABLE_HRP_COLLECTOR},
{"Initialize All"
, BT_UNIT_TEST_FUNCTION_INITIALIZE_ALL},
{"FINISH"
@@ -1193,6 +1198,30 @@ tc_table_t tc_hr_sensor[] = {
{NULL , 0x0000},
};
+tc_table_t tc_hr_collector[] = {
+ {"BACK"
+ , BT_UNIT_TEST_FUNCTION_BACK},
+ {"[collector]HR collector set notification"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_SET_NOTIFICATION},
+ {"[collector]HR collector start scan"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_START_SCAN},
+ {"[collector]HR collector stop scan"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_STOP_SCAN},
+ {"[collector]HR collector connect"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECT},
+ {"[collector]HR collector disconnect"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DISCONNECT},
+ {"[collector]HR collector create"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CREATE},
+ {"[collector]HR collector destroy"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DESTROY},
+ {"[collector]HR collector connection state callback"
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECTION_STATE_CALLBACK},
+ {"[collector]HR collector read bsl value "
+ , BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_GET_BSL_LOC},
+ {NULL , 0x0000},
+};
+
tc_table_t tc_automated_test[] = {
/* Automated test Functions*/
@@ -1303,9 +1332,12 @@ void tc_usage_print(void)
case BT_UNIT_TEST_TABLE_OTP:
tc_table = tc_otp;
break;
- case BT_UNIT_TEST_TABLE_HR_SENSOR:
+ case BT_UNIT_TEST_TABLE_HRP_SENSOR:
tc_table = tc_hr_sensor;
break;
+ case BT_UNIT_TEST_TABLE_HRP_COLLECTOR:
+ tc_table = tc_hr_collector;
+ break;
case BT_UNIT_TEST_TABLE_MAIN:
__default__:
default:
@@ -2555,6 +2587,20 @@ void __bt_gatt_client_value_changed_cb(bt_gatt_h chr,
return;
}
+void __bt_hrp_heart_rate_value_changed_cb(bt_gatt_h chr,
+ unsigned short hr_value, void *user_data)
+{
+ char *uuid = NULL;
+
+ bt_gatt_get_uuid(chr, &uuid);
+
+ TC_PRT("Value changed for [%s]", uuid);
+ TC_PRT("Value [%d]", hr_value);
+
+ g_free(uuid);
+
+ return;
+}
void __bt_HP_client_cp_req_status_changed_cb(bt_gatt_h chr,
char *value, int len, void *user_data)
@@ -3062,6 +3108,20 @@ static void __bt_tds_seeker_connection_state_changed_cb(int result, const char *
BT_ERR("TDS Connection failed!");
}
+static void __bt_hrp_collector_connection_state_changed_cb(int result, const char *remote_address,
+ bt_hrp_collector_h seeker, bool connected, void *user_data)
+{
+ TC_PRT("Result: %s", __bt_get_error_message(result));
+ if (result == BT_ERROR_NONE) {
+ if (connected)
+ TC_PRT("HRP Collector connected(address = %s)", remote_address);
+ else
+ TC_PRT("HRP Collector Disconnected (address = %s)", remote_address);
+ } else
+ BT_ERR("HRP Collection Connection failed!");
+}
+
+
static void __bt_tds_seeker_complete_transport_data_cb(int result, const char *remote_address,
bt_tds_transport_block_list_s *info, void *user_data)
{
@@ -3216,6 +3276,26 @@ static void __bt_adapter_hrp_sensor_adv_state_cb(int result,
"started" : "stopped", adv_state);
}
+void __bt_gatt_client_read_request_completed_cb(int result,
+ bt_gatt_h request_handle, void *user_data)
+{
+ TC_PRT("[HR]Result : %d", result);
+}
+
+void __bt_gatt_client_write_request_completed_cb(int result,
+ bt_gatt_h request_handle, void *user_data)
+{
+ TC_PRT("[HR]Result : %d", result);
+}
+void _bt_hrp_collector_bsl_read_completed_cb(int result,
+ bt_hrp_collector_h request_handle, bt_body_sensor_location_e location, void *user_data)
+{
+ TC_PRT("[HR]Result : %d", result);
+ TC_PRT("[HR]request_handle : %p", request_handle);
+ TC_PRT("[HR]location [%d]", location);
+
+}
+
static void __bt_initialize_all(void)
{
int ret;
@@ -9485,7 +9565,7 @@ int test_input_callback(void *data)
}
break;
}
- case BT_UNIT_TEST_TABLE_HR_SENSOR: {
+ case BT_UNIT_TEST_TABLE_HRP_SENSOR: {
switch (test_id) {
case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_HR_VALUE: {
TC_PRT("HR SENSOR SET HR VALUE\n");
@@ -9552,6 +9632,81 @@ int test_input_callback(void *data)
}
break;
}
+ case BT_UNIT_TEST_TABLE_HRP_COLLECTOR: {
+ switch (test_id) {
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECTION_STATE_CALLBACK: {
+ TC_PRT("HR COLLECTOR CONNECTION STATE CALLBACK\n");
+ if (collector) {
+ ret = bt_hrp_collector_set_connection_state_changed_cb(collector,
+ __bt_hrp_collector_connection_state_changed_cb, NULL);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_SET_NOTIFICATION: {
+ TC_PRT("HR COLLECTOR SET NOTIFICATION\n");
+ if (set_notif == true) {
+ set_notif = false;
+ ret = bt_hrp_collector_set_notification(collector,
+ __bt_hrp_heart_rate_value_changed_cb, true);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ } else {
+ set_notif = true;
+ ret = bt_hrp_collector_set_notification(collector,
+ __bt_hrp_heart_rate_value_changed_cb, false);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CREATE: {
+ TC_PRT("HR COLLECTOR CREATE\n");
+ ret = bt_hrp_collector_create(remote_addr, &collector);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_START_SCAN: {
+ TC_PRT("HR COLLECTOR START SCAN\n");
+ ret = bt_hrp_collector_start_scan(__bt_adapter_le_scan_result_cb);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_STOP_SCAN: {
+ TC_PRT("HR COLLECTOR STOP SCAN\n");
+ ret = bt_hrp_collector_stop_scan();
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECT: {
+ TC_PRT("HR COLLECTOR CONNECT\n");
+ ret = bt_hrp_collector_connect(remote_addr, true);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DISCONNECT: {
+ TC_PRT("HR COLLECTOR DISCONNECT\n");
+ ret = bt_hrp_collector_disconnect(remote_addr);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_GET_BSL_LOC: {
+ TC_PRT("HR COLLECTOR GET BSL LOCATION\n");
+ if (collector) {
+ ret = bt_hrp_get_body_sensor_location(collector, _bt_hrp_collector_bsl_read_completed_cb);
+ TC_PRT("returns %s\n", __bt_get_error_message(ret));
+ }
+ break;
+ }
+ case BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DESTROY: {
+ TC_PRT("HR COLLECTOR DESTROY\n");
+ bt_hrp_collector_destory(collector);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+
case BT_UNIT_TEST_TABLE_ETC: {
static unsigned int delay = 0;
bt_onoff_cnt = 0;
diff --git a/test/bt_unit_test.h b/test/bt_unit_test.h
index bfdb286..d37b39c 100644
--- a/test/bt_unit_test.h
+++ b/test/bt_unit_test.h
@@ -54,7 +54,8 @@ typedef enum {
BT_UNIT_TEST_TABLE_TDS_PROVIDER,
BT_UNIT_TEST_TABLE_TDS_SEEKER,
BT_UNIT_TEST_TABLE_OTP,
- BT_UNIT_TEST_TABLE_HR_SENSOR,
+ BT_UNIT_TEST_TABLE_HRP_SENSOR,
+ BT_UNIT_TEST_TABLE_HRP_COLLECTOR,
BT_UNIT_TEST_TABLE_FINISH = 0xFF,
} bt_unit_test_table_e;
@@ -529,7 +530,16 @@ typedef enum {
BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIFY,
BT_UNIT_TEST_FUNCTION_HR_SENSOR_NOTIFY,
BT_UNIT_TEST_FUNCTION_HR_SENSOR_DESTORY,
-
+ /*HR-Collector*/
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_SET_NOTIFICATION = 1,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_START_SCAN,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_STOP_SCAN,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECT,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DISCONNECT,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CREATE,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_DESTROY,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_CONNECTION_STATE_CALLBACK,
+ BT_UNIT_TEST_FUNCTION_HR_COLLECTOR_GET_BSL_LOC,
BT_UNIT_TEST_FUNCTION_ACTIVATE_FLAG_TO_SET_PARAMETERS = 0XFF,
} bt_unit_test_function_e;