2161 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			2161 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
							 | 
						||
| 
								 | 
							
								be copied by any method or incorporated into another program without
							 | 
						||
| 
								 | 
							
								the express written consent of Aerospace C.Power. This Information or any portion
							 | 
						||
| 
								 | 
							
								thereof remains the property of Aerospace C.Power. The Information contained herein
							 | 
						||
| 
								 | 
							
								is believed to be accurate and Aerospace C.Power assumes no responsibility or
							 | 
						||
| 
								 | 
							
								liability for its use in any way and conveys no license or title under
							 | 
						||
| 
								 | 
							
								any patent or copyright and makes no representation or warranty that this
							 | 
						||
| 
								 | 
							
								Information is free from patent or copyright infringement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								/* os_shim header files */
							 | 
						||
| 
								 | 
							
								#include "os_utils_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* iot common header files */
							 | 
						||
| 
								 | 
							
								#include "iot_io_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_oem_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* smart grid internal header files */
							 | 
						||
| 
								 | 
							
								#include "iot_sg_fr.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg.h"
							 | 
						||
| 
								 | 
							
								#include "proto_645.h"
							 | 
						||
| 
								 | 
							
								#include "proto_69845.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_sta.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_sta_ext.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_sta_flash.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_sta_cfg_flash.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if (IOT_SMART_GRID_EXT_LR_FUNC_ENABLE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* define cnt of load curve configuration */
							 | 
						||
| 
								 | 
							
								#define IOT_SG_STA_EXT_LC_CFG_CNT        (IOT_SG_STA_EXT_LC_PEIWANG + 1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* define extend function read load data default interval time, uint is 1s */
							 | 
						||
| 
								 | 
							
								#define IOT_SG_STA_EXT_LC_INTER          IOT_SG_STA_EXT_LC_CFG_PRD_15MIN
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* define 69845 meter data lr frame max oi number */
							 | 
						||
