pressure_sensor_system/Software/master/PressureSensorBoardMaster/BSP/BLE.c

1085 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "BLE.h"
#include "flash.h"
#include "usart.h"
#include <string.h>
#include <stdint.h>
#define BLE_DBG_EN 0 // 1=开启调试输出0=关闭
#if (BLE_DBG_EN)
#define DEBUG(format, ...) printf("[BLE] " format, ##__VA_ARGS__)
#else
#define DEBUG(format, ...) // 关闭时,宏替换为空,不产生任何代码
#endif
BLE_STATE curr_state;
static size_t current_cmd_index = 0;
static uint32_t cmd_start_time;
static uint8_t current_try_count = 0;
static CmdExecutor_t init_executor;
static CmdExecutor_t first_connect_executor;
static CmdExecutor_t connect_executor;
static CmdExecutor_t trans_cfg_executor; // 用于 AT+TRANSPORT 的执行器
static CmdExecutor_t ready_executor;
static CmdExecutor_t set_executor;
static uint8_t recovery_level = 0; // 放在文件开头
static uint8_t FT_connect = 0; // 放在文件开头
static char host_mac[13];
char ble_rx_buffer[256]; // 定义接收缓冲区
volatile uint8_t ble_cmd_rec_done;
const char* ble_state_names[] = {
"BLE_INIT",
"BLE_FIRST_CONECT",
"BLE_CONNECTED",
"BLE_READY",
"BLE_CFG_TRANS",
"BLE_ERROR",
"BLE_SET",
"BLE_WAITTING"
};
const char* ble_sub_state_names[] = {
"BLE_SUB_STATE_IDLE",
"BLE_SUB_STATE_SEND_WAIT",
"BLE_SUB_STATE_PROCESS_RESP"
};
const BleAtCmd_t ble_init_sequence[] = {
{"AT\\r\\n", 100, 3, NULL, parse_general_resp},
{"AT+LADDR\\r\\n", 100, 3, NULL, parse_laddr_resp},
{NULL, 0, 0, NULL, NULL} // 结束标记
};
const BleAtCmd_t ble_first_connect_sequence[] = {
{"AT+UUID<%d>\\r\\n", 100, 3, prepare_uuid_cmd, parse_general_resp},
{"AT+RESET\\r\\n", 100, 3, NULL, parse_general_resp},
{"AT+NOTI%d\\r\\n",100, 3, prepare_noti_cmd, parse_general_resp},
{NULL, 0, 0, NULL, NULL} // 结束标记
};
const BleAtCmd_t ble_connect_sequence[] = {
// {"AT+DIRADV\\r\\n", 100, 3, NULL, parse_diradv_cmd},
{"AT+DIRADV%d,%d,%s\\r\\n", 100, 3, prepare_diradv_cmd, parse_general_resp},
{NULL, 0, 0, NULL, NULL} // 结束标记
};
const BleAtCmd_t ble_trans_cfg_sequence[] = {
{"AT+TRANSPORT%d\\r\\n", 100, 3, prepare_transport_cmd, parse_general_resp},
{NULL, 0, 0, NULL, NULL} // 结束标记
};
//software reset
const BleAtCmd_t ble_reset_sequence[] = {
{"AT+RESET\r\n", 100, 3, NULL, parse_general_resp},
{NULL, 0, 0, NULL, NULL}
};
// reset to default
const BleAtCmd_t ble_default_sequence[] = {
{"AT+DEFAULT\r\n", 100, 3, NULL, parse_general_resp},
{NULL, 0, 0, NULL, NULL}
};
// total reset sequence
const BleAtCmd_t ble_full_set_sequence[] = {
{"AT+DISC\r\n", 100, 3, NULL, NULL},
{"AT+RESET\r\n", 100, 3, NULL, parse_general_resp},
{"AT+DEFAULT\r\n", 100, 3, NULL, parse_general_resp},
{NULL, 0, 0, NULL, NULL}
};
BleErrorInfo_t g_ble_error = {0};
BleGlobalConfig_t g_ble_config = {
// 连接参数
.mac_addr = "",
.addr_type = 0,
// 广播参数
.adv_param = 0, // 改为0
.adv_type = 0, // 改为0
.target_mac = "", // 初始化为空字符串
// 通信参数
.baud_rate = 9600, // 只有这个是你想保留的非零值
.tx_power = 0,
// UUID
.service_uuid = 0, // 显式写0也可省略
// NOTI选项
.Noption = 1, // 显式写0
// TRANS选项
.Toption = 1 // 显式写0
};
// 错误码表(根据你的模块手册填充)
BleErrorCodeInfo_t g_ble_error_table[] = {
{101, "参数长度错误", RECOVERY_TARGET_RESTART_SEQ}, // 参数错,重试没用
{102, "参数格式错误", RECOVERY_TARGET_RESTART_SEQ}, // 状态错,需检查流程
{103, "参数数据异常", RECOVERY_TARGET_RESTART_SEQ}, // 可重试
{104, "指令错误", RECOVERY_TARGET_SW_RESET_MODULE}, // 可重试
};
void BLE_Init(void)
{
curr_state = BLE_INIT;
ble_cmd_rec_done = 0;
}
BLE_STATE BLE_GetState(void)
{
return curr_state;
}
void BLE_StateMachine_Handler(void)
{
switch(curr_state)
{
case BLE_INIT :
{
if(init_executor.sequence == NULL)
{
init_executor.sequence = ble_init_sequence;
init_executor.cmd_index = 0;
init_executor.retry_cnt = 0;
init_executor.state = EXEC_STATE_IDLE;
}
ExecutorResult_t res = CmdExecutor_Process(&init_executor);
if(res == EXECUTOR_DONE)
{
// 尝试读取保存在本地的数据如果没有则进入first connect
// 如果有则进入connected
if(Load_MAC_From_Flash(host_mac) == 0)
{
curr_state = BLE_CONNECTED;
}
else
{
curr_state = BLE_FIRST_CONECT;
}
memset(&init_executor, 0, sizeof(init_executor));
}
else if(res == EXECUTOR_ERROR)
{
g_ble_error.cmd_index = init_executor.cmd_index;
g_ble_error.error_code =init_executor.error_code;
g_ble_error.main_state = curr_state;
g_ble_error.timestamp = HAL_GetTick();
g_ble_error.origin_state = BLE_INIT;
curr_state = BLE_ERROR;
memset(&init_executor, 0, sizeof(init_executor));
}
}
break;
case BLE_FIRST_CONECT :
{
// 惰性初始化
if (first_connect_executor.sequence == NULL)
{
first_connect_executor.sequence = ble_first_connect_sequence;
first_connect_executor.cmd_index = 0;
first_connect_executor.retry_cnt = 0;
first_connect_executor.state = EXEC_STATE_IDLE;
}
ExecutorResult_t res = CmdExecutor_Process(&first_connect_executor);
if(res == EXECUTOR_DONE)
{
FT_connect = 1;
curr_state = BLE_WAIT_CONNECT;
}
else if(res == EXECUTOR_ERROR)
{
g_ble_error.cmd_index = first_connect_executor.cmd_index;
g_ble_error.error_code =first_connect_executor.error_code;
g_ble_error.main_state = curr_state;
g_ble_error.timestamp = HAL_GetTick();
g_ble_error.origin_state = BLE_FIRST_CONECT;
curr_state = BLE_ERROR;
memset(&first_connect_executor, 0, sizeof(first_connect_executor));
}
}
break;
case BLE_CONNECTED :
{
if (connect_executor.sequence == NULL)
{
connect_executor.sequence = ble_connect_sequence;
connect_executor.cmd_index = 0;
connect_executor.retry_cnt = 0;
connect_executor.state = EXEC_STATE_IDLE;
}
ExecutorResult_t res = CmdExecutor_Process(&connect_executor);
if(res == EXECUTOR_DONE)
{
/*
保存参数到本地
*/
curr_state = BLE_WAIT_CONNECT;
}
else if(res == EXECUTOR_ERROR)
{
g_ble_error.cmd_index = connect_executor.cmd_index;
g_ble_error.error_code =connect_executor.error_code;
g_ble_error.main_state = curr_state;
g_ble_error.timestamp = HAL_GetTick();
g_ble_error.origin_state = BLE_CONNECTED;
curr_state = BLE_ERROR;
memset(&init_executor, 0, sizeof(connect_executor));
}
}
break;
case BLE_WAIT_CONNECT:
{
if(ble_cmd_rec_done == 1)
{
parse_master_addr_resp(ble_rx_buffer);
if(FT_connect)
{
//写入本地flash
Save_MAC_To_Flash(host_mac);
}
curr_state = BLE_CFG_TRANS;
// 并设置一个标志让BLE_READY开始发送透传命令
ble_cmd_rec_done = 0;
}
}
break;
case BLE_CFG_TRANS:
{
// 惰性初始化
if (trans_cfg_executor.sequence == NULL)
{
trans_cfg_executor.sequence = ble_trans_cfg_sequence; // 该序列只包含 AT+TRANSPORT
trans_cfg_executor.cmd_index = 0;
trans_cfg_executor.retry_cnt = 0;
trans_cfg_executor.state = EXEC_STATE_IDLE;
}
ExecutorResult_t res = CmdExecutor_Process(&trans_cfg_executor);
if (res == EXECUTOR_DONE)
{
// 透传开启成功,进入 BLE_READY
curr_state = BLE_READY;
memset(&trans_cfg_executor, 0, sizeof(trans_cfg_executor)); // 清理,下次可能复用
}
else if (res == EXECUTOR_ERROR)
{
g_ble_error.cmd_index = trans_cfg_executor.cmd_index;
g_ble_error.error_code = trans_cfg_executor.error_code;
g_ble_error.main_state = curr_state;
g_ble_error.timestamp = HAL_GetTick();
g_ble_error.origin_state = BLE_CFG_TRANS;
curr_state = BLE_ERROR;
memset(&trans_cfg_executor, 0, sizeof(trans_cfg_executor));
}
// 若返回 BUSY继续等待
break;
}
case BLE_READY :
{
static uint32_t last_transmit_time = 0;
uint32_t now = HAL_GetTick();
if (now - last_transmit_time >= 300) // 定义发送间隔
{
// 发送透传数据(例如从应用层获取)
uint8_t tx_data[] = "Hello BLE!\r\n";
HAL_UART_Transmit(&huart1, tx_data, sizeof(tx_data)-1, 100);
last_transmit_time = now;
}
// 接收数据已在回调中处理,无需额外操作
break;
}
break;
case BLE_ERROR :
{
const uint8_t MAX_RECOVERY_LEVEL = 3;
recovery_level++;
if (recovery_level > MAX_RECOVERY_LEVEL) {
DEBUG("恢复尝试已达上限(%d次进入等待", MAX_RECOVERY_LEVEL);
curr_state = BLE_WAITTING;
break;
}
switch(g_ble_error.type)
{
case ERR_TYPE_NONE:
curr_state = g_ble_error.origin_state;
break;
case ERR_TYPE_PREPARE_FAILED:
{
g_ble_error.recovery_target = RECOVERY_TARGET_RECONFIG_UART;
//curr_state = BLE_WAITTING;
}
break;
case ERR_TYPE_TIMEOUT_EXCEEDED:
g_ble_error.recovery_target = RECOVERY_TARGET_RESTART_SEQ;
//curr_state = BLE_SET;
//重新配置串口信息
break;
case ERR_TYPE_PARSE_FAILED:
// DEBUG("error message ,main state:%s, sub state:%s, cmd_index:%d, timestamp:%d",
// ble_state_names[g_ble_error.main_state], ble_sub_state_names[g_ble_error.sub_state], g_ble_error.cmd_index, g_ble_error.timestamp);
g_ble_error.recovery_target = RECOVERY_TARGET_RESTART_SEQ;
//重新配置串口信息
break;
case ERR_TYPE_MODULE_ERROR:
{
uint8_t table_size = sizeof(g_ble_error_table) / sizeof(g_ble_error_table[0]);
uint8_t i;
for(i = 0; i < table_size; i++)
{
if(g_ble_error.error_code == g_ble_error_table[i].code)
{
g_ble_error.recovery_target = g_ble_error_table[i].recovery_target;
DEBUG("error message ,main state:%s, sub state:%s, cmd_index:%d, timestamp:%d",
ble_state_names[g_ble_error.main_state], ble_sub_state_names[g_ble_error.sub_state], g_ble_error.cmd_index, g_ble_error.timestamp);
//curr_state = BLE_SET;
break;
}
}
if(i == table_size)
{
g_ble_error.recovery_target = RECOVERY_TARGET_RESTART_SEQ;
}
break;
}
default:
g_ble_error.recovery_target = RECOVERY_TARGET_PANIC;
break;
}
// 3. 执行恢复动作
switch(g_ble_error.recovery_target)
{
case RECOVERY_TARGET_RESTART_SEQ:
// 重启当前流程阶段:根据 origin_state 重置对应的执行器
switch(g_ble_error.origin_state)
{
case BLE_INIT:
memset(&init_executor, 0, sizeof(init_executor));
break;
case BLE_FIRST_CONECT:
memset(&first_connect_executor, 0, sizeof(first_connect_executor));
break;
case BLE_CONNECTED:
memset(&connect_executor, 0, sizeof(connect_executor));
break;
default:
break;
}
// 返回原状态,重新开始执行序列
recovery_level = 0;
curr_state = g_ble_error.origin_state;
break;
case RECOVERY_TARGET_RECONFIG_UART:
// 重新配置 MCU 串口(调用你的串口初始化函数)
// 例如: MX_USART1_UART_Init();
// 然后重置对应执行器
switch(g_ble_error.origin_state)
{
case BLE_INIT:
memset(&init_executor, 0, sizeof(init_executor));
break;
case BLE_FIRST_CONECT:
memset(&first_connect_executor, 0, sizeof(first_connect_executor));
break;
case BLE_CONNECTED:
memset(&connect_executor, 0, sizeof(connect_executor));
break;
default:
break;
}
recovery_level = 0;
curr_state = g_ble_error.origin_state;
break;
case RECOVERY_TARGET_SW_RESET_MODULE:
case RECOVERY_TARGET_FACTORY_RESET:
// 需要通过 AT 命令执行,进入 BLE_SET 状态
// 注意origin_state 保持不变BLE_SET 执行完后会返回它
curr_state = BLE_SET;
break;
case RECOVERY_TARGET_HARD_RESET_MODULE:
// 硬件复位模块:拉低复位引脚,延时,拉高
// 假设有 BLE_RST_PIN 控制
// HAL_GPIO_WritePin(BLE_RST_GPIO_Port, BLE_RST_Pin, GPIO_PIN_RESET);
// HAL_Delay(100);
// HAL_GPIO_WritePin(BLE_RST_GPIO_Port, BLE_RST_Pin, GPIO_PIN_SET);
// 复位后重置对应执行器
switch(g_ble_error.origin_state)
{
case BLE_INIT:
memset(&init_executor, 0, sizeof(init_executor));
break;
case BLE_FIRST_CONECT:
memset(&first_connect_executor, 0, sizeof(first_connect_executor));
break;
case BLE_CONNECTED:
memset(&connect_executor, 0, sizeof(connect_executor));
break;
default:
break;
}
recovery_level = 0;
curr_state = g_ble_error.origin_state;
break;
case RECOVERY_TARGET_SOFT_RESET_MCU:
// 软件复位整个 MCU
//NVIC_SystemReset();
break;
case RECOVERY_TARGET_PANIC:
default:
// 无法恢复,进入等待状态
DEBUG("error message ,main state:%s, sub state:%s, cmd_index:%d, timestamp:%d",
ble_state_names[g_ble_error.main_state], ble_sub_state_names[g_ble_error.sub_state], g_ble_error.cmd_index, g_ble_error.timestamp);
curr_state = BLE_WAITTING;
break;
}
break;
}
case BLE_SET :
{
const BleAtCmd_t* target_seq = NULL;
switch(g_ble_error.recovery_target)
{
case RECOVERY_TARGET_SW_RESET_MODULE:
{
static const BleAtCmd_t sw_reset_sq[] = {
{"AT+RESET\r\n", 100, 3, NULL, NULL},
{NULL, 0, 0, NULL, NULL}
};
target_seq = sw_reset_sq;
}
break;
case RECOVERY_TARGET_FACTORY_RESET:
{ //回复出厂设置
{
static const BleAtCmd_t factory_reset_seq[] = {
{"AT+DEFAULT\r\n", 100, 3, NULL, NULL},
{NULL, 0, 0, NULL, NULL}
};
target_seq = factory_reset_seq;
}
break;
}
default:
//没有匹配目标则返回原状态
curr_state = g_ble_error.origin_state;
break;
}
if(target_seq != NULL)
{
// 如果 set_executor 尚未启动,则初始化
if(set_executor.sequence == NULL)
{
set_executor.sequence = target_seq;
set_executor.cmd_index = 0;
set_executor.retry_cnt = 0;
set_executor.state = EXEC_STATE_IDLE;
}
ExecutorResult_t res = CmdExecutor_Process(&set_executor);
if(res == EXECUTOR_DONE)
{
// 恢复命令执行成功,将恢复级别清零,返回原状态
// 注意:恢复级别 recovery_level 是在 BLE_ERROR 中定义的静态变量,这里无法直接访问。
// 解决方案:可以在 BLE_ERROR 中定义一个全局或外部变量,或者通过某种方式传递。
// 简单起见,我们可以在 BLE_ERROR 中重置 recovery_level但这里无法做到。
// 一个常见的做法是在 BLE_ERROR 中判断恢复成功与否,但由于这里返回原状态,我们可以在返回前设置一个标志,让 BLE_ERROR 下次进入时重置级别。
// 但考虑到恢复级别只在 BLE_ERROR 中管理,我们可以这样处理:当 BLE_SET 成功返回原状态后,原状态会继续执行,如果再次出错会重新进入 BLE_ERROR此时 recovery_level 仍然存在,但这是合理的(因为已经成功过,应该重置级别?)
// 实际上,一次恢复成功意味着系统已经正常,应该重置级别。所以我们需要在 BLE_SET 成功时通知 BLE_ERROR 重置级别。
// 由于 recovery_level 是 BLE_ERROR 内部的静态变量,无法直接从外部修改。我们可以将 recovery_level 定义为全局变量,或者通过函数接口。
// 这里为了简单,我们假设 recovery_level 是全局变量(例如在文件顶部定义),并在 BLE_SET 成功时清零。
// 请根据实际情况调整。下面假设有一个全局变量 uint8_t g_recovery_level; 并在 BLE_ERROR 中改为使用它。
// 如果没有,你可以将 recovery_level 定义在文件作用域static然后在 BLE_SET 中包含一个 extern 声明。
// 这里我们暂时注释掉,你需要根据你的设计实现。
recovery_level = 0;
memset(&set_executor, 0, sizeof(set_executor));
curr_state = g_ble_error.origin_state;
}
else if(res == EXECUTOR_ERROR)
{
// 恢复命令也失败,将 set_executor 中的错误信息复制到 g_ble_error保留 origin_state
g_ble_error.type = set_executor.error_type;
g_ble_error.error_code = set_executor.error_code;
g_ble_error.cmd_index = set_executor.error_cmd_index;
g_ble_error.timestamp = HAL_GetTick();
// 注意:不要覆盖 origin_state
memset(&set_executor, 0, sizeof(set_executor));
// 再次进入 BLE_ERROR恢复级别将在那里递增
curr_state = BLE_ERROR;
}
// 若返回 BUSY则继续等待不做状态切换
}
break;
}
break;
case BLE_WAITTING:
{
static uint32_t last_time = 0;
uint32_t time = HAL_GetTick();
uint32_t rest = time - last_time;
if(rest >= 500)
{
//输出警报
last_time = time;
}
}
break;
default:
break;
}
}
ExecutorResult_t CmdExecutor_Process(CmdExecutor_t* ex) //发送流程执行器
{
switch(ex->state)
{
case EXEC_STATE_IDLE:
{
ble_cmd_rec_done= 0;
if(ex->sequence[ex->cmd_index].cmd == NULL)
{
DEBUG("init success");
return EXECUTOR_DONE;
}
const BleAtCmd_t *current_cmd = &ex->sequence[ex->cmd_index];
char final_cmd[64];
int prepare_ok = 0; // 标记准备是否成功
if(current_cmd->prepare_cmd != NULL)
{
int prepare_result = current_cmd->prepare_cmd(current_cmd->cmd, final_cmd, sizeof(final_cmd));
if(prepare_result != 0)
{
DEBUG("命令准备失败,错误码: %d跳过此命令", prepare_result);
ex->error_type = ERR_TYPE_PREPARE_FAILED;
ex->error_code = prepare_result;
ex->error_cmd_index = ex->cmd_index;
ex->state = EXEC_STATE_ERROR;
return EXECUTOR_ERROR;
}
else
{
prepare_ok = 1;
}
}
else
{
strncpy(final_cmd, current_cmd->cmd, sizeof(final_cmd));
final_cmd[sizeof(final_cmd) - 1] = '\0';
prepare_ok = 1;
}
if(prepare_ok == 1)
{
//发送命令 待添加实际代码
ex->start_tick = HAL_GetTick();
ex->state = EXEC_STATE_SEND_WAIT;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
return EXECUTOR_BUSY;
}
case EXEC_STATE_SEND_WAIT:
{
const BleAtCmd_t *current_cmd = &ex->sequence[ex->cmd_index];
uint16_t out_time = current_cmd->timeout_ms;
uint8_t try_max = current_cmd->retry_max;
if(ble_cmd_rec_done == 1)
{
ex->retry_cnt = 0;
ex->state = EXEC_STATE_PROCESS_RESP;
return EXECUTOR_BUSY;
}
uint32_t time = HAL_GetTick();
if((time - ex->start_tick) > out_time)
{
ex->retry_cnt++;
if(ex->retry_cnt <= try_max)
{
ex->state = EXEC_STATE_IDLE;
ble_cmd_rec_done = 0; // 建议清零,避免旧数据影响下一次
return EXECUTOR_BUSY;
}
else
{
ex->error_type = ERR_TYPE_TIMEOUT_EXCEEDED;
ex->error_code = 0;
ex->error_cmd_index = ex->cmd_index;
ex->state = EXEC_STATE_ERROR;
return EXECUTOR_ERROR;
}
}
return EXECUTOR_BUSY;
}
case EXEC_STATE_PROCESS_RESP:
{
//接受串口回传具体信息
//char process_data[] = 缓存区数据
const BleAtCmd_t *current_cmd = &ex->sequence[ex->cmd_index];
int result;
if ((current_cmd->parse_resp) != NULL)
{
result = current_cmd->parse_resp(ble_rx_buffer);
}
else
{
result = parse_general_resp(ble_rx_buffer);
}
if(result == 0) //解析正确
{
ex->cmd_index++;
ex->retry_cnt = 0;
ex->state = EXEC_STATE_IDLE;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
else if(result > 0) //模块返回错误码
{
ex->retry_cnt++;
if(ex->retry_cnt <= current_cmd->retry_max)
{
ex->state = EXEC_STATE_IDLE;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
else
{
ex->error_type = ERR_TYPE_MODULE_ERROR;
ex->error_code = result;
ex->error_cmd_index = ex->cmd_index;
ex->state = EXEC_STATE_ERROR;
return EXECUTOR_ERROR;
}
}
else //result<0
{
//解析失败的其他情况
ex->retry_cnt++;
if(ex->retry_cnt <= current_cmd->retry_max)
{
ex->state = EXEC_STATE_IDLE;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
else
{
ex->error_type = ERR_TYPE_PARSE_FAILED;
ex->error_code = result;
ex->error_cmd_index = ex->cmd_index;
ex->state = EXEC_STATE_ERROR;
return EXECUTOR_ERROR;
}
}
}
break;
default:
break;
}
}
uint8_t BLE_UART_RxCallback(uint8_t *data, uint16_t len)
{
// 防止缓冲区溢出,保留一个字节给结束符
uint16_t copy_len = (len < sizeof(ble_rx_buffer)) ? len : (sizeof(ble_rx_buffer) - 1);
memcpy(ble_rx_buffer, data, copy_len);
ble_rx_buffer[copy_len] = '\0'; // 添加字符串结束符,便于字符串函数使用
// 置位接收完成标志
ble_cmd_rec_done = 1;
return 0;
}
int parse_general_resp(const char* resp)
{
if(resp == NULL)
{
return -1;
}
const char *ok_result = strstr(resp, "OK");
if(ok_result != NULL)
{
return 0;
}
int err_code = 0;
int auth = sscanf(resp, "ERROR=<%d>", &err_code);
if(auth == 1)
{
uint8_t table_size = sizeof(g_ble_error_table)/sizeof(g_ble_error_table[0]);
for(uint8_t i = 0; i<table_size; i++)
{
if(err_code == g_ble_error_table[i].code)
{
DEBUG("%s", g_ble_error_table[i].desc);
return err_code;
}
}
DEBUG("未知错误码:%d", err_code);
return err_code;
}
DEBUG("无法识别的响应: %s", resp);
return -1; // 添加默认返回值
}
int prepare_diradv_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
if(cmd_buf == NULL || buf_size <= 0)
{
return -1;
}
uint8_t para = g_ble_config.adv_param; //取出序号
uint8_t type = g_ble_config.addr_type; //取出地址类型
char* mac = g_ble_config.target_mac; //取出mac地址
int needed_len = snprintf(cmd_buf, buf_size, cmd_template, para, type, mac);
if(needed_len < 0)
{
return -1;
}
else if(needed_len >= buf_size)
{
return -2;
}
else
{
return -3;
}
}
int parse_laddr_resp(const char* resp)
{
if (resp == NULL)
{
return -1; // 无效输入
}
char mac[13]; // 用于临时存储提取的MAC地址12字符 + '\0'
// 使用sscanf提取等号后面的连续12个字符自动跳过空白符
if (sscanf(resp, "+LADDR=%12s", mac) == 1)
{
// 检查提取的字符串长度是否为12防止意外截断
if (strlen(mac) == 12)
{
// 将MAC地址复制到全局配置结构体中
strncpy(g_ble_config.mac_addr, mac, 12);
g_ble_config.mac_addr[12] = '\0'; // 确保字符串终止
return 0; // 解析成功
}
}
// 如果响应格式不匹配或长度不对,则解析失败
return -1;
}
uint8_t parse_master_addr_resp(const char* resp)
{
char *res = strstr(ble_rx_buffer, "0x");
if (res != NULL)
{
char *num_start = res + 2; // 跳过 "0x"
char mac_str[13]; // 12字符 + 结束符
int i = 0;
// 遍历直到遇到非十六进制字符或字符串结束
while (*num_start != '\0')
{
char c = *num_start;
// 判断是否十六进制字符
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f'))
{
if (i < sizeof(mac_str) - 1)
{ // 防止缓冲区溢出
mac_str[i++] = c;
}
else
{
break; // 超出缓冲区,停止
}
}
else
{
break; // 遇到非十六进制字符,停止
}
num_start++;
}
mac_str[i] = '\0'; // 添加字符串结束符
// 此时 mac_str 就是提取出的字符串
// 例如保存到全局变量
strncpy(host_mac, mac_str, 12);
host_mac[12] = '\0';
}
}
int prepare_uuid_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
if (cmd_buf == NULL || buf_size <= 0)
{
return -1; // 参数错误
}
uint16_t uuid = g_ble_config.service_uuid; // 从全局配置中取出 UUID
int needed_len = snprintf(cmd_buf, buf_size, cmd_template, uuid);
if (needed_len < 0)
{
return -1; // 格式化错误
}
else if (needed_len >= buf_size)
{
return -2; // 缓冲区不足
}
else
{
return 0; // 成功
}
}
int prepare_noti_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
if (cmd_buf == NULL || buf_size <= 0)
{
return -1; // 参数错误
}
uint8_t noti_opt = g_ble_config.Noption; // 从全局配置中取出通知选项0或1
int needed_len = snprintf(cmd_buf, buf_size, cmd_template, noti_opt);
if (needed_len < 0)
{
return -1; // 格式化错误
}
else if (needed_len >= buf_size)
{
return -2; // 缓冲区不足
}
else
{
return 0; // 成功
}
}
int prepare_transport_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
if (cmd_buf == NULL || buf_size <= 0)
{
return -1; // 参数错误
}
uint8_t transport_opt = g_ble_config.Toption; // 从全局配置中取出透传选项
int needed_len = snprintf(cmd_buf, buf_size, cmd_template, transport_opt);
if (needed_len < 0)
{
return -1; // 格式化错误
}
else if (needed_len >= buf_size)
{
return -2; // 缓冲区不足
}
else
{
return 0; // 成功
}
}