From d50f1302de1858f6edeeacd2952d2fb7e4739397 Mon Sep 17 00:00:00 2001 From: Wuchuyuan <1917507415@qq.com> Date: Mon, 7 Sep 2026 19:40:13 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=85=B3=E9=97=AD1=E5=88=86=E9=92=9F?= =?UTF-8?q?=E6=B2=A1=E9=87=8D=E8=BF=9E=E5=B0=B1=E5=88=87=E6=85=A2=E5=B9=BF?= =?UTF-8?q?=E6=92=AD=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?1=E5=88=86=E9=92=9F=E4=B9=8B=E5=90=8E=E9=87=8D=E8=BF=9E?= =?UTF-8?q?=E4=B8=8D=E4=B8=8A=E7=BD=91=E5=85=B3=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=202=E3=80=81=E8=B0=83=E6=95=B4=E6=9C=80=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8C=85=E9=95=BF=E5=BA=A6=E8=87=B3512=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96BLE=E6=95=B0=E6=8D=AE=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E4=BB=A5=E6=94=AF=E6=8C=81=E5=88=86=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/usr_le_code/bleproto_packer.c | 96 +++++++++++++++++++++--------- apps/usr_le_code/bleproto_packer.h | 12 ++-- apps/usr_le_code/usr_le_adv.c | 29 +++++---- apps/usr_le_code/usr_le_recieve.c | 22 ++++--- apps/usr_periph/board_pin.h | 7 +++ 5 files changed, 116 insertions(+), 50 deletions(-) diff --git a/apps/usr_le_code/bleproto_packer.c b/apps/usr_le_code/bleproto_packer.c index b1c6159..7f08bb2 100644 --- a/apps/usr_le_code/bleproto_packer.c +++ b/apps/usr_le_code/bleproto_packer.c @@ -673,51 +673,89 @@ int bleproto_appdata_serialize(bleproto_appdata_t *appdata, int bleproto_appdata_wrap_raw(uint8_t *txbuf, uint16_t txbuf_size, + uint8_t packetlen, const bleproto_appdata_header_t *header, const uint8_t *payload, uint16_t payload_len) { - uint16_t total; + uint8_t frame_max; + uint16_t totalframe; + uint16_t need; + uint16_t offset = 0; + uint16_t data_offset = 0; + uint16_t i; - if (!txbuf || !header) { - BLEPROTO_T_E("Invalid parameters"); + if (!txbuf || !header || packetlen <= BLEPROTO_APPDATA_HEADR_LEN) { + printf("Invalid parameters"); return -1; } if (payload_len > 0 && !payload) { - BLEPROTO_T_E("Invalid payload"); - return -1; - } - /* 单帧 this_frame_len 为 uint8,超过 255 需走分包 serialize */ - if (payload_len > 255u) { - BLEPROTO_T_E("payload too long for single frame"); + printf("Invalid payload"); return -1; } - total = (uint16_t)(BLEPROTO_APPDATA_HEADR_LEN + payload_len); - if (txbuf_size < total) { - BLEPROTO_T_E("txbuf too short"); + /* 与 serialize 相同:一帧总长 packetlen,其中 8B 头,其余为 payload */ + frame_max = (uint8_t)(packetlen - BLEPROTO_APPDATA_HEADR_LEN); + + if (payload_len == 0) { + totalframe = 1; + } else { + totalframe = (uint16_t)((payload_len + frame_max - 1u) / frame_max); + } + if (totalframe > 255u) { + printf("payload too long, frames %u>255\n", (unsigned)totalframe); return -1; } - /* buf[0]: version[2:0] | datafmt[3:3] | msgtype[7:4] */ - txbuf[0] = UTILS_BITFIELD_SET(header->version, 2, 0) | - UTILS_BITFIELD_SET(header->datafmt, 3, 3) | - UTILS_BITFIELD_SET(header->msgtype, 7, 4); - /* buf[1]: msgid[3:0] | encrypt[4:4] | reserve[7:5] */ - txbuf[1] = UTILS_BITFIELD_SET(header->msgid, 3, 0) | - UTILS_BITFIELD_SET(header->encrypt, 4, 4) | - UTILS_BITFIELD_SET(header->reserve, 7, 5); - txbuf[2] = 1; /* totalframe */ - txbuf[3] = 0; /* frameseq:单帧为 0 */ - txbuf[4] = (uint8_t)payload_len; /* this frame payload len */ - txbuf[5] = header->serviceid; - proto_bytes_put_le16(&txbuf[6], payload_len); - - if (payload_len > 0) { - memcpy(&txbuf[BLEPROTO_APPDATA_HEADR_LEN], payload, payload_len); + need = (uint16_t)((uint16_t)totalframe * BLEPROTO_APPDATA_HEADR_LEN + payload_len); + if (txbuf_size < need) { + printf("txbuf too short %u<%u\n", (unsigned)txbuf_size, (unsigned)need); + return -1; } - return (int)total; + for (i = 0; i < totalframe; i++) { + uint8_t this_len; + uint8_t frameseq; + + if (totalframe == 1u) { + this_len = (uint8_t)payload_len; + frameseq = 0; /* 单帧序号为 0 */ + } else if ((uint16_t)(i + 1u) < totalframe) { + this_len = frame_max; + frameseq = (uint8_t)(i + 1u); /* 分包从 1 起 */ + } else { + this_len = (uint8_t)(payload_len - data_offset); + frameseq = (uint8_t)(i + 1u); + } + + /* buf[0]: version[2:0] | datafmt[3:3] | msgtype[7:4] */ + txbuf[offset + 0] = UTILS_BITFIELD_SET(header->version, 2, 0) | + UTILS_BITFIELD_SET(header->datafmt, 3, 3) | + UTILS_BITFIELD_SET(header->msgtype, 7, 4); + /* buf[1]: msgid[3:0] | encrypt[4:4] | reserve[7:5] */ + txbuf[offset + 1] = UTILS_BITFIELD_SET(header->msgid, 3, 0) | + UTILS_BITFIELD_SET(header->encrypt, 4, 4) | + UTILS_BITFIELD_SET(header->reserve, 7, 5); + txbuf[offset + 2] = (uint8_t)totalframe; + txbuf[offset + 3] = frameseq; + txbuf[offset + 4] = this_len; + txbuf[offset + 5] = header->serviceid; + proto_bytes_put_le16(&txbuf[offset + 6], payload_len); + + offset = (uint16_t)(offset + BLEPROTO_APPDATA_HEADR_LEN); + if (this_len != 0) { + memcpy(&txbuf[offset], &payload[data_offset], this_len); + offset = (uint16_t)(offset + this_len); + data_offset = (uint16_t)(data_offset + this_len); + } + } + + if (totalframe > 1u) { + printf("wrap_raw split %uB -> %u frames, out %uB\n", + (unsigned)payload_len, (unsigned)totalframe, (unsigned)offset); + } + + return (int)offset; } int bleproto_appdata_deserialize(uint8_t * buf, diff --git a/apps/usr_le_code/bleproto_packer.h b/apps/usr_le_code/bleproto_packer.h index 8ec82c1..e4c1d9c 100644 --- a/apps/usr_le_code/bleproto_packer.h +++ b/apps/usr_le_code/bleproto_packer.h @@ -586,17 +586,21 @@ int bleproto_appdata_serialize(bleproto_appdata_t *appdata, uint16_t size); /** - * @brief 将已打包好的 payload 包装成单帧 appdata(不分包) - * @param txbuf 输出缓冲 + * @brief 将已打包好的 payload 包装成 appdata(超过单帧则按 packetlen 分包) + * @param txbuf 输出缓冲(须能放下 每帧8B头 × 帧数 + payload) * @param txbuf_size 输出缓冲大小 + * @param packetlen BLE GATT 单包有效长度,与 serialize 相同(本板 247) * @param header 应用层头(datalen/totalframe/frameseq 由本函数填写) * @param payload 已序列化的 service 数据;可为 NULL(payload_len==0) - * @param payload_len payload 长度,须 <=255(单帧 pthis_frame_len 为 u8) + * @param payload_len 应用数据总长度 * @return >0 总字节数;<0 失败 - * @note 小包场景(JB 55AA 透传等)用此接口,避免 bleproto_appdata_t 大缓冲 + * @note 切帧规则与 serialize 一致:单帧 payload = packetlen - 8; + * 不超过则 totalframe=1、frameseq=0;超过则中间帧填满、末帧剩余, + * frameseq 从 1 递增。避免走 bleproto_appdata_t 大缓冲。 */ int bleproto_appdata_wrap_raw(uint8_t *txbuf, uint16_t txbuf_size, + uint8_t packetlen, const bleproto_appdata_header_t *header, const uint8_t *payload, uint16_t payload_len); diff --git a/apps/usr_le_code/usr_le_adv.c b/apps/usr_le_code/usr_le_adv.c index b99042a..dd5337b 100644 --- a/apps/usr_le_code/usr_le_adv.c +++ b/apps/usr_le_code/usr_le_adv.c @@ -2,9 +2,10 @@ * @file usr_le_adv.c * @brief BLE 广播 / 配对 / OTA 广播切换 * @author cyWu <1917507415@qq.com> - * @date 2026.08.19 - * @version V1.1.0 + * @date 2026.09.07 + * @version V1.2.0 * @history + * - V1.2.0, 2026.09.07, cyWu, 切慢广播由 BOARD_BLE_SLOW_ADV_ENABLE / _SEC 控制 * - V1.0.0, 2026.08.03, cyWu, 首次发布 * - V1.1.0, 2026.08.19, cyWu, 对齐模组注释与助手;保留 SOC 上电绑广播策略 ******************************************************************************/ @@ -16,6 +17,7 @@ #include "bleproto.h" #include "bleproto_api.h" #include "usr_le_product.h" +#include "board_pin.h" #define LOG_TAG_CONST APP #define LOG_TAG "[LE_ADV]" @@ -255,7 +257,11 @@ u8 usr_le_adv_is_paused(void) */ void usr_ble_adv_updata(void) { +#if BOARD_BLE_SLOW_ADV_ENABLE static u16 usr_goto_slow_adv = 0; + /* usr_ble_adv_updata 周期 500ms → 秒数换拍 */ + const u16 slow_ticks = (u16)((BOARD_BLE_SLOW_ADV_SEC) * (1000u / 500u)); +#endif if (usr_le_adv_is_paused()) { /* 扫描期(app_th_scan 分时):不刷广播、不切快慢,只跑协议周期 */ @@ -273,9 +279,10 @@ void usr_ble_adv_updata(void) ble_trans_module_enable(1); } +#if BOARD_BLE_SLOW_ADV_ENABLE if (!usr_ble_is_connected()) { - /* 未连接:回连快广播(80)持续约 60s(500ms×120)后切慢广播 */ + /* 已配对断连:快广播 80 持续 BOARD_BLE_SLOW_ADV_SEC 后切 800 */ if (usr_get_adv_interval() == 80) { if ((usr_var.usr_goto_pair == 0) && usr_auth_data.paired_flag) @@ -283,13 +290,14 @@ void usr_ble_adv_updata(void) 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; + if ((slow_ticks != 0) && (usr_goto_slow_adv >= slow_ticks)) + { + usr_goto_slow_adv = 0; + usr_set_adv_interval(80 * 10); + usr_var.usr_adv_flag = 1; + log_info("ble adv -> slow after %us\n", + (unsigned)BOARD_BLE_SLOW_ADV_SEC); + } } } } @@ -302,6 +310,7 @@ void usr_ble_adv_updata(void) { usr_goto_slow_adv = 0; } +#endif if (usr_get_ota_status() == 0) { diff --git a/apps/usr_le_code/usr_le_recieve.c b/apps/usr_le_code/usr_le_recieve.c index 4e0ddfe..074e605 100644 --- a/apps/usr_le_code/usr_le_recieve.c +++ b/apps/usr_le_code/usr_le_recieve.c @@ -2,11 +2,12 @@ * @file usr_le_recieve.c * @brief BLE 收包入口:bleproto 解析后分发配网 / 对时 / JB 协议 / 组应答 * @author cyWu <1917507415@qq.com> - * @date 2026.08.19 - * @version V1.1.0 + * @date 2026.09.07 + * @version V1.2.0 * @history * - V1.0.0, 2026.08.03, cyWu, 首次发布 * - V1.1.0, 2026.08.19, cyWu, 对齐模组结构;废弃 JSON OTA;修 AUTHDELETE serviceid + * - V1.2.0, 2026.09.07, cyWu, JB 上报超 255 走 wrap_raw 自动分包;加大 txbuf ******************************************************************************/ #include "system/includes.h" @@ -27,15 +28,21 @@ #define LOG_INFO_ENABLE #include "debug.h" -/* 拼 GATT 分包:业务包 ≈ bleproto头 + V2 开销 + JB 帧(<=128),1024 足够 */ +/* 收:GATT 拼包缓冲。发:V2 + bleproto 多帧(单帧总长 247,与 ATT 对齐) */ #define USR_LE_RX_BUF_LEN 1024 -#define USR_LE_V2_WRAP_OVERHEAD 32u /* V2 头开销,JB 帧最大 128 → 约 160 */ +#define USR_LE_V2_WRAP_OVERHEAD 32u /* V2 头开销 */ +#define USR_LE_V2_MAX_LEN (512u + USR_LE_V2_WRAP_OVERHEAD) +#define USR_LE_APPDATA_PACKETLEN 247u /* 对齐 ATT_LOCAL_PAYLOAD_SIZE:8B头+239B数据 */ +#define USR_LE_APPDATA_FRAME_PAYLOAD (USR_LE_APPDATA_PACKETLEN - 8u) +#define USR_LE_TX_BUF_LEN (USR_LE_V2_MAX_LEN + \ + 8u * ((USR_LE_V2_MAX_LEN + USR_LE_APPDATA_FRAME_PAYLOAD - 1u) / \ + USR_LE_APPDATA_FRAME_PAYLOAD)) #define USR_LE_V2_CMD_REPORT 100u /* REPORTCMD_V2 内层 cmd */ #define USR_LE_V2_CMD_RUN 110u /* RUNCMD_V2 内层 cmd */ #define USR_LE_JB_CMD_OFF 4u /* 55 AA | LEN_H LEN_L | CMD */ static int encode_len = 0; -static u8 txbuf[384] = {0}; +static u8 txbuf[USR_LE_TX_BUF_LEN]; static u8 rxbuf[USR_LE_RX_BUF_LEN] = {0}; static u8 s_last_runcmd_msgid = 0; /* RUNCMD_V2 应答须回填最近 msgid */ @@ -75,7 +82,7 @@ static void usr_le_fill_rsp_header(bleproto_appdata_desc_t *out, */ static void usr_le_encode_and_send(bleproto_appdata_desc_t *desc) { - encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), desc); + encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), USR_LE_APPDATA_PACKETLEN, desc); if (encode_len > 0) { printf("encode_len = %d\n", encode_len); @@ -365,7 +372,8 @@ void ble_send_data(u8 *data, u16 len) return; } - elen = bleproto_appdata_wrap_raw(txbuf, sizeof(txbuf), &hdr, v2_buf, (uint16_t)plen); + elen = bleproto_appdata_wrap_raw(txbuf, sizeof(txbuf), USR_LE_APPDATA_PACKETLEN, + &hdr, v2_buf, (uint16_t)plen); printf("ble_send_data jb_cmd=0x%02X active=%d encode_len=%d msgid=%d\n", jb_cmd, is_active_send, elen, hdr.msgid); if (elen <= 0) diff --git a/apps/usr_periph/board_pin.h b/apps/usr_periph/board_pin.h index 06e62e3..e788fb6 100644 --- a/apps/usr_periph/board_pin.h +++ b/apps/usr_periph/board_pin.h @@ -93,6 +93,13 @@ #define BOARD_ZC_SW_POLL_1MS 0 /**< 1=额外挂真实 1ms 软件采样兜底(中断失效时滞后 ≤1ms,代价 1000Hz ISR) */ #define BOARD_ZC_DIAG_LOG 0 /**< 1=500ms 打印一次过零沿计数(台上确认中断在跑,量产出货置 0) */ +/*============================================================================*/ +/* BLE 广播:常电默认保持快广播;电池产品可开超时切慢广播 */ +/*============================================================================*/ + +#define BOARD_BLE_SLOW_ADV_ENABLE 0 /**< 0=一直快广播(80);1=断连满 BOARD_BLE_SLOW_ADV_SEC 后切慢(800) */ +#define BOARD_BLE_SLOW_ADV_SEC 60 /**< 使能后:已配对断连快广播持续秒数再切慢(本机 500ms 一拍) */ + /*============================================================================*/ /* 断连扫描(P2,第 8.2 节) */ /*============================================================================*/