移除静态编译文件,把协议源码移植进来
This commit is contained in:
@@ -0,0 +1,377 @@
|
||||
/******************************************************************************
|
||||
* @file usr_le_recieve.c
|
||||
* @brief BLE 收包入口:bleproto 解析后分发配网 / 对时 / JB 协议 / 组应答
|
||||
* @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, 对齐模组结构;废弃 JSON OTA;修 AUTHDELETE serviceid
|
||||
******************************************************************************/
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "app_main.h"
|
||||
#include "vm.h"
|
||||
#include "bleproto.h"
|
||||
#include "bleproto_api.h"
|
||||
#include "ble_proto.h"
|
||||
#include "usr_rtc.h"
|
||||
#include "usr_le_api.h"
|
||||
#include "jb_protocol.h"
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[USR_LE]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
/* 拼 GATT 分包:业务包 ≈ bleproto头 + V2 开销 + JB 帧(<=128),1024 足够 */
|
||||
#define USR_LE_RX_BUF_LEN 1024
|
||||
#define USR_LE_V2_WRAP_OVERHEAD 32u /* V2 头开销,JB 帧最大 128 → 约 160 */
|
||||
#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 rxbuf[USR_LE_RX_BUF_LEN] = {0};
|
||||
static u8 s_last_runcmd_msgid = 0; /* RUNCMD_V2 应答须回填最近 msgid */
|
||||
|
||||
bleproto_authsetup_req_t usr_auth_data;
|
||||
|
||||
extern void usr_ble_send_data(u8 *data, u16 len);
|
||||
extern u8 usr_ble_is_notify_ready(void);
|
||||
extern void usr_write_pair_info(void);
|
||||
extern void usr_clear_pair_info(void);
|
||||
extern void usr_jb_le_recieve_data(u8 *data, u16 len);
|
||||
extern int8_t jbReportAckCheck(u16 cmd, u8 gateway_int_cnt, int32_t gateway_int0);
|
||||
|
||||
static void usr_data_ana(bleproto_appdata_desc_t *desc);
|
||||
static void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id);
|
||||
|
||||
/**
|
||||
* @brief 填 bleproto 应答头
|
||||
* @param out 输出 desc
|
||||
* @param in 请求 desc(取 msgid)
|
||||
* @param serviceid 服务号
|
||||
*/
|
||||
static void usr_le_fill_rsp_header(bleproto_appdata_desc_t *out,
|
||||
const bleproto_appdata_desc_t *in,
|
||||
uint8_t serviceid)
|
||||
{
|
||||
out->header.version = 0;
|
||||
out->header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
||||
out->header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
||||
out->header.msgid = in->header.msgid;
|
||||
out->header.encrypt = 0;
|
||||
out->header.serviceid = serviceid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 编码并经 BLE 发出
|
||||
* @param desc 已填好的应答
|
||||
*/
|
||||
static void usr_le_encode_and_send(bleproto_appdata_desc_t *desc)
|
||||
{
|
||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), desc);
|
||||
if (encode_len > 0)
|
||||
{
|
||||
printf("encode_len = %d\n", encode_len);
|
||||
usr_ble_send_data(txbuf, encode_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("encode_len fail %d\n", encode_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 是否走网关主动上报(REPORTCMD_V2)
|
||||
* @param jb_cmd 55AA 命令字
|
||||
* @return 1=主动上报,0=RUNCMD 应答
|
||||
*/
|
||||
static uint8_t usr_le_is_gateway_report_cmd(uint8_t jb_cmd)
|
||||
{
|
||||
return (jb_cmd == CMD_REPORT ||
|
||||
jb_cmd == CMD_OTA_COMPLETE ||
|
||||
jb_cmd == CMD_OTA_STOP_MCU)
|
||||
? 1u
|
||||
: 0u;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BLE 收包入口
|
||||
* @param data 收包数据
|
||||
* @param len 数据长度
|
||||
*/
|
||||
void usr_le_data_recieve(u8 *data, u16 len)
|
||||
{
|
||||
static u16 usr_len = 0;
|
||||
/* desc 含 ycmd 等 union,放 static,避免每次收包在栈上开大块 */
|
||||
static bleproto_appdata_desc_t s_rx_desc;
|
||||
int rc_result = 0;
|
||||
|
||||
if (!data || len == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((u32)usr_len + len > sizeof(rxbuf))
|
||||
{
|
||||
printf("### rxbuf overflow, usr_len=%u len=%u, reset\n", usr_len, len);
|
||||
usr_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&rxbuf[usr_len], data, len);
|
||||
usr_len += len;
|
||||
rc_result = bleproto_appdata_decode(rxbuf, usr_len, &s_rx_desc);
|
||||
if (rc_result < 0)
|
||||
{
|
||||
printf("### invild pack\n");
|
||||
usr_len = 0;
|
||||
}
|
||||
else if (rc_result == 0)
|
||||
{
|
||||
printf("### keep recieving\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("### pack recieved ok\n");
|
||||
usr_len = 0;
|
||||
usr_data_ana(&s_rx_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析 bleproto 服务并分发
|
||||
* @param desc 已 decode 的包
|
||||
*/
|
||||
static void usr_data_ana(bleproto_appdata_desc_t *desc)
|
||||
{
|
||||
static bleproto_appdata_desc_t s_encode_desc;
|
||||
|
||||
memset(&s_encode_desc, 0, sizeof(s_encode_desc));
|
||||
printf("desc serviceid=%d msgtype=%d\n",
|
||||
desc->header.serviceid, desc->header.msgtype);
|
||||
|
||||
if (desc->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_REQ)
|
||||
{
|
||||
switch (desc->header.serviceid)
|
||||
{
|
||||
case E_BLEPROTO_SERVICE_ID_DEVICEINFO: {
|
||||
bleproto_deviceinfo_req_t *req = &desc->datast.deviceinfo_req;
|
||||
bleproto_deviceinfo_rsp_t *rsp = &s_encode_desc.datast.deviceinfo_rsp;
|
||||
|
||||
/* 网关从子设备连上开始计时,每 12 小时经 DEVICEINFO 同步一次 */
|
||||
usr_rtc_set_from_unix(req->t, (int32_t)req->gmtoff);
|
||||
|
||||
usr_le_fill_rsp_header(&s_encode_desc, desc, E_BLEPROTO_SERVICE_ID_DEVICEINFO);
|
||||
rsp->hbcycle = 1000;
|
||||
strcpy(rsp->swv, "V1.0.0.00");
|
||||
strcpy(rsp->hwv, "V1.0.0.00");
|
||||
rsp->longcon = 1;
|
||||
rsp->prototype = 4;
|
||||
usr_le_encode_and_send(&s_encode_desc);
|
||||
break;
|
||||
}
|
||||
case E_BLEPROTO_SERVICE_ID_AUTHSETUP: {
|
||||
bleproto_authsetup_rsp_t *au_rsp = &s_encode_desc.datast.authsetup_rsp;
|
||||
|
||||
printf("E_BLEPROTO_SERVICE_ID_AUTHSETUP\n");
|
||||
usr_le_fill_rsp_header(&s_encode_desc, desc, E_BLEPROTO_SERVICE_ID_AUTHSETUP);
|
||||
au_rsp->errcode = 0;
|
||||
memcpy(&usr_auth_data, &desc->datast.authsetup_req, sizeof(usr_auth_data));
|
||||
if (usr_auth_data.paired_flag == 0)
|
||||
{
|
||||
usr_write_pair_info();
|
||||
usr_var.usr_goto_pair = 0; // 新增:退出强制配网
|
||||
printf("usr_auth_data %s %s ", usr_auth_data.authcode, usr_auth_data.devid);
|
||||
printf_buf(usr_auth_data.gwmac, 6);
|
||||
}
|
||||
usr_le_encode_and_send(&s_encode_desc);
|
||||
break;
|
||||
}
|
||||
case E_BLEPROTO_SERVICE_ID_AUTHDELETE: {
|
||||
bleproto_authdelete_rsp_t *aude_rsp = &s_encode_desc.datast.authdelete_rsp;
|
||||
|
||||
printf("E_BLEPROTO_SERVICE_ID_AUTHDELETE\n");
|
||||
usr_le_fill_rsp_header(&s_encode_desc, desc, E_BLEPROTO_SERVICE_ID_AUTHDELETE);
|
||||
memcpy(aude_rsp->gwmac, usr_auth_data.gwmac, 6);
|
||||
if (!memcmp(usr_auth_data.authcode, desc->datast.authdelete_req.authcode, 32))
|
||||
{
|
||||
aude_rsp->errcode = 0;
|
||||
usr_clear_pair_info();
|
||||
}
|
||||
else
|
||||
{
|
||||
aude_rsp->errcode = 501;
|
||||
}
|
||||
usr_le_encode_and_send(&s_encode_desc);
|
||||
break;
|
||||
}
|
||||
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
||||
printf("E_BLEPROTO_SERVICE_ID_RUNCMD\n");
|
||||
break;
|
||||
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
||||
printf("E_BLEPROTO_SERVICE_ID_RUNCMD_V2\n");
|
||||
usr_run_cmd_code_v2(&desc->datast.runcmd_v2_req, desc->header.msgid);
|
||||
break;
|
||||
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
||||
/* JSON OTA 已废弃,SOC 走 JB 0x30/0x32 */
|
||||
printf("JSON OTA deprecated, use JB 0x30/0x32\n");
|
||||
break;
|
||||
default:
|
||||
printf("err !!! default event desc->header.serviceid =%d\n",
|
||||
desc->header.serviceid);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (desc->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_RSP)
|
||||
{
|
||||
switch (desc->header.serviceid)
|
||||
{
|
||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
||||
printf("E_BLEPROTO_SERVICE_ID_REPORTCMD errcode=%d\n",
|
||||
desc->datast.reportcmd_rsp.errcode);
|
||||
break;
|
||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2: {
|
||||
ble_proto_packet_t *rpt_ack = &desc->datast.reportcmd_v2_rsp;
|
||||
|
||||
printf("REPORTCMD_V2 cmd=%u cnt=%u int0=%ld\n",
|
||||
(unsigned)rpt_ack->cmd,
|
||||
(unsigned)rpt_ack->gateway_int_cnt,
|
||||
(long)((rpt_ack->gateway_int_cnt > 0) ? rpt_ack->gateway_int[0] : 0));
|
||||
jbReportAckCheck(rpt_ack->cmd,
|
||||
rpt_ack->gateway_int_cnt,
|
||||
(rpt_ack->gateway_int_cnt > 0) ? rpt_ack->gateway_int[0] : -1);
|
||||
break;
|
||||
}
|
||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||
printf("JSON OTA deprecated, use JB 0x32\n");
|
||||
break;
|
||||
default:
|
||||
printf("unhandled RSP serviceid=%d\n", desc->header.serviceid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief APP RUNCMD_V2:55AA 字节流转交 JB 协议层
|
||||
* @param runcmd_par 内层包
|
||||
* @param usr_msg_id bleproto msgid
|
||||
*/
|
||||
static void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id)
|
||||
{
|
||||
u8 jb_frame[MAX_PACKAGE_LEN];
|
||||
u16 copy_len;
|
||||
|
||||
if (!runcmd_par || !runcmd_par->bytes_data || runcmd_par->device_bytes_len == 0)
|
||||
{
|
||||
printf("usr_run_cmd_code_v2 invalid bytes, len=%u\n",
|
||||
runcmd_par ? runcmd_par->device_bytes_len : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("runcmd_par id = %d, bytes_len = %u\n",
|
||||
runcmd_par->cmd, runcmd_par->device_bytes_len);
|
||||
|
||||
copy_len = runcmd_par->device_bytes_len;
|
||||
if (copy_len > sizeof(jb_frame))
|
||||
{
|
||||
printf("usr_run_cmd_code_v2 bytes too long %u\n", copy_len);
|
||||
return;
|
||||
}
|
||||
memcpy(jb_frame, runcmd_par->bytes_data, copy_len);
|
||||
|
||||
s_last_runcmd_msgid = usr_msg_id;
|
||||
usr_jb_le_recieve_data(jb_frame, copy_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将 JB 协议帧封装为 bleproto V2 后通过 BLE 发送
|
||||
* @param data JB 协议原始帧(55 AA | LEN | CMD | ...)
|
||||
* @param len 帧长度
|
||||
* @note 主动上报(0x07/0x34/0x38) → REPORTCMD_V2;其余 → RUNCMD_V2 应答
|
||||
* 对外符号名保持 ble_send_data,供 jb_protocol 调用
|
||||
*/
|
||||
void ble_send_data(u8 *data, u16 len)
|
||||
{
|
||||
ble_proto_packet_t pkt;
|
||||
bleproto_appdata_header_t hdr;
|
||||
u8 v2_buf[MAX_PACKAGE_LEN + USR_LE_V2_WRAP_OVERHEAD];
|
||||
u8 jb_cmd;
|
||||
u8 is_active_send;
|
||||
int plen;
|
||||
int elen;
|
||||
|
||||
if (!data || len < 5)
|
||||
{
|
||||
printf("ble_send_data invalid param, len=%d\n", len);
|
||||
return;
|
||||
}
|
||||
// if (len > MAX_PACKAGE_LEN)
|
||||
// {
|
||||
// printf("ble_send_data frame too long %u\n", len);
|
||||
// return;
|
||||
// }
|
||||
if (!usr_ble_is_notify_ready())
|
||||
{
|
||||
printf("ble_send_data wait CCC cmd=0x%02X\n", data[USR_LE_JB_CMD_OFF]);
|
||||
return;
|
||||
}
|
||||
|
||||
jb_cmd = data[USR_LE_JB_CMD_OFF];
|
||||
is_active_send = usr_le_is_gateway_report_cmd(jb_cmd);
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.version = 0;
|
||||
hdr.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
||||
hdr.encrypt = 0;
|
||||
|
||||
if (is_active_send)
|
||||
{
|
||||
hdr.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
||||
hdr.msgid = 0;
|
||||
hdr.serviceid = E_BLEPROTO_SERVICE_ID_REPORTCMD_V2;
|
||||
pkt.cmd = USR_LE_V2_CMD_REPORT;
|
||||
pkt.gateway_int_cnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdr.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
||||
hdr.msgid = s_last_runcmd_msgid;
|
||||
hdr.serviceid = E_BLEPROTO_SERVICE_ID_RUNCMD_V2;
|
||||
pkt.cmd = USR_LE_V2_CMD_RUN;
|
||||
pkt.gateway_int_cnt = 2;
|
||||
pkt.gateway_int[0] = 0;
|
||||
pkt.gateway_int[1] = 0;
|
||||
}
|
||||
|
||||
pkt.device_bytes_len = len;
|
||||
pkt.bytes_data = data;
|
||||
|
||||
plen = ble_proto_pack(&pkt, v2_buf, sizeof(v2_buf));
|
||||
if (plen <= 0)
|
||||
{
|
||||
printf("ble_send_data pack fail %d\n", plen);
|
||||
return;
|
||||
}
|
||||
|
||||
elen = bleproto_appdata_wrap_raw(txbuf, sizeof(txbuf), &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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
usr_ble_send_data(txbuf, elen);
|
||||
printf_buf(txbuf, elen);
|
||||
}
|
||||
Reference in New Issue
Block a user