4292 lines
136 KiB
C
4292 lines
136 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
|
|
/* os_shim header files */
|
|
#include "os_types_api.h"
|
|
#include "os_timer_api.h"
|
|
#include "os_utils_api.h"
|
|
|
|
/* iot common header files */
|
|
#include "iot_module_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_utils_api.h"
|
|
#include "iot_system_api.h"
|
|
#include "iot_bitops_api.h"
|
|
#include "iot_bitmap_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_upgrade_api.h"
|
|
|
|
#include "iot_bsrm_common.h"
|
|
#include "iot_bsrm.h"
|
|
#include "iot_plc_hw_tsfm_api.h"
|
|
#include "iot_plc_msg_api.h"
|
|
#include "iot_bsrm_rec.h"
|
|
#include "iot_bsrm_nv.h"
|
|
#include "proto_hw_tsfm.h"
|
|
#include "iot_bsrm_flash.h"
|
|
#include "proto_645_fj.h"
|
|
#include "iot_bsrm_upgrade.h"
|
|
#include "proto_645_vendor.h"
|
|
#include "proto_69845.h"
|
|
#include "iot_plc_hw_topo_api.h"
|
|
#include "iot_bsrm_pm_upgrade.h"
|
|
#include "iot_sg_ext_sta_api.h"
|
|
|
|
/* define extend bsrm app task stack size */
|
|
#define IOT_BSRM_TASK_STACK_SZIE (1024)
|
|
/* define extend bsrm app task prio */
|
|
#define IOT_BSRM_TASK_PRIO (7)
|
|
/* define extend bsrm app message pool size */
|
|
#define IOT_BSRM_MSG_POOL_SIZE (128)
|
|
/* define extend bsrm app PLC data default priority */
|
|
#define IOT_BSRM_PLC_DEFAULT_PRIO (0)
|
|
|
|
/* define bsrm uart buf size */
|
|
#define IOT_BSRM_UART_BUF_SIZE (2048)
|
|
|
|
/* define periodic timer interval, uint is 1ms */
|
|
#define IOT_BSRM_PERIOND_TIMER_INTERVAL (1000)
|
|
/* define request addr and tm timer interval, uint is 1s */
|
|
#define IOT_BSRM_REQ_TIMER_TIMEOUT (60)
|
|
/* define request max count */
|
|
#define IOT_BSRM_REQ_MAX_CNT (15)
|
|
|
|
/* define auto correct tm timer interval, uint is 1s */
|
|
#define IOT_BSRM_AUTO_CORRECT_TM_INTERVAL (24 * 60 * 60)
|
|
|
|
/* define periodic timer interval, uint is 1ms */
|
|
#define IOT_BSRM_MR_TIMER_HANDLE_PERIOD (100)
|
|
|
|
/* the timeout time for 645 response data timeout, uint is 1ms. */
|
|
#define IOT_BSRM_MR_TIMER_RSP_TIMEOUT (2000)
|
|
#define IOT_BSRM_MR_EVT_NODIFY_TIMEOUT (1000)
|
|
#define IOT_BSRM_MR_FWD_TAKEN_TIMEOUT (3000)
|
|
|
|
/* energy base coeff uint: 0.0001 */
|
|
#define IOT_BSRM_BRANCH_BASE_COEFF_VAL (10000)
|
|
|
|
/* enable/disable bsrm app data print */
|
|
#define IOT_BSRM_DEBUG 1
|
|
/* the timeout time for branch event, uint is 1s. */
|
|
#define IOT_BSRM_BRANCH_EVT_TIMEOUT (60 * 15)
|
|
/* branch identification record countdown, uint is 1s */
|
|
#define IOT_BSRM_BR_REC_CD (6)
|
|
|
|
/* bsrm trans mode */
|
|
/* default mode, bsrm get tm and addr from uart */
|
|
#define IOT_BSRM_SESSION_MODE_DEFAULT (0)
|
|
/* trans mode, sg data tranlate to uart */
|
|
#define IOT_BSRM_SESSION_MODE_TRANS (1)
|
|
|
|
/* defines the maximum number of event notification tries */
|
|
#define IOT_BSRM_EVT_NODIFY_TRY_MAX (3)
|
|
|
|
/* define check event gpio interrupt max times, unit: 1/s */
|
|
#define IOT_BSRM_EVENT_CHECK_TIMES (5)
|
|
|
|
/* define bsrm br2 phase */
|
|
#define IOT_BSRM_BR2_PHASE_UNKNOWN (0)
|
|
#define IOT_BSRM_BR2_PHASE_A (1)
|
|
#define IOT_BSRM_BR2_PHASE_B (2)
|
|
#define IOT_BSRM_BR2_PHASE_C (3)
|
|
#define IOT_BSRM_BR2_PHASE_ALL (4)
|
|
|
|
/* define bsrm br2 recode max response count */
|
|
#define IOT_BSRM_BR_REC_MAX_RESP_CNT (4)
|
|
|
|
/* br rec fragmenting transmission window duration, uins is 1s */
|
|
#define IOT_BSRM_BR_REC_FRAG_WIN_DUR (300)
|
|
|
|
#if IOT_BSRM_MODE
|
|
|
|
/* ipc address of sg app */
|
|
static iot_ipc_addr_t sg_app_addr =
|
|
{ IOT_IPC_FID_SG_EXT_SDK, IOT_IPC_CID_SG_EXT_SG_APP};
|
|
|
|
static iot_bsrm_global_t *p_bsrm_glb = NULL;
|
|
|
|
typedef struct _iot_bsrm_rating_current_param {
|
|
/* rating current value, unit: A */
|
|
uint32_t rating_current;
|
|
/* transfer ratio */
|
|
float ratio;
|
|
/* current sampling resistance, unit: 1.0ohm */
|
|
float resistance;
|
|
} iot_bsrm_rating_current_t;
|
|
|
|
/* zhengtai current ratio coeff data table */
|
|
const iot_bsrm_rating_current_t rating_cur_tab[] = {
|
|
{80, 2000.0, 2.0}, {100, 2000.0, 2.0}, {125, 3200.0, 2.0},
|
|
{160, 3200.0, 2.0}, {200, 5000.0, 2.0}, {250, 5000.0, 2.0},
|
|
{315, 6666.667, 2.0}, {400, 6666.667, 2.0}, {500, 9000.0, 2.0},
|
|
{630, 9000.0, 2.0}, {700, 10000.0, 2.0}, {800, 10000.0, 2.0}
|
|
};
|
|
|
|
#if IOT_BSRM_DEBUG
|
|
|
|
void iot_bsrm_data_print(const char* str, uint8_t* buf, uint32_t len)
|
|
{
|
|
static char log_buf[1024];
|
|
uint32_t offset = 0;
|
|
offset = iot_sprintf(log_buf, "%s[len:%d]", str, len);
|
|
for (uint32_t i = 0; i < len; ++i) {
|
|
offset += iot_sprintf(log_buf + offset, "%02X ", buf[i]);
|
|
if (IOT_ARRAY_CNT(log_buf) <= offset + 4) {
|
|
break;
|
|
}
|
|
}
|
|
log_buf[offset] = 0;
|
|
iot_bsrm_printf("%s\n", log_buf);
|
|
}
|
|
|
|
#else
|
|
|
|
void iot_bsrm_data_print(const char* str, uint8_t* buf, uint32_t len)
|
|
{
|
|
(void)str;
|
|
(void)buf;
|
|
(void)len;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* calculating Week of zeller formula */
|
|
static uint8_t iot_bsrm_zeller_calc_week(iot_time_tm_t *tm)
|
|
{
|
|
iot_time_tm_t tm_temp = *tm;
|
|
if (tm_temp.tm_mon < 3) {
|
|
tm_temp.tm_year -= 1;
|
|
tm_temp.tm_mon += 12;
|
|
}
|
|
int32_t c = tm_temp.tm_year / 100;
|
|
int32_t y = tm_temp.tm_year % 100;
|
|
int32_t ans = (c / 4 - 2 * c + y + y / 4 + ( 26 * ( tm_temp.tm_mon + 1)) \
|
|
/ 10 + tm_temp.tm_mday - 1 ) % 7;
|
|
|
|
if (ans < 0)
|
|
ans += 7;
|
|
return (uint8_t)ans;
|
|
}
|
|
|
|
static void iot_bsrm_post_msg(uint16_t msg_type, uint16_t msg_id,
|
|
uint8_t prio, void *data, uint32_t data2)
|
|
{
|
|
iot_bsrm_msg_t *msg;
|
|
msg = (iot_bsrm_msg_t *)iot_task_alloc_msg(p_bsrm_glb->task_h);
|
|
IOT_ASSERT(msg);
|
|
msg->task_msg.type = msg_type;
|
|
msg->task_msg.id = msg_id;
|
|
msg->data = data;
|
|
msg->data2 = data2;
|
|
iot_task_queue_msg(p_bsrm_glb->task_h, &msg->task_msg, prio);
|
|
}
|
|
|
|
static void iot_bsrm_clean_msg(uint16_t msg_type, uint16_t msg_id)
|
|
{
|
|
iot_task_clean_msg(p_bsrm_glb->task_h, msg_type, msg_id);
|
|
}
|
|
|
|
/* callback function for bsrm receive data */
|
|
static void iot_bsrm_uart_recv(uint8_t* buffer, uint32_t buffer_len,
|
|
bool_t is_full_frame, uint32_t invalid_data_len)
|
|
{
|
|
(void)is_full_frame;
|
|
(void)invalid_data_len;
|
|
iot_pkt_t *pkt=NULL;
|
|
|
|
iot_bsrm_data_print("uart recv data:", buffer, buffer_len);
|
|
if (0 == buffer_len) {
|
|
return;
|
|
}
|
|
pkt = iot_pkt_alloc(buffer_len, IOT_BSRM_MID);
|
|
IOT_ASSERT(pkt);
|
|
os_mem_cpy(iot_pkt_put(pkt, buffer_len), buffer, buffer_len);
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_UART,
|
|
IOT_BSRM_MSG_ID_UART_DATA, IOT_BSRM_MSG_QUEUE_LP, (void *)pkt,
|
|
0);
|
|
}
|
|
|
|
static void iot_bsrm_mr_timer_func(timer_id_t timer_id, void *arg)
|
|
{
|
|
(void)timer_id;
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_TIMER,
|
|
IOT_BSRM_MSG_ID_TIMER_CHECK_MR, IOT_BSRM_MSG_QUEUE_LP, arg, 0);
|
|
}
|
|
|
|
static void iot_brm_stop_mr_timer(void)
|
|
{
|
|
os_stop_timer(p_bsrm_glb->mr_timer);
|
|
iot_task_clean_msg(p_bsrm_glb->task_h, IOT_BSRM_MSG_TYPE_TIMER,
|
|
IOT_BSRM_MSG_ID_TIMER_CHECK_MR);
|
|
}
|
|
|
|
static void iot_bsrm_restart_mr_timer(uint32_t dur)
|
|
{
|
|
iot_brm_stop_mr_timer();
|
|
os_start_timer(p_bsrm_glb->mr_timer, dur);
|
|
}
|
|
|
|
void iot_bsrm_uart_send(iot_pkt_t *pkt)
|
|
{
|
|
iot_bsrm_data_print("uart send data:", iot_pkt_data(pkt),
|
|
iot_pkt_data_len(pkt));
|
|
iot_uart_send(p_bsrm_glb->handle, pkt, NULL);
|
|
}
|
|
|
|
static void iot_bsrm_fwd_data(iot_pkt_t *pkt)
|
|
{
|
|
switch (p_bsrm_glb->mr_status) {
|
|
case IOT_BSRM_MR_STATE_IDLE:
|
|
case IOT_BSRM_MR_STATE_READY:
|
|
{
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_FWD;
|
|
}
|
|
case IOT_BSRM_MR_STATE_FWD:
|
|
{
|
|
iot_bsrm_uart_send(pkt);
|
|
iot_bsrm_restart_mr_timer(3000);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_EVT_NODIF:
|
|
case IOT_BSRM_MR_STATE_SYNC_CUR_RATIO_COEFF:
|
|
case IOT_BSRM_MR_STATE_PM_UPGRADE:
|
|
{
|
|
if (p_bsrm_glb->fwd_pkt) {
|
|
iot_pkt_free(p_bsrm_glb->fwd_pkt);
|
|
p_bsrm_glb->fwd_pkt = pkt;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_send_pkt_to_sg_app(iot_pkt_t *pkt)
|
|
{
|
|
iot_sg_ext_header_t *hdr;
|
|
uint8_t *data;
|
|
if (iot_pkt_block_len(pkt, IOT_PKT_BLOCK_HEAD) < sizeof(*hdr)) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
data = (uint8_t *)iot_pkt_push(pkt, sizeof(*hdr));
|
|
hdr = (iot_sg_ext_header_t *)data;
|
|
hdr->mid = IOT_SG_EXT_MID_UART_DATA_FROM_CUS;
|
|
iot_ipc_send(p_bsrm_glb->ipc_h, &sg_app_addr, pkt);
|
|
}
|
|
|
|
static void iot_bsrm_send_data_to_sg_app(uint8_t *data, uint32_t len)
|
|
{
|
|
iot_sg_ext_header_t *hdr;
|
|
iot_pkt_t *pkt;
|
|
uint8_t *ds;
|
|
pkt = iot_pkt_alloc(len + sizeof(*hdr), IOT_BSRM_MID);
|
|
if (pkt == NULL)
|
|
return;
|
|
iot_bsrm_data_print("bsrm to sg app:", data, len);
|
|
ds = iot_pkt_reserve(pkt, sizeof(*hdr));
|
|
os_mem_cpy(ds, data, len);
|
|
iot_pkt_put(pkt, len);
|
|
iot_bsrm_send_pkt_to_sg_app(pkt);
|
|
}
|
|
|
|
static void iot_bsrm_cmd_guard(uint32_t value)
|
|
{
|
|
if (p_bsrm_glb->mr_status == IOT_BSRM_MR_STATE_IDLE) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
os_start_timer(p_bsrm_glb->mr_timer, value);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_set_correct_tm_base()
|
|
{
|
|
/* sync tm done */
|
|
p_bsrm_glb->sync_tm_done = 1;
|
|
iot_rtc_set(&p_bsrm_glb->correct_tm);
|
|
}
|
|
|
|
static void iot_bsrm_set_correct_tm(uint8_t flag)
|
|
{
|
|
if (flag) {
|
|
p_bsrm_glb->sync_tm_state = IOT_BSRM_SYNC_TIME_STATE_IDLE;
|
|
p_bsrm_glb->mr_tm_interval = 0;
|
|
iot_bsrm_set_correct_tm_base();
|
|
iot_bsrm_printf("%s tm: %d/%d/%d %d:%d:%d\n", __FUNCTION__,
|
|
p_bsrm_glb->correct_tm.tm_year,
|
|
p_bsrm_glb->correct_tm.tm_mon,
|
|
p_bsrm_glb->correct_tm.tm_mday,
|
|
p_bsrm_glb->correct_tm.tm_hour,
|
|
p_bsrm_glb->correct_tm.tm_min,
|
|
p_bsrm_glb->correct_tm.tm_sec);
|
|
} else {
|
|
/* ready sync tm */
|
|
p_bsrm_glb->sync_tm_state = IOT_BSRM_SYNC_TIME_STATE_YMD;
|
|
p_bsrm_glb->mr_tm_interval = 0;
|
|
iot_bsrm_cmd_guard(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
iot_bsrm_printf("bsrm correct tm begin\n");
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_set_addr(uint8_t *addr)
|
|
{
|
|
iot_mac_addr_cpy(p_bsrm_glb->addr, addr);
|
|
if (!p_bsrm_glb->addr_valid) {
|
|
/* ready sync tm */
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
iot_bsrm_set_correct_tm(0);
|
|
}
|
|
p_bsrm_glb->addr_valid = 1;
|
|
if (p_bsrm_glb->cur_coeff_sync_sts == IOT_BSRM_SYNC_CUR_COEFF_IDLE) {
|
|
/* ready sync current coeff */
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_DOING;
|
|
iot_bsrm_cmd_guard(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
}
|
|
}
|
|
iot_bsrm_printf("bsrm set addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
|
|
}
|
|
|
|
static uint8_t iot_bsrm_addr_check(uint8_t *dst_addr)
|
|
{
|
|
if (!p_bsrm_glb->addr_valid) {
|
|
return 1;
|
|
}
|
|
return proto_645_mac_addr_cmp(p_bsrm_glb->addr, dst_addr);
|
|
}
|
|
|
|
static void iot_bsrm_check_renew_addr(uint8_t *addr)
|
|
{
|
|
if (!proto_645_pm_addr_valid(addr))
|
|
return;
|
|
if (!p_bsrm_glb->addr_valid ||
|
|
!iot_mac_addr_cmp(addr, p_bsrm_glb->addr)) {
|
|
/* renew addr */
|
|
iot_bsrm_set_addr(addr);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_check_done_handle()
|
|
{
|
|
/* stop bsrm check timer */
|
|
os_stop_timer(p_bsrm_glb->mr_timer);
|
|
iot_bsrm_clean_msg(IOT_BSRM_MSG_TYPE_TIMER,
|
|
IOT_BSRM_MSG_ID_TIMER_CHECK_MR);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_IDLE;
|
|
if (p_bsrm_glb->mr_addr_pend ||
|
|
(p_bsrm_glb->sync_tm_state != IOT_BSRM_SYNC_TIME_STATE_IDLE)) {
|
|
iot_bsrm_cmd_guard(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_bsrm_handle_slave_data(iot_pkt_t *pkt)
|
|
{
|
|
proto_645_header_t *hdr_645;
|
|
uint8_t ret = ERR_FAIL;
|
|
uint32_t di;
|
|
proto_645_time_hms_t *t_hms;
|
|
proto_645_time_ymd_t *t_ymd;
|
|
|
|
hdr_645 = proto_645_format_check(iot_pkt_data(pkt), iot_pkt_data_len(pkt),
|
|
PROTO_645_DIR_SLAVE);
|
|
if (hdr_645 == NULL) {
|
|
goto out;
|
|
}
|
|
ret = ERR_OK;
|
|
proto_645_sub33_handle(hdr_645->data, hdr_645->len);
|
|
di = proto_645_2007_byte_to_di(hdr_645->data);
|
|
hdr_645->len -= PROTO_645_2007_DI_LEN;
|
|
|
|
iot_bsrm_check_renew_addr(hdr_645->addr);
|
|
|
|
switch (p_bsrm_glb->mr_status) {
|
|
case IOT_BSRM_MR_GET_ADDR:
|
|
{
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_SYNC_TIME:
|
|
{
|
|
if ((di == PROTO_645_2007_DI_TIME_YMD) &&
|
|
(p_bsrm_glb->sync_tm_state == IOT_BSRM_SYNC_TIME_STATE_YMD)) {
|
|
t_ymd = (proto_645_time_ymd_t *)(hdr_645->data +
|
|
PROTO_645_2007_DI_LEN);
|
|
p_bsrm_glb->correct_tm.tm_mday = iot_bcd_to_byte(t_ymd->day);
|
|
p_bsrm_glb->correct_tm.tm_mon = iot_bcd_to_byte(t_ymd->month);
|
|
p_bsrm_glb->correct_tm.tm_year = iot_bcd_to_byte(t_ymd->year) +
|
|
2000;
|
|
iot_bsrm_printf("correct ymd success\n");
|
|
/* get ymd success, then get hms, set correct tm pend, get hms */
|
|
p_bsrm_glb->sync_tm_state = IOT_BSRM_SYNC_TIME_STATE_HMS;
|
|
} else if ((di == PROTO_645_2007_DI_TIME_HMS) &&
|
|
(p_bsrm_glb->sync_tm_state == IOT_BSRM_SYNC_TIME_STATE_HMS)) {
|
|
t_hms = (proto_645_time_hms_t *)(hdr_645->data +
|
|
PROTO_645_2007_DI_LEN);
|
|
p_bsrm_glb->correct_tm.tm_hour = iot_bcd_to_byte(t_hms->hour);
|
|
p_bsrm_glb->correct_tm.tm_min = iot_bcd_to_byte(t_hms->minute);
|
|
p_bsrm_glb->correct_tm.tm_sec = iot_bcd_to_byte(t_hms->second);
|
|
iot_bsrm_printf("correct hms success\n");
|
|
iot_bsrm_set_correct_tm(1);
|
|
} else {
|
|
iot_bsrm_printf("%s cancle 645 di: %04x \n", __FUNCTION__, di);
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
iot_bsrm_printf("%s cancle 645 di: %04x \n", __FUNCTION__, di);
|
|
goto out;
|
|
}
|
|
iot_bsrm_check_done_handle();
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_handle_upgrade(uint8_t *data, uint8_t data_len,
|
|
uint8_t *out_buf, uint8_t *len)
|
|
{
|
|
uint32_t result = ERR_OK;
|
|
proto_645_fj_send_file_dl_t *req = (proto_645_fj_send_file_dl_t*)data;
|
|
proto_645_fj_send_file_ul_t rsp;
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
|
|
if (data_len < sizeof(proto_645_fj_send_file_dl_t)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
goto out;
|
|
}
|
|
|
|
iot_bsrm_printf("sg_upgrade: action = %d, seg_len = %d, file_cmd = %d, "
|
|
"is_last = %d, seg_index/total_set_cnt = %d/%d. sn = %d\n",
|
|
req->action, req->cur_seg_len, req->file_cmd,
|
|
req->is_last_seg, req->seg_index, req->total_seg_cnt, 0);
|
|
rsp.segment_index = req->seg_index;
|
|
switch (req->action) {
|
|
case PROTO_645_FJ_UPGRADE_CLEAR_FILE:
|
|
{
|
|
iot_bsrm_upgrade_stop();
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_UPGRADE_CCO_STA_MODULE:
|
|
case PROTO_645_FJ_UPGRADE_LOCAL_MODULE:
|
|
case PROTO_645_FJ_UPGRADE_STA_MODULE:
|
|
{
|
|
if (req->total_seg_cnt == 0 ||
|
|
req->cur_seg_len == 0) {
|
|
/* reject invalid data packet. */
|
|
rsp.segment_index = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
break;
|
|
}
|
|
|
|
if (0 == req->seg_index) {
|
|
iot_bsrm_upgrade_start(req->total_seg_cnt, req->cur_seg_len);
|
|
if (ERR_OK != result) {
|
|
rsp.segment_index = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
break;
|
|
}
|
|
}
|
|
result = iot_bsrm_upgrade_data(req->seg_index, req->cur_seg_len,
|
|
req->data);
|
|
if (ERR_OK != result) {
|
|
rsp.segment_index = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
*len = sizeof(rsp.segment_index);
|
|
os_mem_cpy(out_buf, &rsp, *len);
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_branch_info_evt_req_handle(uint32_t di,
|
|
uint8_t *out_buf, uint8_t *remain_len, uint16_t *len_out)
|
|
{
|
|
uint8_t ret, i, err_code = PROTO_645_2007_ERR_OK;
|
|
uint8_t entry_len;
|
|
uint8_t *p_rsp = NULL;
|
|
uint32_t di_3_1, di_0;
|
|
iot_time_tm_t tm;
|
|
iot_bsrm_nv_info_t *nv_info;
|
|
proto_645_ext_br2_evt_cnt_ul_t *evt_cnt_rsp = NULL;
|
|
iot_bsrm_branch_evt_rec_entry_t *evt_buff;
|
|
proto_645_ext_br2_evt_rec_ul_t *evt_rec_rsp = NULL;
|
|
proto_645_ext_br2_evt_rec_entry_t *evt_rec_data = NULL;
|
|
proto_645_ext_br2_evt_rec_dx_ul_t *evt_rec_rsp_dx = NULL;
|
|
proto_645_ext_br2_evt_rec_entry_dx_t *evt_rec_data_dx = NULL;
|
|
|
|
di_3_1 = di & 0xFFFFFF00;
|
|
if (di_3_1 != PROTO_645_2007_EXT_DI_BR2_EVT_RECORD_ZJ &&
|
|
di_3_1 != PROTO_645_2007_EXT_DI_BR2_EVT_RECORD_DX) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
return err_code;
|
|
}
|
|
di_0 = di & 0xFF;
|
|
nv_info = (iot_bsrm_nv_info_t *)iot_bsrm_nv_get_section(
|
|
iot_bsrm_nv_id_info);
|
|
if (!di_0) {
|
|
evt_cnt_rsp = (proto_645_ext_br2_evt_cnt_ul_t *)(out_buf + *len_out);
|
|
proto_645_unsig_to_bcd(nv_info->evt_occur_cnt, PROTO_645_NUM_LEN,
|
|
evt_cnt_rsp->evt_cnt);
|
|
*len_out += sizeof(*evt_cnt_rsp);
|
|
*remain_len -= sizeof(*evt_cnt_rsp);
|
|
} else {
|
|
ret = iot_bsrm_evt_read(di_0, (uint8_t **)&evt_buff);
|
|
switch (di_3_1) {
|
|
case PROTO_645_2007_EXT_DI_BR2_EVT_RECORD_ZJ:
|
|
{
|
|
evt_rec_rsp =
|
|
(proto_645_ext_br2_evt_rec_ul_t *)(out_buf + *len_out);
|
|
*len_out += sizeof(*evt_rec_rsp);
|
|
*remain_len -= sizeof(*evt_rec_rsp);
|
|
if (ret != ERR_OK) {
|
|
evt_rec_rsp->id_len = 0;
|
|
evt_rec_rsp->signal_cnt = 0;
|
|
break;
|
|
}
|
|
evt_rec_rsp->signal_cnt = evt_buff->data_cnt;
|
|
for (i = 0; i < evt_rec_rsp->signal_cnt; i++) {
|
|
if (evt_buff->record_data[i].id_code_len >
|
|
evt_rec_rsp->id_len) {
|
|
evt_rec_rsp->id_len = evt_buff->record_data[i].id_code_len;
|
|
}
|
|
}
|
|
p_rsp = (uint8_t *)evt_rec_rsp->data;
|
|
for (i = 0; i < evt_rec_rsp->signal_cnt; i++) {
|
|
entry_len = evt_rec_rsp->id_len + sizeof(*evt_rec_data) +
|
|
PROTO_645_EXT_EVT_READ_RESERVE_LEN_ZJ;
|
|
if (*remain_len < entry_len) {
|
|
break;
|
|
}
|
|
evt_rec_data = (proto_645_ext_br2_evt_rec_entry_t *)p_rsp;
|
|
iot_bsrm_time_to_rtctime(evt_buff->record_data[i].ts, &tm);
|
|
evt_rec_data->signal_time.year = (uint8_t)(tm.tm_year - 2000);
|
|
evt_rec_data->signal_time.month = tm.tm_mon;
|
|
evt_rec_data->signal_time.day = tm.tm_mday;
|
|
evt_rec_data->signal_time.hour = tm.tm_hour;
|
|
evt_rec_data->signal_time.minute = tm.tm_min;
|
|
evt_rec_data->signal_time.second = tm.tm_sec;
|
|
evt_rec_data->phase = evt_buff->record_data[i].phase;
|
|
evt_rec_data->signal1_rssi =
|
|
evt_buff->record_data[i].signal1_rssi;
|
|
evt_rec_data->signal2_rssi =
|
|
evt_buff->record_data[i].signal2_rssi;
|
|
evt_rec_data->noise = evt_buff->record_data[i].noise;
|
|
p_rsp += sizeof(*evt_rec_data);
|
|
os_mem_cpy(p_rsp, &evt_buff->record_data[i].id_code,
|
|
evt_buff->record_data[i].id_code_len);
|
|
p_rsp += evt_buff->record_data[i].id_code_len;
|
|
os_mem_set(p_rsp, 0,
|
|
evt_rec_rsp->id_len - evt_buff->record_data[i].id_code_len);
|
|
p_rsp +=
|
|
evt_rec_rsp->id_len - evt_buff->record_data[i].id_code_len;
|
|
os_mem_set(p_rsp, 0, PROTO_645_EXT_EVT_READ_RESERVE_LEN_ZJ);
|
|
p_rsp += PROTO_645_EXT_EVT_READ_RESERVE_LEN_ZJ;
|
|
*len_out += entry_len;
|
|
*remain_len -= entry_len;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_EVT_RECORD_DX:
|
|
{
|
|
evt_rec_rsp_dx =
|
|
(proto_645_ext_br2_evt_rec_dx_ul_t *)(out_buf + *len_out);
|
|
*len_out += sizeof(*evt_rec_rsp_dx);
|
|
*remain_len -= sizeof(*evt_rec_rsp_dx);
|
|
if (ret != ERR_OK) {
|
|
evt_rec_rsp->id_len = 0;
|
|
evt_rec_rsp->signal_cnt = 0;
|
|
break;
|
|
}
|
|
evt_rec_rsp_dx->signal_cnt = evt_buff->data_cnt;
|
|
evt_rec_data_dx = evt_rec_rsp_dx->data;
|
|
for (i = 0; i < evt_rec_rsp_dx->signal_cnt; i++) {
|
|
entry_len = sizeof(*evt_rec_data_dx);
|
|
if (*remain_len < entry_len) {
|
|
break;
|
|
}
|
|
iot_bsrm_time_to_rtctime(evt_buff->record_data[i].ts, &tm);
|
|
evt_rec_data_dx->signal_time.year =
|
|
(uint8_t)(tm.tm_year - 2000);
|
|
evt_rec_data_dx->signal_time.month = tm.tm_mon;
|
|
evt_rec_data_dx->signal_time.day = tm.tm_mday;
|
|
evt_rec_data_dx->signal_time.hour = tm.tm_hour;
|
|
evt_rec_data_dx->signal_time.minute = tm.tm_min;
|
|
evt_rec_data_dx->signal_time.second = tm.tm_sec;
|
|
evt_rec_data_dx->phase = evt_buff->record_data[i].phase;
|
|
evt_rec_data_dx->signal1_rssi =
|
|
evt_buff->record_data[i].signal1_rssi;
|
|
evt_rec_data_dx->signal2_rssi =
|
|
evt_buff->record_data[i].signal2_rssi;
|
|
evt_rec_data_dx->signal_fund_wave = 0;
|
|
evt_rec_data_dx->noise = evt_buff->record_data[i].noise;
|
|
os_mem_cpy(evt_rec_data_dx->id_code,
|
|
&evt_buff->record_data[i].id_code,
|
|
sizeof(evt_rec_data_dx->id_code));
|
|
evt_rec_data_dx++;
|
|
*len_out += entry_len;
|
|
*remain_len -= entry_len;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return err_code;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_handle_upgrade_query_bitmap(uint8_t *out_buf,
|
|
uint8_t *len)
|
|
{
|
|
iot_bsrm_upgrade_info_t query_info = { 0 };
|
|
uint16_t max_array_index;
|
|
uint16_t bitmap_size;
|
|
uint16_t start_array_index;
|
|
uint32_t query_bitmap_cbs;
|
|
uint32_t bitmap_cbs = 0;
|
|
uint8_t recvdone = 0;
|
|
proto_645_fj_query_file_ul_t *rsp = (proto_645_fj_query_file_ul_t *)out_buf;
|
|
uint8_t *bitmap = rsp->array_bitmap;
|
|
|
|
os_mem_set(bitmap, 0, sizeof(rsp->array_bitmap));
|
|
iot_bsrm_query_upgrade_info(&query_info);
|
|
|
|
if (query_info.state <= IOT_BSRM_UPGRADE_ST_IDLE) {
|
|
/* recv done */
|
|
start_array_index = 0;
|
|
recvdone = 1;
|
|
goto out;
|
|
}
|
|
|
|
/* upgrade file segment bitmap size */
|
|
bitmap_size = (uint16_t)((query_info.block_cnt + 7) >> 3);
|
|
/* upgrade file segment bitmap array size */
|
|
max_array_index = (PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN - 1 + bitmap_size) /
|
|
PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN;
|
|
|
|
for (start_array_index = 0; start_array_index < max_array_index - 1;
|
|
start_array_index++) {
|
|
bitmap_size = (uint16_t)iot_bsrm_upgrade_query_bitmap_info(bitmap,
|
|
start_array_index * PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN,
|
|
PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
query_bitmap_cbs = iot_bitmap_cbs(bitmap, bitmap_size);
|
|
if (query_bitmap_cbs !=
|
|
(PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN << 3)) {
|
|
/* not recv done */
|
|
recvdone = 0;
|
|
goto out;
|
|
}
|
|
bitmap_cbs += query_bitmap_cbs;
|
|
}
|
|
|
|
bitmap_size = (uint16_t)iot_bsrm_upgrade_query_bitmap_info(bitmap,
|
|
start_array_index * PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN,
|
|
PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
query_bitmap_cbs = iot_bitmap_cbs(bitmap, bitmap_size);
|
|
bitmap_cbs += query_bitmap_cbs;
|
|
if (bitmap_cbs >= query_info.block_cnt) {
|
|
/* recv done */
|
|
recvdone = 1;
|
|
} else {
|
|
/* not recv done */
|
|
recvdone = 0;
|
|
}
|
|
out:
|
|
if (recvdone) {
|
|
os_mem_set(bitmap, 0 , PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
} else {
|
|
iot_bitmap_reverse(bitmap, PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
}
|
|
rsp->array_index = start_array_index;
|
|
*len = sizeof(*rsp);
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_get_ct_coeff()
|
|
{
|
|
iot_bsrm_nv_param_t *param = \
|
|
(iot_bsrm_nv_param_t *)iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
if ((param->i_coeff == 0xFFFFFFFF) ||
|
|
(param->i_coeff == 0)) {
|
|
param->i_coeff = IOT_BSRM_BRANCH_BASE_COEFF_VAL;
|
|
}
|
|
return param->i_coeff;
|
|
}
|
|
|
|
uint32_t iot_bsrm_set_pm_upgrade_guard_code(uint16_t guard_code)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_bsrm_nv_param_t *param = (iot_bsrm_nv_param_t *)
|
|
iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
|
|
if (guard_code != param->upgrade_pm_guard_code) {
|
|
param->upgrade_pm_guard_code = guard_code;
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_param);
|
|
ret = ERR_OK;
|
|
}
|
|
iot_bsrm_printf("%s flag: %d \n", __FUNCTION__,
|
|
param->upgrade_pm_guard_code);
|
|
return ret;
|
|
}
|
|
|
|
uint16_t iot_bsrm_get_pm_upgrade_guard_code()
|
|
{
|
|
iot_bsrm_nv_param_t *param = (iot_bsrm_nv_param_t *)\
|
|
iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
|
|
iot_bsrm_printf("%s upgrade pm flag: %d \n", __FUNCTION__,
|
|
param->upgrade_pm_guard_code);
|
|
return param->upgrade_pm_guard_code;
|
|
}
|
|
|
|
static void iot_bsrm_load_nv(void)
|
|
{
|
|
uint32_t tmp_coeff = 0;
|
|
hw_topo_ratio_coeff_t coeff = { 0 };
|
|
uint8_t i;
|
|
|
|
/* set the current ratio coefficient to topo module */
|
|
tmp_coeff = iot_bsrm_get_ct_coeff();
|
|
if (tmp_coeff) {
|
|
for (i = 0; i < IOT_PLC_PHASE_CNT; i++) {
|
|
coeff.i_ratio_coeff[i] = tmp_coeff;
|
|
}
|
|
iot_plc_hw_topo_ratio_cfg(&coeff);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_set_ct_coeff(uint32_t i_coeff)
|
|
{
|
|
uint8_t i;
|
|
hw_topo_ratio_coeff_t coeff = { 0 };
|
|
iot_bsrm_nv_param_t *param;
|
|
param = (iot_bsrm_nv_param_t *)\
|
|
iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
if (i_coeff &&
|
|
param->i_coeff != i_coeff) {
|
|
param->i_coeff = i_coeff;
|
|
for (i = 0; i < IOT_PLC_PHASE_CNT; i++) {
|
|
coeff.i_ratio_coeff[i] = param->i_coeff;
|
|
}
|
|
iot_plc_hw_topo_ratio_cfg(&coeff);
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_param);
|
|
iot_bsrm_printf("%s %lu\n", __FUNCTION__, i_coeff);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_set_br_recv_param(iot_bsrm_br_param_t *br_param)
|
|
{
|
|
uint8_t reason = 0;
|
|
hw_topo_rcv_cfg_t cfg = { 0 };
|
|
iot_bsrm_nv_param_t *nv_param = (iot_bsrm_nv_param_t *)
|
|
iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
if (!os_mem_cmp(&nv_param->br_param, br_param, sizeof(*br_param))) {
|
|
goto out;
|
|
}
|
|
if (!br_param->fc) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (!br_param->chara_bit_dur) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if (br_param->id_code_len > IOT_BSRM_BRANCH_ID_CODE_MAX) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (br_param->id_code_len) {
|
|
os_mem_cpy(&nv_param->br_param, br_param, sizeof(*br_param));
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_param);
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
} else {
|
|
cfg.phase = IOT_PLC_PHASE_ALL;
|
|
cfg.fc_valid = br_param->fc ? 1 : 0;
|
|
cfg.fc = br_param->fc;
|
|
cfg.chara_bit_dur = br_param->chara_bit_dur;
|
|
cfg.dur_valid = br_param->chara_bit_dur ? 1 : 0;
|
|
cfg.data_len = min(br_param->id_code_len,
|
|
IOT_HW_TOPO_MAX_NUMBER_OF_CODES);
|
|
os_mem_cpy(cfg.data, br_param->id_code, cfg.data_len);
|
|
iot_plc_hw_topo_rcv_cfg(&cfg);
|
|
iot_bsrm_printf("%s fc:%lu Hz, bit_dur:%lu ms, ", __FUNCTION__,
|
|
br_param->fc, br_param->chara_bit_dur);
|
|
iot_bsrm_data_print("code", br_param->id_code, cfg.data_len);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_br_rec_clear(void)
|
|
{
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_INTERNAL,
|
|
IOT_BSRM_MSG_ID_INTERNAL_BR_REC_CLEAR, IOT_BSRM_MSG_QUEUE_LP, NULL,
|
|
0);
|
|
}
|
|
|
|
static uint8_t iot_bsrm_proto_645_r_extend_data_hander(uint8_t *in_data,
|
|
uint8_t in_len, uint8_t *out_buf, uint8_t *len_out)
|
|
{
|
|
proto_645_ext_bsrm_trans_cmd_t *bsrm_ext_cmd;
|
|
proto_645_ext_ct_coeff_t *i_coeff;
|
|
uint8_t err_code = PROTO_645_2007_ERR_OTHER;
|
|
|
|
if (in_len < sizeof(*bsrm_ext_cmd)) {
|
|
goto out;
|
|
}
|
|
in_len -= sizeof(*bsrm_ext_cmd);
|
|
bsrm_ext_cmd = (proto_645_ext_bsrm_trans_cmd_t *)in_data;
|
|
switch (bsrm_ext_cmd->fn) {
|
|
case PROTO_645_EXT_BSRM_TANS_CMD_FN_W_CT_COEFF:
|
|
{
|
|
if (in_len < sizeof(*i_coeff)) {
|
|
break;
|
|
}
|
|
i_coeff = (proto_645_ext_ct_coeff_t *)bsrm_ext_cmd->data;
|
|
iot_bsrm_set_ct_coeff(i_coeff->coeff);
|
|
*len_out = 0;
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
break;
|
|
}
|
|
case PROTO_645_EXT_BSRM_TANS_CMD_FN_R_CT_COEFF:
|
|
{
|
|
proto_645_2007_di_to_byte(PROTO_645_EXT_BSRM_DI_TANS_CMD, out_buf);
|
|
*len_out = PROTO_645_2007_DI_LEN;
|
|
bsrm_ext_cmd =
|
|
(proto_645_ext_bsrm_trans_cmd_t *)(out_buf + PROTO_645_2007_DI_LEN);
|
|
bsrm_ext_cmd->fn = PROTO_645_EXT_BSRM_TANS_CMD_FN_R_CT_COEFF;
|
|
i_coeff = (proto_645_ext_ct_coeff_t *)bsrm_ext_cmd->data;
|
|
i_coeff->coeff = iot_bsrm_get_ct_coeff();
|
|
*len_out += sizeof(*bsrm_ext_cmd) + sizeof(*i_coeff);
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_plc_phase_to_br2_phase(uint8_t plc_phase)
|
|
{
|
|
uint8_t br2_phase = IOT_BSRM_BR2_PHASE_UNKNOWN;
|
|
|
|
switch (plc_phase) {
|
|
case IOT_PLC_PHASE_ALL:
|
|
{
|
|
br2_phase = IOT_BSRM_BR2_PHASE_ALL;
|
|
break;
|
|
}
|
|
case IOT_PLC_PHASE_A:
|
|
{
|
|
br2_phase = IOT_BSRM_BR2_PHASE_A;
|
|
break;
|
|
}
|
|
case IOT_PLC_PHASE_B:
|
|
{
|
|
br2_phase = IOT_BSRM_BR2_PHASE_B;
|
|
break;
|
|
}
|
|
case IOT_PLC_PHASE_C:
|
|
{
|
|
br2_phase = IOT_BSRM_BR2_PHASE_C;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return br2_phase;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_proto_645_r_data_hander(uint8_t *in_data,
|
|
uint8_t in_len, uint8_t *out_buf, uint8_t *len_out)
|
|
{
|
|
uint32_t di;
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
iot_time_tm_t tm;
|
|
proto_645_time_hms_t *t_hms;
|
|
proto_645_time_ymd_t *t_ymd;
|
|
proto_645_07_time_t *t_all;
|
|
proto_645_ext_read_ver_rsp_t *ver_info;
|
|
uint16_t len = 0;
|
|
uint8_t ret;
|
|
uint32_t ts;
|
|
uint8_t read_cnt;
|
|
uint8_t i;
|
|
iot_pkt_t *read_result = NULL;
|
|
uint16_t total_cnt = 0;
|
|
uint8_t remain_len = *len_out, entry_len;
|
|
uint8_t *p_rsp = NULL;
|
|
uint8_t tmp_out_len = 0;
|
|
iot_bsrm_branch_info_entry_t *data;
|
|
proto_645_ext_br2_recv_rec_dl_t *read_info;
|
|
proto_645_ext_br2_recv_rec_entry_t *result = NULL;
|
|
proto_645_ext_br2_recv_rec_entry_zj_head_t *result2 = NULL;
|
|
proto_645_ext_br2_recv_rec_ul_t *rsp = NULL;
|
|
proto_645_ext_br2_recv_rec_ul_zj_t *rsp2 = NULL;
|
|
proto_645_ext_br2_recv_rec_dl_xiongan_t *read_info2;
|
|
proto_645_ext_br2_recv_rec_ul_xiongan_t *rsp3 = NULL;
|
|
proto_645_ext_br2_recv_rec_entry_xiongan_t *result3 = NULL;
|
|
proto_645_ext_ct_coeff_t *i_coeff;
|
|
int32_t energy;
|
|
|
|
if (in_len < PROTO_645_2007_DI_LEN) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
goto out;
|
|
}
|
|
in_len -= PROTO_645_2007_DI_LEN;
|
|
di = proto_645_2007_byte_to_di(in_data);
|
|
proto_645_2007_di_to_byte(di, out_buf);
|
|
len += PROTO_645_2007_DI_LEN;
|
|
remain_len -= PROTO_645_2007_DI_LEN;
|
|
switch (di) {
|
|
case PROTO_645_2007_DI_TIME_YMD:
|
|
{
|
|
iot_rtc_get(&tm);
|
|
t_ymd = (proto_645_time_ymd_t *)(out_buf + len);
|
|
t_ymd->week = iot_bsrm_zeller_calc_week(&tm);
|
|
t_ymd->day = iot_byte_to_bcd(tm.tm_mday);
|
|
t_ymd->month = iot_byte_to_bcd(tm.tm_mon);
|
|
t_ymd->year = iot_byte_to_bcd((uint8_t)(tm.tm_year - 2000));
|
|
len += sizeof(*t_ymd);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_TIME_HMS:
|
|
{
|
|
iot_rtc_get(&tm);
|
|
t_hms = (proto_645_time_hms_t *)(out_buf + len);
|
|
t_hms->second = iot_byte_to_bcd(tm.tm_sec);
|
|
t_hms->minute = iot_byte_to_bcd(tm.tm_min);
|
|
t_hms->hour = iot_byte_to_bcd(tm.tm_hour);
|
|
len += sizeof(*t_hms);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_TIME:
|
|
{
|
|
iot_rtc_get(&tm);
|
|
t_all = (proto_645_07_time_t *)(out_buf + len);
|
|
t_all->week = iot_bsrm_zeller_calc_week(&tm);;
|
|
t_all->day = iot_byte_to_bcd(tm.tm_mday);
|
|
t_all->month = iot_byte_to_bcd(tm.tm_mon);
|
|
t_all->year = iot_byte_to_bcd((uint8_t)(tm.tm_year - 2000));
|
|
t_all->second = iot_byte_to_bcd(tm.tm_sec);
|
|
t_all->minute = iot_byte_to_bcd(tm.tm_min);
|
|
t_all->hour = iot_byte_to_bcd(tm.tm_hour);
|
|
len += sizeof(*t_all);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_R_ADDR:
|
|
{
|
|
iot_mac_addr_cpy(out_buf + len, p_bsrm_glb->addr);
|
|
len += IOT_MAC_ADDR_LEN;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_UPGRADE_SEND_FILE:
|
|
{
|
|
err_code = iot_bsrm_handle_upgrade(in_data + PROTO_645_2007_DI_LEN,
|
|
in_len - PROTO_645_2007_DI_LEN, out_buf + len, &tmp_out_len);
|
|
len += tmp_out_len;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_UPGRADE_REQ_FILE:
|
|
{
|
|
iot_bsrm_handle_upgrade_query_bitmap(out_buf + len, &tmp_out_len);
|
|
len += tmp_out_len;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD:
|
|
{
|
|
if (in_len < sizeof(*read_info)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
rsp = (proto_645_ext_br2_recv_rec_ul_t *)(out_buf + len);
|
|
read_info = (proto_645_ext_br2_recv_rec_dl_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
tm.tm_year = read_info->start_time.year + 2000;
|
|
tm.tm_mon = read_info->start_time.month;
|
|
tm.tm_mday = read_info->start_time.day;
|
|
tm.tm_hour = read_info->start_time.hour;
|
|
tm.tm_min = read_info->start_time.minute;
|
|
tm.tm_sec = read_info->start_time.second;
|
|
ts = iot_bsrm_rtctime_to_time(&tm);
|
|
read_cnt = read_info->cnt;
|
|
iot_bsrm_printf("read info time %lu-%lu-%lu %lu:%lu:%lu, "
|
|
"recv cnt = %lu, recv idx = %lu DI:%08x \n", tm.tm_year, tm.tm_mon,
|
|
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
read_cnt, read_info->start_index, di);
|
|
ret = iot_bsrm_info_rec_read(&ts, &total_cnt, &read_cnt,
|
|
&read_result, read_info->start_index);
|
|
iot_bsrm_printf("record info total_cnt = %lu, read_cnt = %lu\n",
|
|
total_cnt, read_cnt);
|
|
data = (iot_bsrm_branch_info_entry_t *)iot_pkt_data(read_result);
|
|
rsp->total_cnt = total_cnt;
|
|
rsp->count = 0;
|
|
rsp->start_index = read_info->start_index;
|
|
iot_bsrm_time_to_rtctime(ts, &tm);
|
|
rsp->start_time.year = (uint8_t)(tm.tm_year - 2000);
|
|
rsp->start_time.month = tm.tm_mon;
|
|
rsp->start_time.day = tm.tm_mday;
|
|
rsp->start_time.hour = tm.tm_hour;
|
|
rsp->start_time.minute = tm.tm_min;
|
|
rsp->start_time.second = tm.tm_sec;
|
|
len += sizeof(*rsp);
|
|
if (ret != ERR_OK) {
|
|
break;
|
|
}
|
|
remain_len -= sizeof(*rsp);
|
|
result = rsp ->result;
|
|
for (i = 0; i < read_cnt; i++) {
|
|
if (remain_len < sizeof(*result)) {
|
|
break;
|
|
}
|
|
iot_bsrm_time_to_rtctime(data[i].ts, &tm);
|
|
result[i].signal_time.year = (uint8_t)(tm.tm_year - 2000);
|
|
result[i].signal_time.month = tm.tm_mon;
|
|
result[i].signal_time.day = tm.tm_mday;
|
|
result[i].signal_time.hour = tm.tm_hour;
|
|
result[i].signal_time.minute = tm.tm_min;
|
|
result[i].signal_time.second = tm.tm_sec;
|
|
result[i].is_vaild = data[i].is_vaild;
|
|
result[i].phase = data[i].phase;
|
|
result[i].signal1_rssi = data[i].signal1_rssi;
|
|
result[i].signal2_rssi = data[i].signal2_rssi;
|
|
result[i].base_rssi = data[i].base_rssi;
|
|
result[i].noise = data[i].noise;
|
|
len += sizeof(*result);
|
|
remain_len -= sizeof(*result);
|
|
rsp->count += 1;
|
|
}
|
|
iot_pkt_free(read_result);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD_ZJ:
|
|
{
|
|
if (in_len < sizeof(*read_info)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
rsp2 = (proto_645_ext_br2_recv_rec_ul_zj_t *)(out_buf + len);
|
|
read_info = (proto_645_ext_br2_recv_rec_dl_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
tm.tm_year = read_info->start_time.year + 2000;
|
|
tm.tm_mon = read_info->start_time.month;
|
|
tm.tm_mday = read_info->start_time.day;
|
|
tm.tm_hour = read_info->start_time.hour;
|
|
tm.tm_min = read_info->start_time.minute;
|
|
tm.tm_sec = read_info->start_time.second;
|
|
ts = iot_bsrm_rtctime_to_time(&tm);
|
|
read_cnt = read_info->cnt;
|
|
iot_bsrm_printf("read info time %lu-%lu-%lu %lu:%lu:%lu, "
|
|
"recv cnt = %lu, recv idx = %lu DI:%08x \n", tm.tm_year, tm.tm_mon,
|
|
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
read_cnt, read_info->start_index, di);
|
|
ret = iot_bsrm_info_rec_read(&ts, &total_cnt, &read_cnt,
|
|
&read_result, read_info->start_index);
|
|
iot_bsrm_printf("record info total_cnt = %lu, read_cnt = %lu\n",
|
|
total_cnt, read_cnt);
|
|
data = (iot_bsrm_branch_info_entry_t *)iot_pkt_data(read_result);
|
|
rsp2->total_cnt = total_cnt;
|
|
rsp2->count = 0;
|
|
rsp2->start_index = read_info->start_index;
|
|
iot_bsrm_time_to_rtctime(ts, &tm);
|
|
rsp2->start_time.year = (uint8_t)(tm.tm_year - 2000);
|
|
rsp2->start_time.month = tm.tm_mon;
|
|
rsp2->start_time.day = tm.tm_mday;
|
|
rsp2->start_time.hour = tm.tm_hour;
|
|
rsp2->start_time.minute = tm.tm_min;
|
|
rsp2->start_time.second = tm.tm_sec;
|
|
rsp2->code_len = 0;
|
|
len += sizeof(*rsp2);
|
|
if (ret != ERR_OK) {
|
|
break;
|
|
}
|
|
for (i = 0; i < read_cnt; i++) {
|
|
if (data[i].id_code_len > rsp2->code_len) {
|
|
rsp2->code_len = data[i].id_code_len;
|
|
}
|
|
}
|
|
entry_len = rsp2->code_len + sizeof(*result2) +
|
|
sizeof(roto_645_ext_br2_recv_rec_entry_zj_tail_t);
|
|
remain_len -= sizeof(*rsp2);
|
|
p_rsp = rsp2 ->data;
|
|
for (i = 0; i < read_cnt; i++) {
|
|
if (remain_len < entry_len) {
|
|
break;
|
|
}
|
|
result2 = (proto_645_ext_br2_recv_rec_entry_zj_head_t *)p_rsp;
|
|
iot_bsrm_time_to_rtctime(data[i].ts, &tm);
|
|
result2->signal_time.year = (uint8_t)(tm.tm_year - 2000);
|
|
result2->signal_time.month = tm.tm_mon;
|
|
result2->signal_time.day = tm.tm_mday;
|
|
result2->signal_time.hour = tm.tm_hour;
|
|
result2->signal_time.minute = tm.tm_min;
|
|
result2->signal_time.second = tm.tm_sec;
|
|
result2->phase = data[i].phase;
|
|
result2->signal1_rssi = data[i].signal1_rssi;
|
|
result2->signal2_rssi = data[i].signal2_rssi;
|
|
result2->noise = data[i].noise;
|
|
p_rsp += sizeof(*result2);
|
|
os_mem_cpy(p_rsp, &data[i].id_code, data[i].id_code_len);
|
|
p_rsp += data[i].id_code_len;
|
|
os_mem_set(p_rsp, 0, rsp2->code_len - data[i].id_code_len);
|
|
p_rsp += (rsp2->code_len -data[i].id_code_len);
|
|
os_mem_set(p_rsp, 0,
|
|
sizeof(roto_645_ext_br2_recv_rec_entry_zj_tail_t));
|
|
p_rsp += sizeof(roto_645_ext_br2_recv_rec_entry_zj_tail_t);
|
|
len += entry_len;
|
|
remain_len -= entry_len;
|
|
rsp2->count++;
|
|
}
|
|
iot_pkt_free(read_result);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD_XIONGAN:
|
|
{
|
|
if (in_len < sizeof(*read_info2)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
rsp3 = (proto_645_ext_br2_recv_rec_ul_xiongan_t *)(out_buf + len);
|
|
read_info2 = (proto_645_ext_br2_recv_rec_dl_xiongan_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
tm.tm_year = 2000;
|
|
tm.tm_mon = 1;
|
|
tm.tm_mday = 1;
|
|
tm.tm_hour = 0;
|
|
tm.tm_min = 0;
|
|
tm.tm_sec = 0;
|
|
ts = iot_bsrm_rtctime_to_time(&tm);
|
|
read_cnt = min(read_info2->cnt, 10);
|
|
iot_bsrm_printf("read info time %lu-%lu-%lu %lu:%lu:%lu, "
|
|
"recv cnt = %lu, recv idx = %lu DI:%08x \n", tm.tm_year, tm.tm_mon,
|
|
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
read_cnt, read_info2->start_index, di);
|
|
ret = iot_bsrm_info_rec_read(&ts, &total_cnt, &read_cnt,
|
|
&read_result, read_info2->start_index);
|
|
iot_bsrm_printf("record info total_cnt = %lu, read_cnt = %lu\n",
|
|
total_cnt, total_cnt ? read_cnt : 0);
|
|
data = (iot_bsrm_branch_info_entry_t *)iot_pkt_data(read_result);
|
|
|
|
rsp3->total_cnt = total_cnt;
|
|
rsp3->count = 0;
|
|
len += sizeof(*rsp3);
|
|
if (ret != ERR_OK) {
|
|
break;
|
|
}
|
|
|
|
remain_len -= sizeof(*rsp3);
|
|
p_rsp = rsp3 ->data;
|
|
for (i = 0; i < read_cnt; i++) {
|
|
if (remain_len < sizeof(*result3)) {
|
|
break;
|
|
}
|
|
result3 = (proto_645_ext_br2_recv_rec_entry_xiongan_t *)p_rsp;
|
|
iot_bsrm_time_to_rtctime(data[i].ts, &tm);
|
|
proto_645_rtctime_to_YYMMDDhhmmss(&tm,
|
|
(uint8_t *)&result3->signal_time);
|
|
energy = (int32_t)((data[i].signal1_rssi +
|
|
data[i].signal2_rssi) * 1000);
|
|
proto_645_sig_to_bcd(energy , 4, result3->signal_rssi);
|
|
proto_645_sig_to_bcd((int32_t)(data[i].base_rssi * 1000),
|
|
4, result3->base_rssi);
|
|
proto_645_sig_to_bcd((int32_t)(data[i].noise * 1000),
|
|
4, result3->noise);
|
|
result3->phase = data[i].phase ? data[i].phase : 4;
|
|
p_rsp += sizeof(*result3);
|
|
len += sizeof(*result3);
|
|
remain_len -= sizeof(*result3);
|
|
rsp3->count++;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_READ_VER:
|
|
{
|
|
ver_info = (proto_645_ext_read_ver_rsp_t *)(out_buf + len);
|
|
proto_645_vendor_build_ver_info_base(ver_info);
|
|
len += sizeof(*ver_info);
|
|
break;
|
|
}
|
|
case PROTO_645_EXT_BSRM_DI_TANS_CMD:
|
|
{
|
|
/* reset di payload */
|
|
len -= PROTO_645_2007_DI_LEN;
|
|
err_code = iot_bsrm_proto_645_r_extend_data_hander(
|
|
in_data + PROTO_645_2007_DI_LEN, in_len - PROTO_645_2007_DI_LEN,
|
|
out_buf, &tmp_out_len);
|
|
len += tmp_out_len;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_BRM_CURRENT_COEFF:
|
|
{
|
|
i_coeff = (proto_645_ext_ct_coeff_t *)(out_buf + len);
|
|
i_coeff->coeff = iot_bsrm_get_ct_coeff();
|
|
len += sizeof(*i_coeff);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
err_code = iot_bsrm_branch_info_evt_req_handle(di, out_buf,
|
|
&remain_len, &len);
|
|
break;
|
|
}
|
|
}
|
|
*len_out = (uint8_t)len;
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_proto_645_query_topo_data_hander(uint8_t *in_data,
|
|
uint8_t in_len, uint8_t *out_buf, uint8_t *len_out)
|
|
{
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
uint32_t di;
|
|
proto_645_ext_br2_recv_rec_dl_hn_t *read_info;
|
|
iot_time_tm_t tm = { 0 };
|
|
uint32_t ts;
|
|
uint8_t read_cnt;
|
|
uint16_t total_cnt = 0;
|
|
iot_pkt_t *read_result = NULL;
|
|
uint32_t ret;
|
|
uint8_t remain_len = *len_out;
|
|
uint8_t len = 0;
|
|
iot_bsrm_branch_info_entry_t *rd_data;
|
|
proto_645_ext_br2_recv_rec_ul_hn_t *br_rec_rsp;
|
|
proto_645_ext_br2_recv_rec_entry_hn_t *br_rec_rsp_data;
|
|
|
|
if (in_len < PROTO_645_2007_DI_LEN) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(in_data);
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_DI_BR2_CLEAR_HN:
|
|
{
|
|
iot_bsrm_br_rec_clear();
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD_HN:
|
|
{
|
|
if (in_len < sizeof(*read_info)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
read_info = (proto_645_ext_br2_recv_rec_dl_hn_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
if (read_info->start_index == 0) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
proto_645_2007_di_to_byte(di, out_buf);
|
|
len += PROTO_645_2007_DI_LEN;
|
|
remain_len -= PROTO_645_2007_DI_LEN;
|
|
br_rec_rsp = (proto_645_ext_br2_recv_rec_ul_hn_t *)(out_buf + len);
|
|
tm.tm_year = 2000;
|
|
tm.tm_mon = 1;
|
|
tm.tm_mday = 1;
|
|
tm.tm_hour = 0;
|
|
tm.tm_min = 0;
|
|
tm.tm_sec = 0;
|
|
ts = iot_bsrm_rtctime_to_time(&tm);
|
|
iot_bsrm_printf("read info start: %d, cnt: %d \n",
|
|
read_info->start_index, read_info->cnt);
|
|
read_cnt = read_info->cnt;
|
|
ret = iot_bsrm_info_rec_read(&ts, &total_cnt, &read_cnt,
|
|
&read_result, read_info->start_index - 1);
|
|
iot_bsrm_printf("record info total_cnt = %lu, read_cnt = %lu\n",
|
|
total_cnt, read_cnt);
|
|
rd_data = (iot_bsrm_branch_info_entry_t *)iot_pkt_data(read_result);
|
|
len += sizeof(*br_rec_rsp);
|
|
if (ret != ERR_OK) {
|
|
br_rec_rsp->count = 0;
|
|
break;
|
|
}
|
|
remain_len -= sizeof(*br_rec_rsp);
|
|
br_rec_rsp_data = br_rec_rsp ->data;
|
|
for (uint8_t i = 0; i < read_cnt; i++) {
|
|
if (remain_len < sizeof(*br_rec_rsp_data)) {
|
|
break;
|
|
}
|
|
iot_bsrm_time_to_rtctime(rd_data[i].ts, &tm);
|
|
br_rec_rsp_data->signal_time.year =
|
|
iot_byte_to_bcd((uint8_t)(tm.tm_year - 2000));
|
|
br_rec_rsp_data->signal_time.month = iot_byte_to_bcd(tm.tm_mon);
|
|
br_rec_rsp_data->signal_time.day = iot_byte_to_bcd(tm.tm_mday);
|
|
br_rec_rsp_data->signal_time.hour = iot_byte_to_bcd(tm.tm_hour);
|
|
br_rec_rsp_data->signal_time.minute = iot_byte_to_bcd(tm.tm_min);
|
|
br_rec_rsp_data->signal_time.second = iot_byte_to_bcd(tm.tm_sec);
|
|
switch (rd_data[i].phase) {
|
|
case IOT_PLC_PHASE_A:
|
|
{
|
|
br_rec_rsp_data->phase = 1;
|
|
break;
|
|
}
|
|
case IOT_PLC_PHASE_B:
|
|
{
|
|
br_rec_rsp_data->phase = 2;
|
|
break;
|
|
}
|
|
case IOT_PLC_PHASE_C:
|
|
{
|
|
br_rec_rsp_data->phase = 4;
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
uint32_t energy = (uint32_t)((rd_data[i].signal1_rssi +
|
|
rd_data[i].signal2_rssi) * 100);
|
|
proto_645_sig_to_bcd(energy, PROTO_645_EXT_BRANCH_ENERGY_BCD_LEN_HN,
|
|
br_rec_rsp_data->energy);
|
|
os_mem_cpy(br_rec_rsp_data->code, &rd_data[i].id_code,
|
|
PROTO_645_EXT_BRANCH_CODE_LEN_HN);
|
|
len += sizeof(*br_rec_rsp_data);
|
|
remain_len -= sizeof(*br_rec_rsp_data);
|
|
br_rec_rsp->count++;
|
|
br_rec_rsp_data++;
|
|
}
|
|
iot_pkt_free(read_result);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
break;
|
|
}
|
|
}
|
|
*len_out = (uint8_t)len;
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_proto_645_w_data_hander(uint8_t *in_data,
|
|
uint8_t in_len, uint8_t *out_buf, uint8_t *len_out)
|
|
{
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
uint8_t req_data_len;
|
|
uint32_t di;
|
|
proto_645_ext_ct_coeff_t *i_coeff;
|
|
iot_bsrm_br_param_t br_param = { 0 };
|
|
proto_645_ext_br2_launch_zj_hdr_t *br_hdr;
|
|
proto_645_ext_br2_launch_zj_tail_t *br_tail;
|
|
proto_645_write_data_dest_t *write_data;
|
|
proto_645_time_hms_t *t_hms;
|
|
proto_645_time_ymd_t *t_ymd;
|
|
proto_645_corr_time_t *ct;
|
|
|
|
if (in_len < PROTO_645_2007_DI_LEN) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(in_data);
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_DI_BR2_LAUNCH_ZJ:
|
|
{
|
|
req_data_len = sizeof(*br_hdr) + PROTO_645_2007_DI_LEN +
|
|
sizeof(*br_tail);
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
br_hdr = (proto_645_ext_br2_launch_zj_hdr_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
req_data_len += br_hdr->code_len;
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
br_tail = (proto_645_ext_br2_launch_zj_tail_t *)(br_hdr->code +
|
|
br_hdr->code_len);
|
|
br_param.fc = (br_hdr->freq[0]) | (br_hdr->freq[1] << 8) |
|
|
(br_hdr->freq[2] << 16);
|
|
br_param.chara_bit_dur = br_hdr->chara_bit_dur;
|
|
br_param.pulse_high_dur = br_tail->pulse_high_dur;
|
|
br_param.pulse_low_dur = br_tail->pulse_low_dur;
|
|
br_param.id_code_len = min(br_hdr->code_len,
|
|
IOT_BSRM_BRANCH_ID_CODE_MAX);
|
|
os_mem_cpy(br_param.id_code, br_hdr->code, br_param.id_code_len);
|
|
iot_bsrm_set_br_recv_param(&br_param);
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_BRM_CURRENT_COEFF:
|
|
{
|
|
req_data_len = sizeof(*i_coeff) + PROTO_645_2007_DI_LEN;
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
i_coeff = (proto_645_ext_ct_coeff_t *)(in_data +
|
|
PROTO_645_2007_DI_LEN);
|
|
iot_bsrm_set_ct_coeff(i_coeff->coeff);
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_TIME:
|
|
{
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
break;
|
|
}
|
|
req_data_len = sizeof(*write_data) + sizeof(*ct);
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
write_data = (proto_645_write_data_dest_t *)in_data;
|
|
ct = (proto_645_corr_time_t *)(write_data->data);
|
|
p_bsrm_glb->correct_tm.tm_sec = iot_bcd_to_byte(ct->second);
|
|
p_bsrm_glb->correct_tm.tm_min = iot_bcd_to_byte(ct->minute);
|
|
p_bsrm_glb->correct_tm.tm_hour = iot_bcd_to_byte(ct->hour);
|
|
p_bsrm_glb->correct_tm.tm_mday = iot_bcd_to_byte(ct->day);
|
|
p_bsrm_glb->correct_tm.tm_mon = iot_bcd_to_byte(ct->month);
|
|
p_bsrm_glb->correct_tm.tm_year = iot_bcd_to_byte(ct->year) + 2000;
|
|
iot_bsrm_printf("correct time success\n");
|
|
iot_bsrm_set_correct_tm(1);
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_TIME_YMD:
|
|
{
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
break;
|
|
}
|
|
req_data_len = sizeof(*write_data) + sizeof(*t_ymd);
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
write_data = (proto_645_write_data_dest_t *)in_data;
|
|
t_ymd = (proto_645_time_ymd_t *)(write_data->data);
|
|
p_bsrm_glb->correct_tm.tm_mday = iot_bcd_to_byte(t_ymd->day);
|
|
p_bsrm_glb->correct_tm.tm_mon = iot_bcd_to_byte(t_ymd->month);
|
|
p_bsrm_glb->correct_tm.tm_year = iot_bcd_to_byte(t_ymd->year) +
|
|
2000;
|
|
iot_bsrm_printf("correct ymd success\n");
|
|
iot_bsrm_set_correct_tm(1);
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_TIME_HMS:
|
|
{
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
break;
|
|
}
|
|
req_data_len = sizeof(*write_data) + sizeof(*t_hms);
|
|
if (in_len < req_data_len) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
write_data = (proto_645_write_data_dest_t *)in_data;
|
|
t_hms = (proto_645_time_hms_t *)(write_data->data);
|
|
p_bsrm_glb->correct_tm.tm_hour = iot_bcd_to_byte(t_hms->hour);
|
|
p_bsrm_glb->correct_tm.tm_min = iot_bcd_to_byte(t_hms->minute);
|
|
p_bsrm_glb->correct_tm.tm_sec = iot_bcd_to_byte(t_hms->second);
|
|
iot_bsrm_printf("correct hms success\n");
|
|
iot_bsrm_set_correct_tm(1);
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_BR2_CLEAR_HN:
|
|
{
|
|
iot_bsrm_br_rec_clear();
|
|
*len_out = 0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
break;
|
|
}
|
|
}
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_check_get_zc_phase(uint8_t index)
|
|
{
|
|
const uint8_t phase_buf[] = {GPIO_PA_ZC, GPIO_PB_ZC, GPIO_PC_ZC,
|
|
GPIO_PA_ZC_EXT, GPIO_PB_ZC_EXT, GPIO_PC_ZC_EXT};
|
|
if (index >= sizeof(phase_buf)) {
|
|
return GPIO_NO_VALID;
|
|
}
|
|
return phase_buf[index];
|
|
}
|
|
|
|
static void iot_bsrm_check_timeout_event()
|
|
{
|
|
iot_bsrm_check_event_ctrl_t *event_check = &p_bsrm_glb->check_crtl.event;
|
|
uint8_t event_gpio_num;
|
|
|
|
if (event_check->status != IOT_BSRM_CHECK_EVENT_STATUS_DOING) {
|
|
return;
|
|
}
|
|
event_check->times++;
|
|
if (event_check->times >= IOT_BSRM_EVENT_CHECK_TIMES) {
|
|
event_gpio_num = iot_board_get_gpio(GPIO_PLC_EVENT);
|
|
iot_gpio_close(event_gpio_num);
|
|
event_check->status = IOT_BSRM_CHECK_EVENT_STATUS_DONE;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_check_timeout_handle()
|
|
{
|
|
iot_bsrm_check_zc_ctrl_t *check_ctrl = &p_bsrm_glb->check_crtl.zc_ctrl;
|
|
uint32_t temp, cost_time;
|
|
uint8_t index, zc_phase, tmp_gpio;
|
|
if (check_ctrl->status == IOT_BSRM_CHECK_ZC_STATUS_GOING) {
|
|
cost_time = (uint32_t)(os_boot_time32() - check_ctrl->start_ts);
|
|
if (cost_time > IOT_BSRM_CHECK_ZC_TIMEOUT) {
|
|
while (1) {
|
|
index = iot_bitmap_ffs_and_c(&check_ctrl->started_zc_bm,
|
|
sizeof(check_ctrl->started_zc_bm));
|
|
if (!index) {
|
|
break;
|
|
}
|
|
index--;
|
|
if (index >= 2 * IOT_PLC_PHASE_CNT) {
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
if (check_ctrl->period[index]) {
|
|
continue;
|
|
}
|
|
if (!check_ctrl->trig_cnt[index]) {
|
|
temp = 0;
|
|
} else {
|
|
temp = check_ctrl->total_time[index] /
|
|
check_ctrl->trig_cnt[index];
|
|
}
|
|
check_ctrl->period[index] = temp;
|
|
zc_phase = iot_bsrm_check_get_zc_phase(index);
|
|
tmp_gpio = iot_board_get_gpio(zc_phase);
|
|
iot_gpio_interrupt_enable(tmp_gpio, 0);
|
|
iot_bsrm_printf("%s index %d, time %lu, trig %lu, period %lu\n",
|
|
__FUNCTION__, index, check_ctrl->total_time[index],
|
|
check_ctrl->trig_cnt[index], temp);
|
|
};
|
|
check_ctrl->status = IOT_BSRM_CHECK_ZC_STATUS_DONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_check_zc_gpio_handler(int arg)
|
|
{
|
|
uint32_t cur_counter;
|
|
uint8_t index, zc_phase, tmp_gpio;
|
|
iot_bsrm_check_zc_ctrl_t *check_ctrl = &p_bsrm_glb->check_crtl.zc_ctrl;
|
|
|
|
if (arg >= 2 * IOT_PLC_PHASE_CNT) {
|
|
IOT_ASSERT(0);
|
|
goto err;
|
|
}
|
|
index = arg;
|
|
zc_phase = iot_bsrm_check_get_zc_phase(index);
|
|
tmp_gpio = iot_board_get_gpio(zc_phase);
|
|
cur_counter = iot_gpio_get_trigger_ticks(tmp_gpio);
|
|
if (!(check_ctrl->started_zc_bm & (1 << index))) {
|
|
check_ctrl->started_zc_bm |= 1 << index;
|
|
goto out;
|
|
}
|
|
check_ctrl->total_time[index] += (uint32_t)(cur_counter -
|
|
check_ctrl->pre_tick[index]);
|
|
check_ctrl->trig_cnt[index]++;
|
|
out:
|
|
check_ctrl->pre_tick[index] = cur_counter;
|
|
err:
|
|
return;
|
|
}
|
|
|
|
static void iot_bsrm_check_zc_start(uint8_t zc_bm)
|
|
{
|
|
iot_bsrm_check_zc_ctrl_t *check_ctrl = &p_bsrm_glb->check_crtl.zc_ctrl;
|
|
uint8_t index, tmp_gpio, zc_phase;
|
|
uint8_t reason;
|
|
if (check_ctrl->status == IOT_BSRM_CHECK_ZC_STATUS_GOING) {
|
|
goto out;
|
|
}
|
|
os_mem_set(check_ctrl, 0, sizeof(*check_ctrl));
|
|
while (1) {
|
|
reason = 0;
|
|
index = iot_bitmap_ffs_and_c(&zc_bm, sizeof(zc_bm));
|
|
if (!index || index > 2 * IOT_PLC_PHASE_CNT) {
|
|
break;
|
|
}
|
|
index--;
|
|
zc_phase = iot_bsrm_check_get_zc_phase(index);
|
|
tmp_gpio = iot_board_get_gpio(zc_phase);
|
|
if (tmp_gpio == GPIO_NO_VALID) {
|
|
reason = 1;
|
|
goto next;
|
|
}
|
|
iot_gpio_close(tmp_gpio);
|
|
if (iot_gpio_open_as_interrupt(tmp_gpio)) {
|
|
reason = 2;
|
|
goto next;
|
|
}
|
|
if (iot_gpio_interrupt_config(tmp_gpio, GPIO_INT_EDGE_RAISING,
|
|
iot_bsrm_check_zc_gpio_handler, index,
|
|
GPIO_INT_FUNC_GET_TICKS)) {
|
|
reason = 3;
|
|
goto next;
|
|
}
|
|
check_ctrl->zc_bm |= 1 << index;
|
|
if (iot_gpio_interrupt_enable(tmp_gpio, 1)) {
|
|
reason = 4;
|
|
goto next;
|
|
}
|
|
next:
|
|
if (reason) {
|
|
iot_bsrm_printf("%s index %d, zc_phase:%d, zc_gpio:%d, reason %d\n",
|
|
__FUNCTION__, index, zc_phase, tmp_gpio, reason);
|
|
}
|
|
}
|
|
check_ctrl->status = IOT_BSRM_CHECK_ZC_STATUS_GOING;
|
|
check_ctrl->start_ts = os_boot_time32();
|
|
iot_bsrm_printf("%s zc_bm %02x\n", __FUNCTION__, check_ctrl->zc_bm);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_bsrm_check_zc_quary_data_fill(uint8_t zc_bm,
|
|
proto_645_ext_check_zc_data_t *zc_data)
|
|
{
|
|
iot_bsrm_check_zc_ctrl_t *check_ctrl = &p_bsrm_glb->check_crtl.zc_ctrl;
|
|
uint8_t index, temp_bm;
|
|
temp_bm = check_ctrl->zc_bm & zc_bm;
|
|
zc_data->zc_bm = temp_bm;
|
|
iot_bsrm_printf("%s check_bm %02x, req_bm %02x, rsp_bm%02x\n", __FUNCTION__,
|
|
check_ctrl->zc_bm, zc_bm, temp_bm);
|
|
while (1) {
|
|
index = iot_bitmap_ffs_and_c(&temp_bm, sizeof(temp_bm));
|
|
if (!index || index > 2 * IOT_PLC_PHASE_CNT) {
|
|
break;
|
|
}
|
|
index--;
|
|
zc_data->period[index] = check_ctrl->period[index];
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_evt_intr_func(int arg)
|
|
{
|
|
(void)arg;
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_INTERNAL,
|
|
IOT_BSRM_MSG_ID_INTERNAL_EVENT_INTERRUPT, IOT_BSRM_MSG_QUEUE_LP, NULL,
|
|
0);
|
|
return;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_evt_gpio_intr_init()
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t event_gpio_num = iot_board_get_gpio(GPIO_PLC_EVENT);
|
|
|
|
if (GPIO_NO_VALID == event_gpio_num) {
|
|
goto out;
|
|
}
|
|
iot_gpio_close(event_gpio_num);
|
|
if (iot_gpio_open_as_interrupt(event_gpio_num)) {
|
|
goto out;
|
|
}
|
|
if (iot_gpio_interrupt_config(event_gpio_num, GPIO_INT_EDGE_RAISING,
|
|
iot_bsrm_evt_intr_func, 0, GPIO_INT_FUNC_DISABLE_AUTOSTOP)) {
|
|
goto out;
|
|
}
|
|
iot_gpio_interrupt_enable(event_gpio_num, 1);
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_check_event_start()
|
|
{
|
|
iot_bsrm_check_event_ctrl_t *event_check = &p_bsrm_glb->check_crtl.event;
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (event_check->status == IOT_BSRM_CHECK_EVENT_STATUS_DOING) {
|
|
goto out;
|
|
}
|
|
if (iot_bsrm_evt_gpio_intr_init() != ERR_OK) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
event_check->count = 0;
|
|
event_check->times = 0;
|
|
event_check->status = IOT_BSRM_CHECK_EVENT_STATUS_DOING;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_proto_645_br_data_hander(uint8_t *in_data,
|
|
uint8_t in_len, uint8_t *out_buf, uint8_t *len_out)
|
|
{
|
|
uint32_t di;
|
|
proto_645_ext_i_ms_ul_t *rsp_i_ms;
|
|
proto_645_ext_check_zc_dl_t *req_check_zc;
|
|
proto_645_ext_check_zc_ul_t *rsp_check_zc;
|
|
proto_645_ext_bsrm_evt_check_dl_t *req_check_event;
|
|
proto_645_ext_bsrm_evt_check_ul_t *rsp_check_event;
|
|
|
|
iot_bsrm_check_ctrl_t *check_ctrl = &p_bsrm_glb->check_crtl;
|
|
uint8_t err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
if (in_len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
in_len -= PROTO_645_2007_DI_LEN;
|
|
di = proto_645_2007_byte_to_di(in_data);
|
|
in_data += PROTO_645_2007_DI_LEN;
|
|
proto_645_2007_di_to_byte(di, out_buf);
|
|
*len_out = PROTO_645_2007_DI_LEN;
|
|
out_buf += PROTO_645_2007_DI_LEN;
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_DI_I_MS:
|
|
{
|
|
rsp_i_ms = (proto_645_ext_i_ms_ul_t *)out_buf;
|
|
*len_out += sizeof(*rsp_i_ms);
|
|
rsp_i_ms->ms_i[0] = iot_plc_hw_topo_rms2_get(IOT_PLC_PHASE_A);
|
|
rsp_i_ms->ms_i[1] = iot_plc_hw_topo_rms2_get(IOT_PLC_PHASE_B);
|
|
rsp_i_ms->ms_i[2] = iot_plc_hw_topo_rms2_get(IOT_PLC_PHASE_C);
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_CHECK_ZC:
|
|
{
|
|
if (in_len < sizeof(*req_check_zc)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
req_check_zc = (proto_645_ext_check_zc_dl_t *)in_data;
|
|
rsp_check_zc = (proto_645_ext_check_zc_ul_t *)out_buf;
|
|
*len_out += sizeof(*rsp_check_zc);
|
|
rsp_check_zc->fn = req_check_zc->fn;
|
|
iot_bsrm_printf("%s fn %d, bm %02x\n", __FUNCTION__, req_check_zc->fn,
|
|
req_check_zc->zc_bm);
|
|
switch (req_check_zc->fn) {
|
|
case PROTO_645_EXT_CHECK_FN_REQ:
|
|
{
|
|
iot_bsrm_check_zc_start(req_check_zc->zc_bm);
|
|
break;
|
|
}
|
|
case PROTO_645_EXT_CHECK_FN_QUERY:
|
|
{
|
|
iot_bsrm_check_zc_quary_data_fill(req_check_zc->zc_bm,
|
|
(proto_645_ext_check_zc_data_t *)rsp_check_zc->data);
|
|
*len_out += sizeof(proto_645_ext_check_zc_data_t);
|
|
break;
|
|
}
|
|
default:
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
rsp_check_zc->status = check_ctrl->zc_ctrl.status;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_EXT_DI_CHECK_EVENT_INTERRUPT:
|
|
{
|
|
if (in_len < sizeof(*req_check_event)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
req_check_event = (proto_645_ext_bsrm_evt_check_dl_t *)in_data;
|
|
rsp_check_event = (proto_645_ext_bsrm_evt_check_ul_t *)out_buf;
|
|
*len_out += sizeof(*rsp_check_event);
|
|
rsp_check_event->fn = req_check_event->fn;
|
|
rsp_check_event->count = 0;
|
|
switch (req_check_event->fn) {
|
|
case PROTO_645_EXT_CHECK_FN_REQ:
|
|
{
|
|
if (iot_bsrm_check_event_start() != ERR_OK) {
|
|
/* not support */
|
|
rsp_check_event->result = PROTO_645_EXT_CHECK_EVENT_NOSUPPORT;
|
|
} else {
|
|
/* fwd data */
|
|
err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_EXT_CHECK_FN_QUERY:
|
|
{
|
|
if (p_bsrm_glb->check_crtl.event.status ==
|
|
IOT_BSRM_CHECK_EVENT_STATUS_DONE) {
|
|
rsp_check_event->result = PROTO_645_EXT_CHECK_EVENT_SUCCESS;
|
|
rsp_check_event->count = p_bsrm_glb->check_crtl.event.count;
|
|
} else if (p_bsrm_glb->check_crtl.event.status ==
|
|
IOT_BSRM_CHECK_EVENT_STATUS_DOING) {
|
|
rsp_check_event->result = PROTO_645_EXT_CHECK_EVENT_RUNNING;
|
|
} else {
|
|
rsp_check_event->result = PROTO_645_EXT_CHECK_EVENT_FAIL;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return err_code;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_handle_master_645_data(
|
|
proto_645_header_t *hdr_645)
|
|
{
|
|
uint8_t ret = ERR_FAIL;
|
|
uint8_t fn;
|
|
uint8_t err_code = 0;
|
|
uint8_t *out_buf;
|
|
uint8_t out_len;
|
|
uint8_t *out_ds = p_bsrm_glb->proto_buff;
|
|
uint8_t follow = PROTO_645_FOLLOW_INVALID;
|
|
uint32_t len = 0;
|
|
iot_pkt_t *rsp_pkt;
|
|
uint32_t di;
|
|
uint8_t bcast = 0;
|
|
proto_645_07_dingxin_address_t *new_addr;
|
|
|
|
if (iot_mac_addr_cmp(hdr_645->addr, proto_645_bcast_addr)) {
|
|
bcast = 1;
|
|
}
|
|
proto_645_sub33_handle(hdr_645->data, hdr_645->len);
|
|
os_mem_set(out_ds, 0, PROTO_645_MAX_PKT_LEN);
|
|
out_buf = out_ds + sizeof(*hdr_645);
|
|
out_len = PROTO_645_MAX_DATA_LEN;
|
|
fn = (uint8_t)hdr_645->control.fn;
|
|
di = proto_645_2007_byte_to_di(hdr_645->data);
|
|
switch (fn) {
|
|
case PROTO_645_2007_FN_BSRM_DX_WRITE_ADDR:
|
|
{
|
|
new_addr = (proto_645_07_dingxin_address_t *)hdr_645->data;
|
|
if (new_addr->ident == PROTO_645_2007_BSRM_DX_SET_ADDR_IDENT) {
|
|
iot_bsrm_check_renew_addr(new_addr->addr);
|
|
out_len = 0;
|
|
err_code = PROTO_645_2007_ERR_OK;
|
|
} else {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
err_code = iot_bsrm_proto_645_r_data_hander(hdr_645->data,
|
|
hdr_645->len, out_buf, &out_len);
|
|
if (bcast && (di == PROTO_645_FJ_DI_UPGRADE_SEND_FILE)) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
err_code = iot_bsrm_proto_645_w_data_hander(hdr_645->data, hdr_645->len,
|
|
out_buf, &out_len);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_CORRECT_TIME:
|
|
{
|
|
/* synchro time from 645 correct time data */
|
|
proto_645_corr_time_t *ct = (proto_645_corr_time_t *)hdr_645->data;
|
|
p_bsrm_glb->correct_tm.tm_sec = iot_bcd_to_byte(ct->second);
|
|
p_bsrm_glb->correct_tm.tm_min = iot_bcd_to_byte(ct->minute);
|
|
p_bsrm_glb->correct_tm.tm_hour = iot_bcd_to_byte(ct->hour);
|
|
p_bsrm_glb->correct_tm.tm_mday = iot_bcd_to_byte(ct->day);
|
|
p_bsrm_glb->correct_tm.tm_mon = iot_bcd_to_byte(ct->month);
|
|
p_bsrm_glb->correct_tm.tm_year = iot_bcd_to_byte(ct->year) + 2000;
|
|
iot_bsrm_set_correct_tm(1);
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
default:
|
|
{
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (err_code) {
|
|
len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
|
|
p_bsrm_glb->addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_ABNORMAL,
|
|
follow, fn, PROTO_645_INVALID_DI, 1, &err_code);
|
|
|
|
} else {
|
|
len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
|
|
p_bsrm_glb->addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
|
|
follow, fn, PROTO_645_INVALID_DI, out_len, out_buf);
|
|
}
|
|
rsp_pkt = iot_pkt_alloc(len, IOT_BSRM_MID);
|
|
IOT_ASSERT(rsp_pkt);
|
|
os_mem_cpy(iot_pkt_put(rsp_pkt, len), out_ds, len);
|
|
iot_bsrm_uart_send(rsp_pkt);
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_sg_check_698_req(proto_69845_app_req_resp_t *req_data)
|
|
{
|
|
(void)req_data;
|
|
uint8_t ret = ERR_OK;
|
|
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
goto out;
|
|
}
|
|
|
|
if (false == iot_board_support_topo_rx()) {
|
|
ret = ERR_FAIL;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint16_t iot_bsrm_698_br2_record_info_fill(uint8_t *resp_data,
|
|
uint16_t len_limit, uint8_t sn, uint8_t priority,
|
|
uint8_t first, uint16_t oi, uint8_t is_retry, uint8_t *is_frag)
|
|
{
|
|
uint32_t ret, ts, tmp_value;
|
|
uint16_t total_cnt = 0, i;
|
|
uint16_t fill_len = 0, uint_len;
|
|
uint8_t read_cnt = 0xff, *fill_data;
|
|
iot_pkt_t *read_result = NULL;
|
|
proto_69845_app_ele_data_t * else_data;
|
|
proto_69845_br2_record_info_uint_t *record_uint;
|
|
proto_69845_br2_code_id_t *code_id;
|
|
proto_69845_br2_ext_info_t *ext_info;
|
|
iot_bsrm_branch_info_entry_t *data = NULL;
|
|
proto_69845_app_get_resp_next_t *rsp_next;
|
|
proto_69845_app_get_resp_next_fail_t *rsp_next_fail;
|
|
proto_69845_app_get_resp_normal_t *rsp_nor;
|
|
proto_69845_app_result_normal_t *normal_resp;
|
|
iot_bsrm_br_rec_frag_ctrl_t *frag_ctrl = &p_bsrm_glb->br_rec_frag_ctrl;
|
|
uint8_t frag = 1, end_flag = 0, fill_cnt = 0;
|
|
iot_time_tm_t tm = { 0 }, end_tm = { 0 };
|
|
if (first) {
|
|
frag_ctrl->start_tm.tm_year = 2000;
|
|
frag_ctrl->start_tm.tm_mon = 1;
|
|
frag_ctrl->start_tm.tm_mday = 1;
|
|
frag_ctrl->start_tm.tm_hour = 0;
|
|
frag_ctrl->start_tm.tm_min = 0;
|
|
frag_ctrl->start_tm.tm_sec = 0;
|
|
} else if (!is_retry) {
|
|
if (frag_ctrl->start_up != 1) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
frag_ctrl->start_tm = frag_ctrl->end_tm;
|
|
iot_rtc_delta_add(1, &frag_ctrl->start_tm);
|
|
}
|
|
ts = iot_bsrm_rtctime_to_time(&frag_ctrl->start_tm);
|
|
ret = iot_bsrm_info_rec_read(&ts, &total_cnt, &read_cnt,
|
|
&read_result, 0);
|
|
if (first) {
|
|
if (ret == ERR_OK && total_cnt > IOT_BSRM_BR_REC_MAX_RESP_CNT) {
|
|
/* use framing transmission */
|
|
frag_ctrl->seq = 1;
|
|
frag_ctrl->start_up = 1;
|
|
frag_ctrl->oi = oi;
|
|
} else {
|
|
/* if one frame of message can carry all records, it will respond in
|
|
* the format of "GetResponseNormal".
|
|
*/
|
|
fill_len = sizeof(*rsp_nor);
|
|
frag = 0;
|
|
rsp_nor = (proto_69845_app_get_resp_normal_t *)resp_data;
|
|
rsp_nor->piid_acd.sn = sn;
|
|
rsp_nor->piid_acd.priority = priority;
|
|
rsp_nor->piid_acd.acd = 0;
|
|
proto_69845_oi_to_byte(oi, (uint8_t*)&rsp_nor->oad.oi);
|
|
rsp_nor->oad.attribute_id = 2;
|
|
rsp_nor->oad.attribute_char = 0;
|
|
rsp_nor->oad.element_index = 0;
|
|
if (ret == ERR_OK) {
|
|
rsp_nor->result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
fill_data = rsp_nor->result;
|
|
fill_cnt = total_cnt;
|
|
data = (iot_bsrm_branch_info_entry_t *)
|
|
iot_pkt_data(read_result);
|
|
goto fill_rec;
|
|
} else {
|
|
rsp_nor->result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
else_data = (proto_69845_app_ele_data_t *)rsp_nor->result;
|
|
else_data->data_type = PROTO_69845_APP_DATA_ARRAY;
|
|
else_data->num_of_data = 0;
|
|
fill_len += sizeof(*else_data);
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
rsp_next_fail = (proto_69845_app_get_resp_next_fail_t *)resp_data;
|
|
if (ret != ERR_OK) {
|
|
/* when an error occurs during frame division transmission, reply
|
|
* the error code and terminate the transmission.
|
|
*/
|
|
rsp_next_fail->piid_acd.sn = sn;
|
|
rsp_next_fail->piid_acd.priority = priority;
|
|
rsp_next_fail->end_flag = 1;
|
|
iot_uint16_to_bytes(frag_ctrl->seq, (uint8_t *)&rsp_next_fail->seq, 1);
|
|
rsp_next_fail->data_type = PROTO_69845_GET_RESP_NEXT_ERR;
|
|
rsp_next_fail->err_code = PROTO_69845_APP_DAR_OTHER;
|
|
fill_len = sizeof(*rsp_next_fail);
|
|
goto out;
|
|
}
|
|
|
|
len_limit -= sizeof(*rsp_next) + sizeof(*normal_resp) + sizeof(*else_data);
|
|
data = (iot_bsrm_branch_info_entry_t *)iot_pkt_data(read_result);
|
|
/* calculate 698 apud max response len */
|
|
for (i = 0; i < read_cnt &&
|
|
fill_cnt < IOT_BSRM_BR_REC_MAX_RESP_CNT; i++) {
|
|
uint_len = sizeof(*record_uint) + sizeof(*code_id) +
|
|
data[i].id_code_len + sizeof(*ext_info) + 1;
|
|
if (len_limit < uint_len) {
|
|
break;
|
|
}
|
|
fill_cnt++;
|
|
len_limit -= uint_len;
|
|
}
|
|
if (fill_cnt == total_cnt) {
|
|
end_flag = 1;
|
|
}
|
|
|
|
rsp_next = (proto_69845_app_get_resp_next_t *)resp_data;
|
|
rsp_next->piid_acd.sn = sn;
|
|
rsp_next->piid_acd.priority = priority;
|
|
rsp_next->end_flag = end_flag;
|
|
iot_uint16_to_bytes(frag_ctrl->seq, (uint8_t *)&rsp_next->seq, 1);
|
|
rsp_next->data_type = PROTO_69845_GET_RESP_NEXT_NORMAL;
|
|
rsp_next->num_of_data = 1;
|
|
fill_len += sizeof(*rsp_next);
|
|
|
|
normal_resp = (proto_69845_app_result_normal_t *)rsp_next->data;
|
|
proto_69845_oi_to_byte(frag_ctrl->oi, (uint8_t*)&normal_resp->oad.oi);
|
|
normal_resp->oad.attribute_id = 2;
|
|
normal_resp->oad.attribute_char = 0;
|
|
normal_resp->oad.element_index = 0;
|
|
normal_resp->get_result.result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
fill_data = normal_resp->get_result.result;
|
|
fill_len += sizeof(*normal_resp);
|
|
|
|
fill_rec:
|
|
else_data = (proto_69845_app_ele_data_t *)fill_data;
|
|
else_data->data_type = PROTO_69845_APP_DATA_ARRAY;
|
|
else_data->num_of_data = fill_cnt;
|
|
fill_data += sizeof(*else_data);
|
|
fill_len += sizeof(*else_data);
|
|
|
|
for (i = 0; i < fill_cnt; i++) {
|
|
record_uint = (proto_69845_br2_record_info_uint_t *)fill_data;
|
|
record_uint->data0_type = PROTO_69845_APP_DATA_STRUCTURE;
|
|
record_uint->cnt = 7;
|
|
record_uint->data1_type = PROTO_69845_APP_DATA_TIME_S;
|
|
iot_bsrm_time_to_rtctime(data[i].ts, &tm);
|
|
end_tm = tm;
|
|
iot_uint16_to_bytes(tm.tm_year,
|
|
(uint8_t *)&record_uint->suc_time.year, 1);
|
|
record_uint->suc_time.month = tm.tm_mon;
|
|
record_uint->suc_time.day = tm.tm_mday;
|
|
record_uint->suc_time.hour = tm.tm_hour;
|
|
record_uint->suc_time.minute = tm.tm_min;
|
|
record_uint->suc_time.second = tm.tm_sec;
|
|
record_uint->data2_type = PROTO_69845_APP_DATA_ENUM;
|
|
record_uint->phase = iot_bsrm_plc_phase_to_br2_phase(data[i].phase);
|
|
record_uint->data3_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
|
tmp_value = (uint32_t)(data[i].signal1_rssi * 1000);
|
|
iot_uint32_to_bytes(tmp_value, record_uint->signal1_rssi, 1);
|
|
record_uint->data4_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
|
tmp_value = (uint32_t)(data[i].signal2_rssi * 1000);
|
|
iot_uint32_to_bytes(tmp_value, record_uint->signal2_rssi, 1);
|
|
record_uint->data5_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
|
tmp_value = (uint32_t)(data[i].noise * 1000);
|
|
iot_uint32_to_bytes(tmp_value, record_uint->noise, 1);
|
|
fill_data += sizeof(*record_uint);
|
|
fill_len += sizeof(*record_uint);
|
|
|
|
code_id = (proto_69845_br2_code_id_t *)fill_data;
|
|
code_id->data_type = PROTO_69845_APP_DATA_BIT_STRING;
|
|
code_id->bit_len = data[i].id_code_len * 8;
|
|
fill_data += sizeof(*code_id);
|
|
fill_len += sizeof(*code_id);
|
|
|
|
os_mem_cpy(fill_data, data[i].id_code, data[i].id_code_len);
|
|
fill_data += data[i].id_code_len;
|
|
fill_len += data[i].id_code_len;
|
|
|
|
ext_info = (proto_69845_br2_ext_info_t *)fill_data;
|
|
ext_info->data_type = PROTO_69845_APP_DATA_OCTET_STRING;
|
|
ext_info->byte_len = 1;
|
|
ext_info->data[0] = 0;
|
|
fill_data += (sizeof(*ext_info) + 1);
|
|
fill_len += (sizeof(*ext_info) + 1);
|
|
}
|
|
|
|
if (frag) {
|
|
IOT_ASSERT(frag_ctrl->start_up == 1);
|
|
frag_ctrl->life_cd = IOT_BSRM_BR_REC_FRAG_WIN_DUR;
|
|
frag_ctrl->end_tm = end_tm;
|
|
}
|
|
out:
|
|
if (read_result) {
|
|
iot_pkt_free(read_result);
|
|
}
|
|
*is_frag = frag;
|
|
return fill_len;
|
|
}
|
|
|
|
static uint16_t iot_bsrm_69845_br2_launch_para_fill(uint8_t *result_type,
|
|
uint8_t *result, uint16_t len_limit)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint16_t result_len;
|
|
uint32_t temp;
|
|
proto_69845_br2_launch_para_t *launch_para;
|
|
proto_69845_app_data_t *fc_data;
|
|
proto_69845_app_ele_data_t *ext_info;
|
|
iot_bsrm_nv_param_t *param =
|
|
(iot_bsrm_nv_param_t *)iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
iot_bsrm_br_param_t *br_param = ¶m->br_param;
|
|
result_len = sizeof(*launch_para) + br_param->id_code_len;
|
|
if (len_limit < result_len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
*result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
launch_para = (proto_69845_br2_launch_para_t *)result;
|
|
launch_para->type = PROTO_69845_APP_DATA_STRUCTURE;
|
|
launch_para->cnt = 6;
|
|
launch_para->data0_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
|
iot_uint16_to_bytes(br_param->chara_bit_dur,
|
|
(uint8_t *)&launch_para->chara_bit_dur, 1);
|
|
launch_para->data1_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
|
iot_uint16_to_bytes(br_param->pulse_high_dur,
|
|
(uint8_t *)&launch_para->pulse_high_dur, 1);
|
|
launch_para->data2_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
|
iot_uint16_to_bytes(br_param->pulse_low_dur,
|
|
(uint8_t *)&launch_para->pulse_low_dur, 1);
|
|
launch_para->data3_type = PROTO_69845_APP_DATA_BIT_STRING;
|
|
launch_para->bit_len.mub_flag = 0;
|
|
launch_para->bit_len.byte_num = br_param->id_code_len << 3;
|
|
os_mem_cpy(launch_para->code, br_param->id_code, br_param->id_code_len);
|
|
/* load hw tsfm mode encode frequncy, double-long-unsigned, unit: 0.01Hz */
|
|
if (len_limit < result_len + sizeof(*fc_data)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
fc_data = (proto_69845_app_data_t *)(result + result_len);
|
|
fc_data->data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
|
if (proto_69845_get_data_len(fc_data, len_limit - result_len, &temp)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
result_len += temp;
|
|
iot_uint32_to_bytes(br_param->fc, fc_data->data, 1);
|
|
/* extend information */
|
|
if (len_limit < result_len + sizeof(*ext_info)) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
ext_info = (proto_69845_app_ele_data_t *)(result + result_len);
|
|
ext_info->data_type = PROTO_69845_APP_DATA_OCTET_STRING;
|
|
ext_info->num_of_data = 12;
|
|
if (proto_69845_get_data_len((proto_69845_app_data_t *)ext_info,
|
|
len_limit - result_len, &temp)) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
result_len += temp;
|
|
os_mem_set(ext_info->data, 0, 12);
|
|
out:
|
|
if (reason) {
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
result_len = 0;
|
|
}
|
|
return result_len;
|
|
}
|
|
|
|
iot_pkt_t *iot_bsrm_69845_get_normal_handle(uint8_t *data, uint32_t len)
|
|
{
|
|
uint16_t oi;
|
|
uint16_t total_len, head_len, apdu_len = 0, tail_len, apdu_limit_len;
|
|
uint16_t result_len = 0;
|
|
uint8_t reason = 0, is_frag = 0;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
uint8_t *resp_data;
|
|
addr_info_t addr_info = { 0 };
|
|
proto_69845_app_get_req_normal_t *req;
|
|
proto_69845_frame_head_info_t *hdr_698_resp;
|
|
proto_69845_app_req_resp_t *server_apdu;
|
|
proto_69845_app_get_resp_t *get_resp;
|
|
proto_69845_app_get_resp_normal_t *result_normal;
|
|
uint8_t fragment_type = PROTO_69845_APDU_WHOLE;
|
|
|
|
if (len < sizeof(*req)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
req = (proto_69845_app_get_req_normal_t *)data;
|
|
oi = proto_69845_byte_to_oi((uint8_t *)&req->oad.oi);
|
|
len -= sizeof(*req);
|
|
head_len = sizeof(*hdr_698_resp) + IOT_MAC_ADDR_LEN
|
|
+ PROTO_69845_CA_LEN + PROTO_69845_CHECKSUM_LEN;
|
|
apdu_limit_len = PROTO_69845_PREDICT_APDU_MAX_LEN;
|
|
tail_len = PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN +
|
|
sizeof(proto_69845_tailer_t);
|
|
resp_pkt = iot_pkt_alloc(head_len + apdu_limit_len + tail_len,
|
|
IOT_SMART_GRID_MID);
|
|
if (!resp_pkt) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
resp_data = iot_pkt_data(resp_pkt);
|
|
hdr_698_resp = (proto_69845_frame_head_info_t *)resp_data;
|
|
resp_data += head_len;
|
|
server_apdu = (proto_69845_app_req_resp_t *)resp_data;
|
|
apdu_len += sizeof(*server_apdu);
|
|
get_resp = (proto_69845_app_get_resp_t *)server_apdu->data;
|
|
apdu_len += sizeof(*get_resp);
|
|
switch (oi) {
|
|
case PROTO_69845_APP_OI_BR2_INFO:
|
|
case PROTO_69845_APP_OI_EXT_BR2_INFO:
|
|
{
|
|
apdu_limit_len -= apdu_len;
|
|
result_len = iot_bsrm_698_br2_record_info_fill(get_resp->data,
|
|
apdu_limit_len, req->piid.sn, req->piid.priority, 1, oi, 0,
|
|
&is_frag);
|
|
if (!result_len) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
if (is_frag) {
|
|
fragment_type = PROTO_69845_APDU_PART;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OI_EXT_BR2_LAUNCH:
|
|
case PROTO_69845_APP_OI_BR2_LAUNCH:
|
|
{
|
|
if (req->oad.attribute_id != 4) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
result_normal = (proto_69845_app_get_resp_normal_t *)get_resp->data;
|
|
result_normal->oad = req->oad;
|
|
result_normal->piid_acd.sn = req->piid.sn;
|
|
result_normal->piid_acd.priority = req->piid.priority;
|
|
apdu_len += sizeof(*result_normal);
|
|
apdu_limit_len -= apdu_len;
|
|
result_len = iot_bsrm_69845_br2_launch_para_fill(
|
|
&result_normal->result_type, result_normal->result, apdu_limit_len);
|
|
if (!result_len) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
reason = 6;
|
|
goto drop;
|
|
}
|
|
apdu_len += result_len;
|
|
total_len = head_len + apdu_len + tail_len;
|
|
resp_data += apdu_len;
|
|
iot_pkt_put(resp_pkt, total_len);
|
|
iot_mac_addr_cpy(addr_info.ser_info.addr, p_bsrm_glb->addr);
|
|
addr_info.ser_info.len = IOT_MAC_ADDR_LEN;
|
|
proto_69845_head_fill(hdr_698_resp, head_len, total_len, &addr_info,
|
|
PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
|
|
PROTO_69845_D_P_SERVER_RESPONSE);
|
|
server_apdu->type = PROTO_69845_S_APP_GET_RESP;
|
|
if (fragment_type == PROTO_69845_APDU_PART) {
|
|
get_resp->data_type = PROTO_69845_APP_GET_NEXT;
|
|
} else {
|
|
get_resp->data_type = PROTO_69845_APP_GET_NORMAL;
|
|
}
|
|
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, resp_data, tail_len);
|
|
goto out;
|
|
drop:
|
|
if (resp_pkt) {
|
|
iot_pkt_free(resp_pkt);
|
|
resp_pkt = NULL;
|
|
}
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_bsrm_69845_get_next_handle(uint8_t *data, uint32_t len)
|
|
{
|
|
uint16_t total_len, head_len, apdu_len = 0, tail_len, apdu_limit_len;
|
|
uint16_t result_len = 0, next_seq, ack_seq;
|
|
uint8_t reason = 0, retry_flag = 0, fail_flag = 0;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
uint8_t *resp_data;
|
|
addr_info_t addr_info = { 0 };
|
|
proto_69845_app_get_req_next_t *req;
|
|
proto_69845_frame_head_info_t *hdr_698_resp;
|
|
proto_69845_app_req_resp_t *server_apdu;
|
|
proto_69845_app_get_resp_t *get_resp;
|
|
proto_69845_app_get_resp_next_fail_t *next_fail;
|
|
uint8_t is_frag;
|
|
iot_bsrm_br_rec_frag_ctrl_t *frag_ctrl = &p_bsrm_glb->br_rec_frag_ctrl;
|
|
|
|
if (len < sizeof(*req)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (frag_ctrl->start_up == 0) {
|
|
/* If the fragment transmission is not started, the message is
|
|
* discarded.
|
|
*/
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
req = (proto_69845_app_get_req_next_t *)data;
|
|
len -= sizeof(*req);
|
|
ack_seq = iot_bytes_to_uint16((uint8_t *)&req->last_seq, 1);
|
|
next_seq = ack_seq + 1;
|
|
if (!next_seq) {
|
|
next_seq = 1;
|
|
}
|
|
if (ack_seq == frag_ctrl->seq) {
|
|
/* last response is succeed */
|
|
frag_ctrl->seq = next_seq;
|
|
} else if (next_seq == frag_ctrl->seq) {
|
|
/* last response is losted */
|
|
retry_flag = 1;
|
|
} else {
|
|
/* msg seq is unkown */
|
|
fail_flag = 1;
|
|
}
|
|
head_len = sizeof(*hdr_698_resp) + IOT_MAC_ADDR_LEN
|
|
+ PROTO_69845_CA_LEN + PROTO_69845_CHECKSUM_LEN;
|
|
apdu_limit_len = PROTO_69845_PREDICT_APDU_MAX_LEN;
|
|
tail_len = PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN +
|
|
sizeof(proto_69845_tailer_t);
|
|
resp_pkt = iot_pkt_alloc(head_len + apdu_limit_len + tail_len,
|
|
IOT_SMART_GRID_MID);
|
|
if (!resp_pkt) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
resp_data = iot_pkt_data(resp_pkt);
|
|
hdr_698_resp = (proto_69845_frame_head_info_t *)resp_data;
|
|
resp_data += head_len;
|
|
server_apdu = (proto_69845_app_req_resp_t *)resp_data;
|
|
apdu_len += sizeof(*server_apdu);
|
|
get_resp = (proto_69845_app_get_resp_t *)server_apdu->data;
|
|
apdu_len += sizeof(*get_resp);
|
|
apdu_limit_len -= apdu_len;
|
|
if (fail_flag) {
|
|
next_fail = (proto_69845_app_get_resp_next_fail_t *)get_resp->data;
|
|
next_fail->piid_acd.sn = req->piid.sn;
|
|
next_fail->piid_acd.priority = req->piid.priority;
|
|
next_fail->end_flag = 1;
|
|
iot_uint16_to_bytes(next_seq, (uint8_t *)&next_fail->seq, 1);
|
|
next_fail->data_type = PROTO_69845_GET_RESP_NEXT_ERR;
|
|
next_fail->err_code = PROTO_69845_APP_DAR_OTHER;
|
|
result_len = sizeof(*next_fail);
|
|
} else {
|
|
result_len = iot_bsrm_698_br2_record_info_fill(get_resp->data,
|
|
apdu_limit_len, req->piid.sn, req->piid.priority, 0, 0,
|
|
retry_flag, &is_frag);
|
|
}
|
|
if (!result_len) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
apdu_len += result_len;
|
|
total_len = head_len + apdu_len + tail_len;
|
|
resp_data += apdu_len;
|
|
iot_pkt_put(resp_pkt, total_len);
|
|
iot_mac_addr_cpy(addr_info.ser_info.addr, p_bsrm_glb->addr);
|
|
addr_info.ser_info.len = IOT_MAC_ADDR_LEN;
|
|
proto_69845_head_fill(hdr_698_resp, head_len, total_len, &addr_info,
|
|
PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
|
|
PROTO_69845_D_P_SERVER_RESPONSE);
|
|
server_apdu->type = PROTO_69845_S_APP_GET_RESP;
|
|
get_resp->data_type = PROTO_69845_APP_GET_NEXT;
|
|
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, resp_data, tail_len);
|
|
goto out;
|
|
drop:
|
|
if (resp_pkt) {
|
|
iot_pkt_free(resp_pkt);
|
|
resp_pkt = NULL;
|
|
}
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
static void iot_bsrm_br_rec_frag_ctrl_ageing(void)
|
|
{
|
|
iot_bsrm_br_rec_frag_ctrl_t *frag_ctrl = &p_bsrm_glb->br_rec_frag_ctrl;
|
|
if (frag_ctrl->start_up == 1) {
|
|
if (frag_ctrl->life_cd) {
|
|
frag_ctrl->life_cd--;
|
|
if (!frag_ctrl->life_cd) {
|
|
iot_printf("iot_bsrm_br_rec_frag_ctrl_ageing reach\n");
|
|
os_mem_set(frag_ctrl, 0, sizeof(*frag_ctrl));
|
|
}
|
|
} else {
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_handle_698_get_req(uint8_t *apdu,
|
|
uint32_t len)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
uint8_t *data_ptr = apdu;
|
|
uint32_t data_len = len;
|
|
proto_69845_app_get_req_t *req;
|
|
if (len < sizeof(*req)) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
req = (proto_69845_app_get_req_t *)data_ptr;
|
|
data_ptr += sizeof(*req);
|
|
data_len -= sizeof(*req);
|
|
switch (req->data_type) {
|
|
case PROTO_69845_APP_GET_NORMAL:
|
|
{
|
|
resp_pkt = iot_bsrm_69845_get_normal_handle(data_ptr, data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_GET_NEXT:
|
|
{
|
|
resp_pkt = iot_bsrm_69845_get_next_handle(data_ptr, data_len);
|
|
break;
|
|
}
|
|
default:
|
|
reason = 2;
|
|
break;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_bsrm_printf("%s err reason %d\n", __FUNCTION__, reason);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_69845_handle_br2_launch_para(
|
|
proto_69845_br2_launch_para_t *launch_para, uint32_t para_len)
|
|
{
|
|
uint8_t reason = 0, launch_code_len, *launch_code;
|
|
proto_69845_app_data_t *fc_data;
|
|
uint32_t len;
|
|
iot_bsrm_br_param_t br_param = { 0 };
|
|
if (!launch_para->bit_len.mub_flag) {
|
|
launch_code_len = launch_para->bit_len.byte_num / 8;
|
|
launch_code = launch_para->code;
|
|
} else {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
/* load hw tsfm mode encode frequncy, double-long-unsigned, unit: 0.01Hz */
|
|
fc_data = (proto_69845_app_data_t *)(launch_para->code + launch_code_len);
|
|
para_len -= sizeof(*launch_para) + launch_code_len;
|
|
if (para_len < sizeof(*fc_data) ||
|
|
fc_data->data_type != PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED ||
|
|
proto_69845_get_data_len(fc_data, para_len, &len)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
br_param.fc = iot_bytes_to_uint32(fc_data->data, 1);
|
|
br_param.chara_bit_dur = iot_bytes_to_uint16(
|
|
(uint8_t *)&launch_para->chara_bit_dur ,1);
|
|
br_param.pulse_high_dur = iot_bytes_to_uint16(
|
|
(uint8_t *)&launch_para->pulse_high_dur, 1);
|
|
br_param.pulse_low_dur = iot_bytes_to_uint16(
|
|
(uint8_t *)&launch_para->pulse_low_dur, 1);
|
|
br_param.id_code_len = launch_code_len;
|
|
os_mem_cpy(br_param.id_code, launch_code, launch_code_len);
|
|
iot_bsrm_set_br_recv_param(&br_param);
|
|
out:
|
|
if (reason) {
|
|
iot_bsrm_printf("%s err reason %d\n", __FUNCTION__, reason);
|
|
return ERR_FAIL;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_69845_handle_br2_launch_req(proto_69845_app_omd_t *omd,
|
|
proto_69845_data_cache_desc_t *action_desc)
|
|
{
|
|
uint8_t ele_cnt, reason;
|
|
uint32_t ret, total_len, para_len;
|
|
proto_69845_app_ele_data_t *desc;
|
|
proto_69845_rpt_data_time_s_t *start_time;
|
|
proto_69845_br2_launch_para_t *launch_para;
|
|
|
|
if (omd->method_id != PROTO_OI_BR2_LAUNCH_METHOD_LAUNCH &&
|
|
omd->method_id != PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
total_len = sizeof(*desc);
|
|
if (action_desc->len < total_len) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
desc = (proto_69845_app_ele_data_t *)action_desc->data;
|
|
if (desc->data_type != PROTO_69845_APP_DATA_STRUCTURE) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
if (omd->method_id == PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
ele_cnt = 2;
|
|
total_len = sizeof(*desc) + sizeof(*launch_para) + sizeof(*start_time);
|
|
} else {
|
|
ele_cnt = 6;
|
|
total_len = sizeof(*launch_para);
|
|
}
|
|
if (ele_cnt != desc->num_of_data || (action_desc->len < total_len)) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
if (omd->method_id == PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
launch_para = (proto_69845_br2_launch_para_t *)&desc->data;
|
|
total_len = action_desc->len - sizeof(*desc);
|
|
ret = proto_69845_get_data_len((proto_69845_app_data_t *)launch_para,
|
|
total_len, ¶_len);
|
|
if (ret) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
start_time = (proto_69845_rpt_data_time_s_t *)(desc->data + para_len);
|
|
} else {
|
|
launch_para = (proto_69845_br2_launch_para_t *)action_desc->data;
|
|
start_time = NULL;
|
|
}
|
|
if (iot_bsrm_69845_handle_br2_launch_para(launch_para, para_len) != ERR_OK) {
|
|
reason = 6;
|
|
goto drop;
|
|
}
|
|
goto out;
|
|
drop:
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
return ERR_FAIL;
|
|
out:
|
|
return ERR_OK;
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_handle_698_action_normal_req(uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
uint16_t oi;
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
addr_info_t addr_info = {0};
|
|
proto_69845_app_action_req_single_t *req;
|
|
proto_69845_data_cache_desc_t action_desc = {0};
|
|
|
|
if (len < sizeof(*req)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
req = (proto_69845_app_action_req_single_t*)data;
|
|
oi = proto_69845_byte_to_oi((uint8_t *)&req->omd.oi);
|
|
len -= sizeof(*req);
|
|
if (proto_69845_get_data_len(&req->data, len, &action_desc.len)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
if (len < action_desc.len) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
action_desc.data = (uint8_t *)&req->data;
|
|
switch (oi) {
|
|
case PROTO_69845_APP_OI_BR2_INFO:
|
|
case PROTO_69845_APP_OI_EXT_BR2_INFO:
|
|
{
|
|
if (req->omd.method_id != PROTO_OI_BR2_REC_METHOD_CLEAR) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
iot_bsrm_br_rec_clear();
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OI_EXT_BR2_LAUNCH:
|
|
case PROTO_69845_APP_OI_BR2_LAUNCH:
|
|
{
|
|
if (iot_bsrm_69845_handle_br2_launch_req(&req->omd, &action_desc) !=
|
|
ERR_OK) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
goto drop;
|
|
}
|
|
addr_info.ser_info.type = PROTO_69845_SA_TYPE_SIG;
|
|
addr_info.ser_info.len = IOT_MAC_ADDR_LEN;
|
|
addr_info.ser_info.logical_addr = 0;
|
|
iot_mac_addr_cpy(addr_info.ser_info.addr, p_bsrm_glb->addr);
|
|
addr_info.cli_addr = PROTO_69845_CA_INVAILD_ADD;
|
|
req->omd.oi = oi;
|
|
resp_pkt = proto_69845_action_single_ack(&addr_info, &req->piid, &req->omd,
|
|
PROTO_69845_APP_DAR_SUCCESS);
|
|
goto out;
|
|
drop:
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_handle_698_action_req(uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
uint8_t *data_ptr = data;
|
|
uint32_t data_len = len;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_69845_app_action_req_t *req;
|
|
|
|
if (len < sizeof(*req)) {
|
|
goto out;
|
|
}
|
|
req = (proto_69845_app_action_req_t*)data;
|
|
data_ptr += sizeof(*req);
|
|
data_len -= sizeof(*req);
|
|
switch (req->data_type) {
|
|
case PROTO_69845_APP_ACTION_NORMAL:
|
|
{
|
|
resp_pkt = iot_bsrm_handle_698_action_normal_req(data_ptr, data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_bsrm_69845_set_normal_handle(uint8_t *data, uint32_t len)
|
|
{
|
|
uint16_t oi;
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
addr_info_t addr_info = {0};
|
|
proto_69845_app_set_req_normal_t *req;
|
|
proto_69845_data_cache_desc_t data_desc = {0};
|
|
proto_69845_br2_launch_para_t *launch_para;
|
|
|
|
if (len < sizeof(*req)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
req = (proto_69845_app_set_req_normal_t *)data;
|
|
oi = proto_69845_byte_to_oi((uint8_t *)&req->oad.oi);
|
|
len -= sizeof(*req);
|
|
if (proto_69845_get_data_len(&req->data, len, &data_desc.len)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
if (len < data_desc.len) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
data_desc.data = (uint8_t *)&req->data;
|
|
switch (oi) {
|
|
case PROTO_69845_APP_OI_EXT_BR2_LAUNCH:
|
|
case PROTO_69845_APP_OI_BR2_LAUNCH:
|
|
{
|
|
if (req->oad.attribute_id != 4) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
launch_para = (proto_69845_br2_launch_para_t *)data_desc.data;
|
|
if (iot_bsrm_69845_handle_br2_launch_para(launch_para, data_desc.len) !=
|
|
ERR_OK) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
goto out;
|
|
}
|
|
addr_info.ser_info.type = PROTO_69845_SA_TYPE_SIG;
|
|
addr_info.ser_info.len = IOT_MAC_ADDR_LEN;
|
|
addr_info.ser_info.logical_addr = 0;
|
|
iot_mac_addr_cpy(addr_info.ser_info.addr, p_bsrm_glb->addr);
|
|
addr_info.cli_addr = PROTO_69845_CA_INVAILD_ADD;
|
|
req->oad.oi = oi;
|
|
resp_pkt = proto_69845_set_normal_ack(&addr_info, &req->piid, &req->oad,
|
|
PROTO_69845_APP_DAR_SUCCESS);
|
|
goto out;
|
|
|
|
drop:
|
|
iot_bsrm_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_handle_69845_set_req(uint8_t *data, uint32_t len)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *data_ptr = data;
|
|
uint32_t data_len = len;
|
|
proto_69845_app_set_req_t *req;
|
|
if (len < sizeof(*req)) {
|
|
goto out;
|
|
}
|
|
req = (proto_69845_app_set_req_t *)data;
|
|
data_ptr += sizeof(*req);
|
|
data_len -= sizeof(*req);
|
|
switch (req->data_type) {
|
|
case PROTO_69845_APP_SET_NORMAL:
|
|
{
|
|
pkt = iot_bsrm_69845_set_normal_handle(data_ptr, data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_handle_698_req(
|
|
uint8_t *data, uint32_t len, uint8_t *fwd)
|
|
{
|
|
uint8_t *data_ptr = data, reason = 0, sub33;
|
|
uint32_t data_len = len;
|
|
proto_69845_frame_head_info_t *hdr = NULL;
|
|
proto_69845_app_req_resp_t *req;
|
|
apdu_info_t apdu_desc = {0};
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
addr_info_t addr_info = {0};
|
|
|
|
(void)fwd;
|
|
if (proto_69845_parse(&data_ptr, &data_len, &hdr, &apdu_desc)) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
sub33 = 1;
|
|
proto_69845_get_addr_info(hdr, &addr_info);
|
|
if (addr_info.ser_info.type == PROTO_69845_SA_TYPE_GROUP
|
|
|| addr_info.ser_info.type == PROTO_69845_SA_TYPE_BROADCAST
|
|
|| !iot_bsrm_addr_check(addr_info.ser_info.addr)) {
|
|
goto out;
|
|
}
|
|
if (proto_69845_apdu_sec_ciphertext_check(apdu_desc.ptr, apdu_desc.len)
|
|
== ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
req = (proto_69845_app_req_resp_t*)data_ptr;
|
|
data_ptr += sizeof(*req);
|
|
data_len -= sizeof(*req);
|
|
if (ERR_OK != iot_bsrm_sg_check_698_req(req)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
switch (req->type) {
|
|
case PROTO_69845_C_APP_GET_REQ:
|
|
{
|
|
resp_pkt = iot_bsrm_handle_698_get_req(data_ptr, data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_ACTION_REQ:
|
|
{
|
|
resp_pkt = iot_bsrm_handle_698_action_req(data_ptr, data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_SET_REQ:
|
|
{
|
|
resp_pkt = iot_bsrm_handle_69845_set_req(data_ptr, data_len);
|
|
break;
|
|
}
|
|
default:
|
|
reason = 4;
|
|
break;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_bsrm_printf("handle 698 data err %lu\n", reason);
|
|
}
|
|
if (sub33 && hdr && hdr->ctrl.flag_scramble) {
|
|
proto_69845_add33_handle(apdu_desc.ptr, apdu_desc.len);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_handle_master_698_data(
|
|
uint8_t *data, uint32_t len)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
|
|
resp_pkt = iot_bsrm_handle_698_req(data, len, NULL);
|
|
if (resp_pkt) {
|
|
iot_bsrm_uart_send(resp_pkt);
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_handle_master_data(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t ret = ERR_FAIL, *data;
|
|
uint32_t len = 0;
|
|
proto_645_header_t *hdr_645;
|
|
proto_69845_frame_head_info_t *hdr_698;
|
|
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
|
|
if (hdr_645) {
|
|
iot_bsrm_check_renew_addr(hdr_645->addr);
|
|
ret = iot_bsrm_handle_master_645_data(hdr_645);
|
|
} else {
|
|
hdr_698 = proto_69845_sanity_check(data, len);
|
|
if (hdr_698) {
|
|
iot_bsrm_check_renew_addr(proto_69845_get_ser_addr(hdr_698));
|
|
ret = iot_bsrm_handle_master_698_data(data, len);
|
|
} else {
|
|
iot_bsrm_printf("uart rec invalid data\n");
|
|
ret = ERR_INVAL;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_sg_check_proto_di_r(uint32_t di)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (false == iot_board_support_topo_rx()) {
|
|
switch (di) {
|
|
case PROTO_645_FJ_DI_UPGRADE_SEND_FILE:
|
|
case PROTO_645_FJ_DI_UPGRADE_REQ_FILE:
|
|
case PROTO_645_2007_EXT_DI_READ_VER:
|
|
break;
|
|
default:
|
|
ret = ERR_FAIL;
|
|
break;
|
|
}
|
|
} else {
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD:
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD_ZJ:
|
|
case PROTO_645_2007_EXT_DI_BR2_RECV_RECORD_XIONGAN:
|
|
case PROTO_645_2007_EXT_BRM_CURRENT_COEFF:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
if ((di & 0xFFFFFF00) != PROTO_645_2007_EXT_DI_BR2_EVT_RECORD_ZJ) {
|
|
ret = ERR_FAIL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_sg_check_proto_di_w(uint32_t di)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
if (false == iot_board_support_topo_rx()) {
|
|
ret = ERR_FAIL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void iot_bsrm_sg_645_data_handler(iot_pkt_t *pkt,
|
|
proto_645_header_t *hdr_645)
|
|
{
|
|
uint8_t fn;
|
|
uint8_t err_code = 0;
|
|
uint8_t *out_buf;
|
|
uint8_t out_len;
|
|
uint8_t *out_ds = p_bsrm_glb->proto_buff;
|
|
uint8_t follow = PROTO_645_FOLLOW_INVALID;
|
|
uint32_t len = 0;
|
|
uint32_t di;
|
|
uint8_t fwd = 1;
|
|
uint8_t sub33 = 0;
|
|
if (!iot_bsrm_addr_check(hdr_645->addr)) {
|
|
goto out;
|
|
}
|
|
proto_645_sub33_handle(hdr_645->data, hdr_645->len);
|
|
sub33 = 1;
|
|
fn = (uint8_t)hdr_645->control.fn;
|
|
os_mem_set(out_ds, 0, PROTO_645_MAX_PKT_LEN);
|
|
out_buf = out_ds + sizeof(*hdr_645);
|
|
out_len = PROTO_645_MAX_DATA_LEN;
|
|
switch (fn) {
|
|
case PROTO_645_2007_EXT_FN_BR:
|
|
{
|
|
err_code = iot_bsrm_proto_645_br_data_hander(hdr_645->data,
|
|
hdr_645->len, out_buf, &out_len);
|
|
if (err_code == PROTO_645_2007_ERR_NO_REQ_DATA) {
|
|
goto out;
|
|
}
|
|
fwd = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
if (hdr_645->len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(hdr_645->data);
|
|
if (iot_bsrm_sg_check_proto_di_r(di) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
fwd = 0;
|
|
err_code = iot_bsrm_proto_645_r_data_hander(hdr_645->data,
|
|
hdr_645->len, out_buf, &out_len);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_QUERY_TOPO:
|
|
{
|
|
if (false == iot_board_support_topo_rx()) {
|
|
goto out;
|
|
}
|
|
err_code = iot_bsrm_proto_645_query_topo_data_hander(hdr_645->data,
|
|
hdr_645->len, out_buf, &out_len);
|
|
if (err_code == PROTO_645_2007_ERR_NO_REQ_DATA) {
|
|
goto out;
|
|
}
|
|
fwd = 0;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
if (hdr_645->len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(hdr_645->data);
|
|
if (iot_bsrm_sg_check_proto_di_w(di) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
err_code = iot_bsrm_proto_645_w_data_hander(hdr_645->data, hdr_645->len,
|
|
out_buf, &out_len);
|
|
if (err_code == PROTO_645_2007_ERR_NO_REQ_DATA) {
|
|
goto out;
|
|
}
|
|
fwd = 0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (err_code) {
|
|
len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
|
|
p_bsrm_glb->addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_ABNORMAL,
|
|
follow, fn, PROTO_645_INVALID_DI, 1, &err_code);
|
|
} else {
|
|
len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
|
|
p_bsrm_glb->addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
|
|
follow, fn, PROTO_645_INVALID_DI, out_len, out_buf);
|
|
}
|
|
iot_bsrm_send_data_to_sg_app(out_ds, len);
|
|
out:
|
|
if (fwd) {
|
|
if (sub33) {
|
|
proto_645_add33_handle(hdr_645->data, hdr_645->len);
|
|
}
|
|
iot_bsrm_fwd_data(pkt);
|
|
} else {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_sg_698_data_handler(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data = iot_pkt_data(pkt), fwd = 1;
|
|
uint32_t len = iot_pkt_data_len(pkt);
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
|
|
resp_pkt = iot_bsrm_handle_698_req(data, len, &fwd);
|
|
if (resp_pkt) {
|
|
fwd = 0;
|
|
data = iot_pkt_data(resp_pkt);
|
|
len = iot_pkt_data_len(resp_pkt);
|
|
iot_bsrm_send_data_to_sg_app(data, len);
|
|
iot_pkt_free(resp_pkt);
|
|
}
|
|
if (fwd) {
|
|
iot_bsrm_fwd_data(pkt);
|
|
} else {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_sg_data_handler(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data;
|
|
uint32_t len;
|
|
proto_645_header_t *hdr_645;
|
|
proto_69845_frame_head_info_t *hdr_698;
|
|
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
|
|
if (hdr_645) {
|
|
iot_bsrm_sg_645_data_handler(pkt, hdr_645);
|
|
} else {
|
|
hdr_698 = proto_69845_sanity_check(data, len);
|
|
if (hdr_698) {
|
|
iot_bsrm_sg_698_data_handler(pkt);
|
|
} else {
|
|
iot_bsrm_fwd_data(pkt);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_evt_set_pend(void)
|
|
{
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_TRANS) {
|
|
return;
|
|
}
|
|
p_bsrm_glb->evt_nodify_pend = 1;
|
|
iot_bsrm_cmd_guard(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
}
|
|
|
|
static void iot_bsrm_evt_clear_pend(void)
|
|
{
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_TRANS) {
|
|
return;
|
|
}
|
|
p_bsrm_glb->evt_nodify_pend = 0;
|
|
p_bsrm_glb->evt_nodify_try_cnt = 0;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_handle_evt_nodify_resp(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data;
|
|
uint32_t len;
|
|
uint8_t done = 0;
|
|
proto_645_header_t *hdr = NULL;
|
|
if (pkt == NULL) {
|
|
p_bsrm_glb->evt_nodify_try_cnt++;
|
|
if (p_bsrm_glb->evt_nodify_try_cnt >= IOT_BSRM_EVT_NODIFY_TRY_MAX) {
|
|
iot_bsrm_evt_clear_pend();
|
|
}
|
|
goto out;
|
|
}
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
|
|
if (hdr != NULL
|
|
&& hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA
|
|
&& hdr->control.ack == PROTO_645_ACK_NORMAL) {
|
|
iot_bsrm_evt_clear_pend();
|
|
done = 1;
|
|
}
|
|
iot_pkt_free(pkt);
|
|
out:
|
|
return done;
|
|
}
|
|
|
|
static uint32_t iot_bsrm_rating_cur_to_cur_coeff(
|
|
proto_645_07_rating_current_t *rating_cur)
|
|
{
|
|
uint32_t cur_coeff;
|
|
float ratio = 0;
|
|
uint32_t in_cur;
|
|
float res = 1.0;
|
|
|
|
in_cur = (uint32_t)proto_645_ascii_to_integer(rating_cur->value,
|
|
PROTO_645_2007_RATING_CUR_LEN);
|
|
|
|
uint8_t n = IOT_ARRAY_CNT(rating_cur_tab);
|
|
for (uint8_t i = 0; i < n; i++) {
|
|
if (rating_cur_tab[i].rating_current == in_cur) {
|
|
ratio = rating_cur_tab[i].ratio;
|
|
res = rating_cur_tab[i].resistance;
|
|
break;
|
|
}
|
|
}
|
|
/*
|
|
* cur ration coeff = (k1 / r1) / (k0 / r0), unit: 0.0001.
|
|
* k1: current transformer ratio. r1: Sampling resistance;
|
|
* k0 = 4000 base current transformer,
|
|
* r0 = 4.4ohm base Sampling resistance.
|
|
*/
|
|
cur_coeff = (uint32_t)(ratio * 11.0 / res);
|
|
iot_bsrm_printf("%s input: %lu A,cur_coeff: %d\n", __FUNCTION__, in_cur,
|
|
cur_coeff);
|
|
return cur_coeff;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_handle_cur_coeff_resp(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data;
|
|
uint32_t len;
|
|
proto_645_header_t *hdr = NULL;
|
|
proto_645_07_rating_current_t *rating_cur;
|
|
uint8_t done = 0;
|
|
uint32_t i_coeff;
|
|
uint32_t di;
|
|
|
|
if (NULL == pkt) {
|
|
if (p_bsrm_glb->coeff_sync_cnt++ > IOT_BSRM_SYNC_CUR_COEFF_MAX_CNT) {
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_DONE;
|
|
}
|
|
iot_printf("%s timeout\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
|
|
if (NULL == hdr) {
|
|
goto out;
|
|
}
|
|
if (hdr->len < PROTO_645_2007_DI_LEN + sizeof(*rating_cur)) {
|
|
goto out;
|
|
}
|
|
proto_645_sub33_handle(hdr->data, hdr->len);
|
|
di = proto_645_2007_byte_to_di(hdr->data);
|
|
if (PROTO_645_2007_DI_RATING_CURRENT == di) {
|
|
rating_cur = (proto_645_07_rating_current_t *)
|
|
(hdr->data + PROTO_645_2007_DI_LEN);
|
|
i_coeff = iot_bsrm_rating_cur_to_cur_coeff(rating_cur);
|
|
iot_bsrm_set_ct_coeff(i_coeff);
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_DONE;
|
|
done = 1;
|
|
}
|
|
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
iot_printf("%s, cur_coeff_sync_sts: %d \n", __FUNCTION__,
|
|
p_bsrm_glb->cur_coeff_sync_sts);
|
|
return done;
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_w_cmd_from_cus_handle(uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
uint32_t di;
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
uint8_t handle = 0;
|
|
proto_645_ext_ct_coeff_t *ct_coeff;
|
|
if (len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(data);
|
|
data += PROTO_645_2007_DI_LEN;
|
|
len -= PROTO_645_2007_DI_LEN;
|
|
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_BRM_CURRENT_COEFF:
|
|
{
|
|
handle = 1;
|
|
if (len < sizeof(*ct_coeff)) {
|
|
err_code = PROTO_645_2007_ERR_OTHER;
|
|
break;
|
|
}
|
|
ct_coeff = (proto_645_ext_ct_coeff_t *)data;
|
|
iot_bsrm_set_ct_coeff(ct_coeff->coeff);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (handle) {
|
|
if (err_code != PROTO_645_2007_ERR_OK) {
|
|
pkt = proto_645_build_msg(p_bsrm_glb->addr, &err_code, 1,
|
|
PROTO_645_INVALID_DI,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_ACK_ABNORMAL,
|
|
PROTO_645_2007_FN_WRITE_DATA, PROTO_645_2007_ID,
|
|
PROTO_645_FOLLOW_INVALID);
|
|
} else {
|
|
pkt = proto_645_build_msg(p_bsrm_glb->addr, NULL, 0,
|
|
PROTO_645_INVALID_DI,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
|
|
PROTO_645_2007_FN_WRITE_DATA, PROTO_645_2007_ID,
|
|
PROTO_645_FOLLOW_INVALID);
|
|
}
|
|
|
|
}
|
|
out:
|
|
return pkt;
|
|
|
|
}
|
|
|
|
static iot_pkt_t *iot_bsrm_r_cmd_from_cus_handle(uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
uint32_t di;
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t err_code = PROTO_645_2007_ERR_OK;
|
|
uint8_t handle = 0, out_len = 0;
|
|
uint8_t *out_ds = p_bsrm_glb->proto_buff;
|
|
proto_645_ext_ct_coeff_t *ct_coeff;
|
|
if (len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(data);
|
|
data += PROTO_645_2007_DI_LEN;
|
|
len -= PROTO_645_2007_DI_LEN;
|
|
|
|
switch (di) {
|
|
case PROTO_645_2007_EXT_BRM_CURRENT_COEFF:
|
|
{
|
|
handle = 1;
|
|
ct_coeff = (proto_645_ext_ct_coeff_t *)out_ds;
|
|
out_len += sizeof(*ct_coeff);
|
|
ct_coeff->coeff = iot_bsrm_get_ct_coeff();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (handle) {
|
|
if (err_code != PROTO_645_2007_ERR_OK) {
|
|
pkt = proto_645_build_msg(p_bsrm_glb->addr, &err_code, 1,
|
|
PROTO_645_INVALID_DI, PROTO_645_DIR_SLAVE,
|
|
PROTO_645_ACK_ABNORMAL, PROTO_645_2007_FN_READ_DATA,
|
|
PROTO_645_2007_ID, PROTO_645_FOLLOW_INVALID);
|
|
} else {
|
|
pkt = proto_645_build_msg(p_bsrm_glb->addr, out_ds, out_len, di,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
|
|
PROTO_645_2007_FN_READ_DATA, PROTO_645_2007_ID,
|
|
PROTO_645_FOLLOW_INVALID);
|
|
}
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint8_t iot_bsrm_cmd_from_cus_handle(uint8_t *data,
|
|
uint32_t len)
|
|
{
|
|
uint8_t handle = 0;
|
|
uint8_t sub33 = 0;
|
|
uint8_t *ds;
|
|
uint32_t in_len;
|
|
proto_645_header_t *hdr;
|
|
iot_pkt_t *pkt = NULL;
|
|
hdr = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
|
|
if (!hdr) {
|
|
goto out;
|
|
}
|
|
proto_645_sub33_handle(hdr->data, hdr->len);
|
|
sub33 = 1;
|
|
|
|
ds = hdr->data;
|
|
in_len = hdr->len;
|
|
|
|
switch (hdr->control.fn) {
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
pkt = iot_bsrm_w_cmd_from_cus_handle(ds, in_len);
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
pkt = iot_bsrm_r_cmd_from_cus_handle(ds, in_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (pkt) {
|
|
iot_bsrm_uart_send(pkt);
|
|
handle = 1;
|
|
}
|
|
out:
|
|
if (sub33) {
|
|
proto_645_add33_handle(hdr->data, hdr->len);
|
|
}
|
|
return handle;
|
|
}
|
|
|
|
|
|
static void iot_bsrm_handle_resp_in_tans_mode(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t done = 0;
|
|
uint8_t *data;
|
|
uint32_t len;
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
if (iot_bsrm_cmd_from_cus_handle(data, len)) {
|
|
iot_pkt_free(pkt);
|
|
return;
|
|
}
|
|
switch (p_bsrm_glb->mr_status) {
|
|
case IOT_BSRM_MR_STATE_FWD:
|
|
{
|
|
iot_bsrm_send_data_to_sg_app(data, len);
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_EVT_NODIF:
|
|
{
|
|
done = iot_bsrm_handle_evt_nodify_resp(pkt);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_SYNC_CUR_RATIO_COEFF:
|
|
{
|
|
done = iot_bsrm_handle_cur_coeff_resp(pkt);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_PM_UPGRADE:
|
|
{
|
|
done = iot_bsrm_handle_pm_upgrade_resp(pkt);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_READY:
|
|
case IOT_BSRM_MR_STATE_IDLE:
|
|
{
|
|
iot_bsrm_send_data_to_sg_app(data, len);
|
|
}
|
|
default:
|
|
{
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
}
|
|
if (done) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
iot_bsrm_restart_mr_timer(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_brm_evt_nodify_issue(void)
|
|
{
|
|
proto_645_header_t *hdr;
|
|
proto_645_write_data_dest_t *w;
|
|
proto_645_ext_bsrm_evt_nodify_t *nodify;
|
|
uint8_t *data;
|
|
iot_pkt_t *pkt;
|
|
if (!p_bsrm_glb->evt_nodify_pend) {
|
|
return ERR_NOT_EXIST;
|
|
}
|
|
pkt = iot_pkt_alloc(PROTO_645_PREAMBLE_LEN + sizeof(*hdr) + sizeof(*w) \
|
|
+ sizeof(*nodify) + sizeof(proto_645_tailer_t), IOT_BSRM_MID);
|
|
if (pkt == NULL) {
|
|
return ERR_NOMEM;
|
|
}
|
|
data = iot_pkt_data(pkt);
|
|
os_mem_cpy(data, proto_645_preamble, sizeof(proto_645_preamble));
|
|
data += sizeof(proto_645_preamble);
|
|
iot_pkt_put(pkt, sizeof(proto_645_preamble));
|
|
|
|
hdr = (proto_645_header_t *)data;
|
|
proto_645_header_init(hdr, p_bsrm_glb->addr, PROTO_645_2007_FN_WRITE_DATA,
|
|
PROTO_645_DIR_MASTER, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
|
|
data += sizeof(*hdr);
|
|
iot_pkt_put(pkt, sizeof(*hdr));
|
|
|
|
w = (proto_645_write_data_dest_t *)data;
|
|
proto_645_2007_di_to_byte(PROTO_645_2007_EXT_BSRM_DI_EVT_NODIFY, w->di);
|
|
os_mem_set(w->operator, 0x0, sizeof(w->operator));
|
|
os_mem_set(w->password, 0x0, sizeof(w->password));
|
|
data += sizeof(*w);
|
|
hdr->len += sizeof(*w);
|
|
|
|
nodify = (proto_645_ext_bsrm_evt_nodify_t *)data;
|
|
nodify->flag = 1;
|
|
os_mem_set(nodify->rsvd, 0x0, sizeof(nodify->rsvd));
|
|
hdr->len += sizeof(*nodify);
|
|
|
|
proto_645_add33_handle(hdr->data, hdr->len);
|
|
proto_645_tail_init(hdr);
|
|
iot_pkt_put(pkt, hdr->len + sizeof(proto_645_tailer_t));
|
|
iot_bsrm_uart_send(pkt);
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint32_t iot_brm_sync_cur_coeff(void)
|
|
{
|
|
iot_pkt_t *pkt;
|
|
|
|
if (p_bsrm_glb->cur_coeff_sync_sts != IOT_BSRM_SYNC_CUR_COEFF_DOING) {
|
|
return ERR_EXIST;
|
|
}
|
|
pkt = proto_645_build_mr_msg(PROTO_645_2007_ID, proto_645_any_addr,
|
|
PROTO_645_2007_DI_RATING_CURRENT);
|
|
IOT_ASSERT(pkt);
|
|
iot_bsrm_uart_send(pkt);
|
|
return ERR_OK;
|
|
}
|
|
|
|
static void iot_bsrm_mr_timeout_in_tans_mode(void)
|
|
{
|
|
uint32_t ret;
|
|
uint32_t timeout;
|
|
|
|
switch (p_bsrm_glb->mr_status) {
|
|
case IOT_BSRM_MR_STATE_READY:
|
|
{
|
|
if (p_bsrm_glb->fwd_pkt) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_FWD;
|
|
iot_bsrm_uart_send(p_bsrm_glb->fwd_pkt);
|
|
p_bsrm_glb->fwd_pkt = NULL;
|
|
iot_bsrm_restart_mr_timer(3000);
|
|
goto out;
|
|
}
|
|
ret = iot_brm_sync_cur_coeff();
|
|
if (ret == ERR_OK) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_SYNC_CUR_RATIO_COEFF;
|
|
iot_bsrm_restart_mr_timer(IOT_BSRM_MR_TIMER_RSP_TIMEOUT);
|
|
goto out;
|
|
}
|
|
ret = iot_brm_evt_nodify_issue();
|
|
if (ret == ERR_OK) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_EVT_NODIF;
|
|
iot_bsrm_restart_mr_timer(IOT_BSRM_MR_EVT_NODIFY_TIMEOUT);
|
|
goto out;
|
|
} else if (ret != ERR_NOT_EXIST) {
|
|
/* the execution failed, but the task was not finished yet. */
|
|
break;
|
|
}
|
|
|
|
ret = iot_bsrm_handle_pm_upgrade_req(&timeout);
|
|
if (ret == ERR_OK) {
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_PM_UPGRADE;
|
|
iot_bsrm_restart_mr_timer(timeout);
|
|
goto out;
|
|
} else if (ret == ERR_NOMEM) {
|
|
/* malloc fail, retry again upgrade */
|
|
break;
|
|
}
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_IDLE;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_FWD:
|
|
{
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_SYNC_CUR_RATIO_COEFF:
|
|
{
|
|
iot_bsrm_handle_cur_coeff_resp(NULL);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_EVT_NODIF:
|
|
{
|
|
iot_bsrm_handle_evt_nodify_resp(NULL);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_PM_UPGRADE:
|
|
{
|
|
iot_bsrm_handle_pm_upgrade_resp(NULL);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_READY;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_IDLE:
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
if (p_bsrm_glb->mr_status == IOT_BSRM_MR_STATE_READY) {
|
|
iot_bsrm_restart_mr_timer(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_bsrm_handle_uart_msg(iot_bsrm_msg_t *sg_msg)
|
|
{
|
|
iot_pkt_t *pkt = (iot_pkt_t *)sg_msg->data;
|
|
IOT_ASSERT(sg_msg->task_msg.id == IOT_BSRM_MSG_ID_UART_DATA);
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
/* handle bsrm uart 645 proto data */
|
|
if (ERR_OK != iot_bsrm_handle_slave_data(pkt)) {
|
|
iot_bsrm_handle_master_data(pkt);
|
|
}
|
|
iot_pkt_free(pkt);
|
|
} else {
|
|
iot_bsrm_handle_resp_in_tans_mode(pkt);
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_bsrm_sync_tm_cmd_issue()
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint32_t di = PROTO_645_2007_DI_TIME_HMS;
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if (p_bsrm_glb->sync_tm_state == IOT_BSRM_SYNC_TIME_STATE_YMD) {
|
|
/* get time ymd cmd */
|
|
di = PROTO_645_2007_DI_TIME_YMD;
|
|
}
|
|
pkt = proto_645_build_msg(p_bsrm_glb->addr, NULL, 0, di,
|
|
PROTO_645_DIR_MASTER, PROTO_645_ACK_NORMAL, 0x11, PROTO_645_2007_ID,
|
|
PROTO_645_FOLLOW_INVALID);
|
|
if (pkt) {
|
|
iot_bsrm_uart_send(pkt);
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* handle pending communication commands */
|
|
static uint32_t iot_bsrm_pend_comm_handle(void)
|
|
{
|
|
iot_pkt_t *pkt;
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if (p_bsrm_glb->mr_addr_pend) {
|
|
/* send get addr 645 cmd */
|
|
pkt = proto_645_2007_build_ra_msg();
|
|
if (pkt) {
|
|
p_bsrm_glb->mr_addr_pend = 0;
|
|
p_bsrm_glb->req_cnt++;
|
|
iot_bsrm_uart_send(pkt);
|
|
os_start_timer(p_bsrm_glb->mr_timer, IOT_BSRM_MR_TIMER_RSP_TIMEOUT);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_GET_ADDR;
|
|
ret = ERR_OK;
|
|
}
|
|
} else if (p_bsrm_glb->sync_tm_state != IOT_BSRM_SYNC_TIME_STATE_IDLE) {
|
|
/* sync tm */
|
|
ret = iot_bsrm_sync_tm_cmd_issue();
|
|
if (ret == ERR_OK) {
|
|
if (!p_bsrm_glb->sync_tm_done) {
|
|
p_bsrm_glb->req_cnt++;
|
|
}
|
|
os_start_timer(p_bsrm_glb->mr_timer, IOT_BSRM_MR_TIMER_RSP_TIMEOUT);
|
|
p_bsrm_glb->mr_status = IOT_BSRM_MR_STATE_SYNC_TIME;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void iot_bsrm_mr_timeout_default()
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
switch (p_bsrm_glb->mr_status) {
|
|
case IOT_BSRM_MR_STATE_READY:
|
|
{
|
|
ret = iot_bsrm_pend_comm_handle();
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_GET_ADDR:
|
|
{
|
|
iot_bsrm_printf("bsrm get addr timeout\n");
|
|
break;
|
|
}
|
|
case IOT_BSRM_MR_STATE_SYNC_TIME:
|
|
{
|
|
p_bsrm_glb->sync_tm_state = IOT_BSRM_SYNC_TIME_STATE_IDLE;
|
|
iot_bsrm_printf("bsrm correct time timeout\n");
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
if (ret != ERR_OK) {
|
|
iot_bsrm_check_done_handle();
|
|
}
|
|
}
|
|
|
|
|
|
static void iot_bsrm_mr_timeout()
|
|
{
|
|
if (p_bsrm_glb->session_mode == IOT_BSRM_SESSION_MODE_TRANS) {
|
|
iot_bsrm_mr_timeout_in_tans_mode();
|
|
} else {
|
|
iot_bsrm_mr_timeout_default();
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_branch_info_rec(void)
|
|
{
|
|
iot_bsrm_nv_info_t *nv_info;
|
|
iot_bsrm_branch_evt_rec_entry_t *evt_buf =
|
|
(iot_bsrm_branch_evt_rec_entry_t *)p_bsrm_glb->evt_buf;
|
|
|
|
evt_buf->data_cnt = p_bsrm_glb->data_cnt;
|
|
iot_bsrm_evt_rec_write(p_bsrm_glb->evt_buf);
|
|
p_bsrm_glb->data_cnt = 0;
|
|
p_bsrm_glb->evt_trig_cd = 0;
|
|
os_mem_set(p_bsrm_glb->evt_buf, 0, sizeof(*evt_buf));
|
|
nv_info = (iot_bsrm_nv_info_t *)iot_bsrm_nv_get_section(
|
|
iot_bsrm_nv_id_info);
|
|
nv_info->evt_occur_cnt++;
|
|
iot_bsrm_printf("%s...event cnt %lu\n", __FUNCTION__,
|
|
nv_info->evt_occur_cnt);
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_info);
|
|
iot_bsrm_evt_set_pend();
|
|
}
|
|
|
|
static void iot_bsrm_branch_info_timeout_handle(void)
|
|
{
|
|
iot_bsrm_branch_evt_rec_entry_t *evt_buf =
|
|
(iot_bsrm_branch_evt_rec_entry_t *)p_bsrm_glb->evt_buf;
|
|
iot_bsrm_branch_info_entry_t *rec_buf = &p_bsrm_glb->br_rec_buf;
|
|
if (p_bsrm_glb->br_rec_cd) {
|
|
p_bsrm_glb->br_rec_cd--;
|
|
if (!p_bsrm_glb->br_rec_cd) {
|
|
iot_bsrm_info_rec(rec_buf->ts, sizeof(*rec_buf),
|
|
(uint8_t *)rec_buf);
|
|
os_mem_cpy(&evt_buf->record_data[p_bsrm_glb->data_cnt],
|
|
(uint8_t *)rec_buf, sizeof(*rec_buf));
|
|
p_bsrm_glb->data_cnt++;
|
|
if (!p_bsrm_glb->evt_trig_cd) {
|
|
p_bsrm_glb->evt_trig_cd = IOT_BSRM_BRANCH_EVT_TIMEOUT;
|
|
}
|
|
if (p_bsrm_glb->data_cnt == IOT_BSRM_BRANCH_EVT_ENTRY_INFO_NUM) {
|
|
iot_bsrm_branch_info_rec();
|
|
}
|
|
}
|
|
}
|
|
if (p_bsrm_glb->evt_trig_cd) {
|
|
p_bsrm_glb->evt_trig_cd--;
|
|
if (!p_bsrm_glb->evt_trig_cd) {
|
|
iot_bsrm_branch_info_rec();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_session_mode_main_check()
|
|
{
|
|
uint32_t interval_tm = IOT_BSRM_REQ_TIMER_TIMEOUT;
|
|
|
|
if (p_bsrm_glb->session_mode != IOT_BSRM_SESSION_MODE_DEFAULT) {
|
|
goto out;
|
|
}
|
|
if (p_bsrm_glb->req_cnt >= IOT_BSRM_REQ_MAX_CNT) {
|
|
goto out;
|
|
}
|
|
if (!p_bsrm_glb->addr_valid) {
|
|
if (p_bsrm_glb->mr_tm_interval < interval_tm) {
|
|
p_bsrm_glb->mr_tm_interval++;
|
|
} else {
|
|
if (!p_bsrm_glb->mr_addr_pend) {
|
|
p_bsrm_glb->mr_addr_pend = 1;
|
|
}
|
|
p_bsrm_glb->mr_tm_interval = 0;
|
|
iot_bsrm_cmd_guard(IOT_BSRM_MR_TIMER_HANDLE_PERIOD);
|
|
iot_bsrm_printf("bsrm start request address\n");
|
|
}
|
|
goto out;
|
|
}
|
|
if (p_bsrm_glb->sync_tm_done) {
|
|
interval_tm = IOT_BSRM_AUTO_CORRECT_TM_INTERVAL;
|
|
}
|
|
if (p_bsrm_glb->mr_tm_interval < interval_tm) {
|
|
p_bsrm_glb->mr_tm_interval++;
|
|
} else {
|
|
iot_bsrm_set_correct_tm(0);
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_bsrm_handle_timer_msg(iot_bsrm_msg_t *msg)
|
|
{
|
|
switch (msg->task_msg.id) {
|
|
case IOT_BSRM_MSG_ID_TIMER_PERIOD:
|
|
{
|
|
iot_bsrm_branch_info_timeout_handle();
|
|
iot_bsrm_upgrade_windows();
|
|
iot_bsrm_session_mode_main_check();
|
|
iot_bsrm_check_timeout_handle();
|
|
iot_bsrm_check_timeout_event();
|
|
iot_bsrm_br_rec_frag_ctrl_ageing();
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_ID_TIMER_CHECK_MR:
|
|
{
|
|
iot_bsrm_mr_timeout();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_branch_recv_init(void)
|
|
{
|
|
iot_bsrm_nv_param_t *param = (iot_bsrm_nv_param_t *)iot_bsrm_nv_get_section(
|
|
iot_bsrm_nv_id_param);
|
|
iot_bsrm_br_param_t *br_param = ¶m->br_param;
|
|
hw_topo_rcv_cfg_t cfg = { 0 };
|
|
static const uint8_t id_code_def[] = { 0xAA, 0xE9 };
|
|
if (!br_param->fc) {
|
|
br_param->fc = IOT_BSRM_BRANCH_LOAD_FREQ_DEF;
|
|
br_param->pulse_high_dur = 400;
|
|
br_param->pulse_low_dur = 800;
|
|
br_param->chara_bit_dur = 600;
|
|
br_param->id_code_len = sizeof(id_code_def);
|
|
os_mem_cpy(br_param->id_code, id_code_def, sizeof(id_code_def));
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_param);
|
|
}
|
|
iot_bsrm_printf("%s fc %lu, bit_dur = %lu\n", __FUNCTION__, br_param->fc,
|
|
br_param->chara_bit_dur);
|
|
iot_bsrm_data_print("code", br_param->id_code, br_param->id_code_len);
|
|
cfg.fc = br_param->fc;
|
|
cfg.fc_valid = 1;
|
|
cfg.chara_bit_dur = br_param->chara_bit_dur;
|
|
cfg.dur_valid = 1;
|
|
cfg.data_len = sizeof(id_code_def);
|
|
os_mem_cpy(cfg.data, id_code_def, cfg.data_len);
|
|
cfg.phase = IOT_PLC_PHASE_ALL;
|
|
iot_plc_hw_topo_rcv_cfg(&cfg);
|
|
}
|
|
|
|
static void iot_bsrm_branch_info_handle(iot_pkt_t *pkt)
|
|
{
|
|
uint32_t ts;
|
|
iot_time_tm_t tm;
|
|
uint8_t update = 0, *data, i, id_code_len;
|
|
float rssi1, rssi2;
|
|
hw_tsfm_rx_info_t *rx_info;
|
|
iot_bsrm_branch_info_entry_t *rec_buf;
|
|
uint8_t err_bit_mask, err_bit_cnt = 0;
|
|
iot_bsrm_nv_param_t *nv_param = (iot_bsrm_nv_param_t *)
|
|
iot_bsrm_nv_get_section(iot_bsrm_nv_id_param);
|
|
iot_bsrm_br_param_t *br_param = &nv_param->br_param;
|
|
rec_buf = &p_bsrm_glb->br_rec_buf;
|
|
data = iot_pkt_data(pkt);
|
|
rx_info = (hw_tsfm_rx_info_t *)data;
|
|
data += sizeof(*rx_info);
|
|
id_code_len = (uint8_t)(iot_pkt_data_len(pkt) - sizeof(*rx_info));
|
|
if (id_code_len != br_param->id_code_len) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < id_code_len; i++) {
|
|
err_bit_mask = data[i] ^ br_param->id_code[i];
|
|
err_bit_cnt += iot_bitops_cbs(err_bit_mask);
|
|
}
|
|
if (err_bit_cnt > 1) {
|
|
goto out;
|
|
}
|
|
if (!p_bsrm_glb->br_rec_cd) {
|
|
p_bsrm_glb->br_rec_cd = IOT_BSRM_BR_REC_CD;
|
|
update = 1;
|
|
} else {
|
|
rssi1 = (float)(rx_info->sub_sig_info[0].energy * 0.001);
|
|
rssi2 = (float)(rx_info->sub_sig_info[1].energy * 0.001);
|
|
if ((rssi1 + rssi2) >
|
|
(rec_buf->signal1_rssi + rec_buf->signal2_rssi)) {
|
|
update = 1;
|
|
}
|
|
}
|
|
if (update) {
|
|
iot_rtc_get(&tm);
|
|
ts = iot_bsrm_rtctime_to_time(&tm);
|
|
rec_buf->base_rssi = 0;
|
|
rec_buf->is_vaild = 1;
|
|
rec_buf->phase = rx_info->phase;
|
|
rec_buf->reserved1 = 0;
|
|
rec_buf->ts = ts;
|
|
rec_buf->signal1_rssi = (float)(rx_info->sub_sig_info[0].energy
|
|
* 0.001);
|
|
rec_buf->signal2_rssi = (float)(rx_info->sub_sig_info[1].energy
|
|
* 0.001);
|
|
rec_buf->noise = (float)(rx_info->noise * 0.001);
|
|
if (rec_buf->noise < 0.002) {
|
|
rec_buf->noise = 0.002;
|
|
}
|
|
rec_buf->id_code_len = id_code_len;
|
|
os_mem_cpy(rec_buf->id_code, br_param->id_code, id_code_len);
|
|
os_mem_set(rec_buf->reserved2, 0 ,sizeof(rec_buf->reserved2));
|
|
iot_printf("br info rx ts: %lu-%lu-%lu %lu:%lu:%lu, "
|
|
"phase:%lu, rssi1:%lu, rssi2:%lu, noise:%lu\n",
|
|
tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
|
|
rec_buf->phase, (uint32_t)(rec_buf->signal1_rssi * 1000.0),
|
|
(uint32_t)(rec_buf->signal2_rssi * 1000.0),
|
|
(uint32_t)(rec_buf->noise * 1000.0));
|
|
}
|
|
out:
|
|
iot_pkt_free(pkt);
|
|
return;
|
|
}
|
|
|
|
static void iot_bsrm_handle_internal_msg(iot_bsrm_msg_t *msg)
|
|
{
|
|
iot_pkt_t *pkt;
|
|
iot_bsrm_nv_info_t *nv_info;
|
|
|
|
switch (msg->task_msg.id) {
|
|
case IOT_BSRM_MSG_ID_INTERNAL_HW_TSFM:
|
|
{
|
|
pkt = (iot_pkt_t *)msg->data;
|
|
if (iot_rtc_data_is_revised()) {
|
|
iot_bsrm_branch_info_handle(pkt);
|
|
} else {
|
|
iot_bsrm_printf("%s drop tsfm data, sync tm not done\n",
|
|
__FUNCTION__);
|
|
iot_pkt_free(pkt);
|
|
}
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_ID_INTERNAL_EVENT_INTERRUPT:
|
|
{
|
|
p_bsrm_glb->check_crtl.event.count++;
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_ID_INTERNAL_BR_REC_CLEAR:
|
|
{
|
|
iot_bsrm_rec_info_clear();
|
|
iot_bsrm_rec_evt_clear();
|
|
nv_info = (iot_bsrm_nv_info_t *)iot_bsrm_nv_get_section(
|
|
iot_bsrm_nv_id_info);
|
|
nv_info->evt_occur_cnt = 0;
|
|
iot_bsrm_nv_update_section(iot_bsrm_nv_id_info);
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_config_uart(iot_uart_h uart_h,
|
|
uint32_t baud, uint8_t parity, uint8_t data, uint8_t stop,
|
|
iot_frame_fmt *fmt, uint32_t thrd)
|
|
{
|
|
IOT_ASSERT(uart_h);
|
|
iot_uart_set_config(uart_h, baud, parity, data, stop);
|
|
if (fmt) {
|
|
iot_uart_set_frame(uart_h, fmt);
|
|
}
|
|
iot_uart_set_threshold(uart_h, UART_THR_RXTIMEOUT, thrd);
|
|
iot_bsrm_printf("%s buad %lu, parity %lu\n", __FUNCTION__, baud, parity);
|
|
}
|
|
|
|
static void iot_bsrm_uart_config_ext(iot_sg_ext_uart_t *cfg)
|
|
{
|
|
iot_bsrm_printf("%s baudrate: %d, parity: %d, data: %d, stop: %d \n",
|
|
__FUNCTION__, cfg->baudrate, cfg->parity, cfg->data, cfg->stop);
|
|
iot_bsrm_config_uart(p_bsrm_glb->handle, cfg->baudrate, cfg->parity,
|
|
cfg->data, cfg->stop, cfg->fmt_valid ? &(cfg->fmt) : NULL,
|
|
cfg->thd_rx_tm);
|
|
}
|
|
|
|
static void iot_bsrm_handle_sg_app_msg(iot_bsrm_msg_t *sg_msg)
|
|
{
|
|
|
|
iot_pkt_t *pkt = (iot_pkt_t *)sg_msg->data;
|
|
iot_sg_ext_header_t *hdr;
|
|
iot_bsrm_br_param_t br_param;
|
|
iot_sg_ext_cus_topo_rcv_cfg_t *cfg;
|
|
iot_sg_ext_dev_info_t *dev_info;
|
|
|
|
hdr = (iot_sg_ext_header_t *)iot_pkt_data(pkt);
|
|
|
|
switch (hdr->mid) {
|
|
case IOT_SG_EXT_MID_UART_DATA_FROM_SG:
|
|
{
|
|
iot_pkt_set_data(pkt, hdr->data);
|
|
iot_bsrm_data_print("sg app to bsrm: ", iot_pkt_data(pkt),
|
|
iot_pkt_data_len(pkt));
|
|
iot_bsrm_sg_data_handler(pkt);
|
|
break;
|
|
}
|
|
case IOT_SG_EXT_MID_COMMAND:
|
|
{
|
|
switch (hdr->arg) {
|
|
case IOT_SG_EXT_SID_UART_CFG:
|
|
{
|
|
iot_bsrm_uart_config_ext((iot_sg_ext_uart_t *)hdr->data);
|
|
break;
|
|
}
|
|
case IOT_SG_EXT_SID_TOPO_RCV_CFG:
|
|
{
|
|
cfg = (iot_sg_ext_cus_topo_rcv_cfg_t*)hdr->data;
|
|
br_param.fc = cfg->fc;
|
|
br_param.chara_bit_dur = cfg->chara_bit_dur;
|
|
br_param.pulse_high_dur = cfg->pulse_high_dur;
|
|
br_param.pulse_low_dur = cfg->pulse_low_dur;
|
|
os_mem_cpy(br_param.id_code, cfg->fr_code, cfg->fr_code_len);
|
|
br_param.id_code_len = cfg->fr_code_len;
|
|
iot_bsrm_set_br_recv_param(&br_param);
|
|
break;
|
|
}
|
|
case IOT_SG_EXT_SID_DEV_INFO_SYNC:
|
|
{
|
|
dev_info = (iot_sg_ext_dev_info_t*)hdr->data;
|
|
iot_bsrm_check_renew_addr(dev_info->addr);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
default:
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_msg_exe_func(iot_task_h task_h, iot_task_msg_t *msg)
|
|
{
|
|
(void)task_h;
|
|
iot_bsrm_msg_t *bsrm_msg = (iot_bsrm_msg_t *)msg;
|
|
|
|
switch (bsrm_msg->task_msg.type) {
|
|
case IOT_BSRM_MSG_TYPE_UART:
|
|
{
|
|
iot_bsrm_handle_uart_msg(bsrm_msg);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_TYPE_TIMER:
|
|
{
|
|
iot_bsrm_handle_timer_msg(bsrm_msg);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_TYPE_INTERNAL:
|
|
{
|
|
iot_bsrm_handle_internal_msg(bsrm_msg);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_TYPE_SG_APP:
|
|
{
|
|
iot_bsrm_handle_sg_app_msg(bsrm_msg);
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
iot_task_free_msg(task_h, &bsrm_msg->task_msg);
|
|
}
|
|
|
|
static void iot_bsrm_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *msg)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_bsrm_msg_t *bsrm_msg = (iot_bsrm_msg_t *)msg;
|
|
|
|
switch (bsrm_msg->task_msg.type) {
|
|
case IOT_BSRM_MSG_TYPE_UART:
|
|
{
|
|
pkt = (iot_pkt_t *)bsrm_msg->data;
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_TYPE_TIMER:
|
|
{
|
|
break;
|
|
}
|
|
case IOT_BSRM_MSG_TYPE_INTERNAL:
|
|
{
|
|
pkt = (iot_pkt_t *)bsrm_msg->data;
|
|
iot_pkt_free(pkt);
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
iot_task_free_msg(task_h, &bsrm_msg->task_msg);
|
|
}
|
|
|
|
static void iot_bsrm_period_timer_func(timer_id_t timer_id, void *arg)
|
|
{
|
|
(void)timer_id;
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_TIMER,
|
|
IOT_BSRM_MSG_ID_TIMER_PERIOD, IOT_BSRM_MSG_QUEUE_LP, arg, 0);
|
|
}
|
|
|
|
uint32_t iot_bsrm_rtctime_to_time(iot_time_tm_t *tm)
|
|
{
|
|
int64_t diff;
|
|
iot_time_tm_t tm_base;
|
|
tm_base.tm_year = 1970;
|
|
tm_base.tm_mon = 1;
|
|
tm_base.tm_mday = 1;
|
|
tm_base.tm_hour = 0;
|
|
tm_base.tm_min = 0;
|
|
tm_base.tm_sec = 0;
|
|
diff = iot_rtc_delta_calc(&tm_base, tm);
|
|
IOT_ASSERT(diff >= 0);
|
|
return (uint32_t)diff;
|
|
}
|
|
|
|
void iot_bsrm_time_to_rtctime(uint32_t time, iot_time_tm_t *tm)
|
|
{
|
|
iot_time_tm_t tm_base;
|
|
tm_base.tm_year = 1970;
|
|
tm_base.tm_mon = 1;
|
|
tm_base.tm_mday = 1;
|
|
tm_base.tm_hour = 0;
|
|
tm_base.tm_min = 0;
|
|
tm_base.tm_sec = 0;
|
|
iot_rtc_delta_add((int64_t)time, &tm_base);
|
|
*tm = tm_base;
|
|
}
|
|
|
|
/* this callback function receives the hw tsfm info from PLC LIB */
|
|
static void iot_bsrm_hw_tsfm_plc_recv(
|
|
uint8_t data_type, uint8_t *data, uint8_t len,
|
|
hw_tsfm_rx_info_t *rx_info)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *ds;
|
|
switch (data_type) {
|
|
case PROTO_HW_TSFM_ID_TOPO_RAW:
|
|
{
|
|
pkt = iot_pkt_alloc(sizeof(*rx_info) + len, IOT_BSRM_MID);
|
|
if (!pkt) {
|
|
iot_printf("%s pkt alloc failed\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
ds = iot_pkt_put(pkt, sizeof(*rx_info) + len);
|
|
os_mem_cpy(ds, rx_info, sizeof(*rx_info));
|
|
ds += sizeof(*rx_info);
|
|
os_mem_cpy(ds, data, len);
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_INTERNAL,
|
|
IOT_BSRM_MSG_ID_INTERNAL_HW_TSFM, IOT_BSRM_MSG_QUEUE_LP,
|
|
pkt, 0);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void iot_bsrm_uart_setting(iot_uart_h handle)
|
|
{
|
|
iot_frame_fmt fmt = {0};
|
|
/* set 485 config */
|
|
fmt.preamble_code[0] = PROTO_645_START_CHAR;
|
|
fmt.preamble_codelen = 1;
|
|
fmt.datalen_offset = 8;
|
|
fmt.datalen_size = 1;
|
|
fmt.backcode_offset = 1;
|
|
fmt.backcode_len = 1;
|
|
fmt.datalen_fix = 0;
|
|
fmt.backcode[0] = PROTO_645_END_CHAR;
|
|
fmt.frame_timeout = 30;
|
|
fmt.timeout_mode = TIMEOUT_PERDATA;
|
|
fmt.check_frame_func = proto_645_check_frame_handler;
|
|
iot_bsrm_config_uart(handle, 9600, IOT_UART_PARITY_EVEN, 8, 1, &fmt, 3);
|
|
}
|
|
|
|
void iot_bsrm_ipc_recv(void *param, iot_ipc_addr_t *addr, iot_pkt_t *pkt)
|
|
{
|
|
(void)param;
|
|
iot_bsrm_post_msg(IOT_BSRM_MSG_TYPE_SG_APP, IOT_BSRM_MSG_ID_SG_APP,
|
|
IOT_BSRM_MSG_QUEUE_LP, pkt, (addr->c_id << 4) + addr->f_id);
|
|
}
|
|
|
|
uint32_t iot_bsrm_init(void)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (p_bsrm_glb) {
|
|
goto out;
|
|
}
|
|
p_bsrm_glb = os_mem_malloc(IOT_BSRM_MID, sizeof(*p_bsrm_glb));
|
|
if (p_bsrm_glb == NULL) {
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
/* init bsrm glb param */
|
|
os_mem_set(p_bsrm_glb, 0, sizeof(*p_bsrm_glb));
|
|
|
|
p_bsrm_glb->evt_trig_cd = 0;
|
|
p_bsrm_glb->evt_buf = os_mem_malloc(IOT_BSRM_MID,
|
|
sizeof(iot_bsrm_branch_evt_rec_entry_t));
|
|
if (p_bsrm_glb->evt_buf == NULL) {
|
|
ret = ERR_NOMEM;
|
|
goto err_task;
|
|
}
|
|
/* create extend bsrm task */
|
|
p_bsrm_glb->task_cfg.stack_size = IOT_BSRM_TASK_STACK_SZIE;
|
|
p_bsrm_glb->task_cfg.task_prio = IOT_BSRM_TASK_PRIO;
|
|
p_bsrm_glb->task_cfg.msg_size = sizeof(iot_bsrm_msg_t);
|
|
p_bsrm_glb->task_cfg.msg_cnt = IOT_BSRM_MSG_POOL_SIZE;
|
|
p_bsrm_glb->task_cfg.queue_cnt = IOT_BSRM_MSG_QUEUE_MAX_PRIO;
|
|
p_bsrm_glb->task_cfg.queue_cfg[IOT_BSRM_MSG_QUEUE_HP].quota = 0;
|
|
p_bsrm_glb->task_cfg.queue_cfg[IOT_BSRM_MSG_QUEUE_LP].quota = 0;
|
|
p_bsrm_glb->task_cfg.msg_exe_func = iot_bsrm_msg_exe_func;
|
|
p_bsrm_glb->task_cfg.msg_cancel_func = iot_bsrm_msg_cancel_func;
|
|
p_bsrm_glb->task_h = iot_task_create(IOT_BSRM_MID,
|
|
&p_bsrm_glb->task_cfg);
|
|
if (p_bsrm_glb->task_h == NULL) {
|
|
ret = ERR_NOMEM;
|
|
goto err_task;
|
|
}
|
|
|
|
p_bsrm_glb->periodic_timer = os_create_timer(IOT_BSRM_MID, true,
|
|
iot_bsrm_period_timer_func, NULL);
|
|
if (p_bsrm_glb->periodic_timer == 0) {
|
|
ret = ERR_NOMEM;
|
|
goto err_periodic_timer;
|
|
}
|
|
|
|
p_bsrm_glb->mr_timer = os_create_timer(IOT_BSRM_MID, false,
|
|
iot_bsrm_mr_timer_func, NULL);
|
|
if (p_bsrm_glb->mr_timer == 0) {
|
|
ret = ERR_NOMEM;
|
|
goto err_mr_timer;
|
|
}
|
|
|
|
/* open extend bsrm interface (UART) for bsrm app */
|
|
p_bsrm_glb->handle = iot_uart_open(
|
|
iot_board_get_uart(UART_METER_PORT), iot_bsrm_uart_recv,
|
|
IOT_BSRM_UART_BUF_SIZE, NULL);
|
|
if (p_bsrm_glb->handle == NULL) {
|
|
ret = ERR_BUSY;
|
|
goto err_uart_fail;
|
|
}
|
|
iot_bsrm_uart_setting(p_bsrm_glb->handle);
|
|
|
|
ret = iot_bsrm_flash_init();
|
|
if (ret) {
|
|
ret = ERR_BUSY;
|
|
goto flash_init_err;
|
|
}
|
|
|
|
ret = iot_plc_hw_tsfm_register_listener(iot_bsrm_hw_tsfm_plc_recv);
|
|
if (ret) {
|
|
ret = ERR_NOSUPP;
|
|
goto err_pm_init;
|
|
}
|
|
|
|
ret = iot_bsrm_nv_init();
|
|
if (ret) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOSUPP;
|
|
goto err_nv_init;
|
|
}
|
|
ret = iot_bsrm_rec_init();
|
|
if (ret) {
|
|
ret = ERR_NOMEM;
|
|
goto err_rec_init;
|
|
}
|
|
/* load nonvolatile information */
|
|
iot_bsrm_load_nv();
|
|
|
|
iot_bsrm_branch_recv_init();
|
|
/* init psrm upgrade info*/
|
|
if (iot_bsrm_upgrade_init() != ERR_OK) {
|
|
ret = ERR_NOMEM;
|
|
goto err_upgrade;
|
|
}
|
|
|
|
/* upgrade success, set pm upgrade flag */
|
|
if (IOT_PLC_UPGRADE_SWITCH_SUCC == iot_upgrade_get_switch_part_info()) {
|
|
iot_bsrm_set_pm_upgrade_guard_code(IOT_BSRM_PM_UPGRADE_GUARD_CODE);
|
|
}
|
|
|
|
/* init psrm pm upgrade info */
|
|
if(iot_bsrm_pm_upgrade_init() != ERR_OK) {
|
|
ret = ERR_NOMEM;
|
|
goto err_pm_upgrade;
|
|
}
|
|
|
|
#if (IOT_BSRM_MODE == IOT_BSRM_MODE_DEFAULT)
|
|
p_bsrm_glb->session_mode = IOT_BSRM_SESSION_MODE_DEFAULT;
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_DONE;
|
|
#else
|
|
iot_ipc_client_t client;
|
|
/* register IPC for iot_bsrm */
|
|
client.addr.f_id = IOT_IPC_FID_SG_EXT_SDK;
|
|
client.addr.c_id = IOT_IPC_CID_SG_EXT_CUS_APP;
|
|
client.recv = iot_bsrm_ipc_recv;
|
|
client.param = NULL;
|
|
p_bsrm_glb->ipc_h = iot_ipc_register_client(&client);
|
|
if (p_bsrm_glb->ipc_h == NULL) {
|
|
ret = ERR_BUSY;
|
|
goto err_ipc;
|
|
}
|
|
p_bsrm_glb->session_mode = IOT_BSRM_SESSION_MODE_TRANS;
|
|
if (false == iot_board_support_topo_rx()) {
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_DONE;
|
|
} else {
|
|
p_bsrm_glb->cur_coeff_sync_sts = IOT_BSRM_SYNC_CUR_COEFF_IDLE;
|
|
}
|
|
p_bsrm_glb->coeff_sync_cnt = 0;
|
|
#endif
|
|
p_bsrm_glb->check_crtl.event.status = IOT_BSRM_CHECK_EVENT_STATUS_IDLE;
|
|
|
|
os_start_timer(p_bsrm_glb->periodic_timer,
|
|
IOT_BSRM_PERIOND_TIMER_INTERVAL);
|
|
iot_bsrm_printf("%s init successful\n", __FUNCTION__);
|
|
goto out;
|
|
|
|
#if (IOT_BSRM_MODE == IOT_BSRM_MODE_CUS_APP)
|
|
err_ipc:
|
|
iot_bsrm_pm_upgrade_deinit();
|
|
#endif
|
|
err_pm_upgrade:
|
|
iot_bsrm_upgrade_deinit();
|
|
err_upgrade:
|
|
err_rec_init:
|
|
err_nv_init:
|
|
err_pm_init:
|
|
flash_init_err:
|
|
iot_uart_close(p_bsrm_glb->handle);
|
|
p_bsrm_glb->handle = NULL;
|
|
err_uart_fail:
|
|
os_delete_timer(p_bsrm_glb->mr_timer);
|
|
p_bsrm_glb->mr_timer = 0;
|
|
err_mr_timer:
|
|
os_delete_timer(p_bsrm_glb->periodic_timer);
|
|
p_bsrm_glb->periodic_timer = 0;
|
|
err_periodic_timer:
|
|
iot_task_delete(p_bsrm_glb->task_h);
|
|
p_bsrm_glb->task_h = NULL;
|
|
err_task:
|
|
os_mem_free(p_bsrm_glb);
|
|
p_bsrm_glb = NULL;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* app_bsrm_entry: entry for bsrm app
|
|
*/
|
|
uint32_t app_bsrm_entry()
|
|
{
|
|
uint32_t ret = ERR_PENDING;
|
|
|
|
if (iot_bsrm_init()) {
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif /* IOT_BSRM_MODE */
|