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] Parallel tests are not supported by default
00003 #endif
00004 
00005 #include "mbed.h"
00006 #include "ESP8266Interface.h"
00007 #include "UDPSocket.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_UDP_CLIENT_ECHO_BUFFER_SIZE
00016 #define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
00017 #endif
00018 
00019 #ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
00020 #define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
00021 #endif
00022 
00023 #ifndef MBED_CFG_UDP_CLIENT_ECHO_THREADS
00024 #define MBED_CFG_UDP_CLIENT_ECHO_THREADS 3
00025 #endif
00026 
00027 #ifndef MBED_CFG_ESP8266_TX
00028 #define MBED_CFG_ESP8266_TX D1
00029 #endif
00030 
00031 #ifndef MBED_CFG_ESP8266_RX
00032 #define MBED_CFG_ESP8266_RX D0
00033 #endif
00034 
00035 #ifndef MBED_CFG_ESP8266_DEBUG
00036 #define MBED_CFG_ESP8266_DEBUG false
00037 #endif
00038 
00039 #define STRINGIZE(x) STRINGIZE2(x)
00040 #define STRINGIZE2(x) #x
00041 
00042 
00043 const int ECHO_LOOPS = 16;
00044 ESP8266Interface net(MBED_CFG_ESP8266_TX, MBED_CFG_ESP8266_RX, MBED_CFG_ESP8266_DEBUG);
00045 SocketAddress udp_addr;
00046 Mutex iomutex;
00047 char uuid[48] = {0};
00048 
00049 // NOTE: assuming that "id" stays in the single digits
00050 void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size) {
00051     size_t i = 0;
00052 
00053     tx_buffer[i++] = '0' + id;
00054     tx_buffer[i++] = ' ';
00055 
00056     memcpy(tx_buffer+i, uuid, strlen(uuid));
00057     i += strlen(uuid);
00058 
00059     tx_buffer[i++] = ' ';
00060 
00061     for (; i<tx_size; ++i) {
00062         tx_buffer[i] = (rand() % 10) + '0';
00063     }
00064 }
00065 
00066 
00067 // Each echo class is in charge of one parallel transaction
00068 class Echo {
00069 private:
00070     char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
00071     char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
00072 
00073     UDPSocket sock;
00074     Thread thread;
00075     bool result;
00076     int id;
00077     char *uuid;
00078 
00079 public:
00080     // Limiting stack size to 1k
00081     Echo(): thread(osPriorityNormal, 1024), result(false) {
00082     }
00083 
00084     void start(int id, char *uuid) {
00085         this->id = id;
00086         this->uuid = uuid;
00087         osStatus status = thread.start(callback(this, &Echo::echo));
00088     }
00089 
00090     void join() {
00091         osStatus status = thread.join();
00092         TEST_ASSERT_EQUAL(osOK, status);
00093     }
00094 
00095     void echo() {
00096         int success = 0;
00097 
00098         int err = sock.open(&net);
00099         TEST_ASSERT_EQUAL(0, err);
00100 
00101         sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
00102 
00103         for (int i = 0; success < ECHO_LOOPS; i++) {
00104             prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer));
00105             const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
00106             if (ret >= 0) {
00107                 iomutex.lock();
00108                 printf("[ID:%01d][%02d] sent %d bytes - %.*s  \n", id, i, ret, ret, tx_buffer);
00109                 iomutex.unlock();
00110             } else {
00111                 iomutex.lock();
00112                 printf("[ID:%01d][%02d] Network error %d\n", id, i, ret);
00113                 iomutex.unlock();
00114                 continue;
00115             }
00116 
00117             SocketAddress temp_addr;
00118             const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
00119             if (n >= 0) {
00120                 iomutex.lock();
00121                 printf("[ID:%01d][%02d] recv %d bytes - %.*s  \n", id, i, n, n, tx_buffer);
00122                 iomutex.unlock();
00123             } else {
00124                 iomutex.lock();
00125                 printf("[ID:%01d][%02d] Network error %d\n", id, i, n);
00126                 iomutex.unlock();
00127                 continue;
00128             }
00129 
00130             if ((temp_addr == udp_addr &&
00131                  n == sizeof(tx_buffer) &&
00132                  memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
00133                 success += 1;
00134                 iomutex.lock();
00135                 printf("[ID:%01d][%02d] success #%d\n", id, i, success);
00136                 iomutex.unlock();
00137                 continue;
00138             }
00139 
00140             // failed, clean out any remaining bad packets
00141             sock.set_timeout(0);
00142             while (true) {
00143                 err = sock.recvfrom(NULL, NULL, 0);
00144                 if (err == NSAPI_ERROR_WOULD_BLOCK) {
00145                     break;
00146                 }
00147             }
00148             sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
00149         }
00150 
00151         result = success == ECHO_LOOPS;
00152 
00153         err = sock.close();
00154         TEST_ASSERT_EQUAL(0, err);
00155         if (err) {
00156             result = false;
00157         }
00158     }
00159 
00160     bool get_result() {
00161         return result;
00162     }
00163 };
00164 
00165 Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
00166 
00167 
00168 void test_udp_echo_parallel() {
00169     int err = net.connect(STRINGIZE(MBED_CFG_ESP8266_SSID), STRINGIZE(MBED_CFG_ESP8266_PASS));
00170     TEST_ASSERT_EQUAL(0, err);
00171 
00172     if (err) {
00173         printf("MBED: failed to connect with an error of %d\r\n", err);
00174         GREENTEA_TESTSUITE_RESULT(false);
00175     } else {
00176         printf("UDP client IP Address is %s\n", net.get_ip_address());
00177 
00178         greentea_send_kv("target_ip", net.get_ip_address());
00179 
00180         char recv_key[] = "host_port";
00181         char ipbuf[60] = {0};
00182         char portbuf[16] = {0};
00183         unsigned int port = 0;
00184 
00185         greentea_send_kv("host_ip", " ");
00186         greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
00187 
00188         greentea_send_kv("host_port", " ");
00189         greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
00190         sscanf(portbuf, "%u", &port);
00191 
00192         printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
00193         udp_addr.set_ip_address(ipbuf);
00194         udp_addr.set_port(port);
00195 
00196         // Startup echo threads in parallel
00197         for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
00198             echoers[i] = new Echo;
00199             echoers[i]->start(i, uuid);
00200         }
00201 
00202         bool result = true;
00203 
00204         for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
00205             echoers[i]->join();
00206             result = result && echoers[i]->get_result();
00207             delete echoers[i];
00208         }
00209 
00210         net.disconnect();
00211         TEST_ASSERT_EQUAL(true, result);
00212     }
00213 }
00214 
00215 
00216 // Test setup
00217 utest::v1::status_t test_setup(const size_t number_of_cases) {
00218     GREENTEA_SETUP(120, "udp_echo");
00219     return verbose_test_setup_handler(number_of_cases);
00220 }
00221 
00222 Case cases[] = {
00223     Case("UDP echo parallel", test_udp_echo_parallel),
00224 };
00225 
00226 Specification specification(test_setup, cases);
00227 
00228 int main() {
00229     return !Harness::run(specification);
00230 }
00231