917 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			917 lines
		
	
	
		
			27 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "iot_errno_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_utils_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_uart_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_version_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_system_api.h"
							 | 
						||
| 
								 | 
							
								#include "proto_spg_cco.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_ctrl_api.h"
							 | 
						||
| 
								 | 
							
								#include "proto_645.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if (IOT_SG_CONTROLLER_ENABLE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* report max scan node count */
							 | 
						||
| 
								 | 
							
								#define IOT_CTRL_SCAN_NODE_MAX_CNT      (200)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* command from contrl application */
							 | 
						||
| 
								 | 
							
								typedef struct _ctrl_spg_frame_pkt_t {
							 | 
						||
| 
								 | 
							
								    /* main application function code */
							 | 
						||
| 
								 | 
							
								    uint8_t     afn;
							 | 
						||
| 
								 | 
							
								    /* seccondary application function code */
							 | 
						||
| 
								 | 
							
								    uint8_t     fn;
							 | 
						||
| 
								 | 
							
								    /* sequence number of ctrl command */
							 | 
						||
| 
								 | 
							
								    uint8_t     app_sn;
							 | 
						||
| 
								 | 
							
								    /* length of the applied data (unit: byte)*/
							 | 
						||
| 
								 | 
							
								    uint16_t    app_data_len;
							 | 
						||
| 
								 | 
							
								    /* applied data */
							 | 
						||
| 
								 | 
							
								    uint8_t     *app_data;
							 | 
						||
| 
								 | 
							
								}ctrl_spg_frame_pkt_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _spg_cctt_drv_data {
							 | 
						||
| 
								 | 
							
								    /* seq number */
							 | 
						||
| 
								 | 
							
								    uint8_t     sn;
							 | 
						||
| 
								 | 
							
								    /* requested meter mac */
							 | 
						||
| 
								 | 
							
								    uint8_t     req_mac[IOT_MAC_ADDR_LEN];
							 | 
						||
| 
								 | 
							
								    /* destination mac in address field */
							 | 
						||
| 
								 | 
							
								    uint8_t     dest_mac[IOT_MAC_ADDR_LEN];
							 | 
						||
| 
								 | 
							
								} spg_cctt_drv_data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static spg_cctt_drv_data *drv_data = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_send_uart_sn_ext(uint8_t role, uint8_t afn,
							 | 
						||
| 
								 | 
							
								    uint8_t fn, iot_pkt_t *pkt, uint8_t sn, uint8_t mac_used, uint8_t *req_mac,
							 | 
						||
| 
								 | 
							
								    uint8_t *dec_mac, uint8_t di2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *data = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_hdr_t *pkt_hdr = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_addr_field_t *spg_addr_ptr = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_app_data_t *spg_app_ptr = NULL;
							 | 
						||
| 
								 | 
							
								    uint8_t *cs_ptr = NULL;     //pointer to checksum
							 | 
						||
| 
								 | 
							
								    uint16_t index = 0;
							 | 
						||
| 
								 | 
							
								    uint16_t app_data_len = (uint16_t)iot_pkt_data_len(pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    data = iot_pkt_push(pkt, proto_spg_get_header_len(mac_used));
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(data);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA) + PROTO_SPG_CS_BCODE_LEN) !=
							 | 
						||
| 
								 | 
							
								        proto_spg_get_proto_pkt_len(mac_used, app_data_len)) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								        return ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    pkt_hdr = (proto_spg_hdr_t*)data;
							 | 
						||
| 
								 | 
							
								    pkt_hdr->sof_byte = PROTO_SPG_SOF_BYTE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pkt_hdr->ctrl_byte.dir = PROTO_SPG_DIR_UP_LINK;
							 | 
						||
