Asynchronous sock with event API

Provides an implementation of asynchronous sock for Event Queue. More...

Detailed Description

Provides an implementation of asynchronous sock for Event Queue.

Warning
This feature is experimental! This API is still under development and should not be used in production yet.

How To Use

You need to include at least one module that implements a `sock` API (e.g. gnrc_sock_udp and gnrc_sock_async for the GNRC implementation using UDP) and the module sock_async_event in your application's Makefile.

For the following example `sock_udp` is used. It is however easily adaptable for other sock types:

An asynchronous UDP Echo server using the event API

#include <stdio.h>
#include "net/sock/udp.h"
uint8_t buf[128];
void handler(sock_udp_t *sock, sock_async_flags_t type, void *arg)
{
(void)arg;
if (type & SOCK_ASYNC_MSG_RECV) {
sock_udp_ep_t remote;
ssize_t res;
if ((res = sock_udp_recv(sock, buf, sizeof(buf), 0,
&remote)) >= 0) {
puts("Received a message");
if (sock_udp_send(sock, buf, res, &remote) < 0) {
puts("Error sending reply");
}
}
}
}
int main(void)
{
sock_udp_t sock;
local.port = 12345;
if (sock_udp_create(&sock, &local, NULL, 0) < 0) {
puts("Error creating UDP sock");
return 1;
}
sock_udp_event_init(&sock, &queue, handler, NULL);
event_loop(&queue);
return 0;
}

Above you see a simple UDP echo server using Event Queue. Don't forget to also include the IPv6 module of your networking implementation (e.g. gnrc_ipv6_default for Generic (GNRC) network stack GNRC) and at least one network device.

After including the header file for UDP sock and asynchronous handling, we create the event queue queue and allocate some buffer space buf to store the data received by the server:

#include "net/sock/udp.h"
uint8_t buf[128];

We then define an event handler in form of a function. The event handler checks if the triggering event was a receive event by checking the flags provided with sock_event_t::type. If it is a receive event it copies the incoming message to buf and its sender into remote using sock_udp_recv(). Note, that we use sock_udp_recv() non-blocking by setting timeout to 0. If an error occurs on receive, we just ignore it and return from the event handler.

If we receive a message we use its remote to reply. In case of an error on send, we print an according message:

void handler(sock_udp_t *sock, sock_async_flags_t type, void *arg)
{
(void)arg;
if (type & SOCK_ASYNC_MSG_RECV) {
sock_udp_ep_t remote;
ssize_t res;
if ((res = sock_udp_recv(sock, buf, sizeof(buf), 0,
&remote)) >= 0) {
puts("Received a message");
if (sock_udp_send(sock, buf, res, &remote) < 0) {
puts("Error sending reply");
}
}
}
}

To be able to listen for incoming packets we bind the sock by setting a local end point with a port (12345 in this case).

We then proceed to create the sock. It is bound to local and thus listens for UDP packets with destination port 12345. Since we don't need any further configuration we set the flags to 0. In case of an error we stop the program:

local.port = 12345;
if (sock_udp_create(&sock, &local, NULL, 0) < 0) {
puts("Error creating UDP sock");
return 1;
}

Finally, we initialize the event queue queue, initialize asynchronous event handling for sock using it and the previously defined event handler, and go into an endless loop to handle all occurring events on queue:

sock_udp_event_init(&sock, &queue, handler, NULL);
event_loop(&queue);

Files

file  event.h
 Asynchronous sock using Event Queue definitions.
 
file  sock_async_ctx.h
 Type definitions for asynchronous socks with Event Queue.
 

Data Structures

union  sock_event_cb_t
 Generalized callback type. More...
 
struct  sock_event_t
 Event definition for context scope. More...
 
struct  sock_async_ctx_t
 Asynchronous context for Asynchronous sock with event API. More...
 

Functions

void sock_dtls_event_init (sock_dtls_t *sock, event_queue_t *ev_queue, sock_dtls_cb_t handler, void *handler_arg)
 Makes a DTLS sock able to handle asynchronous events using Event Queue. More...
 
void sock_ip_event_init (sock_ip_t *sock, event_queue_t *ev_queue, sock_ip_cb_t handler, void *handler_arg)
 Makes a raw IPv4/IPv6 sock able to handle asynchronous events using Event Queue. More...
 
void sock_tcp_event_init (sock_tcp_t *sock, event_queue_t *ev_queue, sock_tcp_cb_t handler, void *handler_arg)
 Makes a TCP sock able to handle asynchronous events using Event Queue. More...
 
void sock_tcp_queue_event_init (sock_tcp_queue_t *queue, event_queue_t *ev_queue, sock_tcp_queue_cb_t handler, void *handler_arg)
 Makes a TCP listening queue able to handle asynchronous events using Event Queue. More...
 
void sock_udp_event_init (sock_udp_t *sock, event_queue_t *ev_queue, sock_udp_cb_t handler, void *handler_arg)
 Makes a UDP sock able to handle asynchronous events using Event Queue. More...
 

Function Documentation

◆ sock_dtls_event_init()

void sock_dtls_event_init ( sock_dtls_t sock,
event_queue_t ev_queue,
sock_dtls_cb_t  handler,
void *  handler_arg 
)

Makes a DTLS sock able to handle asynchronous events using Event Queue.

Parameters
[in]sockA DTLS sock object.
[in]ev_queueThe queue the events on sock will be added to.
[in]handlerThe event handler function to call on an event on sock.
[in]handler_argArgument to provided to handler.
Note
Only available with module sock_dtls.

◆ sock_ip_event_init()

void sock_ip_event_init ( sock_ip_t sock,
event_queue_t ev_queue,
sock_ip_cb_t  handler,
void *  handler_arg 
)

Makes a raw IPv4/IPv6 sock able to handle asynchronous events using Event Queue.

Parameters
[in]sockA raw IPv4/IPv6 sock object.
[in]ev_queueThe queue the events on sock will be added to.
[in]handlerThe event handler function to call on an event on sock.
[in]handler_argArgument to provided to handler.
Note
Only available with module sock_ip.

◆ sock_tcp_event_init()

void sock_tcp_event_init ( sock_tcp_t sock,
event_queue_t ev_queue,
sock_tcp_cb_t  handler,
void *  handler_arg 
)

Makes a TCP sock able to handle asynchronous events using Event Queue.

Parameters
[in]sockA TCP sock object.
[in]ev_queueThe queue the events on sock will be added to.
[in]handlerThe event handler function to call on an event on sock.
[in]handler_argArgument to provided to handler.
Note
Only available with module sock_tcp.

◆ sock_tcp_queue_event_init()

void sock_tcp_queue_event_init ( sock_tcp_queue_t queue,
event_queue_t ev_queue,
sock_tcp_queue_cb_t  handler,
void *  handler_arg 
)

Makes a TCP listening queue able to handle asynchronous events using Event Queue.

Parameters
[in]queueA TCP listening queue.
[in]ev_queueThe queue the events on sock will be added to.
[in]handlerThe event handler function to call on an event on sock.
[in]handler_argArgument to provided to handler.
Note
Only available with module sock_tcp.

◆ sock_udp_event_init()

void sock_udp_event_init ( sock_udp_t sock,
event_queue_t ev_queue,
sock_udp_cb_t  handler,
void *  handler_arg 
)

Makes a UDP sock able to handle asynchronous events using Event Queue.

Parameters
[in]sockA UDP sock object.
[in]ev_queueThe queue the events on sock will be added to.
[in]handlerThe event handler function to call on an event on sock.
[in]handler_argArgument to provided to handler.
Note
Only available with module sock_udp.