From 408c25bd5c0e8a648a273cbae7b9be0819fc07b0 Mon Sep 17 00:00:00 2001
From: Wuchuyuan <1917507415@qq.com>
Date: Thu, 3 Sep 2026 15:31:40 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96BLE=E6=96=AD=E8=BF=9E?=
=?UTF-8?q?=E5=90=8E=E9=87=8D=E8=BF=9E=E5=B9=BF=E6=92=AD=E5=92=8C=E6=B8=A9?=
=?UTF-8?q?=E6=B9=BF=E5=BA=A6=E5=B9=BF=E6=92=AD=E5=88=87=E6=8D=A2=E7=9A=84?=
=?UTF-8?q?=E7=A8=8B=E5=BA=8F=E6=9E=B6=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
AC701N.cbp | 4 +
Makefile | 1 +
apps/usr_app/app_th.h | 4 +-
apps/usr_app/app_th_adv.c | 206 +++++++++++++++++++++++++++++++++
apps/usr_app/app_th_adv.h | 41 +++++++
apps/usr_le_code/usr_le_adv.c | 208 ++++------------------------------
apps/usr_le_code/usr_le_api.h | 19 ++++
7 files changed, 294 insertions(+), 189 deletions(-)
create mode 100644 apps/usr_app/app_th_adv.c
create mode 100644 apps/usr_app/app_th_adv.h
diff --git a/AC701N.cbp b/AC701N.cbp
index ed5a134..b56a424 100644
--- a/AC701N.cbp
+++ b/AC701N.cbp
@@ -843,6 +843,10 @@
+
+
+
+
diff --git a/Makefile b/Makefile
index 51a4b7c..7bfbfed 100644
--- a/Makefile
+++ b/Makefile
@@ -468,6 +468,7 @@ c_SRC_FILES := \
apps/usr_app/app_fan.c \
apps/usr_app/app_disp.c \
apps/usr_app/app_th.c \
+ apps/usr_app/app_th_adv.c \
apps/usr_app/app_linkage.c \
apps/usr_app/app_runrec.c \
apps/usr_app/app_timer_task.c \
diff --git a/apps/usr_app/app_th.h b/apps/usr_app/app_th.h
index 9c5e264..b01d3df 100644
--- a/apps/usr_app/app_th.h
+++ b/apps/usr_app/app_th.h
@@ -67,10 +67,10 @@ uint8_t app_th_is_fault(void);
uint8_t app_th_last_sample_ok(void);
/**
- * @brief 取走一次「本周期采样成功」事件(供 usr_le_adv 的 500ms 任务上下文)
+ * @brief 取走一次「本周期采样成功」事件(供 app_th_adv 的 500ms 任务上下文)
* @note ⚠ 生产者是 app_th_poll(20ms 硬件定时器中断上下文),那里只置
* volatile pending,不开关广播、不打日志、不写 flash。
- * 消费者(usr_ble_adv_updata,BLE 线程任务上下文)调本函数取走,
+ * 消费者(app_th_adv_tick,由 usr_ble_adv_updata 调用)调本函数取走,
* 内部 local_irq_disable 保护,取到即清。
* 只在真正采样成功(last_ok 那次)时产生,失败/fault 不产生,
* 温度、湿度都是对外值(与数码管/DP3/DP4 一致)。
diff --git a/apps/usr_app/app_th_adv.c b/apps/usr_app/app_th_adv.c
new file mode 100644
index 0000000..2bc4926
--- /dev/null
+++ b/apps/usr_app/app_th_adv.c
@@ -0,0 +1,206 @@
+/******************************************************************************
+ * @file app_th_adv.c
+ * @brief CBR3 自定义温湿度广播窗实现
+ * @author cyWu <1917507415@qq.com>
+ * @date 2026.09.03
+ * @version V1.0.0
+ * @history
+ * - V1.0.0, 2026.09.03, cyWu, 从 usr_le_adv.c 拆出
+ ******************************************************************************/
+
+#include "app_th_adv.h"
+#include "app_th.h"
+#include "app_linkage.h"
+#include "board_pin.h"
+#include "usr_le_api.h"
+#include "system/includes.h"
+#include "app_main.h"
+
+#define LOG_TAG_CONST APP
+#define LOG_TAG "[TH_ADV]"
+#define LOG_INFO_ENABLE
+#include "debug.h"
+
+extern void usr_set_adv_interval(u16 val);
+extern u16 usr_get_adv_interval(void);
+
+#define TH_ADV_DATA_MAX 31
+#define TH_ADV_WINDOW_TICKS 2 /**< 500ms × 2 = 1s */
+#define TH_ADV_FAST_INTERVAL 80 /**< 窗内快广播,暂停 60s 变慢 */
+#define TH_ADV_TYPE_FLAGS 0x01
+#define TH_ADV_TYPE_LOCAL_NAME 0x09
+#define TH_ADV_TYPE_MANUFACTURER 0xFF
+
+typedef struct {
+ uint8_t ticks; /**< >0 = 窗进行中,剩余 500ms 拍数 */
+ uint16_t interval; /**< 进窗前提速前的间隔;0=进窗前已是快广播 */
+} AppThAdvCtx_t;
+
+static AppThAdvCtx_t s_th_adv;
+
+/**
+ * @brief 配对 / OTA / 已连接 / 未配网 → 不允许发温湿度窗
+ * @return 1=阻塞,0=允许
+ */
+static uint8_t th_adv_blocked(void)
+{
+ if (usr_ble_is_connected()) {
+ return 1;
+ }
+ if (usr_var.usr_goto_pair || usr_var.usr_goto_updata ||
+ usr_var.usr_ota_succ_flag) {
+ return 1;
+ }
+ if (usr_get_pair_flag() == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief 组自定义温湿度 AD(Flags + Complete Local Name + Manufacturer 0xFFFF)
+ * @param tank 缸体编号(非 0)
+ * @param ver 配置版本
+ * @param temp_x10 对外温度 ×10
+ * @param humi 对外湿度 %
+ * @return 无
+ */
+static void th_adv_encode(uint16_t tank, uint8_t ver, int16_t temp_x10, uint8_t humi)
+{
+ uint8_t buf[TH_ADV_DATA_MAX];
+ uint8_t *p = buf;
+ char dec[5];
+ uint8_t digits = 0;
+ uint16_t v = tank;
+ int32_t t_int;
+ uint8_t name_len;
+
+ *p++ = 0x02;
+ *p++ = TH_ADV_TYPE_FLAGS;
+ *p++ = 0x06;
+
+ while (v) {
+ dec[digits++] = (char)('0' + (v % 10));
+ v /= 10;
+ }
+ name_len = (uint8_t)(5 + digits); /* "JBao-" + tank 位数 */
+ *p++ = (uint8_t)(1 + name_len);
+ *p++ = TH_ADV_TYPE_LOCAL_NAME;
+ *p++ = 'J';
+ *p++ = 'B';
+ *p++ = 'a';
+ *p++ = 'o';
+ *p++ = '-';
+ while (digits) {
+ *p++ = (uint8_t)dec[--digits];
+ }
+
+ t_int = temp_x10 / 10;
+ if (t_int < -128) {
+ t_int = -128;
+ }
+ if (t_int > 127) {
+ t_int = 127;
+ }
+ if (humi > 100) {
+ humi = 100;
+ }
+ *p++ = 0x06;
+ *p++ = TH_ADV_TYPE_MANUFACTURER;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = ver;
+ *p++ = (uint8_t)t_int;
+ *p++ = humi;
+
+ usr_ble_adv_set_raw(buf, (uint8_t)(p - buf));
+}
+
+/**
+ * @brief 结束温湿度窗:还原广播间隔,可选切回见宝回连
+ * @param back_to_reconn 1=组回连包(窗自然到期);0=只清窗
+ * @return 无
+ */
+static void th_adv_stop(uint8_t back_to_reconn)
+{
+ if (s_th_adv.ticks == 0) {
+ return;
+ }
+ s_th_adv.ticks = 0;
+ if (s_th_adv.interval != 0) {
+ usr_set_adv_interval(s_th_adv.interval);
+ s_th_adv.interval = 0;
+ }
+ if (back_to_reconn) {
+ usr_ble_adv_encode_reconn();
+ log_info("th adv win end, back to reconn\n");
+ }
+}
+
+/**
+ * @brief 丢掉温湿度窗(不组回连包)
+ * @return 无
+ */
+void app_th_adv_reset(void)
+{
+ s_th_adv.ticks = 0;
+ s_th_adv.interval = 0;
+}
+
+/**
+ * @brief 温湿度窗是否占用广播
+ * @return 1=窗进行中,0=空闲
+ */
+uint8_t app_th_adv_is_active(void)
+{
+ return (s_th_adv.ticks != 0) ? 1 : 0;
+}
+
+/**
+ * @brief 温湿度窗状态机(500ms 一拍)
+ * @return 无
+ */
+void app_th_adv_tick(void)
+{
+#if !BOARD_TH_ENABLE
+ return;
+#else
+ int16_t t_x10 = 0;
+ uint8_t humi = 0;
+ uint16_t tank;
+
+ if (s_th_adv.ticks) {
+ if (th_adv_blocked()) {
+ th_adv_stop(0);
+ } else if (s_th_adv.ticks > 1) {
+ s_th_adv.ticks--;
+ } else {
+ /* 最后一拍必须先 stop(里头要求 ticks!=0),再组回连包 */
+ th_adv_stop(1);
+ }
+ }
+
+ if (th_adv_blocked()) {
+ return;
+ }
+
+ if (!app_th_take_sample(&t_x10, &humi)) {
+ return;
+ }
+
+ tank = app_linkage_get_tank_id();
+ if (tank == 0) {
+ return;
+ }
+
+ if (s_th_adv.ticks == 0) {
+ s_th_adv.interval = (usr_get_adv_interval() != TH_ADV_FAST_INTERVAL) ?
+ usr_get_adv_interval() : 0;
+ usr_set_adv_interval(TH_ADV_FAST_INTERVAL);
+ }
+ th_adv_encode(tank, app_linkage_get_cfg_ver(), t_x10, humi);
+ s_th_adv.ticks = TH_ADV_WINDOW_TICKS;
+ log_info("th adv: tank=%u ver=%u T=%dC H=%u%%\n",
+ tank, app_linkage_get_cfg_ver(), (int)(t_x10 / 10), humi);
+#endif
+}
diff --git a/apps/usr_app/app_th_adv.h b/apps/usr_app/app_th_adv.h
new file mode 100644
index 0000000..0997666
--- /dev/null
+++ b/apps/usr_app/app_th_adv.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * @file app_th_adv.h
+ * @brief CBR3 自定义温湿度广播窗(已绑定未连接时插 1s,再切回见宝回连)
+ * @author cyWu <1917507415@qq.com>
+ * @date 2026.09.03
+ * @version V1.0.0
+ * @history
+ * - V1.0.0, 2026.09.03, cyWu, 从 usr_le_adv.c 拆出
+ *
+ * @note 给 nRF / 自研扫描器看,不是见宝 TLV。GATT 0x2A00 不动。
+ * 进窗条件:未连接 + 已配网 + 非配对 + 非 OTA + tank_id≠0
+ * + 本周期 AHT20 采样成功。窗长 500ms × 2。
+ * ⚠ 只在 usr_ble_adv_updata(500ms 任务上下文)里 tick;
+ * app_th 中断侧只置 pending,本模块是唯一消费者。
+ ******************************************************************************/
+
+#ifndef __APP_TH_ADV_H__
+#define __APP_TH_ADV_H__
+
+#include
+
+/**
+ * @brief 丢掉温湿度窗(不组回连包)
+ * @note usr_ble_adv_init 会自己组绑定/回连,进 init 前调本函数清窗即可
+ * @return 无
+ */
+void app_th_adv_reset(void);
+
+/**
+ * @brief 温湿度窗状态机(500ms 一拍,须在写协议栈广播数据之前调用)
+ * @return 无
+ */
+void app_th_adv_tick(void);
+
+/**
+ * @brief 温湿度窗是否占用广播
+ * @return 1=窗进行中(暂停 60s 变慢广播),0=空闲
+ */
+uint8_t app_th_adv_is_active(void);
+
+#endif /* __APP_TH_ADV_H__ */
diff --git a/apps/usr_le_code/usr_le_adv.c b/apps/usr_le_code/usr_le_adv.c
index fae6be8..2b93783 100644
--- a/apps/usr_le_code/usr_le_adv.c
+++ b/apps/usr_le_code/usr_le_adv.c
@@ -1,16 +1,14 @@
/******************************************************************************
* @file usr_le_adv.c
- * @brief BLE 广播 / 配对 / OTA 广播切换 + 自定义温湿度广播窗
+ * @brief BLE 广播 / 配对 / OTA 广播切换
* @author cyWu <1917507415@qq.com>
* @date 2026.09.03
- * @version V1.2.0,新增「已绑定未连接」时的 1s 温湿度广播窗
+ * @version V1.3.0,温湿度窗拆到 app_th_adv
* @history
* - V1.0.0, 2026.08.03, cyWu, 首次发布
* - V1.1.0, 2026.08.19, cyWu, 对齐模组注释与助手;保留 SOC 上电绑广播策略
- * - V1.2.0, 2026.09.03, cyWu, 已绑定+未连接+有缸体+本周期采样成功 → 发 1s
- * 自定义温湿度广播(3 段 AD:Flags / Complete Local Name / Manufacturer
- * 0xFFFF),随后切回见宝回连包。配置中/未配网/tank=0/采样失败/OTA/已连接
- * 不发。app_th 只置 pending,本文件(500ms 任务上下文)负责组包与切回。
+ * - V1.2.0, 2026.09.03, cyWu, 已绑定未连接温湿度窗(随后拆出)
+ * - V1.3.0, 2026.09.03, cyWu, 温湿度窗迁到 app_th_adv,本文件只留钩子
******************************************************************************/
#include "system/includes.h"
@@ -20,8 +18,8 @@
#include "bleproto.h"
#include "bleproto_api.h"
#include "usr_le_product.h"
-#include "app_th.h"
-#include "app_linkage.h"
+#include "usr_le_api.h"
+#include "app_th_adv.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[LE_ADV]"
@@ -48,17 +46,7 @@
* SOC 决策表(与模组不同:未配网也发绑定广播,便于上电配网):
* usr_goto_pair==1 → 绑定广播
* paired_flag==0 → 绑定广播
- * paired_flag==1 → 回连广播(可被下面的温湿度窗临时顶替 1s)
- *
- * 自定义温湿度广播窗(V1.2.0):
- * 同时满足「未连接 + paired_flag==1 + usr_goto_pair==0 + 非 OTA + tank_id!=0
- * + 本周期 AHT20 采样成功」→ 发 1s(500ms × 2 拍)自定义包,之后 encode4reconn
- * 切回见宝回连包。整包三段,按蓝牙 AD 结构 [Len][Type][Data…] 组:
- * 02 01 06
- * (1+n) 09 "JBao-"(tank 十进制无前导零)
- * 06 FF FF FF
- * 这不是见宝 TLV,不用 encode4heartbeat;见宝回连仍用 encode4reconn。
- * 给 nRF 和以后自研扫描器看,GATT 0x2A00 / gap_device_name 不动。
+ * paired_flag==1 → 回连广播(可被 app_th_adv 临时顶替 1s)
******************************************************************************/
extern u8 muti_adv_data[31];
@@ -66,27 +54,6 @@ extern u8 muti_adv_data_len;
/** 广播数据最大长度(BLE 4.x 31 字节) */
#define USR_ADV_DATA_MAX 31
-/** 温湿度窗持续拍数:500ms × 2 = 1s */
-#define USR_TH_ADV_WINDOW_TICKS 2
-/** 温湿度窗内的快广播间隔(窗内暂停「60s 变慢广播」) */
-#define USR_TH_ADV_FAST_INTERVAL 80
-
-/** AD Type:Flags(与见宝包一致) */
-#define USR_AD_TYPE_FLAGS 0x01
-/** AD Type:Complete Local Name */
-#define USR_AD_TYPE_LOCAL_NAME 0x09
-/** AD Type:Manufacturer Specific Data(禁止用 0x16 Service Data,那是见宝在用的) */
-#define USR_AD_TYPE_MANUFACTURER 0xFF
-
-/** 温湿度窗状态:>0 = 窗进行中,值 = 剩余 500ms 拍数 */
-static u8 s_th_win_ticks = 0;
-/** 窗内提速前的广播间隔,0 = 进窗时本来就是快广播,出窗不还原 */
-static u16 s_th_win_interval = 0;
-
-static void usr_adv_encode_reconn(void);
-static void usr_adv_encode_th(u16 tank, u8 ver, int16_t temp_x10, u8 humi);
-static void usr_th_adv_stop(u8 back_to_reconn);
-static void usr_th_adv_tick(void);
/* 定义在 usr_le_recieve.c,库内共用,不对外导出 */
extern bleproto_authsetup_req_t usr_auth_data;
@@ -206,9 +173,8 @@ void usr_ble_adv_init(void)
memcpy(prodcode, g_usr_le_prodcode, BLEPROTO_ADV_TLV_LENGTH_PRODCODE);
memcpy(pcode, g_usr_le_pcode, BLE_PROTO_ADV_LENGTH_PCODE);
- /* 广播策略重置:清掉温湿度窗(若有),间隔由本函数统一置 80 */
- s_th_win_ticks = 0;
- s_th_win_interval = 0;
+ /* 产品温湿度窗清掉;间隔由本函数统一置 80 */
+ app_th_adv_reset();
usr_set_adv_interval(80);
if (usr_var.usr_ota_succ_flag)
@@ -265,7 +231,7 @@ u8 usr_get_pair_flag(void)
* @note 只组包并置 usr_adv_flag=1,真正下发由 usr_ble_adv_updata 完成
* @return 无
*/
-static void usr_adv_encode_reconn(void)
+void usr_ble_adv_encode_reconn(void)
{
uint8_t manucode[BLEPROTO_ADV_TLV_LENGTH_MANUCODE] = {0};
uint8_t prodcode[BLEPROTO_ADV_TLV_LENGTH_PRODCODE];
@@ -281,153 +247,21 @@ static void usr_adv_encode_reconn(void)
}
/**
- * @brief 组自定义温湿度广播包(三段 AD,非见宝 TLV,给 nRF/自研扫描器)
- * @note 整包:02 01 06 / (1+n) 09 "JBao-" / 06 FF FF FF ver T H
- * Company ID 0xFFFF 小端;温度 int8 ℃(向 0 取整,钳位 [-128,127]);
- * 湿度 uint8 %。不动 GATT 0x2A00 / gap_device_name。
- * @param tank 缸体编号(非 0)
- * @param ver 配置版本(linkage_config[6])
- * @param temp_x10 温度 ×10
- * @param humi 湿度 %
+ * @brief 用调用方组好的 AD 覆盖广播 payload
+ * @param data 广播数据
+ * @param len 长度(1~31)
* @return 无
*/
-static void usr_adv_encode_th(u16 tank, u8 ver, int16_t temp_x10, u8 humi)
+void usr_ble_adv_set_raw(const uint8_t *data, uint8_t len)
{
- u8 *p = muti_adv_data;
- char dec[5];
- u8 digits = 0;
- u16 v = tank;
- int32_t t_int;
- u8 name_len;
-
- /* 段1 Flags(与见宝一致) */
- *p++ = 0x02;
- *p++ = USR_AD_TYPE_FLAGS;
- *p++ = 0x06;
-
- /* 段2 Complete Local Name "JBao-" */
- while (v) {
- dec[digits++] = (char)('0' + (v % 10));
- v /= 10;
+ if (!data || (len == 0) || (len > USR_ADV_DATA_MAX)) {
+ return;
}
- name_len = (u8)(5 + digits); /* "JBao-" + tank 位数 */
- *p++ = (u8)(1 + name_len); /* AD Length = Type(1) + Data */
- *p++ = USR_AD_TYPE_LOCAL_NAME;
- *p++ = 'J';
- *p++ = 'B';
- *p++ = 'a';
- *p++ = 'o';
- *p++ = '-';
- while (digits) {
- *p++ = (u8)dec[--digits]; /* 反序数组正序发 → 高位在前 */
- }
-
- /* 段3 Manufacturer Specific:Company 0xFFFF(小端) + ver + T(int8) + H */
- t_int = temp_x10 / 10; /* C 整除即向 0 取整 */
- if (t_int < -128) {
- t_int = -128;
- }
- if (t_int > 127) {
- t_int = 127;
- }
- if (humi > 100) {
- humi = 100;
- }
- *p++ = 0x06; /* Type(1) + Company(2) + ver/T/H(3) */
- *p++ = USR_AD_TYPE_MANUFACTURER;
- *p++ = 0xFF; /* Company ID 0xFFFF 低字节 */
- *p++ = 0xFF; /* Company ID 0xFFFF 高字节 */
- *p++ = ver;
- *p++ = (u8)t_int;
- *p++ = humi;
-
- muti_adv_data_len = (u8)(p - muti_adv_data);
+ memcpy(muti_adv_data, data, len);
+ muti_adv_data_len = len;
usr_var.usr_adv_flag = 1;
}
-/**
- * @brief 结束温湿度窗:还原广播间隔,可选切回见宝回连包
- * @param back_to_reconn 1=组回连包(窗自然到期用);
- * 0=只清窗(配对/OTA/连接切换时包由各自流程组)
- * @return 无
- */
-static void usr_th_adv_stop(u8 back_to_reconn)
-{
- if (s_th_win_ticks == 0) {
- return;
- }
- s_th_win_ticks = 0;
- if (s_th_win_interval != 0) {
- /* 进窗前是慢广播 → 还原;进窗前本来就是快广播则不还原 */
- usr_set_adv_interval(s_th_win_interval);
- s_th_win_interval = 0;
- }
- if (back_to_reconn) {
- usr_adv_encode_reconn();
- log_info("th adv win end, back to reconn\n");
- }
-}
-
-/**
- * @brief 温湿度窗状态机(usr_ble_adv_updata 500ms 拍,任务上下文)
- * @note 进窗条件同时满足:未连接 + paired_flag==1 + 非配对 + 非 OTA +
- * tank_id!=0 + 本周期 AHT20 采样成功(take 到的才是本次新值)。
- * 窗长 500ms × 2;窗内再来采样成功 → 刷新段 3 并重计 2 拍。
- * ⚠ app_th 中断侧只置 pending,本函数是唯一消费者。
- * @return 无
- */
-static void usr_th_adv_tick(void)
-{
- int16_t t_x10 = 0;
- u8 humi = 0;
- u8 got;
- u16 tank;
-
- /* 窗进行中:先处理强制结束(配对 / OTA / 连接切换 / 清配网) */
- if (s_th_win_ticks) {
- if (usr_ble_is_connected() || usr_var.usr_goto_pair ||
- (usr_auth_data.paired_flag == 0) || usr_var.usr_goto_updata ||
- usr_var.usr_ota_succ_flag) {
- usr_th_adv_stop(0);
- } else if (s_th_win_ticks > 1) {
- s_th_win_ticks--;
- } else {
- /* 最后一拍:必须先 stop(里头要求 ticks!=0),再组回连包。
- * 若先减成 0 再 stop,会被 if (ticks==0) return 直接丢掉回连。 */
- usr_th_adv_stop(1);
- }
- }
-
- if (usr_ble_is_connected() || usr_var.usr_goto_pair ||
- (usr_auth_data.paired_flag == 0) || usr_var.usr_goto_updata ||
- usr_var.usr_ota_succ_flag) {
- return;
- }
-
- got = app_th_take_sample(&t_x10, &humi);
- if (!got) {
- return;
- }
-
- tank = app_linkage_get_tank_id();
- if (tank == 0) {
- /* 未配缸体:一直回连,不发温湿度窗 */
- return;
- }
-
- if (s_th_win_ticks == 0) {
- /* 进窗:记下当前间隔并提速(窗内暂停「60s 变慢广播」) */
- s_th_win_interval = (usr_get_adv_interval() != USR_TH_ADV_FAST_INTERVAL) ?
- usr_get_adv_interval() : 0;
- usr_set_adv_interval(USR_TH_ADV_FAST_INTERVAL);
- }
- /* 进窗 / 窗内刷新:组包(usr_adv_flag=1,下一行刷新块立即下发) */
- usr_adv_encode_th(tank, app_linkage_get_cfg_ver(), t_x10, humi);
- s_th_win_ticks = USR_TH_ADV_WINDOW_TICKS;
- log_info("th adv: tank=%u ver=%u T=%dC H=%u%%\n",
- tank, app_linkage_get_cfg_ver(), (int)(t_x10 / 10), humi);
-}
-
/**
* @brief 周期处理广播刷新(由 500ms 定时器调用)
* @note 仅当 usr_adv_flag==1 时:停广播 → 写入 muti_adv_data → 再开广播
@@ -436,8 +270,8 @@ void usr_ble_adv_updata(void)
{
static u16 usr_goto_slow_adv = 0;
- /* 温湿度窗状态机:先于广播刷新执行,进/出窗当拍立即生效 */
- usr_th_adv_tick();
+ /* 产品温湿度窗:须先于广播刷新,进/出窗当拍立即生效 */
+ app_th_adv_tick();
if (usr_var.usr_adv_flag)
{
@@ -457,7 +291,7 @@ void usr_ble_adv_updata(void)
{
if ((usr_var.usr_goto_pair == 0) && usr_auth_data.paired_flag)
{
- if ((usr_var.usr_ota_succ_flag == 0) && (s_th_win_ticks == 0))
+ if ((usr_var.usr_ota_succ_flag == 0) && (app_th_adv_is_active() == 0))
{
usr_goto_slow_adv++;
printf("usr_goto_slow_adv = %d\n", usr_goto_slow_adv);
diff --git a/apps/usr_le_code/usr_le_api.h b/apps/usr_le_code/usr_le_api.h
index 4ccb3ba..8dd9cb0 100644
--- a/apps/usr_le_code/usr_le_api.h
+++ b/apps/usr_le_code/usr_le_api.h
@@ -49,6 +49,25 @@ uint8_t usr_get_pair_flag(void);
*/
void usr_app_ota_init(void);
+/**
+ * @brief BLE 是否已连接
+ * @return 1=已连接,0=未连接
+ */
+uint8_t usr_ble_is_connected(void);
+
+/**
+ * @brief 组见宝回连广播包并标记下一拍下发
+ * @note 只组包,真正写入协议栈由 usr_ble_adv_updata 完成
+ */
+void usr_ble_adv_encode_reconn(void);
+
+/**
+ * @brief 用调用方组好的 AD 覆盖广播 payload 并标记下一拍下发
+ * @param data 广播数据(最长 31 字节)
+ * @param len 长度
+ */
+void usr_ble_adv_set_raw(const uint8_t *data, uint8_t len);
+
#ifdef __cplusplus
}
#endif