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

Committer:
RobMeades
Date:
Mon Jun 12 21:32:21 2017 +0000
Revision:
0:7ccf0e7e8a83
Child:
1:bc228becc45d
Initial commit, not yet compiling but I'm tired of doing everything in the on-line IDE so I need to publish to take the code off-line.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RobMeades 0:7ccf0e7e8a83 1 #include "ublox_modem_driver/UbloxATCellularInterface.h"
RobMeades 0:7ccf0e7e8a83 2 #include "greentea-client/test_env.h"
RobMeades 0:7ccf0e7e8a83 3 #include "unity.h"
RobMeades 0:7ccf0e7e8a83 4 #include "utest.h"
RobMeades 0:7ccf0e7e8a83 5 #include "UDPSocket.h"
RobMeades 0:7ccf0e7e8a83 6 #ifdef FEATURE_COMMON_PAL
RobMeades 0:7ccf0e7e8a83 7 #include "mbed_trace.h"
RobMeades 0:7ccf0e7e8a83 8 #define TRACE_GROUP "TEST"
RobMeades 0:7ccf0e7e8a83 9 #else
RobMeades 0:7ccf0e7e8a83 10 #define tr_debug(format, ...) debug(format, ## __VA_ARGS__)
RobMeades 0:7ccf0e7e8a83 11 #define tr_info(format, ...) debug(format, ## __VA_ARGS__)
RobMeades 0:7ccf0e7e8a83 12 #define tr_warn(format, ...) debug(format, ## __VA_ARGS__)
RobMeades 0:7ccf0e7e8a83 13 #define tr_error(format, ...) debug(format, ## __VA_ARGS__)
RobMeades 0:7ccf0e7e8a83 14 #endif
RobMeades 0:7ccf0e7e8a83 15
RobMeades 0:7ccf0e7e8a83 16 using namespace utest::v1;
RobMeades 0:7ccf0e7e8a83 17
RobMeades 0:7ccf0e7e8a83 18 // IMPORTANT!!! if you make a change to the tests here you should
RobMeades 0:7ccf0e7e8a83 19 // check whether the same change should be made to the tests under
RobMeades 0:7ccf0e7e8a83 20 // the GENERIC driver.
RobMeades 0:7ccf0e7e8a83 21
RobMeades 0:7ccf0e7e8a83 22 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 23 // COMPILE-TIME MACROS
RobMeades 0:7ccf0e7e8a83 24 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 25
RobMeades 0:7ccf0e7e8a83 26 // These macros can be overridden with an mbed_app.json file and
RobMeades 0:7ccf0e7e8a83 27 // contents of the following form:
RobMeades 0:7ccf0e7e8a83 28 //
RobMeades 0:7ccf0e7e8a83 29 //{
RobMeades 0:7ccf0e7e8a83 30 // "config": {
RobMeades 0:7ccf0e7e8a83 31 // "default-pin": {
RobMeades 0:7ccf0e7e8a83 32 // "value": "\"1234\""
RobMeades 0:7ccf0e7e8a83 33 // }
RobMeades 0:7ccf0e7e8a83 34 //}
RobMeades 0:7ccf0e7e8a83 35 //
RobMeades 0:7ccf0e7e8a83 36 // See the template_mbed_app.txt in this directory for a fuller example.
RobMeades 0:7ccf0e7e8a83 37
RobMeades 0:7ccf0e7e8a83 38 // Whether debug trace is on
RobMeades 0:7ccf0e7e8a83 39 #ifndef MBED_CONF_APP_DEBUG_ON
RobMeades 0:7ccf0e7e8a83 40 # define MBED_CONF_APP_DEBUG_ON false
RobMeades 0:7ccf0e7e8a83 41 #endif
RobMeades 0:7ccf0e7e8a83 42
RobMeades 0:7ccf0e7e8a83 43 // Run the SIM change tests, which require the DEFAULT_PIN
RobMeades 0:7ccf0e7e8a83 44 // above to be correct for the board on which the test
RobMeades 0:7ccf0e7e8a83 45 // is being run (and the SIM PIN to be disabled before tests run).
RobMeades 0:7ccf0e7e8a83 46 #ifndef MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
RobMeades 0:7ccf0e7e8a83 47 # define MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS 0
RobMeades 0:7ccf0e7e8a83 48 #endif
RobMeades 0:7ccf0e7e8a83 49
RobMeades 0:7ccf0e7e8a83 50 #if MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
RobMeades 0:7ccf0e7e8a83 51 # ifndef MBED_CONF_APP_DEFAULT_PIN
RobMeades 0:7ccf0e7e8a83 52 # error "MBED_CONF_APP_DEFAULT_PIN must be defined to run the SIM tests"
RobMeades 0:7ccf0e7e8a83 53 # endif
RobMeades 0:7ccf0e7e8a83 54 # ifndef MBED_CONF_APP_ALT_PIN
RobMeades 0:7ccf0e7e8a83 55 # error "MBED_CONF_APP_ALT_PIN must be defined to run the SIM tests"
RobMeades 0:7ccf0e7e8a83 56 # endif
RobMeades 0:7ccf0e7e8a83 57 # ifndef MBED_CONF_APP_INCORRECT_PIN
RobMeades 0:7ccf0e7e8a83 58 # error "MBED_CONF_APP_INCORRECT_PIN must be defined to run the SIM tests"
RobMeades 0:7ccf0e7e8a83 59 # endif
RobMeades 0:7ccf0e7e8a83 60 #endif
RobMeades 0:7ccf0e7e8a83 61
RobMeades 0:7ccf0e7e8a83 62 // The credentials of the SIM in the board.
RobMeades 0:7ccf0e7e8a83 63 #ifndef MBED_CONF_APP_DEFAULT_PIN
RobMeades 0:7ccf0e7e8a83 64 // Note: if PIN is enabled on your SIM, or you wish to run the SIM PIN change
RobMeades 0:7ccf0e7e8a83 65 // tests, you must define the PIN for your SIM (see note above on using
RobMeades 0:7ccf0e7e8a83 66 // mbed_app.json to do so).
RobMeades 0:7ccf0e7e8a83 67 # define MBED_CONF_APP_DEFAULT_PIN "0000"
RobMeades 0:7ccf0e7e8a83 68 #endif
RobMeades 0:7ccf0e7e8a83 69 #ifndef MBED_CONF_APP_APN
RobMeades 0:7ccf0e7e8a83 70 # define MBED_CONF_APP_APN NULL
RobMeades 0:7ccf0e7e8a83 71 #endif
RobMeades 0:7ccf0e7e8a83 72 #ifndef MBED_CONF_APP_USERNAME
RobMeades 0:7ccf0e7e8a83 73 # define MBED_CONF_APP_USERNAME NULL
RobMeades 0:7ccf0e7e8a83 74 #endif
RobMeades 0:7ccf0e7e8a83 75 #ifndef MBED_CONF_APP_PASSWORD
RobMeades 0:7ccf0e7e8a83 76 # define MBED_CONF_APP_PASSWORD NULL
RobMeades 0:7ccf0e7e8a83 77 #endif
RobMeades 0:7ccf0e7e8a83 78
RobMeades 0:7ccf0e7e8a83 79 // Alternate PIN to use during pin change testing
RobMeades 0:7ccf0e7e8a83 80 #ifndef MBED_CONF_APP_ALT_PIN
RobMeades 0:7ccf0e7e8a83 81 # define MBED_CONF_APP_ALT_PIN "9876"
RobMeades 0:7ccf0e7e8a83 82 #endif
RobMeades 0:7ccf0e7e8a83 83
RobMeades 0:7ccf0e7e8a83 84 // A PIN that is definitely incorrect
RobMeades 0:7ccf0e7e8a83 85 #ifndef MBED_CONF_APP_INCORRECT_PIN
RobMeades 0:7ccf0e7e8a83 86 # define MBED_CONF_APP_INCORRECT_PIN "1530"
RobMeades 0:7ccf0e7e8a83 87 #endif
RobMeades 0:7ccf0e7e8a83 88
RobMeades 0:7ccf0e7e8a83 89 // Servers and ports
RobMeades 0:7ccf0e7e8a83 90 #ifdef MBED_CONF_APP_ECHO_SERVER
RobMeades 0:7ccf0e7e8a83 91 # ifndef MBED_CONF_APP_ECHO_UDP_PORT
RobMeades 0:7ccf0e7e8a83 92 # error "MBED_CONF_APP_ECHO_UDP_PORT (the port on which your echo server echoes UDP packets) must be defined"
RobMeades 0:7ccf0e7e8a83 93 # endif
RobMeades 0:7ccf0e7e8a83 94 # ifndef MBED_CONF_APP_ECHO_TCP_PORT
RobMeades 0:7ccf0e7e8a83 95 # error "MBED_CONF_APP_ECHO_TCP_PORT (the port on which your echo server echoes TCP packets) must be defined"
RobMeades 0:7ccf0e7e8a83 96 # endif
RobMeades 0:7ccf0e7e8a83 97 #endif
RobMeades 0:7ccf0e7e8a83 98
RobMeades 0:7ccf0e7e8a83 99 #ifndef MBED_CONF_APP_NTP_SERVER
RobMeades 0:7ccf0e7e8a83 100 # define MBED_CONF_APP_NTP_SERVER "2.pool.ntp.org"
RobMeades 0:7ccf0e7e8a83 101 #else
RobMeades 0:7ccf0e7e8a83 102 # ifndef MBED_CONF_APP_NTP_PORT
RobMeades 0:7ccf0e7e8a83 103 # error "MBED_CONF_APP_NTP_PORT must be defined if MBED_CONF_APP_NTP_SERVER is defined"
RobMeades 0:7ccf0e7e8a83 104 # endif
RobMeades 0:7ccf0e7e8a83 105 #endif
RobMeades 0:7ccf0e7e8a83 106 #ifndef MBED_CONF_APP_NTP_PORT
RobMeades 0:7ccf0e7e8a83 107 # define MBED_CONF_APP_NTP_PORT 123
RobMeades 0:7ccf0e7e8a83 108 #endif
RobMeades 0:7ccf0e7e8a83 109
RobMeades 0:7ccf0e7e8a83 110 #ifndef MBED_CONF_APP_LOCAL_PORT
RobMeades 0:7ccf0e7e8a83 111 # define MBED_CONF_APP_LOCAL_PORT 15
RobMeades 0:7ccf0e7e8a83 112 #endif
RobMeades 0:7ccf0e7e8a83 113
RobMeades 0:7ccf0e7e8a83 114 // UDP packet size limit for testing
RobMeades 0:7ccf0e7e8a83 115 #ifndef MBED_CONF_APP_UDP_MAX_PACKET_SIZE
RobMeades 0:7ccf0e7e8a83 116 # define MBED_CONF_APP_UDP_MAX_PACKET_SIZE 1024
RobMeades 0:7ccf0e7e8a83 117 #endif
RobMeades 0:7ccf0e7e8a83 118
RobMeades 0:7ccf0e7e8a83 119 // The maximum size of UDP data fragmented across
RobMeades 0:7ccf0e7e8a83 120 // multiple packets
RobMeades 0:7ccf0e7e8a83 121 #ifndef MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE
RobMeades 0:7ccf0e7e8a83 122 # define MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE 1500
RobMeades 0:7ccf0e7e8a83 123 #endif
RobMeades 0:7ccf0e7e8a83 124
RobMeades 0:7ccf0e7e8a83 125 // TCP packet size limit for testing
RobMeades 0:7ccf0e7e8a83 126 #ifndef MBED_CONF_APP_MBED_CONF_APP_TCP_MAX_PACKET_SIZE
RobMeades 0:7ccf0e7e8a83 127 # define MBED_CONF_APP_TCP_MAX_PACKET_SIZE 1500
RobMeades 0:7ccf0e7e8a83 128 #endif
RobMeades 0:7ccf0e7e8a83 129
RobMeades 0:7ccf0e7e8a83 130 // The number of retries for UDP exchanges
RobMeades 0:7ccf0e7e8a83 131 #define NUM_UDP_RETRIES 5
RobMeades 0:7ccf0e7e8a83 132
RobMeades 0:7ccf0e7e8a83 133 // How long to wait for stuff to travel in the async echo tests
RobMeades 0:7ccf0e7e8a83 134 #define ASYNC_TEST_WAIT_TIME 10000
RobMeades 0:7ccf0e7e8a83 135
RobMeades 0:7ccf0e7e8a83 136 // The maximum number of sockets that can be open at one time
RobMeades 0:7ccf0e7e8a83 137 #define MAX_NUM_SOCKETS 7
RobMeades 0:7ccf0e7e8a83 138
RobMeades 0:7ccf0e7e8a83 139 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 140 // PRIVATE VARIABLES
RobMeades 0:7ccf0e7e8a83 141 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 142
RobMeades 0:7ccf0e7e8a83 143 #ifdef FEATURE_COMMON_PAL
RobMeades 0:7ccf0e7e8a83 144 // Lock for debug prints
RobMeades 0:7ccf0e7e8a83 145 static Mutex mtx;
RobMeades 0:7ccf0e7e8a83 146 #endif
RobMeades 0:7ccf0e7e8a83 147
RobMeades 0:7ccf0e7e8a83 148 // An instance of the cellular driver
RobMeades 0:7ccf0e7e8a83 149 static UbloxATCellularInterface *driver =
RobMeades 0:7ccf0e7e8a83 150 new UbloxATCellularInterface(MDMTXD, MDMRXD,
RobMeades 0:7ccf0e7e8a83 151 MBED_CONF_UBLOX_CELL_BAUD_RATE,
RobMeades 0:7ccf0e7e8a83 152 MBED_CONF_APP_DEBUG_ON);
RobMeades 0:7ccf0e7e8a83 153
RobMeades 0:7ccf0e7e8a83 154 // Connection flag
RobMeades 0:7ccf0e7e8a83 155 static bool connection_has_gone_down = false;
RobMeades 0:7ccf0e7e8a83 156
RobMeades 0:7ccf0e7e8a83 157 // Data to exchange
RobMeades 0:7ccf0e7e8a83 158 static const char send_data[] = "_____0000:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 159 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 160 "_____0100:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 161 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 162 "_____0200:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 163 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 164 "_____0300:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 165 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 166 "_____0400:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 167 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 168 "_____0500:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 169 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 170 "_____0600:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 171 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 172 "_____0700:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 173 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 174 "_____0800:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 175 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 176 "_____0900:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 177 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 178 "_____1000:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 179 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 180 "_____1100:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 181 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 182 "_____1200:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 183 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 184 "_____1300:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 185 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 186 "_____1400:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 187 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 188 "_____1500:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 189 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 190 "_____1600:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 191 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 192 "_____1700:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 193 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 194 "_____1800:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 195 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 196 "_____1900:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 197 "01234567890123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 198 "_____2000:0123456789012345678901234567890123456789"
RobMeades 0:7ccf0e7e8a83 199 "01234567890123456789012345678901234567890123456789";
RobMeades 0:7ccf0e7e8a83 200
RobMeades 0:7ccf0e7e8a83 201 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 202 // PRIVATE FUNCTIONS
RobMeades 0:7ccf0e7e8a83 203 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 204
RobMeades 0:7ccf0e7e8a83 205 #ifdef FEATURE_COMMON_PAL
RobMeades 0:7ccf0e7e8a83 206 // Locks for debug prints
RobMeades 0:7ccf0e7e8a83 207 static void lock()
RobMeades 0:7ccf0e7e8a83 208 {
RobMeades 0:7ccf0e7e8a83 209 mtx.lock();
RobMeades 0:7ccf0e7e8a83 210 }
RobMeades 0:7ccf0e7e8a83 211
RobMeades 0:7ccf0e7e8a83 212 static void unlock()
RobMeades 0:7ccf0e7e8a83 213 {
RobMeades 0:7ccf0e7e8a83 214 mtx.unlock();
RobMeades 0:7ccf0e7e8a83 215 }
RobMeades 0:7ccf0e7e8a83 216 #endif
RobMeades 0:7ccf0e7e8a83 217
RobMeades 0:7ccf0e7e8a83 218 // Callback in case the connection goes down
RobMeades 0:7ccf0e7e8a83 219 static void connection_down_cb(nsapi_error_t err)
RobMeades 0:7ccf0e7e8a83 220 {
RobMeades 0:7ccf0e7e8a83 221 connection_has_gone_down = true;
RobMeades 0:7ccf0e7e8a83 222 }
RobMeades 0:7ccf0e7e8a83 223
RobMeades 0:7ccf0e7e8a83 224 #ifdef MBED_CONF_APP_ECHO_SERVER
RobMeades 0:7ccf0e7e8a83 225 // Make sure that size is greater than 0 and no more than limit,
RobMeades 0:7ccf0e7e8a83 226 // useful since, when moduloing a very large number number,
RobMeades 0:7ccf0e7e8a83 227 // compilers sometimes screw up and produce a small *negative*
RobMeades 0:7ccf0e7e8a83 228 // number. Who knew? For example, GCC decided that
RobMeades 0:7ccf0e7e8a83 229 // 492318453 (0x1d582ef5) modulo 508 was -47 (0xffffffd1).
RobMeades 0:7ccf0e7e8a83 230 static int fix (int size, int limit)
RobMeades 0:7ccf0e7e8a83 231 {
RobMeades 0:7ccf0e7e8a83 232 if (size <= 0) {
RobMeades 0:7ccf0e7e8a83 233 size = limit / 2; // better than 1
RobMeades 0:7ccf0e7e8a83 234 } else if (size > limit) {
RobMeades 0:7ccf0e7e8a83 235 size = limit;
RobMeades 0:7ccf0e7e8a83 236 }
RobMeades 0:7ccf0e7e8a83 237
RobMeades 0:7ccf0e7e8a83 238 return size;
RobMeades 0:7ccf0e7e8a83 239 }
RobMeades 0:7ccf0e7e8a83 240
RobMeades 0:7ccf0e7e8a83 241 // Do a UDP socket echo test to a given host of a given packet size
RobMeades 0:7ccf0e7e8a83 242 static void do_udp_echo(UDPSocket *sock, SocketAddress *host_address, int size)
RobMeades 0:7ccf0e7e8a83 243 {
RobMeades 0:7ccf0e7e8a83 244 bool success = false;
RobMeades 0:7ccf0e7e8a83 245 void * recv_data = malloc (size);
RobMeades 0:7ccf0e7e8a83 246 SocketAddress sender_address;
RobMeades 0:7ccf0e7e8a83 247 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 248
RobMeades 0:7ccf0e7e8a83 249 // Retry this a few times, don't want to fail due to a flaky link
RobMeades 0:7ccf0e7e8a83 250 for (int x = 0; !success && (x < NUM_UDP_RETRIES); x++) {
RobMeades 0:7ccf0e7e8a83 251 tr_debug("Echo testing UDP packet size %d byte(s), try %d.", size, x + 1);
RobMeades 0:7ccf0e7e8a83 252 if ((sock->sendto(*host_address, (void*) send_data, size) == size) &&
RobMeades 0:7ccf0e7e8a83 253 (sock->recvfrom(&sender_address, recv_data, size) == size)) {
RobMeades 0:7ccf0e7e8a83 254 TEST_ASSERT (memcmp(send_data, recv_data, size) == 0);
RobMeades 0:7ccf0e7e8a83 255 TEST_ASSERT (strcmp(sender_address.get_ip_address(), host_address->get_ip_address()) == 0);
RobMeades 0:7ccf0e7e8a83 256 TEST_ASSERT (sender_address.get_port() == host_address->get_port());
RobMeades 0:7ccf0e7e8a83 257 success = true;
RobMeades 0:7ccf0e7e8a83 258 }
RobMeades 0:7ccf0e7e8a83 259 }
RobMeades 0:7ccf0e7e8a83 260 TEST_ASSERT (success);
RobMeades 0:7ccf0e7e8a83 261 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 262
RobMeades 0:7ccf0e7e8a83 263 free (recv_data);
RobMeades 0:7ccf0e7e8a83 264 }
RobMeades 0:7ccf0e7e8a83 265
RobMeades 0:7ccf0e7e8a83 266 // The asynchronous callback
RobMeades 0:7ccf0e7e8a83 267 static void async_cb(bool *callback_triggered)
RobMeades 0:7ccf0e7e8a83 268 {
RobMeades 0:7ccf0e7e8a83 269
RobMeades 0:7ccf0e7e8a83 270 TEST_ASSERT (callback_triggered != NULL);
RobMeades 0:7ccf0e7e8a83 271 *callback_triggered = true;
RobMeades 0:7ccf0e7e8a83 272 }
RobMeades 0:7ccf0e7e8a83 273
RobMeades 0:7ccf0e7e8a83 274 // Do a UDP echo but using the asynchronous driver; we can exchange
RobMeades 0:7ccf0e7e8a83 275 // packets longer in size than one UDP packet this way
RobMeades 0:7ccf0e7e8a83 276 static void do_udp_echo_async(UDPSocket *sock, SocketAddress *host_address,
RobMeades 0:7ccf0e7e8a83 277 int size, bool *callback_triggered)
RobMeades 0:7ccf0e7e8a83 278 {
RobMeades 0:7ccf0e7e8a83 279 void * recv_data = malloc (size);
RobMeades 0:7ccf0e7e8a83 280 int recv_size = 0;
RobMeades 0:7ccf0e7e8a83 281 SocketAddress sender_address;
RobMeades 0:7ccf0e7e8a83 282 Timer timer;
RobMeades 0:7ccf0e7e8a83 283 int x, y, z;
RobMeades 0:7ccf0e7e8a83 284 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 285
RobMeades 0:7ccf0e7e8a83 286 *callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 287 for (y = 0; (recv_size < size) && (y < NUM_UDP_RETRIES); y++) {
RobMeades 0:7ccf0e7e8a83 288 tr_debug("Echo testing UDP packet size %d byte(s) async, try %d.", size, y + 1);
RobMeades 0:7ccf0e7e8a83 289 recv_size = 0;
RobMeades 0:7ccf0e7e8a83 290 // Retry this a few times, don't want to fail due to a flaky link
RobMeades 0:7ccf0e7e8a83 291 if (sock->sendto(*host_address, (void *) send_data, size) == size) {
RobMeades 0:7ccf0e7e8a83 292 // Wait for all the echoed data to arrive
RobMeades 0:7ccf0e7e8a83 293 timer.start();
RobMeades 0:7ccf0e7e8a83 294 while ((recv_size < size) && (timer.read_ms() < ASYNC_TEST_WAIT_TIME)) {
RobMeades 0:7ccf0e7e8a83 295 if (*callback_triggered) {
RobMeades 0:7ccf0e7e8a83 296 *callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 297 x = sock->recvfrom(&sender_address, (char *) recv_data + recv_size, size);
RobMeades 0:7ccf0e7e8a83 298 if (x > 0) {
RobMeades 0:7ccf0e7e8a83 299 recv_size += x;
RobMeades 0:7ccf0e7e8a83 300 }
RobMeades 0:7ccf0e7e8a83 301 tr_debug("%d byte(s) echoed back so far, %d to go.", recv_size, size - recv_size);
RobMeades 0:7ccf0e7e8a83 302 TEST_ASSERT(strcmp(sender_address.get_ip_address(), host_address->get_ip_address()) == 0);
RobMeades 0:7ccf0e7e8a83 303 TEST_ASSERT(sender_address.get_port() == host_address->get_port());
RobMeades 0:7ccf0e7e8a83 304 }
RobMeades 0:7ccf0e7e8a83 305 wait_ms(10);
RobMeades 0:7ccf0e7e8a83 306 }
RobMeades 0:7ccf0e7e8a83 307 timer.stop();
RobMeades 0:7ccf0e7e8a83 308 timer.reset();
RobMeades 0:7ccf0e7e8a83 309
RobMeades 0:7ccf0e7e8a83 310 // If everything arrived back, check it's the same as we sent
RobMeades 0:7ccf0e7e8a83 311 if (recv_size == size) {
RobMeades 0:7ccf0e7e8a83 312 z = memcmp(send_data, recv_data, size);
RobMeades 0:7ccf0e7e8a83 313 if (z != 0) {
RobMeades 0:7ccf0e7e8a83 314 tr_debug("WARNING: mismatch, retrying");
RobMeades 0:7ccf0e7e8a83 315 tr_debug("Sent %d, |%*.*s|", size, size, size, send_data);
RobMeades 0:7ccf0e7e8a83 316 tr_debug("Rcvd %d, |%*.*s|", size, size, size, (char *) recv_data);
RobMeades 0:7ccf0e7e8a83 317 // If things don't match, it could be due to data loss (this is UDP
RobMeades 0:7ccf0e7e8a83 318 // you know...), so set recv_size to 0 to cause another try
RobMeades 0:7ccf0e7e8a83 319 recv_size = 0;
RobMeades 0:7ccf0e7e8a83 320 }
RobMeades 0:7ccf0e7e8a83 321 }
RobMeades 0:7ccf0e7e8a83 322 }
RobMeades 0:7ccf0e7e8a83 323 }
RobMeades 0:7ccf0e7e8a83 324
RobMeades 0:7ccf0e7e8a83 325 TEST_ASSERT(recv_size == size);
RobMeades 0:7ccf0e7e8a83 326 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 327
RobMeades 0:7ccf0e7e8a83 328 free (recv_data);
RobMeades 0:7ccf0e7e8a83 329 }
RobMeades 0:7ccf0e7e8a83 330
RobMeades 0:7ccf0e7e8a83 331 // Send an entire TCP data buffer until done
RobMeades 0:7ccf0e7e8a83 332 static int sendAll(TCPSocket *sock, const char *data, int size)
RobMeades 0:7ccf0e7e8a83 333 {
RobMeades 0:7ccf0e7e8a83 334 int x;
RobMeades 0:7ccf0e7e8a83 335 int count = 0;
RobMeades 0:7ccf0e7e8a83 336 Timer timer;
RobMeades 0:7ccf0e7e8a83 337
RobMeades 0:7ccf0e7e8a83 338 timer.start();
RobMeades 0:7ccf0e7e8a83 339 while ((count < size) && (timer.read_ms() < 10000)) {
RobMeades 0:7ccf0e7e8a83 340 x = sock->send(data + count, size - count);
RobMeades 0:7ccf0e7e8a83 341 if (x > 0) {
RobMeades 0:7ccf0e7e8a83 342 count += x;
RobMeades 0:7ccf0e7e8a83 343 tr_debug("%d byte(s) sent, %d left to send.", count, size - count);
RobMeades 0:7ccf0e7e8a83 344 }
RobMeades 0:7ccf0e7e8a83 345 wait_ms(10);
RobMeades 0:7ccf0e7e8a83 346 }
RobMeades 0:7ccf0e7e8a83 347 timer.stop();
RobMeades 0:7ccf0e7e8a83 348
RobMeades 0:7ccf0e7e8a83 349 return count;
RobMeades 0:7ccf0e7e8a83 350 }
RobMeades 0:7ccf0e7e8a83 351
RobMeades 0:7ccf0e7e8a83 352 // Do a TCP echo but using the asynchronous driver
RobMeades 0:7ccf0e7e8a83 353 static void do_tcp_echo_async(TCPSocket *sock, int size, bool *callback_triggered)
RobMeades 0:7ccf0e7e8a83 354 {
RobMeades 0:7ccf0e7e8a83 355 void * recv_data = malloc (size);
RobMeades 0:7ccf0e7e8a83 356 int recv_size = 0;
RobMeades 0:7ccf0e7e8a83 357 int x, y;
RobMeades 0:7ccf0e7e8a83 358 Timer timer;
RobMeades 0:7ccf0e7e8a83 359 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 360
RobMeades 0:7ccf0e7e8a83 361 *callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 362 tr_debug("Echo testing TCP packet size %d byte(s) async.", size);
RobMeades 0:7ccf0e7e8a83 363 TEST_ASSERT (sendAll(sock, send_data, size) == size);
RobMeades 0:7ccf0e7e8a83 364
RobMeades 0:7ccf0e7e8a83 365 // Wait for all the echoed data to arrive
RobMeades 0:7ccf0e7e8a83 366 timer.start();
RobMeades 0:7ccf0e7e8a83 367 while ((recv_size < size) && (timer.read_ms() < ASYNC_TEST_WAIT_TIME)) {
RobMeades 0:7ccf0e7e8a83 368 if (*callback_triggered) {
RobMeades 0:7ccf0e7e8a83 369 *callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 370 x = sock->recv((char *) recv_data + recv_size, size);
RobMeades 0:7ccf0e7e8a83 371 TEST_ASSERT(x > 0);
RobMeades 0:7ccf0e7e8a83 372 recv_size += x;
RobMeades 0:7ccf0e7e8a83 373 tr_debug("%d byte(s) echoed back so far, %d to go.", recv_size, size - recv_size);
RobMeades 0:7ccf0e7e8a83 374 }
RobMeades 0:7ccf0e7e8a83 375 wait_ms(10);
RobMeades 0:7ccf0e7e8a83 376 }
RobMeades 0:7ccf0e7e8a83 377 TEST_ASSERT(recv_size == size);
RobMeades 0:7ccf0e7e8a83 378 y = memcmp(send_data, recv_data, size);
RobMeades 0:7ccf0e7e8a83 379 if (y != 0) {
RobMeades 0:7ccf0e7e8a83 380 tr_debug("Sent %d, |%*.*s|", size, size, size, send_data);
RobMeades 0:7ccf0e7e8a83 381 tr_debug("Rcvd %d, |%*.*s|", size, size, size, (char *) recv_data);
RobMeades 0:7ccf0e7e8a83 382 TEST_ASSERT(false);
RobMeades 0:7ccf0e7e8a83 383 }
RobMeades 0:7ccf0e7e8a83 384 timer.stop();
RobMeades 0:7ccf0e7e8a83 385
RobMeades 0:7ccf0e7e8a83 386 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 387
RobMeades 0:7ccf0e7e8a83 388 free (recv_data);
RobMeades 0:7ccf0e7e8a83 389 }
RobMeades 0:7ccf0e7e8a83 390 #endif
RobMeades 0:7ccf0e7e8a83 391
RobMeades 0:7ccf0e7e8a83 392 // Get NTP time from a socket
RobMeades 0:7ccf0e7e8a83 393 static void do_ntp_sock (UDPSocket *sock, SocketAddress ntp_address)
RobMeades 0:7ccf0e7e8a83 394 {
RobMeades 0:7ccf0e7e8a83 395 char ntp_values[48] = { 0 };
RobMeades 0:7ccf0e7e8a83 396 time_t timestamp = 0;
RobMeades 0:7ccf0e7e8a83 397 struct tm *localTime;
RobMeades 0:7ccf0e7e8a83 398 char timeString[25];
RobMeades 0:7ccf0e7e8a83 399 time_t TIME1970 = 2208988800U;
RobMeades 0:7ccf0e7e8a83 400 int len;
RobMeades 0:7ccf0e7e8a83 401 bool comms_done = false;
RobMeades 0:7ccf0e7e8a83 402
RobMeades 0:7ccf0e7e8a83 403 ntp_values[0] = '\x1b';
RobMeades 0:7ccf0e7e8a83 404
RobMeades 0:7ccf0e7e8a83 405 // Retry this a few times, don't want to fail due to a flaky link
RobMeades 0:7ccf0e7e8a83 406 for (unsigned int x = 0; !comms_done && (x < NUM_UDP_RETRIES); x++) {
RobMeades 0:7ccf0e7e8a83 407 sock->sendto(ntp_address, (void*) ntp_values, sizeof(ntp_values));
RobMeades 0:7ccf0e7e8a83 408 len = sock->recvfrom(&ntp_address, (void*) ntp_values, sizeof(ntp_values));
RobMeades 0:7ccf0e7e8a83 409 if (len > 0) {
RobMeades 0:7ccf0e7e8a83 410 comms_done = true;
RobMeades 0:7ccf0e7e8a83 411 }
RobMeades 0:7ccf0e7e8a83 412 }
RobMeades 0:7ccf0e7e8a83 413 TEST_ASSERT (comms_done);
RobMeades 0:7ccf0e7e8a83 414
RobMeades 0:7ccf0e7e8a83 415 tr_debug("UDP: %d byte(s) returned by NTP server.", len);
RobMeades 0:7ccf0e7e8a83 416 if (len >= 43) {
RobMeades 0:7ccf0e7e8a83 417 timestamp |= ((int) *(ntp_values + 40)) << 24;
RobMeades 0:7ccf0e7e8a83 418 timestamp |= ((int) *(ntp_values + 41)) << 16;
RobMeades 0:7ccf0e7e8a83 419 timestamp |= ((int) *(ntp_values + 42)) << 8;
RobMeades 0:7ccf0e7e8a83 420 timestamp |= ((int) *(ntp_values + 43));
RobMeades 0:7ccf0e7e8a83 421 timestamp -= TIME1970;
RobMeades 0:7ccf0e7e8a83 422 srand (timestamp);
RobMeades 0:7ccf0e7e8a83 423 tr_debug("srand() called");
RobMeades 0:7ccf0e7e8a83 424 localTime = localtime(&timestamp);
RobMeades 0:7ccf0e7e8a83 425 if (localTime) {
RobMeades 0:7ccf0e7e8a83 426 if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) {
RobMeades 0:7ccf0e7e8a83 427 printf("NTP timestamp is %s.\n", timeString);
RobMeades 0:7ccf0e7e8a83 428 }
RobMeades 0:7ccf0e7e8a83 429 }
RobMeades 0:7ccf0e7e8a83 430 }
RobMeades 0:7ccf0e7e8a83 431 }
RobMeades 0:7ccf0e7e8a83 432
RobMeades 0:7ccf0e7e8a83 433 // Get NTP time
RobMeades 0:7ccf0e7e8a83 434 static void do_ntp(UbloxATCellularInterface *driver)
RobMeades 0:7ccf0e7e8a83 435 {
RobMeades 0:7ccf0e7e8a83 436 UDPSocket sock;
RobMeades 0:7ccf0e7e8a83 437 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 438
RobMeades 0:7ccf0e7e8a83 439 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 440
RobMeades 0:7ccf0e7e8a83 441 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_NTP_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 442 host_address.set_port(MBED_CONF_APP_NTP_PORT);
RobMeades 0:7ccf0e7e8a83 443
RobMeades 0:7ccf0e7e8a83 444 tr_debug("UDP: NIST server %s address: %s on port %d.", MBED_CONF_APP_NTP_SERVER,
RobMeades 0:7ccf0e7e8a83 445 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 446
RobMeades 0:7ccf0e7e8a83 447 sock.set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 448
RobMeades 0:7ccf0e7e8a83 449 do_ntp_sock(&sock, host_address);
RobMeades 0:7ccf0e7e8a83 450
RobMeades 0:7ccf0e7e8a83 451 sock.close();
RobMeades 0:7ccf0e7e8a83 452 }
RobMeades 0:7ccf0e7e8a83 453
RobMeades 0:7ccf0e7e8a83 454 // Use a connection, checking that it is good
RobMeades 0:7ccf0e7e8a83 455 static void use_connection(UbloxATCellularInterface *driver)
RobMeades 0:7ccf0e7e8a83 456 {
RobMeades 0:7ccf0e7e8a83 457 const char * ip_address = driver->get_ip_address();
RobMeades 0:7ccf0e7e8a83 458 const char * net_mask = driver->get_netmask();
RobMeades 0:7ccf0e7e8a83 459 const char * gateway = driver->get_gateway();
RobMeades 0:7ccf0e7e8a83 460
RobMeades 0:7ccf0e7e8a83 461 TEST_ASSERT(driver->is_connected());
RobMeades 0:7ccf0e7e8a83 462
RobMeades 0:7ccf0e7e8a83 463 TEST_ASSERT(ip_address != NULL);
RobMeades 0:7ccf0e7e8a83 464 tr_debug ("IP address %s.", ip_address);
RobMeades 0:7ccf0e7e8a83 465 TEST_ASSERT(net_mask == NULL);
RobMeades 0:7ccf0e7e8a83 466 tr_debug ("Net mask %s.", net_mask);
RobMeades 0:7ccf0e7e8a83 467 TEST_ASSERT(gateway != NULL);
RobMeades 0:7ccf0e7e8a83 468 tr_debug ("Gateway %s.", gateway);
RobMeades 0:7ccf0e7e8a83 469
RobMeades 0:7ccf0e7e8a83 470 do_ntp(driver);
RobMeades 0:7ccf0e7e8a83 471 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 472 }
RobMeades 0:7ccf0e7e8a83 473
RobMeades 0:7ccf0e7e8a83 474 // Drop a connection and check that it has dropped
RobMeades 0:7ccf0e7e8a83 475 static void drop_connection(UbloxATCellularInterface *driver)
RobMeades 0:7ccf0e7e8a83 476 {
RobMeades 0:7ccf0e7e8a83 477 TEST_ASSERT(driver->disconnect() == 0);
RobMeades 0:7ccf0e7e8a83 478 TEST_ASSERT(connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 479 connection_has_gone_down = false;
RobMeades 0:7ccf0e7e8a83 480 TEST_ASSERT(!driver->is_connected());
RobMeades 0:7ccf0e7e8a83 481 }
RobMeades 0:7ccf0e7e8a83 482
RobMeades 0:7ccf0e7e8a83 483 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 484 // TESTS
RobMeades 0:7ccf0e7e8a83 485 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 486
RobMeades 0:7ccf0e7e8a83 487 // Call srand() using the NTP server
RobMeades 0:7ccf0e7e8a83 488 void test_set_randomise() {
RobMeades 0:7ccf0e7e8a83 489 UDPSocket sock;
RobMeades 0:7ccf0e7e8a83 490 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 491
RobMeades 0:7ccf0e7e8a83 492 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 493 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 494 do_ntp(driver);
RobMeades 0:7ccf0e7e8a83 495 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 496 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 497 }
RobMeades 0:7ccf0e7e8a83 498
RobMeades 0:7ccf0e7e8a83 499 #ifdef MBED_CONF_APP_ECHO_SERVER
RobMeades 0:7ccf0e7e8a83 500
RobMeades 0:7ccf0e7e8a83 501 // Test UDP data exchange
RobMeades 0:7ccf0e7e8a83 502 void test_udp_echo() {
RobMeades 0:7ccf0e7e8a83 503 UDPSocket sock;
RobMeades 0:7ccf0e7e8a83 504 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 505 SocketAddress local_address;
RobMeades 0:7ccf0e7e8a83 506 int x;
RobMeades 0:7ccf0e7e8a83 507 int size;
RobMeades 0:7ccf0e7e8a83 508
RobMeades 0:7ccf0e7e8a83 509 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 510 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 511
RobMeades 0:7ccf0e7e8a83 512 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 513 host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
RobMeades 0:7ccf0e7e8a83 514
RobMeades 0:7ccf0e7e8a83 515 tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
RobMeades 0:7ccf0e7e8a83 516 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 517
RobMeades 0:7ccf0e7e8a83 518 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 519
RobMeades 0:7ccf0e7e8a83 520 // Do a bind, just for the helluvit
RobMeades 0:7ccf0e7e8a83 521 local_address.set_port(MBED_CONF_APP_LOCAL_PORT);
RobMeades 0:7ccf0e7e8a83 522 TEST_ASSERT(sock.bind(local_address) == 0);
RobMeades 0:7ccf0e7e8a83 523
RobMeades 0:7ccf0e7e8a83 524 sock.set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 525
RobMeades 0:7ccf0e7e8a83 526 // Test min, max, and some random sizes in-between
RobMeades 0:7ccf0e7e8a83 527 do_udp_echo(&sock, &host_address, 1);
RobMeades 0:7ccf0e7e8a83 528 do_udp_echo(&sock, &host_address, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 529 for (x = 0; x < 10; x++) {
RobMeades 0:7ccf0e7e8a83 530 size = (rand() % MBED_CONF_APP_UDP_MAX_PACKET_SIZE) + 1;
RobMeades 0:7ccf0e7e8a83 531 size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 532 do_udp_echo(&sock, &host_address, size);
RobMeades 0:7ccf0e7e8a83 533 }
RobMeades 0:7ccf0e7e8a83 534
RobMeades 0:7ccf0e7e8a83 535 sock.close();
RobMeades 0:7ccf0e7e8a83 536 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 537 tr_debug("%d UDP packets of size up to %d byte(s) echoed successfully.",
RobMeades 0:7ccf0e7e8a83 538 x, MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 539 }
RobMeades 0:7ccf0e7e8a83 540
RobMeades 0:7ccf0e7e8a83 541 // Test many different sizes of UDP data arriving at once
RobMeades 0:7ccf0e7e8a83 542 void test_udp_echo_recv_sizes() {
RobMeades 0:7ccf0e7e8a83 543 UDPSocket sock;
RobMeades 0:7ccf0e7e8a83 544 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 545 int x, y, z;
RobMeades 0:7ccf0e7e8a83 546 int size;
RobMeades 0:7ccf0e7e8a83 547 int tries = 0;
RobMeades 0:7ccf0e7e8a83 548 unsigned int offset;
RobMeades 0:7ccf0e7e8a83 549 char * recv_data;
RobMeades 0:7ccf0e7e8a83 550 bool packetLoss;
RobMeades 0:7ccf0e7e8a83 551 bool sendSuccess;
RobMeades 0:7ccf0e7e8a83 552 Timer timer;
RobMeades 0:7ccf0e7e8a83 553
RobMeades 0:7ccf0e7e8a83 554 driver->deinit();
RobMeades 0:7ccf0e7e8a83 555 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 556 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 557
RobMeades 0:7ccf0e7e8a83 558 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 559 host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
RobMeades 0:7ccf0e7e8a83 560
RobMeades 0:7ccf0e7e8a83 561 tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
RobMeades 0:7ccf0e7e8a83 562 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 563
RobMeades 0:7ccf0e7e8a83 564 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 565
RobMeades 0:7ccf0e7e8a83 566 do {
RobMeades 0:7ccf0e7e8a83 567 tr_debug("--- UDP packet size test, test try %d, flushing input buffers", tries + 1);
RobMeades 0:7ccf0e7e8a83 568 // First of all, clear any junk from the socket
RobMeades 0:7ccf0e7e8a83 569 sock.set_timeout(1000);
RobMeades 0:7ccf0e7e8a83 570 recv_data = (char *) malloc (MBED_CONF_APP_UDP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 571 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 572 while (sock.recvfrom(&host_address, (void *) recv_data, MBED_CONF_APP_UDP_MAX_PACKET_SIZE) > 0) {
RobMeades 0:7ccf0e7e8a83 573 // Throw it away
RobMeades 0:7ccf0e7e8a83 574 }
RobMeades 0:7ccf0e7e8a83 575 free (recv_data);
RobMeades 0:7ccf0e7e8a83 576
RobMeades 0:7ccf0e7e8a83 577 sock.set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 578
RobMeades 0:7ccf0e7e8a83 579 // Throw random sized UDP packets up...
RobMeades 0:7ccf0e7e8a83 580 x = 0;
RobMeades 0:7ccf0e7e8a83 581 offset = 0;
RobMeades 0:7ccf0e7e8a83 582 while (offset < sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 583 size = (rand() % (MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2)) + 1;
RobMeades 0:7ccf0e7e8a83 584 size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2);
RobMeades 0:7ccf0e7e8a83 585 if (offset + size > sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 586 size = sizeof (send_data) - offset;
RobMeades 0:7ccf0e7e8a83 587 }
RobMeades 0:7ccf0e7e8a83 588 sendSuccess = false;
RobMeades 0:7ccf0e7e8a83 589 for (y = 0; !sendSuccess && (y < NUM_UDP_RETRIES); y++) {
RobMeades 0:7ccf0e7e8a83 590 tr_debug("Sending UDP packet number %d, size %d byte(s), send try %d.", x + 1, size, y + 1);
RobMeades 0:7ccf0e7e8a83 591 if (sock.sendto(host_address, (void *) (send_data + offset), size) == size) {
RobMeades 0:7ccf0e7e8a83 592 sendSuccess = true;
RobMeades 0:7ccf0e7e8a83 593 offset += size;
RobMeades 0:7ccf0e7e8a83 594 }
RobMeades 0:7ccf0e7e8a83 595 }
RobMeades 0:7ccf0e7e8a83 596 TEST_ASSERT(sendSuccess);
RobMeades 0:7ccf0e7e8a83 597 x++;
RobMeades 0:7ccf0e7e8a83 598 }
RobMeades 0:7ccf0e7e8a83 599 tr_debug("--- All UDP packets sent");
RobMeades 0:7ccf0e7e8a83 600
RobMeades 0:7ccf0e7e8a83 601 // ...and capture them all again afterwards
RobMeades 0:7ccf0e7e8a83 602 recv_data = (char *) malloc (sizeof (send_data));
RobMeades 0:7ccf0e7e8a83 603 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 604 memset (recv_data, 0, sizeof (send_data));
RobMeades 0:7ccf0e7e8a83 605 size = 0;
RobMeades 0:7ccf0e7e8a83 606 y = 0;
RobMeades 0:7ccf0e7e8a83 607 packetLoss = false;
RobMeades 0:7ccf0e7e8a83 608 timer.start();
RobMeades 0:7ccf0e7e8a83 609 while ((size < (int) sizeof (send_data)) && (timer.read_ms() < 10000)) {
RobMeades 0:7ccf0e7e8a83 610 y = sock.recvfrom(&host_address, (void *) (recv_data + size), sizeof (send_data) - size);
RobMeades 0:7ccf0e7e8a83 611 if (y > 0) {
RobMeades 0:7ccf0e7e8a83 612 size += y;
RobMeades 0:7ccf0e7e8a83 613 }
RobMeades 0:7ccf0e7e8a83 614 }
RobMeades 0:7ccf0e7e8a83 615 timer.stop();
RobMeades 0:7ccf0e7e8a83 616 timer.reset();
RobMeades 0:7ccf0e7e8a83 617 tr_debug( "--- Either received everything back or timed out waiting");
RobMeades 0:7ccf0e7e8a83 618
RobMeades 0:7ccf0e7e8a83 619 // Check that we reassembled everything correctly
RobMeades 0:7ccf0e7e8a83 620 if (size == sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 621 for (x = 0; ((*(recv_data + x) == *(send_data + x))) && (x < (int) sizeof (send_data)); x++) {
RobMeades 0:7ccf0e7e8a83 622 }
RobMeades 0:7ccf0e7e8a83 623 if (x != sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 624 y = x - 5;
RobMeades 0:7ccf0e7e8a83 625 if (y < 0) {
RobMeades 0:7ccf0e7e8a83 626 y = 0;
RobMeades 0:7ccf0e7e8a83 627 }
RobMeades 0:7ccf0e7e8a83 628 z = 10;
RobMeades 0:7ccf0e7e8a83 629 if (y + z > (int) sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 630 z = sizeof(send_data) - y;
RobMeades 0:7ccf0e7e8a83 631 }
RobMeades 0:7ccf0e7e8a83 632 tr_debug(" --- Difference at character %d (send \"%*.*s\", recv \"%*.*s\")",
RobMeades 0:7ccf0e7e8a83 633 x + 1, z, z, send_data + y, z, z, recv_data + y);
RobMeades 0:7ccf0e7e8a83 634 packetLoss = true;
RobMeades 0:7ccf0e7e8a83 635 }
RobMeades 0:7ccf0e7e8a83 636 } else {
RobMeades 0:7ccf0e7e8a83 637 tr_debug(" --- %d bytes missing (%d bytes received when %d were expected))",
RobMeades 0:7ccf0e7e8a83 638 sizeof (send_data) - size, size, sizeof (send_data));
RobMeades 0:7ccf0e7e8a83 639 packetLoss = true;
RobMeades 0:7ccf0e7e8a83 640 }
RobMeades 0:7ccf0e7e8a83 641 free (recv_data);
RobMeades 0:7ccf0e7e8a83 642 tries++;
RobMeades 0:7ccf0e7e8a83 643 } while (packetLoss && (tries < NUM_UDP_RETRIES));
RobMeades 0:7ccf0e7e8a83 644
RobMeades 0:7ccf0e7e8a83 645 TEST_ASSERT(!packetLoss);
RobMeades 0:7ccf0e7e8a83 646 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 647 sock.close();
RobMeades 0:7ccf0e7e8a83 648 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 649 }
RobMeades 0:7ccf0e7e8a83 650
RobMeades 0:7ccf0e7e8a83 651 // Test UDP data exchange via the asynchronous sigio() mechanism
RobMeades 0:7ccf0e7e8a83 652 void test_udp_echo_async() {
RobMeades 0:7ccf0e7e8a83 653 UDPSocket sock;
RobMeades 0:7ccf0e7e8a83 654 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 655 SocketAddress local_address;
RobMeades 0:7ccf0e7e8a83 656 bool callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 657 int x;
RobMeades 0:7ccf0e7e8a83 658 int size;
RobMeades 0:7ccf0e7e8a83 659
RobMeades 0:7ccf0e7e8a83 660 driver->deinit();
RobMeades 0:7ccf0e7e8a83 661 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 662 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 663
RobMeades 0:7ccf0e7e8a83 664 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 665 host_address.set_port(MBED_CONF_APP_ECHO_UDP_PORT);
RobMeades 0:7ccf0e7e8a83 666
RobMeades 0:7ccf0e7e8a83 667 tr_debug("UDP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
RobMeades 0:7ccf0e7e8a83 668 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 669
RobMeades 0:7ccf0e7e8a83 670 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 671
RobMeades 0:7ccf0e7e8a83 672 // Set up the async callback and set the timeout to zero
RobMeades 0:7ccf0e7e8a83 673 sock.sigio(callback(async_cb, &callback_triggered));
RobMeades 0:7ccf0e7e8a83 674 sock.set_timeout(0);
RobMeades 0:7ccf0e7e8a83 675
RobMeades 0:7ccf0e7e8a83 676 // Test min, max, and some random sizes in-between
RobMeades 0:7ccf0e7e8a83 677 // and this time allow the UDP packets to be fragmented
RobMeades 0:7ccf0e7e8a83 678 do_udp_echo_async(&sock, &host_address, 1, &callback_triggered);
RobMeades 0:7ccf0e7e8a83 679 do_udp_echo_async(&sock, &host_address, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE,
RobMeades 0:7ccf0e7e8a83 680 &callback_triggered);
RobMeades 0:7ccf0e7e8a83 681 for (x = 0; x < 10; x++) {
RobMeades 0:7ccf0e7e8a83 682 size = (rand() % MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE) + 1;
RobMeades 0:7ccf0e7e8a83 683 size = fix(size, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 684 do_udp_echo_async(&sock, &host_address, size, &callback_triggered);
RobMeades 0:7ccf0e7e8a83 685 }
RobMeades 0:7ccf0e7e8a83 686
RobMeades 0:7ccf0e7e8a83 687 sock.close();
RobMeades 0:7ccf0e7e8a83 688
RobMeades 0:7ccf0e7e8a83 689 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 690
RobMeades 0:7ccf0e7e8a83 691 tr_debug("%d UDP packets of size up to %d byte(s) echoed asynchronously and successfully.",
RobMeades 0:7ccf0e7e8a83 692 x, MBED_CONF_APP_UDP_MAX_FRAG_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 693 }
RobMeades 0:7ccf0e7e8a83 694
RobMeades 0:7ccf0e7e8a83 695 // Test many different sizes of TCP data arriving at once
RobMeades 0:7ccf0e7e8a83 696 void test_tcp_echo_recv_sizes() {
RobMeades 0:7ccf0e7e8a83 697 TCPSocket sock;
RobMeades 0:7ccf0e7e8a83 698 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 699 int x, y, z;
RobMeades 0:7ccf0e7e8a83 700 int size;
RobMeades 0:7ccf0e7e8a83 701 unsigned int offset;
RobMeades 0:7ccf0e7e8a83 702 char * recv_data;
RobMeades 0:7ccf0e7e8a83 703 Timer timer;
RobMeades 0:7ccf0e7e8a83 704
RobMeades 0:7ccf0e7e8a83 705 driver->deinit();
RobMeades 0:7ccf0e7e8a83 706 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 707 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 708
RobMeades 0:7ccf0e7e8a83 709 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 710 host_address.set_port(MBED_CONF_APP_ECHO_TCP_PORT);
RobMeades 0:7ccf0e7e8a83 711
RobMeades 0:7ccf0e7e8a83 712 tr_debug("TCP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
RobMeades 0:7ccf0e7e8a83 713 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 714
RobMeades 0:7ccf0e7e8a83 715 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 716
RobMeades 0:7ccf0e7e8a83 717 TEST_ASSERT(sock.connect(host_address) == 0);
RobMeades 0:7ccf0e7e8a83 718
RobMeades 0:7ccf0e7e8a83 719 sock.set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 720
RobMeades 0:7ccf0e7e8a83 721 // Throw random sized TCP packets up...
RobMeades 0:7ccf0e7e8a83 722 x = 0;
RobMeades 0:7ccf0e7e8a83 723 offset = 0;
RobMeades 0:7ccf0e7e8a83 724 while (offset < sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 725 size = (rand() % (MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2)) + 1;
RobMeades 0:7ccf0e7e8a83 726 size = fix(size, MBED_CONF_APP_UDP_MAX_PACKET_SIZE / 2);
RobMeades 0:7ccf0e7e8a83 727 if (offset + size > sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 728 size = sizeof (send_data) - offset;
RobMeades 0:7ccf0e7e8a83 729 }
RobMeades 0:7ccf0e7e8a83 730 tr_debug("Sending TCP packet number %d, size %d byte(s).", x + 1, size);
RobMeades 0:7ccf0e7e8a83 731 TEST_ASSERT(sendAll(&sock, (send_data + offset), size) == size);
RobMeades 0:7ccf0e7e8a83 732 offset += size;
RobMeades 0:7ccf0e7e8a83 733 x++;
RobMeades 0:7ccf0e7e8a83 734 }
RobMeades 0:7ccf0e7e8a83 735
RobMeades 0:7ccf0e7e8a83 736 // ...and capture them all again afterwards
RobMeades 0:7ccf0e7e8a83 737 recv_data = (char *) malloc (sizeof (send_data));
RobMeades 0:7ccf0e7e8a83 738 TEST_ASSERT(recv_data != NULL);
RobMeades 0:7ccf0e7e8a83 739 memset (recv_data, 0, sizeof (send_data));
RobMeades 0:7ccf0e7e8a83 740 size = 0;
RobMeades 0:7ccf0e7e8a83 741 x = 0;
RobMeades 0:7ccf0e7e8a83 742 timer.start();
RobMeades 0:7ccf0e7e8a83 743 while ((size < (int) sizeof (send_data)) && (timer.read_ms() < 30000)) {
RobMeades 0:7ccf0e7e8a83 744 y = sock.recv((void *) (recv_data + size), sizeof (send_data) - size);
RobMeades 0:7ccf0e7e8a83 745 tr_debug("Received TCP packet number %d, size %d byte(s).", x, y);
RobMeades 0:7ccf0e7e8a83 746 size += y;
RobMeades 0:7ccf0e7e8a83 747 x++;
RobMeades 0:7ccf0e7e8a83 748 }
RobMeades 0:7ccf0e7e8a83 749 timer.stop();
RobMeades 0:7ccf0e7e8a83 750 timer.reset();
RobMeades 0:7ccf0e7e8a83 751
RobMeades 0:7ccf0e7e8a83 752 // Check that we reassembled everything correctly
RobMeades 0:7ccf0e7e8a83 753 for (x = 0; ((*(recv_data + x) == *(send_data + x))) && (x < (int) sizeof (send_data)); x++) {
RobMeades 0:7ccf0e7e8a83 754 }
RobMeades 0:7ccf0e7e8a83 755 if (x != sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 756 y = x - 5;
RobMeades 0:7ccf0e7e8a83 757 if (y < 0) {
RobMeades 0:7ccf0e7e8a83 758 y = 0;
RobMeades 0:7ccf0e7e8a83 759 }
RobMeades 0:7ccf0e7e8a83 760 z = 10;
RobMeades 0:7ccf0e7e8a83 761 if (y + z > (int) sizeof (send_data)) {
RobMeades 0:7ccf0e7e8a83 762 z = sizeof(send_data) - y;
RobMeades 0:7ccf0e7e8a83 763 }
RobMeades 0:7ccf0e7e8a83 764 tr_debug("Difference at character %d (send \"%*.*s\", recv \"%*.*s\")",
RobMeades 0:7ccf0e7e8a83 765 x + 1, z, z, send_data + y, z, z, recv_data + y);
RobMeades 0:7ccf0e7e8a83 766 TEST_ASSERT(false);
RobMeades 0:7ccf0e7e8a83 767 }
RobMeades 0:7ccf0e7e8a83 768 free (recv_data);
RobMeades 0:7ccf0e7e8a83 769
RobMeades 0:7ccf0e7e8a83 770 TEST_ASSERT(!connection_has_gone_down);
RobMeades 0:7ccf0e7e8a83 771 sock.close();
RobMeades 0:7ccf0e7e8a83 772 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 773 }
RobMeades 0:7ccf0e7e8a83 774
RobMeades 0:7ccf0e7e8a83 775 // Test TCP data exchange via the asynchronous sigio() mechanism
RobMeades 0:7ccf0e7e8a83 776 void test_tcp_echo_async() {
RobMeades 0:7ccf0e7e8a83 777 TCPSocket sock;
RobMeades 0:7ccf0e7e8a83 778 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 779 bool callback_triggered = false;
RobMeades 0:7ccf0e7e8a83 780 int x;
RobMeades 0:7ccf0e7e8a83 781 int size;
RobMeades 0:7ccf0e7e8a83 782
RobMeades 0:7ccf0e7e8a83 783 driver->deinit();
RobMeades 0:7ccf0e7e8a83 784 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 785 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 786
RobMeades 0:7ccf0e7e8a83 787 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_ECHO_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 788 host_address.set_port(MBED_CONF_APP_ECHO_TCP_PORT);
RobMeades 0:7ccf0e7e8a83 789
RobMeades 0:7ccf0e7e8a83 790 tr_debug("TCP: Server %s address: %s on port %d.", MBED_CONF_APP_ECHO_SERVER,
RobMeades 0:7ccf0e7e8a83 791 host_address.get_ip_address(), host_address.get_port());
RobMeades 0:7ccf0e7e8a83 792
RobMeades 0:7ccf0e7e8a83 793 TEST_ASSERT(sock.open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 794
RobMeades 0:7ccf0e7e8a83 795 // Set up the async callback and set the timeout to zero
RobMeades 0:7ccf0e7e8a83 796 sock.sigio(callback(async_cb, &callback_triggered));
RobMeades 0:7ccf0e7e8a83 797 sock.set_timeout(0);
RobMeades 0:7ccf0e7e8a83 798
RobMeades 0:7ccf0e7e8a83 799 TEST_ASSERT(sock.connect(host_address) == 0);
RobMeades 0:7ccf0e7e8a83 800 // Test min, max, and some random sizes in-between
RobMeades 0:7ccf0e7e8a83 801 do_tcp_echo_async(&sock, 1, &callback_triggered);
RobMeades 0:7ccf0e7e8a83 802 do_tcp_echo_async(&sock, MBED_CONF_APP_TCP_MAX_PACKET_SIZE, &callback_triggered);
RobMeades 0:7ccf0e7e8a83 803 for (x = 0; x < 10; x++) {
RobMeades 0:7ccf0e7e8a83 804 size = (rand() % MBED_CONF_APP_TCP_MAX_PACKET_SIZE) + 1;
RobMeades 0:7ccf0e7e8a83 805 size = fix(size, MBED_CONF_APP_TCP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 806 do_tcp_echo_async(&sock, size, &callback_triggered);
RobMeades 0:7ccf0e7e8a83 807 }
RobMeades 0:7ccf0e7e8a83 808
RobMeades 0:7ccf0e7e8a83 809 sock.close();
RobMeades 0:7ccf0e7e8a83 810
RobMeades 0:7ccf0e7e8a83 811 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 812
RobMeades 0:7ccf0e7e8a83 813 tr_debug("%d TCP packets of size up to %d byte(s) echoed asynchronously and successfully.",
RobMeades 0:7ccf0e7e8a83 814 x, MBED_CONF_APP_TCP_MAX_PACKET_SIZE);
RobMeades 0:7ccf0e7e8a83 815 }
RobMeades 0:7ccf0e7e8a83 816 #endif
RobMeades 0:7ccf0e7e8a83 817
RobMeades 0:7ccf0e7e8a83 818 // Allocate max sockets
RobMeades 0:7ccf0e7e8a83 819 void test_max_sockets() {
RobMeades 0:7ccf0e7e8a83 820 UDPSocket sock[MAX_NUM_SOCKETS];
RobMeades 0:7ccf0e7e8a83 821 UDPSocket sockNone;
RobMeades 0:7ccf0e7e8a83 822 SocketAddress host_address;
RobMeades 0:7ccf0e7e8a83 823
RobMeades 0:7ccf0e7e8a83 824 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 825 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 826
RobMeades 0:7ccf0e7e8a83 827 TEST_ASSERT(driver->gethostbyname(MBED_CONF_APP_NTP_SERVER, &host_address) == 0);
RobMeades 0:7ccf0e7e8a83 828 host_address.set_port(MBED_CONF_APP_NTP_PORT);
RobMeades 0:7ccf0e7e8a83 829
RobMeades 0:7ccf0e7e8a83 830 // Open the first socket and use it
RobMeades 0:7ccf0e7e8a83 831 TEST_ASSERT(sock[0].open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 832 sock[0].set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 833 do_ntp_sock(&sock[0], host_address);
RobMeades 0:7ccf0e7e8a83 834
RobMeades 0:7ccf0e7e8a83 835 // Check that we stop being able to get sockets at the max number
RobMeades 0:7ccf0e7e8a83 836 for (int x = 1; x < (int) (sizeof (sock) / sizeof (sock[0])); x++) {
RobMeades 0:7ccf0e7e8a83 837 TEST_ASSERT(sock[x].open(driver) == 0)
RobMeades 0:7ccf0e7e8a83 838 }
RobMeades 0:7ccf0e7e8a83 839 TEST_ASSERT(sockNone.open(driver) < 0);
RobMeades 0:7ccf0e7e8a83 840
RobMeades 0:7ccf0e7e8a83 841 // Now use the last one
RobMeades 0:7ccf0e7e8a83 842 sock[sizeof (sock) / sizeof (sock[0]) - 1].set_timeout(10000);
RobMeades 0:7ccf0e7e8a83 843 do_ntp_sock(&sock[sizeof (sock) / sizeof (sock[0]) - 1], host_address);
RobMeades 0:7ccf0e7e8a83 844
RobMeades 0:7ccf0e7e8a83 845 // Close all of the sockets
RobMeades 0:7ccf0e7e8a83 846 for (int x = 0; x < (int) (sizeof (sock) / sizeof (sock[0])); x++) {
RobMeades 0:7ccf0e7e8a83 847 TEST_ASSERT(sock[x].close() == 0);
RobMeades 0:7ccf0e7e8a83 848 }
RobMeades 0:7ccf0e7e8a83 849
RobMeades 0:7ccf0e7e8a83 850 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 851 }
RobMeades 0:7ccf0e7e8a83 852
RobMeades 0:7ccf0e7e8a83 853 // Connect with credentials included in the connect request
RobMeades 0:7ccf0e7e8a83 854 void test_connect_credentials() {
RobMeades 0:7ccf0e7e8a83 855
RobMeades 0:7ccf0e7e8a83 856 driver->deinit();
RobMeades 0:7ccf0e7e8a83 857 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 858 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 859 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 860 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 861 }
RobMeades 0:7ccf0e7e8a83 862
RobMeades 0:7ccf0e7e8a83 863 // Test with credentials preset
RobMeades 0:7ccf0e7e8a83 864 void test_connect_preset_credentials() {
RobMeades 0:7ccf0e7e8a83 865
RobMeades 0:7ccf0e7e8a83 866 driver->deinit();
RobMeades 0:7ccf0e7e8a83 867 TEST_ASSERT(driver->init(MBED_CONF_APP_DEFAULT_PIN));
RobMeades 0:7ccf0e7e8a83 868 driver->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
RobMeades 0:7ccf0e7e8a83 869 MBED_CONF_APP_PASSWORD);
RobMeades 0:7ccf0e7e8a83 870 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN) == 0);
RobMeades 0:7ccf0e7e8a83 871 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 872 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 873 }
RobMeades 0:7ccf0e7e8a83 874
RobMeades 0:7ccf0e7e8a83 875 // Test adding and using a SIM pin, then removing it, using the pending
RobMeades 0:7ccf0e7e8a83 876 // mechanism where the change doesn't occur until connect() is called
RobMeades 0:7ccf0e7e8a83 877 void test_check_sim_pin_pending() {
RobMeades 0:7ccf0e7e8a83 878
RobMeades 0:7ccf0e7e8a83 879 driver->deinit();
RobMeades 0:7ccf0e7e8a83 880
RobMeades 0:7ccf0e7e8a83 881 // Enable PIN checking (which will use the current PIN)
RobMeades 0:7ccf0e7e8a83 882 // and also flag that the PIN should be changed to MBED_CONF_APP_ALT_PIN,
RobMeades 0:7ccf0e7e8a83 883 // then try connecting
RobMeades 0:7ccf0e7e8a83 884 driver->set_sim_pin_check(true);
RobMeades 0:7ccf0e7e8a83 885 driver->set_new_sim_pin(MBED_CONF_APP_ALT_PIN);
RobMeades 0:7ccf0e7e8a83 886 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 887 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 888 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 889 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 890 driver->deinit();
RobMeades 0:7ccf0e7e8a83 891
RobMeades 0:7ccf0e7e8a83 892 // Now change the PIN back to what it was before
RobMeades 0:7ccf0e7e8a83 893 driver->set_new_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 894 TEST_ASSERT(driver->connect(MBED_CONF_APP_ALT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 895 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 896 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 897 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 898 driver->deinit();
RobMeades 0:7ccf0e7e8a83 899
RobMeades 0:7ccf0e7e8a83 900 // Check that it was changed back, and this time
RobMeades 0:7ccf0e7e8a83 901 // use the other way of entering the PIN
RobMeades 0:7ccf0e7e8a83 902 driver->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 903 TEST_ASSERT(driver->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
RobMeades 0:7ccf0e7e8a83 904 MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 905 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 906 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 907 driver->deinit();
RobMeades 0:7ccf0e7e8a83 908
RobMeades 0:7ccf0e7e8a83 909 // Remove PIN checking again and check that it no
RobMeades 0:7ccf0e7e8a83 910 // longer matters what the PIN is
RobMeades 0:7ccf0e7e8a83 911 driver->set_sim_pin_check(false);
RobMeades 0:7ccf0e7e8a83 912 TEST_ASSERT(driver->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 913 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 914 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 915 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 916 driver->deinit();
RobMeades 0:7ccf0e7e8a83 917 TEST_ASSERT(driver->init(NULL));
RobMeades 0:7ccf0e7e8a83 918 TEST_ASSERT(driver->connect(MBED_CONF_APP_INCORRECT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 919 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 920 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 921 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 922
RobMeades 0:7ccf0e7e8a83 923 // Put the SIM pin back to the correct value for any subsequent tests
RobMeades 0:7ccf0e7e8a83 924 driver->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 925 }
RobMeades 0:7ccf0e7e8a83 926
RobMeades 0:7ccf0e7e8a83 927 // Test adding and using a SIM pin, then removing it, using the immediate
RobMeades 0:7ccf0e7e8a83 928 // mechanism
RobMeades 0:7ccf0e7e8a83 929 void test_check_sim_pin_immediate() {
RobMeades 0:7ccf0e7e8a83 930
RobMeades 0:7ccf0e7e8a83 931 driver->deinit();
RobMeades 0:7ccf0e7e8a83 932 driver->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 933
RobMeades 0:7ccf0e7e8a83 934 // Enable PIN checking (which will use the current PIN), change
RobMeades 0:7ccf0e7e8a83 935 // the PIN to MBED_CONF_APP_ALT_PIN, then try connecting after powering on and
RobMeades 0:7ccf0e7e8a83 936 // off the modem
RobMeades 0:7ccf0e7e8a83 937 driver->set_sim_pin_check(true, true, MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 938 driver->set_new_sim_pin(MBED_CONF_APP_ALT_PIN, true);
RobMeades 0:7ccf0e7e8a83 939 driver->deinit();
RobMeades 0:7ccf0e7e8a83 940 TEST_ASSERT(driver->init(NULL));
RobMeades 0:7ccf0e7e8a83 941 TEST_ASSERT(driver->connect(MBED_CONF_APP_ALT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 942 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 943 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 944 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 945
RobMeades 0:7ccf0e7e8a83 946 driver->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 947
RobMeades 0:7ccf0e7e8a83 948 // Now change the PIN back to what it was before
RobMeades 0:7ccf0e7e8a83 949 driver->set_new_sim_pin(MBED_CONF_APP_DEFAULT_PIN, true);
RobMeades 0:7ccf0e7e8a83 950 driver->deinit();
RobMeades 0:7ccf0e7e8a83 951 driver->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 952 TEST_ASSERT(driver->init(NULL));
RobMeades 0:7ccf0e7e8a83 953 TEST_ASSERT(driver->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
RobMeades 0:7ccf0e7e8a83 954 MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 955 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 956 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 957
RobMeades 0:7ccf0e7e8a83 958 driver->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 959
RobMeades 0:7ccf0e7e8a83 960 // Remove PIN checking again and check that it no
RobMeades 0:7ccf0e7e8a83 961 // longer matters what the PIN is
RobMeades 0:7ccf0e7e8a83 962 driver->set_sim_pin_check(false, true);
RobMeades 0:7ccf0e7e8a83 963 driver->deinit();
RobMeades 0:7ccf0e7e8a83 964 TEST_ASSERT(driver->init(MBED_CONF_APP_INCORRECT_PIN));
RobMeades 0:7ccf0e7e8a83 965 TEST_ASSERT(driver->connect(NULL, MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME,
RobMeades 0:7ccf0e7e8a83 966 MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 967 use_connection(driver);
RobMeades 0:7ccf0e7e8a83 968 drop_connection(driver);
RobMeades 0:7ccf0e7e8a83 969
RobMeades 0:7ccf0e7e8a83 970 // Put the SIM pin back to the correct value for any subsequent tests
RobMeades 0:7ccf0e7e8a83 971 driver->set_sim_pin(MBED_CONF_APP_DEFAULT_PIN);
RobMeades 0:7ccf0e7e8a83 972 }
RobMeades 0:7ccf0e7e8a83 973
RobMeades 0:7ccf0e7e8a83 974 // Test being able to connect with a local instance of the driver
RobMeades 0:7ccf0e7e8a83 975 // NOTE: since this local instance will fiddle with bits of HW that the
RobMeades 0:7ccf0e7e8a83 976 // static instance thought it owned, the static instance will no longer
RobMeades 0:7ccf0e7e8a83 977 // work afterwards, hence this must be run as the last test in the list
RobMeades 0:7ccf0e7e8a83 978 void test_connect_local_instance_last_test() {
RobMeades 0:7ccf0e7e8a83 979
RobMeades 0:7ccf0e7e8a83 980 UbloxATCellularInterface *pLocalInterface = NULL;
RobMeades 0:7ccf0e7e8a83 981
RobMeades 0:7ccf0e7e8a83 982 pLocalInterface = new UbloxATCellularInterface(MDMTXD, MDMRXD,
RobMeades 0:7ccf0e7e8a83 983 MBED_CONF_UBLOX_CELL_BAUD_RATE,
RobMeades 0:7ccf0e7e8a83 984 MBED_CONF_APP_DEBUG_ON);
RobMeades 0:7ccf0e7e8a83 985 pLocalInterface->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 986
RobMeades 0:7ccf0e7e8a83 987 TEST_ASSERT(pLocalInterface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 988 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 989 use_connection(pLocalInterface);
RobMeades 0:7ccf0e7e8a83 990 drop_connection(pLocalInterface);
RobMeades 0:7ccf0e7e8a83 991 delete pLocalInterface;
RobMeades 0:7ccf0e7e8a83 992
RobMeades 0:7ccf0e7e8a83 993 pLocalInterface = new UbloxATCellularInterface(MDMTXD, MDMRXD,
RobMeades 0:7ccf0e7e8a83 994 MBED_CONF_UBLOX_CELL_BAUD_RATE,
RobMeades 0:7ccf0e7e8a83 995 MBED_CONF_APP_DEBUG_ON);
RobMeades 0:7ccf0e7e8a83 996 pLocalInterface->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 997
RobMeades 0:7ccf0e7e8a83 998 TEST_ASSERT(pLocalInterface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN,
RobMeades 0:7ccf0e7e8a83 999 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0);
RobMeades 0:7ccf0e7e8a83 1000 use_connection(pLocalInterface);
RobMeades 0:7ccf0e7e8a83 1001 drop_connection(pLocalInterface);
RobMeades 0:7ccf0e7e8a83 1002 delete pLocalInterface;
RobMeades 0:7ccf0e7e8a83 1003 }
RobMeades 0:7ccf0e7e8a83 1004
RobMeades 0:7ccf0e7e8a83 1005 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 1006 // TEST ENVIRONMENT
RobMeades 0:7ccf0e7e8a83 1007 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 1008
RobMeades 0:7ccf0e7e8a83 1009 // Setup the test environment
RobMeades 0:7ccf0e7e8a83 1010 utest::v1::status_t test_setup(const size_t number_of_cases) {
RobMeades 0:7ccf0e7e8a83 1011 // Setup Greentea with a timeout
RobMeades 0:7ccf0e7e8a83 1012 GREENTEA_SETUP(960, "default_auto");
RobMeades 0:7ccf0e7e8a83 1013 return verbose_test_setup_handler(number_of_cases);
RobMeades 0:7ccf0e7e8a83 1014 }
RobMeades 0:7ccf0e7e8a83 1015
RobMeades 0:7ccf0e7e8a83 1016 // IMPORTANT!!! if you make a change to the tests here you should
RobMeades 0:7ccf0e7e8a83 1017 // check whether the same change should be made to the tests under
RobMeades 0:7ccf0e7e8a83 1018 // the GENERIC driver.
RobMeades 0:7ccf0e7e8a83 1019
RobMeades 0:7ccf0e7e8a83 1020 // Test cases
RobMeades 0:7ccf0e7e8a83 1021 Case cases[] = {
RobMeades 0:7ccf0e7e8a83 1022 Case("Set randomise", test_set_randomise),
RobMeades 0:7ccf0e7e8a83 1023 #ifdef MBED_CONF_APP_ECHO_SERVER
RobMeades 0:7ccf0e7e8a83 1024 Case("UDP echo test", test_udp_echo),
RobMeades 0:7ccf0e7e8a83 1025 # ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
RobMeades 0:7ccf0e7e8a83 1026 Case("UDP recv sizes", test_udp_echo_recv_sizes),
RobMeades 0:7ccf0e7e8a83 1027 # endif
RobMeades 0:7ccf0e7e8a83 1028 Case("UDP async echo test", test_udp_echo_async),
RobMeades 0:7ccf0e7e8a83 1029 # ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
RobMeades 0:7ccf0e7e8a83 1030 Case("TCP recv sizes", test_tcp_echo_recv_sizes),
RobMeades 0:7ccf0e7e8a83 1031 # endif
RobMeades 0:7ccf0e7e8a83 1032 Case("TCP async echo test", test_tcp_echo_async),
RobMeades 0:7ccf0e7e8a83 1033 #endif
RobMeades 0:7ccf0e7e8a83 1034 #ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 to run this test
RobMeades 0:7ccf0e7e8a83 1035 Case("Alloc max sockets", test_max_sockets),
RobMeades 0:7ccf0e7e8a83 1036 #endif
RobMeades 0:7ccf0e7e8a83 1037 Case("Connect with credentials", test_connect_credentials),
RobMeades 0:7ccf0e7e8a83 1038 Case("Connect with preset credentials", test_connect_preset_credentials),
RobMeades 0:7ccf0e7e8a83 1039 #if MBED_CONF_APP_RUN_SIM_PIN_CHANGE_TESTS
RobMeades 0:7ccf0e7e8a83 1040 Case("Check SIM pin, pending", test_check_sim_pin_pending),
RobMeades 0:7ccf0e7e8a83 1041 Case("Check SIM pin, immediate", test_check_sim_pin_immediate),
RobMeades 0:7ccf0e7e8a83 1042 #endif
RobMeades 0:7ccf0e7e8a83 1043 #ifndef TARGET_UBLOX_C027 // Not enough RAM on little 'ole C027 for this
RobMeades 0:7ccf0e7e8a83 1044 Case("Connect using local instance, must be last test", test_connect_local_instance_last_test)
RobMeades 0:7ccf0e7e8a83 1045 #endif
RobMeades 0:7ccf0e7e8a83 1046 };
RobMeades 0:7ccf0e7e8a83 1047
RobMeades 0:7ccf0e7e8a83 1048 Specification specification(test_setup, cases);
RobMeades 0:7ccf0e7e8a83 1049
RobMeades 0:7ccf0e7e8a83 1050 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 1051 // MAIN
RobMeades 0:7ccf0e7e8a83 1052 // ----------------------------------------------------------------
RobMeades 0:7ccf0e7e8a83 1053
RobMeades 0:7ccf0e7e8a83 1054 int main() {
RobMeades 0:7ccf0e7e8a83 1055
RobMeades 0:7ccf0e7e8a83 1056 #ifdef FEATURE_COMMON_PAL
RobMeades 0:7ccf0e7e8a83 1057 mbed_trace_init();
RobMeades 0:7ccf0e7e8a83 1058
RobMeades 0:7ccf0e7e8a83 1059 mbed_trace_mutex_wait_function_set(lock);
RobMeades 0:7ccf0e7e8a83 1060 mbed_trace_mutex_release_function_set(unlock);
RobMeades 0:7ccf0e7e8a83 1061 #endif
RobMeades 0:7ccf0e7e8a83 1062
RobMeades 0:7ccf0e7e8a83 1063 driver->connection_status_cb(connection_down_cb);
RobMeades 0:7ccf0e7e8a83 1064
RobMeades 0:7ccf0e7e8a83 1065 // Run tests
RobMeades 0:7ccf0e7e8a83 1066 return !Harness::run(specification);
RobMeades 0:7ccf0e7e8a83 1067 }
RobMeades 0:7ccf0e7e8a83 1068
RobMeades 0:7ccf0e7e8a83 1069 // End Of File
RobMeades 0:7ccf0e7e8a83 1070