fork
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "UbloxATCellularInterface.h" 00002 #include "greentea-client/test_env.h" 00003 #include "unity.h" 00004 #include "utest.h" 00005 #include "UDPSocket.h" 00006 #include "mbed_stats.h" 00007 #ifdef FEATURE_COMMON_PAL 00008 #include "mbed_trace.h" 00009 #define TRACE_GROUP "TEST" 00010 #else 00011 #define tr_debug(format, ...) debug(format "\n", ## __VA_ARGS__) 00012 #define tr_info(format, ...) debug(format "\n", ## __VA_ARGS__) 00013 #define tr_warn(format, ...) debug(format "\n", ## __VA_ARGS__) 00014 #define tr_error(format, ...) debug(format "\n", ## __VA_ARGS__) 00015 #endif 00016 00017 using namespace utest::v1; 00018 00019 // IMPORTANT!!! if you make a change to the tests here you should 00020 // check whether the same change should be made to the tests under 00021 // the PPP interface. 00022 00023 // NOTE: these test are only as reliable as UDP across the internet 00024 // over a radio link. The tests expect an NTP server to respond 00025 // to UDP packets and, if configured, an echo server to respond 00026 // to UDP packets. This simply may not happen. Please be patient. 00027 00028 // ---------------------------------------------------------------- 00029 // COMPILE-TIME MACROS 00030 // ---------------------------------------------------------------- 00031 00032 // These macros can be overridden with an mbed_app.json file and 00033 // contents of the following form: 00034 // 00035 //{ 00036 // "config": { 00037 // "default-pin": { 00038 // "value": "\"1234\"" 00039 // } 00040 //} 00041 // 00042 // See the template_mbed_app.txt in this directory for a fuller example. 00043 00044 // Whether we can do the mbed stats tests or not 00045 #ifndef MBED_HEAP_STATS_ENABLED 00046 # define MBED_HEAP_STATS_ENABLED 0 00047 #endif 00048 00049 // Whether debug trace is on 00050 #ifndef MBED_CONF_APP_DEBUG_ON 00051 # define MBED_CONF_APP_DEBUG_ON false 00052 #endif 00053 00054 // The credentials of the SIM in the board. 00055 #ifndef MBED_CONF_APP_DEFAULT_PIN 00056 // Note: if PIN is enabled on your SIM, or you wish to run the SIM PIN change 00057 // tests, you must define the PIN for your SIM (see note above on using 00058 // mbed_app.json to do so). 00059 # define MBED_CONF_APP_DEFAULT_PIN "0000" 00060 #endif 00061 #ifndef MBED_CONF_APP_APN 00062 # define MBED_CONF_APP_APN NULL 00063 #endif 00064 #ifndef MBED_CONF_APP_USERNAME 00065 # define MBED_CONF_APP_USERNAME NULL 00066 #endif 00067 #ifndef MBED_CONF_APP_PASSWORD 00068 # define MBED_CONF_APP_PASSWORD NULL 00069 #endif 00070 00071 // Servers and ports 00072 #ifndef MBED_CONF_APP_NTP_SERVER 00073 # define MBED_CONF_APP_NTP_SERVER "2.pool.ntp.org" 00074 #else 00075 # ifndef MBED_CONF_APP_NTP_PORT 00076 # error "MBED_CONF_APP_NTP_PORT must be defined if MBED_CONF_APP_NTP_SERVER is defined" 00077 # endif 00078 #endif 00079 #ifndef MBED_CONF_APP_NTP_PORT 00080 # define MBED_CONF_APP_NTP_PORT 123 00081 #endif 00082 00083 // UDP packet size limit for testing 00084 #ifndef MBED_CONF_APP_UDP_MAX_PACKET_SIZE 00085 # define MBED_CONF_APP_UDP_MAX_PACKET_SIZE 1024 00086 #endif 00087 00088 // The number of retries for UDP exchanges 00089 #define NUM_UDP_RETRIES 5 00090 00091 // ---------------------------------------------------------------- 00092 // PRIVATE VARIABLES 00093 // ---------------------------------------------------------------- 00094 00095 #ifdef FEATURE_COMMON_PAL 00096 // Lock for debug prints 00097 static Mutex mtx; 00098 #endif 00099 00100 // Connection flag 00101 static bool connection_has_gone_down = false; 00102 00103 // ---------------------------------------------------------------- 00104 // PRIVATE FUNCTIONS 00105 // ---------------------------------------------------------------- 00106 00107 #ifdef FEATURE_COMMON_PAL 00108 // Locks for debug prints 00109 static void lock() 00110 { 00111 mtx.lock(); 00112 } 00113 00114 static void unlock() 00115 { 00116 mtx.unlock(); 00117 } 00118 #endif 00119 00120 // Callback in case the connection goes down 00121 static void connection_down_cb(nsapi_error_t err) 00122 { 00123 connection_has_gone_down = true; 00124 } 00125 00126 // Get NTP time from a socket 00127 static void do_ntp_sock (UDPSocket *sock, SocketAddress ntp_address) 00128 { 00129 char ntp_values[48] = { 0 }; 00130 time_t timestamp = 0; 00131 int len; 00132 bool comms_done = false; 00133 00134 ntp_values[0] = '\x1b'; 00135 00136 // Retry this a few times, don't want to fail due to a flaky link 00137 for (unsigned int x = 0; !comms_done && (x < NUM_UDP_RETRIES); x++) { 00138 sock->sendto(ntp_address, (void*) ntp_values, sizeof(ntp_values)); 00139 len = sock->recvfrom(&ntp_address, (void*) ntp_values, sizeof(ntp_values)); 00140 if (len > 0) { 00141 comms_done = true; 00142 } 00143 } 00144 TEST_ASSERT (comms_done); 00145 00146 tr_debug("UDP: %d byte(s) returned by NTP server.", len); 00147 if (len >= 43) { 00148 struct tm *localTime; 00149 time_t TIME1970 = 2208988800U; 00150 timestamp |= ((int) *(ntp_values + 40)) << 24; 00151 timestamp |= ((int) *(ntp_values + 41)) << 16; 00152 timestamp |= ((int) *(ntp_values + 42)) << 8; 00153 timestamp |= ((int) *(ntp_values + 43)); 00154 timestamp -= TIME1970; 00155 srand (timestamp); 00156 tr_debug("srand() called"); 00157 localTime = localtime(×tamp); 00158 if (localTime) { 00159 char timeString[25]; 00160 if (strftime(timeString, sizeof(timeString), "%a %b %d %H:%M:%S %Y", localTime) > 0) { 00161 printf("NTP timestamp is %s.\n", timeString); 00162 } 00163 } 00164 } 00165 } 00166 00167 // Get NTP time 00168 static void do_ntp(UbloxATCellularInterface *interface) 00169 { 00170 UDPSocket sock; 00171 SocketAddress host_address; 00172 00173 TEST_ASSERT(sock.open(interface) == 0) 00174 00175 TEST_ASSERT(interface->gethostbyname(MBED_CONF_APP_NTP_SERVER, &host_address) == 0); 00176 host_address.set_port(MBED_CONF_APP_NTP_PORT); 00177 00178 tr_debug("UDP: NIST server %s address: %s on port %d.", MBED_CONF_APP_NTP_SERVER, 00179 host_address.get_ip_address(), host_address.get_port()); 00180 00181 sock.set_timeout(10000); 00182 00183 do_ntp_sock(&sock, host_address); 00184 00185 sock.close(); 00186 } 00187 00188 // Use a connection, checking that it is good 00189 static void use_connection(UbloxATCellularInterface *interface) 00190 { 00191 const char * ip_address = interface->get_ip_address(); 00192 const char * net_mask = interface->get_netmask(); 00193 const char * gateway = interface->get_gateway(); 00194 00195 TEST_ASSERT(interface->is_connected()); 00196 00197 TEST_ASSERT(ip_address != NULL); 00198 tr_debug ("IP address %s.", ip_address); 00199 TEST_ASSERT(net_mask == NULL); 00200 tr_debug ("Net mask %s.", net_mask); 00201 TEST_ASSERT(gateway != NULL); 00202 tr_debug ("Gateway %s.", gateway); 00203 00204 do_ntp(interface); 00205 TEST_ASSERT(!connection_has_gone_down); 00206 } 00207 00208 // Drop a connection and check that it has dropped 00209 static void drop_connection(UbloxATCellularInterface *interface) 00210 { 00211 TEST_ASSERT(interface->disconnect() == 0); 00212 TEST_ASSERT(connection_has_gone_down); 00213 connection_has_gone_down = false; 00214 TEST_ASSERT(!interface->is_connected()); 00215 } 00216 00217 // ---------------------------------------------------------------- 00218 // TESTS 00219 // ---------------------------------------------------------------- 00220 00221 // Test that sleep is possible both 00222 // before and after running the driver. 00223 void test_sleep() { 00224 00225 TEST_ASSERT(sleep_manager_can_deep_sleep() == true); 00226 00227 // Create an instance of the cellular interface 00228 UbloxATCellularInterface *interface = 00229 new UbloxATCellularInterface(MDMTXD, MDMRXD, 00230 MBED_CONF_UBLOX_CELL_BAUD_RATE, 00231 MBED_CONF_APP_DEBUG_ON); 00232 interface->connection_status_cb(connection_down_cb); 00233 00234 // Use it 00235 TEST_ASSERT(interface->init(MBED_CONF_APP_DEFAULT_PIN)); 00236 TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, 00237 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0); 00238 use_connection(interface); 00239 TEST_ASSERT(sleep_manager_can_deep_sleep() == false); 00240 drop_connection(interface); 00241 00242 // Destroy the instance 00243 delete interface; 00244 00245 TEST_ASSERT(sleep_manager_can_deep_sleep() == true); 00246 } 00247 00248 // Test that if communication with the modem 00249 // fails for some reason that sleeping is possible 00250 // afterwards (specific case found by Rostyslav Y.) 00251 void test_sleep_failed_connection() { 00252 00253 TEST_ASSERT(sleep_manager_can_deep_sleep() == true); 00254 00255 // Create a bad instance of the cellular interface 00256 UbloxATCellularInterface *interface = 00257 new UbloxATCellularInterface(MDMTXD, MDMRXD, 00258 20, /* Silly baud rate */ 00259 MBED_CONF_APP_DEBUG_ON); 00260 00261 // [Fail to] use it 00262 TEST_ASSERT_FALSE(interface->init(MBED_CONF_APP_DEFAULT_PIN)); 00263 TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, 00264 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) != NSAPI_ERROR_OK); 00265 // Destroy the instance 00266 delete interface; 00267 00268 TEST_ASSERT(sleep_manager_can_deep_sleep() == true); 00269 } 00270 00271 #if MBED_HEAP_STATS_ENABLED 00272 // Test for memory leaks. 00273 void test_memory_leak() { 00274 00275 mbed_stats_heap_t heap_stats_start; 00276 mbed_stats_heap_t heap_stats; 00277 00278 mbed_stats_heap_get(&heap_stats_start); 00279 00280 // Create an instance of the cellular interface 00281 UbloxATCellularInterface *interface = 00282 new UbloxATCellularInterface(MDMTXD, MDMRXD, 00283 MBED_CONF_UBLOX_CELL_BAUD_RATE, 00284 MBED_CONF_APP_DEBUG_ON); 00285 interface->connection_status_cb(connection_down_cb); 00286 00287 // Use it 00288 TEST_ASSERT(interface->init(MBED_CONF_APP_DEFAULT_PIN)); 00289 TEST_ASSERT(interface->connect(MBED_CONF_APP_DEFAULT_PIN, MBED_CONF_APP_APN, 00290 MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == 0); 00291 mbed_stats_heap_get(&heap_stats); 00292 TEST_ASSERT(heap_stats.current_size > heap_stats_start.current_size); 00293 use_connection(interface); 00294 drop_connection(interface); 00295 00296 // Destroy the instance 00297 delete interface; 00298 00299 mbed_stats_heap_get(&heap_stats); 00300 TEST_ASSERT(heap_stats.current_size == heap_stats_start.current_size); 00301 } 00302 #endif 00303 00304 // ---------------------------------------------------------------- 00305 // TEST ENVIRONMENT 00306 // ---------------------------------------------------------------- 00307 00308 // Setup the test environment 00309 utest::v1::status_t test_setup(const size_t number_of_cases) { 00310 // Setup Greentea with a timeout 00311 GREENTEA_SETUP(300, "default_auto"); 00312 return verbose_test_setup_handler(number_of_cases); 00313 } 00314 00315 // IMPORTANT!!! if you make a change to the tests here you should 00316 // check whether the same change should be made to the tests under 00317 // the PPP interface. 00318 00319 // Test cases 00320 Case cases[] = { 00321 Case("Sleep test", test_sleep), 00322 Case("Sleep test with failed modem comms", test_sleep_failed_connection) 00323 #if MBED_HEAP_STATS_ENABLED 00324 , Case("Memory leak test", test_memory_leak) 00325 #endif 00326 }; 00327 00328 Specification specification(test_setup, cases); 00329 00330 // ---------------------------------------------------------------- 00331 // MAIN 00332 // ---------------------------------------------------------------- 00333 00334 int main() { 00335 00336 #ifdef FEATURE_COMMON_PAL 00337 mbed_trace_init(); 00338 00339 mbed_trace_mutex_wait_function_set(lock); 00340 mbed_trace_mutex_release_function_set(unlock); 00341 #endif 00342 00343 // Run tests 00344 return !Harness::run(specification); 00345 } 00346 00347 // End Of File
Generated on Wed Jul 13 2022 14:24:30 by 1.7.2