@@ -119,6 +119,7 @@ static void on_disconnected(struct ble_hrs_client *hrs_client, const ble_evt_t *
119119 hrs_client -> conn_handle = BLE_CONN_HANDLE_INVALID ;
120120 hrs_client -> handles .hrm_cccd_handle = BLE_GATT_HANDLE_INVALID ;
121121 hrs_client -> handles .hrm_handle = BLE_GATT_HANDLE_INVALID ;
122+ hrs_client -> handles .bsl_handle = BLE_GATT_HANDLE_INVALID ;
122123 }
123124}
124125
@@ -128,12 +129,13 @@ void ble_hrs_on_db_disc_evt(struct ble_hrs_client *hrs_client,
128129 __ASSERT (hrs_client , "HRS client instance is NULL" );
129130 __ASSERT (db_discovery_evt , "Discovery event is NULL" );
130131
132+ uint32_t nrf_err ;
131133 const struct ble_gatt_db_char * db_char ;
132134 struct ble_hrs_client_evt hrs_client_evt = {
133135 .evt_type = BLE_HRS_CLIENT_EVT_DISCOVERY_COMPLETE ,
134136 .conn_handle = db_discovery_evt -> conn_handle ,
135137 };
136- struct ble_hrs_handles * handles = & hrs_client -> handles ;
138+ struct ble_hrs_handles * const evt_handles = & hrs_client_evt . discovery_complete . handles ;
137139
138140 /* Check if the Heart Rate Service was discovered. */
139141 if (db_discovery_evt -> evt_type != BLE_DB_DISCOVERY_COMPLETE ||
@@ -142,27 +144,40 @@ void ble_hrs_on_db_disc_evt(struct ble_hrs_client *hrs_client,
142144 return ;
143145 }
144146
145- /* Find the CCCD Handle of the Heart Rate Measurement characteristic . */
147+ /* Iterate discovered characteristics . */
146148 for (uint32_t i = 0 ; i < db_discovery_evt -> discovered_db -> char_count ; i ++ ) {
147149 db_char = & db_discovery_evt -> discovered_db -> characteristics [i ];
148150
149151 if (db_char -> characteristic .uuid .uuid == BLE_UUID_HEART_RATE_MEASUREMENT_CHAR ) {
150- /* Found Heart Rate characteristic. Store CCCD handle and break. */
151- hrs_client_evt .discovery_complete .handles .hrm_cccd_handle =
152- db_char -> cccd_handle ;
153- hrs_client_evt .discovery_complete .handles .hrm_handle =
154- db_char -> characteristic .handle_value ;
155- break ;
152+ /* Found Heart Rate characteristic. Store value and CCCD handle for later
153+ * notification setup.
154+ */
155+ evt_handles -> hrm_cccd_handle = db_char -> cccd_handle ;
156+ evt_handles -> hrm_handle = db_char -> characteristic .handle_value ;
157+
158+ } else if (db_char -> characteristic .uuid .uuid ==
159+ BLE_UUID_BODY_SENSOR_LOCATION_CHAR ) {
160+ /* Found body sensor location characteristic. Store value handle and issue
161+ * a read request. The value will arrive asynchronously in a
162+ * BLE_GATTC_EVT_READ_RSP event.
163+ */
164+ evt_handles -> bsl_handle = db_char -> characteristic .handle_value ;
165+
166+ nrf_err = sd_ble_gattc_read (db_discovery_evt -> conn_handle ,
167+ db_char -> characteristic .handle_value , 0 );
168+ if (nrf_err ) {
169+ LOG_ERR ("Failed to read bsl char value, nrf_err %#x" , nrf_err );
170+ }
156171 }
157172 }
158173
159174 LOG_DBG ("HRS discovered" );
160175
161- /* If the instance has been assigned prior to db_discovery, assign the db_handles . */
176+ /* If the instance has been assigned prior to db_discovery, do not assign the handles . */
162177 if (hrs_client -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
163- if ((handles -> hrm_cccd_handle == BLE_GATT_HANDLE_INVALID ) &&
164- (handles -> hrm_handle == BLE_GATT_HANDLE_INVALID )) {
165- hrs_client -> handles = hrs_client_evt . discovery_complete . handles ;
178+ if ((hrs_client -> handles . hrm_cccd_handle == BLE_GATT_HANDLE_INVALID ) &&
179+ (hrs_client -> handles . hrm_handle == BLE_GATT_HANDLE_INVALID )) {
180+ hrs_client -> handles = * evt_handles ;
166181 }
167182 }
168183
@@ -194,6 +209,31 @@ uint32_t ble_hrs_client_init(struct ble_hrs_client *hrs_client,
194209 return ble_db_discovery_service_register (hrs_client_config -> db_discovery , & hrs_uuid );
195210}
196211
212+ static void on_read_rsp (struct ble_hrs_client * hrs_client , const ble_evt_t * ble_evt )
213+ {
214+ const ble_gattc_evt_read_rsp_t * read_rsp = & ble_evt -> evt .gattc_evt .params .read_rsp ;
215+ struct ble_hrs_client_evt evt = {
216+ .conn_handle = ble_evt -> evt .gattc_evt .conn_handle ,
217+ .evt_type = BLE_HRS_CLIENT_EVT_BSL_UPDATE ,
218+ .body_sensor_location = ble_evt -> evt .gattc_evt .params .read_rsp .data [0 ],
219+ };
220+
221+ if (hrs_client -> conn_handle != ble_evt -> evt .gattc_evt .conn_handle ) {
222+ return ;
223+ }
224+
225+ /* Check if this is a body sensor location response. */
226+ if (read_rsp -> handle != hrs_client -> handles .bsl_handle ) {
227+ return ;
228+ }
229+
230+ if (read_rsp -> len < 1 ) {
231+ return ;
232+ }
233+
234+ hrs_client -> evt_handler (hrs_client , & evt );
235+ }
236+
197237void ble_hrs_client_on_ble_evt (const ble_evt_t * ble_evt , void * hrs_client )
198238{
199239 __ASSERT (ble_evt , "BLE event is NULL" );
@@ -206,6 +246,9 @@ void ble_hrs_client_on_ble_evt(const ble_evt_t *ble_evt, void *hrs_client)
206246 case BLE_GAP_EVT_DISCONNECTED :
207247 on_disconnected (hrs_client , ble_evt );
208248 break ;
249+ case BLE_GATTC_EVT_READ_RSP :
250+ on_read_rsp (hrs_client , ble_evt );
251+ break ;
209252 default :
210253 break ;
211254 }
0 commit comments