Implementation of the CellularInterface for u-blox C027 and C030 (non-N2xx flavour) modems that uses the IP stack on-board the cellular modem, hence not requiring LWIP (and so less RAM) and allowing any AT command exchanges to be carried out at the same time as data transfers (since the modem remains in AT mode all the time). This library may be used from mbed 5.5 onwards. If you need to use SMS, USSD or access the modem file system at the same time as using the CellularInterface then use ublox-at-cellular-interface-ext instead.

Dependents:   example-ublox-cellular-interface example-ublox-cellular-interface_r410M example-ublox-mbed-client example-ublox-cellular-interface ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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