Skip to content

Commit c7f59c4

Browse files
sondrepasilz
andcommitted
bluetooth: services: db_discovery: add library
Signed-off-by: Sondre Pettersen <[email protected]> Co-authored-by: Asil Zogby <[email protected]>
1 parent 57ac2de commit c7f59c4

File tree

6 files changed

+1189
-0
lines changed

6 files changed

+1189
-0
lines changed

include/ble_db_discovery.h

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/**
2+
* Copyright (c) 2013 - 2021, Nordic Semiconductor ASA
3+
*
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without modification,
7+
* are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice, this
10+
* list of conditions and the following disclaimer.
11+
*
12+
* 2. Redistributions in binary form, except as embedded into a Nordic
13+
* Semiconductor ASA integrated circuit in a product or a software update for
14+
* such product, must reproduce the above copyright notice, this list of
15+
* conditions and the following disclaimer in the documentation and/or other
16+
* materials provided with the distribution.
17+
*
18+
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
19+
* contributors may be used to endorse or promote products derived from this
20+
* software without specific prior written permission.
21+
*
22+
* 4. This software, with or without modification, must only be used with a
23+
* Nordic Semiconductor ASA integrated circuit.
24+
*
25+
* 5. Any software provided in binary form under this license must not be reverse
26+
* engineered, decompiled, modified and/or disassembled.
27+
*
28+
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
29+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30+
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
31+
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
32+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
34+
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37+
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38+
*
39+
*/
40+
/**@file
41+
*
42+
* @defgroup ble_db_discovery Database Discovery
43+
* @{
44+
* @ingroup ble_sdk_lib
45+
*
46+
* @brief Database discovery module.
47+
*
48+
* @details This module contains the APIs and types exposed by the DB Discovery module. These APIs
49+
* and types can be used by the application to perform discovery of a service and its
50+
* characteristics at the peer server. This module can also be used to discover the
51+
* desired services in multiple remote devices.
52+
*
53+
* @warning The maximum number of characteristics per service that can be discovered by this module
54+
* is determined by the number of characteristics in the service structure defined in
55+
* db_disc_config.h. If the peer has more than the supported number of characteristics,
56+
* then the first found will be discovered and any further characteristics will be ignored. Only the
57+
* following descriptors will be searched for at the peer: Client Characteristic
58+
* Configuration, Characteristic Extended Properties, Characteristic User Description, and Report
59+
* Reference.
60+
*
61+
* @note Presently only one instance of a Primary Service can be discovered by this module. If
62+
* there are multiple instances of the service at the peer, only the first instance
63+
* of it at the peer is fetched and returned to the application.
64+
*
65+
* @note The application must propagate BLE stack events to this module by calling
66+
* ble_db_discovery_on_ble_evt().
67+
*
68+
*/
69+
70+
#include <stdint.h>
71+
#include <zephyr/kernel.h>
72+
#include <ble_gattc.h>
73+
#include <ble_gq.h>
74+
#define BLE_GATT_DB_MAX_CHARS 6
75+
#define BLE_DB_DISCOVERY_MAX_SRV 6
76+
77+
#ifndef BLE_DB_DISCOVERY_H__
78+
#define BLE_DB_DISCOVERY_H__
79+
80+
/**@brief Macro for defining a ble_db_discovery instance.
81+
*
82+
* @param _name Name of the instance.
83+
* @hideinitializer
84+
*/
85+
#define BLE_DB_DISCOVERY_DEF(_name) \
86+
static struct ble_db_discovery _name = {.discovery_in_progress = 0, \
87+
.conn_handle = BLE_CONN_HANDLE_INVALID}; \
88+
NRF_SDH_BLE_OBSERVER(_name##_obs, ble_db_discovery_on_ble_evt, &_name, \
89+
BLE_DB_DISC_BLE_OBSERVER_PRIO)
90+
91+
struct ble_gatt_db_char {
92+
ble_gattc_char_t
93+
characteristic; /**< Structure containing information about the characteristic. */
94+
uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to
95+
BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */
96+
uint16_t ext_prop_handle; /**< Extended Properties Handle value for this characteristic.
97+
This will be set to BLE_GATT_HANDLE_INVALID if an Extended
98+
Properties descriptor is not present at the server. */
99+
uint16_t user_desc_handle; /**< User Description Handle value for this characteristic. This
100+
will be set to BLE_GATT_HANDLE_INVALID if a User Description
101+
descriptor is not present at the server. */
102+
uint16_t report_ref_handle; /**< Report Reference Handle value for this characteristic. This
103+
will be set to BLE_GATT_HANDLE_INVALID if a Report Reference
104+
descriptor is not present at the server. */
105+
};
106+
107+
struct ble_gatt_db_srv {
108+
ble_uuid_t srv_uuid; /**< UUID of the service. */
109+
uint8_t char_count; /**< Number of characteristics present in the service. */
110+
ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
111+
struct ble_gatt_db_char
112+
charateristics[BLE_GATT_DB_MAX_CHARS]; /**< Array of information related to the
113+
characteristics present in the service.
114+
This list can extend further than one. */
115+
};
116+
117+
enum ble_db_discovery_evt_type {
118+
BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the discovery of one service is
119+
complete. */
120+
BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB
121+
Discovery module. This could typically be because of the
122+
SoftDevice API returning an error code during the DB discover.*/
123+
BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the
124+
peer.*/
125+
BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery instance is
126+
available.*/
127+
};
128+
129+
struct ble_db_discovery_evt {
130+
enum ble_db_discovery_evt_type evt_type; /**< Type of event. */
131+
uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
132+
union {
133+
struct ble_gatt_db_srv
134+
discovered_db; /**< Structure containing the information about the GATT
135+
Database at the server. This will be filled when the event
136+
type is @ref BLE_DB_DISCOVERY_COMPLETE. The UUID field of
137+
this will be filled when the event type is @ref
138+
BLE_DB_DISCOVERY_SRV_NOT_FOUND. */
139+
void const *p_db_instance; /**< Pointer to DB discovery instance @ref
140+
ble_db_discovery_t, indicating availability to the new
141+
discovery process. This will be filled when the event
142+
type is @ref BLE_DB_DISCOVERY_AVAILABLE. */
143+
uint32_t err_code; /**< nRF Error code indicating the type of error which occurred
144+
in the DB Discovery module. This will be filled when the event
145+
type is @ref BLE_DB_DISCOVERY_ERROR. */
146+
} params;
147+
};
148+
149+
typedef void (*ble_db_discovery_evt_handler)(struct ble_db_discovery_evt *p_evt);
150+
151+
struct ble_db_discovery_init {
152+
ble_db_discovery_evt_handler
153+
evt_handler; /**< Event handler to be called by the DB Discovery module. */
154+
struct ble_gq *p_gatt_queue; /**< Pointer to BLE GATT Queue instance. */
155+
};
156+
157+
struct ble_db_discovery_user_evt {
158+
struct ble_db_discovery_evt evt; /**< Pending event. */
159+
ble_db_discovery_evt_handler
160+
evt_handler; /**< Event handler which should be called to raise this event. */
161+
};
162+
163+
struct ble_db_discovery {
164+
struct ble_gatt_db_srv
165+
services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service
166+
being discovered. This is intended for
167+
internal use during service discovery.*/
168+
uint8_t srv_count; /**< Number of services at the peer's GATT database.*/
169+
uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is
170+
intended for internal use during service discovery.*/
171+
uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended
172+
for internal use during service discovery.*/
173+
uint8_t discoveries_count; /**< Number of service discoveries made, both successful and
174+
unsuccessful. */
175+
bool discovery_in_progress; /**< Variable to indicate whether there is a service discovery
176+
in progress. */
177+
uint16_t conn_handle; /**< Connection handle on which the discovery is started. */
178+
uint32_t pending_usr_evt_index; /**< The index to the pending user event array, pointing to
179+
the last added pending user event. */
180+
struct ble_db_discovery_user_evt pending_usr_evts
181+
[BLE_DB_DISCOVERY_MAX_SRV]; /**< Whenever a discovery related event is to be raised
182+
to a user module, it is stored in this array first.
183+
When all expected services have been discovered, all
184+
pending events are sent to the corresponding user
185+
modules. */
186+
};
187+
188+
/**@brief Function for initializing the DB Discovery module.
189+
*
190+
* @param[in] p_db_init Pointer to DB discovery initialization structure.
191+
*
192+
* @retval NRF_SUCCESS On successful initialization.
193+
* @retval NRF_ERROR_NULL If the initialization structure was NULL or
194+
* the structure content is empty.
195+
*/
196+
uint32_t ble_db_discovery_init(struct ble_db_discovery_init *p_db_init);
197+
198+
/**@brief Function for closing the DB Discovery module.
199+
*
200+
* @details This function will clear up any internal variables and states maintained by the
201+
* module. To re-use the module after calling this function, the function @ref
202+
* ble_db_discovery_init must be called again. When using more than one DB Discovery
203+
* instance, this function should be called for each instance.
204+
*
205+
* @param[out] p_db_discovery Pointer to the DB discovery structure.
206+
*
207+
* @retval NRF_SUCCESS Operation success.
208+
*/
209+
uint32_t ble_db_discovery_close(struct ble_db_discovery *const p_db_discovery);
210+
211+
/**@brief Function for registering with the DB Discovery module.
212+
*
213+
* @details The application can use this function to inform which service it is interested in
214+
* discovering at the server.
215+
*
216+
* @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server.
217+
*
218+
* @note The total number of services that can be discovered by this module is @ref
219+
* BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of
220+
* registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV.
221+
*
222+
* @retval NRF_SUCCESS Operation success.
223+
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
224+
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
225+
* @ref ble_db_discovery_init.
226+
* @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module
227+
* has been reached.
228+
*/
229+
uint32_t ble_db_discovery_evt_register(const ble_uuid_t *const p_uuid);
230+
231+
/**@brief Function for starting the discovery of the GATT database at the server.
232+
*
233+
* @param[out] p_db_discovery Pointer to the DB Discovery structure.
234+
* @param[in] conn_handle The handle of the connection for which the discovery should be
235+
* started.
236+
*
237+
* @retval NRF_SUCCESS Operation success.
238+
* @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
239+
* @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
240+
* @ref ble_db_discovery_init, or without calling
241+
* @ref ble_db_discovery_evt_register.
242+
* @retval NRF_ERROR_BUSY If a discovery is already in progress using
243+
* @p p_db_discovery. Use a different @ref ble_db_discovery_t
244+
* structure, or wait for a DB Discovery event before retrying.
245+
* @return This API propagates the error code returned by functions:
246+
* @ref nrf_ble_gq_conn_handle_register and @ref
247+
* nrf_ble_gq_item_add.
248+
*/
249+
uint32_t ble_db_discovery_start(struct ble_db_discovery *p_db_discovery, uint16_t conn_handle);
250+
251+
/**@brief Function for handling the Application's BLE Stack events.
252+
*
253+
* @param[in] p_ble_evt Pointer to the BLE event received.
254+
* @param[in,out] p_context Pointer to the DB Discovery structure.
255+
*/
256+
void ble_db_discovery_on_ble_evt(ble_evt_t const *p_ble_evt, void *p_context);
257+
258+
#endif // BLE_DB_DISCOVERY_H__
259+
260+
/** @} */

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
add_subdirectory_ifdef(CONFIG_BLE_ADV ble_adv)
88
add_subdirectory_ifdef(CONFIG_BLE_CONN_PARAMS ble_conn_params)
99
add_subdirectory_ifdef(CONFIG_BLE_CONN_STATE ble_conn_state)
10+
add_subdirectory_ifdef(CONFIG_BLE_DB_DISCOVERY ble_db_discovery)
1011
add_subdirectory_ifdef(CONFIG_BLE_GATT_QUEUE ble_gq)
1112
add_subdirectory_ifdef(CONFIG_BLE_RACP ble_racp)
1213
add_subdirectory_ifdef(CONFIG_EVENT_SCHEDULER event_scheduler)

lib/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ menu "Libraries"
88
rsource "ble_adv/Kconfig"
99
rsource "ble_conn_params/Kconfig"
1010
rsource "ble_conn_state/Kconfig"
11+
rsource "ble_db_discovery/Kconfig"
1112
rsource "ble_gq/Kconfig"
1213
rsource "ble_racp/Kconfig"
1314
rsource "event_scheduler/Kconfig"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
zephyr_library()
7+
zephyr_library_sources(
8+
ble_db_discovery.c
9+
)

lib/ble_db_discovery/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
menuconfig BLE_DB_DISCOVERY
8+
bool "BLE DB discovery"
9+
depends on SOFTDEVICE
10+
select EXPERIMENTAL
11+
help
12+
database discovery.

0 commit comments

Comments
 (0)