Adding ability to set priority for the Rx thread

Fork of ublox-at-cellular-interface by u-blox

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "UbloxATCellularInterface.h"
00002 #include "greentea-client/test_env.h"
00003 #include "unity.h"
00004 #include "utest.h"
00005 #include "UDPSocket.h"
00006 #ifdef FEATURE_COMMON_PAL
00007 #include "mbed_trace.h"
00008 #define TRACE_GROUP "TEST"
00009 #else
00010 #define tr_debug(format, ...) debug(format "\n", ## __VA_ARGS__)
00011 #define tr_info(format, ...)  debug(format "\n", ## __VA_ARGS__)
00012 #define tr_warn(format, ...)  debug(format "\n", ## __VA_ARGS__)
00013 #define tr_error(format, ...) debug(format "\n", ## __VA_ARGS__)
00014 #endif
00015 
00016 using namespace utest::v1;
00017 
00018 // IMPORTANT!!! if you make a change to the tests here you should
00019 // check whether the same change should be made to the tests under
00020 // the PPP interface.
00021 
00022 // NOTE: these test are only as reliable as UDP across the internet
00023 // over a radio link.  The tests expect an NTP server to respond
00024 // to UDP packets and, if configured, an echo server to respond
00025 // to UDP packets.  This simply may not happen.  Please be patient.
00026 
00027 // ----------------------------------------------------------------
00028 // COMPILE-TIME MACROS
00029 // ----------------------------------------------------------------
00030 
00031 // These macros can be overridden with an mbed_app.json file and
00032 // contents of the following form:
00033 //
00034 //{
00035 //    "config": {
00036 //        "default-pin": {
00037 //            "value": "\"1234\""
00038 //        }
00039 //}
00040 //
00041 // See the template_mbed_app.txt in this directory for a fuller example.
00042 
00043 // Whether debug trace is on
00044 #ifndef MBED_CONF_APP_DEBUG_ON
00045 # define MBED_CONF_APP_DEBUG_ON false
00046 #endif
00047 
00048 // Run the SIM change tests, which require the DEFAULT_PIN
00049 // above to be correct for the board on which the test
00050 // is being run (and the SIM PIN to be disabled before tests run).
00051 #ifndef MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
00052 # define MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS 0
00053 #endif
00054 
00055 #if MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
00056 # ifndef MBED_CONF_APP_DEFAULT_PIN
00057 #   error "MBED_CONF_APP_DEFAULT_PIN must be defined to run the SIM tests"
00058 # endif
00059 # ifndef MBED_CONF_APP_ALT_PIN
00060 #   error "MBED_CONF_APP_ALT_PIN must be defined to run the SIM tests"
00061 # endif
00062 # ifndef MBED_CONF_APP_INCORRECT_PIN
00063 #   error "MBED_CONF_APP_INCORRECT_PIN must be defined to run the SIM tests"
00064 # endif
00065 #endif
00066 
00067 // The credentials of the SIM in the board.
00068 #ifndef MBED_CONF_APP_DEFAULT_PIN
00069 // Note: if PIN is enabled on your SIM, or you wish to run the SIM PIN change
00070 // tests, you must define the PIN for your SIM (see note above on using
00071 // mbed_app.json to do so).
00072 # define MBED_CONF_APP_DEFAULT_PIN "0000"
00073 #endif
00074 #ifndef MBED_CONF_APP_APN
00075 # define MBED_CONF_APP_APN         NULL
00076 #endif
00077 #ifndef MBED_CONF_APP_USERNAME
00078 # define MBED_CONF_APP_USERNAME    NULL
00079 #endif
00080 #ifndef MBED_CONF_APP_PASSWORD
00081 # define MBED_CONF_APP_PASSWORD    NULL
00082 #endif
00083 
00084 // Alternate PIN to use during pin change testing
00085 #ifndef MBED_CONF_APP_ALT_PIN
00086 # define MBED_CONF_APP_ALT_PIN    "9876"
00087 #endif
00088 
00089 // A PIN that is definitely incorrect
00090 #ifndef MBED_CONF_APP_INCORRECT_PIN
00091 # define MBED_CONF_APP_INCORRECT_PIN "1530"
00092 #endif
00093 
00094 // Servers and ports
00095 #ifdef MBED_CONF_APP_ECHO_SERVER
00096 # ifndef MBED_CONF_APP_ECHO_UDP_PORT
00097 #  error "MBED_CONF_APP_ECHO_UDP_PORT (the port on which your echo server echoes UDP packets) must be defined"
00098 # endif
00099 # ifndef MBED_CONF_APP_ECHO_TCP_PORT
00100 #  error "MBED_CONF_APP_ECHO_TCP_PORT (the port on which your echo server echoes TCP packets) must be defined"
00101 # endif
00102 #endif
00103 
00104 #ifndef MBED_CONF_APP_NTP_SERVER
00105 # define MBED_CONF_APP_NTP_SERVER "2.pool.ntp.org"
00106 #else
00107 # ifndef MBED_CONF_APP_NTP_PORT
00108 #  error "MBED_CONF_APP_NTP_PORT must be defined if MBED_CONF_APP_NTP_SERVER is defined"
00109 # endif
00110 #endif
00111 #ifndef MBED_CONF_APP_NTP_PORT
00112 # define MBED_CONF_APP_NTP_PORT 123
00113 #endif
00114 
00115 #ifndef MBED_CONF_APP_LOCAL_PORT
00116 # define MBED_CONF_APP_LOCAL_PORT 15
00117 #endif
00118 
00119 // UDP packet size limit for testing
00120 #ifndef MBED_CONF_APP_UDP_MAX_PACKET_SIZE
00121 #  define MBED_CONF_APP_UDP_MAX_PACKET_SIZE 1024
00122 #endif
00123 
00124 // The maximum size of UDP data fragmented across
00125 // multiple packets
00126 #ifndef MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE
00127 # define MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE 1500
00128 #endif
00129 
00130 // TCP packet size limit for testing
00131 #ifndef MBED_CONF_APP_MBED_CONF_APP_TCP_MAX_PACKET_SIZE
00132 # define MBED_CONF_APP_TCP_MAX_PACKET_SIZE 1500
00133 #endif
00134 
00135 // The number of retries for UDP exchanges
00136 #define NUM_UDP_RETRIES 5
00137 
00138 // How long to wait for stuff to travel in the async echo tests
00139 #define ASYNC_TEST_WAIT_TIME 10000
00140 
00141 // The maximum number of sockets that can be open at one time
00142 #define MAX_NUM_SOCKETS 7
00143 
00144 // ----------------------------------------------------------------
00145 // PRIVATE VARIABLES
00146 // ----------------------------------------------------------------
00147 
00148 #ifdef FEATURE_COMMON_PAL
00149 // Lock for debug prints
00150 static Mutex mtx;
00151 #endif
00152 
00153 // An instance of the cellular interface
00154 static UbloxATCellularInterface *interface =
00155        new UbloxATCellularInterface(MDMTXD, MDMRXD,
00156                                     MBED_CONF_UBLOX_CELL_BAUD_RATE,
00157                                     MBED_CONF_APP_DEBUG_ON);
00158 
00159 // Connection flag
00160 static bool connection_has_gone_down = false;
00161 
00162 // Data to exchange
00163 static const char send_data[] =  "_____0000:0123456789012345678901234567890123456789"
00164                                  "01234567890123456789012345678901234567890123456789"
00165                                  "_____0100:0123456789012345678901234567890123456789"
00166                                  "01234567890123456789012345678901234567890123456789"
00167                                  "_____0200:0123456789012345678901234567890123456789"
00168                                  "01234567890123456789012345678901234567890123456789"
00169                                  "_____0300:0123456789012345678901234567890123456789"
00170                                  "01234567890123456789012345678901234567890123456789"
00171                                  "_____0400:0123456789012345678901234567890123456789"
00172                                  "01234567890123456789012345678901234567890123456789"
00173                                  "_____0500:0123456789012345678901234567890123456789"
00174                                  "01234567890123456789012345678901234567890123456789"
00175                                  "_____0600:0123456789012345678901234567890123456789"
00176                                  "01234567890123456789012345678901234567890123456789"
00177                                  "_____0700:0123456789012345678901234567890123456789"
00178                                  "01234567890123456789012345678901234567890123456789"
00179                                  "_____0800:0123456789012345678901234567890123456789"
00180                                  "01234567890123456789012345678901234567890123456789"
00181                                  "_____0900:0123456789012345678901234567890123456789"
00182                                  "01234567890123456789012345678901234567890123456789"
00183                                  "_____1000:0123456789012345678901234567890123456789"
00184                                  "01234567890123456789012345678901234567890123456789"
00185                                  "_____1100:0123456789012345678901234567890123456789"
00186                                  "01234567890123456789012345678901234567890123456789"
00187                                  "_____1200:0123456789012345678901234567890123456789"
00188                                  "01234567890123456789012345678901234567890123456789"
00189                                  "_____1300:0123456789012345678901234567890123456789"
00190                                  "01234567890123456789012345678901234567890123456789"
00191                                  "_____1400:0123456789012345678901234567890123456789"
00192                                  "01234567890123456789012345678901234567890123456789"
00193                                  "_____1500:0123456789012345678901234567890123456789"
00194                                  "01234567890123456789012345678901234567890123456789"
00195                                  "_____1600:0123456789012345678901234567890123456789"
00196                                  "01234567890123456789012345678901234567890123456789"
00197                                  "_____1700:0123456789012345678901234567890123456789"
00198                                  "01234567890123456789012345678901234567890123456789"
00199                                  "_____1800:0123456789012345678901234567890123456789"
00200                                  "01234567890123456789012345678901234567890123456789"
00201                                  "_____1900:0123456789012345678901234567890123456789"
00202                                  "01234567890123456789012345678901234567890123456789"
00203                                  "_____2000:0123456789012345678901234567890123456789"
00204                                  "01234567890123456789012345678901234567890123456789";
00205 
00206 // ----------------------------------------------------------------
00207 // PRIVATE FUNCTIONS
00208 // ----------------------------------------------------------------
00209 
00210 #ifdef FEATURE_COMMON_PAL
00211 // Locks for debug prints
00212 static void lock()
00213 {
00214     mtx.lock();
00215 }
00216 
00217 static void unlock()
00218 {
00219     mtx.unlock();
00220 }
00221 #endif
00222 
00223 // Callback in case the connection goes down
00224 static void connection_down_cb(nsapi_error_t err)
00225 {
00226     connection_has_gone_down = true;
00227 }
00228 
00229 #ifdef MBED_CONF_APP_ECHO_SERVER
00230 // Make sure that size is greater than 0 and no more than limit,
00231 // useful since, when moduloing a very large number number,
00232 // compilers sometimes screw up and produce a small *negative*
00233 // number.  Who knew?  For example, GCC decided that
00234 // 492318453 (0x1d582ef5) modulo 508 was -47 (0xffffffd1).
00235 static int fix (int size, int limit)
00236 {
00237     if (size <= 0) {
00238         size = limit / 2; // better than 1
00239     } else if (size > limit) {
00240         size = limit;
00241     }
00242 
00243     return size;
00244 }
00245 
00246 // Do a UDP socket echo test to a given host of a given packet size
00247 static void do_udp_echo(UDPSocket *sock, SocketAddress *host_address, int size)
00248 {
00249     bool success = false;
00250     void * recv_data = malloc (size);
00251     SocketAddress sender_address;
00252     TEST_ASSERT(recv_data != NULL);
00253 
00254     // Retry this a few times, don't want to fail due to a flaky link
00255     for (int x = 0; !success && (x < NUM_UDP_RETRIES); x++) {
00256         tr_debug("Echo testing UDP packet size %d byte(s), try %d.", size, x + 1);
00257         if ((sock->sendto(*host_address, (void*) send_data, size) == size) &&
00258             (sock->recvfrom(&sender_address, recv_data, size) == size)) {
00259             TEST_ASSERT (memcmp(send_data, recv_data, size) == 0);
00260             TEST_ASSERT (strcmp(sender_address.get_ip_address(), host_address->get_ip_address()) == 0);
00261             TEST_ASSERT (sender_address.get_port() == host_address->get_port());
00262             success = true;
00263         }
00264     }
00265     TEST_ASSERT (success);
00266     TEST_ASSERT(!connection_has_gone_down);
00267 
00268     free (recv_data);
00269 }
00270 
00271 // The asynchronous callback
00272 static void async_cb(bool *callback_triggered)
00273 {
00274 
00275     TEST_ASSERT (callback_triggered != NULL);
00276     *callback_triggered = true;
00277 }
00278 
00279 // Do a UDP echo but using the asynchronous interface; we can exchange
00280 // packets longer in size than one UDP packet this way
00281 static void do_udp_echo_async(UDPSocket *sock, SocketAddress *host_address,
00282                               int size, bool *callback_triggered)
00283 {
00284     void * recv_data = malloc (size);
00285     int recv_size = 0;
00286     SocketAddress sender_address;
00287     Timer timer;
00288     int x, y, z;
00289     TEST_ASSERT(recv_data != NULL);
00290 
00291     *callback_triggered = false;
00292     for (y = 0; (recv_size < size) && (y < NUM_UDP_RETRIES); y++) {
00293         tr_debug("Echo testing UDP packet size %d byte(s) async, try %d.", size, y + 1);
00294         recv_size = 0;
00295         // Retry this a few times, don't want to fail due to a flaky link
00296         if (sock->sendto(*host_address, (void *) send_data, size) == size) {
00297             // Wait for all the echoed data to arrive
00298             timer.start();
00299             while ((recv_size < size) && (timer.read_ms() < ASYNC_TEST_WAIT_TIME)) {
00300                 if (*callback_triggered) {
00301                     *callback_triggered = false;
00302                     x = sock->recvfrom(&sender_address, (char *) recv_data + recv_size, size);
00303                     if (x > 0) {
00304                         recv_size += x;
00305                     }
00306                     tr_debug("%d byte(s) echoed back so far, %d to go.", recv_size, size - recv_size);
00307                     TEST_ASSERT(strcmp(sender_address.get_ip_address(), host_address->get_ip_address()) == 0);
00308                     TEST_ASSERT(sender_address.get_port() == host_address->get_port());
00309                 }
00310                 wait_ms(10);
00311             }
00312             timer.stop();
00313             timer.reset();
00314 
00315             // If everything arrived back, check it's the same as we sent
00316             if (recv_size == size) {
00317                 z = memcmp(send_data, recv_data, size);
00318                 if (z != 0) {
00319                     tr_debug("WARNING: mismatch, retrying");
00320                     tr_debug("Sent %d, |%*.*s|", size, size, size, send_data);
00321                     tr_debug("Rcvd %d, |%*.*s|", size, size, size, (char *) recv_data);
00322                     // If things don't match, it could be due to data loss (this is UDP
00323                     // you know...), so set recv_size to 0 to cause another try
00324                     recv_size = 0;
00325                 }
00326             }
00327         }
00328     }
00329 
00330     TEST_ASSERT(recv_size == size);
00331     TEST_ASSERT(!connection_has_gone_down);
00332 
00333     free (recv_data);
00334 }
00335 
00336 // Send an entire TCP data buffer until done
00337 static int sendAll(TCPSocket *sock,  const char *data, int size)
00338 {
00339     int x;
00340     int count = 0;
00341     Timer timer;
00342 
00343     timer.start();
00344     while ((count < size) && (timer.read_ms() < 10000)) {
00345         x = sock->send(data + count, size - count);
00346         if (x > 0) {
00347             count += x;
00348             tr_debug("%d byte(s) sent, %d left to send.", count, size - count);
00349         }
00350         wait_ms(10);
00351     }
00352     timer.stop();
00353 
00354     return count;
00355 }
00356 
00357 // Do a TCP echo but using the asynchronous interface
00358 static void do_tcp_echo_async(TCPSocket *sock, int size, bool *callback_triggered)
00359 {
00360     void * recv_data = malloc (size);
00361     int recv_size = 0;
00362     int x, y;
00363     Timer timer;
00364     TEST_ASSERT(recv_data != NULL);
00365 
00366     *callback_triggered = false;
00367     tr_debug("Echo testing TCP packet size %d byte(s) async.", size);
00368     TEST_ASSERT (sendAll(sock, send_data, size) == size);
00369 
00370     // Wait for all the echoed data to arrive
00371     timer.start();
00372     while ((recv_size < size) && (timer.read_ms() < ASYNC_TEST_WAIT_TIME)) {
00373         if (*callback_triggered) {
00374             *callback_triggered = false;
00375             x = sock->recv((char *) recv_data + recv_size, size);
00376             TEST_ASSERT(x > 0);
00377             recv_size += x;
00378             tr_debug("%d byte(s) echoed back so far, %d to go.", recv_size, size - recv_size);
00379         }
00380         wait_ms(10);
00381     }
00382     TEST_ASSERT(recv_size == size);
00383     y = memcmp(send_data, recv_data, size);
00384     if (y != 0) {
00385         tr_debug("Sent %d, |%*.*s|", size, size, size, send_data);
00386         tr_debug("Rcvd %d, |%*.*s|", size, size, size, (char *) recv_data);
00387         TEST_ASSERT(false);
00388     }
00389     timer.stop();
00390 
00391     TEST_ASSERT(!connection_has_gone_down);
00392 
00393     free (recv_data);
00394 }
00395 #endif
00396 
00397 // Get NTP time from a socket
00398 static void do_ntp_sock (UDPSocket *sock, SocketAddress ntp_address)
00399 {
00400     char ntp_values[48] = { 0 };
00401     time_t timestamp = 0;
00402     struct tm *localTime;
00403     char timeString[25];
00404     time_t TIME1970 = 2208988800U;
00405     int len;
00406     bool comms_done = false;
00407 
00408     ntp_values[0] = '\x1b';
00409 
00410     // Retry this a few times, don't want to fail due to a flaky link
00411     for (unsigned int x = 0; !comms_done && (x < NUM_UDP_RETRIES); x++) {
00412         sock->sendto(ntp_address, (void*) ntp_values, sizeof(ntp_values));
00413         len = sock->recvfrom(&ntp_address, (void*) ntp_values, sizeof(ntp_values));
00414         if (len > 0) {
00415             comms_done = true;
00416         }
00417     }
00418     TEST_ASSERT (comms_done);
00419 
00420     tr_debug("UDP: %d byte(s) returned by NTP server.", len);
00421     if (len >= 43) {
00422         timestamp |= ((int) *(ntp_values + 40)) << 24;
00423         timestamp |= ((int) *(ntp_values + 41)) << 16;
00424         timestamp |= ((int) *(ntp_values + 42)) << 8;
00425         timestamp |= ((int) *(ntp_values + 43));
00426         timestamp -= TIME1970;
00427         srand (timestamp);
00428         tr_debug("srand() called");
00429         localTime = localtime(&timestamp);
00430         if (localTime) {
00431             if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
00432                 printf("NTP timestamp is %s.\n", timeString);
00433             }
00434         }
00435     }
00436 }
00437 
00438 // Get NTP time
00439 static void do_ntp(UbloxATCellularInterface *interface)
00440 {
00441     UDPSocket sock;
00442     SocketAddress host_address;
00443 
00444     TEST_ASSERT(sock.open(interface) == 0)
00445 
00446     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_NTP_SERVER, &host_address) == 0);
00447     host_address.set_port(MBED_CONF_APP_NTP_PORT);
00448 
00449     tr_debug("UDP: NIST server %s address: %s on port %d.", MBED_CONF_APP_NTP_SERVER,
00450              host_address.get_ip_address(), host_address.get_port());
00451 
00452     sock.set_timeout(10000);
00453 
00454     do_ntp_sock(&sock, host_address);
00455 
00456     sock.close();
00457 }
00458 
00459 // Use a connection, checking that it is good
00460 static void use_connection(UbloxATCellularInterface *interface)
00461 {
00462     const char * ip_address = interface->get_ip_address();
00463     const char * net_mask = interface->get_netmask();
00464     const char * gateway = interface->get_gateway();
00465 
00466     TEST_ASSERT(interface->is_connected());
00467 
00468     TEST_ASSERT(ip_address != NULL);
00469     tr_debug ("IP address %s.", ip_address);
00470     TEST_ASSERT(net_mask == NULL);
00471     tr_debug ("Net mask %s.", net_mask);
00472     TEST_ASSERT(gateway != NULL);
00473     tr_debug ("Gateway %s.", gateway);
00474 
00475     do_ntp(interface);
00476     TEST_ASSERT(!connection_has_gone_down);
00477 }
00478 
00479 // Drop a connection and check that it has dropped
00480 static void drop_connection(UbloxATCellularInterface *interface)
00481 {
00482     TEST_ASSERT(interface->disconnect() == 0);
00483     TEST_ASSERT(connection_has_gone_down);
00484     connection_has_gone_down = false;
00485     TEST_ASSERT(!interface->is_connected());
00486 }
00487 
00488 // ----------------------------------------------------------------
00489 // TESTS
00490 // ----------------------------------------------------------------
00491 
00492 // Tests of stuff in the base class
00493 void test_base_class() {
00494     const char *imei;
00495     const char *meid;
00496     const char *imsi;
00497     const char *iccid;
00498     int rssi;
00499     
00500     // Power-up the modem
00501     interface->init();
00502     
00503     // Check all of the IMEI, MEID, IMSI and ICCID calls
00504     imei = interface->imei();
00505     if (imei != NULL) {
00506         tr_debug("IMEI is %s.", imei);
00507     } else {
00508         TEST_ASSERT(false);
00509     }
00510     
00511     meid = interface->meid();
00512     if (meid != NULL) {
00513         tr_debug("MEID is %s.", meid);
00514     } else {
00515         TEST_ASSERT(false);
00516     }
00517     
00518     imsi = interface->imsi();
00519     if (imsi != NULL) {
00520         tr_debug("IMSI is %s.", imsi);
00521     } else {
00522         TEST_ASSERT(false);
00523     }
00524     
00525     iccid = interface->iccid();
00526     if (iccid != NULL) {
00527         tr_debug("ICCID is %s.", iccid);
00528     } else {
00529         TEST_ASSERT(false);
00530     }
00531     
00532     // Check the RSSI call at least doesn't assert
00533     rssi = interface->rssi();
00534     tr_debug("RSSI is %d dBm.", rssi);
00535     
00536     // Now connect and check that the answers for the
00537     // static fields are the same while connected
00538     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00539                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00540     
00541     TEST_ASSERT(strcmp(imei, interface->imei()) == 0);
00542     TEST_ASSERT(strcmp(meid, interface->meid()) == 0);
00543     TEST_ASSERT(strcmp(imsi, interface->imsi()) == 0);
00544     TEST_ASSERT(strcmp(iccid, interface->iccid()) == 0);
00545 
00546     // Check that the RSSI call still doesn't assert
00547     rssi = interface->rssi();
00548     tr_debug("RSSI is %d dBm.", rssi);
00549 }
00550 
00551 // Call srand() using the NTP server
00552 void test_set_randomise() {
00553     UDPSocket sock;
00554     SocketAddress host_address;
00555 
00556     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00557                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00558     do_ntp(interface);
00559     TEST_ASSERT(!connection_has_gone_down);
00560     drop_connection(interface);
00561 }
00562 
00563 #ifdef MBED_CONF_APP_ECHO_SERVER
00564 
00565 // Test UDP data exchange
00566 void test_udp_echo() {
00567     UDPSocket sock;
00568     SocketAddress host_address;
00569     SocketAddress local_address;
00570     int x;
00571     int size;
00572 
00573     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00574                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00575 
00576     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
00577     host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
00578 
00579     tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
00580              host_address.get_ip_address(), host_address.get_port());
00581 
00582     TEST_ASSERT(sock.open(interface) == 0)
00583 
00584     // Do a bind, just for the helluvit
00585     local_address.set_port(MBED_CONF_APP_LOCAL_PORT);
00586     TEST_ASSERT(sock.bind(local_address) == 0);
00587 
00588     sock.set_timeout(10000);
00589 
00590     // Test min, max, and some random sizes in-between
00591     do_udp_echo(&sock, &host_address, 1);
00592     do_udp_echo(&sock, &host_address, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
00593     for (x = 0; x < 10; x++) {
00594         size = (rand() % MBED_CONF_APP_UDP_MAX_PACKET_SIZE) + 1;
00595         size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
00596         do_udp_echo(&sock, &host_address, size);
00597     }
00598 
00599     sock.close();
00600     drop_connection(interface);
00601     tr_debug("%d UDP packets of size up to %d byte(s) echoed successfully.",
00602              x, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
00603 }
00604 
00605 // Test many different sizes of UDP data arriving at once
00606 void  test_udp_echo_recv_sizes() {
00607     UDPSocket sock;
00608     SocketAddress host_address;
00609     int x, y, z;
00610     int size;
00611     int tries = 0;
00612     unsigned int offset;
00613     char * recv_data;
00614     bool packetLoss;
00615     bool sendSuccess;
00616     Timer timer;
00617 
00618     interface->deinit();
00619     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00620                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00621 
00622     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
00623     host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
00624 
00625     tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
00626              host_address.get_ip_address(), host_address.get_port());
00627 
00628     TEST_ASSERT(sock.open(interface) == 0)
00629 
00630     do {
00631         tr_debug("--- UDP packet size test, test try %d, flushing input buffers", tries + 1);
00632         // First of all, clear any junk from the socket
00633         sock.set_timeout(1000);
00634         recv_data = (char *) malloc (MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
00635         TEST_ASSERT(recv_data != NULL);
00636         while (sock.recvfrom(&host_address, (void *) recv_data, MBED_CONF_APP_UDP_MAX_PACKET_SIZE) > 0) {
00637             // Throw it away
00638         }
00639         free (recv_data);
00640 
00641         sock.set_timeout(10000);
00642 
00643         // Throw random sized UDP packets up...
00644         x = 0;
00645         offset = 0;
00646         while (offset < sizeof (send_data)) {
00647             size = (rand() % (MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2)) + 1;
00648             size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2);
00649             if (offset + size > sizeof (send_data)) {
00650                 size = sizeof (send_data) - offset;
00651             }
00652             sendSuccess = false;
00653             for (y = 0; !sendSuccess && (y < NUM_UDP_RETRIES); y++) {
00654                 tr_debug("Sending UDP packet number %d, size %d byte(s), send try %d.", x + 1, size, y + 1);
00655                 if (sock.sendto(host_address, (void *) (send_data + offset), size) == size) {
00656                     sendSuccess = true;
00657                     offset += size;
00658                 }
00659             }
00660             TEST_ASSERT(sendSuccess);
00661             x++;
00662         }
00663         tr_debug("--- All UDP packets sent");
00664 
00665         // ...and capture them all again afterwards
00666         recv_data = (char *) malloc (sizeof (send_data));
00667         TEST_ASSERT(recv_data != NULL);
00668         memset (recv_data, 0, sizeof (send_data));
00669         size = 0;
00670         y = 0;
00671         packetLoss = false;
00672         timer.start();
00673         while ((size < (int) sizeof (send_data)) && (timer.read_ms() < 10000)) {
00674             y = sock.recvfrom(&host_address, (void *) (recv_data + size), sizeof (send_data) - size);
00675             if (y > 0) {
00676                 size += y;
00677             }
00678         }
00679         timer.stop();
00680         timer.reset();
00681         tr_debug(   "--- Either received everything back or timed out waiting");
00682 
00683         // Check that we reassembled everything correctly
00684         if (size == sizeof (send_data)) {
00685             for (x = 0; ((*(recv_data + x) == *(send_data + x))) && (x < (int) sizeof (send_data)); x++) {
00686             }
00687             if (x != sizeof (send_data)) {
00688                 y = x - 5;
00689                 if (y < 0) {
00690                     y = 0;
00691                 }
00692                 z = 10;
00693                 if (y + z > (int) sizeof (send_data)) {
00694                     z = sizeof(send_data) - y;
00695                 }
00696                 tr_debug("   --- Difference at character %d (send \"%*.*s\", recv \"%*.*s\")",
00697                          x + 1, z, z, send_data + y, z, z, recv_data + y);
00698                 packetLoss = true;
00699             }
00700         } else {
00701             tr_debug("   --- %d bytes missing (%d bytes received when %d were expected))",
00702                       sizeof (send_data) - size, size, sizeof (send_data));
00703             packetLoss = true;
00704         }
00705         free (recv_data);
00706         tries++;
00707     } while (packetLoss && (tries < NUM_UDP_RETRIES));
00708 
00709     TEST_ASSERT(!packetLoss);
00710     TEST_ASSERT(!connection_has_gone_down);
00711     sock.close();
00712     drop_connection(interface);
00713 }
00714 
00715 // Test UDP data exchange via the asynchronous sigio() mechanism
00716 void test_udp_echo_async() {
00717     UDPSocket sock;
00718     SocketAddress host_address;
00719     SocketAddress local_address;
00720     bool callback_triggered = false;
00721     int x;
00722     int size;
00723 
00724     interface->deinit();
00725     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00726                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00727 
00728     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
00729     host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
00730 
00731     tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
00732              host_address.get_ip_address(), host_address.get_port());
00733 
00734     TEST_ASSERT(sock.open(interface) == 0)
00735 
00736     // Set up the async callback and set the timeout to zero
00737     sock.sigio(callback(async_cb, &callback_triggered));
00738     sock.set_timeout(0);
00739 
00740     // Test min, max, and some random sizes in-between
00741     // and this time allow the UDP packets to be fragmented
00742     do_udp_echo_async(&sock, &host_address, 1, &callback_triggered);
00743     do_udp_echo_async(&sock, &host_address, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE,
00744                       &callback_triggered);
00745     for (x = 0; x < 10; x++) {
00746         size = (rand() % MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE) + 1;
00747         size = fix(size, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE);
00748         do_udp_echo_async(&sock, &host_address, size, &callback_triggered);
00749     }
00750 
00751     sock.close();
00752 
00753     drop_connection(interface);
00754 
00755     tr_debug("%d UDP packets of size up to %d byte(s) echoed asynchronously and successfully.",
00756              x, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE);
00757 }
00758 
00759 // Test many different sizes of TCP data arriving at once
00760 void  test_tcp_echo_recv_sizes() {
00761     TCPSocket sock;
00762     SocketAddress host_address;
00763     int x, y, z;
00764     int size;
00765     unsigned int offset;
00766     char * recv_data;
00767     Timer timer;
00768 
00769     interface->deinit();
00770     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00771                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00772 
00773     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
00774     host_address.set_port(MBED_CONF_APP_ECHO_TCP_PORT);
00775 
00776     tr_debug("TCP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
00777              host_address.get_ip_address(), host_address.get_port());
00778 
00779     TEST_ASSERT(sock.open(interface) == 0)
00780 
00781     TEST_ASSERT(sock.connect(host_address) == 0);
00782 
00783     sock.set_timeout(10000);
00784 
00785     // Throw random sized TCP packets up...
00786     x = 0;
00787     offset = 0;
00788     while (offset < sizeof (send_data)) {
00789         size = (rand() % (MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2)) + 1;
00790         size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2);
00791         if (offset + size > sizeof (send_data)) {
00792             size = sizeof (send_data) - offset;
00793         }
00794         tr_debug("Sending TCP packet number %d, size %d byte(s).", x + 1, size);
00795         TEST_ASSERT(sendAll(&sock, (send_data + offset), size) == size);
00796         offset += size;
00797         x++;
00798     }
00799 
00800     // ...and capture them all again afterwards
00801     recv_data = (char *) malloc (sizeof (send_data));
00802     TEST_ASSERT(recv_data != NULL);
00803     memset (recv_data, 0, sizeof (send_data));
00804     size = 0;
00805     x = 0;
00806     timer.start();
00807     while ((size < (int) sizeof (send_data)) && (timer.read_ms() < 30000)) {
00808         y = sock.recv((void *) (recv_data + size), sizeof (send_data) - size);
00809         tr_debug("Received TCP packet number %d, size %d byte(s).", x, y);
00810         size += y;
00811         x++;
00812     }
00813     timer.stop();
00814     timer.reset();
00815 
00816     // Check that we reassembled everything correctly
00817     for (x = 0; ((*(recv_data + x) == *(send_data + x))) && (x < (int) sizeof (send_data)); x++) {
00818     }
00819     if (x != sizeof (send_data)) {
00820         y = x - 5;
00821         if (y < 0) {
00822             y = 0;
00823         }
00824         z = 10;
00825         if (y + z > (int) sizeof (send_data)) {
00826             z = sizeof(send_data) - y;
00827         }
00828         tr_debug("Difference at character %d (send \"%*.*s\", recv \"%*.*s\")",
00829                  x + 1, z, z, send_data + y, z, z, recv_data + y);
00830         TEST_ASSERT(false);
00831     }
00832     free (recv_data);
00833 
00834     TEST_ASSERT(!connection_has_gone_down);
00835     sock.close();
00836     drop_connection(interface);
00837 }
00838 
00839 // Test TCP data exchange via the asynchronous sigio() mechanism
00840 void test_tcp_echo_async() {
00841     TCPSocket sock;
00842     SocketAddress host_address;
00843     bool callback_triggered = false;
00844     int x;
00845     int size;
00846 
00847     interface->deinit();
00848     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00849                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00850 
00851     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
00852     host_address.set_port(MBED_CONF_APP_ECHO_TCP_PORT);
00853 
00854     tr_debug("TCP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
00855              host_address.get_ip_address(), host_address.get_port());
00856 
00857     TEST_ASSERT(sock.open(interface) == 0)
00858 
00859     // Set up the async callback and set the timeout to zero
00860     sock.sigio(callback(async_cb, &callback_triggered));
00861     sock.set_timeout(0);
00862 
00863     TEST_ASSERT(sock.connect(host_address) == 0);
00864     // Test min, max, and some random sizes in-between
00865     do_tcp_echo_async(&sock, 1, &callback_triggered);
00866     do_tcp_echo_async(&sock, MBED_CONF_APP_TCP_MAX_PACKET_SIZE, &callback_triggered);
00867     for (x = 0; x < 10; x++) {
00868         size = (rand() % MBED_CONF_APP_TCP_MAX_PACKET_SIZE) + 1;
00869         size = fix(size, MBED_CONF_APP_TCP_MAX_PACKET_SIZE);
00870         do_tcp_echo_async(&sock, size, &callback_triggered);
00871     }
00872 
00873     sock.close();
00874 
00875     drop_connection(interface);
00876 
00877     tr_debug("%d TCP packets of size up to %d byte(s) echoed asynchronously and successfully.",
00878              x, MBED_CONF_APP_TCP_MAX_PACKET_SIZE);
00879 }
00880 #endif
00881 
00882 // Allocate max sockets
00883 void test_max_sockets() {
00884     UDPSocket sock[MAX_NUM_SOCKETS];
00885     UDPSocket sockNone;
00886     SocketAddress host_address;
00887 
00888     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00889                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00890 
00891     TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_NTP_SERVER, &host_address) == 0);
00892     host_address.set_port(MBED_CONF_APP_NTP_PORT);
00893 
00894     // Open the first socket and use it
00895     TEST_ASSERT(sock[0].open(interface) == 0)
00896     sock[0].set_timeout(10000);
00897     do_ntp_sock(&sock[0], host_address);
00898 
00899     // Check that we stop being able to get sockets at the max number
00900     for (int x = 1; x < (int) (sizeof (sock) / sizeof (sock[0])); x++) {
00901         TEST_ASSERT(sock[x].open(interface) == 0)
00902     }
00903     TEST_ASSERT(sockNone.open(interface) < 0);
00904 
00905     // Now use the last one
00906     sock[sizeof (sock) / sizeof (sock[0]) - 1].set_timeout(10000);
00907     do_ntp_sock(&sock[sizeof (sock) / sizeof (sock[0]) - 1], host_address);
00908 
00909     // Close all of the sockets
00910     for (int x = 0; x < (int) (sizeof (sock) / sizeof (sock[0])); x++) {
00911         TEST_ASSERT(sock[x].close() == 0);
00912     }
00913 
00914     drop_connection(interface);
00915 }
00916 
00917 // Connect with credentials included in the connect request
00918 void test_connect_credentials() {
00919 
00920     interface->deinit();
00921     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00922                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00923     use_connection(interface);
00924     drop_connection(interface);
00925 }
00926 
00927 // Test with credentials preset
00928 void test_connect_preset_credentials() {
00929 
00930     interface->deinit();
00931     TEST_ASSERT(interface->init(MBED_CONF_APP_DEFAULT_PIN));
00932     interface->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
00933                                MBED_CONF_APP_PASSWORD);
00934     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN) == 0);
00935     use_connection(interface);
00936     drop_connection(interface);
00937 }
00938 
00939 // Test adding and using a SIM pin, then removing it, using the pending
00940 // mechanism where the change doesn't occur until connect() is called
00941 void test_check_sim_pin_pending() {
00942 
00943     interface->deinit();
00944 
00945     // Enable PIN checking (which will use the current PIN)
00946     // and also flag that the PIN should be changed to MBED_CONF_APP_ALT_PIN,
00947     // then try connecting
00948     interface->set_sim_pin_check(true);
00949     interface->set_new_sim_pin(MBED_CONF_APP_ALT_PIN);
00950     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00951                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00952     use_connection(interface);
00953     drop_connection(interface);
00954     interface->deinit();
00955 
00956     // Now change the PIN back to what it was before
00957     interface->set_new_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
00958     TEST_ASSERT(interface->connect(MBED_CONF_APP_ALT_PIN, MBED_CONF_APP_APN,
00959                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00960     use_connection(interface);
00961     drop_connection(interface);
00962     interface->deinit();
00963 
00964     // Check that it was changed back, and this time
00965     // use the other way of entering the PIN
00966     interface->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
00967     TEST_ASSERT(interface->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
00968                                    MBED_CONF_APP_PASSWORD) == 0);
00969     use_connection(interface);
00970     drop_connection(interface);
00971     interface->deinit();
00972 
00973     // Remove PIN checking again and check that it no
00974     // longer matters what the PIN is
00975     interface->set_sim_pin_check(false);
00976     TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
00977                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00978     use_connection(interface);
00979     drop_connection(interface);
00980     interface->deinit();
00981     TEST_ASSERT(interface->init(NULL));
00982     TEST_ASSERT(interface->connect(MBED_CONF_APP_INCORRECT_PIN, MBED_CONF_APP_APN,
00983                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
00984     use_connection(interface);
00985     drop_connection(interface);
00986 
00987     // Put the SIM pin back to the correct value for any subsequent tests
00988     interface->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
00989 }
00990 
00991 // Test adding and using a SIM pin, then removing it, using the immediate
00992 // mechanism
00993 void test_check_sim_pin_immediate() {
00994 
00995     interface->deinit();
00996     interface->connection_status_cb(connection_down_cb);
00997 
00998     // Enable PIN checking (which will use the current PIN), change
00999     // the PIN to MBED_CONF_APP_ALT_PIN, then try connecting after powering on and
01000     // off the modem
01001     interface->set_sim_pin_check(true, true, MBED_CONF_APP_DEFAULT_PIN);
01002     interface->set_new_sim_pin(MBED_CONF_APP_ALT_PIN, true);
01003     interface->deinit();
01004     TEST_ASSERT(interface->init(NULL));
01005     TEST_ASSERT(interface->connect(MBED_CONF_APP_ALT_PIN, MBED_CONF_APP_APN,
01006                                    MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
01007     use_connection(interface);
01008     drop_connection(interface);
01009 
01010     interface->connection_status_cb(connection_down_cb);
01011 
01012     // Now change the PIN back to what it was before
01013     interface->set_new_sim_pin(MBED_CONF_APP_DEFAULT_PIN, true);
01014     interface->deinit();
01015     interface->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
01016     TEST_ASSERT(interface->init(NULL));
01017     TEST_ASSERT(interface->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
01018                                    MBED_CONF_APP_PASSWORD) == 0);
01019     use_connection(interface);
01020     drop_connection(interface);
01021 
01022     interface->connection_status_cb(connection_down_cb);
01023 
01024     // Remove PIN checking again and check that it no
01025     // longer matters what the PIN is
01026     interface->set_sim_pin_check(false, true);
01027     interface->deinit();
01028     TEST_ASSERT(interface->init(MBED_CONF_APP_INCORRECT_PIN));
01029     TEST_ASSERT(interface->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
01030                                    MBED_CONF_APP_PASSWORD) == 0);
01031     use_connection(interface);
01032     drop_connection(interface);
01033 
01034     // Put the SIM pin back to the correct value for any subsequent tests
01035     interface->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
01036 }
01037 
01038 // Test being able to connect with a local instance of the interface
01039 // NOTE: since this local instance will fiddle with bits of HW that the
01040 // static instance thought it owned, the static instance will no longer
01041 // work afterwards, hence this must be run as the last test in the list
01042 void test_connect_local_instance_last_test() {
01043 
01044     UbloxATCellularInterface *pLocalInterface = NULL;
01045 
01046     pLocalInterface = new UbloxATCellularInterface(MDMTXD, MDMRXD,
01047                                                    MBED_CONF_UBLOX_CELL_BAUD_RATE,
01048                                                    MBED_CONF_APP_DEBUG_ON);
01049     pLocalInterface->connection_status_cb(connection_down_cb);
01050 
01051     TEST_ASSERT(pLocalInterface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
01052                                          MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
01053     use_connection(pLocalInterface);
01054     drop_connection(pLocalInterface);
01055     delete pLocalInterface;
01056 
01057     pLocalInterface = new UbloxATCellularInterface(MDMTXD, MDMRXD,
01058                                                    MBED_CONF_UBLOX_CELL_BAUD_RATE,
01059                                                    MBED_CONF_APP_DEBUG_ON);
01060     pLocalInterface->connection_status_cb(connection_down_cb);
01061 
01062     TEST_ASSERT(pLocalInterface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
01063                                          MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
01064     use_connection(pLocalInterface);
01065     drop_connection(pLocalInterface);
01066     delete pLocalInterface;
01067 }
01068 
01069 // ----------------------------------------------------------------
01070 // TEST ENVIRONMENT
01071 // ----------------------------------------------------------------
01072 
01073 // Setup the test environment
01074 utest::v1::status_t test_setup(const size_t number_of_cases) {
01075     // Setup Greentea with a timeout
01076     GREENTEA_SETUP(960, "default_auto");
01077     return verbose_test_setup_handler(number_of_cases);
01078 }
01079 
01080 // IMPORTANT!!! if you make a change to the tests here you should
01081 // check whether the same change should be made to the tests under
01082 // the PPP interface.
01083 
01084 // Test cases
01085 Case cases[] = {
01086     Case("Base class tests", test_base_class),
01087     Case("Set randomise", test_set_randomise),
01088 #ifdef MBED_CONF_APP_ECHO_SERVER
01089     Case("UDP echo test", test_udp_echo),
01090 # ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
01091     Case("UDP recv sizes", test_udp_echo_recv_sizes),
01092 # endif
01093     Case("UDP async echo test", test_udp_echo_async),
01094 # ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
01095     Case("TCP recv sizes", test_tcp_echo_recv_sizes),
01096 # endif
01097     Case("TCP async echo test", test_tcp_echo_async),
01098 #endif
01099 #ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
01100     Case("Alloc max sockets", test_max_sockets),
01101 #endif
01102     Case("Connect with credentials", test_connect_credentials),
01103     Case("Connect with preset credentials", test_connect_preset_credentials),
01104 #if MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
01105     Case("Check SIM pin, pending", test_check_sim_pin_pending),
01106     Case("Check SIM pin, immediate", test_check_sim_pin_immediate),
01107 #endif
01108 #ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 for this
01109     Case("Connect using local instance, must be last test", test_connect_local_instance_last_test)
01110 #endif
01111 };
01112 
01113 Specification specification(test_setup, cases);
01114 
01115 // ----------------------------------------------------------------
01116 // MAIN
01117 // ----------------------------------------------------------------
01118 
01119 int main() {
01120 
01121 #ifdef FEATURE_COMMON_PAL
01122     mbed_trace_init();
01123 
01124     mbed_trace_mutex_wait_function_set(lock);
01125     mbed_trace_mutex_release_function_set(unlock);
01126 #endif
01127 
01128     interface->connection_status_cb(connection_down_cb);
01129 
01130     // Run tests
01131     return !Harness::run(specification);
01132 }
01133 
01134 // End Of File