Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

conn: Simplify and overhaul conn API #5533

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions examples/udp_echo_server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# name of your application
APPLICATION = default

# If no BOARD is found in the environment, use this default:
BOARD ?= native

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

# Uncomment these lines if you want to use platform support from external
# repositories:
#RIOTCPU ?= $(CURDIR)/../../RIOT/thirdparty_cpu
#RIOTBOARD ?= $(CURDIR)/../../RIOT/thirdparty_boards

# Uncomment this to enable scheduler statistics for ps:
#CFLAGS += -DSCHEDSTATISTICS

# If you want to use native with valgrind, you should recompile native
# with the target all-valgrind instead of all:
# make -B clean all-valgrind

# name of your application
APPLICATION = udp_echo_server

# If no BOARD is found in the environment, use this default:
BOARD ?= native

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

BOARD_INSUFFICIENT_MEMORY := # TODO

# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for conn communication via UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_udp
USEMODULE += gnrc_conn_udp
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
CFLAGS += -DDEVELHELP

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include
79 changes: 79 additions & 0 deletions examples/udp_echo_server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
examples/udp_echo_server
========================
This application showcases a simple UDP echo server using RIOT's connectivity
API `conn`.

It listens on port 61616 for incoming UDP packets and returns them to the
original sender.

Usage
=====

Setup
-----
Build, flash and start the application:
```
export BOARD=your_board
make
make flash
make term
```

The `term` make target starts a terminal emulator for your board. It
connects to a default port so you can interact with the shell, usually
that is `/dev/ttyUSB0`. If your port is named differently, the
`PORT=/dev/yourport` variable can be used to override this.


Sending a packet to the server
------------------------------

The `ifconfig` command will help you to configure and review all available
network configuration. On an `samr21-xpro` it will print something like the
following. The global IPv6 address is available if you set-up a [border
router][6lbr]:

```
2016-06-08 17:29:57,780 - INFO # ifconfig
2016-06-08 17:29:57,785 - INFO # Iface 7 HWaddr: 76:0e Channel: 26 Page: 0
NID: 0x23
2016-06-08 17:29:57,791 - INFO # Long HWaddr: 5a:5a:5c:5c:87:92:76:0e
2016-06-08 17:29:57,796 - INFO # TX-Power: 0dBm State: IDLE max. Retrans.: 3 CSMA Retries: 4
2016-06-08 17:29:57,802 - INFO # ACK_REQ CSMA MTU:1280 HL:64 6LO IPHC
2016-06-08 17:29:57,805 - INFO # Source address length: 8
2016-06-08 17:29:57,816 - INFO # Link type: wireless
2016-06-08 17:29:57,819 - INFO # inet6 addr: ff02::1/128 scope: local [multicast]
2016-06-08 17:29:57,821 - INFO # inet6 addr: fe80::585a:5c5c:8792:760e/64 scope: local
2016-06-08 17:29:57,825 - INFO # inet6 addr: ff02::1:ff92:760e/128 scope: local [multicast]
2016-06-08 17:29:57,830 - INFO # inet6 addr: ff02::1a/128 scope: local [multicast]
2016-06-08 17:29:57,821 - INFO # inet6 addr: 2001:db8::585a:5c5c:8792:760e/64 scope: global
```

If you now send a UDP message to one of the IPv6 addresses given with port 61616,
the node will print out this information and return a UDP packet to the sender:

```
2016-06-08 17:34:22,417 - INFO # Message "Hello!" receive from [fd00:dead:beef::1]:TODO
```

To send a UDP message using e.g. [netcat](http://nc110.sourceforge.net/)
through a [border router][6lbr] or when using the `native` `BOARD`:

```bash
echo "Hello\!" | nc -6 -u 2001:db8::585a:5c5c:8792:760e 61616
```

Note however, that some versions of `netcat` do not have IPv6 support and might
yield error messages. Because of that, we recommend the BSD version of `netcat`.

Alternatively you can send with e.g. the [`gnrc_networking`
example][gnrc_networking]:

```
udp send fe80::585a:5c5c:8792:760e 61616 "Hello!"
2016-06-08 17:46:09,116 - INFO # > udp send fe80::585a:5c5c:8792:760e 61616 "Hello!"
2016-06-08 17:46:09,124 - INFO # Success: send 6 byte to [fe80::585a:5c5c:8792:760e]:61616
```

[6lbr] ../gnrc_border_router/README.md
[gnrc_networking] ../gnrc_networking/README.md
104 changes: 104 additions & 0 deletions examples/udp_echo_server/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup examples
* @{
*
* @file
* @brief Default application that shows a lot of functionality of RIOT
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
*
* @}
*/

#include <stdio.h>
#include <string.h>

#include "net/af.h"
#include "net/conn/udp.h"
#include "msg.h"
#include "shell.h"
#include "shell_commands.h"
#include "thread.h"

#define ECHO_SERVER_BUFSIZE (64)
#define ECHO_SERVER_PORT (61616)
#define ECHO_SERVER_PRIO (THREAD_PRIORITY_MAIN - 1)
#define ECHO_SERVER_STACK_SIZE (THREAD_STACKSIZE_MAIN)

/* shell line buffer */
static char line_buf[SHELL_DEFAULT_BUFSIZE];
static char echo_server_buf[ECHO_SERVER_BUFSIZE];
static char echo_server_stack[ECHO_SERVER_STACK_SIZE];
static const conn_ep_udp_t server_address = { .addr = { .ipv6 = IPV6_ADDR_UNSPECIFIED },
.family = AF_INET6,
.netif = CONN_EP_ANY_NETIF,
.port = ECHO_SERVER_PORT };

static void *echo_server(void *arg)
{
conn_udp_t server;

(void)arg;
/* create connectivity end-point for server */
if (conn_udp_create(&server, &server_address, NULL) < 0) {
puts("Unable to start server");
return NULL;
}
while (1) {
conn_ep_udp_t client_address;
int res;

/* wait for packet */
res = conn_udp_recvfrom(&server, echo_server_buf,
sizeof(echo_server_buf), 0, &client_address);
/* only print out and reply to valid results*/
if (res >= 0) {
char addr_str[IPV6_ADDR_MAX_STR_LEN];

echo_server_buf[res] = '\0';
/* convert source address to string */
switch (client_address.family) {
case AF_INET6:
ipv6_addr_to_str(addr_str,
&client_address.addr.ipv6,
sizeof(addr_str));
break;
default:
memcpy(addr_str, "???", sizeof("???"));
break;
}
/* output received message */
printf("Message \"%s\" received from [%s]:%u\n",
echo_server_buf, addr_str, client_address.port);
/* send reply */
conn_udp_sendto(&server, echo_server_buf, res,
&client_address);
}
}
return NULL;
}

int main(void)
{
/* start server thread */
if (thread_create(echo_server_stack, sizeof(echo_server_stack),
ECHO_SERVER_PRIO, THREAD_CREATE_STACKTEST, echo_server,
NULL, "echo_server") <= KERNEL_PID_UNDEF) {
puts("Unable to start server thread");
return 1;
}

/* initialize shell with default commands */
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);

return 0;
}
61 changes: 26 additions & 35 deletions sys/include/net/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

