Cellular example for BG96 module. In addition to default example integration of GNSS module is presented. Tested on Hani-IoT board with Shiratech LTE CAT-M1/NB1 Arduino Shield containing BG96 module.

Dependencies:   BG96_GNSS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2017 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "common_functions.h"
00019 #include "CellularNonIPSocket.h"
00020 #include "CellularDevice.h"
00021 #include "UDPSocket.h"
00022 #include "CellularLog.h"
00023 #include "BG96_GNSS.h"
00024 
00025 #define UDP 0
00026 #define TCP 1
00027 #define NONIP 2
00028 
00029 // Number of retries /
00030 #define RETRY_COUNT 3
00031 
00032 NetworkInterface *iface;
00033 
00034 // Echo server hostname
00035 const char *host_name = MBED_CONF_APP_ECHO_SERVER_HOSTNAME;
00036 
00037 // Echo server port (same for TCP and UDP)
00038 const int port = MBED_CONF_APP_ECHO_SERVER_PORT;
00039 
00040 static rtos::Mutex trace_mutex;
00041 
00042 #if MBED_CONF_MBED_TRACE_ENABLE
00043 static void trace_wait()
00044 {
00045     trace_mutex.lock();
00046 }
00047 
00048 static void trace_release()
00049 {
00050     trace_mutex.unlock();
00051 }
00052 
00053 static char time_st[50];
00054 
00055 static char* trace_time(size_t ss)
00056 {
00057     snprintf(time_st, 49, "[%08llums]", Kernel::get_ms_count());
00058     return time_st;
00059 }
00060 
00061 static void trace_open()
00062 {
00063     mbed_trace_init();
00064     mbed_trace_prefix_function_set( &trace_time );
00065 
00066     mbed_trace_mutex_wait_function_set(trace_wait);
00067     mbed_trace_mutex_release_function_set(trace_release);
00068 
00069     mbed_cellular_trace::mutex_wait_function_set(trace_wait);
00070     mbed_cellular_trace::mutex_release_function_set(trace_release);
00071 }
00072 
00073 static void trace_close()
00074 {
00075     mbed_cellular_trace::mutex_wait_function_set(NULL);
00076     mbed_cellular_trace::mutex_release_function_set(NULL);
00077 
00078     mbed_trace_free();
00079 }
00080 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
00081 
00082 Thread dot_thread(osPriorityNormal, 512);
00083 
00084 void print_function(const char *format, ...)
00085 {
00086     trace_mutex.lock();
00087     va_list arglist;
00088     va_start( arglist, format );
00089     vprintf(format, arglist);
00090     va_end( arglist );
00091     trace_mutex.unlock();
00092 }
00093 
00094 void dot_event()
00095 {
00096     while (true) {
00097         ThisThread::sleep_for(4000);
00098         if (iface && iface->get_connection_status() == NSAPI_STATUS_GLOBAL_UP) {
00099             break;
00100         } else {
00101             trace_mutex.lock();
00102             printf(".");
00103             fflush(stdout);
00104             trace_mutex.unlock();
00105         }
00106     }
00107 }
00108 
00109 /**
00110  * Connects to the Cellular Network
00111  */
00112 nsapi_error_t do_connect()
00113 {
00114     nsapi_error_t retcode = NSAPI_ERROR_OK;
00115     uint8_t retry_counter = 0;
00116 
00117     while (iface->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) {
00118         retcode = iface->connect();
00119         if (retcode == NSAPI_ERROR_AUTH_FAILURE) {
00120             print_function("\n\nAuthentication Failure. Exiting application\n");
00121         } else if (retcode == NSAPI_ERROR_OK) {
00122             print_function("\n\nConnection Established.\n");
00123         } else if (retry_counter > RETRY_COUNT) {
00124             print_function("\n\nFatal connection failure: %d\n", retcode);
00125         } else {
00126             print_function("\n\nCouldn't connect: %d, will retry\n", retcode);
00127             retry_counter++;
00128             continue;
00129         }
00130         break;
00131     }
00132     return retcode;
00133 }
00134 
00135 /**
00136  * Opens:
00137  * - UDP or TCP socket with the given echo server and performs an echo
00138  *   transaction retrieving current.
00139  * - Cellular Non-IP socket for which the data delivery path is decided
00140  *   by network's control plane CIoT optimisation setup, for the given APN.
00141  */
00142 nsapi_error_t test_send_recv()
00143 {
00144     nsapi_size_or_error_t retcode;
00145 #if MBED_CONF_APP_SOCK_TYPE == TCP
00146     TCPSocket sock;
00147 #elif MBED_CONF_APP_SOCK_TYPE == UDP
00148     UDPSocket sock;
00149 #elif MBED_CONF_APP_SOCK_TYPE == NONIP
00150     CellularNonIPSocket sock;
00151 #endif
00152 
00153 #if MBED_CONF_APP_SOCK_TYPE == NONIP
00154     retcode = sock.open((CellularContext*)iface);
00155 #else
00156     retcode = sock.open(iface);
00157 #endif
00158 
00159     if (retcode != NSAPI_ERROR_OK) {
00160 #if MBED_CONF_APP_SOCK_TYPE == TCP
00161         print_function("TCPSocket.open() fails, code: %d\n", retcode);
00162 #elif MBED_CONF_APP_SOCK_TYPE == UDP
00163         print_function("UDPSocket.open() fails, code: %d\n", retcode);
00164 #elif MBED_CONF_APP_SOCK_TYPE == NONIP
00165         print_function("CellularNonIPSocket.open() fails, code: %d\n", retcode);
00166 #endif
00167         return -1;
00168     }
00169 
00170     int n = 0;
00171     const char *echo_string = "TEST";
00172     char recv_buf[4];
00173 
00174     sock.set_timeout(15000);
00175 
00176 #if MBED_CONF_APP_SOCK_TYPE == NONIP
00177     retcode = sock.send((void*) echo_string, strlen(echo_string));
00178     if (retcode < 0) {
00179         print_function("CellularNonIPSocket.send() fails, code: %d\n", retcode);
00180         return -1;
00181     } else {
00182         print_function("CellularNonIPSocket: Sent %d Bytes\n", retcode);
00183     }
00184 
00185     n = sock.recv((void*) recv_buf, sizeof(recv_buf));
00186 
00187 #else
00188 
00189     SocketAddress sock_addr;
00190     retcode = iface->gethostbyname(host_name, &sock_addr);
00191     if (retcode != NSAPI_ERROR_OK) {
00192         print_function("Couldn't resolve remote host: %s, code: %d\n", host_name, retcode);
00193         return -1;
00194     }
00195 
00196     sock_addr.set_port(port);
00197 
00198 #if MBED_CONF_APP_SOCK_TYPE == TCP
00199     retcode = sock.connect(sock_addr);
00200     if (retcode < 0) {
00201         print_function("TCPSocket.connect() fails, code: %d\n", retcode);
00202         return -1;
00203     } else {
00204         print_function("TCP: connected with %s server\n", host_name);
00205     }
00206     retcode = sock.send((void*) echo_string, strlen(echo_string));
00207     if (retcode < 0) {
00208         print_function("TCPSocket.send() fails, code: %d\n", retcode);
00209         return -1;
00210     } else {
00211         print_function("TCP: Sent %d Bytes to %s\n", retcode, host_name);
00212     }
00213 
00214     n = sock.recv((void*) recv_buf, sizeof(recv_buf));
00215 #else
00216 
00217     retcode = sock.sendto(sock_addr, (void*) echo_string, strlen(echo_string));
00218     if (retcode < 0) {
00219         print_function("UDPSocket.sendto() fails, code: %d\n", retcode);
00220         return -1;
00221     } else {
00222         print_function("UDP: Sent %d Bytes to %s\n", retcode, host_name);
00223     }
00224 
00225     n = sock.recvfrom(&sock_addr, (void*) recv_buf, sizeof(recv_buf));
00226 #endif
00227 #endif
00228 
00229     sock.close();
00230 
00231     if (n > 0) {
00232         print_function("Received from echo server %d Bytes\n", n);
00233         return 0;
00234     }
00235 
00236     return -1;
00237 }
00238 
00239 int main()
00240 {
00241     print_function("\n\nmbed-os-example-cellular\n");
00242     print_function("\n\nBuilt: %s, %s\n", __DATE__, __TIME__);
00243 #ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN
00244     print_function("\n\n[MAIN], plmn: %s\n", (MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN ? MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN : "NULL"));
00245 #endif
00246 
00247     print_function("Establishing connection\n");
00248 #if MBED_CONF_MBED_TRACE_ENABLE
00249     trace_open();
00250 #else
00251     dot_thread.start(dot_event);
00252 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
00253 
00254 #if MBED_CONF_APP_SOCK_TYPE == NONIP
00255     iface = CellularContext::get_default_nonip_instance();
00256 #else
00257     iface = CellularContext::get_default_instance();
00258 #endif
00259 
00260     MBED_ASSERT(iface);
00261 
00262     // sim pin, apn, credentials and possible plmn are taken automatically from json when using NetworkInterface::set_default_parameters()
00263     iface->set_default_parameters();
00264 
00265     nsapi_error_t retcode = NSAPI_ERROR_NO_CONNECTION;
00266 
00267     /* Attempt to connect to a cellular network */
00268     if (do_connect() == NSAPI_ERROR_OK) {
00269         retcode = test_send_recv();
00270     }
00271 
00272     /* Create GPS data using existing cellular interface */
00273     BG96_GNSS bg96_gps_module;
00274     gps_data_t gps_data;
00275 
00276     /* Power on GPS module on BG96 */
00277     bg96_gps_module.set_gps_power(true);
00278     
00279     /* Wait until GPS is fixed and get GPS data */
00280     while (FAILURE == bg96_gps_module.get_gps_data(&gps_data)) {
00281         thread_sleep_for(5000);
00282     }
00283 
00284     /* Print GPS data */
00285     bg96_gps_module.print_gps_data(&gps_data);
00286 
00287     if (iface->disconnect() != NSAPI_ERROR_OK) {
00288         print_function("\n\n disconnect failed.\n\n");
00289     }
00290 
00291     if (retcode == NSAPI_ERROR_OK) {
00292         print_function("\n\nSuccess. Exiting \n\n");
00293     } else {
00294         print_function("\n\nFailure. Exiting \n\n");
00295     }
00296 
00297 #if MBED_CONF_MBED_TRACE_ENABLE
00298     trace_close();
00299 #else
00300     dot_thread.terminate();
00301 #endif // #if MBED_CONF_MBED_TRACE_ENABLE
00302 
00303     return 0;
00304 }
00305 // EOF