375 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			375 lines
		
	
	
		
			11 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.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
/* iot common header files */
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_pkt_api.h"
 | 
						|
 | 
						|
/* smart grid internal header files */
 | 
						|
#include "proto_gw_app.h"
 | 
						|
#include "iot_sg_ctrl.h"
 | 
						|
 | 
						|
#if (IOT_SG_CONTROLLER_ENABLE && IOT_GW_CTRL_APP_ENABLE)
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_read_meter(uint8_t *data, uint16_t datalen,
 | 
						|
    uint16_t sn)
 | 
						|
{
 | 
						|
    iot_pkt_t *plc_pkt;
 | 
						|
    uint16_t total_size;
 | 
						|
    uint8_t *pkt_data;
 | 
						|
    gw_app_meter_r_ul_t *meter_read_hdr;
 | 
						|
    gw_app_header_t *app_hdr;
 | 
						|
 | 
						|
    total_size = sizeof(*app_hdr) + sizeof(*meter_read_hdr) + datalen;
 | 
						|
    plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
 | 
						|
        NULL, sg_ctrl_global->local_mac_addr,
 | 
						|
        GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
 | 
						|
    IOT_ASSERT(plc_pkt);
 | 
						|
 | 
						|
    pkt_data = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    /* fill in header */
 | 
						|
    app_hdr = (gw_app_header_t *)pkt_data;
 | 
						|
    app_hdr->id = GW_APP_ID_CONCENTRATOR_METER_R;
 | 
						|
    app_hdr->port = GW_APP_PORT_OTHER;
 | 
						|
    app_hdr->control = 0;
 | 
						|
 | 
						|
    meter_read_hdr = (gw_app_meter_r_ul_t *)(app_hdr + 1);
 | 
						|
    meter_read_hdr->ver = GW_APP_VERSION;
 | 
						|
    meter_read_hdr->header_len = sizeof(*meter_read_hdr);
 | 
						|
    meter_read_hdr->seq = sn;
 | 
						|
    meter_read_hdr->data_type = GW_APP_DATA_TYPE_TRANSPARENT;
 | 
						|
    meter_read_hdr->data_len = datalen;
 | 
						|
    meter_read_hdr->ack_status = 0;
 | 
						|
    meter_read_hdr->option = 0;
 | 
						|
    os_mem_cpy(meter_read_hdr->data, data, datalen);
 | 
						|
    iot_pkt_put(plc_pkt, total_size);
 | 
						|
    iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
 | 
						|
    return ;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_get_id_info(uint8_t id_type, uint16_t sn, uint8_t qr_cnt)
 | 
						|
{
 | 
						|
    uint8_t *data_ptr;
 | 
						|
    iot_pkt_t *plc_pkt;
 | 
						|
    gw_app_header_t *app_hdr;
 | 
						|
    gw_app_query_module_id_dl_t *query_data;
 | 
						|
    uint16_t total_size = sizeof(*app_hdr) + sizeof(*query_data);
 | 
						|
 | 
						|
    total_size = sizeof(*app_hdr) + sizeof(*query_data);
 | 
						|
    plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
 | 
						|
        NULL, sg_ctrl_global->local_mac_addr,
 | 
						|
        GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
 | 
						|
    IOT_ASSERT(plc_pkt);
 | 
						|
 | 
						|
    data_ptr = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    app_hdr = (gw_app_header_t *)data_ptr;
 | 
						|
 | 
						|
    app_hdr->id = GW_APP_ID_QUERY_MODULE_ID_INFO;
 | 
						|
    app_hdr->port = GW_APP_PORT_OTHER;
 | 
						|
    app_hdr->control = GW_APP_CONTROL;
 | 
						|
 | 
						|
    query_data = (gw_app_query_module_id_dl_t *)(app_hdr + 1);
 | 
						|
    query_data->ver = GW_APP_VERSION;
 | 
						|
    query_data->header_len = sizeof(*query_data);
 | 
						|
    query_data->dir = 0;
 | 
						|
    query_data->seq = sn;
 | 
						|
    if (id_type == 1) {
 | 
						|
        query_data->id_type = GW_APP_ID_INFO_TYPE_CHIP;
 | 
						|
    } else {
 | 
						|
        if (qr_cnt & 0x01) {
 | 
						|
            query_data->id_type = GW_APP_ID_INFO_TYPE_MOD;
 | 
						|
        } else {
 | 
						|
            query_data->id_type = GW_APP_ID_INFO_TYPE_MOD_EXT;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_put(plc_pkt, total_size);
 | 
						|
    iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_sg_ctrl_gw_handle_sta_read_meter_data(gw_app_header_t *app_hdr,
 | 
						|
    uint32_t app_len)
 | 
						|
{
 | 
						|
    gw_app_meter_r_ul_t *meter_read_hdr;
 | 
						|
    uint16_t app_sn;
 | 
						|
    uint8_t reason = 0;
 | 
						|
    info_pool_t *info_pool = &sg_ctrl_global->info_pool;
 | 
						|
 | 
						|
    meter_read_hdr = (gw_app_meter_r_ul_t *)(app_hdr + 1);
 | 
						|
    if (app_len < sizeof(*meter_read_hdr)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    app_len = app_len - sizeof(*meter_read_hdr);
 | 
						|
    if (app_len < meter_read_hdr->data_len ) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (meter_read_hdr->ver != GW_APP_VERSION) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (meter_read_hdr->data_type != GW_APP_DATA_TYPE_TRANSPARENT) {
 | 
						|
        reason = 4;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    app_sn = meter_read_hdr->seq;
 | 
						|
    if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) {
 | 
						|
        reason = 5;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_sg_ctrl_ul_sn_exist(app_sn)) {
 | 
						|
        reason = 6;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__,
 | 
						|
            reason);
 | 
						|
    } else {
 | 
						|
        iot_sg_ctrl_rpt_sta_data(meter_read_hdr->data,
 | 
						|
            (uint16_t)meter_read_hdr->data_len, IOT_CTRL_EVENT_METER_DATA);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_sg_ctrl_gw_handle_sta_id_info(gw_app_header_t *app_hdr,
 | 
						|
    uint32_t len)
 | 
						|
{
 | 
						|
    info_pool_t *info_pool = &sg_ctrl_global->info_pool;
 | 
						|
    gw_app_query_chip_id_ul_t *rpt_chip_id;
 | 
						|
    gw_app_query_module_id_ul_t *rpt =
 | 
						|
        (gw_app_query_module_id_ul_t *)(app_hdr + 1);
 | 
						|
    uint8_t reason = 0;
 | 
						|
 | 
						|
    if (len < sizeof(*rpt)) {
 | 
						|
        reason = 1;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (rpt->dir != 1) {
 | 
						|
        reason = 2;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (false == iot_sg_ctrl_pool_sn_exist(info_pool, rpt->seq, true)) {
 | 
						|
        reason = 3;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_sg_ctrl_ul_sn_exist(rpt->seq)) {
 | 
						|
         reason = 4;
 | 
						|
         goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (rpt->id_type == GW_APP_ID_INFO_TYPE_CHIP) {
 | 
						|
        rpt_chip_id = (gw_app_query_chip_id_ul_t *)(app_hdr + 1);
 | 
						|
        if (len < sizeof(*rpt_chip_id)) {
 | 
						|
            reason = 5;
 | 
						|
            goto err;
 | 
						|
        }
 | 
						|
        if (rpt_chip_id->chip_id_len > GW_APP_CHIP_ID_INFO_LEN) {
 | 
						|
            reason = 6;
 | 
						|
            goto err;
 | 
						|
        }
 | 
						|
        iot_sg_ctrl_id_info_rpt(rpt_chip_id->chip_info,
 | 
						|
            rpt_chip_id->chip_id_len, PROTO_CTRL_ID_INFO_TYPE_CHIP,
 | 
						|
            rpt_chip_id->dev_type);
 | 
						|
    } else {
 | 
						|
        if (rpt->module_id_len > GW_APP_MODULE_ID_INFO_LEN) {
 | 
						|
            reason = 7;
 | 
						|
            goto err;
 | 
						|
        }
 | 
						|
        iot_sg_ctrl_id_info_rpt(rpt->module_info, rpt->module_id_len,
 | 
						|
            PROTO_CTRL_ID_INFO_TYPE_MODULE, rpt->dev_type);
 | 
						|
    }
 | 
						|
 | 
						|
err:
 | 
						|
    iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__, reason);
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_handle_sta_app_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint32_t pkt_len;
 | 
						|
    gw_app_header_t *app_hdr;
 | 
						|
    uint8_t reason = 0;
 | 
						|
 | 
						|
    app_hdr = (gw_app_header_t *)iot_pkt_data(pkt);
 | 
						|
    pkt_len = (uint16_t)iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
 | 
						|
    if (pkt_len <= sizeof(*app_hdr)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (app_hdr->port != GW_APP_PORT_OTHER) {
 | 
						|
        iot_cus_printf("WARNING: %s drop invalid gw app data\n", __FUNCTION__);
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    switch (app_hdr->id) {
 | 
						|
    case GW_APP_ID_CONCENTRATOR_METER_R:
 | 
						|
    {
 | 
						|
        iot_sg_ctrl_gw_handle_sta_read_meter_data(app_hdr,
 | 
						|
            pkt_len - sizeof(*app_hdr));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
    case GW_APP_ID_QUERY_MODULE_ID_INFO:
 | 
						|
    {
 | 
						|
        iot_sg_ctrl_gw_handle_sta_id_info(app_hdr, pkt_len - sizeof(*app_hdr));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
    default:
 | 
						|
        reason = 3;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
out:
 | 
						|
    if (reason) {
 | 
						|
        iot_cus_printf("%s : drop req , reason %lu \n", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_handle_cco_app_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    gw_app_header_t *app_hdr;
 | 
						|
    gw_app_ctrl_proto_t *rsp = NULL;
 | 
						|
 | 
						|
    info_pool_t *info_pool = &sg_ctrl_global->info_pool;
 | 
						|
    uint8_t app_sn = 0;
 | 
						|
    uint8_t *pkt_data;
 | 
						|
    uint32_t pkt_len;
 | 
						|
    uint8_t reason = 0;
 | 
						|
 | 
						|
    pkt_data = iot_pkt_data(pkt);
 | 
						|
    app_hdr = (gw_app_header_t *)pkt_data;
 | 
						|
    pkt_len = iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
 | 
						|
    if (pkt_len <= sizeof(*app_hdr)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    pkt_len = pkt_len - sizeof(*app_hdr);
 | 
						|
    switch (app_hdr->id) {
 | 
						|
    case GW_APP_ID_CTRL_PROTO:
 | 
						|
    {
 | 
						|
        rsp = (gw_app_ctrl_proto_t *)(app_hdr + 1);
 | 
						|
        if (pkt_len < sizeof(*rsp)) {
 | 
						|
            reason = 2;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        pkt_len = pkt_len - sizeof(*rsp);
 | 
						|
        if (pkt_len < rsp->data_len) {
 | 
						|
            reason = 3;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        if (rsp->proto_type != GW_APP_CTRL_PROTO_3762) {
 | 
						|
            reason = 4;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        reason = 5;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_sg_ctrl_get_ckq_data_sn((uint8_t *)(rsp + 1), &app_sn)) {
 | 
						|
        if (iot_sg_ctrl_ul_sn_exist(app_sn)) {
 | 
						|
             reason = 6;
 | 
						|
             goto out;
 | 
						|
         }
 | 
						|
    } else if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) {
 | 
						|
        reason = 7;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if ((!reason) && rsp) {
 | 
						|
        iot_pkt_set_data(pkt, rsp->data);
 | 
						|
        iot_pkt_set_tail(pkt, rsp->data + rsp->data_len);
 | 
						|
        iot_sg_ctrl_rpt_cco_data(pkt);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__,
 | 
						|
            reason);
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_send_data_to_cco(uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
    gw_app_header_t *app_hdr;
 | 
						|
    gw_app_ctrl_proto_t *ctrl_hdr;
 | 
						|
    iot_pkt_t *plc_pkt;
 | 
						|
    uint8_t *pkt_data;
 | 
						|
    uint16_t total_size;
 | 
						|
 | 
						|
    total_size = sizeof(*app_hdr) + sizeof(*ctrl_hdr) + len;
 | 
						|
    plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle,
 | 
						|
        NULL, sg_ctrl_global->local_mac_addr,
 | 
						|
        GW_APP_PRIO_METER_READ, total_size, IOT_PLC_MAX_RETRY_CNT);
 | 
						|
    IOT_ASSERT(plc_pkt);
 | 
						|
 | 
						|
    pkt_data = iot_pkt_block_ptr(plc_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    /* fill in header */
 | 
						|
    app_hdr = (gw_app_header_t *)pkt_data;
 | 
						|
    app_hdr->id = GW_APP_ID_CTRL_PROTO;
 | 
						|
    app_hdr->port = GW_APP_PORT_OTHER;
 | 
						|
    app_hdr->control = 0;
 | 
						|
 | 
						|
    ctrl_hdr = (gw_app_ctrl_proto_t *)(app_hdr + 1);
 | 
						|
    ctrl_hdr->proto_type = GW_APP_CTRL_PROTO_3762;
 | 
						|
    ctrl_hdr->data_len = len;
 | 
						|
    os_mem_cpy(ctrl_hdr->data, data, len);
 | 
						|
    iot_pkt_put(plc_pkt, total_size);
 | 
						|
 | 
						|
    iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
#else  /* IOT_SG_CONTROLLER_ENABLE && IOT_GW_APP_ENABLE */
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_read_meter(uint8_t *data, uint16_t datalen,
 | 
						|
    uint16_t sn)
 | 
						|
{
 | 
						|
    (void)data;
 | 
						|
    (void)datalen;
 | 
						|
    (void)sn;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_get_id_info(uint8_t id_type, uint16_t sn, uint8_t qr_cnt)
 | 
						|
{
 | 
						|
    (void)id_type;
 | 
						|
    (void)sn;
 | 
						|
    (void)qr_cnt;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_handle_sta_app_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)pkt;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_handle_cco_app_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)pkt;
 | 
						|
}
 | 
						|
 | 
						|
void iot_sg_ctrl_gw_send_data_to_cco(uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
    (void)data;
 | 
						|
    (void)len;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* IOT_SG_CONTROLLER_ENABLE && IOT_GW_APP_ENABLE */
 |