/**
* @defgroup net_conn Application connection API
* @defgroup net_conn Application connectivity API
* @ingroup net
* @brief Provides a minimal common API for applications to connect to the
* different network stacks.
Expand All @@ -29,42 +29,44 @@
* | Network Stack |
* +---------------+
*
* This module provides a minimal set of functions to establish a connection using
* different types of connections. Together, they serve as a common API
* that connects application- and network stack code.
* This module provides a minimal set of functions to establish connectivity or
* send and receives datagrams using different types of connectivity. Together,
* they serve as a common API that connects application- and network stack code.
*
* Currently the following connection types are defined:
* Currently the following connectivity types are defined:
*
* * @ref conn_ip_t (net/conn/ip.h): raw IP connections
* * @ref conn_tcp_t (net/conn/tcp.h): TCP connections
* * @ref conn_udp_t (net/conn/udp.h): UDP connections
* * @ref conn_ip_t (net/conn/ip.h): raw IP connectivity
* * @ref conn_tcp_t (net/conn/tcp.h): TCP connectivity
* * @ref conn_udp_t (net/conn/udp.h): UDP connectivity
*
* Each network stack must implement at least one connection type.
* Each network stack must implement at least one connectivity type.
*
* Note that there might be no relation between the different connection types.
* For simplicity and modularity this API doesn't put any restriction of the actual
* implementation of the type. For example, one implementation might choose
* to have all connection types have a common base class or use the raw IPv6
* connection type to send e.g. UDP packets, while others will keep them
* Note that there might be no relation between the different connectivity
* types.
* For simplicity and modularity this API doesn't put any restriction of the
* actual implementation of the type. For example, one implementation might
* choose to have all connectivity types have a common base class or use the raw
* IPv6 connectivity type to send e.g. UDP packets, while others will keep them
* completely separate from each other.
*
* How To Use
* ==========
*
* A RIOT application uses the functions provided by one or more of the connection types
* headers (for example @ref conn_udp_t), regardless of the network stack it uses.
* The network stack used under the bonnet is specified by including the appropriate
* module (for example USEMODULE += gnrc_conn_udp)
* A RIOT application uses the functions provided by one or more of the
* connectivity type headers (for example @ref conn_udp), regardless of the
* network stack it uses.
* The network stack used under the bonnet is specified by including the
* appropriate module (for example USEMODULE += gnrc_conn_udp)
*
* This allows for network stack agnostic code on the application layer.
* The application code to establish a connection is always the same, allowing
* the network stack underneath to be switched simply by changing the USEMODULE
* definition in the application's Makefile.
* The application code to establish connectivity is always the same, allowing
* the network stack underneath to be switched simply by changing the
* `USEMODULE` definitions in the application's Makefile.
*
* @{
*
* @file
* @brief Application connection API definitions
* @brief Application connectivity API definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
Expand All @@ -73,27 +75,16 @@
#ifndef NET_CONN_H_
#define NET_CONN_H_

#include <stdbool.h>

#include "net/conn/ip.h"
#include "net/conn/tcp.h"
#include "net/conn/udp.h"
#include "net/ipv6/addr.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Find the best matching source address for a given prefix
*
* @param[in] dst Pointer to the IPv6 address to find a match for
* Must not be NULL
*
* @return NULL if no matching address on any interface could be found
* @return pointer to an IPv6 address configured on an interface with the best
* match to @p dst
*/
ipv6_addr_t *conn_find_best_source(const ipv6_addr_t *dst);

#ifdef __cplusplus
}
#endif
Expand Down
45 changes: 45 additions & 0 deletions sys/include/net/conn/addr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @defgroup net_conn_addr Address abstractions
* @ingroup net_conn
* @brief Address abstractions for usage with @ref net_conn.
* @{
*
* @file
* @brief Address abstraction definitions for @ref net_conn.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef CONN_ADDR_H_
#define CONN_ADDR_H_

#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Type to abstract both IPv4 and IPv6 addresses
*/
typedef union {
#ifdef CONN_HAS_IPV6
ipv6_addr_t ipv6; /**< IPv6 address mode */
#endif
ipv4_addr_t ipv4; /**< IPv4 address mode */
} conn_addr_ip_t;

#ifdef __cplusplus
}
#endif

#endif /* CONN_ADDR_H_ */
/** @} */
Loading