Mistake on this page?
Report an issue in GitHub or email us

Cellular

CellularBase class hierarchy

The CellularBase provides a C++ API for connecting to the internet over a Cellular device.

Arm Mbed OS provides a reference implementation of CellularBase, which has more information.

Getting started

  1. Choose an Mbed board that supports cellular, such as the UBLOX-C027 or MTS-DRAGONFLY.

  2. Clone mbed-os-example-cellular. Follow the instructions in the repository.

    1. Compile the code.
    2. Flash the board.

    You see output similar to the excerpt below:

mbed-os-example-cellular
Establishing connection ......

Connection Established.
TCP: connected with echo.mbedcloudtesting.com server
TCP: Sent 4 Bytes to echo.mbedcloudtesting.com
Received from echo server 4 Bytes


Success. Exiting

Basic working principles

You can use and extend a cellular interface in various different ways. For example,

  • Using AT commands to control sockets in an existing IP stack built into the cellular modem.

  • Using a PPP (Point-to-Point Protocol) pipe to pass IP packets between an Mbed OS supported IP stack and cellular modem device.

mbed-os-example-cellular uses PPP or AT mode depending on the modem. We can summarize this particular design as follows:

  • It uses an external IP stack, such as LWIP, or on-chip network stacks such as when the modem does not support PPP.
  • The easy cellular connection uses standard 3GPP AT 27.007 AT commands to set up the cellular modem and to register to the network.
  • After registration, the driver opens a PPP pipe using LWIP with the cellular modem and connects to the internet. If AT only mode is in use, then modem-specific AT commands are used for socket data control.

CellularBase class reference

Public Types
typedef mbed::Callback< void(nsapi_error_t result, SocketAddress *address)> hostbyname_cb_t
 Hostname translation callback (for use with gethostbyname_async()). More...
Public Member Functions
virtual void set_credentials (const char *apn, const char *uname=0, const char *pwd=0)=0
 Set the cellular network credentials. More...
virtual void set_plmn (const char *plmn)=0
 Set the plmn. More...
virtual void set_sim_pin (const char *sim_pin)=0
 Set the PIN code for SIM card. More...
virtual nsapi_error_t connect (const char *sim_pin, const char *apn=0, const char *uname=0, const char *pwd=0)=0
 Attempt to connect to a cellular network with a PIN and credentials. More...
virtual nsapi_error_t connect ()=0
 Attempt to connect to a cellular network. More...
virtual nsapi_error_t disconnect ()=0
 Stop the interface. More...
virtual bool is_connected ()=0
 Check if the connection is currently established. More...
virtual const char * get_ip_address ()=0
 Get the local IP address. More...
virtual const char * get_netmask ()=0
 Get the local network mask. More...
virtual const char * get_gateway ()=0
 Get the local gateways. More...
virtual CellularBasecellularBase ()
 Return pointer to a CellularBase. More...
virtual const char * get_mac_address ()
 Get the local MAC address. More...
virtual nsapi_error_t set_network (const char *ip_address, const char *netmask, const char *gateway)
 Configure this network interface to use a static IP address. More...
virtual nsapi_error_t set_dhcp (bool dhcp)
 Enable or disable DHCP on connecting the network. More...
virtual nsapi_error_t gethostbyname (const char *host, SocketAddress *address, nsapi_version_t version=NSAPI_UNSPEC)
 Translate a hostname to an IP address with specific version. More...
virtual nsapi_value_or_error_t gethostbyname_async (const char *host, hostbyname_cb_t callback, nsapi_version_t version=NSAPI_UNSPEC)
 Translate a hostname to an IP address (asynchronous). More...
virtual nsapi_error_t gethostbyname_async_cancel (int id)
 Cancel asynchronous hostname translation. More...
virtual nsapi_error_t add_dns_server (const SocketAddress &address)
 Add a domain name server to list of servers to query. More...
virtual void attach (mbed::Callback< void(nsapi_event_t, intptr_t)> status_cb)
 Register callback for status reporting. More...
