功能:集成SU-03T语音模块,完善UI代码文档

- 在CMakeLists.txt中添加SU-03T语音模块依赖。
- 在main.cpp中实现SU-03T接收回调函数,处理接收消息。
- 完善各UI源文件文档,包括动作、屏幕和字体,明确模块作用与数据流向。
- 更新主应用逻辑,初始化并启动SU-03T接收器。
- 修改过程中确保兼容性,保留原有接口。
This commit is contained in:
Wang Beihong
2026-04-22 01:06:10 +08:00
parent 65de57a49c
commit ffdb7065e3
46 changed files with 1341 additions and 12 deletions

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/JW01/JW01.c
* 角色: JW01 气体传感器串口解析与数据提取
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "JW01.h"
#include <ctype.h>
@@ -13,6 +22,10 @@ static const char *TAG = "JW01";
static bool s_inited = false;
static uint32_t s_parse_fail_count = 0;
/* 函数: jw01_parse_binary_frames
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t jw01_parse_binary_frames(const uint8_t *buf, int len, jw01_data_t *out)
{
bool found = false;
@@ -43,6 +56,10 @@ static esp_err_t jw01_parse_binary_frames(const uint8_t *buf, int len, jw01_data
return ESP_OK;
}
/* 函数: str_to_upper_inplace
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void str_to_upper_inplace(char *s)
{
while (*s != '\0') {
@@ -51,6 +68,10 @@ static void str_to_upper_inplace(char *s)
}
}
/* 函数: extract_float_by_key
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static bool extract_float_by_key(const char *line, const char *key, float *out)
{
char up_line[160];
@@ -91,6 +112,10 @@ static bool extract_float_by_key(const char *line, const char *key, float *out)
return true;
}
/* 函数: jw01_parse_line
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t jw01_parse_line(const char *line, jw01_data_t *out)
{
jw01_data_t data = {0};
@@ -115,6 +140,10 @@ static esp_err_t jw01_parse_line(const char *line, jw01_data_t *out)
return ESP_OK;
}
/* 函数: jw01_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t jw01_init(void)
{
if (s_inited) {
@@ -148,6 +177,10 @@ esp_err_t jw01_init(void)
return ESP_OK;
}
/* 函数: jw01_read
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t jw01_read(jw01_data_t *out_data, int timeout_ms)
{
ESP_RETURN_ON_FALSE(out_data != NULL, ESP_ERR_INVALID_ARG, TAG, "out_data is null");

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/JW01/include/JW01.h
* 角色: JW01 气体传感器串口解析与数据提取
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdbool.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/MQ-2/MQ-2.c
* 角色: MQ-2 模拟气体传感器采样与百分比映射
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "MQ-2.h"
#include "esp_adc/adc_oneshot.h"
@@ -11,6 +20,10 @@ static const char *TAG = "MQ2";
static adc_oneshot_unit_handle_t s_adc_handle = NULL;
static bool s_inited = false;
/* 函数: mq2_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t mq2_init(void)
{
if (s_inited) {
@@ -34,6 +47,10 @@ esp_err_t mq2_init(void)
return ESP_OK;
}
/* 函数: mq2_read_raw
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t mq2_read_raw(int *raw_out)
{
ESP_RETURN_ON_FALSE(raw_out != NULL, ESP_ERR_INVALID_ARG, TAG, "raw_out is null");
@@ -51,6 +68,10 @@ esp_err_t mq2_read_raw(int *raw_out)
return ESP_OK;
}
/* 函数: mq2_read_percent
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t mq2_read_percent(float *percent_out)
{
ESP_RETURN_ON_FALSE(percent_out != NULL, ESP_ERR_INVALID_ARG, TAG, "percent_out is null");
@@ -61,11 +82,19 @@ esp_err_t mq2_read_percent(float *percent_out)
return ESP_OK;
}
/* 函数: mq2_is_alarm
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
bool mq2_is_alarm(float percent, float threshold_percent)
{
return percent >= threshold_percent;
}
/* 函数: mq2_get_adc_handle
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
adc_oneshot_unit_handle_t mq2_get_adc_handle(void)
{
return s_adc_handle;

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/MQ-2/include/MQ-2.h
* 角色: MQ-2 模拟气体传感器采样与百分比映射
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdbool.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/bh1750/bh1750.c
* 角色: BH1750 光照传感器驱动封装
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
@@ -25,6 +34,10 @@ typedef struct {
/**
* @brief 向 BH1750 写入一个字节的辅助函数
*/
/* 函数: bh1750_write_byte
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t bh1750_write_byte(const bh1750_dev_t *const sens, const uint8_t byte)
{
return i2c_master_transmit(sens->i2c_handle, &byte, 1, pdMS_TO_TICKS(1000));
@@ -38,6 +51,10 @@ static esp_err_t bh1750_write_byte(const bh1750_dev_t *const sens, const uint8_t
* @param handle_ret [out] 返回创建好的设备句柄
* @return esp_err_t 成功返回 ESP_OK
*/
/* 函数: bh1750_create
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, bh1750_handle_t *handle_ret)
{
esp_err_t ret = ESP_OK;
@@ -65,6 +82,10 @@ esp_err_t bh1750_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr,
/**
* @brief 删除 BH1750 设备并释放资源
*/
/* 函数: bh1750_delete
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_delete(bh1750_handle_t sensor)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
@@ -78,6 +99,10 @@ esp_err_t bh1750_delete(bh1750_handle_t sensor)
/**
* @brief 进入掉电模式(低功耗)
*/
/* 函数: bh1750_power_down
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_power_down(bh1750_handle_t sensor)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
@@ -87,6 +112,10 @@ esp_err_t bh1750_power_down(bh1750_handle_t sensor)
/**
* @brief 唤醒并进入上电模式
*/
/* 函数: bh1750_power_on
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_power_on(bh1750_handle_t sensor)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
@@ -97,6 +126,10 @@ esp_err_t bh1750_power_on(bh1750_handle_t sensor)
* @brief 设置测量时间倍率 (MTreg)
* 用于改变传感器的测量灵敏度
*/
/* 函数: bh1750_set_measure_time
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_set_measure_time(bh1750_handle_t sensor, const uint8_t measure_time)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
@@ -116,6 +149,10 @@ esp_err_t bh1750_set_measure_time(bh1750_handle_t sensor, const uint8_t measure_
/**
* @brief 设置测量模式(连续测量或单词测量,以及分辨率选择)
*/
/* 函数: bh1750_set_measure_mode
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_set_measure_mode(bh1750_handle_t sensor, const bh1750_measure_mode_t cmd_measure)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
@@ -129,6 +166,10 @@ esp_err_t bh1750_set_measure_mode(bh1750_handle_t sensor, const bh1750_measure_m
* @param data [out] 返回转换后的光照强度值 (单位: Lux)
* @return esp_err_t
*/
/* 函数: bh1750_get_data
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_get_data(bh1750_handle_t sensor, float *const data)
{
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/bh1750/bh1750_use.c
* 角色: BH1750 光照传感器驱动封装
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c_master.h"
@@ -11,11 +20,19 @@ static const char *TAG = "BH1750_USE";
static i2c_master_bus_handle_t s_i2c_bus_handle = NULL;
static bh1750_handle_t s_bh1750_handle = NULL;
/* 函数: bh1750_get_i2c_bus_handle
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
i2c_master_bus_handle_t bh1750_get_i2c_bus_handle(void)
{
return s_i2c_bus_handle;
}
/* 函数: bh1750_user_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_user_init(void)
{
if (s_i2c_bus_handle == NULL) {
@@ -38,6 +55,10 @@ esp_err_t bh1750_user_init(void)
return bh1750_power_on(s_bh1750_handle);
}
/* 函数: bh1750_user_read
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t bh1750_user_read(float *lux)
{
if (s_bh1750_handle == NULL) return ESP_ERR_INVALID_STATE;
@@ -48,6 +69,10 @@ esp_err_t bh1750_user_read(float *lux)
return bh1750_get_data(s_bh1750_handle, lux);
}
/* 函数: bh1750_user_deinit
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
void bh1750_user_deinit(void)
{
if (s_bh1750_handle) {

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/bh1750/include/bh1750.h
* 角色: BH1750 光照传感器驱动封装
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/bh1750/include/bh1750_use.h
* 角色: BH1750 光照传感器驱动封装
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#ifndef BH1750_USE_H
#define BH1750_USE_H

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/fire_sensor/fire_sensor.c
* 角色: 火焰传感器 ADC 采样与危险判定
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "fire_sensor.h"
#include "MQ-2.h"
@@ -13,6 +22,10 @@ static const char *TAG = "fire_sensor";
static adc_oneshot_unit_handle_t s_adc_handle = NULL;
static bool s_inited = false;
/* 函数: fire_sensor_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t fire_sensor_init(void)
{
if (s_inited) {
@@ -35,6 +48,10 @@ esp_err_t fire_sensor_init(void)
return ESP_OK;
}
/* 函数: fire_sensor_read_raw
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t fire_sensor_read_raw(int *raw_out)
{
ESP_RETURN_ON_FALSE(raw_out != NULL, ESP_ERR_INVALID_ARG, TAG, "raw_out is null");
@@ -52,6 +69,10 @@ esp_err_t fire_sensor_read_raw(int *raw_out)
return ESP_OK;
}
/* 函数: fire_sensor_read_percent
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t fire_sensor_read_percent(float *percent_out)
{
ESP_RETURN_ON_FALSE(percent_out != NULL, ESP_ERR_INVALID_ARG, TAG, "percent_out is null");
@@ -71,6 +92,10 @@ esp_err_t fire_sensor_read_percent(float *percent_out)
return ESP_OK;
}
/* 函数: fire_sensor_is_danger
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
bool fire_sensor_is_danger(float percent, float threshold_percent)
{
return percent >= threshold_percent;

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/fire_sensor/include/fire_sensor.h
* 角色: 火焰传感器 ADC 采样与危险判定
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdbool.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/human_door/human_door.c
* 角色: 人体/门磁输入采集
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "human_door.h"
#include "driver/gpio.h"
@@ -6,6 +15,10 @@
static const char *TAG = "human_door";
static bool s_inited = false;
/* 函数: human_door_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t human_door_init(void)
{
if (s_inited) {
@@ -25,6 +38,10 @@ esp_err_t human_door_init(void)
return ESP_OK;
}
/* 函数: human_door_read
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t human_door_read(human_door_state_t *out_state)
{
ESP_RETURN_ON_FALSE(out_state != NULL, ESP_ERR_INVALID_ARG, TAG, "out_state is null");

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/human_door/include/human_door.h
* 角色: 人体/门磁输入采集
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdbool.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/lvgl_st7789_use/include/lvgl_st7789_use.h
* 角色: ST7789 屏幕与 LVGL 适配
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
// SPDX-License-Identifier: MIT
#pragma once

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/relay_ctrl/include/relay_ctrl.h
* 角色: 四路继电器状态控制
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include "esp_err.h"

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/relay_ctrl/relay_ctrl.c
* 角色: 四路继电器状态控制
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "relay_ctrl.h"
#include <stdint.h>
#include "esp_check.h"
@@ -13,11 +22,19 @@ typedef struct {
static relay_ctx_t s_ctx;
/* 函数: relay_level_from_state
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static inline int relay_level_from_state(int id, bool on)
{
return (on == s_ctx.config[id].active_high) ? 1 : 0;
}
/* 函数: relay_validate_id
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t relay_validate_id(relay_ctrl_id_t relay_id)
{
ESP_RETURN_ON_FALSE(relay_id >= RELAY_CTRL_ID_1 && relay_id < RELAY_CTRL_ID_MAX,
@@ -25,6 +42,10 @@ static esp_err_t relay_validate_id(relay_ctrl_id_t relay_id)
return ESP_OK;
}
/* 函数: relay_ctrl_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_init(const relay_config_t config[RELAY_CTRL_ID_MAX])
{
uint64_t pin_bit_mask = 0;
@@ -58,6 +79,10 @@ esp_err_t relay_ctrl_init(const relay_config_t config[RELAY_CTRL_ID_MAX])
return ESP_OK;
}
/* 函数: relay_ctrl_set
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_set(relay_ctrl_id_t relay_id, bool on)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
@@ -74,6 +99,10 @@ esp_err_t relay_ctrl_set(relay_ctrl_id_t relay_id, bool on)
return ESP_OK;
}
/* 函数: relay_ctrl_toggle
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_toggle(relay_ctrl_id_t relay_id)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
@@ -81,6 +110,10 @@ esp_err_t relay_ctrl_toggle(relay_ctrl_id_t relay_id)
return relay_ctrl_set(relay_id, !s_ctx.states[relay_id]);
}
/* 函数: relay_ctrl_get
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_get(relay_ctrl_id_t relay_id, bool *on_out)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
@@ -90,6 +123,10 @@ esp_err_t relay_ctrl_get(relay_ctrl_id_t relay_id, bool *on_out)
return ESP_OK;
}
/* 函数: relay_ctrl_set_all
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_set_all(bool relay1_on, bool relay2_on, bool relay3_on, bool relay4_on)
{
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_1, relay1_on), TAG, "set relay1 failed");

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/sntp_time/include/sntp_time.h
* 角色: SNTP 对时与时间刷新
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdint.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/sntp_time/sntp_time.c
* 角色: SNTP 对时与时间刷新
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -23,6 +32,10 @@ static TaskHandle_t s_time_refresh_task = NULL;
static time_t get_current_time(void);
/* 函数: publish_sntp_time_var
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void publish_sntp_time_var(const char *value)
{
if (set_var_sntp_time != NULL) {
@@ -30,6 +43,10 @@ static void publish_sntp_time_var(const char *value)
}
}
/* 函数: format_current_time
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void format_current_time(char *buffer, size_t buffer_size)
{
time_t now = get_current_time();
@@ -39,6 +56,10 @@ static void format_current_time(char *buffer, size_t buffer_size)
strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", &timeinfo);
}
/* 函数: sntp_time_refresh_task
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void sntp_time_refresh_task(void *arg)
{
(void)arg;
@@ -52,6 +73,10 @@ static void sntp_time_refresh_task(void *arg)
}
// =========================== 时间相关函数 ===========================
/* 函数: set_timezone
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void set_timezone(void)
{
// 设置中国标准时间(北京时间)
@@ -60,12 +85,20 @@ static void set_timezone(void)
ESP_LOGI(TAG, "时区设置为北京时间 (CST-8)");
}
/* 函数: get_current_time
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static time_t get_current_time(void)
{
// 使用POSIX函数获取时间
return time(NULL);
}
/* 函数: print_current_time
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void print_current_time(void)
{
char buffer[64];
@@ -74,6 +107,10 @@ static void print_current_time(void)
ESP_LOGI(TAG, "当前时间: %s", buffer);
}
/* 函数: start_time_refresh_task_if_needed
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t start_time_refresh_task_if_needed(void)
{
if (s_time_refresh_task != NULL) {
@@ -89,6 +126,10 @@ static esp_err_t start_time_refresh_task_if_needed(void)
return (ok == pdPASS) ? ESP_OK : ESP_ERR_NO_MEM;
}
/* 函数: configure_sntp_servers
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void configure_sntp_servers(void)
{
ESP_LOGI(TAG, "初始化SNTP服务");
@@ -105,6 +146,10 @@ static void configure_sntp_servers(void)
#endif
}
/* 函数: wait_for_time_sync
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wait_for_time_sync(uint32_t timeout_ms)
{
int64_t start_ms = esp_timer_get_time() / 1000;
@@ -123,6 +168,10 @@ static esp_err_t wait_for_time_sync(uint32_t timeout_ms)
}
}
/* 函数: sntp_timp_sync_time
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t sntp_timp_sync_time(uint32_t timeout_ms)
{
if (timeout_ms == 0) {

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "su-03t.c"
INCLUDE_DIRS "include"
REQUIRES driver)

View File

@@ -0,0 +1,113 @@
/*
* 文件: components/su-03t/include/su-03t.h
* 角色: SU-03T 语音模块串口协议适配
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
/*
* SU-03T 语音模块接口声明
*
* 说明:
* 1) 固定使用 UART2默认引脚 RX=IO41 / TX=IO42波特率 115200。
* 2) 提供固定帧协议封装与原始十六进制发送两种方式。
* 3) 提供同步收帧与后台异步回调,便于语音事件实时上报。
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SU03T_UART_PORT UART_NUM_2
#define SU03T_UART_BAUD 115200
#define SU03T_UART_TX_IO GPIO_NUM_42
#define SU03T_UART_RX_IO GPIO_NUM_41
#define SU03T_DEFAULT_HEAD_H 0xAA
#define SU03T_DEFAULT_HEAD_L 0x55
#define SU03T_DEFAULT_TAIL_H 0x55
#define SU03T_DEFAULT_TAIL_L 0xAA
#define SU03T_MAX_PARAM_LEN 256
typedef struct {
uint8_t head_h;
uint8_t head_l;
uint8_t tail_h;
uint8_t tail_l;
} su03t_frame_format_t;
typedef struct {
uint8_t msgno;
uint8_t params[SU03T_MAX_PARAM_LEN];
size_t params_len;
} su03t_frame_t;
/* 异步接收回调: 每收到一帧完整数据触发一次。 */
typedef void (*su03t_rx_callback_t)(const su03t_frame_t *frame, void *user_ctx);
/**
* @brief 初始化 SU-03T 串口驱动
* @return ESP_OK 成功;其它为驱动安装或串口配置错误
*/
esp_err_t su03t_init(void);
/**
* @brief 配置帧头帧尾(默认 AA55 ... 55AA
*/
esp_err_t su03t_set_frame_format(const su03t_frame_format_t *fmt);
/**
* @brief 获取当前帧格式配置
*/
esp_err_t su03t_get_frame_format(su03t_frame_format_t *fmt_out);
/**
* @brief 发送固定格式消息
* @param msgno 消息编号1字节
* @param params 参数区首地址,可为 NULL当 params_len 为 0
* @param params_len 参数区长度
*/
esp_err_t su03t_send_frame(uint8_t msgno, const uint8_t *params, size_t params_len);
/**
* @brief 发送十六进制字符串(支持空格分隔)
* @param hex_string 十六进制文本,例如 "AA 55 01 11 22 55 AA"
*/
esp_err_t su03t_send_hex_string(const char *hex_string);
/**
* @brief 同步接收并解析一帧消息
* @param out_frame 输出帧
* @param timeout_ms 超时时间(毫秒)
*/
esp_err_t su03t_recv_frame(su03t_frame_t *out_frame, uint32_t timeout_ms);
/**
* @brief 启动后台接收任务,持续解析并回调
* @param callback 收到完整帧时的回调函数
* @param user_ctx 回调透传上下文指针
* @param task_stack_size 接收任务栈大小,传 0 使用默认值
* @param task_priority 接收任务优先级,传 0 使用默认值
*/
esp_err_t su03t_start_receiver(su03t_rx_callback_t callback, void *user_ctx, uint32_t task_stack_size, UBaseType_t task_priority);
/**
* @brief 停止后台接收任务
*/
esp_err_t su03t_stop_receiver(void);
#ifdef __cplusplus
}
#endif

