Netconn API

Netconn API is addon on top of existing connection module and allows sending and receiving data with sequential API calls, similar to POSIX socket API.

It can operate in client mode and uses operating system features, such as message queues and semaphore to link non-blocking callback API for connections with sequential API for application thread.

Note

Connection API does not directly allow receiving data with sequential and linear code execution. All is based on connection event system. Netconn adds this functionality as it is implemented on top of regular connection API.

Warning

Netconn API are designed to be called from application threads ONLY. It is not allowed to call any of netconn API functions from within interrupt or callback event functions.

Netconn client

Netconn API client block diagram

Netconn API client block diagram

Above block diagram shows basic architecture of netconn client application. There is always one application thread (in green) which calls netconn API functions to interact with connection API in synchronous mode.

Every netconn connection uses dedicated structure to handle message queue for data received packet buffers. Each time new packet is received (red block, data received event), reference to it is written to message queue of netconn structure, while application thread reads new entries from the same queue to get packets.

Netconn client example
  1#include "netconn_client.h"
  2#include "lwcell/lwcell.h"
  3#include "lwcell/lwcell_network_api.h"
  4
  5#if LWCELL_CFG_NETCONN
  6
  7/**
  8 * \brief           Host and port settings
  9 */
 10#define NETCONN_HOST "example.com"
 11#define NETCONN_PORT 80
 12
 13/**
 14 * \brief           Request header to send on successful connection
 15 */
 16static const char request_header[] = ""
 17                                     "GET / HTTP/1.1\r\n"
 18                                     "Host: " NETCONN_HOST "\r\n"
 19                                     "Connection: close\r\n"
 20                                     "\r\n";
 21
 22/**
 23 * \brief           Netconn client thread implementation
 24 * \param[in]       arg: User argument
 25 */
 26void
 27netconn_client_thread(void const* arg) {
 28    lwcellr_t res;
 29    lwcell_pbuf_p pbuf;
 30    lwcell_netconn_p client;
 31    lwcell_sys_sem_t* sem = (void*)arg;
 32
 33    /* Request attach to network */
 34    while (lwcell_network_request_attach() != lwcellOK) {
 35        lwcell_delay(1000);
 36    }
 37
 38    /*
 39     * First create a new instance of netconn
 40     * connection and initialize system message boxes
 41     * to accept received packet buffers
 42     */
 43    if ((client = lwcell_netconn_new(LWCELL_NETCONN_TYPE_TCP)) != NULL) {
 44        /*
 45         * Connect to external server as client
 46         * with custom NETCONN_CONN_HOST and CONN_PORT values
 47         *
 48         * Function will block thread until we are successfully connected (or not) to server
 49         */
 50        if ((res = lwcell_netconn_connect(client, NETCONN_HOST, NETCONN_PORT)) == lwcellOK) {
 51            printf("Connected to %s\r\n", NETCONN_HOST);
 52
 53            /* Send data to server */
 54            if ((res = lwcell_netconn_write(client, request_header, sizeof(request_header) - 1)) == lwcellOK) {
 55                res = lwcell_netconn_flush(client); /* Flush data to output */
 56            }
 57            if (res == lwcellOK) { /* Were data sent? */
 58                printf("Data were successfully sent to server\r\n");
 59
 60                /*
 61                 * Since we sent HTTP request,
 62                 * we are expecting some data from server
 63                 * or at least forced connection close from remote side
 64                 */
 65                do {
 66                    /*
 67                     * Receive single packet of data
 68                     *
 69                     * Function will block thread until new packet
 70                     * is ready to be read from remote side
 71                     *
 72                     * After function returns, don't forgot the check value.
 73                     * Returned status will give you info in case connection
 74                     * was closed too early from remote side
 75                     */
 76                    res = lwcell_netconn_receive(client, &pbuf);
 77                    if (res
 78                        == lwcellCLOSED) { /* Was the connection closed? This can be checked by return status of receive function */
 79                        printf("Connection closed by remote side...\r\n");
 80                        break;
 81                    } else if (res == lwcellTIMEOUT) {
 82                        printf("Netconn timeout while receiving data. You may try multiple readings before deciding to "
 83                               "close manually\r\n");
 84                    }
 85
 86                    if (res == lwcellOK && pbuf != NULL) { /* Make sure we have valid packet buffer */
 87                        /*
 88                         * At this point read and manipulate
 89                         * with received buffer and check if you expect more data
 90                         *
 91                         * After you are done using it, it is important
 92                         * you free the memory otherwise memory leaks will appear
 93                         */
 94                        printf("Received new data packet of %d bytes\r\n", (int)lwcell_pbuf_length(pbuf, 1));
 95                        lwcell_pbuf_free_s(&pbuf); /* Free the memory after usage */
 96                    }
 97                } while (1);
 98            } else {
 99                printf("Error writing data to remote host!\r\n");
100            }
101
102            /*
103             * Check if connection was closed by remote server
104             * and in case it wasn't, close it manually
105             */
106            if (res != lwcellCLOSED) {
107                lwcell_netconn_close(client);
108            }
109        } else {
110            printf("Cannot connect to remote host %s:%d!\r\n", NETCONN_HOST, NETCONN_PORT);
111        }
112        lwcell_netconn_delete(client); /* Delete netconn structure */
113    }
114    lwcell_network_request_detach(); /* Detach from network */
115
116    if (lwcell_sys_sem_isvalid(sem)) {
117        lwcell_sys_sem_release(sem);
118    }
119    lwcell_sys_thread_terminate(NULL); /* Terminate current thread */
120}
121
122#endif /* LWCELL_CFG_NETCONN */

