examples/gcoap: update README and add new handlers

This commit is contained in:
Alexandre Abadie 2017-09-14 09:52:28 +02:00
parent c2b78be6c6
commit 6e28e95c00
2 changed files with 77 additions and 13 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);
/* 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)