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

3046 lines
103 KiB
C
Raw Blame History

/****************************************************************************
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