Easily add all supported connectivity methods to your mbed OS project

Dependencies:   type-yd-driver

Committer:
MACRUM
Date:
Wed Jul 12 10:52:58 2017 +0000
Revision:
0:615f90842ce8
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:615f90842ce8 1 #ifndef MBED_EXTENDED_TESTS
MACRUM 0:615f90842ce8 2 #error [NOT_SUPPORTED] Pressure tests are not supported by default
MACRUM 0:615f90842ce8 3 #endif
MACRUM 0:615f90842ce8 4
MACRUM 0:615f90842ce8 5 #include "mbed.h"
MACRUM 0:615f90842ce8 6 #include "ESP8266Interface.h"
MACRUM 0:615f90842ce8 7 #include "TCPSocket.h"
MACRUM 0:615f90842ce8 8 #include "greentea-client/test_env.h"
MACRUM 0:615f90842ce8 9 #include "unity/unity.h"
MACRUM 0:615f90842ce8 10 #include "utest.h"
MACRUM 0:615f90842ce8 11
MACRUM 0:615f90842ce8 12 using namespace utest::v1;
MACRUM 0:615f90842ce8 13
MACRUM 0:615f90842ce8 14
MACRUM 0:615f90842ce8 15 #ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
MACRUM 0:615f90842ce8 16 #define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN 64
MACRUM 0:615f90842ce8 17 #endif
MACRUM 0:615f90842ce8 18
MACRUM 0:615f90842ce8 19 #ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX
MACRUM 0:615f90842ce8 20 #define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
MACRUM 0:615f90842ce8 21 #endif
MACRUM 0:615f90842ce8 22
MACRUM 0:615f90842ce8 23 #ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED
MACRUM 0:615f90842ce8 24 #define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
MACRUM 0:615f90842ce8 25 #endif
MACRUM 0:615f90842ce8 26
MACRUM 0:615f90842ce8 27 #ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG
MACRUM 0:615f90842ce8 28 #define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
MACRUM 0:615f90842ce8 29 #endif
MACRUM 0:615f90842ce8 30
MACRUM 0:615f90842ce8 31 #ifndef MBED_CFG_ESP8266_TX
MACRUM 0:615f90842ce8 32 #define MBED_CFG_ESP8266_TX D1
MACRUM 0:615f90842ce8 33 #endif
MACRUM 0:615f90842ce8 34
MACRUM 0:615f90842ce8 35 #ifndef MBED_CFG_ESP8266_RX
MACRUM 0:615f90842ce8 36 #define MBED_CFG_ESP8266_RX D0
MACRUM 0:615f90842ce8 37 #endif
MACRUM 0:615f90842ce8 38
MACRUM 0:615f90842ce8 39 #ifndef MBED_CFG_ESP8266_DEBUG
MACRUM 0:615f90842ce8 40 #define MBED_CFG_ESP8266_DEBUG false
MACRUM 0:615f90842ce8 41 #endif
MACRUM 0:615f90842ce8 42
MACRUM 0:615f90842ce8 43
MACRUM 0:615f90842ce8 44 // Simple xorshift pseudorandom number generator
MACRUM 0:615f90842ce8 45 class RandSeq {
MACRUM 0:615f90842ce8 46 private:
MACRUM 0:615f90842ce8 47 uint32_t x;
MACRUM 0:615f90842ce8 48 uint32_t y;
MACRUM 0:615f90842ce8 49 static const int A = 15;
MACRUM 0:615f90842ce8 50 static const int B = 18;
MACRUM 0:615f90842ce8 51 static const int C = 11;
MACRUM 0:615f90842ce8 52
MACRUM 0:615f90842ce8 53 public:
MACRUM 0:615f90842ce8 54 RandSeq(uint32_t seed=MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED)
MACRUM 0:615f90842ce8 55 : x(seed), y(seed) {}
MACRUM 0:615f90842ce8 56
MACRUM 0:615f90842ce8 57 uint32_t next(void) {
MACRUM 0:615f90842ce8 58 x ^= x << A;
MACRUM 0:615f90842ce8 59 x ^= x >> B;
MACRUM 0:615f90842ce8 60 x ^= y ^ (y >> C);
MACRUM 0:615f90842ce8 61 return x + y;
MACRUM 0:615f90842ce8 62 }
MACRUM 0:615f90842ce8 63
MACRUM 0:615f90842ce8 64 void skip(size_t size) {
MACRUM 0:615f90842ce8 65 for (size_t i = 0; i < size; i++) {
MACRUM 0:615f90842ce8 66 next();
MACRUM 0:615f90842ce8 67 }
MACRUM 0:615f90842ce8 68 }
MACRUM 0:615f90842ce8 69
MACRUM 0:615f90842ce8 70 void buffer(uint8_t *buffer, size_t size) {
MACRUM 0:615f90842ce8 71 RandSeq lookahead = *this;
MACRUM 0:615f90842ce8 72
MACRUM 0:615f90842ce8 73 for (size_t i = 0; i < size; i++) {
MACRUM 0:615f90842ce8 74 buffer[i] = lookahead.next() & 0xff;
MACRUM 0:615f90842ce8 75 }
MACRUM 0:615f90842ce8 76 }
MACRUM 0:615f90842ce8 77
MACRUM 0:615f90842ce8 78 int cmp(uint8_t *buffer, size_t size) {
MACRUM 0:615f90842ce8 79 RandSeq lookahead = *this;
MACRUM 0:615f90842ce8 80
MACRUM 0:615f90842ce8 81 for (size_t i = 0; i < size; i++) {
MACRUM 0:615f90842ce8 82 int diff = buffer[i] - (lookahead.next() & 0xff);
MACRUM 0:615f90842ce8 83 if (diff != 0) {
MACRUM 0:615f90842ce8 84 return diff;
MACRUM 0:615f90842ce8 85 }
MACRUM 0:615f90842ce8 86 }
MACRUM 0:615f90842ce8 87 return 0;
MACRUM 0:615f90842ce8 88 }
MACRUM 0:615f90842ce8 89 };
MACRUM 0:615f90842ce8 90
MACRUM 0:615f90842ce8 91 // Shared buffer for network transactions
MACRUM 0:615f90842ce8 92 uint8_t *buffer;
MACRUM 0:615f90842ce8 93 size_t buffer_size;
MACRUM 0:615f90842ce8 94
MACRUM 0:615f90842ce8 95 // Tries to get the biggest buffer possible on the device. Exponentially
MACRUM 0:615f90842ce8 96 // grows a buffer until heap runs out of space, and uses half to leave
MACRUM 0:615f90842ce8 97 // space for the rest of the program
MACRUM 0:615f90842ce8 98 void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
MACRUM 0:615f90842ce8 99 size_t i = min;
MACRUM 0:615f90842ce8 100 while (i < max) {
MACRUM 0:615f90842ce8 101 void *b = malloc(i);
MACRUM 0:615f90842ce8 102 if (!b) {
MACRUM 0:615f90842ce8 103 i /= 4;
MACRUM 0:615f90842ce8 104 if (i < min) {
MACRUM 0:615f90842ce8 105 i = min;
MACRUM 0:615f90842ce8 106 }
MACRUM 0:615f90842ce8 107 break;
MACRUM 0:615f90842ce8 108 }
MACRUM 0:615f90842ce8 109 free(b);
MACRUM 0:615f90842ce8 110 i *= 2;
MACRUM 0:615f90842ce8 111 }
MACRUM 0:615f90842ce8 112
MACRUM 0:615f90842ce8 113 *buffer = (uint8_t *)malloc(i);
MACRUM 0:615f90842ce8 114 *size = i;
MACRUM 0:615f90842ce8 115 TEST_ASSERT(buffer);
MACRUM 0:615f90842ce8 116 }
MACRUM 0:615f90842ce8 117
MACRUM 0:615f90842ce8 118
MACRUM 0:615f90842ce8 119 void test_tcp_packet_pressure() {
MACRUM 0:615f90842ce8 120 generate_buffer(&buffer, &buffer_size,
MACRUM 0:615f90842ce8 121 MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
MACRUM 0:615f90842ce8 122 MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
MACRUM 0:615f90842ce8 123 printf("MBED: Generated buffer %d\r\n", buffer_size);
MACRUM 0:615f90842ce8 124
MACRUM 0:615f90842ce8 125 ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
MACRUM 0:615f90842ce8 126 int err = net.connect(MBED_CFG_ESP8266_SSID, MBED_CFG_ESP8266_PASS);
MACRUM 0:615f90842ce8 127 TEST_ASSERT_EQUAL(0, err);
MACRUM 0:615f90842ce8 128
MACRUM 0:615f90842ce8 129 printf("MBED: TCPClient IP address is '%s'\n", net.get_ip_address());
MACRUM 0:615f90842ce8 130 printf("MBED: TCPClient waiting for server IP and port...\n");
MACRUM 0:615f90842ce8 131
MACRUM 0:615f90842ce8 132 greentea_send_kv("target_ip", net.get_ip_address());
MACRUM 0:615f90842ce8 133
MACRUM 0:615f90842ce8 134 char recv_key[] = "host_port";
MACRUM 0:615f90842ce8 135 char ipbuf[60] = {0};
MACRUM 0:615f90842ce8 136 char portbuf[16] = {0};
MACRUM 0:615f90842ce8 137 unsigned int port = 0;
MACRUM 0:615f90842ce8 138
MACRUM 0:615f90842ce8 139 greentea_send_kv("host_ip", " ");
MACRUM 0:615f90842ce8 140 greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
MACRUM 0:615f90842ce8 141
MACRUM 0:615f90842ce8 142 greentea_send_kv("host_port", " ");
MACRUM 0:615f90842ce8 143 greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
MACRUM 0:615f90842ce8 144 sscanf(portbuf, "%u", &port);
MACRUM 0:615f90842ce8 145
MACRUM 0:615f90842ce8 146 printf("MBED: Server IP address received: %s:%d \n", ipbuf, port);
MACRUM 0:615f90842ce8 147
MACRUM 0:615f90842ce8 148 TCPSocket sock;
MACRUM 0:615f90842ce8 149 SocketAddress tcp_addr(ipbuf, port);
MACRUM 0:615f90842ce8 150
MACRUM 0:615f90842ce8 151 Timer timer;
MACRUM 0:615f90842ce8 152 timer.start();
MACRUM 0:615f90842ce8 153
MACRUM 0:615f90842ce8 154 // Tests exponentially growing sequences
MACRUM 0:615f90842ce8 155 for (size_t size = MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN;
MACRUM 0:615f90842ce8 156 size < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX;
MACRUM 0:615f90842ce8 157 size *= 2) {
MACRUM 0:615f90842ce8 158 err = sock.open(&net);
MACRUM 0:615f90842ce8 159 TEST_ASSERT_EQUAL(0, err);
MACRUM 0:615f90842ce8 160 err = sock.connect(tcp_addr);
MACRUM 0:615f90842ce8 161 TEST_ASSERT_EQUAL(0, err);
MACRUM 0:615f90842ce8 162 printf("TCP: %s:%d streaming %d bytes\r\n", ipbuf, port, size);
MACRUM 0:615f90842ce8 163
MACRUM 0:615f90842ce8 164 sock.set_blocking(false);
MACRUM 0:615f90842ce8 165
MACRUM 0:615f90842ce8 166 // Loop to send/recv all data
MACRUM 0:615f90842ce8 167 RandSeq tx_seq;
MACRUM 0:615f90842ce8 168 RandSeq rx_seq;
MACRUM 0:615f90842ce8 169 size_t rx_count = 0;
MACRUM 0:615f90842ce8 170 size_t tx_count = 0;
MACRUM 0:615f90842ce8 171 size_t window = buffer_size;
MACRUM 0:615f90842ce8 172
MACRUM 0:615f90842ce8 173 while (tx_count < size || rx_count < size) {
MACRUM 0:615f90842ce8 174 // Send out data
MACRUM 0:615f90842ce8 175 if (tx_count < size) {
MACRUM 0:615f90842ce8 176 size_t chunk_size = size - tx_count;
MACRUM 0:615f90842ce8 177 if (chunk_size > window) {
MACRUM 0:615f90842ce8 178 chunk_size = window;
MACRUM 0:615f90842ce8 179 }
MACRUM 0:615f90842ce8 180
MACRUM 0:615f90842ce8 181 tx_seq.buffer(buffer, chunk_size);
MACRUM 0:615f90842ce8 182 int td = sock.send(buffer, chunk_size);
MACRUM 0:615f90842ce8 183
MACRUM 0:615f90842ce8 184 if (td > 0) {
MACRUM 0:615f90842ce8 185 if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
MACRUM 0:615f90842ce8 186 printf("TCP: tx -> %d\r\n", td);
MACRUM 0:615f90842ce8 187 }
MACRUM 0:615f90842ce8 188 tx_seq.skip(td);
MACRUM 0:615f90842ce8 189 tx_count += td;
MACRUM 0:615f90842ce8 190 } else if (td != NSAPI_ERROR_WOULD_BLOCK) {
MACRUM 0:615f90842ce8 191 // We may fail to send because of buffering issues,
MACRUM 0:615f90842ce8 192 // cut buffer in half
MACRUM 0:615f90842ce8 193 if (window > MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) {
MACRUM 0:615f90842ce8 194 window /= 2;
MACRUM 0:615f90842ce8 195 }
MACRUM 0:615f90842ce8 196
MACRUM 0:615f90842ce8 197 if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
MACRUM 0:615f90842ce8 198 printf("TCP: Not sent (%d), window = %d\r\n", td, window);
MACRUM 0:615f90842ce8 199 }
MACRUM 0:615f90842ce8 200 }
MACRUM 0:615f90842ce8 201 }
MACRUM 0:615f90842ce8 202
MACRUM 0:615f90842ce8 203 // Verify recieved data
MACRUM 0:615f90842ce8 204 while (rx_count < size) {
MACRUM 0:615f90842ce8 205 int rd = sock.recv(buffer, buffer_size);
MACRUM 0:615f90842ce8 206 TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
MACRUM 0:615f90842ce8 207 if (rd > 0) {
MACRUM 0:615f90842ce8 208 if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
MACRUM 0:615f90842ce8 209 printf("TCP: rx <- %d\r\n", rd);
MACRUM 0:615f90842ce8 210 }
MACRUM 0:615f90842ce8 211 int diff = rx_seq.cmp(buffer, rd);
MACRUM 0:615f90842ce8 212 TEST_ASSERT_EQUAL(0, diff);
MACRUM 0:615f90842ce8 213 rx_seq.skip(rd);
MACRUM 0:615f90842ce8 214 rx_count += rd;
MACRUM 0:615f90842ce8 215 } else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
MACRUM 0:615f90842ce8 216 break;
MACRUM 0:615f90842ce8 217 }
MACRUM 0:615f90842ce8 218 }
MACRUM 0:615f90842ce8 219 }
MACRUM 0:615f90842ce8 220
MACRUM 0:615f90842ce8 221 err = sock.close();
MACRUM 0:615f90842ce8 222 TEST_ASSERT_EQUAL(0, err);
MACRUM 0:615f90842ce8 223 }
MACRUM 0:615f90842ce8 224
MACRUM 0:615f90842ce8 225 timer.stop();
MACRUM 0:615f90842ce8 226 printf("MBED: Time taken: %fs\r\n", timer.read());
MACRUM 0:615f90842ce8 227 printf("MBED: Speed: %.3fkb/s\r\n",
MACRUM 0:615f90842ce8 228 8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
MACRUM 0:615f90842ce8 229 MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
MACRUM 0:615f90842ce8 230
MACRUM 0:615f90842ce8 231 net.disconnect();
MACRUM 0:615f90842ce8 232 }
MACRUM 0:615f90842ce8 233
MACRUM 0:615f90842ce8 234
MACRUM 0:615f90842ce8 235 // Test setup
MACRUM 0:615f90842ce8 236 utest::v1::status_t test_setup(const size_t number_of_cases) {
MACRUM 0:615f90842ce8 237 char uuid[48] = {0};
MACRUM 0:615f90842ce8 238 GREENTEA_SETUP_UUID(120, "tcp_echo", uuid, 48);
MACRUM 0:615f90842ce8 239
MACRUM 0:615f90842ce8 240 // create mac address based on uuid
MACRUM 0:615f90842ce8 241 uint64_t mac = 0;
MACRUM 0:615f90842ce8 242 for (int i = 0; i < sizeof(uuid); i++) {
MACRUM 0:615f90842ce8 243 mac += uuid[i];
MACRUM 0:615f90842ce8 244 }
MACRUM 0:615f90842ce8 245 mbed_set_mac_address((const char*)mac, /*coerce control bits*/ 1);
MACRUM 0:615f90842ce8 246
MACRUM 0:615f90842ce8 247 return verbose_test_setup_handler(number_of_cases);
MACRUM 0:615f90842ce8 248 }
MACRUM 0:615f90842ce8 249
MACRUM 0:615f90842ce8 250 Case cases[] = {
MACRUM 0:615f90842ce8 251 Case("TCP packet pressure", test_tcp_packet_pressure),
MACRUM 0:615f90842ce8 252 };
MACRUM 0:615f90842ce8 253
MACRUM 0:615f90842ce8 254 Specification specification(test_setup, cases);
MACRUM 0:615f90842ce8 255
MACRUM 0:615f90842ce8 256 int main() {
MACRUM 0:615f90842ce8 257 return !Harness::run(specification);
MACRUM 0:615f90842ce8 258 }
MACRUM 0:615f90842ce8 259