9319 lines
317 KiB
C
9319 lines
317 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"
|
|
#include "iot_version_api.h"
|
|
#include "iot_bitmap_api.h"
|
|
#include "iot_plc_led_api.h"
|
|
|
|
/* smart grid internal header files */
|
|
#include "iot_sg_fr.h"
|
|
#include "iot_sg.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"
|
|
#include "proto_645_fj.h"
|
|
#include "iot_sg_sta_upgrade.h"
|
|
#include "iot_board_api.h"
|
|
|
|
#if (IOT_SMART_GRID_EXT_FJ_FUNC_ENABLE)
|
|
|
|
/* define data freeze state */
|
|
#define IOT_SG_STA_EXT_FREEZR_STATE_IDLE (0)
|
|
#define IOT_SG_STA_EXT_FREEZR_STATE_SEND (1)
|
|
#define IOT_SG_STA_EXT_FREEZR_STATE_WAIT (2)
|
|
|
|
/* define data freeze function */
|
|
#define IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_1 (0)
|
|
#define IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_0 (1)
|
|
#define IOT_SG_STA_EXT_FREEZR_FUNC_RPT (2)
|
|
#define IOT_SG_STA_EXT_FREEZR_FUNC_CNT (3)
|
|
|
|
/* freeze task data default random report time max value, uint is 1% */
|
|
#define IOT_SG_STA_EXT_TASK_RANDOM_RPT_PERCENT_MAX (90)
|
|
/* freeze task data default random report time, uint is 1% */
|
|
#define IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_DEF (50)
|
|
/* freeze task data default random report time min percent of task cycle, uint is 1% */
|
|
#define IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_MIN (10)
|
|
/* freeze task data default random report time max value, uint is 1s */
|
|
#define IOT_SG_STA_EXT_TASK_RANDOM_RPT_TIME_MAX (300)
|
|
/* freeze task data default random report time min value, uint is 1s */
|
|
#define IOT_SG_STA_EXT_TASK_RANDON_RPT_TIME_MIN (1)
|
|
/* freeze task data record unit default lengtht */
|
|
#define IOT_SG_STA_EXT_TASK_REC_UNIT_LEN_DEF (200)
|
|
/* freeze task data report default cnt within 24H */
|
|
#define IOT_SG_STA_EXT_TASK_RPT_CNT_DEF (100)
|
|
/* freeze task data repeat reporting dur, uint is 1s */
|
|
#define IOT_SG_STA_EXT_TASK_RE_RPT_DUR (15)
|
|
|
|
/* freeze task response data cache len */
|
|
#define IOT_SG_STA_EXT_FREEZR_CACHE_LEN (1024)
|
|
|
|
/* freeze task response data cache len for simple 698 */
|
|
#define IOT_SG_STA_EXT_FREEZR_698_CACHE_LEN (2048)
|
|
|
|
/* collect last day freeze data min interval time, uint is 1s */
|
|
#define IOT_SG_STA_EXT_FREEZE_LAST_DF_MIN_TIME (60 * 30)
|
|
|
|
/* chg task cache di list max len */
|
|
#define IOT_SG_STA_EXT_CACHE_DI_LIST_MAX_LEN (128)
|
|
|
|
/* write meter multiple data item flag enable */
|
|
#define IOT_SG_STA_EXT_WRITE_MULT_FLAG_EN (0)
|
|
|
|
/* define led blink enable counter, unit is 1s refresh interval */
|
|
#define IOT_SG_STA_EXT_LED_BLINK_EN_CNT (2)
|
|
|
|
/* define freeze data build msg type */
|
|
#define IOT_SG_STA_EXT_FREEZE_BUILD_MSG_645 (0)
|
|
#define IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698 (1)
|
|
|
|
/* define simple 698 max len desc byte number */
|
|
#define IOT_SG_STA_EXT_698_LEN_BYTE_MAX_NUM (2)
|
|
|
|
/* pack for the structures in the whole file */
|
|
#pragma pack(push) /* save the pack status */
|
|
#pragma pack(1) /* 1 byte align */
|
|
|
|
/* freeze task response data cache infomation */
|
|
typedef struct _iot_sg_sta_ext_freeze_resp_cache_data {
|
|
/* record time */
|
|
iot_sg_meter_unit_time_with_sec_t rec_time;
|
|
/* cache di count */
|
|
uint8_t di_cnt;
|
|
/* unit data len */
|
|
uint16_t unit_len;
|
|
/* iot_sg_sta_drv_meter_fj_unit_data_t */
|
|
uint8_t unit_data[0];
|
|
} iot_sg_sta_ext_freeze_resp_cache_data_t;
|
|
|
|
/* freeze task response data cache di infomation */
|
|
typedef struct _iot_sg_sta_ext_freeze_resp_cache_di_info {
|
|
/* di */
|
|
uint32_t di;
|
|
/* resp len */
|
|
uint8_t resp_len;
|
|
/* resp data first byte */
|
|
uint8_t resp_first_byte;
|
|
} iot_sg_sta_ext_freeze_resp_cache_di_info_t;
|
|
|
|
/* freeze task response data cache */
|
|
typedef struct _iot_sg_sta_ext_freeze_resp_cache_hdr {
|
|
/* task type, see PROTO_645_FJ_TASK_TYPE_XXX */
|
|
uint8_t type;
|
|
/* freeze data start time */
|
|
iot_time_tm_t start_tm;
|
|
/* freeze data cache end time */
|
|
iot_time_tm_t cache_end_tm;
|
|
/* freeze data cache end time index */
|
|
uint16_t cache_end_tm_idx;
|
|
/* task cycle*/
|
|
proto_645_fj_task_cycle_t cycle;
|
|
/* storage times to task response */
|
|
uint16_t storage_times;
|
|
/* query count */
|
|
uint8_t query_cnt;
|
|
/* response count */
|
|
uint8_t rsp_cnt;
|
|
/* di count*/
|
|
uint8_t di_cnt;
|
|
/* di */
|
|
iot_sg_sta_ext_freeze_resp_cache_di_info_t di_info[0];
|
|
/* iot_sg_sta_ext_freeze_resp_cache_data_t */
|
|
} iot_sg_sta_ext_freeze_resp_cache_hdr_t;
|
|
|
|
#pragma pack(pop) /* restore the pack status */
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_comm_cfg_save(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *cfg_comm);
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_count(uint8_t task_id,
|
|
uint8_t flag_total_cnt, uint8_t count);
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_group_get(uint8_t id)
|
|
{
|
|
uint8_t group = PROTO_645_FJ_TASK_GROUP_UNKNOWN;
|
|
|
|
if (id >= PROTO_FJ_FREEZE_645_TASK_ID_MIN &&
|
|
id <= PROTO_FJ_FREEZE_645_TASK_ID_MAX) {
|
|
group = PROTO_645_FJ_TASK_GROUP_645;
|
|
} else if (id >= PROTO_FJ_FREEZE_698_TASK_ID_MIN &&
|
|
id <= PROTO_FJ_FREEZE_698_TASK_ID_MAX) {
|
|
group = PROTO_645_FJ_TASK_GROUP_698;
|
|
}
|
|
return group;
|
|
}
|
|
|
|
static iot_sg_sta_drv_meter_fj_unit_data_t *iot_sg_ext_freeze_di_unit_data_get(
|
|
uint32_t di, uint8_t *data, uint16_t len, uint8_t unit_cnt)
|
|
{
|
|
uint8_t i;
|
|
uint16_t offset = 0;
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data = NULL;
|
|
|
|
if (!data || !len || !unit_cnt) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < unit_cnt; i++) {
|
|
if (len < sizeof(*unit_data)) {
|
|
goto out;
|
|
}
|
|
len -= sizeof(*unit_data);
|
|
unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)(data + offset);
|
|
if (len < unit_data->len) {
|
|
goto out;
|
|
}
|
|
len -= unit_data->len;
|
|
offset += (sizeof(*unit_data) + unit_data->len);
|
|
if (unit_data->len < PROTO_645_2007_DI_LEN) {
|
|
continue;
|
|
}
|
|
if (di == proto_645_2007_byte_to_di(unit_data->data)) {
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
}
|
|
out:
|
|
if (ret != ERR_OK) {
|
|
unit_data = NULL;
|
|
}
|
|
return unit_data;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_chg_unit_di_list_get(
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *cur_data,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_data,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
uint32_t *di_list, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, j, skip, di_full = 0, last_di_fill = 0;
|
|
uint8_t di_cnt = 0, i, tmp_offset, valid_len, *unit_data_tmp, resp_data_cnt;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
|
|
if (!cur_data || !last_data || !di_list || !len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (cache_hdr) {
|
|
for (i = 0; i < cache_hdr->di_cnt; i++) {
|
|
di_list[i] = cache_hdr->di_info[i].di;
|
|
di_cnt++;
|
|
if (di_cnt >= len / PROTO_645_2007_DI_LEN) {
|
|
break;
|
|
}
|
|
}
|
|
goto out;
|
|
}
|
|
valid_len = cur_data->valid_len;
|
|
unit_data_tmp = cur_data->uint_data;
|
|
resp_data_cnt = cur_data->resp_data_cnt;
|
|
tmp_offset = 0;
|
|
di_fill:
|
|
for (i = 0; i < resp_data_cnt; i++) {
|
|
if (valid_len < sizeof(*unit_data)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)
|
|
(unit_data_tmp + tmp_offset);
|
|
valid_len -= sizeof(*unit_data);
|
|
if (valid_len < unit_data->len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
valid_len -= unit_data->len;
|
|
tmp_offset += sizeof(*unit_data) + unit_data->len;
|
|
if (unit_data->len <= PROTO_645_2007_DI_LEN) {
|
|
continue;
|
|
}
|
|
skip = 0;
|
|
for (j = 0; j < di_cnt; j++) {
|
|
if (!os_mem_cmp((uint8_t *)&di_list[i], unit_data->data,
|
|
PROTO_645_2007_DI_LEN)) {
|
|
skip = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (skip) {
|
|
continue;
|
|
}
|
|
os_mem_cpy((uint8_t *)&di_list[di_cnt], unit_data->data,
|
|
PROTO_645_2007_DI_LEN);
|
|
di_cnt++;
|
|
if (di_cnt >= len / PROTO_645_2007_DI_LEN) {
|
|
di_full = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (di_full) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (!last_di_fill) {
|
|
last_di_fill = 1;
|
|
valid_len = last_data->valid_len;
|
|
unit_data_tmp = last_data->uint_data;
|
|
resp_data_cnt = last_data->resp_data_cnt;
|
|
tmp_offset = 0;
|
|
goto di_fill;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return di_cnt;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_645_di_ff_unit_min_len_get(uint32_t di)
|
|
{
|
|
uint8_t unit_data_len = 0;
|
|
switch (di) {
|
|
case PROTO_645_2007_DI_V_ALL:
|
|
{
|
|
unit_data_len = PROTO_645_V_LEN;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_I_ALL:
|
|
{
|
|
unit_data_len = PROTO_645_07_A_LEN;
|
|
break;
|
|
}
|
|
case PROTO_645_2007_DI_P_ALL:
|
|
case PROTO_645_2007_DI_PF_ALL:
|
|
case PROTO_645_2007_DI_Q_ALL:
|
|
{
|
|
unit_data_len = PROTO_645_07_P_LEN;
|
|
break;
|
|
}
|
|
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;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return unit_data_len;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_645_unit_to_698_unit(uint32_t di,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t unit_len, i, *data_tmp;
|
|
iot_sg_meter_max_demand_and_ht_t *pos_demand, *neg_demand;
|
|
|
|
if ((di | 0xFFFF00FF) == 0xFFFFFFFF) {
|
|
unit_len = iot_sg_sta_ext_fj_645_di_ff_unit_min_len_get(di);
|
|
if (!unit_len || (len % unit_len )) {
|
|
iot_data_reverse(data, len);
|
|
goto out;
|
|
}
|
|
data_tmp = data;
|
|
for (i = 0; i < (len / unit_len); i++) {
|
|
iot_data_reverse(data_tmp, unit_len);
|
|
data_tmp += unit_len;
|
|
}
|
|
} else {
|
|
switch (di) {
|
|
case PROTO_645_2007_DI_EPT_POS_DEMAND:
|
|
{
|
|
if (len != sizeof(*pos_demand)) {
|
|
break;
|
|
}
|
|
pos_demand = (iot_sg_meter_max_demand_and_ht_t *)data;
|
|
iot_data_reverse(pos_demand->max_demand,
|
|
IOT_SG_STA_METER_POWER_LEN);
|
|
iot_data_reverse(pos_demand->max_demand +
|
|
IOT_SG_STA_METER_POWER_LEN,
|
|
sizeof(*pos_demand) - IOT_SG_STA_METER_POWER_LEN);
|
|
goto out;
|
|
}
|
|
case PROTO_645_2007_DI_EPT_NEG_DEMAND:
|
|
{
|
|
if (len != sizeof(*neg_demand)) {
|
|
break;
|
|
}
|
|
neg_demand = (iot_sg_meter_max_demand_and_ht_t *)data;
|
|
iot_data_reverse(neg_demand->max_demand,
|
|
IOT_SG_STA_METER_POWER_LEN);
|
|
iot_data_reverse(neg_demand->max_demand +
|
|
IOT_SG_STA_METER_POWER_LEN,
|
|
sizeof(*neg_demand) - IOT_SG_STA_METER_POWER_LEN);
|
|
goto out;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
iot_data_reverse(data, len);
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_chg_data_to_resp(
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *cur_data,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_data,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data, uint16_t max_len,
|
|
uint8_t type, proto_645_fj_task_cycle_t cycle,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
uint8_t msg_type, uint8_t task_id)
|
|
{
|
|
iot_pkt_t *di_list_pkt = NULL;
|
|
uint32_t *di_list;
|
|
uint8_t resp_first_byte;
|
|
uint8_t resp_len = 0, i, unit_len, reason = 0, di_cnt, group_type;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *cur_unit_data, *last_unit_data;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *chg_unit_data;
|
|
proto_645_fj_task_data_query_di_unit_t *di_unit;
|
|
|
|
if (!cur_data || !last_data || !resp_data || !max_len) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (max_len < sizeof(*resp_data)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
max_len -= sizeof(*resp_data);
|
|
resp_data->type = type;
|
|
resp_data->start.year =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.year);
|
|
resp_data->start.month =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.month);
|
|
resp_data->start.day =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.day);
|
|
resp_data->start.hour =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.hour);
|
|
resp_data->start.minute =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.minute);
|
|
resp_data->start.second =
|
|
iot_byte_to_bcd((uint8_t)last_data->uint_time.second);
|
|
if (last_data->storage_times) {
|
|
resp_data->storage_times = last_data->storage_times - 1;
|
|
} else {
|
|
resp_data->storage_times = last_data->storage_times;
|
|
}
|
|
resp_data->task_cycle = cycle;
|
|
resp_data->frozen_point_cnt = 2;
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
resp_data->start.year = (uint8_t)last_data->uint_time.year;
|
|
resp_data->start.month = (uint8_t)last_data->uint_time.month;
|
|
resp_data->start.day = (uint8_t)last_data->uint_time.day;
|
|
resp_data->start.hour = (uint8_t)last_data->uint_time.hour;
|
|
resp_data->start.minute = (uint8_t)last_data->uint_time.minute;
|
|
resp_data->start.second = (uint8_t)last_data->uint_time.second;
|
|
iot_data_reverse((uint8_t *)&resp_data->start,
|
|
sizeof(resp_data->start));
|
|
iot_data_reverse((uint8_t *)&resp_data->storage_times,
|
|
sizeof(resp_data->storage_times));
|
|
iot_data_reverse((uint8_t *)&resp_data->task_cycle,
|
|
sizeof(resp_data->task_cycle));
|
|
}
|
|
resp_data->di_cnt = 0;
|
|
di_list_pkt = iot_pkt_alloc(IOT_SG_STA_EXT_CACHE_DI_LIST_MAX_LEN,
|
|
IOT_SMART_GRID_MID);
|
|
if (!di_list_pkt) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
di_list = (uint32_t *)iot_pkt_put(di_list_pkt,
|
|
IOT_SG_STA_EXT_CACHE_DI_LIST_MAX_LEN);
|
|
di_cnt = iot_sg_sta_ext_fj_task_chg_unit_di_list_get(cur_data, last_data,
|
|
cache_hdr, di_list, IOT_SG_STA_EXT_CACHE_DI_LIST_MAX_LEN);
|
|
if (!di_cnt) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
group_type = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
for (i = 0; i < di_cnt; i++) {
|
|
last_unit_data = iot_sg_ext_freeze_di_unit_data_get(di_list[i],
|
|
last_data->uint_data, last_data->valid_len,
|
|
last_data->resp_data_cnt);
|
|
cur_unit_data = iot_sg_ext_freeze_di_unit_data_get(di_list[i],
|
|
cur_data->uint_data, cur_data->valid_len, cur_data->resp_data_cnt);
|
|
if (!last_unit_data && !cur_unit_data) {
|
|
continue;
|
|
}
|
|
if (last_unit_data) {
|
|
chg_unit_data = last_unit_data;
|
|
} else {
|
|
chg_unit_data = cur_unit_data;
|
|
}
|
|
unit_len = sizeof(*di_unit) + (chg_unit_data->len -
|
|
PROTO_645_2007_DI_LEN) * resp_data->frozen_point_cnt;
|
|
/* check response msg max len */
|
|
if ((resp_len + unit_len) > max_len) {
|
|
resp_data->result = PROTO_645_FJ_READ_RESP_DATA_OVERFLOW;
|
|
break;
|
|
}
|
|
di_unit = (proto_645_fj_task_data_query_di_unit_t *)
|
|
(resp_data->di_data + resp_len);
|
|
di_unit->length = chg_unit_data->len - PROTO_645_2007_DI_LEN;
|
|
os_mem_cpy((uint8_t *)&di_unit->di, chg_unit_data->data,
|
|
PROTO_645_2007_DI_LEN);
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
iot_data_reverse((uint8_t *)&di_unit->di, sizeof(di_unit->di));
|
|
}
|
|
resp_first_byte = 0xff;
|
|
if (last_unit_data) {
|
|
os_mem_cpy(di_unit->di_data, last_unit_data->data +
|
|
PROTO_645_2007_DI_LEN, di_unit->length);
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698 &&
|
|
group_type == PROTO_645_FJ_TASK_GROUP_645) {
|
|
iot_sg_sta_ext_fj_645_unit_to_698_unit(di_unit->di,
|
|
di_unit->di_data, di_unit->length);
|
|
}
|
|
if (di_unit->length) {
|
|
resp_first_byte = di_unit->di_data[0];
|
|
}
|
|
} else {
|
|
os_mem_set(di_unit->di_data, 0xFF, di_unit->length);
|
|
}
|
|
if (cur_unit_data) {
|
|
os_mem_cpy(di_unit->di_data + di_unit->length,
|
|
cur_unit_data->data + PROTO_645_2007_DI_LEN, di_unit->length);
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698 &&
|
|
group_type == PROTO_645_FJ_TASK_GROUP_645) {
|
|
iot_sg_sta_ext_fj_645_unit_to_698_unit(di_unit->di,
|
|
di_unit->di_data + di_unit->length, di_unit->length);
|
|
}
|
|
if (di_unit->length) {
|
|
resp_first_byte = di_unit->di_data[di_unit->length];
|
|
}
|
|
} else {
|
|
os_mem_set(di_unit->di_data + di_unit->length, 0xFF,
|
|
di_unit->length);
|
|
}
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698 &&
|
|
resp_first_byte != 0xff) {
|
|
di_unit->di_data[0] = resp_first_byte;
|
|
di_unit->di_data[di_unit->length] = resp_first_byte;
|
|
}
|
|
resp_len += unit_len;
|
|
resp_data->di_cnt++;
|
|
}
|
|
if (resp_data->result != PROTO_645_FJ_READ_RESP_DATA_OVERFLOW) {
|
|
resp_data->result = PROTO_645_FJ_READ_RESP_DATA_OK;
|
|
}
|
|
resp_len += sizeof(*resp_data);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s drop %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
if (di_list_pkt) {
|
|
iot_pkt_free(di_list_pkt);
|
|
}
|
|
return resp_len;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_single_data_to_resp(
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_data,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data, uint8_t max_len,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg_info, uint8_t msg_type,
|
|
uint8_t task_id)
|
|
{
|
|
uint8_t group_type;
|
|
uint8_t resp_len = 0, i, offset = 0, unit_len, valid_len, reason = 0;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
proto_645_fj_task_data_query_di_unit_t *di_unit;
|
|
|
|
if (!task_data || !resp_data || !max_len || !cfg_info) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (max_len < sizeof(*resp_data)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
max_len -= sizeof(*resp_data);
|
|
resp_data->type = cfg_info->type;
|
|
resp_data->start.year =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.year);
|
|
resp_data->start.month =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.month);
|
|
resp_data->start.day =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.day);
|
|
resp_data->start.hour =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.hour);
|
|
resp_data->start.minute =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.minute);
|
|
resp_data->start.second =
|
|
iot_byte_to_bcd((uint8_t)task_data->uint_time.second);
|
|
if (task_data->storage_times) {
|
|
resp_data->storage_times = task_data->storage_times - 1;
|
|
} else {
|
|
resp_data->storage_times = task_data->storage_times;
|
|
}
|
|
resp_data->task_cycle.value = cfg_info->value;
|
|
resp_data->task_cycle.unit = cfg_info->unit;
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
resp_data->start.year = (uint8_t)task_data->uint_time.year;
|
|
resp_data->start.month = (uint8_t)task_data->uint_time.month;
|
|
resp_data->start.day = (uint8_t)task_data->uint_time.day;
|
|
resp_data->start.hour = (uint8_t)task_data->uint_time.hour;
|
|
resp_data->start.minute = (uint8_t)task_data->uint_time.minute;
|
|
resp_data->start.second = (uint8_t)task_data->uint_time.second;
|
|
iot_data_reverse((uint8_t *)&resp_data->start,
|
|
sizeof(resp_data->start));
|
|
iot_data_reverse((uint8_t *)&resp_data->storage_times,
|
|
sizeof(resp_data->storage_times));
|
|
iot_data_reverse((uint8_t *)&resp_data->task_cycle,
|
|
sizeof(resp_data->task_cycle));
|
|
}
|
|
resp_data->frozen_point_cnt = 1;
|
|
resp_data->di_cnt = 0;
|
|
valid_len = task_data->valid_len;
|
|
group_type = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
for (i = 0; i < task_data->resp_data_cnt; i++) {
|
|
if (valid_len < sizeof(*unit_data)) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)
|
|
(task_data->uint_data + offset);
|
|
valid_len -= sizeof(*unit_data);
|
|
if (valid_len < unit_data->len) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
valid_len -= unit_data->len;
|
|
unit_len = sizeof(*unit_data) + unit_data->len;
|
|
offset += unit_len;
|
|
if (unit_data->len <= PROTO_645_2007_DI_LEN) {
|
|
continue;
|
|
}
|
|
/* check response msg max len */
|
|
if ((resp_len + unit_len) > max_len) {
|
|
resp_data->result = PROTO_645_FJ_READ_RESP_DATA_OVERFLOW;
|
|
break;
|
|
}
|
|
di_unit = (proto_645_fj_task_data_query_di_unit_t *)
|
|
(resp_data->di_data + resp_len);
|
|
di_unit->length = unit_data->len - PROTO_645_2007_DI_LEN;
|
|
os_mem_cpy((uint8_t *)&di_unit->di, unit_data->data,
|
|
PROTO_645_2007_DI_LEN);
|
|
os_mem_cpy(di_unit->di_data, unit_data->data + PROTO_645_2007_DI_LEN,
|
|
di_unit->length);
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
iot_data_reverse((uint8_t *)&di_unit->di, sizeof(di_unit->di));
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_645) {
|
|
iot_sg_sta_ext_fj_645_unit_to_698_unit(di_unit->di,
|
|
di_unit->di_data, di_unit->length);
|
|
}
|
|
}
|
|
resp_len += unit_len;
|
|
resp_data->di_cnt++;
|
|
}
|
|
if (resp_data->result != PROTO_645_FJ_READ_RESP_DATA_OVERFLOW) {
|
|
resp_data->result = PROTO_645_FJ_READ_RESP_DATA_OK;
|
|
}
|
|
resp_len += sizeof(*resp_data);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s drop %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return resp_len;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_reset(
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info)
|
|
{
|
|
if (rpt_info->rpt_pkt) {
|
|
iot_pkt_free(rpt_info->rpt_pkt);
|
|
}
|
|
os_mem_set(rpt_info, 0, sizeof(*rpt_info));
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_rpt_msg_data_fill(
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_task_unit,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg_info,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data,
|
|
uint8_t max_len, uint8_t msg_type, uint8_t task_id)
|
|
{
|
|
uint8_t len;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
if (last_task_unit && cfg_info->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
cycle.value = cfg_info->value;
|
|
cycle.unit = cfg_info->unit;
|
|
len = iot_sg_sta_ext_fj_task_chg_data_to_resp(task_unit, last_task_unit,
|
|
resp_data, max_len, cfg_info->type, cycle, NULL, msg_type, task_id);
|
|
} else {
|
|
len = iot_sg_sta_ext_fj_task_single_data_to_resp(task_unit, resp_data,
|
|
max_len, cfg_info, msg_type, task_id);
|
|
}
|
|
if (!len) {
|
|
resp_data->type = cfg_info->type;
|
|
resp_data->result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
len = sizeof(resp_data->result) + sizeof(resp_data->type);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_rpt_msg_build(
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_task_unit,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg_info,
|
|
uint8_t task_id, uint8_t mode)
|
|
{
|
|
uint8_t max_len = PROTO_645_FJ_RESP_DATA_MAX_LEN, len, cache_len, msg_type;
|
|
uint32_t di = PROTO_645_FJ_DI_QR_TASK_DATA + task_id;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_69845_app_result_normal_t *result;
|
|
proto_69845_octet_string_uint_t *oct_hdr;
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data;
|
|
|
|
pkt = iot_pkt_alloc(max_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
if (mode == PROTO_645_FJ_REPORT_MODE_645) {
|
|
resp_data = (proto_645_fj_task_data_query_hdr_ul_t *)iot_pkt_data(pkt);
|
|
msg_type = IOT_SG_STA_EXT_FREEZE_BUILD_MSG_645;
|
|
} else {
|
|
len = sizeof(*result) + sizeof(*oct_hdr) + 1;
|
|
iot_pkt_reserve(pkt, len);
|
|
resp_data = (proto_645_fj_task_data_query_hdr_ul_t *)iot_pkt_data(pkt);
|
|
max_len -= len;
|
|
msg_type = IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698;
|
|
}
|
|
len = iot_sg_sta_ext_fj_rpt_msg_data_fill(task_unit, last_task_unit,
|
|
cfg_info, resp_data, max_len, msg_type, task_id);
|
|
iot_pkt_put(pkt, len);
|
|
if (mode == PROTO_645_FJ_REPORT_MODE_698) {
|
|
if (len < 128) {
|
|
cache_len = 0;
|
|
} else {
|
|
cache_len = 1;
|
|
}
|
|
cache_len = sizeof(*result) + sizeof(*oct_hdr) + cache_len;
|
|
result = (proto_69845_app_result_normal_t*)iot_pkt_push(pkt, cache_len);
|
|
iot_uint32_to_bytes(di, (uint8_t*)(&result->oad), 1);
|
|
result->get_result.result_type = PROTO_69845_APP_GET_RESULT_DATA;
|
|
oct_hdr = (proto_69845_octet_string_uint_t*)result->get_result.result;
|
|
oct_hdr->data_type = PROTO_69845_APP_DATA_OCTET_STRING;
|
|
if (len < 128) {
|
|
oct_hdr->len_info.mub_flag = 0;
|
|
oct_hdr->len_info.byte_num = len;
|
|
} else {
|
|
oct_hdr->len_info.mub_flag = 1;
|
|
oct_hdr->len_info.byte_num = 1;
|
|
oct_hdr->len_and_data[0] = len;
|
|
}
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_random_rpt_tm_get(
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t random_rpt_time)
|
|
{
|
|
uint16_t time = 0;
|
|
uint32_t field = 0;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
cycle.value = cfg->value;
|
|
cycle.unit = cfg->unit;
|
|
field = proto_645_fj_task_cycle_to_sec(&cycle);
|
|
field = (field * random_rpt_time) / 100;
|
|
if (field > IOT_SG_STA_EXT_TASK_RANDOM_RPT_TIME_MAX) {
|
|
field = IOT_SG_STA_EXT_TASK_RANDOM_RPT_TIME_MAX;
|
|
} else if (field < IOT_SG_STA_EXT_TASK_RANDON_RPT_TIME_MIN) {
|
|
field = IOT_SG_STA_EXT_TASK_RANDON_RPT_TIME_MIN;
|
|
}
|
|
time = (uint16_t)(os_rand() % field);
|
|
iot_sg_printf("random rpt time %lu in [0, %lu]\n", time, field);
|
|
return time;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_data_rpt_msg_merge_cnt_get(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *comm_cfg, uint8_t task_id)
|
|
{
|
|
uint8_t merge_cnt = 0, i;
|
|
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (comm_cfg->task_rpt[i].id == task_id) {
|
|
merge_cnt = comm_cfg->task_rpt[i].cnt;
|
|
break;
|
|
}
|
|
}
|
|
return merge_cnt;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_rpt_645_msg_check(
|
|
proto_645_fj_task_data_query_hdr_ul_t *src_hdr,
|
|
proto_645_fj_task_data_query_hdr_ul_t *merge_hdr)
|
|
{
|
|
uint8_t *src_ptr, *merge_ptr, i;
|
|
uint32_t ret = ERR_FAIL;
|
|
int64_t interval;
|
|
iot_time_tm_t src_tm = {0}, merge_tm = {0};
|
|
proto_645_fj_task_data_query_di_unit_t *src_unit, *merge_unit;
|
|
|
|
if (merge_hdr->type != PROTO_645_FJ_TASK_TYPE_FREEZE
|
|
|| src_hdr->type != merge_hdr->type
|
|
|| src_hdr->task_cycle.value != merge_hdr->task_cycle.value
|
|
|| src_hdr->task_cycle.unit != merge_hdr->task_cycle.unit
|
|
|| src_hdr->di_cnt != merge_hdr->di_cnt) {
|
|
goto out;
|
|
}
|
|
src_tm.tm_year = iot_bcd_to_byte(src_hdr->start.year) + 2000;
|
|
src_tm.tm_mon = iot_bcd_to_byte(src_hdr->start.month);
|
|
src_tm.tm_mday = iot_bcd_to_byte(src_hdr->start.day);
|
|
src_tm.tm_hour = iot_bcd_to_byte(src_hdr->start.hour);
|
|
src_tm.tm_min = iot_bcd_to_byte(src_hdr->start.minute);
|
|
src_tm.tm_sec = iot_bcd_to_byte(src_hdr->start.second);
|
|
merge_tm.tm_year = iot_bcd_to_byte(merge_hdr->start.year) + 2000;
|
|
merge_tm.tm_mon = iot_bcd_to_byte(merge_hdr->start.month);
|
|
merge_tm.tm_mday = iot_bcd_to_byte(merge_hdr->start.day);
|
|
merge_tm.tm_hour = iot_bcd_to_byte(merge_hdr->start.hour);
|
|
merge_tm.tm_min = iot_bcd_to_byte(merge_hdr->start.minute);
|
|
merge_tm.tm_sec = iot_bcd_to_byte(merge_hdr->start.second);
|
|
interval = (int64_t)proto_645_fj_task_cycle_to_sec(&src_hdr->task_cycle);
|
|
interval = interval * src_hdr->frozen_point_cnt;
|
|
iot_rtc_delta_add(interval, &src_tm);
|
|
if (iot_rtc_delta_calc(&src_tm, &merge_tm) != 0) {
|
|
goto out;
|
|
}
|
|
src_ptr = src_hdr->di_data;
|
|
merge_ptr = merge_hdr->di_data;
|
|
for (i = 0; i < src_hdr->di_cnt; i++) {
|
|
src_unit = (proto_645_fj_task_data_query_di_unit_t*)src_ptr;
|
|
merge_unit = (proto_645_fj_task_data_query_di_unit_t*)merge_ptr;
|
|
if ((src_unit->di != merge_unit->di)
|
|
|| (src_unit->length != merge_unit->length)) {
|
|
goto out;
|
|
}
|
|
src_ptr += (sizeof(*src_unit) +
|
|
src_unit->length * src_hdr->frozen_point_cnt);
|
|
merge_ptr += (sizeof(*merge_unit) +
|
|
merge_unit->length * merge_hdr->frozen_point_cnt);
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_rpt_645_msg_total_len_get(
|
|
proto_645_fj_task_data_query_hdr_ul_t *src_hdr, uint32_t len,
|
|
uint8_t merge_cnt)
|
|
{
|
|
uint8_t *src_ptr, i;
|
|
uint32_t total_len = len;
|
|
proto_645_fj_task_data_query_di_unit_t *src_unit;
|
|
|
|
src_ptr = src_hdr->di_data;
|
|
for (i = 0; i < src_hdr->di_cnt; i++) {
|
|
src_unit = (proto_645_fj_task_data_query_di_unit_t*)src_ptr;
|
|
total_len += (src_unit->length * merge_cnt);
|
|
src_ptr += (sizeof(*src_unit) +
|
|
src_unit->length * src_hdr->frozen_point_cnt);
|
|
}
|
|
return total_len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_ext_data_rpt_645_msg_merge(uint8_t *src_data,
|
|
uint32_t src_len, uint8_t *merge_data, uint32_t merge_len)
|
|
{
|
|
uint8_t *src_ptr, *merge_ptr, *total_ptr, *ptr,i;
|
|
uint32_t total_len;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_data_query_hdr_ul_t *src_hdr, *merge_hdr, *total_hdr;
|
|
proto_645_fj_task_data_query_di_unit_t *src_unit, *merge_unit, *total_unit;
|
|
|
|
(void)merge_len;
|
|
src_hdr = (proto_645_fj_task_data_query_hdr_ul_t*)src_data;
|
|
merge_hdr = (proto_645_fj_task_data_query_hdr_ul_t*)merge_data;
|
|
if (iot_sg_ext_data_rpt_645_msg_check(src_hdr, merge_hdr)) {
|
|
goto out;
|
|
}
|
|
total_len = iot_sg_ext_data_rpt_645_msg_total_len_get(src_hdr, src_len,
|
|
merge_hdr->frozen_point_cnt);
|
|
if (total_len > PROTO_645_FJ_RESP_DATA_MAX_LEN) {
|
|
src_hdr->result = PROTO_645_FJ_READ_RESP_DATA_OVERFLOW;
|
|
goto out;
|
|
}
|
|
pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
|
|
total_hdr = (proto_645_fj_task_data_query_hdr_ul_t*)iot_pkt_put(pkt,
|
|
total_len);
|
|
os_mem_cpy(total_hdr, src_hdr, sizeof(*src_hdr));
|
|
total_hdr->frozen_point_cnt += merge_hdr->frozen_point_cnt;
|
|
src_ptr = src_hdr->di_data;
|
|
merge_ptr = merge_hdr->di_data;
|
|
total_ptr = total_hdr->di_data;
|
|
for (i = 0; i < total_hdr->di_cnt; i++) {
|
|
src_unit = (proto_645_fj_task_data_query_di_unit_t*)src_ptr;
|
|
merge_unit = (proto_645_fj_task_data_query_di_unit_t*)merge_ptr;
|
|
total_unit = (proto_645_fj_task_data_query_di_unit_t*)total_ptr;
|
|
os_mem_cpy(total_unit, src_unit, sizeof(*src_unit));
|
|
total_len = src_unit->length * src_hdr->frozen_point_cnt;
|
|
os_mem_cpy(total_unit->di_data, src_unit->di_data, total_len);
|
|
ptr = total_unit->di_data + total_len;
|
|
total_len = merge_unit->length * merge_hdr->frozen_point_cnt;
|
|
os_mem_cpy(ptr, merge_unit->di_data, total_len);
|
|
src_ptr += (sizeof(*src_unit) +
|
|
src_unit->length * src_hdr->frozen_point_cnt);
|
|
merge_ptr += (sizeof(*merge_unit) +
|
|
merge_unit->length * merge_hdr->frozen_point_cnt);
|
|
total_ptr += (sizeof(*total_unit) +
|
|
total_unit->length * total_hdr->frozen_point_cnt);
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_ext_data_rpt_698_msg_merge(uint8_t *src_data,
|
|
uint32_t src_len, uint8_t *merge_data, uint32_t merge_len)
|
|
{
|
|
uint8_t *ptr;
|
|
uint32_t len = src_len + merge_len;
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
if (len < IOT_SG_STA_EXT_FREEZR_CACHE_LEN) {
|
|
pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
|
|
if (pkt) {
|
|
ptr = iot_pkt_put(pkt, len);
|
|
os_mem_cpy(ptr, src_data, src_len);
|
|
ptr += src_len;
|
|
os_mem_cpy(ptr, merge_data, merge_len);
|
|
}
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_ext_data_rpt_msg_merge(uint8_t *addr,
|
|
uint8_t task_id, uint8_t *merge_cnt, uint8_t rpt_mode, uint8_t msg_type,
|
|
iot_pkt_t *unit_pkt)
|
|
{
|
|
uint8_t i, idx = 0xff;
|
|
uint16_t max_cnt = *merge_cnt + 1;
|
|
iot_pkt_t *rpt_pkt = unit_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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_merge_uint_t *merge_info;
|
|
|
|
*merge_cnt = 1;
|
|
if ((rpt_mode == PROTO_645_FJ_REPORT_MODE_645)
|
|
&& (msg_type != PROTO_645_FJ_TASK_TYPE_FREEZE)) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
merge_info = &freeze_task->merge_list[i];
|
|
if (merge_info->merge_pkt) {
|
|
if (iot_mac_addr_cmp(addr, merge_info->addr)
|
|
&& task_id == merge_info->task_id) {
|
|
idx = i;
|
|
goto handle;
|
|
}
|
|
} else if (idx == 0xff) {
|
|
idx = i;
|
|
}
|
|
}
|
|
if (i == 0xff) {
|
|
goto out;
|
|
}
|
|
handle:
|
|
merge_info = &freeze_task->merge_list[idx];
|
|
if (merge_info->merge_pkt && (merge_info->mode == rpt_mode)) {
|
|
if (rpt_mode == PROTO_645_FJ_REPORT_MODE_645) {
|
|
rpt_pkt = iot_sg_ext_data_rpt_645_msg_merge(
|
|
iot_pkt_data(merge_info->merge_pkt),
|
|
iot_pkt_data_len(merge_info->merge_pkt),
|
|
iot_pkt_data(unit_pkt), iot_pkt_data_len(unit_pkt));
|
|
} else {
|
|
rpt_pkt = iot_sg_ext_data_rpt_698_msg_merge(
|
|
iot_pkt_data(merge_info->merge_pkt),
|
|
iot_pkt_data_len(merge_info->merge_pkt),
|
|
iot_pkt_data(unit_pkt), iot_pkt_data_len(unit_pkt));
|
|
}
|
|
if (rpt_pkt) {
|
|
iot_pkt_free(merge_info->merge_pkt);
|
|
iot_pkt_free(unit_pkt);
|
|
merge_info->msg_cnt++;
|
|
if (merge_info->msg_cnt >= max_cnt) {
|
|
*merge_cnt = merge_info->msg_cnt;
|
|
os_mem_set(merge_info, 0, sizeof(*merge_info));
|
|
} else {
|
|
merge_info->merge_pkt = rpt_pkt;
|
|
rpt_pkt = NULL;
|
|
*merge_cnt = 0;
|
|
}
|
|
} else {
|
|
rpt_pkt = merge_info->merge_pkt;
|
|
*merge_cnt = merge_info->msg_cnt;
|
|
merge_info->merge_pkt = unit_pkt;
|
|
merge_info->msg_cnt = 1;
|
|
}
|
|
} else {
|
|
if (merge_info->merge_pkt) {
|
|
iot_pkt_free(merge_info->merge_pkt);
|
|
}
|
|
merge_info->merge_pkt = rpt_pkt;
|
|
merge_info->mode = rpt_mode;
|
|
merge_info->task_id = task_id;
|
|
merge_info->msg_cnt = 1;
|
|
iot_mac_addr_cpy(merge_info->addr, addr);
|
|
rpt_pkt = NULL;
|
|
*merge_cnt = 0;
|
|
}
|
|
out:
|
|
return rpt_pkt;
|
|
}
|
|
|
|
static void iot_sg_ext_data_rpt_msg_merge_del(uint8_t *addr,
|
|
uint8_t task_id)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_merge_uint_t *merge_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
merge_info = &freeze_task->merge_list[i];
|
|
if (iot_mac_addr_cmp(addr, merge_info->addr)
|
|
&& task_id == merge_info->task_id) {
|
|
if (merge_info->merge_pkt) {
|
|
iot_pkt_free(merge_info->merge_pkt);
|
|
os_mem_set(merge_info, 0, sizeof(*merge_info));
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_sg_ext_data_rpt_msg_merge_del_by_mode(
|
|
uint8_t mode)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_merge_uint_t *merge_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
merge_info = &freeze_task->merge_list[i];
|
|
if (merge_info->mode == mode && merge_info->merge_pkt
|
|
&& (iot_sg_sta_ext_fj_task_group_get(merge_info->task_id)
|
|
== PROTO_645_FJ_TASK_GROUP_645)) {
|
|
iot_pkt_free(merge_info->merge_pkt);
|
|
os_mem_set(merge_info, 0, sizeof(*merge_info));
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_add(iot_pkt_t *rpt_pkt, uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t mode,
|
|
uint8_t msg_cnt)
|
|
{
|
|
uint8_t i, old_idx = 0;
|
|
uint32_t 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
if (!rpt_pkt || !addr || !task_id || (task_id >
|
|
PROTO_FJ_FREEZE_TASK_ID_MAX) || !msg_cnt || !cfg) {
|
|
goto out;
|
|
}
|
|
if (iot_sg_sta_power_off_check()) {
|
|
iot_pkt_free(rpt_pkt);
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt == NULL) {
|
|
goto handle;
|
|
}
|
|
if (!tm) {
|
|
old_idx = i;
|
|
tm = rpt_info->tm;
|
|
} else if (rpt_info->tm < tm) {
|
|
old_idx = i;
|
|
tm = rpt_info->tm;
|
|
}
|
|
}
|
|
rpt_info = &freeze_task->rpt_list[old_idx];
|
|
handle:
|
|
iot_sg_sta_ext_fj_rpt_reset(rpt_info);
|
|
rpt_info->rpt_pkt = rpt_pkt;
|
|
rpt_info->seq = iot_sg_sta_get_event_rpt_seq();
|
|
rpt_info->rpt_cnt = 0;
|
|
rpt_info->task_id = task_id;
|
|
rpt_info->mode = !!mode;
|
|
rpt_info->msg_cnt = msg_cnt;
|
|
iot_mac_addr_cpy(rpt_info->addr, addr);
|
|
rpt_info->tm = (uint32_t)(os_boot_time64() / 1000);
|
|
rpt_info->random_rpt_tm = iot_sg_sta_ext_fj_random_rpt_tm_get(cfg,
|
|
freeze_task->comm_cfg.random_rpt_time);
|
|
rpt_info->rpt_tm = rpt_info->tm + rpt_info->random_rpt_tm;
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_del(uint8_t *addr,
|
|
uint8_t task_id)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt && iot_mac_addr_cmp(rpt_info->addr, addr)
|
|
&& (rpt_info->task_id == task_id)) {
|
|
iot_sg_sta_ext_fj_rpt_reset(rpt_info);
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_del_by_mode(uint8_t mode)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt && (mode == rpt_info->mode)
|
|
&& (iot_sg_sta_ext_fj_task_group_get(rpt_info->task_id)
|
|
== PROTO_645_FJ_TASK_GROUP_645)) {
|
|
iot_sg_sta_ext_fj_rpt_reset(rpt_info);
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
uint8_t iot_sg_sta_ext_fj_rpt_seq_check(uint16_t seq)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt && rpt_info->seq == seq) {
|
|
return 1;
|
|
}
|
|
}
|
|
out:
|
|
return 0;
|
|
}
|
|
|
|
void iot_sg_sta_ext_fj_rpt_ack_handle(uint16_t seq)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t *rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
return;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt && rpt_info->seq == seq) {
|
|
iot_sg_sta_ext_fj_rpt_count(rpt_info->task_id, 0,
|
|
rpt_info->msg_cnt);
|
|
iot_sg_sta_ext_fj_rpt_reset(rpt_info);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_sg_ext_data_rpt_task_finish_handle(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_merge_uint_t *merge_info;
|
|
|
|
if (iot_sg_ext_data_task_finish_check(addr, task_id)) {
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
merge_info = &freeze_task->merge_list[i];
|
|
if (merge_info->merge_pkt && (task_id == merge_info->task_id)
|
|
&& iot_mac_addr_cmp(addr, merge_info->addr)) {
|
|
iot_sg_sta_ext_fj_rpt_add(merge_info->merge_pkt, addr, task_id,
|
|
cfg, merge_info->mode, merge_info->msg_cnt);
|
|
os_mem_set(merge_info, 0, sizeof(*merge_info));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_sg_sta_ext_freeze_flash_cfg_valid_set(uint8_t task_id,
|
|
uint8_t flag_valid)
|
|
{
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
if (!freeze_task) {
|
|
goto out;
|
|
}
|
|
if (!task_id || task_id > PROTO_FJ_FREEZE_TASK_ID_MAX) {
|
|
goto out;
|
|
}
|
|
if (flag_valid) {
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (freeze_task->valid_id[i]
|
|
&& freeze_task->valid_id[i] == task_id) {
|
|
goto out;
|
|
}
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (!freeze_task->valid_id[i]) {
|
|
freeze_task->valid_id[i] = task_id;
|
|
goto out;
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (freeze_task->valid_id[i]
|
|
&& freeze_task->valid_id[i] == task_id) {
|
|
freeze_task->valid_id[i] = 0;
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_freeze_flash_cfg_valid_check(uint8_t task_id,
|
|
uint8_t *idx)
|
|
{
|
|
uint8_t flag_valid = 0, 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
if (!freeze_task) {
|
|
goto out;
|
|
}
|
|
if (!task_id || task_id > PROTO_FJ_FREEZE_TASK_ID_MAX) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (freeze_task->valid_id[i] && freeze_task->valid_id[i] == task_id) {
|
|
if (idx) {
|
|
*idx = i;
|
|
}
|
|
flag_valid = 1;
|
|
break;
|
|
}
|
|
}
|
|
out:
|
|
return flag_valid;
|
|
|
|
}
|
|
|
|
static iot_time_tm_t *iot_sg_ext_data_freeze_get_node_tm(
|
|
iot_sg_sta_node_desc_t *node, uint8_t task_id)
|
|
{
|
|
uint8_t idx = 0;
|
|
iot_time_tm_t *tm = NULL;
|
|
if (!node || !iot_sg_sta_ext_freeze_flash_cfg_valid_check(task_id, &idx)) {
|
|
goto out;
|
|
}
|
|
tm = &node->ext.freeze_info.task_tm[idx];
|
|
out:
|
|
return tm;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_freeze_exe_cnt_set(uint8_t task_id,
|
|
uint16_t exe_cnt, uint16_t triger_cnt, uint8_t flag_first)
|
|
{
|
|
uint8_t i = 0, idle = 0xFF;
|
|
uint32_t ret = ERR_NOMEM;
|
|
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_freeze_task_t* task_info = ext_info->freeze_task_info;
|
|
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_info->exe_cnt_remain[i].task_id == task_id) {
|
|
task_info->exe_cnt_remain[i].count = exe_cnt;
|
|
task_info->exe_cnt_remain[i].trigger_cnt = triger_cnt;
|
|
if (flag_first) {
|
|
task_info->exe_cnt_remain[i].data_cnt = 0;
|
|
task_info->exe_cnt_remain[i].valid_len = 0;
|
|
os_mem_set(task_info->exe_cnt_remain[i].last_data, 0,
|
|
sizeof(task_info->exe_cnt_remain[i].last_data));
|
|
}
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
if (task_info->exe_cnt_remain[i].task_id == 0 && idle == 0xFF) {
|
|
idle = i;
|
|
}
|
|
}
|
|
if (idle != 0xFF) {
|
|
task_info->exe_cnt_remain[idle].count = exe_cnt;
|
|
task_info->exe_cnt_remain[idle].task_id = task_id;
|
|
task_info->exe_cnt_remain[idle].trigger_cnt = triger_cnt;
|
|
task_info->exe_cnt_remain[idle].data_cnt = 0;
|
|
task_info->exe_cnt_remain[idle].valid_len = 0;
|
|
task_info->exe_cnt_remain[idle].rpt_total_cnt = 0;
|
|
task_info->exe_cnt_remain[idle].rpt_cnt = 0;
|
|
os_mem_set(task_info->exe_cnt_remain[idle].last_data, 0,
|
|
sizeof(task_info->exe_cnt_remain[idle].last_data));
|
|
ret = ERR_OK;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_freeze_exe_cnt_get(uint8_t task_id,
|
|
uint16_t* exe_cnt, uint16_t* trigger_cnt)
|
|
{
|
|
uint8_t i = 0;
|
|
uint32_t ret = ERR_NOT_EXIST;
|
|
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_freeze_task_t* task_info = ext_info->freeze_task_info;
|
|
|
|
IOT_ASSERT(exe_cnt);
|
|
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_info->exe_cnt_remain[i].task_id == task_id) {
|
|
*exe_cnt = task_info->exe_cnt_remain[i].count;
|
|
*trigger_cnt = task_info->exe_cnt_remain[i].trigger_cnt;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void iot_sg_ext_freeze_exe_cnt_del(uint8_t task_id)
|
|
{
|
|
uint8_t i = 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_freeze_task_t* task_info = ext_info->freeze_task_info;
|
|
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_info->exe_cnt_remain[i].task_id == task_id) {
|
|
task_info->exe_cnt_remain[i].task_id = 0;
|
|
task_info->exe_cnt_remain[i].count = 0;
|
|
task_info->exe_cnt_remain[i].trigger_cnt = 0;
|
|
task_info->exe_cnt_remain[i].data_cnt = 0;
|
|
task_info->exe_cnt_remain[i].valid_len = 0;
|
|
os_mem_set(task_info->exe_cnt_remain[i].last_data, 0,
|
|
sizeof(task_info->exe_cnt_remain[i].last_data));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static iot_sg_sta_ext_freeze_task_exe_cnt_t*
|
|
iot_sg_ext_freeze_last_data_get(uint8_t task_id)
|
|
{
|
|
uint8_t i = 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_freeze_task_t* task_info = ext_info->freeze_task_info;
|
|
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_info->exe_cnt_remain[i].task_id == task_id) {
|
|
return &task_info->exe_cnt_remain[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_flash_cfg_get(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_info_t *task_info)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_valid_check(task_id, NULL)) {
|
|
goto out;
|
|
}
|
|
if (iot_sg_sta_flash_clct_task_info_get(addr, task_id, (uint8_t *)task_info,
|
|
sizeof(*task_info), IOT_SG_STA_METER_DATA_TYPE_FJ_TASK)) {
|
|
goto out;
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_rpt_retry_cnt_get(uint8_t* addr, uint8_t task_id)
|
|
{
|
|
uint8_t reason = 0, count = PROTO_645_FJ_FREEZE_TASK_RERPT_CNT_DEF;
|
|
iot_pkt_t* pkt = NULL;
|
|
uint32_t time = 0;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
iot_sg_sta_drv_meter_fj_task_info_t* cfg;
|
|
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_freeze_task_t* freeze_task = ext_info->freeze_task_info;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t*)iot_pkt_put(pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg) != ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
cycle.value = cfg->value;
|
|
cycle.unit = cfg->unit;
|
|
time = proto_645_fj_task_cycle_to_sec(&cycle);
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE && time < 300) {
|
|
/* For frozen data tasks with a cycle of less than 5 minutes */
|
|
count = freeze_task->comm_cfg.retry_freeze;
|
|
} else {
|
|
count = freeze_task->comm_cfg.retry_nonfreeze;
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_led_blink_disable(
|
|
iot_sg_sta_ext_freeze_task_t *task)
|
|
{
|
|
if (!task->led_blink_en_cnt) {
|
|
iot_plc_led_request(IOT_PLC_LED_SEARCH_METER_END);
|
|
}
|
|
task->led_blink_en_cnt = IOT_SG_STA_EXT_LED_BLINK_EN_CNT;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_led_blink_timeout_enable(
|
|
iot_sg_sta_ext_freeze_task_t *task)
|
|
{
|
|
if (task->led_blink_en_cnt) {
|
|
task->led_blink_en_cnt--;
|
|
if (!task->led_blink_en_cnt) {
|
|
iot_plc_led_request(IOT_PLC_LED_SEARCH_METER_START);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_count(uint8_t task_id,
|
|
uint8_t flag_total_cnt, uint8_t count)
|
|
{
|
|
iot_sg_sta_ext_freeze_task_exe_cnt_t *exe_info;
|
|
|
|
exe_info = iot_sg_ext_freeze_last_data_get(task_id);
|
|
if (exe_info) {
|
|
if (flag_total_cnt) {
|
|
exe_info->rpt_total_cnt += count;
|
|
} else {
|
|
exe_info->rpt_cnt += count;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_rpt_handle(void)
|
|
{
|
|
uint8_t i, *data, retry_cnt;
|
|
uint32_t len, ret, curr_tm, wait, di = PROTO_645_FJ_DI_QR_TASK_DATA;
|
|
server_addr_info_t server_info = {0};
|
|
iot_pkt_t *msg_pkt = 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_freeze_task_t* freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_rpt_uint_t* rpt_info;
|
|
|
|
if (freeze_task == NULL) {
|
|
return;
|
|
}
|
|
curr_tm = (uint32_t)(os_boot_time64() / 1000);
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
rpt_info = &freeze_task->rpt_list[i];
|
|
if (rpt_info->rpt_pkt) {
|
|
retry_cnt = iot_sg_sta_ext_fj_rpt_retry_cnt_get(rpt_info->addr,
|
|
rpt_info->task_id);
|
|
retry_cnt++;
|
|
if (rpt_info->rpt_cnt >= retry_cnt
|
|
|| iot_sg_sta_power_off_check()) {
|
|
iot_sg_sta_ext_fj_rpt_reset(rpt_info);
|
|
continue;
|
|
}
|
|
if (curr_tm < rpt_info->rpt_tm) {
|
|
continue;
|
|
}
|
|
di += rpt_info->task_id;
|
|
if (rpt_info->mode == PROTO_645_FJ_REPORT_MODE_645) {
|
|
msg_pkt = proto_645_fj_build_msg(rpt_info->addr,
|
|
iot_pkt_data(rpt_info->rpt_pkt),
|
|
(uint8_t)iot_pkt_data_len(rpt_info->rpt_pkt),
|
|
di, PROTO_645_FJ_FN_ACTIVE_RPT);
|
|
} else {
|
|
server_info.len = IOT_MAC_ADDR_LEN;
|
|
server_info.type = PROTO_69845_SA_TYPE_SIG;
|
|
iot_mac_addr_cpy(server_info.addr, rpt_info->addr);
|
|
msg_pkt = proto_69845_build_rpt_noti_list_msg(
|
|
iot_pkt_data(rpt_info->rpt_pkt),
|
|
(uint16_t)iot_pkt_data_len(rpt_info->rpt_pkt),
|
|
rpt_info->msg_cnt, &server_info, (uint8_t)rpt_info->seq);
|
|
}
|
|
if (msg_pkt == NULL) {
|
|
continue;
|
|
}
|
|
data = iot_pkt_data(msg_pkt);
|
|
len = iot_pkt_data_len(msg_pkt);
|
|
ret = iot_sg_sta_report_event_with_seq(rpt_info->addr, data, len,
|
|
rpt_info->seq);
|
|
if (ret == ERR_OK) {
|
|
iot_sg_sta_ext_fj_led_blink_disable(freeze_task);
|
|
rpt_info->rpt_cnt++;
|
|
wait = rpt_info->random_rpt_tm > IOT_SG_STA_EXT_TASK_RE_RPT_DUR
|
|
? rpt_info->random_rpt_tm : IOT_SG_STA_EXT_TASK_RE_RPT_DUR;
|
|
rpt_info->rpt_tm = curr_tm + wait;
|
|
iot_sg_printf("%s task_id %lu report %luth\n",
|
|
__FUNCTION__, rpt_info->task_id, rpt_info->rpt_cnt);
|
|
}
|
|
iot_pkt_free(msg_pkt);
|
|
}
|
|
}
|
|
}
|
|
|
|
void iot_sg_sta_ext_freeze_node_tm_update(iot_sg_sta_node_desc_t *node)
|
|
{
|
|
uint8_t idx, task_id;
|
|
int64_t delta;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_info;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
iot_pkt_t *task_pkt = NULL;
|
|
|
|
if (!freeze_task) {
|
|
goto out;
|
|
}
|
|
task_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto out;
|
|
}
|
|
task_info = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*task_info));
|
|
for (idx = 0; idx < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; idx++) {
|
|
task_id = freeze_task->valid_id[idx];
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(node->entry.addr,
|
|
task_id, task_info) != ERR_OK) {
|
|
continue;
|
|
}
|
|
cycle.value = task_info->value;
|
|
cycle.unit = task_info->unit;
|
|
delta = (int64_t)proto_645_fj_task_cycle_to_sec(&cycle);
|
|
if (cycle.unit == PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_DAY ||
|
|
iot_sg_sta_ext_node_tm_check(&node->ext.freeze_info.task_tm[idx],
|
|
delta)) {
|
|
os_mem_set(&node->ext.freeze_info.task_tm[idx], 0x0,
|
|
sizeof(iot_time_tm_t));
|
|
}
|
|
}
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
}
|
|
|
|
static void iot_sg_ext_data_freeze_cur_info_clear(
|
|
iot_sg_sta_ext_freeze_task_t *freeze_task)
|
|
{
|
|
if (!freeze_task) {
|
|
return;
|
|
}
|
|
freeze_task->cur_state = IOT_SG_STA_EXT_FREEZR_STATE_IDLE;
|
|
freeze_task->cur_task_id = 0;
|
|
freeze_task->task_end = 0;
|
|
freeze_task->cur_di_idx = 0;
|
|
freeze_task->cur_mr_di_cnt = 0;
|
|
freeze_task->flag_resp = 0;
|
|
freeze_task->flag_nack_resp = 0;
|
|
freeze_task->flag_rpt = 0;
|
|
freeze_task->repeat_cnt = 0;
|
|
freeze_task->timeout_cnt = 0;
|
|
if (freeze_task->resp_pkt) {
|
|
iot_pkt_free(freeze_task->resp_pkt);
|
|
freeze_task->resp_pkt = NULL;
|
|
}
|
|
}
|
|
|
|
void iot_sg_ext_data_freeze_reset(void)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
iot_sg_sta_ext_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
if (freeze_task) {
|
|
iot_sg_ext_data_freeze_cur_info_clear(freeze_task);
|
|
freeze_task->task_bm = 0;
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_freeze_unit_data_offset_get(uint8_t *data_offset,
|
|
uint8_t max_len, uint8_t resp_data_cnt, uint8_t *data)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
uint8_t offset = 0, i;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
|
|
for (i = 0; i < resp_data_cnt; i++) {
|
|
if (offset >= max_len) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)(data + offset);
|
|
offset += sizeof(*unit_data) + unit_data->len;
|
|
}
|
|
*data_offset = offset;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint64_t iot_sg_ext_freeze_rpt_value_get(uint8_t *data, uint8_t len,
|
|
uint8_t group_type, uint8_t is_big_endian)
|
|
{
|
|
uint8_t i;
|
|
uint64_t cross_value = 0;
|
|
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
for (i = 0; i < len; i++) {
|
|
if (is_big_endian) {
|
|
cross_value |= (data[len - i - 1] << (i * 8));
|
|
} else {
|
|
cross_value |= (data[i] << (i * 8));
|
|
}
|
|
}
|
|
} else {
|
|
for (i = len; i != 0; i--) {
|
|
cross_value += iot_bcd_to_byte(data[i - 1]);
|
|
if ((i - 1) != 0) {
|
|
cross_value *= 100;
|
|
}
|
|
}
|
|
}
|
|
return cross_value;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_freeze_cross_grads_get(uint64_t value,
|
|
proto_645_fj_task_set_cross_rpt_t *cross, uint8_t group_type)
|
|
{
|
|
uint8_t grads = 0, *cross_data, cross_data_len;
|
|
uint64_t cross_value1, cross_value2;
|
|
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
cross_data = cross->value_list + sizeof(proto_69845_app_data_t);
|
|
cross_data_len = cross->value_len - sizeof(proto_69845_app_data_t);
|
|
} else {
|
|
cross_data = cross->value_list;
|
|
cross_data_len = cross->value_len;
|
|
}
|
|
cross_value1 = iot_sg_ext_freeze_rpt_value_get(cross_data, cross_data_len,
|
|
group_type, 0);
|
|
if (value <= cross_value1) {
|
|
goto out;
|
|
}
|
|
cross_data += cross_data_len;
|
|
for (grads = 1; grads < cross->cnt; grads++) {
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
cross_data += sizeof(proto_69845_app_data_t);
|
|
}
|
|
cross_value2 = iot_sg_ext_freeze_rpt_value_get(cross_data,
|
|
cross_data_len, group_type, 0);
|
|
if (value > cross_value1 && value <= cross_value2) {
|
|
goto out;
|
|
}
|
|
cross_value1 = cross_value2;
|
|
cross_data += cross_data_len;
|
|
}
|
|
/* running to here value >= end crossing value */
|
|
out:
|
|
return grads;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_freeze_cross_rpt_check(
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t *data, uint8_t len,
|
|
uint8_t *save_data, uint8_t save_len, uint8_t group_type)
|
|
{
|
|
uint64_t rsp_value, save_value;
|
|
uint8_t flag_rpt = 0, desc_len = cfg->desc_len;
|
|
uint8_t rsp_grads, save_grads, reason = 0, is_big_endian = 0;
|
|
proto_645_fj_task_set_cross_rpt_t *cross;
|
|
proto_69845_app_data_t *save_app_data, *resp_app_data, *set_app_data;
|
|
|
|
if (!cfg || !data || !len || !save_data || !save_len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
cross = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
if (desc_len < sizeof(*cross)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
desc_len -= sizeof(*cross);
|
|
if (desc_len < cross->cnt * cross->value_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (cross->value_len > PROTO_645_FJ_TASK_DESC_CROSS_VALUE_MAX_LEN) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (save_len != cross->value_len || len != cross->value_len) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
if (len < sizeof(*resp_app_data)) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
resp_app_data = (proto_69845_app_data_t *)data;
|
|
save_app_data = (proto_69845_app_data_t *)save_data;
|
|
set_app_data = (proto_69845_app_data_t *)cross->value_list;
|
|
if (resp_app_data->data_type != set_app_data->data_type ||
|
|
save_app_data->data_type != set_app_data->data_type) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
len -= sizeof(*resp_app_data);
|
|
data += sizeof(*resp_app_data);
|
|
save_len -= sizeof(*save_app_data);
|
|
save_data += sizeof(*save_app_data);
|
|
is_big_endian = 1;
|
|
}
|
|
if (!cross->cnt) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
rsp_value = iot_sg_ext_freeze_rpt_value_get(data, len, group_type,
|
|
is_big_endian);
|
|
save_value = iot_sg_ext_freeze_rpt_value_get(save_data, save_len,
|
|
group_type, is_big_endian);
|
|
rsp_grads = iot_sg_ext_freeze_cross_grads_get(rsp_value, cross, group_type);
|
|
save_grads = iot_sg_ext_freeze_cross_grads_get(save_value, cross,
|
|
group_type);
|
|
iot_sg_printf("%s rsp_value %lu grads %lu save_value %lu grads %lu\n",
|
|
__FUNCTION__, (uint32_t)rsp_value, rsp_grads, (uint32_t)save_value,
|
|
save_grads);
|
|
if (rsp_grads != save_grads) {
|
|
flag_rpt = 1;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s fail reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return flag_rpt;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_freeze_chg_rpt_check(
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t *data, uint8_t len,
|
|
uint8_t *save_data, uint8_t save_len, uint8_t debug_flag,
|
|
uint8_t group_type)
|
|
{
|
|
uint64_t rsp_value, save_value, change_value, max_value;
|
|
uint8_t flag_rpt = 0, desc_len = cfg->desc_len, *chg_data, chg_data_len;
|
|
uint8_t reason = 0, is_big_endian = 0;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg;
|
|
proto_69845_app_data_t *save_app_data, *resp_app_data, *set_app_data;
|
|
|
|
if (!cfg || !data || !len || !save_data || !save_len) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
chg = (proto_645_fj_task_set_change_rpt_hdr_t*)cfg->desc;
|
|
if (desc_len < sizeof(*chg )) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
desc_len -= sizeof(*chg);
|
|
if (desc_len < chg->value_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (chg->value_len > PROTO_645_FJ_TASK_DESC_CHANGE_VALUE_MAX_LEN) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (save_len != chg->value_len || len != chg->value_len) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
if (len < sizeof(*save_app_data)) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
resp_app_data = (proto_69845_app_data_t *)data;
|
|
save_app_data = (proto_69845_app_data_t *)save_data;
|
|
set_app_data = (proto_69845_app_data_t *)chg->value_list;
|
|
if (resp_app_data->data_type != set_app_data->data_type ||
|
|
save_app_data->data_type != set_app_data->data_type) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
len -= sizeof(*resp_app_data);
|
|
data += sizeof(*resp_app_data);
|
|
save_len -= sizeof(*save_app_data);
|
|
save_data += sizeof(*save_app_data);
|
|
chg_data_len = chg->value_len - sizeof(*set_app_data);
|
|
chg_data = chg->value_list + sizeof(*set_app_data);
|
|
is_big_endian = 1;
|
|
} else {
|
|
chg_data_len = chg->value_len;
|
|
chg_data = chg->value_list;
|
|
}
|
|
rsp_value = iot_sg_ext_freeze_rpt_value_get(data, len, group_type,
|
|
is_big_endian);
|
|
save_value = iot_sg_ext_freeze_rpt_value_get(save_data, save_len,
|
|
group_type, is_big_endian);
|
|
max_value = iot_sg_ext_freeze_rpt_value_get(chg_data, chg_data_len,
|
|
group_type, 0);
|
|
if (debug_flag) {
|
|
iot_sg_printf("%s rsp_value %lu, save_value %lu, change value %lu\n",
|
|
__FUNCTION__, (uint32_t)rsp_value, (uint32_t)save_value,
|
|
(uint32_t)max_value);
|
|
}
|
|
if (rsp_value >= save_value) {
|
|
change_value = rsp_value - save_value;
|
|
} else {
|
|
change_value = save_value - rsp_value;
|
|
}
|
|
if (change_value >= max_value) {
|
|
flag_rpt = 1;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s fail reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return flag_rpt;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_freeze_rpt_di_check(uint32_t rsp_di,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t idx;
|
|
uint32_t ret = ERR_FAIL, di;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
for (idx = 0; idx < incon_rpt->di_cnt; idx++) {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&incon_rpt->di[idx]);
|
|
if (di == rsp_di) {
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&cross_rpt->di);
|
|
if (di == rsp_di) {
|
|
ret = ERR_OK;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t *)cfg->desc;
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&chg_rpt->di);
|
|
if (di == rsp_di) {
|
|
ret = ERR_OK;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_freeze_rpt_check(uint8_t *addr, uint8_t *data,
|
|
uint8_t len, iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t task_id,
|
|
uint8_t *first_rpt_task)
|
|
{
|
|
uint8_t *save_data, save_len, reason = 0, group_type;
|
|
uint8_t flag_rpt = 0, rsp_len, *rsp_data;
|
|
uint16_t latest_idx = 0, unit_len = 0;
|
|
uint32_t rsp_di;
|
|
int64_t delta;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
iot_time_tm_t *node_tm = NULL, last_tm = {0};
|
|
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_data;
|
|
iot_sg_sta_ext_freeze_task_exe_cnt_t *last_info;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
|
|
if (!cfg || !addr || !data || !task_id || !first_rpt_task) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (len < PROTO_645_2007_DI_LEN) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
group_type = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
rsp_di = proto_645_2007_byte_to_di(data);
|
|
if (iot_sg_ext_freeze_rpt_di_check(rsp_di, cfg)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
rsp_len = len - PROTO_645_2007_DI_LEN;
|
|
rsp_data = data + PROTO_645_2007_DI_LEN;
|
|
last_info = iot_sg_ext_freeze_last_data_get(task_id);
|
|
if (!last_info || !last_info->valid_len || !last_info->data_cnt) {
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
task_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
task_data = (iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(
|
|
task_pkt, unit_len);
|
|
if (iot_sg_sta_flash_ct_unit_data_find_latest(addr, &latest_idx,
|
|
(uint8_t *)task_data, unit_len, task_id,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK) != ERR_OK) {
|
|
if (cfg->type != PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
*first_rpt_task = 1;
|
|
}
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
node_tm = iot_sg_ext_data_freeze_get_node_tm(node, task_id);
|
|
last_tm.tm_year = (uint16_t)(task_data->uint_time.year + 2000);
|
|
last_tm.tm_mon = (uint8_t)task_data->uint_time.month;
|
|
last_tm.tm_mday = (uint8_t)task_data->uint_time.day;
|
|
last_tm.tm_hour = (uint8_t)task_data->uint_time.hour;
|
|
last_tm.tm_min = (uint8_t)task_data->uint_time.minute;
|
|
cycle.value = cfg->value;
|
|
cycle.unit = cfg->unit;
|
|
delta = (int64_t)proto_645_fj_task_cycle_to_sec(&cycle);
|
|
if (!node_tm || iot_rtc_delta_calc(&last_tm, node_tm) != delta) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
if (!last_info) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
last_info->data_cnt = task_data->resp_data_cnt;
|
|
last_info->valid_len = task_data->valid_len;
|
|
os_mem_cpy(last_info->last_data, task_data->uint_data,
|
|
last_info->valid_len);
|
|
}
|
|
unit_data = iot_sg_ext_freeze_di_unit_data_get(rsp_di,
|
|
task_data->uint_data, task_data->valid_len,
|
|
task_data->resp_data_cnt);
|
|
} else {
|
|
unit_data = iot_sg_ext_freeze_di_unit_data_get(rsp_di,
|
|
last_info->last_data, last_info->valid_len,
|
|
last_info->data_cnt);
|
|
}
|
|
if (!unit_data) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
if (unit_data->len <= PROTO_645_2007_DI_LEN) {
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
save_len = unit_data->len - PROTO_645_2007_DI_LEN;
|
|
save_data = unit_data->data + PROTO_645_2007_DI_LEN;
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_CROSS_RPT) {
|
|
flag_rpt = iot_sg_ext_freeze_cross_rpt_check(cfg, rsp_data,
|
|
rsp_len, save_data, save_len, group_type);
|
|
} else if (cfg->type == PROTO_645_FJ_TASK_TYPE_INCON_RPT) {
|
|
if (rsp_len != save_len) {
|
|
reason = 10;
|
|
goto out;
|
|
}
|
|
if (os_mem_cmp(rsp_data, save_data, save_len) != 0) {
|
|
flag_rpt = 1;
|
|
goto out;
|
|
}
|
|
} else if (cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
flag_rpt = iot_sg_ext_freeze_chg_rpt_check(cfg, rsp_data,
|
|
rsp_len, save_data, save_len, 1, group_type);
|
|
}
|
|
out:
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return flag_rpt;
|
|
}
|
|
|
|
static void iot_sg_ext_freeze_cur_task_resp_handle(uint8_t *addr, uint8_t *data,
|
|
uint8_t len)
|
|
{
|
|
uint8_t max_len, offset, ret = 0, first_rpt_task = 0;
|
|
uint16_t unit_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_freeze_task_t *freeze = ext_info->freeze_task_info;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *resp_data;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
|
|
if (!addr || !data || !len) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
task_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, freeze->cur_task_id, cfg)) {
|
|
ret = 3;
|
|
goto out;
|
|
}
|
|
if (!freeze->resp_pkt) {
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
freeze->resp_pkt =
|
|
iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!freeze->resp_pkt) {
|
|
ret = 4;
|
|
goto out;
|
|
}
|
|
iot_pkt_put(freeze->resp_pkt, unit_len);
|
|
}
|
|
resp_data = (iot_sg_sta_drv_meter_fj_task_unit_t *)
|
|
iot_pkt_data(freeze->resp_pkt);
|
|
max_len = IOT_SG_STA_METER_FJ_TASK_RECORD_UINT_LEN;
|
|
if (len + sizeof(*unit_data) + resp_data->valid_len > max_len) {
|
|
freeze->task_end = 1;
|
|
ret = 5;
|
|
goto out;
|
|
}
|
|
if (iot_sg_ext_freeze_unit_data_offset_get(&offset, max_len,
|
|
resp_data->resp_data_cnt, resp_data->uint_data)) {
|
|
ret = 6;
|
|
goto out;
|
|
}
|
|
unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)
|
|
(resp_data->uint_data + offset);
|
|
unit_data->len = len;
|
|
os_mem_cpy(unit_data->data, data, len);
|
|
resp_data->resp_data_cnt++;
|
|
resp_data->valid_len += (len + sizeof(*unit_data));
|
|
if ((cfg->type == PROTO_645_FJ_TASK_TYPE_CROSS_RPT ||
|
|
cfg->type == PROTO_645_FJ_TASK_TYPE_INCON_RPT ||
|
|
cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) && !freeze->flag_rpt) {
|
|
if (iot_sg_ext_freeze_rpt_check(addr, data, len, cfg,
|
|
freeze->cur_task_id, &first_rpt_task)) {
|
|
freeze->flag_rpt = 1;
|
|
}
|
|
freeze->first_rpt_task = first_rpt_task;
|
|
} else if (cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE) {
|
|
freeze->flag_rpt = 1;
|
|
}
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
iot_sg_printf("%s ret %lu\n", __FUNCTION__, ret);
|
|
return;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_freeze_handle_645(uint16_t seq,
|
|
uint8_t data_type, uint8_t *resp_data, uint16_t resp_len,
|
|
uint8_t *req_data, uint16_t req_len)
|
|
{
|
|
uint8_t reason = 0, di_cnt, i, multi_data_len, *multi_data;
|
|
uint32_t ret = ERR_INVAL, di;
|
|
proto_645_header_t *resp_hdr, *req_hdr;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
proto_645_fj_multi_resp_data_t *multi_resp;
|
|
iot_sg_sta_ext_freeze_task_t *freeze = ext_info->freeze_task_info;
|
|
|
|
(void)seq;
|
|
if (ext_info->freeze_task_info->cur_state !=
|
|
IOT_SG_STA_EXT_FREEZR_STATE_WAIT) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (data_type != IOT_SG_STA_DATA_TYPE_645_07) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if ((req_data == NULL) || !req_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if ((resp_data == NULL) || !resp_len) {
|
|
ret = ERR_TIMEOVER;
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (iot_sg_ext_read_645_nack_check(req_data, req_len, resp_data, resp_len,
|
|
ext_info->addr) == ERR_OK) {
|
|
iot_sg_printf("%s nack\n", __FUNCTION__);
|
|
freeze->flag_nack_resp = 1;
|
|
reason = 5;
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
if (proto_645_check_di_fn_match(req_data, req_len,
|
|
resp_data, resp_len)) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
resp_hdr = (proto_645_header_t*)resp_data;
|
|
req_hdr = (proto_645_header_t*)req_data;
|
|
if (!iot_mac_addr_cmp(req_hdr->addr, resp_hdr->addr)) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
if ((resp_hdr->control.ack != PROTO_645_ACK_NORMAL)
|
|
|| (resp_hdr->control.dir != PROTO_645_DIR_SLAVE)) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
if (!iot_mac_addr_cmp(ext_info->addr, resp_hdr->addr)) {
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
if (resp_hdr->len < PROTO_645_2007_DI_LEN) {
|
|
reason = 10;
|
|
goto out;
|
|
}
|
|
proto_645_sub33_handle(resp_hdr->data, resp_hdr->len);
|
|
di = proto_645_2007_byte_to_di(resp_hdr->data);
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_METER_MULTI_DI_READ &&
|
|
freeze->cur_mr_di_cnt > 1) {
|
|
multi_data_len = resp_hdr->len - PROTO_645_2007_DI_LEN;
|
|
multi_data = resp_hdr->data + PROTO_645_2007_DI_LEN;
|
|
di_cnt = (uint8_t)(di & 0x000000ff);
|
|
for (i = 0; i < di_cnt; i++) {
|
|
if (multi_data_len < sizeof(*multi_resp)) {
|
|
reason = 11;
|
|
goto out;
|
|
}
|
|
multi_data_len -= sizeof(*multi_resp);
|
|
multi_resp = (proto_645_fj_multi_resp_data_t *)multi_data;
|
|
if (multi_data_len < multi_resp->data_len) {
|
|
reason = 12;
|
|
goto out;
|
|
}
|
|
multi_data_len -= multi_resp->data_len;
|
|
iot_sg_ext_freeze_cur_task_resp_handle(ext_info->addr,
|
|
multi_resp->data, multi_resp->data_len);
|
|
ret = ERR_OK;
|
|
multi_data += (sizeof(*multi_resp) + multi_resp->data_len);
|
|
if (i < di_cnt -1) {
|
|
if (!multi_data_len) {
|
|
reason = 13;
|
|
goto out;
|
|
}
|
|
/* skip the separator */
|
|
if (*multi_data != 0xbb) {
|
|
reason = 14;
|
|
goto out;
|
|
}
|
|
multi_data_len -= 1;
|
|
multi_data += 1;
|
|
}
|
|
}
|
|
} else {
|
|
iot_sg_ext_freeze_cur_task_resp_handle(ext_info->addr, resp_hdr->data,
|
|
resp_hdr->len);
|
|
ret = ERR_OK;
|
|
}
|
|
out:
|
|
iot_sg_printf("%s reason %d\n", __FUNCTION__, reason);
|
|
return ret;
|
|
}
|
|
|
|
void iot_sg_sta_ext_fj_698_oad_data_handle(
|
|
proto_69845_app_oad_resp_hdr_t *oad_data, uint32_t oad_data_len)
|
|
{
|
|
uint8_t *data, buff_len;
|
|
iot_pkt_t *buff_pkt = 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;
|
|
|
|
if (!oad_data_len) {
|
|
goto out;
|
|
}
|
|
buff_len = (uint8_t)(sizeof(proto_69845_app_oad_t) + oad_data_len);
|
|
buff_pkt = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
|
|
if (!buff_pkt) {
|
|
goto out;
|
|
}
|
|
data = iot_pkt_put(buff_pkt, buff_len);
|
|
os_mem_cpy(data, &oad_data->oad, sizeof(proto_69845_app_oad_t));
|
|
iot_data_reverse(data, sizeof(proto_69845_app_oad_t));
|
|
data += sizeof(proto_69845_app_oad_t);
|
|
os_mem_cpy(data, oad_data->result, oad_data_len);
|
|
iot_sg_ext_freeze_cur_task_resp_handle(ext_info->addr,
|
|
iot_pkt_data(buff_pkt), buff_len);
|
|
out:
|
|
if (buff_pkt) {
|
|
iot_pkt_free(buff_pkt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void iot_sg_ext_data_freeze_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 = ERR_INVAL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
|
|
if (data_type == IOT_SG_STA_DATA_TYPE_645_07) {
|
|
ret = iot_sg_ext_data_freeze_handle_645(seq, data_type, resp_data,
|
|
resp_len, req_data, req_len);
|
|
} else 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);
|
|
}
|
|
if (ret == ERR_OK || ret == ERR_TIMEOVER) {
|
|
if (ret == ERR_OK) {
|
|
ext_info->freeze_task_info->flag_resp = 1;
|
|
}
|
|
ext_info->freeze_task_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_sta_ext_freeze_cur_task_reset(uint8_t *addr, uint8_t task_id)
|
|
{
|
|
uint8_t idx = 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_node_desc_t *node;
|
|
|
|
node = iot_sg_sta_node_find_by_addr(addr);
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_valid_check(task_id, &idx)
|
|
|| !node || !freeze_task) {
|
|
return;
|
|
}
|
|
os_mem_set(&node->ext.freeze_info.task_tm[idx], 0x0,
|
|
sizeof(iot_time_tm_t));
|
|
if (task_id == freeze_task->cur_task_id) {
|
|
iot_sg_ext_data_freeze_cur_info_clear(freeze_task);
|
|
freeze_task->task_bm &= ~(1 << idx);
|
|
}
|
|
iot_sg_printf("%s id %lu\n", __FUNCTION__, task_id);
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_freeze_task_same_check(
|
|
iot_sg_sta_drv_meter_fj_task_info_t *local_cfg,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *add_cfg)
|
|
{
|
|
uint8_t same_flag = 0;
|
|
|
|
if (!local_cfg || !add_cfg) {
|
|
goto out;
|
|
}
|
|
if (local_cfg->type == add_cfg->type &&
|
|
local_cfg->value == add_cfg->value &&
|
|
local_cfg->unit == add_cfg->unit &&
|
|
local_cfg->delay == add_cfg->delay &&
|
|
local_cfg->save_cnt == add_cfg->save_cnt &&
|
|
local_cfg->rec_total_len == add_cfg->rec_total_len &&
|
|
local_cfg->prio == add_cfg->prio &&
|
|
local_cfg->storage_mode == add_cfg->storage_mode &&
|
|
local_cfg->exe_cnt == add_cfg->exe_cnt &&
|
|
local_cfg->desc_len == add_cfg->desc_len &&
|
|
local_cfg->flag_rpt == add_cfg->flag_rpt &&
|
|
!os_mem_cmp(local_cfg->desc, add_cfg->desc, add_cfg->desc_len)) {
|
|
same_flag = 1;
|
|
}
|
|
out:
|
|
return same_flag;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_cnt_check(uint8_t *addr,
|
|
uint8_t task_id)
|
|
{
|
|
uint8_t i, cnt = 0;
|
|
uint32_t ret = ERR_FAIL;
|
|
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_freeze_task_t *task_cfg = ext_info->freeze_task_info;
|
|
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
|
|
|
if (!node || !task_cfg) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_cfg->valid_id[i]) {
|
|
if (task_cfg->valid_id[i] == task_id) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
cnt++;
|
|
}
|
|
}
|
|
if (cnt != IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT) {
|
|
ret = ERR_OK;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_flash_freeze_task_exe_cnt_set(uint8_t* addr,
|
|
uint8_t task_id, uint16_t exe_cnt_remain, uint16_t trigger_cnt,
|
|
uint8_t rpt_cnt)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint16_t index = 0, unit_len = 0;
|
|
uint32_t ret = ERR_OK;
|
|
iot_pkt_t* pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t* unit;
|
|
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
unit = (iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(pkt, unit_len);
|
|
if (iot_sg_sta_flash_ct_unit_data_find_latest(addr, &index, (uint8_t *)unit,
|
|
unit_len, task_id, IOT_SG_STA_METER_DATA_TYPE_FJ_TASK) == ERR_OK) {
|
|
unit->exe_cnt_remain = exe_cnt_remain;
|
|
unit->save_cnt = trigger_cnt;
|
|
unit->rpt_cnt = rpt_cnt;
|
|
ret = iot_sg_sta_flash_ct_unit_data_save(
|
|
addr, index, (uint8_t *)unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 2;
|
|
}
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void iot_sg_sta_ext_fj_task_restart(void)
|
|
{
|
|
uint8_t i, task_id, addr[IOT_MAC_ADDR_LEN], reason = 0;
|
|
iot_pkt_t* task_pkt = 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_ext_freeze_task_reset_t *reset = &freeze_task->reset;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_info;
|
|
|
|
if (!freeze_task) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (!reset->cnt) {
|
|
goto out;
|
|
}
|
|
iot_mac_addr_cpy(addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(addr);
|
|
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_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*task_info));
|
|
for (i = reset->cur_idx; i < reset->cnt; i++) {
|
|
task_id = reset->task_id[i];
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, task_info)
|
|
== ERR_OK) {
|
|
iot_sg_ext_freeze_exe_cnt_set(task_id, task_info->exe_cnt, 0, 1);
|
|
iot_sg_ext_flash_freeze_task_exe_cnt_set(addr, task_id,
|
|
task_info->exe_cnt, 0, 0);
|
|
break;
|
|
}
|
|
}
|
|
reset->cur_idx = ++i;
|
|
if (reset->cur_idx >= reset->cnt) {
|
|
os_mem_set(reset, 0x0, sizeof(*reset));
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s fail reason %d\n", __FUNCTION__, reason);
|
|
}
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_freeze_task_add(uint8_t *addr, uint8_t task_id,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_info;
|
|
|
|
if (!cfg) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
task_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_cnt_check(addr, task_id)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
task_info = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*task_info));
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, task_info)) {
|
|
if (iot_sg_sta_ext_freeze_task_same_check(task_info, cfg)) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
if (iot_sg_sta_flash_clct_task_add(addr, (uint8_t *)cfg,
|
|
sizeof(*cfg), IOT_SG_STA_METER_DATA_TYPE_FJ_TASK) != ERR_OK) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_ext_freeze_cur_task_reset(addr, task_id);
|
|
iot_sg_sta_ext_fj_rpt_del(addr, task_id);
|
|
iot_sg_ext_data_rpt_msg_merge_del(addr, task_id);
|
|
iot_sg_sta_ext_freeze_flash_cfg_valid_set(task_id, 1);
|
|
iot_sg_ext_freeze_exe_cnt_set(task_id, cfg->exe_cnt, 0, 1);
|
|
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_freeze_task_del(uint8_t *addr,
|
|
uint8_t task_id)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_valid_check(task_id, NULL)) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
ret = iot_sg_sta_flash_clct_task_del(addr, task_id, 1,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_ext_freeze_cur_task_reset(addr, task_id);
|
|
iot_sg_sta_ext_fj_rpt_del(addr, task_id);
|
|
iot_sg_ext_data_rpt_msg_merge_del(addr, task_id);
|
|
iot_sg_ext_freeze_exe_cnt_del(task_id);
|
|
iot_sg_sta_ext_freeze_flash_cfg_valid_set(task_id, 0);
|
|
ret = ERR_OK;
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_del_all(uint8_t *addr)
|
|
{
|
|
uint8_t i;
|
|
uint32_t ret = ERR_FAIL;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
|
|
|
if (!freeze_task || !node) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (freeze_task->valid_id[i]) {
|
|
ret = iot_sg_sta_ext_freeze_task_del(addr,
|
|
freeze_task->valid_id[i]);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_get(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if (!cfg) {
|
|
goto out;
|
|
}
|
|
ret = iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_freeze_task_id_get(iot_sg_sta_ext_fj_task_id_t *task)
|
|
{
|
|
uint8_t i, m = 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_freeze_task_t *task_cfg = ext_info->freeze_task_info;
|
|
|
|
if (task_cfg) {
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (task_cfg->valid_id[i]) {
|
|
task->task_list[m] = task_cfg->valid_id[i];
|
|
m++;
|
|
}
|
|
}
|
|
task->task_cnt = m;
|
|
} else {
|
|
task->task_cnt = 0;
|
|
}
|
|
}
|
|
|
|
static iot_time_tm_t iot_sg_ext_get_next_data_freeze_ts(iot_time_tm_t *curr_tm,
|
|
iot_time_tm_t *node_tm, iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
int64_t interval;
|
|
iot_time_tm_t tm = { 0 };
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
if (!cfg || !curr_tm || !node_tm) {
|
|
goto out;
|
|
}
|
|
cycle.value = cfg->value;
|
|
cycle.unit = cfg->unit;
|
|
interval = (int64_t)proto_645_fj_task_cycle_to_sec(&cycle);
|
|
tm = *curr_tm;
|
|
iot_sg_ext_set_integral_point(&tm, interval, 1);
|
|
if (tm.tm_year == node_tm->tm_year && tm.tm_mon == node_tm->tm_mon &&
|
|
tm.tm_mday == node_tm->tm_mday && tm.tm_hour == node_tm->tm_hour &&
|
|
tm.tm_min == node_tm->tm_min && tm.tm_sec == node_tm->tm_sec) {
|
|
iot_rtc_delta_add(1, &tm);
|
|
iot_sg_ext_set_integral_point(&tm, interval, 1);
|
|
}
|
|
if (cfg->delay) {
|
|
iot_rtc_delta_add(cfg->delay, &tm);
|
|
}
|
|
out:
|
|
return tm;
|
|
}
|
|
|
|
static void iot_sg_ext_data_freeze_cur_task_done(void)
|
|
{
|
|
uint8_t idx = 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_valid_check(freeze_task->cur_task_id,
|
|
&idx)) {
|
|
return;
|
|
}
|
|
freeze_task->task_bm |= (1 << idx);
|
|
iot_sg_ext_data_freeze_cur_info_clear(freeze_task);
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_data_freeze_task_id_get_by_func(uint8_t *addr,
|
|
uint8_t func)
|
|
{
|
|
uint8_t task_id = 0, idx = 0;
|
|
iot_pkt_t *task_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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *local_cfg;
|
|
|
|
task_pkt = iot_pkt_alloc(sizeof(*local_cfg), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto out;
|
|
}
|
|
local_cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*local_cfg));
|
|
for (task_id = PROTO_FJ_FREEZE_TASK_ID_MIN;
|
|
task_id <= PROTO_FJ_FREEZE_TASK_ID_MAX;
|
|
task_id++) {
|
|
if (!iot_sg_sta_ext_freeze_flash_cfg_valid_check(task_id, &idx)) {
|
|
continue;
|
|
}
|
|
if (freeze_task->task_bm & (1 << idx)) {
|
|
continue;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, local_cfg)
|
|
!= ERR_OK) {
|
|
continue;
|
|
}
|
|
if (func == IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_1) {
|
|
if (local_cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE
|
|
&& local_cfg->prio) {
|
|
goto out;
|
|
}
|
|
} else if (func == IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_0) {
|
|
if (local_cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE
|
|
&& !local_cfg->prio) {
|
|
goto out;
|
|
}
|
|
} else if (func == IOT_SG_STA_EXT_FREEZR_FUNC_RPT) {
|
|
if (local_cfg->type == PROTO_645_FJ_TASK_TYPE_INCON_RPT ||
|
|
local_cfg->type == PROTO_645_FJ_TASK_TYPE_CROSS_RPT ||
|
|
local_cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
task_id = 0;
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return task_id;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_freeze_tm_check(uint8_t type)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (iot_sg_sta_rtc_valid_check(0)) {
|
|
reason = 1;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (type == PROTO_645_FJ_TASK_TYPE_FREEZE) {
|
|
if (iot_sg_sta_rtc_valid_check(1)) {
|
|
reason = 2;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
if (ret != ERR_OK) {
|
|
iot_sg_printf("%s fail %d type %lu\n", __FUNCTION__, reason, type);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_freeze_tm_check_by_prio(uint8_t prio)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t ret = ERR_OK;
|
|
|
|
if (iot_sg_sta_rtc_valid_check(0)) {
|
|
reason = 1;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
if (prio == IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_1 ||
|
|
prio == IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_0) {
|
|
if (iot_sg_sta_rtc_valid_check(1)) {
|
|
reason = 2;
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
if (ret != ERR_OK) {
|
|
iot_sg_printf("%s fail %d prio %lu\n", __FUNCTION__, reason, prio);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_data_freeze_cur_task_update(uint8_t *addr)
|
|
{
|
|
uint8_t func, task_id;
|
|
|
|
uint32_t ret = ERR_FAIL;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
/* func execution priority:
|
|
* IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_1 > IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_0 >
|
|
* IOT_SG_STA_EXT_FREEZR_FUNC_RPT
|
|
*/
|
|
for (func = IOT_SG_STA_EXT_FREEZR_FUNC_PRIO_1;
|
|
func < IOT_SG_STA_EXT_FREEZR_FUNC_CNT; func++) {
|
|
if (iot_sg_ext_data_freeze_tm_check_by_prio(func) != ERR_OK) {
|
|
continue;
|
|
}
|
|
task_id = iot_sg_ext_data_freeze_task_id_get_by_func(addr, func);
|
|
if (task_id) {
|
|
freeze_task->cur_task_id = task_id;
|
|
ret = ERR_OK;
|
|
iot_sg_printf("%s to %lu\n", __FUNCTION__, task_id);
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_cur_freeze_di_update(
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t di_cnt = 0;
|
|
uint32_t ret = ERR_OK;;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
iot_sg_sta_ext_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
|
|
if (!cfg || freeze_task->task_end) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
freeze_task->cur_di_idx += freeze_task->cur_mr_di_cnt;
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t *)cfg->desc;
|
|
if (freeze_task->cur_di_idx >= freeze_hdr->data_cnt) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
di_cnt = incon_rpt->di_cnt;
|
|
if (freeze_task->flag_rpt) {
|
|
/* freeze data report, meter read follow di */
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)
|
|
(incon_rpt->di + incon_rpt->di_cnt);
|
|
di_cnt += flw_rpt->follow_di_cnt;
|
|
}
|
|
if (freeze_task->cur_di_idx >= di_cnt) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
di_cnt++;
|
|
if (freeze_task->flag_rpt) {
|
|
/* freeze data report, meter read follow di */
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)
|
|
(cross_rpt->value_list + cross_rpt->cnt * cross_rpt->value_len);
|
|
di_cnt += flw_rpt->follow_di_cnt;
|
|
}
|
|
if (freeze_task->cur_di_idx >= di_cnt) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t*)cfg->desc;
|
|
di_cnt++;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)
|
|
(chg_rpt->value_list + chg_rpt->value_len);
|
|
di_cnt += flw_rpt->follow_di_cnt;
|
|
if (freeze_task->cur_di_idx >= di_cnt) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ret = ERR_FAIL;
|
|
break;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void iot_sg_ext_chg_to_data_freeze_ts(
|
|
iot_time_tm_t *node_tm, iot_sg_sta_drv_meter_fj_task_info_t *cfg,
|
|
uint8_t flag_last)
|
|
{
|
|
int64_t interval;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
cycle.value = cfg->value;
|
|
cycle.unit = cfg->unit;
|
|
interval = (int64_t)proto_645_fj_task_cycle_to_sec(&cycle);
|
|
if (flag_last) {
|
|
interval = 0 - interval;
|
|
}
|
|
iot_rtc_delta_add(interval, node_tm);
|
|
}
|
|
|
|
static void iot_sg_ext_data_freeze_save(uint8_t *addr, uint8_t task_id,
|
|
iot_time_tm_t *tm)
|
|
{
|
|
uint8_t valid_rpt_cnt = 1;
|
|
uint8_t merge_cnt, rpt_mode = PROTO_645_FJ_REPORT_MODE_698;
|
|
uint32_t ret, reason = 0;
|
|
uint16_t max_cnt = 0, index = 0, exe_cnt = 0, trigger_cnt = 0, unit_len = 0;
|
|
iot_pkt_t *pkt = NULL, *rpt_pkt = NULL, *task_pkt = NULL;
|
|
iot_time_tm_t cache_tm = { 0 }, node_tm;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *resp_data = NULL, *flash_data = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
iot_sg_sta_ext_freeze_task_exe_cnt_t *last_data =
|
|
iot_sg_ext_freeze_last_data_get(task_id);
|
|
|
|
if (!freeze_task->resp_pkt || !addr || !tm) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
task_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg) != ERR_OK) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
resp_data = (iot_sg_sta_drv_meter_fj_task_unit_t *)
|
|
iot_pkt_data(freeze_task->resp_pkt);
|
|
if (cfg->type != PROTO_645_FJ_TASK_TYPE_FREEZE &&
|
|
!freeze_task->first_rpt_task && !freeze_task->flag_rpt) {
|
|
ret = iot_sg_ext_freeze_exe_cnt_get(task_id, &exe_cnt, &trigger_cnt);
|
|
if(ret || 0 == exe_cnt) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (exe_cnt != (uint16_t)~0) {
|
|
exe_cnt--;
|
|
iot_sg_ext_freeze_exe_cnt_set(task_id, exe_cnt, trigger_cnt, 0);
|
|
}
|
|
goto out;
|
|
}
|
|
node_tm = *tm;
|
|
if (cfg->delay) {
|
|
iot_rtc_delta_add(0 - cfg->delay, &node_tm);
|
|
}
|
|
resp_data->uint_time.year = node_tm.tm_year - 2000;
|
|
resp_data->uint_time.month = node_tm.tm_mon;
|
|
resp_data->uint_time.day = node_tm.tm_mday;
|
|
resp_data->uint_time.hour = node_tm.tm_hour;
|
|
resp_data->uint_time.minute = node_tm.tm_min;
|
|
resp_data->uint_time.second = node_tm.tm_sec;
|
|
resp_data->rpt_cnt = 0;
|
|
max_cnt = iot_sg_sta_flash_ct_unit_cnt_get(addr, task_id);
|
|
if (!max_cnt) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
flash_data =
|
|
(iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(pkt, unit_len);
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
iot_sg_ext_chg_to_data_freeze_ts(&node_tm, cfg, 1);
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &index, &node_tm,
|
|
(uint8_t *)flash_data, unit_len, task_id, 1,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret == ERR_OK) {
|
|
cache_tm.tm_year = (uint16_t)(flash_data->uint_time.year + 2000);
|
|
cache_tm.tm_mon = (uint8_t)flash_data->uint_time.month;
|
|
cache_tm.tm_mday = (uint8_t)flash_data->uint_time.day;
|
|
cache_tm.tm_hour = (uint8_t)flash_data->uint_time.hour;
|
|
cache_tm.tm_min = (uint8_t)flash_data->uint_time.minute;
|
|
cache_tm.tm_sec = flash_data->uint_time.second;
|
|
if (iot_rtc_delta_calc(&cache_tm, &node_tm) != 0) {
|
|
index++;
|
|
}
|
|
resp_data->save_cnt = flash_data->save_cnt;
|
|
resp_data->save_cnt++;
|
|
resp_data->storage_times = flash_data->storage_times;
|
|
resp_data->storage_times++;
|
|
if (resp_data->uint_time.year == flash_data->uint_time.year &&
|
|
resp_data->uint_time.month == flash_data->uint_time.month &&
|
|
resp_data->uint_time.day == flash_data->uint_time.day) {
|
|
resp_data->rpt_cnt = flash_data->rpt_cnt;
|
|
}
|
|
} else {
|
|
if ((cfg->type == PROTO_645_FJ_TASK_TYPE_INCON_RPT
|
|
|| cfg->type == PROTO_645_FJ_TASK_TYPE_CROSS_RPT)
|
|
&& freeze_task->first_rpt_task) {
|
|
resp_data->save_cnt = 0;
|
|
resp_data->storage_times = 0;
|
|
/* for current report state count */
|
|
valid_rpt_cnt = 0;
|
|
} else {
|
|
resp_data->save_cnt = 1;
|
|
resp_data->storage_times = 1;
|
|
}
|
|
}
|
|
ret = iot_sg_ext_freeze_exe_cnt_get(task_id, &exe_cnt, &trigger_cnt);
|
|
if(ret || 0 == exe_cnt) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
if (exe_cnt != (uint16_t)~0) {
|
|
exe_cnt--;
|
|
}
|
|
resp_data->exe_cnt_remain = exe_cnt;
|
|
iot_sg_ext_freeze_exe_cnt_set(task_id, exe_cnt, resp_data->save_cnt, 0);
|
|
if (index >= max_cnt) {
|
|
index = 0;
|
|
}
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
if (!last_data || !last_data->valid_len || !last_data->data_cnt) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
os_mem_set(flash_data, 0, sizeof(*flash_data));
|
|
flash_data->uint_time.year = node_tm.tm_year - 2000;
|
|
flash_data->uint_time.month = node_tm.tm_mon;
|
|
flash_data->uint_time.day = node_tm.tm_mday;
|
|
flash_data->uint_time.hour = node_tm.tm_hour;
|
|
flash_data->uint_time.minute = node_tm.tm_min;
|
|
flash_data->uint_time.second = node_tm.tm_sec;
|
|
flash_data->save_cnt = resp_data->save_cnt;
|
|
flash_data->storage_times = resp_data->storage_times;
|
|
flash_data->exe_cnt_remain = resp_data->exe_cnt_remain;
|
|
flash_data->resp_data_cnt = last_data->data_cnt;
|
|
flash_data->valid_len = last_data->valid_len;
|
|
os_mem_cpy(flash_data->uint_data, last_data->last_data,
|
|
flash_data->valid_len);
|
|
iot_sg_ext_chg_to_data_freeze_ts(&node_tm, cfg, 0);
|
|
}
|
|
if (freeze_task->flag_rpt && cfg->flag_rpt) {
|
|
if (!freeze_task->comm_cfg.report_max_cnt) {
|
|
resp_data->rpt_cnt = 0;
|
|
goto save;
|
|
}
|
|
if (freeze_task->comm_cfg.report_max_cnt != 0xff &&
|
|
resp_data->rpt_cnt >= freeze_task->comm_cfg.report_max_cnt) {
|
|
goto save;
|
|
}
|
|
if (iot_sg_sta_ext_fj_task_group_get(task_id)
|
|
== PROTO_645_FJ_TASK_GROUP_645) {
|
|
rpt_mode = freeze_task->comm_cfg.rpt_mode;
|
|
}
|
|
rpt_pkt = iot_sg_sta_ext_fj_rpt_msg_build(resp_data, flash_data,
|
|
cfg, task_id, rpt_mode);
|
|
merge_cnt = iot_sg_ext_data_rpt_msg_merge_cnt_get(
|
|
&freeze_task->comm_cfg, task_id);
|
|
if (merge_cnt) {
|
|
rpt_pkt = iot_sg_ext_data_rpt_msg_merge(addr, task_id, &merge_cnt,
|
|
rpt_mode, cfg->type, rpt_pkt);
|
|
} else {
|
|
merge_cnt = 1;
|
|
}
|
|
if (rpt_pkt) {
|
|
resp_data->rpt_cnt++;
|
|
iot_sg_sta_ext_fj_rpt_add(rpt_pkt, addr, task_id, cfg,
|
|
rpt_mode, merge_cnt);
|
|
}
|
|
iot_sg_ext_data_rpt_task_finish_handle(addr, task_id, cfg);
|
|
}
|
|
save:
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
flash_data->rpt_cnt = resp_data->rpt_cnt;
|
|
ret = iot_sg_sta_flash_ct_unit_data_save(
|
|
addr, index, (uint8_t *)flash_data, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
index++;
|
|
if (index >= max_cnt) {
|
|
index = 0;
|
|
}
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_save(
|
|
addr, index, (uint8_t *)resp_data, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 10;
|
|
goto out;
|
|
}
|
|
if (cfg->flag_rpt && valid_rpt_cnt) {
|
|
iot_sg_sta_ext_fj_rpt_count(task_id, 1, valid_rpt_cnt);
|
|
}
|
|
iot_sg_sta_flash_ct_unit_data_check(addr, index, &node_tm,
|
|
task_id, IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x task id %lu idx %lu\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 rpt_cnt %lu\n", __FUNCTION__,
|
|
node_tm.tm_year, node_tm.tm_mon, node_tm.tm_mday, node_tm.tm_hour,
|
|
node_tm.tm_min, node_tm.tm_sec, resp_data->rpt_cnt);
|
|
out:
|
|
if (last_data && resp_data) {
|
|
last_data->data_cnt = resp_data->resp_data_cnt;
|
|
last_data->valid_len = resp_data->valid_len;
|
|
os_mem_cpy(last_data->last_data, resp_data->uint_data,
|
|
resp_data->valid_len);
|
|
}
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
}
|
|
return;
|
|
}
|
|
|
|
static void iot_sg_ext_freeze_tail_time_fill(
|
|
proto_645_fj_freeze_data_desc_tail_t *tail, iot_time_tm_t *tm)
|
|
{
|
|
iot_time_tm_t new_tm = { 0 };
|
|
int64_t delta = 0;
|
|
|
|
if (!tail || !tm) {
|
|
return;
|
|
}
|
|
if (tail->ts.year == 0x99) {
|
|
new_tm.tm_year = tm->tm_year;
|
|
} else {
|
|
new_tm.tm_year = iot_bcd_to_byte(tail->ts.year) + 2000;
|
|
}
|
|
if (tail->ts.month == 0x99) {
|
|
new_tm.tm_mon = tm->tm_mon;
|
|
} else {
|
|
new_tm.tm_mon = iot_bcd_to_byte(tail->ts.month);
|
|
}
|
|
if (tail->ts.day == 0x99) {
|
|
new_tm.tm_mday = tm->tm_mday;
|
|
} else {
|
|
new_tm.tm_mday = iot_bcd_to_byte(tail->ts.day);
|
|
}
|
|
if (tail->ts.hour == 0x99) {
|
|
new_tm.tm_hour = tm->tm_hour;
|
|
} else {
|
|
new_tm.tm_hour = iot_bcd_to_byte(tail->ts.hour);
|
|
}
|
|
if (tail->ts.minute == 0x99) {
|
|
new_tm.tm_min = tm->tm_min;
|
|
} else {
|
|
new_tm.tm_min = iot_bcd_to_byte(tail->ts.minute);
|
|
}
|
|
switch (tail->ts_desc.unit) {
|
|
case PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_DAY:
|
|
{
|
|
delta = tail->ts_desc.value * 60 * 60 * 24;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_HOUR:
|
|
{
|
|
delta = tail->ts_desc.value * 60 * 60;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_MIN:
|
|
{
|
|
delta = tail->ts_desc.value * 60;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_SEC:
|
|
{
|
|
delta = tail->ts_desc.value;
|
|
break;
|
|
}
|
|
default:
|
|
iot_sg_printf("%s delta invalid\n");
|
|
break;
|
|
}
|
|
if (!tail->ts_desc.flag) {
|
|
iot_rtc_delta_add(delta, &new_tm);
|
|
} else {
|
|
iot_rtc_delta_add(0 - delta, &new_tm);
|
|
}
|
|
tail->ts.year = iot_byte_to_bcd((uint8_t)(new_tm.tm_year - 2000));
|
|
tail->ts.month = iot_byte_to_bcd(new_tm.tm_mon);
|
|
tail->ts.day = iot_byte_to_bcd(new_tm.tm_mday);
|
|
tail->ts.hour = iot_byte_to_bcd(new_tm.tm_hour);
|
|
tail->ts.minute = iot_byte_to_bcd(new_tm.tm_min);
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_freeze_data_desc_offset_get(uint8_t *desc_offser,
|
|
uint8_t desc_len, uint8_t *data, uint8_t idx)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
uint8_t i, offset_len = 0;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des;
|
|
|
|
for (i = 0; i < idx; i++) {
|
|
if (offset_len >= desc_len) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
freeze_des = (proto_645_fj_freeze_data_desc_hdr_t *)(data + offset_len);
|
|
offset_len += sizeof(*freeze_des) + freeze_des->data_len;
|
|
}
|
|
*desc_offser = offset_len;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_freeze_di_list_get(uint8_t cur_idx,
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint32_t *di_list, uint8_t max_cnt)
|
|
{
|
|
uint8_t di_cnt = 0, offset_len = 0, i;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des;
|
|
|
|
if (!freeze_hdr || !cfg || !di_list) {
|
|
goto out;
|
|
}
|
|
for (i = cur_idx; i < freeze_hdr->data_cnt; i++) {
|
|
if (iot_sg_ext_freeze_data_desc_offset_get(&offset_len, cfg->desc_len,
|
|
freeze_hdr->data_desc, i) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
freeze_des = (proto_645_fj_freeze_data_desc_hdr_t *)(
|
|
freeze_hdr->data_desc + offset_len);
|
|
if (freeze_des->format_type != PROTO_645_FJ_FREEZE_DATA_FORMAT_NO_TS ||
|
|
freeze_des->data_len != PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
di_list[di_cnt] = proto_645_2007_byte_to_di(freeze_des->data);
|
|
di_cnt++;
|
|
if (di_cnt >= max_cnt) {
|
|
goto out;
|
|
}
|
|
}
|
|
out:
|
|
return di_cnt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_task_freeze_muilt_msg_build(uint8_t *addr,
|
|
uint8_t cur_idx, proto_645_fj_task_set_freeze_hdr_t *freeze_hdr,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint8_t *cur_mr_di_cnt)
|
|
{
|
|
uint8_t di_list_cnt, di_list_pkt_len;
|
|
uint32_t *di_list = NULL;
|
|
iot_pkt_t *di_list_pkt = NULL, *pkt = NULL;
|
|
|
|
di_list_pkt_len = PROTO_645_FJ_METER_MULTI_DI_CNT_MAX *
|
|
PROTO_645_2007_DI_LEN;
|
|
di_list_pkt = iot_pkt_alloc(di_list_pkt_len, IOT_SMART_GRID_MID);
|
|
if (!di_list_pkt) {
|
|
goto out;
|
|
}
|
|
di_list = (uint32_t *)iot_pkt_put(di_list_pkt,
|
|
di_list_pkt_len);
|
|
di_list_cnt = iot_sg_sta_ext_fj_task_freeze_di_list_get(cur_idx, freeze_hdr,
|
|
cfg, di_list, PROTO_645_FJ_METER_MULTI_DI_CNT_MAX);
|
|
if (di_list_cnt > 1) {
|
|
pkt = proto_645_fj_build_muilt_mr_msg(addr, di_list,
|
|
di_list_cnt);
|
|
if (pkt) {
|
|
*cur_mr_di_cnt = di_list_cnt;
|
|
}
|
|
}
|
|
out:
|
|
if (di_list_pkt) {
|
|
iot_pkt_free(di_list_pkt);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_comm_cfg_get(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *cfg_comm)
|
|
{
|
|
uint8_t i;
|
|
uint32_t ret = ERR_FAIL;
|
|
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_freeze_task_t *task_info = ext_info->freeze_task_info;
|
|
|
|
if (task_info) {
|
|
cfg_comm->report_max_cnt = task_info->comm_cfg.report_max_cnt;
|
|
cfg_comm->unit_max_len = task_info->comm_cfg.unit_max_len;
|
|
cfg_comm->random_rpt_time = task_info->comm_cfg.random_rpt_time;
|
|
cfg_comm->retry_freeze = task_info->comm_cfg.retry_freeze;
|
|
cfg_comm->retry_nonfreeze = task_info->comm_cfg.retry_nonfreeze;
|
|
cfg_comm->mult_data_item = task_info->comm_cfg.mult_data_item;
|
|
cfg_comm->rpt_mode = task_info->comm_cfg.rpt_mode;
|
|
cfg_comm->cnt = task_info->comm_cfg.cnt;
|
|
for (i = 0; i < cfg_comm->cnt; i++) {
|
|
cfg_comm->task_rpt[i].id = task_info->comm_cfg.task_rpt[i].id;
|
|
cfg_comm->task_rpt[i].cnt = task_info->comm_cfg.task_rpt[i].cnt;
|
|
}
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_ext_69845_mr_msg_build(uint8_t *addr,
|
|
uint32_t *oad_list, uint8_t oad_cnt)
|
|
{
|
|
uint32_t get_list_req_size, oad;
|
|
uint8_t i, oad_idx = 0, attribute;
|
|
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};
|
|
|
|
get_list_req_size = sizeof(proto_69845_app_oad_t) * oad_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 < oad_cnt; i++) {
|
|
os_mem_cpy(&oad, (oad_list + i), sizeof(oad));
|
|
iot_data_reverse((uint8_t *)&oad, sizeof(proto_69845_app_oad_t));
|
|
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++;
|
|
}
|
|
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_ext_meter_freeze_msg_build_698(uint8_t *addr,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t idx, *data, reason = 0;
|
|
uint8_t di_list_cnt = 0, di_list_pkt_len;
|
|
uint32_t *di_list = NULL;
|
|
iot_pkt_t *pkt = NULL, *pkt_tmp = NULL, *di_list_pkt = 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
|
|
if (!addr || !cfg) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
idx = freeze_task->cur_di_idx;
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t *)cfg->desc;
|
|
if (idx >= freeze_hdr->data_cnt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
di_list_pkt_len = PROTO_645_FJ_METER_MULTI_DI_CNT_MAX *
|
|
PROTO_645_2007_DI_LEN;
|
|
di_list_pkt = iot_pkt_alloc(di_list_pkt_len, IOT_SMART_GRID_MID);
|
|
if (!di_list_pkt) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
di_list = (uint32_t *)iot_pkt_put(di_list_pkt, di_list_pkt_len);
|
|
di_list_cnt = iot_sg_sta_ext_fj_task_freeze_di_list_get(idx,
|
|
freeze_hdr, cfg, di_list, PROTO_645_FJ_METER_MULTI_DI_CNT_MAX);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
if (idx < incon_rpt->di_cnt) {
|
|
di_list_cnt = incon_rpt->di_cnt - idx;
|
|
di_list = &incon_rpt->di[idx];
|
|
} else {
|
|
/* freeze data report, meter read follow di */
|
|
idx -= incon_rpt->di_cnt;
|
|
data = (uint8_t *)incon_rpt->di +
|
|
incon_rpt->di_cnt * PROTO_645_2007_DI_LEN;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
if (idx < PROTO_645_FJ_CROSS_RPT_CMP_DI_CNT) {
|
|
di_list = &cross_rpt->di;
|
|
di_list_cnt = 1;
|
|
} else {
|
|
/* freeze data report, meter read follow di */
|
|
idx -= PROTO_645_FJ_CROSS_RPT_CMP_DI_CNT;
|
|
data = cross_rpt->value_list + cross_rpt->cnt * cross_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t *)cfg->desc;
|
|
if (idx < PROTO_645_FJ_CHANGE_RPT_CMP_DI_CNT) {
|
|
di_list = &chg_rpt->di;
|
|
di_list_cnt = 1;
|
|
} else {
|
|
/* meter read follow di */
|
|
idx -= PROTO_645_FJ_CHANGE_RPT_CMP_DI_CNT;
|
|
data = chg_rpt->value_list + chg_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
pkt = iot_sg_ext_69845_mr_msg_build(addr, di_list, di_list_cnt);
|
|
freeze_task->cur_mr_di_cnt = di_list_cnt;
|
|
out:
|
|
if (pkt_tmp) {
|
|
iot_pkt_free(pkt_tmp);
|
|
}
|
|
if (di_list_pkt) {
|
|
iot_pkt_free(di_list_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_ext_meter_freeze_msg_build_645(uint8_t *addr,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t idx, offset_len = 0, *data_tmp,*data, data_len, reason = 0;
|
|
uint8_t di_list_cnt = 0, mult_data_item;
|
|
uint32_t di = PROTO_645_INVALID_DI, delta = 0, *di_list = NULL;
|
|
iot_pkt_t *pkt = NULL, *pkt_tmp = NULL;
|
|
iot_time_tm_t 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
proto_645_fj_freeze_data_desc_tail_t *tail;
|
|
proto_645_fj_task_time_domain_t *time_domain;
|
|
|
|
if (!addr || !cfg) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (iot_sg_ext_data_freeze_tm_check(cfg->type) != ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if (iot_mac_addr_valid(freeze_task->comm_cfg.mult_di_addr)) {
|
|
mult_data_item = freeze_task->comm_cfg.mult_data_item;
|
|
} else {
|
|
mult_data_item = PROTO_645_FJ_METET_MULT_DATA_ITEM_DEF;
|
|
}
|
|
iot_sg_sta_rtc_get(&tm, 0);
|
|
idx = freeze_task->cur_di_idx;
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t *)cfg->desc;
|
|
if (idx >= freeze_hdr->data_cnt) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (iot_sg_ext_freeze_data_desc_offset_get(&offset_len, cfg->desc_len,
|
|
freeze_hdr->data_desc, idx)) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
freeze_des = (proto_645_fj_freeze_data_desc_hdr_t *)(
|
|
freeze_hdr->data_desc + offset_len);
|
|
if (!freeze_des) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
di = proto_645_2007_byte_to_di(freeze_des->data);
|
|
data = freeze_des->data + PROTO_645_2007_DI_LEN;
|
|
data_len = freeze_des->data_len - PROTO_645_2007_DI_LEN;
|
|
if (freeze_des->format_type == PROTO_645_FJ_FREEZE_DATA_FORMAT_WITH_TS
|
|
|| freeze_des->format_type ==
|
|
PROTO_645_FJ_FREEZE_DATA_FORMAT_WITH_TSR) {
|
|
pkt_tmp = iot_pkt_alloc(data_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_tmp) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
data_tmp = iot_pkt_put(pkt_tmp, data_len);
|
|
os_mem_cpy(data_tmp, data, data_len);
|
|
if (data_len < sizeof(*tail)) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
if (freeze_des->format_type ==
|
|
PROTO_645_FJ_FREEZE_DATA_FORMAT_WITH_TSR) {
|
|
if (data_len < (sizeof(*tail) + sizeof(*time_domain))) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
time_domain = (proto_645_fj_task_time_domain_t*)
|
|
(data_tmp + (data_len - sizeof(*time_domain)));
|
|
data_len -= sizeof(*time_domain);
|
|
if (proto_645_fj_task_time_domain_to_sec(time_domain,
|
|
&delta) == ERR_OK) {
|
|
if (delta) {
|
|
iot_sg_ext_set_integral_point(&tm, (int64_t)delta, 0);
|
|
}
|
|
} else {
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
}
|
|
tail = (proto_645_fj_freeze_data_desc_tail_t *)
|
|
(data_tmp + (data_len - sizeof(*tail)));
|
|
/* fill current time to msg */
|
|
iot_sg_ext_freeze_tail_time_fill(tail, &tm);
|
|
pkt = proto_645_fj_build_mr_msg(addr, data_tmp, data_len -
|
|
sizeof(tail->ts_desc), di, PROTO_645_2007_FN_READ_DATA);
|
|
freeze_task->cur_mr_di_cnt = 1;
|
|
} else {
|
|
if (mult_data_item) {
|
|
pkt = iot_sg_sta_ext_fj_task_freeze_muilt_msg_build(addr,
|
|
idx, freeze_hdr, cfg, &freeze_task->cur_mr_di_cnt);
|
|
if (pkt) {
|
|
goto out;
|
|
}
|
|
/* muilt di msg pkt is NULL go to build single di msg */
|
|
}
|
|
pkt = proto_645_fj_build_mr_msg(addr, data, data_len, di,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
freeze_task->cur_mr_di_cnt = 1;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
if (idx < incon_rpt->di_cnt) {
|
|
di_list_cnt = incon_rpt->di_cnt - idx;
|
|
if (mult_data_item && di_list_cnt > 1) {
|
|
di_list = &incon_rpt->di[idx];
|
|
} else {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&incon_rpt->di[idx]);
|
|
}
|
|
} else {
|
|
/* freeze data report, meter read follow di */
|
|
idx -= incon_rpt->di_cnt;
|
|
data = (uint8_t *)incon_rpt->di +
|
|
incon_rpt->di_cnt * PROTO_645_2007_DI_LEN;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
if (mult_data_item && di_list_cnt > 1) {
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
}
|
|
} else {
|
|
reason = 10;
|
|
goto out;
|
|
}
|
|
}
|
|
if (di_list) {
|
|
if (di_list_cnt > PROTO_645_FJ_METER_MULTI_DI_CNT_MAX) {
|
|
di_list_cnt = PROTO_645_FJ_METER_MULTI_DI_CNT_MAX;
|
|
}
|
|
pkt = proto_645_fj_build_muilt_mr_msg(addr, di_list, di_list_cnt);
|
|
freeze_task->cur_mr_di_cnt = di_list_cnt;
|
|
} else {
|
|
pkt = proto_645_fj_build_mr_msg(addr, NULL, 0, di,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
freeze_task->cur_mr_di_cnt = 1;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
if (idx < PROTO_645_FJ_CROSS_RPT_CMP_DI_CNT) {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&cross_rpt->di);
|
|
} else {
|
|
/* freeze data report, meter read follow di */
|
|
idx -= PROTO_645_FJ_CROSS_RPT_CMP_DI_CNT;
|
|
data = cross_rpt->value_list + cross_rpt->cnt * cross_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
if (mult_data_item && di_list_cnt > 1) {
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
}
|
|
} else {
|
|
reason = 11;
|
|
goto out;
|
|
}
|
|
}
|
|
if (di_list) {
|
|
if (di_list_cnt > PROTO_645_FJ_METER_MULTI_DI_CNT_MAX) {
|
|
di_list_cnt = PROTO_645_FJ_METER_MULTI_DI_CNT_MAX;
|
|
}
|
|
pkt = proto_645_fj_build_muilt_mr_msg(addr, di_list, di_list_cnt);
|
|
freeze_task->cur_mr_di_cnt = di_list_cnt;
|
|
} else {
|
|
pkt = proto_645_fj_build_mr_msg(addr, NULL, 0, di,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
freeze_task->cur_mr_di_cnt = 1;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t *)cfg->desc;
|
|
if (idx < PROTO_645_FJ_CHANGE_RPT_CMP_DI_CNT) {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&chg_rpt->di);
|
|
} else {
|
|
/* meter read follow di */
|
|
idx -= PROTO_645_FJ_CHANGE_RPT_CMP_DI_CNT;
|
|
data = chg_rpt->value_list + chg_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
if (idx < flw_rpt->follow_di_cnt) {
|
|
di_list_cnt = flw_rpt->follow_di_cnt - idx;
|
|
if (mult_data_item && di_list_cnt > 1) {
|
|
di_list = &flw_rpt->di[idx];
|
|
} else {
|
|
di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
}
|
|
} else {
|
|
reason = 12;
|
|
goto out;
|
|
}
|
|
}
|
|
if (di_list) {
|
|
if (di_list_cnt > PROTO_645_FJ_METER_MULTI_DI_CNT_MAX) {
|
|
di_list_cnt = PROTO_645_FJ_METER_MULTI_DI_CNT_MAX;
|
|
}
|
|
pkt = proto_645_fj_build_muilt_mr_msg(addr, di_list, di_list_cnt);
|
|
freeze_task->cur_mr_di_cnt = di_list_cnt;
|
|
} else {
|
|
pkt = proto_645_fj_build_mr_msg(addr, NULL, 0, di,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
freeze_task->cur_mr_di_cnt = 1;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
if (pkt_tmp) {
|
|
iot_pkt_free(pkt_tmp);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static void iot_sg_ext_day_freeze_task_last_check(uint8_t *addr,
|
|
iot_time_tm_t *node_tm, iot_time_tm_t *cur_tm,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint16_t flash_idx = 0, unit_len = 0;
|
|
uint32_t ret;
|
|
int64_t delta;
|
|
iot_time_tm_t last_tm;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit;
|
|
|
|
if (!addr || !node_tm || !cur_tm || !cfg) {
|
|
goto out;
|
|
}
|
|
if (cfg->type != PROTO_645_FJ_TASK_TYPE_FREEZE ||
|
|
cfg->unit != PROTO_645_FJ_TASK_CYCLE_UNIT_TYPE_DAY) {
|
|
goto out;
|
|
}
|
|
delta = iot_rtc_delta_calc(cur_tm, node_tm);
|
|
if (delta <= IOT_SG_STA_EXT_FREEZE_LAST_DF_MIN_TIME) {
|
|
/* next freeze data will be collected soon,
|
|
* do not collect last freeze data.
|
|
*/
|
|
goto out;
|
|
}
|
|
last_tm = *cur_tm;
|
|
last_tm.tm_hour = 0;
|
|
last_tm.tm_min = 0;
|
|
last_tm.tm_sec = 0;
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
task_unit = (iot_sg_sta_drv_meter_fj_task_unit_t *)
|
|
iot_pkt_put(pkt, unit_len);
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &flash_idx,
|
|
&last_tm, (uint8_t *)task_unit, unit_len, cfg->id, 0,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
*node_tm = last_tm;
|
|
if (cfg->delay) {
|
|
iot_rtc_delta_add(cfg->delay, node_tm);
|
|
}
|
|
goto out;
|
|
}
|
|
if (last_tm.tm_year != (uint16_t)task_unit->uint_time.year + 2000 ||
|
|
last_tm.tm_mon != (uint8_t)task_unit->uint_time.month ||
|
|
last_tm.tm_mday != (uint8_t)task_unit->uint_time.day) {
|
|
*node_tm = last_tm;
|
|
if (cfg->delay) {
|
|
iot_rtc_delta_add(cfg->delay, node_tm);
|
|
}
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_data_freeze_task_trigger_cnt_check(
|
|
uint8_t task_type, uint8_t *desc, uint16_t trigger_cnt)
|
|
{
|
|
uint8_t done = 0;
|
|
uint16_t max_cnt;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_hdr;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_hdr;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_hdr;
|
|
|
|
switch (task_type) {
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_hdr = (proto_645_fj_task_set_incon_rpt_hdr_t*)desc;
|
|
max_cnt = incon_hdr->triger_cnt;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_hdr = (proto_645_fj_task_set_cross_rpt_t*)desc;
|
|
max_cnt = cross_hdr->triger_cnt;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_hdr = (proto_645_fj_task_set_change_rpt_hdr_t*)desc;
|
|
max_cnt = chg_hdr->triger_cnt;
|
|
break;
|
|
}
|
|
default:
|
|
goto out;
|
|
}
|
|
if (trigger_cnt >= max_cnt) {
|
|
done = 1;
|
|
}
|
|
out:
|
|
return done;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_task_is_runing(uint8_t task_id,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *local_cfg)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint16_t exe_cnt = 0, trigger_cnt = 0;
|
|
|
|
if (iot_sg_ext_freeze_exe_cnt_get(task_id, &exe_cnt, &trigger_cnt)) {
|
|
goto out;
|
|
}
|
|
if (exe_cnt == 0 || iot_sg_ext_data_freeze_task_trigger_cnt_check(
|
|
local_cfg->type, local_cfg->desc, trigger_cnt)) {
|
|
goto out;
|
|
}
|
|
ret = 1;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_fj_task_cfg_desc_reverse(uint8_t task_type,
|
|
uint8_t *desc, uint8_t desc_len, uint8_t desc_is_big_endian,
|
|
uint8_t group_type)
|
|
{
|
|
uint8_t other_len;
|
|
uint8_t reason = 0, *data, len, i, j, di_cnt, des_len, *des_data;
|
|
uint32_t ret = ERR_FAIL, di;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des_hdr;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_hdr;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_tail;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_hdr;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *change_hdr;
|
|
|
|
switch (task_type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
if (desc_len < sizeof(*freeze_hdr)) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t*)desc;
|
|
if ((freeze_hdr->data_cnt > PROTO_645_FJ_TASK_DESC_FREEZE_MAX_CNT)
|
|
|| !freeze_hdr->data_cnt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
data = freeze_hdr->data_desc;
|
|
len = desc_len - sizeof(*freeze_hdr);
|
|
for (i = 0; i < freeze_hdr->data_cnt; i++) {
|
|
if (len < sizeof(*freeze_des_hdr)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
freeze_des_hdr = (proto_645_fj_freeze_data_desc_hdr_t*)data;
|
|
len -= sizeof(*freeze_des_hdr);
|
|
data += sizeof(*freeze_des_hdr);
|
|
if (len < freeze_des_hdr->data_len) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
len -= freeze_des_hdr->data_len;
|
|
data += freeze_des_hdr->data_len;
|
|
des_len = freeze_des_hdr->data_len;
|
|
des_data = freeze_des_hdr->data;
|
|
switch (freeze_des_hdr->format_type) {
|
|
case PROTO_645_FJ_FREEZE_DATA_FORMAT_NO_TS:
|
|
{
|
|
if ((des_len < PROTO_645_2007_DI_LEN) ||
|
|
(des_len > PROTO_645_FJ_TASK_DESC_FREEZE_MAX_LEN)) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
di = iot_bytes_to_uint32(des_data, desc_is_big_endian);
|
|
iot_data_reverse(des_data, PROTO_645_2007_DI_LEN);
|
|
des_len -= PROTO_645_2007_DI_LEN;
|
|
des_data += PROTO_645_2007_DI_LEN;
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_METER_MULTI_DI_READ) {
|
|
di_cnt = (uint8_t)(di & 0x000000ff);
|
|
if (!di_cnt) {
|
|
break;
|
|
}
|
|
if (di_cnt * PROTO_645_2007_DI_LEN + di_cnt - 1 > des_len) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < di_cnt; j++) {
|
|
iot_data_reverse(des_data, PROTO_645_2007_DI_LEN);
|
|
des_data += PROTO_645_2007_DI_LEN;
|
|
if (j < di_cnt - 1) {
|
|
des_data++;
|
|
}
|
|
}
|
|
} else {
|
|
if (des_len > 1) {
|
|
iot_data_reverse(des_data, des_len);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_FREEZE_DATA_FORMAT_WITH_TS:
|
|
{
|
|
if (des_len < (PROTO_645_2007_DI_LEN +
|
|
sizeof(proto_645_fj_freeze_data_desc_tail_t))
|
|
|| (des_len > PROTO_645_FJ_TASK_DESC_FREEZE_MAX_LEN)) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
iot_data_reverse(des_data, PROTO_645_2007_DI_LEN);
|
|
des_len -= PROTO_645_2007_DI_LEN;
|
|
des_data += PROTO_645_2007_DI_LEN;
|
|
other_len = des_len -
|
|
sizeof(proto_645_fj_freeze_data_desc_tail_t);
|
|
if (other_len > 1) {
|
|
iot_data_reverse(des_data, other_len);
|
|
}
|
|
des_data += other_len;
|
|
iot_data_reverse(des_data, sizeof(proto_645_fj_time_ymdhm_t));
|
|
des_data += sizeof(proto_645_fj_time_ymdhm_t);
|
|
iot_data_reverse(des_data, sizeof(proto_645_fj_task_cycle_t));
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_FREEZE_DATA_FORMAT_WITH_TSR:
|
|
{
|
|
if ((des_len < (PROTO_645_2007_DI_LEN +
|
|
sizeof(proto_645_fj_freeze_data_desc_tail_t) +
|
|
sizeof(proto_645_fj_task_time_domain_t)))
|
|
|| (des_len > PROTO_645_FJ_TASK_DESC_FREEZE_MAX_LEN)) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
iot_data_reverse(des_data, PROTO_645_2007_DI_LEN);
|
|
des_len -= PROTO_645_2007_DI_LEN;
|
|
des_data += PROTO_645_2007_DI_LEN;
|
|
other_len = des_len -
|
|
(sizeof(proto_645_fj_freeze_data_desc_tail_t) +
|
|
sizeof(proto_645_fj_task_time_domain_t));
|
|
if (other_len > 1) {
|
|
iot_data_reverse(des_data, other_len);
|
|
}
|
|
des_data += other_len;
|
|
iot_data_reverse(des_data, sizeof(proto_645_fj_time_ymdhm_t));
|
|
des_data += sizeof(proto_645_fj_time_ymdhm_t);
|
|
iot_data_reverse(des_data, sizeof(proto_645_fj_task_cycle_t));
|
|
break;
|
|
}
|
|
default:
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
if (desc_len < sizeof(*incon_hdr)) {
|
|
reason = 10;
|
|
goto out;
|
|
}
|
|
incon_hdr = (proto_645_fj_task_set_incon_rpt_hdr_t*)desc;
|
|
iot_data_reverse((uint8_t *)&incon_hdr->triger_cnt,
|
|
sizeof(incon_hdr->triger_cnt));
|
|
if (!incon_hdr->di_cnt) {
|
|
reason = 11;
|
|
goto out;
|
|
}
|
|
data = (uint8_t*)incon_hdr->di;
|
|
len = desc_len - sizeof(*incon_hdr);
|
|
if (len < (incon_hdr->di_cnt * PROTO_645_2007_DI_LEN)) {
|
|
reason = 12;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < incon_hdr->di_cnt; j++) {
|
|
iot_data_reverse((uint8_t *)&incon_hdr->di[j],
|
|
PROTO_645_2007_DI_LEN);
|
|
}
|
|
len = len - incon_hdr->di_cnt * PROTO_645_2007_DI_LEN;
|
|
data = data + incon_hdr->di_cnt * PROTO_645_2007_DI_LEN;
|
|
if (len < sizeof(*flw_tail)) {
|
|
reason = 13;
|
|
goto out;
|
|
}
|
|
len = len - sizeof(*flw_tail);
|
|
flw_tail = (proto_645_fj_task_set_flw_rpt_hdr_t*)data;
|
|
if (((flw_tail->follow_di_cnt * PROTO_645_2007_DI_LEN) > len)
|
|
&& flw_tail->follow_di_cnt) {
|
|
reason = 14;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < flw_tail->follow_di_cnt; j++) {
|
|
iot_data_reverse((uint8_t *)&flw_tail->di[j],
|
|
PROTO_645_2007_DI_LEN);
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
if (desc_len < sizeof(*cross_hdr)) {
|
|
reason = 15;
|
|
goto out;
|
|
}
|
|
cross_hdr = (proto_645_fj_task_set_cross_rpt_t*)desc;
|
|
iot_data_reverse((uint8_t *)&cross_hdr->triger_cnt,
|
|
sizeof(cross_hdr->triger_cnt));
|
|
iot_data_reverse((uint8_t *)&cross_hdr->di, sizeof(cross_hdr->di));
|
|
if (cross_hdr->value_len > PROTO_645_FJ_TASK_DESC_CROSS_VALUE_MAX_LEN
|
|
|| !cross_hdr->value_len) {
|
|
reason = 16;
|
|
goto out;
|
|
}
|
|
if (cross_hdr->cnt < PROTO_645_FJ_TASK_DESC_CROSS_VALUE_MIN_CNT
|
|
|| cross_hdr->cnt > PROTO_645_FJ_TASK_DESC_CROSS_VALUE_MAX_CNT) {
|
|
reason = 17;
|
|
goto out;
|
|
}
|
|
data = cross_hdr->value_list;
|
|
len = desc_len - sizeof(*cross_hdr);
|
|
if (len < cross_hdr->value_len * cross_hdr->cnt) {
|
|
reason = 18;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < cross_hdr->cnt; j++) {
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698 &&
|
|
cross_hdr->value_len > 2) {
|
|
/* skip data type */
|
|
data++;
|
|
len--;
|
|
iot_data_reverse(data, cross_hdr->value_len - 1);
|
|
len -= (cross_hdr->value_len - 1);
|
|
data += (cross_hdr->value_len - 1);
|
|
} else if (group_type == PROTO_645_FJ_TASK_GROUP_645 &&
|
|
cross_hdr->value_len > 1) {
|
|
iot_data_reverse(data, cross_hdr->value_len);
|
|
len -= cross_hdr->value_len;
|
|
data += cross_hdr->value_len;
|
|
} else {
|
|
len -= cross_hdr->value_len;
|
|
data += cross_hdr->value_len;
|
|
}
|
|
}
|
|
if (len < sizeof(*flw_tail)) {
|
|
reason = 19;
|
|
goto out;
|
|
}
|
|
len = len - sizeof(*flw_tail);
|
|
flw_tail = (proto_645_fj_task_set_flw_rpt_hdr_t*)data;
|
|
if (((flw_tail->follow_di_cnt * PROTO_645_2007_DI_LEN) > len)
|
|
&& flw_tail->follow_di_cnt) {
|
|
reason = 20;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < flw_tail->follow_di_cnt; j++) {
|
|
iot_data_reverse((uint8_t *)&flw_tail->di[j],
|
|
PROTO_645_2007_DI_LEN);
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
if (desc_len < sizeof(*change_hdr)) {
|
|
reason = 21;
|
|
goto out;
|
|
}
|
|
change_hdr = (proto_645_fj_task_set_change_rpt_hdr_t*)desc;
|
|
iot_data_reverse((uint8_t *)&change_hdr->triger_cnt,
|
|
sizeof(change_hdr->triger_cnt));
|
|
iot_data_reverse((uint8_t *)&change_hdr->di, sizeof(change_hdr->di));
|
|
if (change_hdr->value_len > PROTO_645_FJ_TASK_DESC_CHANGE_VALUE_MAX_LEN
|
|
|| !change_hdr->value_len) {
|
|
reason = 22;
|
|
goto out;
|
|
}
|
|
data = change_hdr->value_list;
|
|
len = desc_len - sizeof(*change_hdr);
|
|
if (len < change_hdr->value_len) {
|
|
reason = 23;
|
|
goto out;
|
|
}
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698 &&
|
|
change_hdr->value_len > 2) {
|
|
/* skip data type */
|
|
data++;
|
|
len--;
|
|
iot_data_reverse(data, change_hdr->value_len - 1);
|
|
len -= (change_hdr->value_len - 1);
|
|
data += (change_hdr->value_len - 1);
|
|
} else if (group_type == PROTO_645_FJ_TASK_GROUP_645 &&
|
|
change_hdr->value_len > 1) {
|
|
iot_data_reverse(data, change_hdr->value_len);
|
|
len -= change_hdr->value_len;
|
|
data += change_hdr->value_len;
|
|
} else {
|
|
len -= change_hdr->value_len;
|
|
data += change_hdr->value_len;
|
|
}
|
|
|
|
if (len < sizeof(*flw_tail)) {
|
|
reason = 24;
|
|
goto out;
|
|
}
|
|
len = len - sizeof(*flw_tail);
|
|
flw_tail = (proto_645_fj_task_set_flw_rpt_hdr_t*)data;
|
|
if (((flw_tail->follow_di_cnt * PROTO_645_2007_DI_LEN) > len)
|
|
&& flw_tail->follow_di_cnt) {
|
|
reason = 25;
|
|
goto out;
|
|
}
|
|
for (j = 0; j < flw_tail->follow_di_cnt; j++) {
|
|
iot_data_reverse((uint8_t *)&flw_tail->di[j],
|
|
PROTO_645_2007_DI_LEN);
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s reason %d\n", __FUNCTION__, reason);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
uint8_t iot_sg_ext_data_task_finish_check(uint8_t *addr,
|
|
uint8_t task_id)
|
|
{
|
|
uint8_t complete = 0;
|
|
uint32_t ret;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
|
|
task_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)iot_pkt_put(task_pkt,
|
|
sizeof(*cfg));
|
|
ret = iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
if (iot_sg_ext_task_is_runing(task_id, cfg)) {
|
|
goto out;
|
|
}
|
|
complete = 1;
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return complete;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_muilt_flag_to_save(uint8_t mult_data_item)
|
|
{
|
|
uint8_t addr[IOT_MAC_ADDR_LEN] = { 0 };
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
sta_glb->drv->get_login_addr(addr);
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
goto out;
|
|
}
|
|
|
|
iot_mac_addr_cpy(comm_cfg.mult_di_addr, addr);
|
|
comm_cfg.mult_data_item = mult_data_item;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_data_freeze_task_handle(iot_sg_sta_node_desc_t *node,
|
|
iot_time_tm_t curr_tm)
|
|
{
|
|
uint32_t ret;
|
|
uint16_t *triger_cnt;
|
|
uint8_t task_done = 0, flag_new = 0, timeout, group_type, data_type;
|
|
iot_pkt_t *pkt = NULL, *task_pkt = NULL;
|
|
iot_time_tm_t tm = curr_tm, *node_tm = 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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *local_cfg;
|
|
|
|
if (!freeze_task->cur_task_id) {
|
|
goto done;
|
|
}
|
|
task_pkt = iot_pkt_alloc(sizeof(*local_cfg), IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto done;
|
|
}
|
|
local_cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(task_pkt, sizeof(*local_cfg));
|
|
ret = iot_sg_sta_ext_freeze_flash_cfg_get(node->entry.addr,
|
|
freeze_task->cur_task_id, local_cfg);
|
|
if (ret != ERR_OK) {
|
|
goto done;
|
|
}
|
|
group_type = iot_sg_sta_ext_fj_task_group_get(local_cfg->id);
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
/* 698 group meter read msg is big endian */
|
|
iot_sg_sta_ext_fj_task_cfg_desc_reverse(local_cfg->type,
|
|
local_cfg->desc, local_cfg->desc_len, 0, group_type);
|
|
/* triger count check is little endian */
|
|
if (local_cfg->type == PROTO_645_FJ_TASK_TYPE_INCON_RPT ||
|
|
local_cfg->type == PROTO_645_FJ_TASK_TYPE_CROSS_RPT ||
|
|
local_cfg->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
triger_cnt = (uint16_t *)local_cfg->desc;
|
|
iot_data_reverse((uint8_t *)triger_cnt, sizeof(*triger_cnt));
|
|
}
|
|
}
|
|
if (!iot_sg_ext_task_is_runing(freeze_task->cur_task_id, local_cfg)) {
|
|
goto done;
|
|
}
|
|
if (iot_sg_ext_data_freeze_tm_check(local_cfg->type) != ERR_OK) {
|
|
goto done;
|
|
}
|
|
node_tm = iot_sg_ext_data_freeze_get_node_tm(node,
|
|
freeze_task->cur_task_id);
|
|
if (!node_tm) {
|
|
goto done;
|
|
}
|
|
switch (freeze_task->cur_state) {
|
|
case IOT_SG_STA_EXT_FREEZR_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) {
|
|
*node_tm = iot_sg_ext_get_next_data_freeze_ts(&tm, node_tm,
|
|
local_cfg);
|
|
/* check day freeze task */
|
|
iot_sg_ext_day_freeze_task_last_check(node->entry.addr, node_tm, &tm,
|
|
local_cfg);
|
|
} else if (iot_rtc_delta_calc(node_tm, &tm) >= 0) {
|
|
freeze_task->cur_state = IOT_SG_STA_EXT_FREEZR_STATE_SEND;
|
|
flag_new = 1;
|
|
goto send;
|
|
}
|
|
goto done;
|
|
}
|
|
case IOT_SG_STA_EXT_FREEZR_STATE_WAIT:
|
|
{
|
|
if (!freeze_task->timeout_cnt) {
|
|
if (freeze_task->flag_resp) {
|
|
freeze_task->repeat_cnt = 0;
|
|
}
|
|
if (!freeze_task->repeat_cnt) {
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_645 &&
|
|
!iot_mac_addr_valid(freeze_task->comm_cfg.mult_di_addr) &&
|
|
freeze_task->cur_mr_di_cnt > 1) {
|
|
if (freeze_task->flag_resp &&
|
|
!freeze_task->flag_nack_resp) {
|
|
iot_sg_sta_ext_fj_muilt_flag_to_save(1);
|
|
} else {
|
|
iot_sg_sta_ext_fj_muilt_flag_to_save(0);
|
|
flag_new = 1;
|
|
freeze_task->cur_state =
|
|
IOT_SG_STA_EXT_FREEZR_STATE_SEND;
|
|
goto send;
|
|
}
|
|
}
|
|
if (iot_sg_ext_cur_freeze_di_update(local_cfg)) {
|
|
iot_sg_ext_data_freeze_save(node->entry.addr,
|
|
freeze_task->cur_task_id, node_tm);
|
|
if (iot_sg_ext_task_is_runing(
|
|
freeze_task->cur_task_id, local_cfg)) {
|
|
*node_tm = iot_sg_ext_get_next_data_freeze_ts(
|
|
&tm, node_tm, local_cfg);
|
|
} else {
|
|
os_mem_set(node_tm, 0, sizeof(*node_tm));
|
|
}
|
|
goto done;
|
|
} else {
|
|
flag_new = 1;
|
|
}
|
|
} else {
|
|
freeze_task->repeat_cnt--;
|
|
}
|
|
freeze_task->cur_state = IOT_SG_STA_EXT_FREEZR_STATE_SEND;
|
|
goto send;
|
|
} else {
|
|
freeze_task->timeout_cnt--;
|
|
}
|
|
break;
|
|
}
|
|
case IOT_SG_STA_EXT_FREEZR_STATE_SEND:
|
|
{
|
|
send:
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698) {
|
|
data_type = IOT_SG_STA_DATA_TYPE_69845;
|
|
pkt = iot_sg_ext_meter_freeze_msg_build_698(node->entry.addr,
|
|
local_cfg);
|
|
} else {
|
|
pkt = iot_sg_ext_meter_freeze_msg_build_645(node->entry.addr,
|
|
local_cfg);
|
|
data_type = IOT_SG_STA_DATA_TYPE_645_07;
|
|
}
|
|
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_DATA_FREEZE,
|
|
node->entry.addr, 0, 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 task %lu "
|
|
"di idx %lu\n", __FUNCTION__, node->entry.addr[0],
|
|
node->entry.addr[1], node->entry.addr[2],node->entry.addr[3],
|
|
node->entry.addr[4], node->entry.addr[5],
|
|
freeze_task->cur_task_id, freeze_task->cur_di_idx);
|
|
freeze_task->cur_state = IOT_SG_STA_EXT_FREEZR_STATE_WAIT;
|
|
freeze_task->timeout_cnt = IOT_SG_STA_EXT_READ_DATA_TIMEOUT;
|
|
freeze_task->flag_resp = 0;
|
|
freeze_task->flag_nack_resp = 0;
|
|
if (flag_new) {
|
|
freeze_task->repeat_cnt = 1;
|
|
}
|
|
}
|
|
iot_pkt_free(pkt);
|
|
} else {
|
|
if (iot_sg_ext_cur_freeze_di_update(local_cfg)) {
|
|
iot_sg_ext_data_freeze_save(node->entry.addr,
|
|
freeze_task->cur_task_id, node_tm);
|
|
if (iot_sg_ext_task_is_runing(
|
|
freeze_task->cur_task_id, local_cfg)) {
|
|
*node_tm = iot_sg_ext_get_next_data_freeze_ts(
|
|
&tm, node_tm, local_cfg);
|
|
} else {
|
|
os_mem_set(node_tm, 0, sizeof(*node_tm));
|
|
}
|
|
goto done;
|
|
} else {
|
|
flag_new = 1;
|
|
goto send;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
goto out;
|
|
done:
|
|
task_done = 1;
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return task_done;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_task_info_check(
|
|
iot_sg_sta_drv_meter_fj_task_info_t* info)
|
|
{
|
|
uint32_t ret = ERR_INVAL, cycle_sec;
|
|
uint8_t reason = 0, group;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
group = iot_sg_sta_ext_fj_task_group_get(info->id);
|
|
if (group == PROTO_645_FJ_TASK_GROUP_UNKNOWN) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (info->type != PROTO_645_FJ_TASK_TYPE_FREEZE
|
|
&& info->type != PROTO_645_FJ_TASK_TYPE_CROSS_RPT
|
|
&& info->type != PROTO_645_FJ_TASK_TYPE_INCON_RPT
|
|
&& info->type != PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
cycle.unit = info->unit;
|
|
cycle.value = info->value;
|
|
cycle_sec = proto_645_fj_task_cycle_to_sec(&cycle);
|
|
if (cycle_sec == 0) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (info->delay >= cycle_sec) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
if (!info->save_cnt) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (!info->exe_cnt) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
if (!info->desc_len) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
if (proto_645_fj_task_info_desc_check(info->type,
|
|
info->desc, info->desc_len, group)) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_ext_data_freeze_cfg_init(uint8_t task_init, uint8_t *addr)
|
|
{
|
|
uint8_t task_id = task_init;
|
|
uint16_t index, exe_cnt, triger_cnt, unit_len = 0;
|
|
iot_pkt_t *flash_pkt = NULL, *pkt_unit = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *flash_cfg;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t* unit;
|
|
|
|
if (task_id > PROTO_FJ_FREEZE_TASK_ID_MAX) {
|
|
goto out;
|
|
}
|
|
flash_pkt = iot_pkt_alloc(sizeof(*flash_cfg), IOT_SMART_GRID_MID);
|
|
if (!flash_pkt) {
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
pkt_unit = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_unit) {
|
|
iot_pkt_free(flash_pkt);
|
|
goto out;
|
|
}
|
|
flash_cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)iot_pkt_put(flash_pkt,
|
|
sizeof(*flash_cfg));
|
|
unit = (iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(pkt_unit,
|
|
unit_len);
|
|
for (; task_id <= PROTO_FJ_FREEZE_TASK_ID_MAX; task_id++) {
|
|
if (iot_sg_sta_flash_clct_task_info_get(addr, task_id,
|
|
(uint8_t *)flash_cfg, sizeof(*flash_cfg),
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK) == ERR_OK) {
|
|
if (iot_sg_ext_task_info_check(flash_cfg) != ERR_OK) {
|
|
iot_sg_sta_flash_clct_task_del(addr, task_id, 1,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
continue;
|
|
}
|
|
os_delay(10);
|
|
if (!flash_cfg->storage_mode) {
|
|
iot_sg_sta_ext_freeze_flash_cfg_valid_set(task_id, 1);
|
|
if (iot_sg_sta_flash_ct_unit_data_find_latest(addr, &index,
|
|
(uint8_t *)unit, unit_len, task_id,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK) == ERR_OK) {
|
|
exe_cnt = unit->exe_cnt_remain;
|
|
triger_cnt = unit->save_cnt;
|
|
} else {
|
|
exe_cnt = flash_cfg->exe_cnt;
|
|
triger_cnt = 0;
|
|
}
|
|
iot_sg_ext_freeze_exe_cnt_set(task_id, exe_cnt, triger_cnt, 0);
|
|
iot_sg_printf("%s id %lu success\n", __FUNCTION__, task_id);
|
|
} else {
|
|
iot_sg_sta_flash_clct_task_del(addr, task_id, 1,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
}
|
|
task_id++;
|
|
break;
|
|
}
|
|
}
|
|
iot_pkt_free(flash_pkt);
|
|
iot_pkt_free(pkt_unit);
|
|
out:
|
|
return task_id;
|
|
}
|
|
|
|
uint8_t iot_sg_ext_data_freeze_func(uint8_t *addr)
|
|
{
|
|
uint8_t complete = 0;
|
|
iot_time_tm_t tm = {0};
|
|
iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
|
|
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_freeze_task_t *task_info;
|
|
|
|
if (!node || !ext_info->freeze_task_info) {
|
|
complete = 1;
|
|
goto out;
|
|
}
|
|
task_info = ext_info->freeze_task_info;
|
|
task_info->init_task_id =
|
|
iot_sg_ext_data_freeze_cfg_init((uint8_t)task_info->init_task_id, addr);
|
|
if (task_info->init_task_id <= PROTO_FJ_FREEZE_TASK_ID_MAX) {
|
|
complete = 1;
|
|
goto out;
|
|
}
|
|
if (task_info->stop_dur) {
|
|
complete = 1;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_rtc_get(&tm, 0);
|
|
next_task:
|
|
if (task_info->cur_state == IOT_SG_STA_EXT_FREEZR_STATE_IDLE) {
|
|
if (iot_sg_ext_data_freeze_cur_task_update(addr) != ERR_OK) {
|
|
complete = 1;
|
|
goto out;
|
|
}
|
|
}
|
|
if (iot_sg_ext_data_freeze_task_handle(node, tm)) {
|
|
iot_sg_ext_data_freeze_cur_task_done();
|
|
goto next_task;
|
|
}
|
|
out:
|
|
return complete;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_freeze_task_comm_cfg_init(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *cfg_comm)
|
|
{
|
|
uint8_t need_save = 0, i, addr[IOT_MAC_ADDR_LEN];
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_flash_fj_task_comm_cfg_t *cfg = NULL;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (pkt == NULL) {
|
|
goto def;
|
|
}
|
|
BUILD_BUG_ON(IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT ==
|
|
IOT_SG_STA_FLASH_FJ_TASK_RPT_CFG_CNT);
|
|
cfg = (iot_sg_sta_flash_fj_task_comm_cfg_t*)iot_pkt_put(pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_flash_fj_task_comm_cfg_get(cfg) == ERR_OK) {
|
|
cfg_comm->report_max_cnt = cfg->report_max_cnt;
|
|
cfg_comm->unit_max_len = cfg->unit_max_len;
|
|
cfg_comm->random_rpt_time = cfg->random_rpt_time;
|
|
cfg_comm->retry_freeze = cfg->retry_freeze;
|
|
cfg_comm->retry_nonfreeze = cfg->retry_nonfreeze;
|
|
sta_glb->drv->get_login_addr(addr);
|
|
if (iot_mac_addr_cmp(cfg->mult_di_addr, addr)) {
|
|
cfg_comm->mult_data_item = cfg->mult_data_item;
|
|
iot_mac_addr_cpy(cfg_comm->mult_di_addr, addr);
|
|
} else {
|
|
cfg_comm->mult_data_item = PROTO_645_FJ_METET_MULT_DATA_ITEM_DEF;
|
|
os_mem_set(cfg_comm->mult_di_addr, 0x0, IOT_MAC_ADDR_LEN);
|
|
}
|
|
cfg_comm->rpt_mode = cfg->rpt_mode;
|
|
cfg_comm->cnt = cfg->cnt;
|
|
for (i = 0; i < cfg_comm->cnt; i++) {
|
|
cfg_comm->task_rpt[i].id = cfg->task_rpt[i].id;
|
|
cfg_comm->task_rpt[i].cnt = cfg->task_rpt[i].cnt;
|
|
}
|
|
} else {
|
|
def:
|
|
cfg_comm->report_max_cnt = IOT_SG_STA_EXT_TASK_RPT_CNT_DEF;
|
|
cfg_comm->unit_max_len = IOT_SG_STA_EXT_TASK_REC_UNIT_LEN_DEF;
|
|
cfg_comm->random_rpt_time = IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_DEF;
|
|
cfg_comm->retry_freeze = PROTO_645_FJ_FREEZE_TASK_RERPT_CNT_DEF;
|
|
cfg_comm->retry_nonfreeze = PROTO_645_FJ_NON_FREEZE_TASK_RERPT_CNT_DEF;
|
|
cfg_comm->mult_data_item = PROTO_645_FJ_METET_MULT_DATA_ITEM_DEF;
|
|
os_mem_set(cfg_comm->mult_di_addr, 0x0, IOT_MAC_ADDR_LEN);
|
|
cfg_comm->rpt_mode = PROTO_645_FJ_REPORT_MODE_645;
|
|
cfg_comm->cnt = 0;
|
|
os_mem_set(cfg_comm->task_rpt, 0, sizeof(cfg_comm->task_rpt));
|
|
goto save;
|
|
}
|
|
if (cfg_comm->retry_freeze > PROTO_645_FJ_FREEZE_TASK_RERPT_CNT_MAX) {
|
|
cfg_comm->retry_freeze = PROTO_645_FJ_FREEZE_TASK_RERPT_CNT_DEF;
|
|
need_save = 1;
|
|
}
|
|
if (cfg_comm->retry_nonfreeze >
|
|
PROTO_645_FJ_NON_FREEZE_TASK_RERPT_CNT_MAX) {
|
|
cfg_comm->retry_nonfreeze = PROTO_645_FJ_NON_FREEZE_TASK_RERPT_CNT_DEF;
|
|
need_save = 1;
|
|
}
|
|
if (cfg_comm->random_rpt_time > IOT_SG_STA_EXT_TASK_RANDOM_RPT_PERCENT_MAX
|
|
|| cfg_comm->random_rpt_time <
|
|
IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_MIN) {
|
|
cfg_comm->random_rpt_time = IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_DEF;
|
|
need_save = 1;
|
|
}
|
|
if (cfg_comm->mult_data_item > PROTO_645_FJ_METET_MULT_DATA_ITEM_MAX) {
|
|
cfg_comm->mult_data_item = PROTO_645_FJ_METET_MULT_DATA_ITEM_DEF;
|
|
need_save = 1;
|
|
}
|
|
if (cfg_comm->rpt_mode > PROTO_645_FJ_REPORT_MODE_698) {
|
|
cfg_comm->rpt_mode = PROTO_645_FJ_REPORT_MODE_645;
|
|
need_save = 1;
|
|
}
|
|
if (cfg_comm->cnt > IOT_SG_STA_FLASH_FJ_TASK_RPT_CFG_CNT) {
|
|
cfg_comm->cnt = 0;
|
|
os_mem_set(cfg_comm->task_rpt, 0, sizeof(cfg_comm->task_rpt));
|
|
need_save = 1;
|
|
}
|
|
if (!need_save) {
|
|
goto out;
|
|
}
|
|
save:
|
|
if (cfg) {
|
|
cfg->unit_max_len = cfg_comm->unit_max_len;
|
|
cfg->report_max_cnt = cfg_comm->report_max_cnt;
|
|
cfg->random_rpt_time = cfg_comm->random_rpt_time;
|
|
cfg->retry_freeze = cfg_comm->retry_freeze;
|
|
cfg->retry_nonfreeze = cfg_comm->retry_nonfreeze;
|
|
cfg->mult_data_item = cfg_comm->mult_data_item;
|
|
iot_mac_addr_cpy(cfg->mult_di_addr, cfg_comm->mult_di_addr);
|
|
cfg->rpt_mode = cfg_comm->rpt_mode;
|
|
cfg->cnt = cfg_comm->cnt;
|
|
for (i = 0; i < cfg->cnt; i++) {
|
|
cfg->task_rpt[i].id = cfg_comm->task_rpt[i].id;
|
|
cfg->task_rpt[i].cnt = cfg_comm->task_rpt[i].cnt;
|
|
}
|
|
iot_sg_sta_flash_fj_task_comm_cfg_save(cfg);
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_comm_same_check(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *cfg_comm,
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *task_cfg)
|
|
{
|
|
uint8_t i;
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
if ((task_cfg->report_max_cnt != cfg_comm->report_max_cnt)
|
|
|| (task_cfg->unit_max_len != cfg_comm->unit_max_len)
|
|
|| (task_cfg->random_rpt_time != cfg_comm->random_rpt_time)
|
|
|| (task_cfg->retry_freeze != cfg_comm->retry_freeze)
|
|
|| (task_cfg->retry_nonfreeze != cfg_comm->retry_nonfreeze)
|
|
|| (task_cfg->mult_data_item != cfg_comm->mult_data_item)
|
|
|| (!iot_mac_addr_cmp(task_cfg->mult_di_addr, cfg_comm->mult_di_addr))
|
|
|| (task_cfg->rpt_mode != cfg_comm->rpt_mode)
|
|
|| (task_cfg->cnt != cfg_comm->cnt)) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < cfg_comm->cnt; i++) {
|
|
if ((task_cfg->task_rpt[i].id != cfg_comm->task_rpt[i].id)
|
|
|| (task_cfg->task_rpt[i].cnt != cfg_comm->task_rpt[i].cnt)) {
|
|
goto out;
|
|
}
|
|
}
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_task_comm_cfg_save(
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t *cfg_comm)
|
|
{
|
|
uint8_t reason = 0, i;
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_pkt_t *pkt_buf = NULL;
|
|
iot_sg_sta_flash_fj_task_comm_cfg_t *flash_cfg;
|
|
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_freeze_task_t *task_info = ext_info->freeze_task_info;
|
|
|
|
if (!task_info) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_same_check(&task_info->comm_cfg,
|
|
cfg_comm) == ERR_OK) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
pkt_buf = iot_pkt_alloc(sizeof(*flash_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt_buf) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
flash_cfg = (iot_sg_sta_flash_fj_task_comm_cfg_t*)iot_pkt_put(pkt_buf,
|
|
sizeof(*flash_cfg));
|
|
flash_cfg->unit_max_len = cfg_comm->unit_max_len;
|
|
flash_cfg->report_max_cnt = cfg_comm->report_max_cnt;
|
|
flash_cfg->random_rpt_time = cfg_comm->random_rpt_time;
|
|
flash_cfg->retry_freeze = cfg_comm->retry_freeze;
|
|
flash_cfg->retry_nonfreeze = cfg_comm->retry_nonfreeze;
|
|
flash_cfg->mult_data_item = cfg_comm->mult_data_item;
|
|
iot_mac_addr_cpy(flash_cfg->mult_di_addr, cfg_comm->mult_di_addr);
|
|
flash_cfg->rpt_mode = cfg_comm->rpt_mode;
|
|
flash_cfg->cnt = cfg_comm->cnt;
|
|
for (i = 0; i < flash_cfg->cnt; i++) {
|
|
flash_cfg->task_rpt[i].id = cfg_comm->task_rpt[i].id;
|
|
flash_cfg->task_rpt[i].cnt = cfg_comm->task_rpt[i].cnt;
|
|
}
|
|
ret = iot_sg_sta_flash_fj_task_comm_cfg_save(flash_cfg);
|
|
if (ret) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
task_info->comm_cfg.report_max_cnt = cfg_comm->report_max_cnt;
|
|
task_info->comm_cfg.unit_max_len = cfg_comm->unit_max_len;
|
|
task_info->comm_cfg.random_rpt_time = cfg_comm->random_rpt_time;
|
|
task_info->comm_cfg.retry_freeze = cfg_comm->retry_freeze;
|
|
task_info->comm_cfg.retry_nonfreeze = cfg_comm->retry_nonfreeze;
|
|
task_info->comm_cfg.mult_data_item = cfg_comm->mult_data_item;
|
|
iot_mac_addr_cpy(task_info->comm_cfg.mult_di_addr, cfg_comm->mult_di_addr);
|
|
task_info->comm_cfg.rpt_mode = cfg_comm->rpt_mode;
|
|
task_info->comm_cfg.cnt = cfg_comm->cnt;
|
|
for (i = 0; i < task_info->comm_cfg.cnt; i++) {
|
|
task_info->comm_cfg.task_rpt[i].id = cfg_comm->task_rpt[i].id;
|
|
task_info->comm_cfg.task_rpt[i].cnt = cfg_comm->task_rpt[i].cnt;
|
|
}
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
if (pkt_buf) {
|
|
iot_pkt_free(pkt_buf);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_freeze_stop_dur_get(void)
|
|
{
|
|
uint16_t stop_dur = 0;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
|
|
if (ext_info->freeze_task_info) {
|
|
stop_dur = (uint16_t)(ext_info->freeze_task_info->stop_dur / 60);
|
|
if (ext_info->freeze_task_info->stop_dur % 60) {
|
|
stop_dur++;
|
|
}
|
|
}
|
|
return stop_dur;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_freeze_stop_dur_node_tm_check(uint16_t stop_dur)
|
|
{
|
|
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_node_desc_t *node;
|
|
iot_time_tm_t tm = { 0 };
|
|
|
|
node = iot_sg_sta_node_find_by_addr(ext_info->addr);
|
|
if (!node) {
|
|
return;
|
|
}
|
|
iot_sg_sta_rtc_get(&tm, 0);
|
|
iot_rtc_delta_add(stop_dur * 60, &tm);
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (iot_rtc_delta_calc(&tm, &node->ext.freeze_info.task_tm[i]) < 0) {
|
|
os_mem_set(&node->ext.freeze_info.task_tm[i], 0x0,
|
|
sizeof(iot_time_tm_t));
|
|
}
|
|
}
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_freeze_stop_dur_set(uint16_t stop_dur)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
|
|
if (ext_info->freeze_task_info) {
|
|
ext_info->freeze_task_info->stop_dur = stop_dur * 60;
|
|
iot_sg_sta_ext_freeze_stop_dur_node_tm_check(stop_dur);
|
|
iot_sg_ext_data_freeze_reset();
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void iot_sg_sta_ext_fj_freeze_refresh(void)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
iot_sg_sta_ext_freeze_task_t *task = ext_info->freeze_task_info;
|
|
|
|
if (task) {
|
|
iot_sg_sta_ext_fj_led_blink_timeout_enable(task);
|
|
iot_sg_sta_ext_fj_rpt_handle();
|
|
if (task->stop_dur) {
|
|
task->stop_dur--;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_freeze_task_init(void)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
|
|
ext_info->freeze_task_info = os_mem_malloc(IOT_SMART_GRID_MID,
|
|
sizeof(iot_sg_sta_ext_freeze_task_t));
|
|
os_mem_set(ext_info->freeze_task_info, 0,
|
|
sizeof(iot_sg_sta_ext_freeze_task_t));
|
|
if (ext_info->freeze_task_info) {
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_init(
|
|
&ext_info->freeze_task_info->comm_cfg);
|
|
ext_info->freeze_task_info->init_task_id =
|
|
PROTO_FJ_FREEZE_TASK_ID_MIN;
|
|
ret = ERR_OK;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void iot_sg_sta_ext_freeze_task_deinit(void)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
|
|
|
|
if (ext_info->freeze_task_info) {
|
|
os_mem_free(ext_info->freeze_task_info);
|
|
ext_info->freeze_task_info = NULL;
|
|
}
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_qr_chip_id(uint8_t *addr)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_chip_id_t chip_id = { 0 };
|
|
|
|
BUILD_BUG_ON(sizeof(proto_645_fj_chip_id_t) == IOT_CHIP_MMID_LEN);
|
|
|
|
iot_oem_get_chip_mmid((uint8_t *)&chip_id, sizeof(chip_id));
|
|
pkt = proto_645_fj_build_query_chip_id(addr, (uint8_t *)&chip_id,
|
|
sizeof(chip_id));
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_qr_mod_id(uint8_t *addr)
|
|
{
|
|
iot_oem_base_cfg_t *base_cfg;
|
|
uint8_t mod_id[PROTO_645_FJ_MOD_ID_SIZE] = { 0 }, i;
|
|
|
|
if (iot_oem_get_base_cfg(&base_cfg) != ERR_OK) {
|
|
return proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
}
|
|
BUILD_BUG_ON(IOT_OEM_DEVICE_ID_LEN * 2 <= PROTO_645_FJ_MOD_ID_SIZE);
|
|
for (i = 0; i < IOT_OEM_DEVICE_ID_LEN; i++) {
|
|
mod_id[i * 2] = (base_cfg->dev_id[i] & 0x0F) + 0x30;
|
|
mod_id[i * 2 + 1] = ((base_cfg->dev_id[i] >> 4) & 0x0F) + 0x30;
|
|
}
|
|
iot_data_reverse(mod_id, PROTO_645_FJ_MOD_ID_SIZE);
|
|
return proto_645_fj_build_query_mod_id(addr, mod_id, sizeof(mod_id));
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_get_mod_ver(proto_645_fj_mod_ver_info_t *ver_info)
|
|
{
|
|
uint16_t vendor_id, chip_code;
|
|
iot_build_info_t ts_info;
|
|
|
|
vendor_id = iot_sg_get_vendor_id();
|
|
ver_info->vendor_id = (vendor_id << 8) | ((vendor_id & 0xFF00) >> 8);
|
|
chip_code = iot_sg_get_chip_code();
|
|
ver_info->chip_code = (chip_code << 8) | ((chip_code & 0xFF00) >> 8);
|
|
iot_version_get_user_build_info(&ts_info);
|
|
ver_info->day = iot_byte_to_bcd(ts_info.day);
|
|
ver_info->month = iot_byte_to_bcd(ts_info.month);
|
|
ver_info->year = iot_byte_to_bcd(ts_info.year);
|
|
ver_info->version[0] = (ts_info.sw_ver & 0xFF);
|
|
ver_info->version[1] = (ts_info.sw_ver >> 8);
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_qr_mod_ver(uint8_t *addr)
|
|
{
|
|
proto_645_fj_mod_ver_info_t ver_info = { 0 };
|
|
|
|
iot_sg_sta_ext_fj_get_mod_ver(&ver_info);
|
|
return proto_645_fj_build_query_mod_ver(addr, (uint8_t *)&ver_info,
|
|
sizeof(ver_info));
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_sta_ext_fj_write_tm_soc(uint8_t *addr, uint8_t fn,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_tm_soc;
|
|
iot_pkt_t *rsp_pkt = NULL, *ct_cfg_pkt = NULL;
|
|
iot_time_tm_t curr_tm = {0};
|
|
iot_sg_sta_flash_fj_ct_cfg_t *ct_cfg;
|
|
iot_sg_sta_flash_fj_ct_rec_t ct_rec;
|
|
proto_645_fj_mod_tm_soc_t *mod_tm_soc;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*mod_tm_soc)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
mod_tm_soc = (proto_645_fj_mod_tm_soc_t *)
|
|
(data + sizeof(proto_645_write_data_dest_t));
|
|
req_tm_soc = iot_bcd_to_byte(mod_tm_soc->tm_soc);
|
|
/* only support two time source for FJ, other values is invalid */
|
|
if ((req_tm_soc != PROTO_645_FJ_MOD_TM_SOC_NET) &&
|
|
(req_tm_soc != PROTO_645_FJ_MOD_TM_SOC_PM)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
/* save correct time record to flash when receive module correct time
|
|
* command or setting command of timer management class according to FJ
|
|
*/
|
|
if (iot_sg_sta_rtc_get(&curr_tm, 0) == ERR_OK) {
|
|
ct_rec.ntb_delta = 0;
|
|
ct_rec.second = curr_tm.tm_sec;
|
|
ct_rec.minute = curr_tm.tm_min;
|
|
ct_rec.hour = curr_tm.tm_hour;
|
|
ct_rec.day = curr_tm.tm_mday;
|
|
ct_rec.month = curr_tm.tm_mon;
|
|
ct_rec.year = (uint8_t)(curr_tm.tm_year - 2000);
|
|
iot_sg_sta_flash_fj_ct_rec_save(&ct_rec);
|
|
}
|
|
ct_cfg_pkt =
|
|
iot_pkt_alloc(sizeof(iot_sg_sta_flash_fj_ct_cfg_t), IOT_SMART_GRID_MID);
|
|
if (ct_cfg_pkt) {
|
|
ct_cfg = (iot_sg_sta_flash_fj_ct_cfg_t *)iot_pkt_data(ct_cfg_pkt);
|
|
if (sta_glb->tm_soc != req_tm_soc) {
|
|
iot_sg_sta_rtc_clear(1);
|
|
sta_glb->tm_soc = req_tm_soc;
|
|
ct_cfg->tm_soc = sta_glb->tm_soc;
|
|
ct_cfg->ct_dur = sta_glb->ct_dur;
|
|
iot_sg_sta_flash_fj_ct_cfg_save(ct_cfg);
|
|
if (sta_glb->tm_soc == PROTO_645_FJ_MOD_TM_SOC_PM){
|
|
iot_sg_sta_rtc_clear(0);
|
|
iot_sg_sta_start_get_time();
|
|
}
|
|
}
|
|
} else {
|
|
if (sta_glb->tm_soc != req_tm_soc) {
|
|
iot_sg_sta_rtc_clear(1);
|
|
sta_glb->tm_soc = req_tm_soc;
|
|
if (sta_glb->tm_soc == PROTO_645_FJ_MOD_TM_SOC_PM) {
|
|
iot_sg_sta_rtc_clear(0);
|
|
iot_sg_sta_start_get_time();
|
|
}
|
|
}
|
|
}
|
|
iot_sg_printf("%s tm_soc %lu\n", __FUNCTION__, sta_glb->tm_soc);
|
|
rsp_pkt = proto_645_2007_build_ack_msg(addr, fn);
|
|
goto out;
|
|
|
|
nack:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
rsp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
out:
|
|
if (ct_cfg_pkt) {
|
|
iot_pkt_free(ct_cfg_pkt);
|
|
}
|
|
return rsp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_sta_ext_fj_write_ct_dur(uint8_t *addr, uint8_t fn,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint16_t req_ct_dur = 0;
|
|
uint32_t tmp_dur;
|
|
iot_pkt_t *rsp_pkt = NULL, *ct_cfg_pkt = NULL;
|
|
iot_time_tm_t curr_tm = {0};
|
|
iot_sg_sta_flash_fj_ct_cfg_t *ct_cfg;
|
|
iot_sg_sta_flash_fj_ct_rec_t ct_rec;
|
|
proto_645_fj_mod_ct_dur_t *mod_ct_dur;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*mod_ct_dur)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
mod_ct_dur = (proto_645_fj_mod_ct_dur_t *)
|
|
(data + sizeof(proto_645_write_data_dest_t));
|
|
iot_bcd_to_uint32((uint8_t *)&(mod_ct_dur->ct_dur),
|
|
sizeof(mod_ct_dur->ct_dur), 0, &tmp_dur);
|
|
req_ct_dur = (uint16_t)tmp_dur;
|
|
if (req_ct_dur < PROTO_645_FJ_MOD_CT_DUR_MIN) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
ct_cfg_pkt =
|
|
iot_pkt_alloc(sizeof(iot_sg_sta_flash_fj_ct_cfg_t), IOT_SMART_GRID_MID);
|
|
if(ct_cfg_pkt) {
|
|
ct_cfg = (iot_sg_sta_flash_fj_ct_cfg_t *)iot_pkt_data(ct_cfg_pkt);
|
|
if (sta_glb->ct_dur != req_ct_dur) {
|
|
sta_glb->ct_dur = req_ct_dur;
|
|
ct_cfg->ct_dur = sta_glb->ct_dur;
|
|
ct_cfg->tm_soc = sta_glb->tm_soc;
|
|
iot_sg_sta_flash_fj_ct_cfg_save(ct_cfg);
|
|
}
|
|
} else {
|
|
sta_glb->ct_dur = req_ct_dur;
|
|
}
|
|
/* save correct time record to flash when receive module correct time
|
|
* command or setting command of timer management class according to FJ
|
|
*/
|
|
if (iot_sg_sta_rtc_get(&curr_tm, 0) == ERR_OK) {
|
|
ct_rec.ntb_delta = 0;
|
|
ct_rec.second = curr_tm.tm_sec;
|
|
ct_rec.minute = curr_tm.tm_min;
|
|
ct_rec.hour = curr_tm.tm_hour;
|
|
ct_rec.day = curr_tm.tm_mday;
|
|
ct_rec.month = curr_tm.tm_mon;
|
|
ct_rec.year = (uint8_t)(curr_tm.tm_year - 2000);
|
|
iot_sg_sta_flash_fj_ct_rec_save(&ct_rec);
|
|
}
|
|
iot_sg_printf("%s ct_dur %lu\n", __FUNCTION__, sta_glb->ct_dur);
|
|
rsp_pkt = proto_645_2007_build_ack_msg(addr, fn);
|
|
goto out;
|
|
|
|
nack:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
rsp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
out:
|
|
if (ct_cfg_pkt) {
|
|
iot_pkt_free(ct_cfg_pkt);
|
|
}
|
|
return rsp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_sta_ext_fj_write_mod_tm(uint8_t *addr, uint8_t fn,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t curr_ts;
|
|
iot_pkt_t *rsp_pkt = NULL;
|
|
iot_time_tm_t drv_tm;
|
|
iot_sg_sta_flash_fj_ct_rec_t ct_rec;
|
|
proto_645_07_time_ymdhms_t *mod_tm;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
curr_ts = (uint32_t)(os_boot_time64() / 1000);
|
|
if (sta_glb->last_gen_ct_ts &&
|
|
(((curr_ts - sta_glb->last_gen_ct_ts) / 60) < sta_glb->ct_dur)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
if (sta_glb->tm_soc != PROTO_645_FJ_MOD_TM_SOC_NET) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*mod_tm)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
mod_tm = (proto_645_07_time_ymdhms_t *)
|
|
(data + sizeof(proto_645_write_data_dest_t));
|
|
drv_tm.tm_year = iot_bcd_to_byte(mod_tm->year) + 2000;
|
|
drv_tm.tm_mon = iot_bcd_to_byte(mod_tm->month);
|
|
drv_tm.tm_mday = iot_bcd_to_byte(mod_tm->day);
|
|
drv_tm.tm_hour = iot_bcd_to_byte(mod_tm->hour);
|
|
drv_tm.tm_min = iot_bcd_to_byte(mod_tm->minute);
|
|
drv_tm.tm_sec = iot_bcd_to_byte(mod_tm->second);
|
|
iot_sg_sta_rtc_set(&drv_tm, 1);
|
|
/* reset next read data time */
|
|
iot_sg_sta_ext_tm_reset();
|
|
iot_sg_sta_ext_fj_power_up_down_record_handle(IOT_SG_STA_POWER_REC_TYPE_UP);
|
|
sta_glb->last_gen_ct_ts = (uint32_t)(os_boot_time64() / 1000);
|
|
|
|
ct_rec.ntb_delta = 0;
|
|
ct_rec.second = drv_tm.tm_sec;
|
|
ct_rec.minute = drv_tm.tm_min;
|
|
ct_rec.hour = drv_tm.tm_hour;
|
|
ct_rec.day = drv_tm.tm_mday;
|
|
ct_rec.month = drv_tm.tm_mon;
|
|
ct_rec.year = (uint8_t)(drv_tm.tm_year - 2000);
|
|
iot_sg_sta_flash_fj_ct_rec_save(&ct_rec);
|
|
rsp_pkt = proto_645_2007_build_ack_msg(addr, fn);
|
|
goto out;
|
|
|
|
nack:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
rsp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
out:
|
|
return rsp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_sta_ext_fj_ntb_ct(uint8_t *addr, uint8_t fn,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t curr_ts, curr_ntb, ret;
|
|
iot_pkt_t *rsp_pkt = NULL, *ct_pkt = NULL;
|
|
iot_time_tm_t req_tm;
|
|
iot_sg_sta_flash_fj_ct_rec_t ct_rec;
|
|
proto_645_fj_ntb_corr_time_t *ntb_ct;
|
|
proto_645_corr_time_t corr_tm;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
curr_ts = (uint32_t)(os_boot_time64() / 1000);
|
|
if (sta_glb->last_ntb_ct_ts &&
|
|
(((curr_ts - sta_glb->last_ntb_ct_ts) / 60) < sta_glb->ct_dur)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
if (sta_glb->tm_soc != PROTO_645_FJ_MOD_TM_SOC_NET) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*ntb_ct)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
ntb_ct = (proto_645_fj_ntb_corr_time_t *)
|
|
(data + sizeof(proto_645_write_data_dest_t));
|
|
if (!ntb_ct->ntb) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
/* module correct time */
|
|
req_tm.tm_year = iot_bcd_to_byte(ntb_ct->year) + 2000;
|
|
req_tm.tm_mon = iot_bcd_to_byte(ntb_ct->mon);
|
|
req_tm.tm_mday = iot_bcd_to_byte(ntb_ct->day);
|
|
req_tm.tm_hour = iot_bcd_to_byte(ntb_ct->hour);
|
|
req_tm.tm_min = iot_bcd_to_byte(ntb_ct->min);
|
|
req_tm.tm_sec = iot_bcd_to_byte(ntb_ct->sec);
|
|
iot_sg_sta_cur_ntb_correct_ts(ntb_ct->ntb, &req_tm);
|
|
iot_sg_sta_rtc_set(&req_tm, 1);
|
|
/* reset next read data time */
|
|
iot_sg_sta_ext_tm_reset();
|
|
iot_sg_sta_ext_fj_power_up_down_record_handle(IOT_SG_STA_POWER_REC_TYPE_UP);
|
|
sta_glb->last_ntb_ct_ts = (uint32_t)(os_boot_time64() / 1000);
|
|
/* save correct time record to flash */
|
|
curr_ntb = iot_plc_get_ntb(p_sg_glb->plc_app_h);
|
|
curr_ntb = curr_ntb - ntb_ct->ntb;
|
|
ct_rec.ntb_delta = IOT_SG_STA_NTB_TO_MS(curr_ntb) * 1000;
|
|
ct_rec.second = req_tm.tm_sec;
|
|
ct_rec.minute = req_tm.tm_min;
|
|
ct_rec.hour = req_tm.tm_hour;
|
|
ct_rec.day = req_tm.tm_mday;
|
|
ct_rec.month = req_tm.tm_mon;
|
|
ct_rec.year = (uint8_t)(req_tm.tm_year - 2000);
|
|
iot_sg_sta_flash_fj_ct_rec_save(&ct_rec);
|
|
corr_tm.year = iot_byte_to_bcd((uint8_t)(req_tm.tm_year - 2000));
|
|
corr_tm.month = iot_byte_to_bcd(req_tm.tm_mon);
|
|
corr_tm.day = iot_byte_to_bcd(req_tm.tm_mday);
|
|
corr_tm.hour = iot_byte_to_bcd(req_tm.tm_hour);
|
|
corr_tm.minute = iot_byte_to_bcd(req_tm.tm_min);
|
|
corr_tm.second = iot_byte_to_bcd(req_tm.tm_sec);
|
|
ct_pkt = proto_645_build_corr_msg(NULL, &corr_tm);
|
|
if (ct_pkt == NULL) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
ret = sta_glb->drv->correct_time(ct_pkt, 1);
|
|
if (ret) {
|
|
reason = 6;
|
|
goto nack;
|
|
}
|
|
rsp_pkt = proto_645_2007_build_ack_msg(addr, fn);
|
|
goto out;
|
|
|
|
nack:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
rsp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
out:
|
|
return rsp_pkt;
|
|
}
|
|
|
|
/* get module time
|
|
* return ERR_OK for success case, ERR_FAIL for fail case
|
|
*/
|
|
static uint32_t iot_sg_sta_ext_fj_get_mod_tm(proto_645_07_time_ymdhms_t *mod_tm)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
iot_time_tm_t curr_tm;
|
|
|
|
if (iot_sg_sta_rtc_get(&curr_tm, 0)) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
mod_tm->year = iot_byte_to_bcd((uint8_t)(curr_tm.tm_year - 2000));
|
|
mod_tm->month = iot_byte_to_bcd(curr_tm.tm_mon);
|
|
mod_tm->day = iot_byte_to_bcd(curr_tm.tm_mday);
|
|
mod_tm->hour = iot_byte_to_bcd(curr_tm.tm_hour);
|
|
mod_tm->minute = iot_byte_to_bcd(curr_tm.tm_min);
|
|
mod_tm->second = iot_byte_to_bcd(curr_tm.tm_sec);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_fj_get_latest_ct_rec(
|
|
proto_645_fj_mod_ct_rec_t *ct_rec)
|
|
{
|
|
uint8_t reason = 0;;
|
|
uint32_t ret = ERR_OK;
|
|
iot_sg_sta_flash_fj_ct_rec_t ct_rec_flash;
|
|
|
|
if (iot_sg_sta_flash_fj_latest_ct_rec_get(&ct_rec_flash) != ERR_OK) {
|
|
reason = 1;
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
ct_rec->ntb_delta = ct_rec_flash.ntb_delta;
|
|
ct_rec->second = iot_byte_to_bcd((uint8_t)ct_rec_flash.second);
|
|
ct_rec->minute = iot_byte_to_bcd((uint8_t)ct_rec_flash.minute);
|
|
ct_rec->hour = iot_byte_to_bcd((uint8_t)ct_rec_flash.hour);
|
|
ct_rec->day = iot_byte_to_bcd((uint8_t)ct_rec_flash.day);
|
|
ct_rec->month = iot_byte_to_bcd((uint8_t)ct_rec_flash.month);
|
|
ct_rec->year = iot_byte_to_bcd((uint8_t)ct_rec_flash.year);
|
|
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void iot_sg_sta_ext_fj_get_evt_rpt_cfg(proto_645_fj_evt_rpt_cfg_t *cfg)
|
|
{
|
|
iot_sg_sta_evt_global_t *evt_glb = &p_sg_glb->desc.sta->evt;
|
|
cfg->mode = evt_glb->fj_evt_rpt_mode;
|
|
cfg->rpt_pin_type = evt_glb->fj_evt_rpt_type;
|
|
cfg->rpt_pin_en = evt_glb->fj_evt_rpt_en;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_evt_rpt_cfg(
|
|
uint8_t *addr, uint8_t *data, uint8_t len)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_evt_global_t *evt_glb = &sta_glb->evt;
|
|
proto_645_fj_evt_rpt_cfg_t *cfg_in;
|
|
iot_sg_sta_flash_fj_evt_rpt_cfg_t *cfg_flash;
|
|
iot_pkt_t *pkt, *buff_pkt = NULL;
|
|
uint8_t write_valid = 0, change_valid = 0, err_code, reason;
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*cfg_in)) {
|
|
err_code = PROTO_645_FJ_ERR_LEN;
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
cfg_in = (proto_645_fj_evt_rpt_cfg_t *)
|
|
(data + sizeof(proto_645_write_data_dest_t));
|
|
if (cfg_in->mode >= PROTO_645_FJ_EVT_RPT_MODE_MAX) {
|
|
err_code = PROTO_645_FJ_ERR_OTHER;
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
buff_pkt = iot_pkt_alloc(sizeof(*cfg_flash), IOT_SMART_GRID_MID);
|
|
if (!buff_pkt) {
|
|
err_code = PROTO_645_FJ_ERR_OTHER;
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
cfg_flash = (iot_sg_sta_flash_fj_evt_rpt_cfg_t *)iot_pkt_put(
|
|
buff_pkt, sizeof(*cfg_flash));
|
|
if (iot_sg_sta_flash_fj_evt_rpt_cfg_get(cfg_flash) != ERR_OK) {
|
|
write_valid = 1;
|
|
change_valid = 1;
|
|
} else {
|
|
/* if parameter change, write it into flash */
|
|
if (cfg_in->mode != cfg_flash->fj_evt_rpt_mode ||
|
|
cfg_in->rpt_pin_type != cfg_flash->fj_evt_rpt_type ||
|
|
cfg_in->rpt_pin_en != cfg_flash->fj_evt_rpt_en) {
|
|
write_valid = 1;
|
|
}
|
|
/* if parameter change, need to re-enable event report to update report
|
|
* parameter in the following two cases:
|
|
* 1. report mode change;
|
|
* 2. report mode not change, but current mode is fujian external mode.
|
|
*/
|
|
if (write_valid && (cfg_in->mode != cfg_flash->fj_evt_rpt_mode ||
|
|
cfg_in->mode == PROTO_645_FJ_EVT_RPT_MODE_EXT_FJ)) {
|
|
change_valid = 1;
|
|
}
|
|
}
|
|
if (write_valid) {
|
|
iot_sg_printf("%s param change mode %lu -> %lu, type %lu -> %lu, en_fj "
|
|
"%lu -> %lu\n", __FUNCTION__, cfg_flash->fj_evt_rpt_mode,
|
|
cfg_in->mode, cfg_flash->fj_evt_rpt_type, cfg_in->rpt_pin_type,
|
|
cfg_flash->fj_evt_rpt_en, cfg_in->rpt_pin_en);
|
|
cfg_flash->fj_evt_rpt_mode = cfg_in->mode;
|
|
cfg_flash->fj_evt_rpt_type = cfg_in->rpt_pin_type;
|
|
cfg_flash->fj_evt_rpt_en = cfg_in->rpt_pin_en;
|
|
if (iot_sg_sta_flash_fj_evt_rpt_cfg_save(cfg_flash)) {
|
|
err_code = PROTO_645_FJ_ERR_OTHER;
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
evt_glb->fj_evt_rpt_mode = cfg_flash->fj_evt_rpt_mode;
|
|
evt_glb->fj_evt_rpt_type = cfg_flash->fj_evt_rpt_type;
|
|
evt_glb->fj_evt_rpt_en = cfg_flash->fj_evt_rpt_en;
|
|
}
|
|
if (change_valid) {
|
|
iot_sg_sta_module_report_re_enable();
|
|
}
|
|
pkt = proto_645_2007_build_w_rsp(addr);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(err_code, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
iot_printf("%s fail reason %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
if (buff_pkt) {
|
|
iot_pkt_free(buff_pkt);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_evt_rpt_cfg(uint8_t *addr)
|
|
{
|
|
proto_645_fj_evt_rpt_cfg_t cfg = { 0 };
|
|
iot_sg_sta_ext_fj_get_evt_rpt_cfg(&cfg);
|
|
return proto_645_fj_build_qr_evt_rpt_cfg(addr, (uint8_t *)&cfg,
|
|
sizeof(cfg));
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_tm_soc(uint8_t *addr)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
proto_645_fj_mod_tm_soc_t mod_tm_soc;
|
|
|
|
mod_tm_soc.tm_soc = iot_byte_to_bcd(sta_glb->tm_soc);
|
|
return proto_645_fj_build_qr_tm_soc(addr, (uint8_t *)&mod_tm_soc,
|
|
sizeof(mod_tm_soc));
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_ct_rec(uint8_t *addr, uint8_t fn)
|
|
{
|
|
proto_645_fj_mod_ct_rec_t mod_ct_rec;
|
|
|
|
if (iot_sg_sta_ext_fj_get_latest_ct_rec(&mod_ct_rec) != ERR_OK) {
|
|
return proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
}
|
|
return proto_645_fj_build_query_ct_rec(addr, (uint8_t *)&mod_ct_rec,
|
|
sizeof(mod_ct_rec));
|
|
}
|
|
|
|
static iot_pkt_t * iot_sg_sta_ext_fj_read_ct_dur(uint8_t *addr)
|
|
{
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
proto_645_fj_mod_ct_dur_t mod_ct_dur;
|
|
|
|
iot_uint32_to_bcd(sta_glb->ct_dur, sizeof(mod_ct_dur.ct_dur),
|
|
(uint8_t *)&(mod_ct_dur.ct_dur));
|
|
return proto_645_fj_build_query_ct_dur(addr, (uint8_t *)&mod_ct_dur,
|
|
sizeof(mod_ct_dur));
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_mod_tm(uint8_t *addr, uint8_t fn)
|
|
{
|
|
proto_645_07_time_ymdhms_t mod_tm;
|
|
|
|
if (iot_sg_sta_ext_fj_get_mod_tm(&mod_tm) != ERR_OK) {
|
|
return proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr, fn);
|
|
}
|
|
return proto_645_fj_build_query_mod_tm(addr, (uint8_t *)&mod_tm,
|
|
sizeof(mod_tm));
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_task(uint8_t *addr,
|
|
uint32_t di, uint8_t is_simple_698)
|
|
{
|
|
uint8_t reason = 0, local_addr[IOT_MAC_ADDR_LEN], group;
|
|
iot_pkt_t *pkt = NULL, *pkt_buf1 = NULL, *pkt_buf2 = NULL;
|
|
uint8_t task_id = (uint8_t)(di & 0x000000ff), data_len, *data;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_cfg;
|
|
proto_645_fj_task_set_hdr_t *qr_task_info;
|
|
|
|
if (task_id > PROTO_FJ_FREEZE_TASK_ID_MAX || !task_id) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
pkt_buf1 = iot_pkt_alloc(sizeof(*task_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt_buf1) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
data = iot_pkt_put(pkt_buf1, sizeof(*task_cfg));
|
|
task_cfg = (iot_sg_sta_drv_meter_fj_task_info_t*)data;
|
|
if (iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
iot_mac_addr_cpy(local_addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(local_addr);
|
|
} else {
|
|
iot_mac_addr_cpy(local_addr, addr);
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_get(local_addr, task_id, task_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
data_len = sizeof(*qr_task_info) + task_cfg->desc_len;
|
|
pkt_buf2 = iot_pkt_alloc(data_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buf2) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
data = iot_pkt_put(pkt_buf2, data_len);
|
|
qr_task_info = (proto_645_fj_task_set_hdr_t*)data;
|
|
qr_task_info->type = task_cfg->type;
|
|
qr_task_info->cycle.value = task_cfg->value;
|
|
qr_task_info->cycle.unit = task_cfg->unit;
|
|
qr_task_info->cycle.flag = 0;
|
|
qr_task_info->cycle.rsvd = 0;
|
|
qr_task_info->delay = task_cfg->delay;
|
|
qr_task_info->save_cnt = task_cfg->save_cnt;
|
|
qr_task_info->rec_total_len = task_cfg->rec_total_len;
|
|
qr_task_info->prio_desc.prio = task_cfg->prio;
|
|
qr_task_info->prio_desc.storage_mode = task_cfg->storage_mode;
|
|
qr_task_info->prio_desc.rsvd_1 = 0;
|
|
qr_task_info->prio_desc.flag_rpt = task_cfg->flag_rpt;
|
|
qr_task_info->prio_desc.rsvd_2 = 0;
|
|
qr_task_info->exe_cnt = task_cfg->exe_cnt;
|
|
os_mem_cpy(qr_task_info->task_info_desc, task_cfg->desc,
|
|
task_cfg->desc_len);
|
|
group = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
if (is_simple_698) {
|
|
iot_data_reverse((uint8_t *)&qr_task_info->cycle,
|
|
sizeof(qr_task_info->cycle));
|
|
iot_data_reverse((uint8_t *)&qr_task_info->save_cnt,
|
|
sizeof(qr_task_info->save_cnt));
|
|
iot_data_reverse((uint8_t *)&qr_task_info->exe_cnt,
|
|
sizeof(qr_task_info->exe_cnt));
|
|
iot_sg_sta_ext_fj_task_cfg_desc_reverse(qr_task_info->type,
|
|
qr_task_info->task_info_desc, task_cfg->desc_len, 0, group);
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, data, data_len, di,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
if (pkt_buf1) {
|
|
iot_pkt_free(pkt_buf1);
|
|
}
|
|
if (pkt_buf2) {
|
|
iot_pkt_free(pkt_buf2);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_reset_cnt(uint8_t *addr)
|
|
{
|
|
proto_645_fj_module_reset_cnt_t reset_count = { 0 };
|
|
|
|
reset_count.reset_cnt = (uint16_t)(
|
|
iot_board_get_reset_count(SYSTEM_RESET_SOFT) +
|
|
iot_board_get_reset_count(SYSTEM_RESET_WDT) +
|
|
iot_board_get_reset_count(SYSTEM_RESET_PWR));
|
|
return proto_645_fj_build_qr_rst_cnt(addr, (uint8_t *)&reset_count,
|
|
sizeof(reset_count));
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_pd_cnt(uint8_t *addr)
|
|
{
|
|
proto_645_fj_pd_cnt_t pd_count = { 0 };
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
iot_sg_sta_flash_fj_pwr_rec_t *record;
|
|
pkt_buff = iot_pkt_alloc(sizeof(*record), IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
goto nack;
|
|
}
|
|
record = (iot_sg_sta_flash_fj_pwr_rec_t *)iot_pkt_put(pkt_buff,
|
|
sizeof(*record));
|
|
/* the power down count save in the latest record */
|
|
if (iot_sg_sta_flash_fj_pwr_record_get(record, 1) == ERR_OK) {
|
|
pd_count.pd_cnt = record->power_down_cnt;
|
|
}
|
|
pkt = proto_645_fj_build_qr_pd_cnt(addr, (uint8_t *)&pd_count,
|
|
sizeof(pd_count));
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_rpt_status(uint8_t *addr,
|
|
uint8_t is_simple_698)
|
|
{
|
|
uint8_t reason = 0, len, i;
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
proto_645_fj_rpt_status_t *rpt;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
if (!freeze_task) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
len = sizeof(*rpt) + IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT *
|
|
sizeof(proto_645_fj_task_rpt_status_t);
|
|
pkt_buff = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
rpt = (proto_645_fj_rpt_status_t *)iot_pkt_put(pkt_buff, sizeof(*rpt));
|
|
for (i = 0; i < IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT; i++) {
|
|
if (!freeze_task->exe_cnt_remain[i].task_id) {
|
|
continue;
|
|
}
|
|
rpt->task_status[rpt->cnt].id = freeze_task->exe_cnt_remain[i].task_id;
|
|
if (freeze_task->exe_cnt_remain[i].rpt_total_cnt >=
|
|
freeze_task->exe_cnt_remain[i].rpt_cnt) {
|
|
rpt->task_status[rpt->cnt].fail_cnt =
|
|
freeze_task->exe_cnt_remain[i].rpt_total_cnt -
|
|
freeze_task->exe_cnt_remain[i].rpt_cnt;
|
|
} else {
|
|
rpt->task_status[rpt->cnt].fail_cnt = 0 -
|
|
freeze_task->exe_cnt_remain[i].rpt_cnt +
|
|
freeze_task->exe_cnt_remain[i].rpt_total_cnt;
|
|
}
|
|
rpt->task_status[rpt->cnt].rpt_cnt =
|
|
freeze_task->exe_cnt_remain[i].rpt_cnt;
|
|
if (is_simple_698) {
|
|
iot_data_reverse((uint8_t *)&rpt->task_status[rpt->cnt].fail_cnt,
|
|
sizeof(rpt->task_status[rpt->cnt].fail_cnt));
|
|
iot_data_reverse((uint8_t *)&rpt->task_status[rpt->cnt].rpt_cnt,
|
|
sizeof(rpt->task_status[rpt->cnt].rpt_cnt));
|
|
}
|
|
rpt->cnt++;
|
|
iot_pkt_put(pkt_buff, sizeof(proto_645_fj_task_rpt_status_t));
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, iot_pkt_data(pkt_buff),
|
|
(uint8_t)iot_pkt_data_len(pkt_buff), PROTO_645_FJ_DI_RPT_STATUS,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_multi_rpt(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0, len, i;
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
proto_645_fj_multi_rpt_t *rpt;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
len = sizeof(*rpt) + comm_cfg.cnt * sizeof(proto_645_fj_multi_rpt_param_t);
|
|
pkt_buff = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
rpt = (proto_645_fj_multi_rpt_t *)iot_pkt_put(pkt_buff, len);
|
|
rpt->cnt = comm_cfg.cnt;
|
|
for (i = 0; i < rpt->cnt; i++) {
|
|
rpt->task_param[i].id = comm_cfg.task_rpt[i].id;
|
|
rpt->task_param[i].cnt = comm_cfg.task_rpt[i].cnt;
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t *)rpt, len,
|
|
PROTO_645_FJ_DI_MULTI_RPT, PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_rpt_mode(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0, rpt_mode;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
rpt_mode = comm_cfg.rpt_mode;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&rpt_mode,
|
|
sizeof(rpt_mode), PROTO_645_FJ_DI_RPT_MODE,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_pd_valid_time(uint8_t *addr)
|
|
{
|
|
proto_645_fj_pd_valid_time_t pd_valid_time = { 0 };
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
iot_sg_sta_flash_fj_pwr_rpt_cfg_t *rpt_cfg;
|
|
pkt_buff = iot_pkt_alloc(sizeof(*rpt_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
goto nack;
|
|
}
|
|
rpt_cfg = (iot_sg_sta_flash_fj_pwr_rpt_cfg_t *)iot_pkt_put(
|
|
pkt_buff, sizeof(*rpt_cfg));
|
|
if (iot_sg_sta_flash_fj_pwr_rpt_cfg_get(rpt_cfg) == ERR_OK) {
|
|
pd_valid_time.pd_valid_time = rpt_cfg->pd_valid_time;
|
|
} else {
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_fj_build_pd_valid_time(addr, pd_valid_time.pd_valid_time);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(
|
|
PROTO_645_FJ_ERR_OTHER, addr, PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_pd_rec(uint8_t *addr, uint32_t di)
|
|
{
|
|
proto_645_fj_pd_rec_t pd_record = { 0 };
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
iot_sg_sta_flash_fj_pwr_rec_t *record;
|
|
pkt_buff = iot_pkt_alloc(sizeof(*record), IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
goto nack;
|
|
}
|
|
record =(iot_sg_sta_flash_fj_pwr_rec_t *)iot_pkt_put(pkt_buff,
|
|
sizeof(*record));
|
|
if (iot_sg_sta_flash_fj_pwr_record_get(record, di & 0x0000000f) == ERR_OK) {
|
|
if (record->flag_valid_power_off) {
|
|
pd_record.power_down_time.year =
|
|
iot_byte_to_bcd(record->power_off_year);
|
|
pd_record.power_down_time.month =
|
|
iot_byte_to_bcd((uint8_t)record->power_off_month);
|
|
pd_record.power_down_time.day =
|
|
iot_byte_to_bcd((uint8_t)record->power_off_day);
|
|
pd_record.power_down_time.hour =
|
|
iot_byte_to_bcd((uint8_t)record->power_off_hour);
|
|
pd_record.power_down_time.minute =
|
|
iot_byte_to_bcd((uint8_t)record->power_off_minute);
|
|
pd_record.power_down_time.second =
|
|
iot_byte_to_bcd((uint8_t)record->power_off_second);
|
|
} else {
|
|
iot_sg_printf("%s Invalid power down record last %lu\n",
|
|
__FUNCTION__, (di & 0x0000000f));
|
|
goto nack;
|
|
}
|
|
|
|
if ( record->flag_valid_power_on) {
|
|
pd_record.power_on_time.year =
|
|
iot_byte_to_bcd(record->power_on_year);
|
|
pd_record.power_on_time.month =
|
|
iot_byte_to_bcd((uint8_t)record->power_on_month);
|
|
pd_record.power_on_time.day =
|
|
iot_byte_to_bcd((uint8_t)record->power_on_day);
|
|
pd_record.power_on_time.hour =
|
|
iot_byte_to_bcd((uint8_t)record->power_on_hour);
|
|
pd_record.power_on_time.minute =
|
|
iot_byte_to_bcd((uint8_t)record->power_on_minute);
|
|
pd_record.power_on_time.second =
|
|
iot_byte_to_bcd((uint8_t)record->power_on_second);
|
|
} else {
|
|
/**
|
|
* When the power on time is invalid,
|
|
* default 2000-1-1 0:0:0,BCD.
|
|
*/
|
|
os_mem_set(&pd_record.power_on_time, 0,
|
|
sizeof(pd_record.power_on_time));
|
|
pd_record.power_on_time.month = 1;
|
|
pd_record.power_on_time.day = 1;
|
|
}
|
|
} else {
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t *)&pd_record, sizeof(pd_record),
|
|
di, PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(
|
|
PROTO_645_FJ_ERR_OTHER, addr, PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_task(uint8_t *addr,
|
|
uint32_t di, uint8_t *data, uint8_t len, uint8_t is_simple_698)
|
|
{
|
|
uint8_t reason = 0, local_addr[IOT_MAC_ADDR_LEN], group;
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
uint8_t task_id = (uint8_t)(di & 0x000000ff), *req_data = data;
|
|
uint8_t req_len = len;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_cfg;
|
|
proto_645_fj_task_set_hdr_t *set_task_info;
|
|
|
|
group = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
if (group == PROTO_645_FJ_TASK_GROUP_UNKNOWN) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
if (!is_simple_698 && group == PROTO_645_FJ_TASK_GROUP_698) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*set_task_info)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
set_task_info = (proto_645_fj_task_set_hdr_t*)req_data;
|
|
if (is_simple_698) {
|
|
iot_data_reverse((uint8_t *)&set_task_info->cycle,
|
|
sizeof(set_task_info->cycle));
|
|
iot_data_reverse((uint8_t *)&set_task_info->save_cnt,
|
|
sizeof(set_task_info->save_cnt));
|
|
iot_data_reverse((uint8_t *)&set_task_info->exe_cnt,
|
|
sizeof(set_task_info->exe_cnt));
|
|
iot_sg_sta_ext_fj_task_cfg_desc_reverse(set_task_info->type,
|
|
set_task_info->task_info_desc, req_len - sizeof(*set_task_info),
|
|
1, group);
|
|
}
|
|
if (proto_645_fj_task_set_msg_check(set_task_info, req_len, group)) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
BUILD_BUG_ON(IOT_SG_STA_EXT_FJ_FREEZE_TASK_CFG_MAX_LEN ==
|
|
PROTO_645_FJ_FREEZE_TASK_CFG_MAX_LEN);
|
|
if (req_len - sizeof(*set_task_info) >
|
|
IOT_SG_STA_EXT_FJ_FREEZE_TASK_CFG_MAX_LEN) {
|
|
reason = 6;
|
|
goto nack;
|
|
}
|
|
pkt_buff = iot_pkt_alloc(sizeof(*task_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 7;
|
|
goto nack;
|
|
}
|
|
task_cfg = (iot_sg_sta_drv_meter_fj_task_info_t*)iot_pkt_put(pkt_buff,
|
|
sizeof(*task_cfg));
|
|
task_cfg->id = task_id;
|
|
task_cfg->type = set_task_info->type;
|
|
task_cfg->value = set_task_info->cycle.value;
|
|
task_cfg->unit = set_task_info->cycle.unit;
|
|
task_cfg->delay = set_task_info->delay;
|
|
task_cfg->save_cnt = set_task_info->save_cnt;
|
|
task_cfg->rec_total_len = set_task_info->rec_total_len;
|
|
task_cfg->prio = set_task_info->prio_desc.prio;
|
|
task_cfg->exe_cnt = set_task_info->exe_cnt;
|
|
task_cfg->storage_mode = set_task_info->prio_desc.storage_mode;
|
|
task_cfg->flag_rpt = set_task_info->prio_desc.flag_rpt;
|
|
task_cfg->desc_len = req_len - sizeof(*set_task_info);
|
|
os_mem_cpy(task_cfg->desc, set_task_info->task_info_desc,
|
|
task_cfg->desc_len);
|
|
if (iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
iot_mac_addr_cpy(local_addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(local_addr);
|
|
} else {
|
|
iot_mac_addr_cpy(local_addr, addr);
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_add(local_addr, task_id, task_cfg)) {
|
|
reason = 8;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_del_task(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, i, task_id, req_len = len, *req_data = data;
|
|
uint8_t local_addr[IOT_MAC_ADDR_LEN];
|
|
iot_pkt_t *pkt;
|
|
proto_645_fj_task_del_dl_t *del_info;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*del_info)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
del_info = (proto_645_fj_task_del_dl_t*)req_data;
|
|
if (!del_info->del_cnt) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
iot_mac_addr_cpy(local_addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(local_addr);
|
|
} else {
|
|
iot_mac_addr_cpy(local_addr, addr);
|
|
}
|
|
if (del_info->del_cnt == PROTO_645_FJ_TASK_DEL_ALL) {
|
|
iot_sg_sta_ext_freeze_task_del_all(local_addr);
|
|
} else {
|
|
if (req_len < (sizeof(*del_info) + del_info->del_cnt)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
for (i = 0; i < del_info->del_cnt; i++) {
|
|
task_id = del_info->task_num[i];
|
|
iot_sg_sta_ext_freeze_task_del(local_addr, task_id);
|
|
}
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_rec_max_len(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_rec_max_t cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
cfg.rec_max_len = comm_cfg.unit_max_len;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&cfg,
|
|
sizeof(cfg), PROTO_645_FJ_DI_SET_TASK_REC_MAX_LEN,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_rec_max_len(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, *req_data = data;
|
|
uint8_t local_addr[IOT_MAC_ADDR_LEN] = {0};
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_rec_max_t *cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*cfg)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
cfg = (proto_645_fj_task_set_rec_max_t*)req_data;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (comm_cfg.unit_max_len != cfg->rec_max_len) {
|
|
comm_cfg.unit_max_len = cfg->rec_max_len;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
if (iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
iot_mac_addr_cpy(local_addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(local_addr);
|
|
} else {
|
|
iot_mac_addr_cpy(local_addr, addr);
|
|
}
|
|
iot_sg_sta_ext_freeze_task_del_all(local_addr);
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_meter_multi_data_flag(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_meter_muilt_data_item_t cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
cfg.mult_data_item = comm_cfg.mult_data_item;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&cfg,
|
|
sizeof(cfg), PROTO_645_FJ_DI_METER_MULTI_DATA_ITEM,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_meter_multi_data_flag(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
#if IOT_SG_STA_EXT_WRITE_MULT_FLAG_EN
|
|
uint8_t reason = 0, req_len = len, *req_data = data;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_meter_muilt_data_item_t *cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*cfg)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
cfg = (proto_645_fj_task_meter_muilt_data_item_t*)req_data;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (cfg->mult_data_item > PROTO_645_FJ_METET_MULT_DATA_ITEM_MAX) {
|
|
comm_cfg.mult_data_item = PROTO_645_FJ_METET_MULT_DATA_ITEM_DEF;
|
|
} else {
|
|
comm_cfg.mult_data_item = cfg->mult_data_item;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
#else
|
|
iot_pkt_t *pkt = NULL;
|
|
(void)data;
|
|
(void)len;
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
#endif
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_rpt_max_cnt(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_rpt_max_t cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
cfg.rpt_cnt = comm_cfg.report_max_cnt;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&cfg,
|
|
sizeof(cfg), PROTO_645_FJ_DI_SET_RPT_MAX_CNT,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_random_rpt_time(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_random_rpt_t random_rpt;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
random_rpt.time = comm_cfg.random_rpt_time;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&random_rpt,
|
|
sizeof(random_rpt), PROTO_645_FJ_DI_SET_RPT_MAX_CNT,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t* iot_sg_sta_ext_fj_read_rpt_retry_count(uint8_t* addr)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_rpt_retry_t data;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t cfg;
|
|
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&cfg)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
data.retry_freeze = cfg.retry_freeze;
|
|
data.retry_nonfreeze = cfg.retry_nonfreeze;
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&data, sizeof(data),
|
|
PROTO_645_FJ_DI_SET_RPT_RETRY_COUNT, PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_multi_rpt(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, *req_data = data, rpt_cnt, i, idx = 0;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
proto_645_fj_multi_rpt_t *rpt;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*rpt)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
rpt = (proto_645_fj_multi_rpt_t *)req_data;
|
|
rpt_cnt = rpt->cnt;
|
|
if (!rpt_cnt) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (rpt_cnt > IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT) {
|
|
rpt_cnt = IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT;
|
|
}
|
|
req_len -= sizeof(*rpt);
|
|
if (req_len < sizeof(proto_645_fj_multi_rpt_param_t) * rpt_cnt) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
comm_cfg.cnt = rpt_cnt;
|
|
for (i = 0; i < rpt_cnt; i++) {
|
|
if ((rpt->task_param[i].id > PROTO_FJ_FREEZE_645_TASK_ID_MAX &&
|
|
rpt->task_param[i].id < PROTO_FJ_FREEZE_698_TASK_ID_MIN ) ||
|
|
rpt->task_param[i].id > PROTO_FJ_FREEZE_698_TASK_ID_MAX) {
|
|
continue;
|
|
}
|
|
comm_cfg.task_rpt[idx].id = rpt->task_param[i].id;
|
|
comm_cfg.task_rpt[idx].cnt = rpt->task_param[i].cnt;
|
|
idx++;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 6;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_report_mode(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, *req_data = data, src_mode;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (!req_len) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
src_mode = comm_cfg.rpt_mode;
|
|
comm_cfg.rpt_mode = !!req_data[0];
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
if (src_mode != comm_cfg.rpt_mode) {
|
|
iot_sg_ext_data_rpt_msg_merge_del_by_mode(src_mode);
|
|
iot_sg_sta_ext_fj_rpt_del_by_mode(src_mode);
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_task_restart(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t task_id[IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT] = { 0 };
|
|
uint8_t reason = 0, req_len = len, *req_data = data, task_cnt;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_freeze_task_reset_t *restart;
|
|
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_freeze_task_t *freeze_task = ext_info->freeze_task_info;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*restart)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(*restart);
|
|
restart = (proto_645_fj_freeze_task_reset_t *)req_data;
|
|
task_cnt = restart->cnt;
|
|
if (task_cnt != 0xFF) {
|
|
if (!task_cnt || task_cnt > req_len) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (task_cnt > IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT) {
|
|
task_cnt = IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT;
|
|
}
|
|
os_mem_cpy(task_id, restart->task_id, task_cnt);
|
|
} else {
|
|
task_cnt = IOT_SG_STA_EXT_FJ_FREEZE_TASK_MAX_CNT;
|
|
os_mem_cpy(task_id, freeze_task->valid_id, task_cnt);
|
|
}
|
|
|
|
if (freeze_task) {
|
|
if ((freeze_task->reset.cnt != task_cnt) ||
|
|
(os_mem_cmp(freeze_task->reset.task_id, task_id,
|
|
task_cnt) != 0)) {
|
|
freeze_task->reset.cnt = task_cnt;
|
|
freeze_task->reset.cur_idx = 0;
|
|
os_mem_cpy(freeze_task->reset.task_id, task_id,
|
|
task_cnt);
|
|
}
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_rpt_max_cnt(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, *req_data = data;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_rpt_max_t *cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*cfg)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
cfg = (proto_645_fj_task_set_rpt_max_t*)req_data;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
comm_cfg.report_max_cnt = cfg->rpt_cnt;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_random_rpt_time(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, *req_data = data;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_random_rpt_t *random_rpt;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*random_rpt)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
random_rpt = (proto_645_fj_task_set_random_rpt_t*)req_data;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
comm_cfg.random_rpt_time = random_rpt->time;
|
|
if (comm_cfg.random_rpt_time > IOT_SG_STA_EXT_TASK_RANDOM_RPT_PERCENT_MAX ||
|
|
comm_cfg.random_rpt_time < IOT_SG_STA_EXT_TASK_RANDON_RPT_PERCENT_MIN) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t* iot_sg_sta_ext_fj_write_rpt_retry_count(uint8_t* addr,
|
|
uint8_t* data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0, req_len = len, * req_data = data;
|
|
iot_pkt_t* pkt = NULL;
|
|
proto_645_fj_rpt_retry_t* cfg;
|
|
iot_sg_sta_ext_freeze_task_comm_cfg_t comm_cfg;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (req_len <= sizeof(proto_645_write_data_dest_t)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req_len -= sizeof(proto_645_write_data_dest_t);
|
|
req_data += sizeof(proto_645_write_data_dest_t);
|
|
if (req_len < sizeof(*cfg)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
cfg = (proto_645_fj_rpt_retry_t*)req_data;
|
|
if (cfg->retry_freeze > PROTO_645_FJ_FREEZE_TASK_RERPT_CNT_MAX
|
|
|| cfg->retry_nonfreeze > PROTO_645_FJ_NON_FREEZE_TASK_RERPT_CNT_MAX) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_get(&comm_cfg)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
comm_cfg.retry_freeze = cfg->retry_freeze;
|
|
comm_cfg.retry_nonfreeze = cfg->retry_nonfreeze;
|
|
if (iot_sg_sta_ext_freeze_task_comm_cfg_save(&comm_cfg)) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_task_state(uint8_t *addr)
|
|
{
|
|
uint8_t reason = 0, len, i;
|
|
iot_pkt_t *pkt = NULL, *pkt_buf = NULL;
|
|
iot_sg_sta_ext_fj_task_id_t task = {0};
|
|
proto_645_fj_task_qr_state_t *task_state;
|
|
|
|
iot_sg_sta_ext_freeze_task_id_get(&task);
|
|
len = sizeof(*task_state) + task.task_cnt;
|
|
pkt_buf = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
|
|
if (pkt_buf == NULL) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
task_state = (proto_645_fj_task_qr_state_t*)iot_pkt_put(pkt_buf, len);
|
|
task_state->task_cnt = task.task_cnt;
|
|
for (i = 0; i < task_state->task_cnt; i++) {
|
|
task_state->task_num[i] = task.task_list[i];
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)task_state,
|
|
len, PROTO_645_FJ_DI_QR_TASK_STATE,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_stop_dur(uint8_t *addr,
|
|
uint8_t is_simple_698)
|
|
{
|
|
uint16_t curr_dur;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_task_stop_dur_t resp;
|
|
|
|
curr_dur = iot_sg_sta_ext_freeze_stop_dur_get();
|
|
if (is_simple_698) {
|
|
iot_uint16_to_bytes(curr_dur, (uint8_t *)&resp.stop_dur, 1);
|
|
} else {
|
|
iot_uint32_to_bcd(curr_dur, sizeof(resp.stop_dur), resp.stop_dur);
|
|
}
|
|
pkt = proto_645_fj_build_msg(addr, (uint8_t*)&resp,
|
|
sizeof(resp), PROTO_645_FJ_DI_SET_TASK_STOP_DUR,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_stop_dur(uint8_t *addr, uint8_t *data,
|
|
uint8_t len, uint8_t is_simple_698)
|
|
{
|
|
uint8_t reason = 0;
|
|
uint32_t stop_dur, curr_stop_dur;
|
|
iot_pkt_t *pkt = NULL;
|
|
proto_645_fj_task_set_task_stop_dur_t *req;
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
if (len < (sizeof(proto_645_write_data_dest_t) + sizeof(*req))) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
req = (proto_645_fj_task_set_task_stop_dur_t*)(data +
|
|
sizeof(proto_645_write_data_dest_t));
|
|
if (is_simple_698) {
|
|
stop_dur = iot_bytes_to_uint16((uint8_t *)&req->stop_dur, 1);
|
|
} else {
|
|
if (!iot_bcd_to_uint32(req->stop_dur, sizeof(req->stop_dur),
|
|
0, &stop_dur)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
}
|
|
curr_stop_dur = iot_sg_sta_ext_freeze_stop_dur_get();
|
|
if (stop_dur > PROTO_645_FJ_TASK_STOP_DUR_MAX || stop_dur < curr_stop_dur) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
if (iot_sg_sta_ext_freeze_stop_dur_set((uint16_t)stop_dur)) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason %lu\n", __FUNCTION__, reason);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_mod_work_v(uint8_t *addr)
|
|
{
|
|
uint8_t v[PROTO_645_V_LEN];
|
|
iot_pkt_t *pkt;
|
|
v[0] = 0x20;
|
|
v[1] = 0x01;
|
|
pkt = proto_645_fj_build_msg(addr, v, sizeof(v),
|
|
PROTO_645_FJ_DI_QR_MOD_WORK_V, PROTO_645_2007_FN_READ_DATA);
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_handle_send_file(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
iot_pkt_t *pkt_645 = NULL;
|
|
uint8_t bcast = 0;
|
|
proto_645_fj_send_file_dl_t *req;
|
|
uint32_t ack_no;
|
|
|
|
if (!addr) {
|
|
goto err;
|
|
}
|
|
|
|
if (iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
bcast = 1;
|
|
}
|
|
|
|
if (!data || len <= PROTO_645_2007_DI_LEN) {
|
|
goto err;
|
|
}
|
|
if (len < (sizeof(*req) + PROTO_645_2007_DI_LEN)) {
|
|
goto err;
|
|
}
|
|
|
|
proto_645_sub33_handle(data, len);
|
|
req = (proto_645_fj_send_file_dl_t*)(data + PROTO_645_2007_DI_LEN);
|
|
ack_no = req->seg_index;
|
|
|
|
iot_sg_printf("sg_upgrade: action = %d, seg_len = %d, file_cmd = %d, "
|
|
"is_last = %d, seg_index/total_set_cnt = %d/%d. sn = %d\n",
|
|
req->action, req->cur_seg_len, req->file_cmd,
|
|
req->is_last_seg, req->seg_index, req->total_seg_cnt, 0);
|
|
|
|
switch (req->action) {
|
|
case PROTO_645_FJ_UPGRADE_CLEAR_FILE:
|
|
{
|
|
iot_sg_sta_upgrade_handle_file_segment(
|
|
IOT_SG_STA_SEG_UPGRADE_ACTION_STOP,
|
|
IOT_SG_STA_UPGRADE_SESSION_TYPE_645, (uint16_t)req->seg_index,
|
|
req->total_seg_cnt, NULL, 0, 1, PROTO_645_FJ_UPGRADE_WINDOWS * 60);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_UPGRADE_CCO_STA_MODULE:
|
|
case PROTO_645_FJ_UPGRADE_LOCAL_MODULE:
|
|
{
|
|
/* reject invalid data packet. */
|
|
ack_no = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_UPGRADE_STA_MODULE:
|
|
{
|
|
if (iot_sg_sta_upgrade_handle_file_segment(
|
|
IOT_SG_STA_SEG_UPGRADE_ACTION_UPGRADE,
|
|
IOT_SG_STA_UPGRADE_SESSION_TYPE_645, (uint16_t)req->seg_index,
|
|
req->total_seg_cnt, req->data, req->cur_seg_len, 1,
|
|
PROTO_645_FJ_UPGRADE_WINDOWS * 60) != ERR_OK) {
|
|
ack_no = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ack_no = PROTO_645_FJ_INVALID_SEG_INDEX;
|
|
break;
|
|
}
|
|
|
|
if (!bcast) {
|
|
pkt_645 = proto_645_fj_build_upgrade_send_file_ack(addr, ack_no);
|
|
}
|
|
goto out;
|
|
|
|
err:
|
|
if (!bcast) {
|
|
pkt_645 = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_LEN, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
}
|
|
out:
|
|
return pkt_645;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_handle_query_file(uint8_t *addr)
|
|
{
|
|
iot_pkt_t *pkt_645 = NULL;
|
|
iot_pkt_t *bitmap_pkt = NULL, *allbitmap_pkt = NULL;
|
|
iot_sg_sta_upgrade_info_t *upgrade_info =
|
|
&p_sg_glb->desc.sta->upgrade_info;
|
|
uint8_t *bitmap_data = NULL, *allbitmap;
|
|
uint32_t bitmap_size;
|
|
uint32_t i, len;
|
|
uint8_t array_index = 0;
|
|
uint8_t done = 0;
|
|
|
|
if (!addr || iot_mac_addr_cmp(addr, proto_645_bcast_addr)) {
|
|
goto out;
|
|
}
|
|
|
|
bitmap_pkt = iot_pkt_alloc(PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN,
|
|
IOT_SMART_GRID_MID);
|
|
if (!bitmap_pkt) {
|
|
goto out;
|
|
}
|
|
bitmap_data = iot_pkt_data(bitmap_pkt);
|
|
if ((upgrade_info->state == IOT_SG_STA_UPGRADE_ST_IDLE) ||
|
|
(upgrade_info->session_type != IOT_SG_STA_UPGRADE_SESSION_TYPE_645)) {
|
|
/* not recv upgrade data */
|
|
done = 0;
|
|
goto done;
|
|
}
|
|
|
|
if (upgrade_info->skip) {
|
|
/* recv done */
|
|
done = 1;
|
|
goto done;
|
|
}
|
|
|
|
allbitmap_pkt = iot_sg_sta_get_recv_bitmap(0, IOT_SG_STA_QUERY_ALL_BLOCK);
|
|
if (!allbitmap_pkt) {
|
|
/* not recv upgrade data */
|
|
done = 0;
|
|
goto done;
|
|
}
|
|
allbitmap = iot_pkt_data(allbitmap_pkt);
|
|
bitmap_size = iot_pkt_data_len(allbitmap_pkt);
|
|
|
|
if (iot_bitmap_cbs(allbitmap, (uint16_t)bitmap_size) >=
|
|
upgrade_info->block_cnt) {
|
|
/* recv done */
|
|
done = 1;
|
|
goto done;
|
|
}
|
|
|
|
for (i = 0, array_index = 0; i < bitmap_size; i += len, array_index++) {
|
|
if (i + PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN <= bitmap_size) {
|
|
len = PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN;
|
|
} else {
|
|
len = bitmap_size - i;
|
|
os_mem_set(bitmap_data, 0,
|
|
PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN - len);
|
|
}
|
|
if ((len << 3) != iot_bitmap_cbs(allbitmap + i, (uint16_t)len)) {
|
|
os_mem_cpy(bitmap_data, allbitmap + i, len);
|
|
break;
|
|
}
|
|
}
|
|
iot_bitmap_reverse(bitmap_data, PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
goto out;
|
|
done:
|
|
if (done == 0) {
|
|
os_mem_set(bitmap_data, 0xFF, PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
} else {
|
|
os_mem_set(bitmap_data, 0, PROTO_645_FJ_FILE_SEGMENT_ARRAY_LEN);
|
|
}
|
|
out:
|
|
if (bitmap_pkt) {
|
|
pkt_645 = proto_645_fj_build_upgrade_query_file_ack(addr, array_index,
|
|
bitmap_data);
|
|
iot_pkt_free(bitmap_pkt);
|
|
}
|
|
if (allbitmap_pkt) {
|
|
iot_pkt_free(allbitmap_pkt);
|
|
}
|
|
iot_sg_printf("sg_upgrade: fj645 query bitmap, done: %d, array_index: %d\n",
|
|
done, array_index);
|
|
return pkt_645;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_write_pd_valid_time(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t reason = 0;
|
|
iot_sg_sta_evt_global_t *evt_glb = &p_sg_glb->desc.sta->evt;
|
|
iot_pkt_t *pkt, *pkt_buff = NULL;
|
|
proto_645_fj_pd_valid_time_t *pd_valid_time;
|
|
iot_sg_sta_flash_fj_pwr_rpt_cfg_t *rpt_cfg;
|
|
uint8_t write_valid = 0;
|
|
if (len < sizeof(proto_645_write_data_dest_t) + sizeof(*pd_valid_time)) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
pd_valid_time = (proto_645_fj_pd_valid_time_t *)(data +
|
|
sizeof(proto_645_write_data_dest_t));
|
|
if (pd_valid_time->pd_valid_time < IOT_SG_STA_FJ_PD_EVT_VALID_TIME_MIN ||
|
|
pd_valid_time->pd_valid_time > IOT_SG_STA_FJ_PD_EVT_VALID_TIME_MAX) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
pkt_buff = iot_pkt_alloc(sizeof(*rpt_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
rpt_cfg = (iot_sg_sta_flash_fj_pwr_rpt_cfg_t *)iot_pkt_put(pkt_buff,
|
|
sizeof(*rpt_cfg));
|
|
if (iot_sg_sta_flash_fj_pwr_rpt_cfg_get(rpt_cfg) != ERR_OK) {
|
|
write_valid = 1;
|
|
} else if (rpt_cfg->pd_valid_time != pd_valid_time->pd_valid_time) {
|
|
write_valid = 1;
|
|
}
|
|
if (write_valid) {
|
|
iot_sg_printf("%s pd valid time %lus->%lus\n", __FUNCTION__,
|
|
rpt_cfg->pd_valid_time, pd_valid_time->pd_valid_time);
|
|
rpt_cfg->pd_valid_time = pd_valid_time->pd_valid_time;
|
|
if (iot_sg_sta_flash_fj_pwr_rpt_cfg_save(rpt_cfg) != ERR_OK) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
evt_glb->fj_pd_valid_time = pd_valid_time->pd_valid_time;
|
|
}
|
|
pkt = proto_645_2007_build_ack_msg(addr, PROTO_645_2007_FN_WRITE_DATA);
|
|
goto out;
|
|
nack:
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
if (reason) {
|
|
iot_sg_printf("%s resp nack, reason\n", __FUNCTION__, reason);
|
|
}
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_chg_flag_get(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_unit_t *cur_data,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_data)
|
|
{
|
|
uint32_t chg_di;
|
|
uint8_t chg_flag = 0, reason = 0;
|
|
iot_pkt_t *cfg_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *last_unit_data, *cur_unit_data;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
|
|
if (!addr || !cur_data || !last_data) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (cur_data->valid_len < sizeof(*cur_unit_data)) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
cur_unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)cur_data->uint_data;
|
|
if (cur_data->valid_len - sizeof(*cur_unit_data) < cur_unit_data->len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (cur_unit_data->len <= PROTO_645_2007_DI_LEN) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
chg_di = proto_645_2007_byte_to_di(cur_unit_data->data);
|
|
last_unit_data = iot_sg_ext_freeze_di_unit_data_get(chg_di,
|
|
last_data->uint_data, last_data->valid_len, last_data->resp_data_cnt);
|
|
if (!last_unit_data) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (last_unit_data->len <= PROTO_645_2007_DI_LEN) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
cfg_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!cfg_pkt) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(cfg_pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg) != ERR_OK) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
chg_flag = iot_sg_ext_freeze_chg_rpt_check(cfg,
|
|
cur_unit_data->data + PROTO_645_2007_DI_LEN,
|
|
cur_unit_data->len - PROTO_645_2007_DI_LEN,
|
|
last_unit_data->data + PROTO_645_2007_DI_LEN,
|
|
last_unit_data->len - PROTO_645_2007_DI_LEN, 0,
|
|
iot_sg_sta_ext_fj_task_group_get(task_id));
|
|
out:
|
|
if (reason) {
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
}
|
|
if (cfg_pkt) {
|
|
iot_pkt_free(cfg_pkt);
|
|
}
|
|
return chg_flag;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_chg_data_resp_by_time(uint8_t *addr,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data, uint16_t max_len,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
uint8_t msg_type, uint8_t task_id)
|
|
{
|
|
uint8_t data_len = 0, reason = 0, i;
|
|
uint16_t idx = 0, unit_len = 0;
|
|
uint32_t ret, task_cycle;
|
|
iot_pkt_t *start_pkt = NULL, *end_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *start_task_unit, *end_task_unit;
|
|
iot_time_tm_t end_tm = { 0 }, start_tm = { 0 };
|
|
|
|
if (!resp_data || !cache_hdr) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
start_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!start_pkt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
start_task_unit = (iot_sg_sta_drv_meter_fj_task_unit_t *)
|
|
iot_pkt_put(start_pkt, unit_len);
|
|
end_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!end_pkt) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
end_task_unit =
|
|
(iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(end_pkt, unit_len);
|
|
start_tm = cache_hdr->start_tm;
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &idx, &start_tm,
|
|
(uint8_t *)start_task_unit, unit_len, task_id, 0,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
start_tm.tm_year = (uint16_t)(start_task_unit->uint_time.year + 2000);
|
|
start_tm.tm_mon = (uint8_t)start_task_unit->uint_time.month;
|
|
start_tm.tm_mday = (uint8_t)start_task_unit->uint_time.day;
|
|
start_tm.tm_hour = (uint8_t)start_task_unit->uint_time.hour;
|
|
start_tm.tm_min = (uint8_t)start_task_unit->uint_time.minute;
|
|
start_tm.tm_sec = (uint8_t)start_task_unit->uint_time.second;
|
|
task_cycle = proto_645_fj_task_cycle_to_sec(&cache_hdr->cycle);
|
|
for (i = 0; i < IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT; i++) {
|
|
if (idx == IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT - 1) {
|
|
idx = 0;
|
|
} else {
|
|
idx++;
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, idx,
|
|
(uint8_t *)end_task_unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
end_tm.tm_year = (uint16_t)(end_task_unit->uint_time.year + 2000);
|
|
end_tm.tm_mon = (uint8_t)end_task_unit->uint_time.month;
|
|
end_tm.tm_mday = (uint8_t)end_task_unit->uint_time.day;
|
|
end_tm.tm_hour = (uint8_t)end_task_unit->uint_time.hour;
|
|
end_tm.tm_min = (uint8_t)end_task_unit->uint_time.minute;
|
|
end_tm.tm_sec = (uint8_t)end_task_unit->uint_time.second;
|
|
if (iot_rtc_delta_calc(&start_tm, &end_tm) == task_cycle &&
|
|
iot_sg_sta_ext_fj_task_chg_flag_get(addr, task_id, end_task_unit,
|
|
start_task_unit)) {
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_to_resp(end_task_unit,
|
|
start_task_unit, resp_data, max_len, cache_hdr->type,
|
|
cache_hdr->cycle, cache_hdr, msg_type, task_id);
|
|
goto out;
|
|
}
|
|
os_mem_cpy(&start_tm, &end_tm, sizeof(end_tm));
|
|
os_mem_cpy(start_task_unit, end_task_unit, sizeof(*end_task_unit));
|
|
}
|
|
out:
|
|
if (start_pkt) {
|
|
iot_pkt_free(start_pkt);
|
|
}
|
|
if (end_pkt) {
|
|
iot_pkt_free(end_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
}
|
|
return data_len;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_task_chg_data_resp_by_idx(uint8_t *addr,
|
|
uint16_t index_ptr, iot_sg_sta_drv_meter_fj_task_unit_t *cur_task_unit,
|
|
uint8_t task_id, iot_sg_sta_drv_meter_fj_task_info_t *task_info,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data, uint8_t max_len,
|
|
uint8_t idx, uint8_t msg_type)
|
|
{
|
|
uint8_t data_len = 0, reason = 0;
|
|
uint16_t i, flash_idx = index_ptr, chg_idx = 0, old_start_idx = 0;
|
|
uint16_t unit_len = 0;
|
|
uint32_t ret, task_cycle;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *last_task_unit;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
iot_time_tm_t end_time = { 0 }, start_time = { 0 };
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
|
|
if (!cur_task_unit) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
task_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
last_task_unit =
|
|
(iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(task_pkt, unit_len);
|
|
end_time.tm_year = (uint16_t)(cur_task_unit->uint_time.year + 2000);
|
|
end_time.tm_mon = (uint8_t)cur_task_unit->uint_time.month;
|
|
end_time.tm_mday = (uint8_t)cur_task_unit->uint_time.day;
|
|
end_time.tm_hour = (uint8_t)cur_task_unit->uint_time.hour;
|
|
end_time.tm_min = (uint8_t)cur_task_unit->uint_time.minute;
|
|
end_time.tm_sec = (uint8_t)cur_task_unit->uint_time.second;
|
|
cycle.value = task_info->value;
|
|
cycle.unit = task_info->unit;
|
|
task_cycle = proto_645_fj_task_cycle_to_sec(&cycle);
|
|
for (i = 0; i < IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT; i++) {
|
|
if (flash_idx == 0) {
|
|
flash_idx = IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT - 1;
|
|
} else {
|
|
flash_idx--;
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, flash_idx,
|
|
(uint8_t *)last_task_unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
break;
|
|
}
|
|
start_time.tm_year = (uint16_t)(last_task_unit->uint_time.year + 2000);
|
|
start_time.tm_mon = (uint8_t)last_task_unit->uint_time.month;
|
|
start_time.tm_mday = (uint8_t)last_task_unit->uint_time.day;
|
|
start_time.tm_hour = (uint8_t)last_task_unit->uint_time.hour;
|
|
start_time.tm_min = (uint8_t)last_task_unit->uint_time.minute;
|
|
start_time.tm_sec = (uint8_t)last_task_unit->uint_time.second;
|
|
if (iot_rtc_delta_calc(&start_time, &end_time) == task_cycle &&
|
|
iot_sg_sta_ext_fj_task_chg_flag_get(addr, task_id, cur_task_unit,
|
|
last_task_unit)) {
|
|
chg_idx++;
|
|
old_start_idx = flash_idx;
|
|
if (chg_idx >= idx) {
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_to_resp(cur_task_unit,
|
|
last_task_unit, resp_data, max_len, task_info->type, cycle,
|
|
NULL, msg_type, task_id);
|
|
goto out;
|
|
}
|
|
}
|
|
os_mem_cpy(&end_time, &start_time, sizeof(start_time));
|
|
os_mem_cpy(cur_task_unit, last_task_unit, sizeof(*cur_task_unit));
|
|
}
|
|
if (chg_idx) {
|
|
flash_idx = old_start_idx;
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, flash_idx,
|
|
(uint8_t *)last_task_unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
if (flash_idx >= IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT - 1) {
|
|
flash_idx = 0;
|
|
} else {
|
|
flash_idx++;
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, flash_idx,
|
|
(uint8_t *)cur_task_unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_to_resp(cur_task_unit,
|
|
last_task_unit, resp_data, max_len, task_info->type, cycle, NULL,
|
|
msg_type, task_id);
|
|
} else {
|
|
reason = 5;
|
|
}
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
}
|
|
return data_len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_freeze_data_by_idx(uint8_t *addr,
|
|
uint32_t di, uint8_t idx, uint8_t msg_type)
|
|
{
|
|
uint32_t ret;
|
|
uint16_t latest_idx, flash_idx, task_unit_len = 0;
|
|
uint8_t task_id, data_len = 0, max_len;
|
|
uint8_t result = PROTO_645_FJ_READ_RESP_DATA_OK;
|
|
iot_pkt_t *resp_pkt = NULL, *pkt = NULL, *task_pkt = NULL, *cfg_pkt;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *task_info;
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp_data;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit;
|
|
iot_time_tm_t tm = { 0 };
|
|
|
|
task_id = (uint8_t)(di & 0x000000FF);
|
|
cfg_pkt = iot_pkt_alloc(sizeof(*task_info), IOT_SMART_GRID_MID);
|
|
if (!cfg_pkt) {
|
|
goto out;
|
|
}
|
|
task_info = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(cfg_pkt, sizeof(*task_info));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, task_info)
|
|
!= ERR_OK) {
|
|
goto out;
|
|
}
|
|
max_len = PROTO_645_FJ_RESP_DATA_MAX_LEN - PROTO_645_2007_DI_LEN;
|
|
pkt = iot_pkt_alloc(max_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
resp_data = (proto_645_fj_task_data_query_hdr_ul_t *)
|
|
iot_pkt_put(pkt, max_len);
|
|
if (!idx) {
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &task_unit_len, NULL);
|
|
task_pkt = iot_pkt_alloc(task_unit_len, IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto out;
|
|
}
|
|
task_unit = (iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(task_pkt,
|
|
task_unit_len);
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_latest(addr, &latest_idx,
|
|
(uint8_t *)task_unit, task_unit_len, task_id,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
goto build;
|
|
}
|
|
if (task_info->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_resp_by_idx(addr, latest_idx,
|
|
task_unit, task_id, task_info, resp_data, max_len, idx, msg_type);
|
|
if (!data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
goto build;
|
|
}
|
|
/* read index >= 1 */
|
|
if (latest_idx >= idx) {
|
|
flash_idx = latest_idx - idx + 1;
|
|
} else {
|
|
flash_idx = IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT -
|
|
(idx - latest_idx) + 1;
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, flash_idx,
|
|
(uint8_t *)task_unit, task_unit_len, task_id);
|
|
if (ret == ERR_OK) {
|
|
data_len = iot_sg_sta_ext_fj_task_single_data_to_resp(task_unit,
|
|
resp_data, max_len, task_info, msg_type, task_id);
|
|
if (!data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
} else {
|
|
tm.tm_year = 1970;
|
|
tm.tm_mon = 1;
|
|
tm.tm_mday = 1;
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &flash_idx,
|
|
&tm, (uint8_t *)task_unit, task_unit_len, task_id, 0,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
goto build;
|
|
}
|
|
data_len = iot_sg_sta_ext_fj_task_single_data_to_resp(task_unit,
|
|
resp_data, max_len, task_info, msg_type, task_id);
|
|
if (!data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
}
|
|
build:
|
|
if (result == PROTO_645_FJ_READ_RESP_DATA_INVALID) {
|
|
resp_data->type = task_info->type;
|
|
resp_data->result = result;
|
|
data_len = sizeof(resp_data->result) + sizeof(resp_data->type);
|
|
}
|
|
resp_pkt = proto_645_fj_build_msg(addr, (uint8_t *)resp_data, data_len,
|
|
di, PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
if (cfg_pkt) {
|
|
iot_pkt_free(cfg_pkt);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_freeze_unit_data_to_cache(
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
iot_sg_sta_ext_freeze_resp_cache_data_t *cache_data, uint16_t cache_len,
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_data, uint16_t task_data_idx)
|
|
{
|
|
uint8_t i, reason = 0;
|
|
uint16_t len = 0;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *local_unit_data, *cache_unit_data;
|
|
|
|
if (!cache_hdr || !cache_data || !cache_len || !task_data) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
if (sizeof(*cache_data) > cache_len) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
cache_len -= sizeof(*cache_data);
|
|
for (i = 0; i < cache_hdr->di_cnt; i++) {
|
|
local_unit_data = iot_sg_ext_freeze_di_unit_data_get(
|
|
cache_hdr->di_info[i].di, task_data->uint_data, task_data->valid_len,
|
|
task_data->resp_data_cnt);
|
|
if (!local_unit_data) {
|
|
continue;
|
|
}
|
|
if (local_unit_data->len + sizeof(*cache_unit_data) > cache_len) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
cache_unit_data = (iot_sg_sta_drv_meter_fj_unit_data_t *)
|
|
(cache_data->unit_data + len);
|
|
cache_unit_data->len = local_unit_data->len;
|
|
os_mem_cpy(cache_unit_data->data, local_unit_data->data,
|
|
local_unit_data->len);
|
|
cache_hdr->di_info[i].resp_len = local_unit_data->len;
|
|
if (local_unit_data->len > PROTO_645_2007_DI_LEN) {
|
|
cache_hdr->di_info[i].resp_first_byte =
|
|
local_unit_data->data[PROTO_645_2007_DI_LEN];
|
|
} else {
|
|
cache_hdr->di_info[i].resp_first_byte = 0xff;
|
|
}
|
|
cache_data->di_cnt++;
|
|
cache_len -= local_unit_data->len + sizeof(*cache_unit_data);
|
|
len += local_unit_data->len + sizeof(*cache_unit_data);
|
|
}
|
|
out:
|
|
if (len) {
|
|
cache_data->rec_time = task_data->uint_time;
|
|
cache_data->unit_len = len;
|
|
cache_hdr->rsp_cnt++;
|
|
cache_hdr->cache_end_tm.tm_year =
|
|
(uint16_t)(task_data->uint_time.year + 2000);
|
|
cache_hdr->cache_end_tm.tm_mon = (uint8_t)task_data->uint_time.month;
|
|
cache_hdr->cache_end_tm.tm_mday = (uint8_t)task_data->uint_time.day;
|
|
cache_hdr->cache_end_tm.tm_hour = (uint8_t)task_data->uint_time.hour;
|
|
cache_hdr->cache_end_tm.tm_min = (uint8_t)task_data->uint_time.minute;
|
|
cache_hdr->cache_end_tm.tm_sec = task_data->uint_time.second;
|
|
cache_hdr->cache_end_tm_idx = task_data_idx;
|
|
len += sizeof(*cache_data);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
}
|
|
return len;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_freeze_flash_data_to_cache(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
uint16_t cache_max_len)
|
|
{
|
|
uint8_t i, reason = 0, first_unit = 0;
|
|
uint16_t len = cache_max_len, idx = 0, cache_len, unit_len;
|
|
uint32_t ret;
|
|
int64_t delta;
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit;
|
|
iot_sg_sta_ext_freeze_resp_cache_data_t *cache_data;
|
|
proto_645_fj_task_cycle_t cycle = { 0 };
|
|
iot_pkt_t *task_pkt = NULL;
|
|
iot_time_tm_t unit_tm = { 0 }, end_tm = { 0 }, start_tm = { 0 };
|
|
|
|
if (!cache_hdr || !cache_max_len || !addr) {
|
|
goto out;
|
|
}
|
|
if (!cache_hdr->query_cnt) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
task_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
task_unit =
|
|
(iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(task_pkt, unit_len);
|
|
start_tm = cache_hdr->start_tm;
|
|
ret = iot_sg_sta_flash_ct_unit_data_find_by_time(addr, &idx, &start_tm,
|
|
(uint8_t *)task_unit, unit_len, task_id, 0,
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK);
|
|
if (ret != ERR_OK) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
unit_tm.tm_year = (uint16_t)(task_unit->uint_time.year + 2000);
|
|
unit_tm.tm_mon = (uint8_t)task_unit->uint_time.month;
|
|
unit_tm.tm_mday = (uint8_t)task_unit->uint_time.day;
|
|
unit_tm.tm_hour = (uint8_t)task_unit->uint_time.hour;
|
|
unit_tm.tm_min = (uint8_t)task_unit->uint_time.minute;
|
|
unit_tm.tm_sec = (uint8_t)task_unit->uint_time.second;
|
|
cycle.value = cache_hdr->cycle.value;
|
|
cycle.unit = cache_hdr->cycle.unit;
|
|
delta = proto_645_fj_task_cycle_to_sec(&cycle) * (cache_hdr->query_cnt - 1);
|
|
end_tm = cache_hdr->start_tm;
|
|
iot_rtc_delta_add(delta, &end_tm);
|
|
if (cache_hdr->type == PROTO_645_FJ_TASK_TYPE_FREEZE &&
|
|
iot_rtc_delta_calc(&end_tm, &unit_tm) > 0) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
cache_data = (iot_sg_sta_ext_freeze_resp_cache_data_t *)
|
|
(cache_hdr->di_info + cache_hdr->di_cnt);
|
|
cache_len = iot_sg_sta_ext_fj_freeze_unit_data_to_cache(cache_hdr,
|
|
cache_data, len, task_unit, idx);
|
|
if (len < cache_len) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (!first_unit && cache_len) {
|
|
cache_hdr->storage_times = task_unit->storage_times;
|
|
first_unit = 1;
|
|
}
|
|
len -= cache_len;
|
|
cache_data = (iot_sg_sta_ext_freeze_resp_cache_data_t *)(
|
|
(uint8_t *)cache_data + cache_len);
|
|
for (i = 0; i < cache_hdr->query_cnt - 1; i++) {
|
|
if (len < sizeof(*cache_data)) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
idx++;
|
|
if (idx >= IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT) {
|
|
idx = 0;
|
|
}
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, idx, (uint8_t *)task_unit,
|
|
unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
continue;
|
|
}
|
|
unit_tm.tm_year = (uint16_t)(task_unit->uint_time.year + 2000);
|
|
unit_tm.tm_mon = (uint8_t)task_unit->uint_time.month;
|
|
unit_tm.tm_mday = (uint8_t)task_unit->uint_time.day;
|
|
unit_tm.tm_hour = (uint8_t)task_unit->uint_time.hour;
|
|
unit_tm.tm_min = (uint8_t)task_unit->uint_time.minute;
|
|
unit_tm.tm_sec = (uint8_t)task_unit->uint_time.second;
|
|
if (iot_rtc_delta_calc(&end_tm, &unit_tm) > 0) {
|
|
reason = 7;
|
|
goto out;
|
|
}
|
|
cache_len = iot_sg_sta_ext_fj_freeze_unit_data_to_cache(cache_hdr,
|
|
cache_data, len, task_unit, idx);
|
|
if (len < cache_len) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
if (!first_unit && cache_len) {
|
|
first_unit = 1;
|
|
cache_hdr->storage_times = task_unit->storage_times;
|
|
}
|
|
len -= cache_len;
|
|
cache_data = (iot_sg_sta_ext_freeze_resp_cache_data_t *)(
|
|
(uint8_t *)cache_data + cache_len);
|
|
}
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n", __FUNCTION__, reason);
|
|
}
|
|
return cache_max_len - len;
|
|
}
|
|
|
|
static iot_sg_sta_drv_meter_fj_unit_data_t *iot_sg_sta_ext_fj_cache_di_data_find(
|
|
iot_sg_sta_ext_freeze_resp_cache_data_t *cache_data, uint16_t cache_len,
|
|
uint8_t cache_cnt, uint32_t di, iot_time_tm_t *tm, uint8_t task_type)
|
|
{
|
|
uint8_t i;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data = NULL;
|
|
iot_time_tm_t rec_tm;
|
|
|
|
if (!cache_data || !cache_len || !cache_cnt || !tm) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < cache_cnt; i++) {
|
|
if (cache_len < sizeof(*cache_data)) {
|
|
goto out;
|
|
}
|
|
cache_len -= sizeof(*cache_data);
|
|
if (cache_len < cache_data->unit_len) {
|
|
goto out;
|
|
}
|
|
cache_len -= cache_data->unit_len;
|
|
rec_tm.tm_year = (uint16_t)(cache_data->rec_time.year + 2000);
|
|
rec_tm.tm_mon = (uint8_t)cache_data->rec_time.month;
|
|
rec_tm.tm_mday = (uint8_t)cache_data->rec_time.day;
|
|
rec_tm.tm_hour = (uint8_t)cache_data->rec_time.hour;
|
|
rec_tm.tm_min = (uint8_t)cache_data->rec_time.minute;
|
|
rec_tm.tm_sec = cache_data->rec_time.second;
|
|
if (!iot_rtc_delta_calc(&rec_tm, tm) ||
|
|
task_type != PROTO_645_FJ_TASK_TYPE_FREEZE) {
|
|
unit_data = iot_sg_ext_freeze_di_unit_data_get(di,
|
|
cache_data->unit_data, cache_data->unit_len, cache_data->di_cnt);
|
|
if (unit_data) {
|
|
goto out;
|
|
}
|
|
}
|
|
cache_data = (iot_sg_sta_ext_freeze_resp_cache_data_t *)
|
|
(cache_data->unit_data + cache_data->unit_len);
|
|
}
|
|
out:
|
|
return unit_data;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_fj_freeze_resp_overflow_check(uint8_t *addr,
|
|
uint8_t task_id, iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
iot_time_tm_t *last_tm, int64_t delta, uint16_t fill_time_cnt)
|
|
{
|
|
iot_sg_sta_drv_meter_fj_task_unit_t *task_unit;
|
|
uint32_t ret = ERR_FAIL;
|
|
uint16_t flash_idx = cache_hdr->cache_end_tm_idx, unit_len = 0;
|
|
iot_pkt_t *task_pkt = NULL;
|
|
iot_time_tm_t tm, end_tm;
|
|
|
|
if (fill_time_cnt >= cache_hdr->query_cnt) {
|
|
goto out;
|
|
}
|
|
if (flash_idx >= IOT_SG_STA_METER_FJ_FRZ_TASK_MARK_MAX_CNT - 1) {
|
|
flash_idx = 0;
|
|
} else {
|
|
flash_idx++;
|
|
}
|
|
iot_sg_sta_flash_unit_get_data_info(
|
|
IOT_SG_STA_METER_DATA_TYPE_FJ_TASK, &unit_len, NULL);
|
|
task_pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
|
|
if (!task_pkt) {
|
|
goto out;
|
|
}
|
|
task_unit =
|
|
(iot_sg_sta_drv_meter_fj_task_unit_t *)iot_pkt_put(task_pkt, unit_len);
|
|
ret = iot_sg_sta_flash_ct_unit_data_read(addr, flash_idx,
|
|
(uint8_t *)task_unit, unit_len, task_id);
|
|
if (ret != ERR_OK) {
|
|
goto out;
|
|
}
|
|
tm.tm_year = (uint16_t)(task_unit->uint_time.year + 2000);
|
|
tm.tm_mon = (uint8_t)task_unit->uint_time.month;
|
|
tm.tm_mday = (uint8_t)task_unit->uint_time.day;
|
|
tm.tm_hour = (uint8_t)task_unit->uint_time.hour;
|
|
tm.tm_min = (uint8_t)task_unit->uint_time.minute;
|
|
tm.tm_sec = (uint8_t)task_unit->uint_time.second;
|
|
end_tm = cache_hdr->start_tm;
|
|
iot_rtc_delta_add(delta * (cache_hdr->query_cnt - 1), &end_tm);
|
|
if ((iot_rtc_delta_calc(last_tm, &tm) > 0 ) &&
|
|
(iot_rtc_delta_calc(&tm, &end_tm) >= 0 )) {
|
|
/* last_tm < tm <= end_tm */
|
|
ret = ERR_OK;
|
|
}
|
|
out:
|
|
if (task_pkt) {
|
|
iot_pkt_free(task_pkt);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_freeze_cache_to_resp(uint8_t *addr,
|
|
proto_645_fj_task_data_query_hdr_ul_t *resp, uint16_t resp_max_len,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr, uint16_t cache_len,
|
|
uint8_t msg_type, uint8_t task_id)
|
|
{
|
|
int64_t delta;
|
|
uint16_t len = resp_max_len, fill_time_cnt;
|
|
uint8_t frozen_point_cnt = 0, frozen_point_cnt_last = 0, group_type;
|
|
uint8_t di_info_len, *di_data, resp_len, reason = 0;
|
|
uint8_t i, j, unit_len = 0, valid_di_cnt = 0;
|
|
iot_sg_sta_ext_freeze_resp_cache_data_t *cache_data;
|
|
iot_sg_sta_drv_meter_fj_unit_data_t *unit_data;
|
|
proto_645_fj_task_data_query_di_unit_t *di_unit;
|
|
iot_time_tm_t tm = { 0 }, last_tm = { 0 }, cache_end_tm;
|
|
|
|
if (!resp || !len || !cache_hdr || !cache_len) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (cache_len < sizeof(*cache_hdr)) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
cache_len -= sizeof(*cache_hdr);
|
|
if (!cache_hdr->di_cnt) {
|
|
reason = 4;
|
|
goto drop;
|
|
}
|
|
di_info_len = cache_hdr->di_cnt *
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
if (cache_len < di_info_len) {
|
|
reason = 5;
|
|
goto drop;
|
|
}
|
|
cache_len -= di_info_len;
|
|
if (cache_len < sizeof(*cache_data)) {
|
|
reason = 6;
|
|
goto drop;
|
|
}
|
|
cache_end_tm = cache_hdr->cache_end_tm;
|
|
cache_data = (iot_sg_sta_ext_freeze_resp_cache_data_t *)(
|
|
(uint8_t *)cache_hdr->di_info + di_info_len);
|
|
for (i = 0 ; i < cache_hdr->di_cnt; i++) {
|
|
if (!cache_hdr->di_info[i].resp_len ||
|
|
cache_hdr->di_info[i].resp_len <= PROTO_645_2007_DI_LEN) {
|
|
continue;
|
|
}
|
|
unit_len += (cache_hdr->di_info[i].resp_len - PROTO_645_2007_DI_LEN);
|
|
valid_di_cnt++;
|
|
}
|
|
if (!unit_len) {
|
|
reason = 7;
|
|
goto drop;
|
|
}
|
|
delta = proto_645_fj_task_cycle_to_sec(&cache_hdr->cycle);
|
|
if (!delta) {
|
|
reason = 8;
|
|
goto drop;
|
|
}
|
|
if (len < sizeof(*resp)) {
|
|
reason = 9;
|
|
goto drop;
|
|
}
|
|
len -= sizeof(*resp);
|
|
if (len < valid_di_cnt * sizeof(*di_unit)) {
|
|
reason = 10;
|
|
goto drop;
|
|
}
|
|
if (unit_len >= (len - valid_di_cnt * sizeof(*di_unit))) {
|
|
fill_time_cnt = 1;
|
|
} else {
|
|
fill_time_cnt = (len - valid_di_cnt * sizeof(*di_unit)) / unit_len;
|
|
}
|
|
if (fill_time_cnt > cache_hdr->query_cnt) {
|
|
fill_time_cnt = cache_hdr->query_cnt;
|
|
}
|
|
resp->type = cache_hdr->type;
|
|
resp->result = PROTO_645_FJ_READ_RESP_DATA_OK;
|
|
resp->start.year = iot_byte_to_bcd((uint8_t)cache_data->rec_time.year);
|
|
resp->start.month = iot_byte_to_bcd((uint8_t)cache_data->rec_time.month);
|
|
resp->start.day = iot_byte_to_bcd((uint8_t)cache_data->rec_time.day);
|
|
resp->start.hour = iot_byte_to_bcd((uint8_t)cache_data->rec_time.hour);
|
|
resp->start.minute = iot_byte_to_bcd((uint8_t)cache_data->rec_time.minute);
|
|
resp->start.second = iot_byte_to_bcd(cache_data->rec_time.second);
|
|
if (cache_hdr->storage_times) {
|
|
resp->storage_times = cache_hdr->storage_times - 1;
|
|
} else {
|
|
resp->storage_times = cache_hdr->storage_times;
|
|
}
|
|
resp->task_cycle = cache_hdr->cycle;
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
resp->start.year = (uint8_t)cache_data->rec_time.year;
|
|
resp->start.month = (uint8_t)cache_data->rec_time.month;
|
|
resp->start.day = (uint8_t)cache_data->rec_time.day;
|
|
resp->start.hour = (uint8_t)cache_data->rec_time.hour;
|
|
resp->start.minute = (uint8_t)cache_data->rec_time.minute;
|
|
resp->start.second = (uint8_t)cache_data->rec_time.second;
|
|
iot_data_reverse((uint8_t *)&resp->start, sizeof(resp->start));
|
|
iot_data_reverse((uint8_t *)&resp->storage_times,
|
|
sizeof(resp->storage_times));
|
|
iot_data_reverse((uint8_t *)&resp->task_cycle,
|
|
sizeof(resp->task_cycle));
|
|
}
|
|
di_unit = (proto_645_fj_task_data_query_di_unit_t *)resp->di_data;
|
|
group_type = iot_sg_sta_ext_fj_task_group_get(task_id);
|
|
for (i = 0 ; i < cache_hdr->di_cnt; i++) {
|
|
if (!cache_hdr->di_info[i].resp_len ||
|
|
cache_hdr->di_info[i].resp_len <= PROTO_645_2007_DI_LEN) {
|
|
continue;
|
|
}
|
|
resp_len = cache_hdr->di_info[i].resp_len - PROTO_645_2007_DI_LEN;
|
|
if (len < sizeof(*di_unit) + resp_len * fill_time_cnt) {
|
|
resp->result = PROTO_645_FJ_READ_RESP_DATA_OVERFLOW;
|
|
reason = 11;
|
|
goto out;
|
|
}
|
|
resp->di_cnt++;
|
|
di_unit->di = cache_hdr->di_info[i].di;
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698) {
|
|
iot_data_reverse((uint8_t *)&di_unit->di, sizeof(di_unit->di));
|
|
}
|
|
di_unit->length = resp_len;
|
|
len -= sizeof(*di_unit);
|
|
di_data = di_unit->di_data;
|
|
tm.tm_year = (uint16_t)(cache_data->rec_time.year + 2000);
|
|
tm.tm_mon = (uint8_t)cache_data->rec_time.month;
|
|
tm.tm_mday = (uint8_t)cache_data->rec_time.day;
|
|
tm.tm_hour = (uint8_t)cache_data->rec_time.hour;
|
|
tm.tm_min = (uint8_t)cache_data->rec_time.minute;
|
|
tm.tm_sec = (uint8_t)cache_data->rec_time.second;
|
|
frozen_point_cnt = 0;
|
|
for (j = 0; j < fill_time_cnt; j++) {
|
|
unit_data = iot_sg_sta_ext_fj_cache_di_data_find(cache_data,
|
|
cache_len, cache_hdr->rsp_cnt, cache_hdr->di_info[i].di, &tm,
|
|
cache_hdr->type);
|
|
if (unit_data) {
|
|
if (unit_data->len == resp_len + PROTO_645_2007_DI_LEN) {
|
|
os_mem_cpy(di_data, unit_data->data + PROTO_645_2007_DI_LEN,
|
|
resp_len);
|
|
if (msg_type == IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698 &&
|
|
group_type == PROTO_645_FJ_TASK_GROUP_645) {
|
|
iot_sg_sta_ext_fj_645_unit_to_698_unit(di_unit->di,
|
|
unit_data->data, unit_data->len);
|
|
}
|
|
} else {
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698 && resp_len) {
|
|
di_data[0] = cache_hdr->di_info[i].resp_first_byte;
|
|
os_mem_set(di_data + 1, 0xff, resp_len - 1);
|
|
} else {
|
|
os_mem_set(di_data, 0xff, resp_len);
|
|
}
|
|
}
|
|
} else {
|
|
if (group_type == PROTO_645_FJ_TASK_GROUP_698 && resp_len) {
|
|
di_data[0] = cache_hdr->di_info[i].resp_first_byte;
|
|
os_mem_set(di_data + 1, 0xff, resp_len - 1);
|
|
} else {
|
|
os_mem_set(di_data, 0xff, resp_len);
|
|
}
|
|
}
|
|
di_data += resp_len;
|
|
len -= resp_len;
|
|
frozen_point_cnt++;
|
|
last_tm = tm;
|
|
if (iot_rtc_delta_calc(&tm, &cache_end_tm) <= 0) {
|
|
break;
|
|
}
|
|
iot_rtc_delta_add(delta, &tm);
|
|
}
|
|
if (!frozen_point_cnt_last) {
|
|
frozen_point_cnt_last = frozen_point_cnt;
|
|
} else if (frozen_point_cnt_last != frozen_point_cnt) {
|
|
/* must be the same to all di frozen point count */
|
|
reason = 12;
|
|
goto drop;
|
|
}
|
|
di_unit = (proto_645_fj_task_data_query_di_unit_t *)di_data;
|
|
}
|
|
resp->frozen_point_cnt = frozen_point_cnt;
|
|
if (iot_sg_sta_ext_fj_freeze_resp_overflow_check(addr, task_id, cache_hdr,
|
|
&last_tm, delta, fill_time_cnt) == ERR_OK) {
|
|
resp->result = PROTO_645_FJ_READ_RESP_DATA_OVERFLOW;
|
|
}
|
|
goto out;
|
|
drop:
|
|
len = resp_max_len;
|
|
iot_sg_printf("%s drop %d\n",__FUNCTION__, reason);
|
|
out:
|
|
return resp_max_len - len;
|
|
}
|
|
|
|
static uint32_t iot_sg_ext_fj_cfg_di_check(uint32_t di,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg)
|
|
{
|
|
uint8_t idx, offset_len = 0, *data;
|
|
uint32_t ret = ERR_INVAL, cfg_di;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t *)cfg->desc;
|
|
for (idx = 0; idx < freeze_hdr->data_cnt; idx++) {
|
|
if (iot_sg_ext_freeze_data_desc_offset_get(&offset_len,
|
|
cfg->desc_len, freeze_hdr->data_desc, idx)) {
|
|
goto out;
|
|
}
|
|
freeze_des = (proto_645_fj_freeze_data_desc_hdr_t *)(
|
|
freeze_hdr->data_desc + offset_len);
|
|
cfg_di = proto_645_2007_byte_to_di(freeze_des->data);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
if (!incon_rpt->di_cnt) {
|
|
goto out;
|
|
}
|
|
for (idx = 0; idx < incon_rpt->di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&incon_rpt->di[idx]);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
data = (uint8_t *)incon_rpt->di +
|
|
incon_rpt->di_cnt * PROTO_645_2007_DI_LEN;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&cross_rpt->di);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
data = cross_rpt->value_list + cross_rpt->cnt * cross_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t*)cfg->desc;
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&chg_rpt->di);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
data = chg_rpt->value_list + chg_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (di == cfg_di) {
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static void iot_sg_ext_fj_cfg_di_fill_to_cache_hdr(
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr,
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg, uint16_t cache_max_len)
|
|
{
|
|
uint8_t idx, offset_len = 0, *data;
|
|
uint32_t cfg_di;
|
|
proto_645_fj_task_set_freeze_hdr_t *freeze_hdr;
|
|
proto_645_fj_freeze_data_desc_hdr_t *freeze_des;
|
|
proto_645_fj_task_set_incon_rpt_hdr_t *incon_rpt;
|
|
proto_645_fj_task_set_flw_rpt_hdr_t *flw_rpt;
|
|
proto_645_fj_task_set_cross_rpt_t *cross_rpt;
|
|
proto_645_fj_task_set_change_rpt_hdr_t *chg_rpt;
|
|
|
|
if (!cache_hdr || !cfg || !cache_max_len) {
|
|
goto out;
|
|
}
|
|
switch (cfg->type) {
|
|
case PROTO_645_FJ_TASK_TYPE_FREEZE:
|
|
{
|
|
freeze_hdr = (proto_645_fj_task_set_freeze_hdr_t *)cfg->desc;
|
|
for (idx = 0; idx < freeze_hdr->data_cnt; idx++) {
|
|
if (iot_sg_ext_freeze_data_desc_offset_get(&offset_len,
|
|
cfg->desc_len, freeze_hdr->data_desc, idx)) {
|
|
goto out;
|
|
}
|
|
freeze_des = (proto_645_fj_freeze_data_desc_hdr_t *)(
|
|
freeze_hdr->data_desc + offset_len);
|
|
cfg_di = proto_645_2007_byte_to_di(freeze_des->data);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_INCON_RPT:
|
|
{
|
|
incon_rpt = (proto_645_fj_task_set_incon_rpt_hdr_t *)cfg->desc;
|
|
if (!incon_rpt->di_cnt) {
|
|
goto out;
|
|
}
|
|
for (idx = 0; idx < incon_rpt->di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&incon_rpt->di[idx]);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
data = (uint8_t *)incon_rpt->di +
|
|
incon_rpt->di_cnt * PROTO_645_2007_DI_LEN;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CROSS_RPT:
|
|
{
|
|
cross_rpt = (proto_645_fj_task_set_cross_rpt_t *)cfg->desc;
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&cross_rpt->di);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
data = cross_rpt->value_list + cross_rpt->cnt * cross_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_TASK_TYPE_CHG_RPT:
|
|
{
|
|
chg_rpt = (proto_645_fj_task_set_change_rpt_hdr_t*)cfg->desc;
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&chg_rpt->di);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
data = chg_rpt->value_list + chg_rpt->value_len;
|
|
flw_rpt = (proto_645_fj_task_set_flw_rpt_hdr_t *)data;
|
|
for (idx = 0; idx < flw_rpt->follow_di_cnt; idx++) {
|
|
cfg_di = proto_645_2007_byte_to_di((uint8_t *)&flw_rpt->di[idx]);
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = cfg_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_read_freeze_query_info_to_cache_hdr(
|
|
uint8_t *addr, uint8_t task_id, uint8_t *data, uint8_t len,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr, uint16_t cache_max_len)
|
|
{
|
|
int64_t delta;
|
|
uint32_t query_di;
|
|
uint16_t cache_hdr_len = 0;
|
|
uint8_t i, reason = 0;
|
|
iot_pkt_t *cfg_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
iot_time_tm_t start_tm = { 0 };
|
|
proto_645_fj_task_data_query_hdr_dl_t *query_hdr;
|
|
proto_645_fj_task_data_query_tail_dl_t *query_tail;
|
|
|
|
if (!addr || !data || !len || !cache_hdr || !cache_max_len) {
|
|
goto out;
|
|
}
|
|
cfg_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!cfg_pkt) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(cfg_pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg) != ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if (cache_max_len < sizeof(*cache_hdr)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(*cache_hdr);
|
|
cache_hdr->type = cfg->type;
|
|
cache_hdr->cycle.value = cfg->value;
|
|
cache_hdr->cycle.unit = cfg->unit;
|
|
if (len < sizeof(*query_hdr)) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
len -= sizeof(*query_hdr);
|
|
query_hdr = (proto_645_fj_task_data_query_hdr_dl_t *)data;
|
|
if (query_hdr->type != PROTO_645_FJ_TASK_QR_TYPE_WITH_TIME) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (len < PROTO_645_2007_DI_LEN * query_hdr->di_cnt) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
len -= PROTO_645_2007_DI_LEN * query_hdr->di_cnt;
|
|
/* cache request info */
|
|
if (query_hdr->di_cnt) {
|
|
for (i = 0; i < query_hdr->di_cnt; i++) {
|
|
query_di = proto_645_2007_byte_to_di(
|
|
(uint8_t *)&query_hdr->di_list[i]);
|
|
if (iot_sg_ext_fj_cfg_di_check(query_di, cfg)) {
|
|
continue;
|
|
}
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
break;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = query_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
|
|
} else {
|
|
iot_sg_ext_fj_cfg_di_fill_to_cache_hdr(cache_hdr, cfg, cache_max_len);
|
|
}
|
|
if (len < sizeof(*query_tail)) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
query_tail = (proto_645_fj_task_data_query_tail_dl_t *)(query_hdr->di_list +
|
|
query_hdr->di_cnt);
|
|
start_tm.tm_year = iot_bcd_to_byte(query_tail->start.year) + 2000;
|
|
start_tm.tm_mon = iot_bcd_to_byte(query_tail->start.month);
|
|
start_tm.tm_mday = iot_bcd_to_byte(query_tail->start.day);
|
|
start_tm.tm_hour = iot_bcd_to_byte(query_tail->start.hour);
|
|
start_tm.tm_min = iot_bcd_to_byte(query_tail->start.minute);
|
|
start_tm.tm_sec = iot_bcd_to_byte(query_tail->start.second);
|
|
delta = proto_645_fj_task_cycle_to_sec(&cache_hdr->cycle);
|
|
iot_sg_ext_set_integral_point(&start_tm, delta, 1);
|
|
cache_hdr->start_tm.tm_year = start_tm.tm_year;
|
|
cache_hdr->start_tm.tm_mon = start_tm.tm_mon;
|
|
cache_hdr->start_tm.tm_mday = start_tm.tm_mday;
|
|
cache_hdr->start_tm.tm_hour = start_tm.tm_hour;
|
|
cache_hdr->start_tm.tm_min = start_tm.tm_min;
|
|
cache_hdr->start_tm.tm_sec = start_tm.tm_sec;
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE) {
|
|
cache_hdr->query_cnt = query_tail->cnt;
|
|
} else {
|
|
cache_hdr->query_cnt = 1;
|
|
}
|
|
cache_hdr_len = sizeof(*cache_hdr) + cache_hdr->di_cnt *
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
out:
|
|
if (cfg_pkt) {
|
|
iot_pkt_free(cfg_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n",__FUNCTION__,reason);
|
|
}
|
|
return cache_hdr_len;
|
|
}
|
|
|
|
static uint16_t iot_sg_sta_ext_fj_read_freeze_query_info_to_cache_hdr2(
|
|
uint8_t *addr, uint8_t task_id, uint8_t *data, uint8_t len,
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr, uint16_t cache_max_len)
|
|
{
|
|
int64_t delta;
|
|
uint32_t query_di;
|
|
uint16_t cache_hdr_len = 0;
|
|
uint8_t i, reason = 0;
|
|
iot_pkt_t *cfg_pkt = NULL;
|
|
iot_sg_sta_drv_meter_fj_task_info_t *cfg;
|
|
iot_time_tm_t start_tm = { 0 };
|
|
proto_645_fj_task_data_query_hdr2_dl_t *query_hdr;
|
|
proto_645_fj_task_data_query_tail2_dl_t *query_tail;
|
|
|
|
if (!addr || !data || !len || !cache_hdr || !cache_max_len) {
|
|
goto out;
|
|
}
|
|
cfg_pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!cfg_pkt) {
|
|
reason = 1;
|
|
goto out;
|
|
}
|
|
cfg = (iot_sg_sta_drv_meter_fj_task_info_t *)
|
|
iot_pkt_put(cfg_pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_ext_freeze_flash_cfg_get(addr, task_id, cfg) != ERR_OK) {
|
|
reason = 2;
|
|
goto out;
|
|
}
|
|
if (cache_max_len < sizeof(*cache_hdr)) {
|
|
reason = 3;
|
|
goto out;
|
|
}
|
|
cache_max_len -= sizeof(*cache_hdr);
|
|
cache_hdr->type = cfg->type;
|
|
cache_hdr->cycle.value = cfg->value;
|
|
cache_hdr->cycle.unit = cfg->unit;
|
|
if (len < sizeof(*query_hdr)) {
|
|
reason = 4;
|
|
goto out;
|
|
}
|
|
len -= sizeof(*query_hdr);
|
|
query_hdr = (proto_645_fj_task_data_query_hdr2_dl_t *)data;
|
|
if (query_hdr->type != PROTO_645_FJ_TASK_QR_TYPE_WITH_TIME2) {
|
|
reason = 5;
|
|
goto out;
|
|
}
|
|
if (len < PROTO_645_2007_DI_LEN * query_hdr->oad_cnt) {
|
|
reason = 6;
|
|
goto out;
|
|
}
|
|
len -= PROTO_645_2007_DI_LEN * query_hdr->oad_cnt;
|
|
/* cache request info */
|
|
if (query_hdr->oad_cnt) {
|
|
for (i = 0; i < query_hdr->oad_cnt; i++) {
|
|
query_di = iot_bytes_to_uint32(
|
|
(uint8_t *)&query_hdr->oad_list[i], 1);
|
|
if (iot_sg_ext_fj_cfg_di_check(query_di, cfg)) {
|
|
continue;
|
|
}
|
|
if (cache_max_len <
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t)) {
|
|
break;
|
|
}
|
|
cache_max_len -= sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
cache_hdr->di_info[cache_hdr->di_cnt].di = query_di;
|
|
cache_hdr->di_cnt++;
|
|
}
|
|
|
|
} else {
|
|
iot_sg_ext_fj_cfg_di_fill_to_cache_hdr(cache_hdr, cfg, cache_max_len);
|
|
}
|
|
if (len < sizeof(*query_tail)) {
|
|
reason = 8;
|
|
goto out;
|
|
}
|
|
query_tail = (proto_645_fj_task_data_query_tail2_dl_t *)
|
|
(query_hdr->oad_list + query_hdr->oad_cnt);
|
|
if (query_tail->data_type != PROTO_69845_APP_DATA_TIME_S) {
|
|
reason = 9;
|
|
goto out;
|
|
}
|
|
start_tm.tm_year = iot_bytes_to_uint16((uint8_t *)&query_tail->year, 1);
|
|
start_tm.tm_mon = query_tail->month;
|
|
start_tm.tm_mday = query_tail->day;
|
|
start_tm.tm_hour = query_tail->hour;
|
|
start_tm.tm_min = query_tail->minute;
|
|
start_tm.tm_sec = query_tail->second;
|
|
delta = proto_645_fj_task_cycle_to_sec(&cache_hdr->cycle);
|
|
iot_sg_ext_set_integral_point(&start_tm, delta, 1);
|
|
cache_hdr->start_tm.tm_year = start_tm.tm_year;
|
|
cache_hdr->start_tm.tm_mon = start_tm.tm_mon;
|
|
cache_hdr->start_tm.tm_mday = start_tm.tm_mday;
|
|
cache_hdr->start_tm.tm_hour = start_tm.tm_hour;
|
|
cache_hdr->start_tm.tm_min = start_tm.tm_min;
|
|
cache_hdr->start_tm.tm_sec = start_tm.tm_sec;
|
|
if (cfg->type == PROTO_645_FJ_TASK_TYPE_FREEZE) {
|
|
cache_hdr->query_cnt = query_tail->cnt;
|
|
} else {
|
|
cache_hdr->query_cnt = 1;
|
|
}
|
|
cache_hdr_len = sizeof(*cache_hdr) + cache_hdr->di_cnt *
|
|
sizeof(iot_sg_sta_ext_freeze_resp_cache_di_info_t);
|
|
out:
|
|
if (cfg_pkt) {
|
|
iot_pkt_free(cfg_pkt);
|
|
}
|
|
if (reason) {
|
|
iot_sg_printf("%s err %d\n",__FUNCTION__,reason);
|
|
}
|
|
return cache_hdr_len;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_freeze_data_by_time2(uint8_t *addr,
|
|
uint32_t di, uint8_t *data, uint8_t len, uint8_t msg_type,
|
|
uint32_t valid_len)
|
|
{
|
|
uint8_t result = PROTO_645_FJ_READ_RESP_DATA_OK, task_id;
|
|
uint16_t cache_max_len, cache_data_len, cache_hdr_len, max_len, data_len = 0;
|
|
iot_pkt_t *pkt = NULL, *cache_pkt = NULL;
|
|
proto_645_fj_task_data_query_hdr_ul_t *query_ul;
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr;
|
|
|
|
cache_max_len = IOT_SG_STA_EXT_FREEZR_698_CACHE_LEN;
|
|
cache_pkt = iot_pkt_alloc(cache_max_len, IOT_SMART_GRID_MID);
|
|
if (!cache_pkt) {
|
|
goto out;
|
|
}
|
|
cache_hdr = (iot_sg_sta_ext_freeze_resp_cache_hdr_t *)iot_pkt_put(cache_pkt,
|
|
cache_max_len);
|
|
task_id = (uint8_t)(di & 0x000000FF);
|
|
cache_hdr_len = iot_sg_sta_ext_fj_read_freeze_query_info_to_cache_hdr2(addr,
|
|
task_id, data, len, cache_hdr, cache_max_len);
|
|
if (!cache_hdr_len || cache_max_len < cache_hdr_len) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= cache_hdr_len;
|
|
max_len = (uint16_t)valid_len;
|
|
pkt = iot_pkt_alloc(max_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
query_ul = (proto_645_fj_task_data_query_hdr_ul_t *)iot_pkt_data(pkt);
|
|
if (cache_hdr->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_resp_by_time(addr, query_ul,
|
|
max_len, cache_hdr, msg_type, task_id);
|
|
if (!data_len || max_len < data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
goto build;
|
|
}
|
|
cache_data_len = iot_sg_sta_ext_fj_freeze_flash_data_to_cache(addr,
|
|
task_id, cache_hdr, cache_max_len);
|
|
if (!cache_data_len || cache_max_len < cache_data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
goto build;
|
|
}
|
|
cache_max_len -= cache_data_len;
|
|
data_len = iot_sg_sta_ext_fj_freeze_cache_to_resp(addr, query_ul, max_len,
|
|
cache_hdr, IOT_SG_STA_EXT_FREEZR_698_CACHE_LEN - cache_max_len,
|
|
msg_type, task_id);
|
|
if (!data_len || max_len < data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
build:
|
|
if (result == PROTO_645_FJ_READ_RESP_DATA_INVALID) {
|
|
query_ul->type = cache_hdr->type;
|
|
query_ul->result = result;
|
|
data_len = sizeof(query_ul->result) + sizeof(query_ul->type);
|
|
}
|
|
iot_pkt_put(pkt, data_len);
|
|
out:
|
|
if (cache_pkt) {
|
|
iot_pkt_free(cache_pkt);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_freeze_data_by_time(uint8_t *addr,
|
|
uint32_t di, uint8_t *data, uint8_t len, uint8_t msg_type)
|
|
{
|
|
uint8_t task_id, max_len, data_len = 0;
|
|
uint8_t result = PROTO_645_FJ_READ_RESP_DATA_OK;
|
|
uint16_t cache_max_len, cache_data_len, cache_hdr_len;
|
|
iot_pkt_t *resp_pkt = NULL, *pkt = NULL, *cache_pkt = NULL;
|
|
proto_645_fj_task_data_query_hdr_ul_t *query_ul;
|
|
iot_sg_sta_ext_freeze_resp_cache_hdr_t *cache_hdr;
|
|
|
|
cache_max_len = IOT_SG_STA_EXT_FREEZR_CACHE_LEN;
|
|
cache_pkt = iot_pkt_alloc(cache_max_len, IOT_SMART_GRID_MID);
|
|
if (!cache_pkt) {
|
|
goto out;
|
|
}
|
|
cache_hdr = (iot_sg_sta_ext_freeze_resp_cache_hdr_t *)iot_pkt_put(cache_pkt,
|
|
cache_max_len);
|
|
task_id = (uint8_t)(di & 0x000000FF);
|
|
cache_hdr_len = iot_sg_sta_ext_fj_read_freeze_query_info_to_cache_hdr(addr,
|
|
task_id, data, len, cache_hdr, cache_max_len);
|
|
if (!cache_hdr_len || cache_max_len < cache_hdr_len) {
|
|
goto out;
|
|
}
|
|
cache_max_len -= cache_hdr_len;
|
|
max_len = PROTO_645_FJ_RESP_DATA_MAX_LEN - PROTO_645_2007_DI_LEN;
|
|
pkt = iot_pkt_alloc(max_len, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
query_ul = (proto_645_fj_task_data_query_hdr_ul_t *)
|
|
iot_pkt_put(pkt, max_len);
|
|
if (cache_hdr->type == PROTO_645_FJ_TASK_TYPE_CHG_RPT) {
|
|
data_len = iot_sg_sta_ext_fj_task_chg_data_resp_by_time(addr, query_ul,
|
|
max_len, cache_hdr, msg_type, task_id);
|
|
if (!data_len || max_len < data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
goto build;
|
|
}
|
|
cache_data_len = iot_sg_sta_ext_fj_freeze_flash_data_to_cache(addr,
|
|
task_id, cache_hdr, cache_max_len);
|
|
if (!cache_data_len || cache_max_len < cache_data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
goto build;
|
|
}
|
|
cache_max_len -= cache_data_len;
|
|
data_len = (uint8_t)iot_sg_sta_ext_fj_freeze_cache_to_resp(addr, query_ul,
|
|
max_len, cache_hdr, IOT_SG_STA_EXT_FREEZR_CACHE_LEN - cache_max_len,
|
|
msg_type, task_id);
|
|
if (!data_len || max_len < data_len) {
|
|
result = PROTO_645_FJ_READ_RESP_DATA_INVALID;
|
|
}
|
|
build:
|
|
if (result == PROTO_645_FJ_READ_RESP_DATA_INVALID) {
|
|
query_ul->type = cache_hdr->type;
|
|
query_ul->result = result;
|
|
data_len = sizeof(query_ul->result) + sizeof(query_ul->type);
|
|
}
|
|
resp_pkt = proto_645_fj_build_msg(addr, (uint8_t *)query_ul, data_len,
|
|
di, PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
if (cache_pkt) {
|
|
iot_pkt_free(cache_pkt);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_read_freeze_data(uint8_t *addr, uint32_t di,
|
|
uint8_t *data, uint8_t len, uint8_t is_simple_698, uint32_t valid_len)
|
|
{
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
uint8_t *read_type, msg_type;
|
|
proto_645_fj_task_data_query_no_time_dl_t *query_no_timw;
|
|
|
|
if (!addr || !data || len <= PROTO_645_2007_DI_LEN) {
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
len -= PROTO_645_2007_DI_LEN;
|
|
if (len < sizeof(*read_type)) {
|
|
goto nack;
|
|
}
|
|
read_type = data + PROTO_645_2007_DI_LEN;
|
|
if (is_simple_698) {
|
|
msg_type = IOT_SG_STA_EXT_FREEZE_BUILD_MSG_698;
|
|
} else {
|
|
msg_type = IOT_SG_STA_EXT_FREEZE_BUILD_MSG_645;
|
|
}
|
|
if (read_type[0] == PROTO_645_FJ_TASK_QR_TYPE_NOTIME) {
|
|
if (len < sizeof(*query_no_timw)) {
|
|
goto nack;
|
|
}
|
|
query_no_timw = (proto_645_fj_task_data_query_no_time_dl_t *)read_type;
|
|
resp_pkt = iot_sg_sta_ext_fj_read_freeze_data_by_idx(addr, di,
|
|
query_no_timw->last_num, msg_type);
|
|
} else if (!is_simple_698 &&
|
|
read_type[0] == PROTO_645_FJ_TASK_QR_TYPE_WITH_TIME) {
|
|
resp_pkt = iot_sg_sta_ext_fj_read_freeze_data_by_time(addr, di,
|
|
read_type, len, msg_type);
|
|
} else if (is_simple_698 &&
|
|
read_type[0] == PROTO_645_FJ_TASK_QR_TYPE_WITH_TIME2) {
|
|
resp_pkt = iot_sg_sta_ext_fj_read_freeze_data_by_time2(addr, di,
|
|
read_type, len, msg_type, valid_len);
|
|
}
|
|
if (resp_pkt) {
|
|
goto out;
|
|
}
|
|
nack:
|
|
resp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_fj_build_single_di_read_resp(uint8_t *addr,
|
|
uint8_t *data, uint8_t len, uint32_t di, uint8_t nack)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
switch (di) {
|
|
case PROTO_645_FJ_DI_QR_CHIP_ID:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_qr_chip_id(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_MOD_ID:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_qr_mod_id(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_MOD_VER:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_qr_mod_ver(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_TM:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_mod_tm(addr, PROTO_645_2007_FN_READ_DATA);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_CT_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_ct_dur(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_LAST_CT_REC:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_ct_rec(addr, PROTO_645_2007_FN_READ_DATA);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_TM_SOC:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_tm_soc(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_EVT_RPT_CFG:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_evt_rpt_cfg(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_MOD_WORK_V:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_mod_work_v(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_REC_MAX_LEN:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rec_max_len(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_MAX_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_max_cnt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RANDOM_RPT_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_random_rpt_time(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_RETRY_COUNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_retry_count(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_METER_MULTI_DATA_ITEM:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_meter_multi_data_flag(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_TASK_STATE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_task_state(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_STOP_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_stop_dur(addr, 0);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_UPGRADE_SEND_FILE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_handle_send_file(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_UPGRADE_REQ_FILE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_handle_query_file(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_MODULE_RESET_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_reset_cnt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_PD_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_pd_cnt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_PD_EVT_VALID_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_pd_valid_time(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_MODE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_mode(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MULTI_RPT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_multi_rpt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_STATUS:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_status(addr, 0);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST1:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST2:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST3:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST4:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST5:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST6:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST7:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST8:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST9:
|
|
case PROTO_645_FJ_DI_QR_POWER_RECORD_LAST10:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_pd_rec(addr, di);
|
|
break;
|
|
}
|
|
default:
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_DI_SET_TASK) {
|
|
pkt = iot_sg_sta_ext_fj_read_task(addr, di, 0);
|
|
} else if ((di & 0xffffff00) == PROTO_645_FJ_DI_QR_TASK_DATA) {
|
|
pkt = iot_sg_sta_ext_fj_read_freeze_data(addr, di, data, len, 0, 0);
|
|
} else if (nack && ((di & 0xffff0000) == PROTO_645_FJ_DI_QR_TASK_DATA)) {
|
|
/* EBE0xxxx not support, response nack */
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
}
|
|
/* no relevant DI, forward to meter */
|
|
break;
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_set_data_result_check(uint8_t *data, uint32_t len)
|
|
{
|
|
uint8_t dar = PROTO_69845_APP_DAR_OTHER;
|
|
proto_645_header_t *hdr;
|
|
|
|
hdr = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
|
|
if (!hdr) {
|
|
goto out;
|
|
}
|
|
if (!hdr->control.ack) {
|
|
dar = PROTO_69845_APP_DAR_SUCCESS;
|
|
}
|
|
out:
|
|
return dar;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_set_data_handle(uint8_t *addr, uint32_t di,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t dar, buff_len, *buff_data;
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
|
|
buff_len = len + sizeof(di);
|
|
pkt_buff = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
goto out;
|
|
}
|
|
buff_data = iot_pkt_put(pkt_buff, buff_len);
|
|
proto_645_2007_di_to_byte(di, buff_data);
|
|
os_mem_cpy(buff_data + PROTO_645_2007_DI_LEN, data, len);
|
|
proto_645_add33_handle(buff_data, buff_len);
|
|
switch (di) {
|
|
case PROTO_645_FJ_DI_DEL_TASK:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_del_task(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_REC_MAX_LEN:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rec_max_len(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_MAX_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rpt_max_cnt(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_STOP_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_stop_dur(addr, buff_data, buff_len, 1);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RANDOM_RPT_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_random_rpt_time(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_RETRY_COUNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rpt_retry_count(addr, buff_data,buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_TAST_RESET:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_task_restart(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_MODE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_report_mode(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MULTI_RPT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_multi_rpt(addr, buff_data, buff_len);
|
|
break;
|
|
}
|
|
default:
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_DI_SET_TASK) {
|
|
pkt = iot_sg_sta_ext_fj_write_task(addr, di, buff_data,
|
|
buff_len, 1);
|
|
}
|
|
break;
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
dar = iot_sg_sta_ext_set_data_result_check(iot_pkt_data(pkt),
|
|
iot_pkt_data_len(pkt));
|
|
iot_pkt_free(pkt);
|
|
} else {
|
|
dar = PROTO_69845_APP_DAR_OTHER;
|
|
}
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
return dar;
|
|
}
|
|
|
|
static iot_pkt_t *iot_iot_sg_sta_ext_set_data_resp(addr_info_t *addr_info,
|
|
proto_69845_app_piid_t *piid, proto_69845_app_oad_with_dar_t *oad_with_dar,
|
|
uint8_t oad_cnt, uint8_t is_security)
|
|
{
|
|
uint32_t len;
|
|
iot_pkt_t *pkt = NULL, *apdu_pkt = NULL;
|
|
proto_69845_apdu_t *apdu;
|
|
proto_69845_app_set_resp_t *set;
|
|
proto_69845_app_set_resp_normal_list_t *normal_list;
|
|
|
|
len = sizeof(*apdu) + sizeof(*set) + sizeof(*normal_list) +
|
|
sizeof(*oad_with_dar) * oad_cnt + PROTO_69845_NO_TIME_TAG_LEN +
|
|
PROTO_69845_NO_FLW_DATA_LEN;
|
|
apdu_pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
|
|
if (!apdu_pkt) {
|
|
goto out;
|
|
}
|
|
apdu = (proto_69845_apdu_t *)iot_pkt_put(apdu_pkt, len);
|
|
apdu->type = PROTO_69845_S_APP_SET_RESP;
|
|
set = (proto_69845_app_set_resp_t *)apdu->data;
|
|
set->data_type = PROTO_69845_APP_SET_NORMALLIST;
|
|
normal_list = (proto_69845_app_set_resp_normal_list_t *)set->data;
|
|
normal_list->piid_acd.sn = piid->sn;
|
|
normal_list->piid_acd.priority = piid->priority;
|
|
normal_list->oad_cnt = oad_cnt;
|
|
os_mem_cpy(normal_list->result, oad_with_dar,
|
|
sizeof(*oad_with_dar) * oad_cnt);
|
|
if (is_security) {
|
|
pkt = proto_69845_build_apdu_data_with_security_resp_msg(
|
|
(uint8_t *)apdu, len, addr_info);
|
|
} else {
|
|
pkt = proto_69845_build_apdu_data_msg((uint8_t *)apdu, len,
|
|
addr_info, PROTO_69845_D_P_SERVER_RESPONSE);
|
|
}
|
|
out:
|
|
return pkt;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_fj_action_data_fill(uint8_t *data, uint32_t len,
|
|
uint8_t *fill_data, uint32_t *fill_len, uint8_t *optional,
|
|
uint32_t valid_len)
|
|
{
|
|
proto_645_header_t *hdr = NULL;
|
|
uint8_t byte_num = 0, *octet_string_len;
|
|
uint8_t *octet_string_data = 0, *data_tmp = NULL;
|
|
uint16_t data_len;
|
|
uint32_t ret = ERR_FAIL, app_data_len;
|
|
proto_69845_app_len_descript_t *len_desc;
|
|
proto_69845_app_data_t *app_data;
|
|
|
|
hdr = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
|
|
if (hdr) {
|
|
if (hdr->control.ack) {
|
|
goto out;
|
|
}
|
|
if (hdr->len < PROTO_645_2007_DI_LEN) {
|
|
goto out;
|
|
}
|
|
proto_645_sub33_handle(hdr->data, hdr->len);
|
|
data_len = (uint16_t)(hdr->len - PROTO_645_2007_DI_LEN);
|
|
data_tmp = hdr->data + PROTO_645_2007_DI_LEN;
|
|
} else {
|
|
data_len = (uint16_t)len;
|
|
data_tmp = data;
|
|
}
|
|
if (data_len) {
|
|
*optional = PROTO_69845_APP_OPTIONAL_DATA;
|
|
} else {
|
|
*optional = PROTO_69845_APP_OPTIONAL_NO_DATA;
|
|
ret = ERR_OK;
|
|
goto out;
|
|
}
|
|
if (data_len > 255) {
|
|
byte_num = 2;
|
|
} else if (data_len > 127) {
|
|
byte_num = 1;
|
|
} else {
|
|
byte_num = 0;
|
|
}
|
|
app_data_len = data_len + sizeof(*app_data) + sizeof(*len_desc) + byte_num;
|
|
if (valid_len < app_data_len) {
|
|
goto out;
|
|
}
|
|
(*fill_len) += app_data_len;
|
|
app_data = (proto_69845_app_data_t *)fill_data;
|
|
app_data->data_type = PROTO_69845_APP_DATA_OCTET_STRING;
|
|
len_desc = (proto_69845_app_len_descript_t *)app_data->data;
|
|
if (byte_num == 1) {
|
|
len_desc->mub_flag = 1;
|
|
len_desc->byte_num = 1;
|
|
octet_string_len = (uint8_t *)len_desc + 1;
|
|
*octet_string_len = (uint8_t)data_len;
|
|
octet_string_data = octet_string_len + byte_num;
|
|
} else if (byte_num == 2) {
|
|
len_desc->mub_flag = 1;
|
|
len_desc->byte_num = 2;
|
|
octet_string_len = (uint8_t *)len_desc + 1;
|
|
iot_uint16_to_bytes(data_len, octet_string_len, 1);
|
|
octet_string_data = octet_string_len + byte_num;
|
|
} else {
|
|
len_desc->mub_flag = 0;
|
|
len_desc->byte_num = (uint8_t)data_len;
|
|
octet_string_data = (uint8_t *)len_desc + 1;
|
|
}
|
|
os_mem_cpy(octet_string_data, data_tmp, data_len);
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_fj_action_data_handle(uint8_t *addr, uint32_t di,
|
|
uint8_t *data, uint8_t len, uint8_t *fill_data, uint32_t *fill_len,
|
|
uint8_t *optional, uint32_t valid_len)
|
|
{
|
|
uint32_t valid_len_tmp;
|
|
uint8_t dar = PROTO_69845_APP_DAR_OTHER, buff_len, *buff_data;
|
|
iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
|
|
|
|
buff_len = len + sizeof(di);
|
|
pkt_buff = iot_pkt_alloc(buff_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_buff) {
|
|
goto out;
|
|
}
|
|
buff_data = iot_pkt_put(pkt_buff, buff_len);
|
|
proto_645_2007_di_to_byte(di, buff_data);
|
|
os_mem_cpy(buff_data + PROTO_645_2007_DI_LEN, data, len);
|
|
proto_645_add33_handle(buff_data, buff_len);
|
|
switch (di) {
|
|
case PROTO_645_FJ_DI_SET_TASK_REC_MAX_LEN:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rec_max_len(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_MAX_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_max_cnt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_QR_TASK_STATE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_task_state(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_STOP_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_stop_dur(addr, 1);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RANDOM_RPT_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_random_rpt_time(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_RETRY_COUNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_retry_count(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_METER_MULTI_DATA_ITEM:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_meter_multi_data_flag(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_MODE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_mode(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MULTI_RPT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_multi_rpt(addr);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_STATUS:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_read_rpt_status(addr, 1);
|
|
break;
|
|
}
|
|
default:
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_DI_SET_TASK) {
|
|
pkt = iot_sg_sta_ext_fj_read_task(addr, di, 1);
|
|
} else if ((di & 0xffffff00) == PROTO_645_FJ_DI_QR_TASK_DATA) {
|
|
valid_len_tmp = valid_len - sizeof(proto_69845_app_data_t) -
|
|
sizeof(proto_69845_app_len_descript_t) -
|
|
IOT_SG_STA_EXT_698_LEN_BYTE_MAX_NUM;
|
|
pkt = iot_sg_sta_ext_fj_read_freeze_data(addr, di, buff_data,
|
|
buff_len, 1, valid_len_tmp);
|
|
}
|
|
break;
|
|
}
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
if (iot_sg_sta_ext_fj_action_data_fill(iot_pkt_data(pkt),
|
|
iot_pkt_data_len(pkt), fill_data, fill_len, optional,
|
|
valid_len) == ERR_OK) {
|
|
dar = PROTO_69845_APP_DAR_SUCCESS;
|
|
}
|
|
out:
|
|
if (pkt_buff) {
|
|
iot_pkt_free(pkt_buff);
|
|
}
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return dar;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_fj_security_handle(
|
|
proto_69845_frame_head_info_t *hdr_698, uint8_t *data, uint32_t data_len)
|
|
{
|
|
uint8_t *data_tmp;
|
|
uint16_t sec_len;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
proto_69845_app_sec_req_resp_info_t *sec_req;
|
|
proto_69845_app_len_descript_t *len_desc;
|
|
proto_69845_app_req_resp_t *req;
|
|
|
|
if (data_len < sizeof(*sec_req)) {
|
|
goto out;
|
|
}
|
|
data_len -= sizeof(*sec_req);
|
|
sec_req = (proto_69845_app_sec_req_resp_info_t*)data;
|
|
if (sec_req->type != PROTO_69845_SEC_DATA_TYPE_PLAINTEXT) {
|
|
goto out;
|
|
}
|
|
len_desc = (proto_69845_app_len_descript_t *)((uint8_t *)sec_req + 1);
|
|
if (!len_desc->mub_flag) {
|
|
data_tmp = sec_req->data;
|
|
sec_len = sec_req->len;
|
|
} else {
|
|
if (len_desc->byte_num == 1) {
|
|
sec_len = sec_req->data[0];
|
|
data_tmp = sec_req->data + 1;
|
|
data_len -= 1;
|
|
} else if (len_desc->byte_num == 2) {
|
|
sec_len = iot_bytes_to_uint16(sec_req->data, 1);
|
|
data_tmp = sec_req->data + 2;
|
|
data_len -= 2;
|
|
} else {
|
|
goto out;
|
|
}
|
|
}
|
|
if (data_len < sec_len) {
|
|
goto out;
|
|
}
|
|
if (sec_len < sizeof(*req)) {
|
|
goto out;
|
|
}
|
|
sec_len -= sizeof(*req);
|
|
req = (proto_69845_app_req_resp_t*)data_tmp;
|
|
switch (req->type) {
|
|
case PROTO_69845_C_APP_SET_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_set_handle(hdr_698, req->data,
|
|
sec_len, 1);
|
|
break;
|
|
}
|
|
case PROTO_69845_C_APP_ACTION_REQ:
|
|
{
|
|
resp_pkt = iot_sg_sta_ext_fj_action_handle(hdr_698, req->data,
|
|
sec_len, 1);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
out:
|
|
return resp_pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_fj_action_handle(proto_69845_frame_head_info_t *hdr_698,
|
|
uint8_t *data, uint32_t data_len, uint8_t is_security)
|
|
{
|
|
iot_pkt_t *pkt = NULL, *pkt_result = NULL;
|
|
uint8_t *ptr = data, i, *oad_data;
|
|
uint16_t pkt_result_len = IOT_SG_STA_EXT_FREEZR_CACHE_LEN;
|
|
uint32_t len = data_len, di, oad_data_len = 0, fill_len = 0;
|
|
proto_69845_app_action_req_t *req;
|
|
proto_69845_app_action_resp_t *resp;
|
|
proto_69845_app_action_req_list_t *req_lis;
|
|
proto_69845_app_action_resp_normal_list_t *resp_list = NULL;
|
|
proto_69845_app_omd_with_data_t *omd_with_data;
|
|
proto_69845_app_omd_with_dar_t *omd_with_dar;
|
|
proto_69845_app_len_descript_t *len_desc;
|
|
proto_69845_apdu_t *apdu = NULL;
|
|
addr_info_t addr_info = { 0 };
|
|
|
|
proto_69845_get_addr_info(hdr_698, &addr_info);
|
|
if (iot_mac_addr_cmp(addr_info.ser_info.addr, proto_645_bcast_addr)
|
|
|| ((addr_info.ser_info.type == PROTO_69845_SA_TYPE_BROADCAST)
|
|
&& (addr_info.ser_info.addr[0] == PROTO_69845_SA_BROADCAST_ADD))) {
|
|
/* broadcast command not supported */
|
|
goto out;
|
|
}
|
|
if (len < sizeof(*req)) {
|
|
iot_sg_printf("%s err\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*req);
|
|
len -= sizeof(*req);
|
|
req = (proto_69845_app_action_req_t*)data;
|
|
if (req->data_type != PROTO_69845_APP_ACTION_NORMALLIST) {
|
|
goto out;
|
|
}
|
|
if (len < sizeof(*req_lis)) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*req_lis);
|
|
len -= sizeof(*req_lis);
|
|
req_lis = (proto_69845_app_action_req_list_t *)req->data;
|
|
if (!req_lis->omd_cnt) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < req_lis->omd_cnt; i++) {
|
|
if (fill_len + sizeof(*omd_with_dar) > pkt_result_len) {
|
|
break;
|
|
}
|
|
omd_with_data = (proto_69845_app_omd_with_data_t *)ptr;
|
|
if (len < sizeof(*omd_with_data)) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*omd_with_data);
|
|
len -= sizeof(*omd_with_data);
|
|
di = iot_bytes_to_uint32((uint8_t*)&omd_with_data->omd, 1);
|
|
if (i == 0 && ((di & 0XFF000000) != PROTO_645_FJ_DI_FREEZE_TASK)) {
|
|
goto out;
|
|
}
|
|
if (!pkt_result) {
|
|
pkt_result = iot_pkt_alloc(pkt_result_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_result) {
|
|
goto out;
|
|
}
|
|
apdu = (proto_69845_apdu_t *)iot_pkt_put(pkt_result, pkt_result_len);
|
|
apdu->type = PROTO_69845_S_APP_ACTION_RESP;
|
|
resp = (proto_69845_app_action_resp_t *)apdu->data;
|
|
resp->data_type = PROTO_69845_APP_ACTION_NORMALLIST;
|
|
resp_list = (proto_69845_app_action_resp_normal_list_t *)resp->data;
|
|
resp_list->piid_acd.sn = req_lis->piid.sn;
|
|
resp_list->piid_acd.priority = req_lis->piid.priority;
|
|
fill_len += (sizeof(*apdu) + sizeof(*resp) + sizeof(*resp_list));
|
|
pkt_result_len -= (PROTO_69845_NO_FLW_DATA_LEN +
|
|
PROTO_69845_NO_TIME_TAG_LEN);
|
|
}
|
|
omd_with_dar = (proto_69845_app_omd_with_dar_t *)
|
|
(iot_pkt_data(pkt_result) + fill_len);
|
|
omd_with_dar->omd = omd_with_data->omd;
|
|
if (omd_with_data->data.data_type != PROTO_69845_APP_DATA_OCTET_STRING) {
|
|
goto out;
|
|
}
|
|
if (len < sizeof(*len_desc)) {
|
|
goto out;
|
|
}
|
|
if (proto_69845_get_data_len(&omd_with_data->data,
|
|
len, &oad_data_len) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*len_desc);
|
|
len -= sizeof(*len_desc);
|
|
len_desc = (proto_69845_app_len_descript_t *)omd_with_data->data.data;
|
|
oad_data = omd_with_data->data.data;
|
|
oad_data += sizeof(*len_desc);
|
|
oad_data_len -= (sizeof(omd_with_data->data) + sizeof(*len_desc));
|
|
if (len_desc->mub_flag) {
|
|
len -= len_desc->byte_num;
|
|
ptr += len_desc->byte_num;
|
|
oad_data += len_desc->byte_num;
|
|
oad_data_len -= len_desc->byte_num;
|
|
}
|
|
if (len < oad_data_len) {
|
|
goto out;
|
|
}
|
|
len -= oad_data_len;
|
|
ptr += oad_data_len;
|
|
fill_len += sizeof(*omd_with_dar);
|
|
resp_list->omd_cnt++;
|
|
omd_with_dar->dar = iot_sg_sta_ext_fj_action_data_handle(
|
|
addr_info.ser_info.addr, di, oad_data, (uint8_t)oad_data_len,
|
|
omd_with_dar->data, &fill_len, &omd_with_dar->optional,
|
|
pkt_result_len - fill_len);
|
|
}
|
|
fill_len += (PROTO_69845_NO_FLW_DATA_LEN + PROTO_69845_NO_TIME_TAG_LEN);
|
|
if (is_security) {
|
|
pkt = proto_69845_build_apdu_data_with_security_resp_msg(
|
|
(uint8_t *)apdu, fill_len, &addr_info);
|
|
} else {
|
|
pkt = proto_69845_build_apdu_data_msg((uint8_t *)apdu, fill_len,
|
|
&addr_info, PROTO_69845_D_P_SERVER_RESPONSE);
|
|
}
|
|
out:
|
|
if (pkt_result) {
|
|
iot_pkt_free(pkt_result);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_fj_set_handle(proto_69845_frame_head_info_t *hdr_698,
|
|
uint8_t *data, uint32_t data_len, uint8_t is_security)
|
|
{
|
|
iot_pkt_t *pkt = NULL, *pkt_result = NULL;
|
|
uint8_t *ptr = data, i, pkt_result_len, *oad_data, addr[IOT_MAC_ADDR_LEN];
|
|
uint32_t len = data_len, di, oad_data_len = 0;
|
|
proto_69845_app_set_req_t *set;
|
|
proto_69845_app_set_req_normal_list_t *normal_list;
|
|
proto_69845_app_oad_with_data_t *oad_with_data;
|
|
proto_69845_app_oad_with_dar_t *oad_with_dar = NULL;
|
|
proto_69845_app_len_descript_t *len_desc;
|
|
addr_info_t addr_info = { 0 };
|
|
|
|
proto_69845_get_addr_info(hdr_698, &addr_info);
|
|
if ((addr_info.ser_info.type == PROTO_69845_SA_TYPE_BROADCAST)
|
|
&& (addr_info.ser_info.addr[0] == PROTO_69845_SA_BROADCAST_ADD)) {
|
|
iot_mac_addr_cpy(addr, proto_645_bcast_addr);
|
|
} else {
|
|
iot_mac_addr_cpy(addr, addr_info.ser_info.addr);
|
|
}
|
|
if (len < sizeof(*set)) {
|
|
iot_sg_printf("%s err\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*set);
|
|
len -= sizeof(*set);
|
|
set = (proto_69845_app_set_req_t*)data;
|
|
if (set->data_type != PROTO_69845_APP_SET_NORMALLIST) {
|
|
goto out;
|
|
}
|
|
if (len < sizeof(*normal_list)) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*normal_list);
|
|
len -= sizeof(*normal_list);
|
|
normal_list = (proto_69845_app_set_req_normal_list_t *)set->data;
|
|
if (!normal_list->oad_cnt) {
|
|
goto out;
|
|
}
|
|
for (i = 0; i < normal_list->oad_cnt; i++) {
|
|
oad_with_data = (proto_69845_app_oad_with_data_t *)ptr;
|
|
if (len < sizeof(*oad_with_data)) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*oad_with_data);
|
|
len -= sizeof(*oad_with_data);
|
|
di = iot_bytes_to_uint32((uint8_t*)&oad_with_data->oad, 1);
|
|
if (i == 0 && ((di & 0XFF000000) != PROTO_645_FJ_DI_FREEZE_TASK)) {
|
|
goto out;
|
|
}
|
|
if (!pkt_result) {
|
|
pkt_result_len = normal_list->oad_cnt * sizeof(*oad_with_dar);
|
|
pkt_result = iot_pkt_alloc(pkt_result_len, IOT_SMART_GRID_MID);
|
|
if (!pkt_result) {
|
|
goto out;
|
|
}
|
|
oad_with_dar = (proto_69845_app_oad_with_dar_t *)
|
|
iot_pkt_put(pkt_result, pkt_result_len);
|
|
}
|
|
oad_with_dar[i].oad = oad_with_data->oad;
|
|
if (oad_with_data->data.data_type != PROTO_69845_APP_DATA_OCTET_STRING) {
|
|
goto out;
|
|
}
|
|
if (len < sizeof(*len_desc)) {
|
|
goto out;
|
|
}
|
|
if (proto_69845_get_data_len(&oad_with_data->data,
|
|
len, &oad_data_len) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
ptr += sizeof(*len_desc);
|
|
len -= sizeof(*len_desc);
|
|
len_desc = (proto_69845_app_len_descript_t *)oad_with_data->data.data;
|
|
oad_data = oad_with_data->data.data;
|
|
oad_data += sizeof(*len_desc);
|
|
oad_data_len -= (sizeof(oad_with_data->data) + sizeof(*len_desc));
|
|
if (len_desc->mub_flag) {
|
|
len -= len_desc->byte_num;
|
|
ptr += len_desc->byte_num;
|
|
oad_data += len_desc->byte_num;
|
|
oad_data_len -= len_desc->byte_num;
|
|
}
|
|
if (len < oad_data_len) {
|
|
goto out;
|
|
}
|
|
len -= oad_data_len;
|
|
ptr += oad_data_len;
|
|
oad_with_dar[i].dar = iot_sg_sta_ext_fj_set_data_handle(
|
|
addr, di, oad_data, (uint8_t)oad_data_len);
|
|
}
|
|
pkt = iot_iot_sg_sta_ext_set_data_resp(&addr_info, &normal_list->piid,
|
|
oad_with_dar, normal_list->oad_cnt, is_security);
|
|
out:
|
|
if (pkt_result) {
|
|
iot_pkt_free(pkt_result);
|
|
}
|
|
return pkt;
|
|
}
|
|
|
|
static iot_pkt_t *iot_sg_sta_ext_fj_build_multi_di_read_resp(uint8_t *addr,
|
|
uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i, resp_data_len = 0, fill_len, req_di[PROTO_645_2007_DI_LEN];
|
|
uint8_t *req_list_data, *fill_data, reason = 0;
|
|
iot_pkt_t *pkt = NULL, *resp_pkt = NULL, *single_di_pkt;
|
|
proto_645_fj_multi_di_read_t *req_read, *resp_read;
|
|
proto_645_fj_multi_di_list_t *req_list, *resp_list;
|
|
proto_645_header_t *hdr;
|
|
|
|
if (!addr || !data || len <= PROTO_645_2007_DI_LEN) {
|
|
reason = 1;
|
|
goto nack;
|
|
}
|
|
proto_645_sub33_handle(data, len);
|
|
len -= PROTO_645_2007_DI_LEN;
|
|
if (len < sizeof(*req_read)) {
|
|
reason = 2;
|
|
goto nack;
|
|
}
|
|
len -= sizeof(*req_read);
|
|
req_read = (proto_645_fj_multi_di_read_t *)(data + PROTO_645_2007_DI_LEN);
|
|
if (req_read->di_cnt < PROTO_645_FJ_MULTI_DI_MIN_CNT ||
|
|
req_read->di_cnt > PROTO_645_FJ_MULTI_DI_MAX_CNT) {
|
|
reason = 3;
|
|
goto nack;
|
|
}
|
|
req_list_data = req_read->di_list;
|
|
pkt = iot_pkt_alloc(PROTO_645_FJ_MULTI_DI_RESP_MAX_LEN,
|
|
IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
reason = 4;
|
|
goto nack;
|
|
}
|
|
resp_read = (proto_645_fj_multi_di_read_t *)iot_pkt_data(pkt);
|
|
resp_data_len += sizeof(*resp_read);
|
|
for (i = 0; i < req_read->di_cnt; i++) {
|
|
if (len < sizeof(*req_list)) {
|
|
reason = 5;
|
|
goto nack;
|
|
}
|
|
req_list = (proto_645_fj_multi_di_list_t *)req_list_data;
|
|
if (req_list->len < PROTO_645_FJ_MULTI_DI_DATA_MIN_LEN ||
|
|
req_list->len > PROTO_645_FJ_MULTI_DI_DATA_MAX_LEN) {
|
|
reason = 6;
|
|
goto nack;
|
|
}
|
|
len -= sizeof(*req_list);
|
|
if (req_list->len > len) {
|
|
reason = 7;
|
|
goto nack;
|
|
}
|
|
len -= req_list->len;
|
|
req_list_data += (req_list->len + sizeof(*req_list));
|
|
os_mem_cpy(req_di, req_list->data, PROTO_645_2007_DI_LEN);
|
|
proto_645_add33_handle(req_list->data, req_list->len);
|
|
single_di_pkt = iot_sg_sta_ext_fj_build_single_di_read_resp(addr,
|
|
req_list->data, req_list->len, proto_645_2007_byte_to_di(req_di), 0);
|
|
if (single_di_pkt) {
|
|
hdr = proto_645_format_check(iot_pkt_data(single_di_pkt),
|
|
iot_pkt_data_len(single_di_pkt), PROTO_645_DIR_SLAVE);
|
|
if (hdr && hdr->control.ack == PROTO_645_ACK_NORMAL) {
|
|
fill_data = hdr->data;
|
|
fill_len = hdr->len;
|
|
proto_645_sub33_handle(fill_data, fill_len);
|
|
} else {
|
|
fill_data = req_di;
|
|
fill_len = PROTO_645_2007_DI_LEN;
|
|
}
|
|
} else {
|
|
fill_data = req_di;
|
|
fill_len = PROTO_645_2007_DI_LEN;
|
|
}
|
|
if (sizeof(*resp_list) + fill_len + resp_data_len >
|
|
PROTO_645_FJ_MULTI_DI_RESP_MAX_LEN) {
|
|
if (single_di_pkt) {
|
|
iot_pkt_free(single_di_pkt);
|
|
}
|
|
break;
|
|
}
|
|
resp_list = (proto_645_fj_multi_di_list_t *)((uint8_t *)resp_read +
|
|
resp_data_len);
|
|
resp_list->len = fill_len;
|
|
resp_data_len += sizeof(resp_list->len);
|
|
os_mem_cpy(resp_list->data, fill_data, fill_len);
|
|
resp_data_len += fill_len;
|
|
resp_read->di_cnt++;
|
|
if (single_di_pkt) {
|
|
iot_pkt_free(single_di_pkt);
|
|
}
|
|
}
|
|
resp_pkt = proto_645_fj_build_msg(addr, (uint8_t *)resp_read,
|
|
resp_data_len, PROTO_645_FJ_MULTI_DI_READ, PROTO_645_2007_FN_READ_DATA);
|
|
goto out;
|
|
nack:
|
|
resp_pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
iot_sg_printf("%s nack reason %d\n", __FUNCTION__, reason);
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return resp_pkt;
|
|
}
|
|
|
|
void iot_sg_sta_ext_fj_power_up_down_record_handle(uint8_t type)
|
|
{
|
|
uint8_t is_overlast = 0;
|
|
uint32_t ret, reason = 0;
|
|
int64_t run_time, delay_time;
|
|
uint16_t power_down_cnt = 0;
|
|
iot_time_tm_t tm, tm_power_down;
|
|
iot_sg_sta_flash_fj_pwr_rec_t record = {0};
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
if (iot_sg_sta_get_user_type() != USER_TYPE_STATE_GRID_FUJIAN) {
|
|
goto out;
|
|
}
|
|
if (type == IOT_SG_STA_POWER_REC_TYPE_CLEAR) {
|
|
iot_sg_sta_flash_fj_pwr_record_clear();
|
|
goto out;
|
|
}
|
|
ret = iot_sg_sta_flash_fj_pwr_record_get(&record, 1);
|
|
if (type == IOT_SG_STA_POWER_REC_TYPE_UP) {
|
|
/* power on event */
|
|
if (ret || record.flag_valid_power_on == 1) {
|
|
/**
|
|
* if there is no power off record or power on record already
|
|
* exists, the power on record will not be modify.
|
|
*/
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if(sta_glb->tm_soc == PROTO_645_FJ_MOD_TM_SOC_NET)
|
|
{
|
|
if (iot_sg_sta_rtc_get(&tm, 1) != ERR_OK) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
} else {
|
|
if (iot_sg_sta_rtc_get(&tm, 0) != ERR_OK) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
}
|
|
iot_sg_printf("%s record 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);
|
|
if (!iot_sg_sta_power_off_check()) {
|
|
/**
|
|
* While power in normal,
|
|
* Set the system startup time as power on time.
|
|
*/
|
|
run_time = os_boot_time64() / 1000;
|
|
/**
|
|
* The time interval between the power on of the processing module
|
|
* and the start of the program.
|
|
*/
|
|
run_time += IOT_SG_STA_POWER_UP_CHARGING_TIME;
|
|
iot_rtc_delta_add(-run_time, &tm);
|
|
}
|
|
tm_power_down.tm_year = record.power_off_year + 2000;
|
|
tm_power_down.tm_mon = (uint8_t)record.power_off_month;
|
|
tm_power_down.tm_mday = (uint8_t)record.power_off_day;
|
|
tm_power_down.tm_hour = (uint8_t)record.power_off_hour;
|
|
tm_power_down.tm_min = (uint8_t)record.power_off_minute;
|
|
tm_power_down.tm_sec = (uint8_t)record.power_off_second;
|
|
if (iot_rtc_delta_calc(&tm_power_down, &tm) < 0) {
|
|
os_mem_set(&tm, 0, sizeof(tm));
|
|
tm.tm_year = 2000;
|
|
tm.tm_mon = 1;
|
|
tm.tm_mday = 1;
|
|
}
|
|
record.power_on_year = (uint8_t)(tm.tm_year - 2000);
|
|
record.power_on_month = tm.tm_mon;
|
|
record.power_on_day = tm.tm_mday;
|
|
record.power_on_hour = tm.tm_hour;
|
|
record.power_on_minute = tm.tm_min;
|
|
record.power_on_second = tm.tm_sec;
|
|
record.flag_valid_power_on = 1;
|
|
is_overlast = 1;
|
|
iot_sg_printf("%s power up[%lu] %lu-%lu-%lu %lu:%lu:%lu\n",
|
|
__FUNCTION__, sta_glb->tm_soc, tm.tm_year, tm.tm_mon, tm.tm_mday,
|
|
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
|
} else if (type == IOT_SG_STA_POWER_REC_TYPE_DOWN) {
|
|
if (ret == ERR_OK) {
|
|
power_down_cnt = record.power_down_cnt;
|
|
}
|
|
os_mem_set((uint8_t *)&record, 0x0, sizeof(record));
|
|
if (sta_glb->tm_soc == PROTO_645_FJ_MOD_TM_SOC_NET) {
|
|
ret = iot_sg_sta_rtc_get(&tm, 1);
|
|
} else {
|
|
ret = iot_sg_sta_rtc_get(&tm, 0);
|
|
}
|
|
if (ret == ERR_OK) {
|
|
/* Calculate the time when the power down occurred */
|
|
delay_time = sta_glb->evt.fj_pd_valid_time +
|
|
IOT_SG_STA_POWER_DOWN_DETECTED_LAG_TIME;
|
|
iot_rtc_delta_add(-delay_time, &tm);
|
|
} else {
|
|
os_mem_set(&tm, 0, sizeof(tm));
|
|
tm.tm_year = 2000;
|
|
tm.tm_mon = 1;
|
|
tm.tm_mday = 1;
|
|
}
|
|
record.power_off_year = (uint8_t)(tm.tm_year - 2000);
|
|
record.power_off_month = tm.tm_mon;
|
|
record.power_off_day = tm.tm_mday;
|
|
record.power_off_hour = tm.tm_hour;
|
|
record.power_off_minute = tm.tm_min;
|
|
record.power_off_second = tm.tm_sec;
|
|
record.flag_valid_power_off = 1;
|
|
record.flag_valid_power_on = 0;
|
|
record.power_down_cnt = power_down_cnt + 1;
|
|
iot_sg_printf("%s power down[%lu] %lu-%lu-%lu %lu:%lu:%lu\n",
|
|
__FUNCTION__, sta_glb->tm_soc, tm.tm_year, tm.tm_mon, tm.tm_mday,
|
|
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
|
} else {
|
|
reason = 6;
|
|
goto drop;
|
|
}
|
|
iot_sg_sta_flash_fj_pwr_record_save(&record, is_overlast);
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s drop %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
iot_pkt_t *iot_sg_sta_ext_fj_func(uint8_t *addr, uint8_t fn,
|
|
uint32_t di, uint8_t *data, uint8_t len)
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
iot_sg_printf("%s fn:%02x di:%08x\n", __FUNCTION__, fn, di);
|
|
switch (fn) {
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
if (di == PROTO_645_FJ_MULTI_DI_READ) {
|
|
pkt = iot_sg_sta_ext_fj_build_multi_di_read_resp(addr, data, len);
|
|
} else {
|
|
pkt = iot_sg_sta_ext_fj_build_single_di_read_resp(addr, data, len,
|
|
di, 1);
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
switch (di) {
|
|
case PROTO_645_FJ_DI_MOD_TM:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_mod_tm(addr, fn, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_CT_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_ct_dur(addr, fn, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_CT_NTB:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_ntb_ct(addr, fn, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MOD_TM_SOC:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_tm_soc(addr, fn, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_EVT_RPT_CFG:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_evt_rpt_cfg(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_DEL_TASK:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_del_task(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_REC_MAX_LEN:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rec_max_len(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_MAX_CNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rpt_max_cnt(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RANDOM_RPT_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_random_rpt_time(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_TAST_RESET:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_task_restart(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_RPT_MODE:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_report_mode(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_MULTI_RPT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_multi_rpt(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_RPT_RETRY_COUNT:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_rpt_retry_count(addr, data,len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_METER_MULTI_DATA_ITEM:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_meter_multi_data_flag(addr, data, len);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_SET_TASK_STOP_DUR:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_stop_dur(addr, data, len, 0);
|
|
break;
|
|
}
|
|
case PROTO_645_FJ_DI_PD_EVT_VALID_TIME:
|
|
{
|
|
pkt = iot_sg_sta_ext_fj_write_pd_valid_time(addr, data, len);
|
|
break;
|
|
}
|
|
default:
|
|
if ((di & 0xffffff00) == PROTO_645_FJ_DI_SET_TASK) {
|
|
pkt = iot_sg_sta_ext_fj_write_task(addr, di, data, len, 0);
|
|
} else if ((di & 0xffff0000) == PROTO_645_FJ_DI_QR_TASK_DATA) {
|
|
/* EBE0xxxx not support, response nack */
|
|
pkt = proto_645_2007_build_nack_msg(PROTO_645_FJ_ERR_OTHER, addr,
|
|
PROTO_645_2007_FN_WRITE_DATA);
|
|
}
|
|
/* no relevant DI, forward to meter */
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_DATA_C:
|
|
{
|
|
/* todo */
|
|
break;
|
|
}
|
|
default:
|
|
/* no relevant FN, forward to meter */
|
|
break;
|
|
}
|
|
|
|
return pkt;
|
|
}
|
|
|
|
void iot_sg_sta_fj_tm_cfg_init(void)
|
|
{
|
|
iot_pkt_t *ct_cfg_pkt = NULL;
|
|
iot_sg_sta_flash_fj_ct_cfg_t *ct_cfg;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
ct_cfg_pkt =
|
|
iot_pkt_alloc(sizeof(iot_sg_sta_flash_fj_ct_cfg_t), IOT_SMART_GRID_MID);
|
|
if (ct_cfg_pkt == NULL) {
|
|
/* native use default value */
|
|
sta_glb->tm_soc = PROTO_645_FJ_MOD_TM_SOC_NET;
|
|
sta_glb->ct_dur = PROTO_645_FJ_MOD_CT_DUR_DEFAULT;
|
|
goto out;
|
|
}
|
|
ct_cfg = (iot_sg_sta_flash_fj_ct_cfg_t *)iot_pkt_data(ct_cfg_pkt);
|
|
if (iot_sg_sta_flash_fj_ct_cfg_get(ct_cfg) != ERR_OK) {
|
|
goto def;
|
|
}
|
|
sta_glb->tm_soc = ct_cfg->tm_soc;
|
|
sta_glb->ct_dur = ct_cfg->ct_dur;
|
|
goto out;
|
|
|
|
def:
|
|
/* native use default value */
|
|
sta_glb->tm_soc = PROTO_645_FJ_MOD_TM_SOC_NET;
|
|
sta_glb->ct_dur = PROTO_645_FJ_MOD_CT_DUR_DEFAULT;
|
|
/* save default value to flash */
|
|
ct_cfg->tm_soc = PROTO_645_FJ_MOD_TM_SOC_NET;
|
|
ct_cfg->ct_dur = PROTO_645_FJ_MOD_CT_DUR_DEFAULT;
|
|
iot_sg_sta_flash_fj_ct_cfg_save(ct_cfg);
|
|
out:
|
|
if (ct_cfg_pkt) {
|
|
iot_pkt_free(ct_cfg_pkt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void iot_sg_sta_fj_evt_rpt_init(void)
|
|
{
|
|
iot_sg_sta_evt_global_t *evt_glb = &p_sg_glb->desc.sta->evt;
|
|
iot_sg_sta_flash_fj_evt_rpt_cfg_t *fj_evt_cfg;
|
|
iot_pkt_t *pkt = NULL;
|
|
pkt = iot_pkt_alloc(sizeof(*fj_evt_cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
return;
|
|
};
|
|
fj_evt_cfg = (iot_sg_sta_flash_fj_evt_rpt_cfg_t *)iot_pkt_put(
|
|
pkt, sizeof(*fj_evt_cfg));
|
|
|
|
if (iot_sg_sta_flash_fj_evt_rpt_cfg_get(fj_evt_cfg) == ERR_OK) {
|
|
evt_glb->fj_evt_rpt_mode = fj_evt_cfg->fj_evt_rpt_mode;
|
|
evt_glb->fj_evt_rpt_type = fj_evt_cfg->fj_evt_rpt_type;
|
|
evt_glb->fj_evt_rpt_en = fj_evt_cfg->fj_evt_rpt_en;
|
|
} else {
|
|
/* default is IOT_SG_STA_FJ_EVT_RPT_TYPE_OCCUR */
|
|
evt_glb->fj_evt_rpt_type = IOT_SG_STA_FJ_EVT_RPT_TYPE_OCCUR;
|
|
/* default is IOT_SG_STA_FJ_EVT_RPT_MODE_EXT */
|
|
evt_glb->fj_evt_rpt_mode = IOT_SG_STA_FJ_EVT_RPT_MODE_EXT;
|
|
/* default is 1, event report enable when report mode is fujian ext */
|
|
evt_glb->fj_evt_rpt_en = 1;
|
|
fj_evt_cfg->fj_evt_rpt_mode = evt_glb->fj_evt_rpt_mode;
|
|
fj_evt_cfg->fj_evt_rpt_type = evt_glb->fj_evt_rpt_type;
|
|
fj_evt_cfg->fj_evt_rpt_en = evt_glb->fj_evt_rpt_en;
|
|
iot_sg_sta_flash_fj_evt_rpt_cfg_save(fj_evt_cfg);
|
|
}
|
|
iot_printf("%s - mode %lu, type %lu, enable %lu\n", __FUNCTION__,
|
|
evt_glb->fj_evt_rpt_mode, evt_glb->fj_evt_rpt_type,
|
|
evt_glb->fj_evt_rpt_en);
|
|
iot_pkt_free(pkt);
|
|
return;
|
|
}
|
|
|
|
void iot_sg_sta_fj_pd_cfg_init(void)
|
|
{
|
|
iot_sg_sta_evt_global_t *evt_glb = &p_sg_glb->desc.sta->evt;
|
|
iot_sg_sta_flash_fj_pwr_rpt_cfg_t *cfg;
|
|
iot_pkt_t *pkt;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*cfg), IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
evt_glb->fj_pd_valid_time = IOT_SG_STA_FJ_PD_EVT_VALID_TIME_DFT;
|
|
return;
|
|
}
|
|
cfg = (iot_sg_sta_flash_fj_pwr_rpt_cfg_t *)iot_pkt_put(pkt, sizeof(*cfg));
|
|
if (iot_sg_sta_flash_fj_pwr_rpt_cfg_get(cfg) == ERR_OK) {
|
|
evt_glb->fj_pd_valid_time = cfg->pd_valid_time;
|
|
} else {
|
|
/* default is 5, IOT_SG_STA_FJ_PD_EVT_VALID_TIME_DFT */
|
|
evt_glb->fj_pd_valid_time = IOT_SG_STA_FJ_PD_EVT_VALID_TIME_DFT;
|
|
cfg->pd_valid_time = evt_glb->fj_pd_valid_time;
|
|
iot_sg_sta_flash_fj_pwr_rpt_cfg_save(cfg);
|
|
}
|
|
iot_pkt_free(pkt);
|
|
}
|
|
|
|
#endif /* IOT_SMART_GRID_EXT_FJ_FUNC_ENABLE */
|