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

645 lines
13 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 :
switch(g_ble_error.type)
{
case ERR_TYPE_NONE:
break;
case ERR_TYPE_PREPARE_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);
curr_state = BLE_WAITTING;
}
break;
case ERR_TYPE_TIMEOUT_EXCEEDED:
{
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;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
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);
curr_state = BLE_SET;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
}
break;
case ERR_TYPE_MODULE_ERROR:
{
for(uint8_t i = 0; i < 4; i++)
{
if(g_ble_error.error_code == g_ble_error_table[i].code)
{
g_ble_error.
}
}
}
break;
default:
break;
}
break;
case BLE_SET :
{
if() //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
{
}
else if() //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
}
}
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)
{
}