2879 lines
97 KiB
C
2879 lines
97 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 includes */
|
|
#include "os_utils_api.h"
|
|
|
|
/* iot common header files */
|
|
#include "iot_io_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_version_api.h"
|
|
#include "iot_bitmap_api.h"
|
|
|
|
/* smart grid internal header files */
|
|
#include "iot_sg.h"
|
|
#include "proto_crc16.h"
|
|
#include "iot_sg_sta_tsfm.h"
|
|
#include "iot_sg_sta_ext.h"
|
|
#include "iot_sg_sta_ext_comm.h"
|
|
#include "iot_sg_ext_sta_api.h"
|
|
#include "proto_nw_app.h"
|
|
#include "proto_645.h"
|
|
#include "proto_645_fj.h"
|
|
#include "iot_sg_sta_upgrade.h"
|
|
#include "iot_board_api.h"
|
|
|
|
#if (IOT_SMART_GRID_EXT_FUNC_ENABLE && IOT_GW_APP_ENABLE)
|
|
|
|
/* define meter invalid data unit max len */
|
|
#define IOT_SG_STA_EXT_METER_INVALID_DATA_LEN (4)
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_module_func_for_645(uint8_t *addr,
|
|
uint8_t fn, uint32_t di, uint8_t *data, uint8_t len)
|
|
{
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
|
|
(void)fn;
|
|
(void)len;
|
|
iot_sg_printf("%s user_type %lu\n", __FUNCTION__, user_type);
|
|
switch (user_type) {
|
|
case USER_TYPE_SOUTHEN_POWER_GRID_GX:
|
|
{
|
|
if (di == PROTO_645_2007_DI_CR_V_A) {
|
|
resp_pkt = iot_sg_sta_ext_load_record_gx_func(addr, di, data);
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_XIAN:
|
|
if (di == PROTO_645_2007_DI_AI_TOPO_START
|
|
|| di == PROTO_645_2007_DI_AI_TOPO_QUERY
|
|
|| di == PROTO_645_2007_DI_AI_LL_START
|
|
|| di == PROTO_645_2007_DI_AI_LL_QUERY) {
|
|
resp_pkt = iot_sg_sta_ext_ai_rsp_handle(addr, di, data, len);
|
|
} else {
|
|
resp_pkt = iot_sg_sta_ext_load_record_xian_func(addr, di, data);
|
|
}
|
|
break;
|
|
case USER_TYPE_STATE_GRID_HEBEI:
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_load_record_xian_func(addr, di, data);
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG:
|
|
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
|
|
{
|
|
if (di == PROTO_645_2007_DI_CR_ALL_BY_TIME) {
|
|
resp_pkt = iot_sg_sta_ext_load_record_pw_func_1(addr, di, data);
|
|
} else {
|
|
resp_pkt = iot_sg_sta_ext_load_record_pw_func(addr, di, data);
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_func(addr, fn, di, data, len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
iot_sg_printf("%s ret %s\n", __FUNCTION__, (resp_pkt ? "success" : "fail"));
|
|
return resp_pkt;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_judge_module_func_for_645(
|
|
proto_645_header_t *hdr_645)
|
|
{
|
|
uint8_t extended = 0;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_node_desc_t *node = NULL;
|
|
gw_app_header_t *hdr;
|
|
|
|
node = iot_sg_sta_node_find_by_addr(hdr_645->addr);
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_XIAN:
|
|
{
|
|
if (hdr_645->control.fn == PROTO_645_2007_FN_AI_XIAN) {
|
|
if (sta_glb->proto == IOT_SG_STA_APP_PROTO_GW) {
|
|
hdr = (gw_app_header_t *)iot_pkt_block_ptr(sta_glb->req.pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
if (hdr->id != GW_APP_ID_CONCENTRATOR_METER_R
|
|
&& hdr->id != GW_APP_ID_CONCENTRATOR_P_METER_R) {
|
|
goto out;
|
|
}
|
|
extended = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C) {
|
|
goto out;
|
|
}
|
|
if (sta_glb->proto == IOT_SG_STA_APP_PROTO_GW) {
|
|
hdr = (gw_app_header_t *)iot_pkt_block_ptr(sta_glb->req.pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
if (hdr->id != GW_APP_ID_HISTORY_DATA_READ) {
|
|
goto out;
|
|
}
|
|
}
|
|
if (sta_glb->ext_info.clct_param.enabled) {
|
|
extended = 1;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_HEBEI:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C) {
|
|
goto out;
|
|
}
|
|
if (hdr_645->len != PROTO_645_READ_LR_CURVE_DATA_LEN) {
|
|
goto out;
|
|
}
|
|
if (node) {
|
|
extended = 1;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_SOUTHEN_POWER_GRID_GX:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C) {
|
|
goto out;
|
|
}
|
|
if (hdr_645->len != PROTO_645_READ_LR_CURVE_DATA_LEN) {
|
|
goto out;
|
|
}
|
|
if (node && !node->supp_lr && !node->is_three_phase) {
|
|
extended = 1;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C) {
|
|
goto out;
|
|
}
|
|
if (hdr_645->len != PROTO_645_READ_LR_CURVE_DATA_LEN) {
|
|
goto out;
|
|
}
|
|
if (node && node->lr_en) {
|
|
extended = 1;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C) {
|
|
goto out;
|
|
}
|
|
if (hdr_645->len != PROTO_645_READ_LR_CURVE_DATA_LEN) {
|
|
goto out;
|
|
}
|
|
if (node && ((node->data_type == IOT_SG_STA_DATA_TYPE_645_07)
|
|
|| (node->data_type == IOT_SG_STA_DATA_TYPE_645_97))) {
|
|
extended = 1;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_WRITE_DATA) {
|
|
goto out;
|
|
}
|
|
extended = 1;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return extended;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_module_645_addr_check(uint8_t *addr, uint8_t fn)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
if ((fn == PROTO_645_2007_FN_WRITE_DATA)
|
|
&& iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
}
|
|
default:
|
|
if (iot_sg_sta_node_find_by_addr(addr)) {
|
|
ret = ERR_OK;
|
|
}
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_module_645_handle(uint8_t data_type,
|
|
iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data;
|
|
uint32_t len, ret = ERR_OK, di;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_645_header_t *hdr_645;
|
|
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
if (iot_sg_sta_get_user_type() == USER_TYPE_STATE_GRID_FUJIAN) {
|
|
hdr_645 = proto_645_format_check_ext(data, len, PROTO_645_DIR_MASTER);
|
|
} else {
|
|
hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
|
|
}
|
|
if (!hdr_645) {
|
|
ret = ERR_NOSUPP;
|
|
goto out;
|
|
}
|
|
if (!iot_sg_sta_ext_judge_module_func_for_645(hdr_645)) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (iot_sg_sta_ext_module_645_addr_check(hdr_645->addr,
|
|
hdr_645->control.fn)) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
ret = proto_645_get_di_by_sub33(hdr_645->data, hdr_645->len,
|
|
PROTO_645_2007_ID, &di);
|
|
if (ret) {
|
|
goto out;
|
|
}
|
|
resp_pkt = iot_sg_sta_ext_module_func_for_645(hdr_645->addr,
|
|
hdr_645->control.fn, di, hdr_645->data, hdr_645->len);
|
|
if (resp_pkt) {
|
|
iot_sg_sta_meter_read_done_framework(data_type, resp_pkt);
|
|
ret = ERR_OK;
|
|
} else {
|
|
ret = ERR_INVAL;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_module_corr_645_handle(iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data, user_type = iot_sg_sta_get_user_type();
|
|
uint32_t len, ret = ERR_OK, di;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_645_header_t *hdr_645;
|
|
|
|
if (user_type != USER_TYPE_STATE_GRID_FUJIAN
|
|
&& user_type != USER_TYPE_STATE_GRID_XIAN) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
|
|
if (!hdr_645) {
|
|
ret = ERR_NOSUPP;
|
|
goto out;
|
|
}
|
|
if (!iot_mac_addr_cmp(hdr_645->addr, proto_645_bcast_addr)
|
|
&& !iot_sg_sta_node_find_by_addr(hdr_645->addr)) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (user_type == USER_TYPE_STATE_GRID_FUJIAN) {
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_READ_DATA_C
|
|
&& hdr_645->control.fn != PROTO_645_2007_FN_WRITE_DATA) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
} else if (user_type == USER_TYPE_STATE_GRID_XIAN) {
|
|
if (hdr_645->control.fn != PROTO_645_2007_FN_AI_XIAN) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
} else {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
ret = proto_645_get_di_by_sub33(hdr_645->data, hdr_645->len,
|
|
PROTO_645_2007_ID, &di);
|
|
if (ret) {
|
|
goto out;
|
|
}
|
|
resp_pkt = iot_sg_sta_ext_module_func_for_645(hdr_645->addr,
|
|
hdr_645->control.fn, di, hdr_645->data, hdr_645->len);
|
|
if (resp_pkt) {
|
|
iot_pkt_free(resp_pkt);
|
|
} else {
|
|
ret = ERR_FAIL;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_judge_module_func_for_698(
|
|
proto_69845_frame_head_info_t *hdr_698)
|
|
{
|
|
uint8_t extended = 0, *ser_addr;
|
|
iot_sg_sta_node_desc_t *node = NULL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
gw_app_header_t *hdr;
|
|
|
|
ser_addr = proto_69845_get_ser_addr(hdr_698);
|
|
node = iot_sg_sta_node_find_by_addr(ser_addr);
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
if (sta_glb->proto == IOT_SG_STA_APP_PROTO_GW) {
|
|
hdr = (gw_app_header_t *)iot_pkt_block_ptr(sta_glb->req.pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
if (hdr->id != GW_APP_ID_HISTORY_DATA_READ) {
|
|
goto out;
|
|
}
|
|
}
|
|
if (sta_glb->ext_info.clct_param.enabled) {
|
|
extended = 1;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
extended = 1;
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG:
|
|
{
|
|
if (node && (node->data_type == IOT_SG_STA_DATA_TYPE_69845)
|
|
&& node->time_abnormal) {
|
|
extended = 1;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
|
|
{
|
|
if (node && (node->data_type == IOT_SG_STA_DATA_TYPE_69845)) {
|
|
extended = 1;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (!extended && sta_glb->br2_enable) {
|
|
extended = 1;
|
|
}
|
|
out:
|
|
return extended;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_module_698_addr_check(server_addr_info_t *ser_info,
|
|
uint8_t *flag_trans)
|
|
{
|
|
uint8_t dev_addr[IOT_MAC_ADDR_LEN] = {0};
|
|
uint32_t ret = ERR_FAIL, dev_type;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
if (!sta_glb->drv) {
|
|
goto out;
|
|
}
|
|
dev_type = sta_glb->drv->get_device_type();
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
switch (dev_type) {
|
|
case IOT_SG_STA_DEV_TYPE_POWER_METER:
|
|
case IOT_SG_STA_DEV_TYPE_COLLECTOR_T2:
|
|
{
|
|
if (ser_info->logical_addr != PROTO_69845_JS_LOGICAL_ADDR) {
|
|
goto out;
|
|
}
|
|
sta_glb->drv->get_device_addr(dev_addr);
|
|
if (!iot_sg_sta_node_find_by_addr(ser_info->addr)
|
|
&& !iot_mac_addr_cmp(dev_addr, ser_info->addr)) {
|
|
*flag_trans = 0;
|
|
goto out;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
if (iot_mac_addr_cmp(ser_info->addr, proto_645_bcast_addr)
|
|
|| ((ser_info->type == PROTO_69845_SA_TYPE_BROADCAST)
|
|
&& (ser_info->addr[0] == PROTO_69845_SA_BROADCAST_ADD))) {
|
|
ret = ERR_OK;
|
|
} else if (iot_sg_sta_node_find_by_addr(ser_info->addr)) {
|
|
ret = ERR_OK;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
if (iot_sg_sta_node_find_by_addr(ser_info->addr)) {
|
|
ret = ERR_OK;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG:
|
|
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
|
|
{
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (sta_glb->br2_enable) {
|
|
if (ser_info->logical_addr != PROTO_69845_ZJ_LOGICAL_ADDR) {
|
|
goto out;
|
|
}
|
|
*flag_trans = 0;
|
|
sta_glb->drv->get_device_addr(dev_addr);
|
|
if (!iot_sg_sta_node_find_by_addr(ser_info->addr)
|
|
&& !iot_mac_addr_cmp(dev_addr, ser_info->addr)) {
|
|
goto out;
|
|
}
|
|
ret = ERR_OK;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_handle_br2_record_query(
|
|
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
|
|
proto_69845_app_oad_t *oad)
|
|
{
|
|
uint8_t *data, i, reason, addr_len, idx;
|
|
iot_pkt_t *pkt = NULL;
|
|
uint16_t head_len, tail_len;
|
|
uint32_t total_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_get_resp_t *get_resp;
|
|
proto_69845_app_get_resp_normal_t *normal_resp;
|
|
proto_69845_app_ele_data_t *record_hdr;
|
|
proto_69845_br2_launch_record_uint_t *record_uint;
|
|
iot_sg_sta_tsfm_topo_time_uint_t *launch_time;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_topo_info_t *topo_info = &sta_glb->hw_tsfm_info.tsfm_topo_info;
|
|
iot_sg_sta_tsfm_topo_record_t *record = &topo_info->send_record;
|
|
|
|
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(*record_hdr) + sizeof(*record_uint) * record->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 =0;
|
|
normal_resp->result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
record_hdr = (proto_69845_app_ele_data_t*)normal_resp->result;
|
|
record_hdr->data_type = PROTO_69845_APP_DATA_ARRAY;
|
|
record_hdr->num_of_data = record->cnt;
|
|
data = data + sizeof(*app_resp) + sizeof(*get_resp) +sizeof(*normal_resp)
|
|
+ sizeof(*record_hdr);
|
|
idx = record->idx;
|
|
for (i = 0; i < record->cnt; i++) {
|
|
idx--;
|
|
if (idx >= IOT_SG_STA_TSFM_TOPO_RECORD_CNT_MAX) {
|
|
idx = IOT_SG_STA_TSFM_TOPO_RECORD_CNT_MAX - 1;
|
|
}
|
|
launch_time = &record->list[idx];
|
|
record_uint = (proto_69845_br2_launch_record_uint_t*)data;
|
|
record_uint->type = PROTO_69845_APP_DATA_STRUCTURE;
|
|
record_uint->cnt = 2;
|
|
record_uint->data0_type = PROTO_69845_APP_DATA_TIME_S;
|
|
iot_uint16_to_bytes(launch_time->start_tm.tm_year,
|
|
(uint8_t*)&record_uint->start.year, 1);
|
|
record_uint->start.month = launch_time->start_tm.tm_mon;
|
|
record_uint->start.day = launch_time->start_tm.tm_mday;
|
|
record_uint->start.hour = launch_time->start_tm.tm_hour;
|
|
record_uint->start.minute = launch_time->start_tm.tm_min;
|
|
record_uint->start.second = launch_time->start_tm.tm_sec;
|
|
record_uint->data1_type = PROTO_69845_APP_DATA_TIME_S;
|
|
iot_uint16_to_bytes(launch_time->end_tm.tm_year,
|
|
(uint8_t*)&record_uint->end.year, 1);
|
|
record_uint->end.month = launch_time->end_tm.tm_mon;
|
|
record_uint->end.day = launch_time->end_tm.tm_mday;
|
|
record_uint->end.hour = launch_time->end_tm.tm_hour;
|
|
record_uint->end.minute = launch_time->end_tm.tm_min;
|
|
record_uint->end.second = launch_time->end_tm.tm_sec;
|
|
data += sizeof(*record_uint);
|
|
}
|
|
/* 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 iot_pkt_t *iot_sg_sta_ext_get_normal_resp_zj(
|
|
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_BR2_LAUNCH_RECORD:
|
|
{
|
|
if (oad->attribute_id != PROTO_OI_BR2_LAUNCH_RECORD_ATT_RECORD) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
pkt = iot_sg_sta_ext_handle_br2_record_query(hdr_698, piid, oad);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_normal_resp(
|
|
proto_69845_frame_head_info_t *hdr_698, proto_69845_app_piid_t *piid,
|
|
proto_69845_app_oad_t *oad)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
pkt = iot_sg_sta_ext_get_normal_resp_js(hdr_698, piid, oad);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (!pkt && sta_glb->br2_enable) {
|
|
pkt = iot_sg_sta_ext_get_normal_resp_zj(hdr_698, piid, oad);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_get_normal_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *ptr = data;
|
|
proto_69845_app_oad_t oad = {0};
|
|
proto_69845_app_get_req_normal_t *get_hdr;
|
|
|
|
if (data_len < sizeof(*get_hdr)) {
|
|
iot_sg_printf("%s err\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
get_hdr = (proto_69845_app_get_req_normal_t*)ptr;
|
|
oad.oi = proto_69845_byte_to_oi((uint8_t*)&get_hdr->oad.oi);
|
|
oad.element_index = get_hdr->oad.element_index;
|
|
oad.attribute_id = get_hdr->oad.attribute_id;
|
|
oad.attribute_char = get_hdr->oad.attribute_char;
|
|
pkt = iot_sg_sta_ext_get_normal_resp(hdr_698, &get_hdr->piid, &oad);
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_normal_list_analysis(
|
|
uint8_t *data, uint32_t data_len, uint8_t omd_cnt,
|
|
proto_69845_get_normal_list_desc_t *action_desc)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t *ptr = data, i;
|
|
uint32_t len = data_len;
|
|
proto_69845_app_oad_t *oad_ptr;
|
|
|
|
for (i = 0; i < omd_cnt; i++) {
|
|
if (len < sizeof(*oad_ptr)) {
|
|
goto out;
|
|
}
|
|
oad_ptr = (proto_69845_app_oad_t*)ptr;
|
|
action_desc->list[i].oad.oi = proto_69845_byte_to_oi(
|
|
(uint8_t*)&oad_ptr->oi);
|
|
action_desc->list[i].oad.attribute_id = oad_ptr->attribute_id;
|
|
action_desc->list[i].oad.attribute_char = oad_ptr->attribute_char;
|
|
action_desc->list[i].oad.element_index = oad_ptr->element_index;
|
|
ptr += sizeof(*oad_ptr);
|
|
len -= sizeof(*oad_ptr);
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_normal_list_resp(
|
|
proto_69845_frame_head_info_t *hdr_698,
|
|
proto_69845_get_normal_list_desc_t *cache_list)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
(void)hdr_698;
|
|
(void)cache_list;
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
pkt = iot_sg_sta_ext_get_normal_list_resp_js(hdr_698, cache_list);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_get_normal_list_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
uint8_t *ptr = data, reason = 0;
|
|
uint32_t len = data_len, buff_len;
|
|
proto_69845_app_get_req_normal_list_t *get_list_hdr;
|
|
proto_69845_get_normal_list_desc_t *cache_list;
|
|
|
|
if (len < sizeof(*get_list_hdr)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
get_list_hdr = (proto_69845_app_get_req_normal_list_t*)data;
|
|
ptr += sizeof(*get_list_hdr);
|
|
len -= sizeof(*get_list_hdr);
|
|
if (!get_list_hdr->oad_cnt) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
buff_len = sizeof(proto_69845_get_normal_unit_desc_t) *
|
|
get_list_hdr->oad_cnt;
|
|
buff_len += sizeof(*cache_list);
|
|
pkt_buff = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
cache_list = (proto_69845_get_normal_list_desc_t*)iot_pkt_put(pkt_buff,
|
|
buff_len);
|
|
cache_list->piid = get_list_hdr->piid;
|
|
cache_list->cnt = get_list_hdr->oad_cnt;
|
|
if (iot_sg_sta_ext_normal_list_analysis(ptr, len,
|
|
cache_list->cnt, cache_list)) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
pkt = iot_sg_sta_ext_get_normal_list_resp(hdr_698, cache_list);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_min_frozen_oad_sig_data_fill(uint32_t load_len,
|
|
uint8_t *result_data, uint8_t data_type, uint8_t *meter_data,
|
|
uint8_t meter_data_len)
|
|
{
|
|
proto_69845_app_data_t *app_data;
|
|
uint8_t invalid_data[IOT_SG_STA_EXT_METER_INVALID_DATA_LEN] =
|
|
{0xFF, 0xFF, 0xFF, 0xFF};
|
|
uint16_t temp_16, unit_len = 0;
|
|
uint32_t temp_32;
|
|
|
|
if (meter_data_len > IOT_SG_STA_EXT_METER_INVALID_DATA_LEN) {
|
|
goto err;
|
|
}
|
|
unit_len += sizeof(*app_data);
|
|
if (unit_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
if (os_mem_cmp(meter_data, invalid_data, meter_data_len)) {
|
|
if (data_type == PROTO_69845_APP_DATA_LONG_UNSIGNED ||
|
|
data_type == PROTO_69845_APP_DATA_LONG) {
|
|
unit_len += PROTO_69845_METER_DATA_LONG_LEN;
|
|
if (unit_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data->data_type = data_type;
|
|
temp_16 = (uint16_t)proto_645_bcd_to_integer(meter_data,
|
|
meter_data_len, 0);
|
|
iot_uint16_to_bytes(temp_16, app_data->data, 1);
|
|
} else if (data_type == PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED ||
|
|
data_type == PROTO_69845_APP_DATA_DOUBLE_LONG) {
|
|
unit_len += PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
if (unit_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data->data_type = data_type;
|
|
temp_32 = proto_645_bcd_to_integer(meter_data,
|
|
meter_data_len, 1);
|
|
iot_uint32_to_bytes(temp_32, app_data->data, 1);
|
|
} else {
|
|
goto err;
|
|
}
|
|
} else {
|
|
app_data->data_type = PROTO_69845_APP_DATA_NULL;
|
|
}
|
|
goto out;
|
|
err:
|
|
unit_len = 0;
|
|
out:
|
|
return unit_len;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_min_frozen_oad_data_fill(uint32_t load_len,
|
|
uint8_t *result_data, uint8_t data_type, uint8_t ele_cnt,
|
|
uint8_t *meter_data, uint8_t meter_data_len, uint8_t sig_flag)
|
|
{
|
|
proto_69845_app_data_t *app_data;
|
|
proto_69845_app_ele_data_t *ele_data;
|
|
uint8_t invalid_data[IOT_SG_STA_EXT_METER_INVALID_DATA_LEN] =
|
|
{0xFF, 0xFF, 0xFF, 0xFF}, data_valid = 0, i;
|
|
uint16_t unit_len = 0, unit_len_tmp;
|
|
|
|
if (meter_data_len > IOT_SG_STA_EXT_METER_INVALID_DATA_LEN) {
|
|
goto err;
|
|
}
|
|
if (sig_flag) {
|
|
unit_len = iot_sg_sta_ext_min_frozen_oad_sig_data_fill(load_len,
|
|
result_data, data_type, meter_data, meter_data_len);
|
|
} else {
|
|
for (i = 0; i < ele_cnt; i++) {
|
|
if (os_mem_cmp(meter_data + (meter_data_len * i),
|
|
invalid_data, meter_data_len)) {
|
|
data_valid = 1;
|
|
}
|
|
}
|
|
if (data_valid) {
|
|
unit_len += sizeof(*ele_data);
|
|
if (unit_len > load_len) {
|
|
goto err;
|
|
}
|
|
load_len -= unit_len;
|
|
ele_data = (proto_69845_app_ele_data_t *)result_data;
|
|
ele_data->data_type = PROTO_69845_APP_DATA_ARRAY;
|
|
ele_data->num_of_data = ele_cnt;
|
|
result_data += sizeof(*ele_data);
|
|
for (i = 0; i < ele_cnt; i++) {
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_sig_data_fill(
|
|
load_len, result_data, data_type, meter_data,
|
|
meter_data_len);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
goto err;
|
|
}
|
|
meter_data += meter_data_len;
|
|
load_len -= unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
}
|
|
} else {
|
|
unit_len += sizeof(*app_data);
|
|
if (unit_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_NULL;
|
|
result_data += sizeof(app_data);
|
|
}
|
|
}
|
|
goto out;
|
|
err:
|
|
unit_len = 0;
|
|
out:
|
|
return unit_len;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
iot_time_tm_t *start_tm, uint16_t cur_cnt, uint16_t uint_cnt,
|
|
proto_69845_app_data_rcsd_t *rcsd, uint8_t *unit_data,
|
|
iot_sg_meter_lc_uint_xian_data_t *lc_cache, uint32_t load_len,
|
|
uint8_t valid_flag, uint8_t *addr, int64_t inter)
|
|
{
|
|
uint32_t oad;
|
|
uint16_t unit_len = 0, unit_len_tmp;
|
|
uint8_t i, *req_data, *temp_data, cnt, meter_data_len;
|
|
uint8_t *result_data = unit_data, ele_cnt, reason = 0, sig_flag = 0;
|
|
proto_69845_app_data_csd_t *csd;
|
|
proto_69845_app_data_t *app_data;
|
|
proto_69845_app_data_time_s_t *data_time;
|
|
iot_sg_sta_node_desc_t *node = NULL;
|
|
iot_time_tm_t tm_temp = { 0 };
|
|
|
|
node = iot_sg_sta_node_find_by_addr(addr);
|
|
if (!node) {
|
|
reason = 1;
|
|
goto err;
|
|
}
|
|
req_data = rcsd->csd_list;
|
|
for (cnt = 0; cnt < uint_cnt; cnt++) {
|
|
for (i = 0; i < rcsd->cnt; i++) {
|
|
csd = (proto_69845_app_data_csd_t*)(req_data +
|
|
(sizeof(*csd) + sizeof(oad)) * i);
|
|
if (csd->type != PROTO_OI_CSD_TYPE_OAD) {
|
|
/* Road-style selection descriptors are not currently supported */
|
|
reason = 2;
|
|
goto err;
|
|
}
|
|
oad = iot_bytes_to_uint32((uint8_t*)csd->csd_data, 1);
|
|
if (!valid_flag && oad != PROTO_69845_APP_OAD_FROZEN_T) {
|
|
reason = 3;
|
|
goto null_data;
|
|
}
|
|
sig_flag = 0;
|
|
ele_cnt = 0;
|
|
meter_data_len = 0;
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_P_T:
|
|
case PROTO_69845_APP_OAD_P_A:
|
|
{
|
|
sig_flag = 1;
|
|
ele_cnt = 1;
|
|
meter_data_len = PROTO_645_07_P_LEN;
|
|
if (sizeof(lc_cache->active_power) < meter_data_len * ele_cnt) {
|
|
reason = 4;
|
|
goto err;
|
|
}
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_P_T:
|
|
{
|
|
temp_data = lc_cache->active_power.total;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_P_A:
|
|
{
|
|
temp_data = lc_cache->active_power.a;
|
|
break;
|
|
}
|
|
default:
|
|
reason = 5;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG, ele_cnt,
|
|
temp_data, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 6;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_GND_CURRENT:
|
|
{
|
|
sig_flag = 1;
|
|
ele_cnt = 1;
|
|
meter_data_len = PROTO_645_07_A_LEN;
|
|
if (sizeof(lc_cache->n) < meter_data_len * ele_cnt) {
|
|
reason = 7;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG,
|
|
ele_cnt, lc_cache->n, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 8;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_VOLTAGE_A:
|
|
{
|
|
sig_flag = 1;
|
|
}
|
|
case PROTO_69845_APP_OAD_VOLTAGE:
|
|
{
|
|
if (node->is_three_phase) {
|
|
ele_cnt = IOT_PLC_PHASE_CNT;
|
|
} else {
|
|
ele_cnt = 1;
|
|
}
|
|
meter_data_len = PROTO_645_V_LEN;
|
|
if (sizeof(lc_cache->v) < meter_data_len * ele_cnt) {
|
|
reason = 9;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_LONG_UNSIGNED, ele_cnt,
|
|
lc_cache->v.a, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 10;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_CURRENT_A:
|
|
{
|
|
sig_flag = 1;
|
|
}
|
|
case PROTO_69845_APP_OAD_CURRENT:
|
|
{
|
|
if (node->is_three_phase) {
|
|
ele_cnt = IOT_PLC_PHASE_CNT;
|
|
} else {
|
|
ele_cnt = 1;
|
|
}
|
|
meter_data_len = PROTO_645_07_A_LEN;
|
|
if (sizeof(lc_cache->i) < meter_data_len * ele_cnt) {
|
|
reason = 11;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG,
|
|
ele_cnt, lc_cache->i.a, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 12;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_P:
|
|
{
|
|
if (node->is_three_phase) {
|
|
ele_cnt = IOT_PLC_PHASE_CNT + 1;
|
|
} else {
|
|
ele_cnt = 2;
|
|
}
|
|
meter_data_len = PROTO_645_07_P_LEN;
|
|
if (sizeof(lc_cache->active_power) < meter_data_len * ele_cnt) {
|
|
reason = 13;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG,
|
|
ele_cnt, lc_cache->active_power.total,
|
|
meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 14;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
|
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
|
{
|
|
sig_flag = 1;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_NEG:
|
|
case PROTO_69845_APP_OAD_EPT_POS:
|
|
{
|
|
switch(oad) {
|
|
case PROTO_69845_APP_OAD_EPT_POS:
|
|
{
|
|
temp_data = lc_cache->fda_power.total;
|
|
ele_cnt = sizeof(proto_645_07_energy_data_t) /
|
|
PROTO_645_07_ENERGY_DATA_LEN;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_NEG:
|
|
{
|
|
temp_data = lc_cache->bda_power.total;
|
|
ele_cnt = sizeof(proto_645_07_energy_data_t) /
|
|
PROTO_645_07_ENERGY_DATA_LEN;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
|
{
|
|
temp_data = lc_cache->fda_power.total;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
|
{
|
|
temp_data = lc_cache->bda_power.total;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
default:
|
|
reason = 15;
|
|
goto err;
|
|
}
|
|
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
|
if (sizeof(proto_645_07_energy_data_t) <
|
|
meter_data_len * ele_cnt) {
|
|
reason = 16;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED,
|
|
ele_cnt, temp_data, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 17;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_FROZEN_T:
|
|
{
|
|
if (sizeof(*app_data) + sizeof(*data_time) > load_len) {
|
|
reason = 18;
|
|
goto err;
|
|
}
|
|
tm_temp = *start_tm;
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_TIME_S;
|
|
data_time = (proto_69845_app_data_time_s_t*)app_data->data;
|
|
iot_rtc_delta_add((inter * (cur_cnt + cnt)), &tm_temp);
|
|
iot_uint16_to_bytes(tm_temp.tm_year,
|
|
(uint8_t*)&data_time->year, 1);
|
|
data_time->month = tm_temp.tm_mon;
|
|
data_time->day = tm_temp.tm_mday;
|
|
data_time->hour = tm_temp.tm_hour;
|
|
data_time->minute = tm_temp.tm_min;
|
|
load_len -= sizeof(*app_data) + sizeof(*data_time);
|
|
unit_len += sizeof(*app_data) + sizeof(*data_time);
|
|
result_data += sizeof(*app_data) + sizeof(*data_time);
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_Q_T:
|
|
case PROTO_69845_APP_OAD_Q_A:
|
|
{
|
|
sig_flag = 1;
|
|
}
|
|
case PROTO_69845_APP_OAD_Q:
|
|
{
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_Q_T:
|
|
{
|
|
temp_data = lc_cache->reactive_power.total;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_Q_A:
|
|
{
|
|
temp_data = lc_cache->reactive_power.a;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_Q:
|
|
{
|
|
temp_data = lc_cache->reactive_power.total;
|
|
if (node->is_three_phase) {
|
|
ele_cnt = IOT_PLC_PHASE_CNT + 1;
|
|
} else {
|
|
ele_cnt = 2;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
reason = 19;
|
|
goto err;
|
|
}
|
|
meter_data_len = PROTO_645_07_P_LEN;
|
|
if (sizeof(lc_cache->reactive_power) <
|
|
meter_data_len * ele_cnt) {
|
|
reason = 20;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_DOUBLE_LONG,
|
|
ele_cnt, temp_data, meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 21;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_PF_T:
|
|
case PROTO_69845_APP_OAD_PF_A:
|
|
{
|
|
sig_flag = 1;
|
|
}
|
|
case PROTO_69845_APP_OAD_PF:
|
|
{
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_PF_T:
|
|
{
|
|
temp_data = lc_cache->power_factor.total;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_PF_A:
|
|
{
|
|
temp_data = lc_cache->power_factor.a;
|
|
ele_cnt = 1;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_PF:
|
|
{
|
|
temp_data = lc_cache->power_factor.total;
|
|
if (node->is_three_phase) {
|
|
ele_cnt = IOT_PLC_PHASE_CNT + 1;
|
|
} else {
|
|
ele_cnt = 2;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
reason = 22;
|
|
goto err;
|
|
}
|
|
meter_data_len = PROTO_645_07_PF_LEN;
|
|
if (sizeof(lc_cache->power_factor) <
|
|
meter_data_len * ele_cnt) {
|
|
reason = 23;
|
|
goto err;
|
|
}
|
|
unit_len_tmp = iot_sg_sta_ext_min_frozen_oad_data_fill(load_len,
|
|
result_data, PROTO_69845_APP_DATA_LONG, ele_cnt, temp_data,
|
|
meter_data_len, sig_flag);
|
|
if (!unit_len_tmp || unit_len_tmp > load_len) {
|
|
reason = 24;
|
|
goto err;
|
|
}
|
|
load_len -= unit_len_tmp;
|
|
unit_len += unit_len_tmp;
|
|
result_data += unit_len_tmp;
|
|
break;
|
|
}
|
|
default:
|
|
null_data:
|
|
if (sizeof(*app_data) > load_len) {
|
|
unit_len = 0;
|
|
reason = 25;
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_NULL;
|
|
load_len -= sizeof(*app_data);
|
|
unit_len += sizeof(*app_data);
|
|
result_data += sizeof(*app_data);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
goto out;
|
|
err:
|
|
unit_len = 0;
|
|
out:
|
|
iot_sg_printf("%s reason %d\n", __FUNCTION__, reason);
|
|
return unit_len;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_fill_min_frozen_resp_data(int64_t inter,
|
|
proto_69845_app_data_rcsd_t *rcsd, uint8_t *data,uint32_t load_len,
|
|
iot_time_tm_t *start_time, iot_time_tm_t *end_time, uint8_t *addr)
|
|
{
|
|
int64_t delta;
|
|
uint16_t index[2] = { 0 }, index_tmp, n, write_cnt = 0;
|
|
uint16_t write_data_len = 0, delta_cnt, unit_len, max_cnt;
|
|
uint32_t ret, load_total_len = load_len;
|
|
uint8_t *result_data = NULL, reason = 0;
|
|
uint8_t i, unit_cnt, flag_up[2] = { 0 };
|
|
uint8_t start_idx = 0, end_idx = 1, first_point = 0;
|
|
proto_69845_app_get_result_t *result_head;
|
|
proto_69845_app_rpt_array_result_t *array_result;
|
|
iot_sg_meter_lc_uint_xian_data_t *lc_cache;
|
|
iot_time_tm_t tm[2] = { 0 }, tm_old = { 0 }, tm_new = { 0 };
|
|
iot_pkt_t *pkt_buff = NULL;
|
|
|
|
if (!rcsd || !data || !load_len ||!addr) {
|
|
reason = 1;
|
|
goto err;
|
|
}
|
|
if (iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_XIAN_LC, &unit_len, &max_cnt)) {
|
|
reason = 2;
|
|
goto err;
|
|
}
|
|
pkt_buff = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 3;
|
|
goto err;
|
|
}
|
|
lc_cache = (iot_sg_meter_lc_uint_xian_data_t *)iot_pkt_put(pkt_buff,
|
|
unit_len);
|
|
if (load_len < (sizeof(*result_head) + sizeof(*array_result))) {
|
|
reason = 4;
|
|
goto err;
|
|
}
|
|
load_len -= sizeof(*result_head) + sizeof(*array_result);
|
|
result_head = (proto_69845_app_get_result_t*)data;
|
|
result_head->result_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
array_result = (proto_69845_app_rpt_array_result_t*)result_head->result;
|
|
delta = iot_rtc_delta_calc(start_time, end_time);
|
|
if (delta < 0) {
|
|
reason = 5;
|
|
goto err;
|
|
}
|
|
if ((delta / inter) + 1 > 0xff) {
|
|
unit_cnt = 0xff;
|
|
} else {
|
|
unit_cnt = (uint8_t)(delta / inter + 1);
|
|
}
|
|
array_result->array_len = unit_cnt;
|
|
result_data = array_result->data;
|
|
tm[start_idx] = *start_time;
|
|
tm[end_idx] = *end_time;
|
|
flag_up[start_idx] = 0;
|
|
flag_up[end_idx] = 1;
|
|
ret = iot_sg_sta_flash_unit_data_find_by_multiple_time(addr,
|
|
index, tm, 2, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC, flag_up);
|
|
if (ret != ERR_OK || index[start_idx] == 0xffff ||
|
|
index[end_idx] == 0xffff) {
|
|
reason = 6;
|
|
goto err;
|
|
}
|
|
if (index[end_idx] >= index[start_idx]) {
|
|
n = index[end_idx] - index[start_idx] + 1;
|
|
} else {
|
|
n = max_cnt - (index[start_idx] - index[end_idx]) + 1;
|
|
}
|
|
os_mem_cpy(&tm_new, start_time, sizeof(tm_new));
|
|
index_tmp = index[start_idx];
|
|
for (i = 0; i < n; i++) {
|
|
if (write_cnt == unit_cnt) {
|
|
break;
|
|
}
|
|
ret = iot_sg_sta_flash_unit_data_read(addr, index_tmp,
|
|
(uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC);
|
|
if (ret == ERR_OK) {
|
|
tm_old = tm_new;
|
|
tm_new.tm_year = (uint16_t)lc_cache->year + 2000;
|
|
tm_new.tm_mon = (uint8_t)lc_cache->month;
|
|
tm_new.tm_mday = (uint8_t)lc_cache->day;
|
|
tm_new.tm_hour = (uint8_t)lc_cache->hour;
|
|
tm_new.tm_min = (uint8_t)lc_cache->minute;
|
|
delta = iot_rtc_delta_calc(&tm_old, &tm_new);
|
|
if (delta >= (inter * max_cnt)) {
|
|
delta_cnt = max_cnt;
|
|
} else {
|
|
delta_cnt = (uint16_t)(delta / inter);
|
|
if (delta % inter) {
|
|
/* if it's not the whole point, find the next point */
|
|
os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
|
|
goto done;
|
|
}
|
|
}
|
|
if (!first_point) {
|
|
first_point = 1;
|
|
if (!delta_cnt) {
|
|
goto write;
|
|
} else {
|
|
if (delta_cnt >= unit_cnt) {
|
|
write_data_len =
|
|
iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
start_time, write_cnt, unit_cnt, rcsd, result_data,
|
|
lc_cache, load_len, 0, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 7;
|
|
goto err;
|
|
}
|
|
write_cnt = unit_cnt;
|
|
load_len -= write_data_len;
|
|
break;
|
|
}
|
|
/* delta_cnt contains the first invalid point */
|
|
write_data_len = iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
start_time, write_cnt, delta_cnt, rcsd, result_data,
|
|
lc_cache, load_len, 0, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 8;
|
|
goto err;
|
|
}
|
|
write_cnt += delta_cnt;
|
|
result_data += write_data_len;
|
|
load_len -= write_data_len;
|
|
goto write;
|
|
}
|
|
} else {
|
|
if (!delta_cnt) {
|
|
/* load record delta time too short
|
|
* ignore current data unit.
|
|
*/
|
|
os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
|
|
goto done;
|
|
} else if (delta_cnt == 1) {
|
|
goto write;
|
|
} else {
|
|
if ((write_cnt + delta_cnt) > unit_cnt) {
|
|
delta_cnt = (uint8_t)(unit_cnt - write_cnt);
|
|
write_data_len =
|
|
iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
start_time, write_cnt, delta_cnt, rcsd,
|
|
result_data, lc_cache, load_len, 0, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 9;
|
|
goto err;
|
|
}
|
|
write_cnt = unit_cnt;
|
|
load_len -= write_data_len;
|
|
break;
|
|
}
|
|
write_data_len = iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
start_time, write_cnt, delta_cnt - 1, rcsd, result_data,
|
|
lc_cache, load_len, 0, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 10;
|
|
goto err;
|
|
}
|
|
write_cnt += (delta_cnt - 1);
|
|
result_data += write_data_len;
|
|
load_len -= write_data_len;
|
|
}
|
|
}
|
|
write:
|
|
write_data_len = iot_sg_sta_ext_min_frozen_uint_data_write(
|
|
start_time, write_cnt, 1, rcsd, result_data, lc_cache,
|
|
load_len, 1, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 11;
|
|
goto err;
|
|
}
|
|
write_cnt++;
|
|
result_data += write_data_len;
|
|
load_len -= write_data_len;
|
|
}
|
|
done:
|
|
index_tmp++;
|
|
if (index_tmp >= max_cnt) {
|
|
index_tmp = 0;
|
|
}
|
|
}
|
|
if (write_cnt < unit_cnt) {
|
|
write_data_len = iot_sg_sta_ext_min_frozen_uint_data_write(start_time,
|
|
write_cnt, unit_cnt - write_cnt, rcsd, result_data, lc_cache,
|
|
load_len, 0, addr, inter);
|
|
if (!write_data_len || write_data_len > load_len) {
|
|
reason = 12;
|
|
goto err;
|
|
}
|
|
load_len -= write_data_len;
|
|
}
|
|
goto out;
|
|
err:
|
|
load_len = load_total_len;
|
|
iot_sg_printf("%s err reason %d\n", __FUNCTION__, reason);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return load_total_len - load_len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_min_frozen_data_resp(
|
|
proto_69845_app_oad_t *oad, proto_69845_app_piid_t *piid,
|
|
proto_69845_data_cache_desc_t *rcsd_cache, addr_info_t *server_addr,
|
|
iot_time_tm_t *start_timr, iot_time_tm_t *end_time, int64_t inter)
|
|
{
|
|
uint16_t head_len;
|
|
uint8_t *resp_data, reason = 0;
|
|
uint8_t *apdu_data = NULL, *no_time_tag, *no_flw, csd_list_len = 0;
|
|
iot_pkt_t *apdu_pkt = NULL, *resp_pkt = NULL;
|
|
uint32_t size_result, result_end, result_head, length;
|
|
proto_69845_apdu_t *apdu;
|
|
proto_69845_app_req_resp_t *resp;
|
|
proto_69845_app_get_simp_record_resp_t *simp_record_resp;
|
|
proto_69845_app_data_rcsd_t *rcsd, *rcsd_resp;
|
|
proto_69845_app_data_csd_t *csd;
|
|
proto_69845_app_oad_t *oad_resp;
|
|
proto_69845_frame_head_info_t *hdr_698_resp;
|
|
|
|
if (!oad || !piid || !rcsd_cache || !server_addr ||
|
|
!start_timr || !end_time) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (rcsd_cache->len < sizeof(*rcsd)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
rcsd = (proto_69845_app_data_rcsd_t *)rcsd_cache->data;
|
|
csd_list_len = rcsd->cnt * (sizeof(*csd) +sizeof(*oad_resp));
|
|
if (rcsd_cache->len - sizeof(*rcsd) < csd_list_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
result_head = sizeof(*resp) + sizeof(*apdu) + sizeof(*rcsd_resp) +
|
|
sizeof(*simp_record_resp) + csd_list_len;
|
|
result_end = PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN;
|
|
if (PROTO_69845_PREDICT_APDU_MAX_LEN < result_head + result_end) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
apdu_pkt = iot_pkt_alloc(PROTO_69845_PREDICT_APDU_MAX_LEN,
|
|
IOT_SMART_GRID_MID);
|
|
if (!apdu_pkt) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
apdu_data = iot_pkt_put(apdu_pkt, PROTO_69845_PREDICT_APDU_MAX_LEN);
|
|
apdu = (proto_69845_apdu_t *)apdu_data;
|
|
apdu->type = PROTO_69845_S_APP_GET_RESP;
|
|
resp = (proto_69845_app_req_resp_t*)apdu->data;
|
|
resp->type = PROTO_69845_APP_GET_RECORD;
|
|
simp_record_resp = (proto_69845_app_get_simp_record_resp_t*)resp->data;
|
|
simp_record_resp->piid_acd.sn = piid->sn;
|
|
simp_record_resp->piid_acd.priority = piid->priority;
|
|
simp_record_resp->piid_acd.acd = 0;
|
|
simp_record_resp->oad.attribute_char = oad->attribute_char;
|
|
simp_record_resp->oad.attribute_id = oad->attribute_id;
|
|
simp_record_resp->oad.element_index = oad->element_index;
|
|
iot_uint16_to_bytes(oad->oi, (uint8_t *)&simp_record_resp->oad.oi, 1);
|
|
rcsd_resp = (proto_69845_app_data_rcsd_t*)simp_record_resp->rsd_and_road;
|
|
rcsd_resp->cnt = rcsd->cnt;
|
|
os_mem_cpy(rcsd_resp->csd_list, rcsd->csd_list,
|
|
rcsd->cnt * (sizeof(*csd) + sizeof(*oad_resp)));
|
|
size_result = iot_sg_sta_fill_min_frozen_resp_data(inter, rcsd,
|
|
apdu_data + result_head, PROTO_69845_PREDICT_APDU_MAX_LEN -
|
|
result_head - result_end, start_timr, end_time,
|
|
server_addr->ser_info.addr);
|
|
if (!size_result) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
no_time_tag = apdu_data + result_head + size_result + 1;
|
|
*no_time_tag = 0;
|
|
no_flw = apdu_data + result_head + size_result + 2;
|
|
*no_flw = 0;
|
|
|
|
length = sizeof(*hdr_698_resp) + server_addr->ser_info.len +
|
|
PROTO_69845_CA_LEN + PROTO_69845_CHECKSUM_LEN + result_head +
|
|
size_result + result_end + sizeof(proto_69845_tailer_t);
|
|
resp_pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
|
|
if (!resp_pkt) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
resp_data = iot_pkt_put(resp_pkt, length);
|
|
hdr_698_resp = (proto_69845_frame_head_info_t *)resp_data;
|
|
head_len = sizeof(*hdr_698_resp) + server_addr->ser_info.len
|
|
+ PROTO_69845_CA_LEN + PROTO_69845_CHECKSUM_LEN;
|
|
proto_69845_head_fill(hdr_698_resp, head_len, (uint16_t)length,
|
|
server_addr, PROTO_69845_FN_USER_DATA, PROTO_69845_APDU_WHOLE,
|
|
PROTO_69845_D_P_SERVER_RESPONSE);
|
|
resp_data += head_len;
|
|
os_mem_cpy(resp_data, apdu_data, result_head + size_result + result_end);
|
|
resp_data += result_head + size_result + result_end;
|
|
/* fill 698.45 proto tailer */
|
|
proto_69845_tail_fill(hdr_698_resp, resp_data,
|
|
sizeof(proto_69845_tailer_t));
|
|
out:
|
|
if (!resp_pkt) {
|
|
iot_sg_printf("%s err reason %d\n", __FUNCTION__, reason);
|
|
}
|
|
if (apdu_pkt) {
|
|
iot_pkt_free(apdu_pkt);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_min_frozen_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;
|
|
uint32_t temp_oad;
|
|
int64_t inter;
|
|
proto_69845_app_data_rsd_t *rsd_hdr;
|
|
proto_69845_app_data_rsd_type2_t *rsd_type2;
|
|
proto_69845_app_data_rsd_type2_data_t *rsd_type2_data;
|
|
proto_69845_app_data_ti_t ti = { 0 };
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
iot_time_tm_t start_tm, end_tm;
|
|
addr_info_t server_addr = { 0 };
|
|
|
|
if (!rsd->data || !rsd->len) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (rsd->len < (sizeof(*rsd_hdr) + sizeof(*rsd_type2) +
|
|
sizeof(*rsd_type2_data) - sizeof(proto_69845_app_data_rcsd_t))) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
proto_69845_get_addr_info(hdr_698, &server_addr);
|
|
if (!iot_sg_sta_node_find_by_addr(server_addr.ser_info.addr)) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
rsd_hdr = (proto_69845_app_data_rsd_t *)rsd->data;
|
|
switch(rsd_hdr->type) {
|
|
case PROTO_OI_RSD_TYPE_2:
|
|
{
|
|
rsd_type2 = (proto_69845_app_data_rsd_type2_t *)rsd_hdr->rsd_data;
|
|
temp_oad = iot_bytes_to_uint32((uint8_t *)&rsd_type2->oad, 1);
|
|
if (temp_oad != PROTO_69845_APP_OAD_FROZEN_T) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
rsd_type2_data = (proto_69845_app_data_rsd_type2_data_t*)rsd_type2->data;
|
|
if (!rsd_type2_data->rcsd.cnt) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
if (rsd_type2_data->ti_type != PROTO_69845_APP_DATA_TI) {
|
|
reason = 6;
|
|
goto drop;
|
|
}
|
|
ti.uint = rsd_type2_data->ti.uint;
|
|
ti.value = iot_bytes_to_uint16(
|
|
(uint8_t*)&rsd_type2_data->ti.value, 1);
|
|
inter = proto_69845_ti_data_to_sec(&ti);
|
|
start_tm.tm_year = iot_bytes_to_uint16(
|
|
(uint8_t*)&rsd_type2_data->start_time.year, 1);
|
|
start_tm.tm_mon = rsd_type2_data->start_time.month;
|
|
start_tm.tm_mday = rsd_type2_data->start_time.day;
|
|
start_tm.tm_hour = rsd_type2_data->start_time.hour;
|
|
start_tm.tm_min = rsd_type2_data->start_time.minute;
|
|
start_tm.tm_sec = rsd_type2_data->start_time.second;
|
|
iot_sg_ext_set_integral_point(&start_tm, inter, 1);
|
|
end_tm.tm_year = iot_bytes_to_uint16(
|
|
(uint8_t*)&rsd_type2_data->end_time.year, 1);
|
|
end_tm.tm_mon = rsd_type2_data->end_time.month;
|
|
end_tm.tm_mday = rsd_type2_data->end_time.day;
|
|
end_tm.tm_hour = rsd_type2_data->end_time.hour;
|
|
end_tm.tm_min = rsd_type2_data->end_time.minute;
|
|
end_tm.tm_sec = rsd_type2_data->end_time.second;
|
|
/* PROTO_OI_RSD_TYPE_2 read minute frozen data,
|
|
* response data time less than end time.
|
|
*/
|
|
iot_rtc_delta_add(-1, &end_tm);
|
|
iot_sg_ext_set_integral_point(&end_tm, inter, 0);
|
|
if (iot_rtc_delta_calc(&end_tm, &start_tm) > 0) {
|
|
reason = 7;
|
|
goto drop;
|
|
}
|
|
resp_pkt = iot_sg_sta_ext_min_frozen_data_resp(oad, piid, rcsd,
|
|
&server_addr, &start_tm, &end_tm, inter);
|
|
goto out;
|
|
}
|
|
default:
|
|
reason = 8;
|
|
break;
|
|
}
|
|
drop:
|
|
iot_sg_printf("%s reason %d\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_record_resp_hn(
|
|
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)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
switch (oad->oi) {
|
|
case PROTO_69845_APP_OI_MIN_FROZEN:
|
|
{
|
|
if (oad->attribute_id != PROTO_OI_DEV_MIN_FROZEN_ATT_FROZEN_TAB) {
|
|
goto out;
|
|
}
|
|
pkt = iot_sg_sta_ext_min_frozen_data_query(hdr_698, piid, oad, rsd,
|
|
road_rcsd);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_record_resp(
|
|
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)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
pkt = iot_sg_sta_ext_get_record_resp_js(hdr_698, piid, oad,
|
|
rsd, road_rcsd);
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
pkt = iot_sg_sta_ext_get_record_resp_hn(hdr_698, piid, oad,
|
|
rsd, road_rcsd);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_get_record_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *ptr = data, reason = 0;
|
|
uint32_t len = data_len;
|
|
proto_69845_data_cache_desc_t rsd = { 0 }, rcsd = { 0 };
|
|
proto_69845_app_oad_t oad = { 0 };
|
|
proto_69845_app_get_req_record_t *get_record_hdr;
|
|
proto_69845_app_piid_t *piid;
|
|
|
|
if (len < sizeof(*get_record_hdr)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
get_record_hdr = (proto_69845_app_get_req_record_t*)data;
|
|
ptr += sizeof(*get_record_hdr);
|
|
len -= sizeof(*get_record_hdr);
|
|
piid = &get_record_hdr->piid;
|
|
oad.oi = proto_69845_byte_to_oi((uint8_t*)&get_record_hdr->oad.oi);
|
|
oad.element_index = get_record_hdr->oad.element_index;
|
|
oad.attribute_id = get_record_hdr->oad.attribute_id;
|
|
oad.attribute_char = get_record_hdr->oad.attribute_char;
|
|
if (proto_69845_get_rsd_data_len(ptr, len, &rsd.len)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
if (len < rsd.len) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
rsd.data = ptr;
|
|
ptr += rsd.len;
|
|
len -= rsd.len;
|
|
if (proto_69845_get_rcsd_data_len(ptr, len, &rcsd.len)) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
if (len < rcsd.len) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
rcsd.data = ptr;
|
|
pkt = iot_sg_sta_ext_get_record_resp(hdr_698, piid, &oad, &rsd, &rcsd);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_handle_hn(
|
|
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;
|
|
|
|
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_RECORD:
|
|
{
|
|
pkt = iot_sg_sta_ext_get_record_handle(hdr_698, ptr, len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_get_handle_zj(
|
|
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;
|
|
|
|
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;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_action_list_analysis(
|
|
uint8_t *data, uint32_t data_len,
|
|
proto_69845_action_list_desc_t *action_desc)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t *ptr = data, i;
|
|
uint32_t len = data_len, omd_data_len = 0;
|
|
proto_69845_app_omd_with_data_t *omd_with_data;
|
|
|
|
for (i = 0; i < action_desc->cnt; i++) {
|
|
if (len < sizeof(*omd_with_data)) {
|
|
goto out;
|
|
}
|
|
omd_with_data = (proto_69845_app_omd_with_data_t*)ptr;
|
|
action_desc->list[i].omd.oi = proto_69845_byte_to_oi(
|
|
(uint8_t*)&omd_with_data->omd.oi);
|
|
action_desc->list[i].omd.method_id =
|
|
omd_with_data->omd.method_id;
|
|
action_desc->list[i].omd.operation_mode =
|
|
omd_with_data->omd.operation_mode;
|
|
if (proto_69845_get_data_len(&omd_with_data->data, len,
|
|
&omd_data_len)) {
|
|
goto out;
|
|
}
|
|
action_desc->list[i].omd_data = (uint8_t*)&omd_with_data->data;
|
|
action_desc->list[i].len = (uint16_t)omd_data_len;
|
|
omd_data_len += sizeof(omd_with_data->omd);
|
|
if (len < omd_data_len) {
|
|
goto out;
|
|
}
|
|
ptr += omd_data_len;
|
|
len -= omd_data_len;
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_action_list_resp(
|
|
proto_69845_frame_head_info_t *hdr_698,
|
|
proto_69845_action_list_desc_t *action)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
(void)hdr_698;
|
|
(void)action;
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
pkt = iot_sg_sta_ext_action_list_resp_js(hdr_698, action);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_action_list_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
uint8_t *ptr = data, reason = 0;
|
|
uint32_t len = data_len, buff_len;
|
|
proto_69845_action_list_desc_t *cache_list;
|
|
proto_69845_app_action_req_list_t *action_list;
|
|
|
|
if (len < sizeof(*action_list)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
action_list = (proto_69845_app_action_req_list_t*)ptr;
|
|
ptr += sizeof(*action_list);
|
|
len -= sizeof(*action_list);
|
|
if (!action_list->omd_cnt) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
buff_len = sizeof(proto_69845_action_list_unit_desc_t) *
|
|
action_list->omd_cnt;
|
|
buff_len += sizeof(*cache_list);
|
|
pkt_buff = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
cache_list = (proto_69845_action_list_desc_t*)iot_pkt_put(pkt_buff,
|
|
buff_len);
|
|
cache_list->piid = action_list->piid;
|
|
cache_list->cnt = action_list->omd_cnt;
|
|
if (iot_sg_sta_ext_action_list_analysis(ptr, len, cache_list)) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
pkt = iot_sg_sta_ext_action_list_resp(hdr_698, cache_list);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_handle_br2_launch_req(
|
|
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)
|
|
{
|
|
uint8_t ele_cnt, reason = 0, launch_code_len, *launch_code;
|
|
uint8_t dar = PROTO_69845_APP_DAR_OTHER;
|
|
uint16_t year, seq;
|
|
uint16_t pulse_high_dur, pulse_low_dur, chara_bit_dur;
|
|
uint32_t ret, total_len, para_len;
|
|
addr_info_t addr_info = {0};
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_07_time_ymdhms_t launch_tm;
|
|
proto_69845_app_ele_data_t *desc;
|
|
proto_69845_rpt_data_time_s_t *start_time;
|
|
proto_69845_br2_launch_para_t *launch_para;
|
|
iot_sg_ext_cus_topo_rcv_cfg_t cfg = {0};
|
|
proto_69845_app_data_t *fc_data = NULL;
|
|
|
|
(void)launch_tm;
|
|
(void)seq;
|
|
if (omd->method_id != PROTO_OI_BR2_LAUNCH_METHOD_LAUNCH
|
|
&& omd->method_id != PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
total_len = sizeof(*desc);
|
|
if (action_desc->len < total_len) {
|
|
reason = 2;
|
|
goto ack;
|
|
}
|
|
desc = (proto_69845_app_ele_data_t*)action_desc->data;
|
|
if (desc->data_type != PROTO_69845_APP_DATA_STRUCTURE) {
|
|
reason = 3;
|
|
goto ack;
|
|
}
|
|
if (omd->method_id == PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
ele_cnt = 2;
|
|
total_len = sizeof(*desc) + sizeof(*launch_para) + sizeof(*start_time);
|
|
} else {
|
|
ele_cnt = 6;
|
|
total_len = sizeof(*launch_para);
|
|
}
|
|
if (ele_cnt != desc->num_of_data || (action_desc->len < total_len)) {
|
|
reason = 4;
|
|
goto ack;
|
|
}
|
|
if (omd->method_id == PROTO_OI_BR2_LAUNCH_METHOD_TIME_LAUNCH) {
|
|
launch_para = (proto_69845_br2_launch_para_t*)&desc->data;
|
|
total_len = action_desc->len - sizeof(*desc);
|
|
ret = proto_69845_get_data_len((proto_69845_app_data_t*)launch_para,
|
|
total_len, ¶_len);
|
|
if (ret) {
|
|
reason = 5;
|
|
goto ack;
|
|
}
|
|
start_time = (proto_69845_rpt_data_time_s_t*)(desc->data + para_len);
|
|
} else {
|
|
launch_para = (proto_69845_br2_launch_para_t*)action_desc->data;
|
|
start_time = NULL;
|
|
}
|
|
if (!launch_para->bit_len.mub_flag) {
|
|
launch_code_len = launch_para->bit_len.byte_num / 8;
|
|
launch_code = launch_para->code;
|
|
} else {
|
|
reason = 6;
|
|
goto ack;
|
|
}
|
|
if (start_time) {
|
|
year = iot_bytes_to_uint16((uint8_t*)&start_time->year, 1);
|
|
launch_tm.year = iot_byte_to_bcd((uint8_t)(year - 2000));
|
|
launch_tm.month = iot_byte_to_bcd(start_time->month);
|
|
launch_tm.day = iot_byte_to_bcd(start_time->day);
|
|
launch_tm.hour = iot_byte_to_bcd(start_time->hour);
|
|
launch_tm.minute = iot_byte_to_bcd(start_time->minute);
|
|
launch_tm.second = iot_byte_to_bcd(start_time->second);
|
|
} else {
|
|
launch_tm.year = 0xff;
|
|
launch_tm.month = 0xff;
|
|
launch_tm.day = 0xff;
|
|
launch_tm.hour = 0xff;
|
|
launch_tm.minute = 0xff;
|
|
launch_tm.second = 0xff;
|
|
}
|
|
|
|
pulse_high_dur = iot_bytes_to_uint16((uint8_t*)&launch_para->pulse_high_dur,
|
|
1);
|
|
pulse_low_dur = iot_bytes_to_uint16((uint8_t*)&launch_para->pulse_low_dur,
|
|
1);
|
|
chara_bit_dur = iot_bytes_to_uint16((uint8_t*)&launch_para->chara_bit_dur,
|
|
1);
|
|
cfg.pulse_high_dur = pulse_high_dur;
|
|
cfg.pulse_low_dur = pulse_low_dur;
|
|
cfg.chara_bit_dur = chara_bit_dur;
|
|
os_mem_cpy(cfg.fr_code, launch_code, launch_code_len);
|
|
cfg.fr_code_len = launch_code_len;
|
|
fc_data = (proto_69845_app_data_t *)(launch_para->code + launch_code_len);
|
|
cfg.fc = iot_bytes_to_uint32(fc_data->data, 1);
|
|
iot_sg_ext_topo_rcv_cfg_to_cus(&cfg);
|
|
seq = piid->sn;
|
|
if (iot_sg_sta_tsfm_topo_br2_launch_start(&launch_tm,
|
|
launch_code, launch_code_len, pulse_high_dur, pulse_low_dur,
|
|
chara_bit_dur, &seq, IOT_PLC_HW_TSFM_LOAD_ENCODE_RAW)) {
|
|
reason = 7;
|
|
} else {
|
|
dar = PROTO_69845_APP_DAR_SUCCESS;
|
|
}
|
|
ack:
|
|
proto_69845_get_addr_info(hdr_698, &addr_info);
|
|
pkt = proto_69845_action_single_ack(&addr_info, piid, omd,
|
|
dar);
|
|
out:
|
|
if (reason) {
|
|
iot_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_action_normal_resp_zj(
|
|
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;
|
|
|
|
switch (omd->oi) {
|
|
case PROTO_69845_APP_OI_BR2_LAUNCH:
|
|
case PROTO_69845_APP_OI_EXT_BR2_LAUNCH:
|
|
{
|
|
pkt = iot_sg_sta_ext_handle_br2_launch_req(hdr_698, piid, omd,
|
|
action_desc);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_action_normal_resp(
|
|
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;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
switch (iot_sg_sta_get_user_type()) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
pkt = iot_sg_sta_ext_action_normal_resp_js(hdr_698, piid, omd,
|
|
action_desc);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (!pkt && sta_glb->br2_enable) {
|
|
pkt = iot_sg_sta_ext_action_normal_resp_zj(hdr_698, piid, omd,
|
|
action_desc);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_action_normal_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *ptr = data, reason = 0;
|
|
proto_69845_app_omd_t omd = {0};
|
|
uint32_t len = data_len;
|
|
proto_69845_app_action_req_single_t *action_single;
|
|
proto_69845_data_cache_desc_t action_desc = {0};
|
|
|
|
if (len < sizeof(*action_single)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
action_single = (proto_69845_app_action_req_single_t*)ptr;
|
|
omd.oi = proto_69845_byte_to_oi((uint8_t*)&action_single->omd.oi);
|
|
omd.method_id = action_single->omd.method_id;
|
|
omd.operation_mode = action_single->omd.operation_mode;
|
|
ptr += sizeof(*action_single);
|
|
len -= sizeof(*action_single);
|
|
if (proto_69845_get_data_len(&action_single->data, len, &action_desc.len)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
if (len < action_desc.len) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
action_desc.data = (uint8_t*)&action_single->data;
|
|
pkt = iot_sg_sta_ext_action_normal_resp(hdr_698, &action_single->piid,
|
|
&omd, &action_desc);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_action_handle_zj(
|
|
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;
|
|
|
|
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;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_fill_698_resp_data(
|
|
iot_sg_meter_pw_lc_uint_data_t *lc_cache, proto_69845_app_data_rcsd_t *rcsd,
|
|
uint32_t len, uint8_t *data, uint32_t load_len)
|
|
{
|
|
uint16_t temp_16;
|
|
uint32_t temp_32, fill_data_len = 0, oad;
|
|
uint8_t invalid_data[4] = { 0xFF, 0xFF, 0xFF, 0XFF };
|
|
uint8_t *req_data, *result_data = NULL, oad_len, *temp_data;
|
|
uint8_t i, j;
|
|
proto_69845_app_data_csd_t *csd;
|
|
proto_69845_app_data_t *app_data;
|
|
proto_69845_app_data_time_s_t *data_time;
|
|
proto_69845_app_ele_data_t *ele_data;
|
|
proto_69845_app_get_result_t *result_head;
|
|
proto_69845_app_rpt_array_result_t *array_result;
|
|
if (!lc_cache || !rcsd || !data || !load_len) {
|
|
goto err;
|
|
}
|
|
fill_data_len += sizeof(*result_head) + sizeof(*array_result);
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
result_head = (proto_69845_app_get_result_t*)data;
|
|
result_head->result_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
array_result = (proto_69845_app_rpt_array_result_t*)result_head->result;
|
|
array_result->array_len = 1;
|
|
result_data = array_result->data;
|
|
|
|
oad_len = sizeof(*csd) + sizeof(oad);
|
|
len -= sizeof(*rcsd);
|
|
req_data = rcsd->csd_list;
|
|
for (i = 0; i < rcsd->cnt && len >= oad_len; i++) {
|
|
len -= oad_len;
|
|
csd = (proto_69845_app_data_csd_t*)req_data;
|
|
if (csd->type != PROTO_OI_CSD_TYPE_OAD) {
|
|
/* Road-style selection descriptors are not currently supported */
|
|
goto err;
|
|
}
|
|
oad = iot_bytes_to_uint32((uint8_t*)csd->csd_data, 1);
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
|
{
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type =
|
|
PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
|
temp_32 = (uint32_t)proto_645_bcd_to_integer(lc_cache->ept_pos,
|
|
sizeof(lc_cache->ept_pos), 1);
|
|
iot_uint32_to_bytes(temp_32, app_data->data, 1);
|
|
result_data += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
|
{
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type =
|
|
PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
|
temp_32 = proto_645_bcd_to_integer(lc_cache->ept_neg,
|
|
sizeof(lc_cache->ept_neg), 0);
|
|
iot_uint32_to_bytes(temp_32, app_data->data, 1);
|
|
result_data += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_VOLTAGE:
|
|
{
|
|
fill_data_len += sizeof(*ele_data);
|
|
temp_data = lc_cache->v.a;
|
|
ele_data = (proto_69845_app_ele_data_t *)result_data;
|
|
ele_data->data_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
ele_data->num_of_data = 0;
|
|
result_data += sizeof(*ele_data);
|
|
for (j = 0; j < IOT_PLC_PHASE_CNT; j++) {
|
|
if (os_mem_cmp(temp_data, invalid_data, PROTO_645_V_LEN)) {
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
ele_data->num_of_data++;
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
|
temp_16 = (uint16_t)proto_645_bcd_to_integer(temp_data,
|
|
sizeof(lc_cache->v.a), 0);
|
|
iot_uint16_to_bytes(temp_16, app_data->data, 1);
|
|
result_data += sizeof(*result_data) +
|
|
PROTO_69845_METER_DATA_LONG_LEN;
|
|
}
|
|
temp_data += PROTO_645_V_LEN;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_CURRENT:
|
|
{
|
|
fill_data_len += sizeof(*ele_data);
|
|
temp_data = lc_cache->i.a;
|
|
ele_data = (proto_69845_app_ele_data_t *)result_data;
|
|
ele_data->data_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
ele_data->num_of_data = 0;
|
|
result_data += sizeof(*ele_data);
|
|
for (j = 0; j < IOT_PLC_PHASE_CNT; j++) {
|
|
if (os_mem_cmp(temp_data, invalid_data, PROTO_645_07_A_LEN)) {
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
ele_data->num_of_data++;
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
|
temp_32 = proto_645_bcd_to_integer(temp_data,
|
|
sizeof(lc_cache->i.a), 1);
|
|
iot_uint32_to_bytes(temp_32, app_data->data, 1);
|
|
result_data += sizeof(*result_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
}
|
|
temp_data += PROTO_645_07_A_LEN;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_P:
|
|
{
|
|
fill_data_len += sizeof(*ele_data);
|
|
temp_data = lc_cache->active_power.total;
|
|
ele_data = (proto_69845_app_ele_data_t *)result_data;
|
|
ele_data->data_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
ele_data->num_of_data = 0;
|
|
result_data += sizeof(*ele_data);
|
|
for (j = 0; j < IOT_PLC_PHASE_CNT + 1; j++) {
|
|
if (os_mem_cmp(temp_data, invalid_data, PROTO_645_07_P_LEN)) {
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
ele_data->num_of_data++;
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
|
temp_32 = proto_645_bcd_to_integer(temp_data,
|
|
sizeof(lc_cache->active_power.total), 0);
|
|
iot_uint32_to_bytes(temp_32, app_data->data, 1);
|
|
result_data += sizeof(*result_data) +
|
|
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
|
}
|
|
temp_data += PROTO_645_07_P_LEN;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_PF:
|
|
{
|
|
fill_data_len += sizeof(*ele_data);
|
|
temp_data = lc_cache->power_factor.total;
|
|
ele_data = (proto_69845_app_ele_data_t *)result_data;
|
|
ele_data->data_type = PROTO_69845_APP_RPT_RESULT_DATA;
|
|
ele_data->num_of_data = 0;
|
|
result_data += sizeof(*ele_data);
|
|
for (j = 0; j < IOT_PLC_PHASE_CNT + 1; j++) {
|
|
if (os_mem_cmp(temp_data, invalid_data, PROTO_645_07_PF_LEN)) {
|
|
fill_data_len += sizeof(*app_data) +
|
|
PROTO_69845_METER_DATA_LONG_LEN;
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
ele_data->num_of_data++;
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_LONG;
|
|
temp_16 = (uint16_t)proto_645_bcd_to_integer(temp_data,
|
|
sizeof(lc_cache->power_factor.total), 0);
|
|
iot_uint16_to_bytes(temp_16, app_data->data, 1);
|
|
result_data += sizeof(*result_data) +
|
|
PROTO_69845_METER_DATA_LONG_LEN;
|
|
}
|
|
temp_data += PROTO_645_07_PF_LEN;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_69845_APP_OAD_FROZEN_T:
|
|
{
|
|
uint16_t year;
|
|
fill_data_len += sizeof(*app_data) + sizeof(*data_time);
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_TIME_S;
|
|
data_time = (proto_69845_app_data_time_s_t*)app_data->data;
|
|
year = (uint16_t)lc_cache->year + 2000;
|
|
data_time->year = iot_bytes_to_uint16((uint8_t*)&year, 1);
|
|
data_time->month = (uint8_t)lc_cache->month;
|
|
data_time->day = (uint8_t)lc_cache->day;
|
|
data_time->hour = (uint8_t)lc_cache->hour;
|
|
data_time->minute = (uint8_t)lc_cache->minute;
|
|
result_data += sizeof(*data) + sizeof(*data_time);
|
|
break;
|
|
}
|
|
default:
|
|
fill_data_len += sizeof(*app_data);
|
|
if (fill_data_len > load_len) {
|
|
goto err;
|
|
}
|
|
app_data = (proto_69845_app_data_t*)(result_data);
|
|
app_data->data_type = PROTO_69845_APP_DATA_NULL;
|
|
result_data += sizeof(*app_data);
|
|
break;
|
|
}
|
|
req_data += oad_len;
|
|
}
|
|
goto out;
|
|
err:
|
|
fill_data_len = 0;
|
|
iot_sg_printf("%s err\n", __FUNCTION__);
|
|
out:
|
|
return fill_data_len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_fill_698_frozen_data(
|
|
iot_sg_meter_pw_lc_uint_data_t *lc_cache, proto_69845_app_data_rcsd_t *rcsd,
|
|
uint32_t len, proto_69845_app_oad_t *oad, server_addr_info_t *server_addr,
|
|
proto_69845_app_piid_acd_t *piid)
|
|
{
|
|
uint8_t *data = NULL, *no_time_tag, *no_flw;
|
|
iot_pkt_t *apdu_pkt = NULL, *resp_pkt = NULL;
|
|
uint32_t size_result, result_end, result_head;
|
|
proto_69845_apdu_t *apdu;
|
|
proto_69845_app_req_resp_t *resp;
|
|
proto_69845_app_get_simp_record_resp_t *simp_record_resp;
|
|
proto_69845_app_data_rcsd_t *rcsd_resp;
|
|
proto_69845_app_data_csd_t *csd;
|
|
proto_69845_app_oad_t *oad_resp;
|
|
addr_info_t addr_info = {0};
|
|
if (!lc_cache || !rcsd || !rcsd->cnt) {
|
|
goto out;
|
|
}
|
|
result_head = sizeof(*resp) + sizeof(*apdu) + sizeof(*rcsd_resp) +
|
|
sizeof(*simp_record_resp) + rcsd->cnt * (sizeof(*csd) +
|
|
sizeof(*oad_resp));
|
|
result_end = PROTO_69845_NO_TIME_TAG_LEN + PROTO_69845_NO_FLW_DATA_LEN;
|
|
if (PROTO_69845_PREDICT_APDU_MAX_LEN < result_head + result_end) {
|
|
IOT_ASSERT(0);
|
|
goto out;
|
|
}
|
|
apdu_pkt = iot_pkt_alloc(PROTO_69845_PREDICT_APDU_MAX_LEN,
|
|
IOT_SMART_GRID_MID);
|
|
if (!apdu_pkt) {
|
|
goto out;
|
|
}
|
|
data = iot_pkt_put(apdu_pkt, PROTO_69845_PREDICT_APDU_MAX_LEN);
|
|
apdu = (proto_69845_apdu_t *)data;
|
|
apdu->type = PROTO_69845_S_APP_GET_RESP;
|
|
resp = (proto_69845_app_req_resp_t*)apdu->data;
|
|
resp->type = PROTO_69845_APP_GET_RECORD;
|
|
simp_record_resp = (proto_69845_app_get_simp_record_resp_t*)resp->data;
|
|
simp_record_resp->piid_acd = *piid;
|
|
simp_record_resp->oad = *oad;
|
|
rcsd_resp = (proto_69845_app_data_rcsd_t*)simp_record_resp->rsd_and_road;
|
|
rcsd_resp->cnt = rcsd->cnt;
|
|
if (len < rcsd->cnt * (sizeof(*csd) + sizeof(*oad_resp))) {
|
|
goto out;
|
|
}
|
|
os_mem_cpy(rcsd_resp->csd_list, rcsd->csd_list,
|
|
rcsd->cnt * (sizeof(*csd) + sizeof(*oad_resp)));
|
|
size_result = iot_sg_sta_fill_698_resp_data(lc_cache, rcsd, len,
|
|
data + result_head, PROTO_69845_PREDICT_APDU_MAX_LEN -
|
|
result_head - result_end);
|
|
if (!size_result) {
|
|
goto out;
|
|
}
|
|
no_time_tag = data + result_head + size_result + 1;
|
|
*no_time_tag = 0;
|
|
no_flw = data + result_head + size_result + 2;
|
|
*no_flw = 0;
|
|
addr_info.ser_info = *server_addr;
|
|
addr_info.cli_addr = PROTO_69845_CA_INVAILD_ADD;
|
|
resp_pkt = proto_69845_build_apdu_data_with_security_resp_msg(data,
|
|
result_head + size_result + result_end, &addr_info);
|
|
out:
|
|
if (apdu_pkt) {
|
|
iot_pkt_free(apdu_pkt);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_load_698_min_frozen_rec(uint8_t *data,
|
|
uint32_t len, proto_69845_app_oad_t *oad, server_addr_info_t *server_addr,
|
|
proto_69845_app_piid_acd_t *piid)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint16_t start_idx = 0, unit_len = 0;
|
|
uint32_t data_len, ret, temp_oad;
|
|
iot_pkt_t *resp_pkt = NULL, *pkt = NULL;
|
|
iot_time_tm_t start_tm, end_tm, read_tm;
|
|
proto_69845_app_data_rsd_t *rsd;
|
|
iot_sg_meter_pw_lc_uint_data_t *lc_cache = NULL;
|
|
proto_69845_app_data_rsd_type2_t *rsd_type2;
|
|
proto_69845_app_data_rsd_type2_data_t *rsd_type2_data;
|
|
|
|
data_len = sizeof(*rsd) + sizeof(*rsd_type2);
|
|
if (len < data_len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
len -= data_len;
|
|
rsd = (proto_69845_app_data_rsd_t*)data;
|
|
switch(rsd->type) {
|
|
case PROTO_OI_RSD_TYPE_2:
|
|
{
|
|
rsd_type2 = (proto_69845_app_data_rsd_type2_t*)rsd->rsd_data;
|
|
if (len < sizeof(*rsd_type2_data)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
len -= sizeof(*rsd_type2_data);
|
|
temp_oad = iot_bytes_to_uint32((uint8_t*)&rsd_type2->oad, 1);
|
|
if (temp_oad == PROTO_69845_APP_OAD_FROZEN_T) {
|
|
rsd_type2_data =
|
|
(proto_69845_app_data_rsd_type2_data_t*)rsd_type2->data;
|
|
if (rsd_type2_data->rcsd.cnt) {
|
|
start_tm.tm_year = iot_bytes_to_uint16(
|
|
(uint8_t*)&rsd_type2_data->start_time.year, 1);
|
|
start_tm.tm_mon = rsd_type2_data->start_time.month;
|
|
start_tm.tm_mday = rsd_type2_data->start_time.day;
|
|
start_tm.tm_hour = rsd_type2_data->start_time.hour;
|
|
start_tm.tm_min = rsd_type2_data->start_time.minute;
|
|
start_tm.tm_sec = rsd_type2_data->start_time.second;
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_PW_LC, &unit_len, NULL);
|
|
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
lc_cache = (iot_sg_meter_pw_lc_uint_data_t *)iot_pkt_put(
|
|
pkt, unit_len);
|
|
ret = iot_sg_sta_flash_unit_data_find_by_time(server_addr->addr,
|
|
&start_idx, &start_tm, (uint8_t *)lc_cache,
|
|
unit_len, IOT_SG_STA_METER_DATA_TYPE_PW_LC, 0);
|
|
if (ret != ERR_OK) {
|
|
iot_sg_printf("%s %lu-%lu-%lu %lu:%lu:%lu read err\n",
|
|
__FUNCTION__, start_tm.tm_year, start_tm.tm_mon,
|
|
start_tm.tm_mday, start_tm.tm_hour, start_tm.tm_min,
|
|
start_tm.tm_sec);
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
end_tm.tm_year = iot_bytes_to_uint16(
|
|
(uint8_t*)&rsd_type2_data->end_time.year, 1);
|
|
end_tm.tm_mon = rsd_type2_data->end_time.month;
|
|
end_tm.tm_mday = rsd_type2_data->end_time.day;
|
|
end_tm.tm_hour = rsd_type2_data->end_time.hour;
|
|
end_tm.tm_min = rsd_type2_data->end_time.minute;
|
|
end_tm.tm_sec = rsd_type2_data->end_time.second;
|
|
|
|
read_tm.tm_year = (uint8_t)lc_cache->year + 2000;
|
|
read_tm.tm_mon = (uint8_t)lc_cache->month;
|
|
read_tm.tm_mday = (uint8_t)lc_cache->day;
|
|
read_tm.tm_hour = (uint8_t)lc_cache->hour;
|
|
read_tm.tm_min = (uint8_t)lc_cache->minute;
|
|
read_tm.tm_sec = 0;
|
|
iot_sg_printf("%s start time %lu-%lu-%lu %lu:%lu:%lu,"
|
|
"read time %lu-%lu-%lu %lu:%lu:%lu\n", __FUNCTION__,
|
|
start_tm.tm_year, start_tm.tm_mon, start_tm.tm_mday,
|
|
start_tm.tm_hour, start_tm.tm_min, start_tm.tm_sec,
|
|
read_tm.tm_year, read_tm.tm_mon, read_tm.tm_mday,
|
|
read_tm.tm_hour, read_tm.tm_min, read_tm.tm_sec);
|
|
if (iot_rtc_delta_calc(&end_tm, &read_tm) > 0) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
resp_pkt = iot_sg_sta_fill_698_frozen_data(lc_cache,
|
|
&rsd_type2_data->rcsd, len, oad, server_addr, piid);
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
iot_sg_printf("%s read %s reason %lu\n", __FUNCTION__,
|
|
(resp_pkt ? "success" : "fail"), reason);
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_rpt_secu_handle(uint8_t *data, uint32_t len,
|
|
server_addr_info_t *server_addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t oad, head_len;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_69845_apdu_t *req_apdu;
|
|
proto_69845_app_get_req_t *get_req;
|
|
proto_69845_app_rpt_simp_rec_req_hdr_t *simp_rec_req = NULL;
|
|
|
|
head_len = sizeof(*req_apdu) + sizeof(*get_req) + sizeof(*simp_rec_req);
|
|
if (len < head_len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
len -= head_len;
|
|
req_apdu = (proto_69845_apdu_t *)data;
|
|
if (req_apdu->type != PROTO_69845_C_APP_GET_REQ) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
get_req = (proto_69845_app_get_req_t *)req_apdu->data;
|
|
if (get_req->data_type != PROTO_69845_APP_GET_RECORD) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
|
|
simp_rec_req = (proto_69845_app_rpt_simp_rec_req_hdr_t*)get_req->data;
|
|
oad = iot_bytes_to_uint32((uint8_t*)&simp_rec_req->oad, 1);
|
|
switch (oad) {
|
|
case PROTO_69845_APP_OAD_MINF:
|
|
{
|
|
pkt = iot_sg_sta_ext_load_698_min_frozen_rec(
|
|
simp_rec_req->rsd_road_record, len, &simp_rec_req->oad,
|
|
server_addr, &simp_rec_req->piid_acd);
|
|
break;
|
|
}
|
|
default:
|
|
reason = 4;
|
|
break;
|
|
}
|
|
|
|
out:
|
|
iot_sg_printf("%s read %s reason %lu\n", __FUNCTION__,
|
|
(pkt ? "success" : "fail"), reason);
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_br2_apdu_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len,
|
|
uint8_t apdu_type)
|
|
{
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
|
|
switch (apdu_type) {
|
|
case PROTO_69845_C_APP_GET_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_get_handle_zj(hdr_698, data, data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_ACTION_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_action_handle_zj(hdr_698, data,
|
|
data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_module_func_for_698(
|
|
proto_69845_frame_head_info_t *hdr_698, uint32_t len)
|
|
{
|
|
uint8_t *data = NULL, reason = 0, user_type = iot_sg_sta_get_user_type();
|
|
uint32_t data_len = 0;
|
|
apdu_info_t apdu = {0};
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_69845_apdu_t *req_apdu;
|
|
addr_info_t server_addr;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
iot_sg_printf("%s user_type %lu\n", __FUNCTION__, user_type);
|
|
if (proto_69845_get_apdu(hdr_698, len, &apdu)){
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
data = apdu.ptr;
|
|
data_len = apdu.len;
|
|
if (hdr_698->ctrl.flag_scramble) {
|
|
proto_69845_sub33_handle(apdu.ptr, apdu.len);
|
|
}
|
|
if (data_len < sizeof(*req_apdu)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
req_apdu = (proto_69845_apdu_t*)data;
|
|
data += sizeof(*req_apdu);
|
|
data_len -= sizeof(*req_apdu);
|
|
switch (user_type) {
|
|
case USER_TYPE_STATE_GRID_JIANGSU:
|
|
{
|
|
switch (req_apdu->type) {
|
|
case PROTO_69845_C_APP_GET_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_get_handle_js(hdr_698, data, data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_ACTION_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_action_handle_js(hdr_698, data,
|
|
data_len);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_REPORT_RESP:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_rpt_resp_handle_js(hdr_698, data,
|
|
data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_FUJIAN:
|
|
{
|
|
switch (req_apdu->type) {
|
|
case PROTO_69845_C_APP_SET_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_set_handle(hdr_698, data, data_len, 0);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_ACTION_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_action_handle(hdr_698, data,
|
|
data_len, 0);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_SECURITY_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_security_handle(hdr_698, data,
|
|
data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_STATE_GRID_HUNAN:
|
|
case USER_TYPE_STATE_GRID_MENGDONG_LC:
|
|
{
|
|
switch (req_apdu->type) {
|
|
case PROTO_69845_C_APP_GET_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_get_handle_hn(hdr_698, data, data_len);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case USER_TYPE_BRM_PEIWANG:
|
|
case USER_TYPE_BRM_PEIWANG_DUAL_NET:
|
|
{
|
|
switch (req_apdu->type) {
|
|
case PROTO_69845_C_APP_SECURITY_REQ:
|
|
{
|
|
proto_69845_app_sec_req_resp_info_t *sec_req = NULL;
|
|
sec_req = (proto_69845_app_sec_req_resp_info_t *)req_apdu->data;
|
|
if (sec_req->type != PROTO_69845_SEC_DATA_TYPE_PLAINTEXT ||
|
|
sec_req->len > data_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
proto_69845_get_addr_info(hdr_698, &server_addr);
|
|
resp_pkt = iot_sg_sta_ext_rpt_secu_handle(sec_req->data,
|
|
sec_req->len, &server_addr.ser_info);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (!resp_pkt && sta_glb->br2_enable) {
|
|
resp_pkt = iot_sg_sta_ext_br2_apdu_handle(hdr_698, data, data_len,
|
|
req_apdu->type);
|
|
}
|
|
out:
|
|
iot_sg_printf("%s read %s reason %lu\n", __FUNCTION__,
|
|
(resp_pkt ? "success" : "fail"), reason);
|
|
if ((resp_pkt == NULL) && hdr_698->ctrl.flag_scramble
|
|
&& apdu.ptr && apdu.len) {
|
|
proto_69845_add33_handle(apdu.ptr, apdu.len);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_module_698_handle(uint8_t data_type,
|
|
iot_pkt_t *pkt)
|
|
{
|
|
uint8_t *data, reason = 0, flag_trans = 1;
|
|
uint32_t len, ret = ERR_OK;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_69845_frame_head_info_t *hdr_698;
|
|
addr_info_t addr_info = {0};
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
data = iot_pkt_data(pkt);
|
|
len = iot_pkt_data_len(pkt);
|
|
hdr_698 = proto_69845_sanity_check(data, (uint16_t)len);
|
|
if (!hdr_698) {
|
|
reason = 1;
|
|
ret = ERR_NOSUPP;
|
|
goto out;
|
|
}
|
|
if (hdr_698->ctrl.fn != PROTO_69845_FN_USER_DATA
|
|
|| hdr_698->ctrl.fragment != PROTO_69845_APDU_WHOLE) {
|
|
reason = 2;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_CLIENT_RESPONSE
|
|
&& hdr_698->ctrl.dir_prm != PROTO_69845_D_P_CLIENT_REQUEST) {
|
|
reason = 3;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (!iot_sg_sta_ext_judge_module_func_for_698(hdr_698)) {
|
|
reason = 4;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
proto_69845_get_addr_info(hdr_698, &addr_info);
|
|
if (iot_sg_sta_ext_module_698_addr_check(&addr_info.ser_info, &flag_trans)
|
|
!= ERR_OK) {
|
|
reason = 5;
|
|
ret = ERR_INVAL;
|
|
if (flag_trans) {
|
|
goto out;
|
|
} else {
|
|
goto nack;
|
|
}
|
|
}
|
|
resp_pkt = iot_sg_sta_ext_module_func_for_698(hdr_698,
|
|
hdr_698->len + PROTO_69845_START_END_LEN);
|
|
if (resp_pkt) {
|
|
iot_sg_sta_meter_read_done_framework(data_type, resp_pkt);
|
|
} else {
|
|
nack:
|
|
ret = ERR_INVAL;
|
|
if (iot_sg_sta_get_user_type() == USER_TYPE_STATE_GRID_JIANGSU
|
|
|| (sta_glb->br2_enable && !flag_trans)) {
|
|
iot_sg_sta_meter_read_done_framework(data_type, resp_pkt);
|
|
ret = ERR_OK;
|
|
}
|
|
}
|
|
out:
|
|
iot_sg_printf("%s reason %lu\n", __FUNCTION__, reason);
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_fwd_mod_check()
|
|
{
|
|
uint8_t work_code;
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
gw_app_header_t *hdr;
|
|
nw_app_header_t *req_hdr;
|
|
nw_app_data_t *data_hdr;
|
|
nw_app_fwd_module_dl_t *fwd_module;
|
|
|
|
if (!sta_glb->req.pkt) {
|
|
goto out;
|
|
}
|
|
if (sta_glb->proto == IOT_SG_STA_APP_PROTO_GW) {
|
|
hdr = (gw_app_header_t *)iot_pkt_block_ptr(sta_glb->req.pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
if (hdr->id == GW_APP_ID_HISTORY_DATA_READ) {
|
|
ret = ERR_OK;
|
|
}
|
|
} else if (sta_glb->proto == IOT_SG_STA_APP_PROTO_NW) {
|
|
req_hdr = (nw_app_header_t *)iot_pkt_block_ptr(sta_glb->req.pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
data_hdr = (nw_app_data_t *)(req_hdr + 1);
|
|
if (req_hdr->port == NW_APP_PORT_MGR &&
|
|
data_hdr->control_field.frame_type == NW_APP_FRAME_TYPE_DATA_FWD &&
|
|
data_hdr->work_id == NW_APP_WORK_DATA_FWD_TRANS_MODULE) {
|
|
fwd_module = (nw_app_fwd_module_dl_t *)data_hdr->data;
|
|
if (iot_sg_sta_get_user_type() ==
|
|
USER_TYPE_SOUTHEN_POWER_GRID_SHENZHEN) {
|
|
work_code = fwd_module->work_code_other;
|
|
} else {
|
|
work_code = fwd_module->work_code;
|
|
}
|
|
if (work_code != NW_APP_WORK_CODE_TRANS_645) {
|
|
ret = ERR_OK;
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_module_handle(uint8_t data_type, iot_pkt_t *pkt)
|
|
{
|
|
uint32_t ret;
|
|
ret = iot_sg_sta_ext_module_645_handle(data_type, pkt);
|
|
if (ret != ERR_NOSUPP) {
|
|
if (ret) {
|
|
ret = ERR_FAIL;
|
|
}
|
|
goto out;
|
|
}
|
|
ret = iot_sg_sta_ext_module_698_handle(data_type, pkt);
|
|
if (ret != ERR_NOSUPP) {
|
|
if (ret) {
|
|
ret = ERR_FAIL;
|
|
}
|
|
}
|
|
out:
|
|
if (ret != ERR_OK) {
|
|
ret = iot_sg_sta_ext_fwd_mod_check();
|
|
if (ret == ERR_OK) {
|
|
iot_sg_sta_meter_read_done_framework(data_type, NULL);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_correct_handle(iot_pkt_t *pkt)
|
|
{
|
|
return iot_sg_sta_ext_module_corr_645_handle(pkt);
|
|
}
|
|
|
|
#endif /* IOT_SMART_GRID_EXT_FUNC_ENABLE */
|