Files
kunlun/app/smart_grid/sta/iot_sg_sta_ext_js.c
2024-09-28 14:24:04 +08:00

11209 lines
376 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.
****************************************************************************/
/* iot common header files */
#include "iot_io_api.h"
#include "iot_bitmap_api.h"
/* smart grid internal header files */
#include "iot_sg_fr.h"
#include "iot_sg.h"
#include "proto_69845.h"
#include "iot_sg_sta_ext.h"
#include "iot_sg_sta_ext_comm.h"
#include "iot_sg_sta_flash.h"
#include "iot_sg_sta_cfg_flash.h"
#if (IOT_SMART_GRID_EXT_JS_FUNC_ENABLE)
/* define current report clct data cmd */
#define IOT_SG_STA_EXT_JS_RPT_CMD_START (0)
#define IOT_SG_STA_EXT_JS_RPT_CMD_NEXT (1)
#define IOT_SG_STA_EXT_JS_RPT_CMD_STOP (2)
/* define data collection function. */
#define IOT_SG_STA_EXT_DC_FUNC_INVALID (0)
#define IOT_SG_STA_EXT_DC_FUNC_MF (1)
#define IOT_SG_STA_EXT_DC_FUNC_DF (2)
#define IOT_SG_STA_EXT_DC_FUNC_15M_CUR (3)
#define IOT_SG_STA_EXT_DC_FUNC_1M_CUR (4)
/* define data collection state */
#define IOT_SG_STA_EXT_DC_STATE_IDLE (0)
#define IOT_SG_STA_EXT_DC_STATE_SEND (1)
#define IOT_SG_STA_EXT_DC_STATE_WAIT (2)
/* define data collection latest report index update method */
#define IOT_SG_STA_EXT_DC_LAST_IDX_CLEAR (0)
#define IOT_SG_STA_EXT_DC_LAST_IDX_REDUCE (1)
/* define instant data collection time and current time min interval, unit 1s */
#define IOT_SG_STA_EXT_DC_INSTANT_CUR_MIN_INTER (60 * 60)
/* define 69845 meter data collection single frame max oi number */
#define IOT_SG_STA_EXT_DC_FRAME_MAX_OI_NUM (6)
/* define extend function 09 meter extend di type */
/* 09 meter extend di invalid type */
#define IOT_SG_STA_EXT_09_NODE_DI_TYPE_INVAILD (0)
/* 09 meter day forzen data di type */
#define IOT_SG_STA_EXT_09_NODE_DI_TYPE_DF (1)
/* 09 meter impedance anomaly di type */
#define IOT_SG_STA_EXT_09_NODE_DI_TYPE_IA (2)
/* 09 meter hour forzen data di type */
#define IOT_SG_STA_EXT_09_NODE_DI_TYPE_HF (3)
/* define max length of report data, for jangsu */
#define IOT_SG_STA_EXT_RPT_MAX_LEN 470
/* define cache buffer of report data, for jangsu */
#define SIG_CACHE_BUF max(sizeof(proto_645_07_pf_t), \
max(sizeof(proto_645_07_p_t), max(sizeof(proto_645_v_t), \
sizeof(proto_645_07_a_t))))
/* define meter data unit element number */
#define IOT_SG_STA_EXT_ENERGY_ELE_NUM (5)
#define IOT_SG_STA_EXT_3P_V_ELE_NUM (3)
#define IOT_SG_STA_EXT_3P_I_ELE_NUM (3)
#define IOT_SG_STA_EXT_3P_P_ELE_NUM (4)
#define IOT_SG_STA_EXT_SIG_MORE_ELE_NUM (2)
#define IOT_SG_STA_EXT_SIG_OAD_ELE_NUM (1)
/* define save meter type for jangsu protocol */
/* invalid meter type */
#define IOT_SG_STA_EXT_METER_TYPE_INVALID (0)
/* type of single phase meter */
#define IOT_SG_STA_EXT_METER_TYPE_SINGLE (1)
/* type of three phase meter */
#define IOT_SG_STA_EXT_METER_TYPE_3P (2)
/* type of all meter */
#define IOT_SG_STA_EXT_METER_TYPE_ALL (3)
static const uint32_t data_clct_07_rs_di_table[
IOT_SG_STA_07_RUN_STATE_WORD_DI_CNT] = {
PROTO_645_2007_RUN_STATE_WORD_1,
PROTO_645_2007_RUN_STATE_WORD_2,
PROTO_645_2007_RUN_STATE_WORD_3,
PROTO_645_2007_RUN_STATE_WORD_4,
PROTO_645_2007_RUN_STATE_WORD_5,
PROTO_645_2007_RUN_STATE_WORD_6,
PROTO_645_2007_RUN_STATE_WORD_7,
};
static const uint32_t data_clct_97_rs_di_table[
IOT_SG_STA_97_RUN_STATE_WORD_DI_CNT] = {
PROTO_645_1997_DI_RS1,
PROTO_645_1997_DI_RS2,
};
static const uint32_t data_clct_07_time_di_table[
IOT_SG_STA_07_READ_TIME_DI_CNT] = {
PROTO_645_2007_DI_TIME,
PROTO_645_2007_DI_TIME_YMD,
PROTO_645_2007_DI_TIME_HMS,
};
static const uint32_t data_clct_97_time_di_table[
IOT_SG_STA_97_READ_TIME_DI_CNT] = {
PROTO_645_1997_DI_TIME_YMD,
PROTO_645_1997_DI_TIME_HMS,
};
static const uint32_t data_clct_di_table[IOT_SG_STA_EXT_DI_TAB_PRO_MAX_CNT][
IOT_SG_STA_METER_TASK_DI_MAX_CNT] = {
{
PROTO_645_2007_RUN_STATE_WORD_ALL,
PROTO_645_2007_DI_TIME,
PROTO_645_INVALID_DI,
PROTO_645_2007_DI_V_ALL,
PROTO_645_2007_DI_I_ALL,
PROTO_645_2007_DI_I_N,
PROTO_645_2007_DI_P_ALL,
PROTO_645_2007_DI_Q_ALL,
PROTO_645_2007_DI_PF_ALL,
PROTO_645_2007_DI_EPT_POS_ALL,
PROTO_645_2007_DI_EPT_NEG_ALL,
PROTO_645_2007_DI_EQT_POS_ALL,
PROTO_645_2007_DI_EQT_NEG_ALL,
PROTO_645_2007_DI_EQT_QRT1_ALL,
PROTO_645_2007_DI_EQT_QRT2_ALL,
PROTO_645_2007_DI_EQT_QRT3_ALL,
PROTO_645_2007_DI_EQT_QRT4_ALL,
PROTO_645_2007_DI_EQT_QRT1_ALL,
PROTO_645_2007_DI_EQT_QRT2_ALL,
PROTO_645_2007_DI_EQT_QRT3_ALL,
PROTO_645_2007_DI_EQT_QRT4_ALL,
PROTO_645_2007_DI_EPT_POS_DEMAND,
PROTO_645_2007_DI_EPT_NEG_DEMAND,
PROTO_645_2007_DI_COM_RE1_DEM_TIME_ALL,
PROTO_645_2007_DI_COM_RE2_DEM_TIME_ALL,
PROTO_645_2007_DI_EPT_POS_ALL,
PROTO_645_2007_DI_EPT_NEG_ALL,
},
{
PROTO_645_2007_RUN_STATE_WORD_ALL,
PROTO_645_2007_DI_TIME,
PROTO_645_2007_DI_DF_YMDHMS_LAST1,
PROTO_645_2007_DI_V_ALL,
PROTO_645_2007_DI_I_ALL,
PROTO_645_2007_DI_I_N,
PROTO_645_2007_DI_DF_VARIABLE_LAST1,
PROTO_645_2007_DI_DF_VARIABLE_LAST1,
PROTO_645_2007_DI_PF_ALL,
PROTO_645_2007_DI_DF_EP_POS_LAST1,
PROTO_645_2007_DI_DF_EP_NEG_LAST1,
PROTO_645_2007_DI_DF_EQ_POS_LAST1,
PROTO_645_2007_DI_DF_EQ_NEG_LAST1,
PROTO_645_2007_DI_DF_RE_1ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_2ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_3ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_4ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_1ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_2ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_3ST_POWER_LAST1,
PROTO_645_2007_DI_DF_RE_4ST_POWER_LAST1,
PROTO_645_2007_DI_DF_POS_ACT_DEM_TIME_LAST1,
PROTO_645_2007_DI_DF_NEG_ACT_DEM_TIME_LAST1,
PROTO_645_2007_DI_COM_RE1_DEM_TIME_ALL,
PROTO_645_2007_DI_COM_RE2_DEM_TIME_ALL,
PROTO_645_2007_DI_DF_EP_POS_LAST1,
PROTO_645_2007_DI_DF_EP_NEG_LAST1,
},
{
PROTO_645_1997_DI_RS1,
PROTO_645_1997_DI_TIME_YMD,
PROTO_645_INVALID_DI,
PROTO_645_1997_DI_V_ALL,
PROTO_645_1997_DI_I_ALL,
PROTO_645_INVALID_DI,
PROTO_645_1997_DI_P_ALL,
PROTO_645_1997_DI_Q_ALL,
PROTO_645_1997_DI_PF_ALL,
PROTO_645_1997_DI_EPT_POS_ALL,
PROTO_645_1997_DI_EPT_NEG_ALL,
PROTO_645_1997_DI_EQT_POS_ALL,
PROTO_645_1997_DI_EQT_NEG_ALL,
PROTO_645_1997_DI_EQT_QRT1_ALL,
PROTO_645_1997_DI_EQT_QRT2_ALL,
PROTO_645_1997_DI_EQT_QRT3_ALL,
PROTO_645_1997_DI_EQT_QRT4_ALL,
PROTO_645_1997_DI_EQT_QRT1_ALL,
PROTO_645_1997_DI_EQT_QRT2_ALL,
PROTO_645_1997_DI_EQT_QRT3_ALL,
PROTO_645_1997_DI_EQT_QRT4_ALL,
PROTO_645_INVALID_DI,
PROTO_645_INVALID_DI,
PROTO_645_INVALID_DI,
PROTO_645_INVALID_DI,
PROTO_645_1997_DI_EPT_POS_ALL,
PROTO_645_1997_DI_EPT_NEG_ALL,
},
{
PROTO_69845_APP_OAD_RUN_WORD,
PROTO_69845_APP_OAD_TIME,
PROTO_69845_APP_OAD_FROZEN_T,
PROTO_69845_APP_OAD_VOLTAGE,
PROTO_69845_APP_OAD_CURRENT,
PROTO_69845_APP_OAD_GND_CURRENT,
PROTO_69845_APP_OAD_P,
PROTO_69845_APP_OAD_Q,
PROTO_69845_APP_OAD_PF,
PROTO_69845_APP_OAD_EPT_POS,
PROTO_69845_APP_OAD_EPT_NEG,
PROTO_69845_APP_OAD_EQT_POS,
PROTO_69845_APP_OAD_EQT_NEG,
PROTO_69845_APP_OAD_EQT_QRT1_SUM,
PROTO_69845_APP_OAD_EQT_QRT2_SUM,
PROTO_69845_APP_OAD_EQT_QRT3_SUM,
PROTO_69845_APP_OAD_EQT_QRT4_SUM,
PROTO_69845_APP_OAD_EQT_QRT1,
PROTO_69845_APP_OAD_EQT_QRT2,
PROTO_69845_APP_OAD_EQT_QRT3,
PROTO_69845_APP_OAD_EQT_QRT4,
PROTO_69845_APP_OAD_EPT_POS_DEMAND,
PROTO_69845_APP_OAD_EPT_NEG_DEMAND,
PROTO_69845_APP_OAD_EQT_POS_DEMAND,
PROTO_69845_APP_OAD_EQT_NEG_DEMAND,
PROTO_69845_APP_OAD_EPT_POS_SIG,
PROTO_69845_APP_OAD_EPT_NEG_SIG,
},
};
static uint32_t iot_sg_sta_ext_data_clct_get_di_bm_def(uint8_t cfg_type)
{
uint32_t bm = 0;
switch (cfg_type) {
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE1);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE2);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME);
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG);
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_POWER_FACTOR);
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_POWER_FACTOR);
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_VOLTAGE);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_CURRENT);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER);
bm |= (1 << IOT_SG_STA_METER_TASK_DI_TIME);
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
{
bm |= (1 << IOT_SG_STA_METER_TASK_DI_RUN_STATE);
break;
}
default:
IOT_ASSERT(0);
}
return bm;
}
void iot_sg_ext_data_clct_reset(void)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
ext_info->data_clct.timeout_cnt = 0;
ext_info->data_clct.repeat_cnt = 0;
ext_info->data_clct.flag_resp = 0;
ext_info->data_clct.mf_done = 0;
ext_info->data_clct.df_done = 0;
ext_info->data_clct.cur_15m_done = 0;
ext_info->data_clct.cur_1m_done = 0;
ext_info->data_clct.cur_state = IOT_SG_STA_EXT_DC_STATE_IDLE;
ext_info->data_clct.config.cfg_is_latest = 0;
ext_info->data_clct.ft_valid = 0;
}
static iot_time_tm_t *iot_sg_ext_data_clct_get_node_tm(
iot_sg_sta_node_desc_t *node, uint8_t func)
{
iot_time_tm_t *tm = NULL;
switch (func) {
case IOT_SG_STA_EXT_DC_FUNC_1M_CUR:
{
tm = &node->ext.data_clct_info.cur_1m_tm;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_15M_CUR:
{
tm = &node->ext.data_clct_info.cur_15m_tm;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_DF:
{
tm = &node->ext.data_clct_info.df_tm;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_MF:
{
tm = &node->ext.data_clct_info.mf_tm;
break;
}
default:
IOT_ASSERT(0);
break;
}
return tm;
}
static iot_time_tm_t iot_sg_ext_get_next_data_clct_ts(iot_time_tm_t *curr_tm,
uint8_t func)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
int64_t delta_time, interval = data_clct->config.exe_inter;
iot_time_tm_t tm, start_tm = { 0 };
start_tm = data_clct->config.start_time;
iot_sg_ext_set_integral_point(&start_tm, interval, 1);
delta_time = iot_rtc_delta_calc(&start_tm, curr_tm);
if (func == IOT_SG_STA_EXT_DC_FUNC_MF) {
if (delta_time > 0) {
tm = *curr_tm;
} else {
tm = start_tm;
goto out;
}
if (tm.tm_mon < 12) {
tm.tm_mon++;
} else {
tm.tm_year++;
tm.tm_mon = 1;
}
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else {
if (delta_time > 0) {
tm = *curr_tm;
} else {
tm = start_tm;
goto out;
}
delta_time %= interval;
delta_time = interval - delta_time;
iot_rtc_delta_add(delta_time, &tm);
}
if (func == IOT_SG_STA_EXT_DC_FUNC_MF ||
func == IOT_SG_STA_EXT_DC_FUNC_DF) {
iot_rtc_delta_add(data_clct->config.delay, &tm);
}
out:
return tm;
}
static uint32_t iot_sg_ext_data_clct_group_di_update(uint8_t di_pro_type,
uint8_t cur_di)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_data_clct_info_t *data_clct = &sta_glb->ext_info.data_clct;
uint32_t di = PROTO_645_INVALID_DI;
if (di_pro_type >= IOT_SG_STA_EXT_DI_TAB_PRO_MAX_CNT ||
cur_di >= IOT_SG_STA_METER_TASK_DI_MAX_CNT) {
goto out;
}
switch (di_pro_type) {
case IOT_SG_STA_EXT_DI_TAB_PRO_645_07:
case IOT_SG_STA_EXT_DI_TAB_PRO_645_07_FROZEN:
{
switch (data_clct_di_table[di_pro_type][cur_di]) {
case PROTO_645_2007_RUN_STATE_WORD_ALL:
{
if (data_clct->group_di_idx >= IOT_SG_STA_07_RUN_STATE_WORD_DI_CNT)
{
goto out;
}
di = data_clct_07_rs_di_table[data_clct->group_di_idx];
break;
}
case PROTO_645_2007_DI_TIME:
{
if (data_clct->group_di_idx >= IOT_SG_STA_07_READ_TIME_DI_CNT) {
goto out;
}
di = data_clct_07_time_di_table[data_clct->group_di_idx];
break;
}
default:
break;
}
break;
}
case IOT_SG_STA_EXT_DI_TAB_PRO_645_97:
{
switch (data_clct_di_table[di_pro_type][cur_di]) {
case PROTO_645_1997_DI_TIME_YMD:
{
if (data_clct->group_di_idx >= IOT_SG_STA_97_READ_TIME_DI_CNT) {
goto out;
}
di = data_clct_97_time_di_table[data_clct->group_di_idx];
break;
}
case PROTO_645_1997_DI_RS1:
{
if (data_clct->group_di_idx >= IOT_SG_STA_97_RUN_STATE_WORD_DI_CNT)
{
goto out;
}
di = data_clct_97_rs_di_table[data_clct->group_di_idx];
break;
}
default:
break;
}
break;
}
default:
break;
}
out:
return di;
}
static uint32_t iot_sg_ext_data_clct_get_di(uint8_t di_pro_type, uint8_t cur_di)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
uint32_t di;
if (ext_info->data_clct.is_group_di) {
di = iot_sg_ext_data_clct_group_di_update(di_pro_type, cur_di);
} else if (di_pro_type >= IOT_SG_STA_EXT_DI_TAB_PRO_MAX_CNT ||
cur_di >= IOT_SG_STA_METER_TASK_DI_MAX_CNT) {
di = PROTO_645_INVALID_DI;
} else {
di = data_clct_di_table[di_pro_type][cur_di];
}
return di;
}
static iot_pkt_t*iot_sg_ext_data_clct_645_msg_build(uint8_t *addr,
uint8_t p_id, uint8_t *invalid_di)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
iot_pkt_t *pkt = NULL;
uint32_t di;
uint8_t di_pro_type;
if (p_id == PROTO_645_2007_ID) {
if (data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_MF ||
data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_DF) {
if (data_clct->ft_valid || data_clct->cur_clct_di ==
IOT_SG_STA_METER_TASK_DI_FROZEN_TIME) {
di_pro_type = IOT_SG_STA_EXT_DI_TAB_PRO_645_07_FROZEN;
} else {
di_pro_type = IOT_SG_STA_EXT_DI_TAB_PRO_645_07;
}
} else {
di_pro_type = IOT_SG_STA_EXT_DI_TAB_PRO_645_07;
}
} else {
di_pro_type = IOT_SG_STA_EXT_DI_TAB_PRO_645_97;
}
di = iot_sg_ext_data_clct_get_di(di_pro_type, data_clct->cur_clct_di);
if (di != PROTO_645_INVALID_DI) {
pkt = proto_645_build_mr_msg(p_id, addr, di);
} else {
*invalid_di = 1;
}
return pkt;
}
static uint8_t iot_sg_ext_data_clct_nomal_di_cnt_get(uint32_t *di_bm)
{
uint32_t di_bm_tmp = *di_bm;
uint8_t di_cnt = 0, i, di, di_idx, max_di_cnt;
/* current di does not exist in di_bm, need to add current di */
di_cnt++;
max_di_cnt = IOT_SG_STA_EXT_DC_FRAME_MAX_OI_NUM - di_cnt;
for (i = 0; i < max_di_cnt; i++) {
di_idx = (uint8_t)iot_bitmap_ffs((uint8_t *)&di_bm_tmp,
sizeof(di_bm_tmp));
if (di_idx) {
di = di_idx - 1;
if (di == IOT_SG_STA_METER_TASK_DI_FROZEN_TIME) {
break;
} else {
di_bm_tmp &= ~(1 << di);
di_cnt++;
}
} else {
break;
}
}
return di_cnt;
}
static iot_pkt_t *iot_sg_ext_data_clct_69845_nomal_msg_build(uint8_t *addr,
uint32_t *di_bm, uint8_t cur_di)
{
uint8_t di_cnt, i, di, di_idx, attribute;
uint32_t get_list_req_size, oad;
iot_pkt_t *pkt = NULL, *get_list_req = NULL;
proto_69845_app_get_list_req_info_t *req = NULL;
server_addr_info_t server = {0};
di_cnt = iot_sg_ext_data_clct_nomal_di_cnt_get(di_bm);
get_list_req_size = sizeof(proto_69845_app_oad_t) * di_cnt + sizeof(*req);
get_list_req = iot_pkt_alloc(get_list_req_size, IOT_SMART_GRID_MID);
if (!get_list_req) {
goto out;
}
req = (proto_69845_app_get_list_req_info_t *)iot_pkt_put(get_list_req,
get_list_req_size);
req->type = PROTO_69845_APP_GET_NORMALLIST;
req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
req->oad_cnt = di_cnt;
/* fill di from current di */
oad = iot_sg_ext_data_clct_get_di(IOT_SG_STA_EXT_DI_TAB_PRO_69845, cur_di);
req->oad[0].oi = (uint16_t)(oad>> 16);
attribute = (oad >> 8) & 0xff;
req->oad[0].attribute_id = attribute & 0x1f;
req->oad[0].attribute_char = attribute >> 5;
req->oad[0].element_index = oad & 0xff;
/* fill di from di_bm */
for (i = 1; i < di_cnt; i++) {
di_idx = (uint8_t)iot_bitmap_ffs((uint8_t *)di_bm, sizeof(*di_bm));
if (di_idx) {
di = di_idx - 1;
(*di_bm) &= ~(1 << di);
oad = iot_sg_ext_data_clct_get_di(IOT_SG_STA_EXT_DI_TAB_PRO_69845,
di);
req->oad[i].oi = (uint16_t)(oad >> 16);
attribute = (oad >> 8) & 0xff;
req->oad[i].attribute_id = attribute & 0x1f;
req->oad[i].attribute_char = attribute >> 5;
req->oad[i].element_index = oad & 0xff;
} else {
break;
}
}
server.len = PROTO_69845_SA_LEN;
server.type = PROTO_69845_SA_TYPE_SIG;
iot_mac_addr_cpy(server.addr, addr);
pkt = proto_69845_build_get_req_msg_with_rn(req, &server);
iot_pkt_free(get_list_req);
out:
return pkt;
}
static iot_pkt_t *iot_sg_ext_data_clct_69845_record_msg_build(uint8_t *addr,
uint32_t *di_bm, uint8_t cur_di)
{
uint8_t di_cnt, i, di, di_idx, *time_tag, csd_len;
uint32_t get_record_size, oad;
server_addr_info_t server = {0};
proto_69845_app_get_req_record_t *req;
proto_69845_app_req_resp_t *apdu;
proto_69845_app_get_req_t *get_req;
proto_69845_app_data_rcsd_t *rcsd;
proto_69845_app_data_rsd_t *rsd;
proto_69845_app_data_rsd_type9_t *type_9;
proto_69845_app_data_csd_t *csd = NULL;
iot_pkt_t *pkt = NULL, *get_req_record = NULL;
csd_len = sizeof(*csd) + sizeof(oad);
if (cur_di == IOT_SG_STA_METER_TASK_DI_FROZEN_TIME) {
di_cnt = 1;
} else {
/* current di does not exist in di_bm, need to add current di */
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t *)di_bm, sizeof(*di_bm)) + 1;
}
if (di_cnt > IOT_SG_STA_EXT_DC_FRAME_MAX_OI_NUM) {
di_cnt = IOT_SG_STA_EXT_DC_FRAME_MAX_OI_NUM;
}
get_record_size = sizeof(*apdu) + sizeof(*get_req) + sizeof(*req) +
sizeof(*rsd) + sizeof(*type_9) + sizeof(*rcsd) + (csd_len * di_cnt)
+ sizeof(*time_tag);
get_req_record = iot_pkt_alloc(get_record_size, IOT_SMART_GRID_MID);
if (!get_req_record) {
goto out;
}
apdu = (proto_69845_app_req_resp_t *)iot_pkt_put(get_req_record,
get_record_size);
apdu->type = PROTO_69845_C_APP_GET_REQ;
get_req = (proto_69845_app_get_req_t *)apdu->data;
get_req->data_type = PROTO_69845_APP_GET_RECORD;
req = (proto_69845_app_get_req_record_t *)get_req->data;
req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
oad = PROTO_69845_APP_OAD_DF;
iot_uint32_to_bytes(oad, (uint8_t *)&req->oad, 1);
rsd = (proto_69845_app_data_rsd_t *)req->rsd_and_rcsd;
rsd->type = PROTO_OI_RSD_TYPE_9;
type_9 = (proto_69845_app_data_rsd_type9_t *)rsd->rsd_data;
type_9->times = 1;
rcsd = (proto_69845_app_data_rcsd_t *)(rsd->rsd_data + sizeof(*type_9));
rcsd->cnt = di_cnt;
/* fill di from current di */
oad = iot_sg_ext_data_clct_get_di(IOT_SG_STA_EXT_DI_TAB_PRO_69845, cur_di);
csd = (proto_69845_app_data_csd_t *)rcsd->csd_list;
csd->type = PROTO_OI_CSD_TYPE_OAD;
iot_uint32_to_bytes(oad, (uint8_t *)&csd->csd_data, 1);
/* fill di from di_bm */
for (i = 1; i < di_cnt; i++) {
di_idx = (uint8_t)iot_bitmap_ffs((uint8_t *)di_bm, sizeof(*di_bm));
if (di_idx) {
di = di_idx - 1;
(*di_bm) &= ~(1 << di);
oad = iot_sg_ext_data_clct_get_di(IOT_SG_STA_EXT_DI_TAB_PRO_69845,
di);
csd = (proto_69845_app_data_csd_t *)(rcsd->csd_list + (csd_len * i));
csd->type = PROTO_OI_CSD_TYPE_OAD;
iot_uint32_to_bytes(oad, (uint8_t *)&csd->csd_data, 1);
} else {
break;
}
}
time_tag = csd->csd_data + csd_len;
*time_tag = 0;
server.len = PROTO_69845_SA_LEN;
server.type = PROTO_69845_SA_TYPE_SIG;
iot_mac_addr_cpy(server.addr, addr);
pkt = proto_69845_build_apdu_data_with_rn_msg((uint8_t *)apdu,
get_record_size, &server);
out:
if (get_req_record) {
iot_pkt_free(get_req_record);
}
return pkt;
}
static iot_pkt_t*iot_sg_ext_data_clct_69845_msg_build(uint8_t *addr)
{
iot_pkt_t *pkt = NULL;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
if (data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_DF ||
data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_MF) {
if (data_clct->ft_valid || data_clct->cur_clct_di ==
IOT_SG_STA_METER_TASK_DI_FROZEN_TIME) {
pkt = iot_sg_ext_data_clct_69845_record_msg_build(addr,
&data_clct->config.di_bitmap, data_clct->cur_clct_di);
} else {
pkt = iot_sg_ext_data_clct_69845_nomal_msg_build(addr,
&data_clct->config.di_bitmap, data_clct->cur_clct_di);
}
} else {
pkt = iot_sg_ext_data_clct_69845_nomal_msg_build(addr,
&data_clct->config.di_bitmap, data_clct->cur_clct_di);
}
return pkt;
}
static iot_pkt_t *iot_sg_ext_meter_data_clct_msg_build(uint8_t *addr,
uint8_t data_type, uint8_t *invalid_di)
{
iot_pkt_t *pkt = NULL;
if (data_type == IOT_SG_STA_DATA_TYPE_645_97) {
pkt = iot_sg_ext_data_clct_645_msg_build(addr, PROTO_645_1997_ID,
invalid_di);
} else if (data_type == IOT_SG_STA_DATA_TYPE_69845) {
pkt = iot_sg_ext_data_clct_69845_msg_build(addr);
} else {
pkt = iot_sg_ext_data_clct_645_msg_build(addr, PROTO_645_2007_ID,
invalid_di);
}
return pkt;
}
static uint8_t iot_sg_ext_data_clct_func_to_task_type(uint8_t func,
uint8_t is_3p)
{
uint8_t task_type;
switch (func) {
case IOT_SG_STA_EXT_DC_FUNC_MF:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
}
break;
}
case IOT_SG_STA_EXT_DC_FUNC_DF:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
}
break;
}
case IOT_SG_STA_EXT_DC_FUNC_15M_CUR:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
}
break;
}
case IOT_SG_STA_EXT_DC_FUNC_1M_CUR:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
}
break;
}
default:
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
break;
}
return task_type;
}
static void iot_sg_sta_ext_data_get_def_cfg(uint8_t task_type,
iot_sg_sta_ext_data_clct_config_t *cfg)
{
os_mem_set(&cfg->start_time, 0x0, sizeof(iot_time_tm_t));
cfg->start_time.tm_year = 2000;
cfg->start_time.tm_mon = 1;
cfg->start_time.tm_mday = 1;
cfg->di_bitmap = iot_sg_sta_ext_data_clct_get_di_bm_def(task_type);
switch (task_type) {
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
{
cfg->exe_inter = IOT_SG_STA_EXT_DC_EXE_INTER_1MON;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
{
cfg->exe_inter = IOT_SG_STA_EXT_DC_EXE_INTER_1DAY;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
{
cfg->exe_inter = IOT_SG_STA_EXT_DC_EXE_INTER_15MIN;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
{
cfg->exe_inter = IOT_SG_STA_EXT_DC_EXE_INTER_1MIN;
break;
}
default:
break;
}
}
static void iot_sg_sta_ext_data_clct_sec_to_exe_inter(
int64_t sec, proto_69845_app_data_ti_t *exe_inter)
{
int64_t uint = 0;
if (sec < IOT_SG_STA_EXT_DC_EXE_INTER_1MIN) {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_SEC;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1SEC;
} else if (sec < IOT_SG_STA_EXT_DC_EXE_INTER_1MIN * 60) {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1MIN;
} else if (sec < IOT_SG_STA_EXT_DC_EXE_INTER_1DAY) {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_HOUR;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1MIN * 60;
} else if (sec < IOT_SG_STA_EXT_DC_EXE_INTER_1MON) {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_DAY;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1DAY;
} else if (sec < IOT_SG_STA_EXT_DC_EXE_INTER_1MON * 12) {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MON;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1MON;
} else {
exe_inter->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_YEAR;
uint = IOT_SG_STA_EXT_DC_EXE_INTER_1MON * 12;
}
exe_inter->value = (uint16_t)(sec / uint);
}
static uint8_t iot_sg_sta_ext_data_clct_get_def_id_num(uint8_t task_type)
{
uint8_t id_num = 0;
switch (task_type) {
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
{
id_num = PROTO_69845_DC_3P_MF_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
{
id_num = PROTO_69845_DC_3P_DF_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
{
id_num = PROTO_69845_DC_3P_15M_CUR_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
{
id_num = PROTO_69845_DC_3P_1M_CUR_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
{
id_num = PROTO_69845_DC_MF_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
{
id_num = PROTO_69845_DC_DF_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
{
id_num = PROTO_69845_DC_15M_CUR_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
{
id_num = PROTO_69845_DC_1M_CUR_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
{
id_num = PROTO_69845_DC_DC_DEF_ID_NUM;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
{
id_num = PROTO_69845_DC_3P_DC_DEF_ID_NUM;
break;
}
default:
break;
}
return id_num;
}
static void iot_sg_sta_ext_data_clct_get_def_delay(uint8_t task_type,
proto_69845_app_data_ti_t *delay)
{
delay->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
switch (task_type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
{
delay->value = 0;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
{
delay->value = 5;
break;
}
default:
break;
}
}
static void iot_sg_sta_ext_save_def_cfg_to_flash(uint8_t task_type)
{
uint8_t id_num;
uint32_t ret;
iot_sg_meter_js_task_config_hdr_t task_cfg = { 0 };
iot_sg_sta_ext_data_clct_config_t cfg = { 0 };
task_cfg.task_type = task_type;
id_num = iot_sg_sta_ext_data_clct_get_def_id_num(task_type);
task_cfg.task_id = id_num;
task_cfg.scheme_num = id_num;
if (task_type == IOT_SG_STA_METER_JS_CFG_TYPE_1MIN ||
task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN ||
task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C ||
task_type == IOT_SG_STA_METER_JS_CFG_TYPE_D_C) {
task_cfg.clct_type = IOT_SG_STA_METER_CLCT_TYPE_CURRENT;
} else if (task_type == IOT_SG_STA_METER_JS_CFG_TYPE_15MIN ||
task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN) {
task_cfg.clct_type = IOT_SG_STA_METER_CLCT_TYPE_INTER_TIME;
} else {
task_cfg.clct_type = IOT_SG_STA_METER_CLCT_TYPE_FREEZE_TIME;
}
/* get default config */
iot_sg_sta_ext_data_get_def_cfg(task_type, &cfg);
task_cfg.cfg_di_bm = cfg.di_bitmap;
iot_sg_sta_ext_data_clct_sec_to_exe_inter(cfg.exe_inter,
&task_cfg.exe_inter);
iot_sg_sta_ext_data_clct_get_def_delay(task_type, &task_cfg.delay);
task_cfg.start_time.year = cfg.start_time.tm_year;
task_cfg.start_time.month = cfg.start_time.tm_mon;
task_cfg.start_time.day = cfg.start_time.tm_mday;
task_cfg.start_time.hour = cfg.start_time.tm_hour;
task_cfg.start_time.minute = cfg.start_time.tm_min;
task_cfg.start_time.second = cfg.start_time.tm_sec;
ret = iot_sg_sta_flash_js_task_cfg_save(task_type, &task_cfg);
iot_sg_printf("%s task_type %lu di_map 0x%08x all_flag %lu task_id %lu "
"scheme_num %lu ret %lu\n", __FUNCTION__, task_type, task_cfg.cfg_di_bm,
task_cfg.all_flag, task_cfg.task_id, task_cfg.scheme_num, ret);
}
static void iot_sg_sta_ext_data_clct_di_bitmap_merge(uint8_t func,
uint8_t is_3p, iot_sg_sta_ext_data_clct_config_t *cfg)
{
uint8_t task_type;
iot_sg_meter_js_task_config_hdr_t cfg_hdr = { 0 };
if (func == IOT_SG_STA_EXT_DC_FUNC_DF) {
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_D_C;
}
if (!iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, &cfg_hdr)) {
if (!cfg_hdr.task_id || !cfg_hdr.scheme_num) {
return;
}
cfg->di_bitmap |= cfg_hdr.cfg_di_bm;
}
}
}
static uint32_t iot_sg_sta_ext_data_clct_flash_cfg(uint8_t func, uint8_t is_3p)
{
uint32_t ret = ERR_FAIL;
uint8_t task_type;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_config_t *cfg = &ext_info->data_clct.config;
iot_sg_meter_js_task_config_hdr_t cfg_hdr = { 0 };
task_type = iot_sg_ext_data_clct_func_to_task_type(func, is_3p);
if (!iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, &cfg_hdr)) {
if (!cfg_hdr.task_id || !cfg_hdr.scheme_num) {
if (!is_3p) {
/* single phase or all phase task deleted */
goto out;
}
/* query all phase task */
task_type = iot_sg_ext_data_clct_func_to_task_type(func, 0);
if (!iot_sg_sta_flash_js_task_cfg_get_by_type(task_type,
&cfg_hdr)) {
if (!cfg_hdr.task_id || !cfg_hdr.scheme_num ||
!cfg_hdr.all_flag) {
goto out;
}
} else {
goto out;
}
}
cfg->di_bitmap = cfg_hdr.cfg_di_bm;
iot_sg_sta_ext_data_clct_di_bitmap_merge(func, is_3p, cfg);
cfg->exe_inter = proto_69845_ti_data_to_sec(&cfg_hdr.exe_inter);
cfg->delay = (uint16_t)proto_69845_ti_data_to_sec(&cfg_hdr.delay);
cfg->start_time.tm_year = cfg_hdr.start_time.year;
cfg->start_time.tm_mon = cfg_hdr.start_time.month;
cfg->start_time.tm_mday = cfg_hdr.start_time.day;
cfg->start_time.tm_hour = cfg_hdr.start_time.hour;
cfg->start_time.tm_min = cfg_hdr.start_time.minute;
cfg->start_time.tm_sec = cfg_hdr.start_time.second;
ret = ERR_OK;
}
out:
return ret;
}
static uint8_t iot_sg_ext_data_clct_meter_data_check(uint8_t cur_di,
uint8_t data_type)
{
uint8_t frozen_data_flag = 0, next_data_flag = 0;
uint8_t *data = NULL, data_size = 0, i;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
if (data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_MF ||
data_clct->config.cur_func == IOT_SG_STA_EXT_DC_FUNC_DF) {
frozen_data_flag = 1;
}
if (frozen_data_flag != ext_info->frozen_data_flag) {
goto out;
}
switch (cur_di) {
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
data = (uint8_t *)&meter->v;
data_size = sizeof(meter->v);
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
data = (uint8_t *)&meter->a;
data_size = sizeof(meter->a);
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
data = meter->gnd_a;
data_size = sizeof(meter->gnd_a);
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
{
data = (uint8_t *)&meter->ap;
data_size = sizeof(meter->ap);
break;
}
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
data = (uint8_t *)&meter->rp;
data_size = sizeof(meter->rp);
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
data = (uint8_t *)&meter->pf;
data_size = sizeof(meter->pf);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
data = meter->pae.rate_1;
data_size = sizeof(meter->pae.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
data = meter->pae.total;
data_size = sizeof(meter->pae.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
data = meter->nae.rate_1;
data_size = sizeof(meter->nae.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
data = meter->nae.total;
data_size = sizeof(meter->nae.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
data = (uint8_t *)&meter->cre1;
data_size = sizeof(meter->cre1);
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
data = (uint8_t *)&meter->cre2;
data_size = sizeof(meter->cre2);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
{
data = meter->re_1st.rate_1;
data_size = sizeof(meter->re_1st.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
{
data = meter->re_1st.total;
data_size = sizeof(meter->re_1st.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
{
data = meter->re_2st.rate_1;
data_size = sizeof(meter->re_2st.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
{
data = meter->re_2st.total;
data_size = sizeof(meter->re_2st.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
{
data = meter->re_3st.rate_1;
data_size = sizeof(meter->re_3st.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
{
data = meter->re_3st.total;
data_size = sizeof(meter->re_3st.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
data = meter->re_4st.rate_1;
data_size = sizeof(meter->re_4st.rate_1);
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
data = meter->re_4st.total;
data_size = sizeof(meter->re_4st.total);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
{
data = (uint8_t *)&meter->pos_ap_demand;
data_size = sizeof(meter->pos_ap_demand);
break;
}
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
{
data = (uint8_t *)&meter->neg_ap_demand;
data_size = sizeof(meter->neg_ap_demand);
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
{
data = (uint8_t *)&meter->cre1_demand;
data_size = sizeof(meter->cre1_demand);
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
data = (uint8_t *)&meter->cre2_demand;
data_size = sizeof(meter->cre2_demand);
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
data = (uint8_t *)&meter->frozen_time;
data_size = sizeof(meter->frozen_time);
break;
}
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
case IOT_SG_STA_METER_TASK_DI_TIME:
{
if (data_type == IOT_SG_STA_DATA_TYPE_69845) {
/* 69845 meter single di read run state word and time data */
next_data_flag = 0;
goto out;
}
}
default:
next_data_flag = 1;
goto out;
}
for (i = 0; i < data_size; i++) {
if (data[i] != 0xff) {
next_data_flag = 1;
break;
}
}
out:
return next_data_flag;
}
static void iot_sg_ext_data_clct_cur_di_clear()
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
ext_info->data_clct.config.di_bitmap = 0;
}
static uint8_t iot_sg_ext_group_di_max_cnt_get(uint8_t cur_di,
uint8_t data_type)
{
uint8_t di_max_cnt = 0;
switch (cur_di) {
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
{
if (data_type == IOT_SG_STA_DATA_TYPE_645_07) {
di_max_cnt = IOT_SG_STA_07_RUN_STATE_WORD_DI_CNT;
} else if (data_type == IOT_SG_STA_DATA_TYPE_645_97) {
di_max_cnt = IOT_SG_STA_97_RUN_STATE_WORD_DI_CNT;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
if (data_type == IOT_SG_STA_DATA_TYPE_645_07) {
di_max_cnt = IOT_SG_STA_07_READ_TIME_DI_CNT;
} else if (data_type == IOT_SG_STA_DATA_TYPE_645_97) {
di_max_cnt = IOT_SG_STA_97_READ_TIME_DI_CNT;
}
break;
}
default:
break;
}
return di_max_cnt;
}
static uint8_t iot_sg_ext_group_di_handle(uint8_t cur_di, uint8_t data_type)
{
uint8_t di_max_cnt;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
if (!data_clct->is_group_di) {
switch (cur_di) {
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
{
/* valid_flag = 0, running status is valid */
os_mem_set(&ext_info->meter_data.rs_word, 0x0,
sizeof(ext_info->meter_data.rs_word));
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
if (data_type != IOT_SG_STA_DATA_TYPE_69845) {
data_clct->is_group_di = 1;
data_clct->group_di_idx = 0;
}
break;
}
default:
break;
}
} else {
data_clct->group_di_idx++;
di_max_cnt = iot_sg_ext_group_di_max_cnt_get(cur_di, data_type);
if (data_clct->group_di_idx >= di_max_cnt) {
data_clct->is_group_di = 0;
data_clct->group_di_idx = 0;
}
}
return data_clct->is_group_di;
}
static uint32_t iot_sg_ext_data_clct_cur_di_update(uint8_t data_type)
{
uint32_t ret = ERR_FAIL, first_index;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
next_di:
first_index = iot_bitmap_ffs((uint8_t *)&data_clct->config.di_bitmap,
sizeof(data_clct->config.di_bitmap));
if (first_index) {
data_clct->cur_clct_di = (uint8_t)(first_index - 1);
if (iot_sg_ext_group_di_handle(data_clct->cur_clct_di, data_type)) {
ret = ERR_OK;
goto out;
}
data_clct->config.di_bitmap &= ~(1 << data_clct->cur_clct_di);
if (iot_sg_ext_data_clct_meter_data_check(data_clct->cur_clct_di,
data_type)) {
goto next_di;
}
ret = ERR_OK;
}
out:
return ret;
}
static uint8_t iot_sg_ext_data_clct_func_to_data_type(uint8_t func)
{
uint8_t data_type;
switch (func) {
case IOT_SG_STA_EXT_DC_FUNC_MF:
{
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_MF;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_DF:
{
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_DF;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_15M_CUR:
{
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_1M_CUR:
{
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE;
break;
}
default:
data_type = IOT_SG_STA_METER_DATA_TYPE_INVALID;
break;
}
return data_type;
}
static void iot_sg_ext_data_clct_latest_rpt_idx_clear(uint8_t *addr,
uint8_t data_type)
{
uint8_t i, is_invalid = 0, invalid_addr_cnt = 0;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (!addr) {
goto out;
}
if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_SIG_METER &&
data_type == evt_rpt->last_rpt_info.data_type) {
if (iot_mac_addr_cmp(addr, evt_rpt->last_rpt_info.addr)) {
is_invalid = 1;
}
} else if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_MULT_METER &&
data_type == evt_rpt->last_multi_rpt_info.data_type) {
for (i = 0; i < evt_rpt->last_multi_rpt_info.meter_info_cnt; i++) {
meter_info = &evt_rpt->last_multi_rpt_info.meter_info[i];
if (!iot_mac_addr_valid(meter_info->addr)) {
invalid_addr_cnt++;
continue;
}
if (!iot_mac_addr_cmp(addr, meter_info->addr)) {
continue;
}
os_mem_set(meter_info, 0x0, sizeof(*meter_info));
invalid_addr_cnt++;
}
if (invalid_addr_cnt == evt_rpt->last_multi_rpt_info.meter_info_cnt) {
is_invalid = 1;
}
}
if (is_invalid) {
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_INVALID;
}
out:
return;
}
static void iot_sg_ext_data_clct_latest_rpt_idx_reduce(uint8_t *addr,
uint8_t data_type)
{
uint8_t i, is_invalid = 0, invalid_addr_cnt = 0;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (!addr) {
goto out;
}
if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_SIG_METER &&
data_type == evt_rpt->last_rpt_info.data_type) {
if (!iot_mac_addr_cmp(addr, evt_rpt->last_rpt_info.addr)) {
goto out;
}
if (evt_rpt->last_rpt_info.cnt) {
evt_rpt->last_rpt_info.cnt--;
}
if (!evt_rpt->last_rpt_info.cnt) {
is_invalid = 1;
}
} else if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_MULT_METER &&
data_type == evt_rpt->last_multi_rpt_info.data_type) {
for (i = 0; i < evt_rpt->last_multi_rpt_info.meter_info_cnt; i++) {
meter_info = &evt_rpt->last_multi_rpt_info.meter_info[i];
if (!iot_mac_addr_valid(meter_info->addr)) {
invalid_addr_cnt++;
continue;
}
if (!iot_mac_addr_cmp(addr, meter_info->addr)) {
continue;
}
if (meter_info->cnt) {
meter_info->cnt--;
}
if (!meter_info->cnt) {
os_mem_set(meter_info, 0x0, sizeof(*meter_info));
invalid_addr_cnt++;
}
}
if (invalid_addr_cnt == evt_rpt->last_multi_rpt_info.meter_info_cnt) {
is_invalid = 1;
}
}
if (is_invalid) {
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_INVALID;
}
out:
return;
}
static void iot_sg_ext_data_clct_latest_rpt_idx_update(uint8_t *addr,
uint8_t data_type, uint8_t method)
{
switch (method) {
case IOT_SG_STA_EXT_DC_LAST_IDX_CLEAR:
{
iot_sg_ext_data_clct_latest_rpt_idx_clear(addr, data_type);
break;
}
case IOT_SG_STA_EXT_DC_LAST_IDX_REDUCE:
{
iot_sg_ext_data_clct_latest_rpt_idx_reduce(addr, data_type);
break;
}
default:
break;
}
}
static void iot_sg_ext_data_clct_rpt_idx_update_exe(
uint16_t *rpt_idx_ptr, uint16_t *cnt_ptr, uint16_t max_cnt, uint16_t index,
uint8_t *addr, uint8_t *data, uint16_t unit_len, uint8_t data_type,
uint16_t clear_cnt)
{
uint32_t ret;
uint16_t rpt_index = *rpt_idx_ptr, cnt = *cnt_ptr, end_index;
if (!cnt) {
rpt_index = index;
cnt = 1;
iot_sg_ext_data_clct_latest_rpt_idx_update(addr, data_type,
IOT_SG_STA_EXT_DC_LAST_IDX_CLEAR);
} else {
ret = iot_sg_sta_flash_unit_data_read(addr, rpt_index,
data, unit_len, data_type);
if (ret || (clear_cnt >= cnt)) {
rpt_index = index;
cnt = 1;
iot_sg_ext_data_clct_latest_rpt_idx_update(addr, data_type,
IOT_SG_STA_EXT_DC_LAST_IDX_CLEAR);
} else {
if (rpt_index + cnt > max_cnt) {
end_index = rpt_index + cnt - max_cnt - 1;
} else {
end_index = rpt_index + cnt - 1;
}
if (clear_cnt) {
cnt -= clear_cnt;
} else if (end_index != index) {
cnt++;
}
if (cnt > max_cnt) {
cnt = max_cnt;
rpt_index++;
iot_sg_ext_data_clct_latest_rpt_idx_update(addr, data_type,
IOT_SG_STA_EXT_DC_LAST_IDX_REDUCE);
if (rpt_index >= max_cnt) {
rpt_index = 0;
}
}
}
}
*rpt_idx_ptr = rpt_index;
*cnt_ptr = cnt;
}
static void iot_sg_ext_data_clct_rpt_idx_update(uint8_t *addr, uint8_t data_type,
uint16_t index, iot_pkt_t *pkt, uint16_t clear_cnt)
{
uint8_t *data;
uint16_t unit_len;
iot_sg_sta_node_desc_t *node;
IOT_ASSERT(pkt);
data = iot_pkt_data(pkt);
unit_len = (uint16_t)iot_pkt_data_len(pkt);
node = iot_sg_sta_node_find_by_addr(addr);
if (node) {
switch (data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
iot_sg_ext_data_clct_rpt_idx_update_exe(
&node->ext.data_clct_info.mf_rpt_index,
&node->ext.data_clct_info.mf_cnt,
IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT,
index, addr, data, unit_len, data_type,
clear_cnt);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
iot_sg_ext_data_clct_rpt_idx_update_exe(
&node->ext.data_clct_info.df_rpt_index,
&node->ext.data_clct_info.df_cnt,
IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT,
index, addr, data, unit_len, data_type,
clear_cnt);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
iot_sg_ext_data_clct_rpt_idx_update_exe(
&node->ext.data_clct_info.min15_rpt_index,
&node->ext.data_clct_info.min15_cnt,
IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT,
index, addr, data, unit_len, data_type,
clear_cnt);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
iot_sg_ext_data_clct_rpt_idx_update_exe(
&node->ext.data_clct_info.min1_rpt_index,
&node->ext.data_clct_info.min1_cnt,
IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT,
index, addr, data, unit_len, data_type,
clear_cnt);
break;
}
default:
break;
}
}
}
static void iot_sg_sta_ext_data_save_idx_updata(uint8_t *addr,
iot_time_tm_t *tm, uint8_t *data, uint16_t len, uint8_t data_type,
uint16_t *index)
{
uint32_t ret;
iot_sg_meter_unit_time_t *unit_time;
iot_time_tm_t cache_tm = { 0 };
ret = iot_sg_sta_flash_unit_data_find_by_time(addr, index, tm, data,
len, data_type, 1);
if (ret == ERR_OK) {
unit_time = (iot_sg_meter_unit_time_t *)data;
cache_tm.tm_year =
(uint16_t)(unit_time->year + 2000);
cache_tm.tm_mon = (uint8_t)unit_time->month;
cache_tm.tm_mday = (uint8_t)unit_time->day;
cache_tm.tm_hour = (uint8_t)unit_time->hour;
cache_tm.tm_min = (uint8_t)unit_time->minute;
if (iot_rtc_delta_calc(&cache_tm, tm) != 0) {
(*index)++;
}
} else {
*index = 0;
}
}
static void iot_sg_ext_data_clct_state_update(uint8_t *addr, iot_time_tm_t *tm,
uint8_t func, iot_sg_sta_ext_meter_data_t *meter)
{
uint16_t i;
uint8_t task_type, *data, is_valid = 0;
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
if (!node || !meter) {
return;
}
data = (uint8_t *)meter;
for (i = 0; i < sizeof(*meter); i++) {
if (data[i] != 0xFF) {
is_valid = 1;
break;
}
}
if (is_valid) {
task_type = iot_sg_ext_data_clct_func_to_task_type(func,
node->is_three_phase);
if (!(node->ext.data_clct_info.task_suc_bm & (1 << task_type))) {
node->ext.data_clct_info.task_suc_bm |= (1 << task_type);
}
os_mem_cpy(&node->ext.data_clct_info.last_clct_tm, tm, sizeof(*tm));
} else {
if (node->ext.data_clct_info.clct_fail_times < 255) {
node->ext.data_clct_info.clct_fail_times++;
}
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x clct_fail_times "
"%lu\n", __FUNCTION__, node->entry.addr[0], node->entry.addr[1],
node->entry.addr[2], node->entry.addr[3], node->entry.addr[4],
node->entry.addr[5], node->ext.data_clct_info.clct_fail_times);
}
}
static void iot_sg_ext_data_clct_msg_num_update(uint8_t is_send)
{
uint8_t task_type;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
iot_sg_sta_node_desc_t *node;
node = iot_sg_sta_node_find_by_addr(ext_info->addr);
if (!node) {
return;
}
task_type = iot_sg_ext_data_clct_func_to_task_type(
data_clct->config.cur_func, node->is_three_phase);
if (is_send) {
if (data_clct->monitor[task_type].msg_send_num < 0xFFFF) {
data_clct->monitor[task_type].msg_send_num++;
}
} else {
if (data_clct->monitor[task_type].msg_recv_num < 0xFFFF) {
data_clct->monitor[task_type].msg_recv_num++;
}
}
iot_sg_printf("%s task_type %lu msg_send_num %lu msg_recv_num %lu\n",
__FUNCTION__, task_type, data_clct->monitor[task_type].msg_send_num,
data_clct->monitor[task_type].msg_recv_num);
}
static void iot_sg_ext_data_clct_save(uint8_t *addr, uint8_t func,
iot_time_tm_t *tm)
{
uint8_t *buf, data_type;
uint16_t index = 0, max_cnt, uint_len, clear_cnt;
uint32_t ret;
iot_pkt_t *pkt = NULL;
iot_time_tm_t tm_tmp = { 0 };
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
iot_sg_meter_js_frozen_uint_data_t *flash_frozen_data;
iot_sg_meter_js_sig_frozen_uint_data_t *flash_sig_frozen_data;
iot_sg_meter_js_min_curve_uint_data_t *flash_cur_data;
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
iot_sg_printf("%s time %lu-%lu-%lu %lu:%lu:%lu\n", __FUNCTION__,
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec);
data_type = iot_sg_ext_data_clct_func_to_data_type(func);
iot_sg_sta_flash_unit_get_data_info(data_type, &uint_len, &max_cnt);
if (!uint_len) {
goto out;
}
pkt = iot_pkt_alloc(uint_len, IOT_SMART_GRID_MID);
if (!pkt) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto out;
}
buf = iot_pkt_put(pkt, uint_len);
if (func == IOT_SG_STA_EXT_DC_FUNC_MF ||
func == IOT_SG_STA_EXT_DC_FUNC_DF) {
/* day collection and month collection flash save time
* different from collection time
*/
if (ext_info->data_clct.ft_valid) {
tm_tmp.tm_year = iot_bcd_to_byte(meter->frozen_time.year) + 2000;
tm_tmp.tm_mon = iot_bcd_to_byte(meter->frozen_time.month);
tm_tmp.tm_mday = iot_bcd_to_byte(meter->frozen_time.day);
tm_tmp.tm_hour = iot_bcd_to_byte(meter->frozen_time.hour);
tm_tmp.tm_min = iot_bcd_to_byte(meter->frozen_time.minute);
} else {
tm_tmp = *tm;
tm_tmp.tm_hour = 0;
tm_tmp.tm_min = 0;
}
} else {
tm_tmp = *tm;
}
iot_sg_sta_ext_data_save_idx_updata(addr, &tm_tmp, buf, uint_len, data_type,
&index);
if (index >= max_cnt) {
index = 0;
}
switch (func) {
case IOT_SG_STA_EXT_DC_FUNC_MF:
case IOT_SG_STA_EXT_DC_FUNC_DF:
{
flash_frozen_data = (iot_sg_meter_js_frozen_uint_data_t *)buf;
if (ext_info->data_clct.ft_valid) {
ext_info->data_clct.ft_valid = 0;
flash_frozen_data->year =
iot_bcd_to_byte(meter->frozen_time.year);
flash_frozen_data->month =
iot_bcd_to_byte(meter->frozen_time.month);
flash_frozen_data->day =
iot_bcd_to_byte(meter->frozen_time.day);
flash_frozen_data->hour =
iot_bcd_to_byte(meter->frozen_time.hour);
flash_frozen_data->minute =
iot_bcd_to_byte(meter->frozen_time.minute);
} else {
flash_frozen_data->year = (uint32_t)(tm->tm_year % 100);
flash_frozen_data->month = (uint32_t)(tm->tm_mon);
flash_frozen_data->day = (uint32_t)(tm->tm_mday);
flash_frozen_data->hour = 0;
flash_frozen_data->minute = 0;
}
os_mem_cpy(&flash_frozen_data->ept_pos, &meter->pae,
sizeof(meter->pae));
os_mem_cpy(&flash_frozen_data->ept_neg, &meter->nae,
sizeof(meter->nae));
os_mem_cpy(&flash_frozen_data->cre1, &meter->cre1,
sizeof(meter->cre1));
os_mem_cpy(&flash_frozen_data->cre2, &meter->cre2,
sizeof(meter->cre2));
os_mem_cpy(&flash_frozen_data->re_1st_power, &meter->re_1st,
sizeof(meter->re_1st));
os_mem_cpy(&flash_frozen_data->re_2nd_power, &meter->re_2st,
sizeof(meter->re_2st));
os_mem_cpy(&flash_frozen_data->re_3rd_power, &meter->re_3st,
sizeof(meter->re_3st));
os_mem_cpy(&flash_frozen_data->re_4th_power, &meter->re_4st,
sizeof(meter->re_4st));
os_mem_cpy(&flash_frozen_data->pos_act_dem_time,
&meter->pos_ap_demand, sizeof(meter->pos_ap_demand));
os_mem_cpy(&flash_frozen_data->neg_atc_dem_time,
&meter->neg_ap_demand, sizeof(meter->neg_ap_demand));
os_mem_cpy(&flash_frozen_data->com_react1_dem_time, &meter->cre1_demand,
sizeof(meter->cre1_demand));
os_mem_cpy(&flash_frozen_data->com_reatc2_dem_time, &meter->cre2_demand,
sizeof(meter->cre2_demand));
os_mem_cpy(&flash_frozen_data->v, &meter->v, sizeof(meter->v));
os_mem_cpy(&flash_frozen_data->i, &meter->a, sizeof(meter->a));
os_mem_cpy(flash_frozen_data->n, meter->gnd_a, sizeof(meter->gnd_a));
os_mem_cpy(&flash_frozen_data->active_power, &meter->ap,
sizeof(meter->ap));
os_mem_cpy(&flash_frozen_data->reactive_power, &meter->rp,
sizeof(meter->rp));
os_mem_cpy(&flash_frozen_data->power_factor, &meter->pf,
sizeof(meter->pf));
os_mem_cpy(&flash_frozen_data->rs_word, &meter->rs_word,
sizeof(meter->rs_word));
break;
}
case IOT_SG_STA_EXT_DC_FUNC_15M_CUR:
{
if (iot_sg_sta_flash_mode_js_sig_check()) {
flash_sig_frozen_data =
(iot_sg_meter_js_sig_frozen_uint_data_t *)buf;
flash_sig_frozen_data->year = (uint32_t)(tm->tm_year % 100);
flash_sig_frozen_data->month = (uint32_t)(tm->tm_mon);
flash_sig_frozen_data->day = (uint32_t)(tm->tm_mday);
flash_sig_frozen_data->hour = (uint32_t)(tm->tm_hour);
flash_sig_frozen_data->minute = (uint32_t)(tm->tm_min);
os_mem_cpy(&flash_sig_frozen_data->ept_pos, &meter->pae.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->ept_neg, &meter->nae.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->cre1, &meter->cre1.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->cre2, &meter->cre2.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->v, &meter->v.a,
PROTO_645_V_LEN);
os_mem_cpy(&flash_sig_frozen_data->i, &meter->a.a,
PROTO_645_07_A_LEN);
os_mem_cpy(flash_sig_frozen_data->n, meter->gnd_a,
PROTO_645_07_A_LEN);
os_mem_cpy(&flash_sig_frozen_data->active_power, &meter->ap.a,
PROTO_645_07_P_LEN);
os_mem_cpy(&flash_sig_frozen_data->reactive_power, &meter->rp.a,
PROTO_645_07_P_LEN);
os_mem_cpy(&flash_sig_frozen_data->power_factor, &meter->pf.a,
PROTO_645_07_PF_LEN);
} else {
flash_frozen_data = (iot_sg_meter_js_frozen_uint_data_t *)buf;
flash_frozen_data->year = (uint32_t)(tm->tm_year % 100);
flash_frozen_data->month = (uint32_t)(tm->tm_mon);
flash_frozen_data->day = (uint32_t)(tm->tm_mday);
flash_frozen_data->hour = (uint32_t)(tm->tm_hour);
flash_frozen_data->minute = (uint32_t)(tm->tm_min);
os_mem_cpy(&flash_frozen_data->ept_pos, &meter->pae,
sizeof(meter->pae));
os_mem_cpy(&flash_frozen_data->ept_neg, &meter->nae,
sizeof(meter->nae));
os_mem_cpy(&flash_frozen_data->cre1, &meter->cre1,
sizeof(meter->cre1));
os_mem_cpy(&flash_frozen_data->cre2, &meter->cre2,
sizeof(meter->cre2));
os_mem_cpy(&flash_frozen_data->re_1st_power, &meter->re_1st,
sizeof(meter->re_1st));
os_mem_cpy(&flash_frozen_data->re_2nd_power, &meter->re_2st,
sizeof(meter->re_2st));
os_mem_cpy(&flash_frozen_data->re_3rd_power, &meter->re_3st,
sizeof(meter->re_3st));
os_mem_cpy(&flash_frozen_data->re_4th_power, &meter->re_4st,
sizeof(meter->re_4st));
os_mem_cpy(&flash_frozen_data->pos_act_dem_time,
&meter->pos_ap_demand, sizeof(meter->pos_ap_demand));
os_mem_cpy(&flash_frozen_data->neg_atc_dem_time,
&meter->neg_ap_demand, sizeof(meter->neg_ap_demand));
os_mem_cpy(&flash_frozen_data->com_react1_dem_time, &meter->cre1_demand,
sizeof(meter->cre1_demand));
os_mem_cpy(&flash_frozen_data->com_reatc2_dem_time, &meter->cre2_demand,
sizeof(meter->cre2_demand));
os_mem_cpy(&flash_frozen_data->v, &meter->v, sizeof(meter->v));
os_mem_cpy(&flash_frozen_data->i, &meter->a, sizeof(meter->a));
os_mem_cpy(flash_frozen_data->n, meter->gnd_a, sizeof(meter->gnd_a));
os_mem_cpy(&flash_frozen_data->active_power, &meter->ap,
sizeof(meter->ap));
os_mem_cpy(&flash_frozen_data->reactive_power, &meter->rp,
sizeof(meter->rp));
os_mem_cpy(&flash_frozen_data->power_factor, &meter->pf,
sizeof(meter->pf));
}
break;
}
case IOT_SG_STA_EXT_DC_FUNC_1M_CUR:
{
if (iot_sg_sta_flash_mode_js_sig_check()) {
flash_sig_frozen_data =
(iot_sg_meter_js_sig_frozen_uint_data_t *)buf;
flash_sig_frozen_data->year = (uint32_t)(tm->tm_year % 100);
flash_sig_frozen_data->month = (uint32_t)(tm->tm_mon);
flash_sig_frozen_data->day = (uint32_t)(tm->tm_mday);
flash_sig_frozen_data->hour = (uint32_t)(tm->tm_hour);
flash_sig_frozen_data->minute = (uint32_t)(tm->tm_min);
os_mem_cpy(&flash_sig_frozen_data->ept_pos, &meter->pae.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->ept_neg, &meter->nae.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->cre1, &meter->cre1.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->cre2, &meter->cre2.total,
IOT_SG_STA_METER_ENERGY_DATA_LEN);
os_mem_cpy(&flash_sig_frozen_data->v, &meter->v.a,
PROTO_645_V_LEN);
os_mem_cpy(&flash_sig_frozen_data->i, &meter->a.a,
PROTO_645_07_A_LEN);
os_mem_cpy(flash_sig_frozen_data->n, meter->gnd_a,
PROTO_645_07_A_LEN);
os_mem_cpy(&flash_sig_frozen_data->active_power, &meter->ap.a,
PROTO_645_07_P_LEN);
os_mem_cpy(&flash_sig_frozen_data->reactive_power, &meter->rp.a,
PROTO_645_07_P_LEN);
os_mem_cpy(&flash_sig_frozen_data->power_factor, &meter->pf.a,
PROTO_645_07_PF_LEN);
if (iot_bcd_check(meter->time.year) &&
iot_bcd_check(meter->time.hour)) {
flash_sig_frozen_data->time.year =
iot_bcd_to_byte(meter->time.year);
flash_sig_frozen_data->time.month =
iot_bcd_to_byte(meter->time.month);
flash_sig_frozen_data->time.day =
iot_bcd_to_byte(meter->time.day);
flash_sig_frozen_data->time.hour =
iot_bcd_to_byte(meter->time.hour);
flash_sig_frozen_data->time.minute =
iot_bcd_to_byte(meter->time.minute);
flash_sig_frozen_data->time.second =
iot_bcd_to_byte(meter->time.second);
} else {
os_mem_set(&flash_sig_frozen_data->time, 0xff,
sizeof(flash_sig_frozen_data->time));
}
} else {
flash_cur_data = (iot_sg_meter_js_min_curve_uint_data_t *)buf;
flash_cur_data->year = (uint32_t)(tm->tm_year % 100);
flash_cur_data->month = (uint32_t)(tm->tm_mon);
flash_cur_data->day = (uint32_t)(tm->tm_mday);
flash_cur_data->hour = (uint32_t)(tm->tm_hour);
flash_cur_data->minute = (uint32_t)(tm->tm_min);
os_mem_cpy(&flash_cur_data->v, &meter->v, sizeof(meter->v));
os_mem_cpy(&flash_cur_data->i, &meter->a, sizeof(meter->a));
os_mem_cpy(flash_cur_data->n, meter->gnd_a, sizeof(meter->gnd_a));
os_mem_cpy(&flash_cur_data->active_power, &meter->ap,
sizeof(meter->ap));
os_mem_cpy(&flash_cur_data->reactive_power, &meter->rp,
sizeof(meter->rp));
os_mem_cpy(&flash_cur_data->power_factor, &meter->pf,
sizeof(meter->pf));
if (iot_bcd_check(meter->time.year) &&
iot_bcd_check(meter->time.hour)) {
flash_cur_data->time.year =
iot_bcd_to_byte(meter->time.year);
flash_cur_data->time.month =
iot_bcd_to_byte(meter->time.month);
flash_cur_data->time.day =
iot_bcd_to_byte(meter->time.day);
flash_cur_data->time.hour =
iot_bcd_to_byte(meter->time.hour);
flash_cur_data->time.minute =
iot_bcd_to_byte(meter->time.minute);
flash_cur_data->time.second =
iot_bcd_to_byte(meter->time.second);
} else {
os_mem_set(&flash_cur_data->time, 0xff,
sizeof(flash_cur_data->time));
}
}
break;
}
default:
goto out;
}
ret = iot_sg_sta_flash_unit_data_save(addr, index, buf, uint_len,
data_type);
if (ret == ERR_OK) {
clear_cnt = iot_sg_sta_flash_unit_data_check(addr, index, tm,
data_type);
iot_sg_ext_data_clct_rpt_idx_update(addr, data_type, index, pkt,
clear_cnt);
iot_sg_ext_data_clct_state_update(addr, tm, func, meter);
} else {
iot_sg_printf("%s data_type %lu err %lu\n", __FUNCTION__,
data_type, ret);
}
out:
if (pkt) {
iot_pkt_free(pkt);
}
return;
}
static uint32_t iot_sg_ext_data_clct_tm_check(uint8_t func)
{
uint32_t ret;
if (func == IOT_SG_STA_EXT_DC_FUNC_1M_CUR) {
ret = iot_sg_sta_rtc_valid_check(1);
} else {
ret = iot_sg_sta_rtc_valid_check(0);
}
return ret;
}
static void iot_sg_ext_data_clct_cur_func_done(uint8_t func)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
switch (func) {
case IOT_SG_STA_EXT_DC_FUNC_MF:
{
data_clct->mf_done = 1;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_DF:
{
data_clct->df_done = 1;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_1M_CUR:
{
data_clct->cur_1m_done = 1;
break;
}
case IOT_SG_STA_EXT_DC_FUNC_15M_CUR:
{
data_clct->cur_15m_done = 1;
break;
}
default:
IOT_ASSERT(0);
break;
}
}
static uint8_t iot_sg_ext_data_clct_get_run_func(void)
{
uint8_t func = IOT_SG_STA_EXT_DC_FUNC_INVALID;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
if (data_clct->mf_en && !data_clct->mf_done) {
func = IOT_SG_STA_EXT_DC_FUNC_MF;
goto out;
}
if (data_clct->df_en && !data_clct->df_done) {
func = IOT_SG_STA_EXT_DC_FUNC_DF;
goto out;
}
if (data_clct->cur_15m_en && !data_clct->cur_15m_done) {
func = IOT_SG_STA_EXT_DC_FUNC_15M_CUR;
goto out;
}
if (data_clct->cur_1m_en && !data_clct->cur_1m_done) {
func = IOT_SG_STA_EXT_DC_FUNC_1M_CUR;
goto out;
}
out:
return func;
}
static uint8_t iot_sg_ext_data_clct_cfg_update(uint8_t is_3p)
{
uint8_t done = 0, frozen_data_flag;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_config_t *config = &ext_info->data_clct.config;
next_func:
if (!config->cfg_is_latest) {
config->cur_func = iot_sg_ext_data_clct_get_run_func();
if (config->cur_func == IOT_SG_STA_EXT_DC_FUNC_INVALID) {
os_mem_set(config, 0, sizeof(iot_sg_sta_ext_data_clct_config_t));
done = 1;
goto out;
}
if (iot_sg_sta_ext_data_clct_flash_cfg(config->cur_func, is_3p)) {
iot_sg_ext_data_clct_cur_func_done(config->cur_func);
goto next_func;
}
config->cfg_is_latest = 1;
if (config->cur_func == IOT_SG_STA_EXT_DC_FUNC_MF ||
config->cur_func == IOT_SG_STA_EXT_DC_FUNC_DF) {
frozen_data_flag = 1;
} else {
frozen_data_flag = 0;
}
if (frozen_data_flag != ext_info->frozen_data_flag) {
/* 1 min collection data and 15 min collection data can be reused,
* daily collection data and monthly collection data can be reused.
*/
ext_info->frozen_data_flag = frozen_data_flag;
os_mem_set(&ext_info->meter_data, 0xff,
sizeof(ext_info->meter_data));
}
}
out:
return done;
}
static void iot_sg_sta_ext_data_clct_last_df(uint8_t *addr,
iot_time_tm_t *tm)
{
int64_t delta;
uint32_t ret;
uint16_t latest_idx, unit_len, max_cnt;
uint8_t *buff_ptr, data_type = IOT_SG_STA_METER_DATA_TYPE_JS_DF;
iot_sg_meter_unit_time_t *unit_time;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
iot_time_tm_t last_tm, cur_tm;
iot_pkt_t *pkt = NULL;
iot_sg_sta_rtc_get(&cur_tm, 0);
delta = iot_rtc_delta_calc(&cur_tm, tm);
if (delta <= IOT_SG_STA_EXT_DC_EXE_INTER_1MIN * 30) {
/* next freeze data will be collected soon,
* do not collect last freeze data.
*/
goto out;
}
last_tm = cur_tm;
last_tm.tm_hour = 0;
last_tm.tm_min = 0;
last_tm.tm_sec = 0;
iot_sg_sta_flash_unit_get_data_info(data_type, &unit_len, &max_cnt);
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
if (!pkt) {
goto out;
}
buff_ptr = iot_pkt_put(pkt, unit_len);
ret = iot_sg_sta_flash_unit_data_find_latest(addr, &latest_idx,
buff_ptr, unit_len, data_type);
iot_rtc_delta_add(data_clct->config.delay, &last_tm);
if (ret) {
*tm = last_tm;
goto out;
}
unit_time = (iot_sg_meter_unit_time_t *)buff_ptr;
if (last_tm.tm_year != ((uint16_t)unit_time->year + 2000) ||
last_tm.tm_mon != (uint8_t)unit_time->month ||
last_tm.tm_mday != (uint8_t)unit_time->day) {
*tm = last_tm;
}
out:
if (pkt) {
iot_pkt_free(pkt);
}
return;
}
uint8_t iot_sg_ext_data_clct_func(uint8_t *addr)
{
uint32_t ret, dev_type;
uint16_t timeout;
uint8_t complete = 0, last_state = 0, invalid_di = 0, flag_new = 0;
uint8_t func = IOT_SG_STA_EXT_DC_FUNC_INVALID;
iot_time_tm_t tm, *node_tm = NULL;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
iot_pkt_t *pkt;
if (!node) {
complete = 1;
goto out;
}
dev_type = sta_glb->drv->get_device_type();
if (dev_type == IOT_SG_STA_DEV_TYPE_COLLECTOR_T2 &&
!data_clct->sm_complete) {
complete = 1;
goto out;
}
next_func:
if (iot_sg_ext_data_clct_cfg_update(node->is_three_phase)) {
complete = 1;
goto out;
}
func = data_clct->config.cur_func;
if (node->sus_pof && (func == IOT_SG_STA_EXT_DC_FUNC_1M_CUR ||
func == IOT_SG_STA_EXT_DC_FUNC_15M_CUR)) {
goto done;
}
if (iot_sg_ext_data_clct_tm_check(func)) {
goto done;
}
iot_sg_sta_rtc_get(&tm, 0);
last_state = data_clct->cur_state;
node_tm = iot_sg_ext_data_clct_get_node_tm(node, func);
switch (data_clct->cur_state) {
case IOT_SG_STA_EXT_DC_STATE_IDLE:
{
if (!node_tm->tm_year && !node_tm->tm_mon && !node_tm->tm_mday &&
!node_tm->tm_hour && !node_tm->tm_min && !node_tm->tm_sec) {
*node_tm = iot_sg_ext_get_next_data_clct_ts(&tm, func);
if (func == IOT_SG_STA_EXT_DC_FUNC_DF && node->clct_last_df) {
/* power on collection last day frozen */
iot_sg_sta_ext_data_clct_last_df(addr, node_tm);
node->clct_last_df = 0;
}
} else if (iot_rtc_delta_calc(node_tm, &tm) >= 0) {
data_clct->cur_state = IOT_SG_STA_EXT_DC_STATE_SEND;
data_clct->repeat_cnt = 0;
if (iot_sg_ext_data_clct_cur_di_update(node->data_type)) {
iot_sg_ext_data_clct_save(addr, func, node_tm);
*node_tm = iot_sg_ext_get_next_data_clct_ts(&tm, func);
} else {
flag_new = 1;
goto send;
}
}
goto done;
}
case IOT_SG_STA_EXT_DC_STATE_WAIT:
{
if (!data_clct->timeout_cnt) {
if (data_clct->flag_resp) {
data_clct->repeat_cnt = 0;
}
if (!data_clct->repeat_cnt) {
if (iot_sg_ext_data_clct_cur_di_update(node->data_type)) {
iot_sg_ext_data_clct_save(addr, func, node_tm);
*node_tm = iot_sg_ext_get_next_data_clct_ts(&tm, func);
goto done;
} else {
flag_new = 1;
}
} else {
data_clct->repeat_cnt--;
}
data_clct->cur_state = IOT_SG_STA_EXT_DC_STATE_SEND;
goto send;
} else {
data_clct->timeout_cnt--;
break;
}
}
case IOT_SG_STA_EXT_DC_STATE_SEND:
{
send:
pkt = iot_sg_ext_meter_data_clct_msg_build(addr, node->data_type,
&invalid_di);
if (pkt) {
timeout = (IOT_SG_STA_EXT_READ_DATA_TIMEOUT *
IOT_SG_STA_EXT_SM_DELAY / 100);
timeout = min(timeout, IOT_SG_STA_EXT_DRV_READ_TIMEOUT);
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_DATA_CLCT,
addr, 0, node->data_type, iot_pkt_data(pkt),
(uint16_t)iot_pkt_data_len(pkt), timeout);
if (ret == ERR_OK) {
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x func %lu "
"read id %lu\n", __FUNCTION__, addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5], func, data_clct->cur_clct_di);
data_clct->cur_state = IOT_SG_STA_EXT_DC_STATE_WAIT;
data_clct->timeout_cnt = IOT_SG_STA_EXT_READ_DATA_TIMEOUT;
data_clct->flag_resp = 0;
if (flag_new) {
data_clct->repeat_cnt = 1;
}
iot_sg_ext_data_clct_msg_num_update(1);
}
iot_pkt_free(pkt);
} else {
if (invalid_di) {
invalid_di = 0;
if (iot_sg_ext_data_clct_cur_di_update(node->data_type)) {
iot_sg_ext_data_clct_save(addr, func, node_tm);
*node_tm = iot_sg_ext_get_next_data_clct_ts(&tm, func);
goto done;
} else {
flag_new = 1;
goto send;
}
}
}
break;
}
default:
IOT_ASSERT(0);
break;
}
goto out;
done:
iot_sg_ext_data_clct_cur_func_done(func);
data_clct->config.cfg_is_latest = 0;
data_clct->cur_state = IOT_SG_STA_EXT_DC_STATE_IDLE;
goto next_func;
out:
if (last_state != data_clct->cur_state) {
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x state %lu to %lu\n"
, __FUNCTION__, addr[0], addr[1], addr[2], addr[3], addr[4],
addr[5], last_state, data_clct->cur_state);
}
return complete;
}
static uint32_t iot_sg_ext_frozen_time_data_valid_check(
proto_645_07_frozen_time_t *frozen_time)
{
uint32_t ret = ERR_INVAL;
uint8_t reason = 0;
iot_sg_sta_node_desc_t *node;
iot_time_tm_t *clct_tm, frozen_tm = { 0 };
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
if (!frozen_time) {
reason = 1;
goto out;
}
if (!iot_bcd_data_check((uint8_t *)frozen_time, sizeof(*frozen_time))) {
reason = 2;
goto out;
}
node = iot_sg_sta_node_find_by_addr(ext_info->addr);
if (!node) {
reason = 3;
goto out;
}
clct_tm = iot_sg_ext_data_clct_get_node_tm(node,
ext_info->data_clct.config.cur_func);
if (!clct_tm) {
reason = 4;
goto out;
}
frozen_tm.tm_year = iot_bcd_to_byte(frozen_time->year) + 2000;
frozen_tm.tm_mon = iot_bcd_to_byte(frozen_time->month);
frozen_tm.tm_mday = iot_bcd_to_byte(frozen_time->day);
frozen_tm.tm_hour = iot_bcd_to_byte(frozen_time->hour);
frozen_tm.tm_min = iot_bcd_to_byte(frozen_time->minute);
if (clct_tm->tm_year != frozen_tm.tm_year ||
clct_tm->tm_mon != frozen_tm.tm_mon ||
clct_tm->tm_mday != frozen_tm.tm_mday ||
iot_rtc_delta_calc(clct_tm, &frozen_tm) > 0) {
reason = 5;
goto out;
}
ret = ERR_OK;
out:
if (reason) {
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
}
return ret;
}
static uint32_t iot_sg_ext_data_clct_instant_tm_check()
{
int64_t delta;
uint32_t ret = ERR_INVAL;
iot_sg_sta_node_desc_t *node;
iot_time_tm_t *clct_tm, cur_tm = { 0 };
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
node = iot_sg_sta_node_find_by_addr(ext_info->addr);
if (!node) {
goto out;
}
clct_tm = iot_sg_ext_data_clct_get_node_tm(node,
ext_info->data_clct.config.cur_func);
if (!clct_tm) {
goto out;
}
if (iot_sg_sta_rtc_get(&cur_tm, 0)) {
goto out;
}
delta = iot_rtc_delta_calc(clct_tm, &cur_tm);
if (IOT_ABS(delta) < IOT_SG_STA_EXT_DC_INSTANT_CUR_MIN_INTER) {
ret = ERR_OK;
}
out:
return ret;
}
void iot_sg_ext_data_clct_handle(uint16_t seq,
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
uint8_t *req_data, uint16_t req_len)
{
uint32_t ret;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
(void)seq;
(void)data_type;
(void)resp_data;
(void)resp_len;
(void)req_data;
(void)req_len;
if (data_type == IOT_SG_STA_DATA_TYPE_645_07) {
ret = iot_sg_ext_read_645_07_data_handle(seq, data_type, resp_data,
resp_len, req_data, req_len, NULL);
} else if (data_type == IOT_SG_STA_DATA_TYPE_645_97) {
ret = iot_sg_ext_read_645_97_data_handle(seq, data_type, resp_data,
resp_len, req_data, req_len);
} else {
ret = iot_sg_ext_read_698_data_handle(seq, data_type, resp_data,
resp_len, req_data, req_len);
}
if (ext_info->data_clct.cur_clct_di ==
IOT_SG_STA_METER_TASK_DI_FROZEN_TIME && ext_info->frozen_data_flag) {
if (!iot_sg_ext_frozen_time_data_valid_check(&meter->frozen_time)) {
ext_info->data_clct.ft_valid = 1;
} else {
if (iot_sg_ext_data_clct_instant_tm_check()) {
/* instant data collection time and current time
* interval is too long, instant data is invalid.
* clear current di, current function is finished.
*/
iot_sg_ext_data_clct_cur_di_clear();
}
}
}
if (ret == ERR_OK || ret == ERR_TIMEOVER) {
if (ret == ERR_OK) {
ext_info->data_clct.flag_resp = 1;
}
ext_info->data_clct.timeout_cnt = 0;
iot_sg_sta_ext_sm_stop_action();
iot_sg_sta_ext_sm_next_action(IOT_SG_STA_EXT_SM_MIN_DELAY);
if (ret == ERR_OK) {
iot_sg_ext_data_clct_msg_num_update(0);
}
}
}
static void iot_sg_ext_data_clct_cfg_check()
{
uint8_t task_type;
iot_sg_meter_js_task_config_hdr_t cfg = { 0 };
for (task_type = 0; task_type < IOT_SG_STA_METER_JS_CFG_TYPE_MAX;
task_type++) {
if (iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, &cfg)) {
iot_sg_sta_ext_save_def_cfg_to_flash(task_type);
}
}
}
void iot_sg_sta_data_clct_task_init()
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
if (!data_clct->task_init) {
data_clct->df_en = 1;
data_clct->mf_en = 1;
data_clct->cur_1m_en = 1;
data_clct->cur_15m_en = 1;
data_clct->task_init = 1;
iot_sg_ext_data_clct_reset();
iot_sg_ext_data_clct_cfg_check();
}
}
static uint32_t iot_sg_sta_ext_sus_rsd_check(
proto_69845_data_cache_desc_t *rsd,
iot_sg_sta_ext_sus_query_desc_t *query_desc)
{
uint8_t reason = 0, i = 0, tsa_unit_len = 0;
uint32_t ret = ERR_FAIL, len;
proto_69845_app_data_rsd_t *rsd_hdr;
proto_69845_app_data_rsd_type10_t *rsd10_t;
proto_69845_app_data_ms_group_addr_t *group_addr;
proto_69845_app_data_tsa_t *p_tsa;
if (!rsd->data || !rsd->len) {
reason = 1;
goto drop;
}
len = rsd->len;
if (rsd->len < (sizeof(*rsd_hdr) + sizeof(*rsd10_t))) {
reason = 2;
goto drop;
}
rsd_hdr = (proto_69845_app_data_rsd_t*)rsd->data;
if (rsd_hdr->type != PROTO_OI_RSD_TYPE_10) {
reason = 3;
goto drop;
}
rsd10_t = (proto_69845_app_data_rsd_type10_t*)rsd_hdr->rsd_data;
if (rsd10_t->meter_set.type != PROTO_OI_MS_TYPE_GROUP_PM_ADDR) {
reason = 4;
goto drop;
}
len -= (sizeof(*rsd_hdr) + sizeof(*rsd10_t));
if (len < sizeof(*group_addr)) {
reason = 5;
goto drop;
}
group_addr =
(proto_69845_app_data_ms_group_addr_t*)rsd10_t->meter_set.ms_data;
if (!group_addr->cnt ||
group_addr->cnt > IOT_SG_STA_CONNECT_METER_MAX_CNT) {
reason = 6;
goto drop;
}
query_desc->cnt = group_addr->cnt;
tsa_unit_len = sizeof(proto_69845_app_data_tsa_t) + IOT_MAC_ADDR_LEN;
len -= sizeof(*group_addr);
if (len < (uint32_t)(tsa_unit_len * group_addr->cnt)) {
reason = 7;
goto drop;
}
for (i = 0; i < query_desc->cnt; i++) {
p_tsa = (proto_69845_app_data_tsa_t*)
&group_addr->tsa_data[i * tsa_unit_len];
iot_mac_addr_cpy(query_desc->addr[i], p_tsa->sa_and_ca);
iot_mac_addr_reverse(query_desc->addr[i]);
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint32_t iot_sg_sta_ext_clct_rsd_check(
proto_69845_data_cache_desc_t *rsd,
iot_sg_sta_ext_clct_query_desc_t *query_desc)
{
uint8_t reason = 0, i, addr_valid = 0;
uint32_t ret = ERR_FAIL, len;
proto_69845_app_data_rsd_t *rsd_hdr;
proto_69845_app_data_rsd_type678_t *rsd678_t;
proto_69845_app_data_ms_group_addr_t *group_addr;
proto_69845_app_data_tsa_t *addr;
proto_69845_app_data_ti_t tmp_ti = { 0 };
if (!rsd->data || !rsd->len) {
reason = 1;
goto drop;
}
if (rsd->len < (sizeof(*rsd_hdr) + sizeof(*rsd678_t))) {
reason = 2;
goto drop;
}
rsd_hdr = (proto_69845_app_data_rsd_t*)rsd->data;
if (rsd_hdr->type != PROTO_OI_RSD_TYPE_6 &&
rsd_hdr->type != PROTO_OI_RSD_TYPE_7 &&
rsd_hdr->type != PROTO_OI_RSD_TYPE_8) {
reason = 3;
goto drop;
}
rsd678_t = (proto_69845_app_data_rsd_type678_t*)rsd_hdr->rsd_data;
if (rsd678_t->meter_set.type != PROTO_OI_MS_TYPE_GROUP_PM_ADDR) {
reason = 4;
goto drop;
}
len = rsd->len - sizeof(*rsd_hdr) - sizeof(*rsd678_t);
if (len < sizeof(*group_addr)) {
reason = 5;
goto drop;
}
group_addr =
(proto_69845_app_data_ms_group_addr_t*)rsd678_t->meter_set.ms_data;
if (!group_addr->cnt) {
reason = 6;
goto drop;
}
len -= sizeof(*group_addr);
for (i = 0; i < group_addr->cnt; i++) {
if (len < (sizeof(*addr) + IOT_MAC_ADDR_LEN)) {
reason = 7;
goto drop;
}
addr = (proto_69845_app_data_tsa_t*)(group_addr->tsa_data +
sizeof(*addr) * i);
iot_mac_addr_cpy(query_desc->addr, addr->sa_and_ca);
iot_mac_addr_reverse(query_desc->addr);
len -= (sizeof(*addr) + IOT_MAC_ADDR_LEN);
if (iot_sg_sta_node_find_by_addr(query_desc->addr)) {
addr_valid = 1;
break;
}
}
if (!addr_valid) {
reason = 8;
goto drop;
}
tmp_ti.uint = rsd678_t->ti.uint;
tmp_ti.value = iot_bytes_to_uint16((uint8_t *)&rsd678_t->ti.value, 1);
query_desc->interval = proto_69845_ti_data_to_sec(&tmp_ti);
query_desc->start_ts.tm_year = iot_bytes_to_uint16(
(uint8_t*)&rsd678_t->start_time.year, 1);
query_desc->start_ts.tm_mon = rsd678_t->start_time.month;
query_desc->start_ts.tm_mday = rsd678_t->start_time.day;
query_desc->start_ts.tm_hour = rsd678_t->start_time.hour;
query_desc->start_ts.tm_min = rsd678_t->start_time.minute;
query_desc->start_ts.tm_sec = rsd678_t->start_time.second;
iot_sg_ext_set_integral_point(&query_desc->start_ts,
query_desc->interval, 1);
query_desc->end_ts.tm_year = iot_bytes_to_uint16(
(uint8_t*)&rsd678_t->end_time.year, 1);
query_desc->end_ts.tm_mon = rsd678_t->end_time.month;
query_desc->end_ts.tm_mday = rsd678_t->end_time.day;
query_desc->end_ts.tm_hour = rsd678_t->end_time.hour;
query_desc->end_ts.tm_min = rsd678_t->end_time.minute;
query_desc->end_ts.tm_sec = rsd678_t->end_time.second;
iot_sg_ext_set_integral_point(&query_desc->end_ts,
query_desc->interval, 0);
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint32_t iot_sg_sta_ext_oad_check(
proto_69845_app_road_t *road, uint32_t *bitmap)
{
uint8_t i, element_index;
uint32_t map = 0, oad_value;
proto_69845_app_oad_t *oad;
for (i = 0; i < road->cnt; i++) {
oad = &road->ass_oad[i];
element_index = oad->element_index;
oad_value = iot_bytes_to_uint32((uint8_t*)&oad->oi, 1);
oad_value &= 0xffffff00;
switch (oad_value) {
case PROTO_69845_APP_OAD_EPT_POS:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_POS);
}
break;
}
case PROTO_69845_APP_OAD_EPT_NEG:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_EPT_NEG);
}
break;
}
case PROTO_69845_APP_OAD_EQT_POS:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE1);
break;
}
case PROTO_69845_APP_OAD_EQT_NEG:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE2);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT1:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER);
}
break;
}
case PROTO_69845_APP_OAD_EQT_QRT2:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER);
}
break;
}
case PROTO_69845_APP_OAD_EQT_QRT3:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER);
}
break;
}
case PROTO_69845_APP_OAD_EQT_QRT4:
{
if (element_index == 1) {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM);
} else {
map |= (1 << IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER);
}
break;
}
case PROTO_69845_APP_OAD_EPT_POS_DEMAND:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME);
break;
}
case PROTO_69845_APP_OAD_EPT_NEG_DEMAND:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME);
break;
}
case PROTO_69845_APP_OAD_EQT_POS_DEMAND:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME);
break;
}
case PROTO_69845_APP_OAD_EQT_NEG_DEMAND:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME);
break;
}
case PROTO_69845_APP_OAD_VOLTAGE:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_VOLTAGE);
break;
}
case PROTO_69845_APP_OAD_CURRENT:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_CURRENT);
break;
}
case PROTO_69845_APP_OAD_GND_CURRENT:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT);
break;
}
case PROTO_69845_APP_OAD_P:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER);
break;
}
case PROTO_69845_APP_OAD_Q:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER);
break;
}
case PROTO_69845_APP_OAD_PF:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_POWER_FACTOR);
break;
}
case PROTO_69845_APP_OAD_FROZEN_T:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
break;
}
case PROTO_69845_APP_OAD_RUN_WORD:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_RUN_STATE);
break;
}
default:
break;
}
}
*bitmap = map;
if (map) {
return ERR_OK;
} else {
return ERR_FAIL;
}
}
static uint32_t iot_sg_sta_ext_1min_oad_check(
proto_69845_app_road_t *road, uint32_t *bitmap)
{
uint8_t i;
uint32_t map = 0, oad_value;
proto_69845_app_oad_t *oad;
for (i = 0; i < road->cnt; i++) {
oad = &road->ass_oad[i];
oad_value = iot_bytes_to_uint32((uint8_t*)&oad->oi, 1);
switch (oad_value) {
case PROTO_69845_APP_OAD_VOLTAGE:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_VOLTAGE);
break;
}
case PROTO_69845_APP_OAD_CURRENT:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_CURRENT);
break;
}
case PROTO_69845_APP_OAD_GND_CURRENT:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT);
break;
}
case PROTO_69845_APP_OAD_P:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER);
break;
}
case PROTO_69845_APP_OAD_Q:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER);
break;
}
case PROTO_69845_APP_OAD_PF:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_POWER_FACTOR);
break;
}
case PROTO_69845_APP_OAD_FROZEN_T:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
break;
}
case PROTO_69845_APP_OAD_TIME:
{
map |= (1 << IOT_SG_STA_METER_TASK_DI_TIME);
break;
}
default:
break;
}
}
*bitmap = map;
if (map) {
return ERR_OK;
} else {
return ERR_FAIL;
}
}
static uint32_t iot_sg_sta_ext_clct_road_check(
proto_69845_data_cache_desc_t *road,
iot_sg_sta_ext_clct_query_desc_t *query_desc)
{
uint8_t reason = 0;
uint32_t ret = ERR_FAIL, len, oad, oad_total_len;
proto_69845_app_road_t *road_hdr;
if (!road->data || !road->len) {
reason = 1;
goto drop;
}
if (road->len < sizeof(*road_hdr)) {
reason = 2;
goto drop;
}
road_hdr = (proto_69845_app_road_t*)road->data;
if (!road_hdr->cnt) {
reason = 3;
goto drop;
}
oad = iot_bytes_to_uint32((uint8_t*)&road_hdr->rec_oad, 1);
switch (oad) {
case PROTO_69845_APP_OAD_MINF:
{
if (query_desc->interval == IOT_SG_STA_EXT_DC_EXE_INTER_1MIN) {
query_desc->data_type = IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE;
} else if (query_desc->interval == IOT_SG_STA_EXT_DC_EXE_INTER_15MIN) {
query_desc->data_type = IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE;
} else {
reason = 4;
goto drop;
}
break;
}
case PROTO_69845_APP_OAD_DF:
{
query_desc->data_type = IOT_SG_STA_METER_DATA_TYPE_JS_DF;
break;
}
case PROTO_69845_APP_OAD_MF:
{
query_desc->data_type = IOT_SG_STA_METER_DATA_TYPE_JS_MF;
break;
}
default:
reason = 5;
goto drop;
}
len = road->len - sizeof(*road_hdr);
oad_total_len = proto_69845_get_normal_data_len(PROTO_69845_APP_DATA_OAD);
oad_total_len *= road_hdr->cnt;
if (len < oad_total_len) {
reason = 6;
goto drop;
}
if (query_desc->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE) {
if (iot_sg_sta_ext_oad_check(road_hdr, &query_desc->oad_map)) {
reason = 7;
goto drop;
}
} else {
if (iot_sg_sta_ext_1min_oad_check(road_hdr, &query_desc->oad_map)) {
reason = 8;
goto drop;
}
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint16_t iot_sg_sta_ext_get_rpt_csd_len(uint8_t oad_cnt)
{
uint16_t len;
len = sizeof(proto_69845_app_data_csd_t) + sizeof(proto_69845_app_road_t)
+ sizeof(proto_69845_app_oad_t) * oad_cnt;
return len;
}
static uint16_t iot_sg_sta_ext_get_rpt_road_len(uint8_t oad_cnt)
{
uint16_t len;
len = sizeof(proto_69845_app_road_t) +
oad_cnt * sizeof(proto_69845_app_oad_t);
return len;
}
static uint16_t iot_sg_sta_ext_get_rpt_unit_len(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
uint8_t i;
uint16_t len = 0;
len = sizeof(proto_69845_app_ele_data_t);
for (i = 0; i < IOT_SG_STA_METER_TASK_DI_MAX_CNT; i++) {
if ((1 << i) & rpt_info->oad_map) {
switch (i) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
len += sizeof(proto_69845_meter_energy_data_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
len += sizeof(proto_69845_rpt_meter_energy_sum_data_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
len += sizeof(proto_69845_rpt_demand_with_time_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
if (rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_v_3p_t);
} else {
len += sizeof(proto_69845_rpt_v_single_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
if (rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_i_3p_t);
} else {
len += sizeof(proto_69845_rpt_i_single_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
len += sizeof(proto_69845_rpt_i_single_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
if (rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_power_3p_t);
} else {
len += sizeof(proto_69845_rpt_power_single_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
if (rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_pf_3p_t);
} else {
len += sizeof(proto_69845_rpt_pf_single_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
case IOT_SG_STA_METER_TASK_DI_TIME:
{
len += sizeof(proto_69845_rpt_data_time_s_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
{
len += sizeof(proto_69845_rpt_rs_word_t);
break;
}
default:
break;
}
}
}
return len;
}
static uint16_t iot_sg_sta_ext_get_record_flash_cnt(
uint8_t data_type, uint16_t start_index, uint16_t end_index)
{
uint16_t cnt = 0, index_max;
switch (data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
index_max = IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
index_max = IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
index_max = IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
index_max = IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
break;
}
default:
goto out;
}
if ((start_index >= index_max)
|| (end_index >= index_max)) {
goto out;
}
if (end_index >= start_index) {
cnt = end_index - start_index + 1;
} else {
cnt = index_max - start_index + end_index + 1;
}
out:
return cnt;
}
static uint32_t iot_sg_sta_ext_di_to_oad(uint8_t di, uint8_t flag_3p,
uint8_t *ele_num, uint8_t *sig_oad)
{
uint8_t ele_num_ptr = 0, sig_oad_ptr = 0;
uint32_t oad = 0;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
oad = PROTO_69845_APP_OAD_EPT_POS;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
oad = PROTO_69845_APP_OAD_EPT_POS_SIG;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
oad = PROTO_69845_APP_OAD_EPT_NEG;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
oad = PROTO_69845_APP_OAD_EPT_NEG_SIG;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
oad = PROTO_69845_APP_OAD_EQT_POS;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
oad = PROTO_69845_APP_OAD_EQT_NEG;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
{
oad = PROTO_69845_APP_OAD_EQT_QRT1;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
{
oad = PROTO_69845_APP_OAD_EQT_QRT1_SUM;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
{
oad = PROTO_69845_APP_OAD_EQT_QRT2;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
{
oad = PROTO_69845_APP_OAD_EQT_QRT2_SUM;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
{
oad = PROTO_69845_APP_OAD_EQT_QRT3;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
{
oad = PROTO_69845_APP_OAD_EQT_QRT3_SUM;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
oad = PROTO_69845_APP_OAD_EQT_QRT4;
ele_num_ptr = IOT_SG_STA_EXT_ENERGY_ELE_NUM;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
oad = PROTO_69845_APP_OAD_EQT_QRT4_SUM;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
{
oad = PROTO_69845_APP_OAD_EPT_POS_DEMAND;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
{
oad = PROTO_69845_APP_OAD_EPT_NEG_DEMAND;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
{
oad = PROTO_69845_APP_OAD_EQT_POS_DEMAND;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
oad = PROTO_69845_APP_OAD_EQT_NEG_DEMAND;
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
if (flag_3p) {
oad = PROTO_69845_APP_OAD_VOLTAGE;
ele_num_ptr = IOT_SG_STA_EXT_3P_V_ELE_NUM;
} else {
oad = PROTO_69845_APP_OAD_VOLTAGE_A;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
if (flag_3p) {
oad = PROTO_69845_APP_OAD_CURRENT;
ele_num_ptr = IOT_SG_STA_EXT_3P_I_ELE_NUM;
} else {
oad = PROTO_69845_APP_OAD_CURRENT_A;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
oad = PROTO_69845_APP_OAD_GND_CURRENT;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
{
oad = PROTO_69845_APP_OAD_P;
if (flag_3p) {
ele_num_ptr = IOT_SG_STA_EXT_3P_P_ELE_NUM;
} else {
ele_num_ptr = IOT_SG_STA_EXT_SIG_MORE_ELE_NUM;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
oad = PROTO_69845_APP_OAD_Q;
if (flag_3p) {
ele_num_ptr = IOT_SG_STA_EXT_3P_P_ELE_NUM;
} else {
ele_num_ptr = IOT_SG_STA_EXT_SIG_MORE_ELE_NUM;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
oad = PROTO_69845_APP_OAD_PF;
if (flag_3p) {
ele_num_ptr = IOT_SG_STA_EXT_3P_P_ELE_NUM;
} else {
ele_num_ptr = IOT_SG_STA_EXT_SIG_MORE_ELE_NUM;
}
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
oad = PROTO_69845_APP_OAD_FROZEN_T;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
oad = PROTO_69845_APP_OAD_TIME;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
{
oad = PROTO_69845_APP_OAD_RUN_WORD;
ele_num_ptr = IOT_SG_STA_EXT_SIG_OAD_ELE_NUM;
sig_oad_ptr = 1;
break;
}
default:
break;
}
if (ele_num) {
*ele_num = ele_num_ptr;
}
if (sig_oad) {
*sig_oad = sig_oad_ptr;
}
return oad;
}
static uint32_t iot_sg_sta_ext_rpt_road_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt)
{
uint8_t i, m;
uint32_t ret = ERR_FAIL, oad, bm;
proto_69845_app_road_t *road;
if (len < (sizeof(*road) + oad_cnt * sizeof(proto_69845_app_oad_t))) {
goto out;
}
road = (proto_69845_app_road_t*)data;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
oad = PROTO_69845_APP_OAD_MF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
oad = PROTO_69845_APP_OAD_DF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
oad = PROTO_69845_APP_OAD_MINF;
break;
}
default:
goto out;
}
iot_uint32_to_bytes(oad, (uint8_t*)&road->rec_oad, 1);
road->cnt = oad_cnt;
bm = rpt_info->oad_map;
m = 1;
for (i = 0; i < road->cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto out;
}
oad = iot_sg_sta_ext_di_to_oad(m - 1, rpt_info->flag_3p, NULL, NULL);
iot_uint32_to_bytes(oad, (uint8_t*)&road->ass_oad[i], 1);
m++;
}
ret = ERR_OK;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_rpt_csd_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt)
{
uint8_t i, m;
uint32_t ret = ERR_FAIL, oad, bm;
proto_69845_app_data_csd_t *csd;
proto_69845_app_road_t *road;
if (len < (sizeof(*csd) + sizeof(*road) +
oad_cnt * sizeof(proto_69845_app_oad_t))) {
goto out;
}
csd = (proto_69845_app_data_csd_t*)data;
csd->type = 1;
road = (proto_69845_app_road_t*)csd->csd_data;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
oad = PROTO_69845_APP_OAD_MF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
oad = PROTO_69845_APP_OAD_DF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
oad = PROTO_69845_APP_OAD_MINF;
break;
}
default:
goto out;
}
iot_uint32_to_bytes(oad, (uint8_t*)&road->rec_oad, 1);
road->cnt = oad_cnt;
bm = rpt_info->oad_map;
m = 1;
for (i = 0; i < road->cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto out;
}
oad = iot_sg_sta_ext_di_to_oad(m - 1, rpt_info->flag_3p, NULL, NULL);
iot_uint32_to_bytes(oad, (uint8_t*)&road->ass_oad[i], 1);
m++;
}
ret = ERR_OK;
out:
return ret;
}
static void iot_sg_sta_ext_energy_fill(uint8_t *src, uint8_t *dst,
uint8_t flag_sign)
{
uint8_t flag_neg = 0;
uint32_t cache_value;
if (flag_sign) {
cache_value = 0x7fffffff;
flag_neg = !!(0x80 & src[IOT_SG_STA_METER_ENERGY_DATA_LEN - 1]);
src[IOT_SG_STA_METER_ENERGY_DATA_LEN - 1] &= 0x7f;
} else {
cache_value = 0xffffffff;
}
if (src && iot_bcd_data_check(src, IOT_SG_STA_METER_ENERGY_DATA_LEN)) {
iot_bcd_to_uint32(src, IOT_SG_STA_METER_ENERGY_DATA_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
}
iot_uint32_to_bytes(cache_value, dst, 1);
}
static void iot_sg_sta_ext_demand_with_t_fill(
iot_sg_meter_max_demand_and_ht_t *src,
proto_69845_rpt_demand_with_time_t *dst, uint8_t flag_sign)
{
uint8_t flag_neg = 0;
uint32_t cache_value;
if (flag_sign) {
cache_value = 0x7fffffff;
flag_neg = !!(0x80 & src->max_demand[IOT_SG_STA_METER_POWER_LEN - 1]);
src->max_demand[IOT_SG_STA_METER_POWER_LEN - 1] &= 0x7f;
} else {
cache_value = 0xffffffff;
}
if (src && iot_bcd_data_check((uint8_t*)src, sizeof(*src))) {
iot_bcd_to_uint32(src->max_demand, IOT_SG_STA_METER_POWER_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, dst->demand, 1);
if (!cache_value) {
os_mem_set(&dst->time, 0x0, sizeof(dst->time));
} else {
cache_value = iot_bcd_to_byte(src->year) + 2000;
iot_uint16_to_bytes((uint16_t)cache_value,
(uint8_t*)&dst->time.year, 1);
dst->time.month = iot_bcd_to_byte(src->month);
dst->time.day = iot_bcd_to_byte(src->day);
dst->time.hour = iot_bcd_to_byte(src->hour);
dst->time.minute = iot_bcd_to_byte(src->minute);
dst->time.second = 0;
}
} else {
iot_uint32_to_bytes(cache_value, dst->demand, 1);
iot_uint16_to_bytes(0xffff, (uint8_t*)&dst->time.year, 1);
dst->time.month = 0xff;
dst->time.day = 0xff;
dst->time.hour = 0xff;
dst->time.minute = 0xff;
dst->time.second = 0xff;
}
}
static uint32_t iot_sg_sta_ext_rpt_v_fill(proto_645_v_t *src_v,
uint8_t *ptr, uint32_t rec_len, uint8_t flag_3p)
{
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_v_3p_t *v_3p_t;
proto_69845_rpt_v_single_t *v_t;
if (flag_3p) {
if (rec_len < sizeof(*v_3p_t)) {
goto out;
}
v_3p_t = (proto_69845_rpt_v_3p_t*)ptr;
v_3p_t->type = PROTO_69845_APP_DATA_ARRAY;
v_3p_t->cnt = 3;
v_3p_t->type0 = PROTO_69845_APP_DATA_LONG_UNSIGNED;
v_3p_t->type1 = PROTO_69845_APP_DATA_LONG_UNSIGNED;
v_3p_t->type2 = PROTO_69845_APP_DATA_LONG_UNSIGNED;
if (iot_bcd_data_check(src_v->a, sizeof(src_v->a))) {
iot_bcd_to_uint32(src_v->a, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->a, 1);
} else {
os_mem_set(v_3p_t->a, 0xff, sizeof(v_3p_t->a));
}
if (iot_bcd_data_check(src_v->b, sizeof(src_v->b))) {
iot_bcd_to_uint32(src_v->b, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->b, 1);
} else {
os_mem_set(v_3p_t->b, 0xff, sizeof(v_3p_t->b));
}
if (iot_bcd_data_check(src_v->c, sizeof(src_v->c))) {
iot_bcd_to_uint32(src_v->c, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->c, 1);
} else {
os_mem_set(v_3p_t->c, 0xff, sizeof(v_3p_t->c));
}
fill_len = sizeof(*v_3p_t);
} else {
if (rec_len < sizeof(*v_t)) {
goto out;
}
v_t = (proto_69845_rpt_v_single_t*)ptr;
v_t->type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
if (iot_bcd_data_check(src_v->a, sizeof(src_v->a))) {
iot_bcd_to_uint32(src_v->a, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_t->a, 1);
} else {
os_mem_set(v_t->a, 0xff, sizeof(v_t->a));
}
fill_len = sizeof(*v_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_single_i_fill(uint8_t *i,
uint8_t *ptr, uint32_t rec_len)
{
uint8_t flag_neg;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_i_single_t *i_t;
if (rec_len < sizeof(*i_t)) {
goto out;
}
i_t = (proto_69845_rpt_i_single_t*)ptr;
flag_neg = !!(0x80 & i[PROTO_645_07_A_LEN - 1]);
i[PROTO_645_07_A_LEN - 1] &= 0x7f;
i_t->type = PROTO_69845_APP_DATA_DOUBLE_LONG;
if (iot_bcd_data_check(i, PROTO_645_07_A_LEN)) {
iot_bcd_to_uint32(i, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_t->a, 1);
}
fill_len = sizeof(*i_t);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_i_fill(proto_645_07_a_t *src_i,
uint8_t *ptr, uint32_t rec_len, uint8_t flag_3p)
{
uint8_t flag_neg;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_i_3p_t *i_3p_t;
if (flag_3p) {
if (rec_len < sizeof(*i_3p_t)) {
goto out;
}
i_3p_t = (proto_69845_rpt_i_3p_t*)ptr;
i_3p_t->type = PROTO_69845_APP_DATA_ARRAY;
i_3p_t->cnt = 3;
i_3p_t->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG;
i_3p_t->type1 = PROTO_69845_APP_DATA_DOUBLE_LONG;
i_3p_t->type2 = PROTO_69845_APP_DATA_DOUBLE_LONG;
flag_neg = !!(0x80 & src_i->a[PROTO_645_07_A_LEN - 1]);
src_i->a[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_i->a, sizeof(src_i->a))) {
iot_bcd_to_uint32(src_i->a, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_i->b[PROTO_645_07_A_LEN - 1]);
src_i->b[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_i->b, sizeof(src_i->b))) {
iot_bcd_to_uint32(src_i->b, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->b, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_i->c[PROTO_645_07_A_LEN - 1]);
src_i->c[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_i->c, sizeof(src_i->c))) {
iot_bcd_to_uint32(src_i->c, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->c, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->c, 1);
}
fill_len = sizeof(*i_3p_t);
} else {
fill_len = iot_sg_sta_ext_rpt_single_i_fill(src_i->a, ptr, rec_len);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_power_fill(
proto_645_07_p_t *src_power, uint8_t *ptr, uint32_t rec_len,
uint8_t flag_3p)
{
uint8_t flag_neg;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_power_3p_t *power_3p_t;
proto_69845_rpt_power_single_t *power_t;
if (flag_3p) {
if (rec_len < sizeof(*power_3p_t)) {
goto out;
}
power_3p_t = (proto_69845_rpt_power_3p_t*)ptr;
power_3p_t->type = PROTO_69845_APP_DATA_ARRAY;
power_3p_t->cnt = 4;
power_3p_t->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG;
power_3p_t->type1 = PROTO_69845_APP_DATA_DOUBLE_LONG;
power_3p_t->type2 = PROTO_69845_APP_DATA_DOUBLE_LONG;
power_3p_t->type3 = PROTO_69845_APP_DATA_DOUBLE_LONG;
flag_neg = !!(0x80 & src_power->total[PROTO_645_07_P_LEN - 1]);
src_power->total[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->total, sizeof(src_power->total))) {
iot_bcd_to_uint32(src_power->total, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->total, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->total, 1);
}
flag_neg = !!(0x80 & src_power->a[PROTO_645_07_P_LEN - 1]);
src_power->a[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->a, sizeof(src_power->a))) {
iot_bcd_to_uint32(src_power->a, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_power->b[PROTO_645_07_P_LEN - 1]);
src_power->b[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->b, sizeof(src_power->b))) {
iot_bcd_to_uint32(src_power->b, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->b, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_power->c[PROTO_645_07_P_LEN - 1]);
src_power->c[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->c, sizeof(src_power->c))) {
iot_bcd_to_uint32(src_power->c, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->c, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->c, 1);
}
fill_len = sizeof(*power_3p_t);
} else {
if (rec_len < sizeof(*power_t)) {
goto out;
}
power_t = (proto_69845_rpt_power_single_t*)ptr;
power_t->type = PROTO_69845_APP_DATA_ARRAY;
power_t->cnt = 2;
power_t->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG;
power_t->type1 = PROTO_69845_APP_DATA_DOUBLE_LONG;
flag_neg = !!(0x80 & src_power->total[PROTO_645_07_P_LEN - 1]);
src_power->total[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->total,
sizeof(src_power->total))) {
iot_bcd_to_uint32(src_power->total, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_t->total, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_t->total, 1);
}
flag_neg = !!(0x80 & src_power->a[PROTO_645_07_P_LEN - 1]);
src_power->a[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->a, sizeof(src_power->a))) {
iot_bcd_to_uint32(src_power->a, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_t->a, 1);
}
fill_len = sizeof(*power_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_pf_fill(
proto_645_07_pf_t *src_pf, uint8_t *ptr, uint32_t rec_len,
uint8_t flag_3p)
{
uint8_t flag_neg;
uint16_t cache = 0;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_pf_3p_t *pf_3p_t;
proto_69845_rpt_pf_single_t *pf_t;
if (flag_3p) {
if (rec_len < sizeof(*pf_3p_t)) {
goto out;
}
pf_3p_t = (proto_69845_rpt_pf_3p_t*)ptr;
pf_3p_t->type = PROTO_69845_APP_DATA_ARRAY;
pf_3p_t->cnt = 4;
pf_3p_t->type0 = PROTO_69845_APP_DATA_LONG;
pf_3p_t->type1 = PROTO_69845_APP_DATA_LONG;
pf_3p_t->type2 = PROTO_69845_APP_DATA_LONG;
pf_3p_t->type3 = PROTO_69845_APP_DATA_LONG;
flag_neg = !!(0x80 & src_pf->total[PROTO_645_07_PF_LEN - 1]);
src_pf->total[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->total, sizeof(src_pf->total))) {
iot_bcd_to_uint32(src_pf->total, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->total, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->total, 1);
}
flag_neg = !!(0x80 & src_pf->a[PROTO_645_07_PF_LEN - 1]);
src_pf->a[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->a, sizeof(src_pf->a))) {
iot_bcd_to_uint32(src_pf->a, PROTO_645_07_PF_LEN, 0, &cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->a, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_pf->b[PROTO_645_07_PF_LEN - 1]);
src_pf->b[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->b, sizeof(src_pf->b))) {
iot_bcd_to_uint32(src_pf->b, PROTO_645_07_PF_LEN, 0, &cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->b, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_pf->c[PROTO_645_07_PF_LEN - 1]);
src_pf->c[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->c, sizeof(src_pf->c))) {
iot_bcd_to_uint32(src_pf->c, PROTO_645_07_PF_LEN, 0, &cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->c, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->c, 1);
}
fill_len = sizeof(*pf_3p_t);
} else {
if (rec_len < sizeof(*pf_t)) {
goto out;
}
pf_t = (proto_69845_rpt_pf_single_t*)ptr;
pf_t->type = PROTO_69845_APP_DATA_ARRAY;
pf_t->cnt = 2;
pf_t->type0 = PROTO_69845_APP_DATA_LONG;
pf_t->type1 = PROTO_69845_APP_DATA_LONG;
flag_neg = !!(0x80 & src_pf->total[PROTO_645_07_PF_LEN - 1]);
src_pf->total[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->total, sizeof(src_pf->total))) {
iot_bcd_to_uint32(src_pf->total, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_t->total, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_t->total, 1);
}
flag_neg = !!(0x80 & src_pf->a[PROTO_645_07_PF_LEN - 1]);
src_pf->a[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->a, sizeof(src_pf->a))) {
iot_bcd_to_uint32(src_pf->a, PROTO_645_07_PF_LEN, 0, &cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_t->a, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_t->a, 1);
}
fill_len = sizeof(*pf_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_ftime_fill(uint32_t *time, uint8_t *ptr,
uint32_t rec_len)
{
uint32_t fill_len = 0, cache_value;
proto_69845_rpt_data_time_s_t *rpt_time;
iot_sg_meter_unit_time_t *unit_time;
if (rec_len < sizeof(*rpt_time)) {
goto out;
}
rpt_time = (proto_69845_rpt_data_time_s_t*)ptr;
rpt_time->type = PROTO_69845_APP_DATA_TIME_S;
if (*time == 0xffffffff) {
iot_uint16_to_bytes(0xffff, (uint8_t*)&rpt_time->year, 1);
rpt_time->month = 0xff;
rpt_time->day = 0xff;
rpt_time->hour = 0xff;
rpt_time->minute = 0xff;
rpt_time->second = 0xff;
} else {
unit_time = (iot_sg_meter_unit_time_t *)time;
cache_value = unit_time->year + 2000;
iot_uint16_to_bytes((uint16_t)cache_value,
(uint8_t*)&rpt_time->year, 1);
rpt_time->month = (uint8_t)unit_time->month;
rpt_time->day = (uint8_t)unit_time->day;
rpt_time->hour = (uint8_t)unit_time->hour;
rpt_time->minute = (uint8_t)unit_time->minute;
rpt_time->second = 0;
}
fill_len = sizeof(*rpt_time);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_rs_state_fill(iot_sg_meter_rs_word_t *rs_word,
uint8_t *ptr, uint32_t rec_len)
{
uint32_t fill_len = 0;
proto_69845_rpt_rs_word_t *rpt_rs_word;
if (rec_len < sizeof(*rpt_rs_word)) {
goto out;
}
rpt_rs_word = (proto_69845_rpt_rs_word_t *)ptr;
if (rs_word->valid_flag == 0xff) {
os_mem_set(rs_word, 0x0, sizeof(*rs_word));
}
rpt_rs_word->type = PROTO_69845_APP_DATA_ARRAY;
rpt_rs_word->cnt = 7;
rpt_rs_word->data_type1 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type1 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_1, &rs_word->rs_word_1,
sizeof(rs_word->rs_word_1));
rpt_rs_word->data_type2 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type2 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_2, &rs_word->rs_word_2,
sizeof(rs_word->rs_word_2));
rpt_rs_word->data_type3 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type3 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_3, &rs_word->rs_word_3,
sizeof(rs_word->rs_word_3));
rpt_rs_word->data_type4 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type4 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_4, &rs_word->rs_word_4,
sizeof(rs_word->rs_word_4));
rpt_rs_word->data_type5 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type5 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_5, &rs_word->rs_word_5,
sizeof(rs_word->rs_word_5));
rpt_rs_word->data_type6 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type6 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_6, &rs_word->rs_word_6,
sizeof(rs_word->rs_word_6));
rpt_rs_word->data_type7 = PROTO_69845_APP_DATA_BIT_STRING;
rpt_rs_word->type7 = PROTO_69845_APP_DATA_LONG;
os_mem_cpy(&rpt_rs_word->rs_word_7, &rs_word->rs_word_7,
sizeof(rs_word->rs_word_7));
fill_len = sizeof(*rpt_rs_word);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_cur_time_fill(iot_sg_meter_cur_time_t *time,
uint8_t *ptr, uint32_t rec_len)
{
uint32_t fill_len = 0, cache_value;
proto_69845_rpt_data_time_s_t *rpt_time;
if (rec_len < sizeof(*rpt_time)) {
goto out;
}
rpt_time = (proto_69845_rpt_data_time_s_t*)ptr;
rpt_time->type = PROTO_69845_APP_DATA_TIME_S;
if (time->second == 0xff) {
iot_uint16_to_bytes(0xffff, (uint8_t*)&rpt_time->year, 1);
rpt_time->month = 0xff;
rpt_time->day = 0xff;
rpt_time->hour = 0xff;
rpt_time->minute = 0xff;
rpt_time->second = 0xff;
} else {
cache_value = time->year + 2000;
iot_uint16_to_bytes((uint16_t)cache_value,
(uint8_t*)&rpt_time->year, 1);
rpt_time->month = (uint8_t)time->month;
rpt_time->day = (uint8_t)time->day;
rpt_time->hour = (uint8_t)time->hour;
rpt_time->minute = (uint8_t)time->minute;
rpt_time->second = (uint8_t)time->second;
}
fill_len = sizeof(*rpt_time);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_nomin_data_uint_fill(
iot_sg_meter_js_frozen_uint_data_t *frozen_t, uint8_t oad_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, i, di, flag_sign;
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
proto_69845_app_ele_data_t *uint_hdr;
uint_hdr = (proto_69845_app_ele_data_t*)ptr;
uint_hdr->data_type = PROTO_69845_APP_DATA_ARRAY;
uint_hdr->num_of_data = oad_cnt;
ptr += sizeof(*uint_hdr);
for (i = 0; i < oad_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
iot_sg_meter_energy_data_t *src_energy = NULL;
proto_69845_meter_energy_data_t *dst_energy;
if (rec_len < sizeof(*dst_energy)) {
goto drop;
}
dst_energy = (proto_69845_meter_energy_data_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
src_energy = &frozen_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
src_energy = &frozen_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
src_energy = &frozen_t->cre1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
src_energy = &frozen_t->cre2;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
{
src_energy = &frozen_t->re_1st_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
{
src_energy = &frozen_t->re_2nd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
{
src_energy = &frozen_t->re_3rd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
src_energy = &frozen_t->re_4th_power;
break;
}
default:
goto drop;
}
dst_energy->type = PROTO_69845_APP_DATA_ARRAY;
dst_energy->cnt = 5;
dst_energy->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy->total,
dst_energy->total, 0);
dst_energy->type1 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy->rate_1,
dst_energy->rate_1, 0);
dst_energy->type2 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy->rate_2,
dst_energy->rate_2, 0);
dst_energy->type3 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy->rate_3,
dst_energy->rate_3, 0);
dst_energy->type4 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy->rate_4,
dst_energy->rate_4, 0);
rec_len -= sizeof(*dst_energy);
ptr += sizeof(*dst_energy);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
iot_sg_meter_energy_data_t *src_sum = NULL;
proto_69845_rpt_meter_energy_sum_data_t *dst_sum;
if (rec_len < sizeof(*dst_sum)) {
goto drop;
}
dst_sum = (proto_69845_rpt_meter_energy_sum_data_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
src_sum = &frozen_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
src_sum = &frozen_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
{
src_sum = &frozen_t->re_1st_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
{
src_sum = &frozen_t->re_2nd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
{
src_sum = &frozen_t->re_3rd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
src_sum = &frozen_t->re_4th_power;
break;
}
default:
goto drop;
}
dst_sum->type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_sum->total, dst_sum->total, 0);
rec_len -= sizeof(*dst_sum);
ptr += sizeof(*dst_sum);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
iot_sg_meter_max_demand_and_ht_t *src_dem_time = NULL;
proto_69845_rpt_demand_with_time_t *dst_dem_time;
if (rec_len < sizeof(*dst_dem_time)) {
goto drop;
}
dst_dem_time = (proto_69845_rpt_demand_with_time_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
{
src_dem_time = &frozen_t->pos_act_dem_time;
flag_sign = 0;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
{
src_dem_time = &frozen_t->neg_atc_dem_time;
flag_sign = 0;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
{
src_dem_time = &frozen_t->com_react1_dem_time;
flag_sign = 1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
src_dem_time = &frozen_t->com_reatc2_dem_time;
flag_sign = 1;
break;
}
default:
goto drop;
}
dst_dem_time->type = PROTO_69845_APP_DATA_STRUCTURE;
dst_dem_time->cnt = 2;
if (flag_sign) {
dst_dem_time->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG;
} else {
dst_dem_time->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
}
dst_dem_time->type1 = PROTO_69845_APP_DATA_TIME_S;
iot_sg_sta_ext_demand_with_t_fill(src_dem_time, dst_dem_time,
flag_sign);
rec_len -= sizeof(*dst_dem_time);
ptr += sizeof(*dst_dem_time);
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
fill_len = iot_sg_sta_ext_rpt_v_fill(&frozen_t->v, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_i_fill(&frozen_t->i, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_fill(frozen_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
src_power = &frozen_t->active_power;
} else {
src_power = &frozen_t->reactive_power;
}
fill_len = iot_sg_sta_ext_rpt_power_fill(src_power, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
fill_len = iot_sg_sta_ext_rpt_pf_fill(&frozen_t->power_factor, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_fill((uint32_t *)frozen_t, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_RUN_STATE:
{
fill_len = iot_sg_sta_ext_rpt_rs_state_fill(&frozen_t->rs_word, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_min_data_uint_fill(
iot_sg_meter_js_min_curve_uint_data_t *min_t, uint8_t oad_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, i, di;
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
proto_69845_app_ele_data_t *uint_hdr;
uint_hdr = (proto_69845_app_ele_data_t*)ptr;
uint_hdr->data_type = PROTO_69845_APP_DATA_ARRAY;
uint_hdr->num_of_data = oad_cnt;
ptr += sizeof(*uint_hdr);
for (i = 0; i < oad_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
fill_len = iot_sg_sta_ext_rpt_v_fill(&min_t->v, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_i_fill(&min_t->i, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_fill(min_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
src_power = &min_t->active_power;
} else {
src_power = &min_t->reactive_power;
}
fill_len = iot_sg_sta_ext_rpt_power_fill(src_power, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
fill_len = iot_sg_sta_ext_rpt_pf_fill(&min_t->power_factor, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_fill((uint32_t *)min_t, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
fill_len = iot_sg_sta_ext_rpt_cur_time_fill(&min_t->time, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_sig_data_uint_fill(
iot_sg_meter_js_sig_frozen_uint_data_t *sig_t, uint8_t oad_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, n, di, *src_energy = NULL, buf[SIG_CACHE_BUF];
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
proto_69845_app_ele_data_t *uint_hdr;
uint_hdr = (proto_69845_app_ele_data_t*)ptr;
uint_hdr->data_type = PROTO_69845_APP_DATA_ARRAY;
uint_hdr->num_of_data = oad_cnt;
ptr += sizeof(*uint_hdr);
for (n = 0; n < oad_cnt; n++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
proto_69845_meter_energy_data_t *dst_energy;
if (rec_len < sizeof(*dst_energy)) {
goto drop;
}
dst_energy = (proto_69845_meter_energy_data_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
src_energy = sig_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
src_energy = sig_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
src_energy = sig_t->cre1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
src_energy = sig_t->cre2;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
src_energy = NULL;
break;
}
default:
goto drop;
}
dst_energy->type = PROTO_69845_APP_DATA_ARRAY;
dst_energy->cnt = 5;
dst_energy->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy, dst_energy->total, 0);
dst_energy->type1 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_1, 0);
dst_energy->type2 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_2, 0);
dst_energy->type3 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_3, 0);
dst_energy->type4 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_4, 0);
rec_len -= sizeof(*dst_energy);
ptr += sizeof(*dst_energy);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
proto_69845_rpt_meter_energy_sum_data_t *dst_sum;
if (rec_len < sizeof(*dst_sum)) {
goto drop;
}
dst_sum = (proto_69845_rpt_meter_energy_sum_data_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
src_energy = sig_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
src_energy = sig_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
src_energy = NULL;
break;
}
default:
goto drop;
}
dst_sum->type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_energy_fill(src_energy, dst_sum->total, 0);
rec_len -= sizeof(*dst_sum);
ptr += sizeof(*dst_sum);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
proto_69845_rpt_demand_with_time_t *dst_dem_time;
if (rec_len < sizeof(*dst_dem_time)) {
goto drop;
}
dst_dem_time = (proto_69845_rpt_demand_with_time_t*)ptr;
dst_dem_time->type = PROTO_69845_APP_DATA_STRUCTURE;
dst_dem_time->cnt = 2;
dst_dem_time->type1 = PROTO_69845_APP_DATA_TIME_S;
if (di == IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME
|| di == IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME) {
dst_dem_time->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_sg_sta_ext_demand_with_t_fill(NULL, dst_dem_time, 0);
} else {
dst_dem_time->type0 = PROTO_69845_APP_DATA_DOUBLE_LONG;
iot_sg_sta_ext_demand_with_t_fill(NULL, dst_dem_time, 1);
}
rec_len -= sizeof(*dst_dem_time);
ptr += sizeof(*dst_dem_time);
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
proto_645_v_t *v;
BUILD_BUG_ON(sizeof(*v) <= SIG_CACHE_BUF);
v = (proto_645_v_t*)buf;
os_mem_set(v, 0xff, sizeof(*v));
os_mem_cpy(v->a, sig_t->v, PROTO_645_V_LEN);
fill_len = iot_sg_sta_ext_rpt_v_fill(v, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
proto_645_07_a_t *i;
BUILD_BUG_ON(sizeof(*i) <= SIG_CACHE_BUF);
i = (proto_645_07_a_t*)buf;
os_mem_set(i, 0xff, sizeof(*i));
os_mem_cpy(i->a, sig_t->i, PROTO_645_07_A_LEN);
fill_len = iot_sg_sta_ext_rpt_i_fill(i, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_fill(sig_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
BUILD_BUG_ON(sizeof(*src_power) <= SIG_CACHE_BUF);
src_power = (proto_645_07_p_t*)buf;
os_mem_set(src_power, 0xff, sizeof(*src_power));
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
os_mem_cpy(src_power->total, sig_t->active_power,
PROTO_645_07_P_LEN);
os_mem_cpy(src_power->a, sig_t->active_power,
PROTO_645_07_P_LEN);
} else {
os_mem_cpy(src_power->total, sig_t->reactive_power,
PROTO_645_07_P_LEN);
os_mem_cpy(src_power->a, sig_t->reactive_power,
PROTO_645_07_P_LEN);
}
fill_len = iot_sg_sta_ext_rpt_power_fill(src_power, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
proto_645_07_pf_t *power_factor;
BUILD_BUG_ON(sizeof(*power_factor) <= SIG_CACHE_BUF);
power_factor = (proto_645_07_pf_t*)buf;
os_mem_set(power_factor, 0xff, sizeof(*power_factor));
os_mem_cpy(power_factor->total, sig_t->power_factor,
PROTO_645_07_PF_LEN);
os_mem_cpy(power_factor->a, sig_t->power_factor,
PROTO_645_07_PF_LEN);
fill_len = iot_sg_sta_ext_rpt_pf_fill(power_factor, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_fill((uint32_t *)sig_t, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
fill_len = iot_sg_sta_ext_rpt_cur_time_fill(&sig_t->time, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_clct_rcsd_check(
proto_69845_data_cache_desc_t *rcsd,
iot_sg_sta_ext_clct_query_desc_t *query_desc)
{
uint8_t reason = 0, i, *ptr;
uint32_t ret = ERR_FAIL, csd_len, cache_len;
proto_69845_app_data_rcsd_t *rcsd_hdr;
proto_69845_app_data_csd_t *csd_hdr;
proto_69845_data_cache_desc_t road;
if (!rcsd->data || !rcsd->len) {
reason = 1;
goto drop;
}
if (rcsd->len < sizeof(*rcsd_hdr)) {
reason = 2;
goto drop;
}
rcsd_hdr = (proto_69845_app_data_rcsd_t *)rcsd->data;
if (!rcsd_hdr->cnt) {
reason = 3;
goto drop;
}
csd_len = rcsd->len - sizeof(*rcsd_hdr);
ptr = rcsd_hdr->csd_list;
for (i = 0; i < rcsd_hdr->cnt; i++) {
cache_len = 0;
if (proto_69845_get_csd_data_len(ptr, csd_len, &cache_len)) {
reason = 4;
goto drop;
}
if (csd_len < cache_len) {
reason = 5;
goto drop;
}
csd_hdr = (proto_69845_app_data_csd_t *)ptr;
if (csd_hdr->type != PROTO_OI_CSD_TYPE_ROAD) {
csd_len -= cache_len;
ptr += cache_len;
continue;
}
road.data = csd_hdr->csd_data;
road.len = cache_len;
if (iot_sg_sta_ext_clct_road_check(&road, query_desc)) {
reason = 6;
goto drop;
}
ret = ERR_OK;
goto out;
}
reason = 7;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint16_t iot_sg_sta_ext_data_clct_get_interval_cnt(uint8_t *data,
uint16_t data_len, int64_t interval, iot_time_tm_t *last_tm)
{
int64_t cur_interval;
uint16_t interval_cnt = 0;
iot_time_tm_t cur_tm = { 0 };
iot_sg_meter_unit_time_t *unit_time;
if (!data || !last_tm) {
goto out;
}
if (data_len < sizeof(*unit_time)) {
goto out;
}
unit_time = (iot_sg_meter_unit_time_t *)data;
cur_tm.tm_year = (uint16_t)(unit_time->year + 2000);
cur_tm.tm_mon = (uint8_t)unit_time->month;
cur_tm.tm_mday = (uint8_t)unit_time->day;
cur_tm.tm_hour = (uint8_t)unit_time->hour;
cur_tm.tm_min = (uint8_t)unit_time->minute;
cur_interval = iot_rtc_delta_calc(last_tm, &cur_tm);
if (cur_interval < 0) {
goto out;
}
if (interval < IOT_SG_STA_EXT_DC_EXE_INTER_1MON) {
interval_cnt = (uint16_t)(cur_interval / interval);
} else {
interval_cnt = (cur_tm.tm_year * 12 + cur_tm.tm_mon) -
(last_tm->tm_year * 12 + last_tm->tm_mon);
}
out:
return interval_cnt;
}
static iot_time_tm_t iot_sg_ext_get_data_clct_next_or_last_ts(uint8_t data_type,
iot_time_tm_t *curr_tm, int64_t interval, uint8_t is_next)
{
iot_time_tm_t tm = *curr_tm;
if (is_next) {
if (data_type == IOT_SG_STA_METER_DATA_TYPE_JS_MF) {
if (tm.tm_mon < 12) {
tm.tm_mon++;
} else {
tm.tm_year++;
tm.tm_mon = 1;
}
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else {
iot_rtc_delta_add(interval, &tm);
}
} else {
if (data_type == IOT_SG_STA_METER_DATA_TYPE_JS_MF) {
if (tm.tm_mon > 1) {
tm.tm_mon--;
} else {
tm.tm_year--;
tm.tm_mon = 12;
}
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else {
iot_rtc_delta_add(0 - interval, &tm);
}
}
return tm;
}
static uint32_t iot_sg_sta_ext_record_data_uint_fill(uint8_t *uint_data,
uint8_t oad_cnt, uint8_t *data, uint16_t data_len, int64_t interval,
iot_time_tm_t *last_tm, iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
iot_sg_meter_js_min_curve_uint_data_t *min;
iot_sg_meter_js_frozen_uint_data_t *frozen;
iot_sg_meter_js_sig_frozen_uint_data_t *sig;
proto_69845_app_data_t *app_data;
proto_69845_app_sec_mac_info_t *mac;
proto_69845_app_data_time_s_t *time;
iot_time_tm_t cur_tm = { 0 };
uint32_t ret = ERR_FAIL;
if (!uint_data || !data || !rpt_info || !last_tm) {
goto out;
}
if (data_len < sizeof(*app_data) + sizeof(*mac) + IOT_MAC_ADDR_LEN) {
goto out;
}
app_data = (proto_69845_app_data_t *)data;
app_data->data_type = PROTO_69845_APP_DATA_OCTET_STRING;
mac = (proto_69845_app_sec_mac_info_t *)app_data->data;
mac->len = IOT_MAC_ADDR_LEN;
iot_mac_addr_cpy(mac->data, rpt_info->addr);
iot_mac_addr_reverse(mac->data);
data += sizeof(*app_data) + sizeof(*mac) + mac->len;
data_len -= sizeof(*app_data) + sizeof(*mac) + mac->len;
if (data_len < sizeof(*app_data) + sizeof(*time)) {
goto out;
}
app_data = (proto_69845_app_data_t *)data;
app_data->data_type = PROTO_69845_APP_DATA_TIME_S;
cur_tm = iot_sg_ext_get_data_clct_next_or_last_ts(rpt_info->data_type,
last_tm, interval, 1);
os_mem_cpy(last_tm, &cur_tm, sizeof(cur_tm));
time = (proto_69845_app_data_time_s_t *)app_data->data;
time->year = cur_tm.tm_year;
iot_uint16_to_bytes(cur_tm.tm_year, (uint8_t *)&time->year, 1);
time->month = cur_tm.tm_mon;
time->day = cur_tm.tm_mday;
time->hour = cur_tm.tm_hour;
time->minute = cur_tm.tm_min;
time->second = cur_tm.tm_sec;
data += sizeof(*app_data) + sizeof(*time);
data_len -= sizeof(*app_data) + sizeof(*time);
if (iot_sg_sta_flash_mode_js_sig_check()) {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
frozen = (iot_sg_meter_js_frozen_uint_data_t *)uint_data;
ret = iot_sg_sta_ext_nomin_data_uint_fill(frozen, oad_cnt,
data, data_len, rpt_info->oad_map, rpt_info->flag_3p);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
sig = (iot_sg_meter_js_sig_frozen_uint_data_t *)uint_data;
ret = iot_sg_sta_ext_sig_data_uint_fill(sig, oad_cnt,
data, data_len, rpt_info->oad_map, rpt_info->flag_3p);
break;
}
default:
break;
}
} else {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
frozen = (iot_sg_meter_js_frozen_uint_data_t *)uint_data;
ret = iot_sg_sta_ext_nomin_data_uint_fill(frozen, oad_cnt,
data, data_len, rpt_info->oad_map, rpt_info->flag_3p);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
min = (iot_sg_meter_js_min_curve_uint_data_t *)uint_data;
ret = iot_sg_sta_ext_min_data_uint_fill(min, oad_cnt,
data, data_len, rpt_info->oad_map, rpt_info->flag_3p);
break;
}
default:
break;
}
}
out:
return ret;
}
static iot_pkt_t *iot_sg_sta_ext_rpt_get_cache_buff(void)
{
iot_pkt_t *pkt_buff = NULL;
uint16_t buff_len, buff_len1;
iot_sg_sta_flash_unit_get_data_info(IOT_SG_STA_METER_DATA_TYPE_JS_MF,
&buff_len, NULL);
iot_sg_sta_flash_unit_get_data_info(IOT_SG_STA_METER_DATA_TYPE_JS_DF,
&buff_len1, NULL);
buff_len = max(buff_len, buff_len1);
iot_sg_sta_flash_unit_get_data_info(
IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE,
&buff_len1, NULL);
buff_len = max(buff_len, buff_len1);
iot_sg_sta_flash_unit_get_data_info(
IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE,
&buff_len1, NULL);
buff_len = max(buff_len, buff_len1);
pkt_buff = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
if (pkt_buff) {
iot_pkt_put(pkt_buff, buff_len);
}
return pkt_buff;
}
static uint32_t iot_sg_sta_ext_record_data_uint_fill_continue(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt, uint16_t index, iot_pkt_t *pkt_buff, int64_t interval,
uint16_t total_cnt, uint16_t flash_cnt, uint16_t *fill_cnt,
iot_time_tm_t *last_tm)
{
uint8_t *buff_ptr, *w_data = data, *invalid_buff_ptr = NULL, i;
uint16_t unit_len, idx, buff_len, interval_cnt;
uint32_t ret = ERR_FAIL;
iot_pkt_t *invalid_pkt_buff = NULL;
if (!rpt_info || !data || !pkt_buff || !fill_cnt || !last_tm) {
goto drop;
}
invalid_pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (!invalid_pkt_buff) {
goto drop;
}
invalid_buff_ptr = iot_pkt_data(invalid_pkt_buff);
if (index >= flash_cnt) {
interval_cnt = total_cnt - *fill_cnt;
for (i = 0; i < interval_cnt; i++) {
ret = iot_sg_sta_ext_record_data_uint_fill(invalid_buff_ptr,
oad_cnt, w_data, len, interval, last_tm, rpt_info);
w_data += len;
}
(*fill_cnt) += interval_cnt;
ret = ERR_OK;
goto out;
}
buff_ptr = iot_pkt_data(pkt_buff);
buff_len = (uint16_t)iot_pkt_data_len(pkt_buff);
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
}
break;
}
default:
ret = ERR_FAIL;
goto out;
}
iot_sg_sta_flash_unit_get_data_info(rpt_info->data_type, &unit_len, NULL);
if (buff_len < unit_len) {
ret = ERR_FAIL;
goto out;
}
ret = iot_sg_sta_flash_unit_data_read(rpt_info->addr,
idx, buff_ptr, unit_len, rpt_info->data_type);
if (ret) {
goto drop;
}
interval_cnt = iot_sg_sta_ext_data_clct_get_interval_cnt(buff_ptr,
unit_len, interval, last_tm);
if (!interval_cnt) {
ret = ERR_OK;
goto out;
} else if (interval_cnt > 1) {
if (interval_cnt > total_cnt - *fill_cnt) {
interval_cnt = total_cnt - *fill_cnt;
for (i = 0; i < interval_cnt; i++) {
ret = iot_sg_sta_ext_record_data_uint_fill(invalid_buff_ptr,
oad_cnt, w_data, len, interval, last_tm, rpt_info);
w_data += len;
}
(*fill_cnt) += interval_cnt;
ret = ERR_OK;
goto out;
} else {
for (i = 0; i < interval_cnt - 1; i++) {
ret = iot_sg_sta_ext_record_data_uint_fill(invalid_buff_ptr,
oad_cnt, w_data, len, interval, last_tm, rpt_info);
w_data += len;
}
(*fill_cnt) += (interval_cnt - 1);
}
}
ret = iot_sg_sta_ext_record_data_uint_fill(buff_ptr, oad_cnt, w_data,
len, interval, last_tm, rpt_info);
if (ret) {
goto drop;
}
(*fill_cnt) += 1;
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (invalid_pkt_buff) {
iot_pkt_free(invalid_pkt_buff);
}
return ret;
}
static uint16_t iot_sg_sta_ext_get_rpt_data_cnt(uint8_t data_type)
{
uint8_t idx;
uint16_t cnt = 0;
iot_sg_sta_node_desc_t *node;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
if (sta_glb->node_list[idx] != NULL) {
node = sta_glb->node_list[idx];
if (node) {
switch (data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
cnt += node->ext.data_clct_info.mf_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
cnt += node->ext.data_clct_info.df_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
cnt += node->ext.data_clct_info.min15_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
cnt += node->ext.data_clct_info.min1_cnt;
break;
}
default:
break;
}
}
}
}
return cnt;
}
static void iot_sg_sta_ext_get_all_task_cfg(
iot_sg_meter_js_task_cfg_desc_t *cfg_desc, uint8_t element_index)
{
uint8_t cnt = 0, task_type;
uint32_t ret;
iot_sg_meter_js_task_config_hdr_t *config;
for (task_type = 0; task_type < IOT_SG_STA_METER_JS_CFG_TYPE_MAX;
task_type++) {
config = &cfg_desc->cfg_table[cnt];
os_mem_set(config, 0, sizeof(*config));
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config);
if (ret == ERR_OK && config->task_id) {
cnt++;
if (cnt >= IOT_SG_STA_METER_JS_CFG_TYPE_MAX) {
break;
}
}
}
if (element_index && cnt) {
if (element_index <= cnt) {
config = &cfg_desc->cfg_table[0];
os_mem_cpy(config, &cfg_desc->cfg_table[element_index - 1],
sizeof(*config));
cnt = 1;
} else {
os_mem_set(cfg_desc, 0, sizeof(*cfg_desc));
cnt = 0;
}
}
cfg_desc->cnt = cnt;
}
static iot_pkt_t *iot_sg_sta_ext_task_parameter_query(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad, uint8_t element_index)
{
uint8_t *data, i, reason = 0, addr_len;
iot_pkt_t *pkt = NULL, *pkt_buf = NULL;
uint16_t head_len, tail_len;
uint32_t total_len;
addr_info_t addr_info = {0};
iot_sg_meter_js_task_cfg_desc_t *cache;
iot_sg_meter_js_task_config_hdr_t *config;
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_resp_normal_t *normal_resp;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_task_cfg_unit_t *unit_data;
proto_69845_app_runtime_range_unit_t *range_data;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
pkt_buf = iot_pkt_alloc(sizeof(*cache), IOT_SMART_GRID_MID);
if (!pkt_buf) {
reason = 1;
goto out;
}
cache = (iot_sg_meter_js_task_cfg_desc_t*)iot_pkt_put(pkt_buf,
sizeof(*cache));
os_mem_set(cache, 0, sizeof(*cache));
iot_sg_sta_ext_get_all_task_cfg(cache, element_index);
if (!cache->cnt) {
reason = 2;
goto drop;
}
total_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*normal_resp)
+ sizeof(*task_list)
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
total_len += (cache->cnt * (sizeof(*unit_data) +
sizeof(*range_data)));
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 3;
goto drop;
}
data = iot_pkt_put(pkt, total_len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)total_len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_NORMAL;
normal_resp = (proto_69845_app_get_resp_normal_t*)get_resp->data;
normal_resp->piid_acd.sn = piid->sn;
normal_resp->piid_acd.priority = piid->priority;
normal_resp->piid_acd.acd = 0;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&normal_resp->oad.oi);
normal_resp->oad.attribute_id = oad->attribute_id;
normal_resp->oad.attribute_char = oad->attribute_char;
normal_resp->oad.element_index = oad->element_index;
normal_resp->result_type = PROTO_69845_APP_GET_RESULT_DATA;
task_list = (proto_69845_app_ele_data_t*)normal_resp->result;
task_list->data_type = PROTO_69845_APP_DATA_ARRAY;
task_list->num_of_data = cache->cnt;
data = data + sizeof(*app_resp) + sizeof(*get_resp) + sizeof(*normal_resp)
+ sizeof(*task_list);
for (i = 0; i < task_list->num_of_data; i++) {
config = &cache->cfg_table[i];
unit_data = (proto_69845_app_data_task_cfg_unit_t*)data;
unit_data->data0_type = PROTO_69845_APP_DATA_STRUCTURE;
unit_data->task_cfg_ele_cnt = 12;
unit_data->data1_type = PROTO_69845_APP_DATA_UNSIGNED;
unit_data->task_id = config->task_id;
unit_data->data2_type = PROTO_69845_APP_DATA_TI;
unit_data->freq_time.uint = config->exe_inter.uint;
iot_uint16_to_bytes(config->exe_inter.value,
(uint8_t*)&unit_data->freq_time.value, 1);
unit_data->data3_type = PROTO_69845_APP_DATA_ENUM;
unit_data->plan_type = PROTO_69845_DATA_TASK_PLAN_TYPE_NORMAL_CLCT;
unit_data->data4_type = PROTO_69845_APP_DATA_UNSIGNED;
unit_data->plan_num = config->scheme_num;
unit_data->data5_type = PROTO_69845_APP_DATA_TIME_S;
unit_data->start_time = config->start_time;
iot_uint16_to_bytes(config->start_time.year,
(uint8_t*)&unit_data->start_time.year, 1);
unit_data->data6_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes(2099, (uint8_t*)&unit_data->end_time.year, 1);
unit_data->end_time.month = 1;
unit_data->end_time.day = 1;
unit_data->end_time.hour = 0;
unit_data->end_time.minute = 0;
unit_data->end_time.second = 0;
unit_data->data7_type = PROTO_69845_APP_DATA_TI;
unit_data->delay_time = config->delay;
iot_uint16_to_bytes(config->delay.value,
(uint8_t*)&unit_data->delay_time.value, 1);
unit_data->data8_type = PROTO_69845_APP_DATA_UNSIGNED;
unit_data->priority = 2;
unit_data->data9_type = PROTO_69845_APP_DATA_ENUM;
unit_data->state = PROTO_69845_DATA_TASK_STATE_NORMAL;
unit_data->data10_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
iot_uint16_to_bytes(0, (uint8_t*)&unit_data->pre_script_id, 1);
unit_data->data11_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
iot_uint16_to_bytes(0, (uint8_t*)&unit_data->post_script_id, 1);
unit_data->data12_type = PROTO_69845_APP_DATA_STRUCTURE;
unit_data->runtime_desc_ele_cnt = 2;
unit_data->data12_1_type = PROTO_69845_APP_DATA_ENUM;
unit_data->range_type = PROTO_69845_DATA_RUNTIME_RANGE_TYPE_FCBC;
unit_data->data12_2_type = PROTO_69845_APP_DATA_ARRAY;
unit_data->runtime_range_cnt = 1;
unit_data->runtime_range_table[0].data0_type =
PROTO_69845_APP_DATA_STRUCTURE;
unit_data->runtime_range_table[0].cnt = 4;
unit_data->runtime_range_table[0].data1_type =
PROTO_69845_APP_DATA_UNSIGNED;
unit_data->runtime_range_table[0].start_hour = 0;
unit_data->runtime_range_table[0].data2_type =
PROTO_69845_APP_DATA_UNSIGNED;
unit_data->runtime_range_table[0].start_min = 0;
unit_data->runtime_range_table[0].data3_type =
PROTO_69845_APP_DATA_UNSIGNED;
unit_data->runtime_range_table[0].end_hour = 23;
unit_data->runtime_range_table[0].data4_type =
PROTO_69845_APP_DATA_UNSIGNED;
unit_data->runtime_range_table[0].end_min = 59;
data = data + sizeof(*unit_data) + sizeof(*range_data);
}
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return pkt;
}
static void iot_sg_sta_ext_get_all_clct_cfg(
iot_sg_meter_js_task_cfg_desc_t *cfg_desc, uint8_t element_index)
{
uint8_t cnt = 0, task_type;
uint32_t ret;
iot_sg_meter_js_task_config_hdr_t *config;
for (task_type = 0; task_type < IOT_SG_STA_METER_JS_CFG_TYPE_MAX;
task_type++) {
config = &cfg_desc->cfg_table[cnt];
os_mem_set(config, 0, sizeof(*config));
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config);
if (ret == ERR_OK && config->scheme_num) {
cnt++;
if (cnt >= IOT_SG_STA_METER_JS_CFG_TYPE_MAX) {
break;
}
}
}
if (element_index && cnt) {
if (element_index <= cnt) {
config = &cfg_desc->cfg_table[0];
os_mem_cpy(config, &cfg_desc->cfg_table[element_index - 1],
sizeof(*config));
cnt = 1;
} else {
os_mem_set(cfg_desc, 0, sizeof(*cfg_desc));
cnt = 0;
}
}
cfg_desc->cnt = cnt;
}
static uint32_t iot_sg_sta_ext_get_all_clct_len(
iot_sg_meter_js_task_cfg_desc_t *cfg_desc)
{
uint8_t cnt, oad_cnt, i;
uint32_t len = 0;
iot_sg_meter_js_task_config_hdr_t *config;
cnt = min(cfg_desc->cnt, IOT_SG_STA_METER_JS_CFG_TYPE_MAX);
for (i = 0; i < cnt; i++) {
config = &cfg_desc->cfg_table[i];
len += sizeof(proto_69845_app_data_clct_cfg_unit_hdr_t);
len += sizeof(proto_69845_app_data_clct_type_t);
if (config->task_type == IOT_SG_STA_METER_JS_CFG_TYPE_15MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN) {
len += sizeof(proto_69845_app_data_ti_t);
}
len += sizeof(proto_69845_app_data_clct_csd_t);
len += sizeof(proto_69845_app_road_t);
oad_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&config->cfg_di_bm,
sizeof(config->cfg_di_bm));
len += (oad_cnt * sizeof(proto_69845_app_oad_t));
len += sizeof(proto_69845_app_data_clct_ms_t);
if (!config->all_flag) {
len += sizeof(proto_69845_app_data_ms_type_t);
len += 3;
}
len += sizeof(proto_69845_app_data_clct_cfg_unit_tail_t);
}
return len;
}
static iot_pkt_t *iot_sg_sta_ext_clct_parameter_query(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad, uint8_t element_index)
{
uint8_t *data, i, m, task_di, reason, addr_len;
iot_pkt_t *pkt = NULL, *pkt_buf = NULL;
uint16_t head_len, tail_len, oi, value;
uint32_t total_len, config_total_len, oad_value;
addr_info_t addr_info = {0};
iot_sg_meter_js_task_cfg_desc_t *cache;
iot_sg_meter_js_task_config_hdr_t *config;
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_resp_normal_t *normal_resp;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_clct_cfg_unit_hdr_t *unit_hdr;
proto_69845_app_data_clct_type_t *type_hdr;
proto_69845_app_data_ti_t *ti;
proto_69845_app_data_clct_csd_t *csd;
proto_69845_app_road_t *road;
proto_69845_app_data_clct_ms_t *ms;
proto_69845_app_data_ms_type_t *ms_type;
proto_69845_app_data_clct_cfg_unit_tail_t *unit_tail;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
pkt_buf = iot_pkt_alloc(sizeof(*cache), IOT_SMART_GRID_MID);
if (!pkt_buf) {
reason = 1;
goto drop;
}
cache = (iot_sg_meter_js_task_cfg_desc_t*)iot_pkt_put(pkt_buf,
sizeof(*cache));
os_mem_set(cache, 0, sizeof(*cache));
iot_sg_sta_ext_get_all_clct_cfg(cache, element_index);
if (!cache->cnt) {
reason = 2;
goto drop;
}
config_total_len = iot_sg_sta_ext_get_all_clct_len(cache);
total_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*normal_resp)
+ sizeof(*task_list) + config_total_len
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 3;
goto drop;
}
data = iot_pkt_put(pkt, total_len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t*)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)total_len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_NORMAL;
normal_resp = (proto_69845_app_get_resp_normal_t*)get_resp->data;
normal_resp->piid_acd.sn = piid->sn;
normal_resp->piid_acd.priority = piid->priority;
normal_resp->piid_acd.acd = 0;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&normal_resp->oad.oi);
normal_resp->oad.attribute_id = oad->attribute_id;
normal_resp->oad.attribute_char = oad->attribute_char;
normal_resp->oad.element_index = oad->element_index;
normal_resp->result_type = PROTO_69845_APP_GET_RESULT_DATA;
task_list = (proto_69845_app_ele_data_t*)normal_resp->result;
task_list->data_type = PROTO_69845_APP_DATA_ARRAY;
task_list->num_of_data = cache->cnt;
data = data + sizeof(*app_resp) + sizeof(*get_resp) +sizeof(*normal_resp)
+ sizeof(*task_list);
for (i = 0; i < task_list->num_of_data; i++) {
config = &cache->cfg_table[i];
unit_hdr = (proto_69845_app_data_clct_cfg_unit_hdr_t*)data;
unit_hdr->data0_type = PROTO_69845_APP_DATA_STRUCTURE;
unit_hdr->clct_cfg_ele_cnt = 6;
unit_hdr->data1_type = PROTO_69845_APP_DATA_UNSIGNED;
unit_hdr->clct_id = config->scheme_num;
unit_hdr->data2_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
switch (config->task_type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
{
value = IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
{
value = IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
{
value = IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
{
value = IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
break;
}
default:
reason = 4;
goto drop;
}
iot_uint16_to_bytes(value, (uint8_t*)&unit_hdr->clct_cnt, 1);
data += sizeof(*unit_hdr);
type_hdr = (proto_69845_app_data_clct_type_t*)data;
type_hdr->data0_type = PROTO_69845_APP_DATA_STRUCTURE;
type_hdr->ele_cnt = 2;
type_hdr->data1_type = PROTO_69845_APP_DATA_UNSIGNED;
if (config->task_type == IOT_SG_STA_METER_JS_CFG_TYPE_15MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN) {
type_hdr->type = PROTO_69845_DATA_CLCT_UNIT_TYPE_INTERVAL;
type_hdr->data2_type = PROTO_69845_APP_DATA_TI;
data += sizeof(*type_hdr);
ti = (proto_69845_app_data_ti_t*)data;
ti->uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
iot_uint16_to_bytes(15, (uint8_t*)&ti->value, 1);
data += sizeof(*ti);
} else {
if (config->task_type == IOT_SG_STA_METER_JS_CFG_TYPE_1MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_TYPE_D_C
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C) {
type_hdr->type = PROTO_69845_DATA_CLCT_UNIT_TYPE_CURR;
} else {
type_hdr->type = PROTO_69845_DATA_CLCT_UNIT_TYPE_FROZEN;
}
type_hdr->data2_type = PROTO_69845_APP_DATA_NULL;
data += sizeof(*type_hdr);
}
csd = (proto_69845_app_data_clct_csd_t*)data;
csd->data0_type = PROTO_69845_APP_DATA_ARRAY;
csd->csd_cnt = 1;
csd->data1_type = PROTO_69845_APP_DATA_CSD;
csd->type = PROTO_OI_CSD_TYPE_ROAD;
data += sizeof(*csd);
road = (proto_69845_app_road_t*)data;
switch (config->task_type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
{
oi = PROTO_69845_APP_OI_MON_FROZEN;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
{
oi = PROTO_69845_APP_OI_DAY_FROZEN;
break;
}
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
{
oi = PROTO_69845_APP_OI_MIN_FROZEN;
break;
}
default:
reason = 5;
goto drop;
}
proto_69845_oi_to_byte(oi, (uint8_t*)&road->rec_oad.oi);
road->rec_oad.attribute_id = 2;
road->rec_oad.attribute_char = 0;
road->rec_oad.element_index = 0;
road->cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&config->cfg_di_bm,
sizeof(config->cfg_di_bm));
task_di = 0;
for (m = 0; m < road->cnt; m++) {
oad_value = 0xffffffff;
for (;task_di < IOT_SG_STA_METER_TASK_DI_MAX_CNT; task_di++) {
if (config->cfg_di_bm & (0x00000001 << task_di)) {
oad_value = iot_sg_ext_data_clct_get_di(
IOT_SG_STA_EXT_DI_TAB_PRO_69845, task_di);
break;
}
}
if (oad_value == 0xffffffff) {
reason = 6;
goto drop;
}
iot_uint32_to_bytes(oad_value, (uint8_t*)&road->ass_oad[m], 1);
task_di++;
}
data = data + sizeof(*road) + road->cnt * sizeof(proto_69845_app_oad_t);
ms = (proto_69845_app_data_clct_ms_t*)data;
ms->data_type = PROTO_69845_APP_DATA_MS;
if (config->all_flag) {
ms->type = PROTO_OI_MS_TYPE_ALL_PM;
data += sizeof(*ms);
} else {
ms->type = PROTO_OI_MS_TYPE_GROUP_PM_TYPE;
data += sizeof(*ms);
ms_type = (proto_69845_app_data_ms_type_t*)data;
ms_type->cnt = 3;
if (config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C) {
ms_type->type_list[0] = 72;
ms_type->type_list[1] = 74;
ms_type->type_list[2] = 87;
} else {
ms_type->type_list[0] = 82;
ms_type->type_list[1] = 84;
ms_type->type_list[2] = 88;
}
data += sizeof(*ms_type) +
ms_type->cnt * sizeof(ms_type->type_list[0]);
}
unit_tail = (proto_69845_app_data_clct_cfg_unit_tail_t*)data;
unit_tail->data_type = PROTO_69845_APP_DATA_ENUM;
unit_tail->clct_sts_type = PROTO_69845_DATA_CLCT_UNIT_STS_TYPE6;
data += sizeof(*unit_tail);
}
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return pkt;
}
static iot_sg_sta_node_desc_t *iot_sg_sta_ext_clct_state_get_node(
uint8_t index)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_node_desc_t *node;
uint32_t idx, cnt = 1;
for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
if (sta_glb->node_list[idx] != NULL) {
node = sta_glb->node_list[idx];
if (cnt == index) {
return node;
}
cnt++;
}
}
return NULL;
}
static iot_pkt_t *iot_sg_sta_ext_clct_state_query(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad, uint8_t element_index)
{
uint8_t *data, reason, addr_len;
iot_pkt_t *pkt = NULL;
uint16_t head_len, tail_len;
uint32_t total_len;
addr_info_t addr_info = {0};
iot_sg_sta_node_desc_t *node = NULL;
iot_sg_sta_node_data_clct_info_t *clct_data;
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_resp_normal_t *normal_resp;
proto_69845_app_ele_data_t *task_list;
proto_69845_clct_state_t *state_desc;
node = iot_sg_sta_ext_clct_state_get_node(element_index);
if (node == NULL) {
reason = 1;
goto drop;
}
clct_data = &node->ext.data_clct_info;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
total_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*normal_resp)
+ sizeof(*task_list) + sizeof(*state_desc)
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 2;
goto drop;
}
data = iot_pkt_put(pkt, total_len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t*)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)total_len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_NORMAL;
normal_resp = (proto_69845_app_get_resp_normal_t*)get_resp->data;
normal_resp->piid_acd.sn = piid->sn;
normal_resp->piid_acd.priority = piid->priority;
normal_resp->piid_acd.acd = 0;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&normal_resp->oad.oi);
normal_resp->oad.attribute_id = oad->attribute_id;
normal_resp->oad.attribute_char = oad->attribute_char;
normal_resp->oad.element_index = oad->element_index;
normal_resp->result_type = PROTO_69845_APP_GET_RESULT_DATA;
task_list = (proto_69845_app_ele_data_t*)normal_resp->result;
task_list->data_type = PROTO_69845_APP_DATA_ARRAY;
task_list->num_of_data = 1;
data = data + sizeof(*app_resp) + sizeof(*get_resp) +sizeof(*normal_resp)
+ sizeof(*task_list);
/* fill state data */
state_desc = (proto_69845_clct_state_t*)data;
state_desc->type = PROTO_69845_APP_DATA_STRUCTURE;
state_desc->cnt = 8;
state_desc->data0_type = PROTO_69845_APP_DATA_TSA;
state_desc->data1_type = PROTO_69845_APP_DATA_UNSIGNED;
state_desc->data2_type = PROTO_69845_APP_DATA_TSA;
state_desc->data3_type = PROTO_69845_APP_DATA_OAD;
state_desc->data4_type = PROTO_69845_APP_DATA_TIME_S;
state_desc->data5_type = PROTO_69845_APP_DATA_UNSIGNED;
state_desc->data6_type = PROTO_69845_APP_DATA_ENUM;
state_desc->data7_type = PROTO_69845_APP_DATA_ENUM;
state_desc->phase_desc = 0;
state_desc->abnormal_desc = 0;
state_desc->mac_addr.len = sizeof(state_desc->mac_addr.flag)
+ IOT_MAC_ADDR_LEN;
state_desc->mac_addr.flag.sa_type = PROTO_69845_SA_TYPE_SIG;
state_desc->mac_addr.flag.sa_len = IOT_MAC_ADDR_LEN - 1;
state_desc->mac_addr.flag.logical_addr = 0;
iot_mac_addr_cpy(state_desc->mac_addr.addr,
node->entry.addr);
iot_mac_addr_reverse(state_desc->mac_addr.addr);
state_desc->relay_addr.len = sizeof(state_desc->mac_addr.flag)
+ IOT_MAC_ADDR_LEN;
state_desc->relay_addr.flag.sa_type = PROTO_69845_SA_TYPE_SIG;
state_desc->relay_addr.flag.sa_len = IOT_MAC_ADDR_LEN - 1;
state_desc->relay_addr.flag.logical_addr = 0;
iot_mac_addr_cpy(state_desc->relay_addr.addr,
p_sg_glb->plc_state.addr);
if (iot_mac_addr_cmp(state_desc->mac_addr.addr,
state_desc->relay_addr.addr)) {
state_desc->level = 0;
} else {
state_desc->level = 2;
}
iot_uint32_to_bytes(PROTO_69845_APP_OAD_PORT_RS485I,
(uint8_t*)&state_desc->oad, 1);
iot_uint16_to_bytes(clct_data->last_clct_tm.tm_year,
(uint8_t*)&state_desc->last_time.year, 1);
state_desc->last_time.month = clct_data->last_clct_tm.tm_mon;
state_desc->last_time.day = clct_data->last_clct_tm.tm_mday;
state_desc->last_time.hour = clct_data->last_clct_tm.tm_hour;
state_desc->last_time.minute = clct_data->last_clct_tm.tm_min;
state_desc->last_time.second = clct_data->last_clct_tm.tm_sec;
state_desc->fail_cnt = clct_data->clct_fail_times;
data += sizeof(*state_desc);
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
return pkt;
}
static uint32_t iot_sg_sta_ext_clct_monitor_cnt_fill(
proto_69845_clct_monitor_t *monitor,
iot_sg_meter_js_task_config_hdr_t *config)
{
uint8_t idx, task_type, task_3p_type, is_3p = 0;
uint16_t collect_meter_cnt = 0, success_cnt = 0, msg_send_num = 0,
msg_recv_num = 0;
iot_sg_sta_node_desc_t *node;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_data_clct_info_t *data_clct = &ext_info->data_clct;
switch (config->task_type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN:
{
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
task_3p_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
{
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
task_3p_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF:
{
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
task_3p_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN:
{
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
task_3p_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN;
break;
}
default:
goto drop;
}
if (config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN
|| config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C) {
is_3p = 1;
}
for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
if (sta_glb->node_list[idx] != NULL) {
node = sta_glb->node_list[idx];
BUILD_BUG_ON(IOT_SG_STA_METER_JS_CFG_TYPE_MAX <=
sizeof(node->ext.data_clct_info.task_suc_bm) * 8);
if (config->all_flag) {
if (node->ext.data_clct_info.task_suc_bm
& (1 << task_type)) {
success_cnt++;
}
if (node->ext.data_clct_info.task_suc_bm
& (1 << task_3p_type)) {
success_cnt++;
}
collect_meter_cnt++;
} else if (is_3p) {
if (node->ext.data_clct_info.task_suc_bm
& (1 << task_3p_type)) {
success_cnt++;
}
if (node->is_three_phase) {
collect_meter_cnt++;
}
} else {
if (node->ext.data_clct_info.task_suc_bm
& (1 << task_type)) {
success_cnt++;
}
if (!node->is_three_phase) {
collect_meter_cnt++;
}
}
}
}
if (config->all_flag) {
msg_send_num = data_clct->monitor[task_type].msg_send_num +
data_clct->monitor[task_3p_type].msg_send_num;
msg_recv_num = data_clct->monitor[task_type].msg_recv_num+
data_clct->monitor[task_3p_type].msg_recv_num;
} else if (is_3p) {
msg_send_num = data_clct->monitor[task_3p_type].msg_send_num;
msg_recv_num = data_clct->monitor[task_3p_type].msg_recv_num;
} else {
msg_send_num = data_clct->monitor[task_type].msg_send_num;
msg_recv_num = data_clct->monitor[task_type].msg_recv_num;
}
iot_uint16_to_bytes(collect_meter_cnt,
(uint8_t*)&monitor->collect_meter_cnt, 1);
iot_uint16_to_bytes(success_cnt, (uint8_t*)&monitor->success_cnt, 1);
iot_uint16_to_bytes(msg_send_num, (uint8_t*)&monitor->send_cnt, 1);
iot_uint16_to_bytes(msg_recv_num, (uint8_t*)&monitor->rec_cnt, 1);
return ERR_OK;
drop:
return ERR_FAIL;
}
static iot_pkt_t *iot_sg_sta_ext_clct_monitor_query(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad, uint8_t element_index)
{
uint8_t *data, i, reason, addr_len;
iot_pkt_t *pkt = NULL, *pkt_buf = NULL;
uint16_t head_len, tail_len;
uint32_t total_len;
addr_info_t addr_info = {0};
iot_sg_meter_js_task_cfg_desc_t *cache;
iot_sg_meter_js_task_config_hdr_t *config;
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_resp_normal_t *normal_resp;
proto_69845_app_ele_data_t *task_list;
proto_69845_clct_monitor_t *monitor;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
pkt_buf = iot_pkt_alloc(sizeof(*cache), IOT_SMART_GRID_MID);
if (!pkt_buf) {
reason = 1;
goto drop;
}
cache = (iot_sg_meter_js_task_cfg_desc_t*)iot_pkt_put(pkt_buf,
sizeof(*cache));
os_mem_set(cache, 0, sizeof(*cache));
iot_sg_sta_ext_get_all_task_cfg(cache, element_index);
if (!cache->cnt) {
reason = 2;
goto drop;
}
total_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*normal_resp)
+ sizeof(*task_list) + sizeof(*monitor) * cache->cnt
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 3;
goto drop;
}
data = iot_pkt_put(pkt, total_len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t*)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)total_len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_NORMAL;
normal_resp = (proto_69845_app_get_resp_normal_t*)get_resp->data;
normal_resp->piid_acd.sn = piid->sn;
normal_resp->piid_acd.priority = piid->priority;
normal_resp->piid_acd.acd = 0;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&normal_resp->oad.oi);
normal_resp->oad.attribute_id = oad->attribute_id;
normal_resp->oad.attribute_char = oad->attribute_char;
normal_resp->oad.element_index = oad->element_index;
normal_resp->result_type = PROTO_69845_APP_GET_RESULT_DATA;
task_list = (proto_69845_app_ele_data_t*)normal_resp->result;
task_list->data_type = PROTO_69845_APP_DATA_ARRAY;
task_list->num_of_data = cache->cnt;
data = data + sizeof(*app_resp) + sizeof(*get_resp) +sizeof(*normal_resp)
+ sizeof(*task_list);
for (i = 0; i < task_list->num_of_data; i++) {
config = &cache->cfg_table[i];
monitor = (proto_69845_clct_monitor_t*)data;
monitor->type = PROTO_69845_APP_DATA_STRUCTURE;
monitor->cnt = 8;
monitor->data0_type = PROTO_69845_APP_DATA_UNSIGNED;
monitor->task_id = config->task_id;
monitor->data1_type = PROTO_69845_APP_DATA_ENUM;
monitor->task_state = 1;
monitor->data2_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes(config->start_time.year,
(uint8_t*)&monitor->start_time.year, 1);
monitor->start_time.month = config->start_time.month;
monitor->start_time.day = config->start_time.day;
monitor->start_time.hour = config->start_time.hour;
monitor->start_time.minute = config->start_time.minute;
monitor->start_time.second = config->start_time.second;
monitor->data3_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes(2099, (uint8_t*)&monitor->end_time.year, 1);
monitor->end_time.month = 1;
monitor->end_time.day = 1;
monitor->end_time.hour = 0;
monitor->end_time.minute = 0;
monitor->end_time.second = 0;
monitor->data4_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
monitor->data5_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
monitor->data6_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
monitor->data7_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
if (iot_sg_sta_ext_clct_monitor_cnt_fill(monitor, config)) {
reason = 4;
goto drop;
}
data += sizeof(*monitor);
}
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return pkt;
}
static uint16_t iot_sg_sta_ext_get_collect_info_cnt(
uint8_t type)
{
uint16_t cnt = 0;
switch (type) {
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_RPT_CNT:
{
cnt = (uint16_t)iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE);
break;
}
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_RPT_CNT:
{
cnt = (uint16_t)iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE);
break;
}
case PROTO_OI_COLLECTOR_ATT_METER_CNT:
{
cnt = iot_sg_node_reg_get_node_cnt();
break;
}
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_MAX_CNT:
{
cnt = IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
break;
}
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_MAX_CNT:
{
cnt = IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
break;
}
default:
break;
}
return cnt;
}
static uint32_t iot_sg_sta_ext_get_nor_list_oad_resp_len(
proto_69845_get_normal_list_desc_t *cache_list)
{
uint8_t i, cnt;
uint32_t len = 0, addr_len;
proto_69845_app_oad_t *oad;
for (i = 0; i < cache_list->cnt; i++) {
oad = &cache_list->list[i].oad;
switch (oad->oi) {
case PROTO_69845_APP_OI_COLLECTOR:
{
switch (oad->attribute_id) {
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_RPT_CNT:
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_RPT_CNT:
case PROTO_OI_COLLECTOR_ATT_METER_CNT:
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_MAX_CNT:
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_MAX_CNT:
{
len += sizeof(proto_69845_app_data_t) + sizeof(uint16_t);
break;
}
case PROTO_OI_COLLECTOR_ATT_METER_LIST:
{
len += sizeof(proto_69845_app_ele_data_t);
cnt = iot_sg_node_reg_get_node_cnt();
addr_len = (IOT_MAC_ADDR_LEN + sizeof(proto_69845_app_data_t)
+ sizeof(proto_69845_app_data_tsa_t)) * cnt;
len += addr_len;
break;
}
default:
len += sizeof(uint8_t);
break;
}
break;
}
default:
len += sizeof(uint8_t);
break;
}
len += sizeof(proto_69845_app_oad_resp_hdr_t);
}
return len;
}
static iot_pkt_t *iot_sg_sta_ext_clct_record_data_ack(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
iot_sg_sta_ext_clct_query_desc_t *query_desc)
{
uint8_t unit_max_cnt, i, *result, tm_cnt = 2, addr_len;
uint8_t *data, reason = 0, oad_cnt, *unit_total_cnt;
uint8_t flag_up[2] = { 0 };
uint16_t head_len, tail_len, csd_len, road_len, uint_len, fill_cnt = 0;
uint16_t start_idx = 0, end_idx = 1;
uint16_t index[2] ={ 0 }, last_fill_cnt = 0, flash_unit_cnt, unit_cnt;
uint32_t len, ret;
int64_t delta;
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_req_record_t *record_resp;
proto_69845_app_data_rcsd_t *data_rcsd;
proto_69845_app_data_csd_t *csd;
proto_69845_app_oad_t *addr_oad, *time_oad;
iot_sg_sta_ext_clct_rpt_desc_t rpt_info = { 0 };
iot_time_tm_t last_tm = { 0 }, tm[2] = { 0 };
if (!hdr_698 || !query_desc || !piid || !oad) {
reason = 1;
goto drop;
}
if (!iot_mac_addr_valid(query_desc->addr)) {
reason = 2;
goto drop;
}
if (query_desc->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_MF
&& query_desc->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_DF
&& query_desc->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE
&& query_desc->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE) {
reason = 3;
goto drop;
}
if (!query_desc->oad_map) {
reason = 4;
goto drop;
}
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*record_resp) + sizeof(*data_rcsd)
+ PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
len += sizeof(proto_69845_app_data_csd_t) + sizeof(*addr_oad);
len += sizeof(proto_69845_app_data_csd_t) + sizeof(*time_oad);
oad_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&query_desc->oad_map,
sizeof(query_desc->oad_map));
csd_len = iot_sg_sta_ext_get_rpt_csd_len(oad_cnt);
len += csd_len;
len += sizeof(*result);
len += sizeof(*unit_total_cnt);
if (len >= IOT_SG_STA_EXT_RPT_MAX_LEN) {
reason = 5;
goto drop;
}
tm[start_idx] = query_desc->start_ts;
tm[end_idx] = query_desc->end_ts;
flag_up[start_idx] = 0;
flag_up[end_idx] = 1;
ret = iot_sg_sta_flash_unit_data_find_by_multiple_time(query_desc->addr,
index, tm, tm_cnt, query_desc->data_type, flag_up);
if (ret != ERR_OK || index[start_idx] == 0xffff ||
index[end_idx] == 0xffff) {
reason = 6;
goto drop;
}
iot_mac_addr_cpy(rpt_info.addr, query_desc->addr);
rpt_info.flag_3p = query_desc->flag_3p;
rpt_info.data_type = query_desc->data_type;
rpt_info.oad_map = query_desc->oad_map;
rpt_info.start_index = index[start_idx];
rpt_info.end_index = index[end_idx];
uint_len = iot_sg_sta_ext_get_rpt_unit_len(&rpt_info);
uint_len += sizeof(proto_69845_app_data_t);
uint_len += sizeof(proto_69845_app_sec_mac_info_t) + IOT_MAC_ADDR_LEN;
uint_len += sizeof(proto_69845_app_data_t);
uint_len += sizeof(proto_69845_app_data_time_s_t);
unit_max_cnt = (uint8_t)((IOT_SG_STA_EXT_RPT_MAX_LEN - len) / uint_len);
if (!unit_max_cnt) {
reason = 7;
goto drop;
}
delta = iot_rtc_delta_calc(&tm[start_idx], &tm[end_idx]);
if (delta < 0) {
reason = 8;
goto drop;
}
if (query_desc->data_type == IOT_SG_STA_METER_DATA_TYPE_JS_MF) {
unit_cnt = (tm[end_idx].tm_year * 12 + tm[end_idx].tm_mon) -
(tm[start_idx].tm_year * 12 + tm[start_idx].tm_mon) + 1;
} else {
unit_cnt = (uint16_t)(delta / query_desc->interval);
if (!(delta % query_desc->interval)) {
unit_cnt += 1;
}
}
if (unit_cnt > unit_max_cnt) {
unit_cnt = unit_max_cnt;
}
flash_unit_cnt = (uint8_t)iot_sg_sta_ext_get_record_flash_cnt(
rpt_info.data_type, rpt_info.start_index, rpt_info.end_index);
if (!flash_unit_cnt) {
reason = 9;
goto drop;
}
len += uint_len * unit_cnt;
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 10;
goto drop;
}
data = iot_pkt_put(pkt, len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_RECORD;
record_resp = (proto_69845_app_get_req_record_t *)get_resp->data;
record_resp->piid.sn = piid->sn;
record_resp->piid.priority = piid->priority;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&record_resp->oad.oi);
record_resp->oad.attribute_id = oad->attribute_id;
record_resp->oad.attribute_char = oad->attribute_char;
record_resp->oad.element_index = oad->element_index;
data = data + sizeof(*app_resp) + sizeof(*get_resp)
+ sizeof(*record_resp);
pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (!pkt_buff) {
reason = 11;
goto drop;
}
/* fill rcsd */
data_rcsd = (proto_69845_app_data_rcsd_t *)data;
data_rcsd->cnt = 3;
data += sizeof(*data_rcsd);
/* fill csd_1 */
csd = (proto_69845_app_data_csd_t *)data_rcsd->csd_list;
csd->type = PROTO_OI_CSD_TYPE_OAD;
addr_oad = (proto_69845_app_oad_t *)csd->csd_data;
proto_69845_oi_to_byte(PROTO_69845_APP_OI_ADDR, (uint8_t*)&addr_oad->oi);
addr_oad->attribute_id = 2;
addr_oad->attribute_char = 0;
addr_oad->element_index = 0;
data += sizeof(*csd) + sizeof(*addr_oad);
/* fill csd_2 */
csd = (proto_69845_app_data_csd_t *)data;
csd->type = PROTO_OI_CSD_TYPE_OAD;
addr_oad = (proto_69845_app_oad_t *)csd->csd_data;
proto_69845_oi_to_byte(PROTO_69845_APP_OI_CLCT_SAVE_TIME,
(uint8_t*)&addr_oad->oi);
addr_oad->attribute_id = 2;
addr_oad->attribute_char = 0;
addr_oad->element_index = 0;
data += sizeof(*csd) + sizeof(*addr_oad);
/* fill csd_3 */
csd = (proto_69845_app_data_csd_t *)data;
csd->type = PROTO_OI_CSD_TYPE_ROAD;
data += sizeof(*csd);
/* fill road */
road_len = iot_sg_sta_ext_get_rpt_road_len(oad_cnt);
iot_sg_sta_ext_rpt_road_fill(&rpt_info, data, road_len, oad_cnt);
data += road_len;
/* fill result */
result = data;
*result = PROTO_69845_APP_RPT_RESULT_DATA;
data += sizeof(*result);
/* fill unit cnt */
unit_total_cnt = data;
*unit_total_cnt = (uint8_t)unit_cnt;
last_tm = iot_sg_ext_get_data_clct_next_or_last_ts(query_desc->data_type,
&query_desc->start_ts, query_desc->interval, 0);
data += sizeof(*unit_total_cnt);
for (i = 0; i < unit_cnt; i++) {
ret = iot_sg_sta_ext_record_data_uint_fill_continue(&rpt_info, data,
uint_len, oad_cnt, i, pkt_buff, query_desc->interval, unit_cnt,
flash_unit_cnt, &fill_cnt, &last_tm);
if (ret) {
reason = 14;
goto drop;
}
data += (fill_cnt - last_fill_cnt) * uint_len;
last_fill_cnt = fill_cnt;
if (fill_cnt >= unit_cnt) {
break;
}
}
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_clct_record_data_nack(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
proto_69845_data_cache_desc_t *rcsd)
{
uint8_t *data, addr_len;
uint16_t head_len, tail_len;
uint32_t len;
iot_pkt_t *pkt = NULL;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_req_record_t *record_resp;
proto_69845_app_get_result_t *result;
if (!hdr_698 || !piid || !oad || !rcsd) {
goto drop;
}
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*record_resp) + rcsd->len
+ sizeof(*result) + PROTO_69845_DAR_LEN
+ PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
goto drop;
}
data = iot_pkt_put(pkt, len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_RECORD;
record_resp = (proto_69845_app_get_req_record_t *)get_resp->data;
record_resp->piid.sn = piid->sn;
record_resp->piid.priority = piid->priority;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&record_resp->oad.oi);
record_resp->oad.attribute_id = oad->attribute_id;
record_resp->oad.attribute_char = oad->attribute_char;
record_resp->oad.element_index = oad->element_index;
data = data + sizeof(*app_resp) + sizeof(*get_resp)
+ sizeof(*record_resp);
/* fill rcsd */
os_mem_cpy(data, rcsd->data, rcsd->len);
data += rcsd->len;
/* fill result */
result = (proto_69845_app_get_result_t *)data;
result->result_type = PROTO_69845_APP_GET_RESULT_DAR;
result->result[0] = PROTO_69845_APP_DAR_OTHER;
data = data + sizeof(*result) + PROTO_69845_DAR_LEN;
/* fill tail */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_clct_record_data_query(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
proto_69845_data_cache_desc_t *rsd,
proto_69845_data_cache_desc_t *rcsd)
{
uint8_t reason = 0;
iot_pkt_t *pkt = NULL;
iot_sg_sta_ext_clct_query_desc_t query_desc = { 0 };
iot_sg_sta_node_desc_t *node = NULL;
if (iot_sg_sta_ext_clct_rsd_check(rsd, &query_desc)) {
reason = 1;
goto nack;
}
if (iot_sg_sta_ext_clct_rcsd_check(rcsd, &query_desc)) {
reason = 2;
goto nack;
}
if (query_desc.data_type == IOT_SG_STA_METER_DATA_TYPE_JS_MF &&
query_desc.interval != IOT_SG_STA_EXT_DC_EXE_INTER_1MON) {
query_desc.interval = IOT_SG_STA_EXT_DC_EXE_INTER_1MON;
}
node = iot_sg_sta_node_find_by_addr(query_desc.addr);
if (!node) {
reason = 3;
goto nack;
}
query_desc.flag_3p = node->is_three_phase;
pkt = iot_sg_sta_ext_clct_record_data_ack(hdr_698, piid, oad, &query_desc);
if (pkt) {
goto out;
}
nack:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
pkt = iot_sg_sta_ext_clct_record_data_nack(hdr_698, piid, oad, rcsd);
out:
return pkt;
}
static void iot_sg_sta_ext_sus_fill_evt_unit_normal(
uint8_t *data, iot_sg_sta_drv_pf_po_info_t *sus_info)
{
proto_69845_app_norm_evt_unit_t * evt_unit = NULL;
evt_unit = (proto_69845_app_norm_evt_unit_t *)data;
evt_unit->data0_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_uint32_to_bytes(0x01, (uint8_t *)&evt_unit->evt_seq, 1);
evt_unit->data1_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes((uint16_t)(sus_info->pf_year + 2000),
(uint8_t *)&evt_unit->evt_start_time.year, 1);
evt_unit->evt_start_time.month = (uint8_t)sus_info->pf_month;
evt_unit->evt_start_time.day = (uint8_t)sus_info->pf_day;
evt_unit->evt_start_time.hour = (uint8_t)sus_info->pf_hour;
evt_unit->evt_start_time.minute = (uint8_t)sus_info->pf_min;
evt_unit->evt_start_time.second = (uint8_t)sus_info->pf_sec;
evt_unit->data2_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes((uint16_t)(sus_info->po_year + 2000),
(uint8_t *)&evt_unit->evt_end_time.year, 1);
evt_unit->evt_end_time.month = (uint8_t)sus_info->po_month;
evt_unit->evt_end_time.day = (uint8_t)sus_info->po_day;
evt_unit->evt_end_time.hour = (uint8_t)sus_info->po_hour;
evt_unit->evt_end_time.minute = (uint8_t)sus_info->po_min;
evt_unit->evt_end_time.second = (uint8_t)sus_info->po_sec;
evt_unit->data3_type = PROTO_69845_APP_DATA_ENUM;
evt_unit->evt_soc = PROTO_69845_APP_EVT_SOC_485_FALT;
evt_unit->data4_type = PROTO_69845_APP_DATA_ARRAY;
evt_unit->channel_cnt = 1;
evt_unit->data5_type = PROTO_69845_APP_DATA_STRUCTURE;
evt_unit->member_cnt = 2;
evt_unit->data6_type = PROTO_69845_APP_DATA_OAD;
proto_69845_oi_to_byte(PROTO_69845_APP_OI_PLC_WIRELESS_INTERFACE,
(uint8_t*)&evt_unit->channel_oad.oi);
evt_unit->channel_oad.attribute_id = 2;
evt_unit->channel_oad.attribute_char = 0;
evt_unit->channel_oad.element_index = 1;
evt_unit->data7_type = PROTO_69845_APP_DATA_UNSIGNED;
evt_unit->pf_rpt = (uint8_t)sus_info->pf_rpt;
evt_unit->pf_rpt_ok = (uint8_t)sus_info->pf_rpt_ok;
evt_unit->po_rpt = (uint8_t)sus_info->po_rpt;
evt_unit->po_rpt_ok = (uint8_t)sus_info->po_rpt_ok;
}
static void iot_sg_sta_ext_sus_fill_evt_unit_unrecover(
uint8_t *data, iot_sg_sta_drv_pf_po_info_t *sus_info)
{
proto_69845_app_unrecover_evt_unit_t * evt_unit = NULL;
evt_unit = (proto_69845_app_unrecover_evt_unit_t *)data;
evt_unit->data0_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
iot_uint32_to_bytes(0x01, (uint8_t *)&evt_unit->evt_seq, 1);
evt_unit->data1_type = PROTO_69845_APP_DATA_TIME_S;
iot_uint16_to_bytes((uint16_t)(sus_info->pf_year + 2000),
(uint8_t *)&evt_unit->evt_start_time.year, 1);
evt_unit->evt_start_time.month = (uint8_t)sus_info->pf_month;
evt_unit->evt_start_time.day = (uint8_t)sus_info->pf_day;
evt_unit->evt_start_time.hour = (uint8_t)sus_info->pf_hour;
evt_unit->evt_start_time.minute = (uint8_t)sus_info->pf_min;
evt_unit->evt_start_time.second = (uint8_t)sus_info->pf_sec;
evt_unit->data2_type = 0;
evt_unit->data3_type = PROTO_69845_APP_DATA_ENUM;
evt_unit->evt_soc = PROTO_69845_APP_EVT_SOC_485_FALT;
evt_unit->data4_type = PROTO_69845_APP_DATA_ARRAY;
evt_unit->channel_cnt = 1;
evt_unit->data5_type = PROTO_69845_APP_DATA_STRUCTURE;
evt_unit->member_cnt = 2;
evt_unit->data6_type = PROTO_69845_APP_DATA_OAD;
proto_69845_oi_to_byte(PROTO_69845_APP_OI_PLC_WIRELESS_INTERFACE,
(uint8_t*)&evt_unit->channel_oad.oi);
evt_unit->channel_oad.attribute_id = 2;
evt_unit->channel_oad.attribute_char = 0;
evt_unit->channel_oad.element_index = 1;
evt_unit->data7_type = PROTO_69845_APP_DATA_UNSIGNED;
evt_unit->pf_rpt = (uint8_t)sus_info->pf_rpt;
evt_unit->pf_rpt_ok = (uint8_t)sus_info->pf_rpt_ok;
evt_unit->po_rpt = (uint8_t)sus_info->po_rpt;
evt_unit->po_rpt_ok = (uint8_t)sus_info->po_rpt_ok;
}
static iot_pkt_t *iot_sg_sta_ext_sus_get_ele(
iot_sg_sta_ext_sus_query_desc_t *query_desc)
{
uint8_t i = 0, reason = 0;
uint8_t pf_tm_valid, po_tm_valid;
uint8_t addr[IOT_MAC_ADDR_LEN], *data = NULL;
uint16_t evt_unit_len = 0, data_len = 0;
proto_69845_app_abnorm_evt_unit_t *ab_evt_unit;
iot_pkt_t *pkt = NULL;
iot_sg_sta_drv_pf_po_info_t sus_info = {0};
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
if (!sta_glb->drv) {
reason = 1;
goto drop;
}
evt_unit_len = sizeof(proto_69845_app_norm_evt_unit_t) * query_desc->cnt;
pkt = iot_pkt_alloc(evt_unit_len, IOT_SMART_GRID_MID);
if (!pkt) {
reason = 2;
goto drop;
}
data = (uint8_t *)iot_pkt_data(pkt);
for (i = 0; i < query_desc->cnt; i++) {
iot_mac_addr_cpy(addr, query_desc->addr[i]);
os_mem_set(&sus_info, 0x00, sizeof(iot_sg_sta_drv_pf_po_info_t));
sta_glb->drv->get_pm_info(addr, IOT_SG_STA_PM_INFO_TYPE_PF_PO,
(uint8_t *)&sus_info, sizeof(iot_sg_sta_drv_pf_po_info_t));
pf_tm_valid = !!(sus_info.pf_year || sus_info.pf_month ||
sus_info.pf_day || sus_info.pf_hour || sus_info.pf_min ||
sus_info.pf_sec);
po_tm_valid = !!(sus_info.po_year || sus_info.po_month ||
sus_info.po_day || sus_info.po_hour || sus_info.po_min ||
sus_info.po_sec);
/* there is power off and power on record */
if (pf_tm_valid && po_tm_valid) {
iot_sg_sta_ext_sus_fill_evt_unit_normal(data, &sus_info);
data += sizeof(proto_69845_app_norm_evt_unit_t);
data_len += sizeof(proto_69845_app_norm_evt_unit_t);
/* there is power off record, not power on record */
} else if (pf_tm_valid && !po_tm_valid) {
iot_sg_sta_ext_sus_fill_evt_unit_unrecover(data, &sus_info);
data += sizeof(proto_69845_app_unrecover_evt_unit_t);
data_len += sizeof(proto_69845_app_unrecover_evt_unit_t);
/* there is not fault record, or node not exist */
} else if (!pf_tm_valid && !po_tm_valid) {
ab_evt_unit = (proto_69845_app_abnorm_evt_unit_t *)data;
os_mem_set(ab_evt_unit, 0x00,
sizeof(proto_69845_app_abnorm_evt_unit_t));
data += sizeof(proto_69845_app_abnorm_evt_unit_t);
data_len += sizeof(proto_69845_app_abnorm_evt_unit_t);
/* there is power on record, not power off record */
} else {
reason = 3;
goto drop;
}
}
iot_pkt_put(pkt, data_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_sus_record_data_ack(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
iot_sg_sta_ext_sus_query_desc_t *query_desc,
proto_69845_data_cache_desc_t *rcsd)
{
uint8_t *data, *result, *unit_cnt, *ele_data, addr_len;
uint16_t length, ele_len = 0;
uint16_t head_len, tail_len;
addr_info_t addr_info = { 0 };
iot_pkt_t *pkt = NULL, *ele_pkt = NULL;
proto_69845_frame_head_info_t *head;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_record_resp_t *record_resp;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
length = sizeof(proto_69845_frame_head_info_t) + addr_len
+ PROTO_69845_CHECKSUM_LEN
+ sizeof(proto_69845_app_req_resp_t)
+ sizeof(proto_69845_app_get_resp_t)
+ sizeof(proto_69845_app_get_record_resp_t) + (uint16_t)rcsd->len
+ sizeof(*result) + sizeof(*unit_cnt)
+ PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
/* element data */
ele_pkt = iot_sg_sta_ext_sus_get_ele(query_desc);
if (!ele_pkt) {
goto drop;
}
ele_len = (uint16_t)iot_pkt_data_len(ele_pkt);
length += ele_len;
if (length >= IOT_SG_STA_EXT_RPT_MAX_LEN) {
goto drop;
}
pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
if (!pkt)
goto drop;
/* fill 698.45 proto header */
data = iot_pkt_data(pkt);
head = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*head) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(head, head_len, length,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_RECORD;
data = data + sizeof(proto_69845_app_req_resp_t)
+ sizeof(proto_69845_app_get_resp_t);
record_resp = (proto_69845_app_get_record_resp_t*)get_resp->data;
record_resp->piid_acd.sn = piid->sn;
record_resp->piid_acd.priority = piid->priority;
record_resp->piid_acd.acd = 0;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&record_resp->oad.oi);
record_resp->oad.attribute_id = oad->attribute_id;
record_resp->oad.attribute_char = oad->attribute_char;
record_resp->oad.element_index = oad->element_index;
/* fill rcsd */
os_mem_cpy(record_resp->rcsd, rcsd->data, rcsd->len);
data += sizeof(*record_resp) + rcsd->len;
result = data;
*result = PROTO_69845_APP_GET_RESULT_DATA;
data += sizeof(*result);
unit_cnt = data;
*unit_cnt = query_desc->cnt;
data += sizeof(*unit_cnt);
ele_data = data;
/* fill element data */
os_mem_cpy(ele_data, iot_pkt_data(ele_pkt), ele_len);
data += ele_len;
tail_len = PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
proto_69845_tail_fill_without_ts_fl(head, data, tail_len);
iot_pkt_put(pkt, head->len + PROTO_69845_START_END_LEN);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
out:
if (ele_pkt) {
iot_pkt_free(ele_pkt);
}
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_fault_record_data_query(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
proto_69845_data_cache_desc_t *rsd,
proto_69845_data_cache_desc_t *rcsd)
{
uint16_t length;
iot_pkt_t *pkt = NULL, *desc_pkt = NULL;
iot_sg_sta_ext_sus_query_desc_t *query_desc;
length = sizeof(*query_desc);
desc_pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
if (!desc_pkt)
goto out;
query_desc = (iot_sg_sta_ext_sus_query_desc_t *)
iot_pkt_put(desc_pkt, length);
if (iot_sg_sta_ext_sus_rsd_check(rsd, query_desc)) {
goto out;
}
pkt = iot_sg_sta_ext_sus_record_data_ack(hdr_698, piid, oad, query_desc,
rcsd);
out:
if (desc_pkt) {
iot_pkt_free(desc_pkt);
}
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_rpt_action_resp(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_omd_t *omd, uint8_t dar)
{
iot_pkt_t *pkt = NULL;
addr_info_t addr_info = {0};
proto_69845_get_addr_info(hdr_698, &addr_info);
pkt = proto_69845_action_single_ack(&addr_info, piid, omd, dar);
if (pkt == NULL) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
}
return pkt;
}
static void iot_sg_sta_ext_rpt_start(void)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
evt_rpt->cur_state = IOT_SG_STA_COLL_DATA_RPT_STATE_MF;
}
static void iot_sg_sta_ext_rpt_index_update(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
iot_sg_sta_node_desc_t *node;
node = iot_sg_sta_node_find_by_addr(rpt_info->addr);
if (node) {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
node->ext.data_clct_info.mf_rpt_index = rpt_info->end_index + 1;
if (node->ext.data_clct_info.mf_rpt_index >=
IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT) {
node->ext.data_clct_info.mf_rpt_index = 0;
}
if (node->ext.data_clct_info.mf_cnt > rpt_info->cnt) {
node->ext.data_clct_info.mf_cnt -= rpt_info->cnt;
}
else {
node->ext.data_clct_info.mf_cnt = 0;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
node->ext.data_clct_info.df_rpt_index = rpt_info->end_index + 1;
if (node->ext.data_clct_info.df_rpt_index >=
IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT) {
node->ext.data_clct_info.df_rpt_index = 0;
}
if (node->ext.data_clct_info.df_cnt > rpt_info->cnt) {
node->ext.data_clct_info.df_cnt -= rpt_info->cnt;
}
else {
node->ext.data_clct_info.df_cnt = 0;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
node->ext.data_clct_info.min15_rpt_index = rpt_info->end_index + 1;
if (node->ext.data_clct_info.min15_rpt_index >=
IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT) {
node->ext.data_clct_info.min15_rpt_index = 0;
}
if (node->ext.data_clct_info.min15_cnt > rpt_info->cnt) {
node->ext.data_clct_info.min15_cnt -= rpt_info->cnt;
}
else {
node->ext.data_clct_info.min15_cnt = 0;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
node->ext.data_clct_info.min1_rpt_index = rpt_info->end_index + 1;
if (node->ext.data_clct_info.min1_rpt_index >=
IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT) {
node->ext.data_clct_info.min1_rpt_index = 0;
}
if (node->ext.data_clct_info.min1_cnt > rpt_info->cnt) {
node->ext.data_clct_info.min1_cnt -= rpt_info->cnt;
}
else {
node->ext.data_clct_info.min1_cnt = 0;
}
break;
}
default:
break;
}
}
return;
}
static uint32_t iot_sg_sta_ext_get_oad_map(uint8_t rpt_state,
uint32_t *map, uint8_t is_3p)
{
uint8_t cfg_type, type_cache;
uint32_t ret = ERR_FAIL;
iot_pkt_t *pkt_buff = NULL;
iot_sg_meter_js_task_config_hdr_t *cfg;
pkt_buff = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
if (!pkt_buff) {
goto out;
}
cfg = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buff,
sizeof(*cfg));
switch (rpt_state) {
case IOT_SG_STA_COLL_DATA_RPT_STATE_MF:
{
if (is_3p) {
cfg_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF;
} else {
cfg_type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
}
type_cache = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_DF:
{
if (is_3p) {
cfg_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF;
} else {
cfg_type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
}
type_cache = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_15MIN:
{
if (is_3p) {
cfg_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN;
} else {
cfg_type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
}
type_cache = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_1MIN:
{
if (is_3p) {
cfg_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN;
} else {
cfg_type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
}
type_cache = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
break;
}
default:
goto out;
}
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(cfg_type, cfg);
if ((ret == ERR_OK) && cfg->scheme_num) {
*map = cfg->cfg_di_bm;
if (rpt_state == IOT_SG_STA_COLL_DATA_RPT_STATE_MF
|| rpt_state == IOT_SG_STA_COLL_DATA_RPT_STATE_DF) {
*map |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
}
} else if (is_3p) {
/* get all meter cfg */
os_mem_set(cfg, 0, sizeof(*cfg));
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(type_cache, cfg);
if (ret == ERR_OK && cfg->scheme_num && cfg->all_flag) {
*map = cfg->cfg_di_bm;
if (rpt_state == IOT_SG_STA_COLL_DATA_RPT_STATE_MF
|| rpt_state == IOT_SG_STA_COLL_DATA_RPT_STATE_DF) {
*map |= (1 << IOT_SG_STA_METER_TASK_DI_FROZEN_TIME);
}
} else {
ret = ERR_FAIL;
}
} else {
ret = ERR_FAIL;
}
if (ret == ERR_OK && rpt_state == IOT_SG_STA_COLL_DATA_RPT_STATE_DF) {
if (is_3p) {
cfg_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C;
} else {
cfg_type = IOT_SG_STA_METER_JS_CFG_TYPE_D_C;
}
if (iot_sg_sta_flash_js_task_cfg_get_by_type(cfg_type, cfg) == ERR_OK
&& cfg->scheme_num) {
*map |= cfg->cfg_di_bm;
}
}
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return ret;
}
static uint32_t iot_sg_sta_ext_rpt_info_check(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *reason)
{
uint8_t *buff_ptr;
uint16_t unit_len;
uint32_t ret;
iot_pkt_t *pkt_buff = NULL;
iot_sg_sta_flash_unit_get_data_info(rpt_info->data_type, &unit_len, NULL);
pkt_buff = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
if (pkt_buff == NULL) {
ret = ERR_NOMEM;
goto out;
}
buff_ptr = iot_pkt_put(pkt_buff, unit_len);
ret = iot_sg_sta_flash_unit_data_read(rpt_info->addr,
rpt_info->start_index, buff_ptr, unit_len, rpt_info->data_type);
if (ret) {
*reason = 1;
goto drop;
}
ret = iot_sg_sta_flash_unit_data_read(rpt_info->addr,
rpt_info->end_index, buff_ptr, unit_len, rpt_info->data_type);
if (ret) {
*reason = 2;
goto drop;
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_INVAL;
out:
if (pkt_buff) {
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
}
return ret;
}
static uint32_t iot_sg_sta_ext_get_rpt_node(uint8_t rpt_state,
iot_sg_sta_node_desc_t *node, iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
uint32_t ret = ERR_INVAL;
uint16_t *start_idx, *cnt, max_idx;
uint8_t data_type, reason = 0;
if (!node) {
goto out;
}
switch (rpt_state) {
case IOT_SG_STA_COLL_DATA_RPT_STATE_MF:
{
if (!node->ext.data_clct_info.mf_cnt) {
goto out;
}
max_idx = IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
start_idx = &node->ext.data_clct_info.mf_rpt_index;
cnt = &node->ext.data_clct_info.mf_cnt;
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_MF;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_DF:
{
if (!node->ext.data_clct_info.df_cnt) {
goto out;
}
max_idx = IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
start_idx = &node->ext.data_clct_info.df_rpt_index;
cnt = &node->ext.data_clct_info.df_cnt;
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_DF;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_15MIN:
{
if (!node->ext.data_clct_info.min15_cnt) {
goto out;
}
max_idx = IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
start_idx = &node->ext.data_clct_info.min15_rpt_index;
cnt = &node->ext.data_clct_info.min15_cnt;
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE;
break;
}
case IOT_SG_STA_COLL_DATA_RPT_STATE_1MIN:
{
if (!node->ext.data_clct_info.min1_cnt) {
goto out;
}
max_idx = IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
start_idx = &node->ext.data_clct_info.min1_rpt_index;
cnt = &node->ext.data_clct_info.min1_cnt;
data_type = IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE;
break;
}
default:
goto out;
}
iot_mac_addr_cpy(rpt_info->addr, node->entry.addr);
rpt_info->start_index = *start_idx;
if (*start_idx + *cnt > max_idx) {
rpt_info->end_index = *start_idx + *cnt - max_idx - 1;
} else {
rpt_info->end_index = *start_idx + *cnt - 1;
}
rpt_info->data_type = data_type;
rpt_info->cnt = *cnt;
rpt_info->flag_3p = node->is_three_phase;
ret = iot_sg_sta_ext_rpt_info_check(rpt_info, &reason);
if (ret) {
if (ret == ERR_INVAL) {
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x, type %lu "
"reason %lu\n", __FUNCTION__, rpt_info->addr[0],
rpt_info->addr[1], rpt_info->addr[2], rpt_info->addr[3],
rpt_info->addr[4], rpt_info->addr[5], rpt_info->data_type,
reason);
*start_idx = 0;
*cnt = 0;
}
goto out;
}
ret = iot_sg_sta_ext_get_oad_map(rpt_state, &rpt_info->oad_map,
rpt_info->flag_3p);
out:
return ret;
}
static uint32_t iot_sg_sta_ext_get_rpt_info_to_multi_rpt_info(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info,
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
uint32_t ret = ERR_INVAL;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (!rpt_info || !multi_rpt_info) {
goto out;
}
if (!iot_mac_addr_valid(rpt_info->addr)) {
goto out;
}
if (multi_rpt_info->meter_info_cnt >= IOT_SG_STA_CLCT_METER_INFO_MAX_CNT) {
goto out;
}
if (multi_rpt_info->meter_info_cnt) {
if (multi_rpt_info->oad_map != rpt_info->oad_map ||
multi_rpt_info->flag_3p != rpt_info->flag_3p ||
multi_rpt_info->data_type != rpt_info->data_type) {
goto out;
}
} else {
multi_rpt_info->oad_map = rpt_info->oad_map;
multi_rpt_info->flag_3p = rpt_info->flag_3p;
multi_rpt_info->data_type = rpt_info->data_type;
}
meter_info = &multi_rpt_info->meter_info[multi_rpt_info->meter_info_cnt];
iot_mac_addr_cpy(meter_info->addr, rpt_info->addr);
meter_info->end_index = rpt_info->end_index;
meter_info->start_index = rpt_info->start_index;
meter_info->cnt = rpt_info->cnt;
ret = ERR_OK;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_get_simp_rpt_node(uint8_t rpt_state,
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_node_desc_t *node;
iot_sg_sta_ext_clct_rpt_desc_t rpt_info_tmp;
iot_sg_meter_unit_time_t *unit_time;
iot_pkt_t *pkt_buff = NULL;
iot_time_tm_t earliest_tm = { 0 }, cur_tm = { 0 };
uint8_t idx, *buff_ptr;
uint16_t buff_len;
uint32_t ret = ERR_FAIL;
int64_t delta;
if (!multi_rpt_info) {
goto out;
}
pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (!pkt_buff) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto out;
}
buff_len = (uint16_t)iot_pkt_data_len(pkt_buff);
buff_ptr = iot_pkt_data(pkt_buff);
for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
if (sta_glb->node_list[idx] == NULL) {
continue;
}
node = sta_glb->node_list[idx];
if (!iot_mac_addr_valid(node->entry.addr)) {
continue;
}
if (iot_sg_sta_ext_get_rpt_node(rpt_state, node, &rpt_info_tmp)) {
continue;
}
if (iot_sg_sta_flash_unit_data_read(rpt_info_tmp.addr,
rpt_info_tmp.start_index, buff_ptr, buff_len,
rpt_info_tmp.data_type)) {
continue;
}
unit_time = (iot_sg_meter_unit_time_t *)buff_ptr;
cur_tm.tm_year = (uint16_t)unit_time->year + 2000;
cur_tm.tm_mon = (uint8_t)unit_time->month;
cur_tm.tm_mday = (uint8_t)unit_time->day;
cur_tm.tm_hour = (uint8_t)unit_time->hour;
cur_tm.tm_min = (uint8_t)unit_time->minute;
/* get report time earliest node */
if (!multi_rpt_info->meter_info_cnt) {
if (!iot_sg_sta_ext_get_rpt_info_to_multi_rpt_info(&rpt_info_tmp,
multi_rpt_info)) {
earliest_tm = cur_tm;
multi_rpt_info->meter_info_cnt++;
ret = ERR_OK;
}
} else {
delta = iot_rtc_delta_calc(&cur_tm, &earliest_tm);
if (delta == 0) {
if (!iot_sg_sta_ext_get_rpt_info_to_multi_rpt_info(&rpt_info_tmp,
multi_rpt_info)) {
multi_rpt_info->meter_info_cnt++;
ret = ERR_OK;
}
} else if (delta > 0) {
os_mem_set(multi_rpt_info, 0x0, sizeof(*multi_rpt_info));
if (!iot_sg_sta_ext_get_rpt_info_to_multi_rpt_info(&rpt_info_tmp,
multi_rpt_info)) {
earliest_tm = cur_tm;
multi_rpt_info->meter_info_cnt++;
ret = ERR_OK;
}
}
}
}
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return ret;
}
static uint8_t iot_sg_sta_ext_get_rpt_sn(void)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
evt_rpt->seq++;
if (evt_rpt->seq > PROTO_69845_RPT_MAX_SN) {
evt_rpt->seq = 0;
}
return evt_rpt->seq;
}
static uint16_t iot_sg_sta_ext_get_rpt_unit_cnt(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint16_t max_cnt)
{
uint16_t cnt = 0, index_max;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
index_max = IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
index_max = IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
index_max = IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
index_max = IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
break;
}
default:
goto out;
}
if ((rpt_info->start_index >= index_max)
|| (rpt_info->end_index >= index_max)) {
goto out;
}
if (rpt_info->end_index >= rpt_info->start_index) {
cnt = rpt_info->end_index - rpt_info->start_index + 1;
} else {
cnt = index_max - rpt_info->start_index + rpt_info->end_index + 1;
}
if (cnt > max_cnt) {
cnt = max_cnt;
rpt_info->end_index = rpt_info->start_index + cnt - 1;
if (rpt_info->end_index >= index_max) {
rpt_info->end_index -= index_max;
}
}
rpt_info->cnt = cnt;
out:
return cnt;
}
static uint32_t iot_sg_sta_ext_rpt_v_simp_fill(proto_645_v_t *src_v,
uint8_t *ptr, uint32_t rec_len, uint8_t flag_3p)
{
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_v_3p_simp_t *v_3p_t;
proto_69845_rpt_v_single_simp_t *v_t;
if (flag_3p) {
if (rec_len < sizeof(*v_3p_t)) {
goto out;
}
v_3p_t = (proto_69845_rpt_v_3p_simp_t*)ptr;
if (iot_bcd_data_check(src_v->a, sizeof(v_3p_t->a))) {
iot_bcd_to_uint32(src_v->a, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->a, 1);
} else {
os_mem_set(v_3p_t->a, 0xff, sizeof(v_3p_t->a));
}
if (iot_bcd_data_check(src_v->b, sizeof(v_3p_t->b))) {
iot_bcd_to_uint32(src_v->b, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->b, 1);
} else {
os_mem_set(v_3p_t->b, 0xff, sizeof(v_3p_t->b));
}
if (iot_bcd_data_check(src_v->c, sizeof(v_3p_t->c))) {
iot_bcd_to_uint32(src_v->c, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_3p_t->c, 1);
} else {
os_mem_set(v_3p_t->c, 0xff, sizeof(v_3p_t->c));
}
fill_len = sizeof(*v_3p_t);
} else {
if (rec_len < sizeof(*v_t)) {
goto out;
}
v_t = (proto_69845_rpt_v_single_simp_t*)ptr;
if (iot_bcd_data_check(src_v->a, sizeof(src_v->a))) {
iot_bcd_to_uint32(src_v->a, PROTO_645_V_LEN, 0, &cache_value);
iot_uint16_to_bytes((uint16_t)cache_value, v_t->a, 1);
} else {
os_mem_set(v_t->a, 0xff, sizeof(v_t->a));
}
fill_len = sizeof(*v_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_single_i_simp_fill(uint8_t *i,
uint8_t *ptr, uint32_t rec_len)
{
uint8_t flag_neg = 0;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_i_single_simp_t *i_t;
if (rec_len < sizeof(*i_t)) {
goto out;
}
i_t = (proto_69845_rpt_i_single_simp_t*)ptr;
flag_neg = !!(0x80 & i[PROTO_645_07_A_LEN - 1]);
i[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(i, PROTO_645_07_A_LEN)) {
iot_bcd_to_uint32(i, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_t->a, 1);
}
fill_len = sizeof(*i_t);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_i_simp_fill(proto_645_07_a_t *src_i,
uint8_t *ptr, uint32_t rec_len, uint8_t flag_3p)
{
uint8_t flag_neg = 0;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_i_3p_simp_t *i_3p_t;
if (flag_3p) {
if (rec_len < sizeof(*i_3p_t)) {
goto out;
}
i_3p_t = (proto_69845_rpt_i_3p_simp_t*)ptr;
flag_neg = !!(0x80 & src_i->a[PROTO_645_07_A_LEN - 1]);
src_i->a[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_i->a, sizeof(src_i->a))) {
iot_bcd_to_uint32(src_i->a, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_i->b[PROTO_645_07_A_LEN - 1]);
src_i->b[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_i->b, sizeof(src_i->b))) {
iot_bcd_to_uint32(src_i->b, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->b, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_i->c[PROTO_645_07_A_LEN - 1]);
src_i->c[PROTO_645_07_A_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_i->c, sizeof(src_i->c))) {
iot_bcd_to_uint32(src_i->c, PROTO_645_07_A_LEN, 0, &cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, i_3p_t->c, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, i_3p_t->c, 1);
}
fill_len = sizeof(*i_3p_t);
} else {
fill_len = iot_sg_sta_ext_rpt_single_i_simp_fill(src_i->a, ptr, rec_len);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_power_simp_fill(
proto_645_07_p_t *src_power, uint8_t *ptr, uint32_t rec_len,
uint8_t flag_3p)
{
uint8_t flag_neg = 0;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_power_3p_simp_t *power_3p_t;
proto_69845_rpt_power_single_simp_t *power_t;
if (flag_3p) {
if (rec_len < sizeof(*power_3p_t)) {
goto out;
}
power_3p_t = (proto_69845_rpt_power_3p_simp_t*)ptr;
flag_neg = !!(0x80 & src_power->total[PROTO_645_07_P_LEN - 1]);
src_power->total[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_power->total,
sizeof(src_power->total))) {
iot_bcd_to_uint32(src_power->total, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->total, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->total, 1);
}
flag_neg = !!(0x80 & src_power->a[PROTO_645_07_P_LEN - 1]);
src_power->a[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_power->a,
sizeof(src_power->a))) {
iot_bcd_to_uint32(src_power->a, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_power->b[PROTO_645_07_P_LEN - 1]);
src_power->b[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_power->b,
sizeof(src_power->b))) {
iot_bcd_to_uint32(src_power->b, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->b, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_power->c[PROTO_645_07_P_LEN - 1]);
src_power->c[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_power->c,
sizeof(src_power->c))) {
iot_bcd_to_uint32(src_power->c, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_3p_t->c, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_3p_t->c, 1);
}
fill_len = sizeof(*power_3p_t);
} else {
if (rec_len < sizeof(*power_t)) {
goto out;
}
power_t = (proto_69845_rpt_power_single_simp_t*)ptr;
flag_neg = !!(0x80 & src_power->total[PROTO_645_07_P_LEN - 1]);
src_power->total[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_power->total,
sizeof(src_power->total))) {
iot_bcd_to_uint32(src_power->total, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_t->total, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_t->total, 1);
}
flag_neg = !!(0x80 & src_power->a[PROTO_645_07_P_LEN - 1]);
src_power->a[PROTO_645_07_P_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_power->a,
sizeof(src_power->a))) {
iot_bcd_to_uint32(src_power->a, PROTO_645_07_P_LEN, 0,
&cache_value);
if (flag_neg) {
cache_value = 0 - cache_value;
}
iot_uint32_to_bytes(cache_value, power_t->a, 1);
} else {
iot_uint32_to_bytes(0x7fffffff, power_t->a, 1);
}
fill_len = sizeof(*power_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_pf_simp_fill(
proto_645_07_pf_t *src_pf, uint8_t *ptr, uint32_t rec_len,
uint8_t flag_3p)
{
uint8_t flag_neg = 0;
uint16_t cache = 0;
uint32_t cache_value = 0, fill_len = 0;
proto_69845_rpt_pf_3p_simp_t *pf_3p_t;
proto_69845_rpt_pf_single_simp_t *pf_t;
if (flag_3p) {
if (rec_len < sizeof(*pf_3p_t)) {
goto out;
}
pf_3p_t = (proto_69845_rpt_pf_3p_simp_t*)ptr;
flag_neg = !!(0x80 & src_pf->total[PROTO_645_07_PF_LEN - 1]);
src_pf->total[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_pf->total,
sizeof(src_pf->total))) {
iot_bcd_to_uint32(src_pf->total, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->total, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->total, 1);
}
flag_neg = !!(0x80 & src_pf->a[PROTO_645_07_PF_LEN - 1]);
src_pf->a[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_pf->a,
sizeof(src_pf->a))) {
iot_bcd_to_uint32(src_pf->a, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->a, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->a, 1);
}
flag_neg = !!(0x80 & src_pf->b[PROTO_645_07_PF_LEN - 1]);
src_pf->b[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_pf->b,
sizeof(src_pf->b))) {
iot_bcd_to_uint32(src_pf->b, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->b, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->b, 1);
}
flag_neg = !!(0x80 & src_pf->c[PROTO_645_07_PF_LEN - 1]);
src_pf->c[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check((uint8_t*)src_pf->c,
sizeof(src_pf->c))) {
iot_bcd_to_uint32(src_pf->c, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_3p_t->c, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_3p_t->c, 1);
}
fill_len = sizeof(*pf_3p_t);
} else {
if (rec_len < sizeof(*pf_t)) {
goto out;
}
pf_t = (proto_69845_rpt_pf_single_simp_t*)ptr;
flag_neg = !!(0x80 & src_pf->total[PROTO_645_07_PF_LEN - 1]);
src_pf->total[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->total, sizeof(src_pf->total))) {
iot_bcd_to_uint32(src_pf->total, PROTO_645_07_PF_LEN, 0,
&cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_t->total, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_t->total, 1);
}
flag_neg = !!(0x80 & src_pf->a[PROTO_645_07_PF_LEN - 1]);
src_pf->a[PROTO_645_07_PF_LEN - 1] &= 0x7f;
if (iot_bcd_data_check(src_pf->a, sizeof(src_pf->a))) {
iot_bcd_to_uint32(src_pf->a, PROTO_645_07_PF_LEN, 0, &cache_value);
cache = (uint16_t)cache_value;
if (flag_neg) {
cache = 0 - cache;
}
iot_uint16_to_bytes(cache, pf_t->a, 1);
} else {
iot_uint16_to_bytes(0x7fff, pf_t->a, 1);
}
fill_len = sizeof(*pf_t);
}
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_ftime_simp_fill(uint32_t *time, uint8_t *ptr,
uint32_t rec_len)
{
uint32_t fill_len = 0, cache_value;
proto_69845_rpt_data_time_s_simp_t *rpt_time;
iot_sg_meter_unit_time_t *unit_time;
if (rec_len < sizeof(*rpt_time)) {
goto out;
}
rpt_time = (proto_69845_rpt_data_time_s_simp_t*)ptr;
if (*time == 0xffffffff) {
iot_uint16_to_bytes(0xffff, (uint8_t*)&rpt_time->year, 1);
rpt_time->month = 0xff;
rpt_time->day = 0xff;
rpt_time->hour = 0xff;
rpt_time->minute = 0xff;
rpt_time->second = 0xff;
} else {
unit_time = (iot_sg_meter_unit_time_t *)time;
cache_value = unit_time->year + 2000;
iot_uint16_to_bytes((uint16_t)cache_value,
(uint8_t*)&rpt_time->year, 1);
rpt_time->month = (uint8_t)unit_time->month;
rpt_time->day = (uint8_t)unit_time->day;
rpt_time->hour = (uint8_t)unit_time->hour;
rpt_time->minute = (uint8_t)unit_time->minute;
rpt_time->second = 0;
}
fill_len = sizeof(*rpt_time);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_rpt_cur_time_simp_fill(
iot_sg_meter_cur_time_t *time, uint8_t *ptr, uint32_t rec_len)
{
uint32_t fill_len = 0, cache_value;
proto_69845_rpt_data_time_s_simp_t *rpt_time;
if (rec_len < sizeof(*rpt_time)) {
goto out;
}
rpt_time = (proto_69845_rpt_data_time_s_simp_t*)ptr;
if (time->second == 0xff) {
iot_uint16_to_bytes(0xffff, (uint8_t*)&rpt_time->year, 1);
rpt_time->month = 0xff;
rpt_time->day = 0xff;
rpt_time->hour = 0xff;
rpt_time->minute = 0xff;
rpt_time->second = 0xff;
} else {
cache_value = time->year + 2000;
iot_uint16_to_bytes((uint16_t)cache_value,
(uint8_t*)&rpt_time->year, 1);
rpt_time->month = (uint8_t)time->month;
rpt_time->day = (uint8_t)time->day;
rpt_time->hour = (uint8_t)time->hour;
rpt_time->minute = (uint8_t)time->minute;
rpt_time->second = (uint8_t)time->second;
}
fill_len = sizeof(*rpt_time);
out:
return fill_len;
}
static uint32_t iot_sg_sta_ext_sig_simp_data_uint_fill(
iot_sg_meter_js_sig_frozen_uint_data_t *sig_t, uint8_t di_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, n, di,*src_energy = NULL, buf[SIG_CACHE_BUF];
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
for (n = 0; n < di_cnt; n++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
proto_69845_meter_energy_data_simp_t *dst_energy;
if (rec_len < sizeof(*dst_energy)) {
goto drop;
}
dst_energy = (proto_69845_meter_energy_data_simp_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
src_energy = sig_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
src_energy = sig_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
src_energy = sig_t->cre1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
src_energy = sig_t->cre2;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
src_energy = NULL;
break;
}
default:
goto drop;
}
iot_sg_sta_ext_energy_fill(src_energy, dst_energy->total, 0);
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_1, 0);
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_2, 0);
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_3, 0);
iot_sg_sta_ext_energy_fill(NULL, dst_energy->rate_4, 0);
rec_len -= sizeof(*dst_energy);
ptr += sizeof(*dst_energy);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
uint8_t *energy_sum = NULL;
proto_69845_rpt_meter_energy_sum_data_simp_t *dst_sum;
if (rec_len < sizeof(*dst_sum)) {
goto drop;
}
dst_sum = (proto_69845_rpt_meter_energy_sum_data_simp_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
energy_sum = sig_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
energy_sum = sig_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
break;
}
default:
goto drop;
}
iot_sg_sta_ext_energy_fill(energy_sum, dst_sum->total, 0);
rec_len -= sizeof(*dst_sum);
ptr += sizeof(*dst_sum);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
proto_645_v_t *v;
BUILD_BUG_ON(sizeof(*v) <= SIG_CACHE_BUF);
v = (proto_645_v_t*)buf;
os_mem_set(v, 0xff, sizeof(*v));
os_mem_cpy(v->a, sig_t->v, PROTO_645_V_LEN);
fill_len = iot_sg_sta_ext_rpt_v_simp_fill(v, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
proto_645_07_a_t *i;
BUILD_BUG_ON(sizeof(*i) <= SIG_CACHE_BUF);
i = (proto_645_07_a_t*)buf;
os_mem_set(i, 0xff, sizeof(*i));
os_mem_cpy(i->a, sig_t->i, PROTO_645_07_A_LEN);
fill_len = iot_sg_sta_ext_rpt_i_simp_fill(i, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_simp_fill(sig_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
BUILD_BUG_ON(sizeof(*src_power) <= SIG_CACHE_BUF);
src_power = (proto_645_07_p_t*)buf;
os_mem_set(src_power, 0xff, sizeof(*src_power));
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
os_mem_cpy(src_power->total, sig_t->active_power,
PROTO_645_07_P_LEN);
os_mem_cpy(src_power->a, sig_t->active_power,
PROTO_645_07_P_LEN);
} else {
os_mem_cpy(src_power->total, sig_t->reactive_power,
PROTO_645_07_P_LEN);
os_mem_cpy(src_power->a, sig_t->reactive_power,
PROTO_645_07_P_LEN);
}
fill_len = iot_sg_sta_ext_rpt_power_simp_fill(src_power, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
proto_645_07_pf_t *power_factor;
BUILD_BUG_ON(sizeof(*power_factor) <= SIG_CACHE_BUF);
power_factor = (proto_645_07_pf_t*)buf;
os_mem_set(power_factor, 0xff, sizeof(*power_factor));
os_mem_cpy(power_factor->total, sig_t->power_factor,
PROTO_645_07_PF_LEN);
os_mem_cpy(power_factor->a, sig_t->power_factor,
PROTO_645_07_PF_LEN);
fill_len = iot_sg_sta_ext_rpt_pf_simp_fill(power_factor, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_simp_fill((uint32_t *)sig_t,
ptr, rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
fill_len = iot_sg_sta_ext_rpt_cur_time_simp_fill(&sig_t->time, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_nomin_simp_data_uint_fill(
iot_sg_meter_js_frozen_uint_data_t *frozen_t, uint8_t di_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, i, di;
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
for (i = 0; i < di_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
iot_sg_meter_energy_data_t *src_energy = NULL;
proto_69845_meter_energy_data_simp_t *dst_energy;
if (rec_len < sizeof(*dst_energy)) {
goto drop;
}
dst_energy = (proto_69845_meter_energy_data_simp_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
{
src_energy = &frozen_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
{
src_energy = &frozen_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
{
src_energy = &frozen_t->cre1;
break;
}
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
{
src_energy = &frozen_t->cre2;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
{
src_energy = &frozen_t->re_1st_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
{
src_energy = &frozen_t->re_2nd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
{
src_energy = &frozen_t->re_3rd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
src_energy = &frozen_t->re_4th_power;
break;
}
default:
goto drop;
}
iot_sg_sta_ext_energy_fill(src_energy->total,
dst_energy->total, 0);
iot_sg_sta_ext_energy_fill(src_energy->rate_1,
dst_energy->rate_1, 0);
iot_sg_sta_ext_energy_fill(src_energy->rate_2,
dst_energy->rate_2, 0);
iot_sg_sta_ext_energy_fill(src_energy->rate_3,
dst_energy->rate_3, 0);
iot_sg_sta_ext_energy_fill(src_energy->rate_4,
dst_energy->rate_4, 0);
rec_len -= sizeof(*dst_energy);
ptr += sizeof(*dst_energy);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
iot_sg_meter_energy_data_t *src_sum = NULL;
proto_69845_rpt_meter_energy_sum_data_simp_t *dst_sum;
if (rec_len < sizeof(*dst_sum)) {
goto drop;
}
dst_sum = (proto_69845_rpt_meter_energy_sum_data_simp_t*)ptr;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
{
src_sum = &frozen_t->ept_pos;
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
{
src_sum = &frozen_t->ept_neg;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
{
src_sum = &frozen_t->re_1st_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
{
src_sum = &frozen_t->re_2nd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
{
src_sum = &frozen_t->re_3rd_power;
break;
}
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
src_sum = &frozen_t->re_4th_power;
break;
}
default:
goto drop;
}
iot_sg_sta_ext_energy_fill(src_sum->total, dst_sum->total, 0);
rec_len -= sizeof(*dst_sum);
ptr += sizeof(*dst_sum);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
fill_len = iot_sg_sta_ext_rpt_v_simp_fill(&frozen_t->v, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_i_simp_fill(&frozen_t->i, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_simp_fill(frozen_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
src_power = &frozen_t->active_power;
} else {
src_power = &frozen_t->reactive_power;
}
fill_len = iot_sg_sta_ext_rpt_power_simp_fill(src_power, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
fill_len = iot_sg_sta_ext_rpt_pf_simp_fill(&frozen_t->power_factor,
ptr, rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_simp_fill((uint32_t *)frozen_t,
ptr, rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_min_simp_data_uint_fill(
iot_sg_meter_js_min_curve_uint_data_t *min_t, uint8_t di_cnt,
uint8_t *data, uint16_t data_len, uint32_t oad_bm, uint8_t flag_3p)
{
uint8_t m = 1, *ptr = data, i, di;
uint32_t rec_len = data_len;
uint32_t bm = oad_bm, ret = ERR_OK, fill_len;
for (i = 0; i < di_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto drop;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
fill_len = iot_sg_sta_ext_rpt_v_simp_fill(&min_t->v, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_i_simp_fill(&min_t->i, ptr, rec_len,
flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
fill_len = iot_sg_sta_ext_rpt_single_i_simp_fill(min_t->n, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
proto_645_07_p_t *src_power;
if (di == IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER) {
src_power = &min_t->active_power;
} else {
src_power = &min_t->reactive_power;
}
fill_len = iot_sg_sta_ext_rpt_power_simp_fill(src_power, ptr,
rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
fill_len = iot_sg_sta_ext_rpt_pf_simp_fill(&min_t->power_factor,
ptr, rec_len, flag_3p);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
{
fill_len = iot_sg_sta_ext_rpt_ftime_simp_fill((uint32_t *)min_t,
ptr, rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
case IOT_SG_STA_METER_TASK_DI_TIME:
{
fill_len = iot_sg_sta_ext_rpt_cur_time_simp_fill(&min_t->time, ptr,
rec_len);
if ((fill_len == 0) || (rec_len < fill_len)) {
goto drop;
}
rec_len -= fill_len;
ptr += fill_len;
break;
}
default:
goto drop;
}
m++;
}
goto out;
drop:
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_oad_data_uint_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt, uint16_t index, uint8_t is_simple_data)
{
uint8_t *buff_ptr, *ptr = data, di_cnt;
uint16_t unit_len, idx, buff_len;
uint32_t ret = ERR_FAIL;
iot_pkt_t *pkt_buff = NULL;
iot_sg_meter_js_min_curve_uint_data_t *min_t;
iot_sg_meter_js_frozen_uint_data_t *frozen_t;
iot_sg_meter_js_sig_frozen_uint_data_t *sig_t;
pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (pkt_buff == NULL) {
goto drop;
}
buff_ptr = iot_pkt_data(pkt_buff);
buff_len = (uint16_t)iot_pkt_data_len(pkt_buff);
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_MF_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_DF_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_15MIN_CURVE_MARK_MAX_CNT;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
idx = rpt_info->start_index + index;
if (idx >= IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT) {
idx = idx - IOT_SG_STA_METER_JS_1MIN_CURVE_MARK_MAX_CNT;
}
break;
}
default:
ret = ERR_FAIL;
goto out;
}
iot_sg_sta_flash_unit_get_data_info(rpt_info->data_type, &unit_len, NULL);
if (buff_len < unit_len) {
ret = ERR_FAIL;
goto out;
}
ret = iot_sg_sta_flash_unit_data_read(rpt_info->addr,
idx, buff_ptr, unit_len, rpt_info->data_type);
if (ret) {
goto drop;
}
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
if (iot_sg_sta_flash_mode_js_sig_check()) {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
frozen_t = (iot_sg_meter_js_frozen_uint_data_t*)buff_ptr;
if (is_simple_data) {
ret = iot_sg_sta_ext_nomin_simp_data_uint_fill(frozen_t,
di_cnt, ptr, len, rpt_info->oad_map, rpt_info->flag_3p);
} else {
ret = iot_sg_sta_ext_nomin_data_uint_fill(frozen_t, oad_cnt,
ptr, len, rpt_info->oad_map, rpt_info->flag_3p);
}
if (ret) {
goto drop;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
sig_t = (iot_sg_meter_js_sig_frozen_uint_data_t*)buff_ptr;
if (is_simple_data) {
ret = iot_sg_sta_ext_sig_simp_data_uint_fill(sig_t, di_cnt, ptr,
len, rpt_info->oad_map, rpt_info->flag_3p);
} else {
ret = iot_sg_sta_ext_sig_data_uint_fill(sig_t, oad_cnt, ptr, len,
rpt_info->oad_map, rpt_info->flag_3p);
}
if (ret) {
goto drop;
}
break;
}
default:
goto drop;
}
} else {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
frozen_t = (iot_sg_meter_js_frozen_uint_data_t*)buff_ptr;
if (is_simple_data) {
ret = iot_sg_sta_ext_nomin_simp_data_uint_fill(frozen_t,
di_cnt, ptr, len, rpt_info->oad_map, rpt_info->flag_3p);
} else {
ret = iot_sg_sta_ext_nomin_data_uint_fill(frozen_t, oad_cnt,
ptr, len, rpt_info->oad_map, rpt_info->flag_3p);
}
if (ret) {
goto drop;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
min_t = (iot_sg_meter_js_min_curve_uint_data_t*)buff_ptr;
if (is_simple_data) {
ret = iot_sg_sta_ext_min_simp_data_uint_fill(min_t, di_cnt,
ptr, len, rpt_info->oad_map, rpt_info->flag_3p);
} else {
ret = iot_sg_sta_ext_min_data_uint_fill(min_t, oad_cnt, ptr,
len, rpt_info->oad_map, rpt_info->flag_3p);
}
if (ret) {
goto drop;
}
break;
}
default:
goto drop;
}
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return ret;
}
static iot_pkt_t *iot_sg_sta_ext_complex_data_rpt(
proto_69845_frame_head_info_t *hdr_698,
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info,
uint8_t *nack_seq)
{
uint8_t i, *data, reason, *dar, addr_len;
uint8_t oad_cnt, *result, unit_cnt = 0, unit_max_cnt, *unit_total_cnt;
iot_pkt_t *pkt = NULL;
uint16_t uint_len = 0, head_len, tail_len;
uint32_t len, ret, csd_len;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_report_req_t *rpt_resp;
proto_69845_app_rpt_record_list_t *record_rpt;
proto_69845_app_rpt_result_record_t *record_result;
if (!hdr_698 || !rpt_info) {
reason = 1;
goto drop;
}
if (!iot_mac_addr_valid(rpt_info->addr)) {
reason = 2;
goto drop;
}
if (rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_MF
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_DF
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE) {
reason = 3;
goto drop;
}
if (!rpt_info->oad_map) {
reason = 4;
goto drop;
}
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
iot_mac_addr_cpy(addr_info.ser_info.addr, rpt_info->addr);
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*rpt_resp) + sizeof(*record_rpt) + sizeof(*record_result)
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
oad_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
csd_len = iot_sg_sta_ext_get_rpt_csd_len(oad_cnt);
len += csd_len;
len += sizeof(*result);
if (!nack_seq) {
len += sizeof(*unit_total_cnt);
if (len >= IOT_SG_STA_EXT_RPT_MAX_LEN) {
reason = 5;
goto drop;
}
uint_len = iot_sg_sta_ext_get_rpt_unit_len(rpt_info);
unit_max_cnt = (uint8_t)((IOT_SG_STA_EXT_RPT_MAX_LEN - len) / uint_len);
if (!unit_max_cnt) {
reason = 6;
goto drop;
}
unit_cnt = (uint8_t)iot_sg_sta_ext_get_rpt_unit_cnt(rpt_info, unit_max_cnt);
if (!unit_cnt) {
reason = 7;
goto drop;
}
len += uint_len * unit_cnt;
} else {
len += sizeof(*dar);
}
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 9;
goto drop;
}
data = iot_pkt_put(pkt, len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_REPORT_NOTI;
rpt_resp = (proto_69845_app_report_req_t*)app_resp->data;
rpt_resp->data_type = PROTO_69845_APP_REPRORT_RECORDLIST;
record_rpt = (proto_69845_app_rpt_record_list_t*)rpt_resp->data;
if (nack_seq) {
record_rpt->piid_acd.sn = *nack_seq;
} else {
record_rpt->piid_acd.sn = iot_sg_sta_ext_get_rpt_sn();
}
record_rpt->piid_acd.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
record_rpt->piid_acd.acd = 0;
record_rpt->att_cnt = 1;
record_result = (proto_69845_app_rpt_result_record_t*)record_rpt->data;
iot_uint32_to_bytes(PROTO_69845_APP_OAD_REPORT,
(uint8_t*)&record_result->oad, 1);
record_result->rcsd.cnt = 1;
data = data + sizeof(*app_resp) + sizeof(*rpt_resp) +
sizeof(*record_rpt) + sizeof(*record_result);
/* fill csd */
ret = iot_sg_sta_ext_rpt_csd_fill(rpt_info, data, (uint16_t)csd_len,
oad_cnt);
if (ret) {
reason = 10;
goto drop;
}
data += csd_len;
if (!nack_seq) {
result = data;
*result = PROTO_69845_APP_RPT_RESULT_DATA;
data += sizeof(*result);
unit_total_cnt = data;
*unit_total_cnt = unit_cnt;
data += sizeof(*unit_total_cnt);
for (i = 0; i < unit_cnt; i++) {
ret = iot_sg_sta_ext_oad_data_uint_fill(rpt_info, data, uint_len,
oad_cnt, i, 0);
if (ret) {
reason = 11;
goto drop;
}
data += uint_len;
}
} else {
result = data;
*result = PROTO_69845_APP_RPT_RESULT_DAR;
data += sizeof(*result);
dar = data;
*dar = PROTO_69845_APP_DAR_RESULT_LAST;
data += sizeof(*dar);
}
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return pkt;
}
static uint16_t iot_sg_sta_ext_get_simple_data_rsd_len(uint8_t meter_cnt)
{
uint16_t len;
len = sizeof(proto_69845_app_data_rsd_t)
+ sizeof(proto_69845_app_data_rsd_type678_t)
+ sizeof(proto_69845_app_data_ms_group_addr_t)
+ (sizeof(proto_69845_app_data_tsa_t) + IOT_MAC_ADDR_LEN) * meter_cnt;
return len;
}
static uint8_t iot_sg_sta_ext_get_simple_data_oad_cnt(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
uint8_t oad_cnt = 0, di_cnt, i, ele_num = 0, m = 1;
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
for (i = 0; i < di_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map), m);
if (!m) {
goto out;
}
iot_sg_sta_ext_di_to_oad(m - 1, rpt_info->flag_3p, &ele_num, NULL);
oad_cnt += ele_num;
m++;
}
out:
return oad_cnt;
}
static uint16_t iot_sg_sta_ext_get_simple_data_unit_len(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
uint32_t m = 1, di;
uint16_t len = 0;
uint8_t di_cnt, i;
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
for (i = 0; i < di_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map), m);
if (!m) {
goto out;
}
di = m - 1;
switch (di) {
case IOT_SG_STA_METER_TASK_DI_EPT_POS:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG:
case IOT_SG_STA_METER_TASK_DI_COM_RE1:
case IOT_SG_STA_METER_TASK_DI_COM_RE2:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER:
{
len += sizeof(proto_69845_meter_energy_data_simp_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_EPT_POS_SUM:
case IOT_SG_STA_METER_TASK_DI_EPT_NEG_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_1ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_2ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_3ST_POWER_SUM:
case IOT_SG_STA_METER_TASK_DI_RE_4ST_POWER_SUM:
{
len += sizeof(proto_69845_rpt_meter_energy_sum_data_simp_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_POS_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_NEG_ACT_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE1_DEM_TIME:
case IOT_SG_STA_METER_TASK_DI_COM_RE2_DEM_TIME:
{
break;
}
case IOT_SG_STA_METER_TASK_DI_VOLTAGE:
{
if (!rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_v_single_simp_t);
} else {
len += sizeof(proto_69845_rpt_v_3p_simp_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_CURRENT:
{
if (!rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_i_single_simp_t);
} else {
len += sizeof(proto_69845_rpt_i_3p_simp_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_NEUTRAL_CURRENT:
{
len += sizeof(proto_69845_rpt_i_single_simp_t);
break;
}
case IOT_SG_STA_METER_TASK_DI_ACTIVE_POWER:
case IOT_SG_STA_METER_TASK_DI_REACTIVE_POWER:
{
if (!rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_power_single_simp_t);
} else {
len += sizeof(proto_69845_rpt_power_3p_simp_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_POWER_FACTOR:
{
if (!rpt_info->flag_3p) {
len += sizeof(proto_69845_rpt_pf_single_simp_t);
} else {
len += sizeof(proto_69845_rpt_pf_3p_simp_t);
}
break;
}
case IOT_SG_STA_METER_TASK_DI_FROZEN_TIME:
case IOT_SG_STA_METER_TASK_DI_TIME:
{
len += sizeof(proto_69845_rpt_data_time_s_simp_t);
break;
}
default:
break;
}
m++;
}
out:
return len;
}
static int64_t iot_sg_sta_get_data_clct_interval(uint8_t data_type)
{
int64_t interval = 0;
switch (data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
interval = IOT_SG_STA_EXT_DC_EXE_INTER_1MON;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
interval = IOT_SG_STA_EXT_DC_EXE_INTER_1DAY;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
interval = IOT_SG_STA_EXT_DC_EXE_INTER_15MIN;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
interval = IOT_SG_STA_EXT_DC_EXE_INTER_1MIN;
break;
}
default:
break;
}
return interval;
}
static uint32_t iot_sg_sta_ext_simple_data_rsd_time_fill(uint8_t *addr,
uint8_t data_type, proto_69845_app_data_time_s_t *time, uint16_t index,
iot_pkt_t *pkt_buff, uint8_t is_end_time)
{
uint8_t *buff_ptr;
uint16_t unit_len;
uint32_t ret = ERR_FAIL, buff_len;
int64_t interval = 0;
proto_69845_app_data_time_s_t time_cache;
iot_sg_meter_unit_time_t *time_unit;
iot_time_tm_t tm = { 0 }, tm_cache = { 0 };
buff_ptr = iot_pkt_data(pkt_buff);
buff_len = iot_pkt_data_len(pkt_buff);
os_mem_set(buff_ptr, 0, buff_len);
iot_sg_sta_flash_unit_get_data_info(data_type, &unit_len, NULL);
if (unit_len > buff_len) {
goto out;
}
ret = iot_sg_sta_flash_unit_data_read(addr, index, buff_ptr, unit_len,
data_type);
if (ret) {
goto out;
}
time_unit = (iot_sg_meter_unit_time_t*)buff_ptr;
if (is_end_time) {
tm.tm_year = (uint16_t)time_unit->year + 2000;
tm.tm_mon = (uint8_t)time_unit->month;
tm.tm_mday = (uint8_t)time_unit->day;
tm.tm_hour = (uint8_t)time_unit->hour;
tm.tm_min = (uint8_t)time_unit->minute;
tm.tm_sec = 0;
interval = iot_sg_sta_get_data_clct_interval(data_type);
tm_cache = iot_sg_ext_get_data_clct_next_or_last_ts(data_type,
&tm, interval, 1);
time_cache.year = tm_cache.tm_year;
time_cache.month = tm_cache.tm_mon;
time_cache.day = tm_cache.tm_mday;
time_cache.hour = tm_cache.tm_hour;
time_cache.minute = tm_cache.tm_min;
time_cache.second = 0;
} else {
time_cache.year = (uint16_t)time_unit->year + 2000;
time_cache.month = (uint8_t)time_unit->month;
time_cache.day = (uint8_t)time_unit->day;
time_cache.hour = (uint8_t)time_unit->hour;
time_cache.minute = (uint8_t)time_unit->minute;
time_cache.second = 0;
}
*time = time_cache;
iot_uint16_to_bytes(time_cache.year, (uint8_t*)&time->year, 1);
ret = ERR_OK;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_simple_data_rsd_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
iot_pkt_t *pkt_buff)
{
uint32_t ret = ERR_FAIL;
proto_69845_app_data_rsd_t *rsd;
proto_69845_app_data_rsd_type678_t *rsd_type7;
proto_69845_app_data_ms_group_addr_t *group_addr;
proto_69845_app_data_tsa_t *tsa;
if (len < (sizeof(*rsd) + sizeof(*rsd_type7)
+ sizeof(*group_addr) + sizeof(*tsa) + IOT_MAC_ADDR_LEN)) {
goto out;
}
rsd = (proto_69845_app_data_rsd_t*)data;
rsd->type = PROTO_OI_RSD_TYPE_7;
rsd_type7 = (proto_69845_app_data_rsd_type678_t*)rsd->rsd_data;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MON;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_DAY;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
iot_uint16_to_bytes(15, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
default:
goto out;
}
/* fill start ts */
ret = iot_sg_sta_ext_simple_data_rsd_time_fill(rpt_info->addr,
rpt_info->data_type, &rsd_type7->start_time, rpt_info->start_index,
pkt_buff, 0);
if (ret){
goto out;
}
/* fill end ts */
ret = iot_sg_sta_ext_simple_data_rsd_time_fill(rpt_info->addr,
rpt_info->data_type, &rsd_type7->end_time, rpt_info->end_index,
pkt_buff, 1);
if (ret){
goto out;
}
rsd_type7->meter_set.type = PROTO_OI_MS_TYPE_GROUP_PM_ADDR;
group_addr =
(proto_69845_app_data_ms_group_addr_t*)rsd_type7->meter_set.ms_data;
group_addr->cnt = 1;
tsa = (proto_69845_app_data_tsa_t*)group_addr->tsa_data;
tsa->len = sizeof(tsa->flag) + IOT_MAC_ADDR_LEN;
tsa->flag.sa_type = PROTO_69845_SA_TYPE_SIG;
tsa->flag.logical_addr = 0;
tsa->flag.sa_len = IOT_MAC_ADDR_LEN - 1;
os_mem_cpy(tsa->sa_and_ca, rpt_info->addr, IOT_MAC_ADDR_LEN);
iot_mac_addr_reverse(tsa->sa_and_ca);
ret = ERR_OK;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_simple_data_road_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt)
{
uint8_t i, j, oad_idx = 0, m, di_cnt, ele_num = 0, sig_oad = 0;
uint32_t ret = ERR_FAIL, oad, bm;
proto_69845_app_road_t *road;
if (len < (sizeof(*road) + oad_cnt * sizeof(proto_69845_app_oad_t))) {
goto out;
}
road = (proto_69845_app_road_t*)data;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
oad = PROTO_69845_APP_OAD_MF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
oad = PROTO_69845_APP_OAD_DF;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
oad = PROTO_69845_APP_OAD_MINF;
break;
}
default:
goto out;
}
iot_uint32_to_bytes(oad, (uint8_t*)&road->rec_oad, 1);
road->cnt = oad_cnt;
bm = rpt_info->oad_map;
m = 1;
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
for (i = 0; i < di_cnt; i++) {
if (oad_idx >= road->cnt) {
ret = ERR_OK;
goto out;
}
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto out;
}
oad = iot_sg_sta_ext_di_to_oad(m - 1, rpt_info->flag_3p, &ele_num,
&sig_oad);
if (sig_oad) {
iot_uint32_to_bytes(oad, (uint8_t*)&road->ass_oad[oad_idx], 1);
oad_idx++;
} else {
for (j = 0; j < ele_num; j++) {
oad++;
iot_uint32_to_bytes(oad, (uint8_t*)&road->ass_oad[oad_idx], 1);
oad_idx++;
}
}
m++;
}
ret = ERR_OK;
out:
return ret;
}
static void iot_sg_sta_ext_simple_data_last_check(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *result)
{
uint16_t index = rpt_info->end_index, cnt = 0, total_cnt = 0;
iot_sg_sta_node_desc_t *node;
*result = PROTO_69845_APP_RPT_RESULT_DATA;
node = iot_sg_sta_node_find_by_addr(rpt_info->addr);
if (node) {
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
index = node->ext.data_clct_info.mf_rpt_index;
cnt = node->ext.data_clct_info.mf_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
index = node->ext.data_clct_info.df_rpt_index;
cnt = node->ext.data_clct_info.df_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
index = node->ext.data_clct_info.min15_rpt_index;
cnt = node->ext.data_clct_info.min15_cnt;
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
index = node->ext.data_clct_info.min1_rpt_index;
cnt = node->ext.data_clct_info.min1_cnt;
break;
}
default:
break;
}
index = index + cnt - 1;
}
if (rpt_info->end_index >= index) {
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_MF);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_DF);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE);
if (rpt_info->cnt >= total_cnt) {
*result = PROTO_69845_APP_DAR_RESULT_LAST;
}
}
}
static uint8_t iot_sg_sta_ext_simple_data_get_oad_type(uint32_t oad)
{
uint8_t oad_type = PROTO_69845_APP_DATA_NULL;
switch (oad) {
case PROTO_69845_APP_OAD_EPT_POS:
case PROTO_69845_APP_OAD_EPT_POS_SIG:
case PROTO_69845_APP_OAD_EPT_NEG:
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
case PROTO_69845_APP_OAD_EQT_POS:
case PROTO_69845_APP_OAD_EQT_NEG:
case PROTO_69845_APP_OAD_EQT_QRT1:
case PROTO_69845_APP_OAD_EQT_QRT2:
case PROTO_69845_APP_OAD_EQT_QRT3:
case PROTO_69845_APP_OAD_EQT_QRT4:
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
{
oad_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
break;
}
case PROTO_69845_APP_OAD_EPT_POS_DEMAND:
case PROTO_69845_APP_OAD_EPT_NEG_DEMAND:
case PROTO_69845_APP_OAD_EQT_POS_DEMAND:
case PROTO_69845_APP_OAD_EQT_NEG_DEMAND:
{
break;
}
case PROTO_69845_APP_OAD_VOLTAGE:
case PROTO_69845_APP_OAD_VOLTAGE_A:
{
oad_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
break;
}
case PROTO_69845_APP_OAD_CURRENT:
case PROTO_69845_APP_OAD_CURRENT_A:
case PROTO_69845_APP_OAD_GND_CURRENT:
{
oad_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
break;
}
case PROTO_69845_APP_OAD_P:
case PROTO_69845_APP_OAD_Q:
{
oad_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
break;
}
case PROTO_69845_APP_OAD_PF:
{
oad_type = PROTO_69845_APP_DATA_LONG;
break;
}
case PROTO_69845_APP_OAD_FROZEN_T:
case PROTO_69845_APP_OAD_TIME:
{
oad_type = PROTO_69845_APP_DATA_TIME_S;
break;
}
default:
break;
}
return oad_type;
}
static uint32_t iot_sg_sta_ext_simple_data_oad_type_fill(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
uint8_t oad_cnt)
{
uint8_t m, i, j, *type, *ptr = data, di_cnt, ele_num = 0, oad_type;
uint16_t ptr_len = len;
uint32_t bm, ret = ERR_FAIL, oad;
if ((sizeof(*type) * oad_cnt) > ptr_len) {
goto out;
}
bm = rpt_info->oad_map;
m = 1;
di_cnt = (uint8_t)iot_bitmap_cbs((uint8_t*)&rpt_info->oad_map,
sizeof(rpt_info->oad_map));
for (i = 0; i < di_cnt; i++) {
m = (uint8_t)iot_bitmap_ffs_from((uint8_t*)&bm, sizeof(bm), m);
if (!m) {
goto out;
}
oad = iot_sg_sta_ext_di_to_oad(m - 1, rpt_info->flag_3p, &ele_num,
NULL);
oad_type = iot_sg_sta_ext_simple_data_get_oad_type(oad);
for (j = 0; j < ele_num; j++) {
if (!ptr_len) {
ret = ERR_OK;
goto out;
}
type = ptr;
*type = oad_type;
ptr += sizeof(*type);
ptr_len -= sizeof(*type);
}
m++;
}
ret = ERR_OK;
out:
return ret;
}
static uint8_t iot_sg_ext_data_clct_data_type_to_task_type(uint8_t data_type,
uint8_t is_3p)
{
uint8_t task_type;
switch (data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
}
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
if (is_3p) {
task_type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN;
} else {
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
}
break;
}
default:
task_type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
break;
}
return task_type;
}
static uint8_t iot_sg_sta_ext_get_continue_unit_cnt(
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info, uint16_t rpt_cnt)
{
int64_t interval;
uint32_t ret;
uint16_t unit_len, max_cnt = 0, idx;
uint8_t unit_cnt = 0, index, *unit_data, task_type;
iot_pkt_t *pkt = NULL;
iot_sg_meter_unit_time_t *unit_time;
iot_sg_meter_js_task_config_hdr_t cfg_hdr = { 0 };
iot_time_tm_t cur_tm = { 0 }, last_tm = { 0 };
if (!rpt_cnt) {
goto out;
}
ret = iot_sg_sta_flash_unit_get_data_info(rpt_info->data_type, &unit_len,
&max_cnt);
if (ret) {
goto out;
}
if (rpt_cnt > max_cnt) {
rpt_cnt = max_cnt;
}
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
if (!pkt) {
goto out;
}
unit_data = iot_pkt_put(pkt, unit_len);
task_type = iot_sg_ext_data_clct_data_type_to_task_type(
rpt_info->data_type, rpt_info->flag_3p);
if (iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, &cfg_hdr)) {
goto out;
}
interval = proto_69845_ti_data_to_sec(&cfg_hdr.exe_inter);
for (index = 0; index < rpt_cnt; index++) {
idx = rpt_info->start_index + index;
if (idx >= max_cnt) {
idx = idx - max_cnt;
}
ret = iot_sg_sta_flash_unit_data_read(rpt_info->addr,
idx, unit_data, unit_len, rpt_info->data_type);
if (ret) {
goto out;
}
unit_time = (iot_sg_meter_unit_time_t *)unit_data;
if (!index) {
last_tm.tm_year = (uint16_t)unit_time->year + 2000;
last_tm.tm_mon = (uint8_t)unit_time->month;
last_tm.tm_mday = (uint8_t)unit_time->day;
last_tm.tm_hour = (uint8_t)unit_time->hour;
last_tm.tm_min = (uint8_t)unit_time->minute;
unit_cnt++;
continue;
} else {
cur_tm = iot_sg_ext_get_data_clct_next_or_last_ts(
rpt_info->data_type, &last_tm, interval, 1);
if (cur_tm.tm_year == ((uint16_t)unit_time->year + 2000) &&
cur_tm.tm_mon == (uint8_t)unit_time->month &&
cur_tm.tm_mday == (uint8_t)unit_time->day &&
cur_tm.tm_hour == (uint8_t)unit_time->hour &&
cur_tm.tm_min == (uint8_t)unit_time->minute) {
last_tm = cur_tm;
unit_cnt++;
continue;
} else {
break;
}
}
}
out:
if (unit_cnt) {
rpt_info->end_index = rpt_info->start_index + unit_cnt - 1;
if (rpt_info->end_index >= max_cnt) {
rpt_info->end_index -= max_cnt;
}
rpt_info->cnt = unit_cnt;
}
if (pkt) {
iot_pkt_free(pkt);
}
return unit_cnt;
}
static iot_pkt_t *iot_sg_sta_ext_simple_data_rpt(
proto_69845_frame_head_info_t *hdr_698,
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
uint8_t i, *data, reason, addr[IOT_MAC_ADDR_LEN] = {0}, addr_len;
uint8_t oad_cnt, *result, unit_cnt, unit_max_cnt, *unit_total_cnt;
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
uint16_t uint_len, head_len, tail_len, rpt_cnt;
uint32_t len, ret, rsd_len, road_len, data_type_len;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_report_req_t *rpt_resp;
proto_69845_app_rpt_simp_rec_req_hdr_t *simp_rpt;
if (!hdr_698 || !rpt_info) {
reason = 1;
goto drop;
}
if (!iot_mac_addr_valid(rpt_info->addr)) {
reason = 2;
goto drop;
}
if (rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_MF
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_DF
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE
&& rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE) {
reason = 3;
goto drop;
}
if (!rpt_info->oad_map) {
reason = 4;
goto drop;
}
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
sta_glb->drv->get_device_addr(addr);
if (iot_mac_addr_valid(addr)) {
iot_mac_addr_cpy(addr_info.ser_info.addr, addr);
}
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*rpt_resp) + sizeof(*simp_rpt)
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
rsd_len = iot_sg_sta_ext_get_simple_data_rsd_len(1);
len += rsd_len;
oad_cnt = iot_sg_sta_ext_get_simple_data_oad_cnt(rpt_info);
road_len = iot_sg_sta_ext_get_rpt_road_len(oad_cnt);
len += road_len;
len += sizeof(*result);
data_type_len = oad_cnt;
len += data_type_len;
len += sizeof(*unit_total_cnt);
if (len >= IOT_SG_STA_EXT_RPT_MAX_LEN) {
reason = 5;
goto drop;
}
uint_len = iot_sg_sta_ext_get_simple_data_unit_len(rpt_info);
unit_max_cnt = (uint8_t)((IOT_SG_STA_EXT_RPT_MAX_LEN - len) / uint_len);
if (!unit_max_cnt) {
reason = 6;
goto drop;
}
rpt_cnt = iot_sg_sta_ext_get_rpt_unit_cnt(rpt_info, unit_max_cnt);
/* get points of time interval cotinue from points not reported */
unit_cnt = iot_sg_sta_ext_get_continue_unit_cnt(rpt_info, rpt_cnt);
if (!unit_cnt) {
reason = 7;
goto drop;
}
len += uint_len * unit_cnt;
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 8;
goto drop;
}
data = iot_pkt_put(pkt, len);
pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (!pkt_buff) {
reason = 9;
goto drop;
}
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_REPORT);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_REPORT_NOTI;
rpt_resp = (proto_69845_app_report_req_t*)app_resp->data;
rpt_resp->data_type = PROTO_69845_APP_REPRORT_SIMPRECORD;
simp_rpt = (proto_69845_app_rpt_simp_rec_req_hdr_t*)rpt_resp->data;
simp_rpt->piid_acd.sn = iot_sg_sta_ext_get_rpt_sn();
simp_rpt->piid_acd.priority = PROTO_69845_APP_PIID_PRIORITY_HIGH;
simp_rpt->piid_acd.acd = 0;
iot_uint32_to_bytes(PROTO_69845_APP_OAD_REPORT,
(uint8_t*)&simp_rpt->oad, 1);
data = data + sizeof(*app_resp) + sizeof(*rpt_resp) + sizeof(*simp_rpt);
/* fill rsd */
ret = iot_sg_sta_ext_simple_data_rsd_fill(rpt_info, data, (uint16_t)rsd_len,
pkt_buff);
if (ret) {
reason = 10;
goto drop;
}
data += rsd_len;
/* fill road */
ret = iot_sg_sta_ext_simple_data_road_fill(rpt_info, data, (uint16_t)road_len,
oad_cnt);
if (ret) {
reason = 11;
goto drop;
}
data += road_len;
result = data;
iot_sg_sta_ext_simple_data_last_check(rpt_info, result);
data += sizeof(*result);
ret = iot_sg_sta_ext_simple_data_oad_type_fill(rpt_info, data,
(uint16_t)data_type_len, oad_cnt);
if (ret) {
reason = 12;
goto drop;
}
data += data_type_len;
unit_total_cnt = data;
*unit_total_cnt = unit_cnt;
data += sizeof(*unit_total_cnt);
for (i = 0; i < unit_cnt; i++) {
ret = iot_sg_sta_ext_oad_data_uint_fill(rpt_info, data, uint_len,
oad_cnt, i, 1);
if (ret) {
reason = 13;
goto drop;
}
data += uint_len;
}
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return pkt;
}
static uint32_t iot_sg_sta_ext_get_complex_rpt_node(uint8_t rpt_state,
iot_sg_sta_ext_clct_rpt_desc_t *rpt_info)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_node_desc_t *node;
uint8_t idx;
uint32_t ret = ERR_FAIL;
for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
if (sta_glb->node_list[idx] != NULL) {
node = sta_glb->node_list[idx];
ret = iot_sg_sta_ext_get_rpt_node(rpt_state, node, rpt_info);
if (ret == ERR_OK) {
break;
}
}
}
return ret;
}
static uint32_t iot_sg_sta_ext_multi_simple_data_rsd_fill(
iot_sg_sta_ext_clct_multi_rpt_desc_t *rpt_info, uint8_t *data, uint16_t len,
iot_pkt_t *pkt_buff)
{
uint8_t i;
uint32_t ret = ERR_FAIL;
proto_69845_app_data_rsd_t *rsd;
proto_69845_app_data_rsd_type678_t *rsd_type7;
proto_69845_app_data_ms_group_addr_t *group_addr;
proto_69845_app_data_tsa_t *tsa;
if (len < (sizeof(*rsd) + sizeof(*rsd_type7) + sizeof(*group_addr) +
(sizeof(*tsa) + IOT_MAC_ADDR_LEN) * rpt_info->meter_info_cnt)) {
goto out;
}
rsd = (proto_69845_app_data_rsd_t*)data;
rsd->type = PROTO_OI_RSD_TYPE_7;
rsd_type7 = (proto_69845_app_data_rsd_type678_t*)rsd->rsd_data;
switch (rpt_info->data_type) {
case IOT_SG_STA_METER_DATA_TYPE_JS_MF:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MON;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_DF:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_DAY;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
iot_uint16_to_bytes(15, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
case IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE:
{
rsd_type7->ti.uint = PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN;
iot_uint16_to_bytes(1, (uint8_t*)&rsd_type7->ti.value, 1);
break;
}
default:
goto out;
}
if (!rpt_info->meter_info_cnt) {
goto out;
}
/* fill start ts */
ret = iot_sg_sta_ext_simple_data_rsd_time_fill(rpt_info->meter_info[0].addr,
rpt_info->data_type, &rsd_type7->start_time,
rpt_info->meter_info[0].start_index, pkt_buff, 0);
if (ret){
goto out;
}
/* fill end ts */
ret = iot_sg_sta_ext_simple_data_rsd_time_fill(rpt_info->meter_info[0].addr,
rpt_info->data_type, &rsd_type7->end_time,
rpt_info->meter_info[0].end_index, pkt_buff, 1);
if (ret){
goto out;
}
rsd_type7->meter_set.type = PROTO_OI_MS_TYPE_GROUP_PM_ADDR;
group_addr =
(proto_69845_app_data_ms_group_addr_t*)rsd_type7->meter_set.ms_data;
group_addr->cnt = rpt_info->meter_info_cnt;
for (i = 0; i < rpt_info->meter_info_cnt; i++) {
tsa = (proto_69845_app_data_tsa_t*)(group_addr->tsa_data +
(sizeof(*tsa) + IOT_MAC_ADDR_LEN) * i);
tsa->len = sizeof(proto_69845_addr_flag_t) + IOT_MAC_ADDR_LEN;
tsa->flag.sa_type = PROTO_69845_SA_TYPE_SIG;
tsa->flag.logical_addr = 0;
tsa->flag.sa_len = IOT_MAC_ADDR_LEN - 1;
os_mem_cpy(tsa->sa_and_ca, rpt_info->meter_info[i].addr,
IOT_MAC_ADDR_LEN);
iot_mac_addr_reverse(tsa->sa_and_ca);
}
ret = ERR_OK;
out:
return ret;
}
static void iot_sg_sta_ext_multi_simple_data_last_check(
iot_sg_sta_ext_clct_multi_rpt_desc_t *rpt_info, uint8_t *result)
{
uint16_t total_cnt = 0;
*result = PROTO_69845_APP_RPT_RESULT_DATA;
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_MF);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_DF);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE);
total_cnt += iot_sg_sta_ext_get_rpt_data_cnt(
IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE);
if (rpt_info->meter_info_cnt * 1 >= total_cnt) {
*result = PROTO_69845_APP_DAR_RESULT_LAST;
}
}
static iot_pkt_t *iot_sg_sta_ext_simple_data_multi_rpt(
proto_69845_frame_head_info_t *hdr_698,
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
uint8_t i, *data, reason, addr[IOT_MAC_ADDR_LEN] = {0}, max_cnt;
uint8_t oad_cnt, *result, *unit_total_cnt, meter_cnt, addr_len;
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
uint16_t uint_len, head_len, tail_len;
uint32_t len, ret, rsd_len, road_len, data_type_len;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_report_req_t *rpt_resp;
proto_69845_app_rpt_simp_rec_req_hdr_t *simp_rpt;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
iot_sg_sta_ext_clct_rpt_desc_t rpt_info_tmp = { 0 };
if (!hdr_698 || !multi_rpt_info) {
reason = 1;
goto drop;
}
if (!multi_rpt_info->meter_info_cnt ||
multi_rpt_info->meter_info_cnt > IOT_SG_STA_CLCT_METER_INFO_MAX_CNT) {
reason = 2;
goto drop;
}
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
if (!iot_mac_addr_valid(meter_info->addr)) {
reason = 3;
goto drop;
}
if (!rpt_info_tmp.oad_map) {
rpt_info_tmp.oad_map = multi_rpt_info->oad_map;
rpt_info_tmp.flag_3p = multi_rpt_info->flag_3p;
rpt_info_tmp.data_type = multi_rpt_info->data_type;
}
}
if (multi_rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_MF
&& multi_rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_DF
&& multi_rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_15MIN_CURVE
&& multi_rpt_info->data_type != IOT_SG_STA_METER_DATA_TYPE_JS_1MIN_CURVE)
{
reason = 4;
goto drop;
}
if (!multi_rpt_info->oad_map) {
reason = 5;
goto drop;
}
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
sta_glb->drv->get_device_addr(addr);
if (iot_mac_addr_valid(addr)) {
iot_mac_addr_cpy(addr_info.ser_info.addr, addr);
}
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*rpt_resp) + sizeof(*simp_rpt)
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
meter_cnt = multi_rpt_info->meter_info_cnt;
rsd_len = iot_sg_sta_ext_get_simple_data_rsd_len(meter_cnt);
len += rsd_len;
oad_cnt = iot_sg_sta_ext_get_simple_data_oad_cnt(&rpt_info_tmp);
road_len = iot_sg_sta_ext_get_rpt_road_len(oad_cnt);
len += road_len;
len += sizeof(*result);
data_type_len = oad_cnt;
len += data_type_len;
len += sizeof(*unit_total_cnt);
if (len >= IOT_SG_STA_EXT_RPT_MAX_LEN) {
reason = 6;
goto drop;
}
uint_len = iot_sg_sta_ext_get_simple_data_unit_len(&rpt_info_tmp);
max_cnt = (uint8_t)((IOT_SG_STA_EXT_RPT_MAX_LEN - len) / uint_len);
if (!max_cnt) {
reason = 7;
goto drop;
}
if (max_cnt < meter_cnt) {
meter_cnt = max_cnt;
len -= rsd_len;
rsd_len = iot_sg_sta_ext_get_simple_data_rsd_len(meter_cnt);
len += rsd_len;
multi_rpt_info->meter_info_cnt = meter_cnt;
for (i = multi_rpt_info->meter_info_cnt;
i < IOT_SG_STA_CLCT_METER_INFO_MAX_CNT; i++) {
meter_info = &multi_rpt_info->meter_info[i];
os_mem_set(meter_info, 0x0, sizeof(*meter_info));
}
}
len += uint_len * meter_cnt;
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 9;
goto drop;
}
data = iot_pkt_put(pkt, len);
pkt_buff = iot_sg_sta_ext_rpt_get_cache_buff();
if (pkt_buff == NULL) {
reason = 10;
goto drop;
}
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_REPORT);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_REPORT_NOTI;
rpt_resp = (proto_69845_app_report_req_t*)app_resp->data;
rpt_resp->data_type = PROTO_69845_APP_REPRORT_SIMPRECORD;
simp_rpt = (proto_69845_app_rpt_simp_rec_req_hdr_t*)rpt_resp->data;
simp_rpt->piid_acd.sn = iot_sg_sta_ext_get_rpt_sn();
simp_rpt->piid_acd.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
simp_rpt->piid_acd.acd = 0;
iot_uint32_to_bytes(PROTO_69845_APP_OAD_REPORT,
(uint8_t*)&simp_rpt->oad, 1);
data = data + sizeof(*app_resp) + sizeof(*rpt_resp) + sizeof(*simp_rpt);
/* fill rsd */
ret = iot_sg_sta_ext_multi_simple_data_rsd_fill(multi_rpt_info, data,
(uint16_t)rsd_len, pkt_buff);
if (ret) {
reason = 11;
goto drop;
}
data += rsd_len;
/* fill road */
ret = iot_sg_sta_ext_simple_data_road_fill(&rpt_info_tmp, data,
(uint16_t)road_len, oad_cnt);
if (ret) {
reason = 12;
goto drop;
}
data += road_len;
result = data;
iot_sg_sta_ext_multi_simple_data_last_check(multi_rpt_info, result);
data += sizeof(*result);
ret = iot_sg_sta_ext_simple_data_oad_type_fill(&rpt_info_tmp, data,
(uint16_t)data_type_len, oad_cnt);
if (ret) {
reason = 13;
goto drop;
}
data += data_type_len;
unit_total_cnt = data;
*unit_total_cnt = multi_rpt_info->meter_info_cnt;
data += sizeof(*unit_total_cnt);
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
iot_mac_addr_cpy(rpt_info_tmp.addr, meter_info->addr);
rpt_info_tmp.oad_map = multi_rpt_info->oad_map;
rpt_info_tmp.flag_3p = multi_rpt_info->flag_3p;
rpt_info_tmp.data_type = multi_rpt_info->data_type;
rpt_info_tmp.start_index = meter_info->start_index;
rpt_info_tmp.cnt = meter_info->cnt;
rpt_info_tmp.end_index = meter_info->end_index;
ret = iot_sg_sta_ext_oad_data_uint_fill(&rpt_info_tmp, data, uint_len,
oad_cnt, 0, 1);
if (ret) {
reason = 14;
goto drop;
}
data += uint_len;
}
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
pkt = NULL;
}
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
if (pkt_buff) {
iot_pkt_free(pkt_buff);
}
return pkt;
}
static void iot_sg_sta_ext_multi_rpt_index_update(
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
uint8_t i;
iot_sg_sta_ext_clct_rpt_desc_t rpt_info = { 0 };
iot_sg_sta_ext_clct_meter_info_t *meter_info;
rpt_info.data_type = multi_rpt_info->data_type;
rpt_info.cnt = 1;
rpt_info.flag_3p = multi_rpt_info->flag_3p;
rpt_info.oad_map = multi_rpt_info->oad_map;
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
iot_mac_addr_cpy(rpt_info.addr, meter_info->addr);
rpt_info.start_index = meter_info->start_index;
rpt_info.end_index = meter_info->end_index;
rpt_info.cnt = meter_info->cnt;
iot_sg_sta_ext_rpt_index_update(&rpt_info);
}
}
static uint32_t iot_sg_sta_ext_multi_rpt_check(
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
uint16_t i, min_cnt = 0;
uint32_t ret = ERR_INVAL;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (!multi_rpt_info || multi_rpt_info->meter_info_cnt == 1) {
goto out;
}
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
if (i == 0) {
min_cnt = meter_info->cnt;
} else {
if (min_cnt > meter_info->cnt) {
min_cnt = meter_info->cnt;
}
}
}
if (min_cnt < multi_rpt_info->meter_info_cnt) {
ret = ERR_OK;
}
out:
return ret;
}
static void iot_sg_sta_ext_multi_rpt_set_sig_point(
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info)
{
uint8_t i;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (!multi_rpt_info) {
goto out;
}
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
if (meter_info->cnt != 1) {
meter_info->cnt = 1;
meter_info->end_index = meter_info->start_index;
}
}
out:
return;
}
static iot_pkt_t *iot_sg_sta_ext_rpt_next_handle(
proto_69845_frame_head_info_t *hdr_698, uint8_t *seq)
{
uint8_t multi_flag = 0, i;
uint32_t ret, buff_len;
iot_pkt_t *pkt = NULL, *buff_pkt = NULL;
iot_sg_sta_ext_clct_rpt_desc_t rpt_info = { 0 };
iot_sg_sta_ext_clct_multi_rpt_desc_t *multi_rpt_info;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
iot_sg_sta_ext_clct_meter_info_t *meter_info;
if (evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_IDLE) {
goto out;
}
if (seq && (*seq == evt_rpt->seq) && evt_rpt->last_rpt_type) {
if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_SIG_METER) {
iot_sg_sta_ext_rpt_index_update(&evt_rpt->last_rpt_info);
} else {
iot_sg_sta_ext_multi_rpt_index_update(&evt_rpt->last_multi_rpt_info);
}
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_INVALID;
}
evt_rpt->cur_state = IOT_SG_STA_COLL_DATA_RPT_STATE_MF;
buff_len = sizeof(iot_sg_sta_ext_clct_multi_rpt_desc_t);
buff_pkt = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
if (!buff_pkt) {
goto out;
}
multi_rpt_info = (iot_sg_sta_ext_clct_multi_rpt_desc_t *)iot_pkt_put(buff_pkt,
buff_len);
next_state:
if (evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_DF ||
evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_MF) {
os_mem_set(&rpt_info, 0x0, sizeof(rpt_info));
ret = iot_sg_sta_ext_get_complex_rpt_node(evt_rpt->cur_state,
&rpt_info);
multi_flag = 0;
} else {
os_mem_set(multi_rpt_info, 0x0, sizeof(*multi_rpt_info));
ret = iot_sg_sta_ext_get_simp_rpt_node(evt_rpt->cur_state,
multi_rpt_info);
if (ret == ERR_OK) {
if (!iot_sg_sta_ext_multi_rpt_check(multi_rpt_info)) {
iot_sg_sta_ext_multi_rpt_set_sig_point(multi_rpt_info);
multi_flag = 1;
} else {
multi_flag = 0;
iot_mac_addr_cpy(rpt_info.addr,
multi_rpt_info->meter_info[0].addr);
rpt_info.start_index = multi_rpt_info->meter_info[0].start_index;
rpt_info.end_index = multi_rpt_info->meter_info[0].end_index;
rpt_info.cnt = multi_rpt_info->meter_info[0].cnt;
rpt_info.flag_3p = multi_rpt_info->flag_3p;
rpt_info.data_type = multi_rpt_info->data_type;
rpt_info.oad_map = multi_rpt_info->oad_map;
}
}
}
if (ret) {
/* if no data rpt in current state. change state */
evt_rpt->cur_state++;
if (evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_END) {
evt_rpt->cur_state = IOT_SG_STA_COLL_DATA_RPT_STATE_MF;
goto out;
}
goto next_state;
} else {
if (multi_flag) {
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x data type"
" %lu cnt %lu\n", __FUNCTION__, meter_info->addr[0],
meter_info->addr[1], meter_info->addr[2],
meter_info->addr[3], meter_info->addr[4],
meter_info->addr[5], multi_rpt_info->data_type,
meter_info->cnt);
}
} else {
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x data type %lu "
"cnt %lu\n", __FUNCTION__, rpt_info.addr[0], rpt_info.addr[1],
rpt_info.addr[2], rpt_info.addr[3], rpt_info.addr[4],
rpt_info.addr[5], rpt_info.data_type, rpt_info.cnt);
}
if (evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_DF
|| evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_MF) {
pkt = iot_sg_sta_ext_complex_data_rpt(hdr_698, &rpt_info, NULL);
} else if (evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_15MIN
|| evt_rpt->cur_state == IOT_SG_STA_COLL_DATA_RPT_STATE_1MIN){
if (multi_flag) {
pkt = iot_sg_sta_ext_simple_data_multi_rpt(hdr_698,
multi_rpt_info);
} else {
pkt = iot_sg_sta_ext_simple_data_rpt(hdr_698, &rpt_info);
}
}
if (pkt) {
if (multi_flag) {
for (i = 0; i < multi_rpt_info->meter_info_cnt; i++) {
meter_info = &multi_rpt_info->meter_info[i];
iot_sg_printf("%s rpt ok, start idx %lu cnt %lu\n",
__FUNCTION__, meter_info->start_index, meter_info->cnt);
}
os_mem_set(&evt_rpt->last_multi_rpt_info, 0x0,
sizeof(evt_rpt->last_multi_rpt_info));
os_mem_cpy(&evt_rpt->last_multi_rpt_info, multi_rpt_info,
sizeof(*multi_rpt_info));
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_MULT_METER;
} else {
iot_sg_printf("%s rpt ok, start idx %lu cnt %lu\n",
__FUNCTION__, rpt_info.start_index, rpt_info.cnt);
os_mem_set(&evt_rpt->last_rpt_info, 0x0,
sizeof(evt_rpt->last_rpt_info));
os_mem_cpy(&evt_rpt->last_rpt_info, &rpt_info,
sizeof(rpt_info));
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_SIG_METER;
}
}
}
out:
if (buff_pkt) {
iot_pkt_free(buff_pkt);
}
return pkt;
}
static iot_pkt_t *iot_sg_sta_ext_rpt_start_handle(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_omd_t *omd)
{
iot_pkt_t *pkt = NULL;
iot_sg_sta_ext_rpt_start();
pkt = iot_sg_sta_ext_rpt_next_handle(hdr_698, NULL);
if (!pkt) {
pkt = iot_sg_sta_ext_rpt_action_resp(hdr_698, piid, omd,
PROTO_69845_APP_DAR_OI_NO_EXIST);
}
return pkt;
}
static void iot_sg_sta_ext_rpt_stop(void)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
evt_rpt->cur_state = IOT_SG_STA_COLL_DATA_RPT_STATE_IDLE;
}
static iot_pkt_t *iot_sg_sta_ext_rpt_stop_handle(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_omd_t *omd)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
iot_pkt_t *pkt = NULL;
if ((piid->sn == evt_rpt->seq) && evt_rpt->last_rpt_type) {
if (evt_rpt->last_rpt_type == IOT_SG_STA_CLCT_LAST_RPT_SIG_METER) {
iot_sg_sta_ext_rpt_index_update(&evt_rpt->last_rpt_info);
} else {
iot_sg_sta_ext_multi_rpt_index_update(&evt_rpt->last_multi_rpt_info);
}
evt_rpt->last_rpt_type = IOT_SG_STA_CLCT_LAST_RPT_INVALID;
}
iot_sg_sta_ext_rpt_stop();
pkt = iot_sg_sta_ext_rpt_action_resp(hdr_698, piid, omd,
PROTO_69845_APP_DAR_SUCCESS);
return pkt;
}
static uint8_t iot_sg_sta_ext_type_single_to_3p(uint8_t task_type)
{
uint8_t type = task_type;
switch (task_type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
{
type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_MF;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
{
type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
{
type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_15MIN;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
{
type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_1MIN;
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
{
type = IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C;
break;
}
default:
break;
}
return type;
}
static uint8_t iot_sg_sta_ext_task_unit_check(
proto_69845_app_data_task_cfg_unit_t *unit)
{
uint8_t type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
uint16_t uint_value;
if (unit->data0_type != PROTO_69845_APP_DATA_STRUCTURE
|| unit->task_cfg_ele_cnt != 12
|| unit->data1_type != PROTO_69845_APP_DATA_UNSIGNED
|| unit->data2_type != PROTO_69845_APP_DATA_TI
|| unit->data3_type != PROTO_69845_APP_DATA_ENUM
|| unit->plan_type != PROTO_69845_DATA_TASK_PLAN_TYPE_NORMAL_CLCT
|| unit->data4_type != PROTO_69845_APP_DATA_UNSIGNED
|| unit->data5_type != PROTO_69845_APP_DATA_TIME_S
|| unit->data6_type != PROTO_69845_APP_DATA_TIME_S
|| unit->data7_type != PROTO_69845_APP_DATA_TI) {
goto out;
}
uint_value = iot_bytes_to_uint16((uint8_t*)&unit->freq_time.value, 1);
switch (unit->freq_time.uint) {
case PROTO_OI_TI_INTERVAL_UNIT_TYPE_MON:
{
if (uint_value == 1) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
}
break;
}
case PROTO_OI_TI_INTERVAL_UNIT_TYPE_DAY:
{
if (uint_value == 1) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
}
break;
}
case PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN:
{
if (uint_value == 1) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
} else if (uint_value == 15) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
}
break;
}
default:
break;
}
out:
return type;
}
static uint32_t iot_sg_sta_ext_task_add(proto_69845_app_data_t *data,
uint32_t len)
{
iot_pkt_t *pkt_buf = NULL;
uint8_t *ptr = (uint8_t*)data, i, task_type, task_3p_type, reason = 0;
uint32_t ret, rec_len = len, cache_len = 0;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_task_cfg_unit_t *unit_hdr;
proto_69845_app_data_t *data_t;
iot_sg_meter_js_task_config_hdr_t *config;
if (!data || !len) {
reason = 1;
goto drop;
}
if (data->data_type != PROTO_69845_APP_DATA_ARRAY) {
reason = 2;
goto drop;
}
if (rec_len < sizeof(*task_list)) {
reason = 3;
goto drop;
}
task_list = (proto_69845_app_ele_data_t*)ptr;
if (!task_list->num_of_data) {
reason = 4;
goto drop;
}
ptr += sizeof(*task_list);
rec_len -= sizeof(*task_list);
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
reason = 5;
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto drop;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
for (i = 0; i < task_list->num_of_data; i++) {
data_t = (proto_69845_app_data_t*)ptr;
if (proto_69845_get_data_len(data_t, rec_len, &cache_len)) {
reason = 6;
goto drop;
}
if (rec_len < cache_len) {
reason = 7;
goto drop;
}
if (cache_len < sizeof(*unit_hdr)) {
reason = 8;
goto drop;
}
unit_hdr = (proto_69845_app_data_task_cfg_unit_t*)ptr;
task_type = iot_sg_sta_ext_task_unit_check(unit_hdr);
task_3p_type = iot_sg_sta_ext_type_single_to_3p(task_type);
if (task_type == IOT_SG_STA_METER_JS_CFG_TYPE_INVALID) {
reason = 9;
goto drop;
}
os_mem_set(config, 0, sizeof(*config));
if (iot_sg_sta_flash_js_task_cfg_get_by_num(unit_hdr->plan_num,
config)) {
reason = 10;
goto drop;
}
if (config->task_type == IOT_SG_STA_METER_JS_CFG_TYPE_D_C ||
config->task_type == IOT_SG_STA_METER_JS_CFG_3P_TYPE_D_C) {
if (task_type != IOT_SG_STA_METER_JS_CFG_TYPE_DF
&& task_3p_type != IOT_SG_STA_METER_JS_CFG_3P_TYPE_DF) {
reason = 11;
goto drop;
}
} else if ((task_type != config->task_type)
&& (task_3p_type != config->task_type)) {
reason = 12;
goto drop;
}
task_type = config->task_type;
config->task_id = unit_hdr->task_id;
config->exe_inter.uint = unit_hdr->freq_time.uint;
config->exe_inter.value = iot_bytes_to_uint16(
(uint8_t*)&unit_hdr->freq_time.value, 1);
config->delay.uint = unit_hdr->delay_time.uint;
config->delay.value = iot_bytes_to_uint16(
(uint8_t*)&unit_hdr->delay_time.value, 1);
config->start_time = unit_hdr->start_time;
config->start_time.year = iot_bytes_to_uint16(
(uint8_t*)&unit_hdr->start_time.year, 1);
/* save config */
if (iot_sg_sta_flash_js_task_cfg_save(task_type, config)) {
reason = 13;
goto drop;
}
ptr += cache_len;
rec_len -= cache_len;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
ret = ERR_FAIL;
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_task_delete(proto_69845_app_data_t *data,
uint32_t len)
{
iot_pkt_t *pkt_buf = NULL;
uint8_t *ptr = (uint8_t*)data, i, id;
uint32_t ret, rec_len = len;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_t *id_hdr;
iot_sg_meter_js_task_config_hdr_t *config;
if (!data || !len) {
goto drop;
}
if (data->data_type != PROTO_69845_APP_DATA_ARRAY) {
goto drop;
}
if (rec_len < sizeof(*task_list)) {
goto drop;
}
task_list = (proto_69845_app_ele_data_t*)ptr;
if (!task_list->num_of_data) {
goto drop;
}
ptr += sizeof(*task_list);
rec_len -= sizeof(*task_list);
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto drop;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
for (i = 0; i < task_list->num_of_data; i++) {
if (rec_len < sizeof(*id_hdr) + sizeof(id)) {
goto drop;
}
id_hdr = (proto_69845_app_data_t*)ptr;
if (id_hdr->data_type != PROTO_69845_APP_DATA_UNSIGNED) {
goto drop;
}
id = id_hdr->data[0];
os_mem_set(config, 0, sizeof(*config));
/* delete config */
ret = iot_sg_sta_flash_js_task_cfg_get_by_id(id, config);
if (ret == ERR_OK) {
config->task_id = 0;
os_mem_set(&config->exe_inter, 0,
sizeof(config->exe_inter));
os_mem_set(&config->delay, 0,
sizeof(config->delay));
os_mem_set(&config->start_time, 0,
sizeof(config->start_time));
if (iot_sg_sta_flash_js_task_cfg_save(config->task_type,
config)) {
goto drop;
}
iot_sg_printf("%s task_type %lu task_id %lu\n", __FUNCTION__,
config->task_type, id);
}
ptr += (sizeof(*id_hdr) + sizeof(id));
rec_len -= (sizeof(*id_hdr) + sizeof(id));
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_task_clear(void)
{
uint32_t ret;
iot_pkt_t *pkt_buf = NULL;
uint8_t task_type;
iot_sg_meter_js_task_config_hdr_t *config;
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto drop;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
for (task_type = 0; task_type < IOT_SG_STA_METER_JS_CFG_TYPE_MAX;
task_type++) {
os_mem_set(config, 0, sizeof(*config));
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config);
if (ret == ERR_OK) {
iot_sg_printf("%s task_type %lu task_id %lu\n", __FUNCTION__,
task_type, config->task_id);
config->task_id = 0;
os_mem_set(&config->exe_inter, 0,
sizeof(config->exe_inter));
os_mem_set(&config->delay, 0,
sizeof(config->delay));
os_mem_set(&config->start_time, 0,
sizeof(config->start_time));
iot_sg_sta_flash_js_task_cfg_save(task_type, config);
}
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_task_cmd_handle(uint8_t method_id,
proto_69845_app_data_t *data, uint32_t len)
{
uint32_t ret = ERR_FAIL;
switch (method_id) {
case PROTO_OI_TASK_CFG_LIST_MET_ADD:
{
ret = iot_sg_sta_ext_task_add(data, len);
break;
}
case PROTO_OI_TASK_CFG_LIST_MET_DELETE:
{
ret = iot_sg_sta_ext_task_delete(data, len);
break;
}
case PROTO_OI_TASK_CFG_LIST_MET_CLEAR:
{
ret = iot_sg_sta_ext_task_clear();
break;
}
default:
break;
}
return ret;
}
static uint8_t iot_sg_sta_ext_clct_unit_check(
proto_69845_app_road_t *road, proto_69845_app_data_ti_t *ti,
uint32_t *bitmap, uint8_t time_type)
{
uint8_t type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
uint16_t oi, value;
oi = proto_69845_byte_to_oi((uint8_t*)&road->rec_oad.oi);
switch (oi) {
case PROTO_69845_APP_OI_MIN_FROZEN:
{
if (time_type == IOT_SG_STA_METER_CLCT_TYPE_CURRENT) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_1MIN;
} else if (time_type == IOT_SG_STA_METER_CLCT_TYPE_INTER_TIME) {
if (ti->uint != PROTO_OI_TI_INTERVAL_UNIT_TYPE_MIN) {
goto out;
}
value = iot_bytes_to_uint16((uint8_t*)&ti->value, 1);
if (value == 15) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_15MIN;
}
}
break;
}
case PROTO_69845_APP_OI_DAY_FROZEN:
{
if (time_type == IOT_SG_STA_METER_CLCT_TYPE_CURRENT) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_D_C;
} else {
type = IOT_SG_STA_METER_JS_CFG_TYPE_DF;
}
break;
}
case PROTO_69845_APP_OI_MON_FROZEN:
{
type = IOT_SG_STA_METER_JS_CFG_TYPE_MF;
break;
}
default:
break;
}
switch (type) {
case IOT_SG_STA_METER_JS_CFG_TYPE_MF:
case IOT_SG_STA_METER_JS_CFG_TYPE_DF:
case IOT_SG_STA_METER_JS_CFG_TYPE_15MIN:
case IOT_SG_STA_METER_JS_CFG_TYPE_D_C:
{
if (iot_sg_sta_ext_oad_check(road, bitmap)) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
}
break;
}
case IOT_SG_STA_METER_JS_CFG_TYPE_1MIN:
{
if (iot_sg_sta_ext_1min_oad_check(road, bitmap)) {
type = IOT_SG_STA_METER_JS_CFG_TYPE_INVALID;
}
break;
}
default:
break;
}
out:
return type;
}
static uint8_t iot_sg_sta_ext_save_type_change(uint8_t meter_type)
{
uint8_t type = IOT_SG_STA_EXT_METER_TYPE_INVALID;
if (meter_type >= 21 && meter_type <= 35) {
type = IOT_SG_STA_EXT_METER_TYPE_3P;
} else if (meter_type >= 51 && meter_type <= 57) {
type = IOT_SG_STA_EXT_METER_TYPE_SINGLE;
} else if ((meter_type >= 71 && meter_type <= 80) || (meter_type == 87)) {
type = IOT_SG_STA_EXT_METER_TYPE_3P;
} else if ((meter_type >= 81 && meter_type <= 86) || (meter_type == 88)
|| (meter_type == 89)) {
type = IOT_SG_STA_EXT_METER_TYPE_SINGLE;
}
return type;
}
static uint8_t iot_sg_sta_ext_clct_save_type_check(
proto_69845_app_data_clct_ms_t *ms_hdr, uint32_t len)
{
uint32_t cache_len = len;
proto_69845_app_data_ms_type_t *type_hdr;
uint8_t type = IOT_SG_STA_EXT_METER_TYPE_INVALID;
switch (ms_hdr->type) {
case PROTO_OI_MS_TYPE_ALL_PM:
{
type = IOT_SG_STA_EXT_METER_TYPE_ALL;
break;
}
case PROTO_OI_MS_TYPE_GROUP_PM_TYPE:
{
cache_len -= sizeof(*ms_hdr);
if (cache_len < sizeof(*type_hdr)) {
goto out;
}
type_hdr = (proto_69845_app_data_ms_type_t*)ms_hdr->ms_data;
cache_len -= sizeof(*type_hdr);
if (cache_len < (type_hdr->cnt * sizeof(type_hdr->type_list[0]))) {
goto out;
}
type = iot_sg_sta_ext_save_type_change(type_hdr->type_list[0]);
break;
}
default:
break;
}
out:
return type;
}
static uint32_t iot_sg_sta_ext_clct_unit_save(uint8_t task_type,
uint8_t save_type, uint8_t clct_id, uint32_t cfg_di_bm, uint8_t clct_type)
{
uint8_t type_3p;
uint32_t ret = ERR_FAIL;
iot_pkt_t *pkt_buf = NULL;
iot_sg_meter_js_task_config_hdr_t *config;
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto out;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
type_3p = iot_sg_sta_ext_type_single_to_3p(task_type);
iot_sg_printf("%s save type %lu\n", __FUNCTION__, save_type);
switch (save_type) {
case IOT_SG_STA_EXT_METER_TYPE_SINGLE:
{
if (iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config)
== ERR_OK) {
if (config->all_flag && config->scheme_num) {
config->all_flag = 0;
config->task_type = type_3p;
ret = iot_sg_sta_flash_js_task_cfg_save(type_3p, config);
iot_sg_printf("%s task_3p_type %lu ret %lu\n", __FUNCTION__,
type_3p, ret);
}
}
config->task_type = task_type;
config->all_flag = 0;
config->scheme_num = clct_id;
config->clct_type = clct_type;
config->cfg_di_bm = cfg_di_bm;
ret = iot_sg_sta_flash_js_task_cfg_save(task_type, config);
iot_sg_printf("%s task_type %lu ret %lu\n", __FUNCTION__, task_type,
ret);
break;
}
case IOT_SG_STA_EXT_METER_TYPE_3P:
{
iot_sg_sta_flash_js_task_cfg_get_by_type(type_3p, config);
config->task_type = type_3p;
config->all_flag = 0;
config->scheme_num = clct_id;
config->clct_type = clct_type;
config->cfg_di_bm = cfg_di_bm;
ret = iot_sg_sta_flash_js_task_cfg_save(type_3p, config);
iot_sg_printf("%s task_3p_type %lu ret %lu\n", __FUNCTION__,
type_3p, ret);
if (ret) {
goto out;
}
if (iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config)
== ERR_OK) {
if (config->all_flag && config->scheme_num) {
config->all_flag = 0;
config->task_type = task_type;
ret = iot_sg_sta_flash_js_task_cfg_save(task_type, config);
iot_sg_printf("%s task_type %lu ret %lu\n", __FUNCTION__,
task_type, ret);
}
}
break;
}
case IOT_SG_STA_EXT_METER_TYPE_ALL:
{
/* save all meter cfg */
iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config);
config->task_type = task_type;
config->all_flag = 1;
config->scheme_num = clct_id;
config->clct_type = clct_type;
config->cfg_di_bm = cfg_di_bm;
ret = iot_sg_sta_flash_js_task_cfg_save(task_type, config);
iot_sg_printf("%s task_type %lu ret %lu\n", __FUNCTION__, task_type,
ret);
if (ret) {
goto out;
}
iot_sg_sta_flash_js_task_cfg_get_by_type(type_3p, config);
config->task_type = type_3p;
config->all_flag = 0;
config->scheme_num = 0;
config->clct_type = 0;
config->cfg_di_bm = 0;
ret = iot_sg_sta_flash_js_task_cfg_save(type_3p, config);
iot_sg_printf("%s task_3p_type %lu ret %lu\n", __FUNCTION__, type_3p,
ret);
break;
}
default:
break;
}
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_clct_unit_handle(proto_69845_app_data_t *data,
uint32_t len)
{
uint8_t *ptr = (uint8_t*)data, task_type, save_type, time_type = 0, reason = 0;
uint32_t ret, rec_len = len, cfg_di_bm;
proto_69845_app_data_clct_cfg_unit_hdr_t *unit_hdr;
proto_69845_app_data_clct_type_t *clct_type;
proto_69845_app_data_clct_csd_t *csd_hdr;
proto_69845_app_road_t *road_hdr;
proto_69845_app_data_clct_ms_t *ms_hdr;
proto_69845_app_data_ti_t *ti = NULL;
if (!data || !len) {
reason = 1;
goto drop;
}
if (rec_len < sizeof(*unit_hdr)) {
reason = 2;
goto drop;
}
unit_hdr = (proto_69845_app_data_clct_cfg_unit_hdr_t*)ptr;
if (unit_hdr->data0_type != PROTO_69845_APP_DATA_STRUCTURE
|| unit_hdr->clct_cfg_ele_cnt != 6
|| unit_hdr->data1_type != PROTO_69845_APP_DATA_UNSIGNED
|| unit_hdr->data2_type != PROTO_69845_APP_DATA_LONG_UNSIGNED) {
reason = 3;
goto drop;
}
ptr += sizeof(*unit_hdr);
rec_len -= sizeof(*unit_hdr);
if (rec_len < sizeof(*clct_type)) {
reason = 4;
goto drop;
}
clct_type = (proto_69845_app_data_clct_type_t*)ptr;
if (clct_type->data0_type != PROTO_69845_APP_DATA_STRUCTURE
|| clct_type->ele_cnt != 2
|| clct_type->data1_type != PROTO_69845_APP_DATA_UNSIGNED) {
reason = 5;
goto drop;
}
ptr += sizeof(*clct_type);
rec_len -= sizeof(*clct_type);
switch (clct_type->type) {
case PROTO_69845_DATA_CLCT_UNIT_TYPE_CURR:
{
if (clct_type->data2_type != PROTO_69845_APP_DATA_NULL) {
reason = 6;
goto drop;
}
time_type = IOT_SG_STA_METER_CLCT_TYPE_CURRENT;
break;
}
case PROTO_69845_DATA_CLCT_UNIT_TYPE_FROZEN:
{
if (clct_type->data2_type != PROTO_69845_APP_DATA_NULL) {
reason = 6;
goto drop;
}
time_type = IOT_SG_STA_METER_CLCT_TYPE_FREEZE_TIME;
break;
}
case PROTO_69845_DATA_CLCT_UNIT_TYPE_INTERVAL:
{
if (clct_type->data2_type != PROTO_69845_APP_DATA_TI) {
reason = 7;
goto drop;
}
if (rec_len < sizeof(*ti)) {
reason = 8;
goto drop;
}
time_type = IOT_SG_STA_METER_CLCT_TYPE_INTER_TIME;
ti = (proto_69845_app_data_ti_t*)ptr;
ptr += sizeof(*ti);
rec_len -= sizeof(*ti);
break;
}
default:
reason = 9;
goto drop;
}
if (rec_len < sizeof(*csd_hdr)) {
reason = 10;
goto drop;
}
csd_hdr = (proto_69845_app_data_clct_csd_t*)ptr;
if (csd_hdr->data0_type != PROTO_69845_APP_DATA_ARRAY
|| csd_hdr->csd_cnt != 1
|| csd_hdr->data1_type != PROTO_69845_APP_DATA_CSD
|| csd_hdr->type != PROTO_OI_CSD_TYPE_ROAD) {
reason = 11;
goto drop;
}
ptr += sizeof(*csd_hdr);
rec_len -= sizeof(*csd_hdr);
if (rec_len < sizeof(*road_hdr)) {
reason = 12;
goto drop;
}
road_hdr = (proto_69845_app_road_t*)ptr;
if ((rec_len < (sizeof(*road_hdr) +
road_hdr->cnt * sizeof(proto_69845_app_oad_t)))
|| !road_hdr->cnt) {
reason = 13;
goto drop;
}
task_type = iot_sg_sta_ext_clct_unit_check(road_hdr, ti, &cfg_di_bm,
time_type);
if (task_type == IOT_SG_STA_METER_JS_CFG_TYPE_INVALID) {
reason = 14;
goto drop;
}
ptr = ptr + sizeof(*road_hdr) +
road_hdr->cnt * sizeof(proto_69845_app_oad_t);
rec_len = rec_len - (sizeof(*road_hdr) +
road_hdr->cnt * sizeof(proto_69845_app_oad_t));
if (rec_len < sizeof(*ms_hdr)) {
reason = 15;
goto drop;
}
ms_hdr = (proto_69845_app_data_clct_ms_t*)ptr;
if (ms_hdr->data_type != PROTO_69845_APP_DATA_MS) {
goto drop;
}
save_type = iot_sg_sta_ext_clct_save_type_check(ms_hdr, rec_len);
if (save_type == IOT_SG_STA_EXT_METER_TYPE_INVALID) {
reason = 16;
goto drop;
}
ret = iot_sg_sta_ext_clct_unit_save(task_type, save_type,
unit_hdr->clct_id, cfg_di_bm, time_type);
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_clct_add(proto_69845_app_data_t *data,
uint32_t len)
{
uint8_t *ptr = (uint8_t*)data, i, reason = 0;
uint32_t ret, rec_len = len, cache_len = 0;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_t *data_t;
if (!data || !len) {
reason = 1;
goto drop;
}
if (data->data_type != PROTO_69845_APP_DATA_ARRAY) {
reason = 2;
goto drop;
}
if (rec_len < sizeof(*task_list)) {
reason = 3;
goto drop;
}
task_list = (proto_69845_app_ele_data_t*)ptr;
if (!task_list->num_of_data) {
reason = 4;
goto drop;
}
ptr += sizeof(*task_list);
rec_len -= sizeof(*task_list);
for (i = 0; i < task_list->num_of_data; i++) {
if (rec_len < sizeof(*data_t)) {
reason = 5;
goto drop;
}
data_t = (proto_69845_app_data_t*)ptr;
if (proto_69845_get_data_len(data_t, rec_len, &cache_len)) {
reason = 6;
goto drop;
}
if (rec_len < cache_len) {
reason = 7;
goto drop;
}
if (iot_sg_sta_ext_clct_unit_handle(data_t, cache_len)) {
reason = 8;
goto drop;
}
ptr += cache_len;
rec_len -= cache_len;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
ret = ERR_FAIL;
out:
return ret;
}
static uint32_t iot_sg_sta_ext_clct_delete(proto_69845_app_data_t *data,
uint32_t len)
{
iot_pkt_t *pkt_buf = NULL;
uint8_t *ptr = (uint8_t*)data, i, num;
uint32_t ret, rec_len = len;
proto_69845_app_ele_data_t *task_list;
proto_69845_app_data_t *id_hdr;
iot_sg_meter_js_task_config_hdr_t *config;
if (!data || !len) {
goto drop;
}
if (data->data_type != PROTO_69845_APP_DATA_ARRAY) {
goto drop;
}
if (rec_len < sizeof(*task_list)) {
goto drop;
}
task_list = (proto_69845_app_ele_data_t*)ptr;
if (!task_list->num_of_data) {
goto drop;
}
ptr += sizeof(*task_list);
rec_len -= sizeof(*task_list);
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto drop;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
for (i = 0; i < task_list->num_of_data; i++) {
if (rec_len < sizeof(*id_hdr) + sizeof(num)) {
goto drop;
}
id_hdr = (proto_69845_app_data_t*)ptr;
if (id_hdr->data_type != PROTO_69845_APP_DATA_UNSIGNED) {
goto drop;
}
num = id_hdr->data[0];
os_mem_set(config, 0, sizeof(*config));
ret = iot_sg_sta_flash_js_task_cfg_get_by_num(num, config);
if (ret == ERR_OK) {
config->scheme_num = 0;
config->clct_type = 0;
config->cfg_di_bm = 0;
if (iot_sg_sta_flash_js_task_cfg_save(config->task_type,
config)) {
goto drop;
}
iot_sg_printf("%s task_type %lu clct_num %lu\n", __FUNCTION__,
config->task_type, num);
}
ptr += (sizeof(*id_hdr) + sizeof(num));
rec_len -= (sizeof(*id_hdr) + sizeof(num));
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_clct_clear(void)
{
uint32_t ret;
iot_pkt_t *pkt_buf = NULL;
uint8_t task_type;
iot_sg_meter_js_task_config_hdr_t *config;
pkt_buf = iot_pkt_alloc(sizeof(*config), IOT_SMART_GRID_MID);
if (!pkt_buf) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto drop;
}
config = (iot_sg_meter_js_task_config_hdr_t*)iot_pkt_put(pkt_buf,
sizeof(*config));
for (task_type = 0; task_type < IOT_SG_STA_METER_JS_CFG_TYPE_MAX;
task_type++) {
os_mem_set(config, 0, sizeof(*config));
ret = iot_sg_sta_flash_js_task_cfg_get_by_type(task_type, config);
if (ret == ERR_OK) {
iot_sg_printf("%s task_type %lu clct_num %lu\n", __FUNCTION__,
config->task_type, config->scheme_num);
config->scheme_num = 0;
config->clct_type = 0;
config->cfg_di_bm = 0;
iot_sg_sta_flash_js_task_cfg_save(task_type, config);
}
}
ret = ERR_OK;
goto out;
drop:
ret = ERR_FAIL;
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return ret;
}
static uint32_t iot_sg_sta_ext_clct_cmd_handle(uint8_t method_id,
proto_69845_app_data_t *data, uint32_t len)
{
uint32_t ret = ERR_FAIL;
switch (method_id) {
case PROTO_OI_CLCT_LIST_MET_ADD:
{
ret = iot_sg_sta_ext_clct_add(data, len);
break;
}
case PROTO_OI_CLCT_LIST_MET_DELETE:
{
ret = iot_sg_sta_ext_clct_delete(data, len);
break;
}
case PROTO_OI_CLCT_LIST_MET_CLEAR:
{
ret = iot_sg_sta_ext_clct_clear();
break;
}
default:
break;
}
return ret;
}
iot_pkt_t *iot_sg_sta_ext_get_handle_js(
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
{
iot_pkt_t *pkt = NULL;
uint8_t *ptr = data;
uint32_t len = data_len;
proto_69845_app_get_req_t *req = (proto_69845_app_get_req_t*)data;
(void)hdr_698;
if (len < sizeof(*req)) {
iot_sg_printf("%s err\n", __FUNCTION__);
goto out;
}
ptr += sizeof(*req);
len -= sizeof(*req);
switch (req->data_type) {
case PROTO_69845_APP_GET_NORMAL:
{
pkt = iot_sg_sta_ext_get_normal_handle(hdr_698, ptr, len);
break;
}
case PROTO_69845_APP_GET_NORMALLIST:
{
pkt = iot_sg_sta_ext_get_normal_list_handle(hdr_698, ptr, len);
break;
}
case PROTO_69845_APP_GET_RECORD:
{
pkt = iot_sg_sta_ext_get_record_handle(hdr_698, ptr, len);
break;
}
default:
break;
}
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_action_handle_js(
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
{
iot_pkt_t *pkt = NULL;
uint8_t *ptr = data;
uint32_t len = data_len;
proto_69845_app_action_req_t *req = (proto_69845_app_action_req_t*)data;
(void)hdr_698;
if (len < sizeof(*req)) {
iot_sg_printf("%s err\n", __FUNCTION__);
goto out;
}
ptr += sizeof(*req);
len -= sizeof(*req);
switch (req->data_type) {
case PROTO_69845_APP_ACTION_NORMAL:
{
pkt = iot_sg_sta_ext_action_normal_handle(hdr_698, ptr, len);
break;
}
case PROTO_69845_APP_ACTION_NORMALLIST:
{
pkt = iot_sg_sta_ext_action_list_handle(hdr_698, ptr, len);
break;
}
default:
break;
}
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_get_normal_resp_js(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad)
{
uint8_t reason = 0;
iot_pkt_t *pkt = NULL;
switch (oad->oi) {
case PROTO_69845_APP_OI_TASK_CFG_LIST:
{
if (oad->attribute_id != PROTO_OI_TASK_CFG_LIST_ATT_CFG_LIST
|| !oad->element_index) {
reason = 1;
goto drop;
}
pkt = iot_sg_sta_ext_task_parameter_query(hdr_698, piid, oad,
oad->element_index);
break;
}
case PROTO_69845_APP_OI_CLCT_LIST:
{
if (oad->attribute_id != PROTO_OI_CLCT_LIST_ATT_ClCT_LIST
|| !oad->element_index) {
reason = 2;
goto drop;
}
pkt = iot_sg_sta_ext_clct_parameter_query(hdr_698, piid, oad,
oad->element_index);
break;
}
case PROTO_69845_APP_OI_CLCT_STATE_LIST:
{
if (oad->attribute_id != PROTO_OI_CLCT_STATE_LIST_ATT_ClCT_LIST
|| !oad->element_index) {
reason = 3;
goto drop;
}
pkt = iot_sg_sta_ext_clct_state_query(hdr_698, piid, oad,
oad->element_index);
break;
}
case PROTO_69845_APP_OI_CLCT_MONITOR_LIST:
{
if (oad->attribute_id != PROTO_OI_CLCT_MONITOR_LIST_ATT_ClCT_LIST
|| !oad->element_index) {
reason = 4;
goto drop;
}
pkt = iot_sg_sta_ext_clct_monitor_query(hdr_698, piid, oad,
oad->element_index);
break;
}
default:
break;
}
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_get_normal_list_resp_js(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_get_normal_list_desc_t *cache_list)
{
uint8_t *data, i, m, n, *dar, reason, addr_len;
iot_pkt_t *pkt = NULL, *pkt_buf = NULL;
uint16_t head_len, tail_len, cnt;
uint32_t total_len, list_resp_len = 0;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_get_resp_normal_list_t *normal_list_resp;
proto_69845_app_oad_resp_hdr_t *unit_resp_hdr;
proto_69845_app_oad_t *oad;
proto_69845_app_data_t *unit_data, *tsa_desc;
proto_69845_app_ele_data_t *ele_data;
proto_69845_app_data_tsa_t *tsa;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_node_desc_t *node;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
list_resp_len = iot_sg_sta_ext_get_nor_list_oad_resp_len(cache_list);
if (!list_resp_len) {
reason = 1;
goto drop;
}
total_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*get_resp) + sizeof(*normal_list_resp) + list_resp_len
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
reason = 2;
goto drop;
}
data = iot_pkt_put(pkt, total_len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)total_len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_GET_RESP;
get_resp = (proto_69845_app_get_resp_t*)app_resp->data;
get_resp->data_type = PROTO_69845_APP_GET_NORMALLIST;
normal_list_resp = (proto_69845_app_get_resp_normal_list_t*)get_resp->data;
normal_list_resp->piid_acd.sn = cache_list->piid.sn;
normal_list_resp->piid_acd.priority = cache_list->piid.priority;
normal_list_resp->piid_acd.acd = 0;
normal_list_resp->oad_cnt = cache_list->cnt;
data = data + sizeof(*app_resp) + sizeof(*get_resp) +
sizeof(*normal_list_resp);
for (i = 0; i < normal_list_resp->oad_cnt; i++) {
unit_resp_hdr = (proto_69845_app_oad_resp_hdr_t*)data;
oad = &cache_list->list[i].oad;
proto_69845_oi_to_byte(oad->oi, (uint8_t*)&unit_resp_hdr->oad.oi);
unit_resp_hdr->oad.attribute_id = oad->attribute_id;
unit_resp_hdr->oad.attribute_char = oad->attribute_char;
unit_resp_hdr->oad.element_index = oad->element_index;
unit_resp_hdr->result_type = PROTO_69845_APP_GET_RESULT_DATA;
data += sizeof(*unit_resp_hdr);
switch (oad->oi) {
case PROTO_69845_APP_OI_COLLECTOR:
{
switch (oad->attribute_id) {
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_RPT_CNT:
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_RPT_CNT:
case PROTO_OI_COLLECTOR_ATT_METER_CNT:
case PROTO_OI_COLLECTOR_ATT_MIN_DATA_MAX_CNT:
case PROTO_OI_COLLECTOR_ATT_CURVE_DATA_MAX_CNT:
{
unit_data = (proto_69845_app_data_t*)data;
unit_data->data_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
data += sizeof(*unit_data);
cnt = iot_sg_sta_ext_get_collect_info_cnt(oad->attribute_id);
data[0] = (uint8_t)(cnt >> 8);
data[1] = (uint8_t)(cnt & 0xff);
data += sizeof(cnt);
break;
}
case PROTO_OI_COLLECTOR_ATT_METER_LIST:
{
ele_data = (proto_69845_app_ele_data_t*)data;
ele_data->data_type = PROTO_69845_APP_DATA_ARRAY;
ele_data->num_of_data = iot_sg_node_reg_get_node_cnt();
data += sizeof(*ele_data);
n = 0;
for (m = 0; m < ele_data->num_of_data; m++) {
tsa_desc = (proto_69845_app_data_t*)data;
tsa_desc->data_type = PROTO_69845_APP_DATA_TSA;
tsa = (proto_69845_app_data_tsa_t*)tsa_desc->data;
tsa->len = sizeof(tsa->flag) + IOT_MAC_ADDR_LEN;
tsa->flag.sa_len = IOT_MAC_ADDR_LEN - 1;
tsa->flag.logical_addr = 0;
tsa->flag.sa_type = PROTO_69845_SA_TYPE_SIG;
for (; n < IOT_SG_STA_SEC_NODE_MAX; n++) {
if (sta_glb->node_list[n] != NULL) {
node = sta_glb->node_list[n];
if (iot_sg_sta_node_valid_check(node)) {
iot_mac_addr_cpy(tsa->sa_and_ca,
node->entry.addr);
iot_mac_addr_reverse(tsa->sa_and_ca);
data = data + sizeof(*tsa_desc) + sizeof(*tsa)
+ IOT_MAC_ADDR_LEN;
n++;
break;
}
}
}
}
break;
}
default:
unit_resp_hdr->result_type = PROTO_69845_APP_GET_RESULT_DAR;
dar = data;
*dar = PROTO_69845_APP_DAR_OTHER;
data++;
break;
}
break;
}
default:
unit_resp_hdr->result_type = PROTO_69845_APP_GET_RESULT_DAR;
dar = data;
*dar = PROTO_69845_APP_DAR_OTHER;
data++;
break;
}
}
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
goto out;
drop:
if (pkt) {
iot_pkt_free(pkt);
}
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
if (pkt_buf) {
iot_pkt_free(pkt_buf);
}
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_get_record_resp_js(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_app_piid_t *piid,
proto_69845_app_oad_t *oad,
proto_69845_data_cache_desc_t *rsd,
proto_69845_data_cache_desc_t *road_rcsd)
{
uint8_t *ptr;
iot_pkt_t *pkt = NULL;
uint8_t attribute_id;
switch (oad->oi) {
case PROTO_69845_APP_OI_TASK_CFG_LIST:
{
ptr = (uint8_t*)oad;
ptr += sizeof(oad->oi);
attribute_id = *ptr;
if (attribute_id != PROTO_OI_TASK_CFG_LIST_ATT_RECORD_LIST) {
goto out;
}
pkt = iot_sg_sta_ext_clct_record_data_query(hdr_698, piid, oad, rsd,
road_rcsd);
break;
}
case PROTO_69845_APP_OI_DEV_FAULT_REC:
{
if (oad->attribute_id != PROTO_OI_DEV_FAULT_REC_ATT_EVT_REC_TAB) {
goto out;
}
pkt = iot_sg_sta_ext_fault_record_data_query(hdr_698, piid, oad, rsd,
road_rcsd);
break;
}
default:
break;
}
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_action_normal_resp_js(
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
proto_69845_app_omd_t *omd, proto_69845_data_cache_desc_t *action_desc)
{
iot_pkt_t *pkt = NULL;
uint8_t cmd, reason = 0;
proto_69845_app_data_t *desc;
switch (omd->oi) {
case PROTO_69845_APP_OI_COLLECTOR:
{
if (omd->method_id != PROTO_OI_COLLECTOR_ATT_RPT_DATA) {
reason = 1;
goto drop;
}
if (action_desc->len < (sizeof(*desc) + sizeof(cmd))) {
reason = 2;
goto drop;
}
desc = (proto_69845_app_data_t*)action_desc->data;
if (desc->data_type != PROTO_69845_APP_DATA_UNSIGNED) {
reason = 3;
goto drop;
}
cmd = desc->data[0];
if (cmd) {
pkt = iot_sg_sta_ext_rpt_start_handle(hdr_698, piid, omd);
} else {
pkt = iot_sg_sta_ext_rpt_stop_handle(hdr_698, piid, omd);
}
break;
}
default:
break;
}
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_action_list_resp_js(
proto_69845_frame_head_info_t *hdr_698,
proto_69845_action_list_desc_t *action)
{
uint8_t i, *data, addr_len;
iot_pkt_t *pkt = NULL;
uint16_t head_len, tail_len;
uint32_t len, ret;
addr_info_t addr_info = {0};
proto_69845_frame_head_info_t *hdr_698_resp;
proto_69845_app_req_resp_t *app_resp;
proto_69845_app_action_resp_t *action_resp;
proto_69845_app_action_resp_normal_list_t *action_list_resp;
proto_69845_app_omd_with_dar_t *action_result_unit;
addr_len = proto_69845_get_addr_info(hdr_698, &addr_info);
len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN + sizeof(*app_resp)
+ sizeof(*action_resp) + sizeof(*action_list_resp)
+ sizeof(*action_result_unit) * action->cnt
+ PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN
+ sizeof(proto_69845_tailer_t);
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
if (pkt == NULL) {
iot_sg_printf("%s pkt err\n", __FUNCTION__);
goto out;
}
data = iot_pkt_put(pkt, len);
/* fill 698.45 proto header */
hdr_698_resp = (proto_69845_frame_head_info_t *)data;
head_len = sizeof(*hdr_698_resp) + addr_len
+ PROTO_69845_CHECKSUM_LEN;
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)len,
&addr_info, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
PROTO_69845_D_P_SERVER_RESPONSE);
data += head_len;
/* fill plaintext apdu data */
app_resp = (proto_69845_app_req_resp_t*)data;
app_resp->type = PROTO_69845_S_APP_ACTION_RESP;
action_resp = (proto_69845_app_action_resp_t*)app_resp->data;
action_resp->data_type = PROTO_69845_APP_ACTION_NORMALLIST;
action_list_resp =
(proto_69845_app_action_resp_normal_list_t*)action_resp->data;
action_list_resp->piid_acd.sn = action->piid.sn;
action_list_resp->piid_acd.priority = action->piid.priority;
action_list_resp->piid_acd.acd = 0;
action_list_resp->omd_cnt = action->cnt;
data = data + sizeof(*app_resp) + sizeof(*action_resp)
+ sizeof(*action_list_resp);
for (i = 0; i < action->cnt; i++) {
action_result_unit = (proto_69845_app_omd_with_dar_t*)data;
proto_69845_oi_to_byte(action->list[i].omd.oi,
(uint8_t*)&action_result_unit->omd.oi);
switch (action->list[i].omd.oi) {
case PROTO_69845_APP_OI_TASK_CFG_LIST:
{
ret = iot_sg_sta_ext_task_cmd_handle(
action->list[i].omd.method_id,
(proto_69845_app_data_t*)action->list[i].omd_data,
action->list[i].len);
break;
}
case PROTO_69845_APP_OI_CLCT_LIST:
{
ret = iot_sg_sta_ext_clct_cmd_handle(
action->list[i].omd.method_id,
(proto_69845_app_data_t*)action->list[i].omd_data,
action->list[i].len);
break;
}
default:
ret = ERR_FAIL;
break;
}
action_result_unit->omd.method_id = action->list[i].omd.method_id;
action_result_unit->omd.operation_mode =
action->list[i].omd.operation_mode;
if (ret == ERR_OK) {
action_result_unit->dar = PROTO_69845_APP_DAR_SUCCESS;
} else {
action_result_unit->dar = PROTO_69845_APP_DAR_OTHER;
}
action_result_unit->optional = PROTO_69845_APP_OPTIONAL_NO_DATA;
data += sizeof(*action_result_unit);
}
/* fill 698.45 proto tailer */
tail_len = sizeof(proto_69845_tailer_t) + PROTO_69845_NO_TIME_TAG_LEN
+ PROTO_69845_NO_FLW_DATA_LEN;
proto_69845_tail_fill_without_ts_fl(hdr_698_resp, data, tail_len);
out:
return pkt;
}
iot_pkt_t *iot_sg_sta_ext_rpt_resp_handle_js(
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
{
iot_pkt_t *pkt = NULL;
uint8_t seq;
proto_69845_app_piid_t *piid;
proto_69845_app_report_resp_t *req = (proto_69845_app_report_resp_t*)data;
proto_69845_app_omd_t omd;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
iot_sg_sta_ext_clct_rpt_info_t *evt_rpt = &ext_info->data_rpt;
if (data_len < sizeof(*req)) {
goto out;
}
if (req->data_type != PROTO_69845_APP_REPRORT_SIMPRECORD
&& req->data_type != PROTO_69845_APP_REPRORT_RECORDLIST) {
goto out;
}
if (data_len < (sizeof(*req) + sizeof(*piid))) {
goto out;
}
piid = (proto_69845_app_piid_t*)req->data;
seq = piid->sn;
pkt = iot_sg_sta_ext_rpt_next_handle(hdr_698, &seq);
if (!pkt) {
if ((evt_rpt->last_rpt_info.data_type ==
IOT_SG_STA_METER_DATA_TYPE_JS_DF)
|| (evt_rpt->last_rpt_info.data_type ==
IOT_SG_STA_METER_DATA_TYPE_JS_MF)) {
pkt = iot_sg_sta_ext_complex_data_rpt(hdr_698,
&evt_rpt->last_rpt_info, &seq);
} else {
omd.oi = PROTO_69845_APP_OI_COLLECTOR;
omd.method_id = PROTO_OI_COLLECTOR_ATT_RPT_DATA;
omd.operation_mode = 0;
pkt = iot_sg_sta_ext_rpt_action_resp(hdr_698, piid, &omd,
PROTO_69845_APP_DAR_OI_NO_EXIST);
}
}
out:
return pkt;
}
#endif /* IOT_SMART_GRID_EXT_JS_FUNC_ENABLE */