Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
udpsocket_echotest.cpp
00001 /* 00002 * Copyright (c) 2018, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "mbed.h" 00019 #include "UDPSocket.h" 00020 #include "greentea-client/test_env.h" 00021 #include "unity/unity.h" 00022 #include "utest.h" 00023 #include "udp_tests.h" 00024 00025 using namespace utest::v1; 00026 00027 namespace { 00028 static const int SIGNAL_SIGIO = 0x1; 00029 static const int SIGIO_TIMEOUT = 5000; //[ms] 00030 static const int WAIT2RECV_TIMEOUT = 1000; //[ms] 00031 static const int RETRIES = 2; 00032 00033 static const double EXPECTED_LOSS_RATIO = 0.0; 00034 static const double TOLERATED_LOSS_RATIO = 0.3; 00035 00036 UDPSocket sock; 00037 Semaphore tx_sem(0, 1); 00038 00039 static const int BUFF_SIZE = 1200; 00040 char rx_buffer[BUFF_SIZE] = {0}; 00041 char tx_buffer[BUFF_SIZE] = {0}; 00042 00043 static const int PKTS = 22; 00044 static const int pkt_sizes[PKTS] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, \ 00045 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, \ 00046 1100, 1200 00047 }; 00048 } 00049 00050 static void _sigio_handler(osThreadId id) 00051 { 00052 osSignalSet(id, SIGNAL_SIGIO); 00053 } 00054 00055 void UDPSOCKET_ECHOTEST() 00056 { 00057 SocketAddress udp_addr; 00058 get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); 00059 udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); 00060 00061 UDPSocket sock; 00062 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.open(get_interface())); 00063 00064 int recvd; 00065 int sent; 00066 int s_idx = 0; 00067 int packets_sent = 0; 00068 int packets_recv = 0; 00069 for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; pkt_s = ++s_idx) { 00070 pkt_s = pkt_sizes[s_idx]; 00071 00072 fill_tx_buffer_ascii(tx_buffer, BUFF_SIZE); 00073 00074 for (int retry_cnt = 0; retry_cnt <= 2; retry_cnt++) { 00075 memset(rx_buffer, 0, BUFF_SIZE); 00076 sent = sock.sendto(udp_addr, tx_buffer, pkt_s); 00077 if (sent > 0) { 00078 packets_sent++; 00079 } 00080 if (sent != pkt_s) { 00081 printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent); 00082 continue; 00083 } 00084 recvd = sock.recvfrom(NULL, rx_buffer, pkt_s); 00085 if (recvd == pkt_s) { 00086 break; 00087 } 00088 } 00089 if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) { 00090 packets_recv++; 00091 } 00092 } 00093 // Packet loss up to 30% tolerated 00094 if (packets_sent > 0) { 00095 double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent); 00096 printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", packets_sent, packets_recv, loss_ratio); 00097 TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio); 00098 } 00099 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.close()); 00100 } 00101 00102 void udpsocket_echotest_nonblock_receiver(void *receive_bytes) 00103 { 00104 int expt2recv = *(int *)receive_bytes; 00105 int recvd; 00106 for (int retry_cnt = 0; retry_cnt <= RETRIES; retry_cnt++) { 00107 recvd = sock.recvfrom(NULL, rx_buffer, expt2recv); 00108 if (recvd == NSAPI_ERROR_WOULD_BLOCK ) { 00109 wait_ms(WAIT2RECV_TIMEOUT); 00110 --retry_cnt; 00111 continue; 00112 } else if (recvd == expt2recv) { 00113 break; 00114 } 00115 } 00116 00117 drop_bad_packets(sock, -1); // timeout equivalent to set_blocking(false) 00118 00119 tx_sem.release(); 00120 } 00121 00122 void UDPSOCKET_ECHOTEST_NONBLOCK() 00123 { 00124 SocketAddress udp_addr; 00125 get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr); 00126 udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT); 00127 00128 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.open(get_interface())); 00129 sock.set_blocking(false); 00130 sock.sigio(callback(_sigio_handler, Thread::gettid())); 00131 00132 int sent; 00133 int s_idx = 0; 00134 int packets_sent = 0; 00135 int packets_recv = 0; 00136 Thread *thread; 00137 unsigned char *stack_mem = (unsigned char *)malloc(OS_STACK_SIZE); 00138 TEST_ASSERT_NOT_NULL(stack_mem); 00139 00140 for (int pkt_s = pkt_sizes[s_idx]; s_idx < PKTS; ++s_idx) { 00141 pkt_s = pkt_sizes[s_idx]; 00142 00143 thread = new Thread(osPriorityNormal, 00144 OS_STACK_SIZE, 00145 stack_mem, 00146 "receiver"); 00147 TEST_ASSERT_EQUAL(osOK, thread->start(callback(udpsocket_echotest_nonblock_receiver, &pkt_s))); 00148 00149 for (int retry_cnt = 0; retry_cnt <= RETRIES; retry_cnt++) { 00150 fill_tx_buffer_ascii(tx_buffer, pkt_s); 00151 00152 sent = sock.sendto(udp_addr, tx_buffer, pkt_s); 00153 if (sent > 0) { 00154 packets_sent++; 00155 } 00156 if (sent == NSAPI_ERROR_WOULD_BLOCK ) { 00157 if (osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) { 00158 continue; 00159 } 00160 --retry_cnt; 00161 } else if (sent != pkt_s) { 00162 printf("[Round#%02d - Sender] error, returned %d\n", s_idx, sent); 00163 continue; 00164 } 00165 if (tx_sem.wait(WAIT2RECV_TIMEOUT * 2) == 0) { // RX might wait up to WAIT2RECV_TIMEOUT before recvfrom 00166 continue; 00167 } 00168 break; 00169 } 00170 thread->join(); 00171 delete thread; 00172 if (memcmp(tx_buffer, rx_buffer, pkt_s) == 0) { 00173 packets_recv++; 00174 } 00175 } 00176 free(stack_mem); 00177 // Packet loss up to 30% tolerated 00178 if (packets_sent > 0) { 00179 double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent); 00180 printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", packets_sent, packets_recv, loss_ratio); 00181 TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio); 00182 } 00183 TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.close()); 00184 }
Generated on Tue Aug 9 2022 00:37:23 by
1.7.2