From 1e3c82b27d35a4f635d6a9ab9a577728fe4b9aeb Mon Sep 17 00:00:00 2001 From: zhengyujie Date: Tue, 25 Oct 2022 16:47:52 +0800 Subject: [PATCH] ieee802154: add ieee802154 component CI --- .gitlab/ci/dependencies/dependencies.yml | 1 + .gitlab/ci/rules.yml | 24 +- .../test_ieee802154/main/src/ieee802154_cmd.c | 727 ++++++++++++++++++ .../test_ieee802154/pytest_test_ieee802154.py | 603 ++++++++++++++- 4 files changed, 1345 insertions(+), 10 deletions(-) diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index 87a15d404f..d5e958a9c1 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -167,6 +167,7 @@ build:integration_test: # For i154 runners "test:example_test-i154": patterns: + - "example_test-i154" - "target_test-i154" labels: - target_test diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 183264ef83..734134e6d4 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -85,9 +85,11 @@ - "components/**/*" .patterns-target_test-i154: &patterns-target_test-i154 - - "components/esp_netif/**/*" - "components/esp_phy/**/*" - "components/ieee802154/**/*" + +.patterns-example_test-i154: &patterns-example_test-i154 + - "components/esp_netif/**/*" - "components/lwip/**/*" - "components/openthread/**/*" - "examples/common_components/iperf/**/*" @@ -999,6 +1001,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1033,6 +1037,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1065,6 +1071,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1098,6 +1106,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1130,6 +1140,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1162,6 +1174,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1194,6 +1208,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1226,6 +1242,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -1335,6 +1353,8 @@ changes: *patterns-example_test-bt - <<: *if-dev-push changes: *patterns-example_test-ethernet + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-example_test-usb - <<: *if-dev-push @@ -2016,6 +2036,8 @@ when: never - <<: *if-label-example_test - <<: *if-label-target_test + - <<: *if-dev-push + changes: *patterns-example_test-i154 - <<: *if-dev-push changes: *patterns-target_test-i154 diff --git a/components/ieee802154/test_apps/test_ieee802154/main/src/ieee802154_cmd.c b/components/ieee802154/test_apps/test_ieee802154/main/src/ieee802154_cmd.c index c7dde2f060..a4b23c14c6 100644 --- a/components/ieee802154/test_apps/test_ieee802154/main/src/ieee802154_cmd.c +++ b/components/ieee802154/test_apps/test_ieee802154/main/src/ieee802154_cmd.c @@ -13,17 +13,715 @@ #include "argtable3/argtable3.h" #include "ieee802154_cmd.h" #include "esp_phy_init.h" +#include "soc/soc.h" static uint8_t s_tx_frame[131] = { 0 }; static const char* TAG = "i154test"; static void register_rx(void); static void register_tx(void); +static void register_energy(void); +static void register_channel(void); +static void register_txpower(void); +static void register_promisc(void); +static void register_panid(void); +static void register_shortaddr(void); +static void register_extaddr(void); +static void register_coordinator(void); +static void register_pending(void); +static void register_cca(void); +static void register_esp154(void); +static void register_reg(void); +static void register_free(void); void register_ieee802154_cmd(void) { register_rx(); register_tx(); + register_energy(); + register_channel(); + register_txpower(); + register_promisc(); + register_panid(); + register_shortaddr(); + register_extaddr(); + register_coordinator(); + register_pending(); + register_cca(); + register_esp154(); + register_reg(); + register_free(); +} + +static struct { + struct arg_int *duration; + struct arg_end *end; +} energy_args; + +static int process_energy(int argc, char **argv) +{ + uint32_t duration = 0; + + int nerrors = arg_parse(argc, argv, (void **) &energy_args); + if (nerrors != 0) { + arg_print_errors(stderr, energy_args.end, argv[0]); + return 1; + } + + if (energy_args.duration->count) { + duration = energy_args.duration->ival[0]; + if (energy_args.duration->ival[0]) { + ESP_LOGI(TAG, "ed start"); + esp_ieee802154_energy_detect(duration); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_energy(void) +{ + energy_args.duration = + arg_int0("d", "duration", "", "configure the duration of energy detection"); + energy_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "ed", + .help = "configure the duration", + .hint = NULL, + .func = &process_energy, + .argtable = &energy_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'channel' command gets/sets the channel number which the radio will work on */ +static struct { + struct arg_lit *get_channel; + struct arg_int *set_channel; + struct arg_end *end; +} channel_args; + +static int process_channel(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &channel_args); + if (nerrors != 0) { + arg_print_errors(stderr, channel_args.end, argv[0]); + return 1; + } + if (channel_args.get_channel->count) { + uint8_t channel = esp_ieee802154_get_channel(); + ESP_LOGI(TAG, "current channel: %d", channel); + } else if (channel_args.set_channel->count) { + uint8_t channel = channel_args.set_channel->ival[0]; + esp_ieee802154_set_channnel(channel); + ESP_LOGI(TAG, "set channel: %d", channel); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_channel() +{ + channel_args.get_channel = + arg_lit0("g", "get", "get channel number"); + channel_args.set_channel = + arg_int0("s", "set", "", "set channel number"); + channel_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "channel", + .help = "get/set the channel number", + .hint = NULL, + .func = &process_channel, + .argtable = &channel_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'txpower' command gets/sets the txpower */ +static struct { + struct arg_lit *get_txpower; + struct arg_int *set_txpower; + struct arg_end *end; +} txpower_args; + +static int process_txpower(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &txpower_args); + if (nerrors != 0) { + arg_print_errors(stderr, txpower_args.end, argv[0]); + return 1; + } + if (txpower_args.get_txpower->count) { + int8_t txpower = esp_ieee802154_get_txpower(); + ESP_LOGI(TAG, "current txpower: %d", txpower); + } else if (txpower_args.set_txpower->count) { + int8_t txpower = txpower_args.set_txpower->ival[0]; + esp_ieee802154_set_txpower(txpower); + ESP_LOGI(TAG, "set txpower: %d", txpower); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_txpower() +{ + txpower_args.get_txpower = + arg_lit0("g", "get", "get txpower"); + txpower_args.set_txpower = + arg_int0("s", "set", "", "set txpower,value range -80dBm~-10dBm"); + txpower_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "txpower", + .help = "get/set the txpower", + .hint = NULL, + .func = &process_txpower, + .argtable = &txpower_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'promisc' command enable/disable the promiscuous mode */ +static struct { + struct arg_lit *enable; + struct arg_lit *disable; + struct arg_lit *get_promisc; + struct arg_end *end; +} promisc_args; + +static int process_promisc(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &promisc_args); + if (nerrors != 0) { + arg_print_errors(stderr, promisc_args.end, argv[0]); + return 1; + } + + if (promisc_args.enable->count) { + esp_ieee802154_set_promiscuous(true); + ESP_LOGI(TAG, "promiscuous mode is enabled"); + } else if (promisc_args.disable->count) { + esp_ieee802154_set_promiscuous(false); + ESP_LOGI(TAG, "promiscuous mode is disabled"); + } else if (promisc_args.get_promisc->count) { + ESP_LOGI(TAG, "hardware promiscuous mode was %s", esp_ieee802154_get_promiscuous() ? "enabled" : "disabled"); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_promisc() +{ + promisc_args.enable = + arg_lit0("e", "enable", "enable the promiscuous mode"); + promisc_args.disable = + arg_lit0("d", "disable", "disable the promiscuous mode"); + promisc_args.get_promisc = + arg_lit0("g", "get", "get the promiscuous mode"); + promisc_args.end = arg_end(4); + + const esp_console_cmd_t cmd = { + .command = "promisc", + .help = "enable/disable/get the promiscuous mode", + .hint = NULL, + .func = &process_promisc, + .argtable = &promisc_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'panid' command set the device Pan ID */ +static struct { + struct arg_int *set_panid; + struct arg_lit *get_panid; + struct arg_end *end; +} panid_args; + +static int process_panid(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &panid_args); + if (nerrors != 0) { + arg_print_errors(stderr, panid_args.end, argv[0]); + return 1; + } + + if (panid_args.set_panid->count == 1) { + uint16_t panid = panid_args.set_panid->ival[0]; + esp_ieee802154_set_panid(panid); + ESP_LOGI(TAG, "set panid: 0x%x", panid); + } else if (panid_args.get_panid->count) { + uint16_t panid = esp_ieee802154_get_panid(); + ESP_LOGI(TAG, "current panid: 0x%x", panid); + } else { + ESP_LOGE(TAG, "no valid arguments"); + } + + return 0; +} + +static void register_panid() +{ + panid_args.set_panid = + arg_int0(NULL, NULL, "", "set the device Pan ID"); + panid_args.get_panid = + arg_lit0("g", "get", "get the device Pan ID"); + panid_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "panid", + .help = "get/set the device Pan ID", + .hint = NULL, + .func = &process_panid, + .argtable = &panid_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +static struct { + struct arg_int *set_shortaddr; + struct arg_lit *get_shortaddr; + struct arg_end *end; +} shortaddr_args; + +static int process_shortaddr(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &shortaddr_args); + if (nerrors != 0) { + arg_print_errors(stderr, shortaddr_args.end, argv[0]); + return 1; + } + + if (shortaddr_args.set_shortaddr->count == 1) { + uint16_t short_address = shortaddr_args.set_shortaddr->ival[0]; + esp_ieee802154_set_short_address(short_address); + ESP_LOGI(TAG, "set shortaddr: 0x%x", short_address); + } else if (shortaddr_args.get_shortaddr->count) { + uint16_t short_address = esp_ieee802154_get_short_address(); + ESP_LOGI(TAG, "current shortaddr: 0x%x", short_address); + } else { + ESP_LOGE(TAG, "no valid arguments"); + } + + return 0; +} + +static void register_shortaddr() +{ + shortaddr_args.set_shortaddr = + arg_int0(NULL, NULL, "", "set the device short address"); + shortaddr_args.get_shortaddr = + arg_lit0("g", "get", "get the device short address"); + shortaddr_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "shortaddr", + .help = "get/set the device short address", + .hint = NULL, + .func = &process_shortaddr, + .argtable = &shortaddr_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +static struct { + struct arg_lit *get_extaddr; + struct arg_int *set_extaddr; + struct arg_end *end; +} extaddr_args; + +static int process_extaddr(int argc, char **argv) +{ + uint8_t extaddr[8] = {0}; + int nerrors = arg_parse(argc, argv, (void **) &extaddr_args); + if (nerrors != 0) { + arg_print_errors(stderr, extaddr_args.end, argv[0]); + return 1; + } + if (extaddr_args.set_extaddr->count == 8) { + for (uint8_t i = 0; i < 8; i++) { + extaddr[i] = extaddr_args.set_extaddr->ival[i]; + } + esp_ieee802154_set_extended_address(extaddr); + ESP_LOGI(TAG, "set extaddr: %02x%02x%02x%02x%02x%02x%02x%02x", extaddr[7], extaddr[6], extaddr[5], extaddr[4], + extaddr[3], extaddr[2], extaddr[1], extaddr[0]); + } else if (extaddr_args.get_extaddr->count) { + esp_ieee802154_get_extended_address(extaddr); + ESP_LOGI(TAG, "get extaddr: %02x%02x%02x%02x%02x%02x%02x%02x", extaddr[7], extaddr[6], extaddr[5], extaddr[4], + extaddr[3], extaddr[2], extaddr[1], extaddr[0]); + } else { + ESP_LOGE(TAG, "no valid arguments"); + } + + return 0; +} + +static void register_extaddr() +{ + extaddr_args.set_extaddr = + arg_intn(NULL, NULL, "", 0, 127, "set the device extended address"); + extaddr_args.get_extaddr = + arg_lit0("g", "get", "get the device extended address"); + extaddr_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "extaddr", + .help = "set/get the device extended address", + .hint = NULL, + .func = &process_extaddr, + .argtable = &extaddr_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'coordinator' command enable/disable the coordinator */ +static struct { + struct arg_lit *enable; + struct arg_lit *disable; + struct arg_lit *get_coordinator; + struct arg_end *end; +} coordinator_args; + +static int process_coordinator(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &coordinator_args); + if (nerrors != 0) { + arg_print_errors(stderr, coordinator_args.end, argv[0]); + return 1; + } + + if (coordinator_args.enable->count) { + esp_ieee802154_set_coordinator(true); + ESP_LOGI(TAG, "hardware coordinator is enabled"); + } else if (coordinator_args.disable->count) { + esp_ieee802154_set_coordinator(false); + ESP_LOGI(TAG, "hardware coordinator is disabled"); + } else if (coordinator_args.get_coordinator->count) { + ESP_LOGI(TAG, "hardware coordinator was %s", esp_ieee802154_get_coordinator() ? "enabled" : "disabled"); + } + return 0; +} + +static void register_coordinator() +{ + coordinator_args.enable = + arg_lit0("e", "enable", "enable the coordinator"); + coordinator_args.disable = + arg_lit0("d", "disable", "disable the coordinator"); + coordinator_args.get_coordinator = + arg_lit0("g", "get", "get the coordinator"); + coordinator_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "coordinator", + .help = "enable/disable/get the coordinator", + .hint = NULL, + .func = &process_coordinator, + .argtable = &coordinator_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +static struct { + struct arg_int *set_mode; + struct arg_lit *get_mode; + struct arg_lit *reset; + struct arg_int *add_addr; + struct arg_int *del_addr; + struct arg_end *end; +} pending_args; + +static int process_pending(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &pending_args); + if (nerrors != 0) { + arg_print_errors(stderr, pending_args.end, argv[0]); + return 1; + } + + esp_ieee802154_pending_mode_t pending_mode = 0; + if (pending_args.set_mode->count) { + pending_mode = pending_args.set_mode->ival[0]; + esp_ieee802154_set_pending_mode(pending_mode); + ESP_LOGI(TAG, "set auto pending mode as: %d", pending_mode); + } else if (pending_args.get_mode->count) { + pending_mode = esp_ieee802154_get_pending_mode(); + ESP_LOGI(TAG, "get auto pending mode as: %d", pending_mode); + } else if (pending_args.reset->count) { + esp_ieee802154_reset_pending_table(false); + esp_ieee802154_reset_pending_table(true); + ESP_LOGI(TAG, "clear the pending address table"); + } else if (pending_args.add_addr->count == 2) { + uint8_t short_addr[2]; + + short_addr[0] = pending_args.add_addr->ival[0]; + short_addr[1] = pending_args.add_addr->ival[1]; + + esp_ieee802154_add_pending_addr(short_addr, true); + ESP_LOGI(TAG, "add pending shortaddr: 0x%02x%02x", short_addr[1], short_addr[0]); + } else if (pending_args.add_addr->count == 8) { + uint8_t extaddr[8] = {0}; + + for (uint8_t i = 0; i < 8; i++) { + extaddr[i] = pending_args.add_addr->ival[i]; + } + + esp_ieee802154_add_pending_addr(extaddr, false); + ESP_LOGI(TAG, "add pending extaddr: 0x%02x%02x%02x%02x%02x%02x%02x%02x", extaddr[7], extaddr[6], extaddr[5], extaddr[4], + extaddr[3], extaddr[2], extaddr[1], extaddr[0]); + } else if (pending_args.del_addr->count == 2) { + uint8_t short_addr[2]; + + short_addr[0] = pending_args.del_addr->ival[0]; + short_addr[1] = pending_args.del_addr->ival[1]; + + esp_ieee802154_clear_pending_addr(short_addr, true); + ESP_LOGI(TAG, "delete pending shortaddr: 0x%02x%02x", short_addr[1], short_addr[0]); + } else if (pending_args.del_addr->count == 8) { + uint8_t extaddr[8] = {0}; + + for (uint8_t i = 0; i < 8; i++) { + extaddr[i] = pending_args.del_addr->ival[i]; + } + + esp_ieee802154_clear_pending_addr(extaddr, false); + ESP_LOGI(TAG, "delete pending extaddr: 0x%02x%02x%02x%02x%02x%02x%02x%02x", extaddr[7], extaddr[6], extaddr[5], extaddr[4], + extaddr[3], extaddr[2], extaddr[1], extaddr[0]); + } else { + ESP_LOGE(TAG, "no valid arguments"); + } + + return 0; +} + +static void register_pending() +{ + pending_args.set_mode = + arg_int0("m", "mode", "", "set the autopending mode (0: disable; 1: enable; 2: enhanced)"); + pending_args.get_mode = + arg_lit0("g", "get", "get the autopending mode (0: disable; 1: enable; 2: enhanced)"); + pending_args.reset = + arg_lit0("r", "reset", "reset the pending address table"); + pending_args.add_addr = + arg_intn(NULL, NULL, "", 0, 8, "add the address to pending table (2 bytes for short address, 8 bytes for extended address)"); + pending_args.del_addr = + arg_intn("d", "delete", "", 0, 8, "delete the address from pending table (2 bytes for short address, 8 bytes for extended address)"); + pending_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "pending", + .help = "configure the pending address table", + .hint = NULL, + .func = &process_pending, + .argtable = &pending_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +//CCA command +static struct { + struct arg_int *cca_threshold_set; + struct arg_int *cca_mode_set; + struct arg_lit *cca_cfg_get; + struct arg_end *end; +} cca_args; + +static int process_cca(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &cca_args); + + if (nerrors != 0) { + arg_print_errors(stderr, cca_args.end, argv[0]); + return 1; + } + + int8_t cca_threshold = 0; + esp_ieee802154_cca_mode_t cca_mode = 0; + if (cca_args.cca_threshold_set->count) { + cca_threshold = cca_args.cca_threshold_set->ival[0]; + esp_ieee802154_set_cca_threshold(cca_threshold); + ESP_LOGI(TAG, "set cca threshold as: %d", cca_threshold); + } + + else if (cca_args.cca_mode_set->count) { + cca_mode = cca_args.cca_mode_set->ival[0]; + esp_ieee802154_set_cca_mode(cca_mode); + ESP_LOGI(TAG, "set cca mode as: %d", cca_mode); + } + + else if (cca_args.cca_cfg_get->count) { + ESP_LOGI(TAG, "threshold:%d dB, mode: %d", esp_ieee802154_get_cca_threshold(), esp_ieee802154_get_cca_mode()); + } else { + ESP_LOGI(TAG, "no valid arguments"); + } + + return 0; +} + +static void register_cca() +{ + cca_args.cca_threshold_set = + arg_int0("v", "value", "", "cca threshold setting"); + cca_args.cca_mode_set = + arg_int0("m", "mode", "", "cca mode, 0: carrier; 1: ED; 2: carrier or ED; 3: carrier and ED"); + cca_args.cca_cfg_get = + arg_lit0("g", "get", "get the cca cfg"); + cca_args.end = arg_end(4); + + const esp_console_cmd_t cmd = { + .command = "cca", + .help = "cca config", + .hint = NULL, + .func = &process_cca, + .argtable = &cca_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'esp_154' command enable/disable initialize the IEEE 802.15.4 subsystem */ +static struct { + struct arg_lit *enable; + struct arg_lit *disable; + struct arg_end *end; +} esp154_args; + +static int process_esp154(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &esp154_args); + if (nerrors != 0) { + arg_print_errors(stderr, esp154_args.end, argv[0]); + return 1; + } + + if (esp154_args.enable->count) { + esp_ieee802154_enable(); + ESP_LOGI(TAG, "initialize the IEEE 802.15.4 subsystem"); + } else if (esp154_args.disable->count) { + esp_ieee802154_disable(); + ESP_LOGI(TAG, "deinitialize the IEEE 802.15.4 subsystem"); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_esp154() +{ + esp154_args.enable = + arg_lit0("e", "enable", "initialize the IEEE 802.15.4 subsystem"); + esp154_args.disable = + arg_lit0("d", "disable", "deinitialize the IEEE 802.15.4 subsystem"); + esp154_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "esp154", + .help = "enable/disable initialize the IEEE 802.15.4 subsystem", + .hint = NULL, + .func = &process_esp154, + .argtable = &esp154_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'fheap' command check for memory leaks */ +static struct { + struct arg_end *end; +} free_args; + +static int process_free(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &free_args); + if (nerrors != 0) { + arg_print_errors(stderr, free_args.end, argv[0]); + return 1; + } + + esp_get_free_heap_size(); + ESP_LOGI(TAG, "heap size: %"PRIu32"\n", esp_get_free_heap_size()); + return 0; +} + +static void register_free() +{ + free_args.end = arg_end(2); + + const esp_console_cmd_t cmd = { + .command = "fheap", + .help = "get the size of heap memory", + .hint = NULL, + .func = &process_free, + .argtable = &free_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +/* 'reg' command reads/writes the registers */ +extern uint32_t IEEE802154; +static struct { + struct arg_lit *base; + struct arg_int *get_reg; + struct arg_int *set_reg; + struct arg_int *value; + struct arg_end *end; +} reg_args; + +static int process_reg(int argc, char **argv) +{ + uint32_t *base = &IEEE802154; + + int nerrors = arg_parse(argc, argv, (void **) ®_args); + if (nerrors != 0) { + arg_print_errors(stderr, reg_args.end, argv[0]); + return 1; + } + + if (reg_args.get_reg->count == 1) { + uint32_t reg_offset = reg_args.get_reg->ival[0]; + uint32_t reg_value = REG_READ(reg_offset + base); + ESP_LOGI(TAG, "reg 0x%lx value: 0x%lx", reg_offset, reg_value); + } else if (reg_args.set_reg->count == 1 && reg_args.value->count == 1) { + uint32_t reg_offset = reg_args.set_reg->ival[0]; + uint32_t reg_value = reg_args.value->ival[0]; + REG_WRITE(reg_offset + base, reg_value); + ESP_LOGI(TAG, "write reg 0x%lx: 0x%lx", reg_offset, reg_value); + } else { + ESP_LOGE(TAG, "no valid arguments"); + return 1; + } + return 0; +} + +static void register_reg() +{ + reg_args.get_reg = + arg_int0("r", "read", "
", "read the register value"); + reg_args.set_reg = + arg_int0("w", "write", "
", "register address to be written"); + reg_args.value = + arg_int0("v", "value", "", "register value to be written"); + reg_args.end = arg_end(6); + + const esp_console_cmd_t cmd = { + .command = "reg", + .help = "read/write the register", + .hint = NULL, + .func = &process_reg, + .argtable = ®_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); } static struct { @@ -149,6 +847,15 @@ void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ frame[idx], frame[idx+1], frame[idx+2], frame[idx+3], frame[idx+4], frame[idx+5], frame[idx+6], frame[idx+7]); } + + if (ack != NULL) { + ESP_EARLY_LOGI(TAG, "Rx ack %d bytes", ack[0]); + for(uint8_t idx = 1; idx < ack[0]; idx+=8) { + ESP_EARLY_LOGI(TAG, "%02x %02x %02x %02x %02x %02x %02x %02x", + ack[idx], ack[idx+1], ack[idx+2], ack[idx+3], + ack[idx+4], ack[idx+5], ack[idx+6], ack[idx+7]); + } + } } void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) @@ -160,3 +867,23 @@ void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *fr frame[idx+4], frame[idx+5], frame[idx+6], frame[idx+7]); } } + +void esp_ieee802154_energy_detect_done(int8_t power) +{ + ESP_EARLY_LOGI(TAG, "ed_scan_rss_value: %d dB", power); +} + +void esp_ieee802154_transmit_sfd_done(uint8_t *frame) +{ + ESP_EARLY_LOGI(TAG, "tx sfd done, Radio state: %d", esp_ieee802154_get_state()); +} + +void esp_ieee802154_receive_sfd_done(void) +{ + ESP_EARLY_LOGI(TAG, "rx sfd done, Radio state: %d", esp_ieee802154_get_state()); +} + +void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error) +{ + ESP_EARLY_LOGI(TAG, "the Frame Transmission failed, Failure reason: %d", error); +} diff --git a/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py b/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py index 7a93c434dc..b2863b4b34 100644 --- a/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py +++ b/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py @@ -1,12 +1,115 @@ # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 -from typing import Tuple +import random +import re +from time import sleep +from typing import List, Tuple +import pexpect import pytest from pytest_embedded_idf.dut import IdfDut +def generate_shortaddr() -> str: + shortaddr = '' + cnt = 0 + while cnt < 2: + num = random.randint(0, 255) + shortaddr = shortaddr + '0x%02X ' % (num) + cnt = cnt + 1 + shortaddr = shortaddr.rstrip() + return shortaddr + + +def generate_extaddr() -> str: + extaddr = '' + cnt = 0 + while cnt < 8: + num = random.randint(0, 255) + extaddr = extaddr + '0x%02X ' % (num) + cnt = cnt + 1 + extaddr = extaddr.rstrip() + return extaddr + + +def dlt_pendingtable(ser:IdfDut, addr:str) -> None: + if addr != '': + addr_list = re.findall(r'0x([A-Za-z0-9]{2})', addr) + addr_field = '0x' + ''.join(reversed(addr_list)) + addr_field = addr_field.lower() + addr_list = addr.split(' ') + if len(addr_list) == 2 or len(addr_list) == 8: + cmd = 'pending' + for item in addr_list: + cmd = cmd + ' -d {}'.format(item) + cmd = cmd + '\n' + ser.write(cmd) + if len(addr_list) == 2: + ser.expect('delete pending shortaddr: {}'.format(addr_field), timeout=1) + else: + ser.expect('delete pending extaddr: {}'.format(addr_field), timeout=1) + sleep(0.1) + + +def add_pendingtable(ser:IdfDut, addr:str='') -> None: + if len(addr.split(' ')) == 2 or len(addr.split(' ')) == 8: + cmd = 'pending %s\n' % (addr) + addr_list = re.findall(r'0x([A-Za-z0-9]{2})', addr) + addr_field = '0x' + ''.join(reversed(addr_list)) + addr_field = addr_field.lower() + ser.write(cmd) + if len(addr.split(' ')) == 2: + ser.expect('add pending shortaddr: {}'.format(addr_field), timeout=1) + else: + ser.expect('add pending extaddr: {}'.format(addr_field), timeout=1) + sleep(0.1) + + +def generate_wrong_PANID_addr(right:str) -> str: + wrong = '' + for i in right.split(' '): + num = (int(i, 16) + random.randint(1, 255)) % 256 + wrong = wrong + '0x%02X ' % (num) + wrong = wrong.rstrip() + return wrong + + +def set_mismatch_short_extern_addr_pendingtable(ser:IdfDut, addr:str, short:int=12, extern:int=12) -> List[List]: + short_addr = [] + extern_addr = [] + cnt = 0 + while cnt < short: + if len(addr.split(' ')) == 2: + addr = generate_wrong_PANID_addr(addr) + add_pendingtable(ser, addr) + else: + addr = generate_shortaddr() + add_pendingtable(ser, addr) + short_addr.append(addr) + cnt = cnt + 1 + while cnt < extern: + if len(addr.split(' ')) == 8: + addr = generate_wrong_PANID_addr(addr) + add_pendingtable(ser, addr) + else: + addr = generate_extaddr() + add_pendingtable(ser, addr) + extern_addr.append(addr) + cnt = cnt + 1 + return [short_addr, extern_addr] + + +def dlt_short_extern_addr_in_pendingtable(ser:IdfDut, table:List, short:int=5, extern:int=5) -> None: + cnt = 0 + while cnt < short: + dlt_pendingtable(ser, table[0][cnt]) + cnt = cnt + 1 + while cnt < extern: + dlt_pendingtable(ser, table[1][cnt]) + cnt = cnt + 1 + + @pytest.mark.esp32h4 @pytest.mark.ieee802154 @pytest.mark.parametrize( @@ -17,13 +120,495 @@ from pytest_embedded_idf.dut import IdfDut def test_based_txrx(dut: Tuple[IdfDut, IdfDut]) -> None: transmit = dut[0] receive = dut[1] - receive.expect('ieee802154>', timeout=60) + receive.expect('ieee802154>', timeout=1) + transmit.write('channel -s 23') + transmit.expect('set channel: 23', timeout=1) + receive.write('channel -s 23') + receive.expect('set channel: 23', timeout=1) receive.write('rx -r 1') - receive.expect('RX Start', timeout=60) - transmit.expect('ieee802154>', timeout=60) + receive.expect('RX Start', timeout=1) + transmit.expect('ieee802154>', timeout=1) transmit.write('tx -l 10') - transmit.expect('Tx Done 10 bytes', timeout=60) - transmit.expect('00 01 02 03 04 05 06 07', timeout=60) - transmit.expect('08 09 00 00 00 00 00 00', timeout=60) - receive.expect('Rx Done 10 bytes', timeout=60) - receive.expect('00 01 02 03 04 05 06 07', timeout=60) + transmit.expect('tx sfd done, Radio state: 3', timeout=1) + transmit.expect('Tx Done 10 bytes', timeout=1) + transmit.expect('00 01 02 03 04 05 06 07', timeout=1) + transmit.expect('08 09 00 00 00 00 00 00', timeout=1) + receive.expect('rx sfd done, Radio state: 2', timeout=1) + receive.expect('Rx Done 10 bytes', timeout=1) + receive.expect('00 01 02 03 04 05 06 07', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + transmit.write('tx -l 10') + transmit.expect('tx sfd done, Radio state: 3', timeout=1) + transmit.expect('Tx Done 10 bytes', timeout=1) + transmit.expect('00 01 02 03 04 05 06 07', timeout=1) + transmit.expect('08 09 00 00 00 00 00 00', timeout=1) + tmp = receive.expect(pexpect.TIMEOUT, timeout=5) + assert 'Rx Done' not in str(tmp) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_energy(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('ed -d 8') + transmit.expect('ed start', timeout=1) + transmit.expect('ed_scan_rss_value:', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_channel(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('channel -s 23') + transmit.expect('set channel: 23', timeout=1) + transmit.write('channel -g') + transmit.expect('current channel: 23', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_txpower(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('txpower -s 13') + transmit.expect('set txpower: 13', timeout=1) + transmit.write('txpower -g') + transmit.expect('current txpower: 13', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_promiscuous(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('promisc -e') + transmit.expect('promiscuous mode is enabled', timeout=1) + transmit.write('promisc -g') + transmit.expect('hardware promiscuous mode was enabled', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + transmit.write('promisc -g') + transmit.expect('hardware promiscuous mode was disabled', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_panid(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('panid 0x60') + transmit.expect('set panid: 0x60', timeout=1) + transmit.write('panid -g') + transmit.expect('current panid: 0x60', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_shortaddr(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('shortaddr 0x1234') + transmit.expect('set shortaddr: 0x1234', timeout=1) + transmit.write('shortaddr -g') + transmit.expect('current shortaddr: 0x1234', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_extaddr(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('extaddr 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08') + transmit.expect('set extaddr: 0807060504030201', timeout=1) + transmit.write('extaddr -g') + transmit.expect('get extaddr: 0807060504030201', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_coordinator(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('coordinator -e') + transmit.expect('hardware coordinator is enabled', timeout=1) + transmit.write('coordinator -g') + transmit.expect('hardware coordinator was enabled', timeout=1) + transmit.write('coordinator -d') + transmit.expect('hardware coordinator is disabled', timeout=1) + transmit.write('coordinator -g') + transmit.expect('hardware coordinator was disabled', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_pending(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('pending -m 2') + transmit.expect('set auto pending mode as: 2', timeout=1) + transmit.write('pending -g') + transmit.expect('get auto pending mode as: 2', timeout=1) + add_pendingtable(transmit, addr='0x01 0x02') + add_pendingtable(transmit, addr='0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08') + dlt_pendingtable(transmit, addr='0x22 0x11') + dlt_pendingtable(transmit, addr='0x77 0x66 0x55 0x44 0x33 0x22 0x11 0x00') + transmit.write('pending -r') + transmit.expect('clear the pending address table', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_cca(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('cca -v -60') + transmit.expect('set cca threshold as: -60', timeout=1) + transmit.write('cca -m 0') + transmit.expect('set cca mode as: 0', timeout=1) + transmit.write('cca -g') + transmit.expect('threshold:-60 dB, mode: 0', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (2, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_autoack(dut: Tuple[IdfDut, IdfDut]) -> None: + transmit = dut[0] + receive = dut[1] + transmit.expect('ieee802154>', timeout=1) + transmit.write('channel -s 23') + transmit.expect('set channel: 23', timeout=1) + receive.expect('ieee802154>', timeout=1) + receive.write('channel -s 23') + receive.expect('set channel: 23', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + transmit.write('panid 0x280A') + transmit.expect('set panid: 0x280a', timeout=1) + transmit.write('shortaddr 0x435A') + transmit.expect('set shortaddr: 0x435a', timeout=1) + receive.write('panid 0x94BC') + receive.expect('set panid: 0x94bc', timeout=1) + receive.write('shortaddr 0x6FDB') + receive.expect('set shortaddr: 0x6fdb', timeout=1) + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + + transmit.write('tx 0x20 0x88 0x00 0x0A 0x28 0xDB 0x6F 0xBC 0x94 0x5A 0x43 0x68 0x02 0xaa 0x15 0x30 0x01 0x02') + transmit.expect('tx sfd done, Radio state: 3', timeout=1) + transmit.expect('rx sfd done, Radio state: 3', timeout=1) + transmit.expect('Tx Done 18 bytes', timeout=1) + transmit.expect('20 88 00 0a 28 db 6f bc', timeout=1) + transmit.expect('94 5a 43 68 02 aa 15 30', timeout=1) + + receive.expect('rx sfd done, Radio state: 2', timeout=1) + receive.expect('Rx Done 18 bytes', timeout=1) + receive.expect('20 88 00 0a 28 db 6f bc', timeout=1) + receive.expect('94 5a 43 68 02 aa 15 30', timeout=1) + + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('02 00 00', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (2, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: + transmit = dut[0] + receive = dut[1] + +# mode 0: CMD ID = 0x04 --> FP = 1 + transmit.expect('ieee802154>', timeout=1) + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode') + transmit.write('channel -s 23') + transmit.expect('set channel: 23') + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled') + + receive.expect('ieee802154>', timeout=1) + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('channel -s 23') + receive.expect('set channel: 23', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 0') + receive.expect('set auto pending mode as: 0', timeout=1) + receive.write('panid 0x2E74') + receive.expect('set panid: 0x2e74', timeout=1) + receive.write('shortaddr 0x2649') + receive.expect('set shortaddr: 0x2649', timeout=1) + + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x23 0x08 0x00 0x74 0x2E 0x49 0x26 0x04 0x53 0x04 0xe3 0x71 0xc2 0x36 0xf7 0xa5 0x2b 0x68 0x79 0x8c 0x72 0x50 0x8b 0x61 0x55 0x56') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('12 00 00', timeout=1) + +# mode 0: CMD ID != 0x04 --> FP = 0 + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 0') + receive.expect('set auto pending mode as: 0', timeout=1) + receive.write('panid 0x3E66') + receive.expect('set panid: 0x3e66', timeout=1) + receive.write('shortaddr 0x3970') + receive.expect('set shortaddr: 0x3970', timeout=1) + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x23 0x08 0x0c 0x66 0x3E 0x70 0x39 0x01 0xef 0x2e 0x9f 0xf3 0xfe 0x75 0x99 0x35 0x66 0xd3') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('02 00 0c', timeout=1) + +# mode 1: CMD ID = 0x04, src addr in pending table --> FP = 1 + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 1') + receive.expect('set auto pending mode as: 1', timeout=1) + receive.write('panid 0x2D9B') + receive.expect('set panid: 0x2d9b', timeout=1) + receive.write('shortaddr 0x3B21') + receive.expect('set shortaddr: 0x3b21', timeout=1) + + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + transmit.write('panid 0xD9C3') + transmit.expect('set panid: 0xd9c3', timeout=1) + transmit.write('shortaddr 0x93EE') + transmit.expect('set shortaddr: 0x93ee', timeout=1) + + wrong_table = set_mismatch_short_extern_addr_pendingtable(receive, '0xEE 0x93') + dlt_short_extern_addr_in_pendingtable(receive, wrong_table) + add_pendingtable(receive, '0xEE 0x93') + + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x23 0x88 0x00 0x9B 0x2D 0x21 0x3B 0xC3 0xD9 0xEE 0x93 0x04 0xc8 0x05 0xf8 0x1d 0x6e 0xe3') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('12 00 00', timeout=1) + +# mode 1: CMD ID = 0x04, src addr not in pending table --> FP = 0 + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 1') + receive.expect('set auto pending mode as: 1', timeout=1) + receive.write('panid 0x9FE3') + receive.expect('set panid: 0x9fe3', timeout=1) + receive.write('shortaddr 0x9E20') + receive.expect('set shortaddr: 0x9e20', timeout=1) + + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + transmit.write('panid 0xE718') + transmit.expect('set panid: 0xe718', timeout=1) + transmit.write('shortaddr 0xC466') + transmit.expect('set shortaddr: 0xc466', timeout=1) + + wrong_table = set_mismatch_short_extern_addr_pendingtable(receive, '0x66 0xC4') + dlt_short_extern_addr_in_pendingtable(receive, wrong_table) + + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x2b 0x88 0x08 0xE3 0x9F 0x20 0x9E 0x18 0xE7 0x66 0xC4 0x17 0x92 0x8a 0xcd 0x4c 0xd0 0x20 0x40 0x0d 0x46 0x04 0xa0 0xe3 0x9c 0x57') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('02 00 08', timeout=1) + +# mode 2: frame type is data, src addr in pending table --> FP = 1 + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 2') + receive.expect('set auto pending mode as: 2', timeout=1) + receive.write('panid 0xA116') + receive.expect('set panid: 0xa116', timeout=1) + receive.write('shortaddr 0x939C') + receive.expect('set shortaddr: 0x939c', timeout=1) + + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + transmit.write('panid 0x9B0B') + transmit.expect('set panid: 0x9b0b', timeout=1) + transmit.write('shortaddr 0x04E4') + transmit.expect('set shortaddr: 0x4e4', timeout=1) + + wrong_table = set_mismatch_short_extern_addr_pendingtable(receive, '0xE4 0x04') + dlt_short_extern_addr_in_pendingtable(receive, wrong_table) + add_pendingtable(receive, '0xE4 0x04') + + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x21 0x88 0x10 0x16 0xA1 0x9C 0x93 0x0B 0x9B 0xE4 0x04 0xb8 0xc5 0x63 0x43 0xa7 0x81 0xaf') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('12 00 10', timeout=1) + +# mode 2: frame type is data, src addr not in pending table --> FP = 0 + receive.write('pending -r') + receive.expect('clear the pending address table', timeout=1) + receive.write('promisc -d') + receive.expect('promiscuous mode is disabled', timeout=1) + receive.write('rx -r 0') + receive.expect('radio exit receive mode', timeout=1) + receive.write('pending -m 2') + receive.expect('set auto pending mode as: 2', timeout=1) + receive.write('panid 0xE0C9') + receive.expect('set panid: 0xe0c9', timeout=1) + receive.write('shortaddr 0x3325') + receive.expect('set shortaddr: 0x3325', timeout=1) + + transmit.write('rx -r 0') + transmit.expect('radio exit receive mode', timeout=1) + transmit.write('promisc -d') + transmit.expect('promiscuous mode is disabled', timeout=1) + transmit.write('panid 0x844F') + transmit.expect('set panid: 0x844f', timeout=1) + transmit.write('shortaddr 0x7C4C') + transmit.expect('set shortaddr: 0x7c4c', timeout=1) + + wrong_table = set_mismatch_short_extern_addr_pendingtable(receive, '0x4C 0x7C') + dlt_short_extern_addr_in_pendingtable(receive, wrong_table) + + receive.write('rx -r 1') + receive.expect('RX Start', timeout=1) + transmit.write('tx 0x21 0x88 0x10 0xC9 0xE0 0x25 0x33 0x4F 0x84 0x4C 0x7C 0xa8 0xff 0x51 0x72 0xef 0xc1 0xbb') + transmit.expect('Rx ack 5 bytes', timeout=1) + transmit.expect('02 00 10', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_transmit_failed(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('channel -s 23') + transmit.expect('set channel: 23', timeout=1) + transmit.write('cca -v -120') + transmit.expect('set cca threshold as: -120', timeout=1) + transmit.write('tx -l 10 -C') + transmit.expect('the Frame Transmission failed, Failure reason: 1', timeout=1) + transmit.write('tx -l 10') + transmit.expect('tx sfd done, Radio state: 3', timeout=1) + transmit.expect('Tx Done 10 bytes', timeout=1) + transmit.expect('00 01 02 03 04 05 06 07', timeout=1) + transmit.expect('08 09 00 00 00 00 00 00', timeout=1) + + +@pytest.mark.esp32h4 +@pytest.mark.ieee802154 +@pytest.mark.parametrize( + 'count, config, beta_target', [ + (1, 'release', 'esp32h2beta2'), + ], indirect=True +) +def test_based_initialize(dut: IdfDut) -> None: + transmit = dut + transmit.expect('ieee802154>', timeout=1) + transmit.write('fheap') + fst_data = transmit.expect(r'heap size: [0-9]+', timeout=1)[0].decode() + fst_size = re.findall(r'heap size: ([0-9]+)', fst_data) + transmit.write('esp154 -e') + transmit.expect('initialize the IEEE 802.15.4 subsystem', timeout=1) + transmit.write('esp154 -d') + transmit.expect('deinitialize the IEEE 802.15.4 subsystem', timeout=1) + transmit.write('fheap') + scd_data = transmit.expect(r'heap size: [0-9]+', timeout=1)[0].decode() + scd_size = re.findall(r'heap size: ([0-9]+)', scd_data) + print('first heap size: ', int(fst_size[0])) + print('second heap size: ', int(scd_size[0]))