Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

Add sensor CoAP resources #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion 08-coap-basic/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,22 @@
#include "board.h"

static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx);
static ssize_t _led_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx);

/* [TASK 2: add the prototype of your resource handler here] */

/* [TASK 2: declare the array of LEDs here] */
static const gpio_t leds[] = {
LED0_PIN,
LED1_PIN,
LED2_PIN,
};

/* CoAP resources. Must be sorted by path (ASCII order). */
static const coap_resource_t _resources[] = {
/* [TASK 2: register your CoAP resource here] */
{ "/riot/board", COAP_GET, _riot_board_handler, NULL },
{ "/led/", COAP_GET | COAP_PUT | COAP_MATCH_SUBTREE, _led_handler, NULL },
{ "/riot/board", COAP_GET, _riot_board_handler, NULL }
};

/* a gcoap listener is a collection of resources. Additionally we can specify
Expand All @@ -53,9 +60,82 @@ void server_init(void)
gcoap_register_listener(&_listener);

/* [TASK 2: initialize the GPIOs here] */
/* initialize LEDs and turn them off */
for (unsigned i = 0; i < ARRAY_SIZE(leds); i++) {
gpio_init(leds[i], GPIO_OUT);
gpio_set(leds[i]);
}
}

/* [TASK 2: implement the LED handler here] */
static ssize_t _led_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx)
{
(void) ctx; /* argument not used */

/* implement your handler here */
char uri[CONFIG_NANOCOAP_URI_MAX] = { 0 };
/* get the request path, to know which LED is being requested */
if (coap_get_uri_path(pdu, (uint8_t *)uri) <= 0) {
/* reply with an error if we could not parse the URI */
return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST);
}

/* find the LED number, the URI should be /led/<number> */
char *led_str = uri + strlen("/led/");
unsigned led_number = atoi(led_str);

/* verify that the number is valid, respond with an error otherwise */
if (led_number >= ARRAY_SIZE(leds)) {
return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST);
}

ssize_t resp_len = 0;
int led_status = 0;
unsigned method = coap_method2flag(coap_get_code_detail(pdu));

switch (method) {
case COAP_PUT: /* on PUT, we set the status of the LED based on the payload */
if (pdu->payload_len) {
led_status = atoi((char *)pdu->payload);
} else {
return gcoap_response(pdu, buf, len, COAP_CODE_BAD_REQUEST);
}

if (led_status) {
gpio_clear(leds[led_number]);
puts("LED off");
} else {
gpio_set(leds[led_number]);
puts("LED on");
}
return gcoap_response(pdu, buf, len, COAP_CODE_CHANGED);

case COAP_GET: /* on GET, we return the status of the LED in plain text */
/* initialize the CoAP response */
gcoap_resp_init(pdu, buf, len, COAP_CODE_CONTENT);

/* set the content format to plain text */
coap_opt_add_format(pdu, COAP_FORMAT_TEXT);

/* finish the options indicating that we will include a payload */
resp_len = coap_opt_finish(pdu, COAP_OPT_FINISH_PAYLOAD);

/* get the current status of the LED, which is the inverted value of the GPIO */
led_status = !gpio_read(leds[led_number]);

/* based on the status, write the value of the payload to send */
if (led_status) {
pdu->payload[0] = '1';
} else {
pdu->payload[0] = '0';
}
resp_len++;
return resp_len;

}

return 0;
}

/*
* Server callback for /riot/board. Accepts only GET.
Expand Down