765 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			765 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
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_types_api.h"
 | 
						|
#include "os_event_api.h"
 | 
						|
#include "os_timer_api.h"
 | 
						|
 | 
						|
/* iot common header files */
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_plc_api.h"
 | 
						|
#include "iot_swc_api.h"
 | 
						|
#include "iot_app_api.h"
 | 
						|
#include "iot_module_api.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "iot_queue_api.h"
 | 
						|
#include "iot_mem_pool_api.h"
 | 
						|
#include "iot_dbglog_api.h"
 | 
						|
#include "iot_task_api.h"
 | 
						|
#include "iot_oem_api.h"
 | 
						|
#include "iot_board_api.h"
 | 
						|
#include "iot_upgrade_api.h"
 | 
						|
#include "iot_sha1_api.h"
 | 
						|
 | 
						|
/* smart grid internal header files */
 | 
						|
#include "iot_sg_fr.h"
 | 
						|
#include "iot_sg.h"
 | 
						|
#include "iot_sg_msg.h"
 | 
						|
#include "iot_sg_ext.h"
 | 
						|
 | 
						|
#if (IOT_SMART_GRID_ENABLE)
 | 
						|
 | 
						|
/* smart grid PLC data default priority */
 | 
						|
#define IOT_SMART_GRID_PLC_DEFAULT_PRIO     0
 | 
						|
 | 
						|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
 | 
						|
 | 
						|
/* define smart grid message pool size */
 | 
						|
#define IOT_SG_MSG_POOL_SIZE                200
 | 
						|
 | 
						|
#else /* (HW_PLATFORM == HW_PLATFORM_SIMU) */
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
/* define smart grid message pool size */
 | 
						|
#define IOT_SG_MSG_POOL_SIZE                128
 | 
						|
#else
 | 
						|
/* define smart grid message pool size */
 | 
						|
#define IOT_SG_MSG_POOL_SIZE                (64 + 32)
 | 
						|
#endif
 | 
						|
 | 
						|
#endif /* (HW_PLATFORM == HW_PLATFORM_SIMU) */
 | 
						|
 | 
						|
/* define uart buf size */
 | 
						|
#define IOT_SG_UART_BUF_SIZE                (2048+64)
 | 
						|
 | 
						|
/* define fw_read cache size */
 | 
						|
#define IOT_SG_FW_READ_CACHE_SIZE           (512)
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
 | 
						|
#define IOT_SG_LOG_BUF_LEN                  1024
 | 
						|
#define IOT_SMART_GRID_STACK_SZIE           (1024 + 32)
 | 
						|
 | 
						|
#else /* PLC_SUPPORT_CCO_ROLE */
 | 
						|
 | 
						|
#define IOT_SG_LOG_BUF_LEN                  256
 | 
						|
#define IOT_SMART_GRID_STACK_SZIE           (512 + 256)
 | 
						|
 | 
						|
#endif /* PLC_SUPPORT_CCO_ROLE */
 | 
						|
 | 
						|
/* global variables for smart grid module */
 | 
						|
iot_sg_global_t *p_sg_glb = NULL;
 | 
						|
 | 
						|
#if SMART_GRID_DEBUG
 | 
						|
 | 
						|
static char *p_sg_log_buf = NULL;
 | 
						|
 | 
						|
