wifi test

Dependencies:   X_NUCLEO_IKS01A2 mbed-http

Committer:
JMF
Date:
Wed Sep 05 14:28:24 2018 +0000
Revision:
0:24d3eb812fd4
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:24d3eb812fd4 1 #ifndef MBED_EXTENDED_TESTS
JMF 0:24d3eb812fd4 2 #error [NOT_SUPPORTED] Parallel tests are not supported by default
JMF 0:24d3eb812fd4 3 #endif
JMF 0:24d3eb812fd4 4
JMF 0:24d3eb812fd4 5 #include "mbed.h"
JMF 0:24d3eb812fd4 6 #include "ESP8266Interface.h"
JMF 0:24d3eb812fd4 7 #include "UDPSocket.h"
JMF 0:24d3eb812fd4 8 #include "greentea-client/test_env.h"
JMF 0:24d3eb812fd4 9 #include "unity/unity.h"
JMF 0:24d3eb812fd4 10 #include "utest.h"
JMF 0:24d3eb812fd4 11
JMF 0:24d3eb812fd4 12 using namespace utest::v1;
JMF 0:24d3eb812fd4 13
JMF 0:24d3eb812fd4 14
JMF 0:24d3eb812fd4 15 #ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
JMF 0:24d3eb812fd4 16 #define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
JMF 0:24d3eb812fd4 17 #endif
JMF 0:24d3eb812fd4 18
JMF 0:24d3eb812fd4 19 #ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
JMF 0:24d3eb812fd4 20 #define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
JMF 0:24d3eb812fd4 21 #endif
JMF 0:24d3eb812fd4 22
JMF 0:24d3eb812fd4 23 #ifndef MBED_CFG_UDP_CLIENT_ECHO_THREADS
JMF 0:24d3eb812fd4 24 #define MBED_CFG_UDP_CLIENT_ECHO_THREADS 3
JMF 0:24d3eb812fd4 25 #endif
JMF 0:24d3eb812fd4 26
JMF 0:24d3eb812fd4 27 #ifndef MBED_CFG_ESP8266_TX
JMF 0:24d3eb812fd4 28 #define MBED_CFG_ESP8266_TX D1
JMF 0:24d3eb812fd4 29 #endif
JMF 0:24d3eb812fd4 30
JMF 0:24d3eb812fd4 31 #ifndef MBED_CFG_ESP8266_RX
JMF 0:24d3eb812fd4 32 #define MBED_CFG_ESP8266_RX D0
JMF 0:24d3eb812fd4 33 #endif
JMF 0:24d3eb812fd4 34
JMF 0:24d3eb812fd4 35 #ifndef MBED_CFG_ESP8266_DEBUG
JMF 0:24d3eb812fd4 36 #define MBED_CFG_ESP8266_DEBUG false
JMF 0:24d3eb812fd4 37 #endif
JMF 0:24d3eb812fd4 38
JMF 0:24d3eb812fd4 39 #define STRINGIZE(x) STRINGIZE2(x)
JMF 0:24d3eb812fd4 40 #define STRINGIZE2(x) #x
JMF 0:24d3eb812fd4 41
JMF 0:24d3eb812fd4 42
JMF 0:24d3eb812fd4 43 const int ECHO_LOOPS = 16;
JMF 0:24d3eb812fd4 44 ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
JMF 0:24d3eb812fd4 45 SocketAddress udp_addr;
JMF 0:24d3eb812fd4 46 Mutex iomutex;
JMF 0:24d3eb812fd4 47 char uuid[48] = {0};
JMF 0:24d3eb812fd4 48
JMF 0:24d3eb812fd4 49 // NOTE: assuming that "id" stays in the single digits
JMF 0:24d3eb812fd4 50 void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size) {
JMF 0:24d3eb812fd4 51 size_t i = 0;
JMF 0:24d3eb812fd4 52
JMF 0:24d3eb812fd4 53 tx_buffer[i++] = '0' + id;
JMF 0:24d3eb812fd4 54 tx_buffer[i++] = ' ';
JMF 0:24d3eb812fd4 55
JMF 0:24d3eb812fd4 56 memcpy(tx_buffer+i, uuid, strlen(uuid));
JMF 0:24d3eb812fd4 57 i += strlen(uuid);
JMF 0:24d3eb812fd4 58
JMF 0:24d3eb812fd4 59 tx_buffer[i++] = ' ';
JMF 0:24d3eb812fd4 60
JMF 0:24d3eb812fd4 61 for (; i<tx_size; ++i) {
JMF 0:24d3eb812fd4 62 tx_buffer[i] = (rand() % 10) + '0';
JMF 0:24d3eb812fd4 63 }
JMF 0:24d3eb812fd4 64 }
JMF 0:24d3eb812fd4 65
JMF 0:24d3eb812fd4 66
JMF 0:24d3eb812fd4 67 // Each echo class is in charge of one parallel transaction
JMF 0:24d3eb812fd4 68 class Echo {
JMF 0:24d3eb812fd4 69 private:
JMF 0:24d3eb812fd4 70 char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
JMF 0:24d3eb812fd4 71 char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
JMF 0:24d3eb812fd4 72
JMF 0:24d3eb812fd4 73 UDPSocket sock;
JMF 0:24d3eb812fd4 74 Thread thread;
JMF 0:24d3eb812fd4 75 bool result;
JMF 0:24d3eb812fd4 76 int id;
JMF 0:24d3eb812fd4 77 char *uuid;
JMF 0:24d3eb812fd4 78
JMF 0:24d3eb812fd4 79 public:
JMF 0:24d3eb812fd4 80 // Limiting stack size to 1k
JMF 0:24d3eb812fd4 81 Echo(): thread(osPriorityNormal, 1024), result(false) {
JMF 0:24d3eb812fd4 82 }
JMF 0:24d3eb812fd4 83
JMF 0:24d3eb812fd4 84 void start(int id, char *uuid) {
JMF 0:24d3eb812fd4 85 this->id = id;
JMF 0:24d3eb812fd4 86 this->uuid = uuid;
JMF 0:24d3eb812fd4 87 osStatus status = thread.start(callback(this, &Echo::echo));
JMF 0:24d3eb812fd4 88 }
JMF 0:24d3eb812fd4 89
JMF 0:24d3eb812fd4 90 void join() {
JMF 0:24d3eb812fd4 91 osStatus status = thread.join();
JMF 0:24d3eb812fd4 92 TEST_ASSERT_EQUAL(osOK, status);
JMF 0:24d3eb812fd4 93 }
JMF 0:24d3eb812fd4 94
JMF 0:24d3eb812fd4 95 void echo() {
JMF 0:24d3eb812fd4 96 int success = 0;
JMF 0:24d3eb812fd4 97
JMF 0:24d3eb812fd4 98 int err = sock.open(&net);
JMF 0:24d3eb812fd4 99 TEST_ASSERT_EQUAL(0, err);
JMF 0:24d3eb812fd4 100
JMF 0:24d3eb812fd4 101 sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
JMF 0:24d3eb812fd4 102
JMF 0:24d3eb812fd4 103 for (int i = 0; success < ECHO_LOOPS; i++) {
JMF 0:24d3eb812fd4 104 prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer));
JMF 0:24d3eb812fd4 105 const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
JMF 0:24d3eb812fd4 106 if (ret >= 0) {
JMF 0:24d3eb812fd4 107 iomutex.lock();
JMF 0:24d3eb812fd4 108 printf("[ID:%01d][%02d] sent %d bytes - %.*s \n", id, i, ret, ret, tx_buffer);
JMF 0:24d3eb812fd4 109 iomutex.unlock();
JMF 0:24d3eb812fd4 110 } else {
JMF 0:24d3eb812fd4 111 iomutex.lock();
JMF 0:24d3eb812fd4 112 printf("[ID:%01d][%02d] Network error %d\n", id, i, ret);
JMF 0:24d3eb812fd4 113 iomutex.unlock();
JMF 0:24d3eb812fd4 114 continue;
JMF 0:24d3eb812fd4 115 }
JMF 0:24d3eb812fd4 116
JMF 0:24d3eb812fd4 117 SocketAddress temp_addr;
JMF 0:24d3eb812fd4 118 const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
JMF 0:24d3eb812fd4 119 if (n >= 0) {
JMF 0:24d3eb812fd4 120 iomutex.lock();
JMF 0:24d3eb812fd4 121 printf("[ID:%01d][%02d] recv %d bytes - %.*s \n", id, i, n, n, tx_buffer);
JMF 0:24d3eb812fd4 122 iomutex.unlock();
JMF 0:24d3eb812fd4 123 } else {
JMF 0:24d3eb812fd4 124 iomutex.lock();
JMF 0:24d3eb812fd4 125 printf("[ID:%01d][%02d] Network error %d\n", id, i, n);
JMF 0:24d3eb812fd4 126 iomutex.unlock();
JMF 0:24d3eb812fd4 127 continue;
JMF 0:24d3eb812fd4 128 }
JMF 0:24d3eb812fd4 129
JMF 0:24d3eb812fd4 130 if ((temp_addr == udp_addr &&
JMF 0:24d3eb812fd4 131 n == sizeof(tx_buffer) &&
JMF 0:24d3eb812fd4 132 memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
JMF 0:24d3eb812fd4 133 success += 1;
JMF 0:24d3eb812fd4 134 iomutex.lock();
JMF 0:24d3eb812fd4 135 printf("[ID:%01d][%02d] success #%d\n", id, i, success);
JMF 0:24d3eb812fd4 136 iomutex.unlock();
JMF 0:24d3eb812fd4 137 continue;
JMF 0:24d3eb812fd4 138 }
JMF 0:24d3eb812fd4 139
JMF 0:24d3eb812fd4 140 // failed, clean out any remaining bad packets
JMF 0:24d3eb812fd4 141 sock.set_timeout(0);
JMF 0:24d3eb812fd4 142 while (true) {
JMF 0:24d3eb812fd4 143 err = sock.recvfrom(NULL, NULL, 0);
JMF 0:24d3eb812fd4 144 if (err == NSAPI_ERROR_WOULD_BLOCK) {
JMF 0:24d3eb812fd4 145 break;
JMF 0:24d3eb812fd4 146 }
JMF 0:24d3eb812fd4 147 }
JMF 0:24d3eb812fd4 148 sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
JMF 0:24d3eb812fd4 149 }
JMF 0:24d3eb812fd4 150
JMF 0:24d3eb812fd4 151 result = success == ECHO_LOOPS;
JMF 0:24d3eb812fd4 152
JMF 0:24d3eb812fd4 153 err = sock.close();
JMF 0:24d3eb812fd4 154 TEST_ASSERT_EQUAL(0, err);
JMF 0:24d3eb812fd4 155 if (err) {
JMF 0:24d3eb812fd4 156 result = false;
JMF 0:24d3eb812fd4 157 }
JMF 0:24d3eb812fd4 158 }
JMF 0:24d3eb812fd4 159
JMF 0:24d3eb812fd4 160 bool get_result() {
JMF 0:24d3eb812fd4 161 return result;
JMF 0:24d3eb812fd4 162 }
JMF 0:24d3eb812fd4 163 };
JMF 0:24d3eb812fd4 164
JMF 0:24d3eb812fd4 165 Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
JMF 0:24d3eb812fd4 166
JMF 0:24d3eb812fd4 167
JMF 0:24d3eb812fd4 168 void test_udp_echo_parallel() {
JMF 0:24d3eb812fd4 169 int err = net.connect(STRINGIZE(MBED_CFG_ESP8266_SSID), STRINGIZE(MBED_CFG_ESP8266_PASS));
JMF 0:24d3eb812fd4 170 TEST_ASSERT_EQUAL(0, err);
JMF 0:24d3eb812fd4 171
JMF 0:24d3eb812fd4 172 if (err) {
JMF 0:24d3eb812fd4 173 printf("MBED: failed to connect with an error of %d\r\n", err);
JMF 0:24d3eb812fd4 174 GREENTEA_TESTSUITE_RESULT(false);
JMF 0:24d3eb812fd4 175 } else {
JMF 0:24d3eb812fd4 176 printf("UDP client IP Address is %s\n", net.get_ip_address());
JMF 0:24d3eb812fd4 177
JMF 0:24d3eb812fd4 178 greentea_send_kv("target_ip", net.get_ip_address());
JMF 0:24d3eb812fd4 179
JMF 0:24d3eb812fd4 180 char recv_key[] = "host_port";
JMF 0:24d3eb812fd4 181 char ipbuf[60] = {0};
JMF 0:24d3eb812fd4 182 char portbuf[16] = {0};
JMF 0:24d3eb812fd4 183 unsigned int port = 0;
JMF 0:24d3eb812fd4 184
JMF 0:24d3eb812fd4 185 greentea_send_kv("host_ip", " ");
JMF 0:24d3eb812fd4 186 greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
JMF 0:24d3eb812fd4 187
JMF 0:24d3eb812fd4 188 greentea_send_kv("host_port", " ");
JMF 0:24d3eb812fd4 189 greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
JMF 0:24d3eb812fd4 190 sscanf(portbuf, "%u", &port);
JMF 0:24d3eb812fd4 191
JMF 0:24d3eb812fd4 192 printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
JMF 0:24d3eb812fd4 193 udp_addr.set_ip_address(ipbuf);
JMF 0:24d3eb812fd4 194 udp_addr.set_port(port);
JMF 0:24d3eb812fd4 195
JMF 0:24d3eb812fd4 196 // Startup echo threads in parallel
JMF 0:24d3eb812fd4 197 for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
JMF 0:24d3eb812fd4 198 echoers[i] = new Echo;
JMF 0:24d3eb812fd4 199 echoers[i]->start(i, uuid);
JMF 0:24d3eb812fd4 200 }
JMF 0:24d3eb812fd4 201
JMF 0:24d3eb812fd4 202 bool result = true;
JMF 0:24d3eb812fd4 203
JMF 0:24d3eb812fd4 204 for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
JMF 0:24d3eb812fd4 205 echoers[i]->join();
JMF 0:24d3eb812fd4 206 result = result && echoers[i]->get_result();
JMF 0:24d3eb812fd4 207 delete echoers[i];
JMF 0:24d3eb812fd4 208 }
JMF 0:24d3eb812fd4 209
JMF 0:24d3eb812fd4 210 net.disconnect();
JMF 0:24d3eb812fd4 211 TEST_ASSERT_EQUAL(true, result);
JMF 0:24d3eb812fd4 212 }
JMF 0:24d3eb812fd4 213 }
JMF 0:24d3eb812fd4 214
JMF 0:24d3eb812fd4 215
JMF 0:24d3eb812fd4 216 // Test setup
JMF 0:24d3eb812fd4 217 utest::v1::status_t test_setup(const size_t number_of_cases) {
JMF 0:24d3eb812fd4 218 GREENTEA_SETUP(120, "udp_echo");
JMF 0:24d3eb812fd4 219 return verbose_test_setup_handler(number_of_cases);
JMF 0:24d3eb812fd4 220 }
JMF 0:24d3eb812fd4 221
JMF 0:24d3eb812fd4 222 Case cases[] = {
JMF 0:24d3eb812fd4 223 Case("UDP echo parallel", test_udp_echo_parallel),
JMF 0:24d3eb812fd4 224 };
JMF 0:24d3eb812fd4 225
JMF 0:24d3eb812fd4 226 Specification specification(test_setup, cases);
JMF 0:24d3eb812fd4 227
JMF 0:24d3eb812fd4 228 int main() {
JMF 0:24d3eb812fd4 229 return !Harness::run(specification);
JMF 0:24d3eb812fd4 230 }
JMF 0:24d3eb812fd4 231