1278 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1278 lines
		
	
	
		
			37 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 "os_task_api.h"
 | ||
|  | #include "os_event_api.h"
 | ||
|  | #include "os_timer_api.h"
 | ||
|  | #include "os_utils_api.h"
 | ||
|  | #include "iot_task_api.h"
 | ||
|  | #include "iot_module_api.h"
 | ||
|  | #include "os_lock_api.h"
 | ||
|  | #include "iot_plc_cco_api.h"
 | ||
|  | #include "iot_plc_sta_api.h"
 | ||
|  | #include "iot_config_api.h"
 | ||
|  | #include "iot_app_api.h"
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "iot_io_api.h"
 | ||
|  | #include "iot_flash_api.h"
 | ||
|  | #include "iot_uart_api.h"
 | ||
|  | #include "iot_utils_api.h"
 | ||
|  | #include "iot_oem_api.h"
 | ||
|  | #include "iot_board_api.h"
 | ||
|  | #include "iot_gpio_api.h"
 | ||
|  | #include "iot_adc_api.h"
 | ||
|  | #include "demo.h"
 | ||
|  | #include "demo_speed_test.h"
 | ||
|  | 
 | ||
|  | /*
 | ||
|  | LIGHT WORDS: | ||
|  | 
 | ||
|  | 1 -> LIGHT ON , 0 -> LIGHT OFF. | ||
|  | 
 | ||
|  | A: PREPARE | ||
|  |     GR : | 01010101 | | ||
|  |     RD : | 01010101 | | ||
|  | 
 | ||
|  | B: IN TEST | ||
|  |     GR : | 01010101 | | ||
|  |     RD : | 10101010 | | ||
|  | 
 | ||
|  | C: REPORT THE SPEED | ||
|  | IF SPEED LEVEL IS 500Kbps (450Kbps ~ 550Kbps) : | ||
|  | UCAST : | ||
|  |          |   PRE    |    SPEED   | | ||
|  |     GR : | 00000000 | 0101010101 | | ||
|  |     RD : | 00111100 | 0000000000 | | ||
|  | BCAST : | ||
|  |          |   PRE    |    SPEED   | | ||
|  |     GR : | 00111100 | 0000000000 | | ||
|  |     RD : | 00000000 | 0101010101 | | ||
|  | 
 | ||
|  | */ | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_CCO_MAC    {0x48, 0x55, 0x5C, 0xAA, 0xBB, 0xCC}
 | ||
|  | #define APP_DEMO_SPD_STA_MAC    {0x48, 0x55, 0x5C, 0xCC, 0xDD, 0xEE}
 | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_TMR_INTVAL         500 /* 500ms */
 | ||
|  | #define APP_DEMO_SPD_TEST_BUFFER_LEN    1024
 | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_TIMEOUT_MAX        20 /* 10 seconds */
 | ||
|  | 
 | ||
|  | /* ucast && bcast */ | ||
|  | #define APP_DEMO_SPD_CAST_NUM   2
 | ||
|  | 
 | ||
|  | #if (IOT_DEMO_SUB_FUN == IOT_DEMO_SEL_SPEED_TEST)
 | ||
|  | 
 | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  | 
 | ||
|  | /***************** CONFIG AREA START *********************/ | ||
|  | /* [6/7/8] ms * [64/128/256/512/1024]Kbps */ | ||
|  | const uint32_t g_demo_spd_interval[] = {6, 7, 8}; | ||
|  | const uint32_t g_demo_spd_speed[] = {128, 256, 320, 448, 512, 640}; | ||
|  | #define APP_DEMO_SPD_TEST_PACKET_NUM      500
 | ||
|  | /***************** CONFIG AREA END *********************/ | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_INTVL_NUM      \
 | ||
|  |     (sizeof(g_demo_spd_interval)/sizeof(g_demo_spd_interval[0])) | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_SPEED_NUM      \
 | ||
|  |     (sizeof(g_demo_spd_speed)/sizeof(g_demo_spd_speed[0])) | ||
|  | 
 | ||
|  | typedef struct app_demo_spd_info_t | ||
|  | { | ||
|  |     uint16_t    speed; /* Kbps */ | ||
|  |     uint8_t     is_bcast; | ||
|  |     uint8_t     interval; /* ms */ | ||
|  |     uint16_t    pkt_size; /* bytes */ | ||
|  |     uint16_t    rcv_used_time; | ||
|  |     uint32_t    rcv_bytes; | ||
|  |     uint32_t    rcv_pkts; | ||
|  |     uint32_t    pkt_lost_rate; | ||
|  | }spd_info_t; | ||
|  | 
 | ||
|  | spd_info_t g_app_demo_spd_test_items[APP_DEMO_SPD_CAST_NUM][APP_DEMO_SPD_SPEED_NUM][APP_DEMO_SPD_INTVL_NUM]; | ||
|  | 
 | ||
|  | const uint8_t         app_demo_mac_local[] = APP_DEMO_SPD_CCO_MAC; | ||
|  | const uint8_t         app_demo_mac_remote[] = APP_DEMO_SPD_STA_MAC; | ||
|  | 
 | ||
|  | #else /* INCLUDE_APP_DEMO_SPD_SENDER */
 | ||
|  | uint32_t g_app_demo_spd_rcvd_bytes; | ||
|  | uint32_t g_app_demo_spd_rcvd_packets; | ||
|  | 
 | ||
|  | const uint8_t         app_demo_mac_local[] = APP_DEMO_SPD_STA_MAC; | ||
|  | const uint8_t         app_demo_mac_remote[] = APP_DEMO_SPD_CCO_MAC; | ||
|  | 
 | ||
|  | #endif /* INCLUDE_APP_DEMO_SPD_SENDER */
 | ||
|  | 
 | ||
|  | typedef struct iot_app_demo_spd_msg | ||
|  | { | ||
|  |     iot_task_msg_t  msg;        /* The main entity of message. */ | ||
|  |     void            *data;      /* The user data inside this message. */ | ||
|  | }demo_spd_msg_t; | ||
|  | 
 | ||
|  | uint8_t app_demo_spd_buf[APP_DEMO_SPD_TEST_BUFFER_LEN]; | ||
|  | 
 | ||
|  | #define APP_DEMO_RDY_REG        0x01
 | ||
|  | #define APP_DEMO_RDY_LOCAL      0x02
 | ||
|  | #define APP_DEMO_RDY_REMOTE     0x04
 | ||
|  | #define APP_DEMO_RDY_WL         0x08
 | ||
|  | 
 | ||
|  | #define APP_DEMO_RDY_RESTART    0x10
 | ||
|  | #define APP_DEMO_RDY_IDLE       0x20
 | ||
|  | #define APP_DEMO_RDY_TEST       0x40
 | ||
|  | #define APP_DEMO_RDY_S_REPORT   0x80 /* Wait or send single report. */
 | ||
|  | #define APP_DEMO_RDY_FINISH     0x100
 | ||
|  | 
 | ||
