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

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, &para_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 */