2250 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2250 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_app_api.h"
 | 
						|
#include "iot_utils_api.h"
 | 
						|
#include "iot_upgrade_api.h"
 | 
						|
#include "iot_oem_api.h"
 | 
						|
#include "iot_board_api.h"
 | 
						|
#include "iot_bitmap_api.h"
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_system_api.h"
 | 
						|
#include "iot_plc_hw_topo_api.h"
 | 
						|
#include "iot_adc_api.h"
 | 
						|
#include "iot_version_api.h"
 | 
						|
 | 
						|
/* smart grid internal header files */
 | 
						|
#include "iot_sg.h"
 | 
						|
#include "iot_sg_sta.h"
 | 
						|
#include "proto_645.h"
 | 
						|
#include "proto_645_vendor.h"
 | 
						|
#include "proto_645_topo.h"
 | 
						|
#include "iot_sg_sta_tsfm.h"
 | 
						|
#include "iot_sg_sta_topo.h"
 | 
						|
#include "iot_sg_sta_ext.h"
 | 
						|
#include "iot_sg_sta_conn_less.h"
 | 
						|
#include "proto_hw_tsfm.h"
 | 
						|
#include "iot_sg_sta_zc.h"
 | 
						|
 | 
						|
#if (IOT_SMART_GRID_ENABLE || IOT_BSRM_MODE)
 | 
						|
 | 
						|
void proto_645_vendor_build_ver_info_base(proto_645_ext_read_ver_rsp_t *ver_rsp)
 | 
						|
{
 | 
						|
    iot_build_info_t build_info;
 | 
						|
    iot_oem_base_cfg_t *base_cfg = NULL;
 | 
						|
 | 
						|
    IOT_ASSERT(ver_rsp);
 | 
						|
    ver_rsp->type_ver = iot_version_type();
 | 
						|
    ver_rsp->firmware_version = iot_version_hex();
 | 
						|
    iot_version_get_user_build_info(&build_info);
 | 
						|
    ver_rsp->sw_ver = build_info.sw_ver;
 | 
						|
    ver_rsp->app_ver = build_info.app_ver;
 | 
						|
    ver_rsp->year = build_info.year;
 | 
						|
    ver_rsp->month = build_info.month;
 | 
						|
    ver_rsp->day = build_info.day;
 | 
						|
    ver_rsp->hour = build_info.hour;
 | 
						|
    ver_rsp->min = build_info.min;
 | 
						|
    ver_rsp->sec = build_info.sec;
 | 
						|
    iot_oem_get_base_cfg(&base_cfg);
 | 
						|
    os_mem_cpy(ver_rsp->dev_id, base_cfg->dev_id,
 | 
						|
        PROTO_645_2007_EXT_DEVICE_ID_LEN);
 | 
						|
    iot_oem_get_chip_mmid(ver_rsp->chip_mmid,
 | 
						|
        PROTO_645_2007_EXT_CHIP_MMID_ID_LEN);
 | 
						|
#if IOT_BSRM_MODE
 | 
						|
    ver_rsp->img_check_result = 1;
 | 
						|
    ver_rsp->vendor_id = iot_board_load_user_vendor_id();
 | 
						|
#else
 | 
						|
    ver_rsp->vendor_id = iot_sg_get_vendor_id();
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    if (!sta_glb->flag_img_check) {
 | 
						|
        sta_glb->img_check_result = iot_upgrade_fw_hdr_img_crc_check();
 | 
						|
        sta_glb->flag_img_check = 1;
 | 
						|
    }
 | 
						|
    ver_rsp->img_check_result = sta_glb->img_check_result;
 | 
						|
#endif /* IOT_BSRM_MODE */
 | 
						|
    if (IOT_BSRM_MODE || IOT_BRM_ENABLE) {
 | 
						|
        ver_rsp->br_ident = 1;
 | 
						|
    } else {
 | 
						|
        ver_rsp->br_ident = 0;
 | 
						|
    }
 | 
						|
    if (iot_plc_get_comm_type()) {
 | 
						|
        ver_rsp->rf = 1;
 | 
						|
    } else {
 | 
						|
        ver_rsp->rf = 0;
 | 
						|
    }
 | 
						|
    ver_rsp->reserve = 0;
 | 
						|
    ver_rsp->hw_ver = iot_board_hw_version_hex();
 | 
						|
    iot_oem_get_module_mac(ver_rsp->mod_addr);
 | 
						|
    ver_rsp->user_type = iot_oem_get_user_type();
 | 
						|
}
 | 
						|
 | 
						|
#endif /* (IOT_SMART_GRID_ENABLE || IOT_BSRM_MODE) */
 | 
						|
 | 
						|
