I use the nRF52-SDK on an nRF52840 PDK, but if I start a scan request, I don't get the number of scanned channels back in the mlme_scan_conf_t.
I.e. mlme_scan_conf_t::unscanned_channels is always zero.
Additionally, the mlme_scan_conf_t::energy_detect_list is not a NULL-ptr, if I start an ACTIVE-scan. (But it should be according to Table 68 in IEEE Std 802.15.4-2006)
I have included a test program, which can simply be added to the existing 802.15.4 wireless uart example in the sdk-folder:
#ifdef __cplusplus extern "C" { #endif #include "802_15_4_config.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "ral_irq_handlers.h" #include "nrf_drv_clock.h" #include "boards.h" #include "mac_mcps_data.h" #include "sys_init.h" #include "sys_task_scheduler.h" #include "mac_common.h" #include "mac_mlme_beacon_notify.h" #include "mac_mlme_comm_status.h" #include "mac_mlme_pib.h" #include "mac_mlme_scan.h" #include "mac_security.h" #ifdef __cplusplus } #endif #include "SEGGER_RTT.h" #include "SEGGER_RTT_Conf.h" #define CONFIG_POOL_SIZE 0x2000 static __ALIGN(ALIGN_VALUE) uint8_t m_heap[CONFIG_POOL_SIZE]; #define CONFIG_ERROR_PIN LED_4 static void out_of_memory_callback(const void* data); static void memory_freed_callback(const void* data); #ifdef __cplusplus constexpr sys_event_desc_t gen_sys_event_desc_t(sys_event_id_t event_id, void(callback)(const void*)) { return sys_event_desc_t{sys_queue_item_t{}, event_id, callback}; } static sys_event_desc_t m_out_of_memory_desc = gen_sys_event_desc_t(SYS_EVENT_OUT_OF_MEMORY, out_of_memory_callback); static sys_event_desc_t m_memory_freed_desc = gen_sys_event_desc_t(SYS_EVENT_MEMORY_FREED, memory_freed_callback); #else static sys_event_desc_t m_out_of_memory_desc = { .event_id = SYS_EVENT_OUT_OF_MEMORY, .callback = out_of_memory_callback}; static sys_event_desc_t m_memory_freed_desc = { .event_id = SYS_EVENT_MEMORY_FREED, .callback = memory_freed_callback}; #endif static void out_of_memory_callback(const void* data) { LEDS_ON(BIT(CONFIG_ERROR_PIN)); } static void memory_freed_callback(const void* data) { LEDS_OFF(BIT(CONFIG_ERROR_PIN)); } static void app_task_init(void) { LEDS_CONFIGURE(LEDS_MASK); LEDS_OFF(LEDS_MASK); sys_init(m_heap, CONFIG_POOL_SIZE); sys_event_subscribe(&m_out_of_memory_desc); sys_event_subscribe(&m_memory_freed_desc); } static void clock_init(void) { ret_code_t err_code = nrf_drv_clock_init(); ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)); nrf_drv_clock_hfclk_request(NULL); while (!nrf_drv_clock_hfclk_is_running()) { // spin lock } nrf_drv_clock_lfclk_request(NULL); while (!nrf_drv_clock_lfclk_is_running()) { // spin lock } } void print_scan_conf(const mlme_scan_conf_t* sc) { if(sc->status == MAC_SUCCESS) { SEGGER_RTT_printf(0, "unscanned_channels: %x\n", sc->unscanned_channels); SEGGER_RTT_printf(0, "result_list_size: %u\n", sc->result_list_size); if(sc->energy_detect_list != NULL) { SEGGER_RTT_printf(0, "Energy Detect List is not a nullptr.\n"); } } else { SEGGER_RTT_printf(0, "unsuccessful scan\n"); } } bool callback_called = false; void scan_callback(mlme_scan_conf_t* sc) { callback_called = true; }; mlme_scan_req_t gen_mac_scan_req_t( mac_scan_type_t scan_type, uint32_t scan_channels, uint8_t scan_duration, mac_pan_descriptor_t* pan_desc_buf, size_t pan_desc_size, uint8_t* energy_detect_buf, size_t energy_detect_size) { mlme_scan_req_t ret; ret.scan_type = scan_type; ret.scan_channels = scan_channels; ret.scan_duration = scan_duration; ret.pan_descriptors_buf = pan_desc_buf; ret.pan_descriptors_buf_size = pan_desc_size; ret.energy_detect_buf = energy_detect_buf; ret.energy_detect_buf_size = energy_detect_size; return ret; } const mlme_scan_conf_t* scan_req(mac_scan_type_t scan_type, uint32_t scan_channels, uint8_t scan_duration) { #define _ENERGY_DET_SIZE 8 #define _PAN_DESC_SIZE 8 static mac_pan_descriptor_t pd[_PAN_DESC_SIZE]; static uint8_t ed[_ENERGY_DET_SIZE]; static mlme_scan_req_t scan_req; scan_req = gen_mac_scan_req_t(scan_type, scan_channels, scan_duration, pd, _PAN_DESC_SIZE, ed, _ENERGY_DET_SIZE); callback_called = false; mlme_scan_req(&scan_req, scan_callback); while (!callback_called) { sys_task_run(); } return &scan_req.confirm; } int main(void) { ral_irq_handler_import(); SEGGER_RTT_Init(); uint8_t rtt_buf_out[256u]; SEGGER_RTT_ConfigUpBuffer(0, "OUT", rtt_buf_out, 256u, SEGGER_RTT_MODE_NO_BLOCK_TRIM); app_task_init(); sys_task_post(APP_TASK_ID); clock_init(); SEGGER_RTT_printf(0, "....RESET SCAN....\n"); SEGGER_RTT_printf(0, "starting the scan\n"); print_scan_conf(scan_req(ACTIVE_SCAN, 1<<14, 7)); SEGGER_RTT_printf(0, "finished the scan\n"); while (true) { sys_task_run(); } }
It outputs the following via RTT:
starting the scan
unscanned_channels: 0
result_list_size: 1
Energy Detect List is not a nullptr.
finished the scan
I am using the nRF52-SDK-14.2.0 and gcc-7.2.0.