@@ -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,6 +129,7 @@ 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 ,
@@ -142,7 +144,11 @@ 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:
148+ * - HRM: store value handle and CCCD handle for later notification setup.
149+ * - BSL: store value handle and issue a Read Request; the value will
150+ * arrive asynchronously via BLE_GATTC_EVT_READ_RSP.
151+ */
146152 for (uint32_t i = 0 ; i < db_discovery_evt -> discovered_db -> char_count ; i ++ ) {
147153 db_char = & db_discovery_evt -> discovered_db -> characteristics [i ];
148154
@@ -152,7 +158,18 @@ void ble_hrs_on_db_disc_evt(struct ble_hrs_client *hrs_client,
152158 db_char -> cccd_handle ;
153159 hrs_client_evt .discovery_complete .handles .hrm_handle =
154160 db_char -> characteristic .handle_value ;
155- break ;
161+ } else if (db_char -> characteristic .uuid .uuid ==
162+ BLE_UUID_BODY_SENSOR_LOCATION_CHAR ) {
163+ hrs_client_evt .discovery_complete .handles .bsl_handle =
164+ db_char -> characteristic .handle_value ;
165+ nrf_err = sd_ble_gattc_read (db_discovery_evt -> conn_handle ,
166+ db_char -> characteristic .handle_value , 0 );
167+ if (nrf_err ) {
168+ hrs_client_evt .evt_type = BLE_HRS_CLIENT_EVT_ERROR ;
169+ hrs_client_evt .error .reason = nrf_err ;
170+ hrs_client -> evt_handler (hrs_client , & hrs_client_evt );
171+ return ;
172+ }
156173 }
157174 }
158175
@@ -194,18 +211,52 @@ uint32_t ble_hrs_client_init(struct ble_hrs_client *hrs_client,
194211 return ble_db_discovery_service_register (hrs_client_config -> db_discovery , & hrs_uuid );
195212}
196213
214+ static void on_read_rsp (struct ble_hrs_client * hrs_client , const ble_evt_t * ble_evt )
215+ {
216+ const ble_gattc_evt_read_rsp_t * read_rsp = & ble_evt -> evt .gattc_evt .params .read_rsp ;
217+ struct ble_hrs_client_evt evt = {
218+ .conn_handle = ble_evt -> evt .gattc_evt .conn_handle ,
219+ .evt_type = BLE_HRS_CLIENT_EVT_BSL_UPDATE ,
220+ .body_sensor_location = ble_evt -> evt .gattc_evt .params .read_rsp .data [0 ],
221+ };
222+
223+ if (hrs_client -> conn_handle != ble_evt -> evt .gattc_evt .conn_handle ) {
224+ return ;
225+ }
226+
227+ /* Check if this is a body sensor location response. */
228+ if (read_rsp -> handle != hrs_client -> handles .bsl_handle ) {
229+ return ;
230+ }
231+
232+ if (read_rsp -> len < 1 ) {
233+ return ;
234+ }
235+
236+ hrs_client -> evt_handler (hrs_client , & evt );
237+ }
238+
197239void ble_hrs_client_on_ble_evt (const ble_evt_t * ble_evt , void * hrs_client )
198240{
199241 __ASSERT (ble_evt , "BLE event is NULL" );
200242 __ASSERT (hrs_client , "HRS central instance is NULL" );
201243
244+ if (ble_evt -> header .evt_id >= BLE_GAP_EVT_BASE &&
245+ ble_evt -> header .evt_id <= BLE_GAP_EVT_LAST &&
246+ ble_evt -> evt .gap_evt .params .connected .role == BLE_GAP_ROLE_PERIPH ) {
247+ return ;
248+ }
249+
202250 switch (ble_evt -> header .evt_id ) {
203251 case BLE_GATTC_EVT_HVX :
204252 on_hvx (hrs_client , ble_evt );
205253 break ;
206254 case BLE_GAP_EVT_DISCONNECTED :
207255 on_disconnected (hrs_client , ble_evt );
208256 break ;
257+ case BLE_GATTC_EVT_READ_RSP :
258+ on_read_rsp (hrs_client , ble_evt );
259+ break ;
209260 default :
210261 break ;
211262 }
0 commit comments