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