Merge pull request #4287 from kaspar030/add_conn_coap_example
examples: add microcoap, gnrc, conn example
This commit is contained in:
commit
548a63db0d
58
examples/microcoap_server/Makefile
Normal file
58
examples/microcoap_server/Makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# name of your application
|
||||||
|
APPLICATION = microcoap_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 := airfy-beacon chronos msb-430 msb-430h nrf51dongle \
|
||||||
|
nrf6310 pca10000 pca10005 spark-core \
|
||||||
|
stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \
|
||||||
|
yunjia-nrf51822 z1
|
||||||
|
|
||||||
|
# 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_netif_default
|
||||||
|
USEMODULE += auto_init_gnrc_netif
|
||||||
|
# Specify the mandatory networking modules for IPv6 and UDP
|
||||||
|
USEMODULE += gnrc_ipv6_router_default
|
||||||
|
USEMODULE += gnrc_udp
|
||||||
|
# Add a routing protocol
|
||||||
|
USEMODULE += gnrc_rpl
|
||||||
|
# Additional networking modules that can be dropped if not needed
|
||||||
|
USEMODULE += gnrc_icmpv6_echo
|
||||||
|
|
||||||
|
#
|
||||||
|
USEMODULE += gnrc_conn_udp
|
||||||
|
|
||||||
|
USEPKG += microcoap
|
||||||
|
CFLAGS += -DMICROCOAP_DEBUG
|
||||||
|
|
||||||
|
# include this for printing IP addresses
|
||||||
|
USEMODULE += shell_commands
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Use different settings when compiling for one of the following (low-memory)
|
||||||
|
# boards
|
||||||
|
LOW_MEMORY_BOARDS := nucleo-f334
|
||||||
|
|
||||||
|
ifneq (,$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
|
||||||
|
$(info Using low-memory configuration for microcoap_server.)
|
||||||
|
## low-memory tuning values
|
||||||
|
# lower pktbuf buffer size
|
||||||
|
CFLAGS += -DGNRC_PKTBUF_SIZE=1000
|
||||||
|
# disable fib, rpl
|
||||||
|
DISABLE_MODULE += fib gnrc_rpl
|
||||||
|
USEMODULE += prng_minstd
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Change this to 0 show compiler invocation lines by default:
|
||||||
|
QUIET ?= 1
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
62
examples/microcoap_server/README.md
Normal file
62
examples/microcoap_server/README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
microcoap server example
|
||||||
|
========================
|
||||||
|
|
||||||
|
This application is meant to get you started with impementing a CoAP server on RIOT.
|
||||||
|
It uses the gnrc network stack through RIOT's conn socket API.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
To try on native, compile with
|
||||||
|
|
||||||
|
```
|
||||||
|
# make all
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the resulting binary, e.g.,
|
||||||
|
|
||||||
|
```
|
||||||
|
# make term
|
||||||
|
```
|
||||||
|
|
||||||
|
The application is now listening on all it's configured IP addresses.
|
||||||
|
|
||||||
|
Now find out it's link\_layer address:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make term
|
||||||
|
/home/kaspar/src/riot/examples/microcoap_server/bin/native/microcoap_server.elf tap0
|
||||||
|
RIOT native interrupts/signals initialized.
|
||||||
|
LED_GREEN_OFF
|
||||||
|
LED_RED_ON
|
||||||
|
RIOT native board initialized.
|
||||||
|
RIOT native hardware initialization complete.
|
||||||
|
|
||||||
|
main(): This is RIOT! (Version: 2015.12-devel-632-g8f451-booze-add_conn_coap_example)
|
||||||
|
RIOT microcoap example application
|
||||||
|
Configured network interfaces:
|
||||||
|
Iface 5 HWaddr: fa:bf:2b:01:9e:a3
|
||||||
|
MTU:1280 HL:64
|
||||||
|
Source address length: 6
|
||||||
|
Link type: wired
|
||||||
|
inet6 addr: ff02::1/128 scope: local [multicast]
|
||||||
|
inet6 addr: fe80::f8bf:2bff:fe01:9ea3/64 scope: local
|
||||||
|
inet6 addr: ff02::1:ff01:9ea3/128 scope: local [multicast]
|
||||||
|
inet6 addr: ff02::2/128 scope: local [multicast]
|
||||||
|
|
||||||
|
Waiting for incoming UDP packet...
|
||||||
|
```
|
||||||
|
|
||||||
|
The link-layer address in this case is "fe80::f8bf:2bff:fe01:9ea3", the only
|
||||||
|
"scope: local" address set.
|
||||||
|
|
||||||
|
Connect using libcoap CLI
|
||||||
|
=========================
|
||||||
|
|
||||||
|
(replace "fe80::f8bf:2bff:fe01:9ea3" with your link-layer address)
|
||||||
|
|
||||||
|
```
|
||||||
|
# coap-client coap://[fe80::f8bf:2bff:fe01:9ea3%tap0]/riot/board
|
||||||
|
```
|
||||||
101
examples/microcoap_server/coap.c
Normal file
101
examples/microcoap_server/coap.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <coap.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MAX_RESPONSE_LEN 500
|
||||||
|
static uint8_t response[MAX_RESPONSE_LEN] = { 0 };
|
||||||
|
|
||||||
|
static int handle_get_well_known_core(coap_rw_buffer_t *scratch,
|
||||||
|
const coap_packet_t *inpkt,
|
||||||
|
coap_packet_t *outpkt,
|
||||||
|
uint8_t id_hi, uint8_t id_lo);
|
||||||
|
|
||||||
|
static int handle_get_riot_board(coap_rw_buffer_t *scratch,
|
||||||
|
const coap_packet_t *inpkt,
|
||||||
|
coap_packet_t *outpkt,
|
||||||
|
uint8_t id_hi, uint8_t id_lo);
|
||||||
|
|
||||||
|
static const coap_endpoint_path_t path_well_known_core =
|
||||||
|
{ 2, { ".well-known", "core" } };
|
||||||
|
|
||||||
|
static const coap_endpoint_path_t path_riot_board =
|
||||||
|
{ 2, { "riot", "board" } };
|
||||||
|
|
||||||
|
const coap_endpoint_t endpoints[] =
|
||||||
|
{
|
||||||
|
{ COAP_METHOD_GET, handle_get_well_known_core,
|
||||||
|
&path_well_known_core, "ct=40" },
|
||||||
|
{ COAP_METHOD_GET, handle_get_riot_board,
|
||||||
|
&path_riot_board, "ct=0" },
|
||||||
|
/* marks the end of the endpoints array: */
|
||||||
|
{ (coap_method_t)0, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int handle_get_well_known_core(coap_rw_buffer_t *scratch,
|
||||||
|
const coap_packet_t *inpkt, coap_packet_t *outpkt,
|
||||||
|
uint8_t id_hi, uint8_t id_lo)
|
||||||
|
{
|
||||||
|
char *rsp = (char *)response;
|
||||||
|
int len = sizeof(response);
|
||||||
|
const coap_endpoint_t *ep = endpoints;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
len--; // Null-terminated string
|
||||||
|
|
||||||
|
while (NULL != ep->handler) {
|
||||||
|
if (NULL == ep->core_attr) {
|
||||||
|
ep++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < strlen(rsp)) {
|
||||||
|
strncat(rsp, ",", len);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncat(rsp, "<", len);
|
||||||
|
len--;
|
||||||
|
|
||||||
|
for (i = 0; i < ep->path->count; i++) {
|
||||||
|
strncat(rsp, "/", len);
|
||||||
|
len--;
|
||||||
|
|
||||||
|
strncat(rsp, ep->path->elems[i], len);
|
||||||
|
len -= strlen(ep->path->elems[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncat(rsp, ">;", len);
|
||||||
|
len -= 2;
|
||||||
|
|
||||||
|
strncat(rsp, ep->core_attr, len);
|
||||||
|
len -= strlen(ep->core_attr);
|
||||||
|
|
||||||
|
ep++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coap_make_response(scratch, outpkt, (const uint8_t *)rsp,
|
||||||
|
strlen(rsp), id_hi, id_lo, &inpkt->tok,
|
||||||
|
COAP_RSPCODE_CONTENT,
|
||||||
|
COAP_CONTENTTYPE_APPLICATION_LINKFORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_get_riot_board(coap_rw_buffer_t *scratch,
|
||||||
|
const coap_packet_t *inpkt, coap_packet_t *outpkt,
|
||||||
|
uint8_t id_hi, uint8_t id_lo)
|
||||||
|
{
|
||||||
|
const char *riot_name = RIOT_BOARD;
|
||||||
|
int len = strlen(RIOT_BOARD);
|
||||||
|
|
||||||
|
memcpy(response, riot_name, len);
|
||||||
|
|
||||||
|
return coap_make_response(scratch, outpkt, (const uint8_t *)response, len,
|
||||||
|
id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT,
|
||||||
|
COAP_CONTENTTYPE_TEXT_PLAIN);
|
||||||
|
}
|
||||||
47
examples/microcoap_server/main.c
Normal file
47
examples/microcoap_server/main.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*
|
||||||
|
* 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 CoAP example server application (using microcoap)
|
||||||
|
*
|
||||||
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "msg.h"
|
||||||
|
|
||||||
|
#define MAIN_QUEUE_SIZE (8)
|
||||||
|
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
|
||||||
|
|
||||||
|
void microcoap_server_loop(void);
|
||||||
|
|
||||||
|
/* import "ifconfig" shell command, used for printing addresses */
|
||||||
|
extern int _netif_config(int argc, char **argv);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
puts("RIOT microcoap example application");
|
||||||
|
|
||||||
|
/* microcoap_server uses conn which uses gnrc which needs a msg queue */
|
||||||
|
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
|
||||||
|
|
||||||
|
/* print network addresses */
|
||||||
|
puts("Configured network interfaces:");
|
||||||
|
_netif_config(0, NULL);
|
||||||
|
|
||||||
|
/* start coap server loop */
|
||||||
|
microcoap_server_loop();
|
||||||
|
|
||||||
|
/* should be never reached */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
92
examples/microcoap_server/microcoap_conn.c
Normal file
92
examples/microcoap_server/microcoap_conn.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "net/af.h"
|
||||||
|
#include "net/conn/udp.h"
|
||||||
|
|
||||||
|
#ifdef MICROCOAP_DEBUG
|
||||||
|
#define ENABLE_DEBUG (1)
|
||||||
|
#else
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#endif
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "coap.h"
|
||||||
|
|
||||||
|
static uint8_t _udp_buf[512]; /* udp read buffer (max udp payload size) */
|
||||||
|
uint8_t scratch_raw[1024]; /* microcoap scratch buffer */
|
||||||
|
|
||||||
|
coap_rw_buffer_t scratch_buf = { scratch_raw, sizeof(scratch_raw) };
|
||||||
|
|
||||||
|
#define COAP_SERVER_PORT (5683)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starts a blocking and never-returning loop dispatching CoAP requests.
|
||||||
|
*
|
||||||
|
* When using gnrc, make sure the calling thread has an initialized msg queue.
|
||||||
|
*/
|
||||||
|
void microcoap_server_loop(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t laddr[16] = { 0 };
|
||||||
|
uint8_t raddr[16] = { 0 };
|
||||||
|
size_t raddr_len;
|
||||||
|
uint16_t rport;
|
||||||
|
|
||||||
|
conn_udp_t conn;
|
||||||
|
|
||||||
|
int rc = conn_udp_create(&conn, laddr, sizeof(laddr), AF_INET6, COAP_SERVER_PORT);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
DEBUG("Waiting for incoming UDP packet...\n");
|
||||||
|
rc = conn_udp_recvfrom(&conn, (char *)_udp_buf, sizeof(_udp_buf), raddr, &raddr_len, &rport);
|
||||||
|
if (rc < 0) {
|
||||||
|
DEBUG("Error in conn_udp_recvfrom(). rc=%u\n", rc);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t n = rc;
|
||||||
|
|
||||||
|
coap_packet_t pkt;
|
||||||
|
DEBUG("Received packet: ");
|
||||||
|
coap_dump(_udp_buf, n, true);
|
||||||
|
DEBUG("\n");
|
||||||
|
|
||||||
|
/* parse UDP packet to CoAP */
|
||||||
|
if (0 != (rc = coap_parse(&pkt, _udp_buf, n))) {
|
||||||
|
DEBUG("Bad packet rc=%d\n", rc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
coap_packet_t rsppkt;
|
||||||
|
DEBUG("content:\n");
|
||||||
|
coap_dumpPacket(&pkt);
|
||||||
|
|
||||||
|
/* handle CoAP request */
|
||||||
|
coap_handle_req(&scratch_buf, &pkt, &rsppkt);
|
||||||
|
|
||||||
|
/* build reply */
|
||||||
|
size_t rsplen = sizeof(_udp_buf);
|
||||||
|
if ((rc = coap_build(_udp_buf, &rsplen, &rsppkt)) != 0) {
|
||||||
|
DEBUG("coap_build failed rc=%d\n", rc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("Sending packet: ");
|
||||||
|
coap_dump(_udp_buf, rsplen, true);
|
||||||
|
DEBUG("\n");
|
||||||
|
DEBUG("content:\n");
|
||||||
|
coap_dumpPacket(&rsppkt);
|
||||||
|
|
||||||
|
/* send reply via UDP */
|
||||||
|
rc = conn_udp_sendto(_udp_buf, rsplen, NULL, 0, raddr, raddr_len, AF_INET6, COAP_SERVER_PORT, rport);
|
||||||
|
if (rc < 0) {
|
||||||
|
DEBUG("Error sending CoAP reply via udp; %u\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
pkg/microcoap/0005-fix-uninitialized-variable.patch
Normal file
30
pkg/microcoap/0005-fix-uninitialized-variable.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From ac2d404d32d96a50a779ded7ad007f15bcf2b4b0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
Date: Mon, 30 Nov 2015 02:11:12 +0100
|
||||||
|
Subject: [PATCH] fix uninitialized variable
|
||||||
|
|
||||||
|
coap.c: In function 'coap_build':
|
||||||
|
coap.c:298:17: error: 'len' may be used uninitialized in this function
|
||||||
|
[-Werror=maybe-uninitialized]
|
||||||
|
uint8_t len, delta = 0;
|
||||||
|
^
|
||||||
|
---
|
||||||
|
coap.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/coap.c b/coap.c
|
||||||
|
index ada66c2..b6b05af 100644
|
||||||
|
--- a/coap.c
|
||||||
|
+++ b/coap.c
|
||||||
|
@@ -295,7 +295,7 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt)
|
||||||
|
for (i=0;i<pkt->numopts;i++)
|
||||||
|
{
|
||||||
|
uint32_t optDelta;
|
||||||
|
- uint8_t len, delta = 0;
|
||||||
|
+ uint8_t len = 0, delta = 0;
|
||||||
|
|
||||||
|
if (((size_t)(p-buf)) > *buflen)
|
||||||
|
return COAP_ERR_BUFFER_TOO_SMALL;
|
||||||
|
--
|
||||||
|
2.6.2
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user