添加智能灯固件代码

This commit is contained in:
kerwincui
2021-07-13 17:14:51 +08:00
parent 332f74dd17
commit ecc0b91b8b
2568 changed files with 229441 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "simple_sniffer_example_main.c"
"cmd_sniffer.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,61 @@
menu "Example Configuration"
config SNIFFER_STORE_HISTORY
bool "Store command history into flash"
default y
help
Linenoise line editing library provides functions to save and load command history.
If this option is enabled, initalizes a FAT filesystem and uses it to store command history.
choice SNIFFER_PCAP_DESTINATION
prompt "Select destination to store pcap file"
default SNIFFER_PCAP_DESTINATION_SD if IDF_TARGET_ESP32
default SNIFFER_PCAP_DESTINATION_JTAG if IDF_TARGET_ESP32S2
help
Select where to store the pcap file.
Currently support storing files to SD card or to host via JTAG interface.
config SNIFFER_PCAP_DESTINATION_SD
bool "SD Card"
help
Store pcap file to SD card.
config SNIFFER_PCAP_DESTINATION_JTAG
bool "JTAG (App Trace)"
help
Store pcap file to host via JTAG interface.
endchoice
if SNIFFER_PCAP_DESTINATION_SD
config SNIFFER_MOUNT_POINT
string "SD card mount point in the filesystem"
default "/sdcard"
help
Specify the mount point in the VFS (Virtual File System) for SD card.
config SNIFFER_PCAP_FILE_NAME_MAX_LEN
int "Max name length of pcap file"
default 32
help
Specify maximum name length of pcap file.
endif
config SNIFFER_WORK_QUEUE_LEN
int "Length of sniffer work queue"
default 128
help
The sniffer callback function should not do heavy work, so we put all heavy IO operation to another task.
The task gets some basic info of sniffer packet via queue.
Here you should specify the length of queue.
config SNIFFER_TASK_STACK_SIZE
int "Stack size of sniffer task"
default 4096
help
Stack size of sniffer task.
config SNIFFER_TASK_PRIORITY
int "Priority of sniffer task"
default 2
help
Priority of sniffer task.
endmenu

View File

