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

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