ble_advertising.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. */
  11. #include "ble_advdata.h"
  12. #include "ble_advertising.h"
  13. #include "nrf_soc.h"
  14. #include "nrf_log.h"
  15. #include "pstorage.h"
  16. #include "fstorage.h"
  17. #include "sdk_common.h"
  18. #define ADV_LOG(...)
  19. static bool m_advertising_start_pending = false; /**< Flag to keep track of ongoing operations on persistent memory. */
  20. static ble_gap_addr_t m_peer_address; /**< Address of the most recently connected peer, used for direct advertising. */
  21. static ble_advdata_t m_advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */
  22. static ble_adv_evt_t m_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.. */
  23. static ble_advertising_evt_handler_t m_evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */
  24. static ble_advertising_error_handler_t m_error_handler; /**< Handler for the advertising error events. */
  25. static ble_adv_mode_t m_adv_mode_current; /**< Variable to keep track of the current advertising mode. */
  26. static ble_adv_modes_config_t m_adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/
  27. static ble_gap_whitelist_t m_whitelist; /**< Struct that points to whitelisted addresses. */
  28. static ble_gap_addr_t * mp_whitelist_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; /**< Pointer to a list of addresses. Pointed to by the whitelist */
  29. static ble_gap_irk_t * mp_whitelist_irk[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; /**< Pointer to a list of Identity Resolving Keys (IRK). Pointed to by the whitelist */
  30. static bool m_whitelist_temporarily_disabled = false; /**< Flag to keep track of temporary disabling of the whitelist. */
  31. static bool m_whitelist_reply_expected = false; /**< Flag to verify that whitelist is only set when it is requested. */
  32. static bool m_peer_addr_reply_expected = false; /**< Flag to verify that peer address is only set when requested. */
  33. static ble_advdata_manuf_data_t m_manuf_specific_data; /**< Manufacturer specific data structure*/
  34. static uint8_t m_manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/
  35. static ble_advdata_service_data_t m_service_data; /**< Service data structure. */
  36. static uint8_t m_service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */
  37. static ble_advdata_conn_int_t m_slave_conn_int; /**< Connection interval range structure.*/
  38. static int8_t m_tx_power_level; /**< TX power level*/
  39. /**@brief Function for checking that the whitelist has entries.
  40. */
  41. static bool whitelist_has_entries(ble_gap_whitelist_t const * whitelist)
  42. {
  43. if ((whitelist->addr_count != 0) || (whitelist->irk_count != 0))
  44. {
  45. return true;
  46. }
  47. return false;
  48. }
  49. /**@brief Function for setting the stored peer address back to zero.
  50. */
  51. static void ble_advertising_peer_address_clear()
  52. {
  53. memset(&m_peer_address, 0, sizeof(m_peer_address));
  54. }
  55. /**@brief Function for checking if an address is non-zero. Used to determine if
  56. */
  57. static bool peer_address_exists(uint8_t const * address)
  58. {
  59. uint32_t i;
  60. for (i = 0; i < BLE_GAP_ADDR_LEN; i++)
  61. {
  62. if (address[i] != 0)
  63. {
  64. return true;
  65. }
  66. }
  67. return false;
  68. }
  69. uint32_t ble_advertising_init(ble_advdata_t const * p_advdata,
  70. ble_advdata_t const * p_srdata,
  71. ble_adv_modes_config_t const * p_config,
  72. ble_advertising_evt_handler_t const evt_handler,
  73. ble_advertising_error_handler_t const error_handler)
  74. {
  75. uint32_t err_code;
  76. VERIFY_PARAM_NOT_NULL(p_advdata);
  77. VERIFY_PARAM_NOT_NULL(p_config);
  78. m_adv_mode_current = BLE_ADV_MODE_IDLE;
  79. m_evt_handler = evt_handler;
  80. m_error_handler = error_handler;
  81. m_adv_modes_config = *p_config;
  82. ble_advertising_peer_address_clear();
  83. // Prepare Whitelist. Address and IRK double pointers point to allocated arrays.
  84. m_whitelist.pp_addrs = mp_whitelist_addr;
  85. m_whitelist.pp_irks = mp_whitelist_irk;
  86. // Copy and set advertising data.
  87. memset(&m_advdata, 0, sizeof(m_advdata));
  88. // Copy advertising data.
  89. m_advdata.name_type = p_advdata->name_type;
  90. m_advdata.include_appearance = p_advdata->include_appearance;
  91. m_advdata.flags = p_advdata->flags;
  92. m_advdata.short_name_len = p_advdata->short_name_len;
  93. /*
  94. if(p_advdata->uuids_complete != NULL)
  95. {
  96. m_advdata.uuids_complete = p_advdata->uuids_complete;
  97. }
  98. */
  99. m_advdata.uuids_complete = p_advdata->uuids_complete;
  100. m_advdata.uuids_more_available = p_advdata->uuids_more_available;
  101. m_advdata.uuids_solicited = p_advdata->uuids_solicited;
  102. if(p_advdata->p_manuf_specific_data != NULL)
  103. {
  104. m_advdata.p_manuf_specific_data = &m_manuf_specific_data;
  105. m_manuf_specific_data.data.p_data = m_manuf_data_array;
  106. m_advdata.p_manuf_specific_data->company_identifier =
  107. p_advdata->p_manuf_specific_data->company_identifier;
  108. m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size;
  109. for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++)
  110. {
  111. m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i];
  112. }
  113. }
  114. if(p_advdata->p_service_data_array != NULL)
  115. {
  116. m_service_data.data.p_data = m_service_data_array;
  117. m_advdata.p_service_data_array = &m_service_data;
  118. m_advdata.p_service_data_array->data.p_data = m_service_data_array;
  119. m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size;
  120. m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid;
  121. for(uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++)
  122. {
  123. m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i];
  124. }
  125. m_advdata.service_data_count = p_advdata->service_data_count;
  126. }
  127. if(p_advdata->p_slave_conn_int != NULL)
  128. {
  129. m_advdata.p_slave_conn_int = &m_slave_conn_int;
  130. m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval;
  131. m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval;
  132. }
  133. if(p_advdata->p_tx_power_level != NULL)
  134. {
  135. m_advdata.p_tx_power_level = &m_tx_power_level;
  136. m_advdata.p_tx_power_level = p_advdata->p_tx_power_level;
  137. }
  138. err_code = ble_advdata_set(&m_advdata, p_srdata);
  139. return err_code;
  140. }
  141. /** @brief Function to determine if a flash access in in progress. If it is the case, we can not
  142. * start advertising until it is finished. attempted restart
  143. * in @ref ble_advertising_on_sys_evt
  144. *
  145. * @return true if a flash access is in progress, false if not.
  146. */
  147. static bool flash_access_in_progress()
  148. {
  149. uint32_t err_code;
  150. uint32_t count = 0;
  151. err_code = pstorage_access_status_get(&count);
  152. if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_SUCCESS))
  153. {
  154. ADV_LOG("[ADV]: pstorage_access_status_get returned %d.\r\n", err_code);
  155. return true;
  156. }
  157. if (err_code == NRF_ERROR_INVALID_STATE)
  158. {
  159. err_code = fs_queued_op_count_get(&count);
  160. if (err_code != FS_SUCCESS)
  161. {
  162. return false;
  163. }
  164. ADV_LOG("[ADV]: fs_queued_op_count_get gives count %d.\r\n", count);
  165. }
  166. if(count != 0)
  167. {
  168. return true;
  169. }
  170. else
  171. {
  172. return false;
  173. }
  174. }
  175. uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode)
  176. {
  177. uint32_t err_code;
  178. ble_gap_adv_params_t adv_params;
  179. m_adv_mode_current = advertising_mode;
  180. // Verify if there are any pending flash operations. If so, delay starting advertising until
  181. // the flash operations are complete.
  182. if(flash_access_in_progress())
  183. {
  184. m_advertising_start_pending = true;
  185. return NRF_SUCCESS;
  186. }
  187. ADV_LOG("[ADV]: no flash operations in progress, prepare advertising.\r\n");
  188. // Fetch the peer address.
  189. ble_advertising_peer_address_clear();
  190. if ( ((m_adv_modes_config.ble_adv_directed_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
  191. ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED))
  192. ||((m_adv_modes_config.ble_adv_directed_slow_enabled) && (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW))
  193. )
  194. {
  195. if (m_evt_handler != NULL)
  196. {
  197. m_peer_addr_reply_expected = true;
  198. m_evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
  199. }
  200. else
  201. {
  202. m_peer_addr_reply_expected = false;
  203. }
  204. }
  205. // If a mode is disabled, continue to the next mode. I.e fast instead of direct, slow instead of fast, idle instead of slow.
  206. if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED)
  207. &&(!m_adv_modes_config.ble_adv_directed_enabled || !peer_address_exists(m_peer_address.addr)))
  208. {
  209. m_adv_mode_current = BLE_ADV_MODE_DIRECTED_SLOW;
  210. }
  211. if ( (m_adv_mode_current == BLE_ADV_MODE_DIRECTED_SLOW)
  212. &&(!m_adv_modes_config.ble_adv_directed_slow_enabled || !peer_address_exists(m_peer_address.addr)))
  213. {
  214. m_adv_mode_current = BLE_ADV_MODE_FAST;
  215. }
  216. if (!m_adv_modes_config.ble_adv_fast_enabled && m_adv_mode_current == BLE_ADV_MODE_FAST)
  217. {
  218. m_adv_mode_current = BLE_ADV_MODE_SLOW;
  219. }
  220. if (!m_adv_modes_config.ble_adv_slow_enabled && m_adv_mode_current == BLE_ADV_MODE_SLOW)
  221. {
  222. m_adv_mode_current = BLE_ADV_MODE_IDLE;
  223. m_adv_evt = BLE_ADV_EVT_IDLE;
  224. }
  225. // Fetch the whitelist.
  226. if ( (m_evt_handler != NULL)
  227. && (m_adv_mode_current == BLE_ADV_MODE_FAST || m_adv_mode_current == BLE_ADV_MODE_SLOW)
  228. && (m_adv_modes_config.ble_adv_whitelist_enabled)
  229. && (!m_whitelist_temporarily_disabled))
  230. {
  231. m_whitelist_reply_expected = true;
  232. m_evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
  233. }
  234. else
  235. {
  236. m_whitelist_reply_expected = false;
  237. }
  238. // Initialize advertising parameters with default values.
  239. memset(&adv_params, 0, sizeof(adv_params));
  240. adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
  241. adv_params.p_peer_addr = NULL;
  242. adv_params.fp = BLE_GAP_ADV_FP_ANY;
  243. adv_params.p_whitelist = NULL;
  244. // Set advertising parameters and events according to selected advertising mode.
  245. switch (m_adv_mode_current)
  246. {
  247. case BLE_ADV_MODE_DIRECTED:
  248. ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
  249. adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
  250. adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
  251. adv_params.timeout = 0;
  252. adv_params.interval = 0;
  253. m_adv_evt = BLE_ADV_EVT_DIRECTED;
  254. break;
  255. case BLE_ADV_MODE_DIRECTED_SLOW:
  256. ADV_LOG("[ADV]: Starting direct advertisement.\r\n");
  257. adv_params.p_peer_addr = &m_peer_address; // Directed advertising.
  258. adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND;
  259. adv_params.timeout = m_adv_modes_config.ble_adv_directed_slow_timeout;
  260. adv_params.interval = m_adv_modes_config.ble_adv_directed_slow_interval;
  261. m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW;
  262. break;
  263. case BLE_ADV_MODE_FAST:
  264. adv_params.timeout = m_adv_modes_config.ble_adv_fast_timeout;
  265. adv_params.interval = m_adv_modes_config.ble_adv_fast_interval;
  266. if ( whitelist_has_entries(&m_whitelist)
  267. && m_adv_modes_config.ble_adv_whitelist_enabled
  268. && !m_whitelist_temporarily_disabled)
  269. {
  270. adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
  271. adv_params.p_whitelist = &m_whitelist;
  272. m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
  273. err_code = ble_advdata_set(&m_advdata, NULL);
  274. VERIFY_SUCCESS(err_code);
  275. m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
  276. ADV_LOG("[ADV]: Starting fast advertisement with whitelist.\r\n");
  277. }
  278. else
  279. {
  280. m_adv_evt = BLE_ADV_EVT_FAST;
  281. ADV_LOG("[ADV]: Starting fast advertisement.\r\n");
  282. }
  283. break;
  284. case BLE_ADV_MODE_SLOW:
  285. adv_params.interval = m_adv_modes_config.ble_adv_slow_interval;
  286. adv_params.timeout = m_adv_modes_config.ble_adv_slow_timeout;
  287. if ( whitelist_has_entries(&m_whitelist)
  288. && m_adv_modes_config.ble_adv_whitelist_enabled
  289. && !m_whitelist_temporarily_disabled)
  290. {
  291. adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
  292. adv_params.p_whitelist = &m_whitelist;
  293. m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
  294. err_code = ble_advdata_set(&m_advdata, NULL);
  295. VERIFY_SUCCESS(err_code);
  296. m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
  297. ADV_LOG("[ADV]: Starting slow advertisement with whitelist.\r\n");
  298. }
  299. else
  300. {
  301. m_adv_evt = BLE_ADV_EVT_SLOW;
  302. ADV_LOG("[ADV]: Starting slow advertisement.\r\n");
  303. }
  304. break;
  305. default:
  306. break;
  307. }
  308. if (m_adv_mode_current != BLE_ADV_MODE_IDLE)
  309. {
  310. err_code = sd_ble_gap_adv_start(&adv_params);
  311. VERIFY_SUCCESS(err_code);
  312. }
  313. if (m_evt_handler != NULL)
  314. {
  315. m_evt_handler(m_adv_evt);
  316. }
  317. return NRF_SUCCESS;
  318. }
  319. void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt)
  320. {
  321. static uint16_t current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
  322. switch (p_ble_evt->header.evt_id)
  323. {
  324. case BLE_GAP_EVT_CONNECTED:
  325. if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
  326. {
  327. current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
  328. }
  329. break;
  330. // Upon disconnection, whitelist will be activated and direct advertising is started.
  331. case BLE_GAP_EVT_DISCONNECTED:
  332. {
  333. uint32_t err_code;
  334. m_whitelist_temporarily_disabled = false;
  335. if (p_ble_evt->evt.gap_evt.conn_handle == current_slave_link_conn_handle)
  336. {
  337. err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED);
  338. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  339. {
  340. m_error_handler(err_code);
  341. }
  342. }
  343. break;
  344. }
  345. // Upon time-out, the next advertising mode is started, i.e. go from fast to slow or from slow to idle.
  346. case BLE_GAP_EVT_TIMEOUT:
  347. if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING)
  348. {
  349. switch (m_adv_mode_current)
  350. {
  351. case BLE_ADV_MODE_DIRECTED:
  352. ADV_LOG("[ADV]: Timed out from directed advertising.\r\n");
  353. {
  354. uint32_t err_code;
  355. err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED_SLOW);
  356. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  357. {
  358. m_error_handler(err_code);
  359. }
  360. }
  361. break;
  362. case BLE_ADV_MODE_DIRECTED_SLOW:
  363. ADV_LOG("[ADV]: Timed out from directed slow advertising.\r\n");
  364. {
  365. uint32_t err_code;
  366. err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
  367. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  368. {
  369. m_error_handler(err_code);
  370. }
  371. }
  372. break;
  373. case BLE_ADV_MODE_FAST:
  374. {
  375. uint32_t err_code;
  376. m_adv_evt = BLE_ADV_EVT_FAST;
  377. ADV_LOG("[ADV]: Timed out from fast advertising, starting slow advertising.\r\n");
  378. err_code = ble_advertising_start(BLE_ADV_MODE_SLOW);
  379. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  380. {
  381. m_error_handler(err_code);
  382. }
  383. break;
  384. }
  385. case BLE_ADV_MODE_SLOW:
  386. m_adv_evt = BLE_ADV_EVT_IDLE;
  387. ADV_LOG("[ADV]: Timed out from slow advertising, stopping advertising.\r\n");
  388. if (m_evt_handler != NULL)
  389. {
  390. m_evt_handler(m_adv_evt);
  391. }
  392. break;
  393. default:
  394. // No implementation needed.
  395. break;
  396. }
  397. }
  398. break;
  399. default:
  400. // No implementation needed.
  401. break;
  402. }
  403. }
  404. void ble_advertising_on_sys_evt(uint32_t sys_evt)
  405. {
  406. uint32_t err_code = NRF_SUCCESS;
  407. switch (sys_evt)
  408. {
  409. case NRF_EVT_FLASH_OPERATION_SUCCESS:
  410. // Fall through.
  411. //When a flash operation finishes, advertising no longer needs to be pending.
  412. case NRF_EVT_FLASH_OPERATION_ERROR:
  413. if (m_advertising_start_pending)
  414. {
  415. m_advertising_start_pending = false;
  416. err_code = ble_advertising_start(m_adv_mode_current);
  417. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  418. {
  419. m_error_handler(err_code);
  420. }
  421. }
  422. break;
  423. default:
  424. // No implementation needed.
  425. break;
  426. }
  427. }
  428. uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_address)
  429. {
  430. if(m_peer_addr_reply_expected == false)
  431. {
  432. return NRF_ERROR_INVALID_STATE;
  433. }
  434. m_peer_address.addr_type = p_peer_address->addr_type;
  435. for (int i = 0; i < BLE_GAP_ADDR_LEN; i++)
  436. {
  437. m_peer_address.addr[i] = p_peer_address->addr[i];
  438. }
  439. m_peer_addr_reply_expected = false;
  440. return NRF_SUCCESS;
  441. }
  442. uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist)
  443. {
  444. uint32_t i;
  445. if(m_whitelist_reply_expected == false)
  446. {
  447. return NRF_ERROR_INVALID_STATE;
  448. }
  449. m_whitelist.addr_count = p_whitelist->addr_count;
  450. m_whitelist.irk_count = p_whitelist->irk_count;
  451. for (i = 0; i < m_whitelist.irk_count; i++)
  452. {
  453. mp_whitelist_irk[i] = p_whitelist->pp_irks[i];
  454. }
  455. for (i = 0; i < m_whitelist.addr_count; i++)
  456. {
  457. mp_whitelist_addr[i] = p_whitelist->pp_addrs[i];
  458. }
  459. m_whitelist_reply_expected = false;
  460. return NRF_SUCCESS;
  461. }
  462. uint32_t ble_advertising_restart_without_whitelist(void)
  463. {
  464. uint32_t err_code;
  465. if( m_adv_modes_config.ble_adv_whitelist_enabled == BLE_ADV_WHITELIST_ENABLED
  466. && !m_whitelist_temporarily_disabled)
  467. {
  468. if (m_adv_mode_current != BLE_ADV_MODE_IDLE)
  469. {
  470. err_code = sd_ble_gap_adv_stop();
  471. VERIFY_SUCCESS(err_code);
  472. }
  473. m_whitelist_temporarily_disabled = true;
  474. m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
  475. err_code = ble_advdata_set(&m_advdata, NULL);
  476. VERIFY_SUCCESS(err_code);
  477. err_code = ble_advertising_start(m_adv_mode_current);
  478. if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL))
  479. {
  480. m_error_handler(err_code);
  481. }
  482. }
  483. return NRF_SUCCESS;
  484. }