| 
								 | 
							
								    if (role == PROTO_SPG_PRM_SLAVE) {
							 | 
						||
| 
								 | 
							
								        /* response Message */
							 | 
						||
| 
								 | 
							
								        pkt_hdr->ctrl_byte.prm = PROTO_SPG_PRM_SLAVE;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        /* report message */
							 | 
						||
| 
								 | 
							
								        pkt_hdr->ctrl_byte.prm = PROTO_SPG_PRM_MASTER;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    pkt_hdr->ctrl_byte.addr = PROTO_SPG_NO_ADDRESS;
							 | 
						||
| 
								 | 
							
								    pkt_hdr->ctrl_byte.ver = PROTO_SPG_DEFAULT_VERSION;
							 | 
						||
| 
								 | 
							
								    pkt_hdr->ctrl_byte.rsvd = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    index += sizeof(proto_spg_hdr_t);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (mac_used && req_mac && dec_mac) {
							 | 
						||
| 
								 | 
							
								        spg_addr_ptr = (proto_spg_addr_field_t *)(data+index);
							 | 
						||
| 
								 | 
							
								        pkt_hdr->ctrl_byte.addr = PROTO_SPG_WITH_ADDRESS;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* only src mac and dest mac for up link */
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(spg_addr_ptr->src_mac, req_mac, PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        index += PROTO_SPG_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(spg_addr_ptr->dest_mac, dec_mac, PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        index += PROTO_SPG_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    spg_app_ptr = (proto_spg_app_data_t *)(data+index);
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->afn = afn;
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->seq = sn;
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->di[0] = fn;
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->di[1] = afn;
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->di[2] = di2;
							 | 
						||
| 
								 | 
							
								    spg_app_ptr->di[3] = (uint8_t)PROTO_SPG_APP_CTRL_DI3;
							 | 
						||
| 
								 | 
							
								    index += sizeof(proto_spg_app_data_t);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* skip app data as app data is already in iot_pkt */
							 | 
						||
| 
								 | 
							
								    index += app_data_len;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* check sum field */
							 | 
						||
| 
								 | 
							
								    cs_ptr = (data +index);
							 | 
						||
| 
								 | 
							
								    index++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* tail of the frame */
							 | 
						||
| 
								 | 
							
								    data[index] = PROTO_SPG_EOF_BYTE;
							 | 
						||
| 
								 | 
							
								    index++;
							 | 
						||
| 
								 | 
							
								    pkt_hdr->len = index;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    *cs_ptr = proto_spg_get_checksum(data + PROTO_SPG_CTRL_OFFSET,
							 | 
						||
| 
								 | 
							
								        index - PROTO_SPG_CTRL_OFFSET - PROTO_SPG_CHECKSUM_LEN -
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_BACKCODE_LEN);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // put checksum and back code. 2 byte.
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(pkt, PROTO_SPG_CS_BCODE_LEN);
							 | 
						||
| 
								 | 
							
								    iot_ctrl_uart_send(pkt);
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_send_uart_sn(uint8_t role, uint8_t afn,
							 | 
						||
| 
								 | 
							
								    uint8_t fn, iot_pkt_t *pkt, uint8_t di2, uint8_t mac_used, uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (mac_used) {
							 | 
						||
| 
								 | 
							
								        return iot_spg_ctrl_send_uart_sn_ext(role, afn, fn, pkt, sn,
							 | 
						||
| 
								 | 
							
								            SPG_USED_ADDR, drv_data->dest_mac, drv_data->req_mac, di2);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return iot_spg_ctrl_send_uart_sn_ext(role, afn, fn, pkt, sn,
							 | 
						||
| 
								 | 
							
								            SPG_NO_USED_ADDR, NULL, NULL, di2);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_send_uart(uint8_t role, uint8_t afn, uint8_t fn,
							 | 
						||
| 
								 | 
							
								    const uint8_t *app_data, uint16_t len, uint8_t di2, uint8_t mac_used,
							 | 
						||
| 
								 | 
							
								    uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						||
| 
								 | 
							
								    uint8_t *pkt_data = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pkt = iot_pkt_alloc(proto_spg_get_pkt_len(mac_used, len),
							 | 
						||
| 
								 | 
							
								        IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pkt_data = iot_pkt_reserve(pkt, proto_spg_get_rsvd_len(mac_used));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (app_data && len) {
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(pkt_data, app_data, len);
							 | 
						||
| 
								 | 
							
								        iot_pkt_put(pkt, len);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return iot_spg_ctrl_send_uart_sn(role, afn, fn, pkt, di2, mac_used, sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_drv_init()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    iot_frame_fmt fmt = { 0 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!drv_data) {
							 | 
						||
| 
								 | 
							
								        drv_data = os_mem_malloc(IOT_SMART_GRID_MID,
							 | 
						||
| 
								 | 
							
								            sizeof(*drv_data));
							 | 
						||
| 
								 | 
							
								        if (!drv_data) {
							 | 
						||
| 
								 | 
							
								            return ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* config the UART port settings */
							 | 
						||
| 
								 | 
							
								    fmt.preamble_code[0] = PROTO_SPG_SOF_BYTE;
							 | 
						||
| 
								 | 
							
								    fmt.preamble_codelen = PROTO_SPG_PRECODE_LEN;
							 | 
						||
| 
								 | 
							
								    fmt.datalen_offset = 0;
							 | 
						||
| 
								 | 
							
								    fmt.datalen_size = PROTO_SPG_LENGTH_SIZE;
							 | 
						||
| 
								 | 
							
								    fmt.backcode_offset = 0;
							 | 
						||
| 
								 | 
							
								    fmt.backcode_len = PROTO_SPG_BACKCODE_LEN;
							 | 
						||
| 
								 | 
							
								    /* in uart data parsing, datalen means raw data to be send,
							 | 
						||
| 
								 | 
							
								     * excluding preamble/datalen/backcode. For datalen field in
							 | 
						||
| 
								 | 
							
								     * spg datagram means the length of the whole datagram, we shall
							 | 
						||
| 
								 | 
							
								     * set the datalen_fix as below.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    fmt.datalen_fix = fmt.preamble_codelen +
							 | 
						||
| 
								 | 
							
								        fmt.datalen_size + fmt.backcode_len;
							 | 
						||
| 
								 | 
							
								    fmt.backcode[0] = PROTO_SPG_EOF_BYTE;
							 | 
						||
| 
								 | 
							
								    fmt.frame_timeout = CTRL_FRAME_PARSE_TIMEOUT;
							 | 
						||
| 
								 | 
							
								    fmt.timeout_mode = TIMEOUT_PERDATA;
							 | 
						||
| 
								 | 
							
								    fmt.check_frame_func = proto_spg_check_frame_handler;
							 | 
						||
| 
								 | 
							
								    ret = iot_sg_ctrl_config_uart(PROTO_SPG_DEFAULT_BAUD,
							 | 
						||
| 
								 | 
							
								        (uint8_t)IOT_UART_PARITY_EVEN, (uint8_t)IOT_UART_DLEN_8_BITS,
							 | 
						||
| 
								 | 
							
								        (uint8_t)IOT_UART_STOP_1_BITS, &fmt);
							 | 
						||
| 
								 | 
							
								    if (!ret) {
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_drv_deinit()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (drv_data) {
							 | 
						||
| 
								 | 
							
								        os_mem_free(drv_data);
							 | 
						||
| 
								 | 
							
								        drv_data = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_freq_band_handler(
							 | 
						||
| 
								 | 
							
								    iot_plc_freq_band_info_query_rpt_t *rpt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_query_freq_band_t rsp = { 0 };
							 | 
						||
| 
								 | 
							
								    rsp.freq_band = rpt->freq_band;
							 | 
						||
| 
								 | 
							
								    /* report this response to UART/APP */
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_03,
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_F90, (uint8_t *)&rsp, (uint16_t)sizeof(rsp),
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_APP_DI2_00, SPG_NO_USED_ADDR, drv_data->sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_send_00h02_nack(uint8_t reason, uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_afn00_fn02_reject_t reject = { 0 };
							 | 
						||
| 
								 | 
							
								    reject.err_no = reason;
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_00, PROTO_SPG_F2,
							 | 
						||
| 
								 | 
							
								        (uint8_t*)&reject, sizeof(reject), PROTO_SPG_APP_DI2_01,
							 | 
						||
| 
								 | 
							
								        SPG_NO_USED_ADDR, sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_send_00h01_ack(uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_afn00_fn01_conf_t conf = { 0 };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    conf.wait_duration = PROTO_SPG_DEFAULT_WAIT_TIME;
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_00, PROTO_SPG_F1,
							 | 
						||
| 
								 | 
							
								        (uint8_t*)&conf, sizeof(conf), PROTO_SPG_APP_DI2_01,
							 | 
						||
| 
								 | 
							
								        SPG_NO_USED_ADDR, sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_set_freq_band_result(uint8_t result)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!result) {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h01_ack(drv_data->sn);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack(PROTO_SPG_ERR_COMM_TIMEOUT, drv_data->sn);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_01h_f01(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_00h01_ack(frm->app_sn);
							 | 
						||
| 
								 | 
							
								    os_delay(1000);
							 | 
						||
| 
								 | 
							
								    iot_system_restart(IOT_SYS_RST_REASON_CCTT_REQ);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_rpt_data_transfer_handle(uint8_t sn,
							 | 
						||
| 
								 | 
							
								    uint8_t *data, uint16_t len, uint8_t data_type)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_afn22_fn01_data_send_ul_t *rsp;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *rpt_pkt;
							 | 
						||
| 
								 | 
							
								    uint16_t rpt_pkt_len;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rpt_pkt_len = len + sizeof(*rsp);
							 | 
						||
| 
								 | 
							
								    rpt_pkt = iot_pkt_alloc(proto_spg_get_pkt_len(SPG_NO_USED_ADDR,
							 | 
						||
| 
								 | 
							
								        rpt_pkt_len), IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(rpt_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rsp = (spg_afn22_fn01_data_send_ul_t *)iot_pkt_reserve(rpt_pkt,
							 | 
						||
| 
								 | 
							
								        proto_spg_get_rsvd_len(SPG_NO_USED_ADDR));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rsp->data_type = data_type;
							 | 
						||
| 
								 | 
							
								    rsp->data_len = len;
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(rsp->data, data, len);
							 | 
						||
| 
								 | 
							
								    proto_645_add33_handle(rsp->data, len);
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(rpt_pkt, rpt_pkt_len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart_sn(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_22,
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_F1, rpt_pkt, PROTO_SPG_APP_DI2_05, SPG_NO_USED_ADDR, sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_event_report_handle(uint8_t sn,
							 | 
						||
| 
								 | 
							
								    uint8_t *addr, uint8_t dev_type, uint32_t proto_type, uint8_t evt_type,
							 | 
						||
| 
								 | 
							
								    uint8_t *data, uint16_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)addr;
							 | 
						||
| 
								 | 
							
								    (void)dev_type;
							 | 
						||
| 
								 | 
							
								    (void)proto_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (evt_type) {
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_DEVICE_CONNECT_CONF:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s connect conf\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_DEVICE_CONNECT_FAIL:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack(PROTO_SPG_ERR_COMM_TIMEOUT, sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_DEVICE_CONNECTED:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h01_ack(sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_DEVICE_DISCONNECTED:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s disconnected\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_CCO_DATA_RPT:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_rpt_data_transfer_handle(sn, data, len,
							 | 
						||
| 
								 | 
							
								            PROTO_SPG_CTRL_DATA_TYPE_CCO_CTRL);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case IOT_CTRL_EVENT_PASSTHROUGH_RPT:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_rpt_data_transfer_handle(sn, data, len,
							 | 
						||
| 
								 | 
							
								            PROTO_SPG_CTRL_DATA_TYPE_PASSTHROUGH);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s event:%d invalid\n", __FUNCTION__, evt_type);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_01h_init(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (PROTO_SPG_F1 == frm->fn) {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_01h_f01(frm);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_03h_f01()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_afn03_fn01_hw_info_ul_t rsp_data;
							 | 
						||
| 
								 | 
							
								    iot_build_info_t ts_info;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* hw info */
							 | 
						||
| 
								 | 
							
								    uint16_t sw_version = (iot_version_packed() & 0xFFFF);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rsp_data.info.vendor_id = iot_sg_ctrl_get_vendor_id();
							 | 
						||
| 
								 | 
							
								    rsp_data.info.chip_code = iot_sg_ctrl_get_chip_code();
							 | 
						||
| 
								 | 
							
								    iot_version_get_user_build_info(&ts_info);
							 | 
						||
| 
								 | 
							
								    rsp_data.info.day = iot_byte_to_bcd(ts_info.day);
							 | 
						||
| 
								 | 
							
								    rsp_data.info.month = iot_byte_to_bcd(ts_info.month);
							 | 
						||
| 
								 | 
							
								    rsp_data.info.year = iot_byte_to_bcd(ts_info.year);
							 | 
						||
| 
								 | 
							
								    rsp_data.info.version[0] = (sw_version & 0xFF);
							 | 
						||
| 
								 | 
							
								    rsp_data.info.version[1] = (sw_version >> 8);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_03, PROTO_SPG_F1,
							 | 
						||
| 
								 | 
							
								        (const uint8_t *)&rsp_data, sizeof(rsp_data), PROTO_SPG_APP_DI2_00,
							 | 
						||
| 
								 | 
							
								        SPG_NO_USED_ADDR, drv_data->sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_03h_read_param(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (frm->fn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F1:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_03h_f01();
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F90:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_get_freq_band_msg();
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_04h_f90(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t reason = PROTO_SPG_ERR_OTHER;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    spg_set_freq_band_t *app_data =
							 | 
						||
| 
								 | 
							
								        (spg_set_freq_band_t *)frm->app_data;
							 | 
						||
| 
								 | 
							
								    uint16_t len = frm->app_data_len;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!app_data) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (len < sizeof(*app_data)) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_sg_ctrl_set_freq_band_msg(app_data->freq_band);
							 | 
						||
| 
								 | 
							
								    result = ERR_OK;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (ERR_FAIL == result) {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack(reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_04h_set_param(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (frm->fn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F90:
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_04h_f90(frm);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_spg_ctrl_get_proto_data_sn(uint8_t *data, uint16_t data_len,
							 | 
						||
| 
								 | 
							
								    uint8_t *app_sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t result = ERR_FAIL, *spg_hdr;
							 | 
						||
| 
								 | 
							
								    proto_spg_hdr_t *headr_data = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_addr_field_t *addr_data = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_app_data_t *app_data = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    spg_hdr = proto_spg_sanity_check(data, data_len, &result,
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_APP_CTRL_DI3);
							 | 
						||
| 
								 | 
							
								    if (spg_hdr) {
							 | 
						||
| 
								 | 
							
								        headr_data = (proto_spg_hdr_t*)spg_hdr;
							 | 
						||
| 
								 | 
							
								        if (headr_data->ctrl_byte.addr) {
							 | 
						||
| 
								 | 
							
								            addr_data = (proto_spg_addr_field_t*)(spg_hdr +
							 | 
						||
| 
								 | 
							
								                PROTO_SPG_DATA_OFFSET);
							 | 
						||
| 
								 | 
							
								            app_data = (proto_spg_app_data_t*)(spg_hdr + PROTO_SPG_DATA_OFFSET +
							 | 
						||
| 
								 | 
							
								                sizeof(*addr_data));
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            app_data = (proto_spg_app_data_t*)(spg_hdr + PROTO_SPG_DATA_OFFSET);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        *app_sn = app_data->seq;
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ctrl_cco_ctrl_data_send(uint8_t *data, uint16_t data_len,
							 | 
						||
| 
								 | 
							
								    uint8_t app_sn, iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    uint8_t sn;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(data, data_len);
							 | 
						||
| 
								 | 
							
								    if (iot_spg_ctrl_get_proto_data_sn(data, data_len, &sn) != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_data_print("error data", data, data_len);
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_set_data(pkt, data);
							 | 
						||
| 
								 | 
							
								    iot_pkt_set_tail(pkt, data + data_len);
							 | 
						||
| 
								 | 
							
								    if (iot_sg_ctrl_send_data(PROTO_CTRL_CMD_TYPE_MR_CCO, sn, pkt)) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_OTHER;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != result) {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, app_sn);
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ctrl_passthrough_data_send(uint8_t *data, uint16_t data_len,
							 | 
						||
| 
								 | 
							
								    uint8_t app_sn, iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								    uint8_t sn = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    proto_645_sub33_handle(data, data_len);
							 | 
						||
| 
								 | 
							
								    switch (iot_sg_ctrl_get_connect_role()) {
							 | 
						||
| 
								 | 
							
								    case IOT_PLC_DEV_ROLE_CCO:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_spg_ctrl_get_proto_data_sn(data, data_len, &sn) != ERR_OK) {
							 | 
						||
| 
								 | 
							
								            reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								            result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_PLC_DEV_ROLE_STA:
							 | 
						||
| 
								 | 
							
								    case IOT_PLC_DEV_ROLE_PCO:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (iot_sg_ctrl_get_sta_passthrough_state()) {
							 | 
						||
| 
								 | 
							
								            reason = PROTO_SPG_ERR_MASTER_IS_BUSY;
							 | 
						||
| 
								 | 
							
								            result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (proto_645_format_check(data, data_len, PROTO_645_DIR_MASTER)
							 | 
						||
| 
								 | 
							
								            == NULL) {
							 | 
						||
| 
								 | 
							
								            reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								            result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_pkt_set_data(pkt, data);
							 | 
						||
| 
								 | 
							
								    iot_pkt_set_tail(pkt, data + data_len);
							 | 
						||
| 
								 | 
							
								    if (sn) {
							 | 
						||
| 
								 | 
							
								        result = iot_sg_ctrl_send_data(PROTO_CTRL_CMD_TYPE_PASSTHROUGH, sn,
							 | 
						||
| 
								 | 
							
								            pkt);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        result = iot_sg_ctrl_send_data(PROTO_CTRL_CMD_TYPE_PASSTHROUGH,
							 | 
						||
| 
								 | 
							
								            IOT_CTRL_PASSTHROUGH_SN, pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (result != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != result) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_data_print("error data", data, data_len);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, app_sn);
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_sg_ctrl_data_send_handle(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								    uint8_t consumed = 0;
							 | 
						||
| 
								 | 
							
								    spg_afn22_fn01_data_send_dl_t *req;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    req = (spg_afn22_fn01_data_send_dl_t *)frm->app_data;
							 | 
						||
| 
								 | 
							
								    switch (req->data_type) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_CTRL_DATA_TYPE_CCO_CTRL:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_cco_ctrl_data_send(req->data, req->data_len, frm->app_sn,
							 | 
						||
| 
								 | 
							
								            pkt);
							 | 
						||
| 
								 | 
							
								        consumed = 1;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_CTRL_DATA_TYPE_PASSTHROUGH:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_passthrough_data_send(req->data, req->data_len, frm->app_sn,
							 | 
						||
| 
								 | 
							
								            pkt);
							 | 
						||
| 
								 | 
							
								        consumed = 1;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data type error,reason is %lu, data type is %lu",
							 | 
						||
| 
								 | 
							
								            __FUNCTION__, reason, req->data_type);
							 | 
						||
| 
								 | 
							
								            iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!consumed) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_22h_data_send(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								    uint8_t consumed = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (frm->fn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F1:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_data_send_handle(frm, pkt);
							 | 
						||
| 
								 | 
							
								        consumed = 1;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								            iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!consumed) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_41h_f01(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t cnt;
							 | 
						||
| 
								 | 
							
								    uint8_t i;
							 | 
						||
| 
								 | 
							
								    uint16_t rsp_len;
							 | 
						||
| 
								 | 
							
								    spg_afn41_fn01_rpt_node_info_ul *rsp_data = NULL;
							 | 
						||
| 
								 | 
							
								    ctrl_node_info_t *node_info = NULL;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *tmp_pkt;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *tmp2_pkt = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cnt = iot_sg_ctrl_get_scan_node_cnt();
							 | 
						||
| 
								 | 
							
								    if (cnt > IOT_CTRL_SCAN_NODE_MAX_CNT) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("WARNING: %s scan count: %d exceed \n", cnt);
							 | 
						||
| 
								 | 
							
								        cnt = IOT_CTRL_SCAN_NODE_MAX_CNT;
							 | 
						||
| 
								 | 
							
								    } else if (!cnt) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tmp2_pkt = iot_pkt_alloc(cnt * sizeof(ctrl_node_info_t),
							 | 
						||
| 
								 | 
							
								        IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(tmp2_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    node_info = (ctrl_node_info_t *)iot_pkt_data(tmp2_pkt);
							 | 
						||
| 
								 | 
							
								    cnt = iot_sg_ctrl_get_scan_node_info(node_info, 1, cnt);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    rsp_len = sizeof(*rsp_data) + cnt * sizeof(spg_ctrl_node_info_t);
							 | 
						||
| 
								 | 
							
								    tmp_pkt = iot_pkt_alloc(proto_spg_get_pkt_len(SPG_NO_USED_ADDR,
							 | 
						||
| 
								 | 
							
								        rsp_len), IOT_SMART_GRID_MID);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(tmp_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rsp_data = (spg_afn41_fn01_rpt_node_info_ul*)iot_pkt_reserve(tmp_pkt,
							 | 
						||
| 
								 | 
							
								        proto_spg_get_rsvd_len(SPG_NO_USED_ADDR));
							 | 
						||
| 
								 | 
							
								    rsp_data->total_cnt = cnt;
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < cnt; i++, node_info++) {
							 | 
						||
| 
								 | 
							
								        rsp_data->node_info[i].nid = node_info->nid;
							 | 
						||
| 
								 | 
							
								        rsp_data->node_info[i].band_id = node_info->band_id;
							 | 
						||
| 
								 | 
							
								        iot_mac_addr_cpy(rsp_data->node_info[i].addr, node_info->addr);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (tmp2_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(tmp2_pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_put(tmp_pkt, rsp_len);
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_uart_sn(PROTO_SPG_PRM_SLAVE, PROTO_SPG_AFN_41,
							 | 
						||
| 
								 | 
							
								        PROTO_SPG_F1, tmp_pkt, PROTO_SPG_APP_DI2_00, SPG_NO_USED_ADDR,
							 | 
						||
| 
								 | 
							
								        frm->app_sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_41h_f02(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    spg_afn41_fn02_req_connect_node_dl_t *req =
							 | 
						||
| 
								 | 
							
								        (spg_afn41_fn02_req_connect_node_dl_t *)frm->app_data;
							 | 
						||
| 
								 | 
							
								    uint16_t len = frm->app_data_len;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (len < sizeof(spg_afn41_fn02_req_connect_node_dl_t)) {
							 | 
						||
| 
								 | 
							
								        /* invalid data length */
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != iot_sg_ctrl_proto_connect_from_scan_node(req->addr,
							 | 
						||
| 
								 | 
							
								        frm->app_sn)) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != result) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_41h_scan_node_mgr(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (frm->fn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F1:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_41h_f01(frm);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F2:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_41h_f02(frm);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_f0h_f01(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    spg_afnf0_fn01_req_connect_node_dl_t *cmd = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    uint8_t reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cmd = (spg_afnf0_fn01_req_connect_node_dl_t*)frm->app_data;
							 | 
						||
| 
								 | 
							
								    uint16_t len = frm->app_data_len;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (len < sizeof(spg_afnf0_fn01_req_connect_node_dl_t)) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA_LEN;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != iot_sg_ctrl_proto_connect(cmd->addr,
							 | 
						||
| 
								 | 
							
								        (uint8_t)frm->app_sn)) {
							 | 
						||
| 
								 | 
							
								        reason = PROTO_SPG_ERR_INVALID_DATA;
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != result) {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_f0h_f02(ctrl_spg_frame_pkt_t *frm)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_sg_ctrl_reset_connet_status();
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_00h01_ack(frm->app_sn);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_f0h_cmd(ctrl_spg_frame_pkt_t *frm, iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								    uint8_t consumed = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (frm->fn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F1:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_f0h_f01(frm);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_F2:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_f0h_f02(frm);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : 0x%02X,"
							 | 
						||
| 
								 | 
							
								            "fn : 0x%02X\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!consumed) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_spg_ctrl_send_data_handle(ctrl_spg_frame_pkt_t *frm,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t reason= PROTO_SPG_ERR_MASTER_UNSUPPORTED_CMD;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_sg_ctrl_printf("%s: afn = 0x%02X, fn = 0n%lu, sn: %d \n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        frm->afn, frm->fn, frm->app_sn);
							 | 
						||
| 
								 | 
							
								    switch (frm->afn) {
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_01:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_01h_init(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_03:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_03h_read_param(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_04:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_04h_set_param(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_22:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_22h_data_send(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_41:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_41h_scan_node_mgr(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case PROTO_SPG_AFN_F0:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_f0h_cmd(frm, pkt);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != result) {
							 | 
						||
| 
								 | 
							
								        iot_sg_ctrl_printf("%s:data_handle error,reason is %lu,afn : %x,"
							 | 
						||
| 
								 | 
							
								            "fn : %x\n", __FUNCTION__, reason, frm->afn, frm->fn);
							 | 
						||
| 
								 | 
							
								        iot_spg_ctrl_send_00h02_nack((uint8_t)reason, frm->app_sn);
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_sg_ctrl_uart_data_recv_handle - receive uart data
							 | 
						||
| 
								 | 
							
								 * @param pkt: include full 3762 frame, the pkt whill be free
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_uart_data_recv_handle(iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *spg_hdr;
							 | 
						||
| 
								 | 
							
								    uint16_t len = (uint16_t)iot_pkt_data_len(pkt);
							 | 
						||
| 
								 | 
							
								    proto_spg_hdr_t *headr_data = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_addr_field_t *addr_data = NULL;
							 | 
						||
| 
								 | 
							
								    proto_spg_app_data_t *app_data = NULL;
							 | 
						||
| 
								 | 
							
								    ctrl_spg_frame_pkt_t spg_cmd;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(len < sizeof(proto_spg_hdr_t)){
							 | 
						||
| 
								 | 
							
								        goto err;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    spg_hdr = proto_spg_sanity_check(iot_pkt_data(pkt), len,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)&result, PROTO_SPG_APP_CTRL_DI3);
							 | 
						||
| 
								 | 
							
								    if (!spg_hdr) {
							 | 
						||
| 
								 | 
							
								        goto err;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    headr_data = (proto_spg_hdr_t*)spg_hdr;
							 | 
						||
| 
								 | 
							
								    if (headr_data->ctrl_byte.addr) {
							 | 
						||
| 
								 | 
							
								        addr_data = (proto_spg_addr_field_t*)(spg_hdr + PROTO_SPG_DATA_OFFSET);
							 | 
						||
| 
								 | 
							
								        app_data = (proto_spg_app_data_t*)(spg_hdr + PROTO_SPG_DATA_OFFSET +
							 | 
						||
| 
								 | 
							
								            sizeof(*addr_data));
							 | 
						||
| 
								 | 
							
								        /* record mac msg */
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(drv_data->dest_mac, addr_data->dest_mac,
							 | 
						||
| 
								 | 
							
								            PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(drv_data->req_mac, addr_data->src_mac,
							 | 
						||
| 
								 | 
							
								            PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        /* offset address length */
							 | 
						||
| 
								 | 
							
								        headr_data->len -= PROTO_SPG_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								        headr_data->len -= PROTO_SPG_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        os_mem_set(drv_data->dest_mac, 0, PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        os_mem_set(drv_data->req_mac, 0, PROTO_SPG_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								        app_data = (proto_spg_app_data_t*)(spg_hdr + PROTO_SPG_DATA_OFFSET);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* check di data */
							 | 
						||
| 
								 | 
							
								    if ((app_data->di[3] != PROTO_SPG_APP_CTRL_DI3) ||
							 | 
						||
| 
								 | 
							
								        (app_data->di[1] != app_data->afn)) {
							 | 
						||
| 
								 | 
							
								        goto err;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* record seq msg */
							 | 
						||
| 
								 | 
							
								    drv_data->sn = app_data->seq;
							 | 
						||
| 
								 | 
							
								    spg_cmd.app_sn = app_data->seq;
							 | 
						||
| 
								 | 
							
								    spg_cmd.afn = app_data->afn;
							 | 
						||
| 
								 | 
							
								    spg_cmd.fn = app_data->di[0];
							 | 
						||
| 
								 | 
							
								    spg_cmd.app_data_len = headr_data->len - PROTO_SPG_FIX_FIELD_LEN -
							 | 
						||
| 
								 | 
							
								        sizeof(proto_spg_app_data_t);
							 | 
						||
| 
								 | 
							
								    if (!spg_cmd.app_data_len) {
							 | 
						||
| 
								 | 
							
								        spg_cmd.app_data = NULL;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        spg_cmd.app_data = app_data->data;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_spg_ctrl_send_data_handle(&spg_cmd, pkt);
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								err:
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_spg_ctrl_check_data_handle(iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *spg_hdr;
							 | 
						||
| 
								 | 
							
								    uint16_t len = (uint16_t)iot_pkt_data_len(pkt);
							 | 
						||
| 
								 | 
							
								    uint8_t ctrl = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(len < sizeof(proto_spg_hdr_t)){
							 | 
						||
| 
								 | 
							
								        return result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    spg_hdr = proto_spg_sanity_check(iot_pkt_data(pkt), len,
							 | 
						||
| 
								 | 
							
								        (uint8_t *)&result, PROTO_SPG_APP_CTRL_DI3);
							 | 
						||
| 
								 | 
							
								    if (!spg_hdr) {
							 | 
						||
| 
								 | 
							
								        return result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ctrl = spg_hdr[PROTO_SPG_CTRL_OFFSET];
							 | 
						||
| 
								 | 
							
								    if ((ctrl & 0x07) == PROTO_CTRL_COMMUNICAT_RSVD) {
							 | 
						||
| 
								 | 
							
								        result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_ctrl_drv_t g_spg_ctrl_drv = {
							 | 
						||
| 
								 | 
							
								    .drv_id = IOT_CTRL_DRV_ID_SPG,
							 | 
						||
| 
								 | 
							
								    .init = iot_spg_ctrl_drv_init,
							 | 
						||
| 
								 | 
							
								    .deinit = iot_spg_ctrl_drv_deinit,
							 | 
						||
| 
								 | 
							
								    .event_report_handle = iot_spg_ctrl_event_report_handle,
							 | 
						||
| 
								 | 
							
								    .ctrl_drv_data_handle = iot_spg_ctrl_uart_data_recv_handle,
							 | 
						||
| 
								 | 
							
								    .check_data_handle = iot_spg_ctrl_check_data_handle,
							 | 
						||
| 
								 | 
							
								    .freq_band_report_cb = iot_spg_ctrl_freq_band_handler,
							 | 
						||
| 
								 | 
							
								    .freq_band_set_result_cb = iot_spg_ctrl_set_freq_band_result,
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* IOT_SG_CONTROLLER_ENABLE */
							 |