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

3271 lines
100 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os_shim header files */
#include "os_utils_api.h"
/* iot common header files */
#include "iot_io_api.h"
#include "iot_oem_api.h"
/* smart grid internal header files */
#include "iot_sg_fr.h"
#include "iot_sg.h"
#include "proto_645.h"
#include "proto_69845.h"
#include "iot_sg_sta.h"
#include "iot_sg_sta_ext.h"
#include "iot_sg_sta_flash.h"
#include "iot_sg_sta_cfg_flash.h"
#if (IOT_SMART_GRID_EXT_FUNC_ENABLE)
static uint8_t iot_sg_sta_ext_sm_run_check(void)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
if (iot_mac_addr_valid(ext_info->addr)) {
return 1;
} else {
return 0;
}
}
static uint8_t iot_sg_sta_ext_sm_meter_check(uint8_t *addr)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
if (iot_mac_addr_cmp(ext_info->addr, addr)) {
return 1;
} else {
return 0;
}
}
void iot_sg_sta_ext_tm_reset(void)
{
uint8_t reason = 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 (!ext_info->ext_init) {
reason = 1;
goto drop;
}
iot_sg_sta_ext_ec_pulse_time_reset_handle();
if (!iot_sg_sta_ext_sm_run_check()) {
reason = 2;
goto drop;
}
ext_info->flag_tm_reset = 1;
goto out;
drop:
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
out:
return;
}
uint32_t iot_sg_sta_ext_node_tm_check(iot_time_tm_t *tm, int64_t max_delta)
{
iot_time_tm_t curr_tm = { 0 };
int64_t delta;
iot_sg_sta_rtc_get(&curr_tm, 0);
delta = iot_rtc_delta_calc(&curr_tm, tm);
delta = IOT_ABS(delta);
if (delta > max_delta) {
return ERR_FAIL;
} else {
return ERR_OK;
}
}
static void iot_sg_sta_ext_node_tm_update(iot_sg_sta_node_desc_t *node)
{
uint8_t m;
switch (iot_sg_sta_get_user_type()) {
case USER_TYPE_STATE_GRID_XIAN:
{
#if IOT_SMART_GRID_GW_V28_ENABLE
iot_sg_sta_ext_gw_data_clct_node_tm_update(node);
break;
#endif
}
case USER_TYPE_SOUTHEN_POWER_GRID_GX:
case USER_TYPE_BRM_PEIWANG:
case USER_TYPE_STATE_GRID_HEBEI:
case USER_TYPE_STATE_GRID_HUNAN:
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
case USER_TYPE_STATE_GRID_MENGDONG_LC:
{
os_mem_set(&node->ext.lr_info.tm, 0x0, sizeof(iot_time_tm_t));
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGDONG:
{
for (m = 0; m < IOT_SG_EXT_CLCT_TASK_CNT_MAX; m++) {
node->ext.clct_info.task_info[m].tm_year = 0;
node->ext.clct_info.task_info[m].tm_mon = 0;
node->ext.clct_info.task_info[m].tm_mday = 0;
node->ext.clct_info.task_info[m].tm_hour = 0;
node->ext.clct_info.task_info[m].tm_min = 0;
}
break;
}
case USER_TYPE_STATE_GRID_JIANGSU:
{
if (iot_sg_sta_ext_node_tm_check(&node->ext.data_clct_info.mf_tm,
IOT_SG_STA_EXT_CLCT_PRD_1DAY)) {
os_mem_set(&node->ext.data_clct_info.mf_tm, 0x0,
sizeof(iot_time_tm_t));
}
if (iot_sg_sta_ext_node_tm_check(&node->ext.data_clct_info.df_tm,
IOT_SG_STA_EXT_CLCT_PRD_1DAY)) {
os_mem_set(&node->ext.data_clct_info.df_tm, 0x0,
sizeof(iot_time_tm_t));
}
if (iot_sg_sta_ext_node_tm_check(&node->ext.data_clct_info.cur_15m_tm,
IOT_SG_STA_EXT_CLCT_PRD_5MIN)) {
os_mem_set(&node->ext.data_clct_info.cur_15m_tm, 0x0,
sizeof(iot_time_tm_t));
}
if (iot_sg_sta_ext_node_tm_check(&node->ext.data_clct_info.cur_1m_tm,
IOT_SG_STA_EXT_CLCT_PRD_1MIN)) {
os_mem_set(&node->ext.data_clct_info.cur_1m_tm, 0x0,
sizeof(iot_time_tm_t));
}
break;
}
case USER_TYPE_STATE_GRID_FUJIAN:
{
iot_sg_sta_ext_freeze_node_tm_update(node);
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGZHOU:
default:
if (iot_sg_sta_get_proto_type() == IOT_SG_STA_APP_PROTO_NW) {
iot_sg_sta_ext_nw_tm_update(node);
}
break;
}
}
void iot_sg_sta_ext_tm_update(void)
{
uint8_t i;
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;
if (ext_info->flag_tm_reset) {
ext_info->flag_tm_reset = 0;
os_mem_set(&ext_info->lc_info.froze_tm, 0, sizeof(iot_time_tm_t));
os_mem_set(&ext_info->lc_info.last_froze_tm, 0,
sizeof(iot_time_tm_t));
iot_sg_sta_ext_ec_tm_update_handle();
for (i = 0; i < IOT_SG_STA_SEC_NODE_MAX; i++) {
if (sta_glb->node_list[i] != NULL) {
node = sta_glb->node_list[i];
iot_sg_sta_ext_node_tm_update(node);
}
}
}
return;
}
void iot_sg_sta_ext_sm_next_action(uint32_t dur)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
if (!dur) {
dur = 1;
}
os_start_timer(ext_info->ext_timer, dur);
}
void iot_sg_sta_ext_sm_stop_action(void)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
os_stop_timer(ext_info->ext_timer);
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_INTERNAL,
IOT_SG_MSG_ID_INTERN_EXT_SM);
}
static void iot_sg_sta_ext_sm_start(uint8_t *addr, uint32_t dur)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
os_mem_set(ext_info->addr, 0, sizeof(ext_info->addr));
os_mem_set(&ext_info->meter_data, 0xff, sizeof(ext_info->meter_data));
iot_mac_addr_cpy(ext_info->addr, addr);
iot_sg_ext_lr_reset();
iot_sg_sta_ext_nli_info_reset();
iot_sg_sta_ext_curr_clct_clear();
iot_sg_sta_ext_sm_next_action(dur);
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]);
}
static void iot_sg_sta_ext_sm_stop(void)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
ext_info->addr[0], ext_info->addr[1], ext_info->addr[2],
ext_info->addr[3], ext_info->addr[4], ext_info->addr[5]);
os_stop_timer(ext_info->ext_timer);
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_INTERNAL,
IOT_SG_MSG_ID_INTERN_EXT_SM);
os_mem_set(ext_info->addr, 0, sizeof(ext_info->addr));
os_mem_set(&ext_info->meter_data, 0xff, sizeof(ext_info->meter_data));
iot_sg_ext_lr_reset();
iot_sg_ext_data_clct_reset();
iot_sg_sta_ext_curr_clct_clear();
iot_sg_ext_data_freeze_reset();
iot_sg_sta_ext_nw_lc_reset();
iot_sg_sta_ext_nli_info_reset();
}
static void iot_sg_sta_ext_next_meter(uint8_t *addr)
{
uint8_t i, n;
iot_sg_sta_node_desc_t *node;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_sm_stop();
iot_sg_sta_ext_fj_task_restart();
iot_sg_ext_lr_cfg_update();
iot_sg_sta_ext_tm_update();
iot_sg_sta_ext_score_check();
iot_sg_sta_ext_ec_check();
for (n = 0; n < IOT_SG_STA_SEC_NODE_MAX; n++) {
if (sta_glb->node_list[n] != NULL) {
node = sta_glb->node_list[n];
if (iot_mac_addr_cmp(addr, node->entry.addr)) {
break;
}
}
}
for (i = 0; i < IOT_SG_STA_SEC_NODE_MAX; i++) {
n++;
if (n >= IOT_SG_STA_SEC_NODE_MAX) {
n = 0;
}
if (sta_glb->node_list[n]) {
node = sta_glb->node_list[n];
iot_sg_sta_ext_sm_start(node->entry.addr,
IOT_SG_STA_EXT_SM_METER_DELAY);
break;
}
}
}
void iot_sg_ext_set_integral_point(iot_time_tm_t *tm,
int64_t interval, uint8_t after_flag)
{
int64_t delta, interval_delta;
iot_time_tm_t base_tm = { 0 };
if (interval == 0) {
goto out;
}
base_tm.tm_year = 2000;
base_tm.tm_mon = 1;
base_tm.tm_mday = 1;
if (after_flag) {
if (interval < IOT_SG_STA_EXT_DC_EXE_INTER_1MON) {
delta = iot_rtc_delta_calc(&base_tm, tm);
if (delta < 0) {
goto out;
}
interval_delta = delta % interval;
if (interval_delta) {
iot_rtc_delta_add(interval - interval_delta, tm);
}
} else {
if (tm->tm_mday != 1) {
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 (interval < IOT_SG_STA_EXT_DC_EXE_INTER_1MON) {
delta = iot_rtc_delta_calc(&base_tm, tm);
if (delta < 0) {
goto out;
}
interval_delta = delta % interval;
if (interval_delta) {
iot_rtc_delta_add(0 - interval_delta, tm);
}
} else {
if (tm->tm_mday != 1) {
tm->tm_mday = 1;
}
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
}
}
out:
return;
}
uint8_t iot_sg_sta_ext_get_69845_apdu_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;
ext_info->sn_proto_698++;
if (ext_info->sn_proto_698 >= 64) {
ext_info->sn_proto_698 = 0;
}
return ext_info->sn_proto_698;
}
static void iot_sg_ext_698_energy_data_handle(
proto_645_07_energy_data_t *meter_energy_data,
proto_69845_app_ele_data_t *ele_data, uint32_t data_len)
{
uint8_t i, *meter_data, *data;
uint32_t ele_len;
proto_69845_app_data_t *app_data;
ele_len = sizeof(*app_data) + PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
if (data_len < ele_len * ele_data->num_of_data) {
goto out;
}
data = ele_data->data;
BUILD_BUG_ON(sizeof(meter_energy_data->total) ==
IOT_SG_STA_METER_ENERGY_DATA_LEN);
meter_data = meter_energy_data->total;
for (i = 0; i < ele_data->num_of_data && i < PROTO_69845_ENERGY_MAX_ELE_NUM;
i++) {
app_data = (proto_69845_app_data_t *)data;
if (app_data->data_type == PROTO_69845_APP_DATA_DOUBLE_LONG) {
proto_69845_dlong_data_to_meter_bcd_data(app_data->data,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN,
meter_data, IOT_SG_STA_METER_ENERGY_DATA_LEN);
} else {
proto_69845_dlong_unsign_data_to_meter_bcd_data(app_data->data,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN,
meter_data, IOT_SG_STA_METER_ENERGY_DATA_LEN);
}
data += ele_len;
meter_data += IOT_SG_STA_METER_ENERGY_DATA_LEN;
}
out:
return;
}
static void iot_sg_ext_698_cur_demand_data_handle(uint8_t *cur_demand,
uint8_t *data, uint32_t data_len)
{
proto_69845_app_data_t *app_data;
if (data_len < sizeof(*app_data) + PROTO_69845_METER_DATA_DOUBLE_LONG_LEN) {
goto out;
}
app_data = (proto_69845_app_data_t *)data;
if (app_data->data_type != PROTO_69845_APP_DATA_DOUBLE_LONG &&
app_data->data_type != PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED) {
goto out;
}
BUILD_BUG_ON(PROTO_645_07_P_LEN == IOT_SG_STA_METER_POWER_LEN);
if (app_data->data_type == PROTO_69845_APP_DATA_DOUBLE_LONG) {
proto_69845_dlong_data_to_meter_bcd_data(app_data->data,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN, cur_demand,
IOT_SG_STA_METER_POWER_LEN);
} else {
proto_69845_dlong_unsign_data_to_meter_bcd_data(app_data->data,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN, cur_demand,
IOT_SG_STA_METER_POWER_LEN);
}
out:
return;
}
static void iot_sg_ext_698_demand_data_handle(
iot_sg_meter_max_demand_and_ht_t *meter_demand,
proto_69845_app_ele_data_t *ele_data, uint32_t data_len)
{
uint16_t year;
proto_69845_demand_with_time_t *max_demand_data;
if (data_len < sizeof(*max_demand_data) * ele_data->num_of_data) {
goto out;
}
max_demand_data = (proto_69845_demand_with_time_t *)ele_data->data;
if ((max_demand_data->type != PROTO_69845_APP_DATA_STRUCTURE) ||
(max_demand_data->cnt != 2) ||
(max_demand_data->time_type != PROTO_69845_APP_DATA_TIME_S)) {
goto out;
}
if ((max_demand_data->demand_data_type ==
PROTO_69845_APP_DATA_DOUBLE_LONG) ||
(max_demand_data->demand_data_type ==
PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED)) {
if (!max_demand_data->demand) {
os_mem_set(meter_demand, 0x0, sizeof(*meter_demand));
goto out;
}
year = iot_bytes_to_uint16((uint8_t *)&max_demand_data->time.year, 1);
meter_demand->year = iot_byte_to_bcd((uint8_t)(year - 2000));
meter_demand->month = iot_byte_to_bcd(max_demand_data->time.month);
meter_demand->day = iot_byte_to_bcd(max_demand_data->time.day);
meter_demand->hour = iot_byte_to_bcd(max_demand_data->time.hour);
meter_demand->minute = iot_byte_to_bcd(max_demand_data->time.minute);
if ((max_demand_data->demand_data_type ==
PROTO_69845_APP_DATA_DOUBLE_LONG) ) {
proto_69845_dlong_data_to_meter_bcd_data(max_demand_data->demand,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN,
meter_demand->max_demand, IOT_SG_STA_METER_POWER_LEN);
} else {
proto_69845_dlong_unsign_data_to_meter_bcd_data(
max_demand_data->demand,
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN,
meter_demand->max_demand, IOT_SG_STA_METER_POWER_LEN);
}
}
out:
return;
}
static void iot_sg_ext_698_frozen_time_data_handle(
proto_645_07_frozen_time_t *frozen_time, uint8_t *data, uint32_t data_len)
{
uint16_t year;
proto_69845_app_data_t *app_data;
proto_69845_app_data_time_s_t *time;
if (data_len < sizeof(*app_data)) {
goto out;
}
app_data = (proto_69845_app_data_t *)data;
data_len -= sizeof(*app_data);
if (app_data->data_type != PROTO_69845_APP_DATA_TIME_S) {
goto out;
}
if (data_len < sizeof(*time)) {
goto out;
}
time = (proto_69845_app_data_time_s_t *)app_data->data;
year = iot_bytes_to_uint16((uint8_t *)&time->year, 1);
frozen_time->year = iot_byte_to_bcd((uint8_t)(year - 2000));
frozen_time->month = iot_byte_to_bcd(time->month);
frozen_time->day = iot_byte_to_bcd(time->day);
frozen_time->hour = iot_byte_to_bcd(time->hour);
frozen_time->minute = iot_byte_to_bcd(time->minute);
out:
return;
}
static void iot_sg_ext_698_rs_word_handle(iot_sg_meter_rs_word_t *rs_word,
proto_69845_app_ele_data_t *ele_data, uint32_t data_len)
{
uint8_t i, *meter_data, *data;
uint32_t ele_len;
proto_69845_app_ele_data_t *bit_data;
ele_len = sizeof(*bit_data) + PROTO_69845_METER_DATA_LONG_LEN;
if (!ele_data || data_len < ele_len * ele_data->num_of_data) {
goto out;
}
data = ele_data->data;
BUILD_BUG_ON(sizeof(rs_word->rs_word_1) == PROTO_69845_RS_WORD_UNIT_LEN);
meter_data = (uint8_t *)&rs_word->rs_word_1;
for (i = 0; i < ele_data->num_of_data && i < PROTO_69845_RS_WORD_MAX_ELE_NUM;
i++) {
bit_data = (proto_69845_app_ele_data_t *)data;
if (bit_data->data_type == PROTO_69845_APP_DATA_BIT_STRING &&
bit_data->num_of_data == PROTO_69845_RS_WORD_UNIT_LEN * 8) {
os_mem_cpy(meter_data, bit_data->data,
PROTO_69845_RS_WORD_UNIT_LEN);
}
data += ele_len;
meter_data += PROTO_69845_RS_WORD_UNIT_LEN;
}
out:
return;
}
static void iot_sg_ext_698_cur_time_data_handle(
proto_645_07_time_t *cur_time, uint8_t *data, uint32_t data_len)
{
uint16_t year;
proto_69845_app_data_t *app_data;
proto_69845_app_data_time_s_t *time;
if (!cur_time || !data || data_len < sizeof(*app_data)) {
goto out;
}
app_data = (proto_69845_app_data_t *)data;
data_len -= sizeof(*app_data);
if (app_data->data_type != PROTO_69845_APP_DATA_TIME_S) {
goto out;
}
if (data_len < sizeof(*time)) {
goto out;
}
time = (proto_69845_app_data_time_s_t *)app_data->data;
year = iot_bytes_to_uint16((uint8_t *)&time->year, 1);
cur_time->year = iot_byte_to_bcd((uint8_t)(year - 2000));
cur_time->month = iot_byte_to_bcd(time->month);
cur_time->day = iot_byte_to_bcd(time->day);
cur_time->hour = iot_byte_to_bcd(time->hour);
cur_time->minute = iot_byte_to_bcd(time->minute);
cur_time->second = iot_byte_to_bcd(time->second);
out:
return;
}
static void iot_sg_sta_ext_698_ele_data_handle(uint8_t *data, uint32_t data_len,
uint32_t oad_value)
{
uint8_t reason = 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;
proto_69845_app_ele_data_t *ele_data;
if (data_len < sizeof(*ele_data)) {
reason = 1;
goto drop;
}
data_len -= sizeof(*ele_data);
ele_data = (proto_69845_app_ele_data_t *)data;
if (ele_data->data_type != PROTO_69845_APP_DATA_ARRAY) {
reason = 2;
goto drop;
}
if (!ele_data->num_of_data) {
reason = 3;
goto drop;
}
switch (oad_value) {
case PROTO_69845_APP_OAD_EPT_COMP:
{
iot_sg_ext_698_energy_data_handle(&meter->cae, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS:
{
iot_sg_ext_698_energy_data_handle(&meter->pae, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_NEG:
{
iot_sg_ext_698_energy_data_handle(&meter->nae, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_POS:
{
iot_sg_ext_698_energy_data_handle(&meter->cre1, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_NEG:
{
iot_sg_ext_698_energy_data_handle(&meter->cre2, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT1:
{
iot_sg_ext_698_energy_data_handle(&meter->re_1st, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT2:
{
iot_sg_ext_698_energy_data_handle(&meter->re_2st, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT3:
{
iot_sg_ext_698_energy_data_handle(&meter->re_3st, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT4:
{
iot_sg_ext_698_energy_data_handle(&meter->re_4st, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_DEMAND:
{
iot_sg_ext_698_demand_data_handle(&meter->pos_ap_demand, ele_data,
data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_NEG_DEMAND:
{
iot_sg_ext_698_demand_data_handle(&meter->neg_ap_demand, ele_data,
data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_POS_DEMAND:
{
iot_sg_ext_698_demand_data_handle(&meter->cre1_demand, ele_data,
data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_NEG_DEMAND:
{
iot_sg_ext_698_demand_data_handle(&meter->cre2_demand, ele_data,
data_len);
break;
}
case PROTO_69845_APP_OAD_VOLTAGE:
{
proto_69845_v_data_handle(&meter->v, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_CURRENT:
{
proto_69845_a_data_handle(&meter->a, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_P:
{
proto_69845_p_data_handle(&meter->ap, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_Q:
{
proto_69845_p_data_handle(&meter->rp, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_PF:
{
proto_69845_pf_ele_data_handle(&meter->pf, ele_data, data_len);
break;
}
case PROTO_69845_APP_OAD_RUN_WORD:
{
iot_sg_ext_698_rs_word_handle(&meter->rs_word, ele_data, data_len);
break;
}
default:
reason = 4;
break;
}
return;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
}
static void iot_sg_sta_ext_698_oad_data_handle(
proto_69845_app_oad_resp_hdr_t *oad_data, uint32_t data_len)
{
uint32_t oad_value;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_meter_data_t *meter = &sta_glb->ext_info.meter_data;
oad_value = iot_bytes_to_uint32((uint8_t*)&oad_data->oad.oi, 1);
switch (oad_value) {
case PROTO_69845_APP_OAD_GND_CURRENT:
{
proto_69845_gnd_a_data_handle(meter->gnd_a, IOT_SG_STA_METER_A_LEN,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_SIG:
{
proto_69845_energy_sum_data_handle(meter->pae.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
{
proto_69845_energy_sum_data_handle(meter->nae.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_POS_SUM:
{
proto_69845_energy_sum_data_handle(meter->cre1.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_NEG_SUM:
{
proto_69845_energy_sum_data_handle(meter->cre2.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_1st.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_2st.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_3st.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_4st.total,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_TIME:
{
iot_sg_ext_698_cur_time_data_handle(&meter->time, oad_data->result,
data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_DEMAND:
{
iot_sg_ext_698_cur_demand_data_handle(meter->ept_demand,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_DEMAND:
{
iot_sg_ext_698_cur_demand_data_handle(meter->eqt_demand,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_A_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_a,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_B_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_b,
oad_data->result, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_C_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_c,
oad_data->result, data_len);
break;
}
default:
iot_sg_sta_ext_698_ele_data_handle(oad_data->result, data_len,
oad_value);
break;
}
}
static void iot_sg_sta_ext_698_csd_data_handle(proto_69845_app_data_csd_t *csd,
uint8_t *data, uint32_t data_len)
{
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_meter_data_t *meter = &sta_glb->ext_info.meter_data;
uint32_t oad_value;
if (csd->type != PROTO_OI_CSD_TYPE_OAD) {
goto out;
}
oad_value = iot_bytes_to_uint32(csd->csd_data, 1);
switch(oad_value) {
case PROTO_69845_APP_OAD_FROZEN_T:
{
iot_sg_ext_698_frozen_time_data_handle(&meter->frozen_time, data,
data_len);
break;
}
case PROTO_69845_APP_OAD_GND_CURRENT:
{
proto_69845_gnd_a_data_handle(meter->gnd_a, IOT_SG_STA_METER_A_LEN,
data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_SIG:
{
proto_69845_energy_sum_data_handle(meter->pae.total, data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
{
proto_69845_energy_sum_data_handle(meter->nae.total, data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_1st.total,
data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_2st.total,
data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_3st.total,
data, data_len);
break;
}
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
{
proto_69845_energy_sum_data_handle(meter->re_4st.total,
data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_A_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_a, data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_B_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_b, data, data_len);
break;
}
case PROTO_69845_APP_OAD_EPT_POS_C_SIG:
{
proto_69845_energy_sum_data_handle(meter->pos_c, data, data_len);
break;
}
default:
iot_sg_sta_ext_698_ele_data_handle(data, data_len, oad_value);
break;
}
out:
return;
}
static uint32_t iot_sg_ext_69845_get_record_data_handle(
proto_69845_app_get_resp_t *get_resp, uint32_t data_len)
{
uint8_t i, *data, reason = 0, csd_list_len, *record_cnt;
uint32_t ret = ERR_FAIL, oad_value, oad_data_len;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
proto_69845_app_piid_acd_t *piid_acd;
proto_69845_app_rpt_result_record_t *result_record;
proto_69845_app_data_csd_t *csd;
proto_69845_app_get_result_t *result;
if (data_len < sizeof(*piid_acd)) {
reason = 1;
goto drop;
}
piid_acd = (proto_69845_app_piid_acd_t *)get_resp->data;
data_len -= sizeof(*piid_acd);
if (piid_acd->sn != ext_info->sn_proto_698) {
reason = 2;
goto drop;
}
if (data_len < sizeof(*result_record)) {
reason = 3;
goto drop;
}
result_record = (proto_69845_app_rpt_result_record_t *)(get_resp->data +
sizeof(*piid_acd));
data_len -= sizeof(*result_record);
oad_value = iot_bytes_to_uint32((uint8_t *)&result_record->oad.oi, 1);
if (oad_value != PROTO_69845_APP_OAD_MINF &&
oad_value != PROTO_69845_APP_OAD_HF &&
oad_value != PROTO_69845_APP_OAD_DF &&
oad_value != PROTO_69845_APP_OAD_SDF &&
oad_value != PROTO_69845_APP_OAD_MF &&
oad_value != PROTO_69845_APP_OAD_YF &&
oad_value != PROTO_69845_APP_OAD_TTSF &&
oad_value != PROTO_69845_APP_OAD_DTSF &&
oad_value != PROTO_69845_APP_OAD_PSF &&
oad_value != PROTO_69845_APP_OAD_LSF &&
oad_value != PROTO_69845_APP_OAD_LSSF) {
reason = 4;
goto drop;
}
csd_list_len = (sizeof(*csd) + sizeof(proto_69845_app_oad_t)) *
result_record->rcsd.cnt;
if (data_len < csd_list_len) {
reason = 5;
goto drop;
}
csd = (proto_69845_app_data_csd_t *)result_record->rcsd.csd_list;
data = result_record->rcsd.csd_list + csd_list_len;
data_len -= csd_list_len;
if (data_len < sizeof(*result)) {
reason = 6;
goto drop;
}
result = (proto_69845_app_get_result_t *)data;
if (result->result_type != PROTO_69845_APP_GET_RESULT_DATA) {
reason = 7;
goto drop;
}
data += sizeof(*result);
data_len -= sizeof(*result);
record_cnt = data;
if (*record_cnt == 0) {
reason = 8;
goto drop;
}
data += sizeof(*record_cnt);
for (i = 0; i < result_record->rcsd.cnt; i++) {
if (proto_69845_get_data_len((proto_69845_app_data_t *)data, data_len,
&oad_data_len)) {
reason = 9;
goto drop;
}
if (data_len < oad_data_len) {
reason = 10;
goto drop;
}
iot_sg_sta_ext_698_csd_data_handle(csd, data, oad_data_len);
csd = (proto_69845_app_data_csd_t *)(csd->csd_data +
sizeof(proto_69845_app_oad_t));
data += oad_data_len;
data_len -= oad_data_len;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint32_t iot_sg_ext_69845_get_normal_list_data_handle(
proto_69845_app_get_resp_t *get_resp, uint32_t data_len)
{
uint8_t i, *data, reason = 0;
uint8_t user_type = iot_sg_sta_get_user_type();
uint32_t oad_data_len, ret = ERR_FAIL;
proto_69845_app_oad_resp_hdr_t *oad_data;
proto_69845_app_get_resp_normal_list_t *get_normal_resp;
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 (data_len < sizeof(*get_normal_resp)) {
reason = 1;
goto drop;
}
get_normal_resp = (proto_69845_app_get_resp_normal_list_t*)get_resp->data;
data_len -= sizeof(*get_normal_resp);
if (!get_normal_resp->oad_cnt) {
reason = 2;
goto drop;
}
if (get_normal_resp->piid_acd.sn != ext_info->sn_proto_698) {
reason = 3;
goto drop;
}
data = get_normal_resp->oad_data;
for (i = 0; i < get_normal_resp->oad_cnt; i++) {
if (data_len < sizeof(*oad_data)) {
reason = 4;
goto drop;
}
oad_data = (proto_69845_app_oad_resp_hdr_t *)data;
data_len -= sizeof(*oad_data);
data += sizeof(*oad_data);
if (oad_data->result_type != PROTO_69845_APP_GET_RESULT_DATA) {
/* skip dar, see PROTO_69845_APP_DAR_XXX */
data_len--;
data++;
continue;
}
if (proto_69845_get_data_len((proto_69845_app_data_t *)oad_data->result,
data_len, &oad_data_len)) {
reason = 5;
goto drop;
}
if (data_len < oad_data_len) {
reason = 6;
goto drop;
}
if (user_type == USER_TYPE_STATE_GRID_FUJIAN) {
iot_sg_sta_ext_fj_698_oad_data_handle(oad_data, oad_data_len);
} else {
iot_sg_sta_ext_698_oad_data_handle(oad_data, oad_data_len);
}
data += oad_data_len;
data_len -= oad_data_len;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint32_t iot_sg_ext_69845_security_data_handle(
proto_69845_app_sec_req_resp_info_t *sec_resp, uint32_t data_len)
{
uint32_t ret = ERR_FAIL;
uint16_t sec_len;
uint8_t *data;
proto_69845_app_req_resp_t *resp;
proto_69845_app_get_resp_t *get_resp;
proto_69845_app_len_descript_t *len_desc;
len_desc = (proto_69845_app_len_descript_t *)((uint8_t *)sec_resp + 1);
if (!len_desc->mub_flag) {
data = sec_resp->data;
sec_len = sec_resp->len;
} else {
if (len_desc->byte_num == 1) {
sec_len = sec_resp->data[0];
data = sec_resp->data + 1;
data_len -= 1;
} else if (len_desc->byte_num == 2) {
sec_len = iot_bytes_to_uint16(sec_resp->data, 1);
data = sec_resp->data + 2;
data_len -= 2;
} else {
goto out;
}
}
if (data_len < sec_len) {
goto out;
}
if (sec_len < sizeof(*resp)) {
goto out;
}
resp = (proto_69845_app_req_resp_t*)data;
sec_len -= sizeof(*resp);
switch (resp->type) {
case PROTO_69845_S_APP_GET_RESP:
{
if (sec_len < sizeof(*get_resp)) {
goto out;
}
get_resp = (proto_69845_app_get_resp_t*)resp->data;
sec_len -= sizeof(*get_resp);
switch (get_resp->data_type) {
case PROTO_69845_APP_GET_NORMALLIST:
{
ret = iot_sg_ext_69845_get_normal_list_data_handle(get_resp,
sec_len);
break;
}
case PROTO_69845_APP_GET_RECORD:
{
ret = iot_sg_ext_69845_get_record_data_handle(get_resp,
sec_len);
break;
}
default:
break;
}
break;
}
default:
break;
}
out:
return ret;
}
uint32_t iot_sg_ext_read_698_data_handle(uint16_t seq,
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
uint8_t *req_data, uint16_t req_len)
{
uint8_t reason = 0, *req_ser_addr, *resp_ser_addr;
uint32_t ret = ERR_INVAL, len;
proto_69845_frame_head_info_t *resp_hdr, *req_hdr;
proto_69845_app_req_resp_t *resp;
proto_69845_app_sec_req_resp_info_t *sec_resp;
apdu_info_t apdu;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
(void)seq;
if (data_type != IOT_SG_STA_DATA_TYPE_69845) {
reason = 1;
goto drop;
}
if ((req_data == NULL) || !req_len) {
reason = 2;
goto drop;
}
if ((resp_data == NULL) || !resp_len) {
ret = ERR_TIMEOVER;
reason = 3;
goto drop;
}
req_hdr = proto_69845_sanity_check(req_data, req_len);
resp_hdr = proto_69845_sanity_check(resp_data, resp_len);
if(!req_hdr || !resp_hdr) {
reason = 4;
goto drop;
}
req_ser_addr = proto_69845_get_ser_addr(req_hdr);
resp_ser_addr = proto_69845_get_ser_addr(resp_hdr);
if (!iot_mac_addr_cmp(req_ser_addr, resp_ser_addr)) {
reason = 5;
goto drop;
}
if (!iot_mac_addr_cmp(ext_info->addr, resp_ser_addr)) {
reason = 6;
goto drop;
}
if (resp_hdr->ctrl.dir_prm != PROTO_69845_D_P_SERVER_RESPONSE &&
resp_hdr->ctrl.dir_prm != PROTO_69845_D_P_SERVER_REPORT) {
reason = 7;
goto drop;
}
if (resp_hdr->ctrl.fragment != PROTO_69845_APDU_WHOLE) {
reason = 8;
goto drop;
}
if (proto_69845_get_apdu(resp_hdr, resp_len, &apdu)) {
reason = 9;
goto drop;
}
len = apdu.len;
if (len < sizeof(*resp)) {
reason = 10;
goto drop;
}
resp = (proto_69845_app_req_resp_t*)apdu.ptr;
len -= sizeof(*resp);
switch (resp->type) {
case PROTO_69845_S_APP_SECURITY_RESP:
{
if (len < sizeof(*sec_resp)) {
reason = 11;
goto drop;
}
sec_resp = (proto_69845_app_sec_req_resp_info_t*)resp->data;
len -= sizeof(*sec_resp);
if (iot_sg_ext_69845_security_data_handle(sec_resp, len)) {
reason = 12;
goto drop;
}
break;
}
default:
reason = 13;
goto drop;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
uint32_t iot_sg_ext_read_645_nack_check(uint8_t *req_data,
uint16_t req_len, uint8_t *resp_data, uint16_t resp_len, uint8_t *ext_addr)
{
uint32_t ret = ERR_FAIL;
proto_645_header_t *resp_hdr, *req_hdr;
req_hdr = proto_645_format_check(req_data, req_len, PROTO_645_DIR_MASTER);
resp_hdr = proto_645_format_check(resp_data, resp_len, PROTO_645_DIR_SLAVE);
if (!req_hdr || !resp_hdr) {
goto out;
}
if (!iot_mac_addr_cmp(req_hdr->addr, resp_hdr->addr)) {
goto out;
}
if (!iot_mac_addr_cmp(ext_addr, resp_hdr->addr)) {
goto out;
}
if (resp_hdr->control.ack != PROTO_645_ACK_ABNORMAL) {
goto out;
}
ret = ERR_OK;
out:
return ret;
}
uint8_t iot_sg_ext_get_min_data_len(uint8_t len,
uint8_t fill_len, uint8_t unit_len)
{
uint8_t len_tmp = len;
IOT_ASSERT(unit_len);
len_tmp /= unit_len;
len_tmp *= unit_len;
len_tmp = min(fill_len, len_tmp);
return len_tmp;
}
uint32_t iot_sg_ext_read_645_97_data_handle(uint16_t seq,
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
uint8_t *req_data, uint16_t req_len)
{
uint8_t reason = 0, len;
uint16_t rsp_di;
uint32_t ret = ERR_INVAL;
proto_645_97_a_t *a;
proto_645_97_rp_t *rp;
proto_645_header_t *resp_hdr, *req_hdr;
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;
if (data_type != IOT_SG_STA_DATA_TYPE_645_97) {
reason = 1;
goto drop;
}
if ((req_data == NULL) || !req_len) {
reason = 2;
goto drop;
}
if ((resp_data == NULL) || !resp_len) {
ret = ERR_TIMEOVER;
reason = 3;
goto drop;
}
if (iot_sg_ext_read_645_nack_check(req_data, req_len, resp_data, resp_len,
ext_info->addr) == ERR_OK) {
iot_sg_printf("%s nack\n", __FUNCTION__);
goto nack_handle;
}
if (proto_645_check_di_fn_match(req_data, req_len,
resp_data, resp_len)) {
reason = 4;
goto drop;
}
resp_hdr = (proto_645_header_t*)resp_data;
req_hdr = (proto_645_header_t*)req_data;
if (!iot_mac_addr_cmp(req_hdr->addr, resp_hdr->addr)) {
reason = 5;
goto drop;
}
if ((resp_hdr->control.ack != PROTO_645_ACK_NORMAL)
|| (resp_hdr->control.dir != PROTO_645_DIR_SLAVE)) {
reason = 6;
goto drop;
}
if (!iot_mac_addr_cmp(ext_info->addr, resp_hdr->addr)) {
reason = 7;
goto drop;
}
if (resp_hdr->len < PROTO_645_1997_DI_LEN) {
reason = 8;
goto drop;
}
proto_645_sub33_handle(resp_hdr->data, resp_hdr->len);
rsp_di = proto_645_1997_byte_to_di(resp_hdr->data);
iot_sg_printf("%s resp id %08x\n", __FUNCTION__, rsp_di);
switch (rsp_di) {
case PROTO_645_1997_DI_V_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->v.a)) {
reason = 9;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->v),
sizeof(meter->v.a));
os_mem_cpy(&meter->v, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_I_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*a)) {
reason = 10;
goto drop;
}
a = (proto_645_97_a_t*)&resp_hdr->data[PROTO_645_1997_DI_LEN];
proto_645_i_97_to_07(a->a, meter->a.a);
proto_645_i_97_to_07(a->b, meter->a.b);
proto_645_i_97_to_07(a->c, meter->a.c);
break;
}
case PROTO_645_1997_DI_P_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->ap.total)) {
reason = 11;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->ap),
sizeof(meter->ap.total));
os_mem_cpy(&meter->ap, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_Q_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*rp)) {
reason = 12;
goto drop;
}
rp = (proto_645_97_rp_t*)&resp_hdr->data[PROTO_645_1997_DI_LEN];
proto_645_rp_97_to_07(rp->total, meter->rp.total);
proto_645_rp_97_to_07(rp->a, meter->rp.a);
proto_645_rp_97_to_07(rp->b, meter->rp.b);
proto_645_rp_97_to_07(rp->c, meter->rp.c);
break;
}
case PROTO_645_1997_DI_PF_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->pf.total)) {
reason = 13;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->pf),
sizeof(meter->pf.total));
os_mem_cpy(&meter->pf, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EPT_POS_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->pae.total)) {
reason = 14;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->pae),
sizeof(meter->pae.total));
os_mem_cpy(&meter->pae, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EPT_NEG_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->nae.total)) {
reason = 15;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->nae),
sizeof(meter->nae.total));
os_mem_cpy(&meter->nae, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_POS_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->cre1.total)) {
reason = 16;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre1),
sizeof(meter->cre1.total));
os_mem_cpy(&meter->cre1, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_NEG_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->cre2.total)) {
reason = 17;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre2),
sizeof(meter->cre2.total));
os_mem_cpy(&meter->cre2, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_QRT1_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->re_1st.total)) {
reason = 18;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_1st),
sizeof(meter->re_1st.total));
os_mem_cpy(&meter->re_1st, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_QRT2_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->re_2st.total)) {
reason = 19;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_2st),
sizeof(meter->re_2st.total));
os_mem_cpy(&meter->re_2st, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_QRT3_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->re_3st.total)) {
reason = 20;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_3st),
sizeof(meter->re_3st.total));
os_mem_cpy(&meter->re_3st, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EQT_QRT4_ALL:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->re_4st.total)) {
reason = 21;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_4st),
sizeof(meter->re_4st.total));
os_mem_cpy(&meter->re_4st, &resp_hdr->data[PROTO_645_1997_DI_LEN], len);
break;
}
case PROTO_645_1997_DI_EPT_POS_SUM:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->pae.total)) {
reason = 22;
goto drop;
}
os_mem_cpy(meter->pae.total, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->pae.total));
break;
}
case PROTO_645_1997_DI_EPT_NEG_SUM:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->nae.total)) {
reason = 23;
goto drop;
}
os_mem_cpy(meter->nae.total, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->nae.total));
break;
}
case PROTO_645_1997_DI_V_A:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->v.a)) {
reason = 24;
goto drop;
}
os_mem_cpy(&meter->v.a, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->v.a));
break;
}
case PROTO_645_1997_DI_I_A:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < PROTO_645_97_A_LEN) {
reason = 25;
goto drop;
}
proto_645_i_97_to_07(&resp_hdr->data[PROTO_645_1997_DI_LEN],
meter->a.a);
break;
}
case PROTO_645_1997_DI_PF_A:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->pf.a)) {
reason = 26;
goto drop;
}
os_mem_cpy(&meter->pf.total, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->pf.total));
os_mem_cpy(&meter->pf.a, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->pf.a));
break;
}
case PROTO_645_1997_DI_P_A:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(meter->ap.a)) {
reason = 27;
goto drop;
}
os_mem_cpy(&meter->ap.total, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->ap.total));
os_mem_cpy(&meter->ap.a, &resp_hdr->data[PROTO_645_1997_DI_LEN],
sizeof(meter->ap.a));
break;
}
case PROTO_645_1997_DI_Q_A:
{
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < PROTO_645_97_RP_LEN) {
reason = 28;
goto drop;
}
proto_645_rp_97_to_07(&resp_hdr->data[PROTO_645_1997_DI_LEN],
meter->rp.total);
proto_645_rp_97_to_07(&resp_hdr->data[PROTO_645_1997_DI_LEN],
meter->rp.a);
break;
}
case PROTO_645_1997_DI_TIME_YMD:
{
proto_645_time_ymd_t *ymd;
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*ymd)) {
reason = 29;
goto drop;
}
ymd = (proto_645_time_ymd_t*)&resp_hdr->data[PROTO_645_1997_DI_LEN];
meter->time.year = ymd->year;
meter->time.month = ymd->month;
meter->time.day = ymd->day;
meter->time.week = ymd->week;
break;
}
case PROTO_645_1997_DI_TIME_HMS:
{
proto_645_time_hms_t *hms;
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*hms)) {
reason = 30;
goto drop;
}
hms = (proto_645_time_hms_t*)&resp_hdr->data[PROTO_645_1997_DI_LEN];
meter->time.hour = hms->hour;
meter->time.minute = hms->minute;
meter->time.second = hms->second;
break;
}
case PROTO_645_1997_DI_RS1:
{
proto_645_97_pm_rs_word_t *rs1_word;
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*rs1_word)) {
reason = 31;
goto drop;
}
rs1_word =
(proto_645_97_pm_rs_word_t *)&resp_hdr->data[PROTO_645_1997_DI_LEN];
meter->rs_word.rs_word_1.demand_mode = rs1_word->demand_mode;
meter->rs_word.rs_word_1.clock_battery = rs1_word->clock_battery;
meter->rs_word.rs_word_2.a_ap_dir = rs1_word->act_neg_dir;
meter->rs_word.rs_word_2.a_rp_dir = rs1_word->react_neg_dir;
break;
}
case PROTO_645_1997_DI_RS2:
{
proto_645_97_pg_rs_word_t *rs2_word;
len = resp_hdr->len - PROTO_645_1997_DI_LEN;
if (len < sizeof(*rs2_word)) {
reason = 32;
goto drop;
}
rs2_word =
(proto_645_97_pg_rs_word_t *)&resp_hdr->data[PROTO_645_1997_DI_LEN];
meter->rs_word.rs_word_4.cutoff = rs2_word->a_blackout;
meter->rs_word.rs_word_5.cutoff = rs2_word->b_blackout;
meter->rs_word.rs_word_6.cutoff = rs2_word->c_blackout;
meter->rs_word.rs_word_4.over_v = rs2_word->a_overvoltage;
meter->rs_word.rs_word_5.over_v = rs2_word->b_overvoltage;
meter->rs_word.rs_word_6.over_v = rs2_word->c_overvoltage;
break;
}
default:
reason = 33;
goto drop;
}
nack_handle:
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
static uint32_t iot_sg_ext_harmonic_content_data_handle(uint32_t rsp_di,
proto_645_header_t *resp_hdr)
{
uint8_t reason = 0, len, idx = rsp_di & 0xff, *meter_data = NULL;
uint32_t ret = ERR_INVAL;
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;
switch(rsp_di & 0xffffff00) {
case PROTO_645_2007_DI_VHC_A:
case PROTO_645_2007_DI_VHC_B:
case PROTO_645_2007_DI_VHC_C:
case PROTO_645_2007_DI_IHC_A:
case PROTO_645_2007_DI_IHC_B:
case PROTO_645_2007_DI_IHC_C:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < PROTO_645_HARMONIC_CONT_LEN) {
reason = 1;
goto drop;
}
switch(rsp_di & 0xffffff00) {
case PROTO_645_2007_DI_VHC_A:
{
meter_data = (uint8_t *)&meter->a_v_hc;
break;
}
case PROTO_645_2007_DI_VHC_B:
{
meter_data = (uint8_t *)&meter->b_v_hc;
break;
}
case PROTO_645_2007_DI_VHC_C:
{
meter_data = (uint8_t *)&meter->c_v_hc;
break;
}
case PROTO_645_2007_DI_IHC_A:
{
meter_data = (uint8_t *)&meter->a_i_hc;
break;
}
case PROTO_645_2007_DI_IHC_B:
{
meter_data = (uint8_t *)&meter->b_i_hc;
break;
}
case PROTO_645_2007_DI_IHC_C:
{
meter_data = (uint8_t *)&meter->c_i_hc;
break;
}
default:
goto out;
}
if (!meter_data) {
reason = 2;
goto drop;
}
if (idx == 0xff) {
len = iot_sg_ext_get_min_data_len(len,
sizeof(proto_645_07_harmonic_cont_t),
PROTO_645_HARMONIC_CONT_LEN);
os_mem_cpy(meter_data, &resp_hdr->data[PROTO_645_2007_DI_LEN],
len);
} else if (idx <= PROTO_645_HC_BLOCK_UNIT_CNT) {
if (!idx) {
reason = 3;
goto drop;
}
idx--;
os_mem_cpy(meter_data + (idx * PROTO_645_HARMONIC_CONT_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN],
PROTO_645_HARMONIC_CONT_LEN);
}
break;
}
default:
goto out;
}
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
uint32_t iot_sg_ext_read_645_07_data_handle(uint16_t seq,
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
uint8_t *req_data, uint16_t req_len, uint8_t *is_nack)
{
uint8_t reason = 0, *data, len, idx = 0;
uint32_t rsp_di, ret = ERR_INVAL;
iot_time_tm_t time_t = {0};
proto_645_07_frozen_time_t *froze_time;
proto_645_header_t *resp_hdr, *req_hdr;
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_lc_info_t *lr_info = &ext_info->lc_info;
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
(void)seq;
if (data_type != IOT_SG_STA_DATA_TYPE_645_07) {
reason = 1;
goto drop;
}
if ((req_data == NULL) || !req_len) {
reason = 2;
goto drop;
}
if ((resp_data == NULL) || !resp_len) {
ret = ERR_TIMEOVER;
reason = 3;
goto drop;
}
if (iot_sg_ext_read_645_nack_check(req_data, req_len, resp_data, resp_len,
ext_info->addr) == ERR_OK) {
iot_sg_printf("%s nack\n", __FUNCTION__);
if (is_nack) {
*is_nack = 1;
}
goto nack_handle;
}
if (proto_645_check_di_fn_match(req_data, req_len,
resp_data, resp_len)) {
reason = 4;
goto drop;
}
resp_hdr = (proto_645_header_t*)resp_data;
req_hdr = (proto_645_header_t*)req_data;
if (!iot_mac_addr_cmp(req_hdr->addr, resp_hdr->addr)) {
reason = 5;
goto drop;
}
if ((resp_hdr->control.ack != PROTO_645_ACK_NORMAL)
|| (resp_hdr->control.dir != PROTO_645_DIR_SLAVE)) {
reason = 6;
goto drop;
}
if (!iot_mac_addr_cmp(ext_info->addr, resp_hdr->addr)) {
reason = 7;
goto drop;
}
if (resp_hdr->len < PROTO_645_2007_DI_LEN) {
reason = 8;
goto drop;
}
proto_645_sub33_handle(resp_hdr->data, resp_hdr->len);
rsp_di = proto_645_2007_byte_to_di(resp_hdr->data);
iot_sg_printf("%s resp id %08x\n", __FUNCTION__, rsp_di);
switch (rsp_di) {
case PROTO_645_2007_DI_V_A:
case PROTO_645_2007_DI_V_B:
case PROTO_645_2007_DI_V_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_V_LEN) {
reason = 9;
goto drop;
}
idx = ((rsp_di >> 8) & 0xFF) - 1;
if (idx >= sizeof(meter->v) / sizeof(meter->v.a)) {
reason = 10;
goto drop;
}
os_mem_cpy(meter->v.a + (idx * PROTO_645_V_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_V_LEN);
break;
}
case PROTO_645_2007_DI_I_A:
case PROTO_645_2007_DI_I_B:
case PROTO_645_2007_DI_I_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_A_LEN) {
reason = 11;
goto drop;
}
idx = ((rsp_di >> 8) & 0xFF) - 1;
if (idx >= sizeof(meter->a) / sizeof(meter->a.a)) {
reason = 12;
goto drop;
}
os_mem_cpy(meter->a.a + (idx * PROTO_645_07_A_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_07_A_LEN);
break;
}
case PROTO_645_2007_DI_I_N:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_A_LEN) {
reason = 13;
goto drop;
}
os_mem_cpy(meter->gnd_a, &resp_hdr->data[PROTO_645_2007_DI_LEN],
PROTO_645_07_A_LEN);
break;
}
case PROTO_645_2007_DI_P_T:
case PROTO_645_2007_DI_P_A:
case PROTO_645_2007_DI_P_B:
case PROTO_645_2007_DI_P_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_P_LEN) {
reason = 14;
goto drop;
}
idx = (rsp_di >> 8) & 0xFF;
if (idx > sizeof(meter->ap) / sizeof(meter->ap.total)) {
reason = 15;
goto drop;
}
os_mem_cpy(meter->ap.total + (idx * PROTO_645_07_P_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_07_P_LEN);
break;
}
case PROTO_645_2007_DI_Q_T:
case PROTO_645_2007_DI_Q_A:
case PROTO_645_2007_DI_Q_B:
case PROTO_645_2007_DI_Q_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_P_LEN) {
reason = 16;
goto drop;
}
idx = (rsp_di >> 8) & 0xFF;
if (idx > sizeof(meter->rp) / sizeof(meter->rp.total)) {
reason = 17;
goto drop;
}
os_mem_cpy(meter->rp.total + (idx * PROTO_645_07_P_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_07_P_LEN);
break;
}
case PROTO_645_2007_DI_S_T:
case PROTO_645_2007_DI_S_A:
case PROTO_645_2007_DI_S_B:
case PROTO_645_2007_DI_S_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_P_LEN) {
reason = 18;
goto drop;
}
idx = (rsp_di >> 8) & 0xFF;
if (idx > sizeof(meter->atp) / sizeof(meter->atp.total)) {
reason = 18;
goto drop;
}
os_mem_cpy(meter->atp.total + (idx * PROTO_645_07_P_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_07_P_LEN);
break;
}
case PROTO_645_2007_DI_PF_T:
case PROTO_645_2007_DI_PF_A:
case PROTO_645_2007_DI_PF_B:
case PROTO_645_2007_DI_PF_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) < PROTO_645_07_PF_LEN) {
reason = 19;
goto drop;
}
idx = (rsp_di >> 8) & 0xFF;
if (idx > sizeof(meter->pf) / sizeof(meter->pf.total)) {
reason = 20;
goto drop;
}
os_mem_cpy(meter->pf.total + (idx * PROTO_645_07_PF_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_07_PF_LEN);
break;
}
case PROTO_645_2007_DI_PA_A:
case PROTO_645_2007_DI_PA_B:
case PROTO_645_2007_DI_PA_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
PROTO_645_PHASE_ANGLE_LEN) {
reason = 21;
goto drop;
}
idx = ((rsp_di >> 8) & 0xFF) - 1;
if (idx >= sizeof(meter->phase_angle) / sizeof(meter->phase_angle.a)) {
reason = 22;
goto drop;
}
os_mem_cpy(meter->phase_angle.a + (idx * PROTO_645_PHASE_ANGLE_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_PHASE_ANGLE_LEN);
break;
}
case PROTO_645_2007_DI_VW_A:
case PROTO_645_2007_DI_VW_B:
case PROTO_645_2007_DI_VW_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
PROTO_645_WAVEFORM_DIS_LEN) {
reason = 23;
goto drop;
}
idx = ((rsp_di >> 8) & 0xFF) - 1;
if (idx >=
sizeof(meter->v_waveform_dis) / sizeof(meter->v_waveform_dis.a)) {
reason = 24;
goto drop;
}
os_mem_cpy(meter->v_waveform_dis.a + (idx * PROTO_645_WAVEFORM_DIS_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_WAVEFORM_DIS_LEN);
break;
}
case PROTO_645_2007_DI_IW_A:
case PROTO_645_2007_DI_IW_B:
case PROTO_645_2007_DI_IW_C:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
PROTO_645_WAVEFORM_DIS_LEN) {
reason = 25;
goto drop;
}
idx = ((rsp_di >> 8) & 0xFF) - 1;
if (idx >=
sizeof(meter->i_waveform_dis) / sizeof(meter->i_waveform_dis.a)) {
reason = 26;
goto drop;
}
os_mem_cpy(meter->i_waveform_dis.a + (idx * PROTO_645_WAVEFORM_DIS_LEN),
&resp_hdr->data[PROTO_645_2007_DI_LEN], PROTO_645_WAVEFORM_DIS_LEN);
break;
}
case PROTO_645_2007_DI_EPT_POS_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->pae.total)) {
reason = 27;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->pae),
sizeof(meter->pae.total));
os_mem_cpy(&meter->pae, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EPT_NEG_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->nae.total)) {
reason = 28;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->nae),
sizeof(meter->nae.total));
os_mem_cpy(&meter->nae, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_V_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->v.a)) {
reason = 29;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->v),
sizeof(meter->v.a));
os_mem_cpy(&meter->v, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_I_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->a.a)) {
reason = 30;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->a),
sizeof(meter->a.a));
os_mem_cpy(&meter->a, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_P_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->ap.total)) {
reason = 31;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->ap),
sizeof(meter->ap.total));
os_mem_cpy(&meter->ap, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_Q_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rp.total)) {
reason = 32;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->rp),
sizeof(meter->rp.total));
os_mem_cpy(&meter->rp, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_S_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->atp.total)) {
reason = 33;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->atp),
sizeof(meter->atp.total));
os_mem_cpy(&meter->atp, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_PF_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->pf.total)) {
reason = 35;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->pf),
sizeof(meter->pf.total));
os_mem_cpy(&meter->pf, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_PA_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->phase_angle.a)) {
reason = 36;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->phase_angle),
sizeof(meter->phase_angle.a));
os_mem_cpy(&meter->phase_angle, &resp_hdr->data[PROTO_645_2007_DI_LEN],
len);
break;
}
case PROTO_645_2007_DI_VW_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->v_waveform_dis.a)) {
reason = 37;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->v_waveform_dis),
sizeof(meter->v_waveform_dis.a));
os_mem_cpy(&meter->v_waveform_dis,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_IW_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->i_waveform_dis.a)) {
reason = 38;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->i_waveform_dis),
sizeof(meter->i_waveform_dis.a));
os_mem_cpy(&meter->i_waveform_dis,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EPT_COMP_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->cae.total)) {
reason = 39;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cae),
sizeof(meter->cae.total));
os_mem_cpy(&meter->cae, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EPT_POS_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->pae.total)) {
reason = 40;
goto drop;
}
os_mem_cpy(meter->pae.total, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->pae.total));
break;
}
case PROTO_645_2007_DI_EPT_NEG_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->nae.total)) {
reason = 41;
goto drop;
}
os_mem_cpy(meter->nae.total, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->nae.total));
break;
}
case PROTO_645_2007_DI_EQT_POS_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->cre1.total)) {
reason = 42;
goto drop;
}
os_mem_cpy(meter->cre1.total, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->cre1.total));
break;
}
case PROTO_645_2007_DI_EQT_NEG_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->cre2.total)) {
reason = 43;
goto drop;
}
os_mem_cpy(meter->cre2.total, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->cre2.total));
break;
}
case PROTO_645_2007_DI_EQT_QRT1_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->re_1st.total)) {
reason = 44;
goto drop;
}
os_mem_cpy(meter->re_1st.total,
&resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->re_1st.total));
break;
}
case PROTO_645_2007_DI_EQT_QRT2_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->re_2st.total)) {
reason = 45;
goto drop;
}
os_mem_cpy(meter->re_2st.total,
&resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->re_2st.total));
break;
}
case PROTO_645_2007_DI_EQT_QRT3_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->re_3st.total)) {
reason = 46;
goto drop;
}
os_mem_cpy(meter->re_3st.total,
&resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->re_3st.total));
break;
}
case PROTO_645_2007_DI_EQT_QRT4_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->re_4st.total)) {
reason = 47;
goto drop;
}
os_mem_cpy(meter->re_4st.total,
&resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->re_4st.total));
break;
}
case PROTO_645_2007_DI_EPT_DEMAND:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->ept_demand)) {
reason = 48;
goto drop;
}
os_mem_cpy(meter->ept_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->ept_demand));
break;
}
case PROTO_645_2007_DI_EQT_DEMAND:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->eqt_demand)) {
reason = 49;
goto drop;
}
os_mem_cpy(meter->eqt_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->eqt_demand));
break;
}
case PROTO_645_2007_DI_DF_POS_ACT_DEM_TIME_LAST1:
case PROTO_645_2007_DI_EPT_POS_DEMAND:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->pos_ap_demand)) {
reason = 50;
goto drop;
}
os_mem_cpy(&meter->pos_ap_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->pos_ap_demand));
break;
}
case PROTO_645_2007_DI_DF_NEG_ACT_DEM_TIME_LAST1:
case PROTO_645_2007_DI_EPT_NEG_DEMAND:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->neg_ap_demand)) {
reason = 51;
goto drop;
}
os_mem_cpy(&meter->neg_ap_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->neg_ap_demand));
break;
}
case PROTO_645_2007_DI_EPT_COMP_SUM:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->cae.total)) {
reason = 52;
goto drop;
}
os_mem_cpy(meter->cae.total, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->cae.total));
break;
}
case PROTO_645_2007_DI_RT_YMDHMS_LAST1:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(proto_645_07_frozen_time_t)) {
reason = 53;
goto drop;
}
if (!ext_info->lc_info.last_froze_tm.tm_year
&& !ext_info->lc_info.last_froze_tm.tm_mon
&& !ext_info->lc_info.last_froze_tm.tm_mday
&& !ext_info->lc_info.last_froze_tm.tm_hour
&& !ext_info->lc_info.last_froze_tm.tm_min
&& !ext_info->lc_info.last_froze_tm.tm_sec) {
reason = 54;
goto drop;
}
froze_time = (proto_645_07_frozen_time_t*)&resp_hdr->data[
PROTO_645_2007_DI_LEN];
time_t.tm_year = iot_bcd_to_byte(froze_time->year) + 2000;
time_t.tm_mon = iot_bcd_to_byte(froze_time->month);
time_t.tm_mday = iot_bcd_to_byte(froze_time->day);
time_t.tm_hour = iot_bcd_to_byte(froze_time->hour);
time_t.tm_min = iot_bcd_to_byte(froze_time->minute);
if (IOT_ABS(iot_rtc_delta_calc(&time_t, &lr_info->last_froze_tm))
> IOT_SG_STA_EXT_LC_CFG_PRD_15MIN) {
/* if there is too much difference between the last freezing
* time and the freezing record time, sta don't read frozen data.
* sta read current data
*/
lr_info->timeout_cnt = 0;
lr_info->repeat_cnt = 0;
reason = 55;
goto drop;
}
break;
}
case PROTO_645_2007_DI_DF_EP_POS_LAST1:
case PROTO_645_2007_DI_RT_EP_POS_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->pae.total)) {
reason = 56;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->pae),
sizeof(meter->pae.total));
os_mem_cpy(&meter->pae, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_EP_NEG_LAST1:
case PROTO_645_2007_DI_RT_EP_NEG_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->nae.total)) {
reason = 57;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->nae),
sizeof(meter->nae.total));
os_mem_cpy(&meter->nae, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_VARIABLE_LAST1:
case PROTO_645_2007_DI_RT_VARIABLE_LAST1:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
(sizeof(meter->ap) + sizeof(meter->rp))) {
reason = 58;
goto drop;
}
data = &resp_hdr->data[PROTO_645_2007_DI_LEN];
os_mem_cpy(&meter->ap, data, sizeof(meter->ap));
data += sizeof(meter->ap);
os_mem_cpy(&meter->rp, data, sizeof(meter->rp));
break;
}
case PROTO_645_2007_DI_DF_EQ_POS_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->cre1.total)) {
reason = 59;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre1),
sizeof(meter->cre1.total));
os_mem_cpy(&meter->cre1, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_EQ_NEG_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->cre2.total)) {
reason = 60;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre2),
sizeof(meter->cre2.total));
os_mem_cpy(&meter->cre2, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_RE_1ST_POWER_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_1st.total)) {
reason = 61;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_1st),
sizeof(meter->re_1st.total));
os_mem_cpy(&meter->re_1st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_RE_2ST_POWER_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_2st.total)) {
reason = 62;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_2st),
sizeof(meter->re_2st.total));
os_mem_cpy(&meter->re_2st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_RE_3ST_POWER_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_3st.total)) {
reason = 63;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_3st),
sizeof(meter->re_3st.total));
os_mem_cpy(&meter->re_3st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_DF_RE_4ST_POWER_LAST1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_4st.total)) {
reason = 64;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_4st),
sizeof(meter->re_4st.total));
os_mem_cpy(&meter->re_4st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_COM_RE1_DEM_TIME_ALL:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->cre1_demand)) {
reason = 65;
goto drop;
}
os_mem_cpy(&meter->cre1_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->cre1_demand));
break;
}
case PROTO_645_2007_DI_COM_RE2_DEM_TIME_ALL:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->cre2_demand)) {
reason = 66;
goto drop;
}
os_mem_cpy(&meter->cre2_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->cre2_demand));
break;
}
case PROTO_645_2007_DI_DF_YMDHMS_LAST1:
{
if ((resp_hdr->len - PROTO_645_2007_DI_LEN) <
sizeof(meter->frozen_time)) {
reason = 67;
goto drop;
}
os_mem_cpy(&meter->frozen_time, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->frozen_time));
break;
}
case PROTO_645_2007_DI_EQT_QRT1_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_1st.total)) {
reason = 68;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_1st),
sizeof(meter->re_1st.total));
os_mem_cpy(&meter->re_1st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EQT_QRT2_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_2st.total)) {
reason = 69;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_2st),
sizeof(meter->re_2st.total));
os_mem_cpy(&meter->re_2st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EQT_QRT3_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_3st.total)) {
reason = 70;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_3st),
sizeof(meter->re_3st.total));
os_mem_cpy(&meter->re_3st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EQT_QRT4_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->re_4st.total)) {
reason = 71;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->re_4st),
sizeof(meter->re_4st.total));
os_mem_cpy(&meter->re_4st, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EQT_POS_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->cre1.total)) {
reason = 72;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre1),
sizeof(meter->cre1.total));
os_mem_cpy(&meter->cre1, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_EQT_NEG_ALL:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->cre2.total)) {
reason = 74;
goto drop;
}
len = iot_sg_ext_get_min_data_len(len, sizeof(meter->cre2),
sizeof(meter->cre2.total));
os_mem_cpy(&meter->cre2, &resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_TIME:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->time)) {
reason = 74;
goto drop;
}
os_mem_cpy(&meter->time, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->time));
break;
}
case PROTO_645_2007_DI_TIME_YMD:
{
proto_645_time_ymd_t *ymd;
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(*ymd)) {
reason = 75;
goto drop;
}
ymd = (proto_645_time_ymd_t*)&resp_hdr->data[PROTO_645_2007_DI_LEN];
meter->time.year = ymd->year;
meter->time.month = ymd->month;
meter->time.day = ymd->day;
meter->time.week = ymd->week;
break;
}
case PROTO_645_2007_DI_TIME_HMS:
{
proto_645_time_hms_t *hms;
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(*hms)) {
reason = 76;
goto drop;
}
hms = (proto_645_time_hms_t*)&resp_hdr->data[PROTO_645_2007_DI_LEN];
meter->time.hour = hms->hour;
meter->time.minute = hms->minute;
meter->time.second = hms->second;
break;
}
case PROTO_645_2007_RUN_STATE_WORD_1:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_1)) {
reason = 77;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_1,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_2:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_2)) {
reason = 78;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_2,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_3:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_3)) {
reason = 79;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_3,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_4:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_4)) {
reason = 80;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_4,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_5:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_5)) {
reason = 81;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_5,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_6:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_6)) {
reason = 82;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_6,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_RUN_STATE_WORD_7:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->rs_word.rs_word_7)) {
reason = 83;
goto drop;
}
os_mem_cpy(&meter->rs_word.rs_word_7,
&resp_hdr->data[PROTO_645_2007_DI_LEN], len);
break;
}
case PROTO_645_2007_DI_FREQ:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->freq.bcd)) {
reason = 84;
goto drop;
}
os_mem_cpy(meter->freq.bcd, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->freq.bcd));
break;
}
case PROTO_645_2007_DI_1MIN_AVG_P:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->average_p)) {
reason = 85;
goto drop;
}
os_mem_cpy(meter->average_p, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->average_p));
break;
}
case PROTO_645_2007_DI_AT_DEMAND:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->at_demand)) {
reason = 86;
goto drop;
}
os_mem_cpy(meter->at_demand, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->at_demand));
break;
}
case PROTO_645_2007_DI_TEMP:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->temperature)) {
reason = 87;
goto drop;
}
os_mem_cpy(meter->temperature, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->temperature));
break;
}
case PROTO_645_2007_CLOCK_BATTERY_V:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->clock_battery_v)) {
reason = 88;
goto drop;
}
os_mem_cpy(meter->clock_battery_v,
&resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->clock_battery_v));
break;
}
case PROTO_645_2007_MR_BATTERY_V:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->mr_battery_v)) {
reason = 89;
goto drop;
}
os_mem_cpy(meter->mr_battery_v,
&resp_hdr->data[PROTO_645_2007_DI_LEN], sizeof(meter->mr_battery_v));
break;
}
case PROTO_645_2007_INTER_BATTERY_TIME:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < sizeof(meter->work_time)) {
reason = 90;
goto drop;
}
os_mem_cpy(meter->work_time, &resp_hdr->data[PROTO_645_2007_DI_LEN],
sizeof(meter->work_time));
break;
}
case PROTO_645_2007_DI_EPT_POS_A:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < PROTO_645_07_ENERGY_DATA_LEN) {
reason = 91;
goto drop;
}
os_mem_cpy(meter->pos_a, &resp_hdr->data[PROTO_645_2007_DI_LEN],
PROTO_645_07_ENERGY_DATA_LEN);
break;
}
case PROTO_645_2007_DI_EPT_POS_B:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < PROTO_645_07_ENERGY_DATA_LEN) {
reason = 92;
goto drop;
}
os_mem_cpy(meter->pos_b, &resp_hdr->data[PROTO_645_2007_DI_LEN],
PROTO_645_07_ENERGY_DATA_LEN);
break;
}
case PROTO_645_2007_DI_EPT_POS_C:
{
len = resp_hdr->len - PROTO_645_2007_DI_LEN;
if (len < PROTO_645_07_ENERGY_DATA_LEN) {
reason = 93;
goto drop;
}
os_mem_cpy(meter->pos_c, &resp_hdr->data[PROTO_645_2007_DI_LEN],
PROTO_645_07_ENERGY_DATA_LEN);
break;
}
default:
if (iot_sg_ext_harmonic_content_data_handle(rsp_di,
resp_hdr) != ERR_OK) {
reason = 94;
goto drop;
}
break;
}
nack_handle:
ret = ERR_OK;
goto out;
drop:
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
out:
return ret;
}
void iot_sg_ext_read_data_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;
if (data_type == IOT_SG_STA_DATA_TYPE_69845) {
ret = iot_sg_ext_read_698_data_handle(seq, data_type, resp_data,
resp_len, req_data, req_len);
} 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_645_07_data_handle(seq, data_type, resp_data,
resp_len, req_data, req_len, NULL);
}
if (ret == ERR_OK || ret == ERR_TIMEOVER) {
if (ret == ERR_OK) {
ext_info->lc_info.flag_resp = 1;
}
ext_info->lc_info.timeout_cnt = 0;
iot_sg_sta_ext_sm_stop_action();
iot_sg_sta_ext_sm_next_action(IOT_SG_STA_EXT_SM_MIN_DELAY);
}
}
iot_time_tm_t iot_sg_ext_get_next_lr_ts(iot_time_tm_t start_ts,
uint16_t period, iot_time_tm_t curr_tm)
{
int64_t delta_time, interval = (int64_t)period;
iot_time_tm_t tm = curr_tm, tm_start = start_ts;
delta_time = iot_rtc_delta_calc(&tm_start, &tm);
delta_time %= interval;
delta_time = interval - delta_time;
iot_rtc_delta_add(delta_time, &tm);
return tm;
}
void iot_sg_sta_ext_sm_func(void)
{
uint8_t all_done = 1;
iot_sg_sta_node_desc_t *node = NULL;
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
IOT_ASSERT(ext_info->ext_init);
if (iot_mac_addr_valid(ext_info->addr)) {
node = iot_sg_sta_node_find_by_addr(ext_info->addr);
}
if (node == NULL) {
iot_sg_sta_ext_next_meter(ext_info->addr);
return;
}
if (node->lr_en && !iot_sg_ext_lr_func(node->entry.addr) && all_done) {
all_done = 0;
}
if (node->clct_task_en && !iot_sg_sta_ext_clct_func(node->entry.addr)
&& all_done) {
all_done = 0;
}
if (node->ss_en && !iot_sg_ext_state_score(node->entry.addr) && all_done) {
all_done = 0;
}
if (node->data_clct_en && !iot_sg_ext_data_clct_func(node->entry.addr)
&& all_done) {
all_done = 0;
}
if (node->data_freeze_en && !iot_sg_ext_data_freeze_func(node->entry.addr)
&& all_done) {
all_done = 0;
}
if (node->nw_lc_en && !iot_sg_sta_ext_nw_lc_func(node->entry.addr)
&& all_done) {
all_done = 0;
}
if (node->nli_en && !iot_sg_sta_ext_nli_func(node->entry.addr)
&& all_done) {
all_done = 0;
}
if (node->gw_clclt_en &&
!iot_sg_sta_ext_gw_data_freeze_func(node->entry.addr) && all_done) {
all_done = 0;
}
if (node->ec_en && !iot_sg_ext_ec_func(node->entry.addr) && all_done) {
all_done = 0;
}
if (all_done) {
iot_sg_sta_ext_next_meter(node->entry.addr);
} else {
iot_sg_sta_ext_sm_next_action(IOT_SG_STA_EXT_SM_DELAY);
}
}
uint32_t iot_sg_sta_ext_meter_add(iot_sg_sta_node_desc_t *node)
{
uint8_t user_type = iot_sg_sta_get_user_type();
uint32_t ret = ERR_OK;
if (iot_sg_sta_ext_init()) {
goto no_supp;
}
switch (user_type) {
case USER_TYPE_SOUTHEN_POWER_GRID_GX:
{
if (node->lr_en) {
goto out;
}
if (node->is_three_phase || node->supp_lr
|| node->data_type != IOT_SG_STA_DATA_TYPE_645_07) {
goto no_supp;
}
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_GX_CFG);
if (ret) {
goto no_supp;
}
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 1;
break;
}
case USER_TYPE_STATE_GRID_XIAN:
{
if (!node->nli_en && !node->is_three_phase) {
node->nli_en = 1;
node->nli_detected = 0;
}
if (IOT_SMART_GRID_GW_V28_ENABLE) {
if (!node->gw_clclt_en) {
if (node->data_type != IOT_SG_STA_DATA_TYPE_645_07 &&
node->data_type != IOT_SG_STA_DATA_TYPE_69845) {
if (!node->nli_en) {
goto no_supp;
}
} else {
os_mem_set(&node->ext.gw_node_clct_info, 0,
sizeof(node->ext.gw_node_clct_info));
node->gw_clclt_en = 1;
}
}
} else {
if (!node->lr_en && node->data_type == IOT_SG_STA_DATA_TYPE_645_07) {
if (node->is_three_phase) {
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_XIAN_3P_CFG);
} else {
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_XIAN_CFG);
}
if (ret) {
if (!node->nli_en) {
goto no_supp;
}
} else {
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 1;
}
}
}
break;
}
case USER_TYPE_STATE_GRID_HEBEI:
case USER_TYPE_STATE_GRID_HUNAN:
case USER_TYPE_STATE_GRID_MENGDONG_LC:
{
if (node->lr_en) {
goto out;
}
if (user_type == USER_TYPE_STATE_GRID_HUNAN ||
user_type == USER_TYPE_STATE_GRID_MENGDONG_LC) {
if (node->data_type != IOT_SG_STA_DATA_TYPE_645_07 &&
node->data_type != IOT_SG_STA_DATA_TYPE_69845) {
goto no_supp;
}
} else {
if (node->data_type != IOT_SG_STA_DATA_TYPE_645_07) {
goto no_supp;
}
}
if (node->is_three_phase) {
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_XIAN_3P_CFG);
} else {
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_XIAN_CFG);
}
if (ret) {
goto no_supp;
}
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 1;
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGDONG:
{
if (node->clct_task_en) {
goto out;
}
if ((node->data_type != IOT_SG_STA_DATA_TYPE_645_97)
&& (node->data_type != IOT_SG_STA_DATA_TYPE_645_07)) {
goto no_supp;
}
node->clct_task_en = 1;
iot_sg_sta_ext_clct_task_init(node->entry.addr, &node->ext.clct_info);
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGZHOU:
{
if (node->ss_en) {
goto out;
}
node->ss_en = 1;
break;
}
case USER_TYPE_BRM_PEIWANG:
{
if (node->lr_en) {
goto out;
}
switch (node->data_type) {
case IOT_SG_STA_DATA_TYPE_69845:
{
if (!node->time_abnormal) {
goto no_supp;
}
break;
}
case IOT_SG_STA_DATA_TYPE_645_07:
{
if (node->supp_lr && !node->time_abnormal
&& !node->lr_rec_abnormal) {
goto no_supp;
}
break;
}
case IOT_SG_STA_DATA_TYPE_645_97:
{
if (!node->lr_rec_abnormal) {
goto no_supp;
}
break;
}
default:
goto no_supp;
break;
}
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_PEIWANG);
if (ret) {
goto no_supp;
}
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 1;
break;
}
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
{
if (node->lr_en) {
goto out;
}
ret = iot_sg_ext_lr_init(IOT_SG_STA_EXT_LC_PEIWANG);
if (ret) {
goto no_supp;
}
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 1;
break;
}
case USER_TYPE_STATE_GRID_JIANGSU:
{
if (node->data_clct_en) {
goto out;
}
node->data_clct_en = 1;
node->clct_last_df = 1;
os_mem_set(&node->ext.data_clct_info, 0,
sizeof(node->ext.data_clct_info));
iot_sg_sta_data_clct_task_init();
break;
}
case USER_TYPE_STATE_GRID_FUJIAN:
{
if (node->data_freeze_en) {
goto out;
}
if (node->data_type == IOT_SG_STA_DATA_TYPE_645_07 ||
node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
node->data_freeze_en = 1;
os_mem_set(&node->ext.freeze_info, 0, sizeof(node->ext.freeze_info));
} else {
goto no_supp;
}
break;
}
default:
if (iot_sg_sta_get_proto_type() == IOT_SG_STA_APP_PROTO_NW) {
if (node->nw_lc_en && node->ec_en) {
goto out;
}
if (node->data_type != IOT_SG_STA_DATA_TYPE_645_07) {
goto no_supp;
}
node->ec_en = 1;
node->nw_lc_en = 1;
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
iot_sg_sta_ext_ec_node_data_reset(node);
break;
} else {
goto no_supp;
}
}
ret = iot_sg_sta_flash_meter_add(node->entry.addr);
if (ret != ERR_OK) {
goto no_supp;
}
if (!iot_sg_sta_ext_sm_run_check()) {
iot_sg_sta_ext_sm_start(node->entry.addr, 0);
}
iot_sg_printf("%s add pm addr %02x:%02x:%02x:%02x:%02x:%02x user type %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], user_type);
goto out;
no_supp:
node->lr_en = 0;
node->clct_task_en = 0;
node->ss_en = 0;
node->data_clct_en = 0;
node->data_freeze_en = 0;
node->nw_lc_en = 0;
ret = ERR_NOSUPP;
out:
return ret;
}
uint32_t iot_sg_sta_ext_meter_delete(iot_sg_sta_node_desc_t *node)
{
uint32_t ret = ERR_OK;
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
if (!ext_info->ext_init) {
goto no_supp;
}
switch (iot_sg_sta_get_user_type()) {
case USER_TYPE_BRM_PEIWANG:
case USER_TYPE_SOUTHEN_POWER_GRID_GX:
case USER_TYPE_STATE_GRID_XIAN:
case USER_TYPE_STATE_GRID_HEBEI:
case USER_TYPE_STATE_GRID_HUNAN:
case USER_TYPE_STATE_GRID_MENGDONG_LC:
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
{
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
node->lr_en = 0;
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGDONG:
{
node->clct_task_en = 0;
os_mem_set(&node->ext.clct_info, 0, sizeof(node->ext.clct_info));
break;
}
case USER_TYPE_SOUTHEN_POWER_GRID_GUANGZHOU:
{
node->ss_en = 0;
break;
}
case USER_TYPE_STATE_GRID_JIANGSU:
{
node->data_clct_en = 0;
os_mem_set(&node->ext.data_clct_info, 0,
sizeof(node->ext.data_clct_info));
break;
}
case USER_TYPE_STATE_GRID_FUJIAN:
{
node->data_freeze_en = 0;
os_mem_set(&node->ext.freeze_info, 0, sizeof(node->ext.freeze_info));
break;
}
default:
if (iot_sg_sta_get_proto_type() == IOT_SG_STA_APP_PROTO_NW) {
node->lr_en = 0;
node->ec_en = 0;
os_mem_set(&node->ext.lr_info, 0, sizeof(node->ext.lr_info));
iot_sg_sta_ext_ec_node_data_reset(node);
break;
} else {
goto no_supp;
}
}
if (iot_sg_sta_ext_sm_meter_check(node->entry.addr)) {
iot_sg_sta_ext_next_meter(node->entry.addr);
}
goto out;
no_supp:
ret = ERR_NOSUPP;
out:
return ret;
}
uint32_t iot_sg_sta_ext_init(void)
{
uint8_t dev_type, reason = 0, user_type = iot_sg_sta_get_user_type();
uint32_t ret = ERR_OK;
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
BUILD_BUG_ON(PROTO_645_V_LEN == IOT_SG_STA_METER_V_LEN);
BUILD_BUG_ON(PROTO_645_07_A_LEN == IOT_SG_STA_METER_A_LEN);
if (ext_info->ext_dis) {
goto out;
}
if (ext_info->ext_init) {
goto out;
}
if (user_type != USER_TYPE_SOUTHEN_POWER_GRID_GX
&& user_type != USER_TYPE_STATE_GRID_XIAN
&& user_type != USER_TYPE_STATE_GRID_HEBEI
&& user_type != USER_TYPE_STATE_GRID_HUNAN
&& user_type != USER_TYPE_SOUTHEN_POWER_GRID_GUANGDONG
&& user_type != USER_TYPE_SOUTHEN_POWER_GRID_GUANGZHOU
&& user_type != USER_TYPE_BRM_PEIWANG
&& user_type != USER_TYPE_STATE_GRID_JIANGSU
&& user_type != USER_TYPE_BRM_PEIWANG_DUAL_NET
&& user_type != USER_TYPE_STATE_GRID_FUJIAN
&& user_type != USER_TYPE_BRM_SMALL_LOAD_GOLDEN
&& user_type != USER_TYPE_STATE_GRID_MENGDONG_LC
&& sta_glb->proto != IOT_SG_STA_APP_PROTO_NW) {
if (!sta_glb->pib.ro) {
reason = 1;
ret = ERR_FAIL;
goto drop;
}
if (!sta_glb->pib.ro->cfg.fr.en_ext_func) {
reason = 2;
ret = ERR_FAIL;
goto drop;
}
}
if (!sta_glb->drv) {
reason = 3;
ret = ERR_FAIL;
goto drop;
}
dev_type = (uint8_t)sta_glb->drv->get_device_type();
switch (dev_type) {
case IOT_SG_STA_DEV_TYPE_COLLECTOR_T2:
{
if (user_type != USER_TYPE_SOUTHEN_POWER_GRID_GX &&
user_type != USER_TYPE_SOUTHEN_POWER_GRID_GUANGZHOU &&
user_type != USER_TYPE_STATE_GRID_JIANGSU &&
user_type != USER_TYPE_BRM_PEIWANG_DUAL_NET &&
sta_glb->proto != IOT_SG_STA_APP_PROTO_NW) {
reason = 4;
ret = ERR_FAIL;
goto drop;
}
break;
}
case IOT_SG_STA_DEV_TYPE_COLLECTOR_T1:
{
if (sta_glb->proto == IOT_SG_STA_APP_PROTO_NW) {
break;
} else {
reason = 5;
ret = ERR_FAIL;
goto drop;
}
}
case IOT_SG_STA_DEV_TYPE_COLLECTOR_T3:
case IOT_SG_STA_DEV_TYPE_POWER_METER:
default:
break;
}
if (iot_sg_sta_flash_cfg_init()) {
reason = 6;
ret = ERR_FAIL;
goto drop;
}
iot_sg_sta_br2_record_init();
if (iot_sg_sta_flash_init()) {
reason = 7;
ret = ERR_FAIL;
goto drop;
}
if (user_type == USER_TYPE_STATE_GRID_FUJIAN) {
if (iot_sg_sta_ext_freeze_task_init()) {
reason = 8;
ret = ERR_FAIL;
goto drop;
}
}
if (IOT_SMART_GRID_EXT_AI_FUNC_ENABLE &&
user_type == USER_TYPE_STATE_GRID_XIAN) {
if (iot_sg_sta_ext_ai_module_init()) {
reason = 9;
ret = ERR_FAIL;
goto drop;
}
}
if (IOT_SMART_GRID_GW_V28_ENABLE) {
if (iot_sg_sta_ext_gw_clct_task_init()) {
reason = 10;
ret = ERR_FAIL;
goto drop;
}
}
if (IOT_SMART_GRID_EDGE_COMPUTING_ENABLE &&
sta_glb->proto == IOT_SG_STA_APP_PROTO_NW) {
if (iot_sg_sta_ext_ec_init()) {
reason = 11;
ret = ERR_FAIL;
goto drop;
}
}
os_mem_set(ext_info->addr, 0, sizeof(ext_info->addr));
os_mem_set(&ext_info->meter_data, 0xff, sizeof(ext_info->meter_data));
os_mem_set(&ext_info->lc_info, 0, sizeof(ext_info->lc_info));
os_mem_set(&ext_info->clct_param, 0, sizeof(ext_info->clct_param));
os_mem_set(&ext_info->task_clct_info, 0, sizeof(ext_info->task_clct_info));
os_mem_set(&ext_info->lc_info_nw, 0, sizeof(ext_info->lc_info_nw));
os_mem_set(&ext_info->nli_info, 0, sizeof(ext_info->nli_info));
ext_info->ext_init = 1;
iot_sg_printf("%s\n", __FUNCTION__);
goto out;
drop:
iot_sg_printf("%s err %lu, user type %lu\n", __FUNCTION__, reason,
user_type);
out:
return ret;
}
void iot_sg_sta_ext_deinit(void)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
if (ext_info->ext_init) {
iot_sg_sta_ext_freeze_task_deinit();
iot_sg_sta_ext_ai_module_deinit();
iot_sg_sta_ext_nli_reset();
iot_sg_sta_ext_gw_data_clct_task_deinit();
iot_sg_sta_ext_sm_stop();
iot_sg_sta_ext_ec_deinit();
ext_info->ext_init = 0;
iot_sg_printf("%s\n", __FUNCTION__);
}
}
void iot_sg_sta_ext_disable(void)
{
iot_sg_sta_ext_info_t *ext_info = &p_sg_glb->desc.sta->ext_info;
iot_sg_sta_ext_deinit();
ext_info->ext_dis = 1;
}
#endif /* IOT_SMART_GRID_EXT_FUNC_ENABLE */