BLE Heart Rate Profile - Sensor Implementation 11/185811/20
authorAbhishek Chandra <abhishek.ch@samsung.com>
Thu, 2 Aug 2018 12:38:45 +0000 (18:08 +0530)
committerAbhishek Chandra <abhishek.ch@samsung.com>
Tue, 28 Aug 2018 11:56:31 +0000 (11:56 +0000)
BLE heartrate profile sensor implementation in
bluetooth is added ,following CAPI are added :
 - bt_hrp_set_heartrate_value
 - bt_hrp_set_location_value
 - bt_hrp_set_energy_value
 - bt_hrp_set_rr_interval
 - bt_hrp_set_contact_value
 - bt_hrp_set_device_manufacturer_name
 - bt_hrp_set_interval
 - bt_hrp_set_sensor_notification_state_change_cb
 - bt_hrp_set_sensor_send_notification_state_changed_cb
 - bt_hrp_set_sensor_read_value_cb
 - bt_hrp_set_sensor_write_value_cb
 - bt_hrp_sensor_create
 - bt_hrp_sensor_start
 - bt_hrp_sensor_stop
 - bt_hrp_sensor_update_heartrate_value
 - bt_hrp_sensor_destroy

Change-Id: Ia1cc6de29f147ba3b2827c5b6cd0bf3334392e60
Signed-off-by: Abhishek Chandra <abhishek.ch@samsung.com>
CMakeLists.txt
include/bluetooth_internal.h
include/bluetooth_private.h
include/bluetooth_type.h
include/bluetooth_type_internal.h
src/bluetooth-common.c
src/bluetooth-hrp.c [new file with mode: 0644]
test/bt_unit_test.c
test/bt_unit_test.h

index c6d321931e1ad9494846a709fe317dae22f63a80..7605bab478070152a9955f1d35b3edd065c4a287 100644 (file)
@@ -50,6 +50,7 @@ src/bluetooth-dpm.c
 src/bluetooth-proximity.c
 src/bluetooth-tds.c
 src/bluetooth-otp.c
+src/bluetooth-hrp.c
 )
 
 LIST(APPEND SOURCES src/bluetooth-proximity.c)
