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

Cellular

CellularInterface class hierarchy

Note: Some functions, variables or types have been deprecated. Please see the class reference linked below for details.

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

Getting started

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

  2. Clone https://github.com/ARMmbed/mbed-os-example-cellular.

  3. Compile the code.

  4. 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.

CellularInterface class reference

Public Types
typedef mbed::Callback< void(nsapi_value_or_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...
nsapi_error_t connect () override=0
 Attempt to connect to a cellular network. More...
nsapi_error_t disconnect () override=0
 Stop the interface. More...
virtual bool is_connected ()=0
 Check if the connection is currently established. More...
nsapi_error_t get_ip_address (SocketAddress *address) override=0
 Get the local IP address. More...
CellularInterfacecellularInterface () final
 Return pointer to a CellularInterface. More...
void set_default_parameters () override
 defined(DOXYGEN_ONLY) More...
virtual void set_as_default ()
 Set network interface as default one. More...
virtual const char * get_mac_address ()
 Get the local MAC address. More...
virtual nsapi_error_t set_mac_address (uint8_t *mac_addr, nsapi_size_t addr_len)
 Set the MAC address to the interface. More...
virtual nsapi_error_t get_ipv6_link_local_address (SocketAddress *address)
 Get the IPv6 link local address. More...
virtual nsapi_error_t get_netmask (SocketAddress *address)
 Get the local network mask. More...
virtual nsapi_error_t get_gateway (SocketAddress *address)
 Get the local gateway. More...
virtual char * get_interface_name (char *interface_name)
 Get the network interface name. More...
virtual nsapi_error_t set_network (const SocketAddress &ip_address, const SocketAddress &netmask, const SocketAddress &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, const char *interface_name=NULL)
 Translate a hostname to an IP address with specific version using network interface name. More...
virtual nsapi_value_or_error_t getaddrinfo (const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name=NULL)
 Translate a hostname to the multiple IP addresses with specific version using network interface name. More...
virtual nsapi_value_or_error_t gethostbyname_async (const char *host, hostbyname_cb_t callback, nsapi_version_t version=NSAPI_UNSPEC, const char *interface_name=NULL)
 Translate a hostname to an IP address (asynchronous) using network interface name. More...
virtual nsapi_value_or_error_t getaddrinfo_async (const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name=NULL)
 Translate a hostname to the multiple IP addresses (asynchronous) using network interface name. 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, const char *interface_name)
 Add a domain name server to list of servers to query. More...
virtual nsapi_error_t get_dns_server (int index, SocketAddress *address, const char *interface_name=NULL)
 Get a domain name server from a 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...
void add_event_listener (mbed::Callback< void(nsapi_event_t, intptr_t)> status_cb)
 Add event listener for interface. More...
virtual nsapi_connection_status_t get_connection_status () const
 Get the connection status. More...
virtual nsapi_error_t set_blocking (bool blocking)
 Set asynchronous operation of connect() and disconnect() calls. 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 CellularInterfaceget_default_instance ()
 Get the default cellular interface. More...

Usage

To bring up the network interface:

  1. Instantiate an implementation of the CellularInterface 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 "CellularNonIPSocket.h"
#include "UDPSocket.h"
#include "TCPSocket.h"
#include "cellular_demo_tracing.h"

/* configuration choices in mbed_app.json */
#define UDP 0
#define TCP 1
#define NONIP 2

#if MBED_CONF_APP_SOCK_TYPE == TCP
static constexpr char SOCKET_TYPE[] = "TCP";
#elif MBED_CONF_APP_SOCK_TYPE == UDP
static constexpr char SOCKET_TYPE[] = "UDP";
#elif MBED_CONF_APP_SOCK_TYPE == NONIP
static constexpr char SOCKET_TYPE[] = "CellularNonIP";
#endif
static const char ECHO_HOSTNAME[] = MBED_CONF_APP_ECHO_SERVER_HOSTNAME;


class CellularDemo {
    static constexpr uint8_t RETRY_COUNT = 3;

public:
    CellularDemo(NetworkInterface &network)
        : _net(network)
    { }

    ~CellularDemo() { }

