ble_advertising.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /**
  2. * Copyright (c) 2015 - 2019, 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_advertising Advertising Module
  43. * @{
  44. * @ingroup ble_sdk_lib
  45. * @brief Module for handling connectable BLE advertising.
  46. *
  47. * @details The Advertising Module handles connectable advertising for your application. It can
  48. * be configured with advertising modes to suit most typical use cases.
  49. * Your main application can react to changes in advertising modes
  50. * if an event handler is provided.
  51. *
  52. * @note The Advertising Module supports only applications with a single peripheral link.
  53. *
  54. */
  55. #ifndef BLE_ADVERTISING_H__
  56. #define BLE_ADVERTISING_H__
  57. #include <stdint.h>
  58. #include "nrf_error.h"
  59. #include "ble.h"
  60. #include "ble_gap.h"
  61. #include "ble_gattc.h"
  62. #include "ble_advdata.h"
  63. #ifdef __cplusplus
  64. extern "C" {
  65. #endif
  66. /**@brief Macro for defining a ble_advertising instance.
  67. *
  68. * @param _name Name of the instance.
  69. * @hideinitializer
  70. */
  71. #define BLE_ADVERTISING_DEF(_name) \
  72. static ble_advertising_t _name; \
  73. NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
  74. BLE_ADV_BLE_OBSERVER_PRIO, \
  75. ble_advertising_on_ble_evt, &_name); \
  76. NRF_SDH_SOC_OBSERVER(_name ## _soc_obs, \
  77. BLE_ADV_SOC_OBSERVER_PRIO, \
  78. ble_advertising_on_sys_evt, &_name)
  79. /**@brief Advertising modes. */
  80. typedef enum
  81. {
  82. BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing. */
  83. BLE_ADV_MODE_DIRECTED_HIGH_DUTY, /**< Directed advertising (high duty cycle) attempts to connect to the most recently disconnected peer. */
  84. BLE_ADV_MODE_DIRECTED, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */
  85. BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */
  86. BLE_ADV_MODE_SLOW, /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */
  87. } ble_adv_mode_t;
  88. /**@brief Advertising events.
  89. *
  90. * @details These events are propagated to the main application if a handler was provided during
  91. * initialization of the Advertising Module. Events for modes that are not used can be
  92. * ignored. Similarly, BLE_ADV_EVT_WHITELIST_REQUEST and BLE_ADV_EVT_PEER_ADDR_REQUEST
  93. * can be ignored if whitelist and direct advertising is not used.
  94. */
  95. typedef enum
  96. {
  97. BLE_ADV_EVT_IDLE, /**< Idle; no connectable advertising is ongoing.*/
  98. BLE_ADV_EVT_DIRECTED_HIGH_DUTY, /**< Direct advertising mode has started. */
  99. BLE_ADV_EVT_DIRECTED, /**< Directed advertising (low duty cycle) has started. */
  100. BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */
  101. BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started. */
  102. BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */
  103. BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started. */
  104. BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */
  105. BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */
  106. } ble_adv_evt_t;
  107. /**@brief Options for the different advertisement modes.
  108. *
  109. * @details This structure is used to enable or disable advertising modes and to configure time-out
  110. * periods and advertising intervals.
  111. */
  112. typedef struct
  113. {
  114. bool ble_adv_on_disconnect_disabled; /**< Enable or disable automatic return to advertising upon disconnecting.*/
  115. bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
  116. bool ble_adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. Can not be used together with extended advertising. */
  117. bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
  118. bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
  119. bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
  120. uint32_t ble_adv_directed_interval; /**< Advertising interval for directed advertising. */
  121. uint32_t ble_adv_directed_timeout; /**< Time-out (number of tries) for direct advertising. */
  122. uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
  123. uint32_t ble_adv_fast_timeout; /**< Time-out (in units of 10ms) for fast advertising. */
  124. uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
  125. uint32_t ble_adv_slow_timeout; /**< Time-out (in units of 10ms) for slow advertising. */
  126. bool ble_adv_extended_enabled; /**< Enable or disable extended advertising. */
  127. uint32_t ble_adv_secondary_phy; /**< PHY for the secondary (extended) advertising @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
  128. uint32_t ble_adv_primary_phy; /**< PHY for the primary advertising. @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
  129. } ble_adv_modes_config_t;
  130. /**@brief BLE advertising event handler type. */
  131. typedef void (*ble_adv_evt_handler_t) (ble_adv_evt_t const adv_evt);
  132. /**@brief BLE advertising error handler type. */
  133. typedef void (*ble_adv_error_handler_t) (uint32_t nrf_error);
  134. typedef struct
  135. {
  136. bool initialized;
  137. bool advertising_start_pending; /**< Flag to keep track of ongoing operations in flash. */
  138. ble_adv_mode_t adv_mode_current; /**< Variable to keep track of the current advertising mode. */
  139. ble_adv_modes_config_t adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/
  140. uint8_t conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if the advertising results in a connection. */
  141. ble_adv_evt_t adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address. */
  142. ble_adv_evt_handler_t evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */
  143. ble_adv_error_handler_t error_handler; /**< Handler for the advertising error events. */
  144. ble_gap_adv_params_t adv_params; /**< GAP advertising parameters. */
  145. uint8_t adv_handle; /**< Handle for the advertising set. */
  146. #ifdef BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
  147. uint8_t enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED]; /**< Current advertising data in encoded form. */
  148. uint8_t enc_scan_rsp_data[BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED]; /**< Current scan response data in encoded form. */
  149. #else
  150. uint8_t enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Current advertising data in encoded form. */
  151. uint8_t enc_scan_rsp_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Current scan response data in encoded form. */
  152. #endif // BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
  153. ble_gap_adv_data_t adv_data; /**< Advertising data. */
  154. ble_gap_adv_data_t *p_adv_data; /**< Will be set to point to @ref ble_advertising_t::adv_data for undirected advertising, and will be set to NULL for directed advertising. */
  155. uint16_t current_slave_link_conn_handle; /**< Connection handle for the active link. */
  156. ble_gap_addr_t peer_address; /**< Address of the most recently connected peer, used for direct advertising. */
  157. bool peer_addr_reply_expected; /**< Flag to verify that peer address is only set when requested. */
  158. bool whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */
  159. bool whitelist_reply_expected; /**< Flag to verify that the whitelist is only set when requested. */
  160. bool whitelist_in_use; /**< This module needs to be aware of whether or not a whitelist has been set (e.g. using the Peer Manager) in order to start advertising with the proper advertising params (filter policy). */
  161. } ble_advertising_t;
  162. typedef struct
  163. {
  164. uint32_t interval;
  165. uint32_t timeout;
  166. bool enabled;
  167. } ble_adv_mode_config_t;
  168. /**@brief Initialization parameters for the Advertising Module.
  169. * @details This structure is used to pass advertising options, advertising data,
  170. * and an event handler to the Advertising Module during initialization.
  171. */
  172. typedef struct
  173. {
  174. ble_advdata_t advdata; /**< Advertising data: name, appearance, discovery flags, and more. */
  175. ble_advdata_t srdata; /**< Scan response data: Supplement to advertising data. */
  176. ble_adv_modes_config_t config; /**< Select which advertising modes and intervals will be utilized.*/
  177. ble_adv_evt_handler_t evt_handler; /**< Event handler that will be called upon advertising events. */
  178. ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
  179. } ble_advertising_init_t;
  180. /**@brief Function for handling BLE events.
  181. *
  182. * @details This function must be called from the BLE stack event dispatcher for
  183. * the module to handle BLE events that are relevant for the Advertising Module.
  184. *
  185. * @param[in] p_ble_evt BLE stack event.
  186. * @param[in] p_adv Advertising Module instance.
  187. */
  188. void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_adv);
  189. /**@brief Function for handling system events.
  190. *
  191. * @details This function must be called to handle system events that are relevant
  192. * for the Advertising Module.
  193. *
  194. * @param[in] sys_evt System event.
  195. * @param[in] p_adv Advertising Module instance.
  196. */
  197. void ble_advertising_on_sys_evt(uint32_t sys_evt, void * p_adv);
  198. /**@brief Function for initializing the Advertising Module.
  199. *
  200. * @details Encodes the required advertising data and passes it to the stack.
  201. * Also builds a structure to be passed to the stack when starting advertising.
  202. * Most of the supplied data is copied into a local structure where it is manipulated
  203. * depending on what advertising modes are started in @ref ble_advertising_start.
  204. * The exception is advdata_t::uuids_more_available, advdata_t::uuids_complete, and
  205. * advdata_t::uuids_solicited which are stored as pointers. The main application must
  206. * store these UUIDs.
  207. *
  208. * @param[out] p_advertising Advertising Module instance. This structure must be supplied by
  209. * the application. It is initialized by this function and will later
  210. * be used to identify this particular module instance.
  211. * @param[in] p_init Information needed to initialize the module.
  212. *
  213. * @retval NRF_SUCCESS If initialization was successful.
  214. * @retval NRF_ERROR_INVALID_PARAM If the advertising configuration in \p p_init is invalid.
  215. * @return If functions from other modules return errors to this function, the @ref nrf_error are propagated.
  216. */
  217. uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
  218. ble_advertising_init_t const * const p_init);
  219. /**@brief Function for changing the connection settings tag that will be used for upcoming connections.
  220. *
  221. * @details See @ref sd_ble_cfg_set for more details about changing connection settings. If this
  222. * function is never called, @ref BLE_CONN_CFG_TAG_DEFAULT will be used.
  223. *
  224. * @param[in] p_advertising Advertising Module instance.
  225. * @param[in] ble_cfg_tag Configuration for the connection settings (see @ref sd_ble_cfg_set).
  226. */
  227. void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising, uint8_t ble_cfg_tag);
  228. /**@brief Function for starting advertising.
  229. *
  230. * @details You can start advertising in any of the advertising modes that you enabled
  231. * during initialization.
  232. *
  233. * @param[in] p_advertising Advertising Module instance.
  234. * @param[in] advertising_mode Advertising mode.
  235. *
  236. * @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure.
  237. * @retval @ref NRF_ERROR_INVALID_STATE If the module is not initialized.
  238. */
  239. uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
  240. ble_adv_mode_t advertising_mode);
  241. /**@brief Function for setting the peer address.
  242. *
  243. * @details The peer address must be set by the application upon receiving a
  244. * @ref BLE_ADV_EVT_PEER_ADDR_REQUEST event. Without the peer address, the directed
  245. * advertising mode will not be run.
  246. *
  247. * @param[in] p_advertising Advertising Module instance.
  248. * @param[in] p_peer_addr Pointer to a peer address.
  249. *
  250. * @retval @ref NRF_SUCCESS Successfully stored the peer address pointer in the Advertising Module.
  251. * @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected.
  252. */
  253. uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
  254. ble_gap_addr_t * p_peer_addr);
  255. /**@brief Function for setting a whitelist.
  256. *
  257. * @details The whitelist must be set by the application upon receiving a
  258. * @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist
  259. * advertising for fast and slow modes will not be run.
  260. *
  261. * @param[in] p_advertising Advertising Module instance.
  262. * @param[in] p_gap_addrs The list of GAP addresses to whitelist.
  263. * @param[in] addr_cnt The number of GAP addresses to whitelist.
  264. * @param[in] p_gap_irks The list of peer IRK to whitelist.
  265. * @param[in] irk_cnt The number of peer IRK to whitelist.
  266. *
  267. * @retval @ref NRF_SUCCESS If the operation was successful.
  268. * @retval @ref NRF_ERROR_INVALID_STATE If a call to this function was made without a
  269. * BLE_ADV_EVT_WHITELIST_REQUEST event being received.
  270. */
  271. uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
  272. ble_gap_addr_t const * p_gap_addrs,
  273. uint32_t addr_cnt,
  274. ble_gap_irk_t const * p_gap_irks,
  275. uint32_t irk_cnt);
  276. /**@brief Function for disabling whitelist advertising.
  277. *
  278. * @details This function temporarily disables whitelist advertising.
  279. * Calling this function resets the current time-out countdown.
  280. *
  281. * @param[in] p_advertising Advertising Module instance.
  282. *
  283. * @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice.
  284. */
  285. uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising);
  286. /**@brief Function for changing advertising modes configuration.
  287. *
  288. * @details This function can be called if you wish to reconfigure the advertising modes that the
  289. * Advertising Module will cycle through. Enable or disable modes as listed in
  290. * @ref ble_adv_mode_t; or change the duration of the advertising and use of whitelist.
  291. *
  292. * Keep in mind that @ref ble_adv_modes_config_t is also supplied when calling
  293. * @ref ble_advertising_init. Calling @ref ble_advertising_modes_config_set
  294. * is only necessary if your application requires this behaviour to change.
  295. *
  296. * @param[in] p_advertising Advertising Module instance.
  297. * @param[in] p_adv_modes_config Struct to keep track of disabled and enabled advertising modes,
  298. * as well as time-outs and intervals.
  299. */
  300. void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
  301. ble_adv_modes_config_t const * const p_adv_modes_config);
  302. /**@brief Function for updating advertising data.
  303. *
  304. * @details This function can be called if you wish to reconfigure the advertising data The update
  305. * will be effective even if advertising has already been started. If you set \p permanent
  306. * to true, the advertising data will be permanently updated inside the module instance.
  307. * Otherwise, the previous advertising data will be restored when there is transition to
  308. * the next advertising mode (@ref ble_adv_mode_t).
  309. *
  310. * @param[in] p_advertising Advertising Module instance.
  311. * @param[in] p_new_advdata_buf Struct containing new advertising data buffer and scan response
  312. * data buffer.
  313. * @param[in] permanent Indicates if the advertising data update should be persistent.
  314. *
  315. * @return NRF_SUCCESS or any error from @ref sd_ble_gap_adv_set_configure().
  316. */
  317. ret_code_t ble_advertising_advdata_update(ble_advertising_t * const p_advertising,
  318. ble_gap_adv_data_t * const p_new_advdata_buf,
  319. bool permanent);
  320. /** @} */
  321. #ifdef __cplusplus
  322. }
  323. #endif
  324. #endif // BLE_ADVERTISING_H__
  325. /** @} */