Version of easy-connect with the u-blox cellular platforms C027 and C030 added.
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #ifndef MBED_EXTENDED_TESTS 00002 #error [NOT_SUPPORTED] Pressure 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_PACKET_PRESSURE_MIN 00016 #define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN 64 00017 #endif 00018 00019 #ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 00020 #define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000 00021 #endif 00022 00023 #ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 00024 #define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100 00025 #endif 00026 00027 #ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 00028 #define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564 00029 #endif 00030 00031 #ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG 00032 #define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG false 00033 #endif 00034 00035 #ifndef MBED_CFG_ESP8266_TX 00036 #define MBED_CFG_ESP8266_TX D1 00037 #endif 00038 00039 #ifndef MBED_CFG_ESP8266_RX 00040 #define MBED_CFG_ESP8266_RX D0 00041 #endif 00042 00043 #ifndef MBED_CFG_ESP8266_DEBUG 00044 #define MBED_CFG_ESP8266_DEBUG false 00045 #endif 00046 00047 #define STRINGIZE(x) STRINGIZE2(x) 00048 #define STRINGIZE2(x) #x 00049 00050 00051 // Simple xorshift pseudorandom number generator 00052 class RandSeq { 00053 private: 00054 uint32_t x; 00055 uint32_t y; 00056 static const int A = 15; 00057 static const int B = 18; 00058 static const int C = 11; 00059 00060 public: 00061 RandSeq(uint32_t seed=MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED) 00062 : x(seed), y(seed) {} 00063 00064 uint32_t next(void) { 00065 x ^= x << A; 00066 x ^= x >> B; 00067 x ^= y ^ (y >> C); 00068 return x + y; 00069 } 00070 00071 void skip(size_t size) { 00072 for (size_t i = 0; i < size; i++) { 00073 next(); 00074 } 00075 } 00076 00077 void buffer(uint8_t *buffer, size_t size) { 00078 RandSeq lookahead = *this; 00079 00080 for (size_t i = 0; i < size; i++) { 00081 buffer[i] = lookahead.next() & 0xff; 00082 } 00083 } 00084 00085 int cmp(uint8_t *buffer, size_t size) { 00086 RandSeq lookahead = *this; 00087 00088 for (size_t i = 0; i < size; i++) { 00089 int diff = buffer[i] - (lookahead.next() & 0xff); 00090 if (diff != 0) { 00091 return diff; 00092 } 00093 } 00094 return 0; 00095 } 00096 }; 00097 00098 // Shared buffer for network transactions 00099 uint8_t *buffer; 00100 size_t buffer_size; 00101 00102 // Tries to get the biggest buffer possible on the device. Exponentially 00103 // grows a buffer until heap runs out of space, and uses half to leave 00104 // space for the rest of the program 00105 void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) { 00106 size_t i = min; 00107 while (i < max) { 00108 void *b = malloc(i); 00109 if (!b) { 00110 i /= 4; 00111 if (i < min) { 00112 i = min; 00113 } 00114 break; 00115 } 00116 free(b); 00117 i *= 2; 00118 } 00119 00120 *buffer = (uint8_t *)malloc(i); 00121 *size = i; 00122 TEST_ASSERT(buffer); 00123 } 00124 00125 void test_udp_packet_pressure() { 00126 generate_buffer(&buffer, &buffer_size, 00127 MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN, 00128 MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX); 00129 printf("MBED: Generated buffer %d\r\n", buffer_size); 00130 00131 ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG); 00132 int err = net.connect(STRINGIZE(MBED_CFG_ESP8266_SSID), STRINGIZE(MBED_CFG_ESP8266_PASS)); 00133 TEST_ASSERT_EQUAL(0, err); 00134 00135 printf("MBED: UDPClient IP address is '%s'\n", net.get_ip_address()); 00136 printf("MBED: UDPClient waiting for server IP and port...\n"); 00137 00138 greentea_send_kv("target_ip", net.get_ip_address()); 00139 00140 char recv_key[] = "host_port"; 00141 char ipbuf[60] = {0}; 00142 char portbuf[16] = {0}; 00143 unsigned int port = 0; 00144 00145 greentea_send_kv("host_ip", " "); 00146 greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf)); 00147 00148 greentea_send_kv("host_port", " "); 00149 greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf)); 00150 sscanf(portbuf, "%u", &port); 00151 00152 printf("MBED: Server IP address received: %s:%d \n", ipbuf, port); 00153 00154 UDPSocket sock; 00155 SocketAddress udp_addr(ipbuf, port); 00156 00157 Timer timer; 00158 timer.start(); 00159 00160 // Tests exponentially growing sequences 00161 for (size_t size = MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN; 00162 size < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX; 00163 size *= 2) { 00164 err = sock.open(&net); 00165 TEST_ASSERT_EQUAL(0, err); 00166 printf("UDP: %s:%d streaming %d bytes\r\n", ipbuf, port, size); 00167 00168 sock.set_blocking(false); 00169 00170 // Loop to send/recv all data 00171 RandSeq tx_seq; 00172 RandSeq rx_seq; 00173 size_t rx_count = 0; 00174 size_t tx_count = 0; 00175 int known_time = timer.read_ms(); 00176 size_t window = buffer_size; 00177 00178 while (tx_count < size || rx_count < size) { 00179 // Send out packets 00180 if (tx_count < size) { 00181 size_t chunk_size = size - tx_count; 00182 if (chunk_size > window) { 00183 chunk_size = window; 00184 } 00185 00186 tx_seq.buffer(buffer, chunk_size); 00187 int td = sock.sendto(udp_addr, buffer, chunk_size); 00188 00189 if (td > 0) { 00190 if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) { 00191 printf("UDP: tx -> %d\r\n", td); 00192 } 00193 tx_seq.skip(td); 00194 tx_count += td; 00195 } else if (td != NSAPI_ERROR_WOULD_BLOCK) { 00196 // We may fail to send because of buffering issues, revert to 00197 // last good sequence and cut buffer in half 00198 if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) { 00199 window /= 2; 00200 } 00201 00202 if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) { 00203 printf("UDP: Not sent (%d), window = %d\r\n", td, window); 00204 } 00205 } 00206 } 00207 00208 // Prioritize recieving over sending packets to avoid flooding 00209 // the network while handling erronous packets 00210 while (rx_count < size) { 00211 int rd = sock.recvfrom(NULL, buffer, buffer_size); 00212 TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK); 00213 00214 if (rd > 0) { 00215 if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) { 00216 printf("UDP: rx <- %d\r\n", rd); 00217 } 00218 00219 if (rx_seq.cmp(buffer, rd) == 0) { 00220 rx_seq.skip(rd); 00221 rx_count += rd; 00222 known_time = timer.read_ms(); 00223 if (window < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX) { 00224 window += MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN; 00225 } 00226 } 00227 } else if (timer.read_ms() - known_time > 00228 MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) { 00229 // Dropped packet or out of order, revert to last good sequence 00230 // and cut buffer in half 00231 tx_seq = rx_seq; 00232 tx_count = rx_count; 00233 known_time = timer.read_ms(); 00234 if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) { 00235 window /= 2; 00236 } 00237 00238 if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) { 00239 printf("UDP: Dropped, window = %d\r\n", window); 00240 } 00241 } else if (rd == NSAPI_ERROR_WOULD_BLOCK) { 00242 break; 00243 } 00244 } 00245 } 00246 00247 err = sock.close(); 00248 TEST_ASSERT_EQUAL(0, err); 00249 } 00250 00251 timer.stop(); 00252 printf("MBED: Time taken: %fs\r\n", timer.read()); 00253 printf("MBED: Speed: %.3fkb/s\r\n", 00254 8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX - 00255 MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read())); 00256 00257 net.disconnect(); 00258 } 00259 00260 00261 // Test setup 00262 utest::v1::status_t test_setup(const size_t number_of_cases) { 00263 GREENTEA_SETUP(120, "udp_echo"); 00264 return verbose_test_setup_handler(number_of_cases); 00265 } 00266 00267 Case cases[] = { 00268 Case("UDP packet pressure", test_udp_packet_pressure), 00269 }; 00270 00271 Specification specification(test_setup, cases); 00272 00273 int main() { 00274 return !Harness::run(specification); 00275 } 00276
Generated on Tue Jul 12 2022 15:14:29 by 1.7.2