    /** Run the cellular demo. */
    void run()
    {
        /* sim pin, apn, credentials and possible plmn are taken automatically from json
         * when using NetworkInterface::set_default_parameters() */
        _net.set_default_parameters();

        nsapi_size_or_error_t ret = NSAPI_ERROR_NO_CONNECTION;

        if (connect_cellular()) {
            /* ping echo server */
            if (!test_send_and_receive()) {
                printf("Sending and received data failed.\n");
            }

            ret = _net.disconnect();

            if (ret != NSAPI_ERROR_OK) {
                printf("Disconnect failed (error: %d).\n", ret);
            }
        }

        if (ret == NSAPI_ERROR_OK) {
            printf("Success. Exiting\n");
        } else {
            printf("Failure. Exiting\n");
        }
    }

private:
    /**
     * For UDP or TCP it opens a socket with the given echo server and performs an echo transaction.
     * For Cellular Non-IP it opens a socket for which the data delivery path is decided
     * by network's control plane CIoT optimisation setup, for the given APN.
     */
    bool test_send_and_receive()
    {
        nsapi_size_or_error_t ret;

        ret = _socket.open(&_net);

        if (ret != NSAPI_ERROR_OK) {
            printf("%sSocket.open() fails, code: %d\n", SOCKET_TYPE, ret);
            return false;
        }

        _socket.set_timeout(15000);

        if (!resolve_hostname()) {
            return false;
        }

        if (!connect_socket()) {
            return false;
        }

        ret = send_test_data();

        if (ret < 0) {
            printf("%sSocket.send() fails, code: %d\n", SOCKET_TYPE, ret);
            return false;
        } else {
            printf("%s: Sent %d Bytes to %s\n", SOCKET_TYPE, ret, ECHO_HOSTNAME);
        }

        ret = receive_test_data();

        if (ret < 0) {
            printf("%sSocket.recv() fails, code: %d\n", SOCKET_TYPE, ret);
            return false;
        } else {
            printf("Received from echo server %d Bytes\n", ret);
        }

        _socket.close();

        if (ret != NSAPI_ERROR_OK) {
            printf("%sSocket.close() fails, code: %d\n", SOCKET_TYPE, ret);
            return false;
        }

        return true;
    }

    /** Connects to the Cellular Network */
    bool connect_cellular()
    {
        printf("Establishing connection\n");

        /* check if we're already connected */
        if (_net.get_connection_status() == NSAPI_STATUS_GLOBAL_UP) {
            return true;
        }

        nsapi_error_t ret;

        for (uint8_t retry = 0; retry <= RETRY_COUNT; retry++) {
            ret = _net.connect();

            if (ret == NSAPI_ERROR_OK) {
                printf("Connection Established.\n");
                return true;
            } else if (ret == NSAPI_ERROR_AUTH_FAILURE) {
                printf("Authentication Failure.\n");
                return false;
            } else {
                printf("Couldn't connect: %d, will retry\n", ret);
            }
        }

        printf("Fatal connection failure: %d\n", ret);

        return false;
    }

    /** Connects to the Cellular Network */
    bool resolve_hostname()
    {
#if MBED_CONF_APP_SOCK_TYPE != NONIP
        nsapi_error_t ret = _net.gethostbyname(ECHO_HOSTNAME, &_socket_address);

        if (ret != NSAPI_ERROR_OK) {
            printf("Couldn't resolve remote host: %s, code: %d\n", ECHO_HOSTNAME, ret);
            return false;
        }

        _socket_address.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
#endif
        return true;
    }

    bool connect_socket()
    {
#if MBED_CONF_APP_SOCK_TYPE == TCP
        nsapi_error_t ret = _socket.connect(_socket_address);
        if (ret < 0) {
            printf("TCPSocket.connect() fails, code: %d\n", ret);
            return false;
        } else {
            printf("TCP: connected with %s server\n", ECHO_HOSTNAME);
        }
#endif
        return true;
    }

    nsapi_error_t send_test_data()
    {
        const char *echo_string = "TEST";
#if MBED_CONF_APP_SOCK_TYPE == UDP
        return _socket.sendto(_socket_address, (void*)echo_string, strlen(echo_string));
#else
        return _socket.send((void*)echo_string, strlen(echo_string));
#endif
    }

    nsapi_error_t receive_test_data()
    {
        char receive_buffer[4];
#if MBED_CONF_APP_SOCK_TYPE == UDP
        return _socket.recvfrom(&_socket_address, (void*)receive_buffer, sizeof(receive_buffer));
#else
        return _socket.recv((void*)receive_buffer, sizeof(receive_buffer));
#endif
    }

private:
    NetworkInterface &_net;

#if MBED_CONF_APP_SOCK_TYPE == TCP
    TCPSocket _socket;
    SocketAddress _socket_address;
#elif MBED_CONF_APP_SOCK_TYPE == UDP
    UDPSocket _socket;
    SocketAddress _socket_address;
#elif MBED_CONF_APP_SOCK_TYPE == NONIP
    CellularNonIPSocket _socket;
#endif
};

int main() {
    printf("\nmbed-os-example-cellular\n");

    trace_open();

#if MBED_CONF_APP_SOCK_TYPE == NONIP
    NetworkInterface *net = CellularContext::get_default_nonip_instance();
#else
    NetworkInterface *net = CellularContext::get_default_instance();
#endif

    if (net) {
        CellularDemo example(*net);
        example.run();
    } else {
        printf("Failed to get_default_instance()\n");
    }

    trace_close();

    return 0;
}

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.