BLE_Nano nRF51 Central heart rate
Embed:
(wiki syntax)
Show/hide line numbers
ble_db_discovery.c
00001 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 */ 00011 00012 #include "ble_db_discovery.h " 00013 #include <stdlib.h> 00014 #include "ble.h" 00015 #include "nrf_log.h" 00016 00017 #include "sdk_common.h" 00018 00019 #define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */ 00020 #define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */ 00021 #define DB_LOG NRF_LOG_PRINTF_DEBUG /**< A debug logger macro that can be used in this file to do logging information over UART. */ 00022 00023 00024 /**@brief Array of structures containing information about the registered application modules. */ 00025 static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS]; 00026 00027 00028 /**@brief Array of structures containing pending events to be sent to the application modules. 00029 * 00030 * @details Whenever a discovery related event is to be raised to a user module, it will be stored 00031 * in this array first. When all services needed to be discovered have been 00032 * discovered, all pending events will be sent to the corresponding user modules. 00033 **/ 00034 static struct 00035 { 00036 ble_db_discovery_evt_t evt; /**< The pending event. */ 00037 ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */ 00038 } m_pending_user_evts[DB_DISCOVERY_MAX_USERS]; 00039 00040 static ble_db_discovery_evt_handler_t m_evt_handler; 00041 static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */ 00042 static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */ 00043 static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */ 00044 00045 #define MODULE_INITIALIZED (m_initialized == true) 00046 #include "sdk_macros.h" 00047 00048 /**@brief Function for fetching the event handler provided by a registered application module. 00049 * 00050 * @param[in] srv_uuid UUID of the service. 00051 * 00052 * @retval evt_handler Event handler of the module, registered for the given service UUID. 00053 * @retval NULL If no event handler is found. 00054 */ 00055 static ble_db_discovery_evt_handler_t registered_handler_get(const ble_uuid_t * const p_srv_uuid) 00056 { 00057 uint32_t i; 00058 00059 for (i = 0; i < m_num_of_handlers_reg; i++) 00060 { 00061 if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid)) 00062 { 00063 return (m_evt_handler); 00064 } 00065 } 00066 00067 return NULL; 00068 } 00069 00070 00071 /**@brief Function for storing the event handler provided by a registered application module. 00072 * 00073 * @param[in] p_srv_uuid The UUID of the service. 00074 * @param[in] p_evt_handler The event handler provided by the application. 00075 * 00076 * @retval NRF_SUCCESS If the handler was stored or already present in the list. 00077 * @retval NRF_ERROR_NO_MEM If there is no space left to store the handler. 00078 */ 00079 static uint32_t registered_handler_set(const ble_uuid_t * const p_srv_uuid, 00080 ble_db_discovery_evt_handler_t p_evt_handler) 00081 { 00082 if (registered_handler_get(p_srv_uuid) != NULL) 00083 { 00084 return NRF_SUCCESS; 00085 } 00086 if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS) 00087 { 00088 m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid; 00089 00090 m_num_of_handlers_reg++; 00091 00092 return NRF_SUCCESS; 00093 } 00094 else 00095 { 00096 return NRF_ERROR_NO_MEM; 00097 } 00098 } 00099 00100 00101 /**@brief Function for sending all pending discovery events to the corresponding user modules. 00102 */ 00103 static void pending_user_evts_send(void) 00104 { 00105 uint32_t i = 0; 00106 00107 for (i = 0; i < m_num_of_handlers_reg; i++) 00108 { 00109 // Pass the event to the corresponding event handler. 00110 m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt)); 00111 } 00112 m_pending_usr_evt_index = 0; 00113 } 00114 00115 00116 /**@brief Function for indicating error to the application. 00117 * 00118 * @details This function will fetch the event handler based on the UUID of the service being 00119 * discovered. (The event handler is registered by the application beforehand). 00120 * The error code is added to the pending events together with the event handler. 00121 * If no event handler was found, then this function will do nothing. 00122 * 00123 * @param[in] p_db_discovery Pointer to the DB discovery structure. 00124 * @param[in] err_code Error code that should be provided to the application. 00125 * @param[in] conn_handle Connection Handle. 00126 * 00127 */ 00128 static void discovery_error_evt_trigger(ble_db_discovery_t * const p_db_discovery, 00129 uint32_t err_code, 00130 uint16_t const conn_handle) 00131 { 00132 ble_db_discovery_evt_handler_t p_evt_handler; 00133 ble_gatt_db_srv_t * p_srv_being_discovered; 00134 00135 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00136 00137 p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid)); 00138 00139 if (p_evt_handler != NULL) 00140 { 00141 ble_db_discovery_evt_t evt; 00142 00143 evt.conn_handle = conn_handle; 00144 evt.evt_type = BLE_DB_DISCOVERY_ERROR; 00145 evt.params.err_code = err_code; 00146 00147 p_evt_handler(&evt); 00148 } 00149 } 00150 00151 00152 /**@brief Function for triggering a Discovery Complete or Service Not Found event to the 00153 * application. 00154 * 00155 * @details This function will fetch the event handler based on the UUID of the service being 00156 * discovered. (The event handler is registered by the application beforehand). 00157 * It then triggers an event indicating the completion of the service discovery. 00158 * If no event handler was found, then this function will do nothing. 00159 * 00160 * @param[in] p_db_discovery Pointer to the DB discovery structure. 00161 * @param[in] is_srv_found Variable to indicate if the service was found at the peer. 00162 * @param[in] conn_handle Connection Handle. 00163 */ 00164 static void discovery_complete_evt_trigger(ble_db_discovery_t * const p_db_discovery, 00165 bool is_srv_found, 00166 uint16_t const conn_handle) 00167 { 00168 ble_db_discovery_evt_handler_t p_evt_handler; 00169 ble_gatt_db_srv_t * p_srv_being_discovered; 00170 00171 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00172 00173 p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid)); 00174 00175 if (p_evt_handler != NULL) 00176 { 00177 if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS) 00178 { 00179 // Insert an event into the pending event list. 00180 m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle; 00181 00182 m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db = 00183 *p_srv_being_discovered; 00184 if (is_srv_found) 00185 { 00186 m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = 00187 BLE_DB_DISCOVERY_COMPLETE; 00188 } 00189 else 00190 { 00191 m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = 00192 BLE_DB_DISCOVERY_SRV_NOT_FOUND; 00193 } 00194 m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler; 00195 00196 m_pending_usr_evt_index++; 00197 00198 if (m_pending_usr_evt_index == m_num_of_handlers_reg) 00199 { 00200 // All registered modules have pending events. Send all pending events to the user 00201 // modules. 00202 pending_user_evts_send(); 00203 } 00204 else 00205 { 00206 // Too many events pending. Do nothing. (Ideally this should not happen.) 00207 } 00208 } 00209 } 00210 } 00211 00212 00213 /**@brief Function for handling service discovery completion. 00214 * 00215 * @details This function will be used to determine if there are more services to be discovered, 00216 * and if so, initiate the discovery of the next service. 00217 * 00218 * @param[in] p_db_discovery Pointer to the DB Discovery Structure. 00219 * @param[in] conn_handle Connection Handle. 00220 */ 00221 static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery, 00222 uint16_t const conn_handle) 00223 { 00224 p_db_discovery->discoveries_count++; 00225 00226 // Check if more services need to be discovered. 00227 if (p_db_discovery->discoveries_count < m_num_of_handlers_reg) 00228 { 00229 // Reset the current characteristic index since a new service discovery is about to start. 00230 p_db_discovery->curr_char_ind = 0; 00231 00232 // Initiate discovery of the next service. 00233 p_db_discovery->curr_srv_ind++; 00234 00235 ble_gatt_db_srv_t * p_srv_being_discovered; 00236 00237 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00238 00239 p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; 00240 00241 // Reset the characteristic count in the current service to zero since a new service 00242 // discovery is about to start. 00243 p_srv_being_discovered->char_count = 0; 00244 00245 DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", 00246 p_srv_being_discovered->srv_uuid.uuid, conn_handle); 00247 00248 uint32_t err_code; 00249 00250 err_code = sd_ble_gattc_primary_services_discover 00251 ( 00252 conn_handle, 00253 SRV_DISC_START_HANDLE, 00254 &(p_srv_being_discovered->srv_uuid) 00255 ); 00256 if (err_code != NRF_SUCCESS) 00257 { 00258 p_db_discovery->discovery_in_progress = false; 00259 00260 // Error with discovering the service. 00261 // Indicate the error to the registered user application. 00262 discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle); 00263 00264 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00265 m_pending_user_evts[0].evt.conn_handle = conn_handle; 00266 // m_evt_handler(&m_pending_user_evts[0].evt); 00267 00268 return; 00269 } 00270 } 00271 else 00272 { 00273 // No more service discovery is needed. 00274 p_db_discovery->discovery_in_progress = false; 00275 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00276 m_pending_user_evts[0].evt.conn_handle = conn_handle; 00277 //m_evt_handler(&m_pending_user_evts[0].evt); 00278 } 00279 } 00280 00281 00282 /**@brief Function for finding out if a characteristic discovery should be performed after the 00283 * last discovered characteristic. 00284 * 00285 * @details This function is used during the time of database discovery to find out if there is 00286 * a need to do more characteristic discoveries. The value handles of the 00287 * last discovered characteristic is compared with the end handle of the service. 00288 * If the service handle is greater than one of the former characteristic handles, 00289 * it means that a characteristic discovery is required. 00290 * 00291 * @param[in] p_db_discovery The pointer to the DB Discovery structure. 00292 * @param[in] p_after_char The pointer to the last discovered characteristic. 00293 * 00294 * @retval True if a characteristic discovery is required. 00295 * @retval False if a characteristic discovery is NOT required. 00296 */ 00297 static bool is_char_discovery_reqd(ble_db_discovery_t * const p_db_discovery, 00298 ble_gattc_char_t * p_after_char) 00299 { 00300 if ( 00301 p_after_char->handle_value < 00302 p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle 00303 ) 00304 { 00305 // Handle value of the characteristic being discovered is less than the end handle of 00306 // the service being discovered. There is a possibility of more characteristics being 00307 // present. Hence a characteristic discovery is required. 00308 return true; 00309 } 00310 00311 return false; 00312 } 00313 00314 00315 /**@brief Function to find out if a descriptor discovery is required. 00316 * 00317 * @details This function finds out if there is a possibility of existence of descriptors between 00318 * current characteristic and the next characteristic. If so, this function will compute 00319 * the handle range on which the descriptors may be present and will return it. 00320 * If the current characteristic is the last known characteristic, then this function 00321 * will use the service end handle to find out if the current characteristic can have 00322 * descriptors. 00323 * 00324 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00325 * @param[in] p_curr_char Pointer to the current characteristic. 00326 * @param[in] p_next_char Pointer to the next characteristic. This should be NULL if the 00327 * caller knows that there is no characteristic after the current 00328 * characteristic at the peer. 00329 * @param[out] p_handle_range Pointer to the handle range in which descriptors may exist at the 00330 * the peer. 00331 * 00332 * @retval True If a descriptor discovery is required. 00333 * @retval False If a descriptor discovery is NOT required. 00334 */ 00335 static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery, 00336 ble_gatt_db_char_t * p_curr_char, 00337 ble_gatt_db_char_t * p_next_char, 00338 ble_gattc_handle_range_t * p_handle_range) 00339 { 00340 if (p_next_char == NULL) 00341 { 00342 // Current characteristic is the last characteristic in the service. Check if the value 00343 // handle of the current characteristic is equal to the service end handle. 00344 if ( 00345 p_curr_char->characteristic.handle_value == 00346 p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle 00347 ) 00348 { 00349 // No descriptors can be present for the current characteristic. p_curr_char is the last 00350 // characteristic with no descriptors. 00351 return false; 00352 } 00353 00354 p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1; 00355 00356 // Since the current characteristic is the last characteristic in the service, the end 00357 // handle should be the end handle of the service. 00358 p_handle_range->end_handle = 00359 p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle; 00360 00361 return true; 00362 } 00363 00364 // p_next_char != NULL. Check for existence of descriptors between the current and the next 00365 // characteristic. 00366 if ((p_curr_char->characteristic.handle_value + 1) == p_next_char->characteristic.handle_decl) 00367 { 00368 // No descriptors can exist between the two characteristic. 00369 return false; 00370 } 00371 00372 p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1; 00373 p_handle_range->end_handle = p_next_char->characteristic.handle_decl - 1; 00374 00375 return true; 00376 } 00377 00378 00379 /**@brief Function for performing characteristic discovery. 00380 * 00381 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00382 * @param[in] conn_handle Connection Handle. 00383 * 00384 * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic 00385 * discovery. Otherwise an error code. This function returns the error code returned 00386 * by the SoftDevice API @ref sd_ble_gattc_characteristics_discover. 00387 */ 00388 static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discovery, 00389 uint16_t const conn_handle) 00390 { 00391 ble_gatt_db_srv_t * p_srv_being_discovered; 00392 ble_gattc_handle_range_t handle_range; 00393 00394 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00395 00396 if (p_db_discovery->curr_char_ind != 0) 00397 { 00398 // This is not the first characteristic being discovered. Hence the 'start handle' to be 00399 // used must be computed using the handle_value of the previous characteristic. 00400 ble_gattc_char_t * p_prev_char; 00401 uint8_t prev_char_ind = p_db_discovery->curr_char_ind - 1; 00402 00403 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00404 00405 p_prev_char = &(p_srv_being_discovered->charateristics[prev_char_ind].characteristic); 00406 00407 handle_range.start_handle = p_prev_char->handle_value + 1; 00408 } 00409 else 00410 { 00411 // This is the first characteristic of this service being discovered. 00412 handle_range.start_handle = p_srv_being_discovered->handle_range.start_handle; 00413 } 00414 00415 handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle; 00416 00417 return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); 00418 } 00419 00420 00421 /**@brief Function for performing descriptor discovery, if required. 00422 * 00423 * @details This function will check if descriptor discovery is required and then perform it if 00424 * needed. If no more descriptor discovery is required for the service, then the output 00425 * parameter p_raise_discov_complete is set to true, indicating to the caller that a 00426 * discovery complete event can be triggered to the application. 00427 * 00428 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00429 * @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if 00430 * the Discovery Complete event can be triggered to the 00431 * application. 00432 * @param[in] conn_handle Connection Handle. 00433 * 00434 * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor 00435 * discovery, or if no more descriptor discovery is required. Otherwise an error code. 00436 * This function returns the error code returned by the SoftDevice API @ref 00437 * sd_ble_gattc_descriptors_discover. 00438 */ 00439 static uint32_t descriptors_discover(ble_db_discovery_t * const p_db_discovery, 00440 bool * p_raise_discov_complete, 00441 uint16_t const conn_handle) 00442 { 00443 ble_gattc_handle_range_t handle_range; 00444 ble_gatt_db_char_t * p_curr_char_being_discovered; 00445 ble_gatt_db_srv_t * p_srv_being_discovered; 00446 bool is_discovery_reqd = false; 00447 00448 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00449 00450 p_curr_char_being_discovered = 00451 &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]); 00452 00453 if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count) 00454 { 00455 // This is the last characteristic of this service. 00456 is_discovery_reqd = is_desc_discovery_reqd(p_db_discovery, 00457 p_curr_char_being_discovered, 00458 NULL, 00459 &handle_range); 00460 } 00461 else 00462 { 00463 uint8_t i; 00464 ble_gatt_db_char_t * p_next_char; 00465 00466 for (i = p_db_discovery->curr_char_ind; 00467 i < p_srv_being_discovered->char_count; 00468 i++) 00469 { 00470 00471 if (i == (p_srv_being_discovered->char_count - 1)) 00472 { 00473 // The current characteristic is the last characteristic in the service. 00474 p_next_char = NULL; 00475 } 00476 else 00477 { 00478 p_next_char = &(p_srv_being_discovered->charateristics[i + 1]); 00479 } 00480 00481 // Check if it is possible for the current characteristic to have a descriptor. 00482 if (is_desc_discovery_reqd(p_db_discovery, 00483 p_curr_char_being_discovered, 00484 p_next_char, 00485 &handle_range)) 00486 { 00487 is_discovery_reqd = true; 00488 break; 00489 } 00490 else 00491 { 00492 // No descriptors can exist. 00493 p_curr_char_being_discovered = p_next_char; 00494 p_db_discovery->curr_char_ind++; 00495 } 00496 } 00497 } 00498 00499 if (!is_discovery_reqd) 00500 { 00501 // No more descriptor discovery required. Discovery is complete. 00502 // This informs the caller that a discovery complete event can be triggered. 00503 *p_raise_discov_complete = true; 00504 00505 return NRF_SUCCESS; 00506 } 00507 00508 *p_raise_discov_complete = false; 00509 00510 return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range); 00511 } 00512 00513 00514 /**@brief Function for handling primary service discovery response. 00515 * 00516 * @details This function will handle the primary service discovery response and start the 00517 * discovery of characteristics within that service. 00518 * 00519 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00520 * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. 00521 */ 00522 static void on_primary_srv_discovery_rsp(ble_db_discovery_t * const p_db_discovery, 00523 const ble_gattc_evt_t * const p_ble_gattc_evt) 00524 { 00525 ble_gatt_db_srv_t * p_srv_being_discovered; 00526 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00527 00528 if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) 00529 { 00530 return; 00531 } 00532 if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) 00533 { 00534 uint32_t err_code; 00535 const ble_gattc_evt_prim_srvc_disc_rsp_t * p_prim_srvc_disc_rsp_evt; 00536 00537 DB_LOG("Found service UUID 0x%x\r\n", p_srv_being_discovered->srv_uuid.uuid); 00538 00539 p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp); 00540 00541 p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid; 00542 p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range; 00543 00544 err_code = characteristics_discover(p_db_discovery, 00545 p_ble_gattc_evt->conn_handle); 00546 00547 if (err_code != NRF_SUCCESS) 00548 { 00549 p_db_discovery->discovery_in_progress = false; 00550 00551 // Error with discovering the service. 00552 // Indicate the error to the registered user application. 00553 discovery_error_evt_trigger(p_db_discovery, 00554 err_code, 00555 p_ble_gattc_evt->conn_handle); 00556 00557 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00558 m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; 00559 //m_evt_handler(&m_pending_user_evts[0].evt); 00560 } 00561 } 00562 else 00563 { 00564 DB_LOG("Service UUID 0x%x Not found\r\n", p_srv_being_discovered->srv_uuid.uuid); 00565 // Trigger Service Not Found event to the application. 00566 discovery_complete_evt_trigger(p_db_discovery, 00567 false, 00568 p_ble_gattc_evt->conn_handle); 00569 00570 on_srv_disc_completion(p_db_discovery, 00571 p_ble_gattc_evt->conn_handle); 00572 } 00573 } 00574 00575 00576 /**@brief Function for handling characteristic discovery response. 00577 * 00578 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00579 * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. 00580 */ 00581 static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_discovery, 00582 const ble_gattc_evt_t * const p_ble_gattc_evt) 00583 { 00584 uint32_t err_code; 00585 ble_gatt_db_srv_t * p_srv_being_discovered; 00586 bool perform_desc_discov = false; 00587 00588 if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) 00589 { 00590 return; 00591 } 00592 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00593 00594 if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) 00595 { 00596 const ble_gattc_evt_char_disc_rsp_t * p_char_disc_rsp_evt; 00597 00598 p_char_disc_rsp_evt = &(p_ble_gattc_evt->params.char_disc_rsp); 00599 00600 // Find out the number of characteristics that were previously discovered (in earlier 00601 // characteristic discovery responses, if any). 00602 uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count; 00603 00604 // Find out the number of characteristics that are currently discovered (in the 00605 // characteristic discovery response being handled). 00606 uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count; 00607 00608 // Check if the total number of discovered characteristics are supported by this module. 00609 if ((num_chars_prev_disc + num_chars_curr_disc) <= BLE_GATT_DB_MAX_CHARS) 00610 { 00611 // Update the characteristics count. 00612 p_srv_being_discovered->char_count += num_chars_curr_disc; 00613 } 00614 else 00615 { 00616 // The number of characteristics discovered at the peer is more than the supported 00617 // maximum. This module will store only the characteristics found up to this point. 00618 p_srv_being_discovered->char_count = BLE_GATT_DB_MAX_CHARS; 00619 } 00620 00621 uint32_t i; 00622 uint32_t j; 00623 00624 for (i = num_chars_prev_disc, j = 0; i < p_srv_being_discovered->char_count; i++, j++) 00625 { 00626 p_srv_being_discovered->charateristics[i].characteristic = 00627 p_char_disc_rsp_evt->chars[j]; 00628 00629 p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID; 00630 } 00631 00632 ble_gattc_char_t * p_last_known_char; 00633 00634 p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic); 00635 00636 // If no more characteristic discovery is required, or if the maximum number of supported 00637 // characteristic per service has been reached, descriptor discovery will be performed. 00638 if ( 00639 !is_char_discovery_reqd(p_db_discovery, p_last_known_char) || 00640 (p_srv_being_discovered->char_count == BLE_GATT_DB_MAX_CHARS) 00641 ) 00642 { 00643 perform_desc_discov = true; 00644 } 00645 else 00646 { 00647 // Update the current characteristic index. 00648 p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count; 00649 00650 // Perform another round of characteristic discovery. 00651 err_code = characteristics_discover(p_db_discovery, 00652 p_ble_gattc_evt->conn_handle); 00653 00654 if (err_code != NRF_SUCCESS) 00655 { 00656 p_db_discovery->discovery_in_progress = false; 00657 00658 discovery_error_evt_trigger(p_db_discovery, 00659 err_code, 00660 p_ble_gattc_evt->conn_handle); 00661 00662 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00663 m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; 00664 //m_evt_handler(&m_pending_user_evts[0].evt); 00665 00666 return; 00667 } 00668 } 00669 } 00670 else 00671 { 00672 // The previous characteristic discovery resulted in no characteristics. 00673 // descriptor discovery should be performed. 00674 perform_desc_discov = true; 00675 } 00676 00677 if (perform_desc_discov) 00678 { 00679 bool raise_discov_complete; 00680 00681 p_db_discovery->curr_char_ind = 0; 00682 00683 err_code = descriptors_discover(p_db_discovery, 00684 &raise_discov_complete, 00685 p_ble_gattc_evt->conn_handle); 00686 00687 if (err_code != NRF_SUCCESS) 00688 { 00689 p_db_discovery->discovery_in_progress = false; 00690 00691 discovery_error_evt_trigger(p_db_discovery, 00692 err_code, 00693 p_ble_gattc_evt->conn_handle); 00694 00695 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00696 m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; 00697 //m_evt_handler(&m_pending_user_evts[0].evt); 00698 00699 return; 00700 } 00701 if (raise_discov_complete) 00702 { 00703 // No more characteristics and descriptors need to be discovered. Discovery is complete. 00704 // Send a discovery complete event to the user application. 00705 DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection" 00706 " handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, 00707 p_ble_gattc_evt->conn_handle); 00708 00709 discovery_complete_evt_trigger(p_db_discovery, 00710 true, 00711 p_ble_gattc_evt->conn_handle); 00712 00713 on_srv_disc_completion(p_db_discovery, 00714 p_ble_gattc_evt->conn_handle); 00715 } 00716 } 00717 } 00718 00719 00720 /**@brief Function for handling descriptor discovery response. 00721 * 00722 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00723 * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. 00724 */ 00725 static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_discovery, 00726 const ble_gattc_evt_t * const p_ble_gattc_evt) 00727 { 00728 const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt; 00729 ble_gatt_db_srv_t * p_srv_being_discovered; 00730 00731 if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) 00732 { 00733 return; 00734 } 00735 00736 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00737 00738 p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp); 00739 00740 ble_gatt_db_char_t * p_char_being_discovered = 00741 &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]); 00742 00743 if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) 00744 { 00745 // The descriptor was found at the peer. 00746 // If the descriptor was a CCCD, then the cccd_handle needs to be populated. 00747 00748 uint32_t i; 00749 00750 // Loop through all the descriptors to find the CCCD. 00751 for (i = 0; i < p_desc_disc_rsp_evt->count; i++) 00752 { 00753 if ( 00754 p_desc_disc_rsp_evt->descs[i].uuid.uuid == 00755 BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 00756 ) 00757 { 00758 p_char_being_discovered->cccd_handle = p_desc_disc_rsp_evt->descs[i].handle; 00759 00760 break; 00761 } 00762 } 00763 } 00764 00765 bool raise_discov_complete = false; 00766 00767 if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count) 00768 { 00769 // No more characteristics and descriptors need to be discovered. Discovery is complete. 00770 // Send a discovery complete event to the user application. 00771 00772 raise_discov_complete = true; 00773 } 00774 else 00775 { 00776 // Begin discovery of descriptors for the next characteristic. 00777 uint32_t err_code; 00778 00779 p_db_discovery->curr_char_ind++; 00780 00781 err_code = descriptors_discover(p_db_discovery, 00782 &raise_discov_complete, 00783 p_ble_gattc_evt->conn_handle); 00784 00785 if (err_code != NRF_SUCCESS) 00786 { 00787 p_db_discovery->discovery_in_progress = false; 00788 00789 // Error with discovering the service. 00790 // Indicate the error to the registered user application. 00791 discovery_error_evt_trigger(p_db_discovery, 00792 err_code, 00793 p_ble_gattc_evt->conn_handle); 00794 00795 m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; 00796 m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; 00797 00798 return; 00799 } 00800 } 00801 00802 if (raise_discov_complete) 00803 { 00804 DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection" 00805 "handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, 00806 p_ble_gattc_evt->conn_handle); 00807 00808 discovery_complete_evt_trigger(p_db_discovery, 00809 true, 00810 p_ble_gattc_evt->conn_handle); 00811 00812 on_srv_disc_completion(p_db_discovery, 00813 p_ble_gattc_evt->conn_handle); 00814 } 00815 } 00816 00817 00818 uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler) 00819 { 00820 uint32_t err_code = NRF_SUCCESS; 00821 VERIFY_PARAM_NOT_NULL(evt_handler); 00822 00823 m_num_of_handlers_reg = 0; 00824 m_initialized = true; 00825 m_pending_usr_evt_index = 0; 00826 m_evt_handler = evt_handler; 00827 00828 return err_code; 00829 00830 } 00831 00832 00833 uint32_t ble_db_discovery_close() 00834 { 00835 m_num_of_handlers_reg = 0; 00836 m_initialized = false; 00837 m_pending_usr_evt_index = 0; 00838 00839 return NRF_SUCCESS; 00840 } 00841 00842 00843 uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid) 00844 { 00845 VERIFY_PARAM_NOT_NULL(p_uuid); 00846 VERIFY_MODULE_INITIALIZED(); 00847 00848 return registered_handler_set(p_uuid, m_evt_handler); 00849 } 00850 00851 00852 uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, 00853 uint16_t conn_handle) 00854 { 00855 VERIFY_PARAM_NOT_NULL(p_db_discovery); 00856 VERIFY_MODULE_INITIALIZED(); 00857 00858 if (m_num_of_handlers_reg == 0) 00859 { 00860 // No user modules were registered. There are no services to discover. 00861 return NRF_ERROR_INVALID_STATE; 00862 } 00863 00864 if (p_db_discovery->discovery_in_progress) 00865 { 00866 return NRF_ERROR_BUSY; 00867 } 00868 00869 p_db_discovery->conn_handle = conn_handle; 00870 ble_gatt_db_srv_t * p_srv_being_discovered; 00871 00872 m_pending_usr_evt_index = 0; 00873 00874 p_db_discovery->discoveries_count = 0; 00875 p_db_discovery->curr_srv_ind = 0; 00876 00877 p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); 00878 00879 p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; 00880 00881 DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", 00882 p_srv_being_discovered->srv_uuid.uuid, conn_handle); 00883 00884 uint32_t err_code; 00885 00886 err_code = sd_ble_gattc_primary_services_discover(conn_handle, 00887 SRV_DISC_START_HANDLE, 00888 &(p_srv_being_discovered->srv_uuid)); 00889 VERIFY_SUCCESS(err_code); 00890 p_db_discovery->discovery_in_progress = true; 00891 00892 return NRF_SUCCESS; 00893 } 00894 00895 00896 /**@brief Function for handling disconnected event. 00897 * 00898 * @param[in] p_db_discovery Pointer to the DB Discovery structure. 00899 * @param[in] p_ble_gattc_evt Pointer to the GAP event. 00900 */ 00901 static void on_disconnected(ble_db_discovery_t * const p_db_discovery, 00902 const ble_gap_evt_t * const p_evt) 00903 { 00904 if (p_evt->conn_handle == p_db_discovery->conn_handle) 00905 { 00906 p_db_discovery->discovery_in_progress = false; 00907 } 00908 } 00909 00910 00911 void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, 00912 const ble_evt_t * const p_ble_evt) 00913 { 00914 VERIFY_PARAM_NOT_NULL_VOID(p_db_discovery); 00915 VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); 00916 VERIFY_MODULE_INITIALIZED_VOID(); 00917 00918 switch (p_ble_evt->header.evt_id) 00919 { 00920 case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: 00921 on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); 00922 break; 00923 00924 case BLE_GATTC_EVT_CHAR_DISC_RSP: 00925 on_characteristic_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); 00926 break; 00927 00928 case BLE_GATTC_EVT_DESC_DISC_RSP: 00929 on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); 00930 break; 00931 00932 case BLE_GAP_EVT_DISCONNECTED: 00933 on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt)); 00934 break; 00935 00936 default: 00937 break; 00938 } 00939 } 00940
Generated on Wed Jul 13 2022 07:07:19 by 1.7.2