561 lines
19 KiB
C
561 lines
19 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
|
|
/* os_shim header files */
|
|
#include "os_utils_api.h"
|
|
|
|
/* iot common header files */
|
|
#include "iot_io_api.h"
|
|
#include "iot_oem_api.h"
|
|
|
|
/* smart grid internal header files */
|
|
#include "iot_sg.h"
|
|
#include "iot_sg_sta.h"
|
|
#include "proto_645.h"
|
|
#include "proto_69845.h"
|
|
|
|
#if IOT_SMART_GRID_EXT_TM_FUNC_ENABLE
|
|
|
|
/* define time management auto handle interval time. unit is 1s */
|
|
#define IOT_SG_STA_AUTO_TM_INTERVAL (3600 * 25)
|
|
|
|
/* define max delta threshold to save pib, unit is 1min */
|
|
#define IOT_SG_STA_MAX_DELTA_THRESHOLD (1023)
|
|
|
|
/* define correct time delta time, uint is 1s. */
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_MAX (30 * 60)
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_MIN (5 * 60)
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_STOP (5)
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_FIX (4 * 60 + 30)
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_MAX_HLJ (5 * 60)
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_MIN_HLJ (5)
|
|
|
|
#define IOT_SG_STA_CORRECT_TIME_DELTA_HOUR_MAX (9999)
|
|
|
|
/* define auto correct time way */
|
|
#define IOT_SG_STA_AUTO_CT_WAY_INVALID (0)
|
|
#define IOT_SG_STA_AUTO_CT_WAY_FIX_TIME (1)
|
|
#define IOT_SG_STA_AUTO_CT_WAY_CUR_TIME (2)
|
|
|
|
void iot_sg_sta_ext_auto_tm_init(uint8_t *addr)
|
|
{
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_app_info_t *sta_pib = iot_sg_sta_get_rw_pib();
|
|
iot_sg_sta_tm_info_t *auto_tm = &sta_glb->tm_info;
|
|
|
|
if (user_type != USER_TYPE_STATE_GRID_HLJ &&
|
|
user_type != USER_TYPE_STATE_GRID_GANSU &&
|
|
user_type != USER_TYPE_SOUTHEN_POWER_GRID_SHENZHEN) {
|
|
goto out;
|
|
}
|
|
os_mem_set(auto_tm, 0, sizeof(*auto_tm));
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ) {
|
|
auto_tm->threshold = 5 * 60;
|
|
auto_tm->rpt_flag = 1;
|
|
}
|
|
if (!iot_mac_addr_valid(addr)) {
|
|
goto out;
|
|
}
|
|
if (!iot_mac_addr_valid(sta_pib->pm_addr)) {
|
|
goto out;
|
|
}
|
|
if (!iot_mac_addr_cmp(addr, sta_pib->pm_addr)) {
|
|
goto out;
|
|
}
|
|
auto_tm->auto_flag = sta_pib->auto_corr;
|
|
/* time management delta threshold init */
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ) {
|
|
if (sta_pib->delta_mode) {
|
|
auto_tm->threshold = sta_pib->delta_threshold * 60;
|
|
}
|
|
}
|
|
iot_sg_printf("%s auto_flag %lu, threshold %lu s\n", __FUNCTION__,
|
|
auto_tm->auto_flag, auto_tm->threshold);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
void iot_sg_sta_ext_auto_tm_update(void)
|
|
{
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_tm_info_t *auto_tm = &sta_glb->tm_info;
|
|
|
|
if (user_type != USER_TYPE_STATE_GRID_HLJ &&
|
|
user_type != USER_TYPE_STATE_GRID_GANSU &&
|
|
user_type != USER_TYPE_SOUTHEN_POWER_GRID_SHENZHEN) {
|
|
return;
|
|
}
|
|
if (auto_tm->auto_delay) {
|
|
auto_tm->auto_delay--;
|
|
if ((auto_tm->auto_delay % 3600) == 0) {
|
|
iot_sg_printf("%s left auto_delay %luh\n", __FUNCTION__,
|
|
auto_tm->auto_delay / 3600);
|
|
}
|
|
}
|
|
if (auto_tm->rpt_delay) {
|
|
auto_tm->rpt_delay--;
|
|
if ((auto_tm->rpt_delay % 3600) == 0) {
|
|
iot_sg_printf("%s left rpt_delay %luh\n", __FUNCTION__,
|
|
auto_tm->rpt_delay / 3600);
|
|
}
|
|
}
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_auto_ct_interval_check(int64_t interval,
|
|
uint8_t *flag_stop)
|
|
{
|
|
uint8_t ct_way = IOT_SG_STA_AUTO_CT_WAY_INVALID;
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ) {
|
|
if (IOT_ABS(interval) > IOT_SG_STA_CORRECT_TIME_DELTA_MAX_HLJ) {
|
|
ct_way = IOT_SG_STA_AUTO_CT_WAY_FIX_TIME;
|
|
} else if (IOT_ABS(interval) > IOT_SG_STA_CORRECT_TIME_DELTA_MIN_HLJ){
|
|
ct_way = IOT_SG_STA_AUTO_CT_WAY_CUR_TIME;
|
|
}
|
|
goto out;
|
|
} else {
|
|
if (IOT_ABS(interval) <= IOT_SG_STA_CORRECT_TIME_DELTA_MAX &&
|
|
IOT_ABS(interval) >= IOT_SG_STA_CORRECT_TIME_DELTA_MIN) {
|
|
ct_way = IOT_SG_STA_AUTO_CT_WAY_FIX_TIME;
|
|
} else if (IOT_ABS(interval) >= IOT_SG_STA_CORRECT_TIME_DELTA_STOP &&
|
|
IOT_ABS(interval) < IOT_SG_STA_CORRECT_TIME_DELTA_MIN) {
|
|
ct_way = IOT_SG_STA_AUTO_CT_WAY_CUR_TIME;
|
|
}
|
|
if (ct_way == IOT_SG_STA_AUTO_CT_WAY_INVALID ||
|
|
user_type == USER_TYPE_SOUTHEN_POWER_GRID_GX) {
|
|
/* GX auto ct execute only once */
|
|
*flag_stop = 1;
|
|
}
|
|
goto out;
|
|
}
|
|
out:
|
|
return ct_way;
|
|
}
|
|
|
|
static int64_t iot_sg_sta_ext_delay_fix_get()
|
|
{
|
|
int64_t delay_fix;
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ) {
|
|
delay_fix = IOT_SG_STA_CORRECT_TIME_DELTA_MAX_HLJ;
|
|
} else {
|
|
delay_fix = IOT_SG_STA_CORRECT_TIME_DELTA_FIX;
|
|
}
|
|
return delay_fix;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_cache_time_get(iot_time_tm_t *tm)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
int64_t delta_time;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
if (!tm || !iot_time_valid(&sta_glb->tm_info.cache_time) ||
|
|
!sta_glb->tm_info.cache_time_ts) {
|
|
ret = ERR_FAIL;
|
|
goto out;
|
|
}
|
|
*tm = sta_glb->tm_info.cache_time;
|
|
delta_time = (os_boot_time64() / 1000) - sta_glb->tm_info.cache_time_ts;
|
|
iot_rtc_delta_add(delta_time, tm);
|
|
os_mem_set(&sta_glb->tm_info.cache_time, 0x0,
|
|
sizeof(sta_glb->tm_info.cache_time));
|
|
sta_glb->tm_info.cache_time_ts = 0;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_auto_ct(iot_time_tm_t *tm, uint8_t *flag_stop)
|
|
{
|
|
uint8_t addr[IOT_MAC_ADDR_LEN], ct_way;
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
uint32_t ret = ERR_FAIL;
|
|
int64_t interval, delay_fix;
|
|
iot_pkt_t *pkt;
|
|
iot_time_tm_t sys_tm, curr_tm;
|
|
proto_645_corr_time_t time;
|
|
server_addr_info_t server_addr = {0};
|
|
proto_69845_app_piid_t piid;
|
|
iot_sg_sta_node_desc_t *node;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
|
|
iot_mac_addr_cpy(addr, p_sg_glb->plc_state.addr);
|
|
iot_mac_addr_reverse(addr);
|
|
node = iot_sg_sta_node_find_by_addr(addr);
|
|
if (node == NULL) {
|
|
goto out;
|
|
}
|
|
curr_tm = *tm;
|
|
if (user_type == USER_TYPE_SOUTHEN_POWER_GRID_GX) {
|
|
if (iot_sg_sta_ext_cache_time_get(&sys_tm) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (iot_sg_sta_rtc_get(&sys_tm, 1) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
}
|
|
iot_sg_printf("%s sys time %02d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
|
|
sys_tm.tm_year, sys_tm.tm_mon, sys_tm.tm_mday,
|
|
sys_tm.tm_hour, sys_tm.tm_min, sys_tm.tm_sec);
|
|
interval = iot_rtc_delta_calc(&curr_tm, &sys_tm);
|
|
ct_way = iot_sg_sta_ext_auto_ct_interval_check(interval, flag_stop);
|
|
if (ct_way == IOT_SG_STA_AUTO_CT_WAY_FIX_TIME) {
|
|
delay_fix = iot_sg_sta_ext_delay_fix_get();
|
|
if (interval > 0) {
|
|
iot_rtc_delta_add(delay_fix, &curr_tm);
|
|
} else {
|
|
iot_rtc_delta_add(0 - delay_fix, &curr_tm);
|
|
}
|
|
} else if (ct_way == IOT_SG_STA_AUTO_CT_WAY_CUR_TIME){
|
|
curr_tm = sys_tm;
|
|
} else {
|
|
goto out;
|
|
}
|
|
if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
|
|
server_addr.type = PROTO_69845_SA_TYPE_BROADCAST;
|
|
server_addr.len = 1;
|
|
server_addr.addr[0] = PROTO_69845_SA_BROADCAST_ADD;
|
|
server_addr.logical_addr = 0;
|
|
piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
|
|
piid.sn = 0;
|
|
piid.reserved = 0;
|
|
if (sta_glb->tm_info.tm_mode_698 ==
|
|
IOT_SG_STA_698_CORR_TIME_MODE_NO_RN) {
|
|
pkt = proto_69845_build_corr_msg(&server_addr, &curr_tm, &piid, 0);
|
|
} else {
|
|
pkt = proto_69845_build_corr_msg(&server_addr, &curr_tm, &piid, 1);
|
|
}
|
|
if (pkt == NULL) {
|
|
goto out;
|
|
}
|
|
if (sta_glb->drv->correct_time(pkt, 0) == ERR_OK) {
|
|
sta_glb->tm_info.tm_mode_698++;
|
|
if (sta_glb->tm_info.tm_mode_698 >
|
|
IOT_SG_STA_698_CORR_TIME_MODE_WITH_RN) {
|
|
sta_glb->tm_info.tm_mode_698 = 0;
|
|
ret = ERR_OK;
|
|
}
|
|
}
|
|
} else {
|
|
time.year = iot_byte_to_bcd((uint8_t)(curr_tm.tm_year - 2000));
|
|
time.month = iot_byte_to_bcd(curr_tm.tm_mon);
|
|
time.day = iot_byte_to_bcd(curr_tm.tm_mday);
|
|
time.hour = iot_byte_to_bcd(curr_tm.tm_hour);
|
|
time.minute = iot_byte_to_bcd(curr_tm.tm_min);
|
|
time.second = iot_byte_to_bcd(curr_tm.tm_sec);
|
|
pkt = proto_645_build_corr_msg(NULL, &time);
|
|
if (pkt == NULL) {
|
|
goto out;
|
|
}
|
|
ret = sta_glb->drv->correct_time(pkt, 0);
|
|
}
|
|
iot_sg_printf("%s time %02d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
|
|
curr_tm.tm_year, curr_tm.tm_mon, curr_tm.tm_mday,
|
|
curr_tm.tm_hour, curr_tm.tm_min, curr_tm.tm_sec);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_clock_skew_report_hn(uint8_t new_evt, int64_t interval)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t length, addr[IOT_MAC_ADDR_LEN];
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_evt_global_t *evt = &sta_glb->evt;
|
|
iot_time_tm_t time = { 0 };
|
|
proto_645_07_clock_skew_t *clock_skew;
|
|
proto_645_header_t *hdr = NULL;
|
|
|
|
if (iot_sg_sta_get_user_type() != USER_TYPE_STATE_GRID_HUNAN) {
|
|
goto out;
|
|
}
|
|
if (evt->retry_cnt >= 3) {
|
|
iot_sg_printf("%s retry end, cnt %d\n", __FUNCTION__, evt->retry_cnt);
|
|
iot_sg_module_report_reset_status(0);
|
|
goto out;
|
|
}
|
|
if (interval == 0) {
|
|
goto out;
|
|
}
|
|
length = sizeof(proto_645_header_t) + sizeof(proto_645_tailer_t) +
|
|
sizeof(*clock_skew);
|
|
pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
sta_glb->drv->get_login_addr(addr);
|
|
hdr = (proto_645_header_t *)iot_pkt_data(pkt);
|
|
proto_645_header_init(hdr, addr, PROTO_645_2007_FN_CLOCK_SKEW,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
|
|
hdr->len = sizeof(*clock_skew);
|
|
clock_skew = (proto_645_07_clock_skew_t *)hdr->data;
|
|
if (interval > 0) {
|
|
clock_skew->mode = PROTO_645_CS_MODE_METER_BELOW_CCTT;
|
|
} else {
|
|
clock_skew->mode = PROTO_645_CS_MODE_METER_ABOVE_CCTT;
|
|
}
|
|
time.tm_year = 2000;
|
|
time.tm_mon = 1;
|
|
time.tm_mday = 1;
|
|
iot_rtc_delta_add(IOT_ABS(interval), &time);
|
|
clock_skew->time.year = iot_byte_to_bcd((uint8_t)(time.tm_year - 2000));
|
|
clock_skew->time.month = iot_byte_to_bcd(time.tm_mon - 1);
|
|
clock_skew->time.day = iot_byte_to_bcd(time.tm_mday - 1);
|
|
clock_skew->time.hour = iot_byte_to_bcd(time.tm_hour);
|
|
clock_skew->time.minute = iot_byte_to_bcd(time.tm_min);
|
|
clock_skew->time.second = iot_byte_to_bcd(time.tm_sec);
|
|
proto_645_add33_handle(hdr->data, hdr->len);
|
|
/* fill in 645 tailer */
|
|
proto_645_tail_init(hdr);
|
|
iot_pkt_put(pkt, length);
|
|
ret = iot_sg_sta_report_event_with_type(addr, (uint8_t *)hdr, length,
|
|
new_evt, IOT_SG_STA_RPT_MODULE_CLOCK_EVT);
|
|
if (ret == ERR_OK) {
|
|
sta_glb->drv->disable_event_rpt();
|
|
evt->clock_interval = interval;
|
|
evt->retry_cnt++;
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
uint32_t iot_sg_sta_ext_clock_skew_report_hlj(uint8_t new_evt,
|
|
int64_t interval)
|
|
{
|
|
uint8_t sec, min, length, addr[IOT_MAC_ADDR_LEN];
|
|
uint16_t hour;
|
|
uint32_t ret = ERR_FAIL, di = PROTO_645_2007_DI_DELTA_RPT, hour_cache;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_evt_global_t *evt = &sta_glb->evt;
|
|
proto_645_header_t *hdr = NULL;
|
|
proto_645_07_delta_rpt_t *rpt;
|
|
|
|
if (iot_sg_sta_get_user_type() != USER_TYPE_STATE_GRID_HLJ) {
|
|
goto out;
|
|
}
|
|
if (evt->retry_cnt >= 3) {
|
|
iot_sg_printf("%s retry end, cnt %d\n", __FUNCTION__, evt->retry_cnt);
|
|
iot_sg_module_report_reset_status(0);
|
|
goto out;
|
|
}
|
|
if (interval == 0) {
|
|
goto out;
|
|
}
|
|
sec = (uint8_t)(IOT_ABS(interval) % 60);
|
|
min = (uint8_t)((IOT_ABS(interval) / 60) % 60);
|
|
hour_cache = (uint32_t)(IOT_ABS(interval) / 3600);
|
|
if (hour_cache > IOT_SG_STA_CORRECT_TIME_DELTA_HOUR_MAX) {
|
|
hour = IOT_SG_STA_CORRECT_TIME_DELTA_HOUR_MAX;
|
|
min = 59;
|
|
sec = 59;
|
|
} else {
|
|
hour = (uint16_t)hour_cache;
|
|
}
|
|
length = sizeof(proto_645_header_t) + sizeof(proto_645_tailer_t) +
|
|
PROTO_645_2007_DI_LEN + sizeof(*rpt);
|
|
pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
|
|
if (!pkt) {
|
|
goto out;
|
|
}
|
|
sta_glb->drv->get_login_addr(addr);
|
|
hdr = (proto_645_header_t *)iot_pkt_data(pkt);
|
|
proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
|
|
hdr->len = sizeof(*rpt) + PROTO_645_2007_DI_LEN;
|
|
proto_645_2007_di_to_byte(di, hdr->data);
|
|
rpt = (proto_645_07_delta_rpt_t *)(hdr->data + PROTO_645_2007_DI_LEN);
|
|
if (interval > 0) {
|
|
rpt->mode = PROTO_645_CS_MODE_METER_BELOW_CCTT_HLJ;
|
|
} else {
|
|
rpt->mode = PROTO_645_CS_MODE_METER_ABOVE_CCTT_HLJ;
|
|
}
|
|
rpt->sec = iot_byte_to_bcd(sec);
|
|
rpt->min = iot_byte_to_bcd(min);
|
|
rpt->hour_high = iot_byte_to_bcd((uint8_t)(hour / 100));
|
|
rpt->hour_low = iot_byte_to_bcd((uint8_t)(hour % 100));
|
|
proto_645_add33_handle(hdr->data, hdr->len);
|
|
/* fill in 645 tailer */
|
|
proto_645_tail_init(hdr);
|
|
iot_pkt_put(pkt, length);
|
|
ret = iot_sg_sta_report_event_with_type(addr, (uint8_t *)hdr, length,
|
|
new_evt, IOT_SG_STA_RPT_MODULE_CLOCK_EVT);
|
|
if (ret == ERR_OK) {
|
|
sta_glb->drv->disable_event_rpt();
|
|
evt->clock_interval = interval;
|
|
evt->retry_cnt++;
|
|
iot_sg_printf("%s cnt %d\n", __FUNCTION__, evt->retry_cnt);
|
|
}
|
|
out:
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_clock_skew(iot_time_tm_t *tm)
|
|
{
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
uint32_t delta, flag = 0, ret = ERR_FAIL;
|
|
int64_t interval;
|
|
iot_time_tm_t sys_tm, curr_tm;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_tm_info_t *auto_tm = &sta_glb->tm_info;
|
|
|
|
curr_tm = *tm;
|
|
if (user_type == USER_TYPE_STATE_GRID_HUNAN) {
|
|
if (iot_sg_sta_ext_cache_time_get(&sys_tm) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
} else {
|
|
if (iot_sg_sta_rtc_get(&sys_tm, 1) != ERR_OK) {
|
|
goto out;
|
|
}
|
|
}
|
|
interval = iot_rtc_delta_calc(&curr_tm, &sys_tm);
|
|
delta = (uint32_t)IOT_ABS(interval);
|
|
if (interval >= 0) {
|
|
flag = 1;
|
|
}
|
|
iot_sg_printf("%s sys time %02d-%02d-%02d %02d:%02d:%02d, delta %lu, "
|
|
"flag %lu\n", __FUNCTION__, sys_tm.tm_year, sys_tm.tm_mon,
|
|
sys_tm.tm_mday, sys_tm.tm_hour, sys_tm.tm_min, sys_tm.tm_sec,
|
|
delta, flag);
|
|
if ((IOT_ABS(interval) < auto_tm->threshold) || !auto_tm->threshold) {
|
|
goto out;
|
|
}
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ) {
|
|
ret = iot_sg_sta_ext_clock_skew_report_hlj(1, interval);
|
|
} else if (user_type == USER_TYPE_STATE_GRID_HUNAN) {
|
|
ret = iot_sg_sta_ext_clock_skew_report_hn(1, interval);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
void iot_sg_sta_ext_save_auto_correct_pib(uint8_t *flag_auto,
|
|
uint16_t *delta_threshold, uint8_t *addr)
|
|
{
|
|
uint8_t ref, reason, flag_write = 0;
|
|
uint16_t ticket;
|
|
iot_sg_sta_app_info_t *sta_pib = iot_sg_sta_get_rw_pib();
|
|
|
|
if (iot_sg_sta_get_user_type() != USER_TYPE_STATE_GRID_HLJ) {
|
|
goto out;
|
|
}
|
|
if (!iot_mac_addr_valid(addr)) {
|
|
reason = 1;
|
|
goto drop;
|
|
}
|
|
if (!sta_pib) {
|
|
reason = 2;
|
|
goto drop;
|
|
}
|
|
if (flag_auto && sta_pib->auto_corr != *flag_auto) {
|
|
flag_write = 1;
|
|
}
|
|
if (delta_threshold && sta_pib->delta_threshold != *delta_threshold) {
|
|
if (*delta_threshold > IOT_SG_STA_MAX_DELTA_THRESHOLD) {
|
|
reason = 3;
|
|
goto drop;
|
|
}
|
|
flag_write = 1;
|
|
}
|
|
if (flag_write) {
|
|
iot_pib_acquire_app_commit_ref(&ref);
|
|
if (flag_auto) {
|
|
sta_pib->auto_corr = *flag_auto;
|
|
}
|
|
if (delta_threshold) {
|
|
sta_pib->delta_mode = 1;
|
|
sta_pib->delta_threshold = *delta_threshold;
|
|
}
|
|
iot_mac_addr_cpy(sta_pib->pm_addr, addr);
|
|
iot_pib_release_app_commit_ref(&ref);
|
|
iot_pib_app_commit(&ticket);
|
|
iot_sg_printf("%s auto %lu, threshold %lu\n", __FUNCTION__,
|
|
sta_pib->auto_corr, sta_pib->delta_threshold);
|
|
}
|
|
goto out;
|
|
drop:
|
|
iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
|
|
out:
|
|
return;
|
|
}
|
|
|
|
void iot_sg_sta_ext_auto_ct_set(uint8_t enable, uint8_t delay_clean)
|
|
{
|
|
uint8_t user_type = iot_sg_sta_get_user_type();
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_tm_info_t *auto_tm = &sta_glb->tm_info;
|
|
|
|
auto_tm->auto_flag = enable;
|
|
if (delay_clean) {
|
|
auto_tm->auto_delay = 0;
|
|
}
|
|
if (user_type == USER_TYPE_STATE_GRID_HLJ ||
|
|
user_type == USER_TYPE_SOUTHEN_POWER_GRID_SHENZHEN ||
|
|
user_type == USER_TYPE_STATE_GRID_GANSU) {
|
|
iot_sg_sta_ext_save_auto_correct_pib(&auto_tm->auto_flag, NULL,
|
|
p_sg_glb->plc_state.addr);
|
|
}
|
|
}
|
|
|
|
void iot_sg_sta_ext_auto_tm_handle(iot_time_tm_t *tm)
|
|
{
|
|
uint8_t user_type = iot_sg_sta_get_user_type(), flag_stop = 0;
|
|
iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
|
|
iot_sg_sta_tm_info_t *auto_tm = &sta_glb->tm_info;
|
|
|
|
if (user_type != USER_TYPE_STATE_GRID_HLJ &&
|
|
user_type != USER_TYPE_STATE_GRID_GANSU &&
|
|
user_type != USER_TYPE_STATE_GRID_HUNAN &&
|
|
user_type != USER_TYPE_SOUTHEN_POWER_GRID_GX &&
|
|
user_type != USER_TYPE_SOUTHEN_POWER_GRID_SHENZHEN) {
|
|
goto out;
|
|
}
|
|
if (auto_tm->auto_flag && !auto_tm->auto_delay) {
|
|
if (iot_sg_sta_ext_auto_ct(tm, &flag_stop) == ERR_OK) {
|
|
auto_tm->auto_delay = IOT_SG_STA_AUTO_TM_INTERVAL;
|
|
}
|
|
if (flag_stop) {
|
|
iot_sg_sta_ext_auto_ct_set(0, 1);
|
|
}
|
|
}
|
|
if (auto_tm->rpt_flag && !auto_tm->rpt_delay) {
|
|
if (iot_sg_sta_ext_clock_skew(tm) == ERR_OK) {
|
|
auto_tm->rpt_delay = IOT_SG_STA_AUTO_TM_INTERVAL;
|
|
}
|
|
if (user_type == USER_TYPE_STATE_GRID_HUNAN) {
|
|
/* HUNAN clock skew execute only once */
|
|
auto_tm->rpt_flag = 0;
|
|
auto_tm->rpt_delay = 0;
|
|
}
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
#endif /* IOT_SMART_GRID_EXT_TM_FUNC_ENABLE */
|