Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa724c6758 |
@@ -176,6 +176,7 @@
|
|||||||
<Add directory="apps/usr_le_code/thirdpart" />
|
<Add directory="apps/usr_le_code/thirdpart" />
|
||||||
<Add directory="apps/usr_jb_proto/Protocol" />
|
<Add directory="apps/usr_jb_proto/Protocol" />
|
||||||
<Add directory="apps/usr_jb_proto/Utils" />
|
<Add directory="apps/usr_jb_proto/Utils" />
|
||||||
|
<Add directory="apps/usr_periph" />
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
<Add option="-flto" />
|
<Add option="-flto" />
|
||||||
@@ -778,6 +779,10 @@
|
|||||||
<Unit filename="apps/usr_jb_proto/usr_jb_main.c">
|
<Unit filename="apps/usr_jb_proto/usr_jb_main.c">
|
||||||
<Option compilerVar="CC" />
|
<Option compilerVar="CC" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit filename="apps/usr_periph/usr_rtc.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="apps/usr_periph/usr_rtc.h" />
|
||||||
<Unit filename="apps/usr_le_code/ble_proto.h" />
|
<Unit filename="apps/usr_le_code/ble_proto.h" />
|
||||||
<Unit filename="apps/usr_le_code/bleproto.h" />
|
<Unit filename="apps/usr_le_code/bleproto.h" />
|
||||||
<Unit filename="apps/usr_le_code/bleproto_api.h" />
|
<Unit filename="apps/usr_le_code/bleproto_api.h" />
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ INCLUDES := \
|
|||||||
-Iapps/usr_le_code/thirdpart/mjson \
|
-Iapps/usr_le_code/thirdpart/mjson \
|
||||||
-Iapps/usr_jb_proto/Protocol \
|
-Iapps/usr_jb_proto/Protocol \
|
||||||
-Iapps/usr_jb_proto/Utils \
|
-Iapps/usr_jb_proto/Utils \
|
||||||
|
-Iapps/usr_periph \
|
||||||
-I$(SYS_INC_DIR) \
|
-I$(SYS_INC_DIR) \
|
||||||
|
|
||||||
|
|
||||||
@@ -619,6 +620,7 @@ c_SRC_FILES := \
|
|||||||
apps/usr_jb_proto/Utils/jb_common.c \
|
apps/usr_jb_proto/Utils/jb_common.c \
|
||||||
apps/usr_jb_proto/Utils/jb_ringbuffer.c \
|
apps/usr_jb_proto/Utils/jb_ringbuffer.c \
|
||||||
apps/usr_jb_proto/usr_jb_main.c \
|
apps/usr_jb_proto/usr_jb_main.c \
|
||||||
|
apps/usr_periph/usr_rtc.c \
|
||||||
|
|
||||||
|
|
||||||
# usr_le_code 静态库(协议编解码 + 广播/收发)
|
# usr_le_code 静态库(协议编解码 + 广播/收发)
|
||||||
|
|||||||
@@ -157,7 +157,77 @@ __attribute__((weak)) u8 iokey_filter_hook(u8 io_state)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u8 usr_first_power=0;
|
|
||||||
|
/* 开机锁键剩余确认次数;非 0 时扫描一律返回 NO_KEY */
|
||||||
|
static u8 s_boot_lock_cnt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动/关闭开机锁键
|
||||||
|
* @param release_cnt >0:松开后连续确认次数;0:关闭
|
||||||
|
*/
|
||||||
|
void iokey_boot_lock_start(u8 release_cnt)
|
||||||
|
{
|
||||||
|
#if TCFG_IOKEY_BOOT_LOCK_ENABLE
|
||||||
|
s_boot_lock_cnt = release_cnt;
|
||||||
|
#else
|
||||||
|
(void)release_cnt;
|
||||||
|
s_boot_lock_cnt = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 立即关闭开机锁键
|
||||||
|
*/
|
||||||
|
void iokey_boot_lock_stop(void)
|
||||||
|
{
|
||||||
|
s_boot_lock_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 扫描路径更新锁键:监视 port[0],松开则递减计数
|
||||||
|
* @return 1=仍锁定(应返回 NO_KEY),0=已解锁可正常扫描
|
||||||
|
*/
|
||||||
|
static u8 iokey_boot_lock_update(void)
|
||||||
|
{
|
||||||
|
#if !TCFG_IOKEY_BOOT_LOCK_ENABLE
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
u8 key_io;
|
||||||
|
u8 io_level;
|
||||||
|
u8 released;
|
||||||
|
|
||||||
|
if (!s_boot_lock_cnt)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!__this || (__this->num == 0))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_io = __this->port[0].key_type.one_io.port;
|
||||||
|
io_level = gpio_read(key_io);
|
||||||
|
if (__this->port[0].connect_way == ONE_PORT_TO_LOW)
|
||||||
|
{
|
||||||
|
released = io_level; /* 上拉输入,松开为高 */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
released = !io_level; /* 下拉输入,松开为低 */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (released)
|
||||||
|
{
|
||||||
|
s_boot_lock_cnt--;
|
||||||
|
if (s_boot_lock_cnt == 0)
|
||||||
|
{
|
||||||
|
puts("iokey boot lock released\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1; /* 本拍仍屏蔽;计数到 0 后下一拍才开放 */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
u8 io_get_key_value(void)
|
u8 io_get_key_value(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -173,12 +243,7 @@ u8 io_get_key_value(void)
|
|||||||
if (!__this->enable) {
|
if (!__this->enable) {
|
||||||
return NO_KEY;
|
return NO_KEY;
|
||||||
}
|
}
|
||||||
if(usr_first_power)
|
if (iokey_boot_lock_update()) {
|
||||||
{
|
|
||||||
if(gpio_read(IO_PORTB_01))
|
|
||||||
{
|
|
||||||
usr_first_power--;
|
|
||||||
}
|
|
||||||
return NO_KEY;
|
return NO_KEY;
|
||||||
}
|
}
|
||||||
//先扫描单IO接按键方式
|
//先扫描单IO接按键方式
|
||||||
@@ -266,7 +331,7 @@ _iokey_get_value_end:
|
|||||||
int iokey_init(const struct iokey_platform_data *iokey_data)
|
int iokey_init(const struct iokey_platform_data *iokey_data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
usr_first_power=10;
|
|
||||||
__this = iokey_data;
|
__this = iokey_data;
|
||||||
if (__this == NULL) {
|
if (__this == NULL) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -275,6 +340,12 @@ int iokey_init(const struct iokey_platform_data *iokey_data)
|
|||||||
return KEY_NOT_SUPPORT;
|
return KEY_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 长按开机场景:等电源键(port[0])松开后再开放按键扫描 */
|
||||||
|
#if TCFG_IOKEY_BOOT_LOCK_ENABLE
|
||||||
|
iokey_boot_lock_start(IOKEY_BOOT_LOCK_DEFAULT_CNT);
|
||||||
|
#else
|
||||||
|
iokey_boot_lock_stop();
|
||||||
|
#endif
|
||||||
key_io_reset();
|
key_io_reset();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
#include "chgbox_box.h"
|
#include "chgbox_box.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* usr_le_code 库钩子:由静态库导出,供 RCSP BLE 栈回调,非应用层公开 API */
|
||||||
extern void usr_le_data_recieve(u8* data,u16 len);
|
extern void usr_le_data_recieve(u8* data,u16 len);
|
||||||
extern void usr_ble_adv_init();
|
extern void usr_ble_adv_init();
|
||||||
#if 1
|
#if 1
|
||||||
@@ -526,19 +527,15 @@ static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_h
|
|||||||
|
|
||||||
void usr_ble_send_data(u8* data,u16 len)
|
void usr_ble_send_data(u8* data,u16 len)
|
||||||
{
|
{
|
||||||
|
/* CCC 未写时 ATT 发数会失败(常见 app_send_fail:-93),等主机使能通知再发 */
|
||||||
|
if (get_ble_work_state() != BLE_ST_NOTIFY_IDICATE) {
|
||||||
|
log_info("ble send skip, wait CCC");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (app_send_user_data_check(len))
|
if (app_send_user_data_check(len))
|
||||||
{
|
{
|
||||||
app_send_user_data(ATT_CHARACTERISTIC_15f1e601_a277_43fc_a484_dd39ef8a9100_01_VALUE_HANDLE, data, len, ATT_OP_AUTO_READ_CCC);
|
app_send_user_data(ATT_CHARACTERISTIC_15f1e601_a277_43fc_a484_dd39ef8a9100_01_VALUE_HANDLE, data, len, ATT_OP_AUTO_READ_CCC);
|
||||||
}
|
}
|
||||||
//printf("send rsp:");
|
|
||||||
// printf_buf(data,len);
|
|
||||||
printf("\n");
|
|
||||||
for(u8 i=0;i<len;i++)
|
|
||||||
{
|
|
||||||
printf("%c",data[i]);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
static int app_send_user_data(u16 handle, u8 *data, u16 len, u8 handle_type)
|
static int app_send_user_data(u16 handle, u8 *data, u16 len, u8 handle_type)
|
||||||
{
|
{
|
||||||
@@ -961,6 +958,16 @@ u16 usr_get_conn_service()
|
|||||||
{
|
{
|
||||||
return con_handle;
|
return con_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 主机是否已写 CCC,允许 GATT notify/indicate
|
||||||
|
* @return 1=可发数(BLE_ST_NOTIFY_IDICATE),0=还不行
|
||||||
|
*/
|
||||||
|
u8 usr_ble_is_notify_ready(void)
|
||||||
|
{
|
||||||
|
return (get_ble_work_state() == BLE_ST_NOTIFY_IDICATE) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ble_app_disconnect(void)
|
void ble_app_disconnect(void)
|
||||||
{
|
{
|
||||||
ble_disconnect(NULL);
|
ble_disconnect(NULL);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "bt_profile_cfg.h"
|
#include "bt_profile_cfg.h"
|
||||||
#include "dev_manager/dev_manager.h"
|
#include "dev_manager/dev_manager.h"
|
||||||
#include "update_loader_download.h"
|
#include "update_loader_download.h"
|
||||||
|
#include "usr_rtc.h"
|
||||||
|
|
||||||
#ifndef CONFIG_MEDIA_NEW_ENABLE
|
#ifndef CONFIG_MEDIA_NEW_ENABLE
|
||||||
#ifndef CONFIG_MEDIA_DEVELOP_ENABLE
|
#ifndef CONFIG_MEDIA_DEVELOP_ENABLE
|
||||||
@@ -292,6 +293,7 @@ void app_main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
app_var_init();
|
app_var_init();
|
||||||
|
usr_rtc_init(); /* 打开硬件 RTC,网关 DEVICEINFO 对时走 usr_rtc_set_from_unix */
|
||||||
usr_jb_init();
|
usr_jb_init();
|
||||||
|
|
||||||
#if TCFG_MC_BIAS_AUTO_ADJUST
|
#if TCFG_MC_BIAS_AUTO_ADJUST
|
||||||
|
|||||||
@@ -730,7 +730,7 @@ struct port_wakeup port0 = {
|
|||||||
.pullup_down_enable = ENABLE, //配置I/O 内部上下拉是否使能
|
.pullup_down_enable = ENABLE, //配置I/O 内部上下拉是否使能
|
||||||
.edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿
|
.edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿
|
||||||
.filter = PORT_FLT_8ms,
|
.filter = PORT_FLT_8ms,
|
||||||
.iomap = IO_PORTB_01, //唤醒口选择
|
.iomap = TCFG_IOKEY_POWER_ONE_PORT, //唤醒口选择
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
// iokey 配置 //
|
// iokey 配置 //
|
||||||
//*********************************************************************************//
|
//*********************************************************************************//
|
||||||
#define TCFG_IOKEY_ENABLE 1 //是否使能IO按键
|
#define TCFG_IOKEY_ENABLE 1 //是否使能IO按键
|
||||||
|
#define TCFG_IOKEY_BOOT_LOCK_ENABLE 1 //开机锁键:长按开机不松手时屏蔽按键,避免误触关机;不需要则改 0,默认第 0 个端口
|
||||||
|
|
||||||
#define TCFG_IOKEY_POWER_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO
|
#define TCFG_IOKEY_POWER_CONNECT_WAY ONE_PORT_TO_LOW //按键一端接低电平一端接IO
|
||||||
|
|
||||||
|
|||||||
@@ -205,42 +205,41 @@ int ble_proto_unpack(const uint8_t *buf, size_t len, ble_proto_packet_t *pkt)
|
|||||||
|
|
||||||
pkt->bytes_data = (pkt->device_bytes_len > 0) ? p : NULL;
|
pkt->bytes_data = (pkt->device_bytes_len > 0) ? p : NULL;
|
||||||
|
|
||||||
|
// printf("cmd = %d", pkt->cmd);
|
||||||
|
// printf("reserved = %d", pkt->reserved);
|
||||||
|
// printf("gateway_int_cnt = %d", pkt->gateway_int_cnt);
|
||||||
|
// printf("device_int_len = %d", pkt->device_int_len);
|
||||||
|
// printf("device_str_len = %d", pkt->device_str_len);
|
||||||
|
// printf("device_bytes_len = %d", pkt->device_bytes_len);
|
||||||
|
|
||||||
printf("cmd = %d", pkt->cmd);
|
// /* int_data 指向 buf 内部,地址未必 4 字节对齐,
|
||||||
printf("reserved = %d", pkt->reserved);
|
// * 不能直接解引用 int32_t*(对齐访问会触发硬件异常);
|
||||||
printf("gateway_int_cnt = %d", pkt->gateway_int_cnt);
|
// * 必须按字节读取,用 get_be32 还原数值 */
|
||||||
printf("device_int_len = %d", pkt->device_int_len);
|
// if (pkt->int_data && pkt->device_int_len >= 4) {
|
||||||
printf("device_str_len = %d", pkt->device_str_len);
|
// const uint8_t *ip = (const uint8_t *)pkt->int_data;
|
||||||
printf("device_bytes_len = %d", pkt->device_bytes_len);
|
// printf("int_data = ");
|
||||||
|
// for (uint16_t i = 0; i < pkt->device_int_len / 4u; i++) {
|
||||||
/* int_data 指向 buf 内部,地址未必 4 字节对齐,
|
// printf("%08X ", (unsigned int)get_be32(ip + (uint32_t)i * 4u));
|
||||||
* 不能直接解引用 int32_t*(对齐访问会触发硬件异常);
|
// }
|
||||||
* 必须按字节读取,用 get_be32 还原数值 */
|
// printf("\n");
|
||||||
if (pkt->int_data && pkt->device_int_len >= 4) {
|
// }
|
||||||
const uint8_t *ip = (const uint8_t *)pkt->int_data;
|
// /* str_data / bytes_data 不保证有 '\0',用 printf_buf 打印 hex */
|
||||||
printf("int_data = ");
|
// if (pkt->str_data && pkt->device_str_len > 0) {
|
||||||
for (uint16_t i = 0; i < pkt->device_int_len / 4u; i++) {
|
// printf("str_data = ");
|
||||||
printf("%08X ", (unsigned int)get_be32(ip + (uint32_t)i * 4u));
|
// for (size_t i = 0; i < pkt->device_str_len; i++) {
|
||||||
}
|
// printf("%02X ", *(pkt->str_data + i));
|
||||||
printf("\n");
|
// }
|
||||||
}
|
// printf("\n");
|
||||||
/* str_data / bytes_data 不保证有 '\0',用 printf_buf 打印 hex */
|
// }
|
||||||
if (pkt->str_data && pkt->device_str_len > 0) {
|
// if (pkt->bytes_data && pkt->device_bytes_len > 0) {
|
||||||
printf("str_data = ");
|
// printf("bytes_data = ");
|
||||||
for (size_t i = 0; i < pkt->device_str_len; i++) {
|
// for (size_t i = 0; i < pkt->device_bytes_len; i++) {
|
||||||
printf("%02X ", *(pkt->str_data + i));
|
// printf("%02X ", *(pkt->bytes_data + i));
|
||||||
}
|
// }
|
||||||
printf("\n");
|
// printf("\n");
|
||||||
}
|
// }
|
||||||
if (pkt->bytes_data && pkt->device_bytes_len > 0) {
|
// printf("crc = %04X", crc_recv);
|
||||||
printf("bytes_data = ");
|
// printf("\n");
|
||||||
for (size_t i = 0; i < pkt->device_bytes_len; i++) {
|
|
||||||
printf("%02X ", *(pkt->bytes_data + i));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
printf("crc = %04X", crc_recv);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return BLE_PROTO_OK;
|
return BLE_PROTO_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-30
@@ -222,106 +222,113 @@ int bleproto_appdata_encode(uint8_t *txbuf,
|
|||||||
int rc;
|
int rc;
|
||||||
uint16_t txbuf_size = size;
|
uint16_t txbuf_size = size;
|
||||||
|
|
||||||
bleproto_appdata_t appdata;
|
/*
|
||||||
|
* appdata.data[] 在 SMALL 模式下约 2.3KB,供 JSON/OTA 编码中间缓冲。
|
||||||
|
* JB 55AA 透传可走 bleproto_appdata_wrap_raw,不必经本函数。
|
||||||
|
* 此处用 static,避免在调用方任务栈上临时分配。
|
||||||
|
*/
|
||||||
|
static bleproto_appdata_t s_enc_appdata;
|
||||||
|
bleproto_appdata_t *appdata = &s_enc_appdata;
|
||||||
|
|
||||||
/* header */
|
/* header */
|
||||||
{
|
{
|
||||||
appdata.header = desc->header;
|
appdata->header = desc->header;
|
||||||
}
|
}
|
||||||
/* data */
|
/* data */
|
||||||
if (appdata.header.msgtype == BLEPROTO_APPDATA_MSGTYPE_REQ)
|
if (appdata->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_REQ)
|
||||||
{
|
{
|
||||||
switch (appdata.header.serviceid)
|
switch (appdata->header.serviceid)
|
||||||
{
|
{
|
||||||
case E_BLEPROTO_SERVICE_ID_DEVICEINFO:
|
case E_BLEPROTO_SERVICE_ID_DEVICEINFO:
|
||||||
rc = bleproto_encjson_deviceinfo_req(&desc->datast.deviceinfo_req,
|
rc = bleproto_encjson_deviceinfo_req(&desc->datast.deviceinfo_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHSETUP:
|
case E_BLEPROTO_SERVICE_ID_AUTHSETUP:
|
||||||
rc = bleproto_encjson_authsetup_req(&desc->datast.authsetup_req,
|
rc = bleproto_encjson_authsetup_req(&desc->datast.authsetup_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHDELETE:
|
case E_BLEPROTO_SERVICE_ID_AUTHDELETE:
|
||||||
rc = bleproto_encjson_authdelete_req(&desc->datast.authdelete_req,
|
rc = bleproto_encjson_authdelete_req(&desc->datast.authdelete_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
||||||
rc = bleproto_encjson_runcmd_req(&desc->datast.runcmd_req,
|
rc = bleproto_encjson_runcmd_req(&desc->datast.runcmd_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
||||||
rc = bleproto_encjson_reportcmd_req(&desc->datast.reportcmd_req,
|
rc = bleproto_encjson_reportcmd_req(&desc->datast.reportcmd_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_DOACTION:
|
case E_BLEPROTO_SERVICE_ID_DOACTION:
|
||||||
rc = bleproto_encjson_doaction_req(&desc->datast.doaction_req,
|
rc = bleproto_encjson_doaction_req(&desc->datast.doaction_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
||||||
rc = bleproto_encjson_otanotify_req(&desc->datast.otanotify_req,
|
rc = bleproto_encjson_otanotify_req(&desc->datast.otanotify_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||||
rc = bleproto_encjson_otadata_req(&desc->datast.otadata_req,
|
rc = bleproto_encjson_otadata_req(&desc->datast.otadata_req,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.runcmd_v2_req, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.runcmd_v2_req, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.reportcmd_v2_req, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.reportcmd_v2_req, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.otadata_v2_req, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.otadata_v2_req, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unkown serviceid */
|
/* unkown serviceid */
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (appdata.header.msgtype == BLEPROTO_APPDATA_MSGTYPE_RSP)
|
else if (appdata->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_RSP)
|
||||||
{
|
{
|
||||||
switch (appdata.header.serviceid)
|
switch (appdata->header.serviceid)
|
||||||
{
|
{
|
||||||
case E_BLEPROTO_SERVICE_ID_DEVICEINFO:
|
case E_BLEPROTO_SERVICE_ID_DEVICEINFO:
|
||||||
rc = bleproto_encjson_deviceinfo_rsp(&desc->datast.deviceinfo_rsp,
|
rc = bleproto_encjson_deviceinfo_rsp(&desc->datast.deviceinfo_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHSETUP:
|
case E_BLEPROTO_SERVICE_ID_AUTHSETUP:
|
||||||
rc = bleproto_encjson_authsetup_rsp(&desc->datast.authsetup_rsp,
|
rc = bleproto_encjson_authsetup_rsp(&desc->datast.authsetup_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHDELETE:
|
case E_BLEPROTO_SERVICE_ID_AUTHDELETE:
|
||||||
rc = bleproto_encjson_authdelete_rsp(&desc->datast.authdelete_rsp,
|
rc = bleproto_encjson_authdelete_rsp(&desc->datast.authdelete_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
||||||
rc = bleproto_encjson_runcmd_rsp(&desc->datast.runcmd_rsp,
|
rc = bleproto_encjson_runcmd_rsp(&desc->datast.runcmd_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
||||||
rc = bleproto_encjson_reportcmd_rsp(&desc->datast.reportcmd_rsp,
|
rc = bleproto_encjson_reportcmd_rsp(&desc->datast.reportcmd_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_DOACTION:
|
case E_BLEPROTO_SERVICE_ID_DOACTION:
|
||||||
rc = bleproto_encjson_doaction_rsp(&desc->datast.doaction_rsp,
|
rc = bleproto_encjson_doaction_rsp(&desc->datast.doaction_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
||||||
rc = bleproto_encjson_otanotify_rsp(&desc->datast.otanotify_rsp,
|
rc = bleproto_encjson_otanotify_rsp(&desc->datast.otanotify_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||||
rc = bleproto_encbin_otadata_rsp(&desc->datast.otadata_rsp,
|
rc = bleproto_encbin_otadata_rsp(&desc->datast.otadata_rsp,
|
||||||
appdata.data);
|
appdata->data);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.runcmd_v2_rsp, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.runcmd_v2_rsp, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.reportcmd_v2_rsp, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.reportcmd_v2_rsp, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
||||||
rc = ble_proto_pack(&desc->datast.otadata_v2_rsp, appdata.data, sizeof(appdata.data));
|
rc = ble_proto_pack(&desc->datast.otadata_v2_rsp, appdata->data, sizeof(appdata->data));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unkown serviceid */
|
/* unkown serviceid */
|
||||||
@@ -340,10 +347,10 @@ int bleproto_appdata_encode(uint8_t *txbuf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* datalen */
|
/* datalen */
|
||||||
appdata.header.datalen = (uint16_t)rc;
|
appdata->header.datalen = (uint16_t)rc;
|
||||||
|
|
||||||
/* appdata_serialize */
|
/* appdata_serialize */
|
||||||
return bleproto_appdata_serialize(&appdata, packetlen, txbuf, txbuf_size);
|
return bleproto_appdata_serialize(appdata, packetlen, txbuf, txbuf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bleproto_appdata_decode(uint8_t *rxbuf,
|
int bleproto_appdata_decode(uint8_t *rxbuf,
|
||||||
|
|||||||
@@ -671,6 +671,55 @@ int bleproto_appdata_serialize(bleproto_appdata_t *appdata,
|
|||||||
return (offset);
|
return (offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bleproto_appdata_wrap_raw(uint8_t *txbuf,
|
||||||
|
uint16_t txbuf_size,
|
||||||
|
const bleproto_appdata_header_t *header,
|
||||||
|
const uint8_t *payload,
|
||||||
|
uint16_t payload_len)
|
||||||
|
{
|
||||||
|
uint16_t total;
|
||||||
|
|
||||||
|
if (!txbuf || !header) {
|
||||||
|
BLEPROTO_T_E("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");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
total = (uint16_t)(BLEPROTO_APPDATA_HEADR_LEN + payload_len);
|
||||||
|
if (txbuf_size < total) {
|
||||||
|
BLEPROTO_T_E("txbuf too short");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)total;
|
||||||
|
}
|
||||||
|
|
||||||
int bleproto_appdata_deserialize(uint8_t * buf,
|
int bleproto_appdata_deserialize(uint8_t * buf,
|
||||||
uint16_t len,
|
uint16_t len,
|
||||||
bleproto_appdata_t *appdata)
|
bleproto_appdata_t *appdata)
|
||||||
@@ -1958,8 +2007,12 @@ int bleproto_encbin_otadata_rsp(const bleproto_otadata_rsp_t *p,
|
|||||||
data[offset++] = (uint8_t)((p->len >> 16) & 0xFF);
|
data[offset++] = (uint8_t)((p->len >> 16) & 0xFF);
|
||||||
data[offset++] = (uint8_t)((p->len >> 24) & 0xFF);
|
data[offset++] = (uint8_t)((p->len >> 24) & 0xFF);
|
||||||
|
|
||||||
/* serialize data */
|
/* serialize data(data 为外部指针,不再内嵌数组) */
|
||||||
if (p->len > 0 && p->len <= BLEPROTO_APPDATA_OTADATA_SZ) {
|
if (p->len > 0 && p->len <= BLEPROTO_APPDATA_OTADATA_SZ) {
|
||||||
|
if (!p->data) {
|
||||||
|
BLEPROTO_T_E("otadata_rsp.data is NULL");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
memcpy(&data[offset], p->data, p->len);
|
memcpy(&data[offset], p->data, p->len);
|
||||||
offset += p->len;
|
offset += p->len;
|
||||||
}
|
}
|
||||||
@@ -2984,10 +3037,12 @@ int bleproto_debin_otadata_rsp(const uint8_t * data,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* deserialize data */
|
/* 零拷贝:指向输入缓冲,调用方须在下次 decode 前用完 */
|
||||||
if (rsp->len > 0) {
|
if (rsp->len > 0) {
|
||||||
memcpy(rsp->data, &data[offset], rsp->len);
|
rsp->data = &data[offset];
|
||||||
offset += rsp->len;
|
offset += rsp->len;
|
||||||
|
} else {
|
||||||
|
rsp->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
|||||||
@@ -483,7 +483,12 @@ typedef struct bleproto_otadata_rsp {
|
|||||||
int id; ///< file_id
|
int id; ///< file_id
|
||||||
int32_t offset; ///< 当前读取到的数据偏移
|
int32_t offset; ///< 当前读取到的数据偏移
|
||||||
uint32_t len; ///< 当次读取数据的大小
|
uint32_t len; ///< 当次读取数据的大小
|
||||||
uint8_t data[BLEPROTO_APPDATA_OTADATA_SZ]; ///< 读取的数据
|
/**
|
||||||
|
* 固件数据指针(不内嵌大数组,避免 bleproto_appdata_desc_t 膨胀到 2KB+)
|
||||||
|
* - decode:指向 appdata 内部缓冲(零拷贝),下次 decode 前有效
|
||||||
|
* - encode:由调用方提供可读缓冲
|
||||||
|
*/
|
||||||
|
const uint8_t *data;
|
||||||
} bleproto_otadata_rsp_t;
|
} bleproto_otadata_rsp_t;
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* Public Data */
|
/* Public Data */
|
||||||
@@ -580,6 +585,22 @@ int bleproto_appdata_serialize(bleproto_appdata_t *appdata,
|
|||||||
uint8_t * buf,
|
uint8_t * buf,
|
||||||
uint16_t size);
|
uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将已打包好的 payload 包装成单帧 appdata(不分包)
|
||||||
|
* @param txbuf 输出缓冲
|
||||||
|
* @param txbuf_size 输出缓冲大小
|
||||||
|
* @param header 应用层头(datalen/totalframe/frameseq 由本函数填写)
|
||||||
|
* @param payload 已序列化的 service 数据;可为 NULL(payload_len==0)
|
||||||
|
* @param payload_len payload 长度,须 <=255(单帧 pthis_frame_len 为 u8)
|
||||||
|
* @return >0 总字节数;<0 失败
|
||||||
|
* @note 小包场景(JB 55AA 透传等)用此接口,避免 bleproto_appdata_t 大缓冲
|
||||||
|
*/
|
||||||
|
int bleproto_appdata_wrap_raw(uint8_t *txbuf,
|
||||||
|
uint16_t txbuf_size,
|
||||||
|
const bleproto_appdata_header_t *header,
|
||||||
|
const uint8_t *payload,
|
||||||
|
uint16_t payload_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 反序列化应用数据
|
* @brief 反序列化应用数据
|
||||||
*
|
*
|
||||||
|
|||||||
Binary file not shown.
+146
-77
@@ -1,54 +1,89 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* @file usr_le_adv.c
|
||||||
|
* @brief BLE 广播 / 配对 / OTA 广播切换
|
||||||
|
* @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, 对齐模组注释与助手;保留 SOC 上电绑广播策略
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
#include "system/includes.h"
|
#include "system/includes.h"
|
||||||
#include "app_config.h"
|
#include "app_config.h"
|
||||||
#include "asm/pwm_led.h"
|
|
||||||
#include "tone_player.h"
|
|
||||||
#include "ui_manage.h"
|
|
||||||
#include "app_main.h"
|
#include "app_main.h"
|
||||||
#include "app_task.h"
|
|
||||||
#include "asm/charge.h"
|
|
||||||
#include "app_power_manage.h"
|
|
||||||
#include "app_charge.h"
|
|
||||||
#include "user_cfg.h"
|
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "bleproto.h"
|
#include "bleproto.h"
|
||||||
#include "bleproto_api.h"
|
#include "bleproto_api.h"
|
||||||
#include "usr_le_product.h"
|
#include "usr_le_product.h"
|
||||||
|
|
||||||
#define LOG_TAG_CONST APP
|
#define LOG_TAG_CONST APP
|
||||||
#define LOG_TAG "[APP]"
|
#define LOG_TAG "[LE_ADV]"
|
||||||
#define LOG_ERROR_ENABLE
|
#define LOG_ERROR_ENABLE
|
||||||
#define LOG_DEBUG_ENABLE
|
#define LOG_DEBUG_ENABLE
|
||||||
#define LOG_INFO_ENABLE
|
#define LOG_INFO_ENABLE
|
||||||
/* #define LOG_DUMP_ENABLE */
|
|
||||||
#define LOG_CLI_ENABLE
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
extern u8 muti_adv_data[31];//={0};
|
/******************************************************************************
|
||||||
|
* 广播相关三个标志(务必区分):
|
||||||
|
*
|
||||||
|
* 1) usr_auth_data.paired_flag —— 配网结果(存 VM,掉电保持)
|
||||||
|
* - 0:未配网
|
||||||
|
* - 1:已配网(三元组已保存)
|
||||||
|
*
|
||||||
|
* 2) usr_var.usr_goto_pair —— 是否主动进入配网流程(RAM,掉电丢失)
|
||||||
|
* - 0:非配网流程
|
||||||
|
* - 1:app_main 上电 / usr_goto_pair_mode() 触发,发【绑定广播】
|
||||||
|
*
|
||||||
|
* 3) usr_var.usr_adv_flag —— 广播内容是否需要刷新到协议栈(一次性)
|
||||||
|
* - 1:usr_ble_adv_updata() 会重新 set adv data 并 enable
|
||||||
|
* - 0:本周期不刷新
|
||||||
|
*
|
||||||
|
* SOC 决策表(与模组不同:未配网也发绑定广播,便于上电配网):
|
||||||
|
* usr_goto_pair==1 → 绑定广播
|
||||||
|
* paired_flag==0 → 绑定广播
|
||||||
|
* paired_flag==1 → 回连广播
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
extern u8 muti_adv_data[31];
|
||||||
extern u8 muti_adv_data_len;
|
extern u8 muti_adv_data_len;
|
||||||
|
|
||||||
/* 定义在 usr_le_recieve.c,库内共用,不对外导出 */
|
/* 定义在 usr_le_recieve.c,库内共用,不对外导出 */
|
||||||
extern bleproto_authsetup_req_t usr_auth_data;
|
extern bleproto_authsetup_req_t usr_auth_data;
|
||||||
|
|
||||||
extern u8 usr_get_full();
|
extern u16 usr_get_conn_service(void);
|
||||||
extern u16 usr_get_conn_service();
|
|
||||||
extern int muti_make_set_adv_data(u8 *data, u8 data_len);
|
extern int muti_make_set_adv_data(u8 *data, u8 data_len);
|
||||||
extern u8 usr_get_ldoin_all();
|
extern int muti_make_set_adv_data_updata(void);
|
||||||
|
extern void usr_set_adv_interval(u16 val);
|
||||||
|
extern u16 usr_get_adv_interval(void);
|
||||||
|
extern void ble_multi_trans_disconnect(void);
|
||||||
|
extern void ble_trans_module_enable(u8 flag);
|
||||||
|
extern void usr_timer_loop(void);
|
||||||
|
extern u8 usr_get_ota_status(void);
|
||||||
|
extern void usr_ota_exit(void);
|
||||||
|
|
||||||
void usr_ble_adv_updata();
|
void usr_ble_adv_init(void);
|
||||||
|
void usr_ble_adv_updata(void);
|
||||||
|
|
||||||
static int le_timer_handle = 0;
|
static int le_timer_handle = 0;
|
||||||
static int le_timer_handle2=0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
extern u8 get_ldo5v_online_hw(void);
|
* @brief BLE 是否已连接
|
||||||
extern u8 usr_get_work_status();
|
* @return 1=已连接,0=未连接
|
||||||
extern void usr_printf_sta();
|
*/
|
||||||
extern int muti_make_set_adv_data_updata();
|
uint8_t usr_ble_is_connected(void)
|
||||||
|
|
||||||
void usr_get_pair_info()
|
|
||||||
{
|
{
|
||||||
int ret = 0xffff;
|
return (usr_get_conn_service() != 0) ? 1u : 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从 VM 读取配对信息到 usr_auth_data
|
||||||
|
* @note 失败则清零,并将 paired_flag 置 0 写回
|
||||||
|
*/
|
||||||
|
void usr_get_pair_info(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
ret = syscfg_read(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
ret = syscfg_read(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
@@ -57,33 +92,44 @@ void usr_get_pair_info()
|
|||||||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void usr_write_pair_info()
|
|
||||||
|
/**
|
||||||
|
* @brief 标记已配网并保存三元组到 VM
|
||||||
|
* @note AUTHSETUP 成功后调用,paired_flag = 1
|
||||||
|
*/
|
||||||
|
void usr_write_pair_info(void)
|
||||||
{
|
{
|
||||||
usr_auth_data.paired_flag = 1;
|
usr_auth_data.paired_flag = 1;
|
||||||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_clear_pair_info()
|
/**
|
||||||
|
* @brief 清除配对信息并延时复位
|
||||||
|
*/
|
||||||
|
void usr_clear_pair_info(void)
|
||||||
{
|
{
|
||||||
printf("usr_clear_pair_info\n");
|
printf("usr_clear_pair_info_reset\n");
|
||||||
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
||||||
usr_auth_data.paired_flag = 0;
|
usr_auth_data.paired_flag = 0;
|
||||||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||||||
sys_timeout_add(NULL, cpu_reset, 600);
|
sys_timeout_add(NULL, cpu_reset, 600);
|
||||||
}
|
}
|
||||||
void usr_clear_pair_info_noreset()
|
|
||||||
|
/**
|
||||||
|
* @brief 清除配对信息但不复位(用于重新配网)
|
||||||
|
*/
|
||||||
|
void usr_clear_pair_info_noreset(void)
|
||||||
{
|
{
|
||||||
printf("usr_clear_pair_info2\n");
|
printf("usr_clear_pair_info_noreset\n");
|
||||||
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
memset(&usr_auth_data, 0x00, sizeof(usr_auth_data));
|
||||||
usr_auth_data.paired_flag = 0;
|
usr_auth_data.paired_flag = 0;
|
||||||
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
syscfg_write(CFG_USER_PAIR_INFO, (u8 *)&usr_auth_data, sizeof(usr_auth_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void usr_set_adv_interval(u16 val);
|
/**
|
||||||
extern u16 usr_get_adv_interval();
|
* @brief 进入配网模式:清配对 + 置 usr_goto_pair + 发绑定广播
|
||||||
extern void ble_multi_trans_disconnect(void);
|
*/
|
||||||
void usr_ble_adv_init();
|
void usr_goto_pair_mode(void)
|
||||||
void usr_goto_pair_mode()
|
|
||||||
{
|
{
|
||||||
ble_multi_trans_disconnect();
|
ble_multi_trans_disconnect();
|
||||||
usr_clear_pair_info_noreset();
|
usr_clear_pair_info_noreset();
|
||||||
@@ -92,8 +138,23 @@ void usr_goto_pair_mode()
|
|||||||
usr_ble_adv_init();
|
usr_ble_adv_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 断开 BLE 并停止广播(复位/重启前)
|
||||||
|
*/
|
||||||
|
void usr_ble_disconnect_and_stop_adv(void)
|
||||||
|
{
|
||||||
|
printf("usr_ble_disconnect_and_stop_adv\n");
|
||||||
|
ble_multi_trans_disconnect();
|
||||||
|
usr_var.usr_goto_pair = 0;
|
||||||
|
usr_var.usr_adv_flag = 0;
|
||||||
|
ble_trans_module_enable(0);
|
||||||
|
}
|
||||||
|
|
||||||
void usr_ble_adv_init()
|
/**
|
||||||
|
* @brief 按当前标志刷新广播策略并启动周期更新
|
||||||
|
* @note 见文件头「三个标志」;SOC 未配网也发绑定广播
|
||||||
|
*/
|
||||||
|
void usr_ble_adv_init(void)
|
||||||
{
|
{
|
||||||
int8_t txpower = 0;
|
int8_t txpower = 0;
|
||||||
uint8_t manucode[BLEPROTO_ADV_TLV_LENGTH_MANUCODE] = {0};
|
uint8_t manucode[BLEPROTO_ADV_TLV_LENGTH_MANUCODE] = {0};
|
||||||
@@ -106,16 +167,18 @@ void usr_ble_adv_init()
|
|||||||
memcpy(pcode, g_usr_le_pcode, BLE_PROTO_ADV_LENGTH_PCODE);
|
memcpy(pcode, g_usr_le_pcode, BLE_PROTO_ADV_LENGTH_PCODE);
|
||||||
|
|
||||||
usr_set_adv_interval(80);
|
usr_set_adv_interval(80);
|
||||||
if(usr_var.usr_ota_succ_flag)return;
|
if (usr_var.usr_ota_succ_flag)
|
||||||
//muti_adv_data
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (usr_var.usr_goto_pair)
|
if (usr_var.usr_goto_pair)
|
||||||
{
|
{
|
||||||
/* app_main 上电已置 usr_goto_pair=1 并清配对信息,此处发绑定广播供网关配网 */
|
/* app_main 上电已置 usr_goto_pair=1 并清配对信息,此处发绑定广播供网关配网 */
|
||||||
usr_clear_pair_info_noreset();
|
usr_clear_pair_info_noreset();
|
||||||
printf("power on force to par flag= %d\n",usr_auth_data.paired_flag);
|
printf("goto pair bind adv, paired_flag=%d\n", usr_auth_data.paired_flag);
|
||||||
{
|
muti_adv_data_len = bleproto_advdata_encode4bind(muti_adv_data, txpower,
|
||||||
muti_adv_data_len=bleproto_advdata_encode4bind(muti_adv_data,txpower,manucode,pcode,prodcode);
|
manucode, pcode, prodcode);
|
||||||
}
|
|
||||||
usr_var.usr_adv_flag = 1;
|
usr_var.usr_adv_flag = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -123,44 +186,44 @@ void usr_ble_adv_init()
|
|||||||
usr_get_pair_info();
|
usr_get_pair_info();
|
||||||
if (usr_auth_data.paired_flag == 0)
|
if (usr_auth_data.paired_flag == 0)
|
||||||
{
|
{
|
||||||
muti_adv_data_len=bleproto_advdata_encode4bind(muti_adv_data,txpower,manucode,pcode,prodcode);
|
/* SOC:未配网也发绑定广播(模组此处为不广播) */
|
||||||
|
muti_adv_data_len = bleproto_advdata_encode4bind(muti_adv_data, txpower,
|
||||||
|
manucode, pcode, prodcode);
|
||||||
usr_var.usr_adv_flag = 0;
|
usr_var.usr_adv_flag = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(gmac, usr_auth_data.gwmac, 6);
|
memcpy(gmac, usr_auth_data.gwmac, 6);
|
||||||
muti_adv_data_len=bleproto_advdata_encode4reconn(muti_adv_data,txpower,gmac,manucode,pcode,prodcode);
|
muti_adv_data_len = bleproto_advdata_encode4reconn(muti_adv_data, txpower, gmac,
|
||||||
|
manucode, pcode, prodcode);
|
||||||
usr_var.usr_adv_flag = 1;
|
usr_var.usr_adv_flag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usr_ble_adv_updata();
|
usr_ble_adv_updata();
|
||||||
if(le_timer_handle==0)le_timer_handle = sys_timer_add(NULL, usr_ble_adv_updata, 500);
|
if (le_timer_handle == 0)
|
||||||
|
{
|
||||||
|
le_timer_handle = sys_timer_add(NULL, usr_ble_adv_updata, 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 usr_get_pair_flag()
|
/**
|
||||||
|
* @brief 获取是否已配网
|
||||||
|
* @return 1=已配网,0=未配网
|
||||||
|
*/
|
||||||
|
u8 usr_get_pair_flag(void)
|
||||||
{
|
{
|
||||||
return usr_auth_data.paired_flag;
|
return usr_auth_data.paired_flag;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void usr_reconn_adv()
|
/**
|
||||||
|
* @brief 周期处理广播刷新(由 500ms 定时器调用)
|
||||||
|
* @note 仅当 usr_adv_flag==1 时:停广播 → 写入 muti_adv_data → 再开广播
|
||||||
|
*/
|
||||||
|
void usr_ble_adv_updata(void)
|
||||||
{
|
{
|
||||||
int8_t txpower = 0;
|
|
||||||
uint8_t gmac[6]={0};
|
|
||||||
uint8_t manucode[BLEPROTO_ADV_TLV_LENGTH_MANUCODE] = { 0 };
|
|
||||||
uint8_t prodcode[BLEPROTO_ADV_TLV_LENGTH_PRODCODE] = {'C', 'B', 'F', 'D'};
|
|
||||||
uint8_t pcode[6]={'P','C','B','F','D','0'};
|
|
||||||
memcpy(gmac,usr_auth_data.gwmac,6);
|
|
||||||
muti_adv_data_len=bleproto_advdata_encode4reconn(muti_adv_data,txpower,gmac,manucode,pcode,prodcode);
|
|
||||||
usr_adv_flag=1;
|
|
||||||
}*/
|
|
||||||
extern void ble_trans_module_enable(u8 flag);
|
|
||||||
extern void usr_timer_loop();
|
|
||||||
extern u8 usr_get_ota_status();
|
|
||||||
void usr_ble_adv_updata()
|
|
||||||
{
|
|
||||||
//printf("usr_ble_adv_updata\n");
|
|
||||||
static u16 usr_goto_slow_adv = 0;
|
static u16 usr_goto_slow_adv = 0;
|
||||||
|
|
||||||
if (usr_var.usr_adv_flag)
|
if (usr_var.usr_adv_flag)
|
||||||
{
|
{
|
||||||
ble_trans_module_enable(0);
|
ble_trans_module_enable(0);
|
||||||
@@ -171,11 +234,12 @@ void usr_ble_adv_updata()
|
|||||||
ble_trans_module_enable(1);
|
ble_trans_module_enable(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(usr_get_conn_service()==0)
|
if (!usr_ble_is_connected())
|
||||||
{
|
{
|
||||||
|
/* 未连接:回连快广播(80)持续约 60s(500ms×120)后切慢广播 */
|
||||||
if (usr_get_adv_interval() == 80)
|
if (usr_get_adv_interval() == 80)
|
||||||
{
|
{
|
||||||
if((usr_var.usr_goto_pair==0)&&(usr_auth_data.paired_flag))
|
if ((usr_var.usr_goto_pair == 0) && usr_auth_data.paired_flag)
|
||||||
{
|
{
|
||||||
if (usr_var.usr_ota_succ_flag == 0)
|
if (usr_var.usr_ota_succ_flag == 0)
|
||||||
{
|
{
|
||||||
@@ -200,12 +264,14 @@ void usr_ble_adv_updata()
|
|||||||
usr_goto_slow_adv = 0;
|
usr_goto_slow_adv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (usr_get_ota_status() == 0)
|
if (usr_get_ota_status() == 0)
|
||||||
{
|
{
|
||||||
if(usr_get_conn_service()==0)
|
if (!usr_ble_is_connected())
|
||||||
{
|
{
|
||||||
if(usr_var.usr_ota_succ_flag==0)usr_ota_exit();
|
if (usr_var.usr_ota_succ_flag == 0)
|
||||||
|
{
|
||||||
|
usr_ota_exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,36 +279,36 @@ void usr_ble_adv_updata()
|
|||||||
usr_timer_loop();
|
usr_timer_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_soft_off()
|
void usr_soft_off(void)
|
||||||
{
|
{
|
||||||
sys_enter_soft_poweroff(NULL);
|
sys_enter_soft_poweroff(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_ble_adv_updata_OTA()
|
void usr_ble_adv_updata_OTA(void)
|
||||||
{
|
{
|
||||||
//printf("usr_ble_adv_updata\n");
|
|
||||||
ble_trans_module_enable(0);
|
ble_trans_module_enable(0);
|
||||||
usr_var.usr_adv_flag = 0;
|
usr_var.usr_adv_flag = 0;
|
||||||
|
|
||||||
extern u8 usr_mac_addr[6];
|
extern u8 usr_mac_addr[6];
|
||||||
extern int le_controller_set_mac(void *addr);
|
extern int le_controller_set_mac(void *addr);
|
||||||
usr_mac_addr[0] = usr_mac_addr[0] + 1;
|
usr_mac_addr[0] = usr_mac_addr[0] + 1;
|
||||||
le_controller_set_mac(usr_mac_addr); //修改BLE地址
|
le_controller_set_mac(usr_mac_addr);
|
||||||
muti_make_set_adv_data_updata();
|
muti_make_set_adv_data_updata();
|
||||||
printf("###muti_adv_data = ");
|
printf("###muti_adv_data = ");
|
||||||
printf_buf(muti_adv_data, muti_adv_data_len);
|
printf_buf(muti_adv_data, muti_adv_data_len);
|
||||||
ble_trans_module_enable(1);
|
ble_trans_module_enable(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_ota_process()
|
void usr_ota_process(void)
|
||||||
{
|
{
|
||||||
static u8 cnt = 0;
|
static u8 cnt = 0;
|
||||||
|
|
||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
{
|
{
|
||||||
ble_multi_trans_disconnect();
|
ble_multi_trans_disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usr_get_conn_service() == 0)
|
if (!usr_ble_is_connected())
|
||||||
{
|
{
|
||||||
cnt++;
|
cnt++;
|
||||||
if (cnt == 2)
|
if (cnt == 2)
|
||||||
@@ -261,7 +327,10 @@ void usr_ota_process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_app_ota_init()
|
/**
|
||||||
|
* @brief 旧版 RCSP/JSON OTA 入口;产品 JB 0x30/0x32 路径不要调用
|
||||||
|
*/
|
||||||
|
void usr_app_ota_init(void)
|
||||||
{
|
{
|
||||||
usr_var.usr_goto_updata = 1;
|
usr_var.usr_goto_updata = 1;
|
||||||
if (usr_var.ota_timer == 0)
|
if (usr_var.ota_timer == 0)
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* @file usr_le_api.h
|
* @file usr_le_api.h
|
||||||
* @brief usr_le_code 静态库对外 API(广播 / 收发 / 配网)
|
* @brief usr_le_code 静态库对外应用 API(配网 / 配对 / OTA)
|
||||||
* @author cyWu <1917507415@qq.com>
|
* @author cyWu <1917507415@qq.com>
|
||||||
* @date 2026.08.03
|
* @date 2026.08.03
|
||||||
* @version V1.0.0
|
* @version V1.0.1
|
||||||
* @history
|
* @history
|
||||||
* - V1.0.0, 2026.08.03, cyWu, 首次发布
|
* - V1.0.0, 2026.08.03, cyWu, 首次发布
|
||||||
|
* - V1.0.1, 2026.08.19, cyWu, 收敛公开 API,移除 BLE 栈钩子声明
|
||||||
|
*
|
||||||
|
* @note usr_ble_adv_init / usr_le_data_recieve 为 BLE/RCSP 协议栈链接钩子,
|
||||||
|
* 由库内部实现并导出符号,不作为应用层公开接口。
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef __USR_LE_API_H__
|
#ifndef __USR_LE_API_H__
|
||||||
@@ -17,20 +21,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化 BLE 广播数据(绑定广播或重连广播)
|
|
||||||
* @note 根据配对状态与 usr_goto_pair 选择 bind/reconn 广播,并启动 500ms 周期更新
|
|
||||||
*/
|
|
||||||
void usr_ble_adv_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief BLE 协议栈接收数据入口
|
|
||||||
* @param data 接收缓冲区
|
|
||||||
* @param len 本次接收长度
|
|
||||||
* @note 组包后解析 bleproto,并分发 DEVICEINFO/AUTH/RUNCMD/OTA 等服务
|
|
||||||
*/
|
|
||||||
void usr_le_data_recieve(uint8_t *data, uint16_t len);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 进入配对/配网模式
|
* @brief 进入配对/配网模式
|
||||||
* @note 断开当前连接、清除配对信息(不复位),重新发绑定广播
|
* @note 断开当前连接、清除配对信息(不复位),重新发绑定广播
|
||||||
|
|||||||
+211
-366
@@ -1,181 +1,202 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* @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 "system/includes.h"
|
||||||
#include "app_config.h"
|
#include "app_config.h"
|
||||||
#include "asm/pwm_led.h"
|
|
||||||
#include "tone_player.h"
|
|
||||||
#include "ui_manage.h"
|
|
||||||
#include "app_main.h"
|
#include "app_main.h"
|
||||||
#include "app_task.h"
|
|
||||||
#include "asm/charge.h"
|
|
||||||
#include "app_power_manage.h"
|
|
||||||
#include "app_charge.h"
|
|
||||||
#include "user_cfg.h"
|
|
||||||
#include "key_event_deal.h"
|
|
||||||
#include "audio.h"
|
|
||||||
#include "update.h"
|
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "bleproto.h"
|
#include "bleproto.h"
|
||||||
#include "bleproto_api.h"
|
#include "bleproto_api.h"
|
||||||
#include "ble_proto.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_CONST APP
|
||||||
#define LOG_TAG "[APP]"
|
#define LOG_TAG "[USR_LE]"
|
||||||
#define LOG_ERROR_ENABLE
|
#define LOG_ERROR_ENABLE
|
||||||
#define LOG_DEBUG_ENABLE
|
#define LOG_DEBUG_ENABLE
|
||||||
#define LOG_INFO_ENABLE
|
#define LOG_INFO_ENABLE
|
||||||
/* #define LOG_DUMP_ENABLE */
|
|
||||||
#define LOG_CLI_ENABLE
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define FIRM_PACK_LEN 2048 // 128
|
/* 拼 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 u8 start_data[10] = {0x55, 0xAA, 0xFE, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00};
|
static int encode_len = 0;
|
||||||
static u8 end_data[2] = {0xaa, 0x55};
|
|
||||||
static int encode_len = 0x00;
|
|
||||||
static u8 txbuf[384] = {0};
|
static u8 txbuf[384] = {0};
|
||||||
static u8 rxbuf[FIRM_PACK_LEN + 1024] = {0};
|
static u8 rxbuf[USR_LE_RX_BUF_LEN] = {0};
|
||||||
static u8 ota_source_data[FIRM_PACK_LEN * 2] = {0};
|
static u8 s_last_runcmd_msgid = 0; /* RUNCMD_V2 应答须回填最近 msgid */
|
||||||
|
|
||||||
extern u16 usr_get_conn_service();
|
|
||||||
extern void ble_multi_trans_disconnect(void);
|
|
||||||
extern void usr_ble_send_data(u8 *data, u16 len); /// BLE发送接口,MTU 244
|
|
||||||
extern void usr_write_pair_info();
|
|
||||||
extern void usr_clear_pair_info();
|
|
||||||
extern void app_audio_volume_set(u8 value);
|
|
||||||
extern int dual_ota_app_data_deal(u32 msg, u8 *buf, u32 len);
|
|
||||||
extern int uart_tr_send_data(u8 *data, u32 len);
|
|
||||||
extern void usr_intterupt_close();
|
|
||||||
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);
|
|
||||||
|
|
||||||
void usr_ota_deal_task();
|
|
||||||
void usr_data_ana(bleproto_appdata_desc_t *desc);
|
|
||||||
void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id);
|
|
||||||
|
|
||||||
bleproto_authsetup_req_t usr_auth_data;
|
bleproto_authsetup_req_t usr_auth_data;
|
||||||
|
|
||||||
void usr_le_data_recieve(u8 *data, u16 len) /// BLE数据接收
|
extern void usr_ble_send_data(u8 *data, u16 len);
|
||||||
{
|
extern u8 usr_ble_is_notify_ready(void);
|
||||||
// log_info("le recieve: %d",len);
|
extern void usr_write_pair_info(void);
|
||||||
// printf_buf(data, len);
|
extern void usr_clear_pair_info(void);
|
||||||
static u16 usr_len = 0;
|
extern void usr_jb_le_recieve_data(u8 *data, u16 len);
|
||||||
bleproto_appdata_desc_t desc;
|
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;
|
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);
|
memcpy(&rxbuf[usr_len], data, len);
|
||||||
usr_len += len;
|
usr_len += len;
|
||||||
rc_result = bleproto_appdata_decode(rxbuf, usr_len, &desc);
|
rc_result = bleproto_appdata_decode(rxbuf, usr_len, &s_rx_desc);
|
||||||
// printf("rc_result_le## = %d\n",rc_result);
|
|
||||||
if (rc_result < 0)
|
if (rc_result < 0)
|
||||||
{
|
{
|
||||||
// 接收到了非法的数据包,无法解析
|
|
||||||
printf("### invild pack\n");
|
printf("### invild pack\n");
|
||||||
usr_len = 0;
|
usr_len = 0;
|
||||||
}
|
}
|
||||||
else if (rc_result == 0)
|
else if (rc_result == 0)
|
||||||
{
|
{
|
||||||
// 接收的数据不完整,继续接收数据
|
|
||||||
printf("### keep recieving\n");
|
printf("### keep recieving\n");
|
||||||
}
|
}
|
||||||
else //(rc_result > 0)
|
else
|
||||||
{
|
{
|
||||||
// 数据解析成功
|
|
||||||
printf("### pack recieved ok\n");
|
printf("### pack recieved ok\n");
|
||||||
usr_len = 0;
|
usr_len = 0;
|
||||||
usr_data_ana(&desc);
|
usr_data_ana(&s_rx_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_data_ana(bleproto_appdata_desc_t *desc)
|
/**
|
||||||
|
* @brief 解析 bleproto 服务并分发
|
||||||
|
* @param desc 已 decode 的包
|
||||||
|
*/
|
||||||
|
static void usr_data_ana(bleproto_appdata_desc_t *desc)
|
||||||
{
|
{
|
||||||
bleproto_appdata_desc_t encode_desc = {0};
|
static bleproto_appdata_desc_t s_encode_desc;
|
||||||
printf("#############334 desc->header.serviceid = %d\n", desc->header.serviceid);
|
|
||||||
if (desc->header.msgtype /*desc.header.msgtype*/ == BLEPROTO_APPDATA_MSGTYPE_REQ)
|
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)
|
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;
|
||||||
|
|
||||||
case E_BLEPROTO_SERVICE_ID_DEVICEINFO:
|
/* 网关从子设备连上开始计时,每 12 小时经 DEVICEINFO 同步一次 */
|
||||||
|
usr_rtc_set_from_unix(req->t, (int32_t)req->gmtoff);
|
||||||
|
|
||||||
encode_desc.header.version = 0;
|
usr_le_fill_rsp_header(&s_encode_desc, desc, E_BLEPROTO_SERVICE_ID_DEVICEINFO);
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
|
||||||
encode_desc.header.msgid = desc->header.msgid; // 这里的msg_id为上面解析到的包的msg_id;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_DEVICEINFO;
|
|
||||||
|
|
||||||
// deviceinfo rsp序列化
|
|
||||||
bleproto_deviceinfo_rsp_t *rsp = &encode_desc.datast.deviceinfo_rsp;
|
|
||||||
{
|
|
||||||
// 填写设备相关信息
|
|
||||||
rsp->hbcycle = 1000;
|
rsp->hbcycle = 1000;
|
||||||
strcpy(rsp->swv, "V1.0.0.00");
|
strcpy(rsp->swv, "V1.0.0.00");
|
||||||
strcpy(rsp->hwv, "V1.0.0.00");
|
strcpy(rsp->hwv, "V1.0.0.00");
|
||||||
rsp->longcon = 1;
|
rsp->longcon = 1;
|
||||||
rsp->prototype = 4;
|
rsp->prototype = 4;
|
||||||
}
|
usr_le_encode_and_send(&s_encode_desc);
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
printf("encode_len = %d\n", encode_len);
|
|
||||||
// 调用蓝牙协议栈发送数据接口,将数据一包一包的发送出去
|
|
||||||
// 第一包:packetlen
|
|
||||||
// 第二包:packetlen
|
|
||||||
// ......
|
|
||||||
// 第N包: totallen - (packetlen * (N -1))
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
// printf("E_BLEPROTO_SERVICE_ID_DEVICEINFO\n");
|
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHSETUP:
|
}
|
||||||
// 设备处理,回复响应
|
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");
|
printf("E_BLEPROTO_SERVICE_ID_AUTHSETUP\n");
|
||||||
encode_desc.header.version = 0;
|
usr_le_fill_rsp_header(&s_encode_desc, desc, E_BLEPROTO_SERVICE_ID_AUTHSETUP);
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
|
||||||
encode_desc.header.msgid = desc->header.msgid; // 这里的msg_id为上面解析到的包的msg_id;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_AUTHSETUP;
|
|
||||||
|
|
||||||
bleproto_authsetup_rsp_t *au_rsp = &encode_desc.datast.authsetup_rsp;
|
|
||||||
au_rsp->errcode = 0;
|
au_rsp->errcode = 0;
|
||||||
|
|
||||||
memcpy(&usr_auth_data, &desc->datast.authsetup_req, sizeof(usr_auth_data));
|
memcpy(&usr_auth_data, &desc->datast.authsetup_req, sizeof(usr_auth_data));
|
||||||
{
|
|
||||||
// 保存三元组
|
|
||||||
if (usr_auth_data.paired_flag == 0)
|
if (usr_auth_data.paired_flag == 0)
|
||||||
{
|
{
|
||||||
usr_write_pair_info();
|
usr_write_pair_info();
|
||||||
printf("usr_auth_data %s %s ", usr_auth_data.authcode, usr_auth_data.devid);
|
printf("usr_auth_data %s %s ", usr_auth_data.authcode, usr_auth_data.devid);
|
||||||
printf_buf(usr_auth_data.gwmac, 6);
|
printf_buf(usr_auth_data.gwmac, 6);
|
||||||
}
|
}
|
||||||
}
|
usr_le_encode_and_send(&s_encode_desc);
|
||||||
|
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
printf("encode_len = %d\n", encode_len);
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_AUTHDELETE:
|
}
|
||||||
// 设备处理,回复响应
|
case E_BLEPROTO_SERVICE_ID_AUTHDELETE: {
|
||||||
printf("E_BLEPROTO_SERVICE_ID_AUTHDELETE\n");
|
bleproto_authdelete_rsp_t *aude_rsp = &s_encode_desc.datast.authdelete_rsp;
|
||||||
encode_desc.header.version = 0;
|
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
|
||||||
encode_desc.header.msgid = desc->header.msgid; // 这里的msg_id为上面解析到的包的msg_id;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_AUTHSETUP;
|
|
||||||
|
|
||||||
bleproto_authdelete_rsp_t *aude_rsp = &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);
|
memcpy(aude_rsp->gwmac, usr_auth_data.gwmac, 6);
|
||||||
if (!memcmp(usr_auth_data.authcode, desc->datast.authdelete_req.authcode, 32))
|
if (!memcmp(usr_auth_data.authcode, desc->datast.authdelete_req.authcode, 32))
|
||||||
{
|
{
|
||||||
@@ -186,20 +207,10 @@ void usr_data_ana(bleproto_appdata_desc_t *desc)
|
|||||||
{
|
{
|
||||||
aude_rsp->errcode = 501;
|
aude_rsp->errcode = 501;
|
||||||
}
|
}
|
||||||
|
usr_le_encode_and_send(&s_encode_desc);
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
printf("encode_len = %d\n", encode_len);
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD:
|
||||||
// 设备处理,回复响应
|
|
||||||
printf("E_BLEPROTO_SERVICE_ID_RUNCMD\n");
|
printf("E_BLEPROTO_SERVICE_ID_RUNCMD\n");
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_RUNCMD_V2:
|
||||||
@@ -207,108 +218,31 @@ void usr_data_ana(bleproto_appdata_desc_t *desc)
|
|||||||
usr_run_cmd_code_v2(&desc->datast.runcmd_v2_req, desc->header.msgid);
|
usr_run_cmd_code_v2(&desc->datast.runcmd_v2_req, desc->header.msgid);
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
case E_BLEPROTO_SERVICE_ID_OTANOTIFY:
|
||||||
printf("E_BLEPROTO_SERVICE_ID_OTANOTIFY\n");
|
|
||||||
encode_desc.header.version = 0;
|
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
|
||||||
encode_desc.header.msgid = desc->header.msgid; // 这里的msg_id为上面解析到的包的msg_id;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_OTANOTIFY;
|
|
||||||
encode_desc.datast.doaction_rsp.errcode = 0;
|
|
||||||
|
|
||||||
bleproto_otanotify_rsp_t *in_ota_rsp = &encode_desc.datast.otanotify_rsp;
|
|
||||||
|
|
||||||
bleproto_otanotify_req_t *in_ota_data2 = &desc->datast.otanotify_req;
|
|
||||||
printf("in_ota_data id = %d\n", in_ota_data2->id);
|
|
||||||
printf("in_ota_data ver = %s\n", in_ota_data2->version);
|
|
||||||
printf("in_ota_data size= %d\n", in_ota_data2->size);
|
|
||||||
printf("in_ota_data md5 = %s\n", in_ota_data2->md5);
|
|
||||||
{
|
|
||||||
in_ota_rsp->errcode = 0;
|
|
||||||
// 执行命令
|
|
||||||
}
|
|
||||||
|
|
||||||
usr_var.usr_ota_data_id = in_ota_data2->id; // int
|
|
||||||
usr_var.usr_ota_data_size = in_ota_data2->size;
|
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
printf("encode_len = %d\n", encode_len);
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
usr_var.usr_allow_to_flash = 0;
|
|
||||||
usr_var.usr_data_index = 0;
|
|
||||||
start_data[2] = usr_var.usr_ota_data_size & 0x000000ff;
|
|
||||||
start_data[3] = (usr_var.usr_ota_data_size >> 8) & 0x000000ff;
|
|
||||||
start_data[4] = (usr_var.usr_ota_data_size >> 16) & 0x000000ff;
|
|
||||||
start_data[5] = (usr_var.usr_ota_data_size >> 24) & 0x000000ff;
|
|
||||||
dual_ota_app_data_deal(0, start_data, 10);
|
|
||||||
printf("#### buf total size = %d\n", usr_var.usr_ota_data_size);
|
|
||||||
printf_buf(start_data, 10);
|
|
||||||
|
|
||||||
encode_desc.header.version = 0;
|
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
|
||||||
encode_desc.header.msgid = 0; // desc->header.msgid;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_OTADATA;
|
|
||||||
encode_desc.datast.doaction_rsp.errcode = 0;
|
|
||||||
|
|
||||||
encode_desc.datast.otadata_req.id = usr_var.usr_ota_data_id;
|
|
||||||
encode_desc.datast.otadata_req.offset = usr_var.usr_data_index;
|
|
||||||
encode_desc.datast.otadata_req.maxsize = FIRM_PACK_LEN;
|
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len err = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usr_var.usr_double_ota_timer_id == 0)
|
|
||||||
{
|
|
||||||
clk_set("sys", 48 * 1000000L);
|
|
||||||
usr_var.usr_double_ota_timer_id = 1;
|
|
||||||
// clk_set("sys", 120 * 1000000L);
|
|
||||||
os_task_create(usr_ota_deal_task, NULL, 31, FIRM_PACK_LEN, 0, "usr_ota");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||||
printf("E_BLEPROTO_SERVICE_ID_OTADATA\n");
|
|
||||||
break;
|
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
case E_BLEPROTO_SERVICE_ID_OTADATA_V2:
|
||||||
printf("E_BLEPROTO_SERVICE_ID_OTADATA\n");
|
/* JSON OTA 已废弃,SOC 走 JB 0x30/0x32 */
|
||||||
|
printf("JSON OTA deprecated, use JB 0x30/0x32\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("err !!! default event desc->header.serviceid =%d\n", desc->header.serviceid);
|
printf("err !!! default event desc->header.serviceid =%d\n",
|
||||||
|
desc->header.serviceid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (desc->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_RSP)
|
|
||||||
|
if (desc->header.msgtype == BLEPROTO_APPDATA_MSGTYPE_RSP)
|
||||||
{
|
{
|
||||||
printf("BLEPROTO_APPDATA_MSGTYPE_RSP\n");
|
|
||||||
switch (desc->header.serviceid)
|
switch (desc->header.serviceid)
|
||||||
{
|
{
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD:
|
||||||
// 主控回复的响应,设备处理
|
printf("E_BLEPROTO_SERVICE_ID_REPORTCMD errcode=%d\n",
|
||||||
printf("E_BLEPROTO_SERVICE_ID_REPORTCMD\n");
|
desc->datast.reportcmd_rsp.errcode);
|
||||||
printf("cmd id = %d", desc->datast.reportcmd_rsp.errcode);
|
|
||||||
break;
|
break;
|
||||||
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2:
|
case E_BLEPROTO_SERVICE_ID_REPORTCMD_V2: {
|
||||||
{
|
|
||||||
/* 网关对主动上报 / OTA 的应答(非 55AA):
|
|
||||||
* cmd==0 && gateway_int_cnt==1 && gateway_int[0]==0 → 应答成功 */
|
|
||||||
ble_proto_packet_t *rpt_ack = &desc->datast.reportcmd_v2_rsp;
|
ble_proto_packet_t *rpt_ack = &desc->datast.reportcmd_v2_rsp;
|
||||||
printf("E_BLEPROTO_SERVICE_ID_REPORTCMD_V2 cmd=%u cnt=%u int0=%ld\n",
|
|
||||||
|
printf("REPORTCMD_V2 cmd=%u cnt=%u int0=%ld\n",
|
||||||
(unsigned)rpt_ack->cmd,
|
(unsigned)rpt_ack->cmd,
|
||||||
(unsigned)rpt_ack->gateway_int_cnt,
|
(unsigned)rpt_ack->gateway_int_cnt,
|
||||||
(long)((rpt_ack->gateway_int_cnt > 0) ? rpt_ack->gateway_int[0] : 0));
|
(long)((rpt_ack->gateway_int_cnt > 0) ? rpt_ack->gateway_int[0] : 0));
|
||||||
@@ -318,120 +252,23 @@ void usr_data_ana(bleproto_appdata_desc_t *desc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
case E_BLEPROTO_SERVICE_ID_OTADATA:
|
||||||
bleproto_otadata_rsp_t *ota_data_rsp = &desc->datast.otadata_rsp;
|
printf("JSON OTA deprecated, use JB 0x32\n");
|
||||||
// printf("errcode = %d offset = %d len = %d\n",ota_data_rsp->errcode,ota_data_rsp->offset,ota_data_rsp->len);
|
|
||||||
uart_tr_send_data(ota_data_rsp->data, ota_data_rsp->len);
|
|
||||||
memcpy(&ota_source_data[usr_var.usr_allow_to_flash], ota_data_rsp->data, ota_data_rsp->len);
|
|
||||||
usr_var.usr_allow_to_flash += ota_data_rsp->len;
|
|
||||||
usr_var.usr_start_write_flash = 0;
|
|
||||||
if (usr_var.usr_allow_to_flash >= (FIRM_PACK_LEN * 2)) // 0 - 1024
|
|
||||||
// 1024 - 2048
|
|
||||||
// 2048 - 3072
|
|
||||||
// 3072 - 4096
|
|
||||||
{
|
|
||||||
usr_var.usr_start_write_flash = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
usr_var.usr_data_index += FIRM_PACK_LEN;
|
|
||||||
if (usr_var.usr_data_index >= usr_var.usr_ota_data_size)
|
|
||||||
{
|
|
||||||
usr_var.usr_start_write_flash = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// bleproto_appdata_desc_t encode_desc = { 0 };
|
|
||||||
encode_desc.header.version = 0;
|
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
|
||||||
encode_desc.header.msgid = 0; // desc->header.msgid;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_OTADATA;
|
|
||||||
encode_desc.datast.doaction_rsp.errcode = 0;
|
|
||||||
|
|
||||||
encode_desc.datast.otadata_req.id = usr_var.usr_ota_data_id;
|
|
||||||
encode_desc.datast.otadata_req.offset = usr_var.usr_data_index;
|
|
||||||
encode_desc.datast.otadata_req.maxsize = FIRM_PACK_LEN;
|
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len err = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("E_BLEPROTO_SERVICE_ID_REPORTCMD\n");
|
printf("unhandled RSP serviceid=%d\n", desc->header.serviceid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usr_ota_deal_task()
|
/**
|
||||||
|
* @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)
|
||||||
{
|
{
|
||||||
os_time_dly(5);
|
u8 jb_frame[MAX_PACKAGE_LEN];
|
||||||
bleproto_appdata_desc_t encode_desc = {0};
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (usr_var.usr_ota_succ_flag == 0)
|
|
||||||
{
|
|
||||||
if (usr_var.usr_start_write_flash == 1)
|
|
||||||
{
|
|
||||||
// OS_ENTER_CRITICAL();
|
|
||||||
usr_var.usr_data_index += FIRM_PACK_LEN;
|
|
||||||
usr_var.usr_start_write_flash = 0;
|
|
||||||
dual_ota_app_data_deal(0, ota_source_data, usr_var.usr_allow_to_flash);
|
|
||||||
os_time_dly(1);
|
|
||||||
// OS_EXIT_CRITICAL();
|
|
||||||
// printf("usr_var.usr_allow_to_flash = %d\n",usr_var.usr_allow_to_flash);
|
|
||||||
usr_var.usr_allow_to_flash = 0;
|
|
||||||
|
|
||||||
encode_desc.header.version = 0;
|
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
|
||||||
encode_desc.header.msgid = 0; // desc->header.msgid;
|
|
||||||
encode_desc.header.encrypt = 0;
|
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_OTADATA;
|
|
||||||
encode_desc.datast.doaction_rsp.errcode = 0;
|
|
||||||
|
|
||||||
encode_desc.datast.otadata_req.id = usr_var.usr_ota_data_id;
|
|
||||||
encode_desc.datast.otadata_req.offset = usr_var.usr_data_index;
|
|
||||||
encode_desc.datast.otadata_req.maxsize = FIRM_PACK_LEN;
|
|
||||||
encode_len = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
|
||||||
if (encode_len > 0)
|
|
||||||
{
|
|
||||||
usr_ble_send_data(txbuf, encode_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("2encode_len err = %d\n", encode_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (usr_var.usr_start_write_flash == 2)
|
|
||||||
{
|
|
||||||
printf("usr_start_write_flash = %d\n", usr_var.usr_start_write_flash);
|
|
||||||
usr_var.usr_start_write_flash = 0;
|
|
||||||
// OS_ENTER_CRITICAL();
|
|
||||||
dual_ota_app_data_deal(0, ota_source_data, usr_var.usr_allow_to_flash);
|
|
||||||
// OS_EXIT_CRITICAL();
|
|
||||||
printf("usr_var.usr_allow_to_flash = %d\n", usr_var.usr_allow_to_flash);
|
|
||||||
usr_var.usr_allow_to_flash = 0;
|
|
||||||
os_time_dly(30);
|
|
||||||
dual_ota_app_data_deal(0, end_data, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os_time_dly(10);
|
|
||||||
// putchar('6');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 最近一次收到 RUNCMD_V2 请求的 msgid,应答时回填 */
|
|
||||||
static u8 s_last_runcmd_msgid = 0;
|
|
||||||
void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id)
|
|
||||||
{
|
|
||||||
u8 jb_frame[128]; /* 与 jb_protocol.h MAX_PACKAGE_LEN 一致 */
|
|
||||||
u16 copy_len;
|
u16 copy_len;
|
||||||
|
|
||||||
if (!runcmd_par || !runcmd_par->bytes_data || runcmd_par->device_bytes_len == 0)
|
if (!runcmd_par || !runcmd_par->bytes_data || runcmd_par->device_bytes_len == 0)
|
||||||
@@ -444,7 +281,6 @@ void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id)
|
|||||||
printf("runcmd_par id = %d, bytes_len = %u\n",
|
printf("runcmd_par id = %d, bytes_len = %u\n",
|
||||||
runcmd_par->cmd, runcmd_par->device_bytes_len);
|
runcmd_par->cmd, runcmd_par->device_bytes_len);
|
||||||
|
|
||||||
/* 先拷到本地再入 JB 环缓,避免零拷贝指针被后续逻辑覆盖 */
|
|
||||||
copy_len = runcmd_par->device_bytes_len;
|
copy_len = runcmd_par->device_bytes_len;
|
||||||
if (copy_len > sizeof(jb_frame))
|
if (copy_len > sizeof(jb_frame))
|
||||||
{
|
{
|
||||||
@@ -461,16 +297,17 @@ void usr_run_cmd_code_v2(ble_proto_packet_t *runcmd_par, u8 usr_msg_id)
|
|||||||
* @brief 将 JB 协议帧封装为 bleproto V2 后通过 BLE 发送
|
* @brief 将 JB 协议帧封装为 bleproto V2 后通过 BLE 发送
|
||||||
* @param data JB 协议原始帧(55 AA | LEN | CMD | ...)
|
* @param data JB 协议原始帧(55 AA | LEN | CMD | ...)
|
||||||
* @param len 帧长度
|
* @param len 帧长度
|
||||||
* @note 根据 JB CMD 区分主动上报 / 应答:
|
* @note 主动上报(0x07/0x34/0x38) → REPORTCMD_V2;其余 → RUNCMD_V2 应答
|
||||||
* - 主动(0x07/0x34/0x38): REPORTCMD_V2 + REQ + cmd=100
|
* 对外符号名保持 ble_send_data,供 jb_protocol 调用
|
||||||
* - 应答(其余): RUNCMD_V2 + RSP + cmd=110
|
|
||||||
*/
|
*/
|
||||||
void ble_send_data(u8 *data, u16 len)
|
void ble_send_data(u8 *data, u16 len)
|
||||||
{
|
{
|
||||||
bleproto_appdata_desc_t encode_desc = {0};
|
ble_proto_packet_t pkt;
|
||||||
ble_proto_packet_t *pkt = NULL;
|
bleproto_appdata_header_t hdr;
|
||||||
|
u8 v2_buf[MAX_PACKAGE_LEN + USR_LE_V2_WRAP_OVERHEAD];
|
||||||
u8 jb_cmd;
|
u8 jb_cmd;
|
||||||
u8 is_active_send;
|
u8 is_active_send;
|
||||||
|
int plen;
|
||||||
int elen;
|
int elen;
|
||||||
|
|
||||||
if (!data || len < 5)
|
if (!data || len < 5)
|
||||||
@@ -478,54 +315,62 @@ void ble_send_data(u8 *data, u16 len)
|
|||||||
printf("ble_send_data invalid param, len=%d\n", len);
|
printf("ble_send_data invalid param, len=%d\n", len);
|
||||||
return;
|
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帧: 55 AA | LEN_H LEN_L | CMD | SN | ...,CMD 在偏移 4 */
|
jb_cmd = data[USR_LE_JB_CMD_OFF];
|
||||||
jb_cmd = data[4];
|
is_active_send = usr_le_is_gateway_report_cmd(jb_cmd);
|
||||||
/* 主动上报 0x07;MCU 主动 OTA 完成/停止 0x34/0x38;其余按应答 */
|
|
||||||
is_active_send = (jb_cmd == 0x07) || (jb_cmd == 0x34) || (jb_cmd == 0x38);
|
|
||||||
|
|
||||||
encode_desc.header.version = 0;
|
memset(&pkt, 0, sizeof(pkt));
|
||||||
encode_desc.header.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
encode_desc.header.encrypt = 0;
|
hdr.version = 0;
|
||||||
|
hdr.datafmt = BLEPROTO_APPDATA_DATAFMT_JSON;
|
||||||
|
hdr.encrypt = 0;
|
||||||
|
|
||||||
if (is_active_send)
|
if (is_active_send)
|
||||||
{
|
{
|
||||||
/* 主动发送:REPORTCMD_V2 / REQ / cmd=100 */
|
hdr.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_REQ;
|
hdr.msgid = 0;
|
||||||
encode_desc.header.msgid = 0;
|
hdr.serviceid = E_BLEPROTO_SERVICE_ID_REPORTCMD_V2;
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_REPORTCMD_V2;
|
pkt.cmd = USR_LE_V2_CMD_REPORT;
|
||||||
|
pkt.gateway_int_cnt = 0;
|
||||||
pkt = &encode_desc.datast.reportcmd_v2_req;
|
|
||||||
pkt->cmd = 100;
|
|
||||||
pkt->reserved = 0;
|
|
||||||
pkt->gateway_int_cnt = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 应答命令:RUNCMD_V2 / RSP / cmd=110,回填最新 msgid */
|
hdr.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
||||||
encode_desc.header.msgtype = BLEPROTO_APPDATA_MSGTYPE_RSP;
|
hdr.msgid = s_last_runcmd_msgid;
|
||||||
encode_desc.header.msgid = s_last_runcmd_msgid;
|
hdr.serviceid = E_BLEPROTO_SERVICE_ID_RUNCMD_V2;
|
||||||
encode_desc.header.serviceid = E_BLEPROTO_SERVICE_ID_RUNCMD_V2;
|
pkt.cmd = USR_LE_V2_CMD_RUN;
|
||||||
|
pkt.gateway_int_cnt = 2;
|
||||||
pkt = &encode_desc.datast.runcmd_v2_rsp;
|
pkt.gateway_int[0] = 0;
|
||||||
pkt->cmd = 110;
|
pkt.gateway_int[1] = 0;
|
||||||
pkt->reserved = 0;
|
|
||||||
pkt->gateway_int_cnt = 2;
|
|
||||||
pkt->gateway_int[0] = 0;
|
|
||||||
pkt->gateway_int[1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt->device_int_len = 0;
|
pkt.device_bytes_len = len;
|
||||||
pkt->device_str_len = 0;
|
pkt.bytes_data = data;
|
||||||
pkt->device_bytes_len = len;
|
|
||||||
pkt->bytes_data = data;
|
|
||||||
|
|
||||||
elen = bleproto_appdata_encode(txbuf, sizeof(txbuf), sizeof(txbuf), &encode_desc);
|
plen = ble_proto_pack(&pkt, v2_buf, sizeof(v2_buf));
|
||||||
printf("ble_send_data jb_cmd=0x%02X active=%d encode_len=%d msgid=%d\n",
|
if (plen <= 0)
|
||||||
jb_cmd, is_active_send, elen, encode_desc.header.msgid);
|
|
||||||
if (elen > 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);
|
usr_ble_send_data(txbuf, elen);
|
||||||
printf_buf(txbuf, elen);
|
printf_buf(txbuf, elen);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,363 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* @file usr_rtc.c
|
||||||
|
* @brief 板级 RTC 外设实现(BR28 硬件 rtc_dev_ops)
|
||||||
|
* @author cyWu <1917507415@qq.com>
|
||||||
|
* @date 2026.08.19
|
||||||
|
* @version V1.1.0
|
||||||
|
* @history
|
||||||
|
* - V1.0.0, 2026.08.19, cyWu, 从模组固件移植至 SOC SDK
|
||||||
|
* - V1.1.0, 2026.08.19, cyWu, 精简公共接口与缓存逻辑
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "system/includes.h"
|
||||||
|
#include "app_config.h"
|
||||||
|
#include "usr_rtc.h"
|
||||||
|
#include "asm/rtc.h"
|
||||||
|
|
||||||
|
#define LOG_TAG_CONST APP
|
||||||
|
#define LOG_TAG "[USR_RTC]"
|
||||||
|
#define LOG_ERROR_ENABLE
|
||||||
|
#define LOG_DEBUG_ENABLE
|
||||||
|
#define LOG_INFO_ENABLE
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 私有宏 / 类型 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
#define USR_RTC_TZ_MAGIC (0x52544331u) /**< 'RTC1',校验 VM 时区 */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
|
int32_t tz_s;
|
||||||
|
} UsrRtcTzVm_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t inited;
|
||||||
|
uint8_t tz_valid;
|
||||||
|
int32_t tz_s;
|
||||||
|
void *dev;
|
||||||
|
} UsrRtc_t;
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 私有变量 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
static UsrRtc_t s_rtc;
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 私有函数声明 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
static uint8_t usr_rtc_is_leap(uint16_t year);
|
||||||
|
static uint8_t usr_rtc_days_in_month(uint16_t year, uint8_t month);
|
||||||
|
static uint8_t usr_rtc_year_ok(uint16_t year);
|
||||||
|
static void usr_rtc_unix_to_calendar(uint32_t unix_utc, int32_t tz_s,
|
||||||
|
struct sys_time *t);
|
||||||
|
static UsrRtc_Ret_t usr_rtc_write(const struct sys_time *t);
|
||||||
|
static void usr_rtc_load_tz(void);
|
||||||
|
static void usr_rtc_save_tz(int32_t tz_s);
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 公有函数 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开 rtc 设备并加载时区
|
||||||
|
* @return UsrRtc_Ret_t
|
||||||
|
*/
|
||||||
|
UsrRtc_Ret_t usr_rtc_init(void)
|
||||||
|
{
|
||||||
|
struct sys_time t;
|
||||||
|
|
||||||
|
if (s_rtc.inited)
|
||||||
|
{
|
||||||
|
return USR_RTC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TCFG_APP_RTC_EN
|
||||||
|
s_rtc.dev = dev_open("rtc", NULL);
|
||||||
|
if (!s_rtc.dev)
|
||||||
|
{
|
||||||
|
log_error("open rtc fail");
|
||||||
|
return USR_RTC_ERR_NOT_INIT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
log_error("TCFG_APP_RTC_EN=0");
|
||||||
|
return USR_RTC_ERR_NOT_INIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
usr_rtc_load_tz();
|
||||||
|
s_rtc.inited = 1;
|
||||||
|
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
read_sys_time(&t);
|
||||||
|
log_info("rtc open %u-%02u-%02u %02u:%02u:%02u tz=%ld tz_ok=%u",
|
||||||
|
t.year, t.month, t.day, t.hour, t.min, t.sec,
|
||||||
|
(long)s_rtc.tz_s, s_rtc.tz_valid);
|
||||||
|
return USR_RTC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前本地时间
|
||||||
|
* @param t 成功时赋值;失败不改动
|
||||||
|
* @return 1/0
|
||||||
|
*/
|
||||||
|
uint8_t usr_rtc_get_time(struct sys_time *t)
|
||||||
|
{
|
||||||
|
struct sys_time tmp;
|
||||||
|
|
||||||
|
if (!t || !s_rtc.inited || !s_rtc.tz_valid)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
read_sys_time(&tmp);
|
||||||
|
if (!usr_rtc_year_ok(tmp.year))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = tmp;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UTC 秒 + 时区 → 本地日历写入 RTC
|
||||||
|
* @param unix_utc UTC 秒
|
||||||
|
* @param tz_s 时区偏移秒
|
||||||
|
* @return UsrRtc_Ret_t
|
||||||
|
*/
|
||||||
|
UsrRtc_Ret_t usr_rtc_set_from_unix(uint64_t unix_utc, int32_t tz_s)
|
||||||
|
{
|
||||||
|
struct sys_time t;
|
||||||
|
UsrRtc_Ret_t ret;
|
||||||
|
|
||||||
|
if (!s_rtc.inited)
|
||||||
|
{
|
||||||
|
return USR_RTC_ERR_NOT_INIT;
|
||||||
|
}
|
||||||
|
if (unix_utc == 0)
|
||||||
|
{
|
||||||
|
log_debug("unix=0, ignore");
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 网关采样到写入大约慢 1s,在 UTC 上补偿 */
|
||||||
|
unix_utc += USR_RTC_SYNC_COMPENSATE_S;
|
||||||
|
if ((tz_s > USR_RTC_TZ_ABS_MAX_S) || (tz_s < -USR_RTC_TZ_ABS_MAX_S))
|
||||||
|
{
|
||||||
|
log_error("tz out of range %ld", (long)tz_s);
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
if (unix_utc > 0xFFFFFFFFull)
|
||||||
|
{
|
||||||
|
log_error("unix too large");
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
usr_rtc_unix_to_calendar((uint32_t)unix_utc, tz_s, &t);
|
||||||
|
if (!usr_rtc_year_ok(t.year))
|
||||||
|
{
|
||||||
|
log_error("year %u not in %u~%u, wait sync",
|
||||||
|
t.year, USR_RTC_YEAR_MIN, USR_RTC_YEAR_MAX);
|
||||||
|
return USR_RTC_ERR_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = usr_rtc_write(&t);
|
||||||
|
if (ret != USR_RTC_OK)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
usr_rtc_save_tz(tz_s);
|
||||||
|
log_info("set rtc %u-%02u-%02u %02u:%02u:%02u tz=%ld",
|
||||||
|
t.year, t.month, t.day, t.hour, t.min, t.sec, (long)tz_s);
|
||||||
|
return USR_RTC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 私有函数 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 写硬件日历
|
||||||
|
* @param t 本地日历
|
||||||
|
* @return UsrRtc_Ret_t
|
||||||
|
*/
|
||||||
|
static UsrRtc_Ret_t usr_rtc_write(const struct sys_time *t)
|
||||||
|
{
|
||||||
|
struct sys_time tmp;
|
||||||
|
|
||||||
|
if (!t)
|
||||||
|
{
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
if (!s_rtc.inited)
|
||||||
|
{
|
||||||
|
return USR_RTC_ERR_NOT_INIT;
|
||||||
|
}
|
||||||
|
if (!usr_rtc_year_ok(t->year) || (t->month < 1) || (t->month > 12) ||
|
||||||
|
(t->day < 1) || (t->hour > 23) || (t->min > 59) || (t->sec > 59))
|
||||||
|
{
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
if (t->day > usr_rtc_days_in_month(t->year, t->month))
|
||||||
|
{
|
||||||
|
return USR_RTC_ERR_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = *t;
|
||||||
|
write_sys_time(&tmp);
|
||||||
|
return USR_RTC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 是否闰年
|
||||||
|
* @param year 公历年
|
||||||
|
* @return 1/0
|
||||||
|
*/
|
||||||
|
static uint8_t usr_rtc_is_leap(uint16_t year)
|
||||||
|
{
|
||||||
|
if ((year % 400u) == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ((year % 100u) == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((year % 4u) == 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 某月天数
|
||||||
|
* @param year 年
|
||||||
|
* @param month 月 1~12
|
||||||
|
* @return 天数,非法月返回 0
|
||||||
|
*/
|
||||||
|
static uint8_t usr_rtc_days_in_month(uint16_t year, uint8_t month)
|
||||||
|
{
|
||||||
|
static const uint8_t days[12] = {
|
||||||
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
|
||||||
|
if ((month < 1) || (month > 12))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((month == 2) && usr_rtc_is_leap(year))
|
||||||
|
{
|
||||||
|
return 29;
|
||||||
|
}
|
||||||
|
return days[month - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 年份是否在合法窗口
|
||||||
|
* @param year 年
|
||||||
|
* @return 1/0
|
||||||
|
*/
|
||||||
|
static uint8_t usr_rtc_year_ok(uint16_t year)
|
||||||
|
{
|
||||||
|
return ((year >= USR_RTC_YEAR_MIN) && (year <= USR_RTC_YEAR_MAX)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UTC 秒 + 时区 → 本地日历
|
||||||
|
* @param unix_utc UTC 秒
|
||||||
|
* @param tz_s 时区偏移
|
||||||
|
* @param t 输出
|
||||||
|
*/
|
||||||
|
static void usr_rtc_unix_to_calendar(uint32_t unix_utc, int32_t tz_s,
|
||||||
|
struct sys_time *t)
|
||||||
|
{
|
||||||
|
int64_t local;
|
||||||
|
uint32_t days;
|
||||||
|
uint32_t tod;
|
||||||
|
uint16_t y;
|
||||||
|
uint8_t m;
|
||||||
|
uint8_t dim;
|
||||||
|
|
||||||
|
memset(t, 0, sizeof(*t));
|
||||||
|
local = (int64_t)unix_utc + (int64_t)tz_s;
|
||||||
|
if (local < 0)
|
||||||
|
{
|
||||||
|
local = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tod = (uint32_t)(local % 86400);
|
||||||
|
days = (uint32_t)(local / 86400);
|
||||||
|
t->sec = (uint8_t)(tod % 60u);
|
||||||
|
t->min = (uint8_t)((tod / 60u) % 60u);
|
||||||
|
t->hour = (uint8_t)(tod / 3600u);
|
||||||
|
|
||||||
|
y = 1970;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
uint32_t diy = usr_rtc_is_leap(y) ? 366u : 365u;
|
||||||
|
if (days < diy)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
days -= diy;
|
||||||
|
y++;
|
||||||
|
if (y > 4095u)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t->year = y;
|
||||||
|
|
||||||
|
for (m = 1; m <= 12u; m++)
|
||||||
|
{
|
||||||
|
dim = usr_rtc_days_in_month(y, m);
|
||||||
|
if (days < dim)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
days -= dim;
|
||||||
|
}
|
||||||
|
t->month = m;
|
||||||
|
t->day = (uint8_t)(days + 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从 VM 加载时区
|
||||||
|
*/
|
||||||
|
static void usr_rtc_load_tz(void)
|
||||||
|
{
|
||||||
|
UsrRtcTzVm_t vm;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
s_rtc.tz_valid = 0;
|
||||||
|
s_rtc.tz_s = 0;
|
||||||
|
memset(&vm, 0, sizeof(vm));
|
||||||
|
ret = syscfg_read(CFG_USER_TIM_FLAG, (u8 *)&vm, sizeof(vm));
|
||||||
|
if ((ret == (int)sizeof(vm)) && (vm.magic == USR_RTC_TZ_MAGIC))
|
||||||
|
{
|
||||||
|
if ((vm.tz_s <= USR_RTC_TZ_ABS_MAX_S) && (vm.tz_s >= -USR_RTC_TZ_ABS_MAX_S))
|
||||||
|
{
|
||||||
|
s_rtc.tz_s = vm.tz_s;
|
||||||
|
s_rtc.tz_valid = 1;
|
||||||
|
log_info("tz from vm %ld", (long)s_rtc.tz_s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_debug("tz vm empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 时区写入 VM
|
||||||
|
* @param tz_s 时区偏移秒
|
||||||
|
*/
|
||||||
|
static void usr_rtc_save_tz(int32_t tz_s)
|
||||||
|
{
|
||||||
|
UsrRtcTzVm_t vm;
|
||||||
|
|
||||||
|
s_rtc.tz_s = tz_s;
|
||||||
|
s_rtc.tz_valid = 1;
|
||||||
|
vm.magic = USR_RTC_TZ_MAGIC;
|
||||||
|
vm.tz_s = tz_s;
|
||||||
|
syscfg_write(CFG_USER_TIM_FLAG, (u8 *)&vm, sizeof(vm));
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* @file usr_rtc.h
|
||||||
|
* @brief 板级 RTC:硬件对时 + 客户读本地日历
|
||||||
|
* @author cyWu <1917507415@qq.com>
|
||||||
|
* @date 2026.08.19
|
||||||
|
* @version V1.1.0
|
||||||
|
* @history
|
||||||
|
* - V1.0.0, 2026.08.19, cyWu, 从模组固件移植至 SOC SDK
|
||||||
|
* - V1.1.0, 2026.08.19, cyWu, 精简接口;usr_rtc_get_time 返回本地日历
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __USR_RTC_H__
|
||||||
|
#define __USR_RTC_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "system/sys_time.h"
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 宏定义 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
#define USR_RTC_YEAR_MIN (2026u) /**< 合法年份下限 */
|
||||||
|
#define USR_RTC_YEAR_MAX (2098u) /**< 合法年份上限 */
|
||||||
|
#define USR_RTC_TZ_ABS_MAX_S (57600) /**< 时区偏移绝对值上限(±16h) */
|
||||||
|
#define USR_RTC_SYNC_COMPENSATE_S (1u) /**< 网关对时延迟补偿(秒) */
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 错误码(init / set_from_unix) */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USR_RTC_OK = 0,
|
||||||
|
USR_RTC_ERR_PARAM,
|
||||||
|
USR_RTC_ERR_NOT_INIT,
|
||||||
|
USR_RTC_ERR_INVALID, /**< 年份非法,等待 App 对时 */
|
||||||
|
} UsrRtc_Ret_t;
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
/* 外部接口 */
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开 "rtc" 设备并加载时区
|
||||||
|
* @return UsrRtc_Ret_t
|
||||||
|
* @note app_main 启动时调用一次即可
|
||||||
|
*/
|
||||||
|
UsrRtc_Ret_t usr_rtc_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前本地时间(客户常用)
|
||||||
|
* @param t 成功时写入年月日时分秒;失败时不改动
|
||||||
|
* @return 1=已对时且读成功,0=未初始化/未对时/参数非法
|
||||||
|
*/
|
||||||
|
uint8_t usr_rtc_get_time(struct sys_time *t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief App/网关 DEVICEINFO:UTC 秒 + 时区写入 RTC
|
||||||
|
* @param unix_utc UTC Unix 秒;0 无效
|
||||||
|
* @param tz_s 时区偏移秒(东八区 28800)
|
||||||
|
* @return UsrRtc_Ret_t
|
||||||
|
*/
|
||||||
|
UsrRtc_Ret_t usr_rtc_set_from_unix(uint64_t unix_utc, int32_t tz_s);
|
||||||
|
|
||||||
|
#endif /* __USR_RTC_H__ */
|
||||||
@@ -10,10 +10,9 @@ copy ..\..\ota.bin .
|
|||||||
copy ..\..\anc_coeff.bin .
|
copy ..\..\anc_coeff.bin .
|
||||||
copy ..\..\anc_gains.bin .
|
copy ..\..\anc_gains.bin .
|
||||||
|
|
||||||
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin -uboot_compress -key RS-5B88.key
|
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin -uboot_compress
|
||||||
|
|
||||||
|
:: -format all -key RS-5B88.key
|
||||||
:: -format all
|
|
||||||
::-reboot 2500
|
::-reboot 2500
|
||||||
|
|
||||||
@rem 删除临时文件-format all
|
@rem 删除临时文件-format all
|
||||||
|
|||||||
@@ -48,6 +48,23 @@ struct iokey_platform_data {
|
|||||||
extern int iokey_init(const struct iokey_platform_data *iokey_data);
|
extern int iokey_init(const struct iokey_platform_data *iokey_data);
|
||||||
extern u8 io_get_key_value(void);
|
extern u8 io_get_key_value(void);
|
||||||
|
|
||||||
|
/* 开机锁键:长按开机不松手时屏蔽全部按键,避免误触长按关机。
|
||||||
|
* 默认监视 port[0](请把电源键配成第 0 个)。
|
||||||
|
* 松开并连续确认 release_cnt 次扫描后解锁(扫描约 10ms 一次,默认 10 ≈ 100ms)。
|
||||||
|
*
|
||||||
|
* 关闭方式:
|
||||||
|
* 1) 编译关闭:在 board/app_config 里 #define TCFG_IOKEY_BOOT_LOCK_ENABLE 0
|
||||||
|
* 2) 运行关闭:iokey_boot_lock_stop() 或 iokey_boot_lock_start(0)
|
||||||
|
*/
|
||||||
|
#ifndef TCFG_IOKEY_BOOT_LOCK_ENABLE
|
||||||
|
#define TCFG_IOKEY_BOOT_LOCK_ENABLE 1
|
||||||
|
#endif
|
||||||
|
#ifndef IOKEY_BOOT_LOCK_DEFAULT_CNT
|
||||||
|
#define IOKEY_BOOT_LOCK_DEFAULT_CNT 10
|
||||||
|
#endif
|
||||||
|
void iokey_boot_lock_start(u8 release_cnt); /* >0 启动;0=关闭 */
|
||||||
|
void iokey_boot_lock_stop(void); /* 立即关闭锁键 */
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -492,6 +492,7 @@ def write_readme(readme_path: Path, version: str, module_stats: List[dict]) -> N
|
|||||||
"│ ├── common/ # SDK 公共模块",
|
"│ ├── common/ # SDK 公共模块",
|
||||||
"│ ├── earphone/ # 耳机应用",
|
"│ ├── earphone/ # 耳机应用",
|
||||||
"│ ├── usr_jb_proto/ # 应用协议层",
|
"│ ├── usr_jb_proto/ # 应用协议层",
|
||||||
|
"│ ├── usr_periph/ # 板级外设(RTC 等,源码开放)",
|
||||||
"│ └── usr_le_code/ # BLE 协议库(库文件 + 公开头文件)",
|
"│ └── usr_le_code/ # BLE 协议库(库文件 + 公开头文件)",
|
||||||
"├── cpu/ # 芯片相关代码与工具",
|
"├── cpu/ # 芯片相关代码与工具",
|
||||||
"├── include_lib/ # SDK 头文件",
|
"├── include_lib/ # SDK 头文件",
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
1.0.0
|
1.0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user