3046 lines
103 KiB
C
3046 lines
103 KiB
C
/****************************************************************************
|
||
|
||
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
||
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
be copied by any method or incorporated into another program without
|
||
the express written consent of Aerospace C.Power. This Information or any portion
|
||
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
liability for its use in any way and conveys no license or title under
|
||
any patent or copyright and makes no representation or warranty that this
|
||
Information is free from patent or copyright infringement.
|
||
|
||
****************************************************************************/
|
||
/* os_shim header files */
|
||
#include "os_utils_api.h"
|
||
|
||
/* iot common header files */
|
||
#include "iot_io_api.h"
|
||
#include "iot_oem_api.h"
|
||
|
||
/* smart grid internal header files */
|
||
#include "iot_sg_fr.h"
|
||
#include "iot_sg.h"
|
||
#include "proto_645.h"
|
||
#include "proto_69845.h"
|
||
#include "iot_sg_sta.h"
|
||
#include "iot_sg_sta_ext.h"
|
||
#include "iot_sg_sta_flash.h"
|
||
#include "iot_sg_sta_cfg_flash.h"
|
||
|
||
#if (IOT_SMART_GRID_GW_V28_ENABLE)
|
||
|
||
/* define 69845 meter data collection frame max oi number */
|
||
#define IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM (6)
|
||
|
||
/* define gw data collect all task id number */
|
||
#define IOT_SG_STA_EXT_GW_CLCT_TASK_ID_ALL (0xFF)
|
||
|
||
/* define gw data collect state */
|
||
#define IOT_SG_STA_EXT_GW_CLCT_STATE_IDLE (0)
|
||
#define IOT_SG_STA_EXT_GW_CLCT_STATE_SEND (1)
|
||
#define IOT_SG_STA_EXT_GW_CLCT_STATE_WAIT (2)
|
||
#define IOT_SG_STA_EXT_GW_CLCT_STATE_END (3)
|
||
|
||
/* define gw recorde data collect delay time, unit is 1s */
|
||
#define IOT_SG_STA_EXT_GW_RECORD_CLCT_DELAY (5)
|
||
|
||
/* define gw v2.8 data collection report unit max len */
|
||
#define IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN (450)
|
||
/* define gw v2.8 data collection report unit min len */
|
||
#define IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MIN_LEN (50)
|
||
|
||
/* define gw v2.8 data collection report cache pkt len */
|
||
#define IOT_SG_STA_EXT_GW_V28_RPT_PKT_LEN_2K (2048)
|
||
#define IOT_SG_STA_EXT_GW_V28_RPT_PKT_LEN_1K (1024)
|
||
|
||
/* define gw v2.8 data collection unit report state */
|
||
#define IOT_SG_STA_EXT_GW_V28_UNIT_RPT_IDLE (0)
|
||
#define IOT_SG_STA_EXT_GW_V28_UNIT_RPT_START (1)
|
||
#define IOT_SG_STA_EXT_GW_V28_UNIT_RPT_ONGOING (2)
|
||
|
||
/* define node reprot converge time, unit is 1s */
|
||
#define IOT_SG_STA_EXT_GW_NODE_RPT_CNVG_TIME (4)
|
||
|
||
/* define gw recorde data report state */
|
||
#define IOT_SG_STA_EXT_GW_RPT_STATE_IDLE (0)
|
||
#define IOT_SG_STA_EXT_GW_RPT_STATE_READY (1)
|
||
#define IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT (2)
|
||
#define IOT_SG_STA_EXT_GW_RPT_STATE_RPTING (3)
|
||
|
||
/* define gw recorde data report cycle, unit is 1s */
|
||
#define IOT_SG_STA_EXT_GW_RPT_CYCLE (12)
|
||
|
||
/* define gw recorde data report duration, unit is 1ms */
|
||
#define IOT_SG_STA_EXT_GW_RPT_DUR (4000)
|
||
|
||
/* define gw recorde data report random delay time, unit is 1ms */
|
||
#define IOT_SG_STA_EXT_GW_RPT_RANDOM_DUR (2000)
|
||
|
||
/* define max trigger time of recorde data report state machine, unit is 1ms */
|
||
#define IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MAX_TIME (2000)
|
||
|
||
/* define min trigger time of recorde data report state machine, unit is 1ms */
|
||
#define IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME (1)
|
||
|
||
/* define recorde data report fail max cnt */
|
||
#define IOT_SG_STA_EXT_GW_RPT_FAIL_CNT_MAX (3)
|
||
|
||
/* define clear unit info time stamp, unit is 1s */
|
||
#define IOT_SG_STA_EXT_GW_RPT_CLEAR_UNIT_TS (60)
|
||
|
||
uint32_t iot_sg_sta_ext_gw_data_clct_cfg_get(uint8_t *addr,
|
||
uint8_t task_id, iot_sg_sta_drv_meter_gw_clct_task_info_t *task_info)
|
||
{
|
||
uint32_t ret;
|
||
|
||
ret = iot_sg_sta_flash_clct_task_info_get(addr, task_id,
|
||
(uint8_t *)task_info, sizeof(*task_info),
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK);
|
||
return ret;
|
||
}
|
||
|
||
static uint8_t iot_sg_sta_ext_gw_data_clct_task_same_check(
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *local_cfg,
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *add_cfg)
|
||
{
|
||
uint8_t same_flag = 0;
|
||
|
||
if (!local_cfg || !add_cfg) {
|
||
goto out;
|
||
}
|
||
if (local_cfg->pm_type == add_cfg->pm_type &&
|
||
local_cfg->proto_type == add_cfg->proto_type &&
|
||
local_cfg->period == add_cfg->period &&
|
||
local_cfg->di_cnt == add_cfg->di_cnt &&
|
||
!os_mem_cmp(local_cfg->di_info, add_cfg->di_info,
|
||
sizeof(iot_sg_sta_drv_meter_gw_di_info_t) * local_cfg->di_cnt)) {
|
||
same_flag = 1;
|
||
}
|
||
out:
|
||
return same_flag;
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_clct_task_add(iot_sg_sta_node_desc_t *node,
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *cfg)
|
||
{
|
||
uint8_t reason = 0;
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_pkt_t *task_pkt = NULL;
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *task_info;
|
||
|
||
if (!cfg || !cfg->id) {
|
||
reason = 1;
|
||
goto out;
|
||
}
|
||
task_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
||
if (!task_pkt) {
|
||
reason = 2;
|
||
goto out;
|
||
}
|
||
task_info = (iot_sg_sta_drv_meter_gw_clct_task_info_t *)
|
||
iot_pkt_put(task_pkt, sizeof(*task_info));
|
||
if (!iot_sg_sta_ext_gw_data_clct_cfg_get(node->entry.addr, cfg->id,
|
||
task_info)) {
|
||
if (iot_sg_sta_ext_gw_data_clct_task_same_check(task_info, cfg)) {
|
||
ret = ERR_OK;
|
||
goto out;
|
||
}
|
||
}
|
||
if (iot_sg_sta_flash_clct_task_add(node->entry.addr, (uint8_t *)cfg,
|
||
sizeof(*cfg), IOT_SG_STA_METER_DATA_TYPE_GW_TASK) != ERR_OK) {
|
||
reason = 4;
|
||
goto out;
|
||
}
|
||
os_mem_set(&node->ext.gw_node_clct_info.task_tm[cfg->id - 1], 0x0,
|
||
sizeof(iot_time_tm_t));
|
||
ret = ERR_OK;
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
if (task_pkt) {
|
||
iot_pkt_free(task_pkt);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_clct_task_del_all(uint8_t *addr)
|
||
{
|
||
uint8_t i;
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_pkt_t *pkt;
|
||
iot_sg_sta_flash_clct_task_id_t *task_id_info = NULL;
|
||
|
||
pkt = iot_sg_sta_flash_clct_task_id_info_get(addr);
|
||
if (pkt == NULL) {
|
||
goto out;
|
||
}
|
||
task_id_info = (iot_sg_sta_flash_clct_task_id_t*)iot_pkt_data(pkt);
|
||
for (i = 0; i < task_id_info->cnt; i++) {
|
||
if (iot_sg_sta_flash_clct_task_del(addr, task_id_info->task_id[i], 1,
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK) == ERR_OK) {
|
||
ret = ERR_OK;
|
||
}
|
||
}
|
||
out:
|
||
if (pkt) {
|
||
iot_pkt_free(pkt);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_clct_task_del(iot_sg_sta_node_desc_t *node,
|
||
uint8_t task_id)
|
||
{
|
||
uint8_t reason = 0;
|
||
uint32_t ret = ERR_FAIL;
|
||
|
||
if (!node || !task_id) {
|
||
reason = 1;
|
||
goto out;
|
||
}
|
||
if (task_id == IOT_SG_STA_EXT_GW_CLCT_TASK_ID_ALL) {
|
||
ret = iot_sg_sta_ext_gw_clct_task_del_all(node->entry.addr);
|
||
if (ret != ERR_OK) {
|
||
reason = 2;
|
||
goto out;
|
||
}
|
||
os_mem_set(node->ext.gw_node_clct_info.task_tm, 0x0,
|
||
sizeof(node->ext.gw_node_clct_info.task_tm));
|
||
} else {
|
||
ret = iot_sg_sta_flash_clct_task_del(node->entry.addr, task_id, 1,
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK);
|
||
if (ret != ERR_OK) {
|
||
reason = 3;
|
||
goto out;
|
||
}
|
||
os_mem_set(&node->ext.gw_node_clct_info.task_tm[task_id - 1], 0x0,
|
||
sizeof(iot_time_tm_t));
|
||
}
|
||
ret = ERR_OK;
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_data_clct_handle(uint16_t seq,
|
||
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
|
||
uint8_t *req_data, uint16_t req_len)
|
||
{
|
||
uint32_t ret;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
|
||
if (data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
ret = iot_sg_ext_read_698_data_handle(seq, data_type, resp_data,
|
||
resp_len, req_data, req_len);
|
||
} else {
|
||
ret = iot_sg_ext_read_645_07_data_handle(seq, data_type, resp_data,
|
||
resp_len, req_data, req_len, NULL);
|
||
}
|
||
if (ret == ERR_OK || ret == ERR_TIMEOVER) {
|
||
if (ret == ERR_OK) {
|
||
ext_info->gw_clct_info->flag_resp = 1;
|
||
}
|
||
ext_info->gw_clct_info->timeout_cnt = 0;
|
||
iot_sg_sta_ext_sm_stop_action();
|
||
iot_sg_sta_ext_sm_next_action(IOT_SG_STA_EXT_SM_MIN_DELAY);
|
||
}
|
||
}
|
||
|
||
static void iot_sg_ext_gw_data_clct_cur_info_clear(
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info)
|
||
{
|
||
if (!clct_info) {
|
||
return;
|
||
}
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_IDLE;
|
||
clct_info->flag_resp = 0;
|
||
clct_info->repeat_cnt = 0;
|
||
clct_info->timeout_cnt = 0;
|
||
clct_info->index = 0;
|
||
clct_info->last_index_698 = 0;
|
||
}
|
||
|
||
/* device detect time out function */
|
||
static void iot_sg_sta_ext_gw_clct_rpt_func(timer_id_t timer_id,
|
||
void *arg)
|
||
{
|
||
(void)timer_id;
|
||
(void)arg;
|
||
iot_sg_msg_t *msg;
|
||
|
||
msg = (iot_sg_msg_t *)iot_task_alloc_msg(p_sg_glb->task_h);
|
||
if (msg) {
|
||
msg->task_msg.type = IOT_SG_MSG_TYPE_TIMER;
|
||
msg->task_msg.id = IOT_SG_MSG_ID_TIMER_GW_RPT_DELAY;
|
||
iot_task_queue_msg(p_sg_glb->task_h, &msg->task_msg,
|
||
IOT_SG_MSG_QUEUE_LP);
|
||
} else {
|
||
IOT_ASSERT(0);
|
||
}
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_clct_task_init(void)
|
||
{
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
|
||
sta_glb->ext_info.gw_clct_info = os_mem_malloc(IOT_SMART_GRID_MID,
|
||
sizeof(iot_sg_sta_ext_gw_clct_info_t));
|
||
if (sta_glb->ext_info.gw_clct_info == NULL) {
|
||
goto out;
|
||
}
|
||
sta_glb->ext_info.gw_clct_info->report_info.rpt_timer = os_create_timer(
|
||
IOT_SMART_GRID_MID, false, iot_sg_sta_ext_gw_clct_rpt_func, NULL);
|
||
if (sta_glb->ext_info.gw_clct_info->report_info.rpt_timer == 0) {
|
||
goto drop;
|
||
}
|
||
sta_glb->ext_info.gw_clct_info->cur_task_id = 1;
|
||
sta_glb->ext_info.gw_clct_info->report_info.flag_en = 0;
|
||
ret = ERR_OK;
|
||
goto out;
|
||
drop:
|
||
os_mem_free(sta_glb->ext_info.gw_clct_info);
|
||
sta_glb->ext_info.gw_clct_info = NULL;
|
||
out:
|
||
return ret;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_data_clct_task_deinit(void)
|
||
{
|
||
uint8_t i;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info) {
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_CACHE_PKT_CNT; i++) {
|
||
if (!sta_glb->ext_info.gw_clct_info->report_info.pkt[i]) {
|
||
continue;
|
||
}
|
||
iot_pkt_free(sta_glb->ext_info.gw_clct_info->report_info.pkt[i]);
|
||
}
|
||
if (sta_glb->ext_info.gw_clct_info->freeze_698_pkt) {
|
||
iot_pkt_free(sta_glb->ext_info.gw_clct_info->freeze_698_pkt);
|
||
}
|
||
os_delete_timer(sta_glb->ext_info.gw_clct_info->report_info.rpt_timer);
|
||
os_mem_free(sta_glb->ext_info.gw_clct_info);
|
||
sta_glb->ext_info.gw_clct_info = NULL;
|
||
}
|
||
}
|
||
|
||
uint8_t iot_sg_sta_ext_gw_clct_check_supp(void)
|
||
{
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info) {
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_data_clct_node_tm_update(iot_sg_sta_node_desc_t *node)
|
||
{
|
||
uint8_t i, task_id;
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *task_info;
|
||
iot_pkt_t *task_pkt = NULL;
|
||
|
||
task_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
||
if (!task_pkt) {
|
||
goto out;
|
||
}
|
||
task_info = (iot_sg_sta_drv_meter_gw_clct_task_info_t *)
|
||
iot_pkt_put(task_pkt, sizeof(*task_info));
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_CLCT_TASK_MAX_CNT; i++) {
|
||
task_id = i + 1;
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(node->entry.addr, task_id,
|
||
task_info) != ERR_OK) {
|
||
continue;
|
||
}
|
||
if (iot_sg_sta_ext_node_tm_check(&node->ext.gw_node_clct_info.task_tm[i],
|
||
task_info->period * 60)) {
|
||
os_mem_set(&node->ext.gw_node_clct_info.task_tm[i], 0x0,
|
||
sizeof(iot_time_tm_t));
|
||
}
|
||
}
|
||
out:
|
||
if (task_pkt) {
|
||
iot_pkt_free(task_pkt);
|
||
}
|
||
}
|
||
|
||
#if IOT_SMART_GRID_GW_V28_OP2_ENABLE
|
||
|
||
static iot_pkt_t *iot_sg_sta_ext_gw_69845_recorde_msg_build(uint8_t *addr,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info)
|
||
{
|
||
uint8_t di_cnt, i, *time_tag, csd_len, cur_index = 0;;
|
||
uint32_t get_record_size, oad;
|
||
server_addr_info_t server = {0};
|
||
proto_69845_app_get_req_record_t *req;
|
||
proto_69845_app_req_resp_t *apdu;
|
||
proto_69845_app_get_req_t *get_req;
|
||
proto_69845_app_data_rcsd_t *rcsd;
|
||
proto_69845_app_data_rsd_t *rsd;
|
||
proto_69845_app_data_rsd_type9_t *type_9;
|
||
proto_69845_app_data_csd_t *csd = NULL;
|
||
iot_pkt_t *pkt = NULL, *get_req_record = NULL;
|
||
|
||
csd_len = sizeof(*csd) + sizeof(oad);
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
goto out;
|
||
}
|
||
if (!clct_info->index) {
|
||
di_cnt = 1;
|
||
} else {
|
||
di_cnt = clct_info->cur_clct_cfg.di_cnt - clct_info->index;
|
||
}
|
||
if (di_cnt > IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM) {
|
||
di_cnt = IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM;
|
||
}
|
||
get_record_size = sizeof(*apdu) + sizeof(*get_req) + sizeof(*req) +
|
||
sizeof(*rsd) + sizeof(*type_9) + sizeof(*rcsd) + (csd_len * di_cnt)
|
||
+ sizeof(*time_tag);
|
||
get_req_record = iot_pkt_alloc(get_record_size, IOT_SMART_GRID_MID);
|
||
if (!get_req_record) {
|
||
goto out;
|
||
}
|
||
apdu = (proto_69845_app_req_resp_t *)iot_pkt_put(get_req_record,
|
||
get_record_size);
|
||
apdu->type = PROTO_69845_C_APP_GET_REQ;
|
||
get_req = (proto_69845_app_get_req_t *)apdu->data;
|
||
get_req->data_type = PROTO_69845_APP_GET_RECORD;
|
||
req = (proto_69845_app_get_req_record_t *)get_req->data;
|
||
req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
|
||
req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
|
||
oad = clct_info->cur_clct_cfg.di_info[0].di;
|
||
iot_uint32_to_bytes(oad, (uint8_t *)&req->oad, 1);
|
||
rsd = (proto_69845_app_data_rsd_t *)req->rsd_and_rcsd;
|
||
rsd->type = PROTO_OI_RSD_TYPE_9;
|
||
type_9 = (proto_69845_app_data_rsd_type9_t *)rsd->rsd_data;
|
||
type_9->times = 1;
|
||
rcsd = (proto_69845_app_data_rcsd_t *)(rsd->rsd_data + sizeof(*type_9));
|
||
if (!clct_info->index) {
|
||
oad = PROTO_69845_APP_OAD_FROZEN_T;
|
||
csd = (proto_69845_app_data_csd_t *)rcsd->csd_list;
|
||
csd->type = PROTO_OI_CSD_TYPE_OAD;
|
||
iot_uint32_to_bytes(oad, (uint8_t *)&csd->csd_data, 1);
|
||
rcsd->cnt = 1;
|
||
} else {
|
||
for (i = 0; i < di_cnt; i++) {
|
||
oad = clct_info->cur_clct_cfg.di_info[clct_info->index + i].di;
|
||
cur_index = clct_info->index + i;
|
||
if (oad != PROTO_69845_APP_OAD_INVALID &&
|
||
oad != PROTO_69845_APP_OAD_FROZEN_T) {
|
||
csd = (proto_69845_app_data_csd_t *)(rcsd->csd_list +
|
||
(csd_len * i));
|
||
csd->type = PROTO_OI_CSD_TYPE_OAD;
|
||
if (oad != PROTO_69845_APP_OAD_GND_CURRENT) {
|
||
oad &= 0xffff0000;
|
||
oad |= 0x00000200;
|
||
}
|
||
iot_uint32_to_bytes(oad, (uint8_t *)&csd->csd_data, 1);
|
||
rcsd->cnt++;
|
||
}
|
||
}
|
||
}
|
||
clct_info->index = cur_index;
|
||
time_tag = csd->csd_data + csd_len;
|
||
*time_tag = 0;
|
||
server.len = PROTO_69845_SA_LEN;
|
||
server.type = PROTO_69845_SA_TYPE_SIG;
|
||
iot_mac_addr_cpy(server.addr, addr);
|
||
get_record_size = sizeof(*apdu) + sizeof(*get_req) + sizeof(*req) +
|
||
sizeof(*rsd) + sizeof(*type_9) + sizeof(*rcsd) + (csd_len * rcsd->cnt)
|
||
+ sizeof(*time_tag);
|
||
pkt = proto_69845_build_apdu_data_with_rn_msg((uint8_t *)apdu,
|
||
get_record_size, &server);
|
||
out:
|
||
if (get_req_record) {
|
||
iot_pkt_free(get_req_record);
|
||
}
|
||
return pkt;
|
||
}
|
||
|
||
static iot_pkt_t *iot_sg_sta_ext_gw_69845_normal_msg_build(uint8_t *addr,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info)
|
||
{
|
||
uint32_t get_list_req_size, oad;
|
||
uint8_t di_cnt, i, oad_idx = 0, attribute, cur_index = 0;
|
||
iot_pkt_t *pkt = NULL, *get_list_req = NULL;
|
||
proto_69845_app_get_list_req_info_t *req = NULL;
|
||
server_addr_info_t server = {0};
|
||
|
||
if (!clct_info->index) {
|
||
clct_info->index++;
|
||
}
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
goto out;
|
||
}
|
||
di_cnt = clct_info->cur_clct_cfg.di_cnt - clct_info->index;
|
||
if (di_cnt > IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM) {
|
||
di_cnt = IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM;
|
||
}
|
||
get_list_req_size = sizeof(proto_69845_app_oad_t) * di_cnt + sizeof(*req);
|
||
get_list_req = iot_pkt_alloc(get_list_req_size, IOT_SMART_GRID_MID);
|
||
if (!get_list_req) {
|
||
goto out;
|
||
}
|
||
req = (proto_69845_app_get_list_req_info_t *)iot_pkt_put(get_list_req,
|
||
get_list_req_size);
|
||
req->type = PROTO_69845_APP_GET_NORMALLIST;
|
||
req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
|
||
req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
|
||
/* fill di from di_buff */
|
||
for (i = 0; i < di_cnt; i++) {
|
||
if (clct_info->index + i >= IOT_SG_STA_METER_CLCT_TASK_DI_CNT_GW) {
|
||
break;
|
||
}
|
||
oad = clct_info->cur_clct_cfg.di_info[clct_info->index + i].di;
|
||
cur_index = clct_info->index + i;
|
||
if (oad != PROTO_69845_APP_OAD_INVALID &&
|
||
oad != PROTO_69845_APP_OAD_FROZEN_T) {
|
||
if (oad != PROTO_69845_APP_OAD_GND_CURRENT) {
|
||
oad &= 0xffff0000;
|
||
oad |= 0x00000200;
|
||
}
|
||
req->oad[oad_idx].oi = (uint16_t)(oad >> 16);
|
||
attribute = (oad >> 8) & 0xff;
|
||
req->oad[oad_idx].attribute_id = attribute & 0x1f;
|
||
req->oad[oad_idx].attribute_char = attribute >> 5;
|
||
req->oad[oad_idx].element_index = oad & 0xff;
|
||
oad_idx++;
|
||
}
|
||
}
|
||
clct_info->index = cur_index;
|
||
req->oad_cnt = oad_idx;
|
||
server.len = PROTO_69845_SA_LEN;
|
||
server.type = PROTO_69845_SA_TYPE_SIG;
|
||
iot_mac_addr_cpy(server.addr, addr);
|
||
pkt = proto_69845_build_get_req_msg_with_rn(req, &server);
|
||
iot_pkt_free(get_list_req);
|
||
out:
|
||
return pkt;
|
||
}
|
||
|
||
static iot_pkt_t * iot_sg_sta_ext_gw_69845_lr_mr_msg_build(uint8_t *addr,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info)
|
||
{
|
||
iot_pkt_t *pkt;
|
||
|
||
if (clct_info->cur_clct_cfg.di_info[0].di == PROTO_69845_APP_OAD_MINF &&
|
||
clct_info->cur_clct_cfg.period < (IOT_SG_STA_EXT_CLCT_PRD_15MIN / 60)) {
|
||
pkt = iot_sg_sta_ext_gw_69845_normal_msg_build(addr, clct_info);
|
||
} else {
|
||
pkt = iot_sg_sta_ext_gw_69845_recorde_msg_build(addr, clct_info);
|
||
}
|
||
|
||
return pkt;
|
||
}
|
||
|
||
static uint8_t iot_sg_sta_ext_gw_get_rpt_sn(
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info)
|
||
{
|
||
clct_info->seq_698_msg++;
|
||
if (clct_info->seq_698_msg > PROTO_69845_RPT_MAX_SN) {
|
||
clct_info->seq_698_msg = 0;
|
||
}
|
||
return clct_info->seq_698_msg;
|
||
}
|
||
|
||
static uint16_t iot_sg_sta_ext_gw_698_single_element_data_fill(uint32_t oad,
|
||
uint8_t *data, uint32_t data_len, iot_time_tm_t *node_tm)
|
||
{
|
||
int32_t tmp_32;
|
||
int16_t tmp_16, fill_len = 0, year;
|
||
uint8_t *meter_data, meter_data_len, data_type, unit_len_698, is_signed = 0;
|
||
proto_69845_app_data_t *app_data;
|
||
proto_69845_app_data_time_s_t *data_time;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
|
||
|
||
switch (oad) {
|
||
/* TODO: add di here in the future */
|
||
case PROTO_69845_APP_OAD_FROZEN_T:
|
||
{
|
||
if (data_len < sizeof(*app_data) + sizeof(*data_time)) {
|
||
goto out;
|
||
}
|
||
fill_len = sizeof(*app_data) + sizeof(*data_time);
|
||
app_data = (proto_69845_app_data_t*)data;
|
||
app_data->data_type = PROTO_69845_APP_DATA_TIME_S;
|
||
data_time = (proto_69845_app_data_time_s_t*)app_data->data;
|
||
if (proto_645_bcd_data_check((uint8_t*)&meter->frozen_time,
|
||
sizeof(proto_645_07_frozen_time_t), 0)) {
|
||
year = iot_bcd_to_byte(meter->frozen_time.year) + 2000;
|
||
iot_uint16_to_bytes(year, (uint8_t*)&data_time->year, 1);
|
||
data_time->month = iot_bcd_to_byte(meter->frozen_time.month);
|
||
data_time->day = iot_bcd_to_byte(meter->frozen_time.day);
|
||
data_time->hour = iot_bcd_to_byte(meter->frozen_time.hour);
|
||
data_time->minute = iot_bcd_to_byte(meter->frozen_time.minute);
|
||
data_time->second = 0;
|
||
} else {
|
||
iot_uint16_to_bytes(node_tm->tm_year,
|
||
(uint8_t*)&data_time->year, 1);
|
||
data_time->month = node_tm->tm_mon;
|
||
data_time->day = node_tm->tm_mday;
|
||
data_time->hour = node_tm->tm_hour;
|
||
data_time->minute = node_tm->tm_min;
|
||
data_time->second = 0;
|
||
}
|
||
goto out;
|
||
}
|
||
case PROTO_69845_APP_OAD_VOLTAGE_A:
|
||
{
|
||
meter_data = meter->v.a;
|
||
meter_data_len = PROTO_645_V_LEN;
|
||
data_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_CURRENT_A:
|
||
{
|
||
meter_data = meter->a.a;
|
||
meter_data_len = PROTO_645_07_A_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_GND_CURRENT:
|
||
{
|
||
meter_data = meter->gnd_a;
|
||
meter_data_len = PROTO_645_07_A_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P_T:
|
||
{
|
||
meter_data = meter->ap.total;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P_A:
|
||
{
|
||
meter_data = meter->ap.a;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_Q_T:
|
||
{
|
||
meter_data = meter->rp.total;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_Q_A:
|
||
{
|
||
meter_data = meter->rp.a;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
||
{
|
||
meter_data = meter->pae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
||
{
|
||
meter_data = meter->nae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_COMP_SUM:
|
||
{
|
||
meter_data = meter->cae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_POS_SUM:
|
||
{
|
||
meter_data = meter->cre1.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_NEG_SUM:
|
||
{
|
||
meter_data = meter->cre2.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
|
||
{
|
||
meter_data = meter->re_1st.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
|
||
{
|
||
meter_data = meter->re_2st.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
|
||
{
|
||
meter_data = meter->re_3st.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
|
||
{
|
||
meter_data = meter->re_4st.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_DEMAND:
|
||
{
|
||
meter_data = meter->ept_demand;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_DEMAND:
|
||
{
|
||
meter_data = meter->eqt_demand;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
break;
|
||
}
|
||
default:
|
||
goto out;
|
||
}
|
||
if (data_type == PROTO_69845_APP_DATA_DOUBLE_LONG ||
|
||
data_type == PROTO_69845_APP_DATA_LONG) {
|
||
is_signed = 1;
|
||
}
|
||
if (data_type == PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED ||
|
||
data_type == PROTO_69845_APP_DATA_DOUBLE_LONG) {
|
||
unit_len_698 = PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
||
} else {
|
||
unit_len_698 = PROTO_69845_METER_DATA_LONG_LEN;
|
||
}
|
||
if (!proto_645_bcd_data_check(meter_data, meter_data_len, is_signed)) {
|
||
data_type = PROTO_69845_APP_DATA_NULL;
|
||
unit_len_698 = 0;
|
||
}
|
||
if (data_len < sizeof(*app_data) + unit_len_698) {
|
||
goto out;
|
||
}
|
||
app_data = (proto_69845_app_data_t *)data;
|
||
app_data->data_type = data_type;
|
||
if (unit_len_698 == PROTO_69845_METER_DATA_DOUBLE_LONG_LEN) {
|
||
tmp_32 = proto_645_bcd_to_integer(meter_data, meter_data_len,
|
||
is_signed);
|
||
iot_uint32_to_bytes((uint32_t)tmp_32, app_data->data, 1);
|
||
} else if (unit_len_698 == PROTO_69845_METER_DATA_LONG_LEN) {
|
||
tmp_16 = (int16_t)proto_645_bcd_to_integer(meter_data, meter_data_len,
|
||
is_signed);
|
||
iot_uint16_to_bytes((uint16_t)tmp_16, app_data->data, 1);
|
||
}
|
||
fill_len += sizeof(*app_data) + unit_len_698;
|
||
out:
|
||
return fill_len;
|
||
}
|
||
|
||
static uint16_t iot_sg_sta_ext_gw_698_multi_element_data_fill(uint32_t oad,
|
||
uint8_t *data, uint32_t data_len, uint8_t flag_3p)
|
||
{
|
||
int32_t tmp_32;
|
||
int16_t tmp_16, fill_len = 0;
|
||
uint8_t ele_cnt, is_signed = 0, unit_len_698, i, *meter_data;
|
||
uint8_t data_type, meter_data_len;
|
||
proto_69845_app_ele_data_t *ele_data;
|
||
proto_69845_app_data_t *app_data;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
|
||
|
||
switch (oad) {
|
||
/* TODO: add di here in the future */
|
||
case PROTO_69845_APP_OAD_VOLTAGE:
|
||
{
|
||
meter_data = meter->v.a;
|
||
meter_data_len = PROTO_645_V_LEN;
|
||
data_type = PROTO_69845_APP_DATA_LONG_UNSIGNED;
|
||
if (flag_3p) {
|
||
ele_cnt = 3;
|
||
} else {
|
||
ele_cnt = 1;
|
||
}
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_CURRENT:
|
||
{
|
||
meter_data = meter->a.a;
|
||
meter_data_len = PROTO_645_07_A_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
if (flag_3p) {
|
||
ele_cnt = 3;
|
||
} else {
|
||
ele_cnt = 1;
|
||
}
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P:
|
||
{
|
||
meter_data = meter->ap.total;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
if (flag_3p) {
|
||
ele_cnt = 4;
|
||
} else {
|
||
ele_cnt = 2;
|
||
}
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_Q:
|
||
{
|
||
meter_data = meter->rp.total;
|
||
meter_data_len = PROTO_645_07_P_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
if (flag_3p) {
|
||
ele_cnt = 4;
|
||
} else {
|
||
ele_cnt = 2;
|
||
}
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_PF:
|
||
{
|
||
meter_data = meter->pf.total;
|
||
meter_data_len = PROTO_645_07_PF_LEN;
|
||
data_type = PROTO_69845_APP_DATA_LONG;
|
||
if (flag_3p) {
|
||
ele_cnt = 4;
|
||
} else {
|
||
ele_cnt = 2;
|
||
}
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_POS:
|
||
{
|
||
meter_data = meter->pae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
ele_cnt = 5;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_NEG:
|
||
{
|
||
meter_data = meter->nae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED;
|
||
ele_cnt = 5;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_COMP:
|
||
{
|
||
meter_data = meter->cae.total;
|
||
meter_data_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
data_type = PROTO_69845_APP_DATA_DOUBLE_LONG;
|
||
ele_cnt = 5;
|
||
break;
|
||
}
|
||
default:
|
||
goto out;
|
||
}
|
||
if (data_type == PROTO_69845_APP_DATA_DOUBLE_LONG ||
|
||
data_type == PROTO_69845_APP_DATA_LONG) {
|
||
is_signed = 1;
|
||
}
|
||
if (data_type == PROTO_69845_APP_DATA_DOUBLE_LONG_UNSIGNED ||
|
||
data_type == PROTO_69845_APP_DATA_DOUBLE_LONG) {
|
||
unit_len_698 = PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
||
} else {
|
||
unit_len_698 = PROTO_69845_METER_DATA_LONG_LEN;
|
||
}
|
||
if (data_len < sizeof(*ele_data) +
|
||
ele_cnt * (sizeof(*app_data) + unit_len_698)) {
|
||
goto out;
|
||
}
|
||
ele_data = (proto_69845_app_ele_data_t *)data;
|
||
ele_data->data_type = PROTO_69845_APP_DATA_ARRAY;
|
||
ele_data->num_of_data = ele_cnt;
|
||
fill_len += sizeof(*ele_data);
|
||
for (i = 0; i < ele_cnt; i++) {
|
||
app_data = (proto_69845_app_data_t *)(ele_data->data +
|
||
i * (sizeof(*app_data) + unit_len_698));
|
||
if (!proto_645_bcd_data_check(meter_data, meter_data_len, is_signed)) {
|
||
data_type = PROTO_69845_APP_DATA_NULL;
|
||
unit_len_698 = 0;
|
||
}
|
||
app_data->data_type = data_type;
|
||
if (unit_len_698 == PROTO_69845_METER_DATA_DOUBLE_LONG_LEN) {
|
||
tmp_32 = proto_645_bcd_to_integer(meter_data, meter_data_len,
|
||
is_signed);
|
||
iot_uint32_to_bytes((uint32_t)tmp_32, app_data->data, 1);
|
||
} else if (unit_len_698 == PROTO_69845_METER_DATA_LONG_LEN) {
|
||
tmp_16 = (int16_t)proto_645_bcd_to_integer(meter_data, meter_data_len,
|
||
is_signed);
|
||
iot_uint16_to_bytes((uint16_t)tmp_16, app_data->data, 1);
|
||
}
|
||
meter_data += meter_data_len;
|
||
fill_len += sizeof(*app_data) + unit_len_698;
|
||
}
|
||
out:
|
||
return fill_len;
|
||
}
|
||
|
||
static uint16_t iot_sg_sta_ext_gw_698_freeze_data_fill(uint32_t oad,
|
||
uint8_t *data, uint32_t data_len, uint8_t flag_3p, iot_time_tm_t *node_tm)
|
||
{
|
||
uint16_t fill_len = 0;
|
||
proto_69845_app_data_t *app_data;
|
||
|
||
switch (oad) {
|
||
/* TODO: add di here in the future */
|
||
case PROTO_69845_APP_OAD_VOLTAGE_A:
|
||
case PROTO_69845_APP_OAD_CURRENT_A:
|
||
case PROTO_69845_APP_OAD_GND_CURRENT:
|
||
case PROTO_69845_APP_OAD_P_T:
|
||
case PROTO_69845_APP_OAD_P_A:
|
||
case PROTO_69845_APP_OAD_Q_T:
|
||
case PROTO_69845_APP_OAD_Q_A:
|
||
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
||
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
||
case PROTO_69845_APP_OAD_EPT_COMP_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_POS_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_NEG_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
|
||
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
|
||
case PROTO_69845_APP_OAD_EPT_DEMAND:
|
||
case PROTO_69845_APP_OAD_EQT_DEMAND:
|
||
case PROTO_69845_APP_OAD_FROZEN_T:
|
||
{
|
||
fill_len = iot_sg_sta_ext_gw_698_single_element_data_fill(oad, data,
|
||
data_len, node_tm);
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_VOLTAGE:
|
||
case PROTO_69845_APP_OAD_CURRENT:
|
||
case PROTO_69845_APP_OAD_P:
|
||
case PROTO_69845_APP_OAD_PF:
|
||
case PROTO_69845_APP_OAD_EPT_POS:
|
||
case PROTO_69845_APP_OAD_EPT_NEG:
|
||
case PROTO_69845_APP_OAD_Q:
|
||
case PROTO_69845_APP_OAD_EPT_COMP:
|
||
{
|
||
fill_len = iot_sg_sta_ext_gw_698_multi_element_data_fill(oad, data,
|
||
data_len, flag_3p);
|
||
break;
|
||
}
|
||
default:
|
||
if (data_len >= sizeof(!app_data)) {
|
||
app_data = (proto_69845_app_data_t *)data;
|
||
app_data->data_type = PROTO_69845_APP_DATA_NULL;
|
||
fill_len = sizeof(!app_data);
|
||
}
|
||
}
|
||
return fill_len;
|
||
}
|
||
|
||
static iot_pkt_t *iot_sg_sta_ext_gw_698_freeze_msg_build(uint8_t *addr,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info, uint8_t flag_3p,
|
||
iot_time_tm_t *node_tm)
|
||
{
|
||
uint16_t fill_len, cache_fill_len = 0, head_len;
|
||
uint8_t *no_time_tag, *no_flw, attribute, i, *cache_data;
|
||
uint8_t csd_cnt = 0, di_cnt = 0, *data;
|
||
iot_pkt_t *pkt = NULL, *cache_pkt = NULL;
|
||
uint32_t len, csd_len, total_len, apdu_len, cache_len, oad;
|
||
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;
|
||
proto_69845_app_get_result_t *result_head;
|
||
proto_69845_app_rpt_array_result_t *array_result;
|
||
proto_69845_frame_head_info_t *head;
|
||
addr_info_t addr_info = { 0 };
|
||
|
||
len = sizeof(*apdu)+ sizeof(*resp) + sizeof(*simp_record_resp) +
|
||
sizeof(*rcsd_resp) + sizeof(*result_head) +
|
||
sizeof(*array_result) + PROTO_69845_NO_TIME_TAG_LEN +
|
||
PROTO_69845_NO_FLW_DATA_LEN;
|
||
cache_len = PROTO_69845_PREDICT_APDU_MAX_LEN - len;
|
||
cache_pkt = iot_pkt_alloc(cache_len, IOT_SMART_GRID_MID);
|
||
if (!cache_pkt) {
|
||
goto out;
|
||
}
|
||
cache_data = iot_pkt_put(cache_pkt, cache_len);
|
||
csd_len = sizeof(*csd) + sizeof(*oad_resp);
|
||
for (i = 0; i < clct_info->cur_clct_cfg.di_cnt; i++) {
|
||
oad = clct_info->cur_clct_cfg.di_info[i].di;
|
||
if (i == 0) {
|
||
/* current di is master di, replace with frozen time di */
|
||
oad = PROTO_69845_APP_OAD_FROZEN_T;
|
||
} else {
|
||
if (oad == PROTO_69845_APP_OAD_FROZEN_T) {
|
||
continue;
|
||
}
|
||
}
|
||
if (cache_len < csd_len) {
|
||
break;
|
||
}
|
||
cache_len -= csd_len;
|
||
fill_len = iot_sg_sta_ext_gw_698_freeze_data_fill(oad, cache_data,
|
||
cache_len, flag_3p, node_tm);
|
||
if (!fill_len || fill_len > cache_len) {
|
||
break;
|
||
}
|
||
cache_len -= fill_len;
|
||
cache_fill_len += fill_len;
|
||
cache_data += fill_len;
|
||
di_cnt++;
|
||
}
|
||
if (!di_cnt) {
|
||
goto out;
|
||
}
|
||
apdu_len = len + di_cnt * csd_len + cache_fill_len;
|
||
total_len = sizeof(*head) + PROTO_69845_SA_LEN + PROTO_69845_CA_LEN +
|
||
PROTO_69845_CHECKSUM_LEN + apdu_len + sizeof(proto_69845_tailer_t);
|
||
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
|
||
if (!pkt) {
|
||
goto out;
|
||
}
|
||
/* fill 698.45 proto header */
|
||
data = iot_pkt_put(pkt, total_len);
|
||
head = (proto_69845_frame_head_info_t *)data;
|
||
addr_info.ser_info.len = PROTO_69845_SA_LEN;
|
||
addr_info.ser_info.type = PROTO_69845_SA_TYPE_SIG;
|
||
iot_mac_addr_cpy(addr_info.ser_info.addr, addr);
|
||
addr_info.cli_addr = PROTO_69845_CA_INVAILD_ADD;
|
||
head_len = sizeof(*head) + PROTO_69845_SA_LEN
|
||
+ PROTO_69845_CA_LEN + PROTO_69845_CHECKSUM_LEN;
|
||
proto_69845_head_fill(head, 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 apdu */
|
||
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.sn = iot_sg_sta_ext_gw_get_rpt_sn(clct_info);
|
||
simp_record_resp->piid_acd.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
|
||
simp_record_resp->piid_acd.acd = 0;
|
||
oad = clct_info->cur_clct_cfg.di_info[0].di;
|
||
iot_uint16_to_bytes((uint16_t)(oad >> 16),
|
||
(uint8_t *)&simp_record_resp->oad.oi, 1);
|
||
attribute = (oad >> 8) & 0xff;
|
||
simp_record_resp->oad.attribute_id = attribute & 0x1f;
|
||
simp_record_resp->oad.attribute_char = attribute >> 5;
|
||
simp_record_resp->oad.element_index = oad & 0xff;
|
||
rcsd_resp = (proto_69845_app_data_rcsd_t*)simp_record_resp->rsd_and_road;
|
||
rcsd_resp->cnt = di_cnt;
|
||
csd = (proto_69845_app_data_csd_t *)(rcsd_resp->csd_list +
|
||
(i * csd_len));
|
||
for (i = 0; i < clct_info->cur_clct_cfg.di_cnt; i++) {
|
||
oad = clct_info->cur_clct_cfg.di_info[i].di;
|
||
if (i == 0) {
|
||
/* current di is master di, replace with frozen time di */
|
||
oad = PROTO_69845_APP_OAD_FROZEN_T;
|
||
} else {
|
||
if (oad == PROTO_69845_APP_OAD_FROZEN_T) {
|
||
continue;
|
||
}
|
||
}
|
||
csd = (proto_69845_app_data_csd_t *)(rcsd_resp->csd_list +
|
||
(csd_cnt * csd_len));
|
||
csd->type = PROTO_OI_CSD_TYPE_OAD;
|
||
oad_resp = (proto_69845_app_oad_t *)csd->csd_data;
|
||
iot_uint16_to_bytes((uint16_t)(oad >> 16),
|
||
(uint8_t *)&oad_resp->oi, 1);
|
||
attribute = (oad >> 8) & 0xff;
|
||
oad_resp->attribute_id = attribute & 0x1f;
|
||
oad_resp->attribute_char = attribute >> 5;
|
||
oad_resp->element_index = oad & 0xff;
|
||
csd_cnt++;
|
||
}
|
||
result_head = (proto_69845_app_get_result_t *)(rcsd_resp->csd_list +
|
||
di_cnt * csd_len);
|
||
result_head->result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
||
array_result = (proto_69845_app_rpt_array_result_t *)result_head->result;
|
||
array_result->array_len = 1;
|
||
os_mem_cpy(array_result->data, iot_pkt_data(cache_pkt), cache_fill_len);
|
||
no_time_tag = array_result->data + cache_fill_len;
|
||
*no_time_tag = 0;
|
||
no_flw = no_time_tag + 1;
|
||
*no_flw = 0;
|
||
data += apdu_len;
|
||
proto_69845_tail_fill(head, data, sizeof(proto_69845_tailer_t));
|
||
out:
|
||
if (cache_pkt) {
|
||
iot_pkt_free(cache_pkt);
|
||
}
|
||
return pkt;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_data_node_tm_delay(iot_time_tm_t *node_tm,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info, uint8_t dir)
|
||
{
|
||
if (!node_tm || !clct_info) {
|
||
goto out;
|
||
}
|
||
if (clct_info->cur_clct_cfg.di_info[0].di == PROTO_69845_APP_OAD_MINF &&
|
||
clct_info->cur_clct_cfg.period < (IOT_SG_STA_EXT_CLCT_PRD_15MIN / 60)) {
|
||
goto out;
|
||
}
|
||
if (dir) {
|
||
iot_rtc_delta_add(0 - IOT_SG_STA_EXT_GW_RECORD_CLCT_DELAY, node_tm);
|
||
} else {
|
||
iot_rtc_delta_add(IOT_SG_STA_EXT_GW_RECORD_CLCT_DELAY, node_tm);
|
||
}
|
||
out:
|
||
return;
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_rpt_next_time_calc(uint32_t *delay,
|
||
uint64_t *end_ts)
|
||
{
|
||
uint8_t reason = 0, level = p_sg_glb->plc_state.level;
|
||
uint32_t ret = ERR_FAIL, delta;
|
||
uint64_t cur_ts;
|
||
iot_time_tm_t cur_tm, tm = {0}, start_tm;
|
||
|
||
if (!p_sg_glb->plc_state.link_ready) {
|
||
reason = 1;
|
||
goto out;
|
||
}
|
||
if (iot_sg_sta_rtc_get(&cur_tm, 1)) {
|
||
reason = 2;
|
||
goto out;
|
||
}
|
||
cur_ts = os_boot_time64();
|
||
tm.tm_year = 2000;
|
||
tm.tm_mon = 1;
|
||
tm.tm_mday = 1;
|
||
if ((level % 3) == 0) {
|
||
/* level == 3<><33>6<EFBFBD><36>9<EFBFBD><39>12<31><32>15 */
|
||
tm.tm_sec = 0;
|
||
} else if (((level + 1) % 3) == 0) {
|
||
/* level == 2<><32>5<EFBFBD><35>8<EFBFBD><38>11<31><31>14 */
|
||
tm.tm_sec = 4;
|
||
} else {
|
||
/* level == 1<><31>4<EFBFBD><34>7<EFBFBD><37>10<31><30>13 */
|
||
tm.tm_sec = 8;
|
||
}
|
||
start_tm = iot_sg_ext_get_next_lr_ts(tm, IOT_SG_STA_EXT_GW_RPT_CYCLE,
|
||
cur_tm);
|
||
BUILD_BUG_ON(IOT_SG_STA_EXT_GW_RPT_DUR >= IOT_SG_STA_EXT_GW_RPT_RANDOM_DUR);
|
||
delta = (uint32_t)iot_rtc_delta_calc(&cur_tm, &start_tm) * 1000;
|
||
*delay = delta + (os_rand() % IOT_SG_STA_EXT_GW_RPT_RANDOM_DUR);
|
||
*end_ts = cur_ts + delta + IOT_SG_STA_EXT_GW_RPT_DUR;
|
||
ret = ERR_OK;
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_rpt_data_check(void)
|
||
{
|
||
uint8_t i;
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_data;
|
||
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
rpt_data = &rpt_info->unit_info[i];
|
||
if (!rpt_data->data || !rpt_data->len) {
|
||
continue;
|
||
}
|
||
if (rpt_data->len) {
|
||
ret = ERR_OK;
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_rpt_unit_data_clear(void)
|
||
{
|
||
uint8_t i;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
rpt_info = &p_sg_glb->desc.sta->ext_info.gw_clct_info->report_info;
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
if (!rpt_info->unit_info[i].data) {
|
||
continue;
|
||
}
|
||
rpt_info->unit_info[i].report_state =
|
||
IOT_SG_STA_EXT_GW_V28_UNIT_RPT_IDLE;
|
||
rpt_info->unit_info[i].msg_cnt = 0;
|
||
rpt_info->unit_info[i].len = 0;
|
||
rpt_info->unit_info[i].end_ts = 0;
|
||
rpt_info->unit_info[i].seq = 0;
|
||
}
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_unit_timeout_hande(void)
|
||
{
|
||
uint8_t i;
|
||
uint32_t cur_ts = (uint32_t)(os_boot_time64() / 1000);
|
||
uint32_t end_ts = IOT_SG_STA_EXT_GW_RPT_CLEAR_UNIT_TS;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if ((sta_glb->ext_info.gw_clct_info == NULL) || (cur_ts < end_ts)) {
|
||
return;
|
||
}
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
end_ts = cur_ts - end_ts;
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
if (!rpt_info->unit_info[i].data) {
|
||
continue;
|
||
}
|
||
if (!rpt_info->unit_info[i].end_ts) {
|
||
continue;
|
||
}
|
||
if (end_ts >= rpt_info->unit_info[i].end_ts) {
|
||
iot_sg_printf("%s clear idx %lu, seq %lu\n", __FUNCTION__, i,
|
||
rpt_info->unit_info[i].seq);
|
||
rpt_info->unit_info[i].report_state =
|
||
IOT_SG_STA_EXT_GW_V28_UNIT_RPT_IDLE;
|
||
rpt_info->unit_info[i].msg_cnt = 0;
|
||
rpt_info->unit_info[i].len = 0;
|
||
rpt_info->unit_info[i].end_ts = 0;
|
||
rpt_info->unit_info[i].seq = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_stop(void)
|
||
{
|
||
uint32_t cur_ts = (uint32_t)os_boot_time64();
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if (p_sg_glb->desc.sta->ext_info.gw_clct_info == NULL) {
|
||
return;
|
||
}
|
||
rpt_info = &p_sg_glb->desc.sta->ext_info.gw_clct_info->report_info;
|
||
iot_sg_printf("%s state %lu, cur_ts %lu, end_ts %lu\n",
|
||
__FUNCTION__, rpt_info->state, cur_ts, (uint32_t)rpt_info->end_ts);
|
||
os_stop_timer(rpt_info->rpt_timer);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_TIMER,
|
||
IOT_SG_MSG_ID_TIMER_GW_RPT_DELAY);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_INTERNAL,
|
||
IOT_SG_MSG_ID_INTERN_RPT_SEND_DONE);
|
||
rpt_info->state = IOT_SG_STA_EXT_GW_RPT_STATE_IDLE;
|
||
rpt_info->end_ts = 0;
|
||
rpt_info->fail_cnt = 0;
|
||
iot_sg_sta_ext_gw_rpt_unit_data_clear();
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_rpt_sm_change(uint8_t next_state,
|
||
uint32_t dur)
|
||
{
|
||
uint32_t cur_ts;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if (iot_sg_sta_ext_gw_rpt_data_check()) {
|
||
iot_sg_sta_ext_gw_rpt_stop();
|
||
return;
|
||
}
|
||
rpt_info = &p_sg_glb->desc.sta->ext_info.gw_clct_info->report_info;
|
||
if (rpt_info->state != next_state) {
|
||
cur_ts = os_boot_time32();
|
||
iot_sg_printf("%s state %lu to %lu, cur_ts %lu, end_ts %lu, dur %lu\n",
|
||
__FUNCTION__, rpt_info->state, next_state, cur_ts,
|
||
(uint32_t)rpt_info->end_ts, dur);
|
||
switch (next_state) {
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_READY:
|
||
{
|
||
os_stop_timer(rpt_info->rpt_timer);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_TIMER,
|
||
IOT_SG_MSG_ID_TIMER_GW_RPT_DELAY);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_INTERNAL,
|
||
IOT_SG_MSG_ID_INTERN_RPT_SEND_DONE);
|
||
rpt_info->end_ts = 0;
|
||
rpt_info->fail_cnt = 0;
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT:
|
||
{
|
||
if (rpt_info->state == IOT_SG_STA_EXT_GW_RPT_STATE_RPTING) {
|
||
os_stop_timer(rpt_info->rpt_timer);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_TIMER,
|
||
IOT_SG_MSG_ID_TIMER_GW_RPT_DELAY);
|
||
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_INTERNAL,
|
||
IOT_SG_MSG_ID_INTERN_RPT_SEND_DONE);
|
||
} else {
|
||
/* anther state to IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT,
|
||
* do nothing
|
||
*/
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_RPTING:
|
||
{
|
||
/* only IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT
|
||
* to IOT_SG_STA_EXT_GW_RPT_STATE_RPTING,
|
||
* do nothing
|
||
*/
|
||
break;
|
||
}
|
||
default:
|
||
IOT_ASSERT(0);
|
||
break;
|
||
}
|
||
rpt_info->state = next_state;
|
||
}
|
||
if (dur) {
|
||
os_start_timer(rpt_info->rpt_timer, dur);
|
||
}
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_enable(uint8_t flag_en)
|
||
{
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info == NULL) {
|
||
return;
|
||
}
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
if (!rpt_info->flag_en && flag_en) {
|
||
rpt_info->flag_en = 1;
|
||
iot_sg_printf("%s rpt en\n", __FUNCTION__);
|
||
} else if (rpt_info->flag_en && !flag_en) {
|
||
rpt_info->flag_en = 0;
|
||
iot_sg_sta_ext_gw_rpt_stop();
|
||
iot_sg_printf("%s rpt dis\n", __FUNCTION__);
|
||
}
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_rpt_start(void)
|
||
{
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
rpt_info = &p_sg_glb->desc.sta->ext_info.gw_clct_info->report_info;
|
||
if (rpt_info->state == IOT_SG_STA_EXT_GW_RPT_STATE_IDLE) {
|
||
iot_sg_printf("%s\n", __FUNCTION__);
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_READY,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
}
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_rpt_get_data_idx(uint8_t *idx)
|
||
{
|
||
uint8_t i;
|
||
uint32_t ret = ERR_FAIL, cur_ts = (uint32_t)(os_boot_time64() / 1000);
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_data;
|
||
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
rpt_data = &rpt_info->unit_info[i];
|
||
if (!rpt_data->data || !rpt_data->len || !rpt_data->msg_cnt) {
|
||
continue;
|
||
}
|
||
if ((rpt_data->report_state == IOT_SG_STA_EXT_GW_V28_UNIT_RPT_START)
|
||
|| (cur_ts >= rpt_data->end_ts)) {
|
||
*idx = i;
|
||
ret = ERR_OK;
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_rpt_done_callback(void *param,
|
||
uint8_t state)
|
||
{
|
||
uint32_t seq = (uint32_t)param;
|
||
iot_sg_msg_t *msg;
|
||
|
||
msg = (iot_sg_msg_t *)iot_task_alloc_msg(p_sg_glb->task_h);
|
||
if (msg) {
|
||
msg->task_msg.type = IOT_SG_MSG_TYPE_INTERNAL;
|
||
msg->task_msg.id = IOT_SG_MSG_ID_INTERN_RPT_SEND_DONE;
|
||
msg->data2 = (uint16_t)seq;
|
||
msg->data2 = (msg->data2 << 8) | state;
|
||
iot_task_queue_msg(p_sg_glb->task_h, &msg->task_msg,
|
||
IOT_SG_MSG_QUEUE_LP);
|
||
} else {
|
||
IOT_ASSERT(0);
|
||
}
|
||
}
|
||
|
||
static uint16_t iot_sg_sta_ext_gw_rpt_seq_get(void)
|
||
{
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info =
|
||
&p_sg_glb->desc.sta->ext_info.gw_clct_info->report_info;
|
||
|
||
rpt_info->seq++;
|
||
if (rpt_info->seq == 0) {
|
||
rpt_info->seq++;
|
||
}
|
||
return rpt_info->seq;
|
||
}
|
||
|
||
static uint8_t iot_sg_sta_ext_gw_rpt_data_send(void)
|
||
{
|
||
uint8_t idx, ret = ERR_FAIL;
|
||
uint16_t seq;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *unit_data;
|
||
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
if (p_sg_glb->plc_state.link_ready
|
||
&& (iot_sg_sta_ext_gw_rpt_get_data_idx(&idx) == ERR_OK)
|
||
&& (rpt_info->end_ts > os_boot_time64())) {
|
||
unit_data = &rpt_info->unit_info[idx];
|
||
seq = iot_sg_sta_ext_gw_rpt_seq_get();
|
||
ret = (uint8_t)iot_sg_sta_clct_data_rpt_send(unit_data->data,
|
||
(uint16_t)unit_data->len, (uint8_t)unit_data->msg_cnt, seq,
|
||
iot_sg_sta_ext_gw_rpt_done_callback);
|
||
if (ret == ERR_OK) {
|
||
iot_sg_printf("%s idx %lu, seq %lu \n",
|
||
__FUNCTION__, idx, seq);
|
||
unit_data->report_state = IOT_SG_STA_EXT_GW_V28_UNIT_RPT_ONGOING;
|
||
unit_data->seq = seq;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_unit_done(
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *unit_info, uint16_t seq,
|
||
uint8_t state)
|
||
{
|
||
uint8_t idx;
|
||
|
||
for (idx = 0; idx < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; idx++) {
|
||
if (unit_info[idx].seq == seq) {
|
||
break;
|
||
}
|
||
}
|
||
if (idx < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT) {
|
||
if (unit_info[idx].report_state ==
|
||
IOT_SG_STA_EXT_GW_V28_UNIT_RPT_ONGOING) {
|
||
unit_info[idx].seq = 0;
|
||
unit_info[idx].report_state = IOT_SG_STA_EXT_GW_V28_UNIT_RPT_IDLE;
|
||
if (state == IOT_PKT_STATE_TX_OK_RX_OK) {
|
||
unit_info[idx].len = 0;
|
||
unit_info[idx].msg_cnt = 0;
|
||
unit_info[idx].end_ts = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_done_handle(uint16_t seq,
|
||
uint8_t state)
|
||
{
|
||
uint8_t ret = ERR_FAIL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info == NULL) {
|
||
return;
|
||
}
|
||
iot_sg_printf("%s seq %lu, result %lu\n", __FUNCTION__, seq, state);
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
iot_sg_sta_ext_gw_rpt_unit_done(rpt_info->unit_info, seq, state);
|
||
if (rpt_info->state != IOT_SG_STA_EXT_GW_RPT_STATE_RPTING) {
|
||
return;
|
||
}
|
||
if (state == IOT_PKT_STATE_TX_OK_RX_OK) {
|
||
rpt_info->fail_cnt = 0;
|
||
} else if (state == IOT_PKT_STATE_TX_OK_RX_UNKNOWN
|
||
|| state == IOT_PKT_STATE_TX_FAIL
|
||
|| state == IOT_PKT_STATE_UNKNOWN) {
|
||
rpt_info->fail_cnt++;
|
||
}
|
||
if (rpt_info->fail_cnt < IOT_SG_STA_EXT_GW_RPT_FAIL_CNT_MAX) {
|
||
ret = iot_sg_sta_ext_gw_rpt_data_send();
|
||
if (ret == ERR_OK) {
|
||
/* wait for send next data */
|
||
} else if ((os_boot_time64() + IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME)
|
||
< rpt_info->end_ts) {
|
||
/* report time hasn't ended, back to
|
||
* IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT
|
||
*/
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
} else {
|
||
/* report time is almost over, waiting for the end of
|
||
* the report process
|
||
*/
|
||
}
|
||
} else {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_READY,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
}
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_func(void)
|
||
{
|
||
uint32_t dur = 0, ret = ERR_FAIL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info == NULL) {
|
||
return;
|
||
}
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
switch (rpt_info->state) {
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_READY:
|
||
{
|
||
if (iot_sg_sta_ext_gw_rpt_next_time_calc(&dur, &rpt_info->end_ts)
|
||
== ERR_OK) {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT, dur);
|
||
} else {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_READY,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MAX_TIME);
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT:
|
||
{
|
||
ret = iot_sg_sta_ext_gw_rpt_data_send();
|
||
if (rpt_info->end_ts > os_boot_time64()) {
|
||
dur = (uint32_t)(rpt_info->end_ts - os_boot_time64());
|
||
}
|
||
if (ret == ERR_OK && dur) {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_RPTING, dur);
|
||
} else if (dur > IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME) {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_WAIT_RPT,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
} else {
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_READY,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_RPT_STATE_RPTING:
|
||
{
|
||
iot_sg_sta_ext_gw_rpt_sm_change(
|
||
IOT_SG_STA_EXT_GW_RPT_STATE_READY,
|
||
IOT_SG_STA_EXT_GW_RPT_SM_TRIG_MIN_TIME);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_data_freeze_state_end(uint8_t *addr,
|
||
iot_time_tm_t *node_tm, iot_time_tm_t cur_tm, iot_time_tm_t start_tm,
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info, uint8_t flag_3p)
|
||
{
|
||
iot_time_tm_t clct_tm = *node_tm;
|
||
iot_pkt_t *pkt;
|
||
|
||
if (!node_tm || !clct_info) {
|
||
return;
|
||
}
|
||
*node_tm = iot_sg_ext_get_next_lr_ts(start_tm,
|
||
clct_info->cur_clct_cfg.period * 60, cur_tm);
|
||
/* node next time collect time delay */
|
||
iot_sg_sta_ext_gw_data_node_tm_delay(node_tm, clct_info, 0);
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_END;
|
||
/* node last time collect time recover */
|
||
iot_sg_sta_ext_gw_data_node_tm_delay(&clct_tm, clct_info, 1);
|
||
pkt = iot_sg_sta_ext_gw_698_freeze_msg_build(addr, clct_info, flag_3p,
|
||
&clct_tm);
|
||
if (pkt) {
|
||
iot_sg_sta_ext_gw_rpt_data_collect(iot_pkt_data(pkt),
|
||
(uint16_t)iot_pkt_data_len(pkt), 1);
|
||
if (clct_info->freeze_698_pkt) {
|
||
iot_pkt_free(clct_info->freeze_698_pkt);
|
||
}
|
||
clct_info->freeze_698_pkt = pkt;
|
||
}
|
||
}
|
||
|
||
uint8_t iot_sg_sta_ext_gw_data_freeze_func(uint8_t *addr)
|
||
{
|
||
uint8_t complete = 0, last_state = 0, flag_new = 0;
|
||
uint16_t timeout;
|
||
uint32_t ret, di_645;
|
||
iot_pkt_t *pkt;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info = ext_info->gw_clct_info;
|
||
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
||
iot_time_tm_t tm, *node_tm, start_tm = { 0 };
|
||
|
||
IOT_ASSERT(node);
|
||
start_tm.tm_year = 2000;
|
||
start_tm.tm_mon = 1;
|
||
start_tm.tm_mday = 1;
|
||
|
||
if (iot_sg_sta_rtc_get(&tm, 1)) {
|
||
/* get time fail, stop lr function */
|
||
iot_sg_printf("%s get time err\n", __FUNCTION__);
|
||
goto done;
|
||
}
|
||
node_tm = &node->ext.gw_node_clct_info.task_tm[0];
|
||
last_state = clct_info->state;
|
||
switch (clct_info->state) {
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_IDLE:
|
||
{
|
||
if (!node_tm->tm_year && !node_tm->tm_mon &&
|
||
!node_tm->tm_mday && !node_tm->tm_hour &&
|
||
!node_tm->tm_min && !node_tm->tm_sec) {
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(addr, 1,
|
||
&clct_info->cur_clct_cfg) != ERR_OK) {
|
||
goto done;
|
||
}
|
||
/* load read load curve data time stamp */
|
||
*node_tm = iot_sg_ext_get_next_lr_ts(start_tm,
|
||
clct_info->cur_clct_cfg.period * 60, tm);
|
||
iot_sg_sta_ext_gw_data_node_tm_delay(node_tm, clct_info, 0);
|
||
goto done;
|
||
} else if (iot_rtc_delta_calc(node_tm, &tm) >= 0) {
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(addr, 1,
|
||
&clct_info->cur_clct_cfg) != ERR_OK) {
|
||
goto done;
|
||
}
|
||
/* when current tm is greater than or equal to next tm of
|
||
* reading load curve data, start read load curve data.
|
||
*/
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_SEND;
|
||
clct_info->index = 0;
|
||
flag_new = 1;
|
||
goto send;
|
||
} else {
|
||
goto done;
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_WAIT:
|
||
{
|
||
if (!clct_info->timeout_cnt) {
|
||
if (!clct_info->repeat_cnt || clct_info->flag_resp) {
|
||
clct_info->index++;
|
||
clct_info->repeat_cnt = 0;
|
||
flag_new = 1;
|
||
}
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
iot_sg_sta_ext_gw_data_freeze_state_end(addr, node_tm, tm,
|
||
start_tm, clct_info, node->is_three_phase);
|
||
goto done;
|
||
}
|
||
if (clct_info->repeat_cnt) {
|
||
clct_info->repeat_cnt--;
|
||
if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
clct_info->index = clct_info->last_index_698;
|
||
}
|
||
}
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_SEND;
|
||
} else {
|
||
clct_info->timeout_cnt--;
|
||
break;
|
||
}
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_SEND:
|
||
{
|
||
send:
|
||
if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
clct_info->last_index_698 = clct_info->index;
|
||
pkt = iot_sg_sta_ext_gw_69845_lr_mr_msg_build(addr, clct_info);
|
||
} else {
|
||
if (!clct_info->index ||
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index].di ==
|
||
PROTO_69845_APP_OAD_FROZEN_T) {
|
||
/* skip current di */
|
||
clct_info->index++;
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
iot_sg_sta_ext_gw_data_freeze_state_end(addr, node_tm, tm,
|
||
start_tm, clct_info, node->is_three_phase);
|
||
goto done;
|
||
}
|
||
}
|
||
di_645 = proto_698_oad_to_645_di(
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index].di);
|
||
pkt = proto_645_build_mr_msg(PROTO_645_2007_ID, addr, di_645);
|
||
}
|
||
if (pkt) {
|
||
timeout = (IOT_SG_STA_EXT_READ_DATA_TIMEOUT *
|
||
IOT_SG_STA_EXT_SM_DELAY / 100);
|
||
timeout = min(timeout, IOT_SG_STA_EXT_DRV_READ_TIMEOUT);
|
||
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_GW_CLCT,
|
||
addr, 0, node->data_type, iot_pkt_data(pkt),
|
||
(uint16_t)iot_pkt_data_len(pkt), timeout);
|
||
if (ret == ERR_OK) {
|
||
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x read id "
|
||
"%08x idx %lu task id %lu\n", __FUNCTION__, addr[0],
|
||
addr[1], addr[2],addr[3], addr[4], addr[5],
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index].di,
|
||
clct_info->index, clct_info->cur_task_id);
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_WAIT;
|
||
clct_info->timeout_cnt = IOT_SG_STA_EXT_READ_DATA_TIMEOUT;
|
||
if (flag_new) {
|
||
clct_info->repeat_cnt = 1;
|
||
}
|
||
clct_info->flag_resp = 0;
|
||
}
|
||
iot_pkt_free(pkt);
|
||
} else {
|
||
clct_info->index++;
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
iot_sg_sta_ext_gw_data_freeze_state_end(addr, node_tm, tm,
|
||
start_tm, clct_info, node->is_three_phase);
|
||
goto done;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_END:
|
||
{
|
||
goto done;
|
||
break;
|
||
}
|
||
default:
|
||
IOT_ASSERT(0);
|
||
break;
|
||
}
|
||
goto out;
|
||
done:
|
||
iot_sg_ext_gw_data_clct_cur_info_clear(clct_info);
|
||
complete = 1;
|
||
out:
|
||
if (last_state != clct_info->state) {
|
||
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x state %lu to %lu\n"
|
||
, __FUNCTION__, addr[0], addr[1], addr[2], addr[3], addr[4],
|
||
addr[5], last_state, clct_info->state);
|
||
}
|
||
return complete;
|
||
}
|
||
|
||
static iot_sg_sta_ext_gw_clct_report_unit_info_t *
|
||
iot_sg_sta_ext_gw_rpt_unit_get(uint16_t len)
|
||
{
|
||
uint8_t i;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_unit = NULL;
|
||
iot_sg_sta_ext_gw_clct_report_info_t
|
||
*rpt_info = &ext_info->gw_clct_info->report_info;
|
||
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
if (!rpt_info->unit_info[i].data) {
|
||
continue;
|
||
}
|
||
if (rpt_info->unit_info[i].report_state ==
|
||
IOT_SG_STA_EXT_GW_V28_UNIT_RPT_ONGOING) {
|
||
continue;
|
||
}
|
||
if (len > (IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN -
|
||
rpt_info->unit_info[i].len)) {
|
||
continue;
|
||
}
|
||
rpt_unit = &rpt_info->unit_info[i];
|
||
iot_sg_printf("%s idx %d\n", __FUNCTION__, i);
|
||
break;
|
||
}
|
||
return rpt_unit;
|
||
}
|
||
|
||
static iot_sg_sta_ext_gw_clct_report_unit_info_t *
|
||
iot_sg_sta_ext_oldest_rpt_unit_free(
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info)
|
||
{
|
||
uint8_t i, old_idx = 0;
|
||
uint32_t old_ts = 0;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_unit = NULL;
|
||
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
if (!rpt_info->unit_info[i].data) {
|
||
continue;
|
||
}
|
||
if (!old_ts || old_ts > rpt_info->unit_info[i].end_ts) {
|
||
old_ts = rpt_info->unit_info[i].end_ts;
|
||
old_idx = i;
|
||
}
|
||
}
|
||
if (!old_ts) {
|
||
goto out;
|
||
}
|
||
/* clean unit info */
|
||
rpt_unit = &rpt_info->unit_info[old_idx];
|
||
rpt_unit->report_state = IOT_SG_STA_EXT_GW_V28_UNIT_RPT_IDLE;
|
||
rpt_unit->msg_cnt = 0;
|
||
rpt_unit->len = 0;
|
||
rpt_unit->end_ts = 0;
|
||
rpt_unit->seq = 0;
|
||
iot_sg_printf("%s idx %d\n", __FUNCTION__, old_idx);
|
||
out:
|
||
return rpt_unit;
|
||
}
|
||
|
||
static iot_sg_sta_ext_gw_clct_report_unit_info_t *
|
||
iot_sg_sta_ext_gw_rpt_unit_alloc(void)
|
||
{
|
||
uint8_t i = 0, j = 0, valid_pkt_cnt = 0;
|
||
uint16_t len = 0, alloc_len = 0;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_unit = NULL;
|
||
iot_sg_sta_ext_gw_clct_report_info_t
|
||
*rpt_info = &ext_info->gw_clct_info->report_info;
|
||
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_CACHE_PKT_CNT; i++) {
|
||
if (rpt_info->pkt[i]) {
|
||
valid_pkt_cnt++;
|
||
continue;
|
||
}
|
||
if (i <= 1) {
|
||
alloc_len = IOT_SG_STA_EXT_GW_V28_RPT_PKT_LEN_2K;
|
||
rpt_info->pkt[i] = iot_pkt_alloc(alloc_len, IOT_SMART_GRID_MID);
|
||
if (rpt_info->pkt[i]) {
|
||
break;
|
||
}
|
||
}
|
||
alloc_len = IOT_SG_STA_EXT_GW_V28_RPT_PKT_LEN_1K;
|
||
rpt_info->pkt[i] = iot_pkt_alloc(alloc_len, IOT_SMART_GRID_MID);
|
||
break;
|
||
}
|
||
if (i >= IOT_SG_STA_EXT_GW_V28_CACHE_PKT_CNT || !rpt_info->pkt[i]) {
|
||
goto out;
|
||
}
|
||
iot_pkt_put(rpt_info->pkt[i], alloc_len);
|
||
for (j = 0; j < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; j++) {
|
||
if (len + IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN > alloc_len) {
|
||
break;
|
||
}
|
||
if (rpt_info->unit_info[j].data) {
|
||
continue;
|
||
}
|
||
rpt_info->unit_info[j].data = iot_pkt_data(rpt_info->pkt[i]) + len;
|
||
rpt_info->unit_info[j].len = 0;
|
||
len += IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN;
|
||
if (!rpt_unit) {
|
||
rpt_unit = &rpt_info->unit_info[j];
|
||
}
|
||
}
|
||
out:
|
||
if (!rpt_unit && valid_pkt_cnt == IOT_SG_STA_EXT_GW_V28_CACHE_PKT_CNT) {
|
||
rpt_unit = iot_sg_sta_ext_oldest_rpt_unit_free(rpt_info);
|
||
}
|
||
iot_sg_printf("%s pkt cnt %d unit cnt %d \n", __FUNCTION__, (i + 1), j);
|
||
return rpt_unit;
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_rpt_data_compare(uint8_t *data,
|
||
uint16_t len)
|
||
{
|
||
uint8_t i, j, *unit_data;
|
||
uint16_t len_tmp;
|
||
uint32_t ret = ERR_FAIL;
|
||
proto_69845_frame_head_info_t* head;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_report_info_t
|
||
*rpt_info = &ext_info->gw_clct_info->report_info;
|
||
|
||
for (i = 0; i < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_CNT; i++) {
|
||
if (!rpt_info->unit_info[i].data) {
|
||
continue;
|
||
}
|
||
len_tmp = 0;
|
||
unit_data = rpt_info->unit_info[i].data;
|
||
for (j = 0; j < rpt_info->unit_info[i].msg_cnt; j++) {
|
||
head = (proto_69845_frame_head_info_t *)(unit_data + len_tmp);
|
||
if (head->start_char != PROTO_69845_START_BYTE) {
|
||
break;
|
||
}
|
||
len_tmp += head->len + PROTO_69845_START_END_LEN;
|
||
if (len_tmp > rpt_info->unit_info[i].len) {
|
||
break;
|
||
}
|
||
if ((head->len + PROTO_69845_START_END_LEN) != len) {
|
||
continue;
|
||
}
|
||
if (!os_mem_cmp(head, data, len)) {
|
||
ret = ERR_OK;
|
||
goto out;
|
||
}
|
||
}
|
||
}
|
||
out:
|
||
return ret;
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_rpt_data_collect(uint8_t *data,
|
||
uint16_t len, uint8_t flag_local)
|
||
{
|
||
uint8_t *data_tmp, reason = 0;
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_gw_clct_report_info_t *rpt_info;
|
||
iot_sg_sta_ext_gw_clct_report_unit_info_t *rpt_unit = NULL;
|
||
|
||
if (sta_glb->ext_info.gw_clct_info == NULL) {
|
||
reason = 1;
|
||
goto drop;
|
||
}
|
||
rpt_info = &sta_glb->ext_info.gw_clct_info->report_info;
|
||
if (!rpt_info->flag_en) {
|
||
reason = 2;
|
||
goto drop;
|
||
}
|
||
if (!flag_local) {
|
||
if (iot_sg_sta_ext_gw_rpt_data_compare(data, len) == ERR_OK) {
|
||
reason = 3;
|
||
goto drop;
|
||
}
|
||
}
|
||
rpt_unit = iot_sg_sta_ext_gw_rpt_unit_get(len);
|
||
if (!rpt_unit) {
|
||
rpt_unit = iot_sg_sta_ext_gw_rpt_unit_alloc();
|
||
if (!rpt_unit) {
|
||
reason = 4;
|
||
goto drop;
|
||
}
|
||
}
|
||
if (IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN - rpt_unit->len < len) {
|
||
reason = 5;
|
||
goto drop;
|
||
}
|
||
data_tmp = rpt_unit->data + rpt_unit->len;
|
||
os_mem_cpy(data_tmp, data, len);
|
||
rpt_unit->len += len;
|
||
if (flag_local || (IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MAX_LEN -
|
||
rpt_unit->len) < IOT_SG_STA_EXT_GW_V28_RPT_UNIT_MIN_LEN) {
|
||
rpt_unit->report_state = IOT_SG_STA_EXT_GW_V28_UNIT_RPT_START;
|
||
}
|
||
if (!rpt_unit->msg_cnt) {
|
||
rpt_unit->end_ts = (uint32_t)(os_boot_time64() / 1000) +
|
||
IOT_SG_STA_EXT_GW_NODE_RPT_CNVG_TIME;
|
||
}
|
||
rpt_unit->msg_cnt++;
|
||
iot_sg_printf("%s len %d\n", __FUNCTION__, rpt_unit->len);
|
||
iot_sg_sta_ext_gw_rpt_start();
|
||
ret = ERR_OK;
|
||
goto out;
|
||
drop:
|
||
iot_sg_printf("%s drop reason %d\n", __FUNCTION__, reason);
|
||
out:
|
||
return ret;
|
||
}
|
||
|
||
uint16_t iot_sg_sta_ext_gw_clct_data_read(uint8_t *addr, uint8_t task_id,
|
||
iot_time_tm_t *tm, uint8_t *data, uint16_t len, uint8_t *di_cnt,
|
||
uint8_t *proto_type)
|
||
{
|
||
(void)addr;
|
||
(void)task_id;
|
||
(void)tm;
|
||
(void)data;
|
||
(void)len;
|
||
(void)di_cnt;
|
||
(void)proto_type;
|
||
return 0;
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_clct_task_id_exist_check(uint8_t *addr,
|
||
uint8_t task_id)
|
||
{
|
||
(void)addr;
|
||
(void)task_id;
|
||
return ERR_NOT_EXIST;
|
||
}
|
||
|
||
#else /* IOT_SMART_GRID_GW_V28_OP2_ENABLE */
|
||
|
||
static uint8_t iot_sg_sta_ext_gw_clct_698_oad_unit_min_len_get(uint32_t di)
|
||
{
|
||
uint8_t unit_data_len = 0;
|
||
uint16_t oi = (uint16_t)(di >> 16);
|
||
|
||
switch(oi){
|
||
case PROTO_69845_APP_OI_VOLTAGE:
|
||
case PROTO_69845_APP_OI_PF:
|
||
{
|
||
unit_data_len = PROTO_69845_METER_DATA_LONG_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OI_P:
|
||
case PROTO_69845_APP_OI_Q:
|
||
case PROTO_69845_APP_OI_CURRENT:
|
||
case PROTO_69845_APP_OI_EPT_COMP:
|
||
case PROTO_69845_APP_OI_EPT_POS:
|
||
case PROTO_69845_APP_OI_EPT_NEG:
|
||
case PROTO_69845_APP_OI_EQT_POS:
|
||
case PROTO_69845_APP_OI_EQT_NEG:
|
||
case PROTO_69845_APP_OI_EQT_QRT1:
|
||
case PROTO_69845_APP_OI_EQT_QRT2:
|
||
case PROTO_69845_APP_OI_EQT_QRT3:
|
||
case PROTO_69845_APP_OI_EQT_QRT4:
|
||
case PROTO_69845_APP_OI_EPT_DEMAND:
|
||
case PROTO_69845_APP_OI_EQT_DEMAND:
|
||
{
|
||
unit_data_len = PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OI_EPT_POS_DEMAND:
|
||
case PROTO_69845_APP_OI_EPT_NEG_DEMAND:
|
||
{
|
||
unit_data_len = PROTO_69845_METER_DATA_DOUBLE_LONG_LEN +
|
||
sizeof(proto_69845_app_data_time_s_t);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return unit_data_len;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_clct_698_demand_data_write(uint32_t di,
|
||
uint8_t *data, iot_sg_meter_lc_uint_xian_data_t *uint_data)
|
||
{
|
||
int32_t temp_32;
|
||
iot_sg_meter_max_demand_and_ht_t *demand;
|
||
proto_69845_app_data_time_s_t *time;
|
||
|
||
if (di == PROTO_69845_APP_OAD_EPT_POS_DEMAND) {
|
||
demand = (iot_sg_meter_max_demand_and_ht_t *)&uint_data->pos_ap_demand;
|
||
} else if(PROTO_69845_APP_OAD_EPT_NEG_DEMAND) {
|
||
demand = (iot_sg_meter_max_demand_and_ht_t *)&uint_data->neg_ap_demand;
|
||
} else {
|
||
return;
|
||
}
|
||
temp_32 = proto_645_bcd_to_integer(demand->max_demand,
|
||
PROTO_645_07_P_LEN, 0);
|
||
iot_uint32_to_bytes((uint32_t)temp_32, data, 1);
|
||
time = (proto_69845_app_data_time_s_t *)(data +
|
||
PROTO_69845_METER_DATA_DOUBLE_LONG_LEN);
|
||
time->year = iot_bcd_to_byte(demand->year) + 2000;
|
||
time->month = iot_bcd_to_byte(demand->month);
|
||
time->day = iot_bcd_to_byte(demand->day);
|
||
time->hour = iot_bcd_to_byte(demand->hour);
|
||
time->minute = iot_bcd_to_byte(demand->minute);
|
||
time->second = 0;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_clct_698_normal_data_write(uint32_t di,
|
||
uint8_t *data, uint8_t len, iot_sg_meter_lc_uint_xian_data_t *uint_data,
|
||
uint8_t unit_min_len)
|
||
{
|
||
int32_t temp_32;
|
||
int16_t temp_16;
|
||
uint8_t ele_cnt, *meter_data, min_ele_cnt, i, meter_data_uint_len;
|
||
|
||
switch (di) {
|
||
case PROTO_69845_APP_OAD_VOLTAGE_A:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->v;
|
||
meter_data_uint_len = PROTO_645_V_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_VOLTAGE:
|
||
{
|
||
ele_cnt = 3;
|
||
meter_data = (uint8_t *)&uint_data->v;
|
||
meter_data_uint_len = PROTO_645_V_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_CURRENT:
|
||
{
|
||
ele_cnt = 3;
|
||
meter_data = (uint8_t *)&uint_data->i;
|
||
meter_data_uint_len = PROTO_645_07_A_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_CURRENT_A:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->i;
|
||
meter_data_uint_len = PROTO_645_07_A_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_GND_CURRENT:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->n;
|
||
meter_data_uint_len = PROTO_645_07_A_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P_T:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->active_power.total;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P_A:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->active_power.a;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P:
|
||
{
|
||
ele_cnt = 4;
|
||
meter_data = (uint8_t *)&uint_data->active_power;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_PF:
|
||
{
|
||
ele_cnt = 4;
|
||
meter_data = (uint8_t *)&uint_data->power_factor;
|
||
meter_data_uint_len = PROTO_645_07_PF_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_DEMAND:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->ap_demand;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_DEMAND:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->rp_demand;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_POS:
|
||
{
|
||
ele_cnt = 5;
|
||
meter_data = (uint8_t *)&uint_data->fda_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_POS_SIG:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->fda_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_NEG:
|
||
{
|
||
ele_cnt = 5;
|
||
meter_data = (uint8_t *)&uint_data->bda_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_NEG_SIG:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->bda_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_Q:
|
||
{
|
||
ele_cnt = 4;
|
||
meter_data = (uint8_t *)&uint_data->reactive_power;
|
||
meter_data_uint_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_COMP:
|
||
{
|
||
ele_cnt = 5;
|
||
meter_data = (uint8_t *)&uint_data->ca_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_COMP_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->ca_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_POS_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->cr_power1;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_NEG_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->cr_power2;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT1_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->re_1st_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT2_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->re_2nd_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT3_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->re_3rd_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EQT_QRT4_SUM:
|
||
{
|
||
ele_cnt = 1;
|
||
meter_data = (uint8_t *)&uint_data->re_4th_power;
|
||
meter_data_uint_len = PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
default:
|
||
return;
|
||
}
|
||
min_ele_cnt = min(ele_cnt, len / unit_min_len);
|
||
for (i = 0; i < min_ele_cnt; i++) {
|
||
if (unit_min_len == PROTO_69845_METER_DATA_LONG_LEN) {
|
||
temp_16 = (int16_t)proto_645_bcd_to_integer(meter_data,
|
||
meter_data_uint_len, 0);
|
||
iot_uint16_to_bytes((uint16_t)temp_16, data, 1);
|
||
meter_data += meter_data_uint_len;
|
||
data += PROTO_69845_METER_DATA_LONG_LEN;
|
||
} else {
|
||
temp_32 = proto_645_bcd_to_integer(meter_data,
|
||
meter_data_uint_len, 0);
|
||
iot_uint32_to_bytes((uint32_t)temp_32, data, 1);
|
||
meter_data += meter_data_uint_len;
|
||
data += PROTO_69845_METER_DATA_DOUBLE_LONG_LEN;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_clct_uint_698_data_write(uint32_t di,
|
||
uint8_t *data, uint8_t len, iot_sg_meter_lc_uint_xian_data_t *uint_data,
|
||
uint8_t unit_min_len)
|
||
{
|
||
if (!data || !len || !uint_data || !unit_min_len) {
|
||
return;
|
||
}
|
||
switch (di) {
|
||
case PROTO_69845_APP_OAD_EPT_POS_DEMAND:
|
||
case PROTO_69845_APP_OAD_EPT_NEG_DEMAND:
|
||
{
|
||
iot_sg_sta_ext_gw_clct_698_demand_data_write(di, data, uint_data);
|
||
break;
|
||
}
|
||
default:
|
||
iot_sg_sta_ext_gw_clct_698_normal_data_write(di, data, len, uint_data,
|
||
unit_min_len);
|
||
break;
|
||
}
|
||
}
|
||
|
||
static uint8_t iot_sg_sta_ext_gw_clct_645_di_unit_min_len_get(uint32_t di)
|
||
{
|
||
uint8_t unit_data_len = 0;
|
||
switch (di) {
|
||
case PROTO_645_2007_DI_V_A:
|
||
case PROTO_645_2007_DI_V_ALL:
|
||
{
|
||
unit_data_len = PROTO_645_V_LEN;
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_I_A:
|
||
case PROTO_645_2007_DI_I_N:
|
||
case PROTO_645_2007_DI_I_ALL:
|
||
{
|
||
unit_data_len = PROTO_645_07_A_LEN;
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_P_T:
|
||
case PROTO_645_2007_DI_P_A:
|
||
case PROTO_645_2007_DI_P_ALL:
|
||
case PROTO_645_2007_DI_PF_ALL:
|
||
case PROTO_645_2007_DI_Q_ALL:
|
||
case PROTO_645_2007_DI_EQT_DEMAND:
|
||
case PROTO_645_2007_DI_EPT_DEMAND:
|
||
{
|
||
unit_data_len = PROTO_645_07_P_LEN;
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_POS_SUM:
|
||
case PROTO_645_2007_DI_EPT_NEG_SUM:
|
||
case PROTO_645_2007_DI_EQT_POS_SUM:
|
||
case PROTO_645_2007_DI_EQT_NEG_SUM:
|
||
case PROTO_645_2007_DI_EQT_QRT1_SUM:
|
||
case PROTO_645_2007_DI_EQT_QRT2_SUM:
|
||
case PROTO_645_2007_DI_EQT_QRT3_SUM:
|
||
case PROTO_645_2007_DI_EQT_QRT4_SUM:
|
||
case PROTO_645_2007_DI_EPT_COMP_SUM:
|
||
case PROTO_645_2007_DI_EPT_POS_ALL:
|
||
case PROTO_645_2007_DI_EPT_NEG_ALL:
|
||
case PROTO_645_2007_DI_EPT_COMP_ALL:
|
||
{
|
||
unit_data_len= PROTO_645_07_ENERGY_DATA_LEN;
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_POS_DEMAND:
|
||
case PROTO_645_2007_DI_EPT_NEG_DEMAND:
|
||
{
|
||
unit_data_len= PROTO_645_07_CURR_PD_LEN;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return unit_data_len;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_clct_uint_645_data_write(uint32_t di,
|
||
uint8_t *data, uint8_t len, iot_sg_meter_lc_uint_xian_data_t *uint_data)
|
||
{
|
||
uint8_t min_len;
|
||
switch (di) {
|
||
case PROTO_645_2007_DI_V_A:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->v.a));
|
||
os_mem_cpy(data, &uint_data->v.a, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_I_A:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->i.a));
|
||
os_mem_cpy(data, &uint_data->i.a, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_I_N:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->n));
|
||
os_mem_cpy(data, &uint_data->n, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_P_T:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->active_power.total));
|
||
os_mem_cpy(data, &uint_data->active_power.total, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_P_A:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->active_power.a));
|
||
os_mem_cpy(data, &uint_data->active_power.a, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_DEMAND:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->ap_demand));
|
||
os_mem_cpy(data, &uint_data->ap_demand, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_DEMAND:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->rp_demand));
|
||
os_mem_cpy(data, &uint_data->rp_demand, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_POS_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->fda_power));
|
||
os_mem_cpy(data, &uint_data->fda_power, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_NEG_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->bda_power));
|
||
os_mem_cpy(data, &uint_data->bda_power, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_V_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->v));
|
||
os_mem_cpy(data, &uint_data->v, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_I_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->i));
|
||
os_mem_cpy(data, &uint_data->i, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_P_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->active_power));
|
||
os_mem_cpy(data, &uint_data->active_power, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_Q_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->reactive_power));
|
||
os_mem_cpy(data, &uint_data->reactive_power, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_PF_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->power_factor));
|
||
os_mem_cpy(data, &uint_data->power_factor, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_COMP_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->ca_power.total));
|
||
os_mem_cpy(data, uint_data->ca_power.total, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_COMP_ALL:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->ca_power));
|
||
os_mem_cpy(data, &uint_data->ca_power, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_POS_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->fda_power.total));
|
||
os_mem_cpy(data, &uint_data->fda_power.total , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_NEG_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->bda_power.total));
|
||
os_mem_cpy(data, &uint_data->bda_power.total , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_POS_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->cr_power1));
|
||
os_mem_cpy(data, &uint_data->cr_power1 , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_NEG_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->cr_power2));
|
||
os_mem_cpy(data, &uint_data->cr_power2 , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_QRT1_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->re_1st_power));
|
||
os_mem_cpy(data, &uint_data->re_1st_power , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_QRT2_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->re_2nd_power));
|
||
os_mem_cpy(data, &uint_data->re_2nd_power , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_QRT3_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->re_3rd_power));
|
||
os_mem_cpy(data, &uint_data->re_3rd_power , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EQT_QRT4_SUM:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->re_4th_power));
|
||
os_mem_cpy(data, &uint_data->re_4th_power , min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_POS_DEMAND:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->pos_ap_demand));
|
||
os_mem_cpy(data, &uint_data->pos_ap_demand, min_len);
|
||
break;
|
||
}
|
||
case PROTO_645_2007_DI_EPT_NEG_DEMAND:
|
||
{
|
||
min_len= min(len, sizeof(uint_data->neg_ap_demand));
|
||
os_mem_cpy(data, &uint_data->neg_ap_demand, min_len);
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
static uint16_t iot_sg_sta_ext_gw_clct_data_resp_fill(
|
||
uint8_t *data, uint16_t len, uint8_t *di_cnt,
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *task_info,
|
||
iot_sg_meter_lc_uint_xian_data_t *uint_data)
|
||
{
|
||
uint8_t reason = 0, i, unit_min_len, *tmp_data;
|
||
uint16_t fill_len = 0, tmp_len;
|
||
uint32_t di;
|
||
|
||
if (!data || !len || !di_cnt || !task_info || !uint_data) {
|
||
reason = 1;
|
||
goto out;
|
||
}
|
||
tmp_data = data;
|
||
tmp_len = len;
|
||
if (task_info->proto_type != IOT_SG_STA_DATA_TYPE_645_07 &&
|
||
task_info->proto_type != IOT_SG_STA_DATA_TYPE_69845) {
|
||
reason = 2;
|
||
goto out;
|
||
}
|
||
for (i = 0; i < task_info->di_cnt; i++) {
|
||
di = task_info->di_info[i].di;
|
||
if (task_info->proto_type == IOT_SG_STA_DATA_TYPE_645_07) {
|
||
unit_min_len = iot_sg_sta_ext_gw_clct_645_di_unit_min_len_get(di);
|
||
} else {
|
||
unit_min_len = iot_sg_sta_ext_gw_clct_698_oad_unit_min_len_get(di);
|
||
}
|
||
if (!task_info->di_info[i].data_len) {
|
||
continue;
|
||
}
|
||
if (task_info->di_info[i].data_len > tmp_len) {
|
||
reason = 3;
|
||
goto out;
|
||
}
|
||
os_mem_set(tmp_data, 0xFF, task_info->di_info[i].data_len);
|
||
if (unit_min_len && unit_min_len <= task_info->di_info[i].data_len &&
|
||
!(task_info->di_info[i].data_len % unit_min_len)) {
|
||
if (task_info->proto_type == IOT_SG_STA_DATA_TYPE_645_07) {
|
||
iot_sg_sta_ext_gw_clct_uint_645_data_write(di, tmp_data,
|
||
task_info->di_info[i].data_len, uint_data);
|
||
} else {
|
||
iot_sg_sta_ext_gw_clct_uint_698_data_write(di, tmp_data,
|
||
task_info->di_info[i].data_len, uint_data, unit_min_len);
|
||
}
|
||
}
|
||
tmp_len -= task_info->di_info[i].data_len;
|
||
tmp_data += task_info->di_info[i].data_len;
|
||
fill_len += task_info->di_info[i].data_len;
|
||
(*di_cnt) += 1;
|
||
}
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
return fill_len;
|
||
}
|
||
|
||
uint16_t iot_sg_sta_ext_gw_clct_data_read(uint8_t *addr, uint8_t task_id,
|
||
iot_time_tm_t *tm, uint8_t *data, uint16_t len, uint8_t *di_cnt,
|
||
uint8_t *proto_type)
|
||
{
|
||
uint8_t reason = 0;
|
||
uint16_t fill_len = 0, max_cnt, index, unit_len;
|
||
uint32_t ret = ERR_FAIL;
|
||
iot_pkt_t *pkt = NULL, *cfg_pkt = NULL;
|
||
iot_sg_sta_drv_meter_gw_clct_task_info_t *task_info;
|
||
iot_sg_meter_lc_uint_xian_data_t *flash_xian_data;
|
||
|
||
if (!addr || !tm || !data || !len || !di_cnt || !task_id) {
|
||
reason = 1;
|
||
goto out;
|
||
}
|
||
cfg_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
||
if (!cfg_pkt) {
|
||
reason = 2;
|
||
goto out;
|
||
}
|
||
task_info = (iot_sg_sta_drv_meter_gw_clct_task_info_t *)
|
||
iot_pkt_put(cfg_pkt, sizeof(*cfg_pkt));
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(addr, task_id, task_info)
|
||
!= ERR_OK) {
|
||
reason = 3;
|
||
goto out;
|
||
}
|
||
if (iot_sg_sta_flash_unit_get_data_info(IOT_SG_STA_METER_DATA_TYPE_GW_TASK,
|
||
&unit_len, &max_cnt)) {
|
||
reason = 4;
|
||
goto out;
|
||
}
|
||
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
||
if (!pkt) {
|
||
reason = 5;
|
||
goto out;
|
||
}
|
||
flash_xian_data = (iot_sg_meter_lc_uint_xian_data_t*)iot_pkt_put(
|
||
pkt, unit_len);
|
||
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &index, tm,
|
||
(uint8_t *)flash_xian_data, unit_len, task_id, 1,
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK);
|
||
if (ret != ERR_OK) {
|
||
reason = 6;
|
||
goto out;
|
||
}
|
||
if (flash_xian_data->year != (uint32_t)(tm->tm_year % 100) ||
|
||
flash_xian_data->month != (uint32_t)(tm->tm_mon) ||
|
||
flash_xian_data->day != (uint32_t)(tm->tm_mday) ||
|
||
flash_xian_data->hour != (uint32_t)(tm->tm_hour) ||
|
||
flash_xian_data->minute != (uint32_t)(tm->tm_min)) {
|
||
reason = 7;
|
||
goto out;
|
||
}
|
||
fill_len = iot_sg_sta_ext_gw_clct_data_resp_fill(data, len, di_cnt,
|
||
task_info, flash_xian_data);
|
||
if (fill_len) {
|
||
*proto_type = task_info->proto_type;
|
||
}
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
if (pkt) {
|
||
iot_pkt_free(pkt);
|
||
}
|
||
if (cfg_pkt) {
|
||
iot_pkt_free(cfg_pkt);
|
||
}
|
||
return fill_len;
|
||
}
|
||
|
||
static void iot_sg_sta_ext_gw_clct_data_save(uint8_t *addr, iot_time_tm_t *tm)
|
||
{
|
||
|
||
uint8_t reason = 0, task_id;
|
||
uint16_t index = 0, max_cnt = 0, unit_len = 0;
|
||
uint32_t ret;
|
||
iot_pkt_t *pkt = NULL;
|
||
iot_time_tm_t cache_tm = { 0 };
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
|
||
iot_sg_meter_lc_uint_xian_data_t *flash_xian_data;
|
||
|
||
if (iot_sg_sta_flash_unit_get_data_info(IOT_SG_STA_METER_DATA_TYPE_GW_TASK,
|
||
&unit_len, &max_cnt)) {
|
||
reason = 3;
|
||
goto out;
|
||
}
|
||
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
||
if (!pkt) {
|
||
reason = 4;
|
||
goto out;
|
||
}
|
||
flash_xian_data = (iot_sg_meter_lc_uint_xian_data_t*)iot_pkt_put(
|
||
pkt, unit_len);
|
||
task_id = ext_info->gw_clct_info->cur_task_id;
|
||
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &index, tm,
|
||
(uint8_t *)flash_xian_data, unit_len, task_id, 1,
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK);
|
||
if (ret == ERR_OK) {
|
||
cache_tm.tm_year = (uint16_t)(flash_xian_data->year + 2000);
|
||
cache_tm.tm_mon = (uint8_t)flash_xian_data->month;
|
||
cache_tm.tm_mday = (uint8_t)flash_xian_data->day;
|
||
cache_tm.tm_hour = (uint8_t)flash_xian_data->hour;
|
||
cache_tm.tm_min = (uint8_t)flash_xian_data->minute;
|
||
if (iot_rtc_delta_calc(&cache_tm, tm) != 0) {
|
||
index++;
|
||
}
|
||
}
|
||
if (index >= max_cnt) {
|
||
index = 0;
|
||
}
|
||
flash_xian_data->year = (uint32_t)(tm->tm_year % 100);
|
||
flash_xian_data->month = (uint32_t)(tm->tm_mon);
|
||
flash_xian_data->day = (uint32_t)(tm->tm_mday);
|
||
flash_xian_data->hour = (uint32_t)(tm->tm_hour);
|
||
flash_xian_data->minute = (uint32_t)(tm->tm_min);
|
||
os_mem_cpy(&flash_xian_data->v, &meter->v, sizeof(meter->v));
|
||
os_mem_cpy(&flash_xian_data->i, &meter->a, sizeof(meter->a));
|
||
os_mem_cpy(flash_xian_data->n, meter->gnd_a, sizeof(meter->gnd_a));
|
||
os_mem_cpy(&flash_xian_data->active_power, &meter->ap,
|
||
sizeof(meter->ap));
|
||
os_mem_cpy(&flash_xian_data->reactive_power, &meter->rp,
|
||
sizeof(meter->rp));
|
||
os_mem_cpy(&flash_xian_data->power_factor, &meter->pf,
|
||
sizeof(meter->pf));
|
||
os_mem_cpy(&flash_xian_data->ca_power, &meter->cae,
|
||
sizeof(meter->cae));
|
||
os_mem_cpy(&flash_xian_data->fda_power, &meter->pae,
|
||
sizeof(meter->pae));
|
||
os_mem_cpy(&flash_xian_data->bda_power, &meter->nae,
|
||
sizeof(meter->nae));
|
||
os_mem_cpy(flash_xian_data->cr_power1, meter->cre1.total,
|
||
sizeof(meter->cre1.total));
|
||
os_mem_cpy(flash_xian_data->cr_power2, meter->cre2.total,
|
||
sizeof(meter->cre2.total));
|
||
os_mem_cpy(flash_xian_data->re_1st_power, meter->re_1st.total,
|
||
sizeof(meter->re_1st));
|
||
os_mem_cpy(flash_xian_data->re_2nd_power, meter->re_2st.total,
|
||
sizeof(meter->re_2st));
|
||
os_mem_cpy(flash_xian_data->re_3rd_power, meter->re_3st.total,
|
||
sizeof(meter->re_3st));
|
||
os_mem_cpy(flash_xian_data->re_4th_power, meter->re_4st.total,
|
||
sizeof(meter->re_4st));
|
||
os_mem_cpy(flash_xian_data->ap_demand, meter->ept_demand,
|
||
sizeof(meter->ept_demand));
|
||
os_mem_cpy(flash_xian_data->rp_demand, meter->eqt_demand,
|
||
sizeof(meter->eqt_demand));
|
||
os_mem_cpy(flash_xian_data->pos_ap_demand, &meter->pos_ap_demand,
|
||
sizeof(meter->pos_ap_demand));
|
||
os_mem_cpy(flash_xian_data->neg_ap_demand, &meter->neg_ap_demand,
|
||
sizeof(meter->neg_ap_demand));
|
||
ret = iot_sg_sta_flash_ct_unit_data_save(addr, index,
|
||
(uint8_t *)flash_xian_data, unit_len, task_id);
|
||
if (ret != ERR_OK) {
|
||
reason = 5;
|
||
goto out;
|
||
}
|
||
iot_sg_sta_flash_ct_unit_data_check(addr, index, tm, task_id,
|
||
IOT_SG_STA_METER_DATA_TYPE_GW_TASK);
|
||
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x task_id %d idx %d \n",
|
||
__FUNCTION__, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
|
||
task_id, index);
|
||
iot_sg_printf("%s time %lu-%lu-%lu %lu:%lu:%lu\n", __FUNCTION__,
|
||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||
tm->tm_sec);
|
||
out:
|
||
if (reason) {
|
||
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
||
}
|
||
if (pkt) {
|
||
iot_pkt_free(pkt);
|
||
}
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_clct_task_id_exist_check(uint8_t *addr,
|
||
uint8_t task_id)
|
||
{
|
||
uint8_t i;
|
||
uint32_t ret = ERR_NOT_EXIST;
|
||
iot_pkt_t *pkt;
|
||
iot_sg_sta_flash_clct_task_id_t *task_id_info;
|
||
|
||
pkt = iot_sg_sta_flash_clct_task_id_info_get(addr);
|
||
if (pkt == NULL) {
|
||
goto out;
|
||
}
|
||
task_id_info = (iot_sg_sta_flash_clct_task_id_t*)iot_pkt_data(pkt);
|
||
for (i = 0; i < task_id_info->cnt; i++) {
|
||
if (task_id == GW_APP_V28_CLCT_PARAM_TASK_NUM_ALL) {
|
||
if (task_id_info->task_id[i]) {
|
||
ret = ERR_OK;
|
||
break;
|
||
}
|
||
} else {
|
||
if (task_id_info->task_id[i] == task_id) {
|
||
ret = ERR_OK;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
out:
|
||
if (pkt) {
|
||
iot_pkt_free(pkt);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static uint32_t iot_sg_sta_ext_gw_698_oad_check(uint32_t oad)
|
||
{
|
||
uint32_t new_oad = oad;
|
||
|
||
switch(oad) {
|
||
case PROTO_69845_APP_OAD_VOLTAGE_A:
|
||
{
|
||
new_oad = PROTO_69845_APP_OAD_VOLTAGE;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_CURRENT_A:
|
||
{
|
||
new_oad = PROTO_69845_APP_OAD_CURRENT;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_P_T:
|
||
case PROTO_69845_APP_OAD_P_A:
|
||
{
|
||
new_oad = PROTO_69845_APP_OAD_P;
|
||
break;
|
||
}
|
||
case PROTO_69845_APP_OAD_EPT_COMP_SUM:
|
||
{
|
||
new_oad = PROTO_69845_APP_OAD_EPT_COMP;
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
return new_oad;
|
||
}
|
||
|
||
static iot_pkt_t * iot_sg_sta_ext_gw_69845_lr_mr_msg_build(uint8_t *addr)
|
||
{
|
||
uint32_t get_list_req_size, oad;
|
||
uint8_t di_cnt, i, oad_idx = 0, attribute, cur_index = 0;
|
||
iot_pkt_t *pkt = NULL, *get_list_req = NULL;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info = ext_info->gw_clct_info;
|
||
proto_69845_app_get_list_req_info_t *req = NULL;
|
||
server_addr_info_t server = {0};
|
||
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
goto out;
|
||
}
|
||
di_cnt = clct_info->cur_clct_cfg.di_cnt - clct_info->index;
|
||
if (di_cnt > IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM) {
|
||
di_cnt = IOT_SG_STA_EXT_GW_CLCT_MAX_OI_NUM;
|
||
}
|
||
get_list_req_size = sizeof(proto_69845_app_oad_t) * di_cnt + sizeof(*req);
|
||
get_list_req = iot_pkt_alloc(get_list_req_size, IOT_SMART_GRID_MID);
|
||
if (!get_list_req) {
|
||
goto out;
|
||
}
|
||
req = (proto_69845_app_get_list_req_info_t *)iot_pkt_put(get_list_req,
|
||
get_list_req_size);
|
||
req->type = PROTO_69845_APP_GET_NORMALLIST;
|
||
req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
|
||
req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
|
||
/* fill di from di_buff */
|
||
for (i = 0; i < di_cnt; i++) {
|
||
if (clct_info->index + i >= IOT_SG_STA_METER_CLCT_TASK_DI_CNT_GW) {
|
||
break;
|
||
}
|
||
if (clct_info->cur_clct_cfg.proto_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
oad = clct_info->cur_clct_cfg.di_info[clct_info->index + i].di;
|
||
oad = iot_sg_sta_ext_gw_698_oad_check(oad);
|
||
} else {
|
||
oad = proto_645_di_to_698_oad(
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index + i].di);
|
||
}
|
||
cur_index = clct_info->index + i;
|
||
if (oad != PROTO_69845_APP_OAD_INVALID) {
|
||
req->oad[oad_idx].oi = (uint16_t)(oad >> 16);
|
||
attribute = (oad >> 8) & 0xff;
|
||
req->oad[oad_idx].attribute_id = attribute & 0x1f;
|
||
req->oad[oad_idx].attribute_char = attribute >> 5;
|
||
req->oad[oad_idx].element_index = oad & 0xff;
|
||
oad_idx++;
|
||
}
|
||
}
|
||
clct_info->index = cur_index;
|
||
req->oad_cnt = oad_idx;
|
||
server.len = PROTO_69845_SA_LEN;
|
||
server.type = PROTO_69845_SA_TYPE_SIG;
|
||
iot_mac_addr_cpy(server.addr, addr);
|
||
pkt = proto_69845_build_get_req_msg_with_rn(req, &server);
|
||
iot_pkt_free(get_list_req);
|
||
out:
|
||
return pkt;
|
||
}
|
||
|
||
uint8_t iot_sg_sta_ext_gw_data_freeze_func(uint8_t *addr)
|
||
{
|
||
uint8_t complete = 0, last_state = 0, flag_new = 0;
|
||
uint16_t timeout;
|
||
uint32_t ret;
|
||
iot_pkt_t *pkt;
|
||
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
||
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
||
iot_sg_sta_ext_gw_clct_info_t *clct_info = ext_info->gw_clct_info;
|
||
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
||
iot_time_tm_t tm, *node_tm, start_tm = { 0 };
|
||
|
||
IOT_ASSERT(node);
|
||
start_tm.tm_year = 2000;
|
||
start_tm.tm_mon = 1;
|
||
start_tm.tm_mday = 1;
|
||
handle:
|
||
if (!clct_info->cur_task_id) {
|
||
goto done;
|
||
}
|
||
if (iot_sg_sta_ext_gw_clct_task_id_exist_check(addr,
|
||
clct_info->cur_task_id) != ERR_OK) {
|
||
goto done;
|
||
}
|
||
if (iot_sg_sta_rtc_get(&tm, 1)) {
|
||
/* get time fail, stop lr function */
|
||
iot_sg_printf("%s get time err\n", __FUNCTION__);
|
||
goto done;
|
||
}
|
||
/* node_tm index 0 - 7, flash task id 1 -8 */
|
||
node_tm =
|
||
&node->ext.gw_node_clct_info.task_tm[clct_info->cur_task_id - 1];
|
||
last_state = clct_info->state;
|
||
switch (clct_info->state) {
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_IDLE:
|
||
{
|
||
if (!node_tm->tm_year && !node_tm->tm_mon &&
|
||
!node_tm->tm_mday && !node_tm->tm_hour &&
|
||
!node_tm->tm_min && !node_tm->tm_sec) {
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(addr,
|
||
clct_info->cur_task_id, &clct_info->cur_clct_cfg)
|
||
!= ERR_OK) {
|
||
goto done;
|
||
}
|
||
/* load read load curve data time stamp */
|
||
*node_tm = iot_sg_ext_get_next_lr_ts(start_tm,
|
||
clct_info->cur_clct_cfg.period * 60, tm);
|
||
goto done;
|
||
} else if (iot_rtc_delta_calc(node_tm, &tm) >= 0) {
|
||
if (iot_sg_sta_ext_gw_data_clct_cfg_get(addr,
|
||
clct_info->cur_task_id, &clct_info->cur_clct_cfg)
|
||
!= ERR_OK) {
|
||
goto done;
|
||
}
|
||
/* when current tm is greater than or equal to next tm of
|
||
* reading load curve data, start read load curve data.
|
||
*/
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_SEND;
|
||
clct_info->index = 0;
|
||
flag_new = 1;
|
||
goto send;
|
||
} else {
|
||
goto done;
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_WAIT:
|
||
{
|
||
if (!clct_info->timeout_cnt) {
|
||
if (!clct_info->repeat_cnt || clct_info->flag_resp) {
|
||
clct_info->index++;
|
||
clct_info->repeat_cnt = 0;
|
||
flag_new = 1;
|
||
}
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
iot_sg_sta_ext_gw_clct_data_save(addr, node_tm);
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_END;
|
||
*node_tm = iot_sg_ext_get_next_lr_ts(start_tm,
|
||
clct_info->cur_clct_cfg.period * 60, tm);
|
||
goto done;
|
||
}
|
||
if (clct_info->repeat_cnt) {
|
||
clct_info->repeat_cnt--;
|
||
if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
clct_info->index = clct_info->last_index_698;
|
||
}
|
||
}
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_SEND;
|
||
} else {
|
||
clct_info->timeout_cnt--;
|
||
break;
|
||
}
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_SEND:
|
||
{
|
||
send:
|
||
if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
||
clct_info->last_index_698 = clct_info->index;
|
||
pkt = iot_sg_sta_ext_gw_69845_lr_mr_msg_build(addr);
|
||
} else {
|
||
pkt = proto_645_build_mr_msg(PROTO_645_2007_ID, addr,
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index].di);
|
||
}
|
||
if (pkt) {
|
||
timeout = (IOT_SG_STA_EXT_READ_DATA_TIMEOUT *
|
||
IOT_SG_STA_EXT_SM_DELAY / 100);
|
||
timeout = min(timeout, IOT_SG_STA_EXT_DRV_READ_TIMEOUT);
|
||
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_GW_CLCT,
|
||
addr, 0, node->data_type, iot_pkt_data(pkt),
|
||
(uint16_t)iot_pkt_data_len(pkt), timeout);
|
||
if (ret == ERR_OK) {
|
||
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x read id "
|
||
"%08x idx %lu task id %lu\n", __FUNCTION__, addr[0],
|
||
addr[1], addr[2],addr[3], addr[4], addr[5],
|
||
clct_info->cur_clct_cfg.di_info[clct_info->index].di,
|
||
clct_info->index, clct_info->cur_task_id);
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_WAIT;
|
||
clct_info->timeout_cnt = IOT_SG_STA_EXT_READ_DATA_TIMEOUT;
|
||
if (flag_new) {
|
||
clct_info->repeat_cnt = 1;
|
||
}
|
||
clct_info->flag_resp = 0;
|
||
}
|
||
iot_pkt_free(pkt);
|
||
} else {
|
||
clct_info->index++;
|
||
if (clct_info->index >= clct_info->cur_clct_cfg.di_cnt) {
|
||
iot_sg_sta_ext_gw_clct_data_save(addr, node_tm);
|
||
clct_info->state = IOT_SG_STA_EXT_GW_CLCT_STATE_END;
|
||
*node_tm = iot_sg_ext_get_next_lr_ts(start_tm,
|
||
clct_info->cur_clct_cfg.period * 60, tm);
|
||
goto done;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case IOT_SG_STA_EXT_GW_CLCT_STATE_END:
|
||
{
|
||
goto done;
|
||
break;
|
||
}
|
||
default:
|
||
IOT_ASSERT(0);
|
||
break;
|
||
}
|
||
goto out;
|
||
done:
|
||
iot_sg_ext_gw_data_clct_cur_info_clear(clct_info);
|
||
clct_info->cur_task_id++;
|
||
if (clct_info->cur_task_id > IOT_SG_STA_EXT_GW_V28_CLCT_TASK_MAX_CNT) {
|
||
clct_info->cur_task_id = 1;
|
||
complete = 1;
|
||
} else {
|
||
/* continue to the next task */
|
||
goto handle;
|
||
}
|
||
out:
|
||
if (last_state != clct_info->state) {
|
||
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x state %lu to %lu\n"
|
||
, __FUNCTION__, addr[0], addr[1], addr[2], addr[3], addr[4],
|
||
addr[5], last_state, clct_info->state);
|
||
}
|
||
return complete;
|
||
}
|
||
|
||
uint32_t iot_sg_sta_ext_gw_rpt_data_collect(uint8_t *data,
|
||
uint16_t len, uint8_t flag_local)
|
||
{
|
||
(void)data;
|
||
(void)len;
|
||
(void)flag_local;
|
||
return ERR_NOSUPP;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_func(void) { }
|
||
|
||
void iot_sg_sta_ext_gw_rpt_done_handle(uint16_t seq, uint8_t state)
|
||
{
|
||
(void)seq;
|
||
(void)state;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_stop(void) { }
|
||
|
||
void iot_sg_sta_ext_gw_rpt_enable(uint8_t flag_en)
|
||
{
|
||
(void)flag_en;
|
||
}
|
||
|
||
void iot_sg_sta_ext_gw_rpt_unit_timeout_hande(void) { }
|
||
|
||
#endif /* IOT_SMART_GRID_GW_V28_OP2_ENABLE */
|
||
|
||
#endif
|