NuMaker Cellular(NB-IoT/4G)

Committer:
cyliang
Date:
Mon Feb 03 03:29:07 2020 +0000
Revision:
3:6f804b5237be
Parent:
2:8730ba700f06
Child:
4:9432d7355f2b
Sync with OpenNuvoton: migrate to OS 5.15.0 & fix run crash issue when using IAR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cyliang 0:25c616c85d69 1 /*
cyliang 0:25c616c85d69 2 * Copyright (c) 2017 ARM Limited. All rights reserved.
cyliang 0:25c616c85d69 3 * SPDX-License-Identifier: Apache-2.0
cyliang 0:25c616c85d69 4 * Licensed under the Apache License, Version 2.0 (the License); you may
cyliang 0:25c616c85d69 5 * not use this file except in compliance with the License.
cyliang 0:25c616c85d69 6 * You may obtain a copy of the License at
cyliang 0:25c616c85d69 7 *
cyliang 0:25c616c85d69 8 * http://www.apache.org/licenses/LICENSE-2.0
cyliang 0:25c616c85d69 9 *
cyliang 0:25c616c85d69 10 * Unless required by applicable law or agreed to in writing, software
cyliang 0:25c616c85d69 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
cyliang 0:25c616c85d69 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cyliang 0:25c616c85d69 13 * See the License for the specific language governing permissions and
cyliang 0:25c616c85d69 14 * limitations under the License.
cyliang 0:25c616c85d69 15 */
cyliang 0:25c616c85d69 16
cyliang 0:25c616c85d69 17 #include "mbed.h"
cyliang 0:25c616c85d69 18 #include "common_functions.h"
cyliang 0:25c616c85d69 19 #include "UDPSocket.h"
cyliang 0:25c616c85d69 20 #include "CellularLog.h"
cyliang 0:25c616c85d69 21
cyliang 0:25c616c85d69 22 #define UDP 0
cyliang 0:25c616c85d69 23 #define TCP 1
cyliang 0:25c616c85d69 24
cyliang 0:25c616c85d69 25 // Number of retries /
cyliang 0:25c616c85d69 26 #define RETRY_COUNT 3
cyliang 0:25c616c85d69 27
cyliang 0:25c616c85d69 28 NetworkInterface *iface;
cyliang 0:25c616c85d69 29
cyliang 0:25c616c85d69 30 // Echo server hostname
cyliang 0:25c616c85d69 31 const char *host_name = MBED_CONF_APP_ECHO_SERVER_HOSTNAME;
cyliang 0:25c616c85d69 32
cyliang 0:25c616c85d69 33 // Echo server port (same for TCP and UDP)
cyliang 0:25c616c85d69 34 const int port = MBED_CONF_APP_ECHO_SERVER_PORT;
cyliang 0:25c616c85d69 35
cyliang 0:25c616c85d69 36 static rtos::Mutex trace_mutex;
cyliang 0:25c616c85d69 37
cyliang 0:25c616c85d69 38 #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 39 static void trace_wait()
cyliang 0:25c616c85d69 40 {
cyliang 0:25c616c85d69 41 trace_mutex.lock();
cyliang 0:25c616c85d69 42 }
cyliang 0:25c616c85d69 43
cyliang 0:25c616c85d69 44 static void trace_release()
cyliang 0:25c616c85d69 45 {
cyliang 0:25c616c85d69 46 trace_mutex.unlock();
cyliang 0:25c616c85d69 47 }
cyliang 0:25c616c85d69 48
cyliang 0:25c616c85d69 49 static char time_st[50];
cyliang 0:25c616c85d69 50
cyliang 0:25c616c85d69 51 static char* trace_time(size_t ss)
cyliang 0:25c616c85d69 52 {
cyliang 0:25c616c85d69 53 snprintf(time_st, 49, "[%08llums]", Kernel::get_ms_count());
cyliang 0:25c616c85d69 54 return time_st;
cyliang 0:25c616c85d69 55 }
cyliang 0:25c616c85d69 56
cyliang 0:25c616c85d69 57 static void trace_open()
cyliang 0:25c616c85d69 58 {
cyliang 0:25c616c85d69 59 mbed_trace_init();
cyliang 0:25c616c85d69 60 mbed_trace_prefix_function_set( &trace_time );
cyliang 0:25c616c85d69 61
cyliang 0:25c616c85d69 62 mbed_trace_mutex_wait_function_set(trace_wait);
cyliang 0:25c616c85d69 63 mbed_trace_mutex_release_function_set(trace_release);
cyliang 0:25c616c85d69 64
cyliang 0:25c616c85d69 65 mbed_cellular_trace::mutex_wait_function_set(trace_wait);
cyliang 0:25c616c85d69 66 mbed_cellular_trace::mutex_release_function_set(trace_release);
cyliang 0:25c616c85d69 67 }
cyliang 0:25c616c85d69 68
cyliang 0:25c616c85d69 69 static void trace_close()
cyliang 0:25c616c85d69 70 {
cyliang 0:25c616c85d69 71 mbed_cellular_trace::mutex_wait_function_set(NULL);
cyliang 0:25c616c85d69 72 mbed_cellular_trace::mutex_release_function_set(NULL);
cyliang 0:25c616c85d69 73
cyliang 0:25c616c85d69 74 mbed_trace_free();
cyliang 0:25c616c85d69 75 }
cyliang 0:25c616c85d69 76 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 77
cyliang 0:25c616c85d69 78 Thread dot_thread(osPriorityNormal, 512);
cyliang 0:25c616c85d69 79
cyliang 0:25c616c85d69 80 void print_function(const char *format, ...)
cyliang 0:25c616c85d69 81 {
cyliang 0:25c616c85d69 82 trace_mutex.lock();
cyliang 0:25c616c85d69 83 va_list arglist;
cyliang 0:25c616c85d69 84 va_start( arglist, format );
cyliang 0:25c616c85d69 85 vprintf(format, arglist);
cyliang 0:25c616c85d69 86 va_end( arglist );
cyliang 0:25c616c85d69 87 trace_mutex.unlock();
cyliang 0:25c616c85d69 88 }
cyliang 0:25c616c85d69 89
cyliang 0:25c616c85d69 90 void dot_event()
cyliang 0:25c616c85d69 91 {
cyliang 0:25c616c85d69 92 while (true) {
cyliang 0:25c616c85d69 93 ThisThread::sleep_for(4000);
cyliang 0:25c616c85d69 94 if (iface && iface->get_connection_status() == NSAPI_STATUS_GLOBAL_UP) {
cyliang 0:25c616c85d69 95 break;
cyliang 0:25c616c85d69 96 } else {
cyliang 0:25c616c85d69 97 trace_mutex.lock();
cyliang 0:25c616c85d69 98 printf(".");
cyliang 0:25c616c85d69 99 fflush(stdout);
cyliang 0:25c616c85d69 100 trace_mutex.unlock();
cyliang 0:25c616c85d69 101 }
cyliang 0:25c616c85d69 102 }
cyliang 0:25c616c85d69 103 }
cyliang 0:25c616c85d69 104
cyliang 0:25c616c85d69 105 /**
cyliang 0:25c616c85d69 106 * Connects to the Cellular Network
cyliang 0:25c616c85d69 107 */
cyliang 0:25c616c85d69 108 nsapi_error_t do_connect()
cyliang 0:25c616c85d69 109 {
cyliang 0:25c616c85d69 110 nsapi_error_t retcode = NSAPI_ERROR_OK;
cyliang 0:25c616c85d69 111 uint8_t retry_counter = 0;
cyliang 0:25c616c85d69 112
cyliang 0:25c616c85d69 113 while (iface->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) {
cyliang 0:25c616c85d69 114 retcode = iface->connect();
cyliang 0:25c616c85d69 115 if (retcode == NSAPI_ERROR_AUTH_FAILURE) {
cyliang 0:25c616c85d69 116 print_function("\n\nAuthentication Failure. Exiting application\n");
cyliang 0:25c616c85d69 117 } else if (retcode == NSAPI_ERROR_OK) {
cyliang 0:25c616c85d69 118 print_function("\n\nConnection Established.\n");
cyliang 0:25c616c85d69 119 } else if (retry_counter > RETRY_COUNT) {
cyliang 0:25c616c85d69 120 print_function("\n\nFatal connection failure: %d\n", retcode);
cyliang 0:25c616c85d69 121 } else {
cyliang 0:25c616c85d69 122 print_function("\n\nCouldn't connect: %d, will retry\n", retcode);
cyliang 0:25c616c85d69 123 retry_counter++;
cyliang 0:25c616c85d69 124 continue;
cyliang 0:25c616c85d69 125 }
cyliang 0:25c616c85d69 126 break;
cyliang 0:25c616c85d69 127 }
cyliang 0:25c616c85d69 128 return retcode;
cyliang 0:25c616c85d69 129 }
cyliang 0:25c616c85d69 130
cyliang 0:25c616c85d69 131 /**
cyliang 0:25c616c85d69 132 * Opens a UDP or a TCP socket with the given echo server and performs an echo
cyliang 0:25c616c85d69 133 * transaction retrieving current.
cyliang 0:25c616c85d69 134 */
cyliang 0:25c616c85d69 135 nsapi_error_t test_send_recv()
cyliang 0:25c616c85d69 136 {
cyliang 0:25c616c85d69 137 nsapi_size_or_error_t retcode;
cyliang 0:25c616c85d69 138 #if MBED_CONF_APP_SOCK_TYPE == TCP
cyliang 0:25c616c85d69 139 TCPSocket sock;
cyliang 0:25c616c85d69 140 #else
cyliang 0:25c616c85d69 141 UDPSocket sock;
cyliang 0:25c616c85d69 142 #endif
cyliang 0:25c616c85d69 143
cyliang 0:25c616c85d69 144 retcode = sock.open(iface);
cyliang 0:25c616c85d69 145 if (retcode != NSAPI_ERROR_OK) {
cyliang 0:25c616c85d69 146 #if MBED_CONF_APP_SOCK_TYPE == TCP
cyliang 0:25c616c85d69 147 print_function("TCPSocket.open() fails, code: %d\n", retcode);
cyliang 0:25c616c85d69 148 #else
cyliang 0:25c616c85d69 149 print_function("UDPSocket.open() fails, code: %d\n", retcode);
cyliang 0:25c616c85d69 150 #endif
cyliang 0:25c616c85d69 151 return -1;
cyliang 0:25c616c85d69 152 }
cyliang 0:25c616c85d69 153
cyliang 0:25c616c85d69 154 SocketAddress sock_addr;
cyliang 0:25c616c85d69 155 retcode = iface->gethostbyname(host_name, &sock_addr);
cyliang 0:25c616c85d69 156 if (retcode != NSAPI_ERROR_OK) {
cyliang 0:25c616c85d69 157 print_function("Couldn't resolve remote host: %s, code: %d\n", host_name, retcode);
cyliang 0:25c616c85d69 158 return -1;
cyliang 0:25c616c85d69 159 }
cyliang 0:25c616c85d69 160
cyliang 0:25c616c85d69 161 sock_addr.set_port(port);
cyliang 0:25c616c85d69 162
cyliang 0:25c616c85d69 163 sock.set_timeout(15000);
cyliang 0:25c616c85d69 164 int n = 0;
cyliang 0:25c616c85d69 165 const char *echo_string = "TEST";
cyliang 0:25c616c85d69 166 char recv_buf[4];
cyliang 0:25c616c85d69 167 #if MBED_CONF_APP_SOCK_TYPE == TCP
cyliang 0:25c616c85d69 168 retcode = sock.connect(sock_addr);
cyliang 0:25c616c85d69 169 if (retcode < 0) {
cyliang 0:25c616c85d69 170 print_function("TCPSocket.connect() fails, code: %d\n", retcode);
cyliang 0:25c616c85d69 171 return -1;
cyliang 0:25c616c85d69 172 } else {
cyliang 0:25c616c85d69 173 print_function("TCP: connected with %s server\n", host_name);
cyliang 0:25c616c85d69 174 }
cyliang 0:25c616c85d69 175 retcode = sock.send((void*) echo_string, sizeof(echo_string));
cyliang 0:25c616c85d69 176 if (retcode < 0) {
cyliang 0:25c616c85d69 177 print_function("TCPSocket.send() fails, code: %d\n", retcode);
cyliang 0:25c616c85d69 178 return -1;
cyliang 0:25c616c85d69 179 } else {
cyliang 0:25c616c85d69 180 print_function("TCP: Sent %d Bytes to %s\n", retcode, host_name);
cyliang 0:25c616c85d69 181 }
cyliang 0:25c616c85d69 182
cyliang 0:25c616c85d69 183 n = sock.recv((void*) recv_buf, sizeof(recv_buf));
cyliang 0:25c616c85d69 184 #else
cyliang 0:25c616c85d69 185
cyliang 0:25c616c85d69 186 retcode = sock.sendto(sock_addr, (void*) echo_string, sizeof(echo_string));
cyliang 0:25c616c85d69 187 if (retcode < 0) {
cyliang 0:25c616c85d69 188 print_function("UDPSocket.sendto() fails, code: %d\n", retcode);
cyliang 0:25c616c85d69 189 return -1;
cyliang 0:25c616c85d69 190 } else {
cyliang 0:25c616c85d69 191 print_function("UDP: Sent %d Bytes to %s\n", retcode, host_name);
cyliang 0:25c616c85d69 192 }
cyliang 0:25c616c85d69 193
cyliang 0:25c616c85d69 194 n = sock.recvfrom(&sock_addr, (void*) recv_buf, sizeof(recv_buf));
cyliang 0:25c616c85d69 195 #endif
cyliang 0:25c616c85d69 196
cyliang 0:25c616c85d69 197 sock.close();
cyliang 0:25c616c85d69 198
cyliang 0:25c616c85d69 199 if (n > 0) {
cyliang 0:25c616c85d69 200 print_function("Received from echo server %d Bytes\n", n);
cyliang 0:25c616c85d69 201 return 0;
cyliang 0:25c616c85d69 202 }
cyliang 0:25c616c85d69 203
cyliang 0:25c616c85d69 204 return -1;
cyliang 0:25c616c85d69 205 }
cyliang 0:25c616c85d69 206
cyliang 0:25c616c85d69 207 int main()
cyliang 0:25c616c85d69 208 {
cyliang 0:25c616c85d69 209 print_function("\n\nmbed-os-example-cellular\n");
cyliang 0:25c616c85d69 210 print_function("\n\nBuilt: %s, %s\n", __DATE__, __TIME__);
cyliang 0:25c616c85d69 211 #ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN
cyliang 3:6f804b5237be 212 print_function("\n\n[MAIN], plmn: %d\n", MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN);
cyliang 0:25c616c85d69 213 #endif
cyliang 0:25c616c85d69 214
cyliang 0:25c616c85d69 215 print_function("Establishing connection\n");
cyliang 0:25c616c85d69 216 #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 217 trace_open();
cyliang 0:25c616c85d69 218 #else
cyliang 0:25c616c85d69 219 dot_thread.start(dot_event);
cyliang 0:25c616c85d69 220 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 221
cyliang 0:25c616c85d69 222 // sim pin, apn, credentials and possible plmn are taken atuomtically from json when using get_default_instance()
cyliang 0:25c616c85d69 223 iface = NetworkInterface::get_default_instance();
cyliang 0:25c616c85d69 224 MBED_ASSERT(iface);
cyliang 0:25c616c85d69 225
cyliang 0:25c616c85d69 226 nsapi_error_t retcode = NSAPI_ERROR_NO_CONNECTION;
cyliang 0:25c616c85d69 227
cyliang 0:25c616c85d69 228 /* Attempt to connect to a cellular network */
cyliang 0:25c616c85d69 229 if (do_connect() == NSAPI_ERROR_OK) {
cyliang 2:8730ba700f06 230 printf("IP Address is %s\r\n", iface->get_ip_address());
cyliang 0:25c616c85d69 231 retcode = test_send_recv();
cyliang 0:25c616c85d69 232 }
cyliang 0:25c616c85d69 233
cyliang 0:25c616c85d69 234 if (iface->disconnect() != NSAPI_ERROR_OK) {
cyliang 0:25c616c85d69 235 print_function("\n\n disconnect failed.\n\n");
cyliang 0:25c616c85d69 236 }
cyliang 0:25c616c85d69 237
cyliang 0:25c616c85d69 238 if (retcode == NSAPI_ERROR_OK) {
cyliang 0:25c616c85d69 239 print_function("\n\nSuccess. Exiting \n\n");
cyliang 0:25c616c85d69 240 } else {
cyliang 0:25c616c85d69 241 print_function("\n\nFailure. Exiting \n\n");
cyliang 0:25c616c85d69 242 }
cyliang 0:25c616c85d69 243
cyliang 0:25c616c85d69 244 #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 245 trace_close();
cyliang 0:25c616c85d69 246 #else
cyliang 0:25c616c85d69 247 dot_thread.terminate();
cyliang 0:25c616c85d69 248 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
cyliang 0:25c616c85d69 249
cyliang 0:25c616c85d69 250 return 0;
cyliang 0:25c616c85d69 251 }
cyliang 0:25c616c85d69 252 // EOF