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