
6 changed files with 390 additions and 0 deletions
@ -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 |
@ -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 |
||||
``` |
@ -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); |
||||
} |
@ -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; |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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…
Reference in new issue