@@ -0,0 +1,395 @@
/* cmd_sniffer example.
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 "argtable3/argtable3.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include <sys/unistd.h>
#include <sys/fcntl.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_console.h"
#include "esp_app_trace.h"
#include "cmd_sniffer.h"
#include "pcap.h"
#include "sdkconfig.h"
#define SNIFFER_DEFAULT_FILE_NAME "esp-sniffer"
#define SNIFFER_FILE_NAME_MAX_LEN CONFIG_SNIFFER_PCAP_FILE_NAME_MAX_LEN
#define SNIFFER_DEFAULT_CHANNEL (1)
#define SNIFFER_PAYLOAD_FCS_LEN (4)
#define SNIFFER_PROCESS_PACKET_TIMEOUT_MS (100)
#define SNIFFER_PROCESS_APPTRACE_TIMEOUT_US (100)
#define SNIFFER_APPTRACE_RETRY (10)
static const char *SNIFFER_TAG = "cmd_sniffer";
#define SNIFFER_CHECK(a, str, goto_tag, ...) \
do \
{ \
if (!(a)) \
{ \
ESP_LOGE(SNIFFER_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
goto goto_tag; \
} \
} while (0)
typedef struct {
char *filter_name;
uint32_t filter_val;
} wlan_filter_table_t;
typedef struct {
bool is_running;
sniffer_intf_t interf;
uint32_t channel;
uint32_t filter;
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
char filename[SNIFFER_FILE_NAME_MAX_LEN];
#endif
pcap_handle_t pcap;
TaskHandle_t task;
QueueHandle_t work_queue;
SemaphoreHandle_t sem_task_over;
} 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 wlan_filter_table_t wifi_filter_hash_table[SNIFFER_WLAN_FILTER_MAX] = {0};
static uint32_t hash_func(const char *str, uint32_t max_num)
{
uint32_t ret = 0;
char *p = (char *)str;
while (*p) {
ret += *p;
p++;
}
return ret % max_num;
}
static void create_wifi_filter_hashtable(void)
{
char *wifi_filter_keys[SNIFFER_WLAN_FILTER_MAX] = {"mgmt", "data", "ctrl", "misc", "mpdu", "ampdu"};
uint32_t wifi_filter_values[SNIFFER_WLAN_FILTER_MAX] = {WIFI_PROMIS_FILTER_MASK_MGMT, WIFI_PROMIS_FILTER_MASK_DATA,
WIFI_PROMIS_FILTER_MASK_CTRL, WIFI_PROMIS_FILTER_MASK_MISC,
WIFI_PROMIS_FILTER_MASK_DATA_MPDU, WIFI_PROMIS_FILTER_MASK_DATA_AMPDU
};
for (int i = 0; i < SNIFFER_WLAN_FILTER_MAX; i++) {
uint32_t idx = hash_func(wifi_filter_keys[i], SNIFFER_WLAN_FILTER_MAX);
while (wifi_filter_hash_table[idx].filter_name) {
idx++;
if (idx >= SNIFFER_WLAN_FILTER_MAX) {
idx = 0;
}
}
wifi_filter_hash_table[idx].filter_name = wifi_filter_keys[i];
wifi_filter_hash_table[idx].filter_val = wifi_filter_values[i];
}
}
static uint32_t search_wifi_filter_hashtable(const char *key)
{
uint32_t len = strlen(key);
uint32_t start_idx = hash_func(key, SNIFFER_WLAN_FILTER_MAX);
uint32_t idx = start_idx;
while (strncmp(wifi_filter_hash_table[idx].filter_name, key, len)) {
idx++;
if (idx >= SNIFFER_WLAN_FILTER_MAX) {
idx = 0;
}
/* wrong key */
if (idx == start_idx) {
return 0;
}
}
return wifi_filter_hash_table[idx].filter_val;
}
static void wifi_sniffer_cb(void *recv_buf, wifi_promiscuous_pkt_type_t type)
{
sniffer_packet_info_t packet_info;
wifi_promiscuous_pkt_t *sniffer = (wifi_promiscuous_pkt_t *)recv_buf;
/* prepare packet_info */
packet_info.seconds = sniffer->rx_ctrl.timestamp / 1000000U;
packet_info.microseconds = sniffer->rx_ctrl.timestamp % 1000000U;
packet_info.length = sniffer->rx_ctrl.sig_len;
/* For now, the sniffer only dumps the length of the MISC type frame */
if (type != WIFI_PKT_MISC && !sniffer->rx_ctrl.rx_state) {
packet_info.length -= SNIFFER_PAYLOAD_FCS_LEN;
void *backup = malloc(packet_info.length);
if (backup) {
memcpy(backup, sniffer->payload, packet_info.length);
packet_info.payload = backup;
if (snf_rt.work_queue) {
/* send packet_info */
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");
}
}
} else {
ESP_LOGE(SNIFFER_TAG, "No enough memory for promiscuous packet");
}
}
}
static void sniffer_task(void *parameters)
{
sniffer_packet_info_t packet_info;
sniffer_runtime_t *sniffer = (sniffer_runtime_t *)parameters;
while (sniffer->is_running) {
/* receive paclet info from queue */
if (xQueueReceive(sniffer->work_queue, &packet_info, pdMS_TO_TICKS(SNIFFER_PROCESS_PACKET_TIMEOUT_MS)) != pdTRUE) {
continue;
}
if (pcap_capture_packet(sniffer->pcap, packet_info.payload, packet_info.length,
packet_info.seconds, packet_info.microseconds) != ESP_OK) {
ESP_LOGW(SNIFFER_TAG, "save captured packet failed");
}
free(packet_info.payload);
}
/* notify that sniffer task is over */
xSemaphoreGive(sniffer->sem_task_over);
vTaskDelete(NULL);
}
static esp_err_t sniffer_stop(sniffer_runtime_t *sniffer)
{
SNIFFER_CHECK(sniffer->is_running, "sniffer is already stopped", err);
switch (sniffer->interf) {
case SNIFFER_INTF_WLAN:
/* Disable wifi promiscuous mode */
SNIFFER_CHECK(esp_wifi_set_promiscuous(false) == ESP_OK, "stop wifi promiscuous failed", err);
break;
default:
SNIFFER_CHECK(false, "unsupported interface", err);
break;
}
ESP_LOGI(SNIFFER_TAG, "stop WiFi promiscuous ok");
/* stop sniffer local task */
sniffer->is_running = false;
/* wait for task over */
xSemaphoreTake(sniffer->sem_task_over, portMAX_DELAY);
vSemaphoreDelete(sniffer->sem_task_over);
sniffer->sem_task_over = NULL;
/* make sure to free all resources in the left items */
UBaseType_t left_items = uxQueueMessagesWaiting(sniffer->work_queue);
sniffer_packet_info_t packet_info;
while (left_items--) {
xQueueReceive(sniffer->work_queue, &packet_info, pdMS_TO_TICKS(SNIFFER_PROCESS_PACKET_TIMEOUT_MS));
free(packet_info.payload);
}
vQueueDelete(sniffer->work_queue);
sniffer->work_queue = NULL;
/* stop pcap session */
SNIFFER_CHECK(pcap_deinit(sniffer->pcap) == ESP_OK, "stop pcap session failed", err);
return ESP_OK;
err:
return ESP_FAIL;
}
#if CONFIG_SNIFFER_PCAP_DESTINATION_JTAG
static int trace_writefun(void *cookie, const char *buf, int len)
{
return esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, buf, len, SNIFFER_PROCESS_APPTRACE_TIMEOUT_US) == ESP_OK ? len : -1;
}
static int trace_closefun(void *cookie)
{
return esp_apptrace_flush(ESP_APPTRACE_DEST_TRAX, ESP_APPTRACE_TMO_INFINITE) == ESP_OK ? 0 : -1;
}
#endif
static esp_err_t sniffer_start(sniffer_runtime_t *sniffer)
{
pcap_config_t pcap_config;
wifi_promiscuous_filter_t wifi_filter;
switch (sniffer->interf) {
case SNIFFER_INTF_WLAN:
pcap_config.link_type = PCAP_LINK_TYPE_802_11;
break;
default:
SNIFFER_CHECK(false, "unsupported interface", err);
break;
}
/* Create file to write, binary format */
#if CONFIG_SNIFFER_PCAP_DESTINATION_JTAG
pcap_config.fp = funopen("trace", NULL, trace_writefun, NULL, trace_closefun);
#elif CONFIG_SNIFFER_PCAP_DESTINATION_SD
pcap_config.fp = fopen(sniffer->filename, "wb");
#else
#error "pcap file destination hasn't specified"
#endif
SNIFFER_CHECK(pcap_config.fp, "open file failed", err);
ESP_LOGI(SNIFFER_TAG, "open file successfully");
/* init a pcap session */
SNIFFER_CHECK(pcap_init(&pcap_config, &sniffer->pcap) == ESP_OK, "init pcap session failed", err);
sniffer->is_running = true;
sniffer->work_queue = xQueueCreate(CONFIG_SNIFFER_WORK_QUEUE_LEN, sizeof(sniffer_packet_info_t));
SNIFFER_CHECK(sniffer->work_queue, "create work queue failed", err_queue);
sniffer->sem_task_over = xSemaphoreCreateBinary();
SNIFFER_CHECK(sniffer->sem_task_over, "create sem failed", err_sem);
SNIFFER_CHECK(xTaskCreate(sniffer_task, "snifferT", CONFIG_SNIFFER_TASK_STACK_SIZE,
sniffer, CONFIG_SNIFFER_TASK_PRIORITY, &sniffer->task) == pdTRUE,
"create task failed", err_task);
switch (sniffer->interf) {
case SNIFFER_INTF_WLAN:
/* Start WiFi Promicuous Mode */
wifi_filter.filter_mask = sniffer->filter;
esp_wifi_set_promiscuous_filter(&wifi_filter);
esp_wifi_set_promiscuous_rx_cb(wifi_sniffer_cb);
SNIFFER_CHECK(esp_wifi_set_promiscuous(true) == ESP_OK, "start wifi promiscuous failed", err_start);
esp_wifi_set_channel(sniffer->channel, WIFI_SECOND_CHAN_NONE);
ESP_LOGI(SNIFFER_TAG, "start WiFi promiscuous ok");
break;
default:
break;
}
return ESP_OK;
err_start:
vTaskDelete(sniffer->task);
sniffer->task = NULL;
err_task:
vSemaphoreDelete(sniffer->sem_task_over);
sniffer->sem_task_over = NULL;
err_sem:
vQueueDelete(sniffer->work_queue);
sniffer->work_queue = NULL;
err_queue:
sniffer->is_running = false;
pcap_deinit(sniffer->pcap);
err:
return ESP_FAIL;
}
static struct {
struct arg_str *file;
struct arg_str *interface;
struct arg_str *filter;
struct arg_int *channel;
struct arg_lit *stop;
struct arg_end *end;
} sniffer_args;
static int do_sniffer_cmd(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **)&sniffer_args);
if (nerrors != 0) {
arg_print_errors(stderr, sniffer_args.end, argv[0]);
return 0;
}
/* Check whether or not to stop sniffer: "--stop" option */
if (sniffer_args.stop->count) {
/* stop sniffer */
sniffer_stop(&snf_rt);
return 0;
}
/* Check interface: "-i" option */
snf_rt.interf = SNIFFER_INTF_WLAN;
if (sniffer_args.interface->count) {
if (!strncmp(sniffer_args.interface->sval[0], "wlan", 4)) {
snf_rt.interf = SNIFFER_INTF_WLAN;
} else {
ESP_LOGE(SNIFFER_TAG, "unsupported interface %s", sniffer_args.interface->sval[0]);
return 1;
}
}
/* Check channel: "-c" option */
snf_rt.channel = SNIFFER_DEFAULT_CHANNEL;
if (sniffer_args.channel->count) {
snf_rt.channel = sniffer_args.channel->ival[0];
}
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
/* set pcap file name: "-f" option */
int len = snprintf(snf_rt.filename, sizeof(snf_rt.filename), "%s/%s.pcap", CONFIG_SNIFFER_MOUNT_POINT, SNIFFER_DEFAULT_FILE_NAME);
if (sniffer_args.file->count) {
len = snprintf(snf_rt.filename, sizeof(snf_rt.filename), "%s/%s.pcap", CONFIG_SNIFFER_MOUNT_POINT, sniffer_args.file->sval[0]);
}
if (len >= sizeof(snf_rt.filename)) {
ESP_LOGW(SNIFFER_TAG, "pcap file name too long, try to enlarge memory in menuconfig");
}
#endif
#if CONFIG_SNIFFER_PCAP_DESTINATION_JTAG
uint32_t retry = 0;
/* wait until apptrace communication established or timeout */
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX) && (retry < SNIFFER_APPTRACE_RETRY)) {
retry++;
ESP_LOGW(SNIFFER_TAG, "waiting for apptrace established");
vTaskDelay(pdMS_TO_TICKS(1000));
}
if (retry >= SNIFFER_APPTRACE_RETRY) {
ESP_LOGE(SNIFFER_TAG, "waiting for apptrace established timeout");
return 1;
}
#endif
/* Check filter setting: "-F" option */
switch (snf_rt.interf) {
case SNIFFER_INTF_WLAN:
if (sniffer_args.filter->count) {
for (int i = 0; i < sniffer_args.filter->count; i++) {
snf_rt.filter += search_wifi_filter_hashtable(sniffer_args.filter->sval[i]);
}
/* When filter conditions are all wrong */
if (snf_rt.filter == 0) {
snf_rt.filter = WIFI_PROMIS_FILTER_MASK_ALL;
}
} else {
snf_rt.filter = WIFI_PROMIS_FILTER_MASK_ALL;
}
break;
default:
break;
}
/* start sniffer */
sniffer_start(&snf_rt);
return 0;
}
void register_sniffer(void)
{
sniffer_args.file = arg_str0("f", "file", "<file>",
"name of the file storing the packets in pcap format");
sniffer_args.interface = arg_str0("i", "interface", "<wlan>",
"which interface to capture packet");
sniffer_args.filter = arg_strn("F", "filter", "<mgmt|data|ctrl|misc|mpdu|ampdu>", 0, 6, "filter parameters");
sniffer_args.channel = arg_int0("c", "channel", "<channel>", "communication channel to use");
sniffer_args.stop = arg_lit0(NULL, "stop", "stop running sniffer");
sniffer_args.end = arg_end(1);
const esp_console_cmd_t sniffer_cmd = {
.command = "sniffer",
.help = "Capture specific packet and store in pcap format",
.hint = NULL,
.func = &do_sniffer_cmd,
.argtable = &sniffer_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&sniffer_cmd));
create_wifi_filter_hashtable();
}

