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

818 lines
21 KiB
C
Raw Normal View History

2026-02-24 13:00:08 +08:00
#include "BLE.h"
#include <string.h>
#include <stdint.h>
#define BLE_DBG_EN 0 // 1=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0=<3D>ر<EFBFBD>
#if (BLE_DBG_EN)
#define DEBUG(format, ...) printf("[BLE] " format, ##__VA_ARGS__)
#else
#define DEBUG(format, ...) // <20>ر<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>滻Ϊ<E6BBBB>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κδ<CEBA><CEB4><EFBFBD>
#endif
char ble_rx_buffer[256];
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 set_executor;
const char* ble_state_names[] = {
"BLE_INIT",
"BLE_FIRST_CONECT",
"BLE_CONNECTED",
"BLE_READY",
"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"
};
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)
{
/*
<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>first connect
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>connected
*/
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 :
{
ExecutorResult_t res = CmdExecutor_Process(&first_connect_executor);
if(res == EXECUTOR_DONE)
{
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
curr_state = BLE_CONNECTED;
}
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_FIRST_CONECT;
curr_state = BLE_ERROR;
memset(&init_executor, 0, sizeof(first_connect_executor));
}
}
break;
case BLE_CONNECTED :
{
ExecutorResult_t res = CmdExecutor_Process(&connect_executor);
if(res == EXECUTOR_DONE)
{
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
curr_state = BLE_READY;
}
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_CONNECTED;
curr_state = BLE_ERROR;
memset(&init_executor, 0, sizeof(connect_executor));
}
}
break;
case BLE_READY :
{
/*
<EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>򷵻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>error
*/
}
break;
case BLE_ERROR :
2026-02-24 17:01:12 +08:00
{
static uint8_t recovery_level = 0;
const uint8_t MAX_RECOVERY_LEVEL = 3;
2026-02-24 13:00:08 +08:00
switch(g_ble_error.type)
{
case ERR_TYPE_NONE:
2026-02-24 17:01:12 +08:00
curr_state = g_ble_error.origin_state;
2026-02-24 13:00:08 +08:00
break;
case ERR_TYPE_PREPARE_FAILED:
{
2026-02-24 17:01:12 +08:00
g_ble_error.recovery_target = RECOVERY_TARGET_RECONFIG_UART;
//curr_state = BLE_WAITTING;
2026-02-24 13:00:08 +08:00
}
break;
case ERR_TYPE_TIMEOUT_EXCEEDED:
{
2026-02-24 17:01:12 +08:00
g_ble_error.recovery_target = RECOVERY_TARGET_RESTART_SEQ;
//curr_state = BLE_SET;
2026-02-24 13:00:08 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
break;
case ERR_TYPE_PARSE_FAILED:
{
2026-02-24 17:01:12 +08:00
// 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;
2026-02-24 13:00:08 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
break;
case ERR_TYPE_MODULE_ERROR:
2026-02-24 17:01:12 +08:00
{
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++)
2026-02-24 13:00:08 +08:00
{
if(g_ble_error.error_code == g_ble_error_table[i].code)
{
2026-02-24 17:01:12 +08:00
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;
}
if(i == table_size)
{
g_ble_error.recovery_target = RECOVERY_TARGET_RESTART_SEQ;
2026-02-24 13:00:08 +08:00
}
}
}
break;
default:
2026-02-24 17:01:12 +08:00
g_ble_error.recovery_target = RECOVERY_TARGET_PANIC;
2026-02-24 13:00:08 +08:00
break;
}
2026-02-24 17:01:12 +08:00
if(g_ble_error.recovery_target >= RECOVERY_TARGET_SW_RESET_MODULE)
{
recovery_level++;
if(recovery_level > MAX_RECOVERY_LEVEL)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>
DEBUG("<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>", recovery_level);
curr_state = BLE_WAITTING;
break; // <20><><EFBFBD><EFBFBD> BLE_ERROR
}
2026-02-24 13:00:08 +08:00
2026-02-24 17:01:12 +08:00
}
// 3. ִ<>лָ<D0BB><D6B8><EFBFBD><EFBFBD><EFBFBD>
switch(g_ble_error.recovery_target)
{
case RECOVERY_TARGET_RESTART_SEQ:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>̽׶Σ<D7B6><CEA3><EFBFBD><EFBFBD><EFBFBD> origin_state <20><><EFBFBD>ö<EFBFBD>Ӧ<EFBFBD><D3A6>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD>
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;
}
// <20><><EFBFBD><EFBFBD>ԭ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD>ʼִ<CABC><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curr_state = g_ble_error.origin_state;
break;
case RECOVERY_TARGET_RECONFIG_UART:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MCU <20><><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>ڳ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD>磺 MX_USART1_UART_Init();
// Ȼ<><C8BB><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>Ӧִ<D3A6><D6B4><EFBFBD><EFBFBD>
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;
}
curr_state = g_ble_error.origin_state;
break;
// case RECOVERY_TARGET_SW_RESET_MODULE:
case RECOVERY_TARGET_FACTORY_RESET:
// <20><>Ҫͨ<D2AA><CDA8> AT <20><><EFBFBD><EFBFBD>ִ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD> BLE_SET ״̬
// ע<>⣺origin_state <20><><EFBFBD>ֲ<EFBFBD><D6B2>䣬BLE_SET ִ<><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B7B5><EFBFBD><EFBFBD>
curr_state = BLE_SET;
break;
case RECOVERY_TARGET_HARD_RESET_MODULE:
// Ӳ<><D3B2><EFBFBD><EFBFBD>λģ<CEBB><EFBFBD><E9A3BA><EFBFBD>͸<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BLE_RST_PIN <20><><EFBFBD><EFBFBD>
// 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);
// <20><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>Ӧִ<D3A6><D6B4><EFBFBD><EFBFBD>
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;
}
curr_state = g_ble_error.origin_state;
break;
case RECOVERY_TARGET_SOFT_RESET_MCU:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD> MCU
//NVIC_SystemReset();
break;
case RECOVERY_TARGET_PANIC:
default:
// <20>޷<EFBFBD><DEB7>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>״̬
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;
}
}
2026-02-24 13:00:08 +08:00
break;
case BLE_SET :
{
2026-02-24 17:01:12 +08:00
const BleAtCmd_t* target_seq = NULL;
switch(g_ble_error.recovery_target)
2026-02-24 13:00:08 +08:00
{
2026-02-24 17:01:12 +08:00
case RECOVERY_TARGET_SW_RESET_MODULE:
{
static const BleAtCmd_t sw_reset_sq[] = {
{"AT+RESET\r\n", "OK", 100, 3, NULL, NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};
target_seq = sw_reset_sq;
}
break;
case RECOVERY_TARGET_FACTORY_RESET:
//<2F>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
static const BleAtCmd_t factory_reset_seq[] = {
{"AT+DEFAULT\r\n", "OK", 100, 3, NULL, NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};
target_seq = factory_reset_seq;
}
break;
default:
//û<><C3BB>ƥ<EFBFBD><C6A5>Ŀ<EFBFBD><C4BF><EFBFBD>򷵻<EFBFBD>ԭ״̬
curr_state = g_ble_error.origin_state;
break;
}
if(target_seq != NULL)
{
// <20><><EFBFBD><EFBFBD> set_executor <20><>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
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)
{
// <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>гɹ<D0B3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD>ԭ״̬
// ע<><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD> recovery_level <20><><EFBFBD><EFBFBD> BLE_ERROR <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ľ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7>ʡ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BLE_ERROR <20>ж<EFBFBD><D0B6><EFBFBD>һ<EFBFBD><D2BB>ȫ<EFBFBD>ֻ<EFBFBD><D6BB>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>ij<EFBFBD>ַ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ݡ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD> BLE_ERROR <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> recovery_level<65><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BLE_ERROR <20><><EFBFBD>жϻָ<CFBB><D6B8>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>񣬵<EFBFBD><F1A3ACB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFB7B5>ԭ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD> BLE_ERROR <20>´ν<C2B4><CEBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB> BLE_ERROR <20>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BLE_SET <20>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>ԭ״̬<D7B4><CCAC><EFBFBD><EFBFBD>ԭ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴγ<D9B4><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD> BLE_ERROR<4F><52><EFBFBD><EFBFBD>ʱ recovery_level <20><>Ȼ<EFBFBD><C8BB><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>Ϊ<EFBFBD>Ѿ<EFBFBD><D1BE>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC>𣿣<EFBFBD>
// ʵ<><CAB5><EFBFBD>ϣ<EFBFBD>һ<EFBFBD>λָ<CEBB><D6B8>ɹ<EFBFBD><C9B9><EFBFBD>ζ<EFBFBD><CEB6>ϵͳ<CFB5>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA> BLE_SET <20>ɹ<EFBFBD>ʱ֪ͨ BLE_ERROR <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD> recovery_level <20><> BLE_ERROR <20>ڲ<EFBFBD><DAB2>ľ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>ֱ<EFBFBD>Ӵ<EFBFBD><D3B4>ⲿ<EFBFBD>޸ġ<DEB8><C4A1><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF>Խ<EFBFBD> recovery_level <20><><EFBFBD><EFBFBD>Ϊȫ<CEAA>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿڡ<D3BF>
// <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD>˼򵥣<CBBC><F2B5A5A3><EFBFBD><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD> recovery_level <20><>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5A3A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BLE_SET <20>ɹ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD> uint8_t g_recovery_level; <20><><EFBFBD><EFBFBD> BLE_ERROR <20>и<EFBFBD>Ϊʹ<CEAA><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>û<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD> recovery_level <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>static<69><63><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD> BLE_SET <20>а<EFBFBD><D0B0><EFBFBD>һ<EFBFBD><D2BB> extern <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱע<CAB1>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֡<EFBFBD>
// g_recovery_level = 0; // <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
memset(&set_executor, 0, sizeof(set_executor));
curr_state = g_ble_error.origin_state;
}
else if(res == EXECUTOR_ERROR)
{
// <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>Ҳʧ<D2B2>ܣ<EFBFBD><DCA3><EFBFBD> set_executor <20>еĴ<D0B5><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD>Ƶ<EFBFBD> g_ble_error<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD> origin_state<74><65>
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();
// ע<><EFBFBD><E2A3BA>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD> origin_state
memset(&set_executor, 0, sizeof(set_executor));
// <20>ٴν<D9B4><CEBD><EFBFBD> BLE_ERROR<4F><52><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curr_state = BLE_ERROR;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BUSY<53><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>л<EFBFBD>
}
2026-02-24 13:00:08 +08:00
2026-02-24 17:01:12 +08:00
}
2026-02-24 13:00:08 +08:00
break;
case BLE_WAITTING:
{
static uint32_t last_time = 0;
uint32_t time = HAL_GetTick();
uint32_t rest = time - last_time;
if(rest >= 500)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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; // <20><><EFBFBD><EFBFBD>׼<EFBFBD><D7BC><EFBFBD>Ƿ<EFBFBD><C7B7>ɹ<EFBFBD>
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("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>׼<EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d<><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 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)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʴ<EFBFBD><CAB4><EFBFBD>
ex->start_tick = HAL_GetTick();
ex->state = EXEC_STATE_SEND_WAIT;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
return EXECUTOR_BUSY;
}
break;
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; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
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;
}
break;
case EXEC_STATE_PROCESS_RESP:
{
//<2F><><EFBFBD>ܴ<EFBFBD><DCB4>ڻش<DABB><D8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
//char process_data[] = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ
{
ex->cmd_index++;
ex->retry_cnt = 0;
ex->state = EXEC_STATE_IDLE;
ble_cmd_rec_done = 0;
return EXECUTOR_BUSY;
}
else if(result > 0) //ģ<><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD>
{
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
{
//<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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(void)
{
}
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("δ֪<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룺%d", err_code);
return err_code;
}
DEBUG("<EFBFBD>޷<EFBFBD>ʶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ: %s", resp);
return -1; // <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>ֵ
}
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; //ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t type = g_ble_config.addr_type; //ȡ<><C8A1><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
char* mac = g_ble_config.target_mac; //ȡ<><C8A1>mac<61><63>ַ
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_diradv_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
}