mirror of
https://codeberg.org/opentrafficmap/its-g5-receiver-firmware.git
synced 2026-07-30 20:45:39 +00:00
Add config system; auto-start/stop mqtt on eth up/down; first attempt of sending received packets over MQTT
This commit is contained in:
+22
-8
@@ -1,9 +1,23 @@
|
|||||||
idf_component_register(SRCS "main.c"
|
idf_component_register(
|
||||||
"cmd_sniffer.c"
|
SRCS
|
||||||
"cmd_pcap.c"
|
"main.c"
|
||||||
"ethernet.c"
|
"cmd_sniffer.c"
|
||||||
"sdcard.c"
|
"cmd_pcap.c"
|
||||||
"spi.c"
|
"config.c"
|
||||||
PRIV_REQUIRES console esp_wifi fatfs esp_eth app_trace nvs_flash
|
"ethernet.c"
|
||||||
INCLUDE_DIRS ".")
|
"events.c"
|
||||||
|
"mqtt.c"
|
||||||
|
"sdcard.c"
|
||||||
|
"spi.c"
|
||||||
|
PRIV_REQUIRES
|
||||||
|
app_trace
|
||||||
|
console
|
||||||
|
esp_eth
|
||||||
|
esp_netif
|
||||||
|
esp_wifi
|
||||||
|
fatfs
|
||||||
|
nvs_flash
|
||||||
|
INCLUDE_DIRS
|
||||||
|
"."
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
+67
-51
@@ -1,20 +1,16 @@
|
|||||||
/* cmd_sniffer example.
|
#include "sdkconfig.h"
|
||||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, this
|
|
||||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
*/
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
#include "argtable3/argtable3.h"
|
#include "argtable3/argtable3.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include <sys/unistd.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
@@ -22,7 +18,8 @@
|
|||||||
#include "cmd_sniffer.h"
|
#include "cmd_sniffer.h"
|
||||||
#include "cmd_pcap.h"
|
#include "cmd_pcap.h"
|
||||||
#include "esp_check.h"
|
#include "esp_check.h"
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
#define SNIFFER_DEFAULT_CHANNEL (1)
|
#define SNIFFER_DEFAULT_CHANNEL (1)
|
||||||
#define SNIFFER_PAYLOAD_FCS_LEN (4)
|
#define SNIFFER_PAYLOAD_FCS_LEN (4)
|
||||||
@@ -32,7 +29,7 @@
|
|||||||
#define SNIFFER_DECIMAL_NUM (10)
|
#define SNIFFER_DECIMAL_NUM (10)
|
||||||
|
|
||||||
|
|
||||||
static const char *SNIFFER_TAG = "cmd_sniffer";
|
static const char TAG[] = "SNIFFER";
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *filter_name;
|
char *filter_name;
|
||||||
@@ -52,13 +49,6 @@ typedef struct {
|
|||||||
esp_eth_handle_t eth_handles[SNIFFER_MAX_ETH_INTFS];
|
esp_eth_handle_t eth_handles[SNIFFER_MAX_ETH_INTFS];
|
||||||
} sniffer_runtime_t;
|
} sniffer_runtime_t;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *payload;
|
|
||||||
uint32_t length;
|
|
||||||
uint32_t seconds;
|
|
||||||
uint32_t microseconds;
|
|
||||||
} sniffer_packet_info_t;
|
|
||||||
|
|
||||||
static sniffer_runtime_t snf_rt = {0};
|
static sniffer_runtime_t snf_rt = {0};
|
||||||
static wlan_filter_table_t wifi_filter_hash_table[SNIFFER_WLAN_FILTER_MAX] = {0};
|
static wlan_filter_table_t wifi_filter_hash_table[SNIFFER_WLAN_FILTER_MAX] = {0};
|
||||||
static esp_err_t sniffer_stop(sniffer_runtime_t *sniffer);
|
static esp_err_t sniffer_stop(sniffer_runtime_t *sniffer);
|
||||||
@@ -123,28 +113,51 @@ static void queue_packet(void *recv_packet, sniffer_packet_info_t *packet_info)
|
|||||||
if (snf_rt.work_queue) {
|
if (snf_rt.work_queue) {
|
||||||
/* send packet_info */
|
/* send packet_info */
|
||||||
if (xQueueSend(snf_rt.work_queue, packet_info, pdMS_TO_TICKS(SNIFFER_PROCESS_PACKET_TIMEOUT_MS)) != pdTRUE) {
|
if (xQueueSend(snf_rt.work_queue, packet_info, pdMS_TO_TICKS(SNIFFER_PROCESS_PACKET_TIMEOUT_MS)) != pdTRUE) {
|
||||||
ESP_LOGE(SNIFFER_TAG, "sniffer work queue full");
|
ESP_LOGE(TAG, "sniffer work queue full");
|
||||||
free(packet_info->payload);
|
free(packet_info->payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(SNIFFER_TAG, "No enough memory for promiscuous packet");
|
ESP_LOGE(TAG, "No enough memory for promiscuous packet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_packet_event(void *recv_packet, sniffer_packet_info_t *packet_info)
|
||||||
|
{
|
||||||
|
/* Copy a packet from Link Layer driver and queue the copy to be processed by sniffer task */
|
||||||
|
size_t combined_length = sizeof(sniffer_combined_info_t) + packet_info->length;
|
||||||
|
sniffer_combined_info_t *info_to_queue = malloc(combined_length);
|
||||||
|
if (info_to_queue) {
|
||||||
|
info_to_queue->info = *packet_info;
|
||||||
|
// TODO: This is one more copy than would be nice. Can we send shared_ptr over some sort of queue?
|
||||||
|
memcpy(info_to_queue->payload, recv_packet, packet_info->length);
|
||||||
|
info_to_queue->info.payload = NULL;
|
||||||
|
|
||||||
|
int result = esp_event_post(SNIFFER_EVENT_BASE, SNIFFER_GOT_FRAME, info_to_queue, combined_length, 0);
|
||||||
|
if (result != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Could not post event SNIFFER_GOT_FRAME: %s", esp_err_to_name(result));
|
||||||
|
}
|
||||||
|
free(info_to_queue);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "No enough memory for promiscuous packet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wifi_sniffer_cb(void *recv_buf, wifi_promiscuous_pkt_type_t type)
|
static void wifi_sniffer_cb(void *recv_buf, wifi_promiscuous_pkt_type_t type)
|
||||||
{
|
{
|
||||||
sniffer_packet_info_t packet_info;
|
sniffer_packet_info_t packet_info;
|
||||||
wifi_promiscuous_pkt_t *sniffer = (wifi_promiscuous_pkt_t *)recv_buf;
|
wifi_promiscuous_pkt_t *packet = (wifi_promiscuous_pkt_t *)recv_buf;
|
||||||
/* prepare packet_info */
|
/* prepare packet_info */
|
||||||
packet_info.seconds = sniffer->rx_ctrl.timestamp / 1000000U;
|
packet_info.seconds = packet->rx_ctrl.timestamp / 1000000U;
|
||||||
packet_info.microseconds = sniffer->rx_ctrl.timestamp % 1000000U;
|
packet_info.microseconds = packet->rx_ctrl.timestamp % 1000000U;
|
||||||
packet_info.length = sniffer->rx_ctrl.sig_len;
|
packet_info.length = packet->rx_ctrl.sig_len;
|
||||||
|
|
||||||
/* For now, the sniffer only dumps the length of the MISC type frame */
|
/* For now, the sniffer only dumps the length of the MISC type frame */
|
||||||
if (type != WIFI_PKT_MISC && !sniffer->rx_ctrl.rx_state) {
|
if (type != WIFI_PKT_MISC && !packet->rx_ctrl.rx_state) {
|
||||||
packet_info.length -= SNIFFER_PAYLOAD_FCS_LEN;
|
packet_info.length -= SNIFFER_PAYLOAD_FCS_LEN;
|
||||||
queue_packet(sniffer->payload, &packet_info);
|
//queue_packet(sniffer->payload, &packet_info);
|
||||||
|
send_packet_event(packet->payload, &packet_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +197,7 @@ static void sniffer_task(void *parameters)
|
|||||||
}
|
}
|
||||||
if (packet_capture(packet_info.payload, packet_info.length, packet_info.seconds,
|
if (packet_capture(packet_info.payload, packet_info.length, packet_info.seconds,
|
||||||
packet_info.microseconds) != ESP_OK) {
|
packet_info.microseconds) != ESP_OK) {
|
||||||
ESP_LOGW(SNIFFER_TAG, "save captured packet failed");
|
ESP_LOGW(TAG, "save captured packet failed");
|
||||||
}
|
}
|
||||||
free(packet_info.payload);
|
free(packet_info.payload);
|
||||||
if (sniffer->packets_to_sniff > 0) {
|
if (sniffer->packets_to_sniff > 0) {
|
||||||
@@ -204,25 +217,25 @@ static esp_err_t sniffer_stop(sniffer_runtime_t *sniffer)
|
|||||||
bool eth_set_promiscuous;
|
bool eth_set_promiscuous;
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
ESP_GOTO_ON_FALSE(sniffer->is_running, ESP_ERR_INVALID_STATE, err, SNIFFER_TAG, "sniffer is already stopped");
|
ESP_GOTO_ON_FALSE(sniffer->is_running, ESP_ERR_INVALID_STATE, err, TAG, "sniffer is already stopped");
|
||||||
|
|
||||||
switch (sniffer->interf) {
|
switch (sniffer->interf) {
|
||||||
case SNIFFER_INTF_WLAN:
|
case SNIFFER_INTF_WLAN:
|
||||||
/* Disable wifi promiscuous mode */
|
/* Disable wifi promiscuous mode */
|
||||||
ESP_GOTO_ON_ERROR(esp_wifi_set_promiscuous(false), err, SNIFFER_TAG, "stop wifi promiscuous failed");
|
ESP_GOTO_ON_ERROR(esp_wifi_set_promiscuous(false), err, TAG, "stop wifi promiscuous failed");
|
||||||
break;
|
break;
|
||||||
case SNIFFER_INTF_ETH:
|
case SNIFFER_INTF_ETH:
|
||||||
/* Disable Ethernet Promiscuous Mode */
|
/* Disable Ethernet Promiscuous Mode */
|
||||||
eth_set_promiscuous = false;
|
eth_set_promiscuous = false;
|
||||||
ESP_GOTO_ON_ERROR(esp_eth_ioctl(sniffer->eth_handles[sniffer->interf_num], ETH_CMD_S_PROMISCUOUS, ð_set_promiscuous),
|
ESP_GOTO_ON_ERROR(esp_eth_ioctl(sniffer->eth_handles[sniffer->interf_num], ETH_CMD_S_PROMISCUOUS, ð_set_promiscuous),
|
||||||
err, SNIFFER_TAG, "stop Ethernet promiscuous failed");
|
err, TAG, "stop Ethernet promiscuous failed");
|
||||||
esp_eth_update_input_path(sniffer->eth_handles[sniffer->interf_num], NULL, NULL);
|
esp_eth_update_input_path(sniffer->eth_handles[sniffer->interf_num], NULL, NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, SNIFFER_TAG, "unsupported interface");
|
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "unsupported interface");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ESP_LOGI(SNIFFER_TAG, "stop promiscuous ok");
|
ESP_LOGI(TAG, "stop promiscuous ok");
|
||||||
|
|
||||||
/* stop sniffer local task */
|
/* stop sniffer local task */
|
||||||
sniffer->is_running = false;
|
sniffer->is_running = false;
|
||||||
@@ -260,7 +273,7 @@ static esp_err_t sniffer_start(sniffer_runtime_t *sniffer)
|
|||||||
wifi_promiscuous_filter_t wifi_filter;
|
wifi_promiscuous_filter_t wifi_filter;
|
||||||
bool eth_set_promiscuous;
|
bool eth_set_promiscuous;
|
||||||
|
|
||||||
ESP_GOTO_ON_FALSE(!(sniffer->is_running), ESP_ERR_INVALID_STATE, err, SNIFFER_TAG, "sniffer is already running");
|
ESP_GOTO_ON_FALSE(!(sniffer->is_running), ESP_ERR_INVALID_STATE, err, TAG, "sniffer is already running");
|
||||||
|
|
||||||
switch (sniffer->interf) {
|
switch (sniffer->interf) {
|
||||||
case SNIFFER_INTF_WLAN:
|
case SNIFFER_INTF_WLAN:
|
||||||
@@ -270,21 +283,21 @@ static esp_err_t sniffer_start(sniffer_runtime_t *sniffer)
|
|||||||
link_type = PCAP_LINK_TYPE_ETHERNET;
|
link_type = PCAP_LINK_TYPE_ETHERNET;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, SNIFFER_TAG, "unsupported interface");
|
ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "unsupported interface");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init a pcap session */
|
/* init a pcap session */
|
||||||
ESP_GOTO_ON_ERROR(sniff_packet_start(link_type), err, SNIFFER_TAG, "init pcap session failed");
|
ESP_GOTO_ON_ERROR(sniff_packet_start(link_type), err, TAG, "init pcap session failed");
|
||||||
|
|
||||||
sniffer->is_running = true;
|
sniffer->is_running = true;
|
||||||
sniffer->work_queue = xQueueCreate(CONFIG_SNIFFER_WORK_QUEUE_LEN, sizeof(sniffer_packet_info_t));
|
sniffer->work_queue = xQueueCreate(CONFIG_SNIFFER_WORK_QUEUE_LEN, sizeof(sniffer_packet_info_t));
|
||||||
ESP_GOTO_ON_FALSE(sniffer->work_queue, ESP_FAIL, err_queue, SNIFFER_TAG, "create work queue failed");
|
ESP_GOTO_ON_FALSE(sniffer->work_queue, ESP_FAIL, err_queue, TAG, "create work queue failed");
|
||||||
sniffer->sem_task_over = xSemaphoreCreateBinary();
|
sniffer->sem_task_over = xSemaphoreCreateBinary();
|
||||||
ESP_GOTO_ON_FALSE(sniffer->sem_task_over, ESP_FAIL, err_sem, SNIFFER_TAG, "create work queue failed");
|
ESP_GOTO_ON_FALSE(sniffer->sem_task_over, ESP_FAIL, err_sem, TAG, "create work queue failed");
|
||||||
ESP_GOTO_ON_FALSE(xTaskCreate(sniffer_task, "snifferT", CONFIG_SNIFFER_TASK_STACK_SIZE,
|
ESP_GOTO_ON_FALSE(xTaskCreate(sniffer_task, "snifferT", CONFIG_SNIFFER_TASK_STACK_SIZE,
|
||||||
sniffer, CONFIG_SNIFFER_TASK_PRIORITY, &sniffer->task), ESP_FAIL,
|
sniffer, CONFIG_SNIFFER_TASK_PRIORITY, &sniffer->task), ESP_FAIL,
|
||||||
err_task, SNIFFER_TAG, "create task failed");
|
err_task, TAG, "create task failed");
|
||||||
|
|
||||||
switch (sniffer->interf) {
|
switch (sniffer->interf) {
|
||||||
case SNIFFER_INTF_WLAN:
|
case SNIFFER_INTF_WLAN:
|
||||||
@@ -292,20 +305,23 @@ static esp_err_t sniffer_start(sniffer_runtime_t *sniffer)
|
|||||||
wifi_filter.filter_mask = sniffer->filter;
|
wifi_filter.filter_mask = sniffer->filter;
|
||||||
esp_wifi_set_promiscuous_filter(&wifi_filter);
|
esp_wifi_set_promiscuous_filter(&wifi_filter);
|
||||||
esp_wifi_set_promiscuous_rx_cb(wifi_sniffer_cb);
|
esp_wifi_set_promiscuous_rx_cb(wifi_sniffer_cb);
|
||||||
ESP_GOTO_ON_ERROR(esp_wifi_set_promiscuous(true), err_start, SNIFFER_TAG, "set promis failed");
|
ESP_GOTO_ON_ERROR(esp_wifi_set_promiscuous(true), err_start, TAG, "set promis failed");
|
||||||
//ESP_GOTO_ON_ERROR(esp_wifi_set_channel(sniffer->channel, WIFI_SECOND_CHAN_NONE), err_start, SNIFFER_TAG, "set channel failed");
|
//ESP_GOTO_ON_ERROR(esp_wifi_set_channel(sniffer->channel, WIFI_SECOND_CHAN_NONE), err_start, TAG, "set channel failed");
|
||||||
phy_11p_set(1,0);
|
// enable 802.11p mode (enable, unknown (must be 0))
|
||||||
ESP_GOTO_ON_ERROR(esp_wifi_set_channel(140, WIFI_SECOND_CHAN_NONE), err_start, SNIFFER_TAG, "set channel failed");
|
phy_11p_set(1, 0);
|
||||||
|
// set a channel with a frequency close to our desired frequency (not sure if strictly needed)
|
||||||
|
ESP_GOTO_ON_ERROR(esp_wifi_set_channel(140, WIFI_SECOND_CHAN_NONE), err_start, TAG, "set channel failed");
|
||||||
|
// switch channel (channel, ignored, ignored, ht_mode?)
|
||||||
phy_change_channel(sniffer->channel, 1, 0, 0);
|
phy_change_channel(sniffer->channel, 1, 0, 0);
|
||||||
ESP_LOGI(SNIFFER_TAG, "start WiFi promiscuous ok");
|
ESP_LOGI(TAG, "start WiFi promiscuous ok");
|
||||||
break;
|
break;
|
||||||
case SNIFFER_INTF_ETH:
|
case SNIFFER_INTF_ETH:
|
||||||
/* Start Ethernet Promiscuous Mode */
|
/* Start Ethernet Promiscuous Mode */
|
||||||
eth_set_promiscuous = true;
|
eth_set_promiscuous = true;
|
||||||
ESP_GOTO_ON_ERROR(esp_eth_ioctl(sniffer->eth_handles[sniffer->interf_num], ETH_CMD_S_PROMISCUOUS, ð_set_promiscuous),
|
ESP_GOTO_ON_ERROR(esp_eth_ioctl(sniffer->eth_handles[sniffer->interf_num], ETH_CMD_S_PROMISCUOUS, ð_set_promiscuous),
|
||||||
err_start, SNIFFER_TAG, "start Ethernet promiscuous failed");
|
err_start, TAG, "start Ethernet promiscuous failed");
|
||||||
esp_eth_update_input_path(sniffer->eth_handles[sniffer->interf_num], eth_sniffer_cb, NULL);
|
esp_eth_update_input_path(sniffer->eth_handles[sniffer->interf_num], eth_sniffer_cb, NULL);
|
||||||
ESP_LOGI(SNIFFER_TAG, "start Ethernet promiscuous ok");
|
ESP_LOGI(TAG, "start Ethernet promiscuous ok");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -342,7 +358,7 @@ esp_err_t sniffer_reg_eth_intf(esp_eth_handle_t eth_handle)
|
|||||||
while ((snf_rt.eth_handles[i] != NULL) && (i < SNIFFER_MAX_ETH_INTFS)) {
|
while ((snf_rt.eth_handles[i] != NULL) && (i < SNIFFER_MAX_ETH_INTFS)) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
ESP_GOTO_ON_FALSE(i < SNIFFER_MAX_ETH_INTFS, ESP_FAIL, err, SNIFFER_TAG, "maximum num. of eth interfaces registered");
|
ESP_GOTO_ON_FALSE(i < SNIFFER_MAX_ETH_INTFS, ESP_FAIL, err, TAG, "maximum num. of eth interfaces registered");
|
||||||
snf_rt.eth_handles[i] = eth_handle;
|
snf_rt.eth_handles[i] = eth_handle;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@@ -380,16 +396,16 @@ static int do_sniffer_cmd(int argc, char **argv)
|
|||||||
snf_rt.interf = SNIFFER_INTF_ETH;
|
snf_rt.interf = SNIFFER_INTF_ETH;
|
||||||
snf_rt.interf_num = eth_intf_num;
|
snf_rt.interf_num = eth_intf_num;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(SNIFFER_TAG, "interface %s not found", sniffer_args.interface->sval[0]);
|
ESP_LOGE(TAG, "interface %s not found", sniffer_args.interface->sval[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(SNIFFER_TAG, "interface %s not found", sniffer_args.interface->sval[0]);
|
ESP_LOGE(TAG, "interface %s not found", sniffer_args.interface->sval[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snf_rt.interf = SNIFFER_INTF_WLAN;
|
snf_rt.interf = SNIFFER_INTF_WLAN;
|
||||||
ESP_LOGW(SNIFFER_TAG, "sniffing interface set to wlan by default");
|
ESP_LOGW(TAG, "sniffing interface set to wlan by default");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check channel: "-c" option */
|
/* Check channel: "-c" option */
|
||||||
@@ -402,7 +418,7 @@ static int do_sniffer_cmd(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case SNIFFER_INTF_ETH:
|
case SNIFFER_INTF_ETH:
|
||||||
if (sniffer_args.channel->count) {
|
if (sniffer_args.channel->count) {
|
||||||
ESP_LOGW(SNIFFER_TAG, "'channel' option is not available for Ethernet");
|
ESP_LOGW(TAG, "'channel' option is not available for Ethernet");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -427,7 +443,7 @@ static int do_sniffer_cmd(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case SNIFFER_INTF_ETH:
|
case SNIFFER_INTF_ETH:
|
||||||
if (sniffer_args.filter->count) {
|
if (sniffer_args.filter->count) {
|
||||||
ESP_LOGW(SNIFFER_TAG, "'filter' option is not available for Ethernet");
|
ESP_LOGW(TAG, "'filter' option is not available for Ethernet");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -437,7 +453,7 @@ static int do_sniffer_cmd(int argc, char **argv)
|
|||||||
snf_rt.packets_to_sniff = -1;
|
snf_rt.packets_to_sniff = -1;
|
||||||
if (sniffer_args.number->count) {
|
if (sniffer_args.number->count) {
|
||||||
snf_rt.packets_to_sniff = sniffer_args.number->ival[0];
|
snf_rt.packets_to_sniff = sniffer_args.number->ival[0];
|
||||||
ESP_LOGI(SNIFFER_TAG, "%" PRIi32 " packages will be captured", snf_rt.packets_to_sniff);
|
ESP_LOGI(TAG, "%" PRIi32 " packages will be captured", snf_rt.packets_to_sniff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start sniffer */
|
/* start sniffer */
|
||||||
|
|||||||
@@ -14,6 +14,18 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *payload;
|
||||||
|
uint32_t length;
|
||||||
|
uint32_t seconds;
|
||||||
|
uint32_t microseconds;
|
||||||
|
} sniffer_packet_info_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sniffer_packet_info_t info;
|
||||||
|
uint8_t payload[];
|
||||||
|
} sniffer_combined_info_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Supported Sniffer Interface
|
* @brief Supported Sniffer Interface
|
||||||
*
|
*
|
||||||
@@ -42,6 +54,7 @@ typedef enum {
|
|||||||
void register_sniffer_cmd(void);
|
void register_sniffer_cmd(void);
|
||||||
esp_err_t sniffer_reg_eth_intf(esp_eth_handle_t eth_handle);
|
esp_err_t sniffer_reg_eth_intf(esp_eth_handle_t eth_handle);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+596
@@ -0,0 +1,596 @@
|
|||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_mac.h"
|
||||||
|
#include "mbedtls/base64.h"
|
||||||
|
#include "nvs.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static const char TAG[] = "CONFIG";
|
||||||
|
|
||||||
|
static nvs_handle_t handle;
|
||||||
|
|
||||||
|
typedef esp_err_t (*config_u8_getter) (uint8_t *out);
|
||||||
|
typedef esp_err_t (*config_u16_getter) (uint16_t *out);
|
||||||
|
typedef esp_err_t (*config_u32_getter) (uint32_t *out);
|
||||||
|
typedef esp_err_t (*config_u64_getter) (uint64_t *out);
|
||||||
|
typedef esp_err_t (*config_i8_getter) (int8_t *out);
|
||||||
|
typedef esp_err_t (*config_i16_getter) (int16_t *out);
|
||||||
|
typedef esp_err_t (*config_i32_getter) (int32_t *out);
|
||||||
|
typedef esp_err_t (*config_i64_getter) (int64_t *out);
|
||||||
|
typedef esp_err_t (*config_str_getter) (char *out, size_t *size);
|
||||||
|
typedef esp_err_t (*config_blob_getter)(uint8_t *out, size_t *size);
|
||||||
|
|
||||||
|
typedef esp_err_t (*config_u8_setter) (uint8_t val);
|
||||||
|
typedef esp_err_t (*config_u16_setter) (uint16_t val);
|
||||||
|
typedef esp_err_t (*config_u32_setter) (uint32_t val);
|
||||||
|
typedef esp_err_t (*config_u64_setter) (uint64_t val);
|
||||||
|
typedef esp_err_t (*config_i8_setter) (int8_t val);
|
||||||
|
typedef esp_err_t (*config_i16_setter) (int16_t val);
|
||||||
|
typedef esp_err_t (*config_i32_setter) (int32_t val);
|
||||||
|
typedef esp_err_t (*config_i64_setter) (int64_t val);
|
||||||
|
typedef esp_err_t (*config_str_setter) (const char *val);
|
||||||
|
typedef esp_err_t (*config_blob_setter)(const uint8_t *val, size_t size);
|
||||||
|
|
||||||
|
typedef struct config_key {
|
||||||
|
char name[NVS_KEY_NAME_MAX_SIZE];
|
||||||
|
nvs_type_t type;
|
||||||
|
size_t buffer_size;
|
||||||
|
void *getter;
|
||||||
|
void *setter;
|
||||||
|
} config_key_t;
|
||||||
|
|
||||||
|
static esp_err_t config_get_node_id(char *out, size_t *size);
|
||||||
|
|
||||||
|
static const config_key_t config_keys[] = {
|
||||||
|
[CONFIG_INDEX_NODEID] = { "nodeid", NVS_TYPE_STR, CONFIG_NODEID_BUFFER_SIZE, config_get_node_id, NULL },
|
||||||
|
[CONFIG_INDEX_MQTT_URI] = { "mqtturi", NVS_TYPE_STR, CONFIG_MQTT_URI_BUFFER_SIZE, NULL, NULL },
|
||||||
|
};
|
||||||
|
#define CONFIG_KEYS_END (&config_keys[sizeof(config_keys)/sizeof(*config_keys)])
|
||||||
|
|
||||||
|
|
||||||
|
void config_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t err = nvs_flash_init();
|
||||||
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
err = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(nvs_open("its", NVS_READWRITE, &handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t config_get_node_id(char *out, size_t *size)
|
||||||
|
{
|
||||||
|
size_t size_copy = *size;
|
||||||
|
|
||||||
|
esp_err_t res = nvs_get_str(handle, "nodeid", out, &size_copy);
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
if (res != ESP_ERR_NVS_NOT_FOUND)
|
||||||
|
ESP_LOGW(TAG, "nvs_get_str failed: %s", esp_err_to_name(res));
|
||||||
|
|
||||||
|
uint8_t base_mac[6];
|
||||||
|
ESP_ERROR_CHECK(esp_base_mac_addr_get(base_mac));
|
||||||
|
|
||||||
|
int print_res = snprintf(out, *size, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
|
||||||
|
base_mac[0], base_mac[1], base_mac[2], base_mac[3], base_mac[4], base_mac[5]);
|
||||||
|
|
||||||
|
if (print_res > *size - 1)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "buffer too small to print");
|
||||||
|
return ESP_ERR_INVALID_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_res < 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "snprintf failed");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_copy = print_res + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = size_copy;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t config_get_str(config_index_t index, char *out, size_t *size)
|
||||||
|
{
|
||||||
|
const config_key_t *key = &config_keys[index];
|
||||||
|
|
||||||
|
if (key->type != NVS_TYPE_STR)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Attempt to get key %s with wrong type str", key->name);
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->getter)
|
||||||
|
return ((config_str_getter)key->getter)(out, size);
|
||||||
|
else
|
||||||
|
return nvs_get_str(handle, key->name, out, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t config_set_str(config_index_t index, const char *value)
|
||||||
|
{
|
||||||
|
const config_key_t *key = &config_keys[index];
|
||||||
|
|
||||||
|
if (key->type != NVS_TYPE_STR)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Attempt to set key %s with wrong type str", key->name);
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) >= key->buffer_size)
|
||||||
|
return ESP_ERR_INVALID_SIZE;
|
||||||
|
|
||||||
|
if (key->setter)
|
||||||
|
return ((config_str_setter)key->setter)(value);
|
||||||
|
else
|
||||||
|
return nvs_set_str(handle, key->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const config_key_t *config_key_find(const char *name)
|
||||||
|
{
|
||||||
|
for (const config_key_t *it = config_keys; it != CONFIG_KEYS_END; it++)
|
||||||
|
{
|
||||||
|
if (strcmp(name, it->name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
arg_lit_t *raw;
|
||||||
|
arg_str_t *key;
|
||||||
|
arg_str_t *value;
|
||||||
|
arg_end_t *end;
|
||||||
|
} config_set_args;
|
||||||
|
|
||||||
|
static int cmd_config_set(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **)&config_set_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, config_set_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *key_str = config_set_args.key->sval[0];
|
||||||
|
const char *value_str = config_set_args.value->sval[0];
|
||||||
|
|
||||||
|
const config_key_t *key = config_key_find(key_str);
|
||||||
|
if (key == NULL)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "No such config key: %s", key_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t res;
|
||||||
|
switch (key->type)
|
||||||
|
{
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
uint64_t parsed = strtoull(value_str, &end, 0);
|
||||||
|
if (*end != '\0')
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Invalid unsigned integer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((key->type == NVS_TYPE_U8 && parsed > UINT8_MAX) ||
|
||||||
|
(key->type == NVS_TYPE_U16 && parsed > UINT16_MAX) ||
|
||||||
|
(key->type == NVS_TYPE_U32 && parsed > UINT32_MAX))
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Value out of range for type");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->setter == NULL || config_set_args.raw->count)
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = nvs_set_u8(handle, key_str, (uint8_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = nvs_set_u16(handle, key_str, (uint16_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = nvs_set_u32(handle, key_str, (uint32_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = nvs_set_u64(handle, key_str, parsed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = ((config_u8_setter)key->setter)((uint8_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = ((config_u16_setter)key->setter)((uint16_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = ((config_u32_setter)key->setter)((uint32_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = ((config_u64_setter)key->setter)(parsed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I8:
|
||||||
|
case NVS_TYPE_I16:
|
||||||
|
case NVS_TYPE_I32:
|
||||||
|
case NVS_TYPE_I64:
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
int64_t parsed = strtoll(value_str, &end, 0);
|
||||||
|
if (*end != '\0')
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Invalid signed integer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((key->type == NVS_TYPE_I8 && (parsed < INT8_MIN || parsed > INT8_MAX)) ||
|
||||||
|
(key->type == NVS_TYPE_I16 && (parsed < INT16_MIN || parsed > INT16_MAX)) ||
|
||||||
|
(key->type == NVS_TYPE_I32 && (parsed < INT32_MIN || parsed > INT32_MAX)))
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Value out of range for type");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->setter == NULL || config_set_args.raw->count)
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = nvs_set_i8(handle, key_str, (int8_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = nvs_set_i16(handle, key_str, (int16_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = nvs_set_i32(handle, key_str, (int32_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = nvs_set_i64(handle, key_str, parsed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = ((config_i8_setter)key->setter)((int8_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = ((config_i16_setter)key->setter)((int16_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = ((config_i32_setter)key->setter)((int32_t)parsed);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = ((config_i64_setter)key->setter)(parsed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_STR:
|
||||||
|
if (strlen(value_str) >= key->buffer_size)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Value too long");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->setter == NULL || config_set_args.raw->count)
|
||||||
|
res = nvs_set_str(handle, key_str, value_str);
|
||||||
|
else
|
||||||
|
res = ((config_str_setter)key->setter)(value_str);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_BLOB:
|
||||||
|
{
|
||||||
|
unsigned char *buf = malloc(key->buffer_size);
|
||||||
|
size_t olen;
|
||||||
|
int result = mbedtls_base64_decode(buf, key->buffer_size, &olen, (const uint8_t *)value_str, strlen(value_str));
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "mbedtls_base64_decode failed: %#x", result);
|
||||||
|
free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (olen > key->buffer_size)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Value too long");
|
||||||
|
free(buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->setter == NULL || config_set_args.raw->count)
|
||||||
|
res = nvs_set_blob(handle, key_str, buf, olen);
|
||||||
|
else
|
||||||
|
res = ((config_blob_setter)key->setter)(buf, olen);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
// avoid compiler warning
|
||||||
|
res = ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "set failed: %s", esp_err_to_name(res));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_config_set(void)
|
||||||
|
{
|
||||||
|
config_set_args.raw = arg_lit0("R", NULL, "skip setter functions, directly write NVS");
|
||||||
|
config_set_args.key = arg_str1(NULL, NULL, "key", "the key");
|
||||||
|
config_set_args.value = arg_str1(NULL, NULL, "value", "the value to set");
|
||||||
|
config_set_args.end = arg_end(1);
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "config_set",
|
||||||
|
.help = "set a config key",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &cmd_config_set,
|
||||||
|
.argtable = &config_set_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
arg_lit_t *raw;
|
||||||
|
arg_str_t *key;
|
||||||
|
arg_end_t *end;
|
||||||
|
} config_get_args;
|
||||||
|
|
||||||
|
static int cmd_config_get(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **)&config_get_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, config_get_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *key_str = config_get_args.key->sval[0];
|
||||||
|
|
||||||
|
const config_key_t *key = config_key_find(key_str);
|
||||||
|
if (key == NULL)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "No such config key: %s", key_str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t res;
|
||||||
|
|
||||||
|
switch (key->type)
|
||||||
|
{
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
{
|
||||||
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
if (key->getter == NULL || config_get_args.raw->count)
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = nvs_get_u8(handle, key_str, (uint8_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = nvs_get_u16(handle, key_str, (uint16_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = nvs_get_u32(handle, key_str, (uint32_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = nvs_get_u64(handle, key_str, &value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_U8:
|
||||||
|
res = ((config_u8_getter)key->getter)((uint8_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U16:
|
||||||
|
res = ((config_u16_getter)key->getter)((uint16_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U32:
|
||||||
|
res = ((config_u32_getter)key->getter)((uint32_t *)&value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_U64:
|
||||||
|
res = ((config_u64_getter)key->getter)(&value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == ESP_OK)
|
||||||
|
printf("%"PRIu64 "\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I8:
|
||||||
|
case NVS_TYPE_I16:
|
||||||
|
case NVS_TYPE_I32:
|
||||||
|
case NVS_TYPE_I64:
|
||||||
|
{
|
||||||
|
int64_t value = 0;
|
||||||
|
|
||||||
|
if (key->getter == NULL || config_get_args.raw->count)
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_I8:
|
||||||
|
res = nvs_get_i8(handle, key_str, (int8_t *)&value);
|
||||||
|
value = (int64_t)(int8_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I16:
|
||||||
|
res = nvs_get_i16(handle, key_str, (int16_t *)&value);
|
||||||
|
value = (int64_t)(int16_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I32:
|
||||||
|
res = nvs_get_i32(handle, key_str, (int32_t *)&value);
|
||||||
|
value = (int64_t)(int32_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I64:
|
||||||
|
res = nvs_get_i64(handle, key_str, &value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (key->type) {
|
||||||
|
case NVS_TYPE_I8:
|
||||||
|
res = ((config_i8_getter)key->getter)((int8_t *)&value);
|
||||||
|
value = (int64_t)(int8_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I16:
|
||||||
|
res = ((config_i16_getter)key->getter)((int16_t *)&value);
|
||||||
|
value = (int64_t)(int16_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I32:
|
||||||
|
res = ((config_i32_getter)key->getter)((int32_t *)&value);
|
||||||
|
value = (int64_t)(int32_t)value;
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_I64:
|
||||||
|
res = ((config_i64_getter)key->getter)(&value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == ESP_OK)
|
||||||
|
printf("%"PRIi64 "\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_STR:
|
||||||
|
char *value = malloc(key->buffer_size);
|
||||||
|
size_t size = key->buffer_size;
|
||||||
|
|
||||||
|
if (key->getter == NULL || config_get_args.raw->count)
|
||||||
|
res = nvs_get_str(handle, key_str, value, &size);
|
||||||
|
else
|
||||||
|
res = ((config_str_getter)key->getter)(value, &size);
|
||||||
|
|
||||||
|
if (res == ESP_OK)
|
||||||
|
printf("%s\n", value);
|
||||||
|
|
||||||
|
free(value);
|
||||||
|
break;
|
||||||
|
case NVS_TYPE_BLOB:
|
||||||
|
{
|
||||||
|
unsigned char *buf = malloc(key->buffer_size);
|
||||||
|
size_t actual_size;
|
||||||
|
|
||||||
|
if (key->getter == NULL || config_get_args.raw->count)
|
||||||
|
res = nvs_get_blob(handle, key_str, buf, &actual_size);
|
||||||
|
else
|
||||||
|
res = ((config_blob_getter)key->getter)(buf, &actual_size);
|
||||||
|
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
free(buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t base64_buffer_size = (((4 * key->buffer_size / 3) + 3) & ~3) + 1;
|
||||||
|
unsigned char *base64_buf = malloc(base64_buffer_size);
|
||||||
|
size_t olen;
|
||||||
|
int result = mbedtls_base64_encode(base64_buf, base64_buffer_size, &olen, (const uint8_t *)buf, actual_size);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "mbedtls_base64_encode failed: %#x", result);
|
||||||
|
free(buf);
|
||||||
|
free(base64_buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", base64_buf);
|
||||||
|
free(buf);
|
||||||
|
free(base64_buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__builtin_unreachable();
|
||||||
|
// avoid compiler warning
|
||||||
|
res = ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "get failed: %s", esp_err_to_name(res));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_config_get(void)
|
||||||
|
{
|
||||||
|
config_get_args.raw = arg_lit0("R", NULL, "skip getter functions, directly read NVS");
|
||||||
|
config_get_args.key = arg_str1(NULL, NULL, "key", "the key");
|
||||||
|
config_get_args.end = arg_end(1);
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "config_get",
|
||||||
|
.help = "get a config key",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &cmd_config_get,
|
||||||
|
.argtable = &config_get_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_register_commands(void)
|
||||||
|
{
|
||||||
|
register_config_set();
|
||||||
|
register_config_get();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#define CONFIG_NODEID_BUFFER_SIZE 64
|
||||||
|
#define CONFIG_MQTT_URI_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
void config_init(void);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONFIG_INDEX_NODEID,
|
||||||
|
CONFIG_INDEX_MQTT_URI,
|
||||||
|
} config_index_t;
|
||||||
|
|
||||||
|
esp_err_t config_get_str(config_index_t index, char *out, size_t *size);
|
||||||
|
esp_err_t config_set_str(config_index_t index, const char *value);
|
||||||
|
|
||||||
|
|
||||||
|
void config_register_commands(void);
|
||||||
+50
-13
@@ -10,6 +10,7 @@
|
|||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
#include "cmd_sniffer.h"
|
#include "cmd_sniffer.h"
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
#include "ethernet.h"
|
#include "ethernet.h"
|
||||||
|
|
||||||
@@ -18,6 +19,9 @@
|
|||||||
|
|
||||||
static const char TAG[] = "ETHERNET";
|
static const char TAG[] = "ETHERNET";
|
||||||
|
|
||||||
|
static esp_netif_t *mgmt_netif;
|
||||||
|
static esp_eth_handle_t mgmt_eth;
|
||||||
|
|
||||||
/** Event handler for Ethernet events */
|
/** Event handler for Ethernet events */
|
||||||
static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
||||||
int32_t event_id, void *event_data)
|
int32_t event_id, void *event_data)
|
||||||
@@ -33,15 +37,20 @@ static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
|||||||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_DISCONNECTED:
|
case ETHERNET_EVENT_DISCONNECTED:
|
||||||
printf("\n");
|
|
||||||
ESP_LOGI(TAG, "Ethernet link down");
|
ESP_LOGI(TAG, "Ethernet link down");
|
||||||
|
if (eth_handle == mgmt_eth)
|
||||||
|
{
|
||||||
|
esp_err_t post_res = esp_event_post(APP_EVENT_BASE, APP_ETHERNET_MGMT_INTERFACE_DISCONNECTED, NULL, 0, 0);
|
||||||
|
if (post_res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "esp_event_post failed: %s", esp_err_to_name(post_res));
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_START:
|
case ETHERNET_EVENT_START:
|
||||||
printf("\n");
|
|
||||||
ESP_LOGI(TAG, "Ethernet started");
|
ESP_LOGI(TAG, "Ethernet started");
|
||||||
break;
|
break;
|
||||||
case ETHERNET_EVENT_STOP:
|
case ETHERNET_EVENT_STOP:
|
||||||
printf("\n");
|
|
||||||
ESP_LOGI(TAG, "Ethernet stopped");
|
ESP_LOGI(TAG, "Ethernet stopped");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -53,23 +62,48 @@ static void eth_event_handler(void *arg, esp_event_base_t event_base,
|
|||||||
static void ip_event_handler(void *arg, esp_event_base_t event_base,
|
static void ip_event_handler(void *arg, esp_event_base_t event_base,
|
||||||
int32_t event_id, void *event_data)
|
int32_t event_id, void *event_data)
|
||||||
{
|
{
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||||
|
|
||||||
|
char ifname[NETIF_NAMESIZE] = {0};
|
||||||
|
esp_err_t res = esp_netif_get_netif_impl_name(event->esp_netif, ifname);
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Failed to get netif name: %s", esp_err_to_name(res));
|
||||||
|
strcpy(ifname, "unk");
|
||||||
|
}
|
||||||
|
|
||||||
switch (event_id) {
|
switch (event_id) {
|
||||||
case IP_EVENT_ETH_GOT_IP:
|
case IP_EVENT_ETH_GOT_IP:
|
||||||
{
|
{
|
||||||
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
|
||||||
|
|
||||||
char ifname[NETIF_NAMESIZE] = {0};
|
|
||||||
esp_err_t res = esp_netif_get_netif_impl_name(event->esp_netif, ifname);
|
|
||||||
if (res != ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "Failed to get netif name: %s", esp_err_to_name(res));
|
|
||||||
strcpy(ifname, "unk");
|
|
||||||
}
|
|
||||||
|
|
||||||
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
const esp_netif_ip_info_t *ip_info = &event->ip_info;
|
||||||
ESP_LOGI(TAG, "Ethernet %s got IP: " IPSTR " netmask: " IPSTR " gw: " IPSTR, ifname, IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
|
ESP_LOGI(TAG, "Ethernet %s got IP: " IPSTR " netmask: " IPSTR " gw: " IPSTR, ifname, IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
|
||||||
|
|
||||||
|
// If this is the management netif, post an event to start MQTT etc.
|
||||||
|
if (event->esp_netif == mgmt_netif)
|
||||||
|
{
|
||||||
|
esp_err_t post_res = esp_event_post(APP_EVENT_BASE, APP_ETHERNET_MGMT_INTERFACE_CONNECTED, NULL, 0, 0);
|
||||||
|
if (post_res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "esp_event_post failed: %s", esp_err_to_name(post_res));
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IP_EVENT_ETH_LOST_IP:
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Ethernet %s lost IP", ifname);
|
||||||
|
|
||||||
|
// If this is the management netif, post an event to start MQTT etc.
|
||||||
|
if (event->esp_netif == mgmt_netif)
|
||||||
|
{
|
||||||
|
esp_err_t post_res = esp_event_post(APP_EVENT_BASE, APP_ETHERNET_MGMT_INTERFACE_DISCONNECTED, NULL, 0, 0);
|
||||||
|
if (post_res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "esp_event_post failed: %s", esp_err_to_name(post_res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -109,6 +143,9 @@ void initialize_ethernet(void)
|
|||||||
cfg.base = &esp_netif_config;
|
cfg.base = &esp_netif_config;
|
||||||
esp_netif_t *eth_netif = esp_netif_new(&cfg);
|
esp_netif_t *eth_netif = esp_netif_new(&cfg);
|
||||||
|
|
||||||
|
mgmt_netif = eth_netif;
|
||||||
|
mgmt_eth = eth_handles[i];
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
|
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
|
||||||
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
|
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
|
ESP_EVENT_DEFINE_BASE(APP_EVENT_BASE);
|
||||||
|
|
||||||
|
ESP_EVENT_DEFINE_BASE(SNIFFER_EVENT_BASE);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_event.h"
|
||||||
|
|
||||||
|
ESP_EVENT_DECLARE_BASE(APP_EVENT_BASE);
|
||||||
|
|
||||||
|
enum AppEvent
|
||||||
|
{
|
||||||
|
APP_ETHERNET_MGMT_INTERFACE_CONNECTED,
|
||||||
|
APP_ETHERNET_MGMT_INTERFACE_DISCONNECTED
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ESP_EVENT_DECLARE_BASE(SNIFFER_EVENT_BASE);
|
||||||
|
|
||||||
|
enum SnifferEvent
|
||||||
|
{
|
||||||
|
SNIFFER_GOT_FRAME
|
||||||
|
};
|
||||||
@@ -2,3 +2,5 @@ dependencies:
|
|||||||
pcap: "^1.0.0"
|
pcap: "^1.0.0"
|
||||||
espressif/ethernet_init:
|
espressif/ethernet_init:
|
||||||
version: "~1.3.0"
|
version: "~1.3.0"
|
||||||
|
espressif/mqtt:
|
||||||
|
version: "~1.0.0"
|
||||||
|
|||||||
+63
-25
@@ -14,7 +14,9 @@
|
|||||||
|
|
||||||
#include "cmd_sniffer.h"
|
#include "cmd_sniffer.h"
|
||||||
#include "cmd_pcap.h"
|
#include "cmd_pcap.h"
|
||||||
|
#include "config.h"
|
||||||
#include "ethernet.h"
|
#include "ethernet.h"
|
||||||
|
#include "mqtt.h"
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
|
|
||||||
@@ -40,16 +42,6 @@ static void initialize_filesystem(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_nvs(void)
|
|
||||||
{
|
|
||||||
esp_err_t err = nvs_flash_init();
|
|
||||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
||||||
err = nvs_flash_init();
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize wifi with tcp/ip adapter */
|
/* Initialize wifi with tcp/ip adapter */
|
||||||
static void initialize_wifi(void)
|
static void initialize_wifi(void)
|
||||||
{
|
{
|
||||||
@@ -59,27 +51,26 @@ static void initialize_wifi(void)
|
|||||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_main(void)
|
static esp_console_repl_t *repl;
|
||||||
|
static void console_init(void)
|
||||||
{
|
{
|
||||||
initialize_nvs();
|
// 31 buffer size - length of colors and 1 space after prompt - 1 closing angle bracket - 1 null byte
|
||||||
initialize_filesystem();
|
const size_t max_nodeid_length = 31 - (sizeof(LOG_COLOR_I " " LOG_RESET_COLOR) - 1) - 1 - 1;
|
||||||
|
|
||||||
initialize_spi();
|
char prompt[CONFIG_NODEID_BUFFER_SIZE];
|
||||||
|
size_t size = sizeof(prompt);
|
||||||
|
ESP_ERROR_CHECK(config_get_str(CONFIG_INDEX_NODEID, prompt, &size));
|
||||||
|
|
||||||
/*--- Initialize Network ---*/
|
if (size - 1 > max_nodeid_length)
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
strcpy(&prompt[max_nodeid_length - 3], "...");
|
||||||
/* Initialize WiFi */
|
|
||||||
initialize_wifi();
|
strcat(prompt, ">");
|
||||||
/* Initialize Ethernet */
|
|
||||||
initialize_ethernet();
|
|
||||||
|
|
||||||
/*--- Initialize Console ---*/
|
|
||||||
esp_console_repl_t *repl = NULL;
|
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
#if CONFIG_SNIFFER_STORE_HISTORY
|
#if CONFIG_SNIFFER_STORE_HISTORY
|
||||||
repl_config.history_save_path = HISTORY_FILE_PATH;
|
repl_config.history_save_path = HISTORY_FILE_PATH;
|
||||||
#endif
|
#endif
|
||||||
repl_config.prompt = "cli>";
|
repl_config.prompt = prompt;
|
||||||
|
|
||||||
// install console REPL environment
|
// install console REPL environment
|
||||||
#if CONFIG_ESP_CONSOLE_UART
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
@@ -92,15 +83,62 @@ void app_main(void)
|
|||||||
esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
||||||
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_reboot(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
esp_restart();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_reboot(void)
|
||||||
|
{
|
||||||
|
const esp_console_cmd_t cmd = {
|
||||||
|
.command = "reboot",
|
||||||
|
.help = "reboot the device",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &cmd_reboot,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
config_init();
|
||||||
|
|
||||||
|
initialize_filesystem();
|
||||||
|
|
||||||
|
initialize_spi();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
|
||||||
|
// Make sure MQTT has registered its event handlers before Ethernet goes up
|
||||||
|
mqtt_init();
|
||||||
|
|
||||||
|
/*--- Initialize Network ---*/
|
||||||
|
/* Initialize WiFi */
|
||||||
|
initialize_wifi();
|
||||||
|
/* Initialize Ethernet */
|
||||||
|
initialize_ethernet();
|
||||||
|
|
||||||
|
/*--- Initialize Console ---*/
|
||||||
|
console_init();
|
||||||
|
|
||||||
/* Register commands */
|
/* Register commands */
|
||||||
#if CONFIG_ENABLE_SD
|
#if CONFIG_ENABLE_SD
|
||||||
register_mount();
|
sdcard_register_commands();
|
||||||
register_unmount();
|
|
||||||
#endif
|
#endif
|
||||||
register_sniffer_cmd();
|
register_sniffer_cmd();
|
||||||
register_pcap_cmd();
|
register_pcap_cmd();
|
||||||
|
|
||||||
|
config_register_commands();
|
||||||
|
|
||||||
|
register_reboot();
|
||||||
|
|
||||||
// start console REPL
|
// start console REPL
|
||||||
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||||
}
|
}
|
||||||
|
|||||||
+172
@@ -0,0 +1,172 @@
|
|||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "mqtt_client.h"
|
||||||
|
|
||||||
|
#include "cmd_sniffer.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
|
#include "mqtt.h"
|
||||||
|
|
||||||
|
static const char TAG[] = "MQTT";
|
||||||
|
|
||||||
|
static esp_mqtt_client_handle_t client;
|
||||||
|
|
||||||
|
static char topic_prefix[96];
|
||||||
|
static char command_topic[128];
|
||||||
|
static char packet_topic[128];
|
||||||
|
|
||||||
|
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
|
||||||
|
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
|
||||||
|
|
||||||
|
esp_mqtt_event_handle_t event = event_data;
|
||||||
|
esp_mqtt_client_handle_t client = event->client;
|
||||||
|
int msg_id;
|
||||||
|
// your_context_t *context = event->context;
|
||||||
|
switch (event->event_id) {
|
||||||
|
case MQTT_EVENT_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, command_topic, 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTT_EVENT_SUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_UNSUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_PUBLISHED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DATA:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||||
|
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||||
|
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_ERROR:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||||
|
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||||
|
ESP_LOGI(TAG, "Last error code reported from esp-tls: 0x%x", event->error_handle->esp_tls_last_esp_err);
|
||||||
|
ESP_LOGI(TAG, "Last tls stack error number: 0x%x", event->error_handle->esp_tls_stack_err);
|
||||||
|
ESP_LOGI(TAG, "Last captured errno : %d (%s)", event->error_handle->esp_transport_sock_errno,
|
||||||
|
strerror(event->error_handle->esp_transport_sock_errno));
|
||||||
|
} else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
|
||||||
|
ESP_LOGI(TAG, "Connection refused error: 0x%x", event->error_handle->connect_return_code);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Unknown error type: 0x%x", event->error_handle->error_type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int make_topic_prefix()
|
||||||
|
{
|
||||||
|
size_t size = sizeof(topic_prefix);
|
||||||
|
strcpy(topic_prefix, "its/");
|
||||||
|
size -= 4;
|
||||||
|
|
||||||
|
esp_err_t res = config_get_str(CONFIG_INDEX_NODEID, topic_prefix + 4, &size);
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Could not get node ID from config: %s", esp_err_to_name(res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
topic_prefix[4 + size - 1] = '/';
|
||||||
|
topic_prefix[4 + size] = '\0';
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_start(void)
|
||||||
|
{
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "MQTT already started");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
make_topic_prefix();
|
||||||
|
|
||||||
|
strcpy(command_topic, topic_prefix);
|
||||||
|
strcat(command_topic, "command");
|
||||||
|
|
||||||
|
strcpy(packet_topic, topic_prefix);
|
||||||
|
strcat(packet_topic, "packet");
|
||||||
|
|
||||||
|
esp_mqtt_client_config_t mqtt_cfg = {0};
|
||||||
|
|
||||||
|
char mqtt_uri[CONFIG_MQTT_URI_BUFFER_SIZE];
|
||||||
|
size_t size = sizeof(mqtt_uri);
|
||||||
|
esp_err_t res = config_get_str(CONFIG_INDEX_MQTT_URI, mqtt_uri, &size);
|
||||||
|
if (res != ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Could not get MQTT URI from config: %s", esp_err_to_name(res));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mqtt_cfg.broker.address.uri = mqtt_uri;
|
||||||
|
|
||||||
|
esp_mqtt_client_handle_t client_ = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
|
esp_mqtt_client_register_event(client_, ESP_EVENT_ANY_ID, mqtt_event_handler, client_);
|
||||||
|
esp_mqtt_client_start(client_);
|
||||||
|
|
||||||
|
client = client_;
|
||||||
|
ESP_LOGI(TAG, "MQTT started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_stop(void)
|
||||||
|
{
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Attempted to stop MQTT while not running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_mqtt_client_stop(client);
|
||||||
|
|
||||||
|
esp_mqtt_client_handle_t client_ = client;
|
||||||
|
client = NULL;
|
||||||
|
esp_mqtt_client_destroy(client_);
|
||||||
|
ESP_LOGI(TAG, "MQTT stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void app_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
switch (event_id)
|
||||||
|
{
|
||||||
|
case APP_ETHERNET_MGMT_INTERFACE_CONNECTED:
|
||||||
|
mqtt_start();
|
||||||
|
break;
|
||||||
|
case APP_ETHERNET_MGMT_INTERFACE_DISCONNECTED:
|
||||||
|
mqtt_stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sniffer_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
if (!client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (event_id)
|
||||||
|
{
|
||||||
|
case SNIFFER_GOT_FRAME:
|
||||||
|
sniffer_combined_info_t *info = event_data;
|
||||||
|
esp_mqtt_client_publish(client, packet_topic, (const char *)info->payload, info->info.length, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_init(void)
|
||||||
|
{
|
||||||
|
esp_event_handler_register(APP_EVENT_BASE, ESP_EVENT_ANY_ID, app_event_handler, NULL);
|
||||||
|
esp_event_handler_register(SNIFFER_EVENT_BASE, ESP_EVENT_ANY_ID, sniffer_event_handler, NULL);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void mqtt_init(void);
|
||||||
@@ -139,4 +139,11 @@ void register_unmount(void)
|
|||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sdcard_register_commands(void)
|
||||||
|
{
|
||||||
|
register_mount();
|
||||||
|
register_unmount();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CONFIG_ENABLE_SD
|
#endif // CONFIG_ENABLE_SD
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void register_mount(void);
|
void sdcard_register_commands(void);
|
||||||
void register_unmount(void);
|
|
||||||
|
|||||||
@@ -2404,7 +2404,9 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y
|
|||||||
#
|
#
|
||||||
# ESP Trace Configuration
|
# ESP Trace Configuration
|
||||||
#
|
#
|
||||||
|
# default:
|
||||||
# CONFIG_ESP_TRACE_LIB_EXTERNAL is not set
|
# CONFIG_ESP_TRACE_LIB_EXTERNAL is not set
|
||||||
|
# default:
|
||||||
CONFIG_ESP_TRACE_LIB_NONE=y
|
CONFIG_ESP_TRACE_LIB_NONE=y
|
||||||
# default:
|
# default:
|
||||||
CONFIG_ESP_TRACE_LIB_NAME="none"
|
CONFIG_ESP_TRACE_LIB_NAME="none"
|
||||||
@@ -3986,6 +3988,33 @@ CONFIG_WL_SECTOR_SIZE_4096=y
|
|||||||
# default:
|
# default:
|
||||||
CONFIG_WL_SECTOR_SIZE=4096
|
CONFIG_WL_SECTOR_SIZE=4096
|
||||||
# end of Wear Levelling
|
# end of Wear Levelling
|
||||||
|
|
||||||
|
#
|
||||||
|
# ESP-MQTT Configurations
|
||||||
|
#
|
||||||
|
# default:
|
||||||
|
CONFIG_MQTT_PROTOCOL_311=y
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_PROTOCOL_5 is not set
|
||||||
|
# default:
|
||||||
|
CONFIG_MQTT_TRANSPORT_SSL=y
|
||||||
|
# default:
|
||||||
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||||
|
# default:
|
||||||
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
|
||||||
|
# default:
|
||||||
|
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
|
||||||
|
# end of ESP-MQTT Configurations
|
||||||
# end of Component config
|
# end of Component config
|
||||||
|
|
||||||
# default:
|
# default:
|
||||||
|
|||||||
Reference in New Issue
Block a user