index 5b1383c185e39dc9603480a4c18452312f43dac1..67c05ba7470fc6f905ec7c04ba2aab9a4d64c373 100644 (file)
@@ -4250,6 +4250,90 @@ int bt_otp_client_execute_object(bt_otp_client_h otp_client,
 int bt_otp_client_delete_object(bt_otp_client_h otp_client,
                                                        bt_otp_client_object_delete_cb callback,
                                                        void *user_data);
+
+//======================================================================================
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set initial heart rate value , before creating sensor.
+ */
+int bt_hrp_sensor_set_heartrate_value(int heartrate);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set initial Location value , before creating sensor.
+ */
+int bt_hrp_sensor_set_location_value(bt_body_sensor_location_e location);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set initial energy value (Value Range : 0-9) , before creating sensor.
+ */
+int bt_hrp_sensor_set_energy_value(int energy_value);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set initial rr interval value (Value range : 0-8 If EE is supported,
+ * 0-9 if EE not supported) before creating sensor.
+ */
+int bt_hrp_sensor_set_rr_interval(int interval);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set initial contact value , wearable in contact with
+ * user or user has removed it, before creating sensor.
+ */
+int bt_hrp_sensor_set_contact_value(bool enable);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set manufacturer name , before creating sensor.
+ */
+int bt_hrp_sensor_set_device_manufacturer_name(char *manuf_name);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to set Notification callback, before creating sensor.
+ */
+int bt_hrp_sensor_set_sensor_notification_state_change_cb(
+                               bt_gatt_server_characteristic_notification_state_changed_cb     callback, void *user_data);
+
+/**
+ * @internal
+ * @brief HRP Sensor API for creating sensor and services.
+ */
+
+int bt_hrp_sensor_create(void);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to start advertising .
+ */
+
+int bt_hrp_sensor_start(bt_hrp_sensor_advertising_state_changed_cb cb);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to stop advertising .
+ */
+
+int bt_hrp_sensor_stop(void);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to Notify Heartrate value.
+ */
+
+int bt_hrp_sensor_update_heartrate_value(int heartrate);
+
+/**
+ * @internal
+ * @brief HRP Sensor API to destory heart rate sensor .
+ */
+
+int bt_hrp_sensor_destroy();
+
+
 /**
  * @}
  */
index 9fa661b230484a3d93fdd4a1871868e3ef075164..4fadc08d7c785e3fa57fb75a5ef804976ed4fecb 100644 (file)
@@ -586,6 +586,8 @@ typedef void (*bt_adapter_passkey_notification_cb)(const char *remote_address, c
 #define BT_FEATURE_OOB "tizen.org/feature/network.bluetooth.oob"
 #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_CHECK_SUPPORTED_FEATURE(feature_name) \
 do     { \
@@ -927,6 +929,13 @@ int _bt_proximity_connection_set_state_changed(int result, const char *remote_ad
  */
 void _bt_tds_update_seeker_connection_state_changed(int result, const char *remote_address, bool connected);
 
+/**
+ * @internal
+ * @brief Send GATT connection state changed status with remote HRP collector.
+ */
+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.
index 537472be9132c08b02c344f44ae0ff9a7af3ba2c..8f037d5da32de9330cd51d893de109fdb69f3419 100644 (file)
@@ -1708,6 +1708,21 @@ 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.
+ *
+ * @details This callback is called when the connection state is changed.
+ * When you called bt_gatt_connect() or bt_gatt_disconnect(), this callback is also called with error result even though these functions fail.
+ *
+ * @since_tizen 4.0
+ * @param[in] result The result of changing the connection state.
+ * @param[in] connected The state to be changed, true means connected state, Otherwise, false.
+ * @param[in] remote_address The remote_address
+ * @param[in] user_data The user data passed from the callback registration function.
+ *
+ */
+typedef void (*bt_hrp_connection_state_changed_cb)(int result, bool connected, const char *remote_address);
 
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_CLIENT_MODULE
@@ -1822,6 +1837,26 @@ typedef void (*bt_gatt_server_read_value_requested_cb) (const char *remote_addre
 typedef void (*bt_gatt_server_characteristic_notification_state_changed_cb) (bool notify,
                        bt_gatt_server_h server, bt_gatt_h gatt_handle, void *user_data);
 
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
+ * @brief  Called when the remote device enables or disables the Notification/Indication for particular characteristics for HRP.
+ *
+ * @details By using this callback function, server can know notification state.
+ *
+ * @since_tizen 3.0
+ * @remarks The @a server must not be freed by application.
+ * @remarks The @a gatt_handle must not be freed by application.
+ *
+ * @param[in] notify Indicates whether the Notification/Indication is enabled or not
+ * @param[in] server The GATT server handle
+ * @param[in] gatt_handle The characteristic's GATT handle to be read
+ * @param[in] user_data The user data passed from the registration function
+ *
+ */
+typedef void (*bt_hrp_sensor_characteristic_notification_state_changed_cb) (bool notify,
+                                               bt_gatt_server_h server, bt_gatt_h gatt_handle, void *user_data);
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
  * @brief  Called when the sending notification / indication is done.
index babfb95c68ea7c7458802e35b3f9e397539504b5..6f3c27e19103609cb9bdb9ff5eaef84ed53219b9 100644 (file)
@@ -1093,6 +1093,38 @@ typedef void (*bt_otp_client_object_delete_cb)
  * @}
  */
 
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE
+ * @brief  Enumerations of the Bluetooth advertising state for HRP.
+ * @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif
+ */
+typedef enum {
+       BT_HRP_SENSOR_ADVERTISING_STOPPED = 0x00, /**< Bluetooth advertising is stopped */
+       BT_HRP_SENSOR_ADVERTISING_STARTED, /**< Bluetooth advertising is started */
+} bt_hrp_sensor_advertising_state_e;
+
+/**
+ * @internal tizen 4.0
+ * @brief HRP Sensor Advertisement state change callback
+ */
+
+typedef void (*bt_hrp_sensor_advertising_state_changed_cb)(int result,
+               bt_hrp_sensor_advertising_state_e adv_state, void *user_data);
+
+
+/* Body Sensor Enumeration
+*/
+typedef enum {
+       BT_BSL_NOTSUPPORTED = -1,
+       BT_BSL_OTHER = 0,
+       BT_BSL_CHEST,
+       BT_BSL_WRIST,
+       BT_BSL_FINGER,
+       BT_BSL_HAND,
+       BT_BSL_EARLOBE,
+       BT_BSL_FOOT,
+} bt_body_sensor_location_e;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 9b5110b5604ab5fce713250ac7da3f879d034b8c..5679d2fe4ef85f9cf6cbeb455dde7ee1350d04d0 100644 (file)
@@ -2062,6 +2062,10 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                if (cb)
                        cb(_bt_get_error_code(param->result), TRUE, device_addr,
                                bt_event_slot_container[event_index].user_data);
+
+               /*HRP Server*/
+               __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, TRUE);
+
                g_free(device_addr);
                device_addr = NULL;
                break;
@@ -2076,6 +2080,10 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                if (cb)
                        cb(_bt_get_error_code(param->result), FALSE, device_addr,
                                bt_event_slot_container[event_index].user_data);
+
+               /*HRP Server*/
+               __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, FALSE);
+
                g_free(device_addr);
                device_addr = NULL;
                break;
@@ -2166,6 +2174,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                /* OTP Client */
                _bt_otp_client_connection_state_changed(param->result, device_addr, TRUE);
 
+               /*HRP Client*/
+               __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, TRUE);
+
                if (device_addr != NULL)
                        free(device_addr);
                device_addr = NULL;
@@ -2197,6 +2208,9 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                /* OTP Client */
                _bt_otp_client_connection_state_changed(param->result, device_addr, FALSE);
 
+               /*HRP Client*/
+               __bt_hrp_le_connection_state_changed_cb(param->result, device_addr, FALSE);
+
                if (device_addr != NULL)
                        free(device_addr);
                device_addr = NULL;
diff --git a/src/bluetooth-hrp.c b/src/bluetooth-hrp.c
new file mode 100644 (file)
index 0000000..45eb899
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Contact: Abhishek Chandra (abhishek.ch@samsung.com)
+ *
+ * Copyright (c) 2018-2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <bluetooth-api.h>
+
+#include "bluetooth.h"
+#include "bluetooth_private.h"
+#include "bluetooth_internal.h"
+
+
+#define BT_CHECK_HRS_SUPPORT() \
+{ \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
+       BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_HRS); \
+}
+
+/*======================================================================================================
+       Heart Rate Server - Structures
+========================================================================================================*/
+#define HEART_RATE_UUID                                        "180d"
+#define HEART_RATE_MEASUREMENT_UUID            "2a37"
+#define BODY_SENSOR_LOCATION_UUID              "2a38"
+#define HEART_RATE_CONTROL_POINT_UUID  "2a39"
+#define DEVICE_INFORMATION_UUID                        "180a"
+
+#define HEART_RATE_CHARAC_CFG_UUID                                             "2902"
+#define DEVICE_INFO_CHARAC_MANUFACTURER_NAME_STRING            "2A29"
+#define TODO 0
+//Connected Collector List
+typedef struct {
+       char *remote_address;
+       bool isconnected;
+} bt_hrp_collector_notify_info_s;
+
+//Server Info Local Structure
+typedef struct bt_hrp_server_info_s {
+       //fill with Setter API's
+       bool is_notify_cb_set;
+       bool is_hr_value_init;
+       int hr_value;
+       bool is_energy_supported;
+       int energy_value;
+       bool is_in_contact;
+       bool is_rr_interval_set;
+       int rr_interval;
+       bool is_manuf_name_set;
+       char *manufname;
+       bool is_bsl_set;
+       bt_gatt_server_h hrp_sensor;                                                            //Server Created only once
+       bt_gatt_h hrp_service;                                                                          //heart rate service
+       bt_gatt_h dis_service;                                                                          //device information service
+       bt_gatt_h hrs_characteristic;                                                           // heart rate char
+       bt_gatt_h dis_characteristic;                                                           // device info char
+       bt_gatt_h hrs_descriptor;                                                                       // hrs cccd
+       bt_gatt_h bsl_characteristic;                                                           // body sensor location
+       bt_advertiser_h advertiser;
+       bt_hrp_sensor_advertising_state_changed_cb adv_app_cb;          //application callback for updating state changes
+       bt_gatt_server_characteristic_notification_state_changed_cb notif_app_cb; //application callback for updating notification
+       bt_body_sensor_location_e body_sensor_location;                                                 //body sensor location
+       bool cccd_enabled;
+       GSList *hrs_collector_connected_list;                                           //connected collector list , to be updated when read or write cccd request comes from client
+} bt_hrp_server_info_s;
+
+static guint adv_timer_id;
+GSList *sensor_list;
+static bt_hrp_server_info_s hrp_server_info_s;
+
+/*======================================================================================================
+       Heart Rate Server - Utility
+========================================================================================================*/
+
+/*Internal Functions*/
+static void __bt_hrp_sensor_read_value_requested_cb(
+       const char *remote_address, int request_id,
+       bt_gatt_server_h server, bt_gatt_h gatt_handle,
+       int offset, void *user_data)
+{
+
+       BT_INFO("[HR] __bt_gatt_server_read_value_requested_cb");
+       BT_INFO("[HR] remote_address %s", remote_address);
+       BT_INFO("[HR] req_id %d", request_id);
+       BT_INFO("[HR] server %s", (char *)server);
+       BT_INFO("[HR] gatt_handle %s", (char *)gatt_handle);
+       BT_INFO("[HR] Offset %d", offset);
+
+#if TODO
+       else {
+               /* Send Cached response*/
+               bt_gatt_server_send_response(request_id,
+                       BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ, offset,
+                       resp_status, char_value_1, 3 - offset);
+       }
+#endif
+
+
+}
+
+
+static void __bt_hrp_sensor_write_value_requested_cb(const char *remote_address,
+                               int request_id, bt_gatt_server_h server,
+                               bt_gatt_h gatt_handle, bool response_needed, int offset,
+                               const char *value, int len, void *user_data)
+{
+
+       BT_INFO("[HR] __bt_gatt_server_read_value_requested_cb");
+       BT_INFO("[HR] remote_address %s", remote_address);
+       BT_INFO("[HR] req_id %d", request_id);
+       BT_INFO("[HR] server %s", (char *)server);
+       BT_INFO("[HR] gatt_handle %s", (char *)gatt_handle);
+       BT_INFO("[HR] Offset %d", offset);
+
+#if TODO
+       else {
+               /* Send Cached response*/
+               bt_gatt_server_send_response(request_id,
+                       BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE, offset,
+                       resp_status, char_value_1, 3 - offset);
+       }
+#endif
+}
+
+static void __bt_hrp_notification_send_cb(int result,
+       const char *remote_address, bt_gatt_server_h server,
+       bt_gatt_h characteristic, bool completed, void *user_data)
+{
+       BT_INFO("result [%s]", _bt_convert_error_to_string(result));
+       BT_INFO("remote_address : %s", remote_address);
+       BT_INFO("completed : %d", completed);
+       BT_INFO("characteristic : %p", characteristic);
+
+}
+
+static void __bt_hrp_reduced_interval_adv_state_changed_cb(int result,
+       bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state,
+       void *user_data)
+{
+       BT_INFO("[HR]Result : %d", result);
+       BT_INFO("[HR]Advertiser : %p", advertiser);
+       BT_INFO("[HR]Advertising %s [%d]",
+               adv_state == BT_ADAPTER_LE_ADVERTISING_STARTED ?
+               "started" : "stopped", adv_state);
+
+       if (hrp_server_info_s.adv_app_cb && adv_state == BT_ADAPTER_LE_ADVERTISING_STOPPED)
+               hrp_server_info_s.adv_app_cb(result, adv_state, user_data);
+}
+
+static gboolean __hrp_timeout(gpointer user_data)
+{
+       int error_code = BT_ERROR_NONE;
+
+       BT_INFO("__hrp_timeout Timeout !!!\n");
+       adv_timer_id = -1;
+       error_code = bt_adapter_le_stop_advertising(hrp_server_info_s.advertiser);
+       if (error_code != BT_ERROR_NONE)
+               BT_ERR("[HR]add scan response data [0x%04x]", error_code);
+
+       return FALSE;
+}
+
+static void __bt_hrp_gatt_server_set_char_notification_state_change_cb(bool notify,
+               bt_gatt_server_h server, bt_gatt_h gatt_handle,
+               void *user_data)
+{
+       BT_INFO("[HR]__bt_gatt_server_notification_state_change_cb");
+       BT_INFO("[HR]notify %d", notify);
+       BT_INFO("[HR]server %s", (char *)server);
+       BT_INFO("[HR]gatt_handle %s", (char *)gatt_handle);
+
+       if (hrp_server_info_s.notif_app_cb)
+               hrp_server_info_s.notif_app_cb(notify, server,  gatt_handle, user_data);
+
+}
+
+static void __bt_hrp_fast_interval_adv_state_changed_cb(int result,
+       bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state,
+       void *user_data)
+{
+       BT_INFO("[HR]Result : %d", result);
+       BT_INFO("[HR]Advertiser : %p", advertiser);
+       BT_INFO("[HR]Advertising %s [%d]",
+               adv_state == BT_ADAPTER_LE_ADVERTISING_STARTED ?
+               "started" : "stopped", adv_state);
+
+       if (adv_state == BT_ADAPTER_LE_ADVERTISING_STARTED) {
+               adv_timer_id =
+                       g_timeout_add_seconds(29/*Todo :30 Secs , 29 + time to set mode and restart adv*/,
+                                                       __hrp_timeout, hrp_server_info_s.hrp_sensor);
+       } else { /*Advertisement Stopped*/
+               //cancel timer as User requested to STOP
+               if (adv_timer_id != -1) {
+                       BT_DBG("g_source is removed");
+                       g_source_remove(adv_timer_id);
+                       adv_timer_id = -1;
+               } else { //Changing mode to Low energy as 30seconds are passed
+                       int error_code = bt_adapter_le_set_advertising_mode(hrp_server_info_s.advertiser,
+                                                                                                                       BT_ADAPTER_LE_ADVERTISING_MODE_LOW_ENERGY);
+                       if (error_code != BT_ERROR_NONE)
+                               BT_ERR("[HR]add scan response data [0x%04x]", error_code);
+
+                       error_code = bt_adapter_le_start_advertising_new(hrp_server_info_s.advertiser,
+                                                                                               __bt_hrp_reduced_interval_adv_state_changed_cb, NULL);
+                       if (error_code < BT_ERROR_NONE)
+                               BT_ERR("[HR]failed with [0x%04x]", error_code);
+
+                       return;
+               }
+       }
+       /*todo : Send Start and stop enums*/
+       if (hrp_server_info_s.adv_app_cb)
+               hrp_server_info_s.adv_app_cb(result, adv_state, user_data);
+
+}
+
+static int __bt_hrp_create_primary_service(void)
+{
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+       char hrs_char_value[3] ;
+       char desc_value[2] = {1, 0}; /* Notification enabled ,Indication disabled default*/
+
+       if (hrp_server_info_s.hrp_sensor == NULL)
+               return error_code;
+
+       error_code = bt_gatt_service_create(HEART_RATE_UUID, BT_GATT_SERVICE_TYPE_PRIMARY,
+                                                                                       &hrp_server_info_s.hrp_service);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]__createPrimaryService : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       hrs_char_value[0] = (hrp_server_info_s.hr_value > 255) ? 1 : 0;//Uint-16 and Uint-8
+       hrs_char_value[1] =     hrp_server_info_s.hr_value;     /*Measurement Value*/
+       hrs_char_value[2] =     0;              //??
+
+       BT_INFO("[HR] PRIMARY SERVICE CHAR CREATE\n");
+       error_code = bt_gatt_characteristic_create(HEART_RATE_MEASUREMENT_UUID, BT_GATT_PERMISSION_READ,
+                                                                                               BT_GATT_PROPERTY_NOTIFY, hrs_char_value, sizeof(hrs_char_value),
+                                                                                               &hrp_server_info_s.hrs_characteristic);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_characteristic_create HEART_RATE_MEASUREMENT_UUID : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       BT_INFO("[HR] PRIMARY SERVICE SET READ CB\n");
+
+       error_code = bt_gatt_service_add_characteristic(hrp_server_info_s.hrp_service, hrp_server_info_s.hrs_characteristic);
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_service_add_characteristic : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       BT_INFO("[HR] PRIMARY SERVICE DESCRIPTOR CREATE\n");
+       error_code = bt_gatt_descriptor_create(HEART_RATE_CHARAC_CFG_UUID, BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE,
+                                                                                                       desc_value, sizeof(desc_value), &hrp_server_info_s.hrs_descriptor);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_descriptor_create HEART_RATE_CHARAC_CFG_UUID : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       BT_INFO("[HR] PRIMARY SERVICE ADD DESCRIPTOR\n");
+
+       error_code = bt_gatt_characteristic_add_descriptor(hrp_server_info_s.hrs_characteristic, hrp_server_info_s.hrs_descriptor);
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_characteristic_add_descriptor : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+       error_code = bt_gatt_server_set_read_value_requested_cb(hrp_server_info_s.hrs_descriptor,
+                                       __bt_hrp_sensor_read_value_requested_cb, NULL);
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_server_set_read_value_requested_cb : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       error_code = bt_gatt_server_set_write_value_requested_cb(hrp_server_info_s.hrs_descriptor,
+                                       __bt_hrp_sensor_write_value_requested_cb, NULL);
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_server_set_read_value_requested_cb : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+
+       BT_INFO("[HR] PRIMARY SERVICE BSL\n");
+
+       if (hrp_server_info_s.body_sensor_location != BT_BSL_NOTSUPPORTED) {
+
+               char bs_location = hrp_server_info_s.body_sensor_location;
+
+               error_code = bt_gatt_characteristic_create(BODY_SENSOR_LOCATION_UUID, BT_GATT_PERMISSION_READ, BT_GATT_PROPERTY_READ,
+                                                                                       &bs_location, sizeof(bs_location),
+                                                                                       &hrp_server_info_s.bsl_characteristic);
+                       BT_INFO("[HR] PRIMARY SERVICE BSL SET REQUEST CB\n");
+               if (error_code != BT_ERROR_NONE) {
+                       BT_ERR("[HR]bt_gatt_characteristic_create BODY_SENSOR_LOCATION_UUID : %s\n", _bt_convert_error_to_string(error_code));
+                       return error_code;
+               }
+
+               bt_gatt_server_set_read_value_requested_cb(hrp_server_info_s.bsl_characteristic,
+                       __bt_hrp_sensor_read_value_requested_cb, NULL);
+
+
+               if ((NULL != hrp_server_info_s.hrp_service) && (hrp_server_info_s.bsl_characteristic != NULL)) {
+                       BT_INFO("[HR] PRIMARY SERVICE BSL ADD CHAR CB\n");
+
+                       error_code = bt_gatt_service_add_characteristic(hrp_server_info_s.hrp_service, hrp_server_info_s.bsl_characteristic);
+                       if (error_code != BT_ERROR_NONE) {
+                               BT_ERR("[HR]bt_gatt_service_add_characteristic : %s\n", _bt_convert_error_to_string(error_code));
+                               return error_code;
+                       }
+               }
+
+               BT_INFO("[HR] PRIMARY SERVICE REGISTER SERVICE\n");
+
+               error_code = bt_gatt_server_register_service(hrp_server_info_s.hrp_sensor, hrp_server_info_s.hrp_service);
+               if (error_code != BT_ERROR_NONE) {
+                       BT_ERR("[HR]bt_gatt_server_register_service : %s\n", _bt_convert_error_to_string(error_code));
+                       return error_code;
+               }
+       }
+       BT_INFO("[HR] PRIMARY SERVICE EXIT!!!\n");
+
+       return error_code;
+}
+
+static int __bt_hrp_create_secondary_service(void)
+{
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       if (hrp_server_info_s.hrp_sensor == NULL)
+               return error_code;
+
+       error_code = bt_gatt_service_create(DEVICE_INFORMATION_UUID,
+                                               BT_GATT_SERVICE_TYPE_SECONDARY, &hrp_server_info_s.dis_service);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_service_create : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       error_code = bt_gatt_characteristic_create(DEVICE_INFO_CHARAC_MANUFACTURER_NAME_STRING, BT_GATT_PERMISSION_READ,
+                                                                                               BT_GATT_PROPERTY_READ, hrp_server_info_s.manufname,
+                                                                                               strlen(hrp_server_info_s.manufname), &hrp_server_info_s.dis_characteristic);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_characteristic_create : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       bt_gatt_server_set_read_value_requested_cb(hrp_server_info_s.dis_characteristic,
+                                               __bt_hrp_sensor_read_value_requested_cb, NULL);
+
+       error_code = bt_gatt_service_add_characteristic(hrp_server_info_s.dis_service, hrp_server_info_s.dis_characteristic);
+
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_service_add_characteristic : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       error_code = bt_gatt_server_set_characteristic_notification_state_change_cb
+                                                       (hrp_server_info_s.hrs_characteristic,
+                                                       __bt_hrp_gatt_server_set_char_notification_state_change_cb, NULL);
+
+       if (error_code != BT_ERROR_NONE)
+               BT_ERR("[HR]bt_gatt_server_set_characteristic_notification_state_change_cb : %s\n", _bt_convert_error_to_string(error_code));
+
+       error_code = bt_gatt_server_register_service(hrp_server_info_s.hrp_sensor, hrp_server_info_s.dis_service);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_server_register_service : %s\n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       return error_code;
+}
+
+static int __bt_hrp_sensor_create_service(void)
+{
+
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       if (NULL == hrp_server_info_s.hrp_sensor) {
+               BT_ERR("[bt_hrp_sensor_create_service] Call Create First !!\n");
+               return error_code;
+       }
+
+       BT_INFO("[HR] CREATE SERVICE PRIMARY \n");
+       error_code = __bt_hrp_create_primary_service();
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HR]__bt_hrp_create_primary_service : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       BT_INFO("[HR] CREATE SERVICE SECONDARY \n");
+       error_code = __bt_hrp_create_secondary_service();
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HR]__bt_hrp_create_secondary_service : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+       return error_code;
+}
+
+static void _bt_hrp_sensor_client_info_free(gpointer object)
+{
+       bt_hrp_collector_notify_info_s *client_s = (bt_hrp_collector_notify_info_s *)object;
+       g_free(client_s->remote_address);
+       client_s->isconnected = false;
+}
+
+static void _bt_hrp_sensor_initilize(void)
+{
+       hrp_server_info_s.is_notify_cb_set = false;
+       hrp_server_info_s.hrp_sensor = NULL;
+       hrp_server_info_s.hrp_service = NULL;
+       hrp_server_info_s.dis_service = NULL;
+       hrp_server_info_s.hrs_characteristic = NULL;
+       hrp_server_info_s.dis_characteristic = NULL;
+       hrp_server_info_s.hrs_descriptor = NULL;
+       hrp_server_info_s.advertiser = NULL;
+       hrp_server_info_s.adv_app_cb = NULL;
+       hrp_server_info_s.hrs_collector_connected_list = NULL;
+       hrp_server_info_s.is_in_contact = true;
+
+       hrp_server_info_s.cccd_enabled = true; //by default
+
+       if (hrp_server_info_s.is_hr_value_init == false)
+               hrp_server_info_s.hr_value = 0;
+
+       if (hrp_server_info_s.is_bsl_set == false)
+               hrp_server_info_s.body_sensor_location = BT_BSL_OTHER;
+
+       if (hrp_server_info_s.is_energy_supported == false)
+               hrp_server_info_s.energy_value = 0;
+
+       if (hrp_server_info_s.is_rr_interval_set == false)
+               hrp_server_info_s.rr_interval = 2;              //Fill with some default value
+
+       if (hrp_server_info_s.is_manuf_name_set == false)
+               hrp_server_info_s.manufname = g_strdup("SAMSUNG");
+}
+
+void __bt_hrp_le_connection_state_changed_cb(int result,
+                       const char *remote_address, bool connected)
+{
+
+       BT_INFO("[HR] bt_hrp_le_connection_state_changed_cb Result : %d", result);
+       BT_INFO("[HR]IsConnected : %d", connected);
+       BT_INFO("[HR]Remote Address : %s", remote_address);
+       bool isappend = true;
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       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;
+                       }
+               }
+       }
+
+       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);
+       }
+
+       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;
+       }
+
+}
+
+/*Application Interfaces*/
+
+int bt_hrp_sensor_set_heartrate_value(int heartrate)
+{
+
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       if (heartrate < 0)
+               return BT_ERROR_INVALID_PARAMETER;
+
+       hrp_server_info_s.hr_value = heartrate;
+       hrp_server_info_s.is_hr_value_init = true;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_hrp_sensor_set_location_value(bt_body_sensor_location_e location)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       if (location == BT_BSL_NOTSUPPORTED)
+               return BT_ERROR_INVALID_PARAMETER;
+
+
+       hrp_server_info_s.body_sensor_location = location;
+       hrp_server_info_s.is_bsl_set = true;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_hrp_sensor_set_energy_value(int energy_value)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       if ((energy_value < 0) || (energy_value > 9))
+               return BT_ERROR_INVALID_PARAMETER;
+
+       hrp_server_info_s.energy_value = energy_value;
+       hrp_server_info_s.is_energy_supported = true;
+
+       return BT_ERROR_NOT_SUPPORTED;
+
+}
+
+int bt_hrp_sensor_set_contact_value(bool enable)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       hrp_server_info_s.is_in_contact = enable;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_hrp_sensor_set_rr_interval(int interval)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       if ((interval < 0) || (interval > 9)) //Todo : Check for EE support
+               return BT_ERROR_INVALID_PARAMETER;
+
+       hrp_server_info_s.rr_interval = interval;
+       hrp_server_info_s.is_rr_interval_set = true;
+
+       return BT_ERROR_NOT_SUPPORTED;
+}
+
+int bt_hrp_sensor_set_device_manufacturer_name(char *manuf_name)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(manuf_name);
+
+       if (hrp_server_info_s.manufname)
+               g_free(hrp_server_info_s.manufname);
+
+       //Todo : Parsing Logic for manufacturer name .
+
+       hrp_server_info_s.manufname = g_strdup(manuf_name);
+       hrp_server_info_s.is_manuf_name_set = true;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_hrp_sensor_set_sensor_notification_state_change_cb(
+                               bt_gatt_server_characteristic_notification_state_changed_cb     callback, void *user_data)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+
+       hrp_server_info_s.notif_app_cb = callback;
+
+       return BT_ERROR_NONE;
+}
+
+int bt_hrp_sensor_create(void)
+{
+       int error_code = BT_ERROR_NONE;
+       bool is_in_use = false;
+
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       error_code = bt_adapter_is_service_used(HEART_RATE_UUID, &is_in_use);
+
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HRP- Sensor Create] bt_adapter_is_service_used : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       if (true == is_in_use) {
+               BT_ERR("[HRP- Sensor Create] bt_adapter_is_service_used Server Already Created !!");
+               return BT_ERROR_ALREADY_DONE;
+       }
+
+       _bt_hrp_sensor_initilize();
+
+       error_code = bt_gatt_server_initialize();
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HRP- Sensor Create] Gatt Server Initialize error code : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       error_code = bt_gatt_server_create(&hrp_server_info_s.hrp_sensor);
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HRP- Sensor Create] bt_gatt_server_create : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       error_code = __bt_hrp_sensor_create_service();
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HRP- Sensor Create] __bt_hrp_sensor_create_service : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+       return error_code;
+}
+
+int bt_hrp_sensor_start(bt_hrp_sensor_advertising_state_changed_cb cb)
+{
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(cb);
+
+       if (NULL == hrp_server_info_s.hrp_sensor) {
+               BT_ERR("[HR Sensor START] Call Create First !!\n");
+               return error_code;
+       }
+
+       BT_INFO("[HR] START GATT SERVER \n");
+       error_code = bt_gatt_server_start();
+       if (error_code != BT_ERROR_NONE)        {
+               BT_ERR("[HR]bt_gatt_server_start : %s \n", _bt_convert_error_to_string(error_code));
+               return error_code;
+       }
+
+       if (hrp_server_info_s.advertiser == NULL) {
+
+               error_code = bt_adapter_le_create_advertiser(&hrp_server_info_s.advertiser);
+               if (error_code != BT_ERROR_NONE)        {
+                       BT_ERR("[HR Sensor START] bt_adapter_le_create_advertiser : %s \n", _bt_convert_error_to_string(error_code));
+                       return error_code;
+               }
+       } else {
+
+               error_code = bt_adapter_le_clear_advertising_data(hrp_server_info_s.advertiser,
+                       BT_ADAPTER_LE_PACKET_ADVERTISING);
+               if (error_code != BT_ERROR_NONE) {
+                       BT_ERR("[HR Sensor START] clear advertising data [0x%04x]", error_code);
+                       return error_code;
+               }
+               error_code = bt_adapter_le_clear_advertising_data(hrp_server_info_s.advertiser,
+                       BT_ADAPTER_LE_PACKET_SCAN_RESPONSE);
+               if (error_code != BT_ERROR_NONE) {
+                       BT_ERR("[HR Sensor START] clear scan response data [0x%04x]", error_code);
+                       return error_code;
+               }
+       }
+
+       error_code = bt_adapter_le_add_advertising_service_solicitation_uuid(hrp_server_info_s.advertiser,
+                       BT_ADAPTER_LE_PACKET_ADVERTISING, HEART_RATE_UUID);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR Sensor START] add service_solicitation_uuid [0x%04x]", error_code);
+               return error_code;
+       }
+
+       error_code = bt_adapter_le_set_advertising_device_name(hrp_server_info_s.advertiser,
+               BT_ADAPTER_LE_PACKET_ADVERTISING, true);
+
+       if (error_code != BT_ERROR_NONE)
+               BT_ERR("[HR Sensor START] set device name [0x%04x]", error_code);
+
+
+               /*interval = 150*/
+       error_code = bt_adapter_le_set_advertising_mode(hrp_server_info_s.advertiser, BT_ADAPTER_LE_ADVERTISING_MODE_LOW_LATENCY);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR Sensor START] add scan response data [0x%04x]", error_code);
+               return error_code;
+       }
+
+       hrp_server_info_s.adv_app_cb = cb;
+
+       error_code = bt_adapter_le_set_advertising_device_name(hrp_server_info_s.advertiser,
+               BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
+
+       if (error_code != BT_ERROR_NONE)
+               BT_ERR("[HR Sensor START] set device name [0x%04x]", error_code);
+
+       error_code = bt_adapter_le_start_advertising_new(hrp_server_info_s.advertiser,
+                                                                               __bt_hrp_fast_interval_adv_state_changed_cb, NULL);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR Sensor START] failed with [0x%04x]", error_code);
+               return error_code;
+       }
+
+       BT_INFO("[HR Sensor START] bt_hrp_sensor_start exit\n");
+       return error_code;
+
+}
+
+int bt_hrp_sensor_stop()
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       error_code = bt_adapter_le_stop_advertising(hrp_server_info_s.advertiser);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_hrp_sensor_stop failed with [0x%04x]", error_code);
+               return error_code;
+       }
+
+       return error_code;
+
+}
+
+int bt_hrp_sensor_update_heartrate_value(int heartrate)
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+
+       if (NULL == hrp_server_info_s.hrp_sensor) {
+               BT_ERR("[HR Sensor START] Call Create First !!\n");
+               return error_code;
+       }
+
+       if (hrp_server_info_s.cccd_enabled) {
+               error_code = bt_gatt_set_int_value(hrp_server_info_s.hrs_characteristic,
+                               BT_DATA_TYPE_UINT16, heartrate, 1);
+               if (error_code != BT_ERROR_NONE) {
+                       BT_ERR("[HR]bt_gatt_set_int_value failed with [0x%04x]", error_code);
+                       return error_code;
+               }
+       }
+
+       return error_code;
+
+}
+
+int bt_hrp_sensor_destroy()
+{
+       BT_CHECK_HRS_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+
+       BT_INFO("[HR]bt_gatt_server_destroy GATT Destroy\n");
+
+       int error_code = BT_ERROR_NOT_INITIALIZED;
+       bt_gatt_destroy(hrp_server_info_s.hrs_descriptor);
+       bt_gatt_destroy(hrp_server_info_s.hrs_characteristic);
+       bt_gatt_destroy(hrp_server_info_s.dis_characteristic);
+       bt_gatt_destroy(hrp_server_info_s.bsl_characteristic);
+       bt_gatt_destroy(hrp_server_info_s.dis_service);
+       bt_gatt_destroy(hrp_server_info_s.hrp_service);
+
+       BT_INFO("[HR]bt_gatt_server_destroy Advertiser Destroy\n");
+
+       error_code = bt_adapter_le_destroy_advertiser(hrp_server_info_s.advertiser);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_hrp_sensor_stop failed with [0x%04x]", error_code);
+               return error_code;
+       }
+
+       BT_INFO("[HR]bt_gatt_server_destroy Server Destroy\n");
+
+       error_code = bt_gatt_server_destroy(hrp_server_info_s.hrp_sensor);
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_server_destroy failed with [0x%04x]", error_code);
+               return error_code;
+       }
+
+       BT_INFO("[HR]bt_gatt_server_destroy Server Deinit\n");
+
+       error_code = bt_gatt_server_deinitialize();
+       if (error_code != BT_ERROR_NONE) {
+               BT_ERR("[HR]bt_gatt_server_destroy failed with [0x%04x]", error_code);
+               return error_code;
+       }
+
+       hrp_server_info_s.is_notify_cb_set = false;
+       hrp_server_info_s.is_hr_value_init = false;
+       hrp_server_info_s.hr_value = 0;
+       hrp_server_info_s.is_energy_supported = false;
+       hrp_server_info_s.energy_value = 0;
+       hrp_server_info_s.is_in_contact = false;
+       hrp_server_info_s.is_rr_interval_set = false;
+       hrp_server_info_s.rr_interval = 0;
+       hrp_server_info_s.is_manuf_name_set = false;
+       hrp_server_info_s.is_bsl_set = false;
+       hrp_server_info_s.hrp_service = NULL;
+       hrp_server_info_s.dis_service = NULL;
+       hrp_server_info_s.bsl_characteristic = NULL;
+       hrp_server_info_s.dis_characteristic = NULL;
+       hrp_server_info_s.hrs_characteristic = NULL;
+       hrp_server_info_s.hrs_descriptor = NULL;
+       hrp_server_info_s.advertiser = NULL;
+
+       if (hrp_server_info_s.manufname)
+               g_free(hrp_server_info_s.manufname);
+
+       hrp_server_info_s.adv_app_cb = NULL;
+       hrp_server_info_s.notif_app_cb = NULL;
+       hrp_server_info_s.body_sensor_location = BT_BSL_NOTSUPPORTED;
+       hrp_server_info_s.cccd_enabled = false;
+
+       g_slist_free_full(hrp_server_info_s.hrs_collector_connected_list, _bt_hrp_sensor_client_info_free);
+
+       hrp_server_info_s.hrs_collector_connected_list = NULL;
+
+       BT_INFO("[HR]bt_gatt_server_destroy Exit\n");
+
+
+       return error_code;
+
+}
+
index 7547b95c8029505df52f0d927861af3f11d0e661..51c4a69ac3e19aa870386585b787c5ad7b09523e 100644 (file)
@@ -182,6 +182,8 @@ tc_table_t tc_main[] = {
                , BT_UNIT_TEST_TABLE_TDS_SEEKER},
        {"OTP"
                , BT_UNIT_TEST_TABLE_OTP},
