mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
pkg/microcoap/0005-fix-uninitialized-variable.patch
Normal file
BIN
pkg/microcoap/0005-fix-uninitialized-variable.patch
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user