341 lines
9.4 KiB
C
341 lines
9.4 KiB
C
/******************************************************************************
|
||
* @file usr_le_adv.c
|
||
* @brief BLE 广播 / 配对 / OTA 广播切换
|
||
* @author cyWu <1917507415@qq.com>
|
||
* @date 2026.08.19
|
||
* @version V1.1.0
|
||
* @history
|
||
* - V1.0.0, 2026.08.03, cyWu, 首次发布
|
||
* - V1.1.0, 2026.08.19, cyWu, 对齐模组注释与助手;保留 SOC 上电绑广播策略
|
||
******************************************************************************/
|
||
|
||
#include "system/includes.h"
|
||
#include "app_config.h"
|
||
#include "app_main.h"
|
||
#include "vm.h"
|
||
#include "bleproto.h"
|
||
#include "bleproto_api.h"
|
||
#include "usr_le_product.h"
|
||
|
||
#define LOG_TAG_CONST APP
|
||
#define LOG_TAG "[LE_ADV]"
|
||
#define LOG_ERROR_ENABLE
|
||
#define LOG_DEBUG_ENABLE
|
||
#define LOG_INFO_ENABLE
|
||
#include "debug.h"
|
||
|
||
/******************************************************************************
|
||
* 广播相关三个标志(务必区分):
|
||
*
|
||
* 1) usr_auth_data.paired_flag —— 配网结果(存 VM,掉电保持)
|
||
* - 0:未配网
|
||
* - 1:已配网(三元组已保存)
|
||
*
|
||
* 2) usr_var.usr_goto_pair —— 是否主动进入配网流程(RAM,掉电丢失)
|
||
* - 0:非配网流程
|
||
* - 1:app_main 上电 / usr_goto_pair_mode() 触发,发【绑定广播】
|
||
*
|
||
* 3) usr_var.usr_adv_flag —— 广播内容是否需要刷新到协议栈(一次性)
|
||
* - 1:usr_ble_adv_updata() 会重新 set adv data 并 enable
|
||
* - 0:本周期不刷新
|
||
*
|
||
* SOC 决策表(与模组不同:未配网也发绑定广播,便于上电配网):
|
||
* usr_goto_pair==1 → 绑定广播
|
||
* paired_flag==0 → 绑定广播
|
||
* paired_flag==1 → 回连广播
|
||
******************************************************************************/
|
||
|
||
extern u8 muti_adv_data[31];
|
||
extern u8 muti_adv_data_len;
|
||
|
||
/* 定义在 usr_le_recieve.c,库内共用,不对外导出 */
|
||
extern bleproto_authsetup_req_t usr_auth_data;
|
||
|
||
extern u16 usr_get_conn_service(void);
|
||
extern int muti_make_set_adv_data(u8 *data, u8 data_len);
|
||
extern int muti_make_set_adv_data_updata(void);
|
||
extern void usr_set_adv_interval(u16 val);
|
||
extern u16 usr_get_adv_interval(void);
|
||
extern void ble_multi_trans_disconnect(void);
|
||
extern void ble_trans_module_enable(u8 flag);
|
||
extern void usr_timer_loop(void);
|
||
extern u8 usr_get_ota_status(void);
|
||
extern void usr_ota_exit(void);
|
||
|
||
void usr_ble_adv_init(void);
|
||
void usr_ble_adv_updata(void);
|
||
|
||
static int le_timer_handle = 0;
|
||
|
||
/**
|
||
* @brief BLE 是否已连接
|
||
* @return 1=已连接,0=未连接
|
||
*/
|
||
uint8_t usr_ble_is_connected(void)
|
||
{
|
||
return (usr_get_conn_service() != 0) ? 1u : 0u;
|
||
}
|
||
|
||
/**
|
||
* @brief 从 VM 读取配对信息到 usr_auth_data
|
||
* @note 失败则清零,并将 paired_flag 置 0 写回
|
||
*/
|
||
void usr_get_pair_info(void)
|
||
{
|
||
int ret;
|
||
|
||
ret = syscfg_read(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||
if (ret <= 0)
|
||
{
|
||
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
||
usr_auth_data.paired_flag = 0;
|
||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 标记已配网并保存三元组到 VM
|
||
* @note AUTHSETUP 成功后调用,paired_flag = 1
|
||
*/
|
||
void usr_write_pair_info(void)
|
||
{
|
||
usr_auth_data.paired_flag = 1;
|
||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||
}
|
||
|
||
/**
|
||
* @brief 清除配对信息并延时复位
|
||
*/
|
||
void usr_clear_pair_info(void)
|
||
{
|
||
printf("usr_clear_pair_info_reset\n");
|
||
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
||
usr_auth_data.paired_flag = 0;
|
||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||
sys_timeout_add(NULL, cpu_reset, 600);
|
||
}
|
||
|
||
/**
|
||
* @brief 清除配对信息但不复位(用于重新配网)
|
||
*/
|
||
void usr_clear_pair_info_noreset(void)
|
||
{
|
||
printf("usr_clear_pair_info_noreset\n");
|
||
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
||
usr_auth_data.paired_flag = 0;
|
||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||
}
|
||
|
||
/**
|
||
* @brief 进入配网模式:清配对 + 置 usr_goto_pair + 发绑定广播
|
||
*/
|
||
void usr_goto_pair_mode(void)
|
||
{
|
||
ble_multi_trans_disconnect();
|
||
usr_clear_pair_info_noreset();
|
||
usr_var.usr_goto_pair = 1;
|
||
os_time_dly(5);
|
||
usr_ble_adv_init();
|
||
}
|
||
|
||
/**
|
||
* @brief 断开 BLE 并停止广播(复位/重启前)
|
||
*/
|
||
void usr_ble_disconnect_and_stop_adv(void)
|
||
{
|
||
printf("usr_ble_disconnect_and_stop_adv\n");
|
||
ble_multi_trans_disconnect();
|
||
usr_var.usr_goto_pair = 0;
|
||
usr_var.usr_adv_flag = 0;
|
||
ble_trans_module_enable(0);
|
||
}
|
||
|
||
/**
|
||
* @brief 按当前标志刷新广播策略并启动周期更新
|
||
* @note 见文件头「三个标志」;SOC 未配网也发绑定广播
|
||
*/
|
||
void usr_ble_adv_init(void)
|
||
{
|
||
int8_t txpower = 0;
|
||
uint8_t manucode[BLEPROTO_ADV_TLV_LENGTH_MANUCODE] = {0};
|
||
uint8_t prodcode[BLEPROTO_ADV_TLV_LENGTH_PRODCODE];
|
||
uint8_t gmac[6] = {0};
|
||
uint8_t pcode[BLE_PROTO_ADV_LENGTH_PCODE];
|
||
|
||
/* 产品身份由应用层 g_usr_le_* 提供(见 usr_jb_main.c) */
|
||
memcpy(prodcode, g_usr_le_prodcode, BLEPROTO_ADV_TLV_LENGTH_PRODCODE);
|
||
memcpy(pcode, g_usr_le_pcode, BLE_PROTO_ADV_LENGTH_PCODE);
|
||
|
||
usr_set_adv_interval(80);
|
||
if (usr_var.usr_ota_succ_flag)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (usr_var.usr_goto_pair)
|
||
{
|
||
/* app_main 上电已置 usr_goto_pair=1 并清配对信息,此处发绑定广播供网关配网 */
|
||
usr_clear_pair_info_noreset();
|
||
printf("goto pair bind adv, paired_flag=%d\n", usr_auth_data.paired_flag);
|
||
muti_adv_data_len = bleproto_advdata_encode4bind(muti_adv_data, txpower,
|
||
manucode, pcode, prodcode);
|
||
usr_var.usr_adv_flag = 1;
|
||
}
|
||
else
|
||
{
|
||
usr_get_pair_info();
|
||
if (usr_auth_data.paired_flag == 0)
|
||
{
|
||
/* SOC:未配网也发绑定广播(模组此处为不广播) */
|
||
muti_adv_data_len = bleproto_advdata_encode4bind(muti_adv_data, txpower,
|
||
manucode, pcode, prodcode);
|
||
usr_var.usr_adv_flag = 0;
|
||
}
|
||
else
|
||
{
|
||
memcpy(gmac, usr_auth_data.gwmac, 6);
|
||
muti_adv_data_len = bleproto_advdata_encode4reconn(muti_adv_data, txpower, gmac,
|
||
manucode, pcode, prodcode);
|
||
usr_var.usr_adv_flag = 1;
|
||
}
|
||
}
|
||
|
||
usr_ble_adv_updata();
|
||
if (le_timer_handle == 0)
|
||
{
|
||
le_timer_handle = sys_timer_add(NULL, usr_ble_adv_updata, 500);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 获取是否已配网
|
||
* @return 1=已配网,0=未配网
|
||
*/
|
||
u8 usr_get_pair_flag(void)
|
||
{
|
||
return usr_auth_data.paired_flag;
|
||
}
|
||
|
||
/**
|
||
* @brief 周期处理广播刷新(由 500ms 定时器调用)
|
||
* @note 仅当 usr_adv_flag==1 时:停广播 → 写入 muti_adv_data → 再开广播
|
||
*/
|
||
void usr_ble_adv_updata(void)
|
||
{
|
||
static u16 usr_goto_slow_adv = 0;
|
||
|
||
if (usr_var.usr_adv_flag)
|
||
{
|
||
ble_trans_module_enable(0);
|
||
usr_var.usr_adv_flag = 0;
|
||
muti_make_set_adv_data(muti_adv_data, muti_adv_data_len);
|
||
printf("###muti_adv_data = ");
|
||
printf_buf(muti_adv_data, muti_adv_data_len);
|
||
ble_trans_module_enable(1);
|
||
}
|
||
|
||
if (!usr_ble_is_connected())
|
||
{
|
||
/* 未连接:回连快广播(80)持续约 60s(500ms×120)后切慢广播 */
|
||
if (usr_get_adv_interval() == 80)
|
||
{
|
||
if ((usr_var.usr_goto_pair == 0) && usr_auth_data.paired_flag)
|
||
{
|
||
if (usr_var.usr_ota_succ_flag == 0)
|
||
{
|
||
usr_goto_slow_adv++;
|
||
printf("usr_goto_slow_adv = %d\n", usr_goto_slow_adv);
|
||
}
|
||
if (usr_goto_slow_adv >= 120)
|
||
{
|
||
usr_goto_slow_adv = 0;
|
||
usr_set_adv_interval(80 * 10);
|
||
usr_var.usr_adv_flag = 1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
usr_goto_slow_adv = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
usr_goto_slow_adv = 0;
|
||
}
|
||
|
||
if (usr_get_ota_status() == 0)
|
||
{
|
||
if (!usr_ble_is_connected())
|
||
{
|
||
if (usr_var.usr_ota_succ_flag == 0)
|
||
{
|
||
usr_ota_exit();
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 协议层周期处理(上报/应答) */
|
||
usr_timer_loop();
|
||
}
|
||
|
||
void usr_soft_off(void)
|
||
{
|
||
sys_enter_soft_poweroff(NULL);
|
||
}
|
||
|
||
void usr_ble_adv_updata_OTA(void)
|
||
{
|
||
ble_trans_module_enable(0);
|
||
usr_var.usr_adv_flag = 0;
|
||
|
||
extern u8 usr_mac_addr[6];
|
||
extern int le_controller_set_mac(void *addr);
|
||
usr_mac_addr[0] = usr_mac_addr[0] + 1;
|
||
le_controller_set_mac(usr_mac_addr);
|
||
muti_make_set_adv_data_updata();
|
||
printf("###muti_adv_data = ");
|
||
printf_buf(muti_adv_data, muti_adv_data_len);
|
||
ble_trans_module_enable(1);
|
||
}
|
||
|
||
void usr_ota_process(void)
|
||
{
|
||
static u8 cnt = 0;
|
||
|
||
if (cnt == 0)
|
||
{
|
||
ble_multi_trans_disconnect();
|
||
}
|
||
|
||
if (!usr_ble_is_connected())
|
||
{
|
||
cnt++;
|
||
if (cnt == 2)
|
||
{
|
||
usr_ble_adv_updata_OTA();
|
||
}
|
||
if (cnt >= 60)
|
||
{
|
||
cnt = 0;
|
||
cpu_reset();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
cnt = 1;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 旧版 RCSP/JSON OTA 入口;产品 JB 0x30/0x32 路径不要调用
|
||
*/
|
||
void usr_app_ota_init(void)
|
||
{
|
||
usr_var.usr_goto_updata = 1;
|
||
if (usr_var.ota_timer == 0)
|
||
{
|
||
usr_var.ota_timer = sys_timer_add(NULL, usr_ota_process, 1000);
|
||
}
|
||
}
|