373 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			373 lines
		
	
	
		
			10 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_nw_app.h"
 | ||
|  | #include "iot_sg_ctrl.h"
 | ||
|  | 
 | ||
|  | #if (IOT_SG_CONTROLLER_ENABLE && IOT_NW_CTRL_APP_ENABLE)
 | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_send_data_to_cco(uint8_t *data, uint16_t len, | ||
|  |     uint8_t sn) | ||
|  | { | ||
|  |     nw_app_header_t *nw_app_hdr; | ||
|  |     nw_app_data_t *app_hdr; | ||
|  |     nw_app_ctrl_proto_t *ctrl_hdr; | ||
|  |     iot_pkt_t *plc_pkt; | ||
|  |     uint8_t *pkt_data; | ||
|  |     uint16_t total_size; | ||
|  | 
 | ||
|  |     total_size = sizeof(*nw_app_hdr) + 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, | ||
|  |         NW_APP_PRIO_TASK, 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 */ | ||
|  |     nw_app_hdr = (nw_app_header_t *)pkt_data; | ||
|  | 
 | ||
|  |     nw_app_hdr->id = NW_APP_ID; | ||
|  |     nw_app_hdr->port = NW_APP_PORT; | ||
|  |     nw_app_hdr->reserved = 0; | ||
|  |     app_hdr = (nw_app_data_t *)(nw_app_hdr + 1); | ||
|  |     app_hdr->control_field.frame_type = NW_APP_FRAME_TYPE_CTRL; | ||
|  |     app_hdr->control_field.reserved = 0; | ||
|  |     app_hdr->control_field.work_append = NW_APP_CONTROL_NO_VENDOR_INFO; | ||
|  |     app_hdr->control_field.respond = NW_APP_CONTROL_NEED_RSP; | ||
|  |     app_hdr->control_field.start = NW_APP_CONTROL_PRM_MASTER; | ||
|  |     app_hdr->control_field.dir = NW_APP_CONTROL_DOWN_LINK; | ||
|  |     app_hdr->work_id = NW_APP_WORK_CTRL_PROTO; | ||
|  |     app_hdr->ver = NW_APP_VERSION; | ||
|  |     app_hdr->sn = sn; | ||
|  |     app_hdr->len = sizeof(*ctrl_hdr) + len; | ||
|  | 
 | ||
|  |     ctrl_hdr = (nw_app_ctrl_proto_t *)app_hdr->data; | ||
|  |     ctrl_hdr->proto_type = 0; | ||
|  |     ctrl_hdr->sn = sn; | ||
|  |     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; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_passthrough(uint8_t *data, uint16_t len, | ||
|  |     uint8_t sn) | ||
|  | { | ||
|  |     nw_app_header_t *nw_app_hdr; | ||
|  |     nw_app_data_t *app_hdr; | ||
|  |     nw_app_ctrl_proto_passthrough_t *passthrough; | ||
|  |     iot_pkt_t *plc_pkt; | ||
|  |     uint8_t *pkt_data; | ||
|  |     uint16_t total_size; | ||
|  | 
 | ||
|  |     total_size = sizeof(*nw_app_hdr) + sizeof(*app_hdr) + sizeof(*passthrough) + | ||
|  |         len; | ||
|  |     plc_pkt = iot_plc_alloc_ctrl_proto_msdu(sg_ctrl_global->app_handle, | ||
|  |         NULL, sg_ctrl_global->local_mac_addr, | ||
|  |         NW_APP_PRIO_TASK, 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 */ | ||
|  |     nw_app_hdr = (nw_app_header_t *)pkt_data; | ||
|  | 
 | ||
|  |     nw_app_hdr->id = NW_APP_ID; | ||
|  |     nw_app_hdr->port = NW_APP_PORT; | ||
|  |     nw_app_hdr->reserved = 0; | ||
|  |     app_hdr = (nw_app_data_t *)(nw_app_hdr + 1); | ||
|  |     app_hdr->control_field.frame_type = NW_APP_FRAME_TYPE_CTRL; | ||
|  |     app_hdr->control_field.reserved = 0; | ||
|  |     app_hdr->control_field.work_append = NW_APP_CONTROL_NO_VENDOR_INFO; | ||
|  |     app_hdr->control_field.respond = NW_APP_CONTROL_NEED_RSP; | ||
|  |     app_hdr->control_field.start = NW_APP_CONTROL_PRM_MASTER; | ||
|  |     app_hdr->control_field.dir = NW_APP_CONTROL_DOWN_LINK; | ||
|  |     app_hdr->work_id = NW_APP_WORK_CTRL_PASSTHROUGH; | ||
|  |     app_hdr->ver = NW_APP_VERSION; | ||
|  |     app_hdr->sn = sn; | ||
|  |     app_hdr->len = sizeof(*passthrough) + len; | ||
|  | 
 | ||
|  |     passthrough = (nw_app_ctrl_proto_passthrough_t *)app_hdr->data; | ||
|  |     passthrough->proto_type = NW_APP_CTRL_PROTO_TYPE_DEF; | ||
|  |     passthrough->prm = NW_APP_CTRL_PRM_MASTER; | ||
|  |     os_mem_set(passthrough->baud, 0, sizeof(passthrough->baud)); | ||
|  |     passthrough->sn = sn; | ||
|  |     passthrough->data_len = len; | ||
|  |     os_mem_cpy(passthrough->data, data, len); | ||
|  | 
 | ||
|  |     iot_pkt_put(plc_pkt, total_size); | ||
|  |     iot_plc_send_msdu(sg_ctrl_global->app_handle, plc_pkt); | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t iot_sg_ctrl_nw_handle_cco_data(uint8_t *data, | ||
|  |     uint16_t data_len) | ||
|  | { | ||
|  |     nw_app_ctrl_proto_t *rsp = NULL; | ||
|  |     uint8_t app_sn = 0; | ||
|  | 
 | ||
|  |     info_pool_t *info_pool = &sg_ctrl_global->info_pool; | ||
|  |     uint8_t reason = 0; | ||
|  | 
 | ||
|  |     rsp = (nw_app_ctrl_proto_t *)data; | ||
|  |     if (data_len < sizeof(*rsp)) { | ||
|  |         reason = 1; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (data_len < (sizeof(*rsp) + rsp->data_len)) { | ||
|  |         reason = 2; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (iot_sg_ctrl_get_ckq_data_sn(rsp->data, &app_sn)) { | ||
|  |         if (iot_sg_ctrl_ul_sn_exist(app_sn)) { | ||
|  |              reason = 3; | ||
|  |              goto out; | ||
|  |          } | ||
|  |     } else if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) { | ||
|  |         reason = 4; | ||
|  |     } | ||
|  | out: | ||
|  |     if ((!reason) && rsp) { | ||
|  |         iot_sg_ctrl_data_rpt_drv(app_sn, IOT_CTRL_EVENT_CCO_DATA_RPT, rsp->data, | ||
|  |             rsp->data_len); | ||
|  |     } else { | ||
|  |         iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__, reason); | ||
|  |     } | ||
|  |     return reason; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t iot_sg_ctrl_nw_handle_cco_passthrough_data(uint8_t *data, | ||
|  |     uint16_t len) | ||
|  | { | ||
|  |     nw_app_ctrl_proto_passthrough_t *rsp = NULL; | ||
|  |     uint8_t reason = 0; | ||
|  |     uint8_t app_sn; | ||
|  |     info_pool_t *info_pool = &sg_ctrl_global->info_pool; | ||
|  | 
 | ||
|  |     rsp = (nw_app_ctrl_proto_passthrough_t *)data; | ||
|  |     if (len < sizeof(*rsp)) { | ||
|  |         reason = 1; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (len < (sizeof(*rsp) + rsp->data_len)) { | ||
|  |         reason = 2; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (iot_sg_ctrl_get_ckq_data_sn(rsp->data, &app_sn)) { | ||
|  |         if (iot_sg_ctrl_ul_sn_exist(app_sn)) { | ||
|  |              reason = 3; | ||
|  |              goto out; | ||
|  |          } | ||
|  |     } else if (false == iot_sg_ctrl_pool_sn_exist(info_pool, app_sn, true)) { | ||
|  |         reason = 4; | ||
|  |     } | ||
|  | 
 | ||
|  | out: | ||
|  |     if ((!reason) && rsp) { | ||
|  |         iot_sg_ctrl_data_rpt_drv(rsp->sn, IOT_CTRL_EVENT_PASSTHROUGH_RPT, | ||
|  |         rsp->data, rsp->data_len); | ||
|  |     } else { | ||
|  |         iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__, reason); | ||
|  |     } | ||
|  |     return reason; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t iot_sg_ctrl_nw_handle_sta_passthrough_data(uint8_t *data, | ||
|  |     uint16_t len) | ||
|  | { | ||
|  |     nw_app_ctrl_proto_passthrough_t *rsp = NULL; | ||
|  |     uint8_t reason = 0; | ||
|  |     info_pool_t *info_pool = &sg_ctrl_global->info_pool; | ||
|  | 
 | ||
|  |     rsp = (nw_app_ctrl_proto_passthrough_t *)data; | ||
|  |     if (len < sizeof(*rsp)) { | ||
|  |         reason = 1; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (len < (sizeof(*rsp) + rsp->data_len)) { | ||
|  |         reason = 2; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (false == iot_sg_ctrl_pool_sn_exist(info_pool, IOT_CTRL_PASSTHROUGH_SN, | ||
|  |         true)) { | ||
|  |         reason = 3; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  | out: | ||
|  |     if ((!reason) && rsp) { | ||
|  |         iot_sg_ctrl_data_rpt_drv(rsp->sn, IOT_CTRL_EVENT_PASSTHROUGH_RPT, | ||
|  |             rsp->data, rsp->data_len); | ||
|  |     } else { | ||
|  |         iot_cus_printf("%s: drop req, reason %lu\n", __FUNCTION__, reason); | ||
|  |     } | ||
|  |     return reason; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_handle_cco_app_data(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     nw_app_header_t *app_hdr = NULL; | ||
|  |     nw_app_data_t *app_data = NULL; | ||
|  |     uint8_t *pkt_data; | ||
|  |     uint32_t pkt_len; | ||
|  |     uint8_t reason = 0; | ||
|  | 
 | ||
|  |     pkt_data = iot_pkt_data(pkt); | ||
|  |     app_hdr = (nw_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; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (app_hdr->port != NW_APP_PORT) { | ||
|  |         reason = 2; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     app_data = (nw_app_data_t *)(app_hdr + 1); | ||
|  | 
 | ||
|  |     if (app_data->control_field.frame_type != NW_APP_FRAME_TYPE_CTRL) { | ||
|  |         reason = 3; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     switch (app_data->work_id) { | ||
|  |     case NW_APP_WORK_CTRL_PROTO: | ||
|  |     { | ||
|  |         if (iot_sg_ctrl_nw_handle_cco_data(app_data->data, app_data->len)) { | ||
|  |             reason = 4; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     case NW_APP_WORK_CTRL_PASSTHROUGH: | ||
|  |     { | ||
|  |         if (iot_sg_ctrl_nw_handle_cco_passthrough_data(app_data->data, | ||
|  |             app_data->len)) { | ||
|  |             reason = 5; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         reason = 6; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  | out: | ||
|  |     if (reason) { | ||
|  |         iot_cus_printf("%s : drop req , reason %lu \n", __FUNCTION__, reason); | ||
|  |     } | ||
|  |     if (pkt) { | ||
|  |         iot_pkt_free(pkt); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_handle_sta_app_data(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     nw_app_header_t *app_hdr = NULL; | ||
|  |     nw_app_data_t *app_data = NULL; | ||
|  |     uint8_t *pkt_data; | ||
|  |     uint32_t pkt_len; | ||
|  |     uint8_t reason = 0; | ||
|  | 
 | ||
|  |     pkt_data = iot_pkt_data(pkt); | ||
|  |     app_hdr = (nw_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; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (app_hdr->port != NW_APP_PORT) { | ||
|  |         reason = 2; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     app_data = (nw_app_data_t *)(app_hdr + 1); | ||
|  | 
 | ||
|  |     if (app_data->control_field.frame_type != NW_APP_FRAME_TYPE_CTRL && | ||
|  |         app_data->control_field.frame_type != NW_APP_FRAME_TYPE_DATA_FWD) { | ||
|  |         reason = 3; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     switch (app_data->work_id) { | ||
|  |     case NW_APP_WORK_CTRL_PASSTHROUGH: | ||
|  |     { | ||
|  |         if (iot_sg_ctrl_nw_handle_sta_passthrough_data(app_data->data, | ||
|  |             app_data->len)) { | ||
|  |             reason = 4; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         reason = 5; | ||
|  |         break; | ||
|  |     } | ||
|  | out: | ||
|  |     if (reason) { | ||
|  |         iot_cus_printf("%s : drop req , reason %lu \n", __FUNCTION__, reason); | ||
|  |     } | ||
|  |     if (pkt) { | ||
|  |         iot_pkt_free(pkt); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | #else  /* IOT_SG_CONTROLLER_ENABLE && IOT_NW_CTRL_APP_ENABLE */
 | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_send_data_to_cco(uint8_t *data, uint16_t len, | ||
|  |     uint8_t sn) | ||
|  | { | ||
|  |     (void)data; | ||
|  |     (void)len; | ||
|  |     (void)sn; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_passthrough(uint8_t *data, uint16_t len, | ||
|  |     uint8_t sn) | ||
|  | { | ||
|  |     (void)data; | ||
|  |     (void)len; | ||
|  |     (void)sn; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_handle_cco_app_data(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     (void)pkt; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sg_ctrl_nw_handle_sta_app_data(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     (void)pkt; | ||
|  | } | ||
|  | 
 | ||
|  | #endif /* IOT_SG_CONTROLLER_ENABLE && IOT_GW_APP_ENABLE */
 |