mirror of
https://git.beihong.wang/wangbeihong/iot-bedroom-environment-controller.git
synced 2026-04-23 14:13:05 +08:00
feat: 智能家居控制系统 v1.0 初始版本
- 环境监测:温湿度/光照/空气质量传感器采集 - 智能控制:时间段/降温/通风三种自动模式 - 闹钟系统:3个闹钟+温和唤醒功能 - 远程控制:MQTT双向通信 - 本地显示:LVGL图形界面 - 双MCU架构,FreeRTOS 10任务并行 - 完整的1250行README文档
This commit is contained in:
78
.gitignore
vendored
Normal file
78
.gitignore
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Directory metadata
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Build artifacts and directories
|
||||||
|
**/build/
|
||||||
|
build/
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.out
|
||||||
|
*.exe # For any host-side utilities compiled on Windows
|
||||||
|
|
||||||
|
# ESP-IDF specific build outputs
|
||||||
|
*.bin
|
||||||
|
*.elf
|
||||||
|
*.map
|
||||||
|
flasher_args.json # Generated in build directory
|
||||||
|
sdkconfig.old
|
||||||
|
sdkconfig
|
||||||
|
|
||||||
|
# ESP-IDF dependencies
|
||||||
|
# For older versions or manual component management
|
||||||
|
/components/.idf/
|
||||||
|
**/components/.idf/
|
||||||
|
# For modern ESP-IDF component manager
|
||||||
|
managed_components/
|
||||||
|
# If ESP-IDF tools are installed/referenced locally to the project
|
||||||
|
.espressif/
|
||||||
|
|
||||||
|
# CMake generated files
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles/
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
CTestTestfile.cmake
|
||||||
|
|
||||||
|
# Python environment files
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
__pycache__/
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Virtual environment folders
|
||||||
|
venv/
|
||||||
|
.venv/
|
||||||
|
env/
|
||||||
|
|
||||||
|
# Language Servers
|
||||||
|
.clangd/
|
||||||
|
.ccls-cache/
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
|
# Windows specific
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# User-specific configuration files
|
||||||
|
*.user
|
||||||
|
*.workspace # General workspace files, can be from various tools
|
||||||
|
*.suo # Visual Studio Solution User Options
|
||||||
|
*.sln.docstates # Visual Studio
|
||||||
19
.vscode/c_cpp_properties.json
vendored
Normal file
19
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "ESP-IDF",
|
||||||
|
"compilerPath": "/home/beihong/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
|
||||||
|
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"browse": {
|
||||||
|
"path": [
|
||||||
|
"${workspaceFolder}"
|
||||||
|
],
|
||||||
|
"limitSymbolsToIncludedHeaders": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
10
.vscode/launch.json
vendored
Normal file
10
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT GDB Adapter"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"idf.currentSetup": "/home/beihong/esp/v5.5.2/esp-idf",
|
||||||
|
"idf.port": "/dev/ttyACM0",
|
||||||
|
"idf.flashType": "UART"
|
||||||
|
}
|
||||||
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(iot-home)
|
||||||
4
components/lvgl_st7735s_use/CMakeLists.txt
Normal file
4
components/lvgl_st7735s_use/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "ui_display.c" "lvgl_st7735s_use.c"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES driver esp_lcd esp_lvgl_port
|
||||||
|
)
|
||||||
33
components/lvgl_st7735s_use/include/lvgl_st7735s_use.h
Normal file
33
components/lvgl_st7735s_use/include/lvgl_st7735s_use.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
/* LCD size */
|
||||||
|
#define EXAMPLE_LCD_H_RES (160)
|
||||||
|
#define EXAMPLE_LCD_V_RES (80)
|
||||||
|
|
||||||
|
/* LCD SPI总线配置 */
|
||||||
|
#define EXAMPLE_LCD_SPI_NUM (SPI2_HOST) // 使用SPI2主机接口进行通信
|
||||||
|
|
||||||
|
/* LCD显示参数配置 */
|
||||||
|
#define EXAMPLE_LCD_PIXEL_CLK_HZ (40 * 1000 * 1000) // 像素时钟频率设置为40MHz,控制数据传输速度
|
||||||
|
|
||||||
|
/* LCD命令和参数配置 */
|
||||||
|
#define EXAMPLE_LCD_CMD_BITS (8) // 命令位数为8位,用于发送LCD控制命令
|
||||||
|
#define EXAMPLE_LCD_PARAM_BITS (8) // 参数位数为8位,用于发送命令参数
|
||||||
|
|
||||||
|
/* LCD颜色和缓冲区配置 */
|
||||||
|
#define EXAMPLE_LCD_BITS_PER_PIXEL (16) // 每个像素使用16位颜色(RGB565格式)
|
||||||
|
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1) // 启用双缓冲模式,提高显示流畅度
|
||||||
|
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50) // 绘图缓冲区高度为50行,影响刷新性能
|
||||||
|
|
||||||
|
/* LCD背光配置 */
|
||||||
|
#define EXAMPLE_LCD_BL_ON_LEVEL (1) // 背光开启电平为高电平(1)
|
||||||
|
|
||||||
|
/* LCD pins */
|
||||||
|
#define EXAMPLE_LCD_GPIO_SCLK (GPIO_NUM_2)
|
||||||
|
#define EXAMPLE_LCD_GPIO_MOSI (GPIO_NUM_3)
|
||||||
|
#define EXAMPLE_LCD_GPIO_RST (GPIO_NUM_9)
|
||||||
|
#define EXAMPLE_LCD_GPIO_DC (GPIO_NUM_8)
|
||||||
|
#define EXAMPLE_LCD_GPIO_CS (GPIO_NUM_7)
|
||||||
|
#define EXAMPLE_LCD_GPIO_BL (GPIO_NUM_6)
|
||||||
|
|
||||||
|
|
||||||
|
void start_lvgl_demo(void);
|
||||||
38
components/lvgl_st7735s_use/include/ui_display.h
Normal file
38
components/lvgl_st7735s_use/include/ui_display.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef UI_DISPLAY_H
|
||||||
|
#define UI_DISPLAY_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化UI界面
|
||||||
|
*
|
||||||
|
* 该函数负责创建LVGL的用户界面元素,用于显示传感器数据
|
||||||
|
*/
|
||||||
|
void ui_display_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新传感器数据显示
|
||||||
|
*
|
||||||
|
* 该函数用于更新LVGL界面上的传感器数据
|
||||||
|
*
|
||||||
|
* @param temperature 温度值(°C),-1.0表示无效
|
||||||
|
* @param humidity 湿度值(%),-1.0表示无效
|
||||||
|
* @param lux 光照强度(lx),-1.0表示无效
|
||||||
|
* @param ppm 空气中有害气体浓度(ppm)
|
||||||
|
* @param quality_level 空气质量等级描述
|
||||||
|
*/
|
||||||
|
void ui_update_sensor_data(float temperature, float humidity, float lux, float ppm, const char* quality_level);
|
||||||
|
|
||||||
|
/* Time page APIs */
|
||||||
|
void ui_show_time_page(void);
|
||||||
|
void ui_show_sensor_page(void);
|
||||||
|
void ui_time_update(void);
|
||||||
|
void ui_toggle_page(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* UI_DISPLAY_H */
|
||||||
236
components/lvgl_st7735s_use/lvgl_st7735s_use.c
Normal file
236
components/lvgl_st7735s_use/lvgl_st7735s_use.c
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "lvgl_st7735s_use.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/spi_master.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_lcd_panel_io.h"
|
||||||
|
#include "esp_lcd_panel_vendor.h"
|
||||||
|
#include "esp_lcd_panel_ops.h"
|
||||||
|
#include "esp_lvgl_port.h" // 包含LVGL端口头文件,用于LVGL与ESP硬件的接口
|
||||||
|
|
||||||
|
#include "ui_display.h" // 添加新UI界面的头文件
|
||||||
|
static const char *TAG = "lvgl_st7735s_use"; // 用于日志输出的标签,便于调试时识别日志来源
|
||||||
|
|
||||||
|
|
||||||
|
/* LCD IO和面板句柄 */
|
||||||
|
// lcd_io: LCD面板IO句柄,用于与LCD进行通信
|
||||||
|
// lcd_panel: LCD面板句柄,用于控制LCD的各种操作
|
||||||
|
static esp_lcd_panel_io_handle_t lcd_io = NULL;
|
||||||
|
static esp_lcd_panel_handle_t lcd_panel = NULL;
|
||||||
|
|
||||||
|
/* LVGL显示和触摸 */
|
||||||
|
// lvgl_disp: LVGL显示设备句柄,用于LVGL库与显示设备的交互
|
||||||
|
static lv_display_t *lvgl_disp = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化LCD硬件和SPI接口
|
||||||
|
*
|
||||||
|
* 该函数负责初始化LCD所需的GPIO、SPI总线,并配置LCD面板
|
||||||
|
* 包括背光控制、SPI总线配置、面板IO配置和面板驱动安装
|
||||||
|
*
|
||||||
|
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||||
|
*/
|
||||||
|
static esp_err_t app_lcd_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
|
/* LCD背光配置 */
|
||||||
|
// 配置背光GPIO为输出模式,用于控制LCD的背光开关
|
||||||
|
gpio_config_t bk_gpio_config = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT, // 设置GPIO为输出模式
|
||||||
|
.pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL // 设置背光GPIO引脚
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); // 应用GPIO配置并检查错误
|
||||||
|
|
||||||
|
/* LCD初始化 */
|
||||||
|
ESP_LOGD(TAG, "初始化SPI总线"); // 输出调试日志
|
||||||
|
// 配置SPI总线参数,包括时钟、数据线和最大传输大小
|
||||||
|
const spi_bus_config_t buscfg = {
|
||||||
|
.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK, // SPI时钟引脚
|
||||||
|
.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI, // SPI主输出从输入引脚
|
||||||
|
.miso_io_num = GPIO_NUM_NC, // 未使用MISO引脚
|
||||||
|
.quadwp_io_num = GPIO_NUM_NC, // 未使用WP引脚
|
||||||
|
.quadhd_io_num = GPIO_NUM_NC, // 未使用HD引脚
|
||||||
|
.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t), // 最大传输大小
|
||||||
|
};
|
||||||
|
// 初始化SPI总线,使用DMA自动分配通道
|
||||||
|
ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI初始化失败");
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "安装面板IO");
|
||||||
|
// 配置LCD面板IO的SPI参数
|
||||||
|
const esp_lcd_panel_io_spi_config_t io_config = {
|
||||||
|
.dc_gpio_num = EXAMPLE_LCD_GPIO_DC, // 数据/命令选择引脚
|
||||||
|
.cs_gpio_num = EXAMPLE_LCD_GPIO_CS, // 片选引脚
|
||||||
|
.pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ, // 像素时钟频率
|
||||||
|
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // 命令位数
|
||||||
|
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, // 参数位数
|
||||||
|
.spi_mode = 3, // SPI模式
|
||||||
|
.trans_queue_depth = 10, // 传输队列深度
|
||||||
|
};
|
||||||
|
// 创建LCD面板IO,用于SPI通信
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "创建面板IO失败");
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "安装LCD驱动");
|
||||||
|
// 配置LCD面板设备参数
|
||||||
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
|
.reset_gpio_num = EXAMPLE_LCD_GPIO_RST, // 复位引脚
|
||||||
|
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||||
|
.rgb_endian = LCD_RGB_ENDIAN_RGB, // RGB字节序(旧版本)
|
||||||
|
#else
|
||||||
|
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, // RGB元素顺序(新版本)
|
||||||
|
#endif
|
||||||
|
.bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL, // 每像素位数
|
||||||
|
};
|
||||||
|
// 创建ST7789 LCD面板驱动
|
||||||
|
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "创建面板失败");
|
||||||
|
|
||||||
|
// 复位LCD面板
|
||||||
|
esp_lcd_panel_reset(lcd_panel);
|
||||||
|
// 初始化LCD面板
|
||||||
|
esp_lcd_panel_init(lcd_panel);
|
||||||
|
// 设置显示窗口,确保使用正确的分辨率(偏移)
|
||||||
|
esp_lcd_panel_set_gap(lcd_panel, 1, 26);
|
||||||
|
|
||||||
|
// 反转颜色
|
||||||
|
esp_lcd_panel_invert_color(lcd_panel, true);
|
||||||
|
// 打开LCD显示
|
||||||
|
esp_lcd_panel_disp_on_off(lcd_panel, true);
|
||||||
|
|
||||||
|
/* 打开LCD背光 */
|
||||||
|
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// 错误处理标签,用于清理资源
|
||||||
|
err:
|
||||||
|
if (lcd_panel) {
|
||||||
|
esp_lcd_panel_del(lcd_panel); // 删除面板
|
||||||
|
}
|
||||||
|
if (lcd_io) {
|
||||||
|
esp_lcd_panel_io_del(lcd_io); // 删除面板IO
|
||||||
|
}
|
||||||
|
spi_bus_free(EXAMPLE_LCD_SPI_NUM); // 释放SPI总线资源
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化LVGL图形库
|
||||||
|
*
|
||||||
|
* 该函数负责初始化LVGL库,并配置显示设备
|
||||||
|
* 包括LVGL任务配置、显示缓冲区配置和旋转设置
|
||||||
|
*
|
||||||
|
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||||
|
*/
|
||||||
|
static esp_err_t app_lvgl_init(void)
|
||||||
|
{
|
||||||
|
/* 初始化LVGL */
|
||||||
|
// 配置LVGL任务参数
|
||||||
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
|
.task_priority = 4, /* LVGL任务优先级,数值越高优先级越高 */
|
||||||
|
.task_stack = 4096, /* LVGL任务堆栈大小,单位为字节 */
|
||||||
|
.task_affinity = -1, /* LVGL任务绑定核心,-1表示不绑定特定核心 */
|
||||||
|
.task_max_sleep_ms = 500, /* LVGL任务最大睡眠时间,单位为毫秒 */
|
||||||
|
.timer_period_ms = 5 /* LVGL定时器周期,单位为毫秒,用于处理动画和输入 */
|
||||||
|
};
|
||||||
|
// 初始化LVGL端口
|
||||||
|
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL端口初始化失败");
|
||||||
|
|
||||||
|
/* 添加LCD屏幕 */
|
||||||
|
ESP_LOGD(TAG, "添加LCD屏幕");
|
||||||
|
// 配置LVGL显示设备参数
|
||||||
|
const lvgl_port_display_cfg_t disp_cfg = {
|
||||||
|
.io_handle = lcd_io, // LCD面板IO句柄
|
||||||
|
.panel_handle = lcd_panel, // LCD面板句柄
|
||||||
|
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT, // 缓冲区大小
|
||||||
|
.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE, // 是否使用双缓冲
|
||||||
|
.hres = EXAMPLE_LCD_H_RES, // 水平分辨率
|
||||||
|
.vres = EXAMPLE_LCD_V_RES, // 垂直分辨率
|
||||||
|
.monochrome = false, // 是否为单色显示
|
||||||
|
#if LVGL_VERSION_MAJOR >= 9
|
||||||
|
.color_format = LV_COLOR_FORMAT_RGB565, // 颜色格式(LVGL v9及以上)
|
||||||
|
#endif
|
||||||
|
.rotation = { // 旋转设置
|
||||||
|
.swap_xy = 1, // 交换X和Y轴以实现横向显示
|
||||||
|
.mirror_x = 1, // 是否水平镜像
|
||||||
|
.mirror_y = 0, // 是否垂直镜像
|
||||||
|
},
|
||||||
|
.flags = { // 标志位
|
||||||
|
.buff_dma = true, // 是否使用DMA缓冲区
|
||||||
|
#if LVGL_VERSION_MAJOR >= 9
|
||||||
|
.swap_bytes = false, // 是否交换字节序(LVGL v9及以上)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 添加LVGL显示设备
|
||||||
|
lvgl_disp = lvgl_port_add_disp(&disp_cfg);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建并显示LVGL主界面
|
||||||
|
*
|
||||||
|
* 该函数负责创建LVGL的用户界面元素,包括图像、标签和按钮
|
||||||
|
* 并设置它们的位置和属性
|
||||||
|
*/
|
||||||
|
static void app_main_display(void)
|
||||||
|
{
|
||||||
|
// 获取当前活动屏幕对象
|
||||||
|
lv_obj_t *scr = lv_scr_act();
|
||||||
|
|
||||||
|
/* 任务锁定 */
|
||||||
|
// 锁定LVGL任务,防止在创建UI对象时被中断
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
|
||||||
|
/* 设置屏幕背景为黑色 */
|
||||||
|
lv_obj_set_style_bg_color(scr, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
|
|
||||||
|
/* 创建标签 */
|
||||||
|
// 创建标签对象
|
||||||
|
lv_obj_t *label = lv_label_create(scr);
|
||||||
|
// 设置标签文本为"ESP32C3-LVGL"
|
||||||
|
lv_label_set_text(label, "ESP32C3-LVGL1");
|
||||||
|
// 设置标签文本颜色为白色
|
||||||
|
lv_obj_set_style_text_color(label, lv_color_black(), 0);
|
||||||
|
// 设置标签文本字体大小为更小的字体
|
||||||
|
lv_obj_set_style_text_font(label, &lv_font_unscii_8, 0);
|
||||||
|
|
||||||
|
// 设置标签位置在屏幕中心
|
||||||
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
|
/* 任务解锁 */
|
||||||
|
// 解锁LVGL任务
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动LVGL演示程序
|
||||||
|
*
|
||||||
|
* 该函数是程序的入口点,负责初始化LCD硬件、LVGL库,并显示主界面
|
||||||
|
*/
|
||||||
|
void start_lvgl_demo(void)
|
||||||
|
{
|
||||||
|
/* LCD硬件初始化 */
|
||||||
|
// 初始化LCD硬件和SPI接口
|
||||||
|
ESP_ERROR_CHECK(app_lcd_init());
|
||||||
|
|
||||||
|
/* LVGL初始化 */
|
||||||
|
// 初始化LVGL图形库
|
||||||
|
ESP_ERROR_CHECK(app_lvgl_init());
|
||||||
|
|
||||||
|
/* 显示LVGL对象 */
|
||||||
|
// 创建并显示LVGL主界面
|
||||||
|
// app_main_display();
|
||||||
|
|
||||||
|
/* 显示LVGL对象 - 使用新的UI界面初始化函数 */
|
||||||
|
ui_display_init();
|
||||||
|
}
|
||||||
258
components/lvgl_st7735s_use/ui_display.c
Normal file
258
components/lvgl_st7735s_use/ui_display.c
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
#include "ui_display.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static const char *TAG = "ui_display";
|
||||||
|
|
||||||
|
// 全局变量用于存储传感器数据标签
|
||||||
|
static lv_obj_t *temp_label = NULL;
|
||||||
|
static lv_obj_t *humid_label = NULL;
|
||||||
|
static lv_obj_t *lux_label = NULL;
|
||||||
|
static lv_obj_t *air_quality_label = NULL; // 新增空气质量标签
|
||||||
|
|
||||||
|
/* Time page objects */
|
||||||
|
static lv_obj_t *time_container = NULL;
|
||||||
|
static lv_obj_t *date_label = NULL;
|
||||||
|
static lv_obj_t *time_label = NULL;
|
||||||
|
static bool time_page_visible = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化UI界面
|
||||||
|
*
|
||||||
|
* 该函数负责创建LVGL的用户界面元素,用于显示传感器数据
|
||||||
|
* 优化布局以适应非触摸屏设备,所有内容在一个屏幕内显示
|
||||||
|
*/
|
||||||
|
void ui_display_init(void)
|
||||||
|
{
|
||||||
|
// 获取当前活动屏幕对象
|
||||||
|
lv_obj_t *scr = lv_scr_act();
|
||||||
|
|
||||||
|
/* 任务锁定 */
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
|
||||||
|
/* 设置屏幕背景为白色 */
|
||||||
|
lv_obj_set_style_bg_color(scr, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
|
/* 创建标题标签 */
|
||||||
|
lv_obj_t *title_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(title_label, "IoT Home Monitor");
|
||||||
|
lv_obj_set_style_text_color(title_label, lv_palette_main(LV_PALETTE_BLUE), 0);
|
||||||
|
lv_obj_set_style_text_font(title_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 2); // 调整标题位置
|
||||||
|
|
||||||
|
/* 创建温度标签 */
|
||||||
|
temp_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(temp_label, "Temp: --.- C");
|
||||||
|
lv_obj_set_style_text_color(temp_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(temp_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(temp_label, LV_ALIGN_TOP_LEFT, 3, 20); // 调整位置
|
||||||
|
|
||||||
|
/* 创建湿度标签 */
|
||||||
|
humid_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(humid_label, "Humidity: --.- %");
|
||||||
|
lv_obj_set_style_text_color(humid_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(humid_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(humid_label, LV_ALIGN_TOP_LEFT, 3, 35); // 调整位置
|
||||||
|
|
||||||
|
/* 创建光照标签 */
|
||||||
|
lux_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(lux_label, "Light: --.- lux");
|
||||||
|
lv_obj_set_style_text_color(lux_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(lux_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(lux_label, LV_ALIGN_TOP_LEFT, 3, 50); // 调整位置
|
||||||
|
|
||||||
|
/* 创建空气质量标签 */
|
||||||
|
air_quality_label = lv_label_create(scr);
|
||||||
|
lv_label_set_text(air_quality_label, "IAQ : --.- Index");
|
||||||
|
lv_obj_set_style_text_color(air_quality_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(air_quality_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(air_quality_label, LV_ALIGN_TOP_LEFT, 3, 65); // 调整位置
|
||||||
|
|
||||||
|
/* 任务解锁 */
|
||||||
|
lvgl_port_unlock();
|
||||||
|
|
||||||
|
// 创建时间页面(初始隐藏)
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
time_container = lv_obj_create(lv_scr_act());
|
||||||
|
lv_obj_set_size(time_container, lv_pct(100), lv_pct(100));
|
||||||
|
lv_obj_set_style_bg_color(time_container, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(time_container, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
|
date_label = lv_label_create(time_container);
|
||||||
|
lv_label_set_text(date_label, "---- ---- -- ---");
|
||||||
|
lv_obj_set_style_text_color(date_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(date_label, &lv_font_unscii_8, 0);
|
||||||
|
lv_obj_align(date_label, LV_ALIGN_TOP_MID, 0, 6);
|
||||||
|
|
||||||
|
time_label = lv_label_create(time_container);
|
||||||
|
lv_label_set_text(time_label, "--:--:--");
|
||||||
|
lv_obj_set_style_text_color(time_label, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_text_font(time_label, &lv_font_unscii_16, 0);
|
||||||
|
lv_obj_align(time_label, LV_ALIGN_CENTER, 0, 12);
|
||||||
|
|
||||||
|
// 默认显示时间页面,隐藏传感器页面
|
||||||
|
lv_obj_clear_flag(time_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (temp_label) lv_obj_add_flag(temp_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (humid_label) lv_obj_add_flag(humid_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (lux_label) lv_obj_add_flag(lux_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (air_quality_label) lv_obj_add_flag(air_quality_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
time_page_visible = true;
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新传感器数据显示
|
||||||
|
*
|
||||||
|
* 该函数用于更新LVGL界面上的传感器数据
|
||||||
|
*
|
||||||
|
* @param temperature 温度值(°C),-1.0表示无效
|
||||||
|
* @param humidity 湿度值(%),-1.0表示无效
|
||||||
|
* @param lux 光照强度(lx),-1.0表示无效
|
||||||
|
* @param ppm 空气中有害气体浓度(ppm)
|
||||||
|
* @param quality_level 空气质量等级描述
|
||||||
|
*/
|
||||||
|
void ui_update_sensor_data(float temperature, float humidity, float lux, float ppm, const char* quality_level)
|
||||||
|
{
|
||||||
|
if (temp_label != NULL && humid_label != NULL && lux_label != NULL && air_quality_label != NULL)
|
||||||
|
{
|
||||||
|
/* 任务锁定 */
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
|
||||||
|
// 更新温度标签 - 缩短文本以节省空间
|
||||||
|
if (temperature >= -0.5) // -1.0表示无效
|
||||||
|
{
|
||||||
|
char temp_str[32];
|
||||||
|
snprintf(temp_str, sizeof(temp_str), "Temp: %.2f C", temperature);
|
||||||
|
lv_label_set_text(temp_label, temp_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lv_label_set_text(temp_label, "Temp: Invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新湿度标签 - 缩短文本以节省空间
|
||||||
|
if (humidity >= -0.5) // -1.0表示无效
|
||||||
|
{
|
||||||
|
char humid_str[32];
|
||||||
|
snprintf(humid_str, sizeof(humid_str), "Humidity: %.2f %%", humidity);
|
||||||
|
lv_label_set_text(humid_label, humid_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lv_label_set_text(humid_label, "Humidity: Invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新光照标签 - 缩短文本以节省空间
|
||||||
|
if (lux >= -0.5) // -1.0表示无效
|
||||||
|
{
|
||||||
|
char lux_str[32];
|
||||||
|
snprintf(lux_str, sizeof(lux_str), "Light: %.2f lx", lux);
|
||||||
|
lv_label_set_text(lux_label, lux_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lv_label_set_text(lux_label, "Light: Invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新空气质量标签 - 缩短文本以节省空间
|
||||||
|
if (ppm >= 0) // 空气质量值有效
|
||||||
|
{
|
||||||
|
char ppm_str[32];
|
||||||
|
snprintf(ppm_str, sizeof(ppm_str), "IAQ : %.2f Index", ppm);
|
||||||
|
|
||||||
|
// 根据空气质量等级更改颜色
|
||||||
|
lv_color_t color = lv_color_black(); // 默认黑色
|
||||||
|
if (ppm <= 20.0f) {
|
||||||
|
color = lv_color_make(0, 128, 0); // 绿色 - 空气质量优秀
|
||||||
|
} else if (ppm <= 100.0f) {
|
||||||
|
color = lv_color_make(0, 0, 0); // 黑色 - 空气质量良好
|
||||||
|
} else if (ppm <= 300.0f) {
|
||||||
|
color = lv_color_make(255, 165, 0); // 橙色 - 轻度污染
|
||||||
|
} else {
|
||||||
|
color = lv_color_make(255, 0, 0); // 红色 - 中重度污染
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_label_set_text(air_quality_label, ppm_str);
|
||||||
|
lv_obj_set_style_text_color(air_quality_label, color, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lv_label_set_text(air_quality_label, "IAQ : Invalid");
|
||||||
|
lv_obj_set_style_text_color(air_quality_label, lv_color_black(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务解锁 */
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show time page */
|
||||||
|
void ui_show_time_page(void)
|
||||||
|
{
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
if (time_container)
|
||||||
|
{
|
||||||
|
lv_obj_clear_flag(time_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
if (temp_label) lv_obj_add_flag(temp_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (humid_label) lv_obj_add_flag(humid_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (lux_label) lv_obj_add_flag(lux_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (air_quality_label) lv_obj_add_flag(air_quality_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
time_page_visible = true;
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show sensor page */
|
||||||
|
void ui_show_sensor_page(void)
|
||||||
|
{
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
if (time_container)
|
||||||
|
{
|
||||||
|
lv_obj_add_flag(time_container, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
if (temp_label) lv_obj_clear_flag(temp_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (humid_label) lv_obj_clear_flag(humid_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (lux_label) lv_obj_clear_flag(lux_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (air_quality_label) lv_obj_clear_flag(air_quality_label, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
time_page_visible = false;
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle between pages */
|
||||||
|
void ui_toggle_page(void)
|
||||||
|
{
|
||||||
|
if (time_page_visible)
|
||||||
|
ui_show_sensor_page();
|
||||||
|
else
|
||||||
|
ui_show_time_page();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update time label (call periodically) */
|
||||||
|
void ui_time_update(void)
|
||||||
|
{
|
||||||
|
if (!time_page_visible || time_label == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm tm_now;
|
||||||
|
localtime_r(&now, &tm_now);
|
||||||
|
|
||||||
|
char date_buf[64];
|
||||||
|
char time_buf[32];
|
||||||
|
char weekday_buf[32];
|
||||||
|
|
||||||
|
// 年月日和星期合并为一行
|
||||||
|
strftime(date_buf, sizeof(date_buf), "%Y-%m-%d", &tm_now);
|
||||||
|
const char *weekdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
snprintf(date_buf + strlen(date_buf), sizeof(date_buf) - strlen(date_buf), " %s", weekdays[tm_now.tm_wday]);
|
||||||
|
// 时分秒
|
||||||
|
strftime(time_buf, sizeof(time_buf), "%H:%M:%S", &tm_now);
|
||||||
|
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
lv_label_set_text(date_label, date_buf);
|
||||||
|
lv_label_set_text(time_label, time_buf);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
52
components/protocol_examples_common/CMakeLists.txt
Normal file
52
components/protocol_examples_common/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
|
||||||
|
if(${target} STREQUAL "linux")
|
||||||
|
# Header only library for linux
|
||||||
|
|
||||||
|
idf_component_register(INCLUDE_DIRS include
|
||||||
|
SRCS protocol_examples_utils.c)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(srcs "stdin_out.c"
|
||||||
|
"addr_from_stdin.c"
|
||||||
|
"connect.c"
|
||||||
|
"wifi_connect.c"
|
||||||
|
"protocol_examples_utils.c")
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD)
|
||||||
|
list(APPEND srcs "console_cmd.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_ETHERNET)
|
||||||
|
list(APPEND srcs "eth_connect.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_THREAD)
|
||||||
|
list(APPEND srcs "thread_connect.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_PPP)
|
||||||
|
list(APPEND srcs "ppp_connect.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
PRIV_REQUIRES esp_netif esp_driver_gpio esp_driver_uart esp_wifi vfs console esp_eth openthread)
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD)
|
||||||
|
idf_component_optional_requires(PRIVATE console)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_ETHERNET)
|
||||||
|
idf_component_optional_requires(PUBLIC esp_eth)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_THREAD)
|
||||||
|
idf_component_optional_requires(PRIVATE openthread)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_EXAMPLE_CONNECT_PPP)
|
||||||
|
idf_component_optional_requires(PRIVATE esp_tinyusb espressif__esp_tinyusb)
|
||||||
|
endif()
|
||||||
Binary file not shown.
504
components/protocol_examples_common/Kconfig.projbuild
Normal file
504
components/protocol_examples_common/Kconfig.projbuild
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
menu "Example Connection Configuration"
|
||||||
|
|
||||||
|
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_WIFI
|
||||||
|
bool "connect using WiFi interface"
|
||||||
|
depends on !IDF_TARGET_LINUX && (SOC_WIFI_SUPPORTED || ESP_WIFI_REMOTE_ENABLED || ESP_HOST_WIFI_ENABLED)
|
||||||
|
default y if SOC_WIFI_SUPPORTED
|
||||||
|
help
|
||||||
|
Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network.
|
||||||
|
Choose this option to connect with WiFi
|
||||||
|
|
||||||
|
if EXAMPLE_CONNECT_WIFI
|
||||||
|
config EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
bool "Get ssid and password from stdin"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Give the WiFi SSID and password from stdin.
|
||||||
|
|
||||||
|
config EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD
|
||||||
|
depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
bool "Provide wifi connect commands"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Provide wifi connect commands for esp_console.
|
||||||
|
Please use `example_register_wifi_connect_commands` to register them.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_SSID
|
||||||
|
depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
string "WiFi SSID"
|
||||||
|
default "myssid"
|
||||||
|
help
|
||||||
|
SSID (network name) for the example to connect to.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_PASSWORD
|
||||||
|
depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
string "WiFi Password"
|
||||||
|
default "mypassword"
|
||||||
|
help
|
||||||
|
WiFi password (WPA or WPA2) for the example to use.
|
||||||
|
Can be left blank if the network has no security set.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_CONN_MAX_RETRY
|
||||||
|
int "Maximum retry"
|
||||||
|
default 6
|
||||||
|
help
|
||||||
|
Set the Maximum retry to avoid station reconnecting to the AP unlimited,
|
||||||
|
in case the AP is really inexistent.
|
||||||
|
|
||||||
|
choice EXAMPLE_WIFI_SCAN_METHOD
|
||||||
|
prompt "WiFi Scan Method"
|
||||||
|
default EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||||
|
help
|
||||||
|
WiFi scan method:
|
||||||
|
|
||||||
|
If "Fast" is selected, scan will end after find SSID match AP.
|
||||||
|
|
||||||
|
If "All Channel" is selected, scan will end after scan all the channel.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_SCAN_METHOD_FAST
|
||||||
|
bool "Fast"
|
||||||
|
config EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||||
|
bool "All Channel"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
menu "WiFi Scan threshold"
|
||||||
|
config EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD
|
||||||
|
int "WiFi minimum rssi"
|
||||||
|
range -127 0
|
||||||
|
|
||||||
|
default -127
|
||||||
|
help
|
||||||
|
The minimum rssi to accept in the scan mode.
|
||||||
|
|
||||||
|
choice EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD
|
||||||
|
prompt "WiFi Scan auth mode threshold"
|
||||||
|
default EXAMPLE_WIFI_AUTH_OPEN
|
||||||
|
help
|
||||||
|
The weakest authmode to accept in the scan mode.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_AUTH_OPEN
|
||||||
|
bool "OPEN"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WEP
|
||||||
|
bool "WEP"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA_PSK
|
||||||
|
bool "WPA PSK"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA2_PSK
|
||||||
|
bool "WPA2 PSK"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
|
||||||
|
bool "WPA WPA2 PSK"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
|
||||||
|
bool "WPA2 ENTERPRISE"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA3_PSK
|
||||||
|
bool "WPA3 PSK"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
|
||||||
|
bool "WPA2 WPA3 PSK"
|
||||||
|
config EXAMPLE_WIFI_AUTH_WAPI_PSK
|
||||||
|
bool "WAPI PSK"
|
||||||
|
endchoice
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
choice EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD
|
||||||
|
prompt "WiFi Connect AP Sort Method"
|
||||||
|
default EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||||
|
help
|
||||||
|
WiFi connect AP sort method:
|
||||||
|
|
||||||
|
If "Signal" is selected, Sort matched APs in scan list by RSSI.
|
||||||
|
|
||||||
|
If "Security" is selected, Sort matched APs in scan list by security mode.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||||
|
bool "Signal"
|
||||||
|
config EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
|
||||||
|
bool "Security"
|
||||||
|
endchoice
|
||||||
|
endif
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_ETHERNET
|
||||||
|
bool "connect using Ethernet interface"
|
||||||
|
depends on !IDF_TARGET_LINUX
|
||||||
|
default y if !EXAMPLE_CONNECT_WIFI && !EXAMPLE_CONNECT_THREAD
|
||||||
|
help
|
||||||
|
Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network.
|
||||||
|
Choose this option to connect with Ethernet
|
||||||
|
|
||||||
|
if EXAMPLE_CONNECT_ETHERNET
|
||||||
|
config EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE
|
||||||
|
int "emac_rx task stack size"
|
||||||
|
default 2048
|
||||||
|
help
|
||||||
|
This set stack size for emac_rx task
|
||||||
|
|
||||||
|
config EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
bool
|
||||||
|
|
||||||
|
choice EXAMPLE_ETHERNET_TYPE
|
||||||
|
prompt "Ethernet Type"
|
||||||
|
default EXAMPLE_USE_INTERNAL_ETHERNET if SOC_EMAC_SUPPORTED
|
||||||
|
default EXAMPLE_USE_W5500
|
||||||
|
help
|
||||||
|
Select which kind of Ethernet will be used in the example.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_INTERNAL_ETHERNET
|
||||||
|
depends on SOC_EMAC_SUPPORTED
|
||||||
|
select ETH_USE_ESP32_EMAC
|
||||||
|
bool "Internal EMAC"
|
||||||
|
help
|
||||||
|
Select internal Ethernet MAC controller.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_DM9051
|
||||||
|
bool "DM9051 Module"
|
||||||
|
select EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
select ETH_USE_SPI_ETHERNET
|
||||||
|
select ETH_SPI_ETHERNET_DM9051
|
||||||
|
help
|
||||||
|
Select external SPI-Ethernet module.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_W5500
|
||||||
|
bool "W5500 Module"
|
||||||
|
select EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
select ETH_USE_SPI_ETHERNET
|
||||||
|
select ETH_SPI_ETHERNET_W5500
|
||||||
|
help
|
||||||
|
Select external SPI-Ethernet module (W5500).
|
||||||
|
|
||||||
|
config EXAMPLE_USE_OPENETH
|
||||||
|
bool "OpenCores Ethernet MAC (EXPERIMENTAL)"
|
||||||
|
select ETH_USE_OPENETH
|
||||||
|
help
|
||||||
|
When this option is enabled, the example is built with support for
|
||||||
|
OpenCores Ethernet MAC, which allows testing the example in QEMU.
|
||||||
|
Note that this option is used for internal testing purposes, and
|
||||||
|
not officially supported. Examples built with this option enabled
|
||||||
|
will not run on a real ESP32 chip.
|
||||||
|
|
||||||
|
endchoice # EXAMPLE_ETHERNET_TYPE
|
||||||
|
|
||||||
|
if EXAMPLE_USE_INTERNAL_ETHERNET
|
||||||
|
choice EXAMPLE_ETH_PHY_MODEL
|
||||||
|
prompt "Ethernet PHY Device"
|
||||||
|
default EXAMPLE_ETH_PHY_IP101
|
||||||
|
help
|
||||||
|
Select the Ethernet PHY device to use in the example.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_GENERIC
|
||||||
|
bool "Generic 802.3 PHY"
|
||||||
|
help
|
||||||
|
Any Ethernet PHY chip compliant with IEEE 802.3 can be used. However, while
|
||||||
|
basic functionality should always work, some specific features might be limited,
|
||||||
|
even if the PHY meets IEEE 802.3 standard. A typical example is loopback
|
||||||
|
functionality, where certain PHYs may require setting a specific speed mode to
|
||||||
|
operate correctly.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_IP101
|
||||||
|
bool "IP101"
|
||||||
|
help
|
||||||
|
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
|
||||||
|
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_RTL8201
|
||||||
|
bool "RTL8201/SR8201"
|
||||||
|
help
|
||||||
|
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
|
||||||
|
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_LAN87XX
|
||||||
|
bool "LAN87xx"
|
||||||
|
help
|
||||||
|
Below chips are supported:
|
||||||
|
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
|
||||||
|
flexPWR® Technology.
|
||||||
|
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
|
||||||
|
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
|
||||||
|
with HP Auto-MDIX and flexPWR® Technology.
|
||||||
|
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
|
||||||
|
flexPWR® Technology.
|
||||||
|
Goto https://www.microchip.com for more information about them.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_DP83848
|
||||||
|
bool "DP83848"
|
||||||
|
help
|
||||||
|
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
|
||||||
|
Goto http://www.ti.com/product/DP83848J for more information about it.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_KSZ80XX
|
||||||
|
bool "KSZ80xx"
|
||||||
|
help
|
||||||
|
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
|
||||||
|
Ethernet Physical Layer Transceivers (PHY).
|
||||||
|
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
|
||||||
|
KSZ8051, KSZ8061, KSZ8081, KSZ8091
|
||||||
|
Goto https://www.microchip.com for more information about them.
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_MDC_GPIO
|
||||||
|
int "SMI MDC GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 23 if IDF_TARGET_ESP32
|
||||||
|
default 31 if IDF_TARGET_ESP32P4
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SMI MDC.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_MDIO_GPIO
|
||||||
|
int "SMI MDIO GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 18 if IDF_TARGET_ESP32
|
||||||
|
default 52 if IDF_TARGET_ESP32P4
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SMI MDIO.
|
||||||
|
endif
|
||||||
|
|
||||||
|
if EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
config EXAMPLE_ETH_SPI_HOST
|
||||||
|
int "SPI Host Number"
|
||||||
|
range 0 2
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
Set the SPI host used to communicate with the SPI Ethernet Controller.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_SCLK_GPIO
|
||||||
|
int "SPI SCLK GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 14
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SPI SCLK.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_MOSI_GPIO
|
||||||
|
int "SPI MOSI GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 13
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SPI MOSI.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_MISO_GPIO
|
||||||
|
int "SPI MISO GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||||
|
default 12
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SPI MISO.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_CS_GPIO
|
||||||
|
int "SPI CS GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 15
|
||||||
|
help
|
||||||
|
Set the GPIO number used by SPI CS.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_CLOCK_MHZ
|
||||||
|
int "SPI clock speed (MHz)"
|
||||||
|
range 5 80
|
||||||
|
default 36
|
||||||
|
help
|
||||||
|
Set the clock speed (MHz) of SPI interface.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_SPI_INT_GPIO
|
||||||
|
int "Interrupt GPIO number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||||
|
default 4
|
||||||
|
help
|
||||||
|
Set the GPIO number used by the SPI Ethernet module interrupt line.
|
||||||
|
endif # EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_RST_GPIO
|
||||||
|
int "PHY Reset GPIO number"
|
||||||
|
range -1 ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 51 if IDF_TARGET_ESP32P4
|
||||||
|
default 5
|
||||||
|
help
|
||||||
|
Set the GPIO number used to reset PHY chip.
|
||||||
|
Set to -1 to disable PHY chip hardware reset.
|
||||||
|
|
||||||
|
config EXAMPLE_ETH_PHY_ADDR
|
||||||
|
int "PHY Address"
|
||||||
|
range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
Set PHY address according your board schematic.
|
||||||
|
endif # EXAMPLE_CONNECT_ETHERNET
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_PPP
|
||||||
|
bool "connect using Point to Point interface"
|
||||||
|
select LWIP_PPP_SUPPORT
|
||||||
|
help
|
||||||
|
Protocol examples can use PPP connection over serial line.
|
||||||
|
Choose this option to connect to the ppp server running
|
||||||
|
on your laptop over a serial line (either UART or USB ACM)
|
||||||
|
|
||||||
|
if EXAMPLE_CONNECT_PPP
|
||||||
|
choice EXAMPLE_CONNECT_PPP_DEVICE
|
||||||
|
prompt "Choose PPP device"
|
||||||
|
default EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
help
|
||||||
|
Select which peripheral to use to connect to the PPP server.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
bool "USB"
|
||||||
|
depends on SOC_USB_OTG_SUPPORTED
|
||||||
|
select TINYUSB_CDC_ENABLED
|
||||||
|
help
|
||||||
|
Use USB ACM device.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_PPP_DEVICE_UART
|
||||||
|
bool "UART"
|
||||||
|
help
|
||||||
|
Use UART.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
menu "UART Configuration"
|
||||||
|
depends on EXAMPLE_CONNECT_PPP_DEVICE_UART
|
||||||
|
config EXAMPLE_CONNECT_UART_TX_PIN
|
||||||
|
int "TXD Pin Number"
|
||||||
|
default 4
|
||||||
|
range 0 31
|
||||||
|
help
|
||||||
|
Pin number of UART TX.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_UART_RX_PIN
|
||||||
|
int "RXD Pin Number"
|
||||||
|
default 5
|
||||||
|
range 0 31
|
||||||
|
help
|
||||||
|
Pin number of UART RX.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_UART_BAUDRATE
|
||||||
|
int "UART Baudrate"
|
||||||
|
default 115200
|
||||||
|
range 9600 3000000
|
||||||
|
help
|
||||||
|
Baudrate of the UART device
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config EXAMPLE_PPP_CONN_MAX_RETRY
|
||||||
|
int "Maximum retry"
|
||||||
|
default 6
|
||||||
|
help
|
||||||
|
Set the Maximum retry to avoid station reconnecting if the pppd
|
||||||
|
is not available
|
||||||
|
|
||||||
|
endif # EXAMPLE_CONNECT_PPP
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_THREAD
|
||||||
|
bool "Connect using Thread interface"
|
||||||
|
depends on !IDF_TARGET_LINUX && OPENTHREAD_ENABLED
|
||||||
|
default y if SOC_IEEE802154_SUPPORTED
|
||||||
|
select EXAMPLE_CONNECT_IPV6
|
||||||
|
help
|
||||||
|
Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network.
|
||||||
|
Choose this option to connect with Thread.
|
||||||
|
The operational active dataset of the Thread network can be configured in openthread
|
||||||
|
component at '->Components->OpenThread->Thread Core Features->Thread Operational Dataset'
|
||||||
|
|
||||||
|
if EXAMPLE_CONNECT_THREAD
|
||||||
|
config EXAMPLE_THREAD_TASK_STACK_SIZE
|
||||||
|
int "Example Thread task stack size"
|
||||||
|
default 8192
|
||||||
|
help
|
||||||
|
Thread task stack size
|
||||||
|
|
||||||
|
menu "Radio Spinel Options"
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_UART || OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_UART_RX_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_UART
|
||||||
|
int "Uart Rx Pin"
|
||||||
|
default 17
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_UART_TX_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_UART
|
||||||
|
int "Uart Tx pin"
|
||||||
|
default 18
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_UART_BAUD
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_UART
|
||||||
|
int "Uart baud rate"
|
||||||
|
default 460800
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_UART_PORT
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_UART
|
||||||
|
int "Uart port"
|
||||||
|
default 1
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_SPI_CS_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
int "SPI CS Pin"
|
||||||
|
default 10
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_SPI_SCLK_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
int "SPI SCLK Pin"
|
||||||
|
default 12
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_SPI_MISO_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
int "SPI MISO Pin"
|
||||||
|
default 13
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_SPI_MOSI_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
int "SPI MOSI Pin"
|
||||||
|
default 11
|
||||||
|
|
||||||
|
config EXAMPLE_THREAD_SPI_INTR_PIN
|
||||||
|
depends on OPENTHREAD_RADIO_SPINEL_SPI
|
||||||
|
int "SPI Interrupt Pin"
|
||||||
|
default 8
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV4
|
||||||
|
bool
|
||||||
|
depends on LWIP_IPV4
|
||||||
|
default n if EXAMPLE_CONNECT_THREAD
|
||||||
|
default y
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV6
|
||||||
|
depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET || EXAMPLE_CONNECT_PPP || EXAMPLE_CONNECT_THREAD
|
||||||
|
bool "Obtain IPv6 address"
|
||||||
|
default y
|
||||||
|
select LWIP_IPV6
|
||||||
|
select LWIP_PPP_ENABLE_IPV6 if EXAMPLE_CONNECT_PPP
|
||||||
|
help
|
||||||
|
By default, examples will wait until IPv4 and IPv6 local link addresses are obtained.
|
||||||
|
Disable this option if the network does not support IPv6.
|
||||||
|
Choose the preferred IPv6 address type if the connection code should wait until other than
|
||||||
|
the local link address gets assigned.
|
||||||
|
Consider enabling IPv6 stateless address autoconfiguration (SLAAC) in the LWIP component.
|
||||||
|
|
||||||
|
if EXAMPLE_CONNECT_IPV6
|
||||||
|
choice EXAMPLE_CONNECT_PREFERRED_IPV6
|
||||||
|
prompt "Preferred IPv6 Type"
|
||||||
|
default EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
|
||||||
|
help
|
||||||
|
Select which kind of IPv6 address the connect logic waits for.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK
|
||||||
|
bool "Local Link Address"
|
||||||
|
help
|
||||||
|
Blocks until Local link address assigned.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV6_PREF_GLOBAL
|
||||||
|
bool "Global Address"
|
||||||
|
help
|
||||||
|
Blocks until Global address assigned.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL
|
||||||
|
bool "Site Local Address"
|
||||||
|
help
|
||||||
|
Blocks until Site link address assigned.
|
||||||
|
|
||||||
|
config EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL
|
||||||
|
bool "Unique Local Link Address"
|
||||||
|
help
|
||||||
|
Blocks until Unique local address assigned.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
endmenu
|
||||||
Binary file not shown.
66
components/protocol_examples_common/README.md
Normal file
66
components/protocol_examples_common/README.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# protocol_example_connect
|
||||||
|
|
||||||
|
This component implements the most common connection methods for ESP32 boards. It should be used mainly in examples of ESP-IDF to demonstrate functionality of network protocols and other libraries, that need the connection step as a prerequisite.
|
||||||
|
|
||||||
|
## How to use this component
|
||||||
|
|
||||||
|
Choose the preferred interface (WiFi, Ethernet, Thread, PPPoS) to connect to the network and configure the interface.
|
||||||
|
|
||||||
|
It is possible to enable multiple interfaces simultaneously making the connection phase to block until all the chosen interfaces acquire IP addresses.
|
||||||
|
It is also possible to disable all interfaces, skipping the connection phase altogether.
|
||||||
|
|
||||||
|
### WiFi
|
||||||
|
|
||||||
|
Choose WiFi connection method (for chipsets that support it) and configure basic WiFi connection properties:
|
||||||
|
* WiFi SSID
|
||||||
|
* WiFI password
|
||||||
|
* Maximum connection retry (connection would be aborted if it doesn't succeed after specified number of retries)
|
||||||
|
* WiFi scan method (including RSSI and authorization mode threshold)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Ethernet
|
||||||
|
|
||||||
|
Choose Ethernet connection if your board supports it. The most common settings is using Espressif Ethernet Kit, which is also the recommended HW for this selection. You can also select an SPI ethernet device (if your chipset doesn't support internal EMAC or if you prefer). It is also possible to use OpenCores Ethernet MAC if you're running the example under QEMU.
|
||||||
|
|
||||||
|
### Thread
|
||||||
|
|
||||||
|
Choose Thread connection if your board supports IEEE802.15.4 native radio or works with [OpenThread RCP](../../openthread/ot_rcp/README.md). You can configure the Thread network at menuconfig '->Components->OpenThread->Thread Core Features->Thread Operational Dataset'.
|
||||||
|
|
||||||
|
If the Thread end-device joins a Thread network with a Thread Border Router that has the NAT64 feature enabled, the end-device can access the Internet with the standard DNS APIs after configuring the following properties:
|
||||||
|
* Enable DNS64 client ('->Components->OpenThread->Thread Core Features->Enable DNS64 client')
|
||||||
|
* Enable custom DNS external resolve Hook ('->Components->LWIP->Hooks->DNS external resolve Hook->Custom implementation')
|
||||||
|
|
||||||
|
### PPP
|
||||||
|
|
||||||
|
Point to point connection method creates a simple IP tunnel to the counterpart device (running PPP server), typically a Linux machine with pppd service. We currently support only PPP over Serial (using UART or USB CDC). This is useful for simple testing of networking layers, but with some additional configuration on the server side, we could simulate standard model of internet connectivity. The PPP server could be also represented by a cellular modem device with pre-configured connectivity and already switched to PPP mode (this setup is not very flexible though, so we suggest using a standard modem library implementing commands and modes, e.g. [esp_modem](https://components.espressif.com/component/espressif/esp_modem) ).
|
||||||
|
|
||||||
|
> [!Note]
|
||||||
|
> Note that if you choose USB device, you have to manually add a dependency on `esp_tinyusb` component. This step is necessary to keep the `protocol_example_connect` component simple and dependency free. Please run this command from your project location to add the dependency:
|
||||||
|
> ```bash
|
||||||
|
> idf.py add-dependency espressif/esp_tinyusb^1
|
||||||
|
> ```
|
||||||
|
|
||||||
|
#### Setup a PPP server
|
||||||
|
|
||||||
|
Connect the board using UART or USB and note the device name, which would be typically:
|
||||||
|
* `/dev/ttyACMx` for USB devices
|
||||||
|
* `/dev/ttyUSBx` for UART devices
|
||||||
|
|
||||||
|
Run the pppd server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pppd /dev/ttyACM0 115200 192.168.11.1:192.168.11.2 ms-dns 8.8.8.8 modem local noauth debug nocrtscts nodetach +ipv6
|
||||||
|
```
|
||||||
|
|
||||||
|
Please update the parameters with the correct serial device, baud rate, IP addresses, DNS server, use `+ipv6` if `EXAMPLE_CONNECT_IPV6=y`.
|
||||||
|
|
||||||
|
#### Connection to outside
|
||||||
|
|
||||||
|
In order to access other network endpoints, we have to configure some IP/translation rules. The easiest method is to setup a masquerade of the PPPD created interface (`ppp0`) to your default networking interface (`${ETH0}`). Here is an example of such rule:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo iptables -t nat -A POSTROUTING -o ${ETH0} -j MASQUERADE
|
||||||
|
sudo iptables -A FORWARD -i ${ETH0} -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
sudo iptables -A FORWARD -i ppp0 -o ${ETH0} -j ACCEPT
|
||||||
|
```
|
||||||
BIN
components/protocol_examples_common/README.md:Zone.Identifier
Normal file
BIN
components/protocol_examples_common/README.md:Zone.Identifier
Normal file
Binary file not shown.
69
components/protocol_examples_common/addr_from_stdin.c
Normal file
69
components/protocol_examples_common/addr_from_stdin.c
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#define HOST_IP_SIZE 128
|
||||||
|
|
||||||
|
esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *addr_family, struct sockaddr_storage *dest_addr)
|
||||||
|
{
|
||||||
|
char host_ip[HOST_IP_SIZE];
|
||||||
|
int len;
|
||||||
|
static bool already_init = false;
|
||||||
|
|
||||||
|
// this function could be called multiple times -> make sure UART init runs only once
|
||||||
|
if (!already_init) {
|
||||||
|
example_configure_stdin_stdout();
|
||||||
|
already_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore empty or LF only string (could receive from DUT class)
|
||||||
|
do {
|
||||||
|
fgets(host_ip, HOST_IP_SIZE, stdin);
|
||||||
|
len = strlen(host_ip);
|
||||||
|
} while (len<=1 && host_ip[0] == '\n');
|
||||||
|
host_ip[len - 1] = '\0';
|
||||||
|
|
||||||
|
struct addrinfo hints, *addr_list, *cur;
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
|
||||||
|
// run getaddrinfo() to decide on the IP protocol
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = sock_type;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
if( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
for( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
|
||||||
|
memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV4
|
||||||
|
if (cur->ai_family == AF_INET) {
|
||||||
|
*ip_protocol = IPPROTO_IP;
|
||||||
|
*addr_family = AF_INET;
|
||||||
|
// add port number and return on first IPv4 match
|
||||||
|
((struct sockaddr_in*)dest_addr)->sin_port = htons(port);
|
||||||
|
freeaddrinfo( addr_list );
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif // IPV4
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
if (cur->ai_family == AF_INET6) {
|
||||||
|
*ip_protocol = IPPROTO_IPV6;
|
||||||
|
*addr_family = AF_INET6;
|
||||||
|
// add port and interface number and return on first IPv6 match
|
||||||
|
((struct sockaddr_in6*)dest_addr)->sin6_port = htons(port);
|
||||||
|
((struct sockaddr_in6*)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
|
||||||
|
freeaddrinfo( addr_list );
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif // IPV6
|
||||||
|
}
|
||||||
|
// no match found
|
||||||
|
freeaddrinfo( addr_list );
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
Binary file not shown.
148
components/protocol_examples_common/connect.c
Normal file
148
components/protocol_examples_common/connect.c
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_wifi_default.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
static const char *TAG = "example_common";
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
/* types of ipv6 addresses to be displayed on ipv6 events */
|
||||||
|
const char *example_ipv6_addr_types_to_str[6] = {
|
||||||
|
"ESP_IP6_ADDR_IS_UNKNOWN",
|
||||||
|
"ESP_IP6_ADDR_IS_GLOBAL",
|
||||||
|
"ESP_IP6_ADDR_IS_LINK_LOCAL",
|
||||||
|
"ESP_IP6_ADDR_IS_SITE_LOCAL",
|
||||||
|
"ESP_IP6_ADDR_IS_UNIQUE_LOCAL",
|
||||||
|
"ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks the netif description if it contains specified prefix.
|
||||||
|
* All netifs created within common connect component are prefixed with the module TAG,
|
||||||
|
* so it returns true if the specified netif is owned by this module
|
||||||
|
*/
|
||||||
|
bool example_is_our_netif(const char *prefix, esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool netif_desc_matches_with(esp_netif_t *netif, void *ctx)
|
||||||
|
{
|
||||||
|
return strcmp(ctx, esp_netif_get_desc(netif)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_netif_t *get_example_netif_from_desc(const char *desc)
|
||||||
|
{
|
||||||
|
return esp_netif_find_if(netif_desc_matches_with, (void*)desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t print_all_ips_tcpip(void* ctx)
|
||||||
|
{
|
||||||
|
const char *prefix = ctx;
|
||||||
|
// iterate over active interfaces, and print out IPs of "our" netifs
|
||||||
|
esp_netif_t *netif = NULL;
|
||||||
|
while ((netif = esp_netif_next_unsafe(netif)) != NULL) {
|
||||||
|
if (example_is_our_netif(prefix, netif)) {
|
||||||
|
ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV4
|
||||||
|
esp_netif_ip_info_t ip;
|
||||||
|
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF];
|
||||||
|
int ip6_addrs = esp_netif_get_all_ip6(netif, ip6);
|
||||||
|
for (int j = 0; j < ip6_addrs; ++j) {
|
||||||
|
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j]));
|
||||||
|
ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), example_ipv6_addr_types_to_str[ipv6_type]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void example_print_all_netif_ips(const char *prefix)
|
||||||
|
{
|
||||||
|
// Print all IPs in TCPIP context to avoid potential races of removing/adding netifs when iterating over the list
|
||||||
|
esp_netif_tcpip_exec(print_all_ips_tcpip, (void*) prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t example_connect(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
if (example_ethernet_connect() != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ethernet_shutdown));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
if (example_wifi_connect() != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_THREAD
|
||||||
|
if (example_thread_connect() != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_thread_shutdown));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
|
if (example_ppp_connect() != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ppp_shutdown));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_THREAD
|
||||||
|
example_print_all_netif_ips(EXAMPLE_NETIF_DESC_THREAD);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
|
example_print_all_netif_ips(EXAMPLE_NETIF_DESC_PPP);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t example_disconnect(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
example_ethernet_shutdown();
|
||||||
|
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_ethernet_shutdown));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
example_wifi_shutdown();
|
||||||
|
ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_wifi_shutdown));
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
BIN
components/protocol_examples_common/connect.c:Zone.Identifier
Normal file
BIN
components/protocol_examples_common/connect.c:Zone.Identifier
Normal file
Binary file not shown.
87
components/protocol_examples_common/console_cmd.c
Normal file
87
components/protocol_examples_common/console_cmd.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char *TAG = "example_console";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct arg_str *ssid;
|
||||||
|
struct arg_str *password;
|
||||||
|
struct arg_int *channel;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_connect_args_t;
|
||||||
|
static wifi_connect_args_t connect_args;
|
||||||
|
|
||||||
|
static int cmd_do_wifi_connect(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &connect_args);
|
||||||
|
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, connect_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wifi_config_t wifi_config = {
|
||||||
|
.sta = {
|
||||||
|
.scan_method = WIFI_ALL_CHANNEL_SCAN,
|
||||||
|
.sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (connect_args.channel->count > 0) {
|
||||||
|
wifi_config.sta.channel = (uint8_t)(connect_args.channel->ival[0]);
|
||||||
|
}
|
||||||
|
const char *ssid = connect_args.ssid->sval[0];
|
||||||
|
const char *pass = connect_args.password->sval[0];
|
||||||
|
strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
|
||||||
|
if (pass) {
|
||||||
|
strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
|
||||||
|
}
|
||||||
|
example_wifi_sta_do_connect(wifi_config, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_do_wifi_disconnect(int argc, char **argv)
|
||||||
|
{
|
||||||
|
example_wifi_sta_do_disconnect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void example_register_wifi_connect_commands(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Registering WiFi connect commands.");
|
||||||
|
example_wifi_start();
|
||||||
|
|
||||||
|
connect_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
|
||||||
|
connect_args.password = arg_str0(NULL, NULL, "<pass>", "password of AP");
|
||||||
|
connect_args.channel = arg_int0("n", "channel", "<channel>", "channel of AP");
|
||||||
|
connect_args.end = arg_end(2);
|
||||||
|
const esp_console_cmd_t wifi_connect_cmd = {
|
||||||
|
.command = "wifi_connect",
|
||||||
|
.help = "WiFi is station mode, join specified soft-AP",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &cmd_do_wifi_connect,
|
||||||
|
.argtable = &connect_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_connect_cmd) );
|
||||||
|
|
||||||
|
|
||||||
|
const esp_console_cmd_t wifi_disconnect_cmd = {
|
||||||
|
.command = "wifi_disconnect",
|
||||||
|
.help = "Do wifi disconnect",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &cmd_do_wifi_disconnect,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_disconnect_cmd) );
|
||||||
|
}
|
||||||
Binary file not shown.
245
components/protocol_examples_common/eth_connect.c
Normal file
245
components/protocol_examples_common/eth_connect.c
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_eth.h"
|
||||||
|
#if CONFIG_ETH_USE_SPI_ETHERNET
|
||||||
|
#include "driver/spi_master.h"
|
||||||
|
#endif // CONFIG_ETH_USE_SPI_ETHERNET
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_mac.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char *TAG = "ethernet_connect";
|
||||||
|
static SemaphoreHandle_t s_semph_get_ip_addrs = NULL;
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
static SemaphoreHandle_t s_semph_get_ip6_addrs = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static esp_netif_t *eth_start(void);
|
||||||
|
static void eth_stop(void);
|
||||||
|
|
||||||
|
|
||||||
|
/** Event handler for Ethernet events */
|
||||||
|
|
||||||
|
static void eth_on_got_ip(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
||||||
|
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
|
||||||
|
static void eth_on_got_ipv6(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
|
||||||
|
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
|
||||||
|
IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]);
|
||||||
|
if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
|
||||||
|
xSemaphoreGive(s_semph_get_ip6_addrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_eth_event(void *esp_netif, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
switch (event_id) {
|
||||||
|
case ETHERNET_EVENT_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "Ethernet Link Up");
|
||||||
|
ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
|
||||||
|
static esp_eth_handle_t s_eth_handle = NULL;
|
||||||
|
static esp_eth_mac_t *s_mac = NULL;
|
||||||
|
static esp_eth_phy_t *s_phy = NULL;
|
||||||
|
static esp_eth_netif_glue_handle_t s_eth_glue = NULL;
|
||||||
|
|
||||||
|
static esp_netif_t *eth_start(void)
|
||||||
|
{
|
||||||
|
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
|
||||||
|
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
|
||||||
|
esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_ETH;
|
||||||
|
esp_netif_config.route_prio = 64;
|
||||||
|
esp_netif_config_t netif_config = {
|
||||||
|
.base = &esp_netif_config,
|
||||||
|
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
|
||||||
|
};
|
||||||
|
esp_netif_t *netif = esp_netif_new(&netif_config);
|
||||||
|
assert(netif);
|
||||||
|
|
||||||
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
|
mac_config.rx_task_stack_size = CONFIG_EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE;
|
||||||
|
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||||
|
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
|
||||||
|
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
|
||||||
|
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
|
||||||
|
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
|
||||||
|
esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
|
||||||
|
esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
|
||||||
|
s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
|
||||||
|
#if CONFIG_EXAMPLE_ETH_PHY_GENERIC
|
||||||
|
s_phy = esp_eth_phy_new_generic(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_ETH_PHY_IP101
|
||||||
|
s_phy = esp_eth_phy_new_ip101(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
|
||||||
|
s_phy = esp_eth_phy_new_rtl8201(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
|
||||||
|
s_phy = esp_eth_phy_new_lan87xx(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
|
||||||
|
s_phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
|
||||||
|
s_phy = esp_eth_phy_new_ksz80xx(&phy_config);
|
||||||
|
#endif
|
||||||
|
#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
gpio_install_isr_service(0);
|
||||||
|
spi_bus_config_t buscfg = {
|
||||||
|
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
|
||||||
|
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
|
||||||
|
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
|
||||||
|
.quadwp_io_num = -1,
|
||||||
|
.quadhd_io_num = -1,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||||
|
spi_device_interface_config_t spi_devcfg = {
|
||||||
|
.mode = 0,
|
||||||
|
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
|
||||||
|
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
|
||||||
|
.queue_size = 20
|
||||||
|
};
|
||||||
|
#if CONFIG_EXAMPLE_USE_DM9051
|
||||||
|
/* dm9051 ethernet driver is based on spi driver */
|
||||||
|
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
|
||||||
|
dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
|
||||||
|
s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
|
||||||
|
s_phy = esp_eth_phy_new_dm9051(&phy_config);
|
||||||
|
#elif CONFIG_EXAMPLE_USE_W5500
|
||||||
|
/* w5500 ethernet driver is based on spi driver */
|
||||||
|
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
|
||||||
|
w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
|
||||||
|
s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
|
||||||
|
s_phy = esp_eth_phy_new_w5500(&phy_config);
|
||||||
|
#endif
|
||||||
|
#elif CONFIG_EXAMPLE_USE_OPENETH
|
||||||
|
phy_config.autonego_timeout_ms = 100;
|
||||||
|
s_mac = esp_eth_mac_new_openeth(&mac_config);
|
||||||
|
s_phy = esp_eth_phy_new_dp83848(&phy_config);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Install Ethernet driver
|
||||||
|
esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
|
||||||
|
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
/* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
|
||||||
|
We set the ESP_MAC_ETH mac address as the default, if you want to use ESP_MAC_EFUSE_CUSTOM mac address, please enable the
|
||||||
|
configuration: `ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC`
|
||||||
|
*/
|
||||||
|
uint8_t eth_mac[6] = {0};
|
||||||
|
ESP_ERROR_CHECK(esp_read_mac(eth_mac, ESP_MAC_ETH));
|
||||||
|
ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, eth_mac));
|
||||||
|
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
|
||||||
|
|
||||||
|
// combine driver with netif
|
||||||
|
s_eth_glue = esp_eth_new_netif_glue(s_eth_handle);
|
||||||
|
esp_netif_attach(netif, s_eth_glue);
|
||||||
|
|
||||||
|
// Register user defined event handlers
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip, NULL));
|
||||||
|
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6, NULL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_eth_start(s_eth_handle);
|
||||||
|
return netif;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eth_stop(void)
|
||||||
|
{
|
||||||
|
esp_netif_t *eth_netif = get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH);
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event));
|
||||||
|
#endif
|
||||||
|
ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle));
|
||||||
|
ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
|
||||||
|
ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
|
||||||
|
s_eth_handle = NULL;
|
||||||
|
ESP_ERROR_CHECK(s_phy->del(s_phy));
|
||||||
|
ESP_ERROR_CHECK(s_mac->del(s_mac));
|
||||||
|
|
||||||
|
esp_netif_destroy(eth_netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_eth_handle_t get_example_eth_handle(void)
|
||||||
|
{
|
||||||
|
return s_eth_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tear down connection, release resources */
|
||||||
|
void example_ethernet_shutdown(void)
|
||||||
|
{
|
||||||
|
if (s_semph_get_ip_addrs == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||||
|
s_semph_get_ip_addrs = NULL;
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
vSemaphoreDelete(s_semph_get_ip6_addrs);
|
||||||
|
s_semph_get_ip6_addrs = NULL;
|
||||||
|
#endif
|
||||||
|
eth_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t example_ethernet_connect(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV4
|
||||||
|
s_semph_get_ip_addrs = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_get_ip_addrs == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
s_semph_get_ip6_addrs = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_get_ip6_addrs == NULL) {
|
||||||
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
eth_start();
|
||||||
|
ESP_LOGI(TAG, "Waiting for IP(s).");
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV4
|
||||||
|
xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY);
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,44 @@
|
|||||||
|
/* Common utilities for socket address input interface:
|
||||||
|
The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured).
|
||||||
|
This option is typically used in the CI, but could be enabled in the project configuration.
|
||||||
|
In that case this component is used to receive a string that is evaluated and processed to output
|
||||||
|
socket structures to open a connectio
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read and evaluate IP address from stdin
|
||||||
|
*
|
||||||
|
* This API reads stdin and parses the input address using getaddrinfo()
|
||||||
|
* to fill in struct sockaddr_storage (for both IPv4 and IPv6) used to open
|
||||||
|
* a socket. IP protocol is guessed from the IP address string.
|
||||||
|
*
|
||||||
|
* @param[in] port port number of expected connection
|
||||||
|
* @param[in] sock_type expected protocol: SOCK_STREAM or SOCK_DGRAM
|
||||||
|
* @param[out] ip_protocol resultant IP protocol: IPPROTO_IP or IPPROTO_IP6
|
||||||
|
* @param[out] addr_family resultant address family: AF_INET or AF_INET6
|
||||||
|
* @param[out] dest_addr sockaddr_storage structure (for both IPv4 and IPv6)
|
||||||
|
* @return ESP_OK on success, ESP_FAIL otherwise
|
||||||
|
*/
|
||||||
|
esp_err_t get_addr_from_stdin(int port, int sock_type,
|
||||||
|
int *ip_protocol,
|
||||||
|
int *addr_family,
|
||||||
|
struct sockaddr_storage *dest_addr);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* Private Functions of protocol example common */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
#define MAX_IP6_ADDRS_PER_NETIF (5)
|
||||||
|
|
||||||
|
#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK)
|
||||||
|
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL
|
||||||
|
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL)
|
||||||
|
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL
|
||||||
|
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL)
|
||||||
|
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL
|
||||||
|
#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL)
|
||||||
|
#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL
|
||||||
|
#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_...
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
extern const char *example_ipv6_addr_types_to_str[6];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void example_wifi_start(void);
|
||||||
|
void example_wifi_stop(void);
|
||||||
|
esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait);
|
||||||
|
esp_err_t example_wifi_sta_do_disconnect(void);
|
||||||
|
bool example_is_our_netif(const char *prefix, esp_netif_t *netif);
|
||||||
|
void example_print_all_netif_ips(const char *prefix);
|
||||||
|
void example_wifi_shutdown(void);
|
||||||
|
esp_err_t example_wifi_connect(void);
|
||||||
|
void example_ethernet_shutdown(void);
|
||||||
|
esp_err_t example_ethernet_connect(void);
|
||||||
|
void example_thread_shutdown(void);
|
||||||
|
esp_err_t example_thread_connect(void);
|
||||||
|
esp_err_t example_ppp_connect(void);
|
||||||
|
void example_ppp_start(void);
|
||||||
|
void example_ppp_shutdown(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
@@ -0,0 +1,154 @@
|
|||||||
|
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
#include "esp_eth.h"
|
||||||
|
#endif
|
||||||
|
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !CONFIG_IDF_TARGET_LINUX
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
#define EXAMPLE_NETIF_DESC_STA "example_netif_sta"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
#define EXAMPLE_NETIF_DESC_ETH "example_netif_eth"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_THREAD
|
||||||
|
#define EXAMPLE_NETIF_DESC_THREAD "example_netif_thread"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
|
#define EXAMPLE_NETIF_DESC_PPP "example_netif_ppp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST
|
||||||
|
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
|
||||||
|
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
|
||||||
|
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
|
||||||
|
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
|
||||||
|
#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK
|
||||||
|
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Example default interface, prefer the ethernet one if running in example-test (CI) configuration */
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH)
|
||||||
|
#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH)
|
||||||
|
#elif CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA)
|
||||||
|
#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA)
|
||||||
|
#elif CONFIG_EXAMPLE_CONNECT_THREAD
|
||||||
|
#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_THREAD)
|
||||||
|
#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_THREAD)
|
||||||
|
#elif CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
|
#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP)
|
||||||
|
#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure Wi-Fi or Ethernet, connect, wait for IP
|
||||||
|
*
|
||||||
|
* This all-in-one helper function is used in protocols examples to
|
||||||
|
* reduce the amount of boilerplate in the example.
|
||||||
|
*
|
||||||
|
* It is not intended to be used in real world applications.
|
||||||
|
* See examples under examples/wifi/getting_started/ and examples/ethernet/
|
||||||
|
* for more complete Wi-Fi or Ethernet initialization code.
|
||||||
|
*
|
||||||
|
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||||
|
* examples/protocols/README.md for more information about this function.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on successful connection
|
||||||
|
*/
|
||||||
|
esp_err_t example_connect(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counterpart to example_connect, de-initializes Wi-Fi or Ethernet
|
||||||
|
*/
|
||||||
|
esp_err_t example_disconnect(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure stdin and stdout to use blocking I/O
|
||||||
|
*
|
||||||
|
* This helper function is used in ASIO examples. It wraps installing the
|
||||||
|
* UART driver and configuring VFS layer to use UART driver for console I/O.
|
||||||
|
*/
|
||||||
|
esp_err_t example_configure_stdin_stdout(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns esp-netif pointer created by example_connect() described by
|
||||||
|
* the supplied desc field
|
||||||
|
*
|
||||||
|
* @param desc Textual interface of created network interface, for example "sta"
|
||||||
|
* indicate default WiFi station, "eth" default Ethernet interface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_netif_t *get_example_netif_from_desc(const char *desc);
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD
|
||||||
|
/**
|
||||||
|
* @brief Register wifi connect commands
|
||||||
|
*
|
||||||
|
* Provide a simple wifi_connect command in esp_console.
|
||||||
|
* This function can be used after esp_console is initialized.
|
||||||
|
*/
|
||||||
|
void example_register_wifi_connect_commands(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
/**
|
||||||
|
* @brief Get the example Ethernet driver handle
|
||||||
|
*
|
||||||
|
* @return esp_eth_handle_t
|
||||||
|
*/
|
||||||
|
esp_eth_handle_t get_example_eth_handle(void);
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
|
||||||
|
|
||||||
|
#else
|
||||||
|
static inline esp_err_t example_connect(void) {return ESP_OK;}
|
||||||
|
#endif // !CONFIG_IDF_TARGET_LINUX
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Thread configurations for protocol examples
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sdkconfig.h>
|
||||||
|
|
||||||
|
#include <esp_openthread_types.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_OPENTHREAD_RADIO_NATIVE
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.radio_mode = RADIO_MODE_NATIVE, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_OPENTHREAD_RADIO_SPINEL_UART)
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.radio_mode = RADIO_MODE_UART_RCP, \
|
||||||
|
.radio_uart_config = \
|
||||||
|
{ \
|
||||||
|
.port = CONFIG_EXAMPLE_THREAD_UART_PORT, \
|
||||||
|
.uart_config = \
|
||||||
|
{ \
|
||||||
|
.baud_rate = CONFIG_EXAMPLE_THREAD_UART_BAUD, \
|
||||||
|
.data_bits = UART_DATA_8_BITS, \
|
||||||
|
.parity = UART_PARITY_DISABLE, \
|
||||||
|
.stop_bits = UART_STOP_BITS_1, \
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
|
||||||
|
.rx_flow_ctrl_thresh = 0, \
|
||||||
|
.source_clk = UART_SCLK_DEFAULT, \
|
||||||
|
}, \
|
||||||
|
.rx_pin = CONFIG_EXAMPLE_THREAD_UART_RX_PIN, \
|
||||||
|
.tx_pin = CONFIG_EXAMPLE_THREAD_UART_TX_PIN, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
#elif defined(CONFIG_OPENTHREAD_RADIO_SPINEL_SPI)
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.radio_mode = RADIO_MODE_SPI_RCP, \
|
||||||
|
.radio_spi_config = \
|
||||||
|
{ \
|
||||||
|
.host_device = SPI2_HOST, \
|
||||||
|
.dma_channel = 2, \
|
||||||
|
.spi_interface = \
|
||||||
|
{ \
|
||||||
|
.mosi_io_num = CONFIG_EXAMPLE_THREAD_SPI_MOSI_PIN, \
|
||||||
|
.miso_io_num = CONFIG_EXAMPLE_THREAD_SPI_MISO_PIN, \
|
||||||
|
.sclk_io_num = CONFIG_EXAMPLE_THREAD_SPI_SCLK_PIN, \
|
||||||
|
.quadwp_io_num = -1, \
|
||||||
|
.quadhd_io_num = -1, \
|
||||||
|
}, \
|
||||||
|
.spi_device = \
|
||||||
|
{ \
|
||||||
|
.cs_ena_pretrans = 2, \
|
||||||
|
.input_delay_ns = 100, \
|
||||||
|
.mode = 0, \
|
||||||
|
.clock_speed_hz = 2500 * 1000, \
|
||||||
|
.spics_io_num = CONFIG_EXAMPLE_THREAD_SPI_CS_PIN, \
|
||||||
|
.queue_size = 5, \
|
||||||
|
}, \
|
||||||
|
.intr_pin = CONFIG_EXAMPLE_THREAD_SPI_INTR_PIN, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.radio_mode = RADIO_MODE_TREL, \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_OPENTHREAD_CONSOLE_TYPE_UART
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.host_connection_mode = HOST_CONNECTION_MODE_CLI_UART, \
|
||||||
|
.host_uart_config = \
|
||||||
|
{ \
|
||||||
|
.port = 0, \
|
||||||
|
.uart_config = \
|
||||||
|
{ \
|
||||||
|
.baud_rate = 115200, \
|
||||||
|
.data_bits = UART_DATA_8_BITS, \
|
||||||
|
.parity = UART_PARITY_DISABLE, \
|
||||||
|
.stop_bits = UART_STOP_BITS_1, \
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
|
||||||
|
.rx_flow_ctrl_thresh = 0, \
|
||||||
|
.source_clk = UART_SCLK_DEFAULT, \
|
||||||
|
}, \
|
||||||
|
.rx_pin = UART_PIN_NO_CHANGE, \
|
||||||
|
.tx_pin = UART_PIN_NO_CHANGE, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
#elif CONFIG_OPENTHREAD_CONSOLE_TYPE_USB_SERIAL_JTAG
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.host_connection_mode = HOST_CONNECTION_MODE_CLI_USB, \
|
||||||
|
.host_usb_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(), \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.storage_partition_name = "nvs", \
|
||||||
|
.netif_queue_size = 10, \
|
||||||
|
.task_queue_size = 10, \
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Utility functions for protocol examples
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Encode an URI
|
||||||
|
*
|
||||||
|
* @param dest a destination memory location
|
||||||
|
* @param src the source string
|
||||||
|
* @param len the length of the source string
|
||||||
|
* @return uint32_t the count of escaped characters
|
||||||
|
*
|
||||||
|
* @note Please allocate the destination buffer keeping in mind that encoding a
|
||||||
|
* special character will take up 3 bytes (for '%' and two hex digits).
|
||||||
|
* In the worst-case scenario, the destination buffer will have to be 3 times
|
||||||
|
* that of the source string.
|
||||||
|
*/
|
||||||
|
uint32_t example_uri_encode(char *dest, const char *src, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decode an URI
|
||||||
|
*
|
||||||
|
* @param dest a destination memory location
|
||||||
|
* @param src the source string
|
||||||
|
* @param len the length of the source string
|
||||||
|
*
|
||||||
|
* @note Please allocate the destination buffer keeping in mind that a decoded
|
||||||
|
* special character will take up 2 less bytes than its encoded form.
|
||||||
|
* In the worst-case scenario, the destination buffer will have to be
|
||||||
|
* the same size that of the source string.
|
||||||
|
*/
|
||||||
|
void example_uri_decode(char *dest, const char *src, size_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
260
components/protocol_examples_common/ppp_connect.c
Normal file
260
components/protocol_examples_common/ppp_connect.c
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "esp_netif_ppp.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
#include "tinyusb.h"
|
||||||
|
#include "tusb_cdc_acm.h"
|
||||||
|
|
||||||
|
static int s_itf;
|
||||||
|
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE];
|
||||||
|
|
||||||
|
#else // DEVICE is UART
|
||||||
|
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#define BUF_SIZE (1024)
|
||||||
|
static bool s_stop_task = false;
|
||||||
|
|
||||||
|
#endif // CONNECT_PPP_DEVICE
|
||||||
|
|
||||||
|
|
||||||
|
static const char *TAG = "example_connect_ppp";
|
||||||
|
static int s_retry_num = 0;
|
||||||
|
static EventGroupHandle_t s_event_group = NULL;
|
||||||
|
static esp_netif_t *s_netif;
|
||||||
|
static const int GOT_IPV4 = BIT0;
|
||||||
|
static const int CONNECTION_FAILED = BIT1;
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
static const int GOT_IPV6 = BIT2;
|
||||||
|
#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED)
|
||||||
|
#else
|
||||||
|
#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static esp_err_t transmit(void *h, void *buffer, size_t len)
|
||||||
|
{
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE);
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
tinyusb_cdcacm_write_queue(s_itf, buffer, len);
|
||||||
|
tinyusb_cdcacm_write_flush(s_itf, 0);
|
||||||
|
#else // DEVICE_UART
|
||||||
|
uart_write_bytes(UART_NUM_1, buffer, len);
|
||||||
|
#endif // CONNECT_PPP_DEVICE
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_netif_driver_ifconfig_t driver_cfg = {
|
||||||
|
.handle = (void *)1, // singleton driver, just to != NULL
|
||||||
|
.transmit = transmit,
|
||||||
|
};
|
||||||
|
const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg;
|
||||||
|
|
||||||
|
static void on_ip_event(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (event_id == IP_EVENT_PPP_GOT_IP) {
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_netif_t *netif = event->esp_netif;
|
||||||
|
esp_netif_dns_info_t dns_info;
|
||||||
|
ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
||||||
|
esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info);
|
||||||
|
ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4));
|
||||||
|
xEventGroupSetBits(s_event_group, GOT_IPV4);
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
} else if (event_id == IP_EVENT_GOT_IP6) {
|
||||||
|
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
|
||||||
|
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
|
||||||
|
IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]);
|
||||||
|
if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
|
||||||
|
xEventGroupSetBits(s_event_group, GOT_IPV6);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else if (event_id == IP_EVENT_PPP_LOST_IP) {
|
||||||
|
ESP_LOGI(TAG, "Disconnect from PPP Server");
|
||||||
|
s_retry_num++;
|
||||||
|
if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) {
|
||||||
|
ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num);
|
||||||
|
xEventGroupSetBits(s_event_group, CONNECTION_FAILED);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num);
|
||||||
|
esp_netif_action_start(s_netif, 0, 0, 0);
|
||||||
|
esp_netif_action_connected(s_netif, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
static void cdc_rx_callback(int itf, cdcacm_event_t *event)
|
||||||
|
{
|
||||||
|
size_t rx_size = 0;
|
||||||
|
if (itf != s_itf) {
|
||||||
|
// Not our channel
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size);
|
||||||
|
if (ret == ESP_OK) {
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE);
|
||||||
|
// pass the received data to the network interface
|
||||||
|
esp_netif_receive(s_netif, buf, rx_size, NULL);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Read error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void line_state_changed(int itf, cdcacm_event_t *event)
|
||||||
|
{
|
||||||
|
s_itf = itf; // use this channel for the netif communication
|
||||||
|
ESP_LOGI(TAG, "Line state changed on channel %d", itf);
|
||||||
|
}
|
||||||
|
#else // DEVICE is UART
|
||||||
|
|
||||||
|
static void ppp_task(void *args)
|
||||||
|
{
|
||||||
|
uart_config_t uart_config = {};
|
||||||
|
uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE;
|
||||||
|
uart_config.data_bits = UART_DATA_8_BITS;
|
||||||
|
uart_config.parity = UART_PARITY_DISABLE;
|
||||||
|
uart_config.stop_bits = UART_STOP_BITS_1;
|
||||||
|
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||||
|
uart_config.source_clk = UART_SCLK_DEFAULT;
|
||||||
|
|
||||||
|
QueueHandle_t event_queue;
|
||||||
|
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0));
|
||||||
|
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config));
|
||||||
|
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||||
|
ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1));
|
||||||
|
|
||||||
|
char *buffer = (char*)malloc(BUF_SIZE);
|
||||||
|
uart_event_t event;
|
||||||
|
esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif);
|
||||||
|
esp_netif_action_start(s_netif, 0, 0, 0);
|
||||||
|
esp_netif_action_connected(s_netif, 0, 0, 0);
|
||||||
|
while (!s_stop_task) {
|
||||||
|
xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000));
|
||||||
|
if (event.type == UART_DATA) {
|
||||||
|
size_t len;
|
||||||
|
uart_get_buffered_data_len(UART_NUM_1, &len);
|
||||||
|
if (len) {
|
||||||
|
len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0);
|
||||||
|
ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE);
|
||||||
|
esp_netif_receive(s_netif, buffer, len, NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Received UART event: %d", event.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONNECT_PPP_DEVICE
|
||||||
|
|
||||||
|
esp_err_t example_ppp_connect(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Start example_connect.");
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
ESP_LOGI(TAG, "USB initialization");
|
||||||
|
const tinyusb_config_t tusb_cfg = {
|
||||||
|
.device_descriptor = NULL,
|
||||||
|
.string_descriptor = NULL,
|
||||||
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
|
|
||||||
|
tinyusb_config_cdcacm_t acm_cfg = {
|
||||||
|
.usb_dev = TINYUSB_USBDEV_0,
|
||||||
|
.cdc_port = TINYUSB_CDC_ACM_0,
|
||||||
|
.callback_rx = &cdc_rx_callback,
|
||||||
|
.callback_rx_wanted_char = NULL,
|
||||||
|
.callback_line_state_changed = NULL,
|
||||||
|
.callback_line_coding_changed = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
|
||||||
|
/* the second way to register a callback */
|
||||||
|
ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback(
|
||||||
|
TINYUSB_CDC_ACM_0,
|
||||||
|
CDC_EVENT_LINE_STATE_CHANGED,
|
||||||
|
&line_state_changed));
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
|
||||||
|
s_event_group = xEventGroupCreate();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL));
|
||||||
|
|
||||||
|
esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP();
|
||||||
|
base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP;
|
||||||
|
esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg,
|
||||||
|
.driver = ppp_driver_cfg,
|
||||||
|
.stack = ESP_NETIF_NETSTACK_DEFAULT_PPP
|
||||||
|
};
|
||||||
|
|
||||||
|
s_netif = esp_netif_new(&netif_ppp_config);
|
||||||
|
assert(s_netif);
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB
|
||||||
|
esp_netif_action_start(s_netif, 0, 0, 0);
|
||||||
|
esp_netif_action_connected(s_netif, 0, 0, 0);
|
||||||
|
#else // DEVICE is UART
|
||||||
|
s_stop_task = false;
|
||||||
|
if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) {
|
||||||
|
ESP_LOGE(TAG, "Failed to create a ppp connection task");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
#endif // CONNECT_PPP_DEVICE
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Waiting for IP address");
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY);
|
||||||
|
if (bits & CONNECTION_FAILED) {
|
||||||
|
ESP_LOGE(TAG, "Connection failed!");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Connected!");
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void example_ppp_shutdown(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART
|
||||||
|
s_stop_task = true;
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_netif_action_disconnected(s_netif, 0, 0, 0);
|
||||||
|
|
||||||
|
vEventGroupDelete(s_event_group);
|
||||||
|
esp_netif_action_stop(s_netif, 0, 0, 0);
|
||||||
|
esp_netif_destroy(s_netif);
|
||||||
|
s_netif = NULL;
|
||||||
|
s_event_group = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_PPP
|
||||||
Binary file not shown.
388
components/protocol_examples_common/protocol_examples_utils.c
Normal file
388
components/protocol_examples_common/protocol_examples_utils.c
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
/*
|
||||||
|
* Utility functions for protocol examples
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2002-2021 Igor Sysoev
|
||||||
|
* 2011-2022 Nginx, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2002-2021 Igor Sysoev
|
||||||
|
* Copyright (C) 2011-2022 Nginx, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "protocol_examples_utils.h"
|
||||||
|
|
||||||
|
/* Type of Escape algorithms to be used */
|
||||||
|
#define NGX_ESCAPE_URI (0)
|
||||||
|
#define NGX_ESCAPE_ARGS (1)
|
||||||
|
#define NGX_ESCAPE_URI_COMPONENT (2)
|
||||||
|
#define NGX_ESCAPE_HTML (3)
|
||||||
|
#define NGX_ESCAPE_REFRESH (4)
|
||||||
|
#define NGX_ESCAPE_MEMCACHED (5)
|
||||||
|
#define NGX_ESCAPE_MAIL_AUTH (6)
|
||||||
|
|
||||||
|
/* Type of Unescape algorithms to be used */
|
||||||
|
#define NGX_UNESCAPE_URI (1)
|
||||||
|
#define NGX_UNESCAPE_REDIRECT (2)
|
||||||
|
|
||||||
|
|
||||||
|
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, unsigned int type)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
uint32_t *escape;
|
||||||
|
static u_char hex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per RFC 3986 only the following chars are allowed in URIs unescaped:
|
||||||
|
*
|
||||||
|
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||||
|
* gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||||
|
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
* / "*" / "+" / "," / ";" / "="
|
||||||
|
*
|
||||||
|
* And "%" can appear as a part of escaping itself. The following
|
||||||
|
* characters are not allowed and need to be escaped: %00-%1F, %7F-%FF,
|
||||||
|
* " ", """, "<", ">", "\", "^", "`", "{", "|", "}".
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* " ", "#", "%", "?", not allowed */
|
||||||
|
|
||||||
|
static uint32_t uri[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0xd000002d, /* 1101 0000 0000 0000 0000 0000 0010 1101 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* " ", "#", "%", "&", "+", ";", "?", not allowed */
|
||||||
|
|
||||||
|
static uint32_t args[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0xd800086d, /* 1101 1000 0000 0000 0000 1000 0110 1101 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* not ALPHA, DIGIT, "-", ".", "_", "~" */
|
||||||
|
|
||||||
|
static uint32_t uri_component[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* " ", "#", """, "%", "'", not allowed */
|
||||||
|
|
||||||
|
static uint32_t html[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0x500000ad, /* 0101 0000 0000 0000 0000 0000 1010 1101 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* " ", """, "'", not allowed */
|
||||||
|
|
||||||
|
static uint32_t refresh[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0x50000085, /* 0101 0000 0000 0000 0000 0000 1000 0101 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0xd8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
|
||||||
|
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* " ", "%", %00-%1F */
|
||||||
|
|
||||||
|
static uint32_t memcached[] = {
|
||||||
|
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
|
||||||
|
|
||||||
|
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
|
||||||
|
0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
|
||||||
|
|
||||||
|
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mail_auth is the same as memcached */
|
||||||
|
|
||||||
|
static uint32_t *map[] =
|
||||||
|
{ uri, args, uri_component, html, refresh, memcached, memcached };
|
||||||
|
|
||||||
|
|
||||||
|
escape = map[type];
|
||||||
|
|
||||||
|
if (dst == NULL) {
|
||||||
|
|
||||||
|
/* find the number of the characters to be escaped */
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uintptr_t) n;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
if (escape[*src >> 5] & (1U << (*src & 0x1f))) {
|
||||||
|
*dst++ = '%';
|
||||||
|
*dst++ = hex[*src >> 4];
|
||||||
|
*dst++ = hex[*src & 0xf];
|
||||||
|
src++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uintptr_t) dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, unsigned int type)
|
||||||
|
{
|
||||||
|
u_char *d, *s, ch, c, decoded;
|
||||||
|
enum {
|
||||||
|
sw_usual = 0,
|
||||||
|
sw_quoted,
|
||||||
|
sw_quoted_second
|
||||||
|
} state;
|
||||||
|
|
||||||
|
d = *dst;
|
||||||
|
s = *src;
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
decoded = 0;
|
||||||
|
|
||||||
|
while (size--) {
|
||||||
|
|
||||||
|
ch = *s++;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case sw_usual:
|
||||||
|
if (ch == '?'
|
||||||
|
&& (type & (NGX_UNESCAPE_URI | NGX_UNESCAPE_REDIRECT))) {
|
||||||
|
*d++ = ch;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == '%') {
|
||||||
|
state = sw_quoted;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = ch;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sw_quoted:
|
||||||
|
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
decoded = (u_char) (ch - '0');
|
||||||
|
state = sw_quoted_second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = (u_char) (ch | 0x20);
|
||||||
|
if (c >= 'a' && c <= 'f') {
|
||||||
|
decoded = (u_char) (c - 'a' + 10);
|
||||||
|
state = sw_quoted_second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the invalid quoted character */
|
||||||
|
|
||||||
|
state = sw_usual;
|
||||||
|
|
||||||
|
*d++ = ch;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sw_quoted_second:
|
||||||
|
|
||||||
|
state = sw_usual;
|
||||||
|
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
ch = (u_char) ((decoded << 4) + (ch - '0'));
|
||||||
|
|
||||||
|
if (type & NGX_UNESCAPE_REDIRECT) {
|
||||||
|
if (ch > '%' && ch < 0x7f) {
|
||||||
|
*d++ = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = ch;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = (u_char) (ch | 0x20);
|
||||||
|
if (c >= 'a' && c <= 'f') {
|
||||||
|
ch = (u_char) ((decoded << 4) + (c - 'a') + 10);
|
||||||
|
|
||||||
|
if (type & NGX_UNESCAPE_URI) {
|
||||||
|
if (ch == '?') {
|
||||||
|
*d++ = ch;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & NGX_UNESCAPE_REDIRECT) {
|
||||||
|
if (ch == '?') {
|
||||||
|
*d++ = ch;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch > '%' && ch < 0x7f) {
|
||||||
|
*d++ = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*d++ = ch;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the invalid quoted character */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
*dst = d;
|
||||||
|
*src = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t example_uri_encode(char *dest, const char *src, size_t len)
|
||||||
|
{
|
||||||
|
if (!src || !dest) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t ret = ngx_escape_uri((unsigned char *)dest, (unsigned char *)src, len, NGX_ESCAPE_URI_COMPONENT);
|
||||||
|
return (uint32_t)(ret - (uintptr_t)dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void example_uri_decode(char *dest, const char *src, size_t len)
|
||||||
|
{
|
||||||
|
if (!src || !dest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *src_ptr = (unsigned char *)src;
|
||||||
|
unsigned char *dst_ptr = (unsigned char *)dest;
|
||||||
|
ngx_unescape_uri(&dst_ptr, &src_ptr, len, NGX_UNESCAPE_URI);
|
||||||
|
}
|
||||||
Binary file not shown.
32
components/protocol_examples_common/stdin_out.c
Normal file
32
components/protocol_examples_common/stdin_out.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* Common functions for protocol examples, to configure stdin and stdout.
|
||||||
|
|
||||||
|
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 "protocol_examples_common.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "driver/uart_vfs.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
esp_err_t example_configure_stdin_stdout(void)
|
||||||
|
{
|
||||||
|
if (uart_is_driver_installed((uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM)) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
// Initialize VFS & UART so we can use std::cout/cin
|
||||||
|
setvbuf(stdin, NULL, _IONBF, 0);
|
||||||
|
/* Install UART driver for interrupt-driven reads and writes */
|
||||||
|
ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM,
|
||||||
|
256, 0, 0, NULL, 0) );
|
||||||
|
/* Tell VFS to use UART driver */
|
||||||
|
uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||||
|
uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
|
||||||
|
/* Move the caret to the beginning of the next line on '\n' */
|
||||||
|
uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
BIN
components/protocol_examples_common/stdin_out.c:Zone.Identifier
Normal file
BIN
components/protocol_examples_common/stdin_out.c:Zone.Identifier
Normal file
Binary file not shown.
130
components/protocol_examples_common/thread_connect.c
Normal file
130
components/protocol_examples_common/thread_connect.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_event_base.h"
|
||||||
|
#include "esp_vfs_eventfd.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
#include "protocol_examples_common.h"
|
||||||
|
#include "protocol_examples_thread_config.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <esp_openthread_cli.h>
|
||||||
|
#include <esp_openthread_lock.h>
|
||||||
|
#include <esp_openthread_netif_glue.h>
|
||||||
|
#include <esp_openthread_types.h>
|
||||||
|
#include <esp_openthread.h>
|
||||||
|
#include <openthread/dataset.h>
|
||||||
|
#include <openthread/logging.h>
|
||||||
|
|
||||||
|
static TaskHandle_t s_ot_task_handle = NULL;
|
||||||
|
static esp_netif_t *s_openthread_netif = NULL;
|
||||||
|
static SemaphoreHandle_t s_semph_thread_attached = NULL;
|
||||||
|
static SemaphoreHandle_t s_semph_thread_set_dns_server = NULL;
|
||||||
|
static const char *TAG = "example_connect";
|
||||||
|
|
||||||
|
static void thread_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id,
|
||||||
|
void* event_data)
|
||||||
|
{
|
||||||
|
if (event_base == OPENTHREAD_EVENT) {
|
||||||
|
if (event_id == OPENTHREAD_EVENT_ATTACHED) {
|
||||||
|
xSemaphoreGive(s_semph_thread_attached);
|
||||||
|
} else if (event_id == OPENTHREAD_EVENT_SET_DNS_SERVER) {
|
||||||
|
xSemaphoreGive(s_semph_thread_set_dns_server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ot_task_worker(void *aContext)
|
||||||
|
{
|
||||||
|
esp_openthread_platform_config_t config = {
|
||||||
|
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
|
||||||
|
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
|
||||||
|
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_OPENTHREAD();
|
||||||
|
esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_THREAD;
|
||||||
|
esp_netif_config_t cfg = {
|
||||||
|
.base = &esp_netif_config,
|
||||||
|
.stack = &g_esp_netif_netstack_default_openthread,
|
||||||
|
};
|
||||||
|
s_openthread_netif = esp_netif_new(&cfg);
|
||||||
|
assert(s_openthread_netif != NULL);
|
||||||
|
|
||||||
|
// Initialize the OpenThread stack
|
||||||
|
ESP_ERROR_CHECK(esp_openthread_init(&config));
|
||||||
|
ESP_ERROR_CHECK(esp_netif_attach(s_openthread_netif, esp_openthread_netif_glue_init(&config)));
|
||||||
|
esp_openthread_lock_acquire(portMAX_DELAY);
|
||||||
|
(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
|
esp_openthread_cli_init();
|
||||||
|
esp_openthread_cli_create_task();
|
||||||
|
otOperationalDatasetTlvs dataset;
|
||||||
|
otError error = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &dataset);
|
||||||
|
if (error != OT_ERROR_NONE) {
|
||||||
|
ESP_ERROR_CHECK(esp_openthread_auto_start(NULL));
|
||||||
|
} else {
|
||||||
|
ESP_ERROR_CHECK(esp_openthread_auto_start(&dataset));
|
||||||
|
}
|
||||||
|
esp_openthread_lock_release();
|
||||||
|
|
||||||
|
// Run the main loop
|
||||||
|
esp_openthread_launch_mainloop();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
esp_openthread_netif_glue_deinit();
|
||||||
|
esp_netif_destroy(s_openthread_netif);
|
||||||
|
esp_vfs_eventfd_unregister();
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tear down connection, release resources */
|
||||||
|
void example_thread_shutdown(void)
|
||||||
|
{
|
||||||
|
vTaskDelete(s_ot_task_handle);
|
||||||
|
esp_openthread_netif_glue_deinit();
|
||||||
|
esp_netif_destroy(s_openthread_netif);
|
||||||
|
esp_vfs_eventfd_unregister();
|
||||||
|
vSemaphoreDelete(s_semph_thread_set_dns_server);
|
||||||
|
vSemaphoreDelete(s_semph_thread_attached);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t example_thread_connect(void)
|
||||||
|
{
|
||||||
|
s_semph_thread_attached = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_thread_attached == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
s_semph_thread_set_dns_server = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_thread_set_dns_server == NULL) {
|
||||||
|
vSemaphoreDelete(s_semph_thread_attached);
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
// 4 eventfds might be used for Thread
|
||||||
|
// * netif
|
||||||
|
// * ot task queue
|
||||||
|
// * radio driver
|
||||||
|
// * border router
|
||||||
|
esp_vfs_eventfd_config_t eventfd_config = {
|
||||||
|
.max_fds = 4,
|
||||||
|
};
|
||||||
|
esp_vfs_eventfd_register(&eventfd_config);
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(OPENTHREAD_EVENT, ESP_EVENT_ANY_ID, thread_event_handler, NULL));
|
||||||
|
if (xTaskCreate(ot_task_worker, "ot_br_main", CONFIG_EXAMPLE_THREAD_TASK_STACK_SIZE, NULL, 5, &s_ot_task_handle) != pdPASS) {
|
||||||
|
vSemaphoreDelete(s_semph_thread_attached);
|
||||||
|
vSemaphoreDelete(s_semph_thread_set_dns_server);
|
||||||
|
ESP_LOGE(TAG, "Failed to create openthread task");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
xSemaphoreTake(s_semph_thread_attached, portMAX_DELAY);
|
||||||
|
// Wait 1s for the Thread device to set its DNS server with the NAT64 prefix.
|
||||||
|
if (xSemaphoreTake(s_semph_thread_set_dns_server, 1000 / portTICK_PERIOD_MS) != pdPASS) {
|
||||||
|
ESP_LOGW(TAG, "DNS server is not set for the Thread device, might be unable to access the Internet");
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
Binary file not shown.
247
components/protocol_examples_common/wifi_connect.c
Normal file
247
components/protocol_examples_common/wifi_connect.c
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection.
|
||||||
|
|
||||||
|
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 "protocol_examples_common.h"
|
||||||
|
#include "example_common_private.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_WIFI
|
||||||
|
|
||||||
|
static const char *TAG = "example_connect";
|
||||||
|
static esp_netif_t *s_example_sta_netif = NULL;
|
||||||
|
static SemaphoreHandle_t s_semph_get_ip_addrs = NULL;
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
static SemaphoreHandle_t s_semph_get_ip6_addrs = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int s_retry_num = 0;
|
||||||
|
|
||||||
|
static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
s_retry_num++;
|
||||||
|
if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) {
|
||||||
|
ESP_LOGI(TAG, "WiFi Connect failed %d times, stop reconnect.", s_retry_num);
|
||||||
|
/* let example_wifi_sta_do_connect() return */
|
||||||
|
if (s_semph_get_ip_addrs) {
|
||||||
|
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||||
|
}
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
if (s_semph_get_ip6_addrs) {
|
||||||
|
xSemaphoreGive(s_semph_get_ip6_addrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
example_wifi_sta_do_disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wifi_event_sta_disconnected_t *disconn = event_data;
|
||||||
|
if (disconn->reason == WIFI_REASON_ROAMING) {
|
||||||
|
ESP_LOGD(TAG, "station roaming, do nothing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Wi-Fi disconnected %d, trying to reconnect...", disconn->reason);
|
||||||
|
esp_err_t err = esp_wifi_connect();
|
||||||
|
if (err == ESP_ERR_WIFI_NOT_STARTED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void example_handler_on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
esp_netif_create_ip6_linklocal(esp_netif);
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
}
|
||||||
|
|
||||||
|
static void example_handler_on_sta_got_ip(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
s_retry_num = 0;
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
||||||
|
if (s_semph_get_ip_addrs) {
|
||||||
|
xSemaphoreGive(s_semph_get_ip_addrs);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&event->ip_info.ip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
static void example_handler_on_sta_got_ipv6(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
|
||||||
|
if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip);
|
||||||
|
ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif),
|
||||||
|
IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]);
|
||||||
|
|
||||||
|
if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) {
|
||||||
|
if (s_semph_get_ip6_addrs) {
|
||||||
|
xSemaphoreGive(s_semph_get_ip6_addrs);
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
|
||||||
|
|
||||||
|
void example_wifi_start(void)
|
||||||
|
{
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
|
||||||
|
// Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask)
|
||||||
|
esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_STA;
|
||||||
|
esp_netif_config.route_prio = 128;
|
||||||
|
s_example_sta_netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
|
||||||
|
esp_wifi_set_default_wifi_sta_handlers();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void example_wifi_stop(void)
|
||||||
|
{
|
||||||
|
esp_err_t err = esp_wifi_stop();
|
||||||
|
if (err == ESP_ERR_WIFI_NOT_INIT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_deinit());
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(s_example_sta_netif));
|
||||||
|
esp_netif_destroy(s_example_sta_netif);
|
||||||
|
s_example_sta_netif = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait)
|
||||||
|
{
|
||||||
|
if (wait) {
|
||||||
|
s_semph_get_ip_addrs = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_get_ip_addrs == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
s_semph_get_ip6_addrs = xSemaphoreCreateBinary();
|
||||||
|
if (s_semph_get_ip6_addrs == NULL) {
|
||||||
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
s_retry_num = 0;
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect, NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip, NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect, s_example_sta_netif));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6, NULL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
|
esp_err_t ret = esp_wifi_connect();
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "WiFi connect failed! ret:%x", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (wait) {
|
||||||
|
ESP_LOGI(TAG, "Waiting for IP(s)");
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV4
|
||||||
|
xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY);
|
||||||
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
||||||
|
s_semph_get_ip_addrs = NULL;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY);
|
||||||
|
vSemaphoreDelete(s_semph_get_ip6_addrs);
|
||||||
|
s_semph_get_ip6_addrs = NULL;
|
||||||
|
#endif
|
||||||
|
if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t example_wifi_sta_do_disconnect(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect));
|
||||||
|
#if CONFIG_EXAMPLE_CONNECT_IPV6
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6));
|
||||||
|
#endif
|
||||||
|
return esp_wifi_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void example_wifi_shutdown(void)
|
||||||
|
{
|
||||||
|
example_wifi_sta_do_disconnect();
|
||||||
|
example_wifi_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t example_wifi_connect(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Start example_connect.");
|
||||||
|
example_wifi_start();
|
||||||
|
wifi_config_t wifi_config = {
|
||||||
|
.sta = {
|
||||||
|
#if !CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
.ssid = CONFIG_EXAMPLE_WIFI_SSID,
|
||||||
|
.password = CONFIG_EXAMPLE_WIFI_PASSWORD,
|
||||||
|
#endif
|
||||||
|
.scan_method = EXAMPLE_WIFI_SCAN_METHOD,
|
||||||
|
.sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
|
||||||
|
.threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD,
|
||||||
|
.threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
#if CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN
|
||||||
|
example_configure_stdin_stdout();
|
||||||
|
char buf[sizeof(wifi_config.sta.ssid)+sizeof(wifi_config.sta.password)+2] = {0};
|
||||||
|
ESP_LOGI(TAG, "Please input ssid password:");
|
||||||
|
fgets(buf, sizeof(buf), stdin);
|
||||||
|
int len = strlen(buf);
|
||||||
|
buf[len-1] = '\0'; /* removes '\n' */
|
||||||
|
memset(wifi_config.sta.ssid, 0, sizeof(wifi_config.sta.ssid));
|
||||||
|
|
||||||
|
char *rest = NULL;
|
||||||
|
char *temp = strtok_r(buf, " ", &rest);
|
||||||
|
strncpy((char*)wifi_config.sta.ssid, temp, sizeof(wifi_config.sta.ssid));
|
||||||
|
memset(wifi_config.sta.password, 0, sizeof(wifi_config.sta.password));
|
||||||
|
temp = strtok_r(NULL, " ", &rest);
|
||||||
|
if (temp) {
|
||||||
|
strncpy((char*)wifi_config.sta.password, temp, sizeof(wifi_config.sta.password));
|
||||||
|
} else {
|
||||||
|
wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return example_wifi_sta_do_connect(wifi_config, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CONFIG_EXAMPLE_CONNECT_WIFI */
|
||||||
Binary file not shown.
4
components/serial_mcu/CMakeLists.txt
Normal file
4
components/serial_mcu/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "serial_mcu.c"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES driver esp_driver_uart
|
||||||
|
)
|
||||||
2
components/serial_mcu/include/serial_mcu.h
Normal file
2
components/serial_mcu/include/serial_mcu.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
void serial_mcu_init(void); // 初始化串口
|
||||||
|
int sendControlFrame(uint8_t cmd, uint8_t data); // 发送控制帧
|
||||||
47
components/serial_mcu/serial_mcu.c
Normal file
47
components/serial_mcu/serial_mcu.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "serial_mcu.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
// 这里是 serial_mcu.c 的实现代码
|
||||||
|
|
||||||
|
static const char *TAG = "serial_mcu";
|
||||||
|
|
||||||
|
|
||||||
|
#define TXD_PIN (GPIO_NUM_21) // TXD 引脚
|
||||||
|
#define RXD_PIN (GPIO_NUM_20) // RXD 引脚
|
||||||
|
#define UART_PORT_NUM UART_NUM_1 // 使用 UART1
|
||||||
|
|
||||||
|
static const int RX_BUF_SIZE = 1024; // 接收缓冲区大小
|
||||||
|
|
||||||
|
// 初始化串口
|
||||||
|
void serial_mcu_init(void)
|
||||||
|
{
|
||||||
|
// TODO: 初始化串口
|
||||||
|
ESP_LOGD(TAG, "Serial MCU initialized");
|
||||||
|
|
||||||
|
const uart_config_t uart_config = {
|
||||||
|
.baud_rate = 230400, // 波特率
|
||||||
|
.data_bits = UART_DATA_8_BITS, // 数据位
|
||||||
|
.parity = UART_PARITY_DISABLE, // 校验位
|
||||||
|
.stop_bits = UART_STOP_BITS_1, // 停止位
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, // 流控
|
||||||
|
.source_clk = UART_SCLK_DEFAULT, // 时钟源
|
||||||
|
};
|
||||||
|
|
||||||
|
// 配置串口
|
||||||
|
uart_driver_install(UART_PORT_NUM, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
|
||||||
|
uart_param_config(UART_PORT_NUM, &uart_config);
|
||||||
|
uart_set_pin(UART_PORT_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); // 设置引脚
|
||||||
|
// 日志
|
||||||
|
ESP_LOGI(TAG, "UART driver installed");}
|
||||||
|
|
||||||
|
int sendControlFrame(uint8_t cmd, uint8_t data)
|
||||||
|
{
|
||||||
|
uint8_t buf[3] = {0x55, cmd, data};
|
||||||
|
int txBytes = uart_write_bytes(UART_NUM_1, (const char*)buf, 3);
|
||||||
|
ESP_LOGI("TX", "Sent %d bytes CMD=0x%02X DATA=%d", txBytes, cmd, data);
|
||||||
|
return txBytes;
|
||||||
|
}
|
||||||
108
dependencies.lock
Normal file
108
dependencies.lock
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/bh1750:
|
||||||
|
component_hash: e898130f6b2fc4bc0d6022a2e431752bae808b9c94d4cc91596e36ecaf4cb7c6
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.3'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.0.0
|
||||||
|
espressif/cjson:
|
||||||
|
component_hash: 9372811fb197926f522c467627cf4a8e72b681e0366e17879631da801103aef3
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.7.19
|
||||||
|
espressif/esp_lvgl_port:
|
||||||
|
component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
- name: lvgl/lvgl
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: public
|
||||||
|
version: '>=8,<10'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.7.0
|
||||||
|
espressif/mqtt:
|
||||||
|
component_hash: ffdad5659706b4dc14bc63f8eb73ef765efa015bf7e9adf71c813d52a2dc9342
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.3'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.0
|
||||||
|
espressif/servo:
|
||||||
|
component_hash: 309c787e48224255fad458cfd9ab86ea53f0fdad1c5e4f6f0c50309990b17108
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.4'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 0.1.0
|
||||||
|
idf:
|
||||||
|
source:
|
||||||
|
type: idf
|
||||||
|
version: 5.5.2
|
||||||
|
k0i05/esp_ahtxx:
|
||||||
|
component_hash: 34ecd4cc05b54a8ee64a813f80cf2b8efea6f22ecdbf7244640fc29627416fed
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>5.3.0'
|
||||||
|
- name: k0i05/esp_type_utils
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: '>=1.0.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.2.7
|
||||||
|
k0i05/esp_type_utils:
|
||||||
|
component_hash: 95d8ec40268e045f7e264d8035f451e53844b4a2f6d5f112ece6645c5effd639
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>5.3.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.2.7
|
||||||
|
lvgl/lvgl:
|
||||||
|
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 9.4.0
|
||||||
|
protocol_examples_common:
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
path: /home/beihong/esp_projects/iot-home/components/protocol_examples_common
|
||||||
|
type: local
|
||||||
|
version: '*'
|
||||||
|
direct_dependencies:
|
||||||
|
- espressif/bh1750
|
||||||
|
- espressif/cjson
|
||||||
|
- espressif/esp_lvgl_port
|
||||||
|
- espressif/mqtt
|
||||||
|
- espressif/servo
|
||||||
|
- idf
|
||||||
|
- k0i05/esp_ahtxx
|
||||||
|
- protocol_examples_common
|
||||||
|
manifest_hash: 1bbfddd3f393c249aa2425f33f0a08f08c36fdbae7efc3287e867104a15c7d27
|
||||||
|
target: esp32c3
|
||||||
|
version: 2.0.0
|
||||||
6
main/CMakeLists.txt
Normal file
6
main/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
idf_component_register(SRCS "main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
PRIV_REQUIRES esp_wifi cjson nvs_flash lvgl_st7735s_use esp_driver_i2c esp_type_utils esp_timer espressif__servo esp_event esp_netif serial_mcu mqtt
|
||||||
|
WHOLE_ARCHIVE
|
||||||
|
)
|
||||||
|
|
||||||
31
main/idf_component.yml
Normal file
31
main/idf_component.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
## Required IDF version
|
||||||
|
idf:
|
||||||
|
version: '>=4.1.0'
|
||||||
|
# # Put list of dependencies here
|
||||||
|
# # For components maintained by Espressif:
|
||||||
|
# component: "~1.0.0"
|
||||||
|
# # For 3rd party components:
|
||||||
|
# username/component: ">=1.0.0,<2.0.0"
|
||||||
|
# username2/component2:
|
||||||
|
# version: "~1.0.0"
|
||||||
|
# # For transient dependencies `public` flag can be set.
|
||||||
|
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||||
|
# # All dependencies of `main` are public by default.
|
||||||
|
# public: true
|
||||||
|
|
||||||
|
protocol_examples_common:
|
||||||
|
path: ../components/protocol_examples_common
|
||||||
|
|
||||||
|
|
||||||
|
espressif/esp_lvgl_port: ^2.7.0
|
||||||
|
|
||||||
|
k0i05/esp_ahtxx: ^1.2.7
|
||||||
|
espressif/bh1750: ^2.0.0
|
||||||
|
espressif/servo: ^0.1.0
|
||||||
|
|
||||||
|
espressif/mqtt: ^1.0.0
|
||||||
|
espressif/cjson: ^1.7.19
|
||||||
|
|
||||||
|
|
||||||
3127
main/main.c
Normal file
3127
main/main.c
Normal file
File diff suppressed because it is too large
Load Diff
6
partitions.csv
Normal file
6
partitions.csv
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 0x200000,
|
||||||
|
wifi_spiffs, data, spiffs, 0x210000, 0x180000,
|
||||||
|
Reference in New Issue
Block a user