|  | iot_plc_app_h   app_demo_spd_app_handle; | ||
|  | iot_task_h      app_demo_spd_task_handle; | ||
|  | volatile uint32_t   app_demo_spd_ready; | ||
|  | uint32_t        app_demo_spd_current_key = 0x67676767; | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_READY()   \
 | ||
|  |     (((APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG)\ | ||
|  |     & app_demo_spd_ready) == \ | ||
|  |     (APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG) ? \ | ||
|  |     1 : 0) | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_RESTART()  \
 | ||
|  |     (((APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG|APP_DEMO_RDY_RESTART)\ | ||
|  |     & app_demo_spd_ready) == \ | ||
|  |     (APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG|APP_DEMO_RDY_RESTART) ? \ | ||
|  |     1 : 0) | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_CLEAR_STATUS() \
 | ||
|  |     (app_demo_spd_ready &= ~(APP_DEMO_RDY_RESTART | APP_DEMO_RDY_IDLE \ | ||
|  |         | APP_DEMO_RDY_TEST | APP_DEMO_RDY_S_REPORT | APP_DEMO_RDY_FINISH)) | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_HEADER_FLAG    0xEA5E94CD
 | ||
|  | 
 | ||
|  | uint32_t        app_demo_spd_led_red; | ||
|  | uint32_t        app_demo_spd_led_green; | ||
|  | 
 | ||
|  | timer_id_t      app_demo_spd_led_tmr; | ||
|  | timer_id_t      app_demo_spd_trcvd_tmr; | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_EVT_LED_TMR    0x01
 | ||
|  | #define APP_DEMO_SPD_EVT_TRSVD_TMR  0x02
 | ||
|  | 
 | ||
|  | 
 | ||
|  | enum app_demo_spd_header_type_e | ||
|  | { | ||
|  |     HDR_TYPE_TESTING = 0x5A5A, | ||
|  |     HDR_TYPE_S_REPORT= 0x7E7E, | ||
|  |     HDR_TYPE_F_REPORT= 0xD6D6, | ||
|  | }; | ||
|  | 
 | ||
|  | /* Sender -> Receiver */ | ||
|  | typedef struct app_demo_spd_test_header_t | ||
|  | { | ||
|  |     uint32_t    flag; | ||
|  |     uint16_t    type; | ||
|  | 
 | ||
|  |     uint16_t    time_left_ms; | ||
|  |     uint32_t    cur_key; | ||
|  |     uint32_t    index; | ||
|  | }spd_t_hr_t; | ||
|  | 
 | ||
|  | /* Receiver -> Sender */ | ||
|  | typedef struct app_demo_spd_single_report_header_t | ||
|  | { | ||
|  |     uint32_t    flag; | ||
|  |     uint16_t    type; | ||
|  | 
 | ||
|  |     uint16_t    time; | ||
|  |     uint32_t    cur_key; | ||
|  |     uint32_t    bytes; | ||
|  |     uint32_t    packets; | ||
|  | }spd_s_hr_t; | ||
|  | 
 | ||
|  | /* Sender -> Receiver */ | ||
|  | typedef struct app_demo_spd_final_report_header_t | ||
|  | { | ||
|  |     uint32_t    flag; | ||
|  |     uint16_t    type; | ||
|  | 
 | ||
|  |     uint16_t    bcast; | ||
|  |     uint16_t    intval; | ||
|  |     uint16_t    speed; /* Test speed for sender. */ | ||
|  |     uint16_t    pkt_size; | ||
|  |     uint16_t    final_speed; /* receive speed for receiver. We trust this speed. */ | ||
|  |     uint32_t    pkt_lost_rate; /* 8888 -> 88.88% */ | ||
|  | }spd_f_hr_t; | ||
|  | 
 | ||
|  | spd_f_hr_t app_demo_spd_winner[APP_DEMO_SPD_CAST_NUM]; | ||
|  | 
 | ||
|  | #define APP_DEMO_SPD_LW_STEPS_MAX      64
 | ||
|  | 
 | ||
|  | typedef struct app_demo_spd_light_words | ||
|  | { | ||
|  |     uint16_t steps; /* Steps to run out of a final report. */ | ||
|  |     uint16_t pos; /* current step */ | ||
|  |     uint32_t green[APP_DEMO_SPD_LW_STEPS_MAX/32]; /* BIT map for LED, 1 -> light on , 0 -> off */ | ||
|  |     uint32_t red[APP_DEMO_SPD_LW_STEPS_MAX/32]; /* BIT map for LED, 1 -> light on , 0 -> off */ | ||
|  | }light_wd_t; | ||
|  | 
 | ||
|  | light_wd_t g_app_demo_spd_lght_words; | ||
|  | 
 | ||
