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