771 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			771 lines
		
	
	
		
			24 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_tput.h"
 | ||
|  | /* os_ship header files */ | ||
|  | #include "os_task_api.h"
 | ||
|  | #include "os_event_api.h"
 | ||
|  | #include "os_utils_api.h"
 | ||
|  | #include "iot_io.h"
 | ||
|  | #include "iot_pkt_api.h"
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "iot_app_api.h"
 | ||
|  | #include "iot_plc_msg_api.h"
 | ||
|  | #include "iot_plc_msg_cco_api.h"
 | ||
|  | 
 | ||
|  | #if IOT_TPUT_APP_ENABLE
 | ||
|  | 
 | ||
|  | uint8_t app_tput_cco_mac[] = {0x48, 0x55, 0x5C, 0xAA, 0xBB, 0xCC}; | ||
|  | uint8_t app_tput_sta_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x11}; | ||
|  | 
 | ||
|  | /* iot tput global data */ | ||
|  | iot_tput_global_t* p_iot_tput_glb = NULL; | ||
|  | 
 | ||
|  | uint32_t iot_tput_get_msdu_len() | ||
|  | { | ||
|  |     return p_iot_tput_glb->tput_cfg.msdu_size; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_tput_send_msg(uint16_t msg_type, uint16_t msg_id, \ | ||
|  |                        void* data1) | ||
|  | { | ||
|  |     iot_task_msg_t          *msg; | ||
|  |     iot_tput_msg_t     *task_msg; | ||
|  |     msg = iot_task_alloc_msg_with_reserved(p_iot_tput_glb->handle, 0); | ||
|  |     if (!msg) { | ||
|  |         iot_printf("%s, no msg\n", __FUNCTION__); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     task_msg = (iot_tput_msg_t*)msg; | ||
|  |     task_msg->msg.type = msg_type; | ||
|  |     task_msg->msg.id = msg_id; | ||
|  |     task_msg->data = data1; | ||
|  |     iot_task_queue_msg(p_iot_tput_glb->handle, \ | ||
|  |                        &task_msg->msg, IOT_TPUT_TASK_QUEUE_LP); | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_plc_recv_tput(void *param, iot_pkt_t *pkt) | ||
|  | { | ||
|  |     (void)param; | ||
|  |     iot_tput_send_msg(IOT_TPUT_PLC_MSG, 0, pkt); | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_plc_tput_handle_mac_msg(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     iot_plc_msg_header_t *hdr = | ||
|  |         (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA); | ||
|  | 
 | ||
|  |     if (hdr->app_id != IOT_PLC_APP_ID_BCAST && | ||
|  |         hdr->app_id != IOT_TPUT_APP_ID) { | ||
|  |         /* drop corrupted message */ | ||
|  |         iot_pkt_free(pkt); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (p_iot_tput_glb->app_registered == 0 && | ||
|  |         hdr->msg_id != IOT_PLC_MSG_APP_REG_CONF) { | ||
|  |         /* only handle app register confirm message before app registered */ | ||
|  |         iot_pkt_free(pkt); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     switch (hdr->msg_id) { | ||
|  |     /* register app */ | ||
|  |     case IOT_PLC_MSG_APP_REG_CONF: | ||
|  |     { | ||
|  |         iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1); | ||
|  |         if (rpt->result == IOT_PLC_SUCCESS || | ||
|  |             rpt->result == IOT_PLC_SUCCESS_MODIFIED) { | ||
|  |             p_iot_tput_glb->app_registered = 1; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     /* state change 1. in -> out ready = 1
 | ||
|  |      *              2. out -> in ready = 0 | ||
|  |      */ | ||
|  |     case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT : | ||
|  |     { | ||
|  |         iot_plc_dev_state_change_rpt_t* rpt = | ||
|  |             (iot_plc_dev_state_change_rpt_t*)(hdr + 1); | ||
|  | 
 | ||
|  |         if(rpt->is_ready) | ||
|  |         { | ||
|  |             iot_printf("[tput_dbg] STATE CHANGE REPORT, MY ROLE TYPE#%d.\n", | ||
|  |                 rpt->dev_role); | ||
|  | 
 | ||
|  |             iot_printf("[tput_dbg] CCO MAC: %02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |                 rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], | ||
|  |                 rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); | ||
|  | 
 | ||
|  |             iot_printf("[tput_dbg] LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |                 rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2], | ||
|  |                 rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]); | ||
|  | 
 | ||
|  |             if(IOT_PLC_DEV_ROLE_STA == rpt->dev_role) | ||
|  |             { | ||
|  |                 iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.rmt_addr, rpt->cco_mac); | ||
|  |                 p_iot_tput_glb->tput_dev.rmt_valid = true; | ||
|  |             } | ||
|  | 
 | ||
|  |             p_iot_tput_glb->tput_dev.dev_ready  = true; | ||
|  |             p_iot_tput_glb->tput_dev.dev_role   = rpt->dev_role; | ||
|  |             p_iot_tput_glb->tput_dev.nid        = rpt->nid; | ||
|  | 
 | ||
|  |             iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.mac_addr, rpt->local_mac); | ||
|  |             iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.cco_addr, rpt->cco_mac); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             iot_printf("MAC IS NOT READY.",1,2,3,4,5,6); | ||
|  |             p_iot_tput_glb->tput_dev.dev_ready  = false; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     /*call iot_plc_query_dev_info */ | ||
|  |     case IOT_PLC_MSG_DEV_INFO_RPT : | ||
|  |     { | ||
|  |         iot_plc_dev_info_rpt_t* rpt = | ||
|  |             (iot_plc_dev_info_rpt_t*)(hdr + 1); | ||
|  |         if(rpt->is_ready) | ||
|  |         { | ||
|  |             iot_printf("[tput_dbg] DEVICE INFO REPORT MAC GET READY, MY ROLE TYPE#%d.\n", | ||
|  |                 rpt->dev_role,2,3,4,5,6); | ||
|  | 
 | ||
|  |             iot_printf("[tput_dbg] CCO MAC   : %02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |                 rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], | ||
|  |                 rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); | ||
|  | 
 | ||
|  |             iot_printf("LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                 rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2], | ||
|  |                 rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]); | ||
|  | 
 | ||
|  |             p_iot_tput_glb->tput_dev.dev_ready  = true; | ||
|  |             p_iot_tput_glb->tput_dev.dev_role   = rpt->dev_role; | ||
|  | 
 | ||
|  |             if(IOT_PLC_DEV_ROLE_STA == rpt->dev_role) | ||
|  |             { | ||
|  |                 iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.rmt_addr, rpt->cco_mac); | ||
|  |                 p_iot_tput_glb->tput_dev.rmt_valid = true; | ||
|  |             } | ||
|  | 
 | ||
|  |             iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.mac_addr, rpt->local_mac); | ||
|  |             iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.cco_addr, rpt->cco_mac); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             iot_printf("[tput_dbg] MAC IS NOT READY.\n"); | ||
|  |             p_iot_tput_glb->tput_dev.dev_ready  = false; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     /* cco a sta join net */ | ||
|  |     case IOT_PLC_MSG_STA_JOIN_INFO : | ||
|  |     { | ||
|  |         iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1); | ||
|  |         iot_printf("[tput_dbg] STA JOINED : MAC#%02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |             rpt->sta_info.addr[0], rpt->sta_info.addr[1], | ||
|  |             rpt->sta_info.addr[2], rpt->sta_info.addr[3], | ||
|  |             rpt->sta_info.addr[4], rpt->sta_info.addr[5]); | ||
|  | 
 | ||
|  |         if(IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role) | ||
|  |         { | ||
|  |             /* Keep the remote device as the last one we got. */ | ||
|  |             iot_mac_addr_cpy(p_iot_tput_glb->tput_dev.rmt_addr, rpt->sta_info.addr); | ||
|  |             p_iot_tput_glb->tput_dev.rmt_valid = true; | ||
|  |         } | ||
|  | 
 | ||
|  |         break; | ||
|  |     } | ||
|  |     /* cco have sta leave net */ | ||
|  |     case IOT_PLC_MSG_STA_LEAVE_INFO : | ||
|  |     { | ||
|  |         uint32_t cnt; | ||
|  |         iot_plc_sta_leave_info_t* rpt = | ||
|  |             (iot_plc_sta_leave_info_t*)(hdr + 1); | ||
|  | 
 | ||
|  |         for(cnt = 0; cnt < rpt->sta_count; cnt++) | ||
|  |         { | ||
|  |             iot_printf("[tput_dbg] STA LEAVED : MAC#%02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |                rpt->sta[cnt].mac_addr[0], rpt->sta[cnt].mac_addr[1], | ||
|  |                rpt->sta[cnt].mac_addr[2], rpt->sta[cnt].mac_addr[3], | ||
|  |                rpt->sta[cnt].mac_addr[4], rpt->sta[cnt].mac_addr[5]); | ||
|  | 
 | ||
|  |                if((IOT_PLC_DEV_ROLE_STA == p_iot_tput_glb->tput_dev.dev_role) | ||
|  |                 &&(iot_mac_addr_cmp | ||
|  |                 (p_iot_tput_glb->tput_dev.rmt_addr, rpt->sta[cnt].mac_addr))) | ||
|  |                { | ||
|  |                    p_iot_tput_glb->tput_dev.rmt_valid = false; | ||
|  |                } | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     /* receive plc pkt */ | ||
|  |     case IOT_PLC_MSG_MSDU_RECV : | ||
|  |     { | ||
|  |         iot_plc_msdu_recv_t *msdu = (iot_plc_msdu_recv_t*)(hdr + 1); | ||
|  | 
 | ||
|  |         iot_printf("[tput_dbg] MSDU RECEIVED FROM MAC#%02x-%02x-%02x-%02x-%02x-%02x.\n", | ||
|  |                    msdu->src[0], msdu->src[1], msdu->src[2], | ||
|  |                    msdu->src[3], msdu->src[4], msdu->src[5]); | ||
|  | 
 | ||
|  |         iot_tput_send_info_t *send_info = (iot_tput_send_info_t *)(msdu->data \ | ||
|  |             + sizeof(iot_tput_cfg_info_t)); | ||
|  | 
 | ||
|  |         iot_printf("[tput_dbg] seq:%d,  receive_cnt:%d\n", \ | ||
|  |             send_info->seq, \ | ||
|  |             ++p_iot_tput_glb->receive_cnt); | ||
|  | 
 | ||
|  |         if(!p_iot_tput_glb->tput_dev.dev_ready) { | ||
|  |             iot_printf("[tput_dbg] DEVICE NOT READY.PACKET DROPPED.\n"); | ||
|  |             break; | ||
|  |         } | ||
|  | 
 | ||
|  |         if (IOT_PLC_DEV_ROLE_STA == p_iot_tput_glb->tput_dev.dev_role) { | ||
|  | 
 | ||
|  |             os_mem_cpy(&p_iot_tput_glb->tput_cfg, msdu->data,\ | ||
|  |                 sizeof(iot_tput_cfg_info_t)); | ||
|  | 
 | ||
|  |             iot_printf("[tput_dbg] down_up_link:%d\n", \ | ||
|  |                 p_iot_tput_glb->tput_cfg.downlink); | ||
|  | 
 | ||
|  |             /* sta dst addr = receive src addr */ | ||
|  |             os_mem_cpy(p_iot_tput_glb->tput_cfg.dst, msdu->src, 6); | ||
|  | 
 | ||
|  |             if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_UP_LINK && \ | ||
|  |                 os_mem_cmp(p_iot_tput_glb->tput_dev.cco_addr, msdu->src, 6) \ | ||
|  |                 == 0 && p_iot_tput_glb->sta_send_flag == 0) { | ||
|  |                     p_iot_tput_glb->sta_send_flag = 1; | ||
|  |                     iot_tput_timer_start(p_iot_tput_glb->tput_send_timer, \ | ||
|  |                         IOT_TPUT_SEND_PKT_DUR); | ||
|  |                     iot_tput_timer_start(p_iot_tput_glb->tput_period_timer, \ | ||
|  |                         IOT_TPUT_STATIS_DUR); | ||
|  |             } | ||
|  |             else if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_DOWN_LINK &&\ | ||
|  |                 p_iot_tput_glb->sta_send_flag == 0) { | ||
|  |                 iot_printf("[tput_dbg] enable sta req mode\n"); | ||
|  |                 p_iot_tput_glb->sta_send_flag = 1; | ||
|  |                 iot_tput_timer_start(p_iot_tput_glb->tput_req_timer, \ | ||
|  |                     IOT_TPUT_STA_REQ_DUR);   //5s
 | ||
|  |             } | ||
|  |         } | ||
|  |         else if (IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role) { | ||
|  | 
 | ||
|  |             if (IOT_SEQ_INVAILD == send_info->seq && \ | ||
|  |                 p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_DOWN_LINK) { | ||
|  | 
 | ||
|  |                 p_iot_tput_glb->tput_kpbs = \ | ||
|  |                     (send_info->statistics_cnt * iot_tput_get_msdu_len() * 8)/10240; | ||
|  | 
 | ||
|  |                 iot_printf("[tput_dbg] sta statistics_cnt:%d, tupt_kbps:%d\n", \ | ||
|  |                     send_info->statistics_cnt, p_iot_tput_glb->tput_kpbs); | ||
|  | 
 | ||
|  |                 iot_tput_report_rate_test(msdu->src, \ | ||
|  |                     p_iot_tput_glb->tput_cfg.downlink, \ | ||
|  |                     p_iot_tput_glb->tput_kpbs); | ||
|  |             } | ||
|  |             else if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_UP_LINK && \ | ||
|  |                 p_iot_tput_glb->cco_check_rece_flag == 0){ | ||
|  |                 p_iot_tput_glb->cco_check_rece_flag = 1 ; | ||
|  |                 iot_tput_timer_start(p_iot_tput_glb->tput_req_timer, \ | ||
|  |                     IOT_TPUT_STA_REQ_DUR);   //5s
 | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         break; | ||
|  |     } | ||
|  |     /*
 | ||
|  |      * call iot_plc_set_cfg | ||
|  |      */ | ||
|  |     case IOT_PLC_MSG_CFG_SET_CONF : | ||
|  |     { | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_PLC_MSG_FREQ_BAND_SET_RPT: | ||
|  |     { | ||
|  |         /* handle freq band set response */ | ||
|  |         iot_plc_freq_band_set_rpt_t *rpt; | ||
|  |         rpt = (iot_plc_freq_band_set_rpt_t *)(hdr + 1); | ||
|  |         /* result = 0 :  success
 | ||
|  |          * result = 2 :  fail | ||
|  |          */ | ||
|  |         iot_printf("[tput_dbg] set_band status:%d\n", rpt->result); | ||
|  |         if (rpt->result == 0) { | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (pkt) { | ||
|  |         iot_pkt_free(pkt); | ||
|  |     } | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | static void iot_plc_tput_handle_timer_msg(iot_tput_msg_t* task_msg) | ||
|  | { | ||
|  |     switch (task_msg->msg.id) { | ||
|  |     case IOT_TIMER_SEND_PKT : | ||
|  |     { | ||
|  |         uint32_t msdu_len = 0; | ||
|  |         if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_UP_LINK && \ | ||
|  |             IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role) { | ||
|  |             msdu_len = IOT_TPUT_LEN_72; | ||
|  |         } | ||
|  |         else { | ||
|  |             msdu_len = iot_tput_get_msdu_len(); | ||
|  |         } | ||
|  |         iot_tput_send_pkt(p_iot_tput_glb->tput_dev.mac_addr, \ | ||
|  |             p_iot_tput_glb->tput_cfg.dst, msdu_len); | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_TIMER_REQ : | ||
|  |     { | ||
|  |         if (IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role && \ | ||
|  |             p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_UP_LINK) { | ||
|  | 
 | ||
|  |             p_iot_tput_glb->tput_kpbs = \ | ||
|  |                 (p_iot_tput_glb->sta_last_rece_cnt * iot_tput_get_msdu_len() * 8)/10240; | ||
|  | 
 | ||
|  |             iot_printf("[tput_dbg] cco statistics_cnt:%d, tupt_kbps:%d\n", \ | ||
|  |                 p_iot_tput_glb->sta_last_rece_cnt, p_iot_tput_glb->tput_kpbs); | ||
|  | 
 | ||
|  |             iot_tput_report_rate_test(p_iot_tput_glb->tput_cfg.dst, \ | ||
|  |                 p_iot_tput_glb->tput_cfg.downlink,\ | ||
|  |                 p_iot_tput_glb->tput_kpbs); | ||
|  |         } | ||
|  |         else if (IOT_PLC_DEV_ROLE_STA == p_iot_tput_glb->tput_dev.dev_role &&\ | ||
|  |             p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_DOWN_LINK) { | ||
|  |             iot_tput_sta_req(); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (p_iot_tput_glb->sta_last_rece_cnt != p_iot_tput_glb->receive_cnt ) { | ||
|  |             p_iot_tput_glb->sta_last_rece_cnt = p_iot_tput_glb->receive_cnt; | ||
|  |             iot_tput_timer_start(p_iot_tput_glb->tput_req_timer, \ | ||
|  |                 IOT_TPUT_STA_REQ_DUR);   //5s
 | ||
|  |         } | ||
|  |         else { | ||
|  |             p_iot_tput_glb->receive_cnt = 0; | ||
|  |             p_iot_tput_glb->sta_send_flag = 0; | ||
|  |             iot_tput_timer_stop(p_iot_tput_glb->tput_req_timer); | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |         break; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static void iot_tput_task_handle_event(iot_task_h task_h, uint32_t event) | ||
|  | { | ||
|  |     (void)task_h; | ||
|  |     (void)event; | ||
|  | 
 | ||
|  |     /* No event implements yet. */ | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | static void iot_tput_handle_cli_msg(iot_tput_msg_t *sg_msg) | ||
|  | { | ||
|  |     iot_pkt_t *pkt = (iot_pkt_t *)sg_msg->data; | ||
|  |     iot_cli_tput_msg_header_t *hdr; | ||
|  | 
 | ||
|  |     hdr = (iot_cli_tput_msg_header_t *)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD); | ||
|  |     switch (hdr->msg_id) { | ||
|  |     case IOT_CLI_SG_MSG_TEST_TPUT: | ||
|  |     { | ||
|  |         /*clear flag and cnt */ | ||
|  |         p_iot_tput_glb->sta_send_flag = 0; | ||
|  |         p_iot_tput_glb->receive_cnt = 0; | ||
|  |         p_iot_tput_glb->send_cnt = 0; | ||
|  | 
 | ||
|  |         uint8_t *tmp = iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA); | ||
|  |         os_mem_cpy(&p_iot_tput_glb->tput_cfg, tmp, sizeof(iot_tput_cfg_info_t)); | ||
|  | 
 | ||
|  |         iot_printf("[tput_dbg] test_id:%d, down_up_link:%d, pkt_len:%d\n",\ | ||
|  |             p_iot_tput_glb->tput_cfg.test_id, | ||
|  |             p_iot_tput_glb->tput_cfg.downlink, \ | ||
|  |             p_iot_tput_glb->tput_cfg.msdu_size); | ||
|  | 
 | ||
|  |         if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_DOWN_LINK && \ | ||
|  |             (IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role)) { | ||
|  |             /* in down link mode.
 | ||
|  |              * cco each 10ms sends a package, a total of 10s | ||
|  |              */ | ||
|  |             iot_tput_timer_start(p_iot_tput_glb->tput_send_timer, \ | ||
|  |                 IOT_TPUT_SEND_PKT_DUR); | ||
|  |             iot_tput_timer_start(p_iot_tput_glb->tput_period_timer, \ | ||
|  |                 IOT_TPUT_STATIS_DUR); | ||
|  |         } | ||
|  |         else if (p_iot_tput_glb->tput_cfg.downlink == IOT_TPUT_UP_LINK && \ | ||
|  |             (IOT_PLC_DEV_ROLE_CCO == p_iot_tput_glb->tput_dev.dev_role)) { | ||
|  |             /* in up link mode.
 | ||
|  |              * cco each 10ms sends a package, a total of 10*10ms. | ||
|  |              * total 10 pkt to notice sta send pkt. | ||
|  |              */ | ||
|  |             iot_tput_timer_start(p_iot_tput_glb->tput_send_timer, \ | ||
|  |                 IOT_TPUT_SEND_PKT_DUR); | ||
|  |             iot_tput_timer_start(p_iot_tput_glb->tput_period_timer, \ | ||
|  |                 IOT_TPUT_STATIS_TG_DUR); | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | static void iot_tput_task_handle_msg(iot_task_h task_h, iot_task_msg_t *msg) | ||
|  | { | ||
|  |     iot_tput_msg_t *task_msg; | ||
|  |     IOT_ASSERT(task_h == p_iot_tput_glb->handle); | ||
|  |     IOT_ASSERT(msg); | ||
|  | 
 | ||
|  |     task_msg = (iot_tput_msg_t*)msg; | ||
|  | 
 | ||
|  |     switch (task_msg->msg.type) { | ||
|  |     case IOT_TPUT_PLC_MSG : | ||
|  |     { | ||
|  |         iot_plc_tput_handle_mac_msg(task_msg->data); | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_TPUT_TIMER_MSG : | ||
|  |     { | ||
|  |         iot_plc_tput_handle_timer_msg(task_msg); | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_TPUT_CLI_MSG : | ||
|  |     { | ||
|  |         iot_tput_handle_cli_msg(task_msg); | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_task_free_msg(p_iot_tput_glb->handle, msg); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | static void iot_tput_task_handle_msg_cancel(iot_task_h task_h, \ | ||
|  |     iot_task_msg_t *msg) | ||
|  | { | ||
|  |     iot_tput_msg_t *task_msg; | ||
|  |     IOT_ASSERT(task_h == p_iot_tput_glb->handle); | ||
|  |     IOT_ASSERT(msg); | ||
|  | 
 | ||
|  |     task_msg = (iot_tput_msg_t*)msg; | ||
|  |     switch (task_msg->msg.type) { | ||
|  |     case IOT_TPUT_PLC_MSG : | ||
|  |     { | ||
|  |         if (task_msg->data) { | ||
|  |             iot_pkt_free(task_msg->data); | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_TPUT_TIMER_MSG : | ||
|  |     { | ||
|  |         break; | ||
|  |     } | ||
|  |     case IOT_TPUT_CLI_MSG : | ||
|  |     { | ||
|  |         break; | ||
|  |     } | ||
|  |     default: | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_task_free_msg(p_iot_tput_glb->handle, msg); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t iot_tput_timer_start(timer_id_t timer_id, uint32_t dur) | ||
|  | { | ||
|  |     os_start_timer(timer_id, dur); // 10ms
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t iot_tput_timer_stop(timer_id_t timer_id) | ||
|  | { | ||
|  |     os_stop_timer(timer_id); | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_tput_send_timer_handle(timer_id_t timer_id, void * arg) | ||
|  | { | ||
|  |     (void)arg; | ||
|  |     iot_tput_send_msg(IOT_TPUT_TIMER_MSG, IOT_TIMER_SEND_PKT, 0); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_tput_period_timer_handle(timer_id_t timer_id, void * arg) | ||
|  | { | ||
|  |     (void)arg; | ||
|  |     p_iot_tput_glb->sta_send_flag = 0; | ||
|  |     p_iot_tput_glb->receive_cnt = 0; | ||
|  |     p_iot_tput_glb->send_cnt = 0; | ||
|  |     p_iot_tput_glb->cco_check_rece_flag = 0; | ||
|  | 
 | ||
|  |     iot_tput_timer_stop(p_iot_tput_glb->tput_send_timer); | ||
|  |     iot_tput_timer_stop(timer_id); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_tput_req_timer_handle(timer_id_t timer_id, void * arg) | ||
|  | { | ||
|  |     (void)arg; | ||
|  |     iot_tput_timer_stop(timer_id); | ||
|  |     iot_tput_send_msg(IOT_TPUT_TIMER_MSG, IOT_TIMER_REQ, 0); | ||
|  | } | ||
|  | 
 | ||
|  | static void iot_sg_tput_cli_callback(void *param, iot_pkt_t *pkt) | ||
|  | { | ||
|  |     (void)param; | ||
|  |     iot_tput_send_msg(IOT_TPUT_CLI_MSG, 0, pkt); | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t iot_tput_task_init() | ||
|  | { | ||
|  |     uint32_t ret = 0; | ||
|  | 
 | ||
|  |     p_iot_tput_glb = os_mem_malloc(IOT_TPUT_MID, sizeof(iot_tput_global_t)); | ||
|  |     if (p_iot_tput_glb == NULL) { | ||
|  |         ret = ERR_NOMEM; | ||
|  |         goto out; | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_task_config_t *cfg = &p_iot_tput_glb->cfg; | ||
|  | 
 | ||
|  |     p_iot_tput_glb->app_handle = NULL; | ||
|  |     p_iot_tput_glb->tput_dev.link_id = IOT_TPUT_TASK_LIKE_ID; | ||
|  |     p_iot_tput_glb->tput_dev.dev_role = IOT_PLC_DEV_ROLE_INVALID; | ||
|  |     //p_iot_tput_glb->nid = IOT_TPUT_NID;
 | ||
|  | 
 | ||
|  |     cfg->stack_size = 0; | ||
|  |     cfg->task_prio = IOT_TPUT_TASK_PRIO; | ||
|  |     cfg->msg_size = sizeof(iot_tput_msg_t); | ||
|  |     cfg->msg_cnt = IOT_TPUT_TASK_POOL_SIZE; | ||
|  |     cfg->queue_cnt = IOT_TPUT_TASK_QUEUE_MAX_PRIO; | ||
|  |     cfg->queue_cfg[IOT_TPUT_TASK_QUEUE_HP].quota = 0; | ||
|  |     cfg->queue_cfg[IOT_TPUT_TASK_QUEUE_LP].quota = 0; | ||
|  |     cfg->task_event_func = iot_tput_task_handle_event; | ||
|  |     cfg->msg_exe_func = iot_tput_task_handle_msg; | ||
|  |     cfg->msg_cancel_func = iot_tput_task_handle_msg_cancel; | ||
|  | 
 | ||
|  |     p_iot_tput_glb->handle = iot_task_create(IOT_TPUT_MID, &p_iot_tput_glb->cfg); | ||
|  | 
 | ||
|  |     if (p_iot_tput_glb->handle == NULL) { | ||
|  |         ret = ERR_FAIL; | ||
|  |         goto err_hdl; | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_plc_app_t  iot_tput_app = {0}; | ||
|  |     iot_tput_app.app_id = IOT_TPUT_APP_ID; | ||
|  |     iot_tput_app.param = NULL; | ||
|  |     iot_tput_app.prio = 3; | ||
|  |     iot_tput_app.recv = iot_plc_recv_tput; | ||
|  | 
 | ||
|  |     p_iot_tput_glb->app_handle = iot_plc_register_app(&iot_tput_app); | ||
|  |     if (p_iot_tput_glb->app_handle == NULL) { | ||
|  |         ret = ERR_FAIL; | ||
|  |         goto app_err; | ||
|  |     } | ||
|  | 
 | ||
|  |     p_iot_tput_glb->tput_send_timer = os_create_timer(IOT_TPUT_MID, true, \ | ||
|  |                 iot_tput_send_timer_handle, p_iot_tput_glb); | ||
|  |     if (p_iot_tput_glb->tput_send_timer == 0) { | ||
|  |         ret = ERR_FAIL; | ||
|  |         iot_printf("create send timer fail \n"); | ||
|  |         goto timer_err1; | ||
|  |     } | ||
|  | 
 | ||
|  |     p_iot_tput_glb->tput_period_timer = os_create_timer(IOT_TPUT_MID, true, \ | ||
|  |                 iot_tput_period_timer_handle, p_iot_tput_glb); | ||
|  |     if (p_iot_tput_glb->tput_send_timer == 0) { | ||
|  |         ret = ERR_FAIL; | ||
|  |         iot_printf("create timer fail \n"); | ||
|  |         goto timer_err2; | ||
|  |     } | ||
|  |     p_iot_tput_glb->tput_req_timer = os_create_timer(IOT_TPUT_MID, true, \ | ||
|  |                 iot_tput_req_timer_handle, p_iot_tput_glb); | ||
|  |     if (p_iot_tput_glb->tput_req_timer == 0) { | ||
|  |         ret = ERR_FAIL; | ||
|  |         iot_printf("create timer fail \n"); | ||
|  |         goto timer_err3; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* register to cli module */ | ||
|  |     p_iot_tput_glb->cli_tput_interface.recv = iot_sg_tput_cli_callback; | ||
|  |     p_iot_tput_glb->cli_tput_interface.param = p_iot_tput_glb; | ||
|  |     ret = iot_cli_tput_interface_register(&p_iot_tput_glb->cli_tput_interface); | ||
|  |     if (ret) { | ||
|  |         ret = ERR_NOMEM; | ||
|  |         goto reg_err; | ||
|  |     } | ||
|  | 
 | ||
|  | #if PLC_SUPPORT_CCO_ROLE
 | ||
|  |     iot_plc_cfg_set_req_t plc_cfg = {0}; | ||
|  |     plc_cfg.reset = 1; | ||
|  |     plc_cfg.dev_type_valid = 1; | ||
|  |     plc_cfg.dev_type = IOT_PLC_DEV_TYPE_CONCENTRATOR; | ||
|  |     plc_cfg.addr_valid = 1; | ||
|  |     iot_plc_set_cfg(p_iot_tput_glb->app_handle, IOT_PLC_API_REQ_ID_DEFAULT, &plc_cfg); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if PLC_SUPPORT_STA_ROLE
 | ||
|  |     iot_plc_cfg_set_req_t plc_cfg = {0}; | ||
|  |     plc_cfg.reset = 1; | ||
|  |     plc_cfg.dev_type_valid = 1; | ||
|  |     plc_cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER; | ||
|  |     plc_cfg.addr_valid = 1; | ||
|  |     plc_cfg.addr_type = IOT_PLC_MAC_ADDR_TYPE_METER; | ||
|  |     iot_plc_set_cfg(p_iot_tput_glb->app_handle, IOT_PLC_API_REQ_ID_DEFAULT, &plc_cfg); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     goto out; | ||
|  | 
 | ||
|  | reg_err: | ||
|  | 
 | ||
|  | timer_err3: | ||
|  |     os_delete_timer(p_iot_tput_glb->tput_period_timer); | ||
|  |     p_iot_tput_glb->tput_period_timer = 0; | ||
|  | timer_err2: | ||
|  |     os_delete_timer(p_iot_tput_glb->tput_send_timer); | ||
|  |     p_iot_tput_glb->tput_send_timer = 0; | ||
|  | timer_err1: | ||
|  | 
 | ||
|  | app_err: | ||
|  | 
 | ||
|  | err_hdl: | ||
|  |     os_mem_free(p_iot_tput_glb); | ||
|  | out: | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t app_tput_entry() | ||
|  | { | ||
|  |     uint32_t ret = ERR_PENDING; | ||
|  |     iot_printf("[tput_dbg] %s\n", __FUNCTION__); | ||
|  |     if (iot_tput_task_init()) { | ||
|  |         ret = ERR_OK; | ||
|  |     } | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | /* test pkt */ | ||
|  | uint32_t iot_tput_send_pkt(uint8_t *src_addr, uint8_t *dst_addr, | ||
|  |     uint32_t msdu_len) | ||
|  | { | ||
|  |     iot_pkt_t*msdu_pkt; | ||
|  |     uint8_t* ptr; | ||
|  |     iot_printf("[tput_dbg] send_cnt:%d\n", ++p_iot_tput_glb->send_cnt); | ||
|  | 
 | ||
|  |     msdu_pkt = iot_plc_alloc_msdu(p_iot_tput_glb->app_handle, | ||
|  |                 IOT_PLC_MSG_TYPE_UNICAST, IOT_PLC_ACK_TYPE_NONE, \ | ||
|  |                 dst_addr, src_addr, \ | ||
|  |                 p_iot_tput_glb->tput_dev.link_id, | ||
|  |                 msdu_len, IOT_PLC_LOCAL_RETRY_CNT); | ||
|  |     ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL); | ||
|  | 
 | ||
|  |     os_mem_set(ptr, 0x55, msdu_len); | ||
|  | 
 | ||
|  |     os_mem_cpy(ptr, &p_iot_tput_glb->tput_cfg, sizeof(iot_tput_cfg_info_t)); | ||
|  | 
 | ||
|  |     iot_tput_send_info_t send_info = { 0 }; | ||
|  |     send_info.seq = p_iot_tput_glb->send_cnt; | ||
|  | 
 | ||
|  |     os_mem_cpy(ptr + sizeof(iot_tput_cfg_info_t), &send_info, \ | ||
|  |         sizeof(iot_tput_send_info_t)); | ||
|  | 
 | ||
|  |     iot_pkt_put(msdu_pkt, msdu_len); | ||
|  | 
 | ||
|  |     iot_plc_send_msdu(p_iot_tput_glb->app_handle, msdu_pkt); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* for sta request receive how many cnt */ | ||
|  | uint32_t iot_tput_sta_req() | ||
|  | { | ||
|  |     iot_pkt_t*msdu_pkt; | ||
|  |     uint8_t* ptr; | ||
|  |     uint32_t msdu_len = IOT_TPUT_LEN_72; | ||
|  |     msdu_pkt = iot_plc_alloc_msdu(p_iot_tput_glb->app_handle, | ||
|  |                 IOT_PLC_MSG_TYPE_BCAST_1HOP, IOT_PLC_ACK_TYPE_NONE, \ | ||
|  |                 p_iot_tput_glb->tput_dev.cco_addr, \ | ||
|  |                 p_iot_tput_glb->tput_dev.mac_addr, \ | ||
|  |                 p_iot_tput_glb->tput_dev.link_id, | ||
|  |                 msdu_len, IOT_PLC_LOCAL_RETRY_CNT); | ||
|  |     ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL); | ||
|  | 
 | ||
|  |     os_mem_set(ptr, 0x55, msdu_len); | ||
|  | 
 | ||
|  |     os_mem_cpy(ptr, &p_iot_tput_glb->tput_cfg, sizeof(iot_tput_cfg_info_t)); | ||
|  | 
 | ||
|  |     iot_tput_send_info_t send_info = { 0 }; | ||
|  |     send_info.seq = IOT_SEQ_INVAILD; | ||
|  |     send_info.statistics_cnt = p_iot_tput_glb->receive_cnt; | ||
|  | 
 | ||
|  |     os_mem_cpy(ptr + sizeof(iot_tput_cfg_info_t), &send_info, \ | ||
|  |         sizeof(iot_tput_send_info_t)); | ||
|  | 
 | ||
|  |     iot_pkt_put(msdu_pkt, msdu_len); | ||
|  | 
 | ||
|  |     iot_plc_send_msdu(p_iot_tput_glb->app_handle, msdu_pkt); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* cco report rate to cli */ | ||
|  | void iot_tput_report_rate_test(uint8_t *dst, uint8_t down_or_up_link, \ | ||
|  |     uint32_t rate_kpbs) | ||
|  | { | ||
|  |     iot_pkt_t           *buf_pkt = NULL; | ||
|  |     uint32_t rsp_len  = sizeof(iot_cli_tput_msg_header_t) +\ | ||
|  |         sizeof(iot_cli_tput_report_t); | ||
|  | 
 | ||
|  |     buf_pkt = iot_pkt_alloc(rsp_len, IOT_TPUT_MID); | ||
|  |     IOT_ASSERT(buf_pkt); | ||
|  | 
 | ||
|  |     iot_pkt_put(buf_pkt,rsp_len); | ||
|  | 
 | ||
|  |     uint8_t *tmp = iot_pkt_block_ptr(buf_pkt, IOT_PKT_BLOCK_HEAD); | ||
|  | 
 | ||
|  |     iot_cli_tput_msg_header_t *hd = (iot_cli_tput_msg_header_t *)tmp; | ||
|  |     hd->msg_id = IOT_CLI_TPUT_REQ; | ||
|  |     hd->req_id = 0; | ||
|  | 
 | ||
|  |     iot_cli_tput_report_t *result = (iot_cli_tput_report_t *)(tmp + \ | ||
|  |         sizeof(iot_cli_tput_msg_header_t)); | ||
|  |     result->test_id = 1;  //report tput value
 | ||
|  |     result->down_or_up_link = down_or_up_link; | ||
|  |     result->tput_valu = rate_kpbs; | ||
|  |     iot_mac_addr_cpy(result->dst, dst); | ||
|  |     iot_cli_tput_send_data_to_cli_interface(buf_pkt); | ||
|  |     return ; | ||
|  | } | ||
|  | #endif
 |