ublox-at-cellular-interface

Committer:
rob.meades@u-blox.com
Date:
Thu Jun 15 14:04:26 2017 +0100
Revision:
6:63dad754c267
Parent:
1:bc228becc45d
Child:
12:ff6fac481487
Improve template, add extra time for gethostbyname() as it seems to take an age on some networks, rename "driver" to "interface" for consistency with the PPP test suite.

Who changed what in which revision?

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