I am trying to use multiple channels for beacon transmission.I want to hop to a different channel at an interval of 2 seconds.I have configured one device as a pan coordinator and on the other device I am performing channel scanning.I have considered the channel sequence as 14,20,14,20.But when i perform a scan , I receive beacons only from channel 20 and NO_BEACON from channel 14.What is the reason ?
Device 1 - pan coordinator code
#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_associate.h"
#include "mac_mlme_poll.h"
#include "mac_mlme_scan.h"
#include "mac_mlme_start.h"
#include "mac_security.h"
#include "nrf_delay.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
#define C11 (1 << 11)
#define C12 (1 << 12)
#define C13 (1 << 13)
#define C14 (1 << 14)
#define C15 (1 << 15)
#define C16 (1 << 16)
#define C17 (1 << 17)
#define C18 (1 << 18)
#define C19 (1 << 19)
#define C20 (1 << 20)
#define C21 (1 << 21)
#define C22 (1 << 22)
#define C23 (1 << 23)
#define C24 (1 << 24)
#define C25 (1 << 25)
#define C26 (1 << 26)
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
void wait_ms(const uint32_t count) {
SEGGER_RTT_printf(0, "dummy wait: ");
for(volatile uint32_t i=0; i<2432u*count; i++) {
uint32_t j = i%(2432u*100u);
if(j == 0) {
SEGGER_RTT_printf(0, ".", j);
}
}
SEGGER_RTT_printf(0, "\n");
}
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_mac_status(const mac_status_t status) {
switch (status) {
case MAC_NO_BEACON:
SEGGER_RTT_printf(0, "MAC_NO_BEACON");
break;
case MAC_SUCCESS:
SEGGER_RTT_printf(0, "MAC_SUCCESS");
break;
case MAC_LIMIT_REACHED:
SEGGER_RTT_printf(0, "MAC_LIMIT_REACHED");
break;
default:
SEGGER_RTT_printf(0, "0x%x", status);
break;
}
}
void print_addr(const mac_addr_t* addr, const mac_addr_mode_t addr_mode,
const char* field) {
SEGGER_RTT_printf(0, "%s: ", field);
switch (addr_mode) {
case MAC_ADDR_NONE:
SEGGER_RTT_printf(0, "NONE");
break;
case MAC_ADDR_SHORT:
SEGGER_RTT_printf(0, "0x%04x (short)", addr->short_address);
break;
case MAC_ADDR_LONG:
default:
SEGGER_RTT_printf(0, "0x%08x%08x (long)",
(uint32_t)(addr->long_address >> 32),
(uint32_t)(addr->long_address));
break;
}
}
void print_pan_desc(const mac_pan_descriptor_t* pan) {
SEGGER_RTT_printf(0, "{coord_pan_id: 0x%04x, ", pan->coord_pan_id);
print_addr(&(pan->coord_address), pan->coord_addr_mode, "address");
SEGGER_RTT_printf(0,
", logical_channel: %u, timestamp: 0x%x, link_quality: "
"%u, superframe_spec: 0x%x, gts: %s}",
pan->logical_channel, pan->timestamp, pan->link_quality,
pan->superframe_spec, pan->gts_permit ? "true" : "false");
}
void print_scan_conf(const mlme_scan_conf_t* sc) {
SEGGER_RTT_printf(0, "{status: ");
print_mac_status(sc->status);
SEGGER_RTT_printf(0, ", scan_type: ");
switch (sc->scan_type) {
case ED_SCAN:
SEGGER_RTT_printf(0, "ED_SCAN");
break;
case ACTIVE_SCAN:
SEGGER_RTT_printf(0, "ACTIVE_SCAN");
break;
case PASSIVE_SCAN:
SEGGER_RTT_printf(0, "PASSIVE_SCAN");
break;
case ORPHAN_SCAN:
SEGGER_RTT_printf(0, "ORPHAN_SCAN");
break;
default:
SEGGER_RTT_printf(0, "Unknown(%x)", sc->scan_type);
break;
}
SEGGER_RTT_printf(0, ", unscanned_channels: %x", sc->unscanned_channels);
SEGGER_RTT_printf(0, ", result_list_size: %u, results: {",
sc->result_list_size);
for (size_t i = 0; i < sc->result_list_size; i++) {
const mac_pan_descriptor_t* pan = &(sc->pan_descriptor_list[i]);
SEGGER_RTT_printf(0, "Result %u: {pan_descriptor: ", i);
print_pan_desc(pan);
//for an active scan, the content of the energy_detect_list must not be read.
//const uint8_t energy = sc->energy_detect_list[i];
//(void)energy;
//SEGGER_RTT_printf(0, ", energy: %x", energy);
SEGGER_RTT_printf(0, "}, ");
}
SEGGER_RTT_printf(0, "}\n");
}
bool callback_called = false;
void scan_callback(mlme_scan_conf_t* sc) { callback_called = true; };
void start_callback(mlme_start_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;
}
void gen_mac_key_descr_t(mac_key_descr_t* key_descr) {
mac_table_init(&key_descr->id_lookup_list);
mac_table_init(&key_descr->key_device_list);
mac_table_init(&key_descr->key_usage_list);
}
mac_device_descr_t gen_mac_device_descr_t(uint16_t pan_id,
uint16_t short_address,
uint64_t extended_address,
uint32_t frame_counter, bool exempt) {
mac_device_descr_t ret;
ret.pan_id = pan_id;
ret.short_address = short_address;
ret.extended_address = extended_address;
ret.frame_counter = frame_counter;
ret.exempt = exempt;
return ret;
}
mac_security_level_descr_t gen_mac_security_level_descr_t(
uint8_t frame_type, uint8_t cmd_frame_id, uint8_t security_min,
uint8_t override_min) {
mac_security_level_descr_t ret;
ret.security_min = security_min;
ret.override_min = override_min;
ret.frame_type = frame_type;
ret.cmd_frame_id = cmd_frame_id;
return ret;
}
mac_key_id_lookup_descr_t gen_mac_key_id_lookup_descr_t(
mac_key_lookup_size_t size) {
mac_key_id_lookup_descr_t ret;
ret.size = size;
return ret;
}
mac_key_device_descr_t gen_mac_key_device_descr_t(uint8_t device_handle,
uint8_t unique_device,
uint8_t blacklisted) {
mac_key_device_descr_t ret;
ret.device_handle = device_handle;
ret.blacklisted = blacklisted;
ret.unique_device = unique_device;
return ret;
}
mac_key_usage_descr_t gen_mac_key_usage_descr_t(uint8_t frame_type,
uint8_t cmd_frame_id) {
mac_key_usage_descr_t ret;
ret.frame_type = frame_type;
ret.cmd_frame_id = cmd_frame_id;
return ret;
}
pib_id_t gen_pib_id_t_plme(plme_pib_attr_id_t id) {
pib_id_t ret;
ret.plme_id = id;
return ret;
}
pib_id_t gen_pib_id_t(mlme_pib_attr_id_t id) {
pib_id_t ret;
ret.mlme_id = id;
return ret;
}
const char* pib_id_str(pib_id_t id) {
switch(id.mlme_id) {
case MAC_PAN_ID:
return "MAC_PAN_ID";
case MAC_PAN_COORD_EXTENDED_ADDRESS:
return "MAC_PAN_COORD_EXTENDED_ADDRESS";
case MAC_PROMISCUOUS_MODE:
return "MAC_PROMISCUOUS_MODE";
case MAC_EXTENDED_ADDRESS:
return "MAC_EXTENDED_ADDRESS";
case MAC_SHORT_ADDRESS:
return "MAC_SHORT_ADDRESS";
case MAC_BEACON_PAYLOAD_LENGTH:
return "MAC_BEACON_PAYLOAD_LENGTH";
case MAC_BEACON_PAYLOAD:
return "MAC_BEACON_PAYLOAD";
case MAC_BEACON_ORDER:
return "MAC_BEACON_ORDER";
case MAC_RX_ON_WHEN_IDLE:
return "MAC_RX_ON_WHEN_IDLE";
case MAC_BATT_LIFE_EXT:
return "MAC_BATT_LIFE_EXT";
case MAC_IS_PAN_COORD:
return "MAC_IS_PAN_COORD";
case MAC_ASSOCIATION_PERMIT:
return "MAC_ASSOCIATION_PERMIT";
case MAC_GTS_PERMIT:
return "MAC_GTS_PERMIT";
case PHY_CURRENT_CHANNEL_ID:
return "PHY_CURRENT_CHANNEL";
default:
return "**************UNKNOWN****************";
}
}
void print_pib_get_request(const uint8_t* value, uint16_t size,
const char* name) {
SEGGER_RTT_printf(0, "mlme_get: %s: 0x", name);
for (uint16_t i = 0; i < size; i++) {
SEGGER_RTT_printf(0, "%02x", value[i]);
}
SEGGER_RTT_printf(0, "\n");
}
const uint8_t* pib_get_request(pib_id_t id) {
static uint8_t value[256];
mac_status_t res = mlme_get(id, 0, value);
const char* name = pib_id_str(id);
if (res != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-get request(%s): ", name);
print_mac_status(res);
SEGGER_RTT_printf(0, "\n");
// TODO: handle this error
return NULL;
}
print_pib_get_request(value, mlme_pib_attr_size_calc(id, 0), name);
return value;
}
void pib_set_request(pib_id_t id, void * data) {
mac_status_t state = mlme_set(id, 0, data);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request(%s): ", pib_id_str(id));
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
//TODO: handle this error
}
}
const uint8_t* pib_set_get_request(pib_id_t id, void * data) {
pib_set_request(id, data);
return pib_get_request(id);
}
void print_beacon_notify_ind(const mlme_beacon_notify_ind_t* ind) {
SEGGER_RTT_printf(0, "{bsn: %u, pan_descriptor: ", ind->bsn);
print_pan_desc(&(ind->pan_descriptor));
SEGGER_RTT_printf(0, ", sdu_length: %u, sdu: 0x", ind->sdu_length);
for (size_t i = 0u; i < ind->sdu_length; i++) {
SEGGER_RTT_printf(0, "%02x", ind->sdu.p_payload[i]);
}
SEGGER_RTT_printf(0, ", pend_addr_spec: %x}\n", ind->pend_addr_spec);
}
void print_data_ind(const mcps_data_ind_t* ind) {
SEGGER_RTT_printf(0, "{src_pan_id: 0x%04x, ", ind->src_pan_id);
print_addr(&(ind->src_addr), ind->src_addr_mode, "src_addr");
SEGGER_RTT_printf(0, ", dst_pan_id: 0x%04x, ", ind->dst_pan_id);
print_addr(&(ind->dst_addr), ind->dst_addr_mode, "dst_addr");
SEGGER_RTT_printf(0, ", msdu_length: %u, sdu: 0x", ind->msdu_length);
for (size_t i = 0u; i < ind->msdu_length; i++) {
SEGGER_RTT_printf(0, "%02x", ind->msdu.p_payload[i]);
}
SEGGER_RTT_printf(0, ", mpdu_link_quality: %u", ind->mpdu_link_quality);
SEGGER_RTT_printf(0, ", dsn: %u", ind->dsn);
SEGGER_RTT_printf(0, ", timestamp: %u}\n", ind->timestamp);
SEGGER_RTT_printf(0, "\n");
}
void mlme_beacon_notify_ind(mlme_beacon_notify_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Beacon:\n");
print_beacon_notify_ind(_ind);
}
void mlme_poll_ind(mlme_poll_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Poll:\n");
}
//void mac_auto_request_notify_ind(mac_beacon_ind_t* _ind) {
// SEGGER_RTT_printf(0, "Received Auto Request Notif:\n");
//}
//
//void mac_panid_conflict_beacon_notify_ind(const mac_beacon_ind_t * p_beacon) {
// SEGGER_RTT_printf(0, "Received Panid Conflict beacon:\n");
//}
void mcps_data_ind(mcps_data_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Data:\n");
print_data_ind(_ind);
}
void mlme_associate_ind(mlme_associate_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Association:\n");
}
void dummy_wait() {
SEGGER_RTT_printf(0, "dummy wait: ...");
for(volatile size_t i=0; i<1024*1024*8; i++) {
uint32_t j = (i + 10 )%(1024*1024*2);
if(j+44 == 88) {
SEGGER_RTT_printf(0, "%d,", j);
}
}
SEGGER_RTT_printf(0, "\n");
}
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 COORD....\n");
#if (CONFIG_SECURE == 1)
SEGGER_RTT_printf(0, "Compiled with CONFIG_SECURE\n");
#endif
static uint8_t mac_association_permit = true;
#define BEACON_ORDER 0x7u // beacon interval = 2 sec
#define SUPERFRAME_ORDER 0x6u
static uint8_t mac_gts_permit = false;
static uint8_t rx_on_when_idle = true;
static uint8_t beacon_payload[] = {0xabu, 0xabu, 0xabu, 0xabu, 0xbbu, 0xbbu, 0xbbu, 0xbbu};
static uint8_t beacon_payload_length = 8u;
static const uint8_t ext_addr[] = {0xcau, 0xfeu, 0xbeu, 0xefu, 0x00u, 0x00u, 0xffu, 0xffu};
int i=0;
// channel hop sequence
uint8_t channels[] = {20,14,20};
static uint16_t ext_addr_only = MAC_EXTENDED_ADDRESS_ONLY;
pib_set_get_request(gen_pib_id_t(MAC_EXTENDED_ADDRESS), (void *)ext_addr);
pib_set_get_request(gen_pib_id_t(MAC_SHORT_ADDRESS), &ext_addr_only);
pib_set_get_request(gen_pib_id_t(MAC_BEACON_PAYLOAD_LENGTH), &beacon_payload_length);
pib_set_get_request(gen_pib_id_t(MAC_BEACON_PAYLOAD), (void*)beacon_payload);
pib_set_get_request(gen_pib_id_t(MAC_RX_ON_WHEN_IDLE), &rx_on_when_idle);
pib_set_get_request(gen_pib_id_t(MAC_ASSOCIATION_PERMIT), &mac_association_permit);
pib_get_request(gen_pib_id_t(MAC_GTS_PERMIT));
pib_set_get_request(gen_pib_id_t(MAC_GTS_PERMIT), &mac_gts_permit);
static mlme_start_req_t start_req =
{
.pan_id = 0x1111,
.logical_channel = 14,
.start_time = 0x000000,
.beacon_order = BEACON_ORDER,
.superframe_order = SUPERFRAME_ORDER,
.pan_coordinator = true,
.battery_life_extension = false,
.coord_realignment = false,
#if (CONFIG_SECURE == 1)
.coord_realign_security_level = false,
.beacon_security_level = false,
#endif
};
callback_called = false;
mlme_start_req(&start_req, start_callback);
while (!callback_called) {
sys_task_run();
}
SEGGER_RTT_printf(0, "Sent the Start-Request: ");
print_mac_status(start_req.confirm.status);
SEGGER_RTT_printf(0, "\n");
SEGGER_RTT_printf(0, " Channel : %u\n",start_req.logical_channel);
// Code to hop channel
for(i=0;i<3;i++)
{
nrf_delay_ms(100);
pib_set_get_request(gen_pib_id_t_plme( PHY_CURRENT_CHANNEL_ID ), &channels[i]);
}
while (true) {
sys_task_run();
}
}
Device 2 code - channel scanning
#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 "nrf_delay.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
#define C11 (1 << 11)
#define C12 (1 << 12)
#define C13 (1 << 13)
#define C14 (1 << 14)
#define C15 (1 << 15)
#define C16 (1 << 16)
#define C17 (1 << 17)
#define C18 (1 << 18)
#define C19 (1 << 19)
#define C20 (1 << 20)
#define C21 (1 << 21)
#define C22 (1 << 22)
#define C23 (1 << 23)
#define C24 (1 << 24)
#define C25 (1 << 25)
#define C26 (1 << 26)
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_mac_status(const mac_status_t status) {
switch (status) {
case MAC_NO_BEACON:
SEGGER_RTT_printf(0, "MAC_NO_BEACON");
break;
case MAC_SUCCESS:
SEGGER_RTT_printf(0, "MAC_SUCCESS");
break;
case MAC_LIMIT_REACHED:
SEGGER_RTT_printf(0, "MAC_LIMIT_REACHED");
break;
default:
SEGGER_RTT_printf(0, "0x%x", status);
break;
}
}
void print_addr(const mac_addr_t* addr, const mac_addr_mode_t addr_mode,
const char* field) {
SEGGER_RTT_printf(0, "%s: ", field);
switch (addr_mode) {
case MAC_ADDR_NONE:
SEGGER_RTT_printf(0, "NONE");
break;
case MAC_ADDR_SHORT:
SEGGER_RTT_printf(0, "0x%04x (short)", addr->short_address);
break;
case MAC_ADDR_LONG:
default:
SEGGER_RTT_printf(0, "0x%08x%08x (long)",
(uint32_t)(addr->long_address >> 32),
(uint32_t)(addr->long_address));
break;
}
}
void print_pan_desc(const mac_pan_descriptor_t* pan) {
SEGGER_RTT_printf(0, "{coord_pan_id: 0x%04x, ", pan->coord_pan_id);
print_addr(&(pan->coord_address), pan->coord_addr_mode, "address");
SEGGER_RTT_printf(0,
", logical_channel: %u, timestamp: 0x%x, link_quality: "
"%u, superframe_spec: 0x%x, gts: %s}",
pan->logical_channel, pan->timestamp, pan->link_quality,
pan->superframe_spec, pan->gts_permit ? "true" : "false");
}
void print_scan_conf(const mlme_scan_conf_t* sc) {
SEGGER_RTT_printf(0, "{status: ");
print_mac_status(sc->status);
SEGGER_RTT_printf(0, ", scan_type: ");
switch (sc->scan_type) {
case ED_SCAN:
SEGGER_RTT_printf(0, "ED_SCAN");
break;
case ACTIVE_SCAN:
SEGGER_RTT_printf(0, "ACTIVE_SCAN");
break;
case PASSIVE_SCAN:
SEGGER_RTT_printf(0, "PASSIVE_SCAN");
break;
case ORPHAN_SCAN:
SEGGER_RTT_printf(0, "ORPHAN_SCAN");
break;
default:
SEGGER_RTT_printf(0, "Unknown(%x)", sc->scan_type);
break;
}
SEGGER_RTT_printf(0, ", unscanned_channels: %x", sc->unscanned_channels);
SEGGER_RTT_printf(0, ", result_list_size: %u, results: {",
sc->result_list_size);
for (size_t i = 0; i < sc->result_list_size; i++) {
const mac_pan_descriptor_t* pan = &(sc->pan_descriptor_list[i]);
const uint8_t energy = sc->energy_detect_list[i];
SEGGER_RTT_printf(0, "Result %u: {energy: %x, pan_descriptor: ", i,
energy);
print_pan_desc(pan);
SEGGER_RTT_printf(0, "}, ");
}
SEGGER_RTT_printf(0, "}\n");
}
void print_beacon_notify_ind(const mlme_beacon_notify_ind_t* ind) {
SEGGER_RTT_printf(0, "{bsn: %u, pan_descriptor: ", ind->bsn);
print_pan_desc(&(ind->pan_descriptor));
SEGGER_RTT_printf(0, ", sdu_length: %u, sdu: 0x", ind->sdu_length);
for (size_t i = 0u; i < ind->sdu_length; i++) {
SEGGER_RTT_printf(0, "%02x", ind->sdu.p_payload[i]);
}
SEGGER_RTT_printf(0, ", pend_addr_spec: %x}\n", ind->pend_addr_spec);
}
void print_data_ind(const mcps_data_ind_t* ind) {
SEGGER_RTT_printf(0, "{src_pan_id: 0x%04x, ", ind->src_pan_id);
print_addr(&(ind->src_addr), ind->src_addr_mode, "src_addr");
SEGGER_RTT_printf(0, ", dst_pan_id: 0x%04x, ", ind->dst_pan_id);
print_addr(&(ind->dst_addr), ind->dst_addr_mode, "dst_addr");
SEGGER_RTT_printf(0, ", msdu_length: %u, sdu: 0x", ind->msdu_length);
for (size_t i = 0u; i < ind->msdu_length; i++) {
SEGGER_RTT_printf(0, "%02x", ind->msdu.p_payload[i]);
}
// SEGGER_RTT_printf(0, ", mpdu_link_quality: %u", ind->mpdu_link_quality);
// SEGGER_RTT_printf(0, ", dsn: %u", ind->dsn);
SEGGER_RTT_printf(0, ", timestamp: %u}\n", ind->timestamp);
SEGGER_RTT_printf(0, "\n");
}
void mlme_beacon_notify_ind(mlme_beacon_notify_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Beacon: ");
print_beacon_notify_ind(_ind);
}
void mcps_data_ind(mcps_data_ind_t* _ind) {
SEGGER_RTT_printf(0, "Received Data: \n");
print_data_ind(_ind);
}
pib_id_t gen_pib_id_t_plme(plme_pib_attr_id_t id) {
pib_id_t ret;
ret.plme_id = id;
return ret;
}
pib_id_t gen_pib_id_t(mlme_pib_attr_id_t id) {
pib_id_t ret;
ret.mlme_id = id;
return ret;
}
void print_pib_get_request(const uint8_t* value, uint16_t size,
const char* name) {
SEGGER_RTT_printf(0, "mlme_get: %s: 0x", name);
for (uint16_t i = 0; i < size; i++) {
SEGGER_RTT_printf(0, "%02x", value[i]);
}
SEGGER_RTT_printf(0, "\n");
}
const uint8_t* pib_get_request(pib_id_t id, const char* name) {
static uint8_t value[256];
mac_status_t res = mlme_get(id, 0, value);
if (res != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-get request: ");
print_mac_status(res);
SEGGER_RTT_printf(0, "\n");
// TODO: handle this error
return NULL;
}
print_pib_get_request(value, mlme_pib_attr_size_calc(id, 0), name);
return value;
}
void gen_mac_key_descr_t(mac_key_descr_t* key_descr) {
mac_table_init(&key_descr->id_lookup_list);
mac_table_init(&key_descr->key_device_list);
mac_table_init(&key_descr->key_usage_list);
}
mac_device_descr_t gen_mac_device_descr_t(uint16_t pan_id,
uint16_t short_address,
uint64_t extended_address,
uint32_t frame_counter, bool exempt) {
mac_device_descr_t ret;
ret.pan_id = pan_id;
ret.short_address = short_address;
ret.extended_address = extended_address;
ret.frame_counter = frame_counter;
ret.exempt = exempt;
return ret;
}
mac_security_level_descr_t gen_mac_security_level_descr_t(
uint8_t frame_type, uint8_t cmd_frame_id, uint8_t security_min,
uint8_t override_min) {
mac_security_level_descr_t ret;
ret.security_min = security_min;
ret.override_min = override_min;
ret.frame_type = frame_type;
ret.cmd_frame_id = cmd_frame_id;
return ret;
}
mac_key_id_lookup_descr_t gen_mac_key_id_lookup_descr_t(
mac_key_lookup_size_t size) {
mac_key_id_lookup_descr_t ret;
ret.size = size;
return ret;
}
mac_key_device_descr_t gen_mac_key_device_descr_t(uint8_t device_handle,
uint8_t unique_device,
uint8_t blacklisted) {
mac_key_device_descr_t ret;
ret.device_handle = device_handle;
ret.blacklisted = blacklisted;
ret.unique_device = unique_device;
return ret;
}
mac_key_usage_descr_t gen_mac_key_usage_descr_t(uint8_t frame_type,
uint8_t cmd_frame_id) {
mac_key_usage_descr_t ret;
ret.frame_type = frame_type;
ret.cmd_frame_id = cmd_frame_id;
return ret;
}
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;
}
void dummy_wait() {
SEGGER_RTT_printf(0, "dummy wait: ...");
for(volatile size_t i=0; i<1024*1024*8; i++) {
uint32_t j = (i + 10 )%(1024*1024*2);
if(j+44 == 88) {
SEGGER_RTT_printf(0, "%d,", j);
}
}
SEGGER_RTT_printf(0, "\n");
}
int main(void) {
ral_irq_handler_import();
SEGGER_RTT_Init();
uint8_t rtt_buf_out[1024u];
SEGGER_RTT_ConfigUpBuffer(0, "OUT", rtt_buf_out, 1024u,
SEGGER_RTT_MODE_NO_BLOCK_TRIM);
app_task_init();
sys_task_post(APP_TASK_ID);
clock_init();
SEGGER_RTT_printf(0, "....RESET....\n");
#if (CONFIG_SECURE == 1)
SEGGER_RTT_printf(0, "Compiled with CONFIG_SECURE\n");
#endif
static uint8_t security_enabled = true;
static uint16_t pan_id = 0x2222;
static uint16_t other_address = 0xFFFEU;
static uint64_t pan_external = 0x1122334455667788ULL;
static uint8_t promiscuous_mode = true;
static uint8_t rx_on_when_idle = true;
static uint8_t channel_id = 14u;
static uint8_t key[MAC_SECURITY_KEY_SIZE] = {
0x12u, 0x34u, 0x56u, 0x78u, 0x9Au, 0xBCu, 0xDEu, 0xF0u,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u};
static const uint8_t key_lookup_data[KEY_LOOKUP_SIZE_NINE_VAL] = {
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x03};
static uint8_t default_source[KEY_LOOKUP_SIZE_NINE_VAL - 1] = {
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};
static uint8_t auto_request_security_level = MAC_SEC_OFF;
static uint8_t auto_request = false;
static mac_security_level_descr_t sec_level_descr;
sec_level_descr = gen_mac_security_level_descr_t(MAC_DATA, MAC_CMD_DATA_REQ,
MAC_SEC_OFF, false);
static mac_key_id_lookup_descr_t key_id_lookup_descr;
key_id_lookup_descr = gen_mac_key_id_lookup_descr_t(KEY_LOOKUP_SIZE_NINE);
memcpy(key_id_lookup_descr.data, key_lookup_data, KEY_LOOKUP_SIZE_NINE_VAL);
static mac_key_device_descr_t key_device_descr;
key_device_descr = gen_mac_key_device_descr_t(0, false, false);
key_device_descr.table_service.idx = 0;
static mac_device_descr_t device_descr;
device_descr =
gen_mac_device_descr_t(pan_id, other_address, pan_external, 0, false);
static mac_key_usage_descr_t key_usage_descr;
key_usage_descr = gen_mac_key_usage_descr_t(MAC_DATA, MAC_CMD_DATA_REQ);
// build the key_descr-table:
static mac_key_descr_t key_descr;
gen_mac_key_descr_t(&key_descr);
mac_status_t ret1 = mac_table_item_set(&key_descr.id_lookup_list,
&key_id_lookup_descr.table_service,
MAC_KEY_ID_LOOKUP_LIST, 0);
// SEGGER_RTT_printf(0, "table item set1: ");
// print_mac_status(ret1);
mac_status_t ret2 = mac_table_item_set(&key_descr.key_device_list,
&key_device_descr.table_service,
MAC_KEY_DEVICE_LIST, 0);
// SEGGER_RTT_printf(0, "\ntable item set2: ");
// print_mac_status(ret2);
mac_status_t ret3 = mac_table_item_set(&key_descr.key_usage_list,
&key_usage_descr.table_service,
MAC_KEY_USAGE_LIST, 0);
// SEGGER_RTT_printf(0, "\ntable item set3: ");
// print_mac_status(ret3);
SEGGER_RTT_printf(0, "\n");
memcpy(key_descr.key, key, MAC_SECURITY_KEY_SIZE);
//
{
SEGGER_RTT_printf(0, "starting the scan\n");
print_scan_conf(scan_req(ACTIVE_SCAN, C14, 7));
SEGGER_RTT_printf(0, "finished the scan\n");
}
{
SEGGER_RTT_printf(0, "starting the scan\n");
print_scan_conf(scan_req(ACTIVE_SCAN , C20 , 7));
SEGGER_RTT_printf(0, "finished the scan\n");
}
{
SEGGER_RTT_printf(0, "starting the scan\n");
print_scan_conf(scan_req(ACTIVE_SCAN, C14, 7));
SEGGER_RTT_printf(0, "finished the scan\n");
}
{
SEGGER_RTT_printf(0, "starting the scan\n");
print_scan_conf(scan_req(ACTIVE_SCAN , C20, 7));
SEGGER_RTT_printf(0, "finished the scan\n");
}
{
mac_status_t state = mlme_set(gen_pib_id_t(MAC_PAN_ID), 0, &pan_id);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
pib_get_request(gen_pib_id_t(MAC_PAN_ID), "MAC_PAN_ID");
}
{
mac_status_t state = mlme_set(
gen_pib_id_t(MAC_PAN_COORD_EXTENDED_ADDRESS), 0, &pan_external);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
pib_get_request(gen_pib_id_t(MAC_PAN_COORD_EXTENDED_ADDRESS),
"MAC_PAN_COORD_EXTENDED_ADDRESS");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_PROMISCUOUS_MODE), 0, &promiscuous_mode);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
pib_get_request(gen_pib_id_t(MAC_PROMISCUOUS_MODE),
"MAC_PROMISCOUS_MODE");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_RX_ON_WHEN_IDLE), 0, &rx_on_when_idle);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
pib_get_request(gen_pib_id_t(MAC_RX_ON_WHEN_IDLE),
"MAC_RX_ON_WHEN_IDLE");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t_plme(PHY_CURRENT_CHANNEL_ID), 0, &channel_id);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
pib_get_request(gen_pib_id_t_plme(PHY_CURRENT_CHANNEL_ID),
"PHY_CURRENT_CHANNEL_ID");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_KEY_TABLE), 0, &key_descr);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
// pib_get_request(gen_pib_id_t(MAC_KEY_TABLE), "MAC_KEY_TABLE");
// pib_get_request(gen_pib_id_t(MAC_KEY_TABLE_ENTRIES),
// "MAC_KEY_TABLE_ENTRIES");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_DEVICE_TABLE), 0, &device_descr);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
//
// pib_get_request(gen_pib_id_t(MAC_DEVICE_TABLE), "MAC_DEVICE_TABLE");
// pib_get_request(gen_pib_id_t(MAC_DEVICE_TABLE_ENTRIES),
// "MAC_DEVICE_TABLE_ENTRIES");
}
{
mac_status_t state = mlme_set(gen_pib_id_t(MAC_SECURITY_LEVEL_TABLE), 0,
&sec_level_descr);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
// pib_get_request(gen_pib_id_t(MAC_SECURITY_LEVEL_TABLE),
// "MAC_SECURITY_LEVEL_TABLE");
// pib_get_request(gen_pib_id_t(MAC_SECURITY_LEVEL_TABLE_ENTRIES),
// "MAC_SECURITY_LEVEL_TABLE_ENTRIES");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_DEFAULT_KEY_SOURCE), 0, &default_source);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
// pib_get_request(gen_pib_id_t(MAC_DEFAULT_KEY_SOURCE),
// "MAC_DEFAULT_KEY_SOURCE");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_AUTO_REQUEST_SECURITY_LEVEL), 0,
&auto_request_security_level);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_AUTO_REQUEST), 0,
&auto_request);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
//pib_get_request(gen_pib_id_t(MAC_AUTO_REQUEST_SECURITY_LEVEL),
// "MAC_AUTO_REQUEST_SECURITY_LEVEL");
}
{
mac_status_t state =
mlme_set(gen_pib_id_t(MAC_SECURITY_ENABLED), 0, &security_enabled);
if (state != MAC_SUCCESS) {
SEGGER_RTT_printf(0, "failure in pib-set request: ");
print_mac_status(state);
SEGGER_RTT_printf(0, "\n");
}
}
pib_get_request(gen_pib_id_t(MAC_SECURITY_ENABLED),
"MAC_SECURITY_ENABLED");
}
while (true) {
sys_task_run();
}
}