fix(vd960DBN): BLE 分包粒度动态化 — 修复 offlog_query Too large noti 丢包
- 根因: MAX_BLE_DAT_RESPONSE_LEN=96 写死, MTU 协商 96 后整包 102B > MTU-3=93 peripheralChar4Notify 直接 return 丢第一包, 小程序重组不完整 - peripheral.c: 新增 peripheral_get_mtu() getter - dbn_ble_srv.c: ble_notify_chunk_max() 按 min(MTU-9,94) 动态分包 4 处 MAX_BLE_DAT_RESPONSE_LEN 统一替换 (set_response_buf/to_notify/iot_net/iot_topic) - 消除 BLE_Notify_Buf.buf[100] 写 102B 越界 2B 隐患 - 隔离 C 测试 MTU=23/96/185/517 四组全过, 重组 130B 逐字节一致
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include "net_srv.h"
|
||||
#include "offlog.h"
|
||||
extern uint16_t peripheral_get_mtu(void);
|
||||
|
||||
uint8_t g_flag_notify_temp = 0; //临时通知notify flag, 0 disable, 1 enable
|
||||
|
||||
@@ -181,6 +182,24 @@ static uint8_t set_net_info_to_ready(uint8_t * dat_dst)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
* ble_notify_chunk_max: max dat bytes per notify packet
|
||||
* follow negotiated MTU to avoid 'Too large noti' drop:
|
||||
* whole pkt = 4B header(magic/header/len/cmd) + dat + 2B ckb
|
||||
* must satisfy whole pkt <= peripheralMTU - 3 (ATT opcode+handle)
|
||||
* and whole pkt <= MAX_BLE_Notify_Buf_LEN (local buf, no overflow)
|
||||
* MTU=23 -> 14, MTU=96 -> 87, MTU>=103 -> 94
|
||||
* =============================================================
|
||||
static uint16_t ble_notify_chunk_max(void)
|
||||
{
|
||||
uint16_t _mtu = peripheral_get_mtu();
|
||||
if (_mtu < 23) _mtu = ATT_MTU_SIZE; /* fallback before negotiation */
|
||||
uint16_t _limit = _mtu - 9; /* pkt limit - header4 - ckb2 */
|
||||
if (_limit > (MAX_BLE_Notify_Buf_LEN - 6))
|
||||
_limit = MAX_BLE_Notify_Buf_LEN - 6;
|
||||
return _limit;
|
||||
}
|
||||
|
||||
void set_response_iot_net(Buf_DBN_BLE *response_dst)
|
||||
{ // config iot_net
|
||||
uint8_t ret = 0;
|
||||
@@ -205,10 +224,13 @@ void set_response_iot_net(Buf_DBN_BLE *response_dst)
|
||||
memcpy(&(response_dst->dat[i]), iot_net_info.password, strlen(iot_net_info.password));
|
||||
i += strlen(iot_net_info.password);
|
||||
response_dst->dat_len = i;
|
||||
response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
|
||||
if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
|
||||
{
|
||||
response_dst->pkg_amount += 1;
|
||||
uint16_t _chunk = ble_notify_chunk_max();
|
||||
response_dst->pkg_amount = i / _chunk;
|
||||
if((i % _chunk) > 0)
|
||||
{
|
||||
response_dst->pkg_amount += 1;
|
||||
}
|
||||
}
|
||||
response_dst->pkg_seq = 0;
|
||||
|
||||
@@ -232,10 +254,13 @@ void set_response_iot_topic(Buf_DBN_BLE *response_dst)
|
||||
memcpy(&(response_dst->dat[i]), g_iot_topic.topic_sub, strlen(g_iot_topic.topic_sub));
|
||||
i += strlen(g_iot_topic.topic_sub);
|
||||
response_dst->dat_len = i;
|
||||
response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
|
||||
if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
|
||||
{
|
||||
response_dst->pkg_amount += 1;
|
||||
uint16_t _chunk = ble_notify_chunk_max();
|
||||
response_dst->pkg_amount = i / _chunk;
|
||||
if((i % _chunk) > 0)
|
||||
{
|
||||
response_dst->pkg_amount += 1;
|
||||
}
|
||||
}
|
||||
response_dst->pkg_seq = 0;
|
||||
response_dst->flag = 1;
|
||||
@@ -250,8 +275,9 @@ uint8_t set_response_buf(Buf_DBN_BLE *response_dst, uint8_t magic, uint8_t cmd,
|
||||
response_dst->magic = magic;
|
||||
response_dst->cmd = cmd;
|
||||
|
||||
uint8_t _amount = dat_len / MAX_BLE_DAT_RESPONSE_LEN;
|
||||
if((dat_len % MAX_BLE_DAT_RESPONSE_LEN) > 0)
|
||||
uint16_t _chunk = ble_notify_chunk_max();
|
||||
uint8_t _amount = dat_len / _chunk;
|
||||
if((dat_len % _chunk) > 0)
|
||||
{
|
||||
_amount++;
|
||||
}
|
||||
@@ -369,9 +395,12 @@ uint8_t set_response_to_notify(Buf_DBN_BLE *response_ori, BLE_Notify_Buf * notif
|
||||
uint8_t _pkg_amount = response_ori->pkg_amount;
|
||||
uint8_t _pkg_seq = response_ori->pkg_seq;
|
||||
uint8_t _remain_len = response_ori->dat_len - response_ori->dat_offset;
|
||||
if(_remain_len > MAX_BLE_DAT_RESPONSE_LEN)
|
||||
{
|
||||
_remain_len = MAX_BLE_DAT_RESPONSE_LEN;
|
||||
uint16_t _chunk = ble_notify_chunk_max();
|
||||
if(_remain_len > _chunk)
|
||||
{
|
||||
_remain_len = (uint8_t)_chunk;
|
||||
}
|
||||
}
|
||||
_pkg_seq += 1;
|
||||
notify_dst->buf[1] = (_pkg_amount << 4)|(_pkg_seq);
|
||||
|
||||
Reference in New Issue
Block a user