#if IOT_BSRM_MODE
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_tcz_ver_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_EXT_DI_TCZ_READ_VER;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_read_tcz_ver_rsp_t *rsp = NULL;
 | 
						|
    iot_build_info_t build_info = { 0 };
 | 
						|
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_ext_read_tcz_ver_rsp_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_ext_read_tcz_ver_rsp_t) +
 | 
						|
            PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        rsp = (proto_645_ext_read_tcz_ver_rsp_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        rsp->vendor_id = iot_sg_get_vendor_id();
 | 
						|
        rsp->chip_type = 'H';
 | 
						|
        rsp->module_type = 'D';
 | 
						|
        iot_version_get_user_build_info(&build_info);
 | 
						|
        rsp->year = iot_byte_to_bcd(build_info.year);
 | 
						|
        rsp->month = iot_byte_to_bcd(build_info.month);
 | 
						|
        rsp->day = iot_byte_to_bcd(build_info.day);
 | 
						|
        rsp->sw_ver = build_info.sw_ver;
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_tcz_ver_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    (void)addr;
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#if (IOT_SMART_GRID_ENABLE)
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_zc_check();
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_get_mod_sw_ver();
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_build_ver_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_EXT_DI_READ_VER;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_read_ver_rsp_t *rsp = NULL;
 | 
						|
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_ext_read_ver_rsp_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_ext_read_ver_rsp_t) + PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        rsp = (proto_645_ext_read_ver_rsp_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        proto_645_vendor_build_ver_info_base(rsp);
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_build_ver2_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_EXT_DI_READ_VER_2;
 | 
						|
    iot_build_info_t build_info;
 | 
						|
    iot_oem_hw_ver_info_t ver_info;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_read_ver_rsp_v2_t *rsp = NULL;
 | 
						|
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_ext_read_ver_rsp_v2_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_ext_read_ver_rsp_v2_t) +
 | 
						|
            PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        rsp = (proto_645_ext_read_ver_rsp_v2_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        rsp->vendor_id = iot_sg_get_vendor_id();
 | 
						|
        rsp->chip_code = iot_sg_get_chip_code();
 | 
						|
        iot_oem_get_hw_ver_info(&ver_info);
 | 
						|
        iot_version_get_user_build_info(&build_info);
 | 
						|
        os_mem_cpy(rsp->module_ver, ver_info.module_version,
 | 
						|
            min(sizeof(rsp->module_ver), sizeof(ver_info.module_version)));
 | 
						|
        rsp->module_ver_year = ver_info.module_version_year;
 | 
						|
        rsp->module_ver_month = ver_info.module_version_month;
 | 
						|
        rsp->module_ver_day = ver_info.module_version_day;
 | 
						|
        rsp->sw_ver[0] = ((uint8_t)build_info.sw_ver & 0x0f) + 0x30;
 | 
						|
        rsp->sw_ver[1] = ((uint8_t)(build_info.sw_ver >> 4) & 0x0f) + 0x30;
 | 
						|
        rsp->sw_ver[2] = ((uint8_t)(build_info.sw_ver >> 8) & 0x0f) + 0x30;
 | 
						|
        rsp->sw_ver[3] = 0x56;
 | 
						|
        rsp->build_sw_ver = iot_version_hex();
 | 
						|
        rsp->sw_year = iot_byte_to_bcd(build_info.year);
 | 
						|
        rsp->sw_month = iot_byte_to_bcd(build_info.month);
 | 
						|
        rsp->sw_day = iot_byte_to_bcd(build_info.day);
 | 
						|
        os_mem_cpy(rsp->chip_ver, ver_info.chip_ver,
 | 
						|
            min(sizeof(rsp->chip_ver), sizeof(ver_info.chip_ver)));
 | 
						|
        rsp->chip_ver_year = ver_info.chip_year;
 | 
						|
        rsp->chip_ver_month = ver_info.chip_month;
 | 
						|
        rsp->chip_ver_day = ver_info.chip_day;
 | 
						|
        iot_oem_get_module_mac(rsp->dev_mac_addr);
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_mac_and_ver_info(uint8_t *addr,
 | 
						|
    uint8_t fn)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_READ_NW_VER;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_mac_and_ver_info_t *rsp = NULL;
 | 
						|
    iot_build_info_t build_info;
 | 
						|
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_ext_mac_and_ver_info_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, fn, PROTO_645_DIR_SLAVE,
 | 
						|
            PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_ext_mac_and_ver_info_t) +
 | 
						|
            PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        proto_645_add33_handle(hdr->data, PROTO_645_2007_DI_LEN);
 | 
						|
        rsp = (proto_645_ext_mac_and_ver_info_t*)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        iot_oem_get_module_mac(rsp->mac);
 | 
						|
        rsp->vendor_id = iot_sg_get_vendor_id();
 | 
						|
        iot_version_get_user_build_info(&build_info);
 | 
						|
        os_mem_cpy(rsp->module_ver, (uint8_t *)&build_info.sw_ver,
 | 
						|
            sizeof(build_info.sw_ver));
 | 
						|
        rsp->module_ver_year = build_info.year;
 | 
						|
        rsp->module_ver_month = build_info.month;
 | 
						|
        rsp->module_ver_day = build_info.day;
 | 
						|
        rsp->chip_code = iot_sg_get_chip_code();
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_basic_info(uint8_t *addr, uint32_t di)
 | 
						|
{
 | 
						|
    uint8_t chip_name_len;
 | 
						|
    uint8_t chip_name_buf[IOT_CHIP_NAME_BUFFER_MIN_LEN] = { 0 };
 | 
						|
    uint32_t length;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_07_ext_basic_info_t *basic_info;
 | 
						|
    iot_build_info_t build_info;
 | 
						|
 | 
						|
    chip_name_len = iot_board_chip_name_get(chip_name_buf,
 | 
						|
        IOT_CHIP_NAME_BUFFER_MIN_LEN);
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_07_ext_basic_info_t) + chip_name_len;
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_07_ext_basic_info_t) + chip_name_len +
 | 
						|
            PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        basic_info = (proto_645_07_ext_basic_info_t*)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        basic_info->cpu_num = 0;
 | 
						|
        basic_info->vendor_id = iot_sg_get_vendor_id();
 | 
						|
        iot_version_get_user_build_info(&build_info);
 | 
						|
        basic_info->ver_year = build_info.year;
 | 
						|
        basic_info->ver_month = build_info.month;
 | 
						|
        basic_info->ver_day = build_info.day;
 | 
						|
        basic_info->hw_ver = 1;
 | 
						|
        basic_info->sw_ver = build_info.sw_ver;
 | 
						|
        basic_info->mcu_name_len = chip_name_len;
 | 
						|
        if (chip_name_len) {
 | 
						|
            os_mem_cpy(basic_info->mcu_name, chip_name_buf, chip_name_len);
 | 
						|
        }
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_check_code(uint8_t *check_code,
 | 
						|
    uint8_t check_code_len, uint8_t *addr, uint32_t di)
 | 
						|
{
 | 
						|
    uint32_t length;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
 | 
						|
    if (!check_code || !addr) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (check_code_len != IOT_SG_SHA1_CHECK_CODE_LEN) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN + check_code_len;
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        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 = PROTO_645_2007_DI_LEN + check_code_len;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        os_mem_cpy(hdr->data + PROTO_645_2007_DI_LEN, check_code,
 | 
						|
            check_code_len);
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_core_temperature_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint8_t len;
 | 
						|
    uint32_t di = PROTO_645_2007_EXT_READ_CORE_TEMPERATURE;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_core_temperature_t *core_temp = NULL;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    float temp_cali, temp_not_cali;
 | 
						|
 | 
						|
    len = sizeof(*hdr) + PROTO_645_2007_DI_LEN + sizeof(*core_temp) +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(len, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        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 = PROTO_645_2007_DI_LEN + sizeof(*core_temp);
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        core_temp = (proto_645_ext_core_temperature_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        temp_cali = iot_adc_get_core_temperature(1) * 100;
 | 
						|
        if (temp_cali < 0) {
 | 
						|
            core_temp->temp_cali_sign = 1;
 | 
						|
        } else {
 | 
						|
            core_temp->temp_cali_sign = 0;
 | 
						|
        }
 | 
						|
        core_temp->temp_cali = (uint32_t)IOT_ABS(temp_cali);
 | 
						|
        temp_not_cali = iot_adc_get_core_temperature(0) * 100;
 | 
						|
        if (temp_not_cali < 0) {
 | 
						|
            core_temp->temp_not_cali_sign = 1;
 | 
						|
        } else {
 | 
						|
            core_temp->temp_not_cali_sign = 0;
 | 
						|
        }
 | 
						|
        core_temp->temp_not_cali = (uint32_t)IOT_ABS(temp_not_cali);
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, len);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_id_info(uint8_t *addr, uint8_t info_type)
 | 
						|
{
 | 
						|
    uint8_t *data;
 | 
						|
    uint32_t length;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    iot_oem_base_cfg_t *base_cfg = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_query_module_id_rsp_t *module_rsp;
 | 
						|
    proto_645_ext_query_chip_id_rsp_t *chip_rsp;
 | 
						|
 | 
						|
    length = sizeof(*hdr) + sizeof(proto_645_tailer_t);
 | 
						|
    switch (info_type) {
 | 
						|
    case PROTO_645_2007_EXT_CHIP_ID:
 | 
						|
    {
 | 
						|
        length += sizeof(*chip_rsp);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_MODULE_ID:
 | 
						|
    {
 | 
						|
        length += sizeof(*module_rsp);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_VER_ID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_build_ver_info(addr);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_VER2_ID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_build_ver2_info(addr);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_NW_VER_ID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_build_mac_and_ver_info(addr,
 | 
						|
            PROTO_645_2007_FN_READ_DATA);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
#if IOT_SMART_GRID_ZH_FTM_CMD_ENABLE
 | 
						|
    case PROTO_645_2007_EXT_ZC_INFO_ID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_zc_check();
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_INTER_VER_ID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_get_mod_sw_ver();
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    default:
 | 
						|
        length += PROTO_645_2007_EXT_QUERY_ID_ERR_LEN;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        data = iot_pkt_data(pkt);
 | 
						|
        hdr = (proto_645_header_t *)data;
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
        switch (info_type) {
 | 
						|
        case PROTO_645_2007_EXT_CHIP_ID:
 | 
						|
        {
 | 
						|
            hdr->len = sizeof(*chip_rsp);
 | 
						|
            chip_rsp = (proto_645_ext_query_chip_id_rsp_t*)hdr->data;
 | 
						|
            chip_rsp->info_type = info_type;
 | 
						|
            chip_rsp->info_len = PROTO_645_2007_EXT_CHIP_MMID_ID_LEN;
 | 
						|
            iot_oem_get_chip_mmid(chip_rsp->chip_mmid,
 | 
						|
                PROTO_645_2007_EXT_CHIP_MMID_ID_LEN);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_MODULE_ID:
 | 
						|
        {
 | 
						|
            hdr->len = sizeof(*module_rsp);
 | 
						|
            module_rsp = (proto_645_ext_query_module_id_rsp_t*)hdr->data;
 | 
						|
            module_rsp->info_type = info_type;
 | 
						|
            module_rsp->info_len = PROTO_645_2007_EXT_DEVICE_ID_LEN;
 | 
						|
            iot_oem_get_base_cfg(&base_cfg);
 | 
						|
            os_mem_cpy(module_rsp->dev_id, base_cfg->dev_id,
 | 
						|
                PROTO_645_2007_EXT_DEVICE_ID_LEN);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            hdr->control.ack = PROTO_645_ACK_ABNORMAL;
 | 
						|
            hdr->len = PROTO_645_2007_EXT_QUERY_ID_ERR_LEN;
 | 
						|
            hdr->data[0] = PROTO_645_2007_EXT_QUERY_ID_ERR;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_build_hn_id_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint32_t length;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    iot_oem_base_cfg_t *base_cfg = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
 | 
						|
    length = sizeof(*hdr) + sizeof(proto_645_tailer_t)
 | 
						|
        + PROTO_645_2007_EXT_DEVICE_ID_LEN;
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = PROTO_645_2007_EXT_DEVICE_ID_LEN;
 | 
						|
        iot_oem_get_base_cfg(&base_cfg);
 | 
						|
        os_mem_cpy(hdr->data, base_cfg->dev_id,
 | 
						|
           PROTO_645_2007_EXT_DEVICE_ID_LEN);
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t proto_645_vendor_set_module_id(uint8_t *data, uint8_t force)
 | 
						|
{
 | 
						|
    uint32_t ret;
 | 
						|
    iot_oem_base_cfg_t *oem_base_cfg;
 | 
						|
    iot_oem_get_base_cfg(&oem_base_cfg);
 | 
						|
    if (!force && iot_bitmap_cbs(oem_base_cfg->dev_id,
 | 
						|
        PROTO_645_2007_EXT_DEVICE_ID_LEN)) {
 | 
						|
        ret = ERR_EXIST;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    os_mem_cpy(oem_base_cfg->dev_id, data, PROTO_645_2007_EXT_DEVICE_ID_LEN);
 | 
						|
    ret = iot_oem_set_base_cfg(oem_base_cfg);
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t proto_645_vendor_set_id_info(proto_645_ext_set_id_info_req_t *req,
 | 
						|
     uint8_t force)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_INVAL;
 | 
						|
    proto_645_ext_mc_id_info_t *mc_id;
 | 
						|
    switch (req->id_type) {
 | 
						|
    case PROTO_645_2007_EXT_CHIP_ID:
 | 
						|
    {
 | 
						|
        if (req->data_len < PROTO_645_2007_EXT_CHIP_MMID_ID_LEN) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        ret = iot_oem_set_chip_mmid(req->data,
 | 
						|
            PROTO_645_2007_EXT_CHIP_MMID_ID_LEN, force);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_MODULE_ID:
 | 
						|
    {
 | 
						|
        if (req->data_len < PROTO_645_2007_EXT_DEVICE_ID_LEN) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        ret = proto_645_vendor_set_module_id(req->data, force);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_MC_ID:
 | 
						|
    {
 | 
						|
        if (req->data_len < PROTO_645_2007_EXT_DEVICE_ID_LEN +
 | 
						|
            PROTO_645_2007_EXT_CHIP_MMID_ID_LEN) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        mc_id = (proto_645_ext_mc_id_info_t *)req->data;
 | 
						|
        if (!iot_oem_set_chip_mmid(mc_id->chip_mmid,
 | 
						|
            PROTO_645_2007_EXT_CHIP_MMID_ID_LEN, force)) {
 | 
						|
            ret = ERR_OK;
 | 
						|
        }
 | 
						|
        if (!proto_645_vendor_set_module_id(mc_id->mod_id, force)) {
 | 
						|
            ret = ERR_OK;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_build_set_id_info_rsp(uint8_t *addr,
 | 
						|
    uint32_t ret)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_EXT_DI_SET_ID_INFO;
 | 
						|
    uint8_t ack, ret_code;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_ext_set_id_info_rsp_t *rsp;
 | 
						|
    proto_645_header_t *hdr;
 | 
						|
 | 
						|
    length = sizeof(*hdr) + sizeof(proto_645_tailer_t) + sizeof(*rsp) +
 | 
						|
        PROTO_645_2007_DI_LEN;
 | 
						|
    if (ret == ERR_OK) {
 | 
						|
        ack = PROTO_645_ACK_NORMAL;
 | 
						|
        ret_code = ERR_OK_SET_ID_INFO;
 | 
						|
    } else if (ret == ERR_EXIST) {
 | 
						|
        ack = PROTO_645_ACK_ABNORMAL;
 | 
						|
        ret_code = ERR_EXIST_SET_ID_INFO;
 | 
						|
    } else {
 | 
						|
        ack = PROTO_645_ACK_ABNORMAL;
 | 
						|
        ret_code = ERR_INVAL_SET_ID_INFO;
 | 
						|
    }
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_FN_WRITE_DATA,
 | 
						|
            PROTO_645_DIR_SLAVE, ack, PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(*rsp) + PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        rsp = (proto_645_ext_set_id_info_rsp_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
        rsp->ret = ret_code;
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t proto_645_vendor_handle_set_id_info_req(proto_645_header_t *hdr,
 | 
						|
    uint32_t len)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_INVAL, data_len;
 | 
						|
    uint8_t link_type;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    proto_645_ext_set_id_info_req_t *req;
 | 
						|
    link_type = sta_glb->req.link_type;
 | 
						|
 | 
						|
    if (link_type != IOT_SG_LINK_TYPE_PLC_CONN_LESS) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (hdr->control.fn != PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    data_len = len - sizeof(*hdr) - sizeof(proto_645_tailer_t);
 | 
						|
    if (hdr->len > data_len) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (hdr->len < (sizeof(*req) + PROTO_645_2007_DI_LEN)) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    req = (proto_645_ext_set_id_info_req_t *)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN);
 | 
						|
    data_len = data_len - PROTO_645_2007_DI_LEN - sizeof(*req);
 | 
						|
    if (req->data_len > data_len) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    ret = proto_645_vendor_set_id_info(req, 0);
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_br_msg(uint8_t *addr, uint8_t *data,
 | 
						|
    uint8_t len, uint32_t di, uint8_t dir, uint8_t ack)
 | 
						|
{
 | 
						|
    uint8_t data_len = len + PROTO_645_2007_DI_LEN;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr;
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(data_len + sizeof(*hdr) + sizeof(proto_645_tailer_t),
 | 
						|
        IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_EXT_FN_BR,
 | 
						|
            dir, ack, PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = data_len;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        if (data) {
 | 
						|
            os_mem_cpy(hdr->data + PROTO_645_2007_DI_LEN, data, len);
 | 
						|
        }
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, data_len + sizeof(*hdr) + sizeof(proto_645_tailer_t));
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_tsfm_launch_req(uint8_t *addr,
 | 
						|
    uint8_t *tsfm_addr, uint16_t dur_output, uint16_t ahead,
 | 
						|
    uint8_t  repeat_cnt, uint16_t send_interval, uint8_t sn, uint8_t is_rising)
 | 
						|
{
 | 
						|
    proto_645_ext_tsfm_launch_req_t req = { 0 };
 | 
						|
    req.ahead = ahead;
 | 
						|
    req.dur_output = dur_output;
 | 
						|
    req.repeat_cnt = repeat_cnt;
 | 
						|
    req.send_interval = send_interval;
 | 
						|
    req.is_rising = is_rising;
 | 
						|
    req.sn = sn;
 | 
						|
    iot_mac_addr_cpy(req.tsfm_addr, tsfm_addr);
 | 
						|
    return proto_645_vendor_build_br_msg(addr, (uint8_t *)&req, sizeof(req),
 | 
						|
        PROTO_645_2007_EXT_DI_TSFM_LAUNCH, PROTO_645_DIR_MASTER,
 | 
						|
        PROTO_645_ACK_NORMAL);
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_tsfm_clear_req(proto_645_header_t *hdr,
 | 
						|
    uint32_t di)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    uint8_t result = PROTO_645_2007_EXT_BR_RESULT_OK;
 | 
						|
    iot_sg_sta_tsfm_info_t info;
 | 
						|
    uint8_t addr[IOT_MAC_ADDR_LEN];
 | 
						|
 | 
						|
    os_mem_cpy(addr, p_sg_glb->plc_state.addr, IOT_MAC_ADDR_LEN);
 | 
						|
    iot_mac_addr_reverse(addr);
 | 
						|
    if (!iot_mac_addr_cmp(addr, hdr->addr)) {
 | 
						|
        iot_printf("%s fail for addr\n", __FUNCTION__);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    os_mem_set(&info, 0, sizeof(info));
 | 
						|
    iot_sg_sta_save_tsfm_info(&info);
 | 
						|
    pkt = proto_645_vendor_build_br_msg(hdr->addr, &result, sizeof(result), di,
 | 
						|
        PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL);
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_build_br_correct_time_req(uint8_t *addr,
 | 
						|
    iot_time_tm_t *tm)
 | 
						|
{
 | 
						|
    proto_645_corr_time_t time;
 | 
						|
 | 
						|
    time.year = iot_byte_to_bcd((uint8_t)(tm->tm_year - 2000));
 | 
						|
    time.month = iot_byte_to_bcd(tm->tm_mon);
 | 
						|
    time.day = iot_byte_to_bcd(tm->tm_mday);
 | 
						|
    time.hour = iot_byte_to_bcd(tm->tm_hour);
 | 
						|
    time.minute = iot_byte_to_bcd(tm->tm_min);
 | 
						|
    time.second = iot_byte_to_bcd(tm->tm_sec);
 | 
						|
    return proto_645_vendor_build_br_msg(addr, (uint8_t*)&time, sizeof(time),
 | 
						|
        PROTO_645_2007_EXT_BRM_CONN_CORRECT, PROTO_645_DIR_MASTER,
 | 
						|
        PROTO_645_ACK_NORMAL);
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t proto_645_vendor_br2_addr_check(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint8_t mac[IOT_MAC_ADDR_LEN] = {0}, dev_addr[IOT_MAC_ADDR_LEN] = {0};
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
 | 
						|
    os_mem_cpy(mac, p_sg_glb->plc_state.addr, IOT_MAC_ADDR_LEN);
 | 
						|
    iot_mac_addr_reverse(mac);
 | 
						|
    sta_glb->drv->get_device_addr(dev_addr);
 | 
						|
    if (!iot_mac_addr_cmp(mac, addr) && !iot_mac_addr_cmp(dev_addr, addr)) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_br2_launch_yns_req(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t result_err, reason = 0;
 | 
						|
    uint8_t req_data_len, resp_len, is_trans = 1, flag_sub33 = 0;
 | 
						|
    uint32_t di = PROTO_645_2007_EXT_DI_BR2_LAUNCH;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    iot_time_tm_t now_tm;
 | 
						|
    proto_645_header_t *result_hdr;
 | 
						|
    proto_645_ext_br2_launch_t *br_launch = NULL;
 | 
						|
    proto_645_ext_br2_launch_result_t result;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    iot_sg_sta_topo_info_t *topo_info = &sta_glb->hw_tsfm_info.tsfm_topo_info;
 | 
						|
 | 
						|
    if (!sta_glb->br2_enable) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    req_data_len = sizeof(*br_launch) + PROTO_645_2007_DI_LEN;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    flag_sub33 = 1;
 | 
						|
    br_launch = (proto_645_ext_br2_launch_t*)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN);
 | 
						|
    req_data_len = req_data_len + br_launch->code_len +
 | 
						|
        sizeof(proto_645_ext_br2_pulse_width_t);
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 4;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    switch (br_launch->trans_type) {
 | 
						|
    case PROTO_645_EXT_BR2_HANDLE:
 | 
						|
    {
 | 
						|
        is_trans = 0;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_BR2_TRANS:
 | 
						|
    {
 | 
						|
        reason = 5;
 | 
						|
        is_trans = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_BR2_HANDLE_AND_TRANS:
 | 
						|
    {
 | 
						|
        is_trans = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        reason = 6;
 | 
						|
        is_trans = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (br_launch->sn == topo_info->branch2.sn
 | 
						|
        && topo_info->branch2.sn_is_valid) {
 | 
						|
        reason = 7;
 | 
						|
        result_err = 0;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    result_err = iot_sg_sta_tsfm_topo_br2_launch_start(NULL,
 | 
						|
        br_launch->code, br_launch->code_len,
 | 
						|
        IOT_SG_STA_TSFM_BR2_PULSE_HIGH_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_PULSE_LOW_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_CHARA_BIT_DUR_DEF, NULL,
 | 
						|
        IOT_PLC_HW_TSFM_LOAD_ENCODE_RAW);
 | 
						|
    if (result_err) {
 | 
						|
        reason = 8;
 | 
						|
        result_err = 1;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    topo_info->branch2.sn_is_valid = 1;
 | 
						|
    topo_info->branch2.sn = br_launch->sn;
 | 
						|
    result_err = 0;
 | 
						|
resp:
 | 
						|
    if (is_trans) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    result.sn = br_launch->sn;
 | 
						|
    if (result_err) {
 | 
						|
        /* if there is an error, fill in 0xFF */
 | 
						|
        os_mem_set((uint8_t*)&result.tm, 0xFF, sizeof(result.tm));
 | 
						|
    } else {
 | 
						|
        iot_sg_sta_rtc_get(&now_tm, 0);
 | 
						|
        proto_645_rtctime_to_YYMMDDhhmmss(&now_tm, (uint8_t*)&result.tm);
 | 
						|
    }
 | 
						|
    resp_len = sizeof(*result_hdr) + sizeof(result) + PROTO_645_2007_DI_LEN
 | 
						|
        + sizeof(proto_645_tailer_t);
 | 
						|
    result_pkt = iot_pkt_alloc(resp_len, IOT_SMART_GRID_MID);
 | 
						|
    if (result_pkt) {
 | 
						|
        result_hdr = (proto_645_header_t*)iot_pkt_data(result_pkt);
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(result_hdr, hdr->addr,
 | 
						|
            PROTO_645_2007_FN_WRITE_DATA, PROTO_645_DIR_SLAVE,
 | 
						|
            PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
        result_hdr->len = sizeof(result) + PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, result_hdr->data);
 | 
						|
        os_mem_cpy(result_hdr->data + PROTO_645_2007_DI_LEN, &result,
 | 
						|
            sizeof(result));
 | 
						|
        proto_645_add33_handle(result_hdr->data, result_hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(result_hdr);
 | 
						|
        iot_pkt_put(result_pkt, resp_len);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_printf("%s err %lu, is_trans %lu\n", __FUNCTION__, reason,
 | 
						|
            is_trans);
 | 
						|
    }
 | 
						|
    if (flag_sub33) {
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
    }
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_br2_launch_zj_req(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t result_err = 0;
 | 
						|
    uint8_t req_data_len, is_trans = 1, flag_sub33 = 0;
 | 
						|
    uint32_t reason = 0;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    proto_645_07_time_ymdhms_t launch_tm = {0};
 | 
						|
    proto_645_ext_br2_launch_zj_hdr_t *br_hdr = NULL;
 | 
						|
    proto_645_ext_br2_launch_zj_tail_t *br_tail = NULL;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    iot_sg_ext_cus_topo_rcv_cfg_t cfg = {0};
 | 
						|
    (void)launch_tm;
 | 
						|
 | 
						|
    if (!sta_glb->br2_enable) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    req_data_len = sizeof(*br_hdr) + PROTO_645_2007_DI_LEN
 | 
						|
        + sizeof(*br_tail);
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    flag_sub33 = 1;
 | 
						|
    br_hdr = (proto_645_ext_br2_launch_zj_hdr_t*)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN);
 | 
						|
    req_data_len += br_hdr->code_len;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 4;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    br_tail = (proto_645_ext_br2_launch_zj_tail_t*)(br_hdr->code +
 | 
						|
        br_hdr->code_len);
 | 
						|
    switch (br_hdr->trans_type) {
 | 
						|
    case PROTO_645_EXT_BR2_HANDLE:
 | 
						|
    {
 | 
						|
        is_trans = 0;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_BR2_TRANS:
 | 
						|
    {
 | 
						|
        reason = 5;
 | 
						|
        is_trans = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_BR2_HANDLE_AND_TRANS:
 | 
						|
    {
 | 
						|
        is_trans = ((IOT_BSRM_MODE == IOT_BSRM_MODE_CUS_APP) || IOT_BRM_ENABLE)
 | 
						|
            ? 0 : 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        reason = 6;
 | 
						|
        is_trans = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (br_hdr->tm.year != 0xff && br_hdr->tm.month != 0xff
 | 
						|
        && br_hdr->tm.day != 0xff && br_hdr->tm.hour != 0xff
 | 
						|
        && br_hdr->tm.minute != 0xff && br_hdr->tm.second != 0xff) {
 | 
						|
        launch_tm.year = iot_byte_to_bcd(br_hdr->tm.year);
 | 
						|
        launch_tm.month = iot_byte_to_bcd(br_hdr->tm.month);
 | 
						|
        launch_tm.day = iot_byte_to_bcd(br_hdr->tm.day);
 | 
						|
        launch_tm.hour = iot_byte_to_bcd(br_hdr->tm.hour);
 | 
						|
        launch_tm.minute = iot_byte_to_bcd(br_hdr->tm.minute);
 | 
						|
        launch_tm.second = iot_byte_to_bcd(br_hdr->tm.second);
 | 
						|
    } else {
 | 
						|
        launch_tm.year = 0xff;
 | 
						|
        launch_tm.month = 0xff;
 | 
						|
        launch_tm.day = 0xff;
 | 
						|
        launch_tm.hour = 0xff;
 | 
						|
        launch_tm.minute = 0xff;
 | 
						|
        launch_tm.second = 0xff;
 | 
						|
    }
 | 
						|
    cfg.fc = (br_hdr->freq[0]) | (br_hdr->freq[1] << 8) |
 | 
						|
        (br_hdr->freq[2] << 16);
 | 
						|
    cfg.chara_bit_dur = br_hdr->chara_bit_dur;
 | 
						|
    cfg.pulse_high_dur = br_tail->pulse_high_dur;
 | 
						|
    cfg.pulse_low_dur = br_tail->pulse_low_dur;
 | 
						|
    cfg.fr_code_len = br_hdr->code_len;
 | 
						|
    os_mem_cpy(cfg.fr_code, br_hdr->code, br_hdr->code_len);
 | 
						|
    iot_sg_ext_topo_rcv_cfg_to_cus(&cfg);
 | 
						|
 | 
						|
    result_err = iot_sg_sta_tsfm_topo_br2_launch_start(&launch_tm,
 | 
						|
        br_hdr->code, br_hdr->code_len, br_tail->pulse_high_dur,
 | 
						|
        br_tail->pulse_low_dur, br_hdr->chara_bit_dur, NULL,
 | 
						|
        IOT_PLC_HW_TSFM_LOAD_ENCODE_RAW);
 | 
						|
    if (result_err) {
 | 
						|
        reason = 7;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    result_err = 0;
 | 
						|
resp:
 | 
						|
    if (is_trans) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (result_err) {
 | 
						|
        result_pkt = proto_645_2007_build_nack_msg(result_err, hdr->addr,
 | 
						|
            PROTO_645_2007_FN_WRITE_DATA);
 | 
						|
    } else {
 | 
						|
        result_pkt = proto_645_2007_build_w_rsp(hdr->addr);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_printf("%s err %lu, is_trans %lu\n", __FUNCTION__, reason,
 | 
						|
            is_trans);
 | 
						|
    }
 | 
						|
    if (flag_sub33) {
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
    }
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_br_launch_req_bj(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t req_data_len, ret;
 | 
						|
    uint32_t reason = 0;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    proto_645_ext_br_launch_bj_t *br_launch = NULL;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    iot_sg_sta_topo_info_t *topo_info = &sta_glb->hw_tsfm_info.tsfm_topo_info;
 | 
						|
    uint8_t launch_code[2];
 | 
						|
    (void)launch_code;
 | 
						|
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    req_data_len = sizeof(*br_launch) + PROTO_645_2007_DI_LEN;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 1;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    br_launch = (proto_645_ext_br_launch_bj_t*)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN);
 | 
						|
    if (br_launch->launch_sn == topo_info->branch2.sn
 | 
						|
        && topo_info->branch2.sn_is_valid) {
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    launch_code[0] = (uint8_t)br_launch->node_seq & 0xFF;
 | 
						|
    launch_code[1] = (uint8_t)((br_launch->node_seq >> 8) & 0xFF);
 | 
						|
    if (PROTO_645_EXT_BR_BJ_NODE_ID_MAX < br_launch->node_seq ||
 | 
						|
        br_launch->node_seq == 0) {
 | 
						|
        reason = 2;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    if (br_launch->chara_bit_dur > IOT_SG_STA_TSFM_BR2_CHARA_BIT_DUR_DEF) {
 | 
						|
        reason = 3;
 | 
						|
        goto resp;
 | 
						|
    }
 | 
						|
    ret = iot_sg_sta_tsfm_topo_br2_launch_start(NULL, launch_code,
 | 
						|
        sizeof(launch_code), br_launch->pulse_high_dur,
 | 
						|
        br_launch->pulse_low_dur, br_launch->chara_bit_dur, NULL,
 | 
						|
        IOT_PLC_HW_TSFM_LOAD_ENCODE_HAMMING_PREAMBLE_2);
 | 
						|
    if (ret) {
 | 
						|
        reason = 4;
 | 
						|
    }
 | 
						|
    topo_info->branch2.sn_is_valid = 1;
 | 
						|
    topo_info->branch2.sn = br_launch->launch_sn;
 | 
						|
resp:
 | 
						|
    if (reason) {
 | 
						|
        iot_printf("%s err %lu\n", __FUNCTION__, reason);
 | 
						|
        result_pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER,
 | 
						|
            hdr->addr, PROTO_645_2007_FN_WRITE_DATA);
 | 
						|
    } else {
 | 
						|
        result_pkt = proto_645_2007_build_ack_msg(hdr->addr,
 | 
						|
            PROTO_645_2007_FN_WRITE_DATA);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_handle_br2_launch_xiongan_req(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t result_err, req_data_len, reason = 0;
 | 
						|
    uint8_t code[] = {0xAA, 0xE9}, data_len = 2;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    proto_645_07_time_ymdhms_t *launch_start = NULL;
 | 
						|
 | 
						|
    (void)code;
 | 
						|
    (void)data_len;
 | 
						|
    req_data_len = sizeof(*launch_start) + PROTO_645_2007_DI_LEN +
 | 
						|
        PROTO_645_2007_PASSWORD_LEN + PROTO_645_2007_OPERATOR_LEN;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (iot_sg_sta_tsfm_supp_mode_check(IOT_PLC_HW_TSFM_SEND_MODE_LOAD)) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    launch_start = (proto_645_07_time_ymdhms_t *)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN + PROTO_645_2007_PASSWORD_LEN +
 | 
						|
        PROTO_645_2007_OPERATOR_LEN);
 | 
						|
    if (launch_start->year == 0xFF && launch_start->month == 0xFF &&
 | 
						|
        launch_start->day == 0xFF && launch_start->hour == 0xFF &&
 | 
						|
        launch_start->minute == 0xFF && launch_start->second == 0xFF) {
 | 
						|
        launch_start = NULL;
 | 
						|
    }
 | 
						|
    result_err = iot_sg_sta_tsfm_topo_br2_launch_start(launch_start, code,
 | 
						|
        data_len, IOT_SG_STA_TSFM_BR2_PULSE_HIGH_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_PULSE_LOW_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_CHARA_BIT_DUR_DEF, NULL,
 | 
						|
        IOT_PLC_HW_TSFM_LOAD_ENCODE_RAW);
 | 
						|
    if (result_err) {
 | 
						|
        result_pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER,
 | 
						|
            hdr->addr, PROTO_645_2007_FN_WRITE_DATA);
 | 
						|
    } else {
 | 
						|
        result_pkt = proto_645_2007_build_ack_msg(hdr->addr,
 | 
						|
            PROTO_645_2007_FN_WRITE_DATA);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_printf("%s err %lu\n", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_handle_tsfm_send_req(proto_645_header_t *hdr_645)
 | 
						|
{
 | 
						|
    uint8_t *data;
 | 
						|
    uint8_t size;
 | 
						|
    uint32_t ret;
 | 
						|
    iot_pkt_t *resp_pkt = NULL;
 | 
						|
    proto_645_header_t *resp_hdr;
 | 
						|
    uint8_t addr[IOT_MAC_ADDR_LEN];
 | 
						|
    proto_645_ext_tsfm_launch_req_t *head_device;
 | 
						|
    proto_645_ext_tsfm_launch_rsp_t *resp_result;
 | 
						|
    hw_tsfm_send_cfg_t cfg = { 0 };
 | 
						|
    iot_mac_addr_cpy(addr, p_sg_glb->plc_state.addr);
 | 
						|
    iot_mac_addr_reverse(addr);
 | 
						|
    if (!iot_mac_addr_cmp(addr, hdr_645->addr)) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr_645->data, hdr_645->len);
 | 
						|
    if (hdr_645->len < (sizeof(*head_device) + PROTO_645_2007_DI_LEN)) {
 | 
						|
        return resp_pkt;
 | 
						|
    }
 | 
						|
 | 
						|
    size = sizeof(*resp_hdr) + sizeof(proto_645_tailer_t)
 | 
						|
        + sizeof(*resp_result);
 | 
						|
    resp_pkt = iot_pkt_alloc(size, IOT_SMART_GRID_MID);
 | 
						|
    IOT_ASSERT(resp_pkt);
 | 
						|
    data = iot_pkt_data(resp_pkt);
 | 
						|
    resp_hdr = (proto_645_header_t*)data;
 | 
						|
    proto_645_header_init(resp_hdr, hdr_645->addr, hdr_645->control.fn,
 | 
						|
        PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
        PROTO_645_FOLLOW_INVALID);
 | 
						|
    resp_hdr->len = sizeof(*resp_result);
 | 
						|
    resp_result = (proto_645_ext_tsfm_launch_rsp_t *)resp_hdr->data;
 | 
						|
    head_device = (proto_645_ext_tsfm_launch_req_t *)
 | 
						|
        (hdr_645->data + PROTO_645_2007_DI_LEN);
 | 
						|
    if (head_device->repeat_cnt > PROTO_645_EXT_TSFM_SEND_REPEAT_CNT_MAX) {
 | 
						|
        head_device->repeat_cnt = PROTO_645_EXT_TSFM_SEND_REPEAT_CNT_DEF;
 | 
						|
    }
 | 
						|
    if (head_device->send_interval < PROTO_645_EXT_TSFM_SEND_INTERVAL_MIN ||
 | 
						|
        head_device->send_interval > PROTO_645_EXT_TSFM_SEND_INTERVAL_MAX) {
 | 
						|
        head_device->send_interval = PROTO_645_EXT_TSFM_SEND_INTERVAL_DEF;
 | 
						|
    }
 | 
						|
    cfg.mod_mode = IOT_PLC_HW_TSFM_SEND_MODE_ZC;
 | 
						|
    cfg.para.zc.dur_output = head_device->dur_output;
 | 
						|
    cfg.para.zc.ahead = head_device->ahead;
 | 
						|
    cfg.para.zc.is_rising = head_device->is_rising;
 | 
						|
    cfg.phase = IOT_PLC_PHASE_ALL;
 | 
						|
    ret = iot_sg_sta_tsfm_send_restart(head_device->repeat_cnt,
 | 
						|
        head_device->send_interval, head_device->tsfm_addr, &cfg,
 | 
						|
        head_device->sn);
 | 
						|
    iot_printf("%s ahead %lu, dur_output %lu, phase %lu is_rising: %d\n",
 | 
						|
        __FUNCTION__, cfg.para.zc.ahead, cfg.para.zc.dur_output, cfg.phase,
 | 
						|
        cfg.para.zc.is_rising);
 | 
						|
    if (ret == ERR_OK) {
 | 
						|
        resp_result->ret = PROTO_645_2007_EXT_TSFM_RESULT_OK;
 | 
						|
    } else {
 | 
						|
        resp_result->ret = PROTO_645_2007_EXT_TSFM_RESULT_BUSY;
 | 
						|
    }
 | 
						|
    proto_645_add33_handle(resp_hdr->data, resp_hdr->len);
 | 
						|
    proto_645_tail_init(resp_hdr);
 | 
						|
    iot_pkt_put(resp_pkt, size);
 | 
						|
    return resp_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_query_signal(proto_645_header_t *hdr,
 | 
						|
    int8_t snr, int8_t rssi)
 | 
						|
{
 | 
						|
    uint8_t *fill_data, fill_len;
 | 
						|
    uint32_t resp_len;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *resp_hdr;
 | 
						|
    proto_645_07_ext_signal_resp_t *signal_resp;
 | 
						|
    uint32_t di = PROTO_645_2007_EXT_QUERY_SIGNAL_ID;
 | 
						|
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    fill_data = &hdr->data[PROTO_645_2007_DI_LEN];
 | 
						|
    fill_len = hdr->len - PROTO_645_2007_DI_LEN;
 | 
						|
    resp_len = sizeof(*resp_hdr) + PROTO_645_2007_DI_LEN
 | 
						|
        + sizeof(*signal_resp) + fill_len + sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(resp_len, IOT_SMART_GRID_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    resp_hdr = (proto_645_header_t*)iot_pkt_put(pkt, resp_len);
 | 
						|
    proto_645_header_init(resp_hdr, hdr->addr,
 | 
						|
        PROTO_645_2007_FN_READ_DATA, PROTO_645_DIR_SLAVE,
 | 
						|
        PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
    resp_hdr->len = PROTO_645_2007_DI_LEN + sizeof(*signal_resp) + fill_len;
 | 
						|
    proto_645_2007_di_to_byte(di, resp_hdr->data);
 | 
						|
    signal_resp =
 | 
						|
        (proto_645_07_ext_signal_resp_t*)&resp_hdr->data[PROTO_645_2007_DI_LEN];
 | 
						|
    signal_resp->dl_snr = snr;
 | 
						|
    signal_resp->dl_rssi = rssi;
 | 
						|
    os_mem_cpy(signal_resp->fill_data, fill_data, fill_len);
 | 
						|
    proto_645_add33_handle(resp_hdr->data, resp_hdr->len);
 | 
						|
    proto_645_tail_init(resp_hdr);
 | 
						|
    goto out;
 | 
						|
drop:
 | 
						|
    iot_printf("%s fail\n", __FUNCTION__);
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_conn_tsfm_query(
 | 
						|
    proto_645_header_t *hdr_645)
 | 
						|
{
 | 
						|
    uint8_t *data, size, addr[IOT_MAC_ADDR_LEN], flag_3p = 0, v_rps = 0;
 | 
						|
    uint32_t di = PROTO_645_2007_EXT_BRM_DI_CONN_NODE_TSFM_INFO;
 | 
						|
    iot_pkt_t *resp_pkt = NULL;
 | 
						|
    proto_645_header_t *resp_hdr;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    iot_sg_sta_properties_global_t *phase_info = &sta_glb->node_properties;
 | 
						|
    iot_sg_sta_app_info_t *sta_pib = iot_sg_sta_get_rw_pib();
 | 
						|
    proto_645_ext_br_rsp_data_t *resp_data;
 | 
						|
    proto_645_07_ext_brm_nei_node_tsfm_ul_t *resp_result;
 | 
						|
    iot_sg_sta_node_desc_t *node;
 | 
						|
 | 
						|
    iot_mac_addr_cpy(addr, p_sg_glb->plc_state.addr);
 | 
						|
    iot_mac_addr_reverse(addr);
 | 
						|
    if (!iot_mac_addr_cmp(addr, hdr_645->addr) || !sta_pib) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    size = sizeof(*resp_hdr) + sizeof(proto_645_tailer_t)
 | 
						|
        + sizeof(*resp_result) + sizeof(*resp_data);
 | 
						|
    resp_pkt = iot_pkt_alloc(size, IOT_SMART_GRID_MID);
 | 
						|
    if (!resp_pkt) {
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    data = iot_pkt_data(resp_pkt);
 | 
						|
    resp_hdr = (proto_645_header_t*)data;
 | 
						|
    proto_645_header_init(resp_hdr, hdr_645->addr, hdr_645->control.fn,
 | 
						|
        PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
        PROTO_645_FOLLOW_INVALID);
 | 
						|
    resp_hdr->len = sizeof(*resp_result) + sizeof(*resp_data);
 | 
						|
    resp_data = (proto_645_ext_br_rsp_data_t *)resp_hdr->data;
 | 
						|
    proto_645_2007_di_to_byte(di, (uint8_t*)&resp_data->di);
 | 
						|
    resp_data->result = PROTO_645_2007_EXT_BR_RESULT_OK;
 | 
						|
    resp_result = (proto_645_07_ext_brm_nei_node_tsfm_ul_t*)resp_data->data;
 | 
						|
    iot_mac_addr_cpy(addr, p_sg_glb->plc_state.cco_addr);
 | 
						|
    iot_mac_addr_reverse(addr);
 | 
						|
    iot_mac_addr_cpy(resp_result->cco_addr, addr);
 | 
						|
    iot_mac_addr_cpy(resp_result->tsfm_addr, sta_pib->tsfm_addr);
 | 
						|
    resp_result->phase_1 = GW_APP_DATA_PHASE_DEFAULT;
 | 
						|
    resp_result->phase_2 = GW_APP_DATA_PHASE_DEFAULT;
 | 
						|
    resp_result->phase_3 = GW_APP_DATA_PHASE_DEFAULT;
 | 
						|
    switch (sta_pib->phase) {
 | 
						|
    case IOT_PLC_PHASE_A:
 | 
						|
    {
 | 
						|
        resp_result->phase_1 = GW_APP_DATA_PHASE_A;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_PHASE_B:
 | 
						|
    {
 | 
						|
        resp_result->phase_1 = GW_APP_DATA_PHASE_B;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_PHASE_C:
 | 
						|
    {
 | 
						|
        resp_result->phase_1 = GW_APP_DATA_PHASE_C;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        goto finish;
 | 
						|
    }
 | 
						|
    if ((phase_info->detect_state && (phase_info->phase > 1))
 | 
						|
        || iot_sg_sta_is_3p_module()) {
 | 
						|
        v_rps = phase_info->opposite_phase;
 | 
						|
        flag_3p = 1;
 | 
						|
    } else {
 | 
						|
        iot_mac_addr_cpy(addr, p_sg_glb->plc_state.addr);
 | 
						|
        iot_mac_addr_reverse(addr);
 | 
						|
        node = iot_sg_sta_node_find_by_addr(addr);
 | 
						|
        if (sta_glb->drv && (sta_glb->drv->get_device_type() ==
 | 
						|
            IOT_SG_STA_DEV_TYPE_POWER_METER) && node) {
 | 
						|
            v_rps = node->v_rps;
 | 
						|
            flag_3p = node->is_three_phase;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (flag_3p) {
 | 
						|
        switch (resp_result->phase_1) {
 | 
						|
        case GW_APP_DATA_PHASE_A:
 | 
						|
        {
 | 
						|
            if (v_rps) {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_C;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_B;
 | 
						|
            } else {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_B;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_C;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case GW_APP_DATA_PHASE_B:
 | 
						|
        {
 | 
						|
            if (v_rps) {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_A;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_C;
 | 
						|
            } else {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_C;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_A;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case GW_APP_DATA_PHASE_C:
 | 
						|
        {
 | 
						|
            if (v_rps) {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_B;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_A;
 | 
						|
            } else {
 | 
						|
                resp_result->phase_2 = GW_APP_DATA_PHASE_A;
 | 
						|
                resp_result->phase_3 = GW_APP_DATA_PHASE_B;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
           break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
finish:
 | 
						|
    proto_645_add33_handle(resp_hdr->data, resp_hdr->len);
 | 
						|
    proto_645_tail_init(resp_hdr);
 | 
						|
    iot_pkt_put(resp_pkt, size);
 | 
						|
    goto out;
 | 
						|
drop:
 | 
						|
    iot_printf("%s fail\n", __FUNCTION__);
 | 
						|
out:
 | 
						|
    return resp_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static void proto_645_vendor_handle_br_correct_time_req(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t *data, len;
 | 
						|
    iot_time_tm_t iot_ts = { 0 };
 | 
						|
    proto_645_corr_time_t *time;
 | 
						|
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    data = hdr->data + PROTO_645_2007_DI_LEN;
 | 
						|
    len = hdr->len - PROTO_645_2007_DI_LEN;
 | 
						|
    if (iot_bcd_data_check(data, len) && (len >= sizeof(*time))) {
 | 
						|
        time = (proto_645_corr_time_t*)data;
 | 
						|
        /* the year is incomplete in DL/T 645 protocol,
 | 
						|
         * so it add 2000
 | 
						|
         */
 | 
						|
        iot_ts.tm_year = iot_bcd_to_byte(time->year) + 2000;
 | 
						|
        iot_ts.tm_mon = iot_bcd_to_byte(time->month);
 | 
						|
        iot_ts.tm_mday = iot_bcd_to_byte(time->day);
 | 
						|
        iot_ts.tm_hour = iot_bcd_to_byte(time->hour);
 | 
						|
        iot_ts.tm_min = iot_bcd_to_byte(time->minute);
 | 
						|
        iot_ts.tm_sec = iot_bcd_to_byte(time->second);
 | 
						|
        if (iot_sg_sta_get_user_type() == USER_TYPE_BRM_PEIWANG_DUAL_NET) {
 | 
						|
            iot_sg_sta_rtc_set(&iot_ts, 1);
 | 
						|
            iot_sg_sta_start_get_time();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_br2_launch_record_query(
 | 
						|
    proto_645_header_t *hdr, uint32_t di, uint32_t *handle)
 | 
						|
{
 | 
						|
    uint8_t resp_data_len, last_idx = 0;
 | 
						|
    uint32_t resp_size;
 | 
						|
    iot_time_tm_t *tm;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    proto_645_header_t *result_hdr;
 | 
						|
    proto_645_ext_br2_record_cnt_rsp_t *resp_cnt;
 | 
						|
    proto_645_ext_br2_record_resp_t *resp_record;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
    iot_sg_sta_topo_info_t *topo_info = &sta_glb->hw_tsfm_info.tsfm_topo_info;
 | 
						|
    iot_sg_sta_tsfm_topo_record_t *record = &topo_info->send_record;
 | 
						|
 | 
						|
 | 
						|
    if (!sta_glb->br2_enable) {
 | 
						|
        if (handle) {
 | 
						|
            *handle = 0;
 | 
						|
        }
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (di == PROTO_645_2007_EXT_DI_BR2_RECORD_CNT) {
 | 
						|
        resp_data_len = PROTO_645_2007_DI_LEN + sizeof(*resp_cnt);
 | 
						|
    } else {
 | 
						|
        resp_data_len = PROTO_645_2007_DI_LEN + sizeof(*resp_record);
 | 
						|
        last_idx = (uint8_t)(di & 0x000000ff);
 | 
						|
        if (last_idx > record->cnt) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    resp_size = sizeof(*result_hdr) + resp_data_len +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    result_pkt = iot_pkt_alloc(resp_size, IOT_SMART_GRID_MID);
 | 
						|
    if (result_pkt) {
 | 
						|
        result_hdr = (proto_645_header_t*)iot_pkt_data(result_pkt);
 | 
						|
        /* fill in 645 header */
 | 
						|
        proto_645_header_init(result_hdr, hdr->addr,
 | 
						|
            PROTO_645_2007_FN_READ_DATA, PROTO_645_DIR_SLAVE,
 | 
						|
            PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
        result_hdr->len = resp_data_len;
 | 
						|
        proto_645_2007_di_to_byte(di, result_hdr->data);
 | 
						|
        if (di == PROTO_645_2007_EXT_DI_BR2_RECORD_CNT) {
 | 
						|
            resp_cnt = (proto_645_ext_br2_record_cnt_rsp_t*)
 | 
						|
                &result_hdr->data[PROTO_645_2007_DI_LEN];
 | 
						|
            resp_cnt->record_cnt = iot_byte_to_bcd(record->cnt);
 | 
						|
        } else {
 | 
						|
            if (last_idx > record->idx) {
 | 
						|
                last_idx = IOT_SG_STA_TSFM_TOPO_RECORD_CNT_MAX + record->idx -
 | 
						|
                    last_idx;
 | 
						|
            } else {
 | 
						|
                last_idx = record->idx - last_idx;
 | 
						|
            }
 | 
						|
            resp_record = (proto_645_ext_br2_record_resp_t*)
 | 
						|
                &result_hdr->data[PROTO_645_2007_DI_LEN];
 | 
						|
            tm = &record->list[last_idx].start_tm;
 | 
						|
            resp_record->start_tm.year = iot_byte_to_bcd((uint8_t)(tm->tm_year -
 | 
						|
                2000));
 | 
						|
            resp_record->start_tm.month = iot_byte_to_bcd(tm->tm_mon);
 | 
						|
            resp_record->start_tm.day = iot_byte_to_bcd(tm->tm_mday);
 | 
						|
            resp_record->start_tm.hour = iot_byte_to_bcd(tm->tm_hour);
 | 
						|
            resp_record->start_tm.minute = iot_byte_to_bcd(tm->tm_min);
 | 
						|
            resp_record->start_tm.second = iot_byte_to_bcd(tm->tm_sec);
 | 
						|
            tm = &record->list[last_idx].end_tm;
 | 
						|
            resp_record->end_tm.year = iot_byte_to_bcd((uint8_t)(tm->tm_year -
 | 
						|
                2000));
 | 
						|
            resp_record->end_tm.month = iot_byte_to_bcd(tm->tm_mon);
 | 
						|
            resp_record->end_tm.day = iot_byte_to_bcd(tm->tm_mday);
 | 
						|
            resp_record->end_tm.hour = iot_byte_to_bcd(tm->tm_hour);
 | 
						|
            resp_record->end_tm.minute = iot_byte_to_bcd(tm->tm_min);
 | 
						|
            resp_record->end_tm.second = iot_byte_to_bcd(tm->tm_sec);
 | 
						|
        }
 | 
						|
        proto_645_add33_handle(result_hdr->data, result_hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(result_hdr);
 | 
						|
        iot_pkt_put(result_pkt, resp_size);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_br2_launch_hn_req(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t result_err, req_data_len, reason = 0, flag_sub33 = 0;
 | 
						|
    iot_pkt_t *result_pkt = NULL;
 | 
						|
    proto_645_ext_br2_launch_fn_t *launch_start = NULL;
 | 
						|
 | 
						|
    if (iot_sg_sta_tsfm_supp_mode_check(IOT_PLC_HW_TSFM_SEND_MODE_LOAD)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (proto_645_vendor_br2_addr_check(hdr->addr)) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    req_data_len = sizeof(*launch_start) + PROTO_645_2007_DI_LEN;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    flag_sub33 = 1;
 | 
						|
    launch_start = (proto_645_ext_br2_launch_fn_t*)(hdr->data +
 | 
						|
        PROTO_645_2007_DI_LEN);
 | 
						|
    req_data_len = req_data_len + launch_start->code_len;
 | 
						|
    if (hdr->len < req_data_len) {
 | 
						|
        reason = 4;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    result_err = iot_sg_sta_tsfm_topo_br2_launch_start(NULL,
 | 
						|
        launch_start->code, launch_start->code_len,
 | 
						|
        IOT_SG_STA_TSFM_BR2_PULSE_HIGH_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_PULSE_LOW_DUR_DEF,
 | 
						|
        IOT_SG_STA_TSFM_BR2_CHARA_BIT_DUR_DEF, NULL,
 | 
						|
        IOT_PLC_HW_TSFM_LOAD_ENCODE_RAW);
 | 
						|
    if (result_err) {
 | 
						|
        result_pkt = proto_645_2007_build_nack_msg(PROTO_645_2007_ERR_OTHER,
 | 
						|
            hdr->addr, PROTO_645_1997_FN_WRITE_DATA);
 | 
						|
    } else {
 | 
						|
        result_pkt = proto_645_2007_build_ack_msg(hdr->addr,
 | 
						|
            PROTO_645_1997_FN_WRITE_DATA);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_printf("%s err %lu\n", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
    if (flag_sub33) {
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
    }
 | 
						|
    return result_pkt;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief Verify whether the message format is trigger topology.
 | 
						|
 * The message uses the fn 0x04 (only DL/T 645.97), but uses 4-byte
 | 
						|
 * Di(only DL/T 645.07), so special verification is required.
 | 
						|
 */
 | 
						|
static uint32_t proto_645_vendor_br2_launch_hn_format_check(
 | 
						|
    proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_FAIL;
 | 
						|
    uint32_t di = 0;
 | 
						|
    proto_645_ext_br2_launch_fn_t *start = NULL;
 | 
						|
    uint8_t length = PROTO_645_2007_DI_LEN + sizeof(*start);
 | 
						|
    uint8_t len_tmp = 0;
 | 
						|
 | 
						|
    if (!hdr && hdr->len < length) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (ERR_OK == proto_645_get_di_by_sub33(hdr->data, hdr->len,
 | 
						|
        PROTO_645_2007_ID, &di)) {
 | 
						|
        if (di == PROTO_645_EXT_BR2_LAUNCH_START) {
 | 
						|
            start = (proto_645_ext_br2_launch_fn_t*)(hdr->data +
 | 
						|
                PROTO_645_2007_DI_LEN);
 | 
						|
            len_tmp = start->code_len;
 | 
						|
            proto_645_sub33_handle(&len_tmp, sizeof(len_tmp));
 | 
						|
            length += len_tmp;
 | 
						|
            if (hdr->len == length) {
 | 
						|
                ret = ERR_OK;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief Parse the PPM Ping package and return the data.
 | 
						|
 */
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_ppm_ping(proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    int reason = 0;
 | 
						|
    iot_pkt_t *rsp_pkt = NULL;
 | 
						|
    uint32_t length = 0;
 | 
						|
    uint8_t mac[IOT_MAC_ADDR_LEN] = {0};
 | 
						|
    proto_645_header_t *rsp_header = NULL;
 | 
						|
    iot_sg_plc_state_t *plc_glb = &p_sg_glb->plc_state;
 | 
						|
 | 
						|
    if (hdr->len < (sizeof(proto_645_ext_brm_ppm_ping_t) +
 | 
						|
        PROTO_645_2007_DI_LEN)) {
 | 
						|
        reason = 1;
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    iot_mac_addr_cpy(mac, hdr->addr);
 | 
						|
    iot_mac_addr_reverse(mac);
 | 
						|
    if (!iot_mac_addr_cmp(mac, plc_glb->addr)) {
 | 
						|
        reason = 2;
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    length = sizeof(*hdr) + hdr->len + sizeof(proto_645_tailer_t);
 | 
						|
    rsp_pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (!rsp_pkt) {
 | 
						|
        reason = 2;
 | 
						|
        goto drop;
 | 
						|
    }
 | 
						|
    rsp_header = (proto_645_header_t *)iot_pkt_data(rsp_pkt);
 | 
						|
    proto_645_header_init(rsp_header, hdr->addr, hdr->control.fn,
 | 
						|
        PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL, PROTO_645_FOLLOW_INVALID);
 | 
						|
    rsp_header->len = hdr->len;
 | 
						|
    os_mem_cpy(rsp_header->data, hdr->data, hdr->len);
 | 
						|
    proto_645_tail_init(rsp_header);
 | 
						|
    iot_pkt_put(rsp_pkt, length);
 | 
						|
    goto out;
 | 
						|
drop:
 | 
						|
    if (rsp_pkt) {
 | 
						|
        iot_pkt_free(rsp_pkt);
 | 
						|
        rsp_pkt = NULL;
 | 
						|
    }
 | 
						|
    if (reason) {
 | 
						|
        iot_sg_printf("%s err %lu\n", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return rsp_pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_handle_query_pt_info(uint8_t *addr)
 | 
						|
{
 | 
						|
    uint32_t length, di = PROTO_645_2007_EXT_QUERY_PT_INFO;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_read_pt_info_rsp_t *rsp = NULL;
 | 
						|
    iot_board_pt_info_t pt_info = {0};
 | 
						|
 | 
						|
    length = PROTO_645_2007_READ_DATA_PKT_LEN +
 | 
						|
        sizeof(proto_645_ext_read_pt_info_rsp_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, addr, PROTO_645_2007_FN_READ_DATA,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(proto_645_ext_read_pt_info_rsp_t) +
 | 
						|
            PROTO_645_2007_DI_LEN;
 | 
						|
        proto_645_2007_di_to_byte(di, hdr->data);
 | 
						|
        rsp = (proto_645_ext_read_pt_info_rsp_t *)(hdr->data +
 | 
						|
            PROTO_645_2007_DI_LEN);
 | 
						|
 | 
						|
        os_mem_set((uint8_t *)rsp, 0, sizeof(*rsp));
 | 
						|
        iot_board_get_pt_info(&pt_info);
 | 
						|
 | 
						|
        /* production test ppm */
 | 
						|
        if (pt_info.ppm_valid) {
 | 
						|
            rsp->local_pt_ppm_valid = 1;
 | 
						|
            rsp->local_pt_ppm = pt_info.ppm;
 | 
						|
        }
 | 
						|
        /* compensation ppm, not used for sta/cco */
 | 
						|
        rsp->local_tool_ppm_valid = 0;
 | 
						|
 | 
						|
        /* basic production test info */
 | 
						|
        if (pt_info.basic_info_valid) {
 | 
						|
            rsp->basic_data_valid = 1;
 | 
						|
            iot_mac_addr_cpy(rsp->basic_data.golden_mac,
 | 
						|
                pt_info.basic_info.golden_mac);
 | 
						|
            rsp->basic_data.year = pt_info.basic_info.year;
 | 
						|
            rsp->basic_data.month = pt_info.basic_info.month;
 | 
						|
            rsp->basic_data.day = pt_info.basic_info.day;
 | 
						|
            rsp->basic_data.hour = pt_info.basic_info.hour;
 | 
						|
            rsp->basic_data.min = pt_info.basic_info.min;
 | 
						|
            rsp->basic_data.golden_fw_ver = pt_info.basic_info.golden_fw_ver;
 | 
						|
            rsp->basic_data.pt_tool_ver = pt_info.basic_info.pt_tool_ver;
 | 
						|
            rsp->basic_data.pt_board_ver = pt_info.basic_info.pt_board_ver;
 | 
						|
        }
 | 
						|
        /* the dut firmware version, which supported the production test */
 | 
						|
        if (pt_info.pt_dut_ver_valid) {
 | 
						|
            rsp->pt_dut_fw_valid = 1;
 | 
						|
            rsp->pt_dut_fw_ver = pt_info.pt_dut_ver;
 | 
						|
        }
 | 
						|
        /* fix ppm ,not used for sta/cco */
 | 
						|
        rsp->local_fix_ppm_valid = 0;
 | 
						|
 | 
						|
        proto_645_add33_handle(hdr->data, hdr->len);
 | 
						|
        /* fill in 645 tailer */
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t proto_645_handle_vendor_proto(uint8_t *data, uint32_t len,
 | 
						|
    int8_t snr, int8_t rssi)
 | 
						|
{
 | 
						|
    uint32_t handled = 0, di, ret;
 | 
						|
    uint8_t fn, data_type, user_type = iot_sg_sta_get_user_type();
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr;
 | 
						|
    iot_sg_sta_global_t *sta_glb = p_sg_glb->desc.sta;
 | 
						|
 | 
						|
    data_type = (uint8_t)sta_glb->mr.data_type;
 | 
						|
    hdr = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
 | 
						|
    if (!hdr) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (hdr->control.fn == PROTO_645_1997_FN_WRITE_DATA) {
 | 
						|
        if (proto_645_vendor_br2_launch_hn_format_check(hdr) == ERR_OK) {
 | 
						|
            pkt = proto_645_vendor_handle_br2_launch_hn_req(hdr);
 | 
						|
            if (pkt) {
 | 
						|
                handled = 1;
 | 
						|
            }
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    ret = proto_645_get_di(data, len, PROTO_645_DIR_MASTER, &di, &fn);
 | 
						|
    switch (hdr->control.fn) {
 | 
						|
    case PROTO_645_2007_EXT_FN_QUERY_ID:
 | 
						|
    {
 | 
						|
        if (hdr->len == PROTO_645_EXT_QUERY_ID_DATA_LEN) {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_build_id_info(hdr->addr, hdr->data[0]);
 | 
						|
        } else if (hdr->len == PROTO_645_2007_DI_LEN &&
 | 
						|
            di == PROTO_645_2007_EXT_DI_TCZ_READ_VER) {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_build_tcz_ver_info(hdr->addr);
 | 
						|
        } else if (!hdr->len) {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_build_hn_id_info(hdr->addr);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_FN_BR:
 | 
						|
    {
 | 
						|
        if (ret != ERR_OK) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        switch (di) {
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_LAUNCH:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_br_launch_req(hdr, di, 1);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_LAUNCH_STATE:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_br_launch_state_req(hdr, di, 1);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_INFO_QUERY:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_br_info_query_req(hdr, di, 1);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_INFO_CLEAN:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_br_info_clean_req(hdr, di, 1);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_TSFM_LAUNCH:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_tsfm_send_req(hdr);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_TSFM_LAUNCH_CLEAR:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_build_tsfm_clear_req(hdr, di);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_BRM_DI_CONN_NODE_TSFM_INFO:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_conn_tsfm_query(hdr);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_BRM_CONN_CORRECT:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            proto_645_vendor_handle_br_correct_time_req(hdr);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_BRM_PPM_PING:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            pkt = proto_645_vendor_handle_ppm_ping(hdr);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        if (ret != ERR_OK) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        switch (di) {
 | 
						|
        case PROTO_645_2007_EXT_DI_READ_VER:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_build_ver_info(hdr->addr);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_READ_VER_2:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_build_ver2_info(hdr->addr);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_READ_TSFM_INFO:
 | 
						|
        case PROTO_645_2007_EXT_DI_WRITE_TSFM_INFO:
 | 
						|
        {
 | 
						|
            ret = iot_sg_sta_tsfm_msg_handle_from_cco(data_type, data, len);
 | 
						|
            if (ret == ERR_OK) {
 | 
						|
                return 1;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_SET_ID_INFO:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            ret = proto_645_vendor_handle_set_id_info_req(hdr, len);
 | 
						|
            /* set MC_ID only responds OK or INVAL */
 | 
						|
            pkt = proto_645_vendor_build_set_id_info_rsp(hdr->addr, ret);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_READ_NW_VER:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_build_mac_and_ver_info(hdr->addr,
 | 
						|
                    PROTO_645_2007_FN_READ_DATA);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_DI_START_SCORE:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA &&
 | 
						|
                iot_mac_addr_cmp(hdr->addr, proto_645_bcast_addr) &&
 | 
						|
                !sta_glb->ext_info.score_info.enable) {
 | 
						|
                sta_glb->ext_info.score_info.enable = 1;
 | 
						|
                sta_glb->ext_info.score_info.score_en_ts =
 | 
						|
                    os_boot_time64() / 1000;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_QUERY_SIGNAL_ID:
 | 
						|
        {
 | 
						|
            if (user_type == USER_TYPE_STATE_GRID_FUJIAN) {
 | 
						|
                goto out;
 | 
						|
            }
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_query_signal(hdr, snr, rssi);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_QUERY_PT_INFO:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_query_pt_info(hdr->addr);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_CNT:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST1:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST2:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST3:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST4:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST5:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST6:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST7:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST8:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST9:
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_RECORD_LAST10:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                handled = 1;
 | 
						|
                pkt = proto_645_vendor_handle_br2_launch_record_query(hdr, di,
 | 
						|
                    &handled);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_LAUNCH_ZJ:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br2_launch_zj_req(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_LAUNCH:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br2_launch_yns_req(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_BJ_INIT:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br_recv_init_bj(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_BJ_LAUNCH:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br_launch_req_bj(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR_BJ_INFO_QUERY:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br_info_query_req_bj(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_DI_BR2_LAUNCH_XIONGAN:
 | 
						|
        {
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_WRITE_DATA) {
 | 
						|
                pkt = proto_645_vendor_handle_br2_launch_xiongan_req(hdr);
 | 
						|
                if (pkt) {
 | 
						|
                    handled = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_645_2007_EXT_READ_CORE_TEMPERATURE:
 | 
						|
        {
 | 
						|
            handled = 1;
 | 
						|
            if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
                pkt = proto_645_vendor_build_core_temperature_info(hdr->addr);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (handled) {
 | 
						|
        iot_sg_sta_meter_read_done_framework(data_type, pkt);
 | 
						|
    }
 | 
						|
    return handled;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_handle_vendor_proto_cco(uint8_t *cco_addr,
 | 
						|
    uint8_t *data, uint32_t len, int8_t snr, int8_t rssi)
 | 
						|
{
 | 
						|
    uint32_t di, ret;
 | 
						|
    uint8_t fn;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr;
 | 
						|
 | 
						|
    hdr = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
 | 
						|
    if (!hdr) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (!iot_mac_addr_cmp(hdr->addr, cco_addr)) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    ret = proto_645_get_di(data, len, PROTO_645_DIR_MASTER, &di, &fn);
 | 
						|
    if (ret != ERR_OK) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    switch (di) {
 | 
						|
    case PROTO_645_2007_EXT_QUERY_SIGNAL_ID:
 | 
						|
    {
 | 
						|
        if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
            pkt = proto_645_vendor_handle_query_signal(hdr, snr, rssi);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_EXT_QUERY_PT_INFO:
 | 
						|
    {
 | 
						|
        if (hdr->control.fn == PROTO_645_2007_FN_READ_DATA) {
 | 
						|
            pkt = proto_645_vendor_handle_query_pt_info(hdr->addr);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_get_mod_sw_ver()
 | 
						|
{
 | 
						|
    uint32_t length = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
    proto_645_ext_ft_mode_sw_ver_resp_t *sw_ver = NULL;
 | 
						|
    uint8_t buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    iot_build_info_t build_info;
 | 
						|
 | 
						|
    length = sizeof(*hdr) + sizeof(proto_645_tailer_t) + sizeof(*func) +
 | 
						|
        sizeof(*sw_ver);
 | 
						|
    iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
    iot_mac_addr_reverse(buf_addr);
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
 | 
						|
        hdr->len = sizeof(*func) + sizeof(*sw_ver);
 | 
						|
 | 
						|
        iot_version_get_user_build_info(&build_info);
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_GET_SW_VER;
 | 
						|
 | 
						|
        sw_ver = (proto_645_ext_ft_mode_sw_ver_resp_t *)func->data;
 | 
						|
        sw_ver->day = iot_byte_to_bcd(build_info.day);
 | 
						|
        sw_ver->mon = iot_byte_to_bcd(build_info.month);
 | 
						|
        sw_ver->year = iot_byte_to_bcd(build_info.year);
 | 
						|
        sw_ver->ver = iot_version_packed();
 | 
						|
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_set_chip_mmid(proto_645_header_t *header)
 | 
						|
{
 | 
						|
    uint8_t reason = 0;
 | 
						|
    uint32_t ret = ERR_FAIL, length = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func;
 | 
						|
    uint8_t buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
 | 
						|
    if (header->len < (sizeof(*func) + IOT_CHIP_MMID_LEN)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    func = (proto_645_ext_ft_mode_code_t *)header->data;
 | 
						|
    ret = iot_oem_set_chip_mmid(func->data, IOT_CHIP_MMID_LEN, 1);
 | 
						|
    if (ret != ERR_OK) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    length = sizeof(*hdr) + sizeof(*func) + IOT_CHIP_MMID_LEN +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
        iot_mac_addr_reverse(buf_addr);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = IOT_CHIP_MMID_LEN + sizeof(proto_645_ext_ft_mode_code_t);
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_GET_CHIP_MMID;
 | 
						|
        iot_oem_get_chip_mmid(func->data, IOT_CHIP_MMID_LEN);
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_sg_printf("%s reason %lu\n", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_get_chip_mmid(proto_645_header_t *header)
 | 
						|
{
 | 
						|
    uint32_t length = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
    uint8_t buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
 | 
						|
    (void)header;
 | 
						|
    length = sizeof(*hdr) + sizeof(*func) + IOT_CHIP_MMID_LEN +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
        iot_mac_addr_reverse(buf_addr);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(*func) + IOT_CHIP_MMID_LEN;
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_GET_CHIP_MMID;
 | 
						|
        iot_oem_get_chip_mmid(func->data, IOT_CHIP_MMID_LEN);
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *proto_645_vendor_zc_check()
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    uint32_t length = 0;
 | 
						|
    uint8_t i, buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    iot_sg_sta_zc_check_t *check = &p_sg_glb->desc.sta->check;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
    proto_645_ext_ft_mode_zc_check_info_t *zc_info = NULL;
 | 
						|
 | 
						|
    iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
    iot_mac_addr_reverse(buf_addr);
 | 
						|
    iot_sg_sta_zc_start();
 | 
						|
    os_delay(500);
 | 
						|
    iot_sg_sta_zc_stop();
 | 
						|
    length = sizeof(*hdr) + sizeof(*func) + sizeof(*zc_info) +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(*func) + sizeof(*zc_info);
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_ZC_CHECK;
 | 
						|
        zc_info = (proto_645_ext_ft_mode_zc_check_info_t *)func->data;
 | 
						|
        zc_info->clct_type = PROTO_645_EXT_ZC_CLCT_MODE_RISING;
 | 
						|
        zc_info->meter_type = iot_sg_sta_is_3p_module()
 | 
						|
            ? PROTO_645_EXT_ZC_METER_PHASE_THREE
 | 
						|
            : PROTO_645_EXT_ZC_METER_PHASE_SINGLE;
 | 
						|
        for (i = 0; i < IOT_PLC_PHASE_CNT; i++) {
 | 
						|
            if (check->trig_cnt[i] == 0) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            zc_info->data[i].exist = 1;
 | 
						|
            zc_info->data[i].period =
 | 
						|
                (check->total_time[i] / check->trig_cnt[i]) * 25;
 | 
						|
        }
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_set_comm_address(proto_645_header_t *header)
 | 
						|
{
 | 
						|
    uint8_t reason = 0;
 | 
						|
    uint32_t length = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
    uint8_t buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
 | 
						|
    (void)header;
 | 
						|
    if (header->len != (sizeof(*func) + IOT_MAC_ADDR_LEN)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    func = (proto_645_ext_ft_mode_code_t *)header->data;
 | 
						|
    iot_mac_addr_reverse(func->data);
 | 
						|
    iot_oem_set_module_mac(func->data);
 | 
						|
    length = sizeof(*hdr) + sizeof(*func) + IOT_MAC_ADDR_LEN +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
        iot_mac_addr_reverse(buf_addr);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(*func) + IOT_MAC_ADDR_LEN;
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_SET_COMM_ADDR;
 | 
						|
        if (iot_oem_get_module_mac(func->data)) {
 | 
						|
            os_mem_set(func->data, 0xFF, IOT_MAC_ADDR_LEN);
 | 
						|
        } else {
 | 
						|
            iot_mac_addr_reverse(func->data);
 | 
						|
        }
 | 
						|
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_sg_printf("%s reason %u\n", __FUNCTION__, reason);
 | 
						|
        if (pkt) {
 | 
						|
            iot_pkt_free(pkt);
 | 
						|
            pkt = NULL;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_get_comm_address(proto_645_header_t *header)
 | 
						|
{
 | 
						|
    uint32_t length = 0;
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
    uint8_t buf_addr[IOT_MAC_ADDR_LEN];
 | 
						|
 | 
						|
    (void)header;
 | 
						|
    length = sizeof(*hdr) + sizeof(*func) + IOT_MAC_ADDR_LEN +
 | 
						|
        sizeof(proto_645_tailer_t);
 | 
						|
    pkt = iot_pkt_alloc(length, IOT_SMART_GRID_MID);
 | 
						|
    if (pkt) {
 | 
						|
        hdr = (proto_645_header_t *)iot_pkt_data(pkt);
 | 
						|
        iot_mac_addr_cpy(buf_addr, p_sg_glb->plc_state.addr);
 | 
						|
        iot_mac_addr_reverse(buf_addr);
 | 
						|
        proto_645_header_init(hdr, buf_addr, PROTO_645_2007_EXT_FN_QUERY_ID,
 | 
						|
            PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            PROTO_645_FOLLOW_INVALID);
 | 
						|
        hdr->len = sizeof(*func) + IOT_MAC_ADDR_LEN;
 | 
						|
        func = (proto_645_ext_ft_mode_code_t *)hdr->data;
 | 
						|
        func->ft_mode = PROTO_645_EXT_FT_MODE_GET_COMM_ADDR;
 | 
						|
        if (iot_oem_get_module_mac(func->data)) {
 | 
						|
            os_mem_set(func->data, 0xFF, IOT_MAC_ADDR_LEN);
 | 
						|
        } else {
 | 
						|
            iot_mac_addr_reverse(func->data);
 | 
						|
        }
 | 
						|
        proto_645_tail_init(hdr);
 | 
						|
        iot_pkt_put(pkt, length);
 | 
						|
    }
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
iot_pkt_t *proto_645_vendor_sta_nw_ext_uart_cmd_handle(
 | 
						|
    proto_645_header_t *header)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_ext_ft_mode_code_t *func = NULL;
 | 
						|
 | 
						|
    if (header->len < sizeof(*func)) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    func = (proto_645_ext_ft_mode_code_t *)header->data;
 | 
						|
    switch (func->ft_mode) {
 | 
						|
    case PROTO_645_EXT_FT_MODE_GET_CHIP_MMID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_get_chip_mmid(header);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_FT_MODE_SET_CHIP_MMID:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_set_chip_mmid(header);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_FT_MODE_ZC_CHECK:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_zc_check();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_FT_MODE_GET_SW_VER:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_get_mod_sw_ver();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_FT_MODE_SET_COMM_ADDR:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_set_comm_address(header);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_EXT_FT_MODE_GET_COMM_ADDR:
 | 
						|
    {
 | 
						|
        pkt = proto_645_vendor_get_comm_address(header);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
#endif  /* IOT_SMART_GRID_ENABLE && PLC_SUPPORT_STA_ROLE */
 |