virtual nsapi_connection_status_t get_connection_status () const
 Get the connection status. More...
virtual nsapi_error_t set_blocking (bool blocking)
 Set blocking status of connect() which by default should be blocking. More...
virtual EthInterfaceethInterface ()
 Return pointer to an EthInterface. More...
virtual WiFiInterfacewifiInterface ()
 Return pointer to a WiFiInterface. More...
virtual MeshInterfacemeshInterface ()
 Return pointer to a MeshInterface. More...
virtual EMACInterfaceemacInterface ()
 Return pointer to an EMACInterface. More...
Static Public Member Functions
static CellularBaseget_default_instance ()
 Get the default cellular interface. More...

Usage

To bring up the network interface:

  1. Instantiate an implementation of the CellularBase class.
  2. Call the connect(pincode, apn) function with a PIN code for your SIM card and an APN for your network.
  3. Once connected, you can use Mbed OS network sockets as usual.

Cellular example: connection establishment

This example establishes connection with the cellular network using Mbed OS CellularInterface.

/*
 * Copyright (c) 2017 ARM Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "common_functions.h"
#include "UDPSocket.h"
#include "CellularLog.h"

#define UDP 0
#define TCP 1

// SIM pin code goes here
#ifndef MBED_CONF_APP_SIM_PIN_CODE
# define MBED_CONF_APP_SIM_PIN_CODE    "1234"
#endif

#ifndef MBED_CONF_APP_APN
# define MBED_CONF_APP_APN         "internet"
#endif
#ifndef MBED_CONF_APP_USERNAME
# define MBED_CONF_APP_USERNAME    NULL
#endif
#ifndef MBED_CONF_APP_PASSWORD
# define MBED_CONF_APP_PASSWORD    NULL
#endif

// Number of retries /
#define RETRY_COUNT 3

CellularBase *iface;

// Echo server hostname
const char *host_name = MBED_CONF_APP_ECHO_SERVER_HOSTNAME;

// Echo server port (same for TCP and UDP)
const int port = MBED_CONF_APP_ECHO_SERVER_PORT;

static rtos::Mutex trace_mutex;

#if MBED_CONF_MBED_TRACE_ENABLE
static void trace_wait()
{
    trace_mutex.lock();
}

static void trace_release()
{
    trace_mutex.unlock();
}

static char time_st[50];

static char* trace_time(size_t ss)
{
    snprintf(time_st, 49, "[%08llums]", Kernel::get_ms_count());
    return time_st;
}

static void trace_open()
{
    mbed_trace_init();
    mbed_trace_prefix_function_set( &trace_time );

    mbed_trace_mutex_wait_function_set(trace_wait);
    mbed_trace_mutex_release_function_set(trace_release);

    mbed_cellular_trace::mutex_wait_function_set(trace_wait);
    mbed_cellular_trace::mutex_release_function_set(trace_release);
}

static void trace_close()
{
    mbed_cellular_trace::mutex_wait_function_set(NULL);
    mbed_cellular_trace::mutex_release_function_set(NULL);

    mbed_trace_free();
}
#endif // #if MBED_CONF_MBED_TRACE_ENABLE

Thread dot_thread(osPriorityNormal, 512);

void print_function(const char *format, ...)
{
    trace_mutex.lock();
    va_list arglist;
    va_start( arglist, format );
    vprintf(format, arglist);
    va_end( arglist );
    trace_mutex.unlock();
}

void dot_event()
{
    while (true) {
        Thread::wait(4000);
        if (iface && iface->is_connected()) {
            break;
        } else {
            trace_mutex.lock();
            printf(".");
            fflush(stdout);
            trace_mutex.unlock();
        }
    }
}

/**
 * Connects to the Cellular Network
 */
