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