Non-blocking receive

By default, netconn API is written to only work in separate application thread, dedicated for network connection processing. Because of that, by default every function is fully blocking. It will wait until result is ready to be used by application.

It is, however, possible to enable timeout feature for receiving data only. When this feature is enabled, lwcell_netconn_receive() will block for maximal timeout set with lwcell_netconn_set_receive_timeout() function.

When enabled, if there is no received data for timeout amount of time, function will return with timeout status and application needs to process it accordingly.

Tip

LWCELL_CFG_NETCONN_RECEIVE_TIMEOUT must be set to 1 to use this feature.

group LWCELL_NETCONN

Network connection.

Defines

LWCELL_NETCONN_RECEIVE_NO_WAIT

Receive data with no timeout.

Note

Used with lwcell_netconn_set_receive_timeout function

LWCELL_NETCONN_FLAG_FLUSH

Immediate flush after netconn write

Typedefs

typedef struct lwcell_netconn *lwcell_netconn_p

Netconn object structure.

Enums

enum lwcell_netconn_type_t

Netconn connection type.

Values:

enumerator LWCELL_NETCONN_TYPE_TCP = LWCELL_CONN_TYPE_TCP

TCP connection

enumerator LWCELL_NETCONN_TYPE_UDP = LWCELL_CONN_TYPE_UDP

UDP connection

enumerator LWCELL_NETCONN_TYPE_SSL = LWCELL_CONN_TYPE_SSL

TCP connection over SSL Note: This option is unstable on SIM868 devices due to firmware issues

Functions

lwcell_netconn_p lwcell_netconn_new(lwcell_netconn_type_t type)

Create new netconn connection.

Parameters

type[in] Netconn connection type

Returns

New netconn connection on success, NULL otherwise

lwcellr_t lwcell_netconn_delete(lwcell_netconn_p nc)

Delete netconn connection.

Parameters

nc[in] Netconn handle

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

lwcellr_t lwcell_netconn_connect(lwcell_netconn_p nc, const char *host, lwcell_port_t port)

Connect to server as client.

Parameters
  • nc[in] Netconn handle

  • host[in] Pointer to host, such as domain name or IP address in string format

  • port[in] Target port to use