| 
								 | 
							
								#define IOT_SG_STA_EXT_LR_FRAME_MAX_OI_NUM        (6)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_lr_other_handle(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static const iot_sg_sta_ext_lc_cfg_t lc_cfg[IOT_SG_STA_EXT_LC_CFG_CNT] = {
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        .tm = {
							 | 
						||
| 
								 | 
							
								            .tm_year = 2000,
							 | 
						||
| 
								 | 
							
								            .tm_mon = 1,
							 | 
						||
| 
								 | 
							
								            .tm_mday = 1,
							 | 
						||
| 
								 | 
							
								            .tm_hour = 0,
							 | 
						||
| 
								 | 
							
								            .tm_min = 0,
							 | 
						||
| 
								 | 
							
								            .tm_sec = 0,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        .interval = IOT_SG_STA_EXT_LC_INTER,
							 | 
						||
| 
								 | 
							
								        .cnt = 1,
							 | 
						||
| 
								 | 
							
								        .di_buf = {
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_V_A,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        .tm = {
							 | 
						||
| 
								 | 
							
								            .tm_year = 2000,
							 | 
						||
| 
								 | 
							
								            .tm_mon = 1,
							 | 
						||
| 
								 | 
							
								            .tm_mday = 1,
							 | 
						||
| 
								 | 
							
								            .tm_hour = 0,
							 | 
						||
| 
								 | 
							
								            .tm_min = 0,
							 | 
						||
| 
								 | 
							
								            .tm_sec = 0,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        .interval = IOT_SG_STA_EXT_LC_INTER,
							 | 
						||
| 
								 | 
							
								        .cnt = 7,
							 | 
						||
| 
								 | 
							
								        .di_buf = {
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_V_A,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_I_A,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_I_N,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_P_A,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_COMP_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_NEG_ALL,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        .tm = {
							 | 
						||
| 
								 | 
							
								            .tm_year = 2000,
							 | 
						||
| 
								 | 
							
								            .tm_mon = 1,
							 | 
						||
| 
								 | 
							
								            .tm_mday = 1,
							 | 
						||
| 
								 | 
							
								            .tm_hour = 0,
							 | 
						||
| 
								 | 
							
								            .tm_min = 0,
							 | 
						||
| 
								 | 
							
								            .tm_sec = 0,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        .interval = IOT_SG_STA_EXT_LC_INTER,
							 | 
						||
| 
								 | 
							
								        .cnt = 22,
							 | 
						||
| 
								 | 
							
								        .di_buf = {
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_V_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_I_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_I_N,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_P_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_Q_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_PF_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_COMP_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_NEG_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_POS_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_NEG_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_QRT1_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_QRT2_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_QRT3_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_QRT4_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_DEMAND,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EQT_DEMAND,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_DEMAND,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_NEG_DEMAND,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_A,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_B,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_C
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        .tm = {
							 | 
						||
| 
								 | 
							
								            .tm_year = 2000,
							 | 
						||
| 
								 | 
							
								            .tm_mon = 1,
							 | 
						||
| 
								 | 
							
								            .tm_mday = 1,
							 | 
						||
| 
								 | 
							
								            .tm_hour = 0,
							 | 
						||
| 
								 | 
							
								            .tm_min = 0,
							 | 
						||
| 
								 | 
							
								            .tm_sec = 0,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        .interval = IOT_SG_STA_EXT_LC_INTER,
							 | 
						||
| 
								 | 
							
								        .cnt = 11,
							 | 
						||
| 
								 | 
							
								        .di_buf = {
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_V_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_I_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_PF_ALL,
							 | 
						||
| 
								 | 
							
								            /* if sta can't read last frozen time,
							 | 
						||
| 
								 | 
							
								             * sta don't read frozen data. sta read
							 | 
						||
| 
								 | 
							
								             * current data from PROTO_645_2007_DI_EPT_POS_SUM
							 | 
						||
| 
								 | 
							
								             * to PROTO_645_2007_DI_Q_ALL.
							 | 
						||
| 
								 | 
							
								             */
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_RT_YMDHMS_LAST1,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_RT_EP_POS_LAST1,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_RT_EP_NEG_LAST1,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_RT_VARIABLE_LAST1,
							 | 
						||
| 
								 | 
							
								            /* current data */
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_POS_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_EPT_NEG_SUM,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_P_ALL,
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_Q_ALL,
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_get_lr_di_idx(uint32_t di, uint8_t *idx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    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_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (uint8_t i = 0; i < lr_info->cfg->cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (lr_info->cfg->di_buf[i] == di) {
							 | 
						||
| 
								 | 
							
								            *idx = i;
							 | 
						||
| 
								 | 
							
								            return ERR_OK;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ext_lr_cfg_pib_save(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t ref, period;
							 | 
						||
| 
								 | 
							
								    uint16_t ticket;
							 | 
						||
| 
								 | 
							
								    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_clct_param *clct_param = &ext_info->clct_param;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_app_info_t *sta_pib = iot_sg_sta_get_rw_pib();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!sta_pib) {
							 | 
						||
| 
								 | 
							
								        goto drop;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if ((clct_param->cfg.interval != clct_param->cfg_cache.interval)
							 | 
						||
| 
								 | 
							
								        && (sta_pib->ext_lr_period != clct_param->cfg_cache.interval)) {
							 | 
						||
| 
								 | 
							
								        period = (uint8_t)(clct_param->cfg_cache.interval / 60);
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s period %lumin -> %lumin\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								            sta_pib->ext_lr_period, period);
							 | 
						||
| 
								 | 
							
								        if (clct_param->cfg_cache.interval != IOT_SG_STA_EXT_LC_CFG_PRD_1MIN
							 | 
						||
| 
								 | 
							
								            && clct_param->cfg_cache.interval != IOT_SG_STA_EXT_LC_CFG_PRD_5MIN
							 | 
						||
| 
								 | 
							
								            && clct_param->cfg_cache.interval != IOT_SG_STA_EXT_LC_CFG_PRD_15MIN
							 | 
						||
| 
								 | 
							
								            && clct_param->cfg_cache.interval != IOT_SG_STA_EXT_LC_CFG_PRD_30MIN
							 | 
						||
| 
								 | 
							
								            && clct_param->cfg_cache.interval !=
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_EXT_LC_CFG_PRD_60MIN) {
							 | 
						||
| 
								 | 
							
								            period = IOT_SG_STA_EXT_LC_CFG_PRD_15MIN / 60;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_pib_acquire_app_commit_ref(&ref);
							 | 
						||
| 
								 | 
							
								        sta_pib->ext_lr_period = period;
							 | 
						||
| 
								 | 
							
								        iot_pib_release_app_commit_ref(&ref);
							 | 
						||
| 
								 | 
							
								        iot_pib_app_commit(&ticket);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								drop:
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ext_lr_get_pib_cfg(iot_sg_sta_ext_lc_cfg_t *cfg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_app_info_t *sta_pib = iot_sg_sta_get_rw_pib();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!sta_pib) {
							 | 
						||
| 
								 | 
							
								        goto drop;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    cfg->interval = sta_pib->ext_lr_period;
							 | 
						||
| 
								 | 
							
								    cfg->interval *= 60;
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s pib period %lus\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        cfg->interval);
							 | 
						||
| 
								 | 
							
								    if (cfg->interval != IOT_SG_STA_EXT_LC_CFG_PRD_1MIN
							 | 
						||
| 
								 | 
							
								        && cfg->interval != IOT_SG_STA_EXT_LC_CFG_PRD_5MIN
							 | 
						||
| 
								 | 
							
								        && cfg->interval != IOT_SG_STA_EXT_LC_CFG_PRD_15MIN
							 | 
						||
| 
								 | 
							
								        && cfg->interval != IOT_SG_STA_EXT_LC_CFG_PRD_30MIN
							 | 
						||
| 
								 | 
							
								        && cfg->interval != IOT_SG_STA_EXT_LC_CFG_PRD_60MIN) {
							 | 
						||
| 
								 | 
							
								        cfg->interval = IOT_SG_STA_EXT_LC_CFG_PRD_15MIN;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s cfg period %lus\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        sta_pib->ext_lr_period);
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								drop:
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_lr_cfg_reset(uint8_t cfg_id)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (cfg_id >= IOT_SG_STA_EXT_LC_CFG_CNT) {
							 | 
						||
| 
								 | 
							
								        ret = ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.cfg_index = cfg_id;
							 | 
						||
| 
								 | 
							
								    ext_info->clct_param.enabled = 1;
							 | 
						||
| 
								 | 
							
								    os_mem_set(&ext_info->lc_info.last_froze_tm, 0,
							 | 
						||
| 
								 | 
							
								        sizeof(ext_info->lc_info.last_froze_tm));
							 | 
						||
| 
								 | 
							
								    os_mem_set(&ext_info->lc_info.froze_tm, 0,
							 | 
						||
| 
								 | 
							
								        sizeof(ext_info->lc_info.froze_tm));
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&ext_info->clct_param.cfg, &lc_cfg[cfg_id],
							 | 
						||
| 
								 | 
							
								        sizeof(iot_sg_sta_ext_lc_cfg_t));
							 | 
						||
| 
								 | 
							
								    if (cfg_id == IOT_SG_STA_EXT_LC_XIAN_3P_CFG
							 | 
						||
| 
								 | 
							
								        || cfg_id == IOT_SG_STA_EXT_LC_XIAN_CFG) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ext_lr_get_pib_cfg(&ext_info->clct_param.cfg);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.cfg = &ext_info->clct_param.cfg;
							 | 
						||
| 
								 | 
							
								    ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_sg_ext_lr_cfg_update(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t flag_tm_reset = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t idx;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_node_desc_t *node;
							 | 
						||
| 
								 | 
							
								    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_clct_param *clct_param = &ext_info->clct_param;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (clct_param->flag_update) {
							 | 
						||
| 
								 | 
							
								        clct_param->flag_update = 0;
							 | 
						||
| 
								 | 
							
								        if (clct_param->enabled) {
							 | 
						||
| 
								 | 
							
								            iot_sg_ext_lr_cfg_pib_save();
							 | 
						||
| 
								 | 
							
								            os_mem_cpy(&clct_param->cfg, &clct_param->cfg_cache,
							 | 
						||
| 
								 | 
							
								                sizeof(clct_param->cfg));
							 | 
						||
| 
								 | 
							
								            ext_info->lc_info.cfg = &clct_param->cfg;
							 | 
						||
| 
								 | 
							
								            flag_tm_reset = 1;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            ext_info->lc_info.cfg = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s enable:%lu\n", __FUNCTION__, clct_param->enabled);
							 | 
						||
| 
								 | 
							
								        if (ext_info->lc_info.cfg) {
							 | 
						||
| 
								 | 
							
								            iot_sg_printf("%s interval %lu di cnt %lu\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								                ext_info->lc_info.cfg->interval, ext_info->lc_info.cfg->cnt);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!clct_param->enabled && !p_sg_glb->dev_is_ready) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ext_lr_cfg_reset(ext_info->lc_info.cfg_index);
							 | 
						||
| 
								 | 
							
								        flag_tm_reset = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (flag_tm_reset) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(&ext_info->lc_info.last_froze_tm, 0,
							 | 
						||
| 
								 | 
							
								            sizeof(ext_info->lc_info.last_froze_tm));
							 | 
						||
| 
								 | 
							
								        os_mem_set(&ext_info->lc_info.froze_tm, 0,
							 | 
						||
| 
								 | 
							
								            sizeof(ext_info->lc_info.froze_tm));
							 | 
						||
| 
								 | 
							
								        for (idx = 0; idx < IOT_SG_STA_SEC_NODE_MAX; idx++) {
							 | 
						||
| 
								 | 
							
								            if (sta_glb->node_list[idx] != NULL) {
							 | 
						||
| 
								 | 
							
								                node = sta_glb->node_list[idx];
							 | 
						||
| 
								 | 
							
								                os_mem_set(&node->ext.lr_info.tm, 0x0,
							 | 
						||
| 
								 | 
							
								                    sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_sg_ext_lr_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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.index = 0;
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.timeout_cnt = 0;
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.repeat_cnt = 0;
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.flag_resp = 0;
							 | 
						||
| 
								 | 
							
								    ext_info->lc_info.state = IOT_SG_STA_EXT_LC_STATE_IDLE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_sg_ext_lr_init(uint8_t cfg_id)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ext_info->lc_info.cfg) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (cfg_id >= IOT_SG_STA_EXT_LC_CFG_CNT) {
							 | 
						||
| 
								 | 
							
								        ret = ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_ext_lr_cfg_reset(cfg_id);
							 | 
						||
| 
								 | 
							
								    iot_sg_ext_lr_reset();
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ext_lr_data_save(uint8_t *addr, iot_time_tm_t *tm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t reason = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t index = 0, max_cnt = 0, len = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t cache_tm = { 0 };
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_meter_data_t *meter = &ext_info->meter_data;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_gx_lc_uint_data_t *flash_gx_data;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_lc_uint_xian_data_t *flash_xian_data;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_pw_lc_uint_data_t *flash_pw_data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s time %lu-%lu-%lu %lu:%lu:%lu\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
							 | 
						||
| 
								 | 
							
								        tm->tm_sec);
							 | 
						||
| 
								 | 
							
								    switch (iot_sg_sta_get_user_type()) {
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_SOUTHEN_POWER_GRID_GX:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_GX_LC, &len, &max_cnt)) {
							 | 
						||
| 
								 | 
							
								            reason = 1;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								        if (!pkt) {
							 | 
						||
| 
								 | 
							
								            reason = 2;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_gx_data = (iot_sg_meter_gx_lc_uint_data_t *)iot_pkt_put(
							 | 
						||
| 
								 | 
							
								            pkt, len);
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_find_by_time(
							 | 
						||
| 
								 | 
							
								            addr, &index, tm,(uint8_t *)flash_gx_data, len,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_GX_LC, 1);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_year = (uint16_t)(flash_gx_data->year + 2000);
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mon = (uint8_t)flash_gx_data->month;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mday = (uint8_t)flash_gx_data->day;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_hour = (uint8_t)flash_gx_data->hour;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_min = (uint8_t)flash_gx_data->minute;
							 | 
						||
| 
								 | 
							
								            if (iot_rtc_delta_calc(&cache_tm, tm) != 0) {
							 | 
						||
| 
								 | 
							
								                index++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (index >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            index = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_gx_data->year = (uint32_t)(tm->tm_year % 100);
							 | 
						||
| 
								 | 
							
								        flash_gx_data->month = (uint32_t)(tm->tm_mon);
							 | 
						||
| 
								 | 
							
								        flash_gx_data->day = (uint32_t)(tm->tm_mday);
							 | 
						||
| 
								 | 
							
								        flash_gx_data->hour = (uint32_t)(tm->tm_hour);
							 | 
						||
| 
								 | 
							
								        flash_gx_data->minute = (uint32_t)(tm->tm_min);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_gx_data->v, meter->v.a, PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_save(addr, index, (uint8_t *)flash_gx_data,
							 | 
						||
| 
								 | 
							
								            len, IOT_SG_STA_METER_DATA_TYPE_GX_LC);
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_check(addr, index, tm,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_GX_LC);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_XIAN:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_HEBEI:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_HUNAN:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_MENGDONG_LC:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_XIAN_LC, &len, &max_cnt)) {
							 | 
						||
| 
								 | 
							
								            reason = 3;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								        if (!pkt) {
							 | 
						||
| 
								 | 
							
								            reason = 4;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_xian_data = (iot_sg_meter_lc_uint_xian_data_t*)iot_pkt_put(
							 | 
						||
| 
								 | 
							
								            pkt, len);
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_find_by_time(
							 | 
						||
| 
								 | 
							
								            addr, &index, tm, (uint8_t *)flash_xian_data, len,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_XIAN_LC, 1);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_year = (uint16_t)(flash_xian_data->year + 2000);
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mon = (uint8_t)flash_xian_data->month;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mday = (uint8_t)flash_xian_data->day;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_hour = (uint8_t)flash_xian_data->hour;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_min = (uint8_t)flash_xian_data->minute;
							 | 
						||
| 
								 | 
							
								            if (iot_rtc_delta_calc(&cache_tm, tm) != 0) {
							 | 
						||
| 
								 | 
							
								                index++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (index >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            index = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_xian_data->year = (uint32_t)(tm->tm_year % 100);
							 | 
						||
| 
								 | 
							
								        flash_xian_data->month = (uint32_t)(tm->tm_mon);
							 | 
						||
| 
								 | 
							
								        flash_xian_data->day = (uint32_t)(tm->tm_mday);
							 | 
						||
| 
								 | 
							
								        flash_xian_data->hour = (uint32_t)(tm->tm_hour);
							 | 
						||
| 
								 | 
							
								        flash_xian_data->minute = (uint32_t)(tm->tm_min);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->v, &meter->v, sizeof(meter->v));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->i, &meter->a, sizeof(meter->a));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->n, meter->gnd_a, sizeof(meter->gnd_a));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->active_power, &meter->ap,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->ap));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->reactive_power, &meter->rp,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->rp));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->power_factor, &meter->pf,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->pf));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->ca_power, &meter->cae,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->cae));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->fda_power, &meter->pae,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->pae));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_xian_data->bda_power, &meter->nae,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->nae));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->cr_power1, meter->cre1.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->cre1.total));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->cr_power2, meter->cre2.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->cre2.total));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->re_1st_power, meter->re_1st.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->re_1st));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->re_2nd_power, meter->re_2st.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->re_2st));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->re_3rd_power, meter->re_3st.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->re_3st));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->re_4th_power, meter->re_4st.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->re_4st));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->ap_demand, meter->ept_demand,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->ept_demand));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->rp_demand, meter->eqt_demand,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->eqt_demand));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->pos_ap_demand, &meter->pos_ap_demand,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->pos_ap_demand));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->neg_ap_demand, &meter->neg_ap_demand,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->neg_ap_demand));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->pos_a, meter->pos_a, sizeof(meter->pos_a));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->pos_b, meter->pos_b, sizeof(meter->pos_b));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(flash_xian_data->pos_c, meter->pos_c, sizeof(meter->pos_c));
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_save(addr, index, (uint8_t *)flash_xian_data,
							 | 
						||
| 
								 | 
							
								            len, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC);
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_check(addr, index, tm,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_XIAN_LC);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_BRM_PEIWANG:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_BRM_PEIWANG_DUAL_NET:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								                IOT_SG_STA_METER_DATA_TYPE_PW_LC, &len, &max_cnt)) {
							 | 
						||
| 
								 | 
							
								            reason = 5;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								        if (!pkt) {
							 | 
						||
| 
								 | 
							
								            reason = 6;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_pw_data = (iot_sg_meter_pw_lc_uint_data_t*)iot_pkt_put(
							 | 
						||
| 
								 | 
							
								            pkt, len);
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_find_by_time(
							 | 
						||
| 
								 | 
							
								            addr, &index, tm, (uint8_t *)flash_pw_data, len,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_PW_LC, 1);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_year = (uint16_t)(flash_pw_data->year + 2000);
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mon = (uint8_t)flash_pw_data->month;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_mday = (uint8_t)flash_pw_data->day;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_hour = (uint8_t)flash_pw_data->hour;
							 | 
						||
| 
								 | 
							
								            cache_tm.tm_min = (uint8_t)flash_pw_data->minute;
							 | 
						||
| 
								 | 
							
								            if (iot_rtc_delta_calc(&cache_tm, tm) != 0) {
							 | 
						||
| 
								 | 
							
								                index++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (index >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            index = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        flash_pw_data->year = (uint32_t)(tm->tm_year % 100);
							 | 
						||
| 
								 | 
							
								        flash_pw_data->month = (uint32_t)(tm->tm_mon);
							 | 
						||
| 
								 | 
							
								        flash_pw_data->day = (uint32_t)(tm->tm_mday);
							 | 
						||
| 
								 | 
							
								        flash_pw_data->hour = (uint32_t)(tm->tm_hour);
							 | 
						||
| 
								 | 
							
								        flash_pw_data->minute = (uint32_t)(tm->tm_min);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->v, &meter->v, sizeof(meter->v));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->i, &meter->a, sizeof(meter->a));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->active_power, &meter->ap,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->ap));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->reactive_power, &meter->rp,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->rp));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->power_factor, &meter->pf,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->pf));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->ept_pos, &meter->pae.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->pae.total));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&flash_pw_data->ept_neg, &meter->nae.total,
							 | 
						||
