1、对逗猫棒和喂食器的设备增加应答功能

2、对于V3协议的设备,目前只能电脑端应答,对电脑端的应答进行封包并通过BLE发送
This commit is contained in:
2026-07-30 14:43:30 +08:00
parent d8021154f2
commit 79e15a9ccc
23 changed files with 2131 additions and 1883 deletions
+134 -14
View File
@@ -3,8 +3,9 @@
* @brief USB CDC 见宝帧解析:校验后写入产品码并重广播
* @author cyWu <1917507415@qq.com>
* @date 2026.07.24
* @version V1.0.1
* @version V1.0.2
* @history
* - V1.0.2, 2026.07.28, cyWu, 非产品码命令整帧透传 BLE REPORTCMD_V2
* - V1.0.1, 2026.07.24, cyWu, CDC 中断内禁止 syscfg_write,改延时到任务上下文
* - V1.0.0, 2026.07.24, cyWu, 首次发布
******************************************************************************/
@@ -13,6 +14,7 @@
#include "app_config.h"
#include "vm.h"
#include "usr_usb_jb.h"
#include "bleproto_api.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[USB_JB]"
@@ -35,12 +37,17 @@
#define MAX_PACKAGE_LEN 128
#define JB_RB_CAPACITY 256
#define USR_PROD_MAGIC 0x5A
#define USR_JB_BLE_CMD_REPORT 100 /* 0x07/0x34/0x38 → 主动上报类 */
#define USR_JB_BLE_CMD_ACK 110 /* 0x04/0x06/0x31/0x37 → 应答类 */
#define USR_JB_BLE_TX_SZ 384
#ifndef CFG_USER_PROD_INFO
#define CFG_USER_PROD_INFO 28
#endif
extern void usr_ble_adv_init(void);
extern void usr_ble_send_data(u8 *data, u16 len);
extern u16 usr_get_conn_service(void);
/*============================================================================*/
/* 类型 */
@@ -77,6 +84,118 @@ static uint8_t s_pending_sn;
static uint8_t s_pending_prod[USR_PRODCODE_LEN];
static uint8_t s_pending_pcode[USR_PCODE_LEN];
static int s_process_timer;
static uint8_t s_ble_txbuf[USR_JB_BLE_TX_SZ];
static uint8_t s_last_ble_msgid; /* 最近一次 BLE RX 的 msgid */
void usr_ble_rx_msgid_save(uint8_t msgid)
{
s_last_ble_msgid = msgid & 0x0F;
printf("usr_ble rx msgid save=%u\n", s_last_ble_msgid);
}
uint8_t usr_ble_rx_msgid_get(void)
{
return s_last_ble_msgid;
}
/**
* @brief 按 USB JB 命令映射 ble_proto cmd / gateway_int
* @param jb_cmd USB 帧 CMDframe[4]
* @param pkt 待填充的 ble_proto 包
* @return 0 可透传, -1 不支持的命令
*/
static int usr_jb_map_ble_pkt(uint8_t jb_cmd, ble_proto_packet_t *pkt)
{
if (!pkt) {
return -1;
}
memset(pkt, 0, sizeof(*pkt));
switch (jb_cmd) {
case 0x07: /* REPORT */
case 0x34: /* OTA_COMPLETE */
case 0x38: /* OTA_STOP_MCU */
pkt->cmd = USR_JB_BLE_CMD_REPORT;
pkt->gateway_int_cnt = 0;
break;
case 0x04: /* CONTROL_ACK */
case 0x06: /* READ_ACK */
case 0x31: /* OTA_NOTIFY_ACK */
case 0x37: /* OTA_STOP_BLE_ACK */
pkt->cmd = USR_JB_BLE_CMD_ACK;
pkt->gateway_int_cnt = 2;
pkt->gateway_int[0] = 0;
pkt->gateway_int[1] = 0;
break;
default:
return -1;
}
return 0;
}
/**
* @brief 将完整 JB 帧封装为 REPORTCMD_V2 后经 BLE 发出
* @param frame 完整 55 AA 帧
* @param len 帧长度
*/
static void usr_jb_forward_to_ble(const uint8_t *frame, uint16_t len)
{
bleproto_appdata_desc_t encode_desc = {0};
ble_proto_packet_t *pkt;
uint8_t jb_cmd;
int elen;
if (!frame || len < 7 || len > MAX_PACKAGE_LEN) {
return;
}
if (usr_get_conn_service() == 0) {
printf("usr_jb ble forward skip: not connected\n");
return;
}
jb_cmd = frame[4];
pkt = &encode_desc.datast.reportcmd_v2_req;
if (usr_jb_map_ble_pkt(jb_cmd, pkt) != 0) {
printf("usr_jb ble forward ignore jb_cmd=0x%02x\n", jb_cmd);
return;
}
encode_desc.header.version = 0;
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
/* 100 上报用 REQ110 应答用 RSP */
encode_desc.header.msgtype = (pkt->cmd == USR_JB_BLE_CMD_ACK)
? BLEPROTO_APPDATA_MSGTYPE_RSP
: BLEPROTO_APPDATA_MSGTYPE_REQ;
encode_desc.header.msgid = usr_ble_rx_msgid_get();
encode_desc.header.encrypt = 0;
encode_desc.header.serviceid = (pkt->cmd == USR_JB_BLE_CMD_ACK)
? E_BLEPROTO_SERVICE_ID_RUNCMD_V2
: E_BLEPROTO_SERVICE_ID_REPORTCMD_V2;
pkt->reserved = 0;
pkt->device_int_len = 0;
pkt->device_str_len = 0;
pkt->device_bytes_len = len;
pkt->bytes_data = frame;
elen = bleproto_appdata_encode(s_ble_txbuf, sizeof(s_ble_txbuf),
sizeof(s_ble_txbuf), &encode_desc);
printf("usr_jb ble forward jb_cmd=0x%02x ble_cmd=%u msgtype=%u msgid=%u gw_cnt=%u elen=%d\n",
jb_cmd, pkt->cmd, encode_desc.header.msgtype,
encode_desc.header.msgid, pkt->gateway_int_cnt, elen);
if (elen > 0) {
usr_ble_send_data(s_ble_txbuf, (u16)elen);
printf_buf(s_ble_txbuf, elen);
} else {
printf("usr_jb ble encode fail\n");
}
}
/*============================================================================*/
/* 环形缓冲 / 校验 */
@@ -339,24 +458,25 @@ static void usr_jb_process_timeout(void *priv)
printf("usr_jb cmd=0x%02x sn=%u plen=%u\n", cmd, sn, payload_len);
printf_buf(pkt, pkt_len);
if (cmd != USR_JB_CMD_SET_PRODCODE) {
printf("usr_jb ignore cmd 0x%02x\n", cmd);
continue;
}
if (usr_jb_parse_prod_payload(&pkt[6], payload_len,
s_pending_prod, s_pending_pcode) != 0) {
printf("usr_jb set prodcode payload invalid\n");
if (cmd == USR_JB_CMD_SET_PRODCODE) {
if (usr_jb_parse_prod_payload(&pkt[6], payload_len,
s_pending_prod, s_pending_pcode) != 0) {
printf("usr_jb set prodcode payload invalid\n");
#if TCFG_USB_SLAVE_CDC_ENABLE
usr_jb_send_ack(cmd, sn, 0x01);
usr_jb_send_ack(cmd, sn, 0x01);
#endif
continue;
}
/* 缓存后统一落盘,避免同一周期多次写 flash */
s_pending_cmd = cmd;
s_pending_sn = sn;
s_pending_save = 1;
continue;
}
/* 缓存后统一落盘,避免同一周期多次写 flash */
s_pending_cmd = cmd;
s_pending_sn = sn;
s_pending_save = 1;
/* 其它命令:整帧透传到 BLE(按 JB cmd 映射 ble_proto cmd */
usr_jb_forward_to_ble(pkt, pkt_len);
} while (1);
if (!s_pending_save) {