void iot_sg_data_print(const char* str, uint8_t* buf, uint32_t len)
 | 
						|
{
 | 
						|
    if (p_sg_log_buf) {
 | 
						|
        uint32_t offset = 0;
 | 
						|
        offset = iot_sprintf(p_sg_log_buf, "%s[len:%d]", str, len);
 | 
						|
        for (uint32_t i = 0; i < len; ++i) {
 | 
						|
            offset += iot_sprintf(p_sg_log_buf + offset, "%02X ", buf[i]);
 | 
						|
            if (IOT_SG_LOG_BUF_LEN <= offset + 4) {
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        p_sg_log_buf[offset] = 0;
 | 
						|
        iot_sg_printf("%s\n", p_sg_log_buf);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
/* read smart grid info from persistent storage */
 | 
						|
static uint32_t iot_sg_load_pib_info()
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    uint8_t *ro = NULL, *rw = NULL;
 | 
						|
    iot_sg_app_pib_ro_t *pib = NULL;
 | 
						|
    iot_pib_type_t pibtype = MAX_PIB_TYPE + 1, temp_pt;
 | 
						|
 | 
						|
    BUILD_BUG_ON(sizeof(iot_sg_app_pib_ro_t) <= \
 | 
						|
        IOT_PIB_CCO_APP_READ_SECTION_SIZE);
 | 
						|
    BUILD_BUG_ON(sizeof(iot_sg_cco_app_pib_rw_t) <= \
 | 
						|
        IOT_PIB_CCO_APP_WRITE_SECTION_SIZE);
 | 
						|
    BUILD_BUG_ON(sizeof(p_sg_glb->pib.cco.rw->diff) <=
 | 
						|
        IOT_SG_PIB_DIFF_DATA_MAX_LEN);
 | 
						|
    BUILD_BUG_ON(sizeof(iot_sg_app_pib_ro_t) <= \
 | 
						|
        IOT_PIB_STA_APP_READ_SECTION_SIZE);
 | 
						|
    BUILD_BUG_ON(sizeof(iot_sg_sta_app_pib_rw_t) <= \
 | 
						|
        IOT_PIB_STA_APP_WRITE_SECTION_SIZE);
 | 
						|
 | 
						|
    /* get read-only secticon */
 | 
						|
    ret = iot_pib_get_app_section(&ro, &pibtype, IOT_PIB_APP_GET_READ_SECTION);
 | 
						|
    pib = (iot_sg_app_pib_ro_t *)ro;
 | 
						|
    if (ret) {
 | 
						|
        p_sg_glb->role = (iot_plc_is_client_mode() ? IOT_PLC_DEV_ROLE_STA :
 | 
						|
            IOT_PLC_DEV_ROLE_CCO);
 | 
						|
        os_mem_set(&p_sg_glb->pib, 0x0, sizeof(p_sg_glb->pib));
 | 
						|
        ret = ERR_OK;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pibtype > MAX_PIB_TYPE) {
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    /* get writable secticon */
 | 
						|
    iot_pib_get_app_section(&rw, &temp_pt, IOT_PIB_APP_GET_WRITE_SECTION);
 | 
						|
    IOT_ASSERT(rw && temp_pt == pibtype);
 | 
						|
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
    {
 | 
						|
        extern uint32_t g_module_type;
 | 
						|
        p_sg_glb->module_type = (uint8_t)g_module_type;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    {
 | 
						|
        iot_oem_base_cfg_t *oemcfg = NULL;
 | 
						|
        iot_oem_get_base_cfg(&oemcfg);
 | 
						|
        p_sg_glb->module_type = oemcfg->module_type;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    switch (p_sg_glb->module_type) {
 | 
						|
    case MODULE_TYPE_CCO:
 | 
						|
    {
 | 
						|
        p_sg_glb->role = IOT_PLC_DEV_ROLE_CCO;
 | 
						|
        p_sg_glb->pib.cco.ro = &pib->cco_pib;
 | 
						|
        p_sg_glb->pib.cco.rw = (iot_sg_cco_app_pib_rw_t *)rw;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MODULE_TYPE_STA:
 | 
						|
    case MODULE_TYPE_3_PHASE_STA:
 | 
						|
    {
 | 
						|
        p_sg_glb->role = IOT_PLC_DEV_ROLE_STA;
 | 
						|
        p_sg_glb->pib.sta.ro = &pib->pm_pib;
 | 
						|
        p_sg_glb->pib.sta.rw = (iot_sg_sta_app_pib_rw_t *)rw;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MODULE_TYPE_COLLECTOR_II:
 | 
						|
    {
 | 
						|
        p_sg_glb->role = IOT_PLC_DEV_ROLE_STA;
 | 
						|
        p_sg_glb->pib.sta.ro = &pib->ct2_pib;
 | 
						|
        p_sg_glb->pib.sta.rw = (iot_sg_sta_app_pib_rw_t *)rw;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MODULE_TYPE_STA_TEST:
 | 
						|
    {
 | 
						|
        p_sg_glb->role = IOT_PLC_DEV_ROLE_STA;
 | 
						|
        p_sg_glb->pib.sta.ro = &pib->sta_test_pib;
 | 
						|
        p_sg_glb->pib.sta.rw = (iot_sg_sta_app_pib_rw_t *)rw;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        /* unkown module type */
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* iot_sg_plc_callback() - callback method to receive messages from plc link
 | 
						|
 * @param:  param registered alone with the callback
 | 
						|
 * @pkt:    pointer to iot packet which contains the message from plc link
 | 
						|
 */
 | 
						|
static void iot_sg_plc_callback(void *param, iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)param;
 | 
						|
 | 
						|
    /* deliver the message to smart grid task for handling */
 | 
						|
    iot_task_msg_t *t_msg = iot_task_alloc_msg(p_sg_glb->task_h);
 | 
						|
    if (t_msg) {
 | 
						|
        iot_sg_msg_t *msg = (iot_sg_msg_t *)t_msg;
 | 
						|
        msg->data = pkt;
 | 
						|
        t_msg->type = IOT_SG_MSG_TYPE_PLC;
 | 
						|
        t_msg->id = IOT_SG_MSG_ID_PLC_MSG;
 | 
						|
        iot_task_queue_msg(p_sg_glb->task_h, t_msg, IOT_SG_MSG_QUEUE_LP);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * @brief: callback method to receive messages from swc link
 | 
						|
 * @pkt:   pointer to iot packet which contains the message from swc link
 | 
						|
 */
 | 
						|
void iot_sg_swc_callback(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    /* deliver the message to smart grid task for handling */
 | 
						|
    iot_task_msg_t *t_msg = iot_task_alloc_msg(p_sg_glb->task_h);
 | 
						|
    if (t_msg) {
 | 
						|
        iot_sg_msg_t *msg = (iot_sg_msg_t *)t_msg;
 | 
						|
        msg->data = pkt;
 | 
						|
        t_msg->type = IOT_SG_MSG_TYPE_SWC;
 | 
						|
        t_msg->id = IOT_SG_MSG_ID_PLC_MSG;
 | 
						|
        iot_task_queue_msg(p_sg_glb->task_h, t_msg, IOT_SG_MSG_QUEUE_LP);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_handle_plc_msg(iot_sg_msg_t *sg_msg)
 | 
						|
{
 | 
						|
    uint32_t consumed = 0;
 | 
						|
    iot_pkt_t *pkt = (iot_pkt_t *)sg_msg->data;
 | 
						|
    iot_plc_msg_header_t *hdr;
 | 
						|
    IOT_ASSERT(sg_msg->task_msg.id == IOT_SG_MSG_ID_PLC_MSG);
 | 
						|
    hdr = (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
 | 
						|
    if (hdr->app_id != IOT_PLC_APP_ID_BCAST &&
 | 
						|
        hdr->app_id != IOT_PLC_APP_SMART_GRID) {
 | 
						|
        consumed = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (p_sg_glb->plc_state.app_reg == 0 &&
 | 
						|
        hdr->msg_id != IOT_PLC_MSG_APP_REG_CONF) {
 | 
						|
        /* only handle app register confirm message before app registered */
 | 
						|
        consumed = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (hdr->msg_id) {
 | 
						|
    case IOT_PLC_MSG_APP_REG_CONF:
 | 
						|
    {
 | 
						|
        iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1);
 | 
						|
        if (rpt->result == IOT_PLC_SUCCESS ||
 | 
						|
            rpt->result == IOT_PLC_SUCCESS_MODIFIED) {
 | 
						|
            p_sg_glb->plc_state.app_reg = 1;
 | 
						|
            /* try to get the local device info */
 | 
						|
            iot_plc_query_dev_info(p_sg_glb->plc_app_h,
 | 
						|
                IOT_PLC_API_REQ_ID_DEFAULT);
 | 
						|
            iot_sg_printf("%s PLC lib registered msdu type %lu, prio %lu\n",
 | 
						|
                __FUNCTION__, rpt->type, rpt->prio);
 | 
						|
            iot_dbglog_input(IOT_SMART_GRID_MID, DBGLOG_INFO_LVL_2,
 | 
						|
                IOT_SG_HANDLE_PLC_REG_MSG_ID, 2, rpt->type, rpt->prio);
 | 
						|
        } else {
 | 
						|
            consumed = 1;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT:
 | 
						|
    {
 | 
						|
        iot_plc_dev_state_change_rpt_t* rpt =
 | 
						|
            (iot_plc_dev_state_change_rpt_t*)(hdr + 1);
 | 
						|
        if ((rpt->cert_test_detected != p_sg_glb->plc_state.cert_test_detected)
 | 
						|
            && rpt->cert_test_detected) {
 | 
						|
            iot_plc_pm_set_power_recover_policy(0);
 | 
						|
        }
 | 
						|
        p_sg_glb->plc_state.link_ready = rpt->is_ready;
 | 
						|
        p_sg_glb->plc_state.role = rpt->dev_role;
 | 
						|
        p_sg_glb->plc_state.dev_tei = rpt->dev_tei;
 | 
						|
        p_sg_glb->plc_state.pco_tei = rpt->pco_tei;
 | 
						|
        p_sg_glb->plc_state.leave_net_reason = rpt->leave_net_reason;
 | 
						|
        p_sg_glb->plc_state.level = rpt->level;
 | 
						|
        iot_mac_addr_cpy(p_sg_glb->plc_state.addr, rpt->local_mac);
 | 
						|
        iot_mac_addr_cpy(p_sg_glb->plc_state.cco_addr, rpt->cco_mac);
 | 
						|
        iot_sg_printf("%s PLC link state ready %lu, role %lu, nid %lu, "
 | 
						|
            "cco addr %02X:%02X:%02X:%02X:%02X:%02X\n",
 | 
						|
            __FUNCTION__, rpt->is_ready, rpt->dev_role, rpt->nid,
 | 
						|
            rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
 | 
						|
            rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
 | 
						|
        iot_dbglog_input(IOT_SMART_GRID_MID, DBGLOG_INFO_LVL_2,
 | 
						|
            IOT_SG_HANDLE_PLC_STATE_MSG_ID, 8, rpt->is_ready, rpt->dev_role,
 | 
						|
            rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
 | 
						|
            rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_MSG_DEV_INFO_RPT:
 | 
						|
    {
 | 
						|
        iot_plc_dev_info_rpt_t* rpt = (iot_plc_dev_info_rpt_t*)(hdr + 1);
 | 
						|
        p_sg_glb->plc_state.link_ready = rpt->is_ready;
 | 
						|
        p_sg_glb->plc_state.role = rpt->dev_role;
 | 
						|
        p_sg_glb->plc_state.reset_cnt = rpt->hw_reset_cnt + rpt->sw_reset_cnt;
 | 
						|
        p_sg_glb->plc_state.collect_type = rpt->collect_type;
 | 
						|
        p_sg_glb->plc_state.tx_3phase_flag = rpt->tx_3phase_flag;
 | 
						|
        if (!iot_mac_addr_valid(p_sg_glb->plc_state.dev_id))
 | 
						|
            iot_mac_addr_cpy(p_sg_glb->plc_state.dev_id, rpt->local_mac);
 | 
						|
        iot_mac_addr_cpy(p_sg_glb->plc_state.addr, rpt->local_mac);
 | 
						|
        iot_mac_addr_cpy(p_sg_glb->plc_state.cco_addr, rpt->cco_mac);
 | 
						|
        switch (rpt->dev_role) {
 | 
						|
        case IOT_PLC_DEV_ROLE_CCO:
 | 
						|
            /* TBD. temprarily sync up the sg role with PLC role as there
 | 
						|
             * persistent storage to load/save sg role info.
 | 
						|
             */
 | 
						|
            if (rpt->dev_role != p_sg_glb->role) {
 | 
						|
                IOT_ASSERT(0);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case IOT_PLC_DEV_ROLE_PCO:
 | 
						|
        case IOT_PLC_DEV_ROLE_STA:
 | 
						|
            /* TBD. temprarily sync up the sg role with PLC role as there
 | 
						|
             * persistent storage to load/save sg role info.
 | 
						|
             */
 | 
						|
            if (rpt->dev_role != p_sg_glb->role) {
 | 
						|
                IOT_ASSERT(0);
 | 
						|
            }
 | 
						|
            if (hdr->req_id == IOT_SG_UPDATE_PPM_INTO_OEM) {
 | 
						|
                p_sg_glb->plc_state.nw_ppm = (int8_t)rpt->nw_ppm;
 | 
						|
                iot_board_set_ppm((int8_t)rpt->nw_ppm);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            IOT_ASSERT(0);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        consumed = 1;
 | 
						|
 | 
						|
        iot_sg_printf("%s PLC link state ready %lu, role %lu, cco addr "
 | 
						|
            "%02X:%02X:%02X:%02X:%02X:%02X\n",
 | 
						|
            __FUNCTION__, rpt->is_ready, rpt->dev_role,
 | 
						|
            rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
 | 
						|
            rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
 | 
						|
        iot_dbglog_input(IOT_SMART_GRID_MID, DBGLOG_INFO_LVL_2,
 | 
						|
            IOT_SG_HANDLE_PLC_STATE_MSG_ID, 8, rpt->is_ready, rpt->dev_role,
 | 
						|
            rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
 | 
						|
            rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
out:
 | 
						|
    if (consumed)
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    return consumed;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_sg_msg_exe_func(iot_task_h task_h, iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    uint32_t consumed = 0;
 | 
						|
    iot_sg_msg_t *sg_msg = (iot_sg_msg_t *)msg;
 | 
						|
 | 
						|
    switch (msg->type) {
 | 
						|
    case IOT_SG_MSG_TYPE_SWC:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_SG_MSG_TYPE_PLC:
 | 
						|
    {
 | 
						|
        consumed = iot_sg_handle_plc_msg(sg_msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_SG_MSG_TYPE_APP_PROTO:
 | 
						|
    case IOT_SG_MSG_TYPE_APP_CLI:
 | 
						|
    case IOT_SG_MSG_TYPE_CLI:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_SG_MSG_TYPE_UART:
 | 
						|
    case IOT_SG_MSG_TYPE_INTERNAL:
 | 
						|
    case IOT_SG_MSG_TYPE_TIMER:
 | 
						|
    case IOT_SG_MSG_TYPE_DRV:
 | 
						|
    case IOT_SG_MSG_TYPE_COMMAND:
 | 
						|
    case IOT_SG_MSG_TYPE_BRM:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_SG_MSG_TYPE_SUNSOLAR:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (consumed == 0) {
 | 
						|
        p_sg_glb->msg_exe_func(sg_msg);
 | 
						|
    } else {
 | 
						|
        iot_task_free_msg(task_h, msg);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_sg_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)task_h;
 | 
						|
    iot_sg_msg_t *sg_msg = (iot_sg_msg_t *)msg;
 | 
						|
    p_sg_glb->msg_cancel_func(sg_msg);
 | 
						|
}
 | 
						|
 | 
						|
#if (!IOT_SG_EXT_SDK_ENABLE)
 | 
						|
static void iot_sg_uart_func(uint8_t* buffer, uint32_t buffer_len,
 | 
						|
    bool_t is_full_frame, uint32_t invalid_data_len)
 | 
						|
{
 | 
						|
    /* deliver the message to smart grid task for handling */
 | 
						|
    iot_task_msg_t *t_msg;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    (void)invalid_data_len; //solve warming;
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(buffer_len, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        t_msg = iot_task_alloc_msg(p_sg_glb->task_h);
 | 
						|
        if (t_msg) {
 | 
						|
            iot_sg_msg_t *msg = (iot_sg_msg_t *)t_msg;
 | 
						|
            os_mem_cpy(iot_pkt_put(pkt, buffer_len), buffer, buffer_len);
 | 
						|
 | 
						|
            iot_sg_data_print("uart recv-->", buffer, buffer_len);
 | 
						|
            iot_dbglog_input(IOT_SMART_GRID_MID, DBGLOG_INFO,
 | 
						|
                                IOT_SG_CCO_UART_RECV_DATA, 0);
 | 
						|
            msg->data = pkt;
 | 
						|
            if (is_full_frame) {
 | 
						|
                IOT_SG_EXT_UART_FULL_FRAME_SET(msg->data2);
 | 
						|
            }
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
            msg->data3 = iot_plc_get_ntb(p_sg_glb->plc_app_h);
 | 
						|
#endif
 | 
						|
            IOT_SG_EXT_UART_CHNN_SET(msg->data2,
 | 
						|
                IOT_SG_CCO_LOCAL_PROTO_DATA_SOURCE_CCTT);
 | 
						|
            t_msg->type = IOT_SG_MSG_TYPE_UART;
 | 
						|
            t_msg->id = IOT_SG_MSG_ID_UART_DATA;
 | 
						|
            iot_task_queue_msg(p_sg_glb->task_h, t_msg, IOT_SG_MSG_QUEUE_LP);
 | 
						|
        } else {
 | 
						|
            iot_pkt_free(pkt);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void iot_sg_power_down_evt_func(uint32_t message, uint32_t data)
 | 
						|
{
 | 
						|
    iot_sg_msg_t *msg;
 | 
						|
    (void)data;
 | 
						|
    msg = (iot_sg_msg_t *)iot_task_alloc_msg(p_sg_glb->task_h);
 | 
						|
    if (msg) {
 | 
						|
        msg->task_msg.type = IOT_SG_MSG_TYPE_INTERNAL;
 | 
						|
        msg->task_msg.id = IOT_SG_MSG_ID_INTERN_POWER_OFF_INIT;
 | 
						|
        msg->data2 = message;
 | 
						|
        iot_task_queue_msg(p_sg_glb->task_h, &msg->task_msg,
 | 
						|
            IOT_SG_MSG_QUEUE_HP);
 | 
						|
    } else {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t iot_sg_get_power_recover_policy()
 | 
						|
{
 | 
						|
    uint32_t policy = 0;
 | 
						|
    switch (p_sg_glb->user_type) {
 | 
						|
    case USER_TYPE_STATE_GRID_FUJIAN:
 | 
						|
        if (p_sg_glb->role != IOT_PLC_DEV_ROLE_CCO) {
 | 
						|
            policy = 1;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    case USER_TYPE_STATE_GRID_JIANGSU:
 | 
						|
        policy = 1;
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    return policy;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_init()
 | 
						|
{
 | 
						|
    iot_sg_msg_t *msg;
 | 
						|
    uint32_t ret = 0;
 | 
						|
    p_sg_glb = os_mem_malloc(IOT_SMART_GRID_MID, sizeof(*p_sg_glb));
 | 
						|
    if (p_sg_glb == NULL) {
 | 
						|
        ret = ERR_NOMEM;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
#if SMART_GRID_DEBUG
 | 
						|
    p_sg_log_buf = os_mem_malloc(IOT_SMART_GRID_MID, IOT_SG_LOG_BUF_LEN);
 | 
						|
    if (p_sg_log_buf == NULL) {
 | 
						|
        ret = ERR_NOMEM;
 | 
						|
        goto err_no_mem;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    if (iot_version_type() == 1) {
 | 
						|
        iot_cus_print_config(true);
 | 
						|
    } else {
 | 
						|
        iot_cus_print_config(false);
 | 
						|
    }
 | 
						|
 | 
						|
    ret = iot_sg_load_pib_info();
 | 
						|
    if (ret)
 | 
						|
        goto err_ps;
 | 
						|
 | 
						|
    p_sg_glb->user_type = iot_oem_get_user_type();
 | 
						|
 | 
						|
    BUILD_BUG_ON(IOT_NW_APP_ENABLE || IOT_GW_APP_ENABLE);
 | 
						|
 | 
						|
#if (IOT_GW_APP_ENABLE)
 | 
						|
 | 
						|
    p_sg_glb->app_proto = IOT_SG_APP_PROTO_GW;
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
    p_sg_glb->app_proto = IOT_SG_APP_PROTO_NW;
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
    p_sg_glb->dev_is_ready = 0;
 | 
						|
    p_sg_glb->msdu_fwd_enable = 0;
 | 
						|
 | 
						|
    iot_plc_pm_set_power_recover_policy(iot_sg_get_power_recover_policy());
 | 
						|
 | 
						|
    switch (p_sg_glb->role) {
 | 
						|
    case IOT_PLC_DEV_ROLE_CCO:
 | 
						|
        ret = iot_sg_cco_init();
 | 
						|
        break;
 | 
						|
    case IOT_PLC_DEV_ROLE_STA:
 | 
						|
    case IOT_PLC_DEV_ROLE_PCO:
 | 
						|
#if IOT_BRM_ENABLE
 | 
						|
        if (p_sg_glb->user_type != USER_TYPE_BRM_SMALL_LOAD_GOLDEN
 | 
						|
            && p_sg_glb->app_proto == IOT_SG_APP_PROTO_GW) {
 | 
						|
            p_sg_glb->user_type = USER_TYPE_BRM_PEIWANG;
 | 
						|
        }
 | 
						|
#endif
 | 
						|
        ret = iot_sg_sta_init();
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    if (ret)
 | 
						|
        goto err_role;
 | 
						|
 | 
						|
    p_sg_glb->fw_start_addr = iot_board_fw_get_start_addr();
 | 
						|
    /* create smart grid task */
 | 
						|
    os_mem_set(&p_sg_glb->task_cfg, 0, sizeof(p_sg_glb->task_cfg));
 | 
						|
    p_sg_glb->task_cfg.stack_size = IOT_SMART_GRID_STACK_SZIE;
 | 
						|
    p_sg_glb->task_cfg.task_prio = IOT_SMART_GRID_TASK_PRIO;
 | 
						|
    p_sg_glb->task_cfg.msg_size = sizeof(iot_sg_msg_t);
 | 
						|
    p_sg_glb->task_cfg.msg_cnt = IOT_SG_MSG_POOL_SIZE;
 | 
						|
    p_sg_glb->task_cfg.queue_cnt = IOT_SG_MSG_QUEUE_MAX_PRIO;
 | 
						|
    p_sg_glb->task_cfg.queue_cfg[IOT_SG_MSG_QUEUE_HP].quota = 0;
 | 
						|
    p_sg_glb->task_cfg.queue_cfg[IOT_SG_MSG_QUEUE_LP].quota = 0;
 | 
						|
    p_sg_glb->task_cfg.msg_exe_func = iot_sg_msg_exe_func;
 | 
						|
    p_sg_glb->task_cfg.msg_cancel_func = iot_sg_msg_cancel_func;
 | 
						|
 | 
						|
    p_sg_glb->task_h = iot_task_create(IOT_SMART_GRID_MID, &p_sg_glb->task_cfg);
 | 
						|
    if (p_sg_glb->task_h == NULL)
 | 
						|
        goto err_task;
 | 
						|
 | 
						|
#if (IOT_SG_EXT_SDK_ENABLE)
 | 
						|
    p_sg_glb->uart_h = NULL;
 | 
						|
    if (ERR_OK != iot_sg_ext_app_init()) {
 | 
						|
        ret = ERR_BUSY;
 | 
						|
        goto err_uart;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    /* allocate UART port for smart grid app */
 | 
						|
    p_sg_glb->uart_h = iot_uart_open(iot_board_get_uart(UART_METER_PORT),
 | 
						|
        iot_sg_uart_func, IOT_SG_UART_BUF_SIZE, NULL);
 | 
						|
 | 
						|
    if (p_sg_glb->uart_h == NULL) {
 | 
						|
        ret = ERR_BUSY;
 | 
						|
        goto err_uart;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* register smart grid app to plc network */
 | 
						|
    p_sg_glb->plc_app_cfg.app_id = IOT_PLC_APP_SMART_GRID;
 | 
						|
    p_sg_glb->plc_app_cfg.param = p_sg_glb;
 | 
						|
    p_sg_glb->plc_app_cfg.prio = IOT_SMART_GRID_PLC_DEFAULT_PRIO;
 | 
						|
    p_sg_glb->plc_app_cfg.recv = iot_sg_plc_callback;
 | 
						|
    p_sg_glb->plc_app_h = iot_plc_register_app(&p_sg_glb->plc_app_cfg);
 | 
						|
    if (p_sg_glb->plc_app_h == NULL) {
 | 
						|
        ret = ERR_BUSY;
 | 
						|
        goto err_plc;
 | 
						|
    }
 | 
						|
 | 
						|
    /* resgister power down event callback to plc */
 | 
						|
    ret = iot_plc_pm_register_listener(iot_sg_power_down_evt_func);
 | 
						|
    if (ret != ERR_OK) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_swc_init(iot_sg_swc_callback);
 | 
						|
 | 
						|
    /* post a start message */
 | 
						|
    msg = (iot_sg_msg_t *)iot_task_alloc_msg(p_sg_glb->task_h);
 | 
						|
    msg->task_msg.type = IOT_SG_MSG_TYPE_INTERNAL;
 | 
						|
    msg->task_msg.id = IOT_SG_MSG_ID_INTERN_START;
 | 
						|
    iot_task_queue_msg(p_sg_glb->task_h, &msg->task_msg, IOT_SG_MSG_QUEUE_LP);
 | 
						|
 | 
						|
    goto out;
 | 
						|
 | 
						|
err_plc:
 | 
						|
    if (NULL != p_sg_glb->uart_h) {
 | 
						|
        iot_uart_close(p_sg_glb->uart_h);
 | 
						|
        p_sg_glb->uart_h = NULL;
 | 
						|
    }
 | 
						|
err_uart:
 | 
						|
    iot_task_delete(p_sg_glb->task_h);
 | 
						|
    p_sg_glb->task_h = NULL;
 | 
						|
err_task:
 | 
						|
    switch (p_sg_glb->role) {
 | 
						|
    case IOT_PLC_DEV_ROLE_CCO:
 | 
						|
        iot_sg_cco_deinit();
 | 
						|
        break;
 | 
						|
    case IOT_PLC_DEV_ROLE_STA:
 | 
						|
    case IOT_PLC_DEV_ROLE_PCO:
 | 
						|
        iot_sg_sta_deinit();
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
err_role:
 | 
						|
err_ps:
 | 
						|
#if SMART_GRID_DEBUG
 | 
						|
    os_mem_free(p_sg_log_buf);
 | 
						|
    p_sg_log_buf = NULL;
 | 
						|
err_no_mem:
 | 
						|
#endif
 | 
						|
    os_mem_free(p_sg_glb);
 | 
						|
    p_sg_glb = NULL;
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * app_smart_grid_entry: entry for smart grid app
 | 
						|
 */
 | 
						|
uint32_t app_smart_grid_entry()
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_PENDING;
 | 
						|
 | 
						|
    if (iot_sg_init()) {
 | 
						|
        ret = ERR_OK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
iot_sg_plc_state_t* iot_sg_get_plc_state_info(void)
 | 
						|
{
 | 
						|
    return &p_sg_glb->plc_state;
 | 
						|
}
 | 
						|
 | 
						|
uint16_t iot_sg_get_chip_code()
 | 
						|
{
 | 
						|
    uint16_t chip_code, tmp_chip_code;
 | 
						|
    chip_code = iot_oem_get_chip_code();
 | 
						|
    if (0 == chip_code) {
 | 
						|
        /* if chip code is invalid, let's set chip code to 01 */
 | 
						|
        chip_code = 0x3031;
 | 
						|
    } else {
 | 
						|
        tmp_chip_code = chip_code;
 | 
						|
        chip_code = (tmp_chip_code << 8) | ((tmp_chip_code & 0xFF00) >> 8);
 | 
						|
    }
 | 
						|
    return chip_code;
 | 
						|
}
 | 
						|
 | 
						|
uint16_t iot_sg_get_vendor_id()
 | 
						|
{
 | 
						|
    return iot_board_load_user_vendor_id();
 | 
						|
}
 | 
						|
 | 
						|
uint8_t iot_sg_get_phase_cnt(uint8_t phase)
 | 
						|
{
 | 
						|
    uint8_t cnt = 0;
 | 
						|
 | 
						|
    if (phase & 0x1) {
 | 
						|
        cnt++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (phase & 0x2) {
 | 
						|
        cnt++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (phase & 0x4) {
 | 
						|
        cnt++;
 | 
						|
    }
 | 
						|
    return cnt;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_enable_cus_msdu_fwd(uint8_t enable)
 | 
						|
{
 | 
						|
    p_sg_glb->msdu_fwd_enable = !!enable;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_sg_get_fw_sha1_value(uint8_t *check_code, uint8_t check_code_len,
 | 
						|
    uint32_t check_addr, uint16_t check_len)
 | 
						|
{
 | 
						|
    uint8_t *buffer;
 | 
						|
    uint16_t buffer_cnt, i, len_tmp;
 | 
						|
    uint32_t ret = ERR_FAIL, offset = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    iot_sha1_h sha1 = NULL;
 | 
						|
 | 
						|
    if (!check_code || !check_code_len || !check_len) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (check_addr < p_sg_glb->fw_start_addr) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    offset = check_addr - p_sg_glb->fw_start_addr;
 | 
						|
    pkt = iot_pkt_alloc(IOT_SG_FW_READ_CACHE_SIZE, IOT_SMART_GRID_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        ret = ERR_NOMEM;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    buffer = iot_pkt_put(pkt, IOT_SG_FW_READ_CACHE_SIZE);
 | 
						|
    sha1 = iot_sha1_start();
 | 
						|
    if (!sha1) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    buffer_cnt = check_len / IOT_SG_FW_READ_CACHE_SIZE;
 | 
						|
    if (check_len % IOT_SG_FW_READ_CACHE_SIZE) {
 | 
						|
        buffer_cnt++;
 | 
						|
    }
 | 
						|
    for (i = 0; i < buffer_cnt; i++) {
 | 
						|
        iot_running_fw_read(offset, buffer, IOT_SG_FW_READ_CACHE_SIZE);
 | 
						|
        if (check_len >= IOT_SG_FW_READ_CACHE_SIZE) {
 | 
						|
            len_tmp = IOT_SG_FW_READ_CACHE_SIZE;
 | 
						|
        } else {
 | 
						|
            len_tmp = check_len;
 | 
						|
        }
 | 
						|
        offset += len_tmp;
 | 
						|
        check_len -= len_tmp;
 | 
						|
        iot_sha1_update(sha1, buffer, len_tmp);
 | 
						|
    }
 | 
						|
    iot_sha1_finish(sha1, check_code, check_code_len);
 | 
						|
    ret = ERR_OK;
 | 
						|
out:
 | 
						|
    if (pkt) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
    if (sha1) {
 | 
						|
        iot_sha1_end(sha1);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
#endif  /* IOT_SMART_GRID_ENABLE */
 |