Merge pull request #7599 from aabadie/coap_examples_cleanup

coap: examples cleanup
This commit is contained in:
Kaspar Schleiser 2017-10-06 10:15:34 +02:00 committed by GitHub
commit 268f9b718c
8 changed files with 108 additions and 53 deletions

View File

@ -1,19 +1,29 @@
# gcoap Example
## About
This application provides command line access to gcoap, a high-level API for CoAP messaging. See the [CoAP spec][1] for background, and the Modules>Networking>CoAP topic in the source documentation for detailed usage instructions and implementation notes.
This application provides command line access to gcoap, a high-level API for
CoAP messaging. See the [CoAP spec][1] for background, and the
Modules>Networking>CoAP topic in the source documentation for detailed usage
instructions and implementation notes.
We support two setup options for this example:
### Native networking
Build with the standard `Makefile`. Follow the setup [instructions][2] for the gnrc_networking example.
Build with the standard `Makefile`. Follow the setup [instructions][2] for
the gnrc_networking example.
### SLIP-based border router
Build with `Makefile.slip`. Follow the setup instructions in README-slip.md, which are based on the [SLIP instructions][3] for the gnrc_border_router example. We also plan to provide or reference the ethos/UHCP instructions, but we don't have it working yet.
Build with `Makefile.slip`. Follow the setup instructions in README-slip.md,
which are based on the [SLIP instructions][3] for the gnrc_border_router
example. We also plan to provide or reference the ethos/UHCP instructions,
but we don't have it working yet.
## Example Use
This example uses gcoap as a server on RIOT native. Then we send a request from a libcoap example client on the Linux host.
This example uses gcoap as a server on RIOT native. Then we send a request
from a libcoap example client on the Linux host.
### Verify setup from RIOT terminal
@ -26,7 +36,10 @@ Expected response:
CoAP open requests: 0
### Query from libcoap example client
gcoap does not provide any output to the CoAP terminal when it handles a request. We recommend use of Wireshark to see the request and response. You also can add some debug output in the endpoint function callback.
gcoap does not provide any output to the CoAP terminal when it handles a
request. We recommend use of Wireshark to see the request and response. You
also can add some debug output in the endpoint function callback.
./coap-client -N -m get -p 5683 coap://[fe80::1843:8eff:fe40:4eaa%tap0]/.well-known/core
@ -38,6 +51,7 @@ Example response:
The response shows the endpoint registered by the gcoap CLI example.
### Send query to libcoap example server
Start the libcoap example server with the command below.
./coap-server
@ -53,6 +67,19 @@ CLI output:
</>;title="General Info";ct=0,</time>;if="clock";rt="Ticks";title="Internal Clock";ct=0;obs,</async>;ct=0
## Other available CoAP implementations and applications
RIOT also provides package imports and test applications for other CoAP
implementations:
* [Nanocoap](../nanocoap_server): a very lightweight CoAP server based on the
[nanocoap library](https://github.com/kaspar030/sock/tree/master/nanocoap)
implementation
* [Microcoap](../../tests/pkg_microcoap): another lightweight CoAP server based
on the [microcoap library](https://github.com/1248/microcoap) implementation
[1]: https://tools.ietf.org/html/rfc7252 "CoAP spec"
[2]: https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_networking "instructions"
[3]: https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_border_router "SLIP instructions"

View File

@ -32,11 +32,14 @@
static void _resp_handler(unsigned req_state, coap_pkt_t* pdu,
sock_udp_ep_t *remote);
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len);
static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len);
/* CoAP resources */
static const coap_resource_t _resources[] = {
{ "/cli/stats", COAP_GET, _stats_handler },
{ "/cli/stats", COAP_GET | COAP_PUT, _stats_handler },
{ "/riot/board", COAP_GET, _riot_board_handler },
};
static gcoap_listener_t _listener = {
(coap_resource_t *)&_resources[0],
sizeof(_resources) / sizeof(_resources[0]),
@ -88,16 +91,50 @@ static void _resp_handler(unsigned req_state, coap_pkt_t* pdu,
}
/*
* Server callback for /cli/stats. Returns the count of packets sent by the
* CLI.
* Server callback for /cli/stats. Accepts either a GET or a PUT.
*
* GET: Returns the count of packets sent by the CLI.
* PUT: Updates the count of packets. Rejects an obviously bad request, but
* allows any two byte value for example purposes. Semantically, the only
* valid action is to set the value to 0.
*/
static ssize_t _stats_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len)
{
/* read coap method type in packet */
unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu));
switch(method_flag) {
case COAP_GET:
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
/* write the response buffer with the request count value */
size_t payload_len = fmt_u16_dec((char *)pdu->payload, req_count);
return gcoap_finish(pdu, payload_len, COAP_FORMAT_TEXT);
case COAP_PUT:
/* convert the payload to an integer and update the internal
value */
if (pdu->payload_len <= 5) {
char payload[6] = { 0 };
memcpy(payload, (char *)pdu->payload, pdu->payload_len);
req_count = (uint16_t)strtoul(payload, NULL, 10);
return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED);
}
else {
return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST);
}
}
return 0;
}
static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len)
{
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);
size_t payload_len = fmt_u16_dec((char *)pdu->payload, req_count);
return gcoap_finish(pdu, payload_len, COAP_FORMAT_TEXT);
/* write the RIOT board name in the response buffer */
memcpy(pdu->payload, RIOT_BOARD, strlen(RIOT_BOARD));
return gcoap_finish(pdu, strlen(RIOT_BOARD), COAP_FORMAT_TEXT);
}
static size_t _send(uint8_t *buf, size_t len, char *addr_str, char *port_str)

