Version of easy-connect with the u-blox cellular platforms C027 and C030 added.

Dependents:   HelloMQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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