397
components/su-03t/su-03t.c Normal file
View File

@@ -0,0 +1,397 @@
/*
* 文件: components/su-03t/su-03t.c
* 角色: SU-03T 语音模块串口协议适配
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
/*
* SU-03T 语音模块串口适配层
*
* 设计目标:
* 1) 提供统一的 UART2 初始化接口RX=IO41, TX=IO42, 115200
* 2) 支持两类发送方式:
* - 结构化帧发送: 头(2) + msgno(1) + params(N) + 尾(2)
* - 原始十六进制串发送: 方便调试工具或协议快速验证。
* 3) 支持同步收帧与后台异步收帧回调,满足“主控主动发、模块随时上报”的场景。
*/
#include <ctype.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "su-03t.h"
static const char *TAG = "su03t";
static bool s_inited = false;
static TaskHandle_t s_rx_task = NULL;
static volatile bool s_rx_running = false;
static su03t_rx_callback_t s_rx_callback = NULL;
static void *s_rx_user_ctx = NULL;
static su03t_frame_format_t s_fmt = {
.head_h = SU03T_DEFAULT_HEAD_H,
.head_l = SU03T_DEFAULT_HEAD_L,
.tail_h = SU03T_DEFAULT_TAIL_H,
.tail_l = SU03T_DEFAULT_TAIL_L,
};
/*
* 将单个十六进制字符转换为 4bit 数值。
* 返回值:
* - 0~15: 有效十六进制字符
* - -1 : 非法字符
*/
/* 函数: hex_to_nibble
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static int hex_to_nibble(char c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
return -1;
}
/*
* SU-03T 后台接收任务。
* 逻辑:
* 1) 循环调用 su03t_recv_frame() 解析帧。
* 2) 解析成功后,回调上层业务。
* 3) 超时属于正常空闲,不打印告警;仅对非超时错误告警。
*/
/* 函数: su03t_rx_task
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void su03t_rx_task(void *arg)
{
(void)arg;
su03t_frame_t frame;
while (s_rx_running) {
esp_err_t ret = su03t_recv_frame(&frame, 200);
if (ret == ESP_OK) {
if (s_rx_callback != NULL) {
s_rx_callback(&frame, s_rx_user_ctx);
}
} else if (ret != ESP_ERR_TIMEOUT) {
ESP_LOGW(TAG, "recv frame failed: %s", esp_err_to_name(ret));
}
}
s_rx_task = NULL;
vTaskDelete(NULL);
}
/*
* 初始化 UART2 驱动并配置 SU-03T 引脚。
* 注意: 若驱动已安装uart_driver_install 可能返回 ESP_ERR_INVALID_STATE
* 这里将其视为“可继续配置”的情况。
*/
/* 函数: su03t_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_init(void)
{
const uart_config_t uart_cfg = {
.baud_rate = SU03T_UART_BAUD,
.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,
};
esp_err_t ret = uart_driver_install(SU03T_UART_PORT, 1024, 1024, 0, NULL, 0);
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
return ret;
}
ret = uart_param_config(SU03T_UART_PORT, &uart_cfg);
if (ret != ESP_OK) {
return ret;
}
ret = uart_set_pin(SU03T_UART_PORT, SU03T_UART_TX_IO, SU03T_UART_RX_IO,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
if (ret != ESP_OK) {
return ret;
}
s_inited = true;
ESP_LOGI(TAG, "init UART2 done, TX=%d RX=%d baud=%d",
SU03T_UART_TX_IO, SU03T_UART_RX_IO, SU03T_UART_BAUD);
return ESP_OK;
}
/* 设置当前帧头帧尾格式,后续发送与解析都按该格式执行。 */
/* 函数: su03t_set_frame_format
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_set_frame_format(const su03t_frame_format_t *fmt)
{
if (fmt == NULL) {
return ESP_ERR_INVALID_ARG;
}
s_fmt = *fmt;
return ESP_OK;
}
/* 获取当前帧格式,便于业务层调试或回显配置。 */
/* 函数: su03t_get_frame_format
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_get_frame_format(su03t_frame_format_t *fmt_out)
{
if (fmt_out == NULL) {
return ESP_ERR_INVALID_ARG;
}
*fmt_out = s_fmt;
return ESP_OK;
}
/*
* 按协议帧格式发送:
* [head_h head_l msgno params... tail_h tail_l]
*/
/* 函数: su03t_send_frame
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_send_frame(uint8_t msgno, const uint8_t *params, size_t params_len)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (params_len > SU03T_MAX_PARAM_LEN) {
return ESP_ERR_INVALID_SIZE;
}
if (params_len > 0 && params == NULL) {
return ESP_ERR_INVALID_ARG;
}
uint8_t tx_buf[2 + 1 + SU03T_MAX_PARAM_LEN + 2];
size_t idx = 0;
tx_buf[idx++] = s_fmt.head_h;
tx_buf[idx++] = s_fmt.head_l;
tx_buf[idx++] = msgno;
if (params_len > 0) {
memcpy(&tx_buf[idx], params, params_len);
idx += params_len;
}
tx_buf[idx++] = s_fmt.tail_h;
tx_buf[idx++] = s_fmt.tail_l;
int written = uart_write_bytes(SU03T_UART_PORT, (const char *)tx_buf, idx);
if (written < 0 || (size_t)written != idx) {
return ESP_FAIL;
}
return uart_wait_tx_done(SU03T_UART_PORT, pdMS_TO_TICKS(100));
}
/*
* 发送十六进制字符串。
* 输入示例: "AA 55 01 11 22 55 AA"
* 规则:
* 1) 允许空白字符。
* 2) 必须是偶数个十六进制字符。
* 3) 遇到非法字符直接返回参数错误。
*/
/* 函数: su03t_send_hex_string
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_send_hex_string(const char *hex_string)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (hex_string == NULL) {
return ESP_ERR_INVALID_ARG;
}
uint8_t tx_buf[2 + 1 + SU03T_MAX_PARAM_LEN + 2];
size_t out_len = 0;
int high = -1;
for (const char *p = hex_string; *p != '\0'; ++p) {
if (isspace((unsigned char)*p)) {
continue;
}
int n = hex_to_nibble(*p);
if (n < 0) {
return ESP_ERR_INVALID_ARG;
}
if (high < 0) {
high = n;
} else {
if (out_len >= sizeof(tx_buf)) {
return ESP_ERR_INVALID_SIZE;
}
tx_buf[out_len++] = (uint8_t)((high << 4) | n);
high = -1;
}
}
if (high >= 0) {
return ESP_ERR_INVALID_ARG;
}
if (out_len == 0) {
return ESP_ERR_INVALID_ARG;
}
int written = uart_write_bytes(SU03T_UART_PORT, (const char *)tx_buf, out_len);
if (written < 0 || (size_t)written != out_len) {
return ESP_FAIL;
}
return uart_wait_tx_done(SU03T_UART_PORT, pdMS_TO_TICKS(100));
}
/*
* 在超时时间内解析一帧。
* 协议格式:
* head_h head_l msgno param... tail_h tail_l
* 返回:
* - ESP_OK: 成功拿到完整帧
* - ESP_ERR_TIMEOUT: 超时未收到完整帧
* - 其它: 参数或协议错误
*/
/* 函数: su03t_recv_frame
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_recv_frame(su03t_frame_t *out_frame, uint32_t timeout_ms)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (out_frame == NULL) {
return ESP_ERR_INVALID_ARG;
}
memset(out_frame, 0, sizeof(*out_frame));
const TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);
const TickType_t start_tick = xTaskGetTickCount();
uint8_t byte = 0;
uint8_t payload[1 + SU03T_MAX_PARAM_LEN];
size_t payload_len = 0;
bool head_found = false;
while ((xTaskGetTickCount() - start_tick) < timeout_ticks) {
int n = uart_read_bytes(SU03T_UART_PORT, &byte, 1, pdMS_TO_TICKS(20));
if (n <= 0) {
continue;
}
if (!head_found) {
if (byte == s_fmt.head_h) {
int n2 = uart_read_bytes(SU03T_UART_PORT, &byte, 1, pdMS_TO_TICKS(20));
if (n2 > 0 && byte == s_fmt.head_l) {
head_found = true;
payload_len = 0;
}
}
continue;
}
if (payload_len >= sizeof(payload)) {
head_found = false;
payload_len = 0;
continue;
}
payload[payload_len++] = byte;
if (payload_len >= 3 &&
payload[payload_len - 2] == s_fmt.tail_h &&
payload[payload_len - 1] == s_fmt.tail_l) {
size_t body_len = payload_len - 2;
if (body_len < 1) {
return ESP_ERR_INVALID_RESPONSE;
}
out_frame->msgno = payload[0];
out_frame->params_len = body_len - 1;
if (out_frame->params_len > 0) {
memcpy(out_frame->params, &payload[1], out_frame->params_len);
}
return ESP_OK;
}
}
return ESP_ERR_TIMEOUT;
}
/*
* 启动异步接收:
* - callback: 每收到一帧就回调一次
* - task_stack_size/task_priority: 允许上层按系统负载调优
*/
/* 函数: su03t_start_receiver
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_start_receiver(su03t_rx_callback_t callback, void *user_ctx, uint32_t task_stack_size, UBaseType_t task_priority)
{
if (!s_inited) {
return ESP_ERR_INVALID_STATE;
}
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (s_rx_task != NULL) {
return ESP_ERR_INVALID_STATE;
}
if (task_stack_size == 0) {
task_stack_size = 4096;
}
if (task_priority == 0) {
task_priority = 5;
}
s_rx_callback = callback;
s_rx_user_ctx = user_ctx;
s_rx_running = true;
BaseType_t ok = xTaskCreate(su03t_rx_task, "su03t_rx", task_stack_size, NULL, task_priority, &s_rx_task);
if (ok != pdPASS) {
s_rx_running = false;
s_rx_callback = NULL;
s_rx_user_ctx = NULL;
return ESP_ERR_NO_MEM;
}
return ESP_OK;
}
/*
* 停止异步接收。
* 该实现通过标志位让接收任务自行退出,避免跨任务强制删除导致资源状态不一致。
*/
/* 函数: su03t_stop_receiver
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t su03t_stop_receiver(void)
{
if (s_rx_task == NULL) {
return ESP_OK;
}
s_rx_running = false;
return ESP_OK;
}

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/wifi-connect/include/wifi-connect.h
* 角色: Wi-Fi 连接、配网与网络状态管理
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#pragma once
#include <stdbool.h>

View File

@@ -1,3 +1,12 @@
/*
* 文件: components/wifi-connect/wifi-connect.c
* 角色: Wi-Fi 连接、配网与网络状态管理
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -36,6 +45,10 @@
static const char *TAG = "wifi_connect";
/* 函数: wifi_connect_log_state_i
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_log_state_i(const char *state, const char *detail)
{
if (detail != NULL && detail[0] != '\0')
@@ -44,6 +57,10 @@ static void wifi_connect_log_state_i(const char *state, const char *detail)
ESP_LOGI(TAG, "【状态】%s", state);
}
/* 函数: wifi_connect_log_state_w
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_log_state_w(const char *state, const char *detail)
{
if (detail != NULL && detail[0] != '\0')
@@ -52,6 +69,10 @@ static void wifi_connect_log_state_w(const char *state, const char *detail)
ESP_LOGW(TAG, "【状态】%s", state);
}
/* 函数: wifi_connect_log_state_e
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_log_state_e(const char *state, const char *detail)
{
if (detail != NULL && detail[0] != '\0')
@@ -192,11 +213,19 @@ static const char *s_html_page =
"setInterval(()=>{if(isConnected)fetchInfo();},3000);"
"</script></body></html>";
/* 函数: wifi_connect_set_status_locked
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_set_status_locked(wifi_connect_status_t status)
{
s_ctx.status = status;
}
/* 函数: wifi_connect_set_error_locked
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_set_error_locked(const char *message)
{
if (message == NULL)
@@ -207,6 +236,10 @@ static void wifi_connect_set_error_locked(const char *message)
snprintf(s_ctx.last_error, sizeof(s_ctx.last_error), "%s", message);
}
/* 函数: wifi_connect_save_credentials
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_save_credentials(const char *ssid, const char *password)
{
nvs_handle_t handle;
@@ -220,6 +253,10 @@ static esp_err_t wifi_connect_save_credentials(const char *ssid, const char *pas
return err;
}
/* 函数: wifi_connect_clear_config
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t wifi_connect_clear_config(void)
{
nvs_handle_t handle;
@@ -270,6 +307,10 @@ esp_err_t wifi_connect_clear_config(void)
return ESP_OK;
}
/* 函数: wifi_connect_get_config
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t wifi_connect_get_config(wifi_connect_config_t *config)
{
ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TAG, "config is null");
@@ -290,6 +331,10 @@ esp_err_t wifi_connect_get_config(wifi_connect_config_t *config)
return err;
}
/* 函数: wifi_connect_status_to_string
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static const char *wifi_connect_status_to_string(wifi_connect_status_t status)
{
switch (status)
@@ -311,6 +356,10 @@ static const char *wifi_connect_status_to_string(wifi_connect_status_t status)
}
}
/* 函数: wifi_connect_get_status
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
wifi_connect_status_t wifi_connect_get_status(void)
{
if (!s_ctx.initialized || s_ctx.lock == NULL)
@@ -323,6 +372,10 @@ wifi_connect_status_t wifi_connect_get_status(void)
return status;
}
/* 函数: wifi_connect_get_ip
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
const char *wifi_connect_get_ip(void)
{
if (!s_ctx.initialized || s_ctx.lock == NULL)
@@ -335,12 +388,20 @@ const char *wifi_connect_get_ip(void)
return ip_buf;
}
/* 函数: wifi_connect_send_json
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_send_json(httpd_req_t *req, const char *json)
{
httpd_resp_set_type(req, "application/json");
return httpd_resp_sendstr(req, json);
}
/* 函数: wifi_connect_json_escape
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_json_escape(const char *src, char *dst, size_t dst_size)
{
size_t j = 0;
@@ -358,6 +419,10 @@ static void wifi_connect_json_escape(const char *src, char *dst, size_t dst_size
dst[j] = '\0';
}
/* 函数: wifi_connect_auth_to_string
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static const char *wifi_connect_auth_to_string(wifi_auth_mode_t auth)
{
switch (auth)
@@ -383,6 +448,10 @@ static const char *wifi_connect_auth_to_string(wifi_auth_mode_t auth)
}
}
/* 函数: wifi_connect_http_scan_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_scan_handler(httpd_req_t *req)
{
wifi_scan_config_t scan_cfg = {.show_hidden = false};
@@ -430,6 +499,10 @@ static esp_err_t wifi_connect_http_scan_handler(httpd_req_t *req)
return err;
}
/* 函数: wifi_connect_extract_json_string
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static bool wifi_connect_extract_json_string(const char *json, const char *key, char *out, size_t out_len)
{
char pattern[32];
@@ -449,6 +522,10 @@ static bool wifi_connect_extract_json_string(const char *json, const char *key,
return idx > 0 || strcmp(key, "password") == 0;
}
/* 函数: wifi_connect_apply_sta_credentials
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_apply_sta_credentials(const char *ssid, const char *password)
{
wifi_config_t sta_cfg = {0};
@@ -468,6 +545,10 @@ static esp_err_t wifi_connect_apply_sta_credentials(const char *ssid, const char
return ESP_OK;
}
/* 函数: wifi_connect_http_connect_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_connect_handler(httpd_req_t *req)
{
if (req->content_len <= 0 || req->content_len >= WIFI_CONNECT_HTTP_BUF_SIZE)
@@ -513,6 +594,10 @@ static esp_err_t wifi_connect_http_connect_handler(httpd_req_t *req)
return wifi_connect_send_json(req, "{\"ok\":true}");
}
/* 函数: wifi_connect_http_status_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_status_handler(httpd_req_t *req)
{
wifi_connect_status_t status;
@@ -531,6 +616,10 @@ static esp_err_t wifi_connect_http_status_handler(httpd_req_t *req)
return wifi_connect_send_json(req, payload);
}
/* 函数: wifi_connect_http_clear_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_clear_handler(httpd_req_t *req)
{
esp_err_t err = wifi_connect_clear_config();
@@ -539,6 +628,10 @@ static esp_err_t wifi_connect_http_clear_handler(httpd_req_t *req)
return wifi_connect_send_json(req, "{\"ok\":true}");
}
/* 函数: wifi_connect_http_sysinfo_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_sysinfo_handler(httpd_req_t *req)
{
char payload[128];
@@ -546,6 +639,10 @@ static esp_err_t wifi_connect_http_sysinfo_handler(httpd_req_t *req)
return wifi_connect_send_json(req, payload);
}
/* 函数: wifi_connect_http_index_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_index_handler(httpd_req_t *req)
{
httpd_resp_set_hdr(req, "Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
@@ -554,6 +651,10 @@ static esp_err_t wifi_connect_http_index_handler(httpd_req_t *req)
return httpd_resp_send(req, s_html_page, HTTPD_RESP_USE_STRLEN);
}
/* 函数: wifi_connect_get_ap_http_url
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_get_ap_http_url(char *out, size_t out_len)
{
esp_netif_ip_info_t ip_info = {0};
@@ -567,6 +668,10 @@ static void wifi_connect_get_ap_http_url(char *out, size_t out_len)
snprintf(out, out_len, "http://192.168.4.1/");
}
/* 函数: wifi_connect_http_probe_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_probe_handler(httpd_req_t *req)
{
char location[48] = {0};
@@ -580,6 +685,10 @@ static esp_err_t wifi_connect_http_probe_handler(httpd_req_t *req)
static esp_err_t wifi_connect_http_start(void);
static void wifi_connect_http_stop(void);
/* 函数: wifi_connect_http_start
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_http_start(void)
{
if (s_ctx.http_server != NULL)
@@ -622,6 +731,10 @@ static esp_err_t wifi_connect_http_start(void)
return ESP_OK;
}
/* 函数: wifi_connect_http_stop
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_http_stop(void)
{
if (s_ctx.http_server != NULL)
@@ -631,6 +744,10 @@ static void wifi_connect_http_stop(void)
}
}
/* 函数: wifi_connect_build_dns_response
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static size_t wifi_connect_build_dns_response(const uint8_t *req, size_t req_len, uint8_t *resp, size_t resp_max, uint32_t ip_addr)
{
if (req_len < 12 || resp_max < 64)
@@ -683,6 +800,10 @@ static size_t wifi_connect_build_dns_response(const uint8_t *req, size_t req_len
return pos;
}
/* 函数: wifi_connect_dns_task
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_dns_task(void *arg)
{
uint8_t rx_buf[256], tx_buf[512];
@@ -728,6 +849,10 @@ static void wifi_connect_dns_task(void *arg)
vTaskDelete(NULL);
}
/* 函数: wifi_connect_dns_start
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_dns_start(void)
{
if (s_ctx.dns_running)
@@ -741,6 +866,10 @@ static esp_err_t wifi_connect_dns_start(void)
return ESP_OK;
}
/* 函数: wifi_connect_dns_stop
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_dns_stop(void)
{
if (!s_ctx.dns_running)
@@ -751,6 +880,10 @@ static void wifi_connect_dns_stop(void)
s_ctx.dns_task = NULL;
}
/* 函数: wifi_connect_connect_timeout_cb
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_connect_timeout_cb(void *arg)
{
xSemaphoreTake(s_ctx.lock, portMAX_DELAY);
@@ -775,6 +908,10 @@ static void wifi_connect_connect_timeout_cb(void *arg)
xSemaphoreGive(s_ctx.lock);
}
/* 函数: wifi_connect_ap_stop_timer_cb
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_ap_stop_timer_cb(void *arg)
{
xSemaphoreTake(s_ctx.lock, portMAX_DELAY);
@@ -788,6 +925,10 @@ static void wifi_connect_ap_stop_timer_cb(void *arg)
xSemaphoreGive(s_ctx.lock);
}
/* 函数: wifi_connect_event_handler
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
@@ -849,6 +990,10 @@ static void wifi_connect_event_handler(void *arg, esp_event_base_t event_base, i
}
}
/* 函数: wifi_connect_generate_ap_ssid
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static void wifi_connect_generate_ap_ssid(char *out, size_t out_len)
{
uint8_t mac[6] = {0};
@@ -857,6 +1002,10 @@ static void wifi_connect_generate_ap_ssid(char *out, size_t out_len)
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
/* 函数: wifi_connect_start_apsta_locked
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_start_apsta_locked(void)
{
wifi_config_t ap_cfg = {0};
@@ -879,6 +1028,10 @@ static esp_err_t wifi_connect_start_apsta_locked(void)
return ESP_OK;
}
/* 函数: wifi_connect_start
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t wifi_connect_start(void)
{
ESP_RETURN_ON_FALSE(s_ctx.initialized, ESP_ERR_INVALID_STATE, TAG, "not initialized");
@@ -909,6 +1062,10 @@ esp_err_t wifi_connect_start(void)
return ESP_OK;
}
/* 函数: wifi_connect_stop
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t wifi_connect_stop(void)
{
if (!s_ctx.initialized)
@@ -941,6 +1098,10 @@ esp_err_t wifi_connect_stop(void)
return ESP_OK;
}
/* 函数: wifi_connect_try_auto_connect
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t wifi_connect_try_auto_connect(void)
{
wifi_connect_config_t config = {0};
@@ -980,6 +1141,10 @@ static esp_err_t wifi_connect_try_auto_connect(void)
return ESP_OK;
}
/* 函数: wifi_connect_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t wifi_connect_init(void)
{
if (s_ctx.initialized)