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.
main.cpp
00001 #ifndef MBED_EXTENDED_TESTS 00002 #error [NOT_SUPPORTED] Parallel tests are not supported by default 00003 #endif 00004 00005 #include "mbed.h" 00006 #include "ESP8266Interface.h" 00007 #include "UDPSocket.h" 00008 #include "greentea-client/test_env.h" 00009 #include "unity/unity.h" 00010 #include "utest.h" 00011 00012 using namespace utest::v1; 00013 00014 00015 #ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 00016 #define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64 00017 #endif 00018 00019 #ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 00020 #define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500 00021 #endif 00022 00023 #ifndef MBED_CFG_UDP_CLIENT_ECHO_THREADS 00024 #define MBED_CFG_UDP_CLIENT_ECHO_THREADS 3 00025 #endif 00026 00027 #ifndef MBED_CFG_ESP8266_TX 00028 #define MBED_CFG_ESP8266_TX D1 00029 #endif 00030 00031 #ifndef MBED_CFG_ESP8266_RX 00032 #define MBED_CFG_ESP8266_RX D0 00033 #endif 00034 00035 #ifndef MBED_CFG_ESP8266_DEBUG 00036 #define MBED_CFG_ESP8266_DEBUG false 00037 #endif 00038 00039 #define STRINGIZE(x) STRINGIZE2(x) 00040 #define STRINGIZE2(x) #x 00041 00042 00043 const int ECHO_LOOPS = 16; 00044 ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG); 00045 SocketAddress udp_addr; 00046 Mutex iomutex; 00047 char uuid[48] = {0}; 00048 00049 // NOTE: assuming that "id" stays in the single digits 00050 void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size) { 00051 size_t i = 0; 00052 00053 tx_buffer[i++] = '0' + id; 00054 tx_buffer[i++] = ' '; 00055 00056 memcpy(tx_buffer+i, uuid, strlen(uuid)); 00057 i += strlen(uuid); 00058 00059 tx_buffer[i++] = ' '; 00060 00061 for (; i<tx_size; ++i) { 00062 tx_buffer[i] = (rand() % 10) + '0'; 00063 } 00064 } 00065 00066 00067 // Each echo class is in charge of one parallel transaction 00068 class Echo { 00069 private: 00070 char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE]; 00071 char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE]; 00072 00073 UDPSocket sock; 00074 Thread thread; 00075 bool result; 00076 int id; 00077 char *uuid; 00078 00079 public: 00080 // Limiting stack size to 1k 00081 Echo(): thread(osPriorityNormal, 1024), result(false) { 00082 } 00083 00084 void start(int id, char *uuid) { 00085 this->id = id; 00086 this->uuid = uuid; 00087 osStatus status = thread.start(callback(this, &Echo::echo)); 00088 } 00089 00090 void join() { 00091 osStatus status = thread.join(); 00092 TEST_ASSERT_EQUAL(osOK, status); 00093 } 00094 00095 void echo() { 00096 int success = 0; 00097 00098 int err = sock.open(&net); 00099 TEST_ASSERT_EQUAL(0, err); 00100 00101 sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT); 00102 00103 for (int i = 0; success < ECHO_LOOPS; i++) { 00104 prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer)); 00105 const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); 00106 if (ret >= 0) { 00107 iomutex.lock(); 00108 printf("[ID:%01d][%02d] sent %d bytes - %.*s \n", id, i, ret, ret, tx_buffer); 00109 iomutex.unlock(); 00110 } else { 00111 iomutex.lock(); 00112 printf("[ID:%01d][%02d] Network error %d\n", id, i, ret); 00113 iomutex.unlock(); 00114 continue; 00115 } 00116 00117 SocketAddress temp_addr; 00118 const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer)); 00119 if (n >= 0) { 00120 iomutex.lock(); 00121 printf("[ID:%01d][%02d] recv %d bytes - %.*s \n", id, i, n, n, tx_buffer); 00122 iomutex.unlock(); 00123 } else { 00124 iomutex.lock(); 00125 printf("[ID:%01d][%02d] Network error %d\n", id, i, n); 00126 iomutex.unlock(); 00127 continue; 00128 } 00129 00130 if ((temp_addr == udp_addr && 00131 n == sizeof(tx_buffer) && 00132 memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) { 00133 success += 1; 00134 iomutex.lock(); 00135 printf("[ID:%01d][%02d] success #%d\n", id, i, success); 00136 iomutex.unlock(); 00137 continue; 00138 } 00139 00140 // failed, clean out any remaining bad packets 00141 sock.set_timeout(0); 00142 while (true) { 00143 err = sock.recvfrom(NULL, NULL, 0); 00144 if (err == NSAPI_ERROR_WOULD_BLOCK) { 00145 break; 00146 } 00147 } 00148 sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT); 00149 } 00150 00151 result = success == ECHO_LOOPS; 00152 00153 err = sock.close(); 00154 TEST_ASSERT_EQUAL(0, err); 00155 if (err) { 00156 result = false; 00157 } 00158 } 00159 00160 bool get_result() { 00161 return result; 00162 } 00163 }; 00164 00165 Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS]; 00166 00167 00168 void test_udp_echo_parallel() { 00169 int err = net.connect(STRINGIZE(MBED_CFG_ESP8266_SSID), STRINGIZE(MBED_CFG_ESP8266_PASS)); 00170 TEST_ASSERT_EQUAL(0, err); 00171 00172 if (err) { 00173 printf("MBED: failed to connect with an error of %d\r\n", err); 00174 GREENTEA_TESTSUITE_RESULT(false); 00175 } else { 00176 printf("UDP client IP Address is %s\n", net.get_ip_address()); 00177 00178 greentea_send_kv("target_ip", net.get_ip_address()); 00179 00180 char recv_key[] = "host_port"; 00181 char ipbuf[60] = {0}; 00182 char portbuf[16] = {0}; 00183 unsigned int port = 0; 00184 00185 greentea_send_kv("host_ip", " "); 00186 greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf)); 00187 00188 greentea_send_kv("host_port", " "); 00189 greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf)); 00190 sscanf(portbuf, "%u", &port); 00191 00192 printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port); 00193 udp_addr.set_ip_address(ipbuf); 00194 udp_addr.set_port(port); 00195 00196 // Startup echo threads in parallel 00197 for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) { 00198 echoers[i] = new Echo; 00199 echoers[i]->start(i, uuid); 00200 } 00201 00202 bool result = true; 00203 00204 for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) { 00205 echoers[i]->join(); 00206 result = result && echoers[i]->get_result(); 00207 delete echoers[i]; 00208 } 00209 00210 net.disconnect(); 00211 TEST_ASSERT_EQUAL(true, result); 00212 } 00213 } 00214 00215 00216 // Test setup 00217 utest::v1::status_t test_setup(const size_t number_of_cases) { 00218 GREENTEA_SETUP(120, "udp_echo"); 00219 return verbose_test_setup_handler(number_of_cases); 00220 } 00221 00222 Case cases[] = { 00223 Case("UDP echo parallel", test_udp_echo_parallel), 00224 }; 00225 00226 Specification specification(test_setup, cases); 00227 00228 int main() { 00229 return !Harness::run(specification); 00230 } 00231
Generated on Tue Jul 12 2022 15:14:29 by
