BLE_Nano nRF51 Central heart rate

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ble_db_discovery.c Source File

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