Returns

lwcellOK if successfully connected, member of lwcellr_t otherwise

lwcellr_t lwcell_netconn_receive(lwcell_netconn_p nc, lwcell_pbuf_p *pbuf)

Receive data from connection.

Parameters
  • nc[in] Netconn handle used to receive from

  • pbuf[in] Pointer to pointer to save new receive buffer to. When function returns, user must check for valid pbuf value pbuf != NULL

Returns

lwcellOK when new data ready,

Returns

lwcellCLOSED when connection closed by remote side,

Returns

lwcellTIMEOUT when receive timeout occurs

Returns

Any other member of lwcellr_t otherwise

lwcellr_t lwcell_netconn_close(lwcell_netconn_p nc)

Close a netconn connection.

Parameters

nc[in] Netconn handle to close

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

int8_t lwcell_netconn_getconnnum(lwcell_netconn_p nc)

Get connection number used for netconn.

Parameters

nc[in] Netconn handle

Returns

-1 on failure, connection number between 0 and LWCELL_CFG_MAX_CONNS otherwise

void lwcell_netconn_set_receive_timeout(lwcell_netconn_p nc, uint32_t timeout)

Set timeout value for receiving data.

When enabled, lwcell_netconn_receive will only block for up to timeout value and will return if no new data within this time

Parameters
  • nc[in] Netconn handle

  • timeout[in] Timeout in units of milliseconds. Set to 0 to disable timeout feature. Function blocks until data receive or connection closed Set to > 0 to set maximum milliseconds to wait before timeout Set to LWCELL_NETCONN_RECEIVE_NO_WAIT to enable non-blocking receive

uint32_t lwcell_netconn_get_receive_timeout(lwcell_netconn_p nc)

Get netconn receive timeout value.

Parameters

nc[in] Netconn handle

Returns

Timeout in units of milliseconds. If value is 0, timeout is disabled (wait forever)

lwcellr_t lwcell_netconn_write(lwcell_netconn_p nc, const void *data, size_t btw)

Write data to connection output buffers.

Note

This function may only be used on TCP or SSL connections

Parameters
  • nc[in] Netconn handle used to write data to

  • data[in] Pointer to data to write

  • btw[in] Number of bytes to write

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

lwcellr_t lwcell_netconn_write_ex(lwcell_netconn_p nc, const void *data, size_t btw, uint16_t flags)

Extended version of lwcell_netconn_write with additional option to set custom flags.

Note

It is recommended to use this for full features support

Parameters
  • nc[in] Netconn handle used to write data to

  • data[in] Pointer to data to write

  • btw[in] Number of bytes to write

  • flags – Bitwise-ORed set of flags for netconn. Flags start with LWCELL_NETCONN_FLAG_xxx

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

lwcellr_t lwcell_netconn_flush(lwcell_netconn_p nc)

Flush buffered data on netconn TCP/SSL connection.

Note

This function may only be used on TCP/SSL connection

Parameters

nc[in] Netconn handle to flush data

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

lwcellr_t lwcell_netconn_send(lwcell_netconn_p nc, const void *data, size_t btw)

Send data on UDP connection to default IP and port.

Parameters
  • nc[in] Netconn handle used to send

  • data[in] Pointer to data to write

  • btw[in] Number of bytes to write

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise

lwcellr_t lwcell_netconn_sendto(lwcell_netconn_p nc, const lwcell_ip_t *ip, lwcell_port_t port, const void *data, size_t btw)

Send data on UDP connection to specific IP and port.

Note

Use this function in case of UDP type netconn

Parameters
  • nc[in] Netconn handle used to send

  • ip[in] Pointer to IP address

  • port[in] Port number used to send data

  • data[in] Pointer to data to write

  • btw[in] Number of bytes to write

Returns

lwcellOK on success, member of lwcellr_t enumeration otherwise