2022-09-27 05:22:34 -04:00
|
|
|
/*
|
2023-05-15 08:52:31 -04:00
|
|
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
2022-09-27 05:22:34 -04:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
|
|
*/
|
2023-05-15 08:52:31 -04:00
|
|
|
|
2022-09-27 05:22:34 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "esp_system.h"
|
|
|
|
#include "esp_log.h"
|
|
|
|
#include "esp_ieee802154.h"
|
|
|
|
#include "esp_console.h"
|
|
|
|
#include "linenoise/linenoise.h"
|
|
|
|
#include "argtable3/argtable3.h"
|
|
|
|
#include "ieee802154_cmd.h"
|
|
|
|
#include "esp_phy_init.h"
|
2022-10-25 04:47:52 -04:00
|
|
|
#include "soc/soc.h"
|
2023-06-25 02:15:45 -04:00
|
|
|
#include "soc/ieee802154_reg.h"
|
2022-09-27 05:22:34 -04:00
|
|
|
|
|
|
|
static uint8_t s_tx_frame[131] = { 0 };
|
2023-10-11 07:41:20 -04:00
|
|
|
static const char* TAG = "i154cmd";
|
2022-09-27 05:22:34 -04:00
|
|
|
|
|
|
|
static void register_rx(void);
|
|
|
|
static void register_tx(void);
|
2022-10-25 04:47:52 -04:00
|
|
|
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);
|
2022-09-27 05:22:34 -04:00
|
|
|
|
|
|
|
void register_ieee802154_cmd(void)
|
|
|
|
{
|
|
|
|
register_rx();
|
|
|
|
register_tx();
|
2022-10-25 04:47:52 -04:00
|
|
|
register_energy();
|
|
|
|
register_channel();
|
|
|
|
register_txpower();
|
|
|
|
register_promisc();
|
|
|
|
register_panid();
|
|
|
|
register_shortaddr();
|
|
|
|
register_extaddr();
|
|
|
|
register_coordinator();
|
|
|
|
register_pending();
|
|
|
|
register_cca();
|
|
|
|
register_esp154();
|
|
|
|
register_reg();
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2023-10-11 07:41:20 -04:00
|
|
|
ESP_LOGE(TAG, "no valid arguments");
|
|
|
|
return 1;
|
2022-10-25 04:47:52 -04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "no valid arguments");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void register_energy(void)
|
|
|
|
{
|
|
|
|
energy_args.duration =
|
|
|
|
arg_int0("d", "duration", "<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];
|
2023-05-15 08:52:31 -04:00
|
|
|
esp_ieee802154_set_channel(channel);
|
2022-10-25 04:47:52 -04:00
|
|
|
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", "<n>", "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", "<n>", "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, "<panid>", "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, "<shortaddr>", "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],
|
2023-10-11 07:41:20 -04:00
|
|
|
extaddr[3], extaddr[2], extaddr[1], extaddr[0]);
|
2022-10-25 04:47:52 -04:00
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "no valid arguments");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void register_extaddr()
|
|
|
|
{
|
|
|
|
extaddr_args.set_extaddr =
|
|
|
|
arg_intn(NULL, NULL, "<extaddr>", 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", "<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, "<addr>", 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", "<addr>", 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", "<threshold>", "cca threshold setting");
|
|
|
|
cca_args.cca_mode_set =
|
|
|
|
arg_int0("m", "mode", "<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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 'reg' command reads/writes the registers */
|
|
|
|
static struct {
|
|
|
|
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)
|
|
|
|
{
|
2023-06-25 02:15:45 -04:00
|
|
|
uint32_t base = IEEE802154_REG_BASE;
|
2022-10-25 04:47:52 -04:00
|
|
|
|
|
|
|
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", "<address>", "read the register value");
|
|
|
|
reg_args.set_reg =
|
|
|
|
arg_int0("w", "write", "<address>", "register address to be written");
|
|
|
|
reg_args.value =
|
|
|
|
arg_int0("v", "value", "<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));
|
2022-09-27 05:22:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
struct arg_int *length;
|
|
|
|
struct arg_lit *cca_enable;
|
|
|
|
struct arg_int *frame;
|
|
|
|
struct arg_int *offset;
|
|
|
|
struct arg_end *end;
|
|
|
|
} tx_args;
|
|
|
|
|
|
|
|
static int process_tx(int argc, char **argv)
|
|
|
|
{
|
|
|
|
uint8_t tx_frame[128] = { 0 };
|
|
|
|
uint8_t offset = 0;
|
|
|
|
bool cca = false;
|
|
|
|
int nerrors = arg_parse(argc, argv, (void **) &tx_args);
|
|
|
|
if (nerrors != 0) {
|
|
|
|
arg_print_errors(stderr, tx_args.end, argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
memset(tx_frame, 0, sizeof(tx_frame));
|
|
|
|
|
|
|
|
if (tx_args.offset->count && (tx_args.offset->ival[0] >= 0 && tx_args.offset->ival[0] <= 3)) {
|
|
|
|
offset = tx_args.offset->ival[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tx_args.length->count) {
|
|
|
|
tx_frame[0] = tx_args.length->ival[0];
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < tx_frame[0]; i++) {
|
|
|
|
tx_frame[i + 1] = i;
|
|
|
|
}
|
|
|
|
} else if (tx_args.frame->count) {
|
|
|
|
tx_frame[0] = tx_args.frame->count;
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < tx_frame[0]; i++) {
|
|
|
|
tx_frame[i + 1] = tx_args.frame->ival[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tx_args.cca_enable->count) {
|
|
|
|
cca = true;
|
|
|
|
}
|
2023-10-11 07:41:20 -04:00
|
|
|
memcpy(s_tx_frame + offset, tx_frame, sizeof(tx_frame));
|
2022-09-27 05:22:34 -04:00
|
|
|
esp_ieee802154_transmit(s_tx_frame, cca);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void register_tx(void)
|
|
|
|
{
|
|
|
|
tx_args.length =
|
|
|
|
arg_int0("l", "length", "<len>", "frame length");
|
|
|
|
tx_args.cca_enable =
|
|
|
|
arg_lit0("C", "cca_enable", "set cca trigging tx mode true");
|
|
|
|
tx_args.frame =
|
|
|
|
arg_intn(NULL, NULL, "<n>", 0, 127, "transmit raw frame");
|
|
|
|
tx_args.offset =
|
|
|
|
arg_int0("o", "offset", "<offset>", "tx buffer offset");
|
|
|
|
tx_args.end = arg_end(5);
|
|
|
|
|
|
|
|
const esp_console_cmd_t cmd = {
|
|
|
|
.command = "tx",
|
|
|
|
.help = "transmit IEEE 802154 MAC frame",
|
|
|
|
.hint = NULL,
|
|
|
|
.func = &process_tx,
|
|
|
|
.argtable = &tx_args
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
struct arg_int *receive;
|
|
|
|
struct arg_end *end;
|
|
|
|
} rx_args;
|
|
|
|
|
|
|
|
static int process_rx(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int nerrors = arg_parse(argc, argv, (void **) &rx_args);
|
|
|
|
if (nerrors != 0) {
|
|
|
|
arg_print_errors(stderr, rx_args.end, argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rx_args.receive->count == 1) {
|
|
|
|
if (rx_args.receive->ival[0] == 0) {
|
|
|
|
esp_ieee802154_sleep();
|
|
|
|
ESP_LOGI(TAG, "radio exit receive mode");
|
|
|
|
} else if (rx_args.receive->ival[0] == 1) { // receive, non-blocking
|
|
|
|
ESP_LOGI(TAG, "RX Start");
|
|
|
|
esp_ieee802154_receive();
|
|
|
|
esp_ieee802154_set_rx_when_idle(true);
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "no valid arguments");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "no valid arguments");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void register_rx(void)
|
|
|
|
{
|
|
|
|
rx_args.receive =
|
|
|
|
arg_int0("r", "receive", "<mode>", "configure the radio receive mode, 0: disable; 1: enable");
|
|
|
|
rx_args.end = arg_end(2);
|
|
|
|
|
|
|
|
const esp_console_cmd_t cmd = {
|
|
|
|
.command = "rx",
|
|
|
|
.help = "enable/disable the receive mode",
|
|
|
|
.hint = NULL,
|
|
|
|
.func = &process_rx,
|
|
|
|
.argtable = &rx_args
|
|
|
|
};
|
|
|
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
|
|
|
}
|
|
|
|
|
2023-10-11 07:41:20 -04:00
|
|
|
static void esp_ieee802154_frame_print(const uint8_t *frame)
|
2023-06-25 02:15:45 -04:00
|
|
|
{
|
2023-10-11 07:41:20 -04:00
|
|
|
for (uint8_t idx = 1; idx < frame[0]; idx += 8) {
|
|
|
|
ESP_EARLY_LOGI(TAG, "%02x %02x %02x %02x %02x %02x %02x %02x",
|
|
|
|
frame[idx], frame[idx + 1], frame[idx + 2], frame[idx + 3],
|
|
|
|
frame[idx + 4], frame[idx + 5], frame[idx + 6], frame[idx + 7]);
|
|
|
|
}
|
2023-06-25 02:15:45 -04:00
|
|
|
}
|
|
|
|
|
2022-09-27 05:22:34 -04:00
|
|
|
void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info)
|
|
|
|
{
|
|
|
|
ESP_EARLY_LOGI(TAG, "Tx Done %d bytes", frame[0]);
|
2023-10-11 07:41:20 -04:00
|
|
|
esp_ieee802154_frame_print(frame);
|
2022-10-25 04:47:52 -04:00
|
|
|
|
|
|
|
if (ack != NULL) {
|
|
|
|
ESP_EARLY_LOGI(TAG, "Rx ack %d bytes", ack[0]);
|
2023-10-11 07:41:20 -04:00
|
|
|
esp_ieee802154_frame_print(ack);
|
2022-10-25 04:47:52 -04:00
|
|
|
}
|
2022-09-27 05:22:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info)
|
|
|
|
{
|
|
|
|
ESP_EARLY_LOGI(TAG, "Rx Done %d bytes", frame[0]);
|
2023-10-11 07:41:20 -04:00
|
|
|
esp_ieee802154_frame_print(frame);
|
2022-09-27 05:22:34 -04:00
|
|
|
}
|
2022-10-25 04:47:52 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|