ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
nrf_ble_scan.c
Go to the documentation of this file.
1 
41 #include "sdk_common.h"
42 #if NRF_MODULE_ENABLED(NRF_BLE_SCAN)
43 
44 #include "sdk_config.h"
45 #include <stdlib.h>
46 
47 #include "nrf_ble_scan.h"
48 
49 #include <string.h>
50 #include "app_error.h"
51 #include "nrf_assert.h"
52 #include "sdk_macros.h"
53 #include "ble_advdata.h"
54 
55 #define NRF_LOG_MODULE_NAME ble_scan
56 #include "nrf_log.h"
58 
59 
71 static void nrf_ble_scan_connect_with_target(nrf_ble_scan_t const * const p_scan_ctx,
72  ble_gap_evt_adv_report_t const * const p_adv_report)
73 {
74  ret_code_t err_code;
75  scan_evt_t scan_evt;
76 
77  // For readability.
78  ble_gap_addr_t const * p_addr = &p_adv_report->peer_addr;
79  ble_gap_scan_params_t const * p_scan_params = &p_scan_ctx->scan_params;
80  ble_gap_conn_params_t const * p_conn_params = &p_scan_ctx->conn_params;
81  uint8_t con_cfg_tag = p_scan_ctx->conn_cfg_tag;
82 
83  // Return if the automatic connection is disabled.
84  if (!p_scan_ctx->connect_if_match)
85  {
86  return;
87  }
88 
89  // Stop scanning.
90  nrf_ble_scan_stop();
91 
92  memset(&scan_evt, 0, sizeof(scan_evt));
93 
94  // Establish connection.
95  err_code = sd_ble_gap_connect(p_addr,
96  p_scan_params,
97  p_conn_params,
98  con_cfg_tag);
99 
100  NRF_LOG_DEBUG("Connecting");
101 
102  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_CONNECTING_ERROR;
103  scan_evt.params.connecting_err.err_code = err_code;
104 
105  NRF_LOG_DEBUG("Connection status: %d", err_code);
106 
107  // If an error occurred, send an event to the event handler.
108  if ((err_code != NRF_SUCCESS) && (p_scan_ctx->evt_handler != NULL))
109  {
110  p_scan_ctx->evt_handler(&scan_evt);
111  }
112 
113 }
114 
115 
123 static uint16_t nrf_ble_scan_address_type_decode(uint8_t const * p_addr)
124 {
125  uint8_t addr_type = p_addr[0];
126 
127  // See Bluetooth Core Specification Vol 6, Part B, section 1.3.
128  addr_type = addr_type >> 6;
129  addr_type &= 0x03;
130 
131  // Check address type.
132  switch (addr_type)
133  {
134  case 0:
135  {
136  return BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE;
137  }
138 
139  case 1:
140  {
141  return BLE_GAP_ADDR_TYPE_PUBLIC;
142  }
143 
144  case 2:
145  {
146  return BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
147  }
148 
149  case 3:
150  {
151  return BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
152  }
153 
154  default:
155  {
156  return BLE_ERROR_GAP_INVALID_BLE_ADDR;
157  }
158  }
159 }
160 
161 
162 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
163 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
164 
175 static bool find_peer_addr(ble_gap_evt_adv_report_t const * const p_adv_report,
176  ble_gap_addr_t const * p_addr)
177 {
178  if (p_addr->addr_type == p_adv_report->peer_addr.addr_type)
179  {
180  // Compare addresses.
181  if (memcmp(p_addr->addr,
182  p_adv_report->peer_addr.addr,
183  sizeof(p_adv_report->peer_addr.addr)) == 0)
184  {
185  return true;
186  }
187  }
188  return false;
189 }
190 
191 
199 static bool adv_addr_compare(ble_gap_evt_adv_report_t const * const p_adv_report,
200  nrf_ble_scan_t const * const p_scan_ctx)
201 {
202  ble_gap_addr_t const * p_addr = p_scan_ctx->scan_filters.addr_filter.target_addr;
203  uint8_t counter = p_scan_ctx->scan_filters.addr_filter.addr_cnt;
204 
205  for (uint8_t index = 0; index < counter; index++)
206  {
207  // Search for address.
208  if (find_peer_addr(p_adv_report, &p_addr[index]))
209  {
210  return true;
211  }
212  }
213 
214  return false;
215 }
216 
217 
227 static ret_code_t nrf_ble_scan_addr_filter_add(nrf_ble_scan_t * const p_scan_ctx,
228  uint8_t const * p_addr)
229 {
230  ble_gap_addr_t * p_addr_filter = p_scan_ctx->scan_filters.addr_filter.target_addr;
231  uint8_t * p_counter = &p_scan_ctx->scan_filters.addr_filter.addr_cnt;
232  uint8_t index;
233  uint16_t addr_type;
234  uint8_t temp_addr[BLE_GAP_ADDR_LEN];
235 
236  // If no memory for filter.
237  if (*p_counter >= NRF_BLE_SCAN_ADDRESS_CNT)
238  {
239  return NRF_ERROR_NO_MEM;
240  }
241 
242  // Check for duplicated filter.
243  for (index = 0; index < NRF_BLE_SCAN_ADDRESS_CNT; index++)
244  {
245  if (!memcmp(p_addr_filter[index].addr, p_addr, BLE_GAP_ADDR_LEN))
246  {
247  return NRF_SUCCESS;
248  }
249  }
250 
251  // Inverting the address.
252  for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
253  {
254  temp_addr[i] = p_addr[(BLE_GAP_ADDR_LEN - 1) - i];
255  }
256 
257  // Decode address type.
258  addr_type = nrf_ble_scan_address_type_decode(temp_addr);
259 
260  if (addr_type == BLE_ERROR_GAP_INVALID_BLE_ADDR)
261  {
262  return BLE_ERROR_GAP_INVALID_BLE_ADDR;
263  }
264 
265  // Add target address to filter.
266  p_addr_filter[*p_counter].addr_type = (uint8_t)addr_type;
267 
268  for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
269  {
270  p_addr_filter[*p_counter].addr[i] = p_addr[i];
271  }
272 
273  NRF_LOG_DEBUG("Filter set on address type %i, address 0x",
274  p_addr_filter[*p_counter].addr_type);
275 
276  for (index = 0; index < BLE_GAP_ADDR_LEN; index++)
277  {
278  NRF_LOG_DEBUG("%x", p_addr_filter[*p_counter].addr[index]);
279  }
280 
281  NRF_LOG_DEBUG("\n\r");
282 
283  // Increase the address filter counter.
284  *p_counter += 1;
285 
286  return NRF_SUCCESS;
287 }
288 
289 
290 #endif // NRF_BLE_SCAN_ADDRESS_CNT
291 
292 
293 #if (NRF_BLE_SCAN_NAME_CNT > 0)
301 static bool adv_name_compare(ble_gap_evt_adv_report_t const * p_adv_report,
302  nrf_ble_scan_t const * const p_scan_ctx)
303 {
304  nrf_ble_scan_name_filter_t const * p_name_filter = &p_scan_ctx->scan_filters.name_filter;
305  uint8_t counter =
306  p_scan_ctx->scan_filters.name_filter.name_cnt;
307  uint8_t index;
308  uint16_t data_len;
309 
310  data_len = p_adv_report->data.len;
311 
312  // Compare the name found with the name filter.
313  for (index = 0; index < counter; index++)
314  {
315  if (ble_advdata_name_find(p_adv_report->data.p_data,
316  data_len,
317  p_name_filter->target_name[index]))
318  {
319  return true;
320  }
321  }
322 
323  return false;
324 }
325 
326 
337 static ret_code_t nrf_ble_scan_name_filter_add(nrf_ble_scan_t * const p_scan_ctx,
338  char const * p_name)
339 {
340  uint8_t index;
341  uint8_t * counter = &p_scan_ctx->scan_filters.name_filter.name_cnt;
342  uint8_t name_len = strlen(p_name);
343 
344  // Check the name length.
345  if ((name_len == 0) || (name_len > NRF_BLE_SCAN_NAME_MAX_LEN))
346  {
347  return NRF_ERROR_DATA_SIZE;
348  }
349 
350  // If no memory for filter.
351  if (*counter >= NRF_BLE_SCAN_NAME_CNT)
352  {
353  return NRF_ERROR_NO_MEM;
354  }
355 
356  // Check for duplicated filter.
357  for (index = 0; index < NRF_BLE_SCAN_NAME_CNT; index++)
358  {
359  if (!strcmp(p_scan_ctx->scan_filters.name_filter.target_name[index], p_name))
360  {
361  return NRF_SUCCESS;
362  }
363  }
364 
365  // Add name to filter.
366  memcpy(p_scan_ctx->scan_filters.name_filter.target_name[(*counter)++],
367  p_name,
368  strlen(p_name));
369 
370  NRF_LOG_DEBUG("Adding filter on %s name", p_name);
371 
372  return NRF_SUCCESS;
373 }
374 
375 
376 #endif // NRF_BLE_SCAN_NAME_CNT
377 
378 
379 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
387 static bool adv_short_name_compare(ble_gap_evt_adv_report_t const * const p_adv_report,
388  nrf_ble_scan_t const * const p_scan_ctx)
389 {
390  nrf_ble_scan_short_name_filter_t const * p_name_filter =
391  &p_scan_ctx->scan_filters.short_name_filter;
392  uint8_t counter = p_scan_ctx->scan_filters.short_name_filter.name_cnt;
393  uint8_t index;
394  uint16_t data_len;
395 
396  data_len = p_adv_report->data.len;
397 
398  // Compare the name found with the name filters.
399  for (index = 0; index < counter; index++)
400  {
401  if (ble_advdata_short_name_find(p_adv_report->data.p_data,
402  data_len,
403  p_name_filter->short_name[index].short_target_name,
404  p_name_filter->short_name[index].short_name_min_len))
405  {
406  return true;
407  }
408  }
409 
410  return false;
411 }
412 
413 
424 static ret_code_t nrf_ble_scan_short_name_filter_add(nrf_ble_scan_t * const p_scan_ctx,
425  nrf_ble_scan_short_name_t const * p_short_name)
426 {
427  uint8_t index;
428  uint8_t * p_counter =
429  &p_scan_ctx->scan_filters.short_name_filter.name_cnt;
430  nrf_ble_scan_short_name_filter_t * p_short_name_filter =
431  &p_scan_ctx->scan_filters.short_name_filter;
432  uint8_t name_len = strlen(p_short_name->p_short_name);
433 
434  // Check the name length.
435  if ((name_len == 0) || (name_len > NRF_BLE_SCAN_SHORT_NAME_MAX_LEN))
436  {
437  return NRF_ERROR_DATA_SIZE;
438  }
439 
440  // If no memory for filter.
441  if (*p_counter >= NRF_BLE_SCAN_SHORT_NAME_CNT)
442  {
443  return NRF_ERROR_NO_MEM;
444  }
445 
446  // Check for duplicated filter.
447  for (index = 0; index < NRF_BLE_SCAN_SHORT_NAME_CNT; index++)
448  {
449  if (!strcmp(p_short_name_filter->short_name[index].short_target_name,
450  p_short_name->p_short_name))
451  {
452  return NRF_SUCCESS;
453  }
454  }
455 
456  // Add name to the filter.
457  p_short_name_filter->short_name[(*p_counter)].short_name_min_len =
458  p_short_name->short_name_min_len;
459  memcpy(p_short_name_filter->short_name[(*p_counter)++].short_target_name,
460  p_short_name->p_short_name,
461  strlen(p_short_name->p_short_name));
462 
463  NRF_LOG_DEBUG("Adding filter on %s name", p_short_name->p_short_name);
464 
465  return NRF_SUCCESS;
466 }
467 
468 
469 #endif
470 
471 
472 #if (NRF_BLE_SCAN_UUID_CNT > 0)
480 static bool adv_uuid_compare(ble_gap_evt_adv_report_t const * const p_adv_report,
481  nrf_ble_scan_t const * const p_scan_ctx)
482 {
483  nrf_ble_scan_uuid_filter_t const * p_uuid_filter = &p_scan_ctx->scan_filters.uuid_filter;
484  bool const all_filters_mode = p_scan_ctx->scan_filters.all_filters_mode;
485  uint8_t const counter =
486  p_scan_ctx->scan_filters.uuid_filter.uuid_cnt;
487  uint8_t index;
488  uint16_t data_len;
489  uint8_t uuid_match_cnt = 0;
490 
491  data_len = p_adv_report->data.len;
492 
493  for (index = 0; index < counter; index++)
494  {
495 
496  if (ble_advdata_uuid_find(p_adv_report->data.p_data,
497  data_len,
498  &p_uuid_filter->uuid[index]))
499  {
500  uuid_match_cnt++;
501 
502  // In the normal filter mode, only one UUID is needed to match.
503  if (!all_filters_mode)
504  {
505  break;
506  }
507  }
508  else if (all_filters_mode)
509  {
510  break;
511  }
512  else
513  {
514  // Do nothing.
515  }
516  }
517 
518  // In the multifilter mode, all UUIDs must be found in the advertisement packets.
519  if ((all_filters_mode && (uuid_match_cnt == counter)) ||
520  ((!all_filters_mode) && (uuid_match_cnt > 0)))
521  {
522  return true;
523  }
524 
525  return false;
526 }
527 
528 
537 static ret_code_t nrf_ble_scan_uuid_filter_add(nrf_ble_scan_t * const p_scan_ctx,
538  ble_uuid_t const * p_uuid)
539 {
540  ble_uuid_t * p_uuid_filter = p_scan_ctx->scan_filters.uuid_filter.uuid;
541  uint8_t * p_counter = &p_scan_ctx->scan_filters.uuid_filter.uuid_cnt;
542  uint8_t index;
543 
544  // If no memory.
545  if (*p_counter >= NRF_BLE_SCAN_UUID_CNT)
546  {
547  return NRF_ERROR_NO_MEM;
548  }
549 
550  // Check for duplicated filter.
551  for (index = 0; index < NRF_BLE_SCAN_UUID_CNT; index++)
552  {
553  if (p_uuid_filter[index].uuid == p_uuid->uuid)
554  {
555  return NRF_SUCCESS;
556  }
557  }
558 
559  // Add UUID to the filter.
560  p_uuid_filter[(*p_counter)++] = *p_uuid;
561  NRF_LOG_DEBUG("Added filter on UUID %x", p_uuid->uuid);
562 
563  return NRF_SUCCESS;
564 }
565 
566 
567 #endif // NRF_BLE_SCAN_UUID_CNT
568 
569 
570 #if (NRF_BLE_SCAN_APPEARANCE_CNT)
578 static bool adv_appearance_compare(ble_gap_evt_adv_report_t const * const p_adv_report,
579  nrf_ble_scan_t const * const p_scan_ctx)
580 {
581  nrf_ble_scan_appearance_filter_t const * p_appearance_filter =
582  &p_scan_ctx->scan_filters.appearance_filter;
583  uint8_t const counter =
584  p_scan_ctx->scan_filters.appearance_filter.appearance_cnt;
585  uint8_t index;
586  uint16_t data_len;
587 
588  data_len = p_adv_report->data.len;
589 
590  // Verify if the advertised appearance matches the provided appearance.
591  for (index = 0; index < counter; index++)
592  {
593  if (ble_advdata_appearance_find(p_adv_report->data.p_data,
594  data_len,
595  &p_appearance_filter->appearance[index]))
596  {
597  return true;
598  }
599  }
600  return false;
601 }
602 
603 
613 static ret_code_t nrf_ble_scan_appearance_filter_add(nrf_ble_scan_t * const p_scan_ctx,
614  uint16_t appearance)
615 {
616  uint16_t * p_appearance_filter = p_scan_ctx->scan_filters.appearance_filter.appearance;
617  uint8_t * p_counter = &p_scan_ctx->scan_filters.appearance_filter.appearance_cnt;
618  uint8_t index;
619 
620  // If no memory.
621  if (*p_counter >= NRF_BLE_SCAN_APPEARANCE_CNT)
622  {
623  return NRF_ERROR_NO_MEM;
624  }
625 
626  // Check for duplicated filter.
627  for ( index = 0; index < NRF_BLE_SCAN_APPEARANCE_CNT; index++)
628  {
629  if (p_appearance_filter[index] == appearance)
630  {
631  return NRF_SUCCESS;
632  }
633  }
634 
635  // Add appearance to the filter.
636  p_appearance_filter[(*p_counter)++] = appearance;
637  NRF_LOG_DEBUG("Added filter on appearance %x", appearance);
638  return NRF_SUCCESS;
639 }
640 
641 
642 #endif // NRF_BLE_SCAN_APPEARANCE_CNT
643 
644 
645 ret_code_t nrf_ble_scan_filter_set(nrf_ble_scan_t * const p_scan_ctx,
646  nrf_ble_scan_filter_type_t type,
647  void const * p_data)
648 {
649  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
650  VERIFY_PARAM_NOT_NULL(p_data);
651 
652  switch (type)
653  {
654 #if (NRF_BLE_SCAN_NAME_CNT > 0)
655  case SCAN_NAME_FILTER:
656  {
657  char * p_name = (char *)p_data;
658  return nrf_ble_scan_name_filter_add(p_scan_ctx, p_name);
659  }
660 #endif
661 
662 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
663  case SCAN_SHORT_NAME_FILTER:
664  {
665  nrf_ble_scan_short_name_t * p_short_name = (nrf_ble_scan_short_name_t *)p_data;
666  return nrf_ble_scan_short_name_filter_add(p_scan_ctx, p_short_name);
667  }
668 #endif
669 
670 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
671  case SCAN_ADDR_FILTER:
672  {
673  uint8_t * p_addr = (uint8_t *)p_data;
674  return nrf_ble_scan_addr_filter_add(p_scan_ctx, p_addr);
675  }
676 #endif
677 
678 #if (NRF_BLE_SCAN_UUID_CNT > 0)
679  case SCAN_UUID_FILTER:
680  {
681  ble_uuid_t * p_uuid = (ble_uuid_t *)p_data;
682  return nrf_ble_scan_uuid_filter_add(p_scan_ctx, p_uuid);
683  }
684 #endif
685 
686 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
687  case SCAN_APPEARANCE_FILTER:
688  {
689  uint16_t appearance = *((uint16_t *)p_data);
690  return nrf_ble_scan_appearance_filter_add(p_scan_ctx, appearance);
691  }
692 #endif
693 
694  default:
695  return NRF_ERROR_INVALID_PARAM;
696  }
697 }
698 
699 
700 ret_code_t nrf_ble_scan_all_filter_remove(nrf_ble_scan_t * const p_scan_ctx)
701 {
702 #if (NRF_BLE_SCAN_NAME_CNT > 0)
703  nrf_ble_scan_name_filter_t * p_name_filter = &p_scan_ctx->scan_filters.name_filter;
704  memset(p_name_filter->target_name, 0, sizeof(p_name_filter->target_name));
705  p_name_filter->name_cnt = 0;
706 #endif
707 
708 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
709  nrf_ble_scan_short_name_filter_t * p_short_name_filter =
710  &p_scan_ctx->scan_filters.short_name_filter;
711  memset(p_short_name_filter->short_name, 0, sizeof(p_short_name_filter->short_name));
712  p_short_name_filter->name_cnt = 0;
713 #endif
714 
715 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
716  nrf_ble_scan_addr_filter_t * p_addr_filter = &p_scan_ctx->scan_filters.addr_filter;
717  memset(p_addr_filter->target_addr, 0, sizeof(p_addr_filter->target_addr));
718  p_addr_filter->addr_cnt = 0;
719 #endif
720 
721 #if (NRF_BLE_SCAN_UUID_CNT > 0)
722  nrf_ble_scan_uuid_filter_t * p_uuid_filter = &p_scan_ctx->scan_filters.uuid_filter;
723  memset(p_uuid_filter->uuid, 0, sizeof(p_uuid_filter->uuid));
724  p_uuid_filter->uuid_cnt = 0;
725 #endif
726 
727 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
728  nrf_ble_scan_appearance_filter_t * p_appearance_filter =
729  &p_scan_ctx->scan_filters.appearance_filter;
730  memset(p_appearance_filter->appearance, 0, sizeof(p_appearance_filter->appearance));
731  p_appearance_filter->appearance_cnt = 0;
732 #endif
733 
734  return NRF_SUCCESS;
735 }
736 
737 
738 ret_code_t nrf_ble_scan_filters_enable(nrf_ble_scan_t * const p_scan_ctx,
739  uint8_t mode,
740  bool match_all)
741 {
742  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
743 
744  // Check if the mode is correct.
745  if ((!(mode & NRF_BLE_SCAN_ADDR_FILTER)) &&
746  (!(mode & NRF_BLE_SCAN_NAME_FILTER)) &&
747  (!(mode & NRF_BLE_SCAN_UUID_FILTER)) &&
748  (!(mode & NRF_BLE_SCAN_SHORT_NAME_FILTER)) &&
749  (!(mode & NRF_BLE_SCAN_APPEARANCE_FILTER)))
750  {
751  return NRF_ERROR_INVALID_PARAM;
752  }
753 
754  ret_code_t err_code;
755 
756  // Disable filters.
757  err_code = nrf_ble_scan_filters_disable(p_scan_ctx);
758  ASSERT(err_code == NRF_SUCCESS);
759 
760  nrf_ble_scan_filters_t * p_filters = &p_scan_ctx->scan_filters;
761 
762  // Turn on the filters of your choice.
763 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
764  if (mode & NRF_BLE_SCAN_ADDR_FILTER)
765  {
766  p_filters->addr_filter.addr_filter_enabled = true;
767  }
768 #endif
769 
770 #if (NRF_BLE_SCAN_NAME_CNT > 0)
771  if (mode & NRF_BLE_SCAN_NAME_FILTER)
772  {
773  p_filters->name_filter.name_filter_enabled = true;
774  }
775 #endif
776 
777 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
778  if (mode & NRF_BLE_SCAN_SHORT_NAME_FILTER)
779  {
780  p_filters->short_name_filter.short_name_filter_enabled = true;
781  }
782 #endif
783 
784 #if (NRF_BLE_SCAN_UUID_CNT > 0)
785  if (mode & NRF_BLE_SCAN_UUID_FILTER)
786  {
787  p_filters->uuid_filter.uuid_filter_enabled = true;
788  }
789 #endif
790 
791 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
792  if (mode & NRF_BLE_SCAN_APPEARANCE_FILTER)
793  {
794  p_filters->appearance_filter.appearance_filter_enabled = true;
795  }
796 #endif
797 
798  // Select the filter mode.
799  p_filters->all_filters_mode = match_all;
800 
801  return NRF_SUCCESS;
802 }
803 
804 
805 ret_code_t nrf_ble_scan_filters_disable(nrf_ble_scan_t * const p_scan_ctx)
806 {
807  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
808 
809  // Disable all filters.
810 #if (NRF_BLE_SCAN_NAME_CNT > 0)
811  bool * p_name_filter_enabled = &p_scan_ctx->scan_filters.name_filter.name_filter_enabled;
812  *p_name_filter_enabled = false;
813 #endif
814 
815 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
816  bool * p_addr_filter_enabled = &p_scan_ctx->scan_filters.addr_filter.addr_filter_enabled;
817  *p_addr_filter_enabled = false;
818 #endif
819 
820 #if (NRF_BLE_SCAN_UUID_CNT > 0)
821  bool * p_uuid_filter_enabled = &p_scan_ctx->scan_filters.uuid_filter.uuid_filter_enabled;
822  *p_uuid_filter_enabled = false;
823 #endif
824 
825 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
826  bool * p_appearance_filter_enabled =
827  &p_scan_ctx->scan_filters.appearance_filter.appearance_filter_enabled;
828  *p_appearance_filter_enabled = false;
829 #endif
830 
831  return NRF_SUCCESS;
832 }
833 
834 
835 ret_code_t nrf_ble_scan_filter_get(nrf_ble_scan_t * const p_scan_ctx,
836  nrf_ble_scan_filters_t * p_status)
837 {
838  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
839  VERIFY_PARAM_NOT_NULL(p_status);
840 
841  *p_status = p_scan_ctx->scan_filters;
842 
843  return NRF_SUCCESS;
844 }
845 
846 
847 #endif // NRF_BLE_SCAN_FILTER_ENABLE
848 
855 static void nrf_ble_scan_on_adv_report(nrf_ble_scan_t const * const p_scan_ctx,
856  ble_gap_evt_adv_report_t const * const p_adv_report)
857 {
858  scan_evt_t scan_evt;
859 
860 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
861  uint8_t filter_cnt = 0;
862  uint8_t filter_match_cnt = 0;
863 #endif
864 
865  memset(&scan_evt, 0, sizeof(scan_evt));
866 
867  scan_evt.p_scan_params = &p_scan_ctx->scan_params;
868 
869  // If the whitelist is used, do not check the filters and return.
870  if (is_whitelist_used(p_scan_ctx))
871  {
872  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT;
873  scan_evt.params.p_not_found = p_adv_report;
874  p_scan_ctx->evt_handler(&scan_evt);
875 
876  UNUSED_RETURN_VALUE(sd_ble_gap_scan_start(NULL, &p_scan_ctx->scan_buffer));
877  nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
878 
879  return;
880  }
881 
882 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
883  bool const all_filter_mode = p_scan_ctx->scan_filters.all_filters_mode;
884  bool is_filter_matched = false;
885 
886 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
887  bool const addr_filter_enabled = p_scan_ctx->scan_filters.addr_filter.addr_filter_enabled;
888 #endif
889 
890 #if (NRF_BLE_SCAN_NAME_CNT > 0)
891  bool const name_filter_enabled = p_scan_ctx->scan_filters.name_filter.name_filter_enabled;
892 #endif
893 
894 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
895  bool const short_name_filter_enabled =
896  p_scan_ctx->scan_filters.short_name_filter.short_name_filter_enabled;
897 #endif
898 
899 #if (NRF_BLE_SCAN_UUID_CNT > 0)
900  bool const uuid_filter_enabled = p_scan_ctx->scan_filters.uuid_filter.uuid_filter_enabled;
901 #endif
902 
903 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
904  bool const appearance_filter_enabled =
905  p_scan_ctx->scan_filters.appearance_filter.appearance_filter_enabled;
906 #endif
907 
908 
909 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
910  // Check the address filter.
911  if (addr_filter_enabled)
912  {
913  // Number of active filters.
914  filter_cnt++;
915  if (adv_addr_compare(p_adv_report, p_scan_ctx))
916  {
917  // Number of filters matched.
918  filter_match_cnt++;
919  // Information about the filters matched.
920  scan_evt.params.filter_match.filter_match.address_filter_match = true;
921  is_filter_matched = true;
922  }
923  }
924 #endif
925 
926 #if (NRF_BLE_SCAN_NAME_CNT > 0)
927  // Check the name filter.
928  if (name_filter_enabled)
929  {
930  filter_cnt++;
931  if (adv_name_compare(p_adv_report, p_scan_ctx))
932  {
933  filter_match_cnt++;
934 
935  // Information about the filters matched.
936  scan_evt.params.filter_match.filter_match.name_filter_match = true;
937  is_filter_matched = true;
938  }
939  }
940 #endif
941 
942 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
943  if (short_name_filter_enabled)
944  {
945  filter_cnt++;
946  if (adv_short_name_compare(p_adv_report, p_scan_ctx))
947  {
948  filter_match_cnt++;
949 
950  // Information about the filters matched.
951  scan_evt.params.filter_match.filter_match.short_name_filter_match = true;
952  is_filter_matched = true;
953  }
954  }
955 #endif
956 
957 #if (NRF_BLE_SCAN_UUID_CNT > 0)
958  // Check the UUID filter.
959  if (uuid_filter_enabled)
960  {
961  filter_cnt++;
962  if (adv_uuid_compare(p_adv_report, p_scan_ctx))
963  {
964  filter_match_cnt++;
965  // Information about the filters matched.
966  scan_evt.params.filter_match.filter_match.uuid_filter_match = true;
967  is_filter_matched = true;
968  }
969  }
970 #endif
971 
972 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
973  // Check the appearance filter.
974  if (appearance_filter_enabled)
975  {
976  filter_cnt++;
977  if (adv_appearance_compare(p_adv_report, p_scan_ctx))
978  {
979  filter_match_cnt++;
980  // Information about the filters matched.
981  scan_evt.params.filter_match.filter_match.appearance_filter_match = true;
982  is_filter_matched = true;
983  }
984  }
985 
986  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
987 #endif
988 
989  scan_evt.params.filter_match.p_adv_report = p_adv_report;
990 
991  // In the multifilter mode, the number of the active filters must equal the number of the filters matched to generate the notification.
992  if (all_filter_mode && (filter_match_cnt == filter_cnt))
993  {
994  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
995  nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
996  }
997  // In the normal filter mode, only one filter match is needed to generate the notification to the main application.
998  else if ((!all_filter_mode) && is_filter_matched)
999  {
1000  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
1001  nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
1002  }
1003  else
1004  {
1005  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
1006  scan_evt.params.p_not_found = p_adv_report;
1007 
1008  }
1009 
1010 #else // NRF_BLE_SCAN_FILTER_ENABLE
1011  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
1012  scan_evt.params.p_not_found = p_adv_report;
1013 #endif
1014 
1015  // If the event handler is not NULL, notify the main application.
1016  if (p_scan_ctx->evt_handler != NULL)
1017  {
1018  p_scan_ctx->evt_handler(&scan_evt);
1019  }
1020 
1021  // Resume the scanning.
1022  UNUSED_RETURN_VALUE(sd_ble_gap_scan_start(NULL, &p_scan_ctx->scan_buffer));
1023 }
1024 
1025 
1030 bool is_whitelist_used(nrf_ble_scan_t const * const p_scan_ctx)
1031 {
1032  if (p_scan_ctx->scan_params.filter_policy == BLE_GAP_SCAN_FP_WHITELIST ||
1033  p_scan_ctx->scan_params.filter_policy == BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED)
1034  {
1035  return true;
1036  }
1037 
1038  return false;
1039 }
1040 
1041 
1046 static void nrf_ble_scan_default_param_set(nrf_ble_scan_t * const p_scan_ctx)
1047 {
1048  // Set the default parameters.
1049  p_scan_ctx->scan_params.active = 1;
1050  p_scan_ctx->scan_params.interval = NRF_BLE_SCAN_SCAN_INTERVAL;
1051  p_scan_ctx->scan_params.window = NRF_BLE_SCAN_SCAN_WINDOW;
1052  p_scan_ctx->scan_params.timeout = NRF_BLE_SCAN_SCAN_DURATION;
1053  p_scan_ctx->scan_params.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL;
1054  p_scan_ctx->scan_params.scan_phys = BLE_GAP_PHY_1MBPS;
1055 }
1056 
1057 
1062 static void nrf_ble_scan_default_conn_param_set(nrf_ble_scan_t * const p_scan_ctx)
1063 {
1064  p_scan_ctx->conn_params.conn_sup_timeout =
1065  (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_SUPERVISION_TIMEOUT, UNIT_10_MS);
1066  p_scan_ctx->conn_params.min_conn_interval =
1067  (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL, UNIT_1_25_MS);
1068  p_scan_ctx->conn_params.max_conn_interval =
1069  (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL, UNIT_1_25_MS);
1070  p_scan_ctx->conn_params.slave_latency =
1071  (uint16_t)NRF_BLE_SCAN_SLAVE_LATENCY;
1072 }
1073 
1074 
1080 static void nrf_ble_scan_on_timeout(nrf_ble_scan_t const * const p_scan_ctx,
1081  ble_gap_evt_t const * const p_gap)
1082 {
1083  ble_gap_evt_timeout_t const * p_timeout = &p_gap->params.timeout;
1084  scan_evt_t scan_evt;
1085 
1086  memset(&scan_evt, 0, sizeof(scan_evt));
1087 
1088  if (p_timeout->src == BLE_GAP_TIMEOUT_SRC_SCAN)
1089  {
1090  NRF_LOG_DEBUG("BLE_GAP_SCAN_TIMEOUT");
1091  if (p_scan_ctx->evt_handler != NULL)
1092  {
1093  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_SCAN_TIMEOUT;
1094  scan_evt.p_scan_params = &p_scan_ctx->scan_params;
1095  scan_evt.params.timeout.src = p_timeout->src;
1096 
1097  p_scan_ctx->evt_handler(&scan_evt);
1098  }
1099  }
1100 }
1101 
1102 
1108 static void nrf_ble_scan_on_req_report(nrf_ble_scan_t const * const p_scan_ctx,
1109  ble_gap_evt_t const * const p_gap)
1110 {
1111  ble_gap_evt_scan_req_report_t const * p_req_report = &p_gap->params.scan_req_report;
1112  scan_evt_t scan_evt;
1113 
1114  memset(&scan_evt, 0, sizeof(scan_evt));
1115 
1116  if (p_scan_ctx->evt_handler != NULL)
1117  {
1118  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_SCAN_REQ_REPORT;
1119  scan_evt.p_scan_params = &p_scan_ctx->scan_params;
1120  scan_evt.params.req_report = *p_req_report;
1121 
1122  p_scan_ctx->evt_handler(&scan_evt);
1123  }
1124 }
1125 
1126 
1129 void nrf_ble_scan_stop(void)
1130 {
1131  // It is ok to ignore the function return value here, because this function can return NRF_SUCCESS or
1132  // NRF_ERROR_INVALID_STATE, when app is not in the scanning state.
1133  UNUSED_RETURN_VALUE(sd_ble_gap_scan_stop());
1134 }
1135 
1136 
1137 ret_code_t nrf_ble_scan_init(nrf_ble_scan_t * const p_scan_ctx,
1138  nrf_ble_scan_init_t const * const p_init,
1139  nrf_ble_scan_evt_handler_t evt_handler)
1140 {
1141  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1142 
1143  p_scan_ctx->evt_handler = evt_handler;
1144 
1145 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
1146  // Disable all scanning filters.
1147  memset(&p_scan_ctx->scan_filters, 0, sizeof(p_scan_ctx->scan_filters));
1148 #endif
1149 
1150  // If the pointer to the initialization structure exist, use it to scan the configuration.
1151  if (p_init != NULL)
1152  {
1153  p_scan_ctx->connect_if_match = p_init->connect_if_match;
1154  p_scan_ctx->conn_cfg_tag = p_init->conn_cfg_tag;
1155 
1156  if (p_init->p_scan_param != NULL)
1157  {
1158  p_scan_ctx->scan_params = *p_init->p_scan_param;
1159  }
1160  else
1161  {
1162  // Use the default static configuration.
1163  nrf_ble_scan_default_param_set(p_scan_ctx);
1164  }
1165 
1166  if (p_init->p_conn_param != NULL)
1167  {
1168  p_scan_ctx->conn_params = *p_init->p_conn_param;
1169  }
1170  else
1171  {
1172  // Use the default static configuration.
1173  nrf_ble_scan_default_conn_param_set(p_scan_ctx);
1174  }
1175  }
1176  // If pointer is NULL, use the static default configuration.
1177  else
1178  {
1179  nrf_ble_scan_default_param_set(p_scan_ctx);
1180  nrf_ble_scan_default_conn_param_set(p_scan_ctx);
1181 
1182  p_scan_ctx->connect_if_match = false;
1183  }
1184 
1185  // Assign a buffer where the advertising reports are to be stored by the SoftDevice.
1186  p_scan_ctx->scan_buffer.p_data = p_scan_ctx->scan_buffer_data;
1187  p_scan_ctx->scan_buffer.len = NRF_BLE_SCAN_BUFFER;
1188 
1189  return NRF_SUCCESS;
1190 }
1191 
1192 
1193 ret_code_t nrf_ble_scan_start(nrf_ble_scan_t const * const p_scan_ctx)
1194 {
1195  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1196 
1197  ret_code_t err_code;
1198  scan_evt_t scan_evt;
1199 
1200  memset(&scan_evt, 0, sizeof(scan_evt));
1201 
1202  nrf_ble_scan_stop();
1203 
1204  // If the whitelist is used and the event handler is not NULL, send the whitelist request to the main application.
1205  if (is_whitelist_used(p_scan_ctx))
1206  {
1207  if (p_scan_ctx->evt_handler != NULL)
1208  {
1209  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_WHITELIST_REQUEST;
1210  p_scan_ctx->evt_handler(&scan_evt);
1211  }
1212  }
1213 
1214  // Start the scanning.
1215  err_code = sd_ble_gap_scan_start(&p_scan_ctx->scan_params, &p_scan_ctx->scan_buffer);
1216 
1217  // It is okay to ignore this error, because the scan stopped earlier.
1218  if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_SUCCESS))
1219  {
1220  NRF_LOG_ERROR("sd_ble_gap_scan_start returned 0x%x", err_code);
1221  return (err_code);
1222  }
1223  NRF_LOG_DEBUG("Scanning");
1224 
1225  return NRF_SUCCESS;
1226 }
1227 
1228 
1229 ret_code_t nrf_ble_scan_params_set(nrf_ble_scan_t * const p_scan_ctx,
1230  ble_gap_scan_params_t const * const p_scan_param)
1231 {
1232  VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1233 
1234  nrf_ble_scan_stop();
1235 
1236  if (p_scan_param != NULL)
1237  {
1238  // Assign new scanning parameters.
1239  p_scan_ctx->scan_params = *p_scan_param;
1240  }
1241  else
1242  {
1243  // If NULL, use the default static configuration.
1244  nrf_ble_scan_default_param_set(p_scan_ctx);
1245  }
1246 
1247  NRF_LOG_DEBUG("Scanning parameters have been changed successfully");
1248 
1249  return NRF_SUCCESS;
1250 }
1251 
1252 
1258 static void nrf_ble_scan_on_connected_evt(nrf_ble_scan_t const * const p_scan_ctx,
1259  ble_gap_evt_t const * const p_gap_evt)
1260 {
1261  scan_evt_t scan_evt;
1262 
1263  memset(&scan_evt, 0, sizeof(scan_evt));
1264  scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_CONNECTED;
1265  scan_evt.params.connected.p_connected = &p_gap_evt->params.connected;
1266  scan_evt.params.connected.conn_handle = p_gap_evt->conn_handle;
1267  scan_evt.p_scan_params = &p_scan_ctx->scan_params;
1268 
1269  if (p_scan_ctx->evt_handler != NULL)
1270  {
1271  p_scan_ctx->evt_handler(&scan_evt);
1272  }
1273 }
1274 
1275 
1276 ret_code_t nrf_ble_scan_copy_addr_to_sd_gap_addr(ble_gap_addr_t * p_gap_addr,
1277  const uint8_t addr[BLE_GAP_ADDR_LEN])
1278 {
1279  uint16_t addr_type;
1280 
1281  addr_type = nrf_ble_scan_address_type_decode(addr);
1282 
1283  if (addr_type == BLE_ERROR_GAP_INVALID_BLE_ADDR)
1284  {
1285  return BLE_ERROR_GAP_INVALID_BLE_ADDR;
1286  }
1287 
1288  p_gap_addr->addr_type = addr_type;
1289 
1290  for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; ++i)
1291  {
1292  p_gap_addr->addr[i] = addr[BLE_GAP_ADDR_LEN - (i + 1)];
1293  }
1294 
1295  return NRF_SUCCESS;
1296 }
1297 
1298 
1299 void nrf_ble_scan_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_contex)
1300 {
1301  nrf_ble_scan_t * p_scan_data = (nrf_ble_scan_t *)p_contex;
1302  ble_gap_evt_adv_report_t const * p_adv_report = &p_ble_evt->evt.gap_evt.params.adv_report;
1303  ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
1304 
1305  switch (p_ble_evt->header.evt_id)
1306  {
1307  case BLE_GAP_EVT_ADV_REPORT:
1308  nrf_ble_scan_on_adv_report(p_scan_data, p_adv_report);
1309  break;
1310 
1311  case BLE_GAP_EVT_TIMEOUT:
1312  nrf_ble_scan_on_timeout(p_scan_data, p_gap_evt);
1313  break;
1314 
1315  case BLE_GAP_EVT_SCAN_REQ_REPORT:
1316  nrf_ble_scan_on_req_report(p_scan_data, p_gap_evt);
1317 
1318  break;
1319 
1320  case BLE_GAP_EVT_CONNECTED:
1321  nrf_ble_scan_on_connected_evt(p_scan_data, p_gap_evt);
1322  break;
1323 
1324  default:
1325  break;
1326  }
1327 }
1328 
1329 
1330 #endif // NRF_BLE_SCAN_ENABLED
1331 
NRF_LOG_MODULE_REGISTER()