+       {"HRS"
+               , BT_UNIT_TEST_TABLE_HR_SENSOR},
        {"Initialize All"
                , BT_UNIT_TEST_FUNCTION_INITIALIZE_ALL},
        {"FINISH"
@@ -1158,6 +1160,40 @@ tc_table_t tc_otp[] = {
        {NULL                                   , 0x0000},
 };
 
+tc_table_t tc_hr_sensor[] = {
+       /* HR Sensor functions */
+       {"BACK"
+               , BT_UNIT_TEST_FUNCTION_BACK},
+       {"[sensor]Set HeartRate Value"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_HR_VALUE},
+       {"[sensor]Set Location Value"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_LOC_VALUE},
+       {"[sensor]Set Contact Value"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_CONTACT_VALUE},
+       {"[sensor]Set Device Name"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_DEVICE_NAME},
+       {"[sensor]Set Notification Callback"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIF_CB},
+       {"[sensor]Set Read Callback"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_READ_CB},
+       {"[sensor]Set Send Notification Callback"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_SEND_NOTIF_CB},
+       {"HR Sensor Create Instance"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_CREATE},
+       {"HR Sensor Start Advertising"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_START},
+       {"HR Sensor Stop Advertising"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_STOP},
+       {"HR Sensor SET Notify"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIFY},
+       {"HR Sensor Notify"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_NOTIFY},
+       {"HR Sensor Destroy"
+               , BT_UNIT_TEST_FUNCTION_HR_SENSOR_DESTORY},
+       {NULL                                   , 0x0000},
+};
+
+
 tc_table_t tc_automated_test[] = {
        /* Automated test Functions*/
        {"BACK"                                                         , BT_UNIT_TEST_FUNCTION_BACK},
@@ -1267,6 +1303,9 @@ void tc_usage_print(void)
        case BT_UNIT_TEST_TABLE_OTP:
                tc_table = tc_otp;
                break;
+       case BT_UNIT_TEST_TABLE_HR_SENSOR:
+               tc_table = tc_hr_sensor;
+               break;
        case BT_UNIT_TEST_TABLE_MAIN:
 __default__:
        default:
@@ -3167,6 +3206,16 @@ static void __bt_otp_client_object_delete_cb(int result, const char *remote_addr
                BT_ERR("Object[%llu] delete failed!", obj_id);
 }
 
+static void __bt_adapter_hrp_sensor_adv_state_cb(int result,
+               bt_hrp_sensor_advertising_state_e adv_state, void *user_data)
+{
+       TC_PRT("[HR]Result : %d", result);
+       TC_PRT("[HR]Advertiser : %p", advertiser);
+       TC_PRT("[HR]Advertising %s [%d]",
+               adv_state == BT_HRP_SENSOR_ADVERTISING_STARTED ?
+               "started" : "stopped", adv_state);
+}
+
 static void __bt_initialize_all(void)
 {
        int ret;
@@ -9435,6 +9484,73 @@ int test_input_callback(void *data)
                        break;
                }
                break;
+       }
+               case BT_UNIT_TEST_TABLE_HR_SENSOR: {
+               switch (test_id) {
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_HR_VALUE: {
+                       TC_PRT("HR SENSOR SET HR VALUE\n");
+                       int heartrate = 0x38;
+                       bt_hrp_sensor_set_heartrate_value(heartrate);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_LOC_VALUE: {
+                       TC_PRT("HR SENSOR SET LOC VALUE\n");
+                       bt_body_sensor_location_e location = BT_BSL_WRIST;
+                       bt_hrp_sensor_set_location_value(location);
+
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_CONTACT_VALUE: {
+                       TC_PRT("HR SENSOR SET CONTACT VALUE\n");
+                       bool iscontact = true;
+                       bt_hrp_sensor_set_contact_value(iscontact);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_DEVICE_NAME: {
+                       TC_PRT("HR SENSOR SET DEVICE NAME\n");
+                       char *name = g_strdup("SAMSUNG HR");
+                       bt_hrp_sensor_set_device_manufacturer_name(name);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIF_CB: {
+                       TC_PRT("HR SENSOR SET NOTIFICATION CALLBACK\n");
+                       bt_hrp_sensor_set_sensor_notification_state_change_cb(
+                                       __bt_gatt_server_notification_state_change_cb, NULL);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_CREATE: {
+                       TC_PRT("HR SENSOR CREATE\n");
+                       ret  = bt_hrp_sensor_create();
+                       TC_PRT("returns %s\n", __bt_get_error_message(ret));
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_START: {
+                       TC_PRT("HR SENSOR START\n");
+                       ret = bt_hrp_sensor_start(__bt_adapter_hrp_sensor_adv_state_cb);
+                       TC_PRT("returns %s\n", __bt_get_error_message(ret));
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_STOP: {
+                       TC_PRT("HR SENSOR STOP\n");
+                       ret = bt_hrp_sensor_stop();
+                       TC_PRT("returns %s\n", __bt_get_error_message(ret));
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_NOTIFY: {
+                       TC_PRT("HR SENSOR UPDATE HR value\n");
+                       bt_hrp_sensor_update_heartrate_value(7);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_HR_SENSOR_DESTORY: {
+                       TC_PRT("HR SENSOR DESTROY\n");
+                       ret = bt_hrp_sensor_destroy();
+                       TC_PRT("returns %s\n", __bt_get_error_message(ret));
+                       break;
+               }
+               default:
+                       break;
+               }
+               break;
        }
        case BT_UNIT_TEST_TABLE_ETC: {
                static unsigned int delay = 0;
index f2ec69eae3972db1c5d6faa340c89155162f87b0..bfdb2866b6ecadc339d91e8471231808f9c4fb79 100644 (file)
@@ -54,6 +54,7 @@ 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_FINISH = 0xFF,
 } bt_unit_test_table_e;
 
@@ -514,6 +515,22 @@ typedef enum {
        BT_UNIT_TEST_FUNCTION_OTP_CLIENT_EXECUTE_OBJ,
        BT_UNIT_TEST_FUNCTION_OTP_CLIENT_DELETE_OBJ,
 
+       /*HR-Sensor*/
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_HR_VALUE = 1,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_LOC_VALUE,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_CONTACT_VALUE,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_DEVICE_NAME,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIF_CB,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_READ_CB,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_SEND_NOTIF_CB,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_CREATE,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_START,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_STOP,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_SET_NOTIFY,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_NOTIFY,
+       BT_UNIT_TEST_FUNCTION_HR_SENSOR_DESTORY,
+
+
        BT_UNIT_TEST_FUNCTION_ACTIVATE_FLAG_TO_SET_PARAMETERS = 0XFF,
 } bt_unit_test_function_e;