| 
								 | 
							
								            sizeof(meter->nae.total));
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_save(addr, index, (uint8_t *)flash_pw_data,
							 | 
						||
| 
								 | 
							
								            len, IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								        iot_sg_sta_flash_unit_data_check(addr, index, tm,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (reason) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (pkt) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_get_lr_time(iot_time_tm_t *tm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (iot_sg_sta_get_user_type()) {
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_BRM_PEIWANG:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_SOUTHEN_POWER_GRID_GX:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_rtc_get(tm, 0);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_BRM_PEIWANG_DUAL_NET:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_XIAN:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_HEBEI:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_HUNAN:
							 | 
						||
| 
								 | 
							
								    case USER_TYPE_STATE_GRID_MENGDONG_LC:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_rtc_get(tm, 1);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        ret = ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_lr_other_handle(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm;
							 | 
						||
| 
								 | 
							
								    proto_645_07_frozen_mdhm_t time;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_clct_param *clct_param = &ext_info->clct_param;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (clct_param->enabled) {
							 | 
						||
| 
								 | 
							
								        switch (iot_sg_sta_get_user_type()) {
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_BRM_PEIWANG:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_BRM_PEIWANG_DUAL_NET:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (iot_sg_ext_get_lr_time(&tm)) {
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!ext_info->lc_info.froze_tm.tm_year
							 | 
						||
| 
								 | 
							
								                && !ext_info->lc_info.froze_tm.tm_mon
							 | 
						||
| 
								 | 
							
								                && !ext_info->lc_info.froze_tm.tm_mday
							 | 
						||
| 
								 | 
							
								                && !ext_info->lc_info.froze_tm.tm_hour
							 | 
						||
| 
								 | 
							
								                && !ext_info->lc_info.froze_tm.tm_min
							 | 
						||
| 
								 | 
							
								                && !ext_info->lc_info.froze_tm.tm_sec) {
							 | 
						||
| 
								 | 
							
								                /* load read load curve data time stamp */
							 | 
						||
| 
								 | 
							
								                ext_info->lc_info.froze_tm = iot_sg_ext_get_next_lr_ts(
							 | 
						||
| 
								 | 
							
								                    lr_info->cfg->tm, lr_info->cfg->interval, tm);
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            } else if (iot_rtc_delta_calc(&ext_info->lc_info.froze_tm, &tm)
							 | 
						||
| 
								 | 
							
								                < 0) {
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            time.month = 0x99;
							 | 
						||
| 
								 | 
							
								            time.day = 0x99;
							 | 
						||
| 
								 | 
							
								            time.hour = 0x99;
							 | 
						||
| 
								 | 
							
								            time.minute = 0x99;
							 | 
						||
| 
								 | 
							
								            pkt = proto_645_2007_build_frozen_msg(proto_645_bcast_addr, &time);
							 | 
						||
| 
								 | 
							
								            if (pkt) {
							 | 
						||
| 
								 | 
							
								                ret = iot_sg_sta_add_corr_req(iot_pkt_data(pkt),
							 | 
						||
| 
								 | 
							
								                    (uint16_t)iot_pkt_data_len(pkt));
							 | 
						||
| 
								 | 
							
								                if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								                    iot_sg_printf("%s frozen send\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								                    ext_info->lc_info.last_froze_tm =
							 | 
						||
| 
								 | 
							
								                        ext_info->lc_info.froze_tm;
							 | 
						||
| 
								 | 
							
								                    ext_info->lc_info.froze_tm = iot_sg_ext_get_next_lr_ts(
							 | 
						||
| 
								 | 
							
								                        lr_info->cfg->tm, lr_info->cfg->interval, tm);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_SOUTHEN_POWER_GRID_GX:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_STATE_GRID_XIAN:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_STATE_GRID_HEBEI:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_STATE_GRID_HUNAN:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_STATE_GRID_MENGDONG_LC:
							 | 
						||
| 
								 | 
							
								        case USER_TYPE_STATE_GRID:
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t iot_sg_ext_lr_idx_handle(uint8_t index, uint8_t flag_resp)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t idx = index;
							 | 
						||
| 
								 | 
							
								    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_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (lr_info->cfg_index) {
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_PEIWANG:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ((idx < lr_info->cfg->cnt) && (lr_info->cfg->di_buf[idx] ==
							 | 
						||
| 
								 | 
							
								            PROTO_645_2007_DI_RT_YMDHMS_LAST1) && !flag_resp) {
							 | 
						||
| 
								 | 
							
								            if (iot_sg_ext_get_lr_di_idx(PROTO_645_2007_DI_EPT_POS_SUM,
							 | 
						||
| 
								 | 
							
								                &idx) == ERR_OK) {
							 | 
						||
| 
								 | 
							
								                /* if sta can't read the last freezing time,
							 | 
						||
| 
								 | 
							
								                 * sta don't read frozen data. sta read current data.
							 | 
						||
| 
								 | 
							
								                 */
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                /* if sta can't read the last freezing time and current data,
							 | 
						||
| 
								 | 
							
								                 * lr function is finish.
							 | 
						||
| 
								 | 
							
								                 */
							 | 
						||
| 
								 | 
							
								                idx = lr_info->cfg->cnt;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								next:
							 | 
						||
| 
								 | 
							
								        idx++;
							 | 
						||
| 
								 | 
							
								        if (idx < lr_info->cfg->cnt) {
							 | 
						||
| 
								 | 
							
								           switch (lr_info->cfg->di_buf[idx]) {
							 | 
						||
| 
								 | 
							
								           case PROTO_645_2007_DI_EPT_POS_SUM:
							 | 
						||
| 
								 | 
							
								           {
							 | 
						||
| 
								 | 
							
								               if (iot_bcd_data_check(ext_info->meter_data.pae.total,
							 | 
						||
| 
								 | 
							
								                   sizeof(ext_info->meter_data.pae.total))) {
							 | 
						||
| 
								 | 
							
								                   goto next;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								           }
							 | 
						||
| 
								 | 
							
								           case PROTO_645_2007_DI_EPT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								           {
							 | 
						||
| 
								 | 
							
								               if (iot_bcd_data_check(ext_info->meter_data.nae.total,
							 | 
						||
| 
								 | 
							
								                   sizeof(ext_info->meter_data.nae.total))) {
							 | 
						||
| 
								 | 
							
								                   goto next;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								           }
							 | 
						||
| 
								 | 
							
								           case PROTO_645_2007_DI_P_ALL:
							 | 
						||
| 
								 | 
							
								           {
							 | 
						||
| 
								 | 
							
								               if (iot_bcd_data_check(ext_info->meter_data.ap.a,
							 | 
						||
| 
								 | 
							
								                   sizeof(ext_info->meter_data.ap.a))) {
							 | 
						||
| 
								 | 
							
								                   goto next;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								           }
							 | 
						||
| 
								 | 
							
								           case PROTO_645_2007_DI_Q_ALL:
							 | 
						||
| 
								 | 
							
								           {
							 | 
						||
| 
								 | 
							
								               if (iot_bcd_data_check(ext_info->meter_data.rp.a,
							 | 
						||
| 
								 | 
							
								                   sizeof(ext_info->meter_data.rp.a))) {
							 | 
						||
| 
								 | 
							
								                   goto next;
							 | 
						||
| 
								 | 
							
								               }
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								           }
							 | 
						||
| 
								 | 
							
								           default:
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								           }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_GX_CFG:
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_XIAN_CFG:
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_XIAN_3P_CFG:
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        idx++;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return idx;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static iot_pkt_t * iot_sg_ext_69845_lr_mr_msg_build(uint8_t *addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t get_list_req_size, oad;
							 | 
						||
| 
								 | 
							
								    uint8_t di_cnt, i, oad_idx = 0, attribute, cur_index = 0;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL, *get_list_req = NULL;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								    proto_69845_app_get_list_req_info_t *req = NULL;
							 | 
						||
| 
								 | 
							
								    server_addr_info_t server = {0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (lr_info->index >= lr_info->cfg->cnt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    di_cnt = lr_info->cfg->cnt - lr_info->index;
							 | 
						||
| 
								 | 
							
								    if (di_cnt > IOT_SG_STA_EXT_LR_FRAME_MAX_OI_NUM) {
							 | 
						||
| 
								 | 
							
								        di_cnt = IOT_SG_STA_EXT_LR_FRAME_MAX_OI_NUM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    get_list_req_size = sizeof(proto_69845_app_oad_t) * di_cnt + sizeof(*req);
							 | 
						||
| 
								 | 
							
								    get_list_req = iot_pkt_alloc(get_list_req_size, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!get_list_req) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    req = (proto_69845_app_get_list_req_info_t *)iot_pkt_put(get_list_req,
							 | 
						||
| 
								 | 
							
								        get_list_req_size);
							 | 
						||
| 
								 | 
							
								    req->type = PROTO_69845_APP_GET_NORMALLIST;
							 | 
						||
| 
								 | 
							
								    req->piid.priority = PROTO_69845_APP_PIID_PRIORITY_GENERAL;
							 | 
						||
| 
								 | 
							
								    req->piid.sn = iot_sg_sta_ext_get_69845_apdu_sn();
							 | 
						||
| 
								 | 
							
								    /* fill di from di_buff */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < di_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (lr_info->index + i >= IOT_SG_STA_EXT_LR_DI_CNT_MAX) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        oad = proto_645_di_to_698_oad(lr_info->cfg->di_buf[lr_info->index + i]);
							 | 
						||
| 
								 | 
							
								        cur_index = lr_info->index + i;
							 | 
						||
| 
								 | 
							
								        if (oad != PROTO_69845_APP_OAD_INVALID) {
							 | 
						||
| 
								 | 
							
								            req->oad[oad_idx].oi = (uint16_t)(oad >> 16);
							 | 
						||
| 
								 | 
							
								            attribute = (oad >> 8) & 0xff;
							 | 
						||
| 
								 | 
							
								            req->oad[oad_idx].attribute_id = attribute & 0x1f;
							 | 
						||
| 
								 | 
							
								            req->oad[oad_idx].attribute_char = attribute >> 5;
							 | 
						||
| 
								 | 
							
								            req->oad[oad_idx].element_index = oad & 0xff;
							 | 
						||
| 
								 | 
							
								            oad_idx++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lr_info->index = cur_index;
							 | 
						||
| 
								 | 
							
								    req->oad_cnt = oad_idx;
							 | 
						||
| 
								 | 
							
								    server.len = PROTO_69845_SA_LEN;
							 | 
						||
| 
								 | 
							
								    server.type = PROTO_69845_SA_TYPE_SIG;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(server.addr, addr);
							 | 
						||
| 
								 | 
							
								    pkt = proto_69845_build_get_req_msg_with_rn(req, &server);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(get_list_req);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_sg_ext_di_07_to_97(uint8_t *index, uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t flag_3p)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t di_97 = 0, di_07 = di;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (di_07 == PROTO_645_2007_DI_RT_YMDHMS_LAST1) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ext_get_lr_di_idx(PROTO_645_2007_DI_EPT_POS_SUM, index);
							 | 
						||
| 
								 | 
							
								        di_07 = PROTO_645_2007_DI_EPT_POS_SUM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (di_07) {
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_V_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (flag_3p) {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_V_ALL;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_V_A;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (flag_3p) {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_I_ALL;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_I_A;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_PF_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (flag_3p) {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_PF_ALL;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_PF_A;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        di_97 = PROTO_645_1997_DI_EPT_POS_SUM;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        di_97 = PROTO_645_1997_DI_EPT_NEG_SUM;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (flag_3p) {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_P_ALL;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_P_A;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_Q_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (flag_3p) {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_Q_ALL;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            di_97 = PROTO_645_1997_DI_Q_A;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return di_97;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_sg_ext_lr_func(uint8_t *addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t complete = 0, last_state = 0, flag_new = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t timeout;
							 | 
						||
| 
								 | 
							
								    uint32_t ret, di_97;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_info_t *ext_info = &sta_glb->ext_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_node_desc_t *node = iot_sg_sta_node_find_by_addr(addr);
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!lr_info->cfg) {
							 | 
						||
| 
								 | 
							
								        goto done;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(node);
							 | 
						||
| 
								 | 
							
								    last_state = lr_info->state;
							 | 
						||
| 
								 | 
							
								    switch (lr_info->state) {
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_STATE_IDLE:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_sg_ext_get_lr_time(&tm)) {
							 | 
						||
| 
								 | 
							
								            /* get time fail, stop lr function */
							 | 
						||
| 
								 | 
							
								            iot_sg_printf("%s get time err\n",  __FUNCTION__);
							 | 
						||
| 
								 | 
							
								            goto done;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (iot_sg_ext_lr_other_handle() == ERR_OK)
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!node->ext.lr_info.tm.tm_year && !node->ext.lr_info.tm.tm_mon
							 | 
						||
| 
								 | 
							
								            && !node->ext.lr_info.tm.tm_mday && !node->ext.lr_info.tm.tm_hour
							 | 
						||
| 
								 | 
							
								            && !node->ext.lr_info.tm.tm_min && !node->ext.lr_info.tm.tm_sec) {
							 | 
						||
| 
								 | 
							
								            /* load read load curve data time stamp */
							 | 
						||
| 
								 | 
							
								            node->ext.lr_info.tm = iot_sg_ext_get_next_lr_ts(lr_info->cfg->tm,
							 | 
						||
| 
								 | 
							
								                lr_info->cfg->interval, tm);
							 | 
						||
| 
								 | 
							
								            goto done;
							 | 
						||
| 
								 | 
							
								        } else if (iot_rtc_delta_calc(&node->ext.lr_info.tm, &tm) >= 0) {
							 | 
						||
| 
								 | 
							
								            /* when current tm is greater than or equal to next tm of
							 | 
						||
| 
								 | 
							
								             * reading load curve data, start read load curve data.
							 | 
						||
| 
								 | 
							
								             */
							 | 
						||
| 
								 | 
							
								            lr_info->state = IOT_SG_STA_EXT_LC_STATE_SEND;
							 | 
						||
| 
								 | 
							
								            lr_info->index = 0;
							 | 
						||
| 
								 | 
							
								            flag_new = 1;
							 | 
						||
| 
								 | 
							
								            goto send;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            goto done;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_STATE_WAIT:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!lr_info->timeout_cnt) {
							 | 
						||
| 
								 | 
							
								            if (!lr_info->repeat_cnt || lr_info->flag_resp) {
							 | 
						||
| 
								 | 
							
								                lr_info->index = iot_sg_ext_lr_idx_handle(lr_info->index,
							 | 
						||
| 
								 | 
							
								                    lr_info->flag_resp);
							 | 
						||
| 
								 | 
							
								                lr_info->repeat_cnt = 0;
							 | 
						||
| 
								 | 
							
								                flag_new = 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (lr_info->index >= lr_info->cfg->cnt) {
							 | 
						||
| 
								 | 
							
								                iot_sg_ext_lr_data_save(addr, &node->ext.lr_info.tm);
							 | 
						||
| 
								 | 
							
								                lr_info->state = IOT_SG_STA_EXT_LC_STATE_END;
							 | 
						||
| 
								 | 
							
								                if (iot_sg_ext_get_lr_time(&tm)) {
							 | 
						||
| 
								 | 
							
								                    /* get time fail, load read load curve data next time
							 | 
						||
| 
								 | 
							
								                     * stamp base on last time
							 | 
						||
| 
								 | 
							
								                     */
							 | 
						||
| 
								 | 
							
								                    node->ext.lr_info.tm = iot_sg_ext_get_next_lr_ts(
							 | 
						||
| 
								 | 
							
								                        lr_info->cfg->tm, lr_info->cfg->interval,
							 | 
						||
| 
								 | 
							
								                        node->ext.lr_info.tm);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    /* load read load curve data next time stamp base on
							 | 
						||
| 
								 | 
							
								                     * current time
							 | 
						||
| 
								 | 
							
								                     */
							 | 
						||
| 
								 | 
							
								                    node->ext.lr_info.tm = iot_sg_ext_get_next_lr_ts(
							 | 
						||
| 
								 | 
							
								                        lr_info->cfg->tm, lr_info->cfg->interval, tm);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                goto done;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (lr_info->repeat_cnt) {
							 | 
						||
| 
								 | 
							
								                lr_info->repeat_cnt--;
							 | 
						||
| 
								 | 
							
								                if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
							 | 
						||
| 
								 | 
							
								                    lr_info->index = lr_info->last_index_698;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            lr_info->state = IOT_SG_STA_EXT_LC_STATE_SEND;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            lr_info->timeout_cnt--;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_STATE_SEND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								send:
							 | 
						||
| 
								 | 
							
								        if (node->data_type == IOT_SG_STA_DATA_TYPE_69845) {
							 | 
						||
| 
								 | 
							
								            lr_info->last_index_698 = lr_info->index;
							 | 
						||
| 
								 | 
							
								            pkt = iot_sg_ext_69845_lr_mr_msg_build(addr);
							 | 
						||
| 
								 | 
							
								        } else if (node->data_type == IOT_SG_STA_DATA_TYPE_645_97) {
							 | 
						||
| 
								 | 
							
								            di_97 = iot_sg_ext_di_07_to_97(&lr_info->index,
							 | 
						||
| 
								 | 
							
								                lr_info->cfg->di_buf[lr_info->index], node->is_three_phase);
							 | 
						||
| 
								 | 
							
								            pkt = proto_645_build_mr_msg(PROTO_645_1997_ID, addr,
							 | 
						||
| 
								 | 
							
								                di_97);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            pkt = proto_645_build_mr_msg(PROTO_645_2007_ID, addr,
							 | 
						||
| 
								 | 
							
								                lr_info->cfg->di_buf[lr_info->index]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (pkt) {
							 | 
						||
| 
								 | 
							
								            timeout = (IOT_SG_STA_EXT_READ_DATA_TIMEOUT *
							 | 
						||
| 
								 | 
							
								                IOT_SG_STA_EXT_SM_DELAY / 100);
							 | 
						||
| 
								 | 
							
								            timeout = min(timeout, IOT_SG_STA_EXT_DRV_READ_TIMEOUT);
							 | 
						||
| 
								 | 
							
								            ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_READ,
							 | 
						||
| 
								 | 
							
								                addr, 0, node->data_type, iot_pkt_data(pkt),
							 | 
						||
| 
								 | 
							
								                (uint16_t)iot_pkt_data_len(pkt), timeout);
							 | 
						||
| 
								 | 
							
								            if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								                iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x read id "
							 | 
						||
| 
								 | 
							
								                    "%08x idx %lu\n",  __FUNCTION__, addr[0], addr[1], addr[2],
							 | 
						||
| 
								 | 
							
								                    addr[3], addr[4], addr[5],
							 | 
						||
| 
								 | 
							
								                    lr_info->cfg->di_buf[lr_info->index], lr_info->index);
							 | 
						||
| 
								 | 
							
								                lr_info->state = IOT_SG_STA_EXT_LC_STATE_WAIT;
							 | 
						||
| 
								 | 
							
								                lr_info->timeout_cnt = IOT_SG_STA_EXT_READ_DATA_TIMEOUT;
							 | 
						||
| 
								 | 
							
								                if (flag_new) {
							 | 
						||
| 
								 | 
							
								                    lr_info->repeat_cnt = 1;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                lr_info->flag_resp = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_SG_STA_EXT_LC_STATE_END:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        goto done;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								    complete = 1;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (last_state != lr_info->state) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s addr %02x:%02x:%02x:%02x:%02x:%02x state %lu to %lu\n"
							 | 
						||
| 
								 | 
							
								            , __FUNCTION__, addr[0], addr[1], addr[2], addr[3], addr[4],
							 | 
						||
| 
								 | 
							
								            addr[5], last_state, lr_info->state);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return complete;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_sg_ext_get_lr_interval(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t interval;
							 | 
						||
| 
								 | 
							
								    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_lc_info_t *lr_info = &ext_info->lc_info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!lr_info->cfg) {
							 | 
						||
| 
								 | 
							
								        interval = IOT_SG_STA_EXT_LC_INTER;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        interval = lr_info->cfg->interval;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return interval;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t *iot_sg_sta_ext_load_record_pw_func_1(uint8_t *addr, uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *in_data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *cnt, block_len, sum, i, j, *data, re_len;
							 | 
						||
| 
								 | 
							
								    uint16_t next_whole_t, start_idx = 0, latest_idx = 0, n, unit_len, max_cnt;
							 | 
						||
| 
								 | 
							
								    uint16_t inter_time = (uint16_t)(iot_sg_ext_get_lr_interval() / 60);
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm = { 0 }, start_tm = { 0 };
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_dl_t *curve_dl;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_pw_lc_uint_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								    proto_645_header_t *hdr = NULL;
							 | 
						||
| 
								 | 
							
								    int32_t delta;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(PROTO_645_MAX_DATA_LEN +
							 | 
						||
| 
								 | 
							
								        sizeof(*hdr) + sizeof(proto_645_tailer_t), IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    data =  iot_pkt_data(pkt);
							 | 
						||
| 
								 | 
							
								    hdr = (proto_645_header_t *)data;
							 | 
						||
| 
								 | 
							
								    proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
							 | 
						||
| 
								 | 
							
								        PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, sizeof(*hdr));
							 | 
						||
| 
								 | 
							
								    data += sizeof(*hdr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    proto_645_2007_di_to_byte(di, data);
							 | 
						||
| 
								 | 
							
								    hdr->len += PROTO_645_2007_DI_LEN;
							 | 
						||
| 
								 | 
							
								    data += PROTO_645_2007_DI_LEN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(in_data + PROTO_645_2007_DI_LEN, sizeof(*curve_dl));
							 | 
						||
| 
								 | 
							
								    curve_dl = (proto_645_07_curve_dl_t *)(in_data + PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    start_tm.tm_year = iot_bcd_to_byte(curve_dl->year) + 2000;
							 | 
						||
| 
								 | 
							
								    start_tm.tm_mon = iot_bcd_to_byte(curve_dl->mon);
							 | 
						||
| 
								 | 
							
								    start_tm.tm_mday = iot_bcd_to_byte(curve_dl->mday);
							 | 
						||
| 
								 | 
							
								    start_tm.tm_hour = iot_bcd_to_byte(curve_dl->hour);
							 | 
						||
| 
								 | 
							
								    start_tm.tm_min = iot_bcd_to_byte(curve_dl->min);
							 | 
						||
| 
								 | 
							
								    /* calculate the time of the next whole point */
							 | 
						||
| 
								 | 
							
								    next_whole_t = start_tm.tm_min % inter_time;
							 | 
						||
| 
								 | 
							
								    if (next_whole_t) {
							 | 
						||
| 
								 | 
							
								        next_whole_t = inter_time - next_whole_t;
							 | 
						||
| 
								 | 
							
								        next_whole_t *= 60;
							 | 
						||
| 
								 | 
							
								        iot_rtc_delta_add((int64_t)next_whole_t, &start_tm);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s id %08x time %lu-%lu-%lu %lu:%lu:%lu, n %lu\n",
							 | 
						||
| 
								 | 
							
								        __FUNCTION__, di, start_tm.tm_year, start_tm.tm_mon,
							 | 
						||
| 
								 | 
							
								        start_tm.tm_mday, start_tm.tm_hour, start_tm.tm_min,
							 | 
						||
| 
								 | 
							
								        start_tm.tm_sec, curve_dl->n);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    re_len = PROTO_645_MAX_DATA_LEN;
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_PW_LC, &unit_len, &max_cnt);
							 | 
						||
| 
								 | 
							
								    pkt_buff = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s pkt err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_pw_lc_uint_data_t *)iot_pkt_put(pkt_buff,
							 | 
						||
| 
								 | 
							
								        unit_len);
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_data_find_by_time(addr, &start_idx, &start_tm,
							 | 
						||
| 
								 | 
							
								            (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_PW_LC,
							 | 
						||
| 
								 | 
							
								            0)) {
							 | 
						||
| 
								 | 
							
								        goto tail;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    ret = iot_sg_sta_flash_unit_data_find_latest(addr, &latest_idx,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        goto tail;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s start idx:%d latest idx:%d\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        start_idx, latest_idx);
							 | 
						||
| 
								 | 
							
								    if (latest_idx >= start_idx) {
							 | 
						||
| 
								 | 
							
								        n = latest_idx - start_idx + 1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        n = max_cnt - (start_idx - latest_idx) + 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < n; i++) {
							 | 
						||
| 
								 | 
							
								        block_len = 0;
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_read(addr, start_idx,
							 | 
						||
| 
								 | 
							
								            (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								        if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        tm.tm_year = (uint16_t)lc_cache->year + 2000;
							 | 
						||
| 
								 | 
							
								        tm.tm_mon = (uint8_t)lc_cache->month;
							 | 
						||
| 
								 | 
							
								        tm.tm_mday = (uint8_t)lc_cache->day;
							 | 
						||
| 
								 | 
							
								        tm.tm_hour = (uint8_t)lc_cache->hour;
							 | 
						||
| 
								 | 
							
								        tm.tm_min = (uint8_t)lc_cache->minute;
							 | 
						||
| 
								 | 
							
								        delta = (int32_t)iot_rtc_delta_calc(&start_tm, &tm);
							 | 
						||
| 
								 | 
							
								        if (delta < 0 || delta >= (int32_t)(curve_dl->n * inter_time * 60))
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        if (delta % (inter_time * 60) != 0) {
							 | 
						||
| 
								 | 
							
								            goto next;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        data[block_len++] = 0xA0;
							 | 
						||
| 
								 | 
							
								        data[block_len++] = 0xA0;
							 | 
						||
| 
								 | 
							
								        cnt = data + block_len;
							 | 
						||
| 
								 | 
							
								        block_len++;
							 | 
						||
| 
								 | 
							
								        block_len += proto_645_rtctime_to_YYMMDDhhmm(&tm, data + block_len);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, &lc_cache->v, sizeof(lc_cache->v));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->v);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, &lc_cache->i, sizeof(lc_cache->i));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->i);
							 | 
						||
| 
								 | 
							
								        os_mem_set(data + block_len, 0xFF, PROTO_645_07_FREQ_LEN);
							 | 
						||
| 
								 | 
							
								        block_len += PROTO_645_07_FREQ_LEN;
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, &lc_cache->active_power,
							 | 
						||
| 
								 | 
							
								            sizeof(lc_cache->active_power));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->active_power);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, &lc_cache->reactive_power,
							 | 
						||
| 
								 | 
							
								            sizeof(lc_cache->reactive_power));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->reactive_power);
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, &lc_cache->power_factor,
							 | 
						||
| 
								 | 
							
								            sizeof(lc_cache->power_factor));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->power_factor);
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, lc_cache->ept_pos,
							 | 
						||
| 
								 | 
							
								            sizeof(lc_cache->ept_pos));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->ept_pos);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data + block_len, lc_cache->ept_neg,
							 | 
						||
| 
								 | 
							
								            sizeof(lc_cache->ept_neg));
							 | 
						||
| 
								 | 
							
								        block_len += sizeof(lc_cache->ept_neg);
							 | 
						||
| 
								 | 
							
								        os_mem_set(data + block_len, 0xFF, PROTO_645_07_ENERGY_DATA_LEN);
							 | 
						||
| 
								 | 
							
								        block_len += PROTO_645_07_ENERGY_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        os_mem_set(data + block_len, 0xFF, PROTO_645_07_ENERGY_DATA_LEN);
							 | 
						||
| 
								 | 
							
								        block_len += PROTO_645_07_ENERGY_DATA_LEN;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								        data[block_len++] = PROTO_645_DB_SEPARATE_CHAR;
							 | 
						||
| 
								 | 
							
								        *cnt = block_len - 3;
							 | 
						||
| 
								 | 
							
								        for (sum = 0, j = 0; j < block_len; j++)
							 | 
						||
| 
								 | 
							
								            sum += data[j];
							 | 
						||
| 
								 | 
							
								        data[block_len++] = sum;
							 | 
						||
| 
								 | 
							
								        data[block_len++] = 0xE5;
							 | 
						||
| 
								 | 
							
								        hdr->len += block_len;
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(block_len <= PROTO_645_07_CURVE_REC_MAX_SIZE);
							 | 
						||
| 
								 | 
							
								        re_len -= block_len;
							 | 
						||
| 
								 | 
							
								        if (re_len < block_len) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								next:
							 | 
						||
| 
								 | 
							
								        start_idx++;
							 | 
						||
| 
								 | 
							
								        if (start_idx >= max_cnt)
							 | 
						||
| 
								 | 
							
								            start_idx = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								tail:
							 | 
						||
| 
								 | 
							
								    proto_645_add33_handle(hdr->data, hdr->len);
							 | 
						||
| 
								 | 
							
								    proto_645_tail_init(hdr);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, hdr->len + sizeof(proto_645_tailer_t));
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt_buff);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_sta_ext_load_record_pw_uint_data_write(uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *data, uint8_t len, iot_sg_meter_pw_lc_uint_data_t *lc_cache)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    switch(di) {
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_V_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_V_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v.b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_V_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v.c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_V_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_I_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_I_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i.b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_I_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i.c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_I_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_P_T:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.total, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_P_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_P_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_P_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_Q_T:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power.total, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_Q_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_Q_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power.b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_Q_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power.c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_P_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_Q_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_PF_T:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor.total, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_PF_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_PF_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor.b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_PF_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor.c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_PF_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_EP_POS:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->ept_pos, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_CR_EP_NEG:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->ept_neg, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_sta_ext_load_record_fill_curve_data_pw(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t cnt, uint16_t start_idx, uint8_t *addr, iot_time_tm_t *start_tm,
							 | 
						||
| 
								 | 
							
								    uint32_t di, uint8_t uint_data_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint64_t delta;
							 | 
						||
| 
								 | 
							
								    uint32_t ret, write_cnt = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t inter_time = iot_sg_ext_get_lr_interval();
							 | 
						||
| 
								 | 
							
								    uint8_t *w_data = data, first_point = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t latest_idx, i, n, delta_cnt, unit_len, max_cnt;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm_old = { 0 }, tm_new = { 0 };
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_pw_lc_uint_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								    if (inter_time < 60) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_PW_LC, &unit_len, &max_cnt);
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s pkt err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_pw_lc_uint_data_t*)iot_pkt_put(pkt,
							 | 
						||
| 
								 | 
							
								        unit_len);
							 | 
						||
| 
								 | 
							
								    ret = iot_sg_sta_flash_unit_data_find_latest(addr, &latest_idx,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len,
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s start idx:%d latest idx:%d\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        start_idx, latest_idx);
							 | 
						||
| 
								 | 
							
								    if (latest_idx >= start_idx) {
							 | 
						||
| 
								 | 
							
								        n = latest_idx - start_idx + 1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        n = max_cnt - (start_idx - latest_idx) + 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&tm_new, start_tm, sizeof(tm_new));
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < n; i++) {
							 | 
						||
| 
								 | 
							
								        if (write_cnt == cnt) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_read(addr, start_idx,
							 | 
						||
| 
								 | 
							
								            (uint8_t *)lc_cache, unit_len,
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_PW_LC);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            tm_old = tm_new;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_year = (uint16_t)lc_cache->year + 2000;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mon = (uint8_t)lc_cache->month;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mday = (uint8_t)lc_cache->day;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_hour = (uint8_t)lc_cache->hour;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_min = (uint8_t)lc_cache->minute;
							 | 
						||
| 
								 | 
							
								            delta = iot_rtc_delta_calc(&tm_old, &tm_new);
							 | 
						||
| 
								 | 
							
								            if (delta >= (inter_time * max_cnt)) {
							 | 
						||
| 
								 | 
							
								                delta_cnt = max_cnt;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                delta_cnt = (uint16_t)(delta / inter_time);
							 | 
						||
| 
								 | 
							
								                if (delta % inter_time) {
							 | 
						||
| 
								 | 
							
								                    /* if it's not the whole point, find the next point */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!first_point) {
							 | 
						||
| 
								 | 
							
								                first_point = 1;
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if (delta_cnt >= cnt) {
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    /* delta_cnt contains the first invalid point */
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, delta_cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    write_cnt += delta_cnt;
							 | 
						||
| 
								 | 
							
								                    w_data += delta_cnt * uint_data_len;
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    /* load record delta time too short
							 | 
						||
| 
								 | 
							
								                     * ignore current data unit.
							 | 
						||
| 
								 | 
							
								                     */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                } else if (delta_cnt == 1) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if ((write_cnt + delta_cnt) > cnt) {
							 | 
						||
| 
								 | 
							
								                        delta_cnt = (uint8_t)(cnt - write_cnt);
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, delta_cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, (delta_cnt - 1) * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    w_data += ((delta_cnt - 1) * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    write_cnt += (delta_cnt - 1);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								write:
							 | 
						||
| 
								 | 
							
								            iot_sg_sta_ext_load_record_pw_uint_data_write(di, w_data,
							 | 
						||
| 
								 | 
							
								                uint_data_len, lc_cache);
							 | 
						||
| 
								 | 
							
								            write_cnt++;
							 | 
						||
| 
								 | 
							
								            w_data += uint_data_len;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								        start_idx++;
							 | 
						||
| 
								 | 
							
								        if (start_idx >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            start_idx = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (write_cnt < cnt) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(w_data, 0xFF, (cnt - write_cnt) * uint_data_len);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (pkt) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t *iot_sg_sta_ext_load_record_pw_func(uint8_t *addr, uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t curve_max_point, uint_data_len = 0, cnt;
							 | 
						||
| 
								 | 
							
								    uint16_t next_whole_t, start_idx = 0, unit_len;
							 | 
						||
| 
								 | 
							
								    uint16_t inter_time = (uint16_t)(iot_sg_ext_get_lr_interval() / 60);
							 | 
						||
| 
								 | 
							
								    uint32_t total_len, data_len;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t cache_ts = { 0 };
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_dl_t *curve_dl;
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_ul_t *curve_ul = NULL;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_pw_lc_uint_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								    proto_645_header_t *hdr = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!inter_time) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s read id %08x\n", __FUNCTION__, di);
							 | 
						||
| 
								 | 
							
								    uint_data_len = proto_645_07_get_curve_point_len(di);
							 | 
						||
| 
								 | 
							
								    if (!uint_data_len) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_max_point =(PROTO_645_MAX_DATA_LEN - PROTO_645_2007_DI_LEN -
							 | 
						||
| 
								 | 
							
								        sizeof(*curve_ul)) / uint_data_len;
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(data + PROTO_645_2007_DI_LEN, sizeof(*curve_dl));
							 | 
						||
| 
								 | 
							
								    curve_dl = (proto_645_07_curve_dl_t *)(data + PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cnt = min(curve_dl->n, curve_max_point);
							 | 
						||
| 
								 | 
							
								    data_len = PROTO_645_2007_DI_LEN + sizeof(*curve_ul) +
							 | 
						||
| 
								 | 
							
								        cnt * uint_data_len;
							 | 
						||
| 
								 | 
							
								    total_len = sizeof(*hdr) + sizeof(proto_645_tailer_t) + data_len;
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    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 = (uint8_t)data_len;
							 | 
						||
| 
								 | 
							
								    proto_645_2007_di_to_byte(di, hdr->data);
							 | 
						||
| 
								 | 
							
								    curve_ul = (proto_645_07_curve_ul_t *)(hdr->data +
							 | 
						||
| 
								 | 
							
								        PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_year = iot_bcd_to_byte(curve_dl->year) + 2000;
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mon = iot_bcd_to_byte(curve_dl->mon);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mday = iot_bcd_to_byte(curve_dl->mday);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_hour = iot_bcd_to_byte(curve_dl->hour);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_min = iot_bcd_to_byte(curve_dl->min);
							 | 
						||
| 
								 | 
							
								    /* calculate the time of the next whole point */
							 | 
						||
| 
								 | 
							
								    next_whole_t = cache_ts.tm_min % inter_time;
							 | 
						||
| 
								 | 
							
								    if (next_whole_t) {
							 | 
						||
| 
								 | 
							
								        next_whole_t = inter_time - next_whole_t;
							 | 
						||
| 
								 | 
							
								        next_whole_t *= 60;
							 | 
						||
| 
								 | 
							
								        iot_rtc_delta_add((int64_t)next_whole_t, &cache_ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_ul->year = iot_byte_to_bcd((uint8_t)(cache_ts.tm_year - 2000));
							 | 
						||
| 
								 | 
							
								    curve_ul->mon = iot_byte_to_bcd(cache_ts.tm_mon);
							 | 
						||
| 
								 | 
							
								    curve_ul->mday = iot_byte_to_bcd(cache_ts.tm_mday);
							 | 
						||
| 
								 | 
							
								    curve_ul->hour = iot_byte_to_bcd(cache_ts.tm_hour);
							 | 
						||
| 
								 | 
							
								    curve_ul->min = iot_byte_to_bcd(cache_ts.tm_min);
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_PW_LC, &unit_len, NULL);
							 | 
						||
| 
								 | 
							
								    pkt_buff = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s pkt err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_pw_lc_uint_data_t *)iot_pkt_put(pkt_buff,
							 | 
						||
| 
								 | 
							
								        unit_len);
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_data_find_by_time(addr, &start_idx, &cache_ts,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len,
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_PW_LC, 0)) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(curve_ul->data, 0xFF, cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								        goto tail;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_load_record_fill_curve_data_pw(curve_ul->data, cnt,
							 | 
						||
| 
								 | 
							
								        start_idx, addr, &cache_ts, di, uint_data_len);
							 | 
						||
| 
								 | 
							
								tail:
							 | 
						||
| 
								 | 
							
								    proto_645_add33_handle(hdr->data, hdr->len);
							 | 
						||
| 
								 | 
							
								    proto_645_tail_init(hdr);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, total_len);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt_buff);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_sta_ext_load_record_xian_uint_data_write(uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *data, uint8_t len, iot_sg_meter_lc_uint_xian_data_t *lc_cache)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    switch (di) {
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_V_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_N:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->n, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_T:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.total, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power.a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->ap_demand, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->rp_demand, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->fda_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->bda_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_V_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->v, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->i, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->active_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_Q_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->reactive_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_PF_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->power_factor, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_COMP_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, lc_cache->ca_power.total, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_COMP_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->ca_power, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->fda_power.total , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->bda_power.total , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_POS_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->cr_power1 , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->cr_power2 , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT1_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->re_1st_power , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT2_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->re_2nd_power , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT3_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->re_3rd_power , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT4_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->re_4th_power , len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->pos_ap_demand, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->neg_ap_demand, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->pos_a, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_B:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->pos_b, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(data, &lc_cache->pos_c, len);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_sta_ext_load_record_fill_curve_data_xian(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t cnt, uint16_t start_idx, uint8_t *addr, iot_time_tm_t *start_tm,
							 | 
						||
| 
								 | 
							
								    uint32_t di, uint8_t uint_data_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint64_t delta;
							 | 
						||
| 
								 | 
							
								    uint32_t ret, write_cnt = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t inter_time = iot_sg_ext_get_lr_interval();
							 | 
						||
| 
								 | 
							
								    uint8_t *w_data = data, first_point = 0, reason = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t latest_idx, i, n, delta_cnt, unit_len, max_cnt;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm_old = { 0 }, tm_new = { 0 };
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_lc_uint_xian_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (inter_time < 60) {
							 | 
						||
| 
								 | 
							
								        reason = 1;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_XIAN_LC, &unit_len, &max_cnt)) {
							 | 
						||
| 
								 | 
							
								        reason = 2;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        reason = 3;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_lc_uint_xian_data_t *)iot_pkt_put(pkt, unit_len);
							 | 
						||
| 
								 | 
							
								    ret = iot_sg_sta_flash_unit_data_find_latest(addr, &latest_idx,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        reason = 4;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s start idx:%d latest idx:%d\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        start_idx, latest_idx);
							 | 
						||
| 
								 | 
							
								    if (latest_idx >= start_idx) {
							 | 
						||
| 
								 | 
							
								        n = latest_idx - start_idx + 1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        n = max_cnt - (start_idx - latest_idx) + 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&tm_new, start_tm, sizeof(tm_new));
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < n; i++) {
							 | 
						||
| 
								 | 
							
								        if (write_cnt == cnt) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_read(addr, start_idx,
							 | 
						||
| 
								 | 
							
								            (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            tm_old = tm_new;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_year = (uint16_t)lc_cache->year + 2000;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mon = (uint8_t)lc_cache->month;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mday = (uint8_t)lc_cache->day;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_hour = (uint8_t)lc_cache->hour;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_min = (uint8_t)lc_cache->minute;
							 | 
						||
| 
								 | 
							
								            delta = iot_rtc_delta_calc(&tm_old, &tm_new);
							 | 
						||
| 
								 | 
							
								            if (delta >= (inter_time * max_cnt)) {
							 | 
						||
| 
								 | 
							
								                delta_cnt = max_cnt;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                delta_cnt = (uint16_t)(delta / inter_time);
							 | 
						||
| 
								 | 
							
								                if (delta % inter_time) {
							 | 
						||
| 
								 | 
							
								                    /* if it's not the whole point, find the next point */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!first_point) {
							 | 
						||
| 
								 | 
							
								                first_point = 1;
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if (delta_cnt >= cnt) {
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    /* delta_cnt contains the first invalid point */
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, delta_cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    write_cnt += delta_cnt;
							 | 
						||
| 
								 | 
							
								                    w_data += delta_cnt * uint_data_len;
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    /* load record delta time too short
							 | 
						||
| 
								 | 
							
								                     * ignore current data unit.
							 | 
						||
| 
								 | 
							
								                     */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                } else if (delta_cnt == 1) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if ((write_cnt + delta_cnt) > cnt) {
							 | 
						||
| 
								 | 
							
								                        delta_cnt = (uint8_t)(cnt - write_cnt);
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, delta_cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, (delta_cnt - 1) * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    w_data += ((delta_cnt - 1) * uint_data_len);
							 | 
						||
| 
								 | 
							
								                    write_cnt += (delta_cnt - 1);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								write:
							 | 
						||
| 
								 | 
							
								            iot_sg_sta_ext_load_record_xian_uint_data_write(di, w_data,
							 | 
						||
| 
								 | 
							
								                uint_data_len, lc_cache);
							 | 
						||
| 
								 | 
							
								            write_cnt++;
							 | 
						||
| 
								 | 
							
								            w_data += uint_data_len;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								        start_idx++;
							 | 
						||
| 
								 | 
							
								        if (start_idx >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            start_idx = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (reason) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (write_cnt < cnt) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(w_data, 0xFF, (cnt - write_cnt) * uint_data_len);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (pkt) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t *iot_sg_sta_ext_load_record_xian_func(uint8_t *addr, uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t curve_max_point, uint_data_len = 0, cnt;
							 | 
						||
| 
								 | 
							
								    uint16_t next_whole_t, start_idx = 0, unit_len;
							 | 
						||
| 
								 | 
							
								    uint16_t inter_time = (uint16_t)(iot_sg_ext_get_lr_interval() / 60);
							 | 
						||
| 
								 | 
							
								    uint32_t total_len, data_len;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL, *pkt_buff = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t cache_ts = { 0 };
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_xian_dl_t *curve_dl;
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_xian_ul_t *curve_ul = NULL;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_lc_uint_xian_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								    proto_645_header_t *hdr = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!inter_time) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s read id %08x\n", __FUNCTION__, di);
							 | 
						||
| 
								 | 
							
								    switch (di) {
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_V_A:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = PROTO_645_V_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_A:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_N:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = PROTO_645_07_A_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_T:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_A:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_DEMAND:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = PROTO_645_07_P_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_ALL:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_07_energy_data_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_V_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_v_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_I_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_07_a_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_P_ALL:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_Q_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_07_p_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_PF_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_07_pf_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_COMP_ALL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = sizeof(proto_645_07_energy_data_t);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_POS_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_NEG_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT1_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT2_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT3_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EQT_QRT4_SUM:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_COMP_SUM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len= PROTO_645_07_ENERGY_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_DEMAND:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_NEG_DEMAND:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len= PROTO_645_07_CURR_PD_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_A:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_B:
							 | 
						||
| 
								 | 
							
								    case PROTO_645_2007_DI_EPT_POS_C:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        uint_data_len = PROTO_645_07_ENERGY_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_NO_REQ_DATA,
							 | 
						||
| 
								 | 
							
								            addr, PROTO_645_2007_FN_READ_DATA);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_max_point =(PROTO_645_MAX_DATA_LEN - PROTO_645_2007_DI_LEN -
							 | 
						||
| 
								 | 
							
								        sizeof(*curve_ul)) / uint_data_len;
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(data + PROTO_645_2007_DI_LEN, sizeof(*curve_dl));
							 | 
						||
| 
								 | 
							
								    curve_dl = (proto_645_07_curve_xian_dl_t *)(data + PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cnt = min(curve_dl->n, curve_max_point);
							 | 
						||
| 
								 | 
							
								    data_len = PROTO_645_2007_DI_LEN + sizeof(*curve_ul) +
							 | 
						||
| 
								 | 
							
								        cnt * uint_data_len;
							 | 
						||
| 
								 | 
							
								    total_len = sizeof(*hdr) + sizeof(proto_645_tailer_t) + data_len;
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    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 = (uint8_t)data_len;
							 | 
						||
| 
								 | 
							
								    proto_645_2007_di_to_byte(di, hdr->data);
							 | 
						||
| 
								 | 
							
								    curve_ul = (proto_645_07_curve_xian_ul_t *)(hdr->data +
							 | 
						||
| 
								 | 
							
								        PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_year = iot_bcd_to_byte(curve_dl->year) + 2000;
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mon = iot_bcd_to_byte(curve_dl->mon);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mday = iot_bcd_to_byte(curve_dl->mday);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_hour = iot_bcd_to_byte(curve_dl->hour);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_min = iot_bcd_to_byte(curve_dl->min);
							 | 
						||
| 
								 | 
							
								    /* calculate the time of the next whole point */
							 | 
						||
| 
								 | 
							
								    next_whole_t = cache_ts.tm_min % inter_time;
							 | 
						||
| 
								 | 
							
								    if (next_whole_t) {
							 | 
						||
| 
								 | 
							
								        next_whole_t = inter_time - next_whole_t;
							 | 
						||
| 
								 | 
							
								        next_whole_t *= 60;
							 | 
						||
| 
								 | 
							
								        iot_rtc_delta_add((int64_t)next_whole_t, &cache_ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_ul->year = iot_byte_to_bcd((uint8_t)(cache_ts.tm_year - 2000));
							 | 
						||
| 
								 | 
							
								    curve_ul->mon = iot_byte_to_bcd(cache_ts.tm_mon);
							 | 
						||
| 
								 | 
							
								    curve_ul->mday = iot_byte_to_bcd(cache_ts.tm_mday);
							 | 
						||
| 
								 | 
							
								    curve_ul->hour = iot_byte_to_bcd(cache_ts.tm_hour);
							 | 
						||
| 
								 | 
							
								    curve_ul->min = iot_byte_to_bcd(cache_ts.tm_min);
							 | 
						||
| 
								 | 
							
								    if (inter_time > 55) {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_60MIN;
							 | 
						||
| 
								 | 
							
								    } else if (inter_time > 25) {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_30MIN;
							 | 
						||
| 
								 | 
							
								    } else if (inter_time > 10) {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_15MIN;
							 | 
						||
| 
								 | 
							
								    } else if (inter_time > 3) {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_5MIN;
							 | 
						||
| 
								 | 
							
								    } else if (inter_time) {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_1MIN;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        curve_ul->m = PROTO_645_CURVE_FREEZ_DENSITY_NO;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_ul->n = cnt;
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_get_data_info(IOT_SG_STA_METER_DATA_TYPE_XIAN_LC,
							 | 
						||
| 
								 | 
							
								        &unit_len, NULL)) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    pkt_buff = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_sg_printf("%s pkt err\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_lc_uint_xian_data_t *)iot_pkt_put(pkt_buff,
							 | 
						||
| 
								 | 
							
								        unit_len);
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_data_find_by_time(addr, &start_idx, &cache_ts,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_XIAN_LC,
							 | 
						||
| 
								 | 
							
								        0)) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(curve_ul->data, 0xFF, cnt * uint_data_len);
							 | 
						||
| 
								 | 
							
								        goto tail;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_load_record_fill_curve_data_xian(curve_ul->data, cnt,
							 | 
						||
| 
								 | 
							
								        start_idx, addr, &cache_ts, di, uint_data_len);
							 | 
						||
| 
								 | 
							
								tail:
							 | 
						||
| 
								 | 
							
								    proto_645_add33_handle(hdr->data, hdr->len);
							 | 
						||
| 
								 | 
							
								    proto_645_tail_init(hdr);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, total_len);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (pkt_buff) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt_buff);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_sg_sta_ext_load_record_fill_curve_data_gx(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t cnt, uint16_t start_idx, uint8_t *addr, iot_time_tm_t *start_tm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint64_t delta;
							 | 
						||
| 
								 | 
							
								    uint16_t latest_idx, n, i, delta_cnt, max_cnt, unit_len;
							 | 
						||
| 
								 | 
							
								    uint32_t ret, write_cnt = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t inter_time = iot_sg_ext_get_lr_interval();
							 | 
						||
| 
								 | 
							
								    uint8_t *w_data = data, first_point = 0;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t tm_old = { 0 }, tm_new = { 0 };
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_gx_lc_uint_data_t *lc_cache;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (inter_time < 60) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(w_data, 0xFF, cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								        IOT_SG_STA_METER_DATA_TYPE_GX_LC, &unit_len, &max_cnt);
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_gx_lc_uint_data_t *)iot_pkt_put(pkt, unit_len);
							 | 
						||
| 
								 | 
							
								    ret = iot_sg_sta_flash_unit_data_find_latest(addr, &latest_idx,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_GX_LC);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(w_data, 0xFF, cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_printf("%s start idx:%d latest idx:%d\n", __FUNCTION__, start_idx,
							 | 
						||
| 
								 | 
							
								        latest_idx);
							 | 
						||
| 
								 | 
							
								    if (latest_idx >= start_idx) {
							 | 
						||
| 
								 | 
							
								        n = latest_idx - start_idx + 1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        n = max_cnt - (start_idx - latest_idx) + 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&tm_new, start_tm, sizeof(tm_new));
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < n; i++) {
							 | 
						||
| 
								 | 
							
								        if (write_cnt == cnt) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        ret = iot_sg_sta_flash_unit_data_read(addr, start_idx,
							 | 
						||
| 
								 | 
							
								            (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_GX_LC);
							 | 
						||
| 
								 | 
							
								        if (ret == ERR_OK) {
							 | 
						||
| 
								 | 
							
								            tm_old = tm_new;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_year = (uint16_t)lc_cache->year + 2000;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mon = (uint8_t)lc_cache->month;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_mday = (uint8_t)lc_cache->day;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_hour = (uint8_t)lc_cache->hour;
							 | 
						||
| 
								 | 
							
								            tm_new.tm_min = (uint8_t)lc_cache->minute;
							 | 
						||
| 
								 | 
							
								            delta = iot_rtc_delta_calc(&tm_old, &tm_new);
							 | 
						||
| 
								 | 
							
								            if (delta >= (inter_time * max_cnt)) {
							 | 
						||
| 
								 | 
							
								                delta_cnt = max_cnt;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                delta_cnt = (uint16_t)(delta / inter_time);
							 | 
						||
| 
								 | 
							
								                if (delta % inter_time) {
							 | 
						||
| 
								 | 
							
								                    /* if it's not the whole point, find the next point */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!first_point) {
							 | 
						||
| 
								 | 
							
								                first_point = 1;
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if (delta_cnt >= cnt) {
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    /* delta_cnt contains the first invalid point */
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, delta_cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								                    write_cnt += delta_cnt;
							 | 
						||
| 
								 | 
							
								                    w_data += delta_cnt * PROTO_645_V_LEN;
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if (!delta_cnt) {
							 | 
						||
| 
								 | 
							
								                    /* load record delta time too short
							 | 
						||
| 
								 | 
							
								                     * ignore current data unit.
							 | 
						||
| 
								 | 
							
								                     */
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(&tm_new, &tm_old, sizeof(iot_time_tm_t));
							 | 
						||
| 
								 | 
							
								                    goto done;
							 | 
						||
| 
								 | 
							
								                } else if (delta_cnt == 1) {
							 | 
						||
| 
								 | 
							
								                    goto write;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    if ((write_cnt + delta_cnt) > cnt) {
							 | 
						||
| 
								 | 
							
								                        delta_cnt = (uint8_t)(cnt - write_cnt);
							 | 
						||
| 
								 | 
							
								                        os_mem_set(w_data, 0xFF, delta_cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								                        write_cnt = cnt;
							 | 
						||
| 
								 | 
							
								                        break;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    os_mem_set(w_data, 0xFF, (delta_cnt - 1) * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								                    w_data += ((delta_cnt - 1) * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								                    write_cnt += (delta_cnt - 1);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								write:
							 | 
						||
| 
								 | 
							
								            os_mem_cpy(w_data, lc_cache->v, PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								            write_cnt++;
							 | 
						||
| 
								 | 
							
								            w_data += PROTO_645_V_LEN;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								        start_idx++;
							 | 
						||
| 
								 | 
							
								        if (start_idx >= max_cnt) {
							 | 
						||
| 
								 | 
							
								            start_idx = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (write_cnt < cnt) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(w_data, 0xFF, (cnt - write_cnt) * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (pkt) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t *iot_sg_sta_ext_load_record_gx_func(uint8_t *addr, uint32_t di,
							 | 
						||
| 
								 | 
							
								    uint8_t *data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t cnt;
							 | 
						||
| 
								 | 
							
								    uint16_t next_whole_t, start_idx = 0,unit_len = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t inter_time = (uint16_t)(iot_sg_ext_get_lr_interval() / 60);
							 | 
						||
| 
								 | 
							
								    uint32_t total_len, data_len;
							 | 
						||
| 
								 | 
							
								    iot_sg_meter_gx_lc_uint_data_t *lc_cache = NULL;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL, *tmp = NULL;
							 | 
						||
| 
								 | 
							
								    iot_time_tm_t cache_ts = { 0 };
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_dl_t *curve_dl;
							 | 
						||
| 
								 | 
							
								    proto_645_07_curve_ul_t *curve_ul = NULL;
							 | 
						||
| 
								 | 
							
								    proto_645_header_t *hdr = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!inter_time) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_get_data_info(
							 | 
						||
| 
								 | 
							
								            IOT_SG_STA_METER_DATA_TYPE_GX_LC, &unit_len, NULL)) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    tmp = iot_pkt_alloc(unit_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!tmp) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    lc_cache = (iot_sg_meter_gx_lc_uint_data_t *)iot_pkt_put(tmp, unit_len);
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(data + PROTO_645_2007_DI_LEN, sizeof(*curve_dl));
							 | 
						||
| 
								 | 
							
								    curve_dl = (proto_645_07_curve_dl_t *)(data + PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cnt = min(curve_dl->n, PROTO_645_07_V_LR_POINT_MAX_CNT);
							 | 
						||
| 
								 | 
							
								    data_len = PROTO_645_2007_DI_LEN + sizeof(*curve_ul) +
							 | 
						||
| 
								 | 
							
								        cnt * PROTO_645_V_LEN;
							 | 
						||
| 
								 | 
							
								    total_len = sizeof(*hdr) + sizeof(proto_645_tailer_t) + data_len;
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(total_len, IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    if (!pkt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    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 = (uint8_t)data_len;
							 | 
						||
| 
								 | 
							
								    proto_645_2007_di_to_byte(di, hdr->data);
							 | 
						||
| 
								 | 
							
								    curve_ul = (proto_645_07_curve_ul_t *)(hdr->data + PROTO_645_2007_DI_LEN);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_year = iot_bcd_to_byte(curve_dl->year) + 2000;
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mon = iot_bcd_to_byte(curve_dl->mon);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_mday = iot_bcd_to_byte(curve_dl->mday);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_hour = iot_bcd_to_byte(curve_dl->hour);
							 | 
						||
| 
								 | 
							
								    cache_ts.tm_min = iot_bcd_to_byte(curve_dl->min);
							 | 
						||
| 
								 | 
							
								    /* calculate the time of the next whole point */
							 | 
						||
| 
								 | 
							
								    next_whole_t = cache_ts.tm_min % inter_time;
							 | 
						||
| 
								 | 
							
								    if (next_whole_t) {
							 | 
						||
| 
								 | 
							
								        next_whole_t = inter_time - next_whole_t;
							 | 
						||
| 
								 | 
							
								        next_whole_t *= 60;
							 | 
						||
| 
								 | 
							
								        iot_rtc_delta_add((int64_t)next_whole_t, &cache_ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    curve_ul->year = iot_byte_to_bcd((uint8_t)(cache_ts.tm_year - 2000));
							 | 
						||
| 
								 | 
							
								    curve_ul->mon = iot_byte_to_bcd(cache_ts.tm_mon);
							 | 
						||
| 
								 | 
							
								    curve_ul->mday = iot_byte_to_bcd(cache_ts.tm_mday);
							 | 
						||
| 
								 | 
							
								    curve_ul->hour = iot_byte_to_bcd(cache_ts.tm_hour);
							 | 
						||
| 
								 | 
							
								    curve_ul->min = iot_byte_to_bcd(cache_ts.tm_min);
							 | 
						||
| 
								 | 
							
								    if (iot_sg_sta_flash_unit_data_find_by_time(addr, &start_idx, &cache_ts,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)lc_cache, unit_len, IOT_SG_STA_METER_DATA_TYPE_GX_LC, 0)) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(curve_ul->data, 0xFF, cnt * PROTO_645_V_LEN);
							 | 
						||
| 
								 | 
							
								        goto tail;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_sg_sta_ext_load_record_fill_curve_data_gx(curve_ul->data, cnt,
							 | 
						||
| 
								 | 
							
								        start_idx, addr, &cache_ts);
							 | 
						||
| 
								 | 
							
								tail:
							 | 
						||
| 
								 | 
							
								    proto_645_add33_handle(hdr->data, hdr->len);
							 | 
						||
| 
								 | 
							
								    proto_645_tail_init(hdr);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, total_len);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (tmp) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(tmp);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  /* IOT_SMART_GRID_EXT_LR_FUNC_ENABLE */
							 |