Files
JBao_Sprayer_FW/apps/usr_le_code/usr_le_adv.c
T

341 lines
9.4 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.
/******************************************************************************
* @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:非配网流程
* - 1app_main 上电 / usr_goto_pair_mode() 触发,发【绑定广播】
*
* 3) usr_var.usr_adv_flag —— 广播内容是否需要刷新到协议栈(一次性)
* - 1usr_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);
}
}