nsapi_error_t do_connect()
{
    nsapi_error_t retcode = NSAPI_ERROR_OK;
    uint8_t retry_counter = 0;

    while (!iface->is_connected()) {
        retcode = iface->connect();
        if (retcode == NSAPI_ERROR_AUTH_FAILURE) {
            print_function("\n\nAuthentication Failure. Exiting application\n");
        } else if (retcode == NSAPI_ERROR_OK) {
            print_function("\n\nConnection Established.\n");
        } else if (retry_counter > RETRY_COUNT) {
            print_function("\n\nFatal connection failure: %d\n", retcode);
        } else {
            print_function("\n\nCouldn't connect: %d, will retry\n", retcode);
            retry_counter++;
            continue;
        }
        break;
    }
    return retcode;
}

/**
 * Opens a UDP or a TCP socket with the given echo server and performs an echo
 * transaction retrieving current.
 */
nsapi_error_t test_send_recv()
{
    nsapi_size_or_error_t retcode;
#if MBED_CONF_APP_SOCK_TYPE == TCP
    TCPSocket sock;
#else
    UDPSocket sock;
#endif

    retcode = sock.open(iface);
    if (retcode != NSAPI_ERROR_OK) {
#if MBED_CONF_APP_SOCK_TYPE == TCP
        print_function("TCPSocket.open() fails, code: %d\n", retcode);
#else
        print_function("UDPSocket.open() fails, code: %d\n", retcode);
#endif
        return -1;
    }

    SocketAddress sock_addr;
    retcode = iface->gethostbyname(host_name, &sock_addr);
    if (retcode != NSAPI_ERROR_OK) {
        print_function("Couldn't resolve remote host: %s, code: %d\n", host_name, retcode);
        return -1;
    }

    sock_addr.set_port(port);

    sock.set_timeout(15000);
    int n = 0;
    const char *echo_string = "TEST";
    char recv_buf[4];
#if MBED_CONF_APP_SOCK_TYPE == TCP
    retcode = sock.connect(sock_addr);
    if (retcode < 0) {
        print_function("TCPSocket.connect() fails, code: %d\n", retcode);
        return -1;
    } else {
        print_function("TCP: connected with %s server\n", host_name);
    }
    retcode = sock.send((void*) echo_string, sizeof(echo_string));
    if (retcode < 0) {
        print_function("TCPSocket.send() fails, code: %d\n", retcode);
        return -1;
    } else {
        print_function("TCP: Sent %d Bytes to %s\n", retcode, host_name);
    }

    n = sock.recv((void*) recv_buf, sizeof(recv_buf));
#else

    retcode = sock.sendto(sock_addr, (void*) echo_string, sizeof(echo_string));
    if (retcode < 0) {
        print_function("UDPSocket.sendto() fails, code: %d\n", retcode);
        return -1;
    } else {
        print_function("UDP: Sent %d Bytes to %s\n", retcode, host_name);
    }

    n = sock.recvfrom(&sock_addr, (void*) recv_buf, sizeof(recv_buf));
#endif

    sock.close();

    if (n > 0) {
        print_function("Received from echo server %d Bytes\n", n);
        return 0;
    }

    return -1;
}

int main()
{
    print_function("\n\nmbed-os-example-cellular\n");
    print_function("Establishing connection\n");
#if MBED_CONF_MBED_TRACE_ENABLE
    trace_open();
#else
    dot_thread.start(dot_event);
#endif // #if MBED_CONF_MBED_TRACE_ENABLE
    iface = CellularBase::get_default_instance();
    MBED_ASSERT(iface);

    /* Set Pin code for SIM card */
    iface->set_sim_pin(MBED_CONF_APP_SIM_PIN_CODE);

    /* Set network credentials here, e.g., APN */
    iface->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD);

    nsapi_error_t retcode = NSAPI_ERROR_NO_CONNECTION;

    /* Attempt to connect to a cellular network */
    if (do_connect() == NSAPI_ERROR_OK) {
        retcode = test_send_recv();
    }

    if (retcode == NSAPI_ERROR_OK) {
        print_function("\n\nSuccess. Exiting \n\n");
    } else {
        print_function("\n\nFailure. Exiting \n\n");
    }
#if MBED_CONF_MBED_TRACE_ENABLE
    trace_close();
#endif // #if MBED_CONF_MBED_TRACE_ENABLE

    return 0;
}
// EOF

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.