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 scanunscanned_channels: 0result_list_size: 1Energy Detect List is not a nullptr.finished the scan
I am using the nRF52-SDK-14.2.0 and gcc-7.2.0.