Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/nrf52/radio/nrf802154: fix beacon acceptance #20982

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
24 changes: 16 additions & 8 deletions cpu/nrf52/radio/nrf802154/nrf802154_radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,22 @@ static void _power_off(void)
static bool _l2filter(uint8_t *mhr)
{
uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN];
uint8_t src_addr[IEEE802154_LONG_ADDRESS_LEN];
le_uint16_t dst_pan;
le_uint16_t src_pan;
uint8_t pan_bcast[] = IEEE802154_PANID_BCAST;

int addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan);
int dst_addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan);

int src_addr_len = ieee802154_get_src(mhr, src_addr, &src_pan);

if ((mhr[0] & IEEE802154_FCF_TYPE_MASK) == IEEE802154_FCF_TYPE_BEACON) {
if ((memcmp(&nrf802154_pan_id, pan_bcast, 2) == 0)) {
return true;
if (src_addr_len == IEEE802154_SHORT_ADDRESS_LEN ||
src_addr_len == IEEE802154_LONG_ADDRESS_LEN){
if ((memcmp(&nrf802154_pan_id, src_pan.u8, 2) == 0) ||
(memcmp(&nrf802154_pan_id, pan_bcast, 2) == 0)) {
return true;
}
}
}
/* filter PAN ID */
Expand All @@ -138,11 +146,11 @@ static bool _l2filter(uint8_t *mhr)
}

/* check destination address */
if (((addr_len == IEEE802154_SHORT_ADDRESS_LEN) &&
(memcmp(nrf802154_short_addr, dst_addr, addr_len) == 0 ||
memcmp(ieee802154_addr_bcast, dst_addr, addr_len) == 0)) ||
((addr_len == IEEE802154_LONG_ADDRESS_LEN) &&
(memcmp(nrf802154_long_addr, dst_addr, addr_len) == 0))) {
if (((dst_addr_len == IEEE802154_SHORT_ADDRESS_LEN) &&
(memcmp(nrf802154_short_addr, dst_addr, dst_addr_len) == 0 ||
memcmp(ieee802154_addr_bcast, dst_addr, dst_addr_len) == 0)) ||
((dst_addr_len == IEEE802154_LONG_ADDRESS_LEN) &&
(memcmp(nrf802154_long_addr, dst_addr, dst_addr_len) == 0))) {
return true;
}

Expand Down
5 changes: 5 additions & 0 deletions tests/drivers/nrf802154/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# About
This is a manual test application for the NRF802154 radio driver.
Supported boards must have an nRF52-series chip that has an IEEE 802.15.4 radio (e.g. nrf52840dk).

# Usage
For testing the radio driver you can use the ifconfig and txtsnd shell commands
that are included in this application.

For testing beacon frame acceptance you can flash this test onto two nRF52 devices
and use the beaconsend command to send an IEEE 802.15.4 beacon frame.
The opponent should print the received frame details.
73 changes: 72 additions & 1 deletion tests/drivers/nrf802154/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,77 @@ int netdev_ieee802154_minimal_init_devs(netdev_event_cb_t cb) {
return 0;
}

void send_beacon_usage(char *cmd_name)
{
printf("usage: %s [<16 bit hex source PAN ID>] (uses device PAN ID by default)\n", cmd_name);
}

int cmd_send_beacon(int argc, char **argv)
{
uint16_t pan_id;
/* evaluating if argument is present */
switch (argc) {
case 1:
pan_id = nrf802154.dev.pan;
puts("using device PAN ID as source");
break;
case 2:
if (strlen(argv[1]) != 4) {
puts("send: Error parsing PAN ID");
send_beacon_usage(argv[0]);
return 1;
}
pan_id = strtoul(argv[1], NULL, 16);
break;
default:
send_beacon_usage(argv[0]);
return 1;
}

printf("PAN ID: %x\n", pan_id);

/* preparing the mac header */
uint8_t mhr[IEEE802154_MAX_HDR_LEN];
memset(mhr, 0, IEEE802154_MAX_HDR_LEN*sizeof(uint8_t));
le_uint16_t src_pan = byteorder_btols(byteorder_htons(pan_id));
le_uint16_t dst_pan = byteorder_htols(0);
size_t src_len = 2, dst_len = 0;
uint8_t *src = nrf802154.dev.short_addr, *dst = NULL;
uint8_t flags = IEEE802154_FCF_TYPE_BEACON;

int res = ieee802154_set_frame_hdr(mhr, src, src_len,
dst, dst_len,
src_pan, dst_pan,
flags, nrf802154.dev.seq++);
if (res < 0) {
puts("send: Error preparing frame");
send_beacon_usage(argv[0]);
return 1;
}
/* preparing packet to send */
iolist_t iol = {
.iol_base = mhr,
.iol_len = (size_t)res,
.iol_next = NULL,
};

puts("Sending Beacon Frame");

res = netdev_ieee802154_minimal_send(&nrf802154.dev.netdev, &iol);

if (res < 0) {
puts("send: Error on sending");
send_beacon_usage(argv[0]);
return 1;
}
return 0;
}

static const shell_command_t shell_commands[] = {
{ "beaconsend", "Send an IEEE 802.15.4 beacon frame", cmd_send_beacon},
{NULL, NULL, NULL}
};

int main(void)
{
puts("Test application for NRF802154 IEEE 802.15.4 device driver");
Expand All @@ -66,7 +137,7 @@ int main(void)
puts("Initialization successful - starting the shell now");

char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);

return 0;
}
Loading