View File

@ -1,5 +1,5 @@
nanocoap server example
========================
=======================
This application is meant to get you started with implementing a CoAP server on RIOT.
It uses the GNRC network stack through RIOT's
@ -62,15 +62,34 @@ The link-layer address in this case is "fe80::e42a:1aff:feca:10ec", the only
Testing
=======
There are multiple external CoAP clients you can use to test the server on native.
The CoAP server exposes 3 different resources:
* `/.well-known/core`: returns the list of available resources on the server.
This is part of the CoAP specifications. It works only with GET requests.
* `/riot/board`: returns the name of the board running the server. It works
only with GET requests.
* `/riot/value`: returns the value of an internal variable of the server. It
works with GET requests and also with PUT and POST requests, which means that
this value can be updated from a client.
There are multiple external CoAP clients you can use to easily test the server
running on native.
libcoap CLI
-----------
(replace "fe80::e42a:1aff:feca:10ec" with your link-layer address)
* Get the name of the board:
```
# coap-client "coap://[fe80::e42a:1aff:feca:10ec%tap0]/riot/board"
# coap-client -m get coap://[fe80::e42a:1aff:feca:10ec%tap0]/riot/board
```
* Update and get the internal value:
```
# coap-client -m put coap://[fe80::e42a:1aff:feca:10ec%tap0]/riot/value -e 42
# coap-client -m get coap://[fe80::e42a:1aff:feca:10ec%tap0]/riot/value
```
Copper (Firefox Plugin)

View File

@ -1,11 +1,5 @@
# 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)/../..
APPLICATION = pkg_microcoap
include ../Makefile.tests_common
BOARD_INSUFFICIENT_MEMORY := chronos msb-430 msb-430h nucleo32-f031 nucleo32-f042 \
nucleo32-l031 nucleo-f030 nucleo-l053 pca10000 pca10005 \
@ -25,7 +19,6 @@ USEMODULE += gnrc_icmpv6_echo
USEMODULE += gnrc_sock_udp
USEPKG += microcoap
CFLAGS += -DMICROCOAP_DEBUG
# include this for printing IP addresses
USEMODULE += shell_commands
@ -47,21 +40,4 @@ ifneq (,$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
USEMODULE += prng_minstd
endif
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
include $(RIOTBASE)/Makefile.include
# Set a custom channel if needed
ifneq (,$(filter cc110x,$(USEMODULE))) # radio is cc110x sub-GHz
DEFAULT_CHANNEL ?= 0
CFLAGS += -DCC110X_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
else
ifneq (,$(filter at86rf212b,$(USEMODULE))) # radio is IEEE 802.15.4 sub-GHz
DEFAULT_CHANNEL ?= 5
CFLAGS += -DIEEE802154_DEFAULT_SUBGHZ_CHANNEL=$(DEFAULT_CHANNEL)
else # radio is IEEE 802.15.4 2.4 GHz
DEFAULT_CHANNEL ?= 26
CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
endif
endif

View File

@ -1,8 +1,8 @@
microcoap server example
========================
microcoap server test
=====================
This application is meant to get you started with implementing a CoAP server on RIOT.
It uses the GNRC network stack through RIOT's conn socket API.
This application is meant to get you started with implementing a CoAP server
on RIOT. It uses the GNRC network stack through RIOT's conn socket API.
Usage
=====

View File

@ -7,11 +7,11 @@
*/
/**
* @ingroup examples
* @ingroup tests
* @{
*
* @file
* @brief CoAP example server application (using microcoap)
* @brief CoAP test server application (using microcoap)
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @}
@ -28,7 +28,7 @@ extern int _netif_config(int argc, char **argv);
int main(void)
{
puts("RIOT microcoap example application");
puts("RIOT microcoap test application");
puts("Waiting for address autoconfiguration...");
xtimer_sleep(3);

View File

@ -9,11 +9,7 @@
#include "net/af.h"
#include "net/sock/udp.h"
#ifdef MICROCOAP_DEBUG
#define ENABLE_DEBUG (1)
#else
#define ENABLE_DEBUG (0)
#endif
#include "debug.h"
#include "coap.h"