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

645 lines
13 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 <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
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)
{
/*
尝试读取保存在本地的数据如果没有则进入first connect
如果有则进入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)
{
/*
保存参数到本地
*/
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)
{
/*
保存参数到本地
*/
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 :
{
/*
在已经开启透传的情况下周期性发送消息,一般情况不进行跳转其他状态
如果超时则返回连接状态多次出问题则进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;
//重新配置串口信息
}
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;
//重新配置串口信息
}
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() //重新配置串口信息
{
}
else if() //重新启动设备
{
}
}
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;
}
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; // 建议清零,避免旧数据影响下一次
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:
{
//接受串口回传具体信息
//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(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("未知错误码:%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_diradv_cmd(const char* cmd_template, char* cmd_buf, int buf_size)
{
}