41 #include "sdk_common.h"
42 #if NRF_MODULE_ENABLED(NRF_BLE_SCAN)
47 #include "nrf_ble_scan.h"
50 #include "app_error.h"
51 #include "nrf_assert.h"
52 #include "sdk_macros.h"
53 #include "ble_advdata.h"
55 #define NRF_LOG_MODULE_NAME ble_scan
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)
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;
84 if (!p_scan_ctx->connect_if_match)
92 memset(&scan_evt, 0,
sizeof(scan_evt));
95 err_code = sd_ble_gap_connect(p_addr,
100 NRF_LOG_DEBUG(
"Connecting");
102 scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_CONNECTING_ERROR;
103 scan_evt.params.connecting_err.err_code = err_code;
105 NRF_LOG_DEBUG(
"Connection status: %d", err_code);
108 if ((err_code != NRF_SUCCESS) && (p_scan_ctx->evt_handler != NULL))
110 p_scan_ctx->evt_handler(&scan_evt);
123 static uint16_t nrf_ble_scan_address_type_decode(uint8_t
const * p_addr)
125 uint8_t addr_type = p_addr[0];
128 addr_type = addr_type >> 6;
136 return BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE;
141 return BLE_GAP_ADDR_TYPE_PUBLIC;
146 return BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
151 return BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
156 return BLE_ERROR_GAP_INVALID_BLE_ADDR;
162 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
163 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
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)
178 if (p_addr->addr_type == p_adv_report->peer_addr.addr_type)
181 if (memcmp(p_addr->addr,
182 p_adv_report->peer_addr.addr,
183 sizeof(p_adv_report->peer_addr.addr)) == 0)
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)
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;
205 for (uint8_t index = 0; index < counter; index++)
208 if (find_peer_addr(p_adv_report, &p_addr[index]))
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)
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;
234 uint8_t temp_addr[BLE_GAP_ADDR_LEN];
237 if (*p_counter >= NRF_BLE_SCAN_ADDRESS_CNT)
239 return NRF_ERROR_NO_MEM;
243 for (index = 0; index < NRF_BLE_SCAN_ADDRESS_CNT; index++)
245 if (!memcmp(p_addr_filter[index].addr, p_addr, BLE_GAP_ADDR_LEN))
252 for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
254 temp_addr[i] = p_addr[(BLE_GAP_ADDR_LEN - 1) - i];
258 addr_type = nrf_ble_scan_address_type_decode(temp_addr);
260 if (addr_type == BLE_ERROR_GAP_INVALID_BLE_ADDR)
262 return BLE_ERROR_GAP_INVALID_BLE_ADDR;
266 p_addr_filter[*p_counter].addr_type = (uint8_t)addr_type;
268 for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
270 p_addr_filter[*p_counter].addr[i] = p_addr[i];
273 NRF_LOG_DEBUG(
"Filter set on address type %i, address 0x",
274 p_addr_filter[*p_counter].addr_type);
276 for (index = 0; index < BLE_GAP_ADDR_LEN; index++)
278 NRF_LOG_DEBUG(
"%x", p_addr_filter[*p_counter].addr[index]);
281 NRF_LOG_DEBUG(
"\n\r");
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)
304 nrf_ble_scan_name_filter_t
const * p_name_filter = &p_scan_ctx->scan_filters.name_filter;
306 p_scan_ctx->scan_filters.name_filter.name_cnt;
310 data_len = p_adv_report->data.len;
313 for (index = 0; index < counter; index++)
315 if (ble_advdata_name_find(p_adv_report->data.p_data,
317 p_name_filter->target_name[index]))
337 static ret_code_t nrf_ble_scan_name_filter_add(nrf_ble_scan_t *
const p_scan_ctx,
341 uint8_t * counter = &p_scan_ctx->scan_filters.name_filter.name_cnt;
342 uint8_t name_len = strlen(p_name);
345 if ((name_len == 0) || (name_len > NRF_BLE_SCAN_NAME_MAX_LEN))
347 return NRF_ERROR_DATA_SIZE;
351 if (*counter >= NRF_BLE_SCAN_NAME_CNT)
353 return NRF_ERROR_NO_MEM;
357 for (index = 0; index < NRF_BLE_SCAN_NAME_CNT; index++)
359 if (!strcmp(p_scan_ctx->scan_filters.name_filter.target_name[index], p_name))
366 memcpy(p_scan_ctx->scan_filters.name_filter.target_name[(*counter)++],
370 NRF_LOG_DEBUG(
"Adding filter on %s name", p_name);
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)
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;
396 data_len = p_adv_report->data.len;
399 for (index = 0; index < counter; index++)
401 if (ble_advdata_short_name_find(p_adv_report->data.p_data,
403 p_name_filter->short_name[index].short_target_name,
404 p_name_filter->short_name[index].short_name_min_len))
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)
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);
435 if ((name_len == 0) || (name_len > NRF_BLE_SCAN_SHORT_NAME_MAX_LEN))
437 return NRF_ERROR_DATA_SIZE;
441 if (*p_counter >= NRF_BLE_SCAN_SHORT_NAME_CNT)
443 return NRF_ERROR_NO_MEM;
447 for (index = 0; index < NRF_BLE_SCAN_SHORT_NAME_CNT; index++)
449 if (!strcmp(p_short_name_filter->short_name[index].short_target_name,
450 p_short_name->p_short_name))
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));
463 NRF_LOG_DEBUG(
"Adding filter on %s name", p_short_name->p_short_name);
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)
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;
489 uint8_t uuid_match_cnt = 0;
491 data_len = p_adv_report->data.len;
493 for (index = 0; index < counter; index++)
496 if (ble_advdata_uuid_find(p_adv_report->data.p_data,
498 &p_uuid_filter->uuid[index]))
503 if (!all_filters_mode)
508 else if (all_filters_mode)
519 if ((all_filters_mode && (uuid_match_cnt == counter)) ||
520 ((!all_filters_mode) && (uuid_match_cnt > 0)))
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)
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;
545 if (*p_counter >= NRF_BLE_SCAN_UUID_CNT)
547 return NRF_ERROR_NO_MEM;
551 for (index = 0; index < NRF_BLE_SCAN_UUID_CNT; index++)
553 if (p_uuid_filter[index].uuid == p_uuid->uuid)
560 p_uuid_filter[(*p_counter)++] = *p_uuid;
561 NRF_LOG_DEBUG(
"Added filter on UUID %x", p_uuid->uuid);
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)
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;
588 data_len = p_adv_report->data.len;
591 for (index = 0; index < counter; index++)
593 if (ble_advdata_appearance_find(p_adv_report->data.p_data,
595 &p_appearance_filter->appearance[index]))
613 static ret_code_t nrf_ble_scan_appearance_filter_add(nrf_ble_scan_t *
const p_scan_ctx,
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;
621 if (*p_counter >= NRF_BLE_SCAN_APPEARANCE_CNT)
623 return NRF_ERROR_NO_MEM;
627 for ( index = 0; index < NRF_BLE_SCAN_APPEARANCE_CNT; index++)
629 if (p_appearance_filter[index] == appearance)
636 p_appearance_filter[(*p_counter)++] = appearance;
637 NRF_LOG_DEBUG(
"Added filter on appearance %x", appearance);
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,
649 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
650 VERIFY_PARAM_NOT_NULL(p_data);
654 #if (NRF_BLE_SCAN_NAME_CNT > 0)
655 case SCAN_NAME_FILTER:
657 char * p_name = (
char *)p_data;
658 return nrf_ble_scan_name_filter_add(p_scan_ctx, p_name);
662 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
663 case SCAN_SHORT_NAME_FILTER:
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);
670 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
671 case SCAN_ADDR_FILTER:
673 uint8_t * p_addr = (uint8_t *)p_data;
674 return nrf_ble_scan_addr_filter_add(p_scan_ctx, p_addr);
678 #if (NRF_BLE_SCAN_UUID_CNT > 0)
679 case SCAN_UUID_FILTER:
681 ble_uuid_t * p_uuid = (ble_uuid_t *)p_data;
682 return nrf_ble_scan_uuid_filter_add(p_scan_ctx, p_uuid);
686 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
687 case SCAN_APPEARANCE_FILTER:
689 uint16_t appearance = *((uint16_t *)p_data);
690 return nrf_ble_scan_appearance_filter_add(p_scan_ctx, appearance);
695 return NRF_ERROR_INVALID_PARAM;
700 ret_code_t nrf_ble_scan_all_filter_remove(nrf_ble_scan_t *
const p_scan_ctx)
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;
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;
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;
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;
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;
738 ret_code_t nrf_ble_scan_filters_enable(nrf_ble_scan_t *
const p_scan_ctx,
742 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
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)))
751 return NRF_ERROR_INVALID_PARAM;
757 err_code = nrf_ble_scan_filters_disable(p_scan_ctx);
758 ASSERT(err_code == NRF_SUCCESS);
760 nrf_ble_scan_filters_t * p_filters = &p_scan_ctx->scan_filters;
763 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
764 if (mode & NRF_BLE_SCAN_ADDR_FILTER)
766 p_filters->addr_filter.addr_filter_enabled =
true;
770 #if (NRF_BLE_SCAN_NAME_CNT > 0)
771 if (mode & NRF_BLE_SCAN_NAME_FILTER)
773 p_filters->name_filter.name_filter_enabled =
true;
777 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
778 if (mode & NRF_BLE_SCAN_SHORT_NAME_FILTER)
780 p_filters->short_name_filter.short_name_filter_enabled =
true;
784 #if (NRF_BLE_SCAN_UUID_CNT > 0)
785 if (mode & NRF_BLE_SCAN_UUID_FILTER)
787 p_filters->uuid_filter.uuid_filter_enabled =
true;
791 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
792 if (mode & NRF_BLE_SCAN_APPEARANCE_FILTER)
794 p_filters->appearance_filter.appearance_filter_enabled =
true;
799 p_filters->all_filters_mode = match_all;
805 ret_code_t nrf_ble_scan_filters_disable(nrf_ble_scan_t *
const p_scan_ctx)
807 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
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;
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;
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;
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;
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)
838 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
839 VERIFY_PARAM_NOT_NULL(p_status);
841 *p_status = p_scan_ctx->scan_filters;
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)
860 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
861 uint8_t filter_cnt = 0;
862 uint8_t filter_match_cnt = 0;
865 memset(&scan_evt, 0,
sizeof(scan_evt));
867 scan_evt.p_scan_params = &p_scan_ctx->scan_params;
870 if (is_whitelist_used(p_scan_ctx))
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);
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);
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;
886 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
887 bool const addr_filter_enabled = p_scan_ctx->scan_filters.addr_filter.addr_filter_enabled;
890 #if (NRF_BLE_SCAN_NAME_CNT > 0)
891 bool const name_filter_enabled = p_scan_ctx->scan_filters.name_filter.name_filter_enabled;
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;
899 #if (NRF_BLE_SCAN_UUID_CNT > 0)
900 bool const uuid_filter_enabled = p_scan_ctx->scan_filters.uuid_filter.uuid_filter_enabled;
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;
909 #if (NRF_BLE_SCAN_ADDRESS_CNT > 0)
911 if (addr_filter_enabled)
915 if (adv_addr_compare(p_adv_report, p_scan_ctx))
920 scan_evt.params.filter_match.filter_match.address_filter_match =
true;
921 is_filter_matched =
true;
926 #if (NRF_BLE_SCAN_NAME_CNT > 0)
928 if (name_filter_enabled)
931 if (adv_name_compare(p_adv_report, p_scan_ctx))
936 scan_evt.params.filter_match.filter_match.name_filter_match =
true;
937 is_filter_matched =
true;
942 #if (NRF_BLE_SCAN_SHORT_NAME_CNT > 0)
943 if (short_name_filter_enabled)
946 if (adv_short_name_compare(p_adv_report, p_scan_ctx))
951 scan_evt.params.filter_match.filter_match.short_name_filter_match =
true;
952 is_filter_matched =
true;
957 #if (NRF_BLE_SCAN_UUID_CNT > 0)
959 if (uuid_filter_enabled)
962 if (adv_uuid_compare(p_adv_report, p_scan_ctx))
966 scan_evt.params.filter_match.filter_match.uuid_filter_match =
true;
967 is_filter_matched =
true;
972 #if (NRF_BLE_SCAN_APPEARANCE_CNT > 0)
974 if (appearance_filter_enabled)
977 if (adv_appearance_compare(p_adv_report, p_scan_ctx))
981 scan_evt.params.filter_match.filter_match.appearance_filter_match =
true;
982 is_filter_matched =
true;
986 scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
989 scan_evt.params.filter_match.p_adv_report = p_adv_report;
992 if (all_filter_mode && (filter_match_cnt == filter_cnt))
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);
998 else if ((!all_filter_mode) && is_filter_matched)
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);
1005 scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
1006 scan_evt.params.p_not_found = p_adv_report;
1011 scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_NOT_FOUND;
1012 scan_evt.params.p_not_found = p_adv_report;
1016 if (p_scan_ctx->evt_handler != NULL)
1018 p_scan_ctx->evt_handler(&scan_evt);
1022 UNUSED_RETURN_VALUE(sd_ble_gap_scan_start(NULL, &p_scan_ctx->scan_buffer));
1030 bool is_whitelist_used(nrf_ble_scan_t
const *
const p_scan_ctx)
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)
1046 static void nrf_ble_scan_default_param_set(nrf_ble_scan_t *
const p_scan_ctx)
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;
1062 static void nrf_ble_scan_default_conn_param_set(nrf_ble_scan_t *
const p_scan_ctx)
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;
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)
1083 ble_gap_evt_timeout_t
const * p_timeout = &p_gap->params.timeout;
1084 scan_evt_t scan_evt;
1086 memset(&scan_evt, 0,
sizeof(scan_evt));
1088 if (p_timeout->src == BLE_GAP_TIMEOUT_SRC_SCAN)
1090 NRF_LOG_DEBUG(
"BLE_GAP_SCAN_TIMEOUT");
1091 if (p_scan_ctx->evt_handler != NULL)
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;
1097 p_scan_ctx->evt_handler(&scan_evt);
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)
1111 ble_gap_evt_scan_req_report_t
const * p_req_report = &p_gap->params.scan_req_report;
1112 scan_evt_t scan_evt;
1114 memset(&scan_evt, 0,
sizeof(scan_evt));
1116 if (p_scan_ctx->evt_handler != NULL)
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;
1122 p_scan_ctx->evt_handler(&scan_evt);
1129 void nrf_ble_scan_stop(
void)
1133 UNUSED_RETURN_VALUE(sd_ble_gap_scan_stop());
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)
1141 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1143 p_scan_ctx->evt_handler = evt_handler;
1145 #if (NRF_BLE_SCAN_FILTER_ENABLE == 1)
1147 memset(&p_scan_ctx->scan_filters, 0,
sizeof(p_scan_ctx->scan_filters));
1153 p_scan_ctx->connect_if_match = p_init->connect_if_match;
1154 p_scan_ctx->conn_cfg_tag = p_init->conn_cfg_tag;
1156 if (p_init->p_scan_param != NULL)
1158 p_scan_ctx->scan_params = *p_init->p_scan_param;
1163 nrf_ble_scan_default_param_set(p_scan_ctx);
1166 if (p_init->p_conn_param != NULL)
1168 p_scan_ctx->conn_params = *p_init->p_conn_param;
1173 nrf_ble_scan_default_conn_param_set(p_scan_ctx);
1179 nrf_ble_scan_default_param_set(p_scan_ctx);
1180 nrf_ble_scan_default_conn_param_set(p_scan_ctx);
1182 p_scan_ctx->connect_if_match =
false;
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;
1193 ret_code_t nrf_ble_scan_start(nrf_ble_scan_t
const *
const p_scan_ctx)
1195 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1197 ret_code_t err_code;
1198 scan_evt_t scan_evt;
1200 memset(&scan_evt, 0,
sizeof(scan_evt));
1202 nrf_ble_scan_stop();
1205 if (is_whitelist_used(p_scan_ctx))
1207 if (p_scan_ctx->evt_handler != NULL)
1209 scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_WHITELIST_REQUEST;
1210 p_scan_ctx->evt_handler(&scan_evt);
1215 err_code = sd_ble_gap_scan_start(&p_scan_ctx->scan_params, &p_scan_ctx->scan_buffer);
1218 if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_SUCCESS))
1220 NRF_LOG_ERROR(
"sd_ble_gap_scan_start returned 0x%x", err_code);
1223 NRF_LOG_DEBUG(
"Scanning");
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)
1232 VERIFY_PARAM_NOT_NULL(p_scan_ctx);
1234 nrf_ble_scan_stop();
1236 if (p_scan_param != NULL)
1239 p_scan_ctx->scan_params = *p_scan_param;
1244 nrf_ble_scan_default_param_set(p_scan_ctx);
1247 NRF_LOG_DEBUG(
"Scanning parameters have been changed successfully");
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)
1261 scan_evt_t scan_evt;
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;
1269 if (p_scan_ctx->evt_handler != NULL)
1271 p_scan_ctx->evt_handler(&scan_evt);
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])
1281 addr_type = nrf_ble_scan_address_type_decode(addr);
1283 if (addr_type == BLE_ERROR_GAP_INVALID_BLE_ADDR)
1285 return BLE_ERROR_GAP_INVALID_BLE_ADDR;
1288 p_gap_addr->addr_type = addr_type;
1290 for (uint8_t i = 0; i < BLE_GAP_ADDR_LEN; ++i)
1292 p_gap_addr->addr[i] = addr[BLE_GAP_ADDR_LEN - (i + 1)];
1299 void nrf_ble_scan_on_ble_evt(ble_evt_t
const * p_ble_evt,
void * p_contex)
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;
1305 switch (p_ble_evt->header.evt_id)
1307 case BLE_GAP_EVT_ADV_REPORT:
1308 nrf_ble_scan_on_adv_report(p_scan_data, p_adv_report);
1311 case BLE_GAP_EVT_TIMEOUT:
1312 nrf_ble_scan_on_timeout(p_scan_data, p_gap_evt);
1315 case BLE_GAP_EVT_SCAN_REQ_REPORT:
1316 nrf_ble_scan_on_req_report(p_scan_data, p_gap_evt);
1320 case BLE_GAP_EVT_CONNECTED:
1321 nrf_ble_scan_on_connected_evt(p_scan_data, p_gap_evt);
NRF_LOG_MODULE_REGISTER()