View File

@@ -0,0 +1,41 @@
/* cmd_sniffer example — declarations of command registration functions.
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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Supported Sniffer Interface
*
*/
typedef enum {
SNIFFER_INTF_WLAN = 0, /*!< WLAN interface */
} sniffer_intf_t;
/**
* @brief WLAN Sniffer Filter
*
*/
typedef enum {
SNIFFER_WLAN_FILTER_MGMT = 0, /*!< MGMT */
SNIFFER_WLAN_FILTER_CTRL, /*!< CTRL */
SNIFFER_WLAN_FILTER_DATA, /*!< DATA */
SNIFFER_WLAN_FILTER_MISC, /*!< MISC */
SNIFFER_WLAN_FILTER_MPDU, /*!< MPDU */
SNIFFER_WLAN_FILTER_AMPDU, /*!< AMPDU */
SNIFFER_WLAN_FILTER_MAX
} sniffer_wlan_filter_t;
void register_sniffer(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@@ -0,0 +1,213 @@
/* Sniffer example.
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#include "esp_netif.h"
#include "esp_console.h"
#include "esp_event.h"
#include "esp_vfs_fat.h"
#include "esp_wifi.h"
#include "esp_err.h"
#include "esp_log.h"
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#endif
#include "nvs_flash.h"
#include "sdmmc_cmd.h"
#include "cmd_system.h"
#include "cmd_sniffer.h"
#if CONFIG_SNIFFER_STORE_HISTORY
#define HISTORY_MOUNT_POINT "/data"
#define HISTORY_FILE_PATH HISTORY_MOUNT_POINT "/history.txt"
#endif
static const char *TAG = "example";
#if CONFIG_SNIFFER_STORE_HISTORY
/* Initialize filesystem for command history store */
static void initialize_filesystem(void)
{
static wl_handle_t wl_handle;
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true
};
esp_err_t err = esp_vfs_fat_spiflash_mount(HISTORY_MOUNT_POINT, "storage", &mount_config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return;
}
}
#endif
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 */
static void initialize_wifi(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
}
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
static struct {
struct arg_str *device;
struct arg_end *end;
} mount_args;
/** 'mount' command */
static int mount(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **)&mount_args);
if (nerrors != 0) {
arg_print_errors(stderr, mount_args.end, argv[0]);
return 1;
}
/* mount sd card */
if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
ESP_LOGI(TAG, "Initializing SD card");
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1-line modes
gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 4,
.allocation_unit_size = 16 * 1024
};
// initialize SD card and mount FAT filesystem.
sdmmc_card_t *card;
esp_err_t ret = esp_vfs_fat_sdmmc_mount(CONFIG_SNIFFER_MOUNT_POINT, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.",
esp_err_to_name(ret));
}
return 1;
}
/* print card info if mount successfully */
sdmmc_card_print_info(stdout, card);
}
return 0;
}
static void register_mount(void)
{
mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
mount_args.end = arg_end(1);
const esp_console_cmd_t cmd = {
.command = "mount",
.help = "mount the filesystem",
.hint = NULL,
.func = &mount,
.argtable = &mount_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
static int unmount(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **)&mount_args);
if (nerrors != 0) {
arg_print_errors(stderr, mount_args.end, argv[0]);
return 1;
}
/* unmount sd card */
if (!strncmp(mount_args.device->sval[0], "sd", 2)) {
if (esp_vfs_fat_sdmmc_unmount() != ESP_OK) {
ESP_LOGE(TAG, "Card unmount failed");
return -1;
}
ESP_LOGI(TAG, "Card unmounted");
}
return 0;
}
static void register_unmount(void)
{
mount_args.device = arg_str1(NULL, NULL, "<sd>", "choose a proper device to mount/unmount");
mount_args.end = arg_end(1);
const esp_console_cmd_t cmd = {
.command = "unmount",
.help = "unmount the filesystem",
.hint = NULL,
.func = &unmount,
.argtable = &mount_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}
#endif // CONFIG_SNIFFER_PCAP_DESTINATION_SD
void app_main(void)
{
initialize_nvs();
/* Initialize WiFi */
initialize_wifi();
esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
#if CONFIG_SNIFFER_STORE_HISTORY
initialize_filesystem();
repl_config.history_save_path = HISTORY_FILE_PATH;
#endif
repl_config.prompt = "sniffer>";
// init console REPL environment
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
/* Register commands */
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
register_mount();
register_unmount();
#endif
register_sniffer();
register_system();
printf("\n =======================================================\n");
printf(" | Steps to sniffer WiFi packets |\n");
printf(" | |\n");
printf(" | 1. Enter 'help' to check all commands' usage |\n");
printf(" | 2. Enter 'mount <device>' to mount filesystem |\n");
printf(" | 3. Enter 'sniffer' to start capture packets |\n");
printf(" | 4. Enter 'unmount <device>' to unmount filesystem |\n");
printf(" | |\n");
printf(" =======================================================\n\n");
// start console REPL
ESP_ERROR_CHECK(esp_console_start_repl(repl));
}