|  | inline static void app_demo_spd_print_iterm(spd_f_hr_t *p_iterm, uint32_t banner) | ||
|  | { | ||
|  |     if(banner) | ||
|  |     { | ||
|  |         iot_cus_printf( | ||
|  |             "\n SPEED(KbPS)  CAST  INTVAL(MS)  PKT-SIZE(B)  PKT-LOST  TRUE-SPEED(Kbps)"); | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_cus_printf( | ||
|  |         "\n %5d          %c   %6d      %8d      %2d.%02d%%   %10d", | ||
|  |         p_iterm->speed, | ||
|  |         p_iterm->bcast ? 'B' : 'U', | ||
|  |         p_iterm->intval, | ||
|  |         p_iterm->pkt_size, | ||
|  |         p_iterm->pkt_lost_rate/100, | ||
|  |         p_iterm->pkt_lost_rate%100, | ||
|  |         p_iterm->final_speed); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t app_demo_set_band(uint8_t band_id) | ||
|  | { | ||
|  | 
 | ||
|  |     iot_cus_printf("%s: set band to band %d\n", __FUNCTION__, band_id); | ||
|  | 
 | ||
|  |     iot_plc_set_freq_band(app_demo_spd_app_handle, | ||
|  |         IOT_PLC_API_REQ_ID_DEFAULT, band_id); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | /* set sta scan band */ | ||
|  | void app_demo_set_sta_scan_band(uint8_t band_id) | ||
|  | { | ||
|  |     iot_cus_printf("%s: set scan band to band %d\n", __FUNCTION__, band_id); | ||
|  |     uint8_t fb_bitmap[IOT_PLC_BAND_BITMAP_SIZE] = { 0 }; | ||
|  | 
 | ||
|  |     fb_bitmap[band_id / 8] |= 1 << (band_id % 8); | ||
|  | 
 | ||
|  |     iot_plc_set_scan_band_bitmap(app_demo_spd_app_handle, | ||
|  |         IOT_PLC_API_REQ_ID_DEFAULT, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE); | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_plc_send(uint8_t *p_buf, uint32_t size, uint32_t bcast) | ||
|  | { | ||
|  |     iot_pkt_t *msdu_pkt; | ||
|  |     uint8_t *ptr; | ||
|  | 
 | ||
|  |     if(bcast) | ||
|  |     { | ||
|  |         msdu_pkt = iot_plc_alloc_msdu(app_demo_spd_app_handle, | ||
|  |             IOT_PLC_MSG_TYPE_BCAST, IOT_PLC_ACK_TYPE_NONE, | ||
|  |             NULL, | ||
|  |             (uint8_t *)app_demo_mac_local, | ||
|  |             DEMO_APP_LINK_ID, size, 1); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         msdu_pkt = iot_plc_alloc_msdu(app_demo_spd_app_handle, | ||
|  |             IOT_PLC_MSG_TYPE_UNICAST, IOT_PLC_ACK_TYPE_NONE, | ||
|  |             (uint8_t *)app_demo_mac_remote, | ||
|  |             (uint8_t *)app_demo_mac_local, | ||
|  |             DEMO_APP_LINK_ID, size, 0); | ||
|  |     } | ||
|  | 
 | ||
|  |     if(NULL == msdu_pkt) | ||
|  |     { | ||
|  |         DEMO_ERROR("ALLOC PACKET FAILED !!", 1,2,3,4,5,6); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL); | ||
|  | 
 | ||
|  |     os_mem_cpy(ptr, p_buf, size); | ||
|  | 
 | ||
|  |     iot_pkt_put(msdu_pkt, size); | ||
|  | 
 | ||
|  |     /* Forword to PLC. */ | ||
|  |     iot_plc_send_msdu(app_demo_spd_app_handle, msdu_pkt); | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_make_light_words_data(void) | ||
|  | { | ||
|  |     uint32_t b_speed, u_speed, red, green, i, steps; | ||
|  | 
 | ||
|  |     u_speed = (((app_demo_spd_winner[0].final_speed % 100) > 50) | ||
|  |         ? ((app_demo_spd_winner[0].final_speed / 100) + 1) | ||
|  |         : (app_demo_spd_winner[0].final_speed / 100)); | ||
|  | 
 | ||
|  |     b_speed = (((app_demo_spd_winner[1].final_speed % 100) > 50) | ||
|  |         ? (app_demo_spd_winner[1].final_speed / 100 + 1) | ||
|  |         : (app_demo_spd_winner[1].final_speed / 100)); | ||
|  | 
 | ||
|  |     g_app_demo_spd_lght_words.steps = 8 + u_speed * 2 + 8 + b_speed * 2; | ||
|  | 
 | ||
|  |     /* UCAST */ | ||
|  |     green = 0x0; | ||
|  |     steps = 8; | ||
|  |     red = 0x3C; | ||
|  | 
 | ||
|  |     for(i = 0; i < u_speed; i++) | ||
|  |     { | ||
|  |         green <<= 2; | ||
|  |         red <<= 2; | ||
|  |         green |= 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     green <<= 1; | ||
|  |     red <<= 1; | ||
|  | 
 | ||
|  |     steps += u_speed * 2 + 1; | ||
|  | 
 | ||
|  |     g_app_demo_spd_lght_words.green[0] = green << (32 - steps); | ||
|  |     g_app_demo_spd_lght_words.red[0] = red << (32 - steps); | ||
|  |     g_app_demo_spd_lght_words.pos = steps; | ||
|  | 
 | ||
|  |     /* BCAST */ | ||
|  |     red = 0x0; | ||
|  |     steps = 7; | ||
|  |     green = 0x3C; | ||
|  | 
 | ||
|  |     for(i = 0; i < b_speed; i++) | ||
|  |     { | ||
|  |         red <<= 2; | ||
|  |         green <<= 2; | ||
|  |         red |= 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     green <<= 1; | ||
|  |     red <<= 1; | ||
|  | 
 | ||
|  |     steps += b_speed * 2 + 1; | ||
|  | 
 | ||
|  |     /* First 32bits left */ | ||
|  |     i = 32 - g_app_demo_spd_lght_words.pos; | ||
|  | 
 | ||
|  |     if(g_app_demo_spd_lght_words.steps > 32) | ||
|  |     { | ||
|  |         g_app_demo_spd_lght_words.green[0] |= (green >> (steps - i)); | ||
|  |         g_app_demo_spd_lght_words.red[0] |= (red >> (steps - i)); | ||
|  |         g_app_demo_spd_lght_words.green[1] = (green << (32 - (steps - i))); | ||
|  |         g_app_demo_spd_lght_words.red[1] = (red << (32 - (steps - i))); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         g_app_demo_spd_lght_words.green[0] |= (green << (i - steps)); | ||
|  |         g_app_demo_spd_lght_words.red[0] |= (red << (i - steps)); | ||
|  |     } | ||
|  | 
 | ||
|  |     /* Start from bit-0. */ | ||
|  |     g_app_demo_spd_lght_words.pos = 0; | ||
|  | 
 | ||
|  |     DEMO_INFO("LW BITMAP RED : #0x%08x%08x, GREEN #0x%08x%08x, STEPS #%d.", | ||
|  |         g_app_demo_spd_lght_words.red[0], | ||
|  |         g_app_demo_spd_lght_words.red[1], | ||
|  |         g_app_demo_spd_lght_words.green[0], | ||
|  |         g_app_demo_spd_lght_words.green[1], | ||
|  |         g_app_demo_spd_lght_words.steps, 6); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  | 
 | ||
|  | uint32_t g_app_demo_spd_remain_pkts; | ||
|  | spd_info_t *p_app_demo_spd_current_item; | ||
|  | 
 | ||
|  | void app_demo_spd_mac_data_process(iot_plc_msdu_recv_t *p_msdu) | ||
|  | { | ||
|  |     spd_s_hr_t *p_hdr = (spd_s_hr_t *)p_msdu->data; | ||
|  |     uint32_t cast_inx, iterm_inx; | ||
|  |     spd_info_t *p_iterm; | ||
|  |     spd_f_hr_t iterm_print; | ||
|  | 
 | ||
|  |     if((APP_DEMO_SPD_HEADER_FLAG != p_hdr->flag) | ||
|  |         || (HDR_TYPE_S_REPORT != p_hdr->type) | ||
|  |         || (app_demo_spd_current_key != p_hdr->cur_key) | ||
|  |         || (!(app_demo_spd_ready & APP_DEMO_RDY_S_REPORT))) | ||
|  |     { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     DEMO_INFO("Got report from remote, BYTES # %d, PKTS # %d, TIME # %d.", | ||
|  |         p_hdr->bytes, p_hdr->packets, p_hdr->time, 4, 5, 6); | ||
|  | 
 | ||
|  |     p_app_demo_spd_current_item->rcv_bytes = p_hdr->bytes; | ||
|  |     p_app_demo_spd_current_item->rcv_pkts = p_hdr->packets; | ||
|  |     p_app_demo_spd_current_item->rcv_used_time = p_hdr->time; | ||
|  | 
 | ||
|  |     os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  | 
 | ||
|  |     if(p_app_demo_spd_current_item == | ||
|  |         &g_app_demo_spd_test_items\ | ||
|  |         [APP_DEMO_SPD_CAST_NUM - 1][APP_DEMO_SPD_SPEED_NUM - 1][APP_DEMO_SPD_INTVL_NUM - 1]) | ||
|  |     { | ||
|  |         /* All items finished. */ | ||
|  |         iot_cus_printf("\n\nAll test cases:"); | ||
|  |         for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |         { | ||
|  |             p_iterm = &g_app_demo_spd_test_items[cast_inx][0][0]; | ||
|  |             app_demo_spd_winner[cast_inx].pkt_lost_rate = 10000; | ||
|  | 
 | ||
|  |             for(iterm_inx = 0; iterm_inx < APP_DEMO_SPD_SPEED_NUM*APP_DEMO_SPD_INTVL_NUM; iterm_inx++) | ||
|  |             { | ||
|  |                 p_iterm->pkt_lost_rate = 10000 - ((p_iterm->rcv_pkts * 100) / (APP_DEMO_SPD_TEST_PACKET_NUM / 100)); | ||
|  | 
 | ||
|  |                 iterm_print.bcast = p_iterm->is_bcast; | ||
|  |                 iterm_print.intval = p_iterm->interval; | ||
|  |                 iterm_print.speed = p_iterm->speed; | ||
|  |                 iterm_print.pkt_lost_rate = p_iterm->pkt_lost_rate; | ||
|  |                 iterm_print.pkt_size = p_iterm->pkt_size; | ||
|  | 
 | ||
|  |                 iterm_print.final_speed = (8 * p_iterm->rcv_bytes) / p_iterm->rcv_used_time; | ||
|  | 
 | ||
|  |                 /* OS ticks may not be precise. */ | ||
|  |                 iterm_print.final_speed = (iterm_print.final_speed > iterm_print.speed) | ||
|  |                     ? iterm_print.speed : iterm_print.final_speed; | ||
|  | 
 | ||
|  |                 if((app_demo_spd_winner[cast_inx].pkt_lost_rate >= iterm_print.pkt_lost_rate) | ||
|  |                     || (p_iterm->pkt_lost_rate <= 1000)) | ||
|  |                 { | ||
|  |                     os_mem_cpy(&app_demo_spd_winner[cast_inx], &iterm_print, sizeof(iterm_print)); | ||
|  |                 } | ||
|  | 
 | ||
|  |                 if((0 != cast_inx) || (0 != iterm_inx)) | ||
|  |                 { | ||
|  |                     app_demo_spd_print_iterm(&iterm_print, 0); | ||
|  |                 } | ||
|  |                 else | ||
|  |                 { | ||
|  |                     app_demo_spd_print_iterm(&iterm_print, 1); | ||
|  |                 } | ||
|  |                 p_iterm++; | ||
|  |             } | ||
|  |         } | ||
|  |         APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  | 
 | ||
|  |         app_demo_spd_make_light_words_data(); | ||
|  | 
 | ||
|  |         iot_cus_printf("\n\nThe best cases:"); | ||
|  |         for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |         { | ||
|  |             if(0 == cast_inx) | ||
|  |             { | ||
|  |                 app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 1); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 0); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         /* Start timer to send finally report */ | ||
|  |         os_start_timer(app_demo_spd_trcvd_tmr, 500); | ||
|  |         app_demo_spd_ready |= APP_DEMO_RDY_FINISH; | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         app_demo_spd_ready &= ~APP_DEMO_RDY_S_REPORT; | ||
|  |         p_app_demo_spd_current_item++; | ||
|  |         g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM; | ||
|  |         DEMO_INFO("Test %s : speed # %dkbps, psize # %dbytes...", | ||
|  |             p_app_demo_spd_current_item->is_bcast ? "bcast" : "ucast", | ||
|  |             p_app_demo_spd_current_item->speed, p_app_demo_spd_current_item->pkt_size, | ||
|  |             4, 5, 6); | ||
|  |         os_start_timer(app_demo_spd_trcvd_tmr, p_app_demo_spd_current_item->interval); | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_trcvd_tmr_process(void) | ||
|  | { | ||
|  |     static uint32_t static_cnt = APP_DEMO_SPD_TIMEOUT_MAX; | ||
|  |     spd_t_hr_t *p_hdr; | ||
|  |     spd_f_hr_t *p_finally_report; | ||
|  | 
 | ||
|  |     if(!APP_DEMO_SPD_READY()) | ||
|  |     { | ||
|  |         if(os_is_timer_active(app_demo_spd_trcvd_tmr)) | ||
|  |         { | ||
|  |             os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  |         } | ||
|  | 
 | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* Check if receiver reports the resoult. */ | ||
|  |     if(APP_DEMO_RDY_S_REPORT & app_demo_spd_ready) | ||
|  |     { | ||
|  |         /* If no report received, stop this testing. */ | ||
|  |         if(0 == static_cnt) | ||
|  |         { | ||
|  |             /* Regard this as receiver dropped. */ | ||
|  |             APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  |             app_demo_spd_ready |= (APP_DEMO_RDY_IDLE | APP_DEMO_RDY_RESTART); | ||
|  |             os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  |             DEMO_ERROR("WAIT THE REPORT TIMEOUT !!", 1, 2,3,4,5,6); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             static_cnt--; | ||
|  |         } | ||
|  |     } | ||
|  |     else if(APP_DEMO_RDY_FINISH & app_demo_spd_ready) | ||
|  |     { | ||
|  |         static_cnt++; | ||
|  | 
 | ||
|  |         static_cnt = (static_cnt >= APP_DEMO_SPD_CAST_NUM)? 0 : static_cnt; | ||
|  | 
 | ||
|  |         p_finally_report = (spd_f_hr_t *)app_demo_spd_buf; | ||
|  | 
 | ||
|  |         p_finally_report->flag = APP_DEMO_SPD_HEADER_FLAG; | ||
|  |         p_finally_report->type = HDR_TYPE_F_REPORT; | ||
|  | 
 | ||
|  |         p_finally_report->intval = app_demo_spd_winner[static_cnt].intval; | ||
|  |         p_finally_report->bcast = app_demo_spd_winner[static_cnt].bcast; | ||
|  |         p_finally_report->speed = app_demo_spd_winner[static_cnt].speed; | ||
|  |         p_finally_report->pkt_size = app_demo_spd_winner[static_cnt].pkt_size; | ||
|  |         p_finally_report->pkt_lost_rate = app_demo_spd_winner[static_cnt].pkt_lost_rate; | ||
|  |         p_finally_report->final_speed = app_demo_spd_winner[static_cnt].final_speed; | ||
|  | 
 | ||
|  |         app_demo_spd_plc_send(app_demo_spd_buf, sizeof(*p_finally_report), 0); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         static_cnt = APP_DEMO_SPD_TIMEOUT_MAX; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(g_app_demo_spd_remain_pkts > 0) | ||
|  |     { | ||
|  |         /* The last packet. */ | ||
|  |         if(1 == g_app_demo_spd_remain_pkts) | ||
|  |         { | ||
|  |             app_demo_spd_ready |= APP_DEMO_RDY_S_REPORT; | ||
|  |             os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  |             os_start_timer(app_demo_spd_trcvd_tmr, 500); | ||
|  |         } | ||
|  | 
 | ||
|  |         if(APP_DEMO_SPD_TEST_PACKET_NUM == g_app_demo_spd_remain_pkts) | ||
|  |         { | ||
|  |             p_hdr = (spd_t_hr_t *)app_demo_spd_buf; | ||
|  |             p_hdr->flag = APP_DEMO_SPD_HEADER_FLAG; | ||
|  |             p_hdr->type = HDR_TYPE_TESTING; | ||
|  | 
 | ||
|  |             p_hdr->cur_key = os_boot_time32(); | ||
|  |             app_demo_spd_current_key = p_hdr->cur_key; | ||
|  | 
 | ||
|  |             p_hdr->index = 0; | ||
|  | 
 | ||
|  |             p_hdr->time_left_ms = APP_DEMO_SPD_TEST_PACKET_NUM * p_app_demo_spd_current_item->interval; | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             p_hdr->index++; | ||
|  |             p_hdr->time_left_ms -= p_app_demo_spd_current_item->interval; | ||
|  |         } | ||
|  | 
 | ||
|  |         app_demo_spd_plc_send(app_demo_spd_buf, | ||
|  |             p_app_demo_spd_current_item->pkt_size, p_app_demo_spd_current_item->is_bcast); | ||
|  | 
 | ||
|  |         g_app_demo_spd_remain_pkts--; | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_restart(void) | ||
|  | { | ||
|  |     APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  | 
 | ||
|  |     app_demo_spd_ready |= APP_DEMO_RDY_TEST; | ||
|  | 
 | ||
|  |     p_app_demo_spd_current_item = (spd_info_t*)g_app_demo_spd_test_items; | ||
|  |     g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM; | ||
|  | 
 | ||
|  |     DEMO_INFO("Test %s : speed # %dkbps, psize # %dbytes...", | ||
|  |         p_app_demo_spd_current_item->is_bcast ? "bcast" : "ucast", | ||
|  |         p_app_demo_spd_current_item->speed, p_app_demo_spd_current_item->pkt_size, | ||
|  |         4, 5, 6); | ||
|  | 
 | ||
|  |     os_start_timer(app_demo_spd_trcvd_tmr, p_app_demo_spd_current_item->interval); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | #else
 | ||
|  | uint32_t g_app_demo_spd_test_time; | ||
|  | uint32_t g_app_demo_spd_end_test_time; | ||
|  | 
 | ||
|  | void app_demo_spd_mac_data_process(iot_plc_msdu_recv_t *p_msdu) | ||
|  | { | ||
|  |     spd_t_hr_t *p_hdr = (spd_t_hr_t *)p_msdu->data; | ||
|  |     spd_f_hr_t *p_f_hr; | ||
|  |     uint32_t cast_inx; | ||
|  | 
 | ||
|  |     if(APP_DEMO_SPD_HEADER_FLAG != p_hdr->flag) | ||
|  |     { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(HDR_TYPE_TESTING == p_hdr->type) | ||
|  |     { | ||
|  |         if((app_demo_spd_current_key == p_hdr->cur_key) | ||
|  |             && (!(APP_DEMO_RDY_S_REPORT & app_demo_spd_ready))) | ||
|  |         { | ||
|  |             g_app_demo_spd_rcvd_bytes += p_msdu->len; | ||
|  |             g_app_demo_spd_rcvd_packets++; | ||
|  |             g_app_demo_spd_end_test_time = os_boot_time32(); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             if(os_is_timer_active(app_demo_spd_trcvd_tmr)) | ||
|  |             { | ||
|  |                 os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  |             } | ||
|  | 
 | ||
|  |             APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  | 
 | ||
|  |             /* Clear all info since new test begains. */ | ||
|  |             for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |             { | ||
|  |                 app_demo_spd_winner[cast_inx].speed = 0; | ||
|  |             } | ||
|  | 
 | ||
|  |             app_demo_spd_ready |= APP_DEMO_RDY_TEST; | ||
|  | 
 | ||
|  |             g_app_demo_spd_rcvd_bytes = p_msdu->len; | ||
|  |             g_app_demo_spd_rcvd_packets = 1; | ||
|  |             app_demo_spd_current_key = p_hdr->cur_key; | ||
|  | 
 | ||
|  |             g_app_demo_spd_test_time = (p_hdr->time_left_ms > 20000) | ||
|  |                 ? 20000 : p_hdr->time_left_ms; | ||
|  | 
 | ||
|  |             os_start_timer(app_demo_spd_trcvd_tmr, g_app_demo_spd_test_time * 2); | ||
|  | 
 | ||
|  |             g_app_demo_spd_test_time = os_boot_time32(); | ||
|  | 
 | ||
|  |             DEMO_INFO("NEW TEST KEY # %d.", app_demo_spd_current_key,2,3,4,5,6); | ||
|  |         } | ||
|  |     } | ||
|  |     else if((HDR_TYPE_F_REPORT == p_hdr->type) | ||
|  |         && (!(app_demo_spd_ready & APP_DEMO_RDY_FINISH))) | ||
|  |     { | ||
|  |         p_f_hr = (spd_f_hr_t *)p_msdu->data; | ||
|  | 
 | ||
|  |         app_demo_spd_winner[p_f_hr->bcast ? 1 : 0] = *p_f_hr; | ||
|  | 
 | ||
|  |         for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |         { | ||
|  |             if(0 == app_demo_spd_winner[cast_inx].speed) | ||
|  |             { | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         if(APP_DEMO_SPD_CAST_NUM == cast_inx) | ||
|  |         { | ||
|  |             os_stop_timer(app_demo_spd_trcvd_tmr); | ||
|  | 
 | ||
|  |             APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  | 
 | ||
|  |             app_demo_spd_ready |= APP_DEMO_RDY_FINISH; | ||
|  | 
 | ||
|  |             app_demo_spd_make_light_words_data(); | ||
|  | 
 | ||
|  |             iot_cus_printf("\n\nThe best cases:"); | ||
|  |             for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |             { | ||
|  |                 if(0 == cast_inx) | ||
|  |                 { | ||
|  |                     app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 1); | ||
|  |                 } | ||
|  |                 else | ||
|  |                 { | ||
|  |                     app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 0); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_trcvd_tmr_process(void) | ||
|  | { | ||
|  |     spd_s_hr_t *p_rpt = (spd_s_hr_t *)app_demo_spd_buf; | ||
|  |     uint32_t cost_time; | ||
|  | 
 | ||
|  |     APP_DEMO_SPD_CLEAR_STATUS(); | ||
|  | 
 | ||
|  |     app_demo_spd_ready |= APP_DEMO_RDY_S_REPORT; | ||
|  | 
 | ||
|  |     cost_time = (g_app_demo_spd_test_time < g_app_demo_spd_end_test_time) | ||
|  |         ?(g_app_demo_spd_end_test_time - g_app_demo_spd_test_time) | ||
|  |         :(0xFFFFFFFF - g_app_demo_spd_test_time + g_app_demo_spd_end_test_time); | ||
|  | 
 | ||
|  |     p_rpt->bytes = g_app_demo_spd_rcvd_bytes; | ||
|  |     p_rpt->cur_key = app_demo_spd_current_key; | ||
|  |     p_rpt->flag = APP_DEMO_SPD_HEADER_FLAG; | ||
|  |     p_rpt->packets = g_app_demo_spd_rcvd_packets; | ||
|  |     p_rpt->time = cost_time; | ||
|  |     p_rpt->type = HDR_TYPE_S_REPORT; | ||
|  | 
 | ||
|  |     DEMO_INFO("REPORT KEY # %d, TIME # %d, PKT # %d.", | ||
|  |         app_demo_spd_current_key, | ||
|  |         cost_time, | ||
|  |         g_app_demo_spd_rcvd_packets, | ||
|  |         4,5,6); | ||
|  | 
 | ||
|  |     app_demo_spd_plc_send(app_demo_spd_buf, sizeof(*p_rpt), 0); | ||
|  | 
 | ||
|  |     os_start_timer(app_demo_spd_trcvd_tmr, 1000); | ||
|  | } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | uint32_t app_demo_spd_post_msg( uint16_t msg_type, uint16_t msg_id, void *data) | ||
|  | { | ||
|  |     iot_task_msg_t          *msg; | ||
|  |     demo_spd_msg_t     *task_msg; | ||
|  | 
 | ||
|  |     msg = iot_task_alloc_msg_with_reserved(app_demo_spd_task_handle, 0); | ||
|  | 
 | ||
|  |     if (NULL == msg) { | ||
|  |         DEMO_ERROR("ALLOC MSG-BUFFER FAILED !!", 1, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     task_msg = (demo_spd_msg_t*)msg; | ||
|  | 
 | ||
|  |     task_msg->msg.type = msg_type; | ||
|  |     task_msg->msg.id = msg_id; | ||
|  |     task_msg->data = data; | ||
|  | 
 | ||
|  |     iot_task_queue_msg(app_demo_spd_task_handle, | ||
|  |                        &task_msg->msg, DEMO_TASK_MSG_PRIO); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_mac_status_process(iot_pkt_t *pkt) | ||
|  | { | ||
|  |     iot_plc_msg_header_t *hdr = | ||
|  |         (iot_plc_msg_header_t*)iot_pkt_data(pkt); | ||
|  | 
 | ||
|  |     /* Check if this packet belongs to me. */ | ||
|  |     if ((IOT_PLC_APP_ID_BCAST != hdr->app_id) && | ||
|  |             (IOT_PLC_APP_DEMO_ID != hdr->app_id)) | ||
|  |     { | ||
|  |         DEMO_ERROR("INVALID PACKET FROM MAC, APP ID#%d.", hdr->app_id,2,3,4,5,6); | ||
|  |         iot_pkt_free(pkt); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* Check if I'm registerd before handling msg. */ | ||
|  |     if ((!(app_demo_spd_ready & APP_DEMO_RDY_REG)) && | ||
|  |         (IOT_PLC_MSG_APP_REG_CONF != hdr->msg_id)) | ||
|  |     { | ||
|  |         DEMO_ERROR("INVALID PACKET FROM MAC, MSG ID#%d, STATUS#0x%08X.", | ||
|  |             hdr->msg_id, app_demo_spd_ready,3,4,5,6); | ||
|  |         iot_pkt_free(pkt); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     switch (hdr->msg_id) | ||
|  |     { | ||
|  |         case IOT_PLC_MSG_APP_REG_CONF : | ||
|  |         { | ||
|  |             iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1); | ||
|  |             iot_plc_cfg_set_req_t cfg; | ||
|  | 
 | ||
|  |             if ((IOT_PLC_SUCCESS == rpt->result) || | ||
|  |                 (IOT_PLC_SUCCESS_MODIFIED == rpt->result)) { | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_REG; | ||
|  |                 DEMO_INFO("APP REGISTERED SUCCESSFULLY.",1,2,3,4,5,6); | ||
|  | 
 | ||
|  |                 os_mem_set(&cfg, 0, sizeof(cfg)); | ||
|  |                 cfg.addr_valid = 1; | ||
|  |                 cfg.addr_type = IOT_PLC_MAC_ADDR_TYPE_METER; | ||
|  |                 iot_mac_addr_cpy(cfg.addr, (uint8_t *)app_demo_mac_local); | ||
|  |                 cfg.dev_type_valid = 1; | ||
|  | 
 | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  |                 cfg.dev_type = IOT_PLC_DEV_TYPE_CONCENTRATOR; | ||
|  | #else
 | ||
|  |                 cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER; | ||
|  | #endif
 | ||
|  |                 cfg.reset = 1; | ||
|  | 
 | ||
|  |                 DEMO_INFO("SET LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                     app_demo_mac_local[0], app_demo_mac_local[1], | ||
|  |                     app_demo_mac_local[2], app_demo_mac_local[3], | ||
|  |                     app_demo_mac_local[4], app_demo_mac_local[5]); | ||
|  | 
 | ||
|  |                 iot_plc_set_cfg | ||
|  |                     (app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT, &cfg); | ||
|  | 
 | ||
|  |                 iot_plc_set_whitelist | ||
|  |                     (app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT, | ||
|  |                     IOT_PLC_WL_ENABLE, 0, NULL); | ||
|  |             } | ||
|  | 
 | ||
|  |             break; | ||
|  |         } | ||
|  |         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) | ||
|  |             { | ||
|  |                 DEMO_INFO("STATE CHANGE REPORT MAC GET READY, MY ROLE TYPE#%d.", | ||
|  |                     rpt->dev_role,2,3,4,5,6); | ||
|  | 
 | ||
|  |                 DEMO_INFO("CCO MAC   : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                     rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], | ||
|  |                     rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); | ||
|  | 
 | ||
|  |                 DEMO_INFO("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]); | ||
|  | 
 | ||
|  |                 if((IOT_PLC_DEV_ROLE_STA == rpt->dev_role) | ||
|  |                     && (!os_mem_cmp(app_demo_mac_remote, rpt->cco_mac, sizeof(app_demo_mac_remote)))) | ||
|  |                 { | ||
|  |                     app_demo_spd_ready |= APP_DEMO_RDY_REMOTE; | ||
|  |                 } | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_LOCAL; | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6); | ||
|  |                 app_demo_spd_ready &= (~APP_DEMO_RDY_LOCAL); | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_RESTART; | ||
|  |             } | ||
|  |             break; | ||
|  |         } | ||
|  |         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) | ||
|  |             { | ||
|  |                 DEMO_INFO("DEVICE INFO REPORT MAC GET READY, MY ROLE TYPE#%d.", | ||
|  |                     rpt->dev_role,2,3,4,5,6); | ||
|  | 
 | ||
|  |                 DEMO_INFO("CCO MAC   : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                     rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2], | ||
|  |                     rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]); | ||
|  | 
 | ||
|  |                 DEMO_INFO("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]); | ||
|  | 
 | ||
|  |                 if((IOT_PLC_DEV_ROLE_STA == rpt->dev_role) | ||
|  |                     && iot_mac_addr_cmp(app_demo_mac_remote, rpt->cco_mac)) | ||
|  |                 { | ||
|  |                     app_demo_spd_ready |= APP_DEMO_RDY_REMOTE; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_LOCAL; | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6); | ||
|  |                 app_demo_spd_ready &= (~APP_DEMO_RDY_LOCAL); | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_RESTART; | ||
|  |             } | ||
|  |             break; | ||
|  |         } | ||
|  |         case IOT_PLC_MSG_STA_JOIN_INFO : | ||
|  |         { | ||
|  |             iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1); | ||
|  |             DEMO_INFO("STA JOINED : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                 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_mac_addr_cmp(app_demo_mac_remote, rpt->sta_info.addr)) | ||
|  |             { | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_REMOTE; | ||
|  |             } | ||
|  | 
 | ||
|  |             break; | ||
|  |         } | ||
|  |         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++) | ||
|  |             { | ||
|  |                 DEMO_INFO("STA LEAVED : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                    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_mac_addr_cmp(app_demo_mac_remote, rpt->sta[cnt].mac_addr)) | ||
|  |                    { | ||
|  |                        app_demo_spd_ready &= ~APP_DEMO_RDY_REMOTE; | ||
|  |                        app_demo_spd_ready |= APP_DEMO_RDY_RESTART; | ||
|  |                    } | ||
|  |             } | ||
|  | 
 | ||
|  |             break; | ||
|  |         } | ||
|  |         case IOT_PLC_MSG_NW_WL_SET_RPT: | ||
|  |         { | ||
|  |             if(!(APP_DEMO_RDY_WL & app_demo_spd_ready)) | ||
|  |             { | ||
|  |                 iot_plc_set_whitelist | ||
|  |                     (app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT, | ||
|  |                     IOT_PLC_WL_ADD, 1, (uint8_t *)app_demo_mac_remote); | ||
|  | 
 | ||
|  |                 DEMO_INFO("SET WHITELIST : %02x-%02x-%02x-%02x-%02x-%02x.", | ||
|  |                     app_demo_mac_remote[0], app_demo_mac_remote[1], | ||
|  |                     app_demo_mac_remote[2], app_demo_mac_remote[3], | ||
|  |                     app_demo_mac_remote[4], app_demo_mac_remote[5]); | ||
|  | 
 | ||
|  |                 app_demo_spd_ready |= APP_DEMO_RDY_WL; | ||
|  |             } | ||
|  |         } | ||
|  |         case IOT_PLC_MSG_MSDU_RECV: | ||
|  |         { | ||
|  |             iot_plc_msdu_recv_t *p_msdu = (iot_plc_msdu_recv_t*) | ||
|  |                 (iot_pkt_data(pkt) + sizeof(iot_plc_msg_header_t)); | ||
|  | 
 | ||
|  |             if(APP_DEMO_SPD_READY()) | ||
|  |             { | ||
|  |                 app_demo_spd_mac_data_process(p_msdu); | ||
|  |             } | ||
|  |         } | ||
|  |         default : | ||
|  |         { | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     if(pkt) | ||
|  |     { | ||
|  |         iot_pkt_free(pkt); | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_plc_rcv(void *param, iot_pkt_t *p_pkt) | ||
|  | { | ||
|  |     (void)param; | ||
|  | 
 | ||
|  |     app_demo_spd_post_msg(E_DEMO_MSG_FROM_MAC, 0, (void*)p_pkt); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | /* Register an APP to PLC-layer,so we can transmit/receive packet from it. */ | ||
|  | uint32_t app_demo_spd_app_reg(void) | ||
|  | { | ||
|  |     iot_plc_app_t app; | ||
|  | 
 | ||
|  |     app.app_id  = IOT_PLC_APP_DEMO_ID; | ||
|  |     app.param   = NULL; | ||
|  |     app.prio    = DEMO_PLC_CMD_PRIO; | ||
|  |     app.recv    = app_demo_spd_plc_rcv; | ||
|  | 
 | ||
|  |     app_demo_spd_app_handle = iot_plc_register_app(&app); | ||
|  | 
 | ||
|  |     if(NULL == app_demo_spd_app_handle) | ||
|  |     { | ||
|  |         DEMO_ERROR("REGISTER APP FAILED !!", 1, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_light_status_idle(void) | ||
|  | { | ||
|  |     static uint32_t status = 0; | ||
|  | 
 | ||
|  |     iot_gpio_value_set(app_demo_spd_led_green, status); | ||
|  |     iot_gpio_value_set(app_demo_spd_led_red, status); | ||
|  | 
 | ||
|  |     status = status ? 0 : 1; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_light_status_test(void) | ||
|  | { | ||
|  |     static uint32_t status = 0; | ||
|  | 
 | ||
|  |     if(status) | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_green, 0); | ||
|  |         iot_gpio_value_set(app_demo_spd_led_red, 1); | ||
|  | 
 | ||
|  |         status = 0; | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_green, 1); | ||
|  |         iot_gpio_value_set(app_demo_spd_led_red, 0); | ||
|  | 
 | ||
|  |         status = 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_light_status_report(void) | ||
|  | { | ||
|  |     uint32_t green, red, mask; | ||
|  | 
 | ||
|  |     if(g_app_demo_spd_lght_words.pos >= g_app_demo_spd_lght_words.steps) | ||
|  |     { | ||
|  |         g_app_demo_spd_lght_words.pos = 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(g_app_demo_spd_lght_words.pos > 31) | ||
|  |     { | ||
|  |         mask = 1 << ( 63 - g_app_demo_spd_lght_words.pos); | ||
|  |         green = g_app_demo_spd_lght_words.green[1]; | ||
|  |         red = g_app_demo_spd_lght_words.red[1]; | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         mask = 1 << ( 31 - g_app_demo_spd_lght_words.pos); | ||
|  |         green = g_app_demo_spd_lght_words.green[0]; | ||
|  |         red = g_app_demo_spd_lght_words.red[0]; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(mask & green) | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_green, 0); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_green, 1); | ||
|  |     } | ||
|  | 
 | ||
|  |     if(mask & red) | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_red, 0); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         iot_gpio_value_set(app_demo_spd_led_red, 1); | ||
|  |     } | ||
|  | 
 | ||
|  |     g_app_demo_spd_lght_words.pos++; | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_led_tmr_process(void) | ||
|  | { | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  |     if(APP_DEMO_SPD_RESTART()) | ||
|  |     { | ||
|  |         app_demo_spd_restart(); | ||
|  |     } | ||
|  | #endif
 | ||
|  |     if((APP_DEMO_RDY_TEST | APP_DEMO_RDY_S_REPORT) & app_demo_spd_ready) | ||
|  |     { | ||
|  |         app_demo_spd_light_status_test(); | ||
|  |     } | ||
|  |     else if(APP_DEMO_RDY_FINISH & app_demo_spd_ready) | ||
|  |     { | ||
|  |         app_demo_spd_light_status_report(); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         app_demo_spd_light_status_idle(); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_task_event_handle(iot_task_h task_h, uint32_t event) | ||
|  | { | ||
|  |     (void)task_h; | ||
|  | 
 | ||
|  |     if(APP_DEMO_SPD_EVT_TRSVD_TMR == event) | ||
|  |     { | ||
|  |         app_demo_spd_trcvd_tmr_process(); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         app_demo_spd_led_tmr_process(); | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_tmr_handle(timer_id_t tid, void *data) | ||
|  | { | ||
|  |     (void)tid; | ||
|  | 
 | ||
|  |     os_set_task_event_with_v | ||
|  |         (iot_task_get_os_task_h(app_demo_spd_task_handle), (uint32_t)data); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_task_msg_handle(iot_task_h task_h, iot_task_msg_t *msg) | ||
|  | { | ||
|  |     demo_spd_msg_t *dm_msg = (demo_spd_msg_t *)msg; | ||
|  | 
 | ||
|  |     (void)task_h; | ||
|  | 
 | ||
|  |     if((NULL == dm_msg) | ||
|  |         ||(!DEMO_MSG_VALID(dm_msg->msg.type))) | ||
|  |     { | ||
|  |         /* Maybe this can cause memory overflow! */ | ||
|  |         DEMO_ERROR("HANDLE AN INVALID MSG !!", 1,2,3,4,5,6); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(E_DEMO_MSG_FROM_MAC == dm_msg->msg.type) | ||
|  |     { | ||
|  |         app_demo_spd_mac_status_process((iot_pkt_t *)dm_msg->data); | ||
|  |     } | ||
|  | 
 | ||
|  |     iot_task_free_msg(task_h, &(dm_msg->msg)); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void app_demo_spd_task_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg) | ||
|  | { | ||
|  |     (void)task_h; | ||
|  |     (void)msg; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t app_demo_spd_module_init(void) | ||
|  | { | ||
|  |     iot_task_config_t t_cfg; | ||
|  | 
 | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  |     uint32_t intval_inx, speed_inx, cast_inx; | ||
|  |     spd_info_t *p_spd_info; | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     t_cfg.stack_size       = 0; | ||
|  |     t_cfg.task_prio        = DEMO_MSG_HANDLE_TASK_PRIO; | ||
|  |     t_cfg.msg_size         = sizeof(demo_spd_msg_t); | ||
|  |     t_cfg.msg_cnt          = DEMO_MSG_PENDING_LIMIT; | ||
|  |     t_cfg.queue_cnt        = DEMO_MSG_TASK_PRIO_QUE; | ||
|  |     t_cfg.queue_cfg[0].quota = 0; | ||
|  |     t_cfg.task_event_func  = app_demo_spd_task_event_handle; | ||
|  |     t_cfg.msg_exe_func     = app_demo_spd_task_msg_handle; | ||
|  |     t_cfg.msg_cancel_func  = app_demo_spd_task_msg_cancel; | ||
|  | 
 | ||
|  |     app_demo_spd_task_handle    = iot_task_create(IOT_APP_DEMO_MID, &t_cfg); | ||
|  | 
 | ||
|  |     if(NULL == app_demo_spd_task_handle) | ||
|  |     { | ||
|  |         DEMO_ERROR("iot_task_create RETURNS NULL !!", 1,2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  | #if INCLUDE_APP_DEMO_SPD_SENDER
 | ||
|  | 
 | ||
|  |     os_mem_set(g_app_demo_spd_test_items, 0x0, sizeof(g_app_demo_spd_test_items)); | ||
|  |     for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++) | ||
|  |     { | ||
|  |         for(speed_inx = 0; speed_inx < APP_DEMO_SPD_SPEED_NUM; speed_inx++) | ||
|  |         { | ||
|  |             for(intval_inx = 0; intval_inx < APP_DEMO_SPD_INTVL_NUM; intval_inx++) | ||
|  |             { | ||
|  |                 p_spd_info = &g_app_demo_spd_test_items[cast_inx][speed_inx][intval_inx]; | ||
|  |                 p_spd_info->is_bcast = cast_inx ? 1 : 0; | ||
|  |                 p_spd_info->speed = g_demo_spd_speed[speed_inx]; | ||
|  |                 p_spd_info->interval = g_demo_spd_interval[intval_inx]; | ||
|  | 
 | ||
|  |                 p_spd_info->pkt_size = (p_spd_info->speed * p_spd_info->interval) / 8; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM; | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     app_demo_spd_ready = APP_DEMO_RDY_RESTART | APP_DEMO_RDY_IDLE; | ||
|  | 
 | ||
|  |     app_demo_spd_led_red = iot_board_get_gpio(GPIO_TX_LED); | ||
|  |     app_demo_spd_led_green = iot_board_get_gpio(GPIO_RX_LED); | ||
|  | 
 | ||
|  |     if((ERR_OK != iot_gpio_open_as_output(app_demo_spd_led_red)) | ||
|  |         ||(ERR_OK != iot_gpio_set_pull_mode(app_demo_spd_led_red, GPIO_PULL_UP))) | ||
|  |     { | ||
|  |         DEMO_ERROR("OPEN GPIO#%d FAILED !!", app_demo_spd_led_red, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if((ERR_OK != iot_gpio_open_as_output(app_demo_spd_led_green)) | ||
|  |         ||(ERR_OK != iot_gpio_set_pull_mode(app_demo_spd_led_green, GPIO_PULL_UP))) | ||
|  |     { | ||
|  |         DEMO_ERROR("OPEN GPIO#%d FAILED !!", app_demo_spd_led_green, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if((timer_id_t)NULL == (app_demo_spd_led_tmr = os_create_timer | ||
|  |             (IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_spd_tmr_handle, | ||
|  |             (void *)APP_DEMO_SPD_EVT_LED_TMR))) | ||
|  |     { | ||
|  |         DEMO_ERROR("CREATE LED TMR FAILED !!", 1, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if((timer_id_t)NULL == (app_demo_spd_trcvd_tmr = os_create_timer | ||
|  |             (IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_spd_tmr_handle, | ||
|  |             (void *)APP_DEMO_SPD_EVT_TRSVD_TMR))) | ||
|  |     { | ||
|  |         DEMO_ERROR("CREATE TRANSEICE TMR FAILED !!", 1, 2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if(ERR_OK != app_demo_spd_app_reg()) | ||
|  |     { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (iot_plc_is_client_mode()) { | ||
|  |         /* default set sta only scan band 1, freq: 2.4M to 5.6M */ | ||
|  |         app_demo_set_sta_scan_band(PLC_LIB_FREQ_BAND_1); | ||
|  | 
 | ||
|  |         /* close watchdog */ | ||
|  |         iot_plc_wdg_set(app_demo_spd_app_handle, 0, 0); | ||
|  |     } | ||
|  | 
 | ||
|  |     DEMO_INFO("    SET BAND ID...", 1,2,3,4,5,6); | ||
|  |     if(ERR_OK != app_demo_set_band(PLC_LIB_FREQ_BAND_1)) | ||
|  |     { | ||
|  |         DEMO_ERROR("SET BAND ID FAILED !!", 1,2,3,4,5,6); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     app_demo_spd_ready |= APP_DEMO_RDY_IDLE; | ||
|  | 
 | ||
|  |     os_start_timer(app_demo_spd_led_tmr, APP_DEMO_SPD_TMR_INTVAL); | ||
|  | 
 | ||
|  |     DEMO_INFO("SPEED TEST INIT DONE.",1,2,3,4,5,6); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | 
 | ||
|  | } | ||
|  | #endif
 |