diff --git a/08-coap-basic/README.md b/08-coap-basic/README.md index 9764c71..d9091ea 100644 --- a/08-coap-basic/README.md +++ b/08-coap-basic/README.md @@ -49,7 +49,7 @@ $ make all flash term **You should see one wireless interface.** **Among other things, it has a MAC address (Long HWaddr), a maximum transmission unit (MTU) and one or more IPv6 addresses.** **They are denoted `inet6 addr`. You may not see the one with `scope:global`.** -**In this case, one of the node's IPv6 addresses is `2001:db8::5d0f:7b9d:ae49:3ee6`.** +**In this case, one of the node's IPv6 addresseterms is `2001:db8::5d0f:7b9d:ae49:3ee6`.** **3. Make a coap GET request to your own node. Use your IP address from the previous step.** **You can check how to use the `coap` shell command by typing:** @@ -60,6 +60,7 @@ $ make all flash term **The default UDP port for CoAP servers is `5683`:** ```sh > coap get 2001:db8::5d0f:7b9d:ae49:3ee6 5683 /.well-known/core +coap get 2001:db8::d08e:7060:6eff:7da6 5683 /.well-known/core ``` **You should get a response with `code 2.05` and the paths of the resources.** @@ -71,6 +72,8 @@ $ make all flash term **4. Try to get the board name from the `/riot/board` resource, sending a GET request.** **The command should look almost as the one in step 3, but with a different path at the end.** +coap get 2001:db8::d08e:7060:6eff:7da6 5683 /.riot/board + ## Task 2 @@ -215,6 +218,8 @@ on. **1. Turn the LED 0 of some other board on:** ```sh > coap put 2001:db8::814c:35fc:fd31:5fde 5683 /led/0 1 + +coap put 2001:db8::d08e:7060:6eff:7da6 5683 /led/0 1 ``` --- @@ -256,6 +261,8 @@ temperature and humidity readings of the room. **`/.well-known/core` resource to find which resources it exposes.** **Use the `coap` shell command as in task 1.** +coap get 2001:db8::4860:3c76:8f4b:16e6 5683 /.well-known/core + **2. Once you have found the resources, try getting the current temperature** **and humidity values.** @@ -270,6 +277,8 @@ node that is exposing pressure and magnetic readings in the room. **According to the specification, the resource type of the lookup resource** **should be `rt=core.rd-lookup-res`** +coap get fd00:dead:beef::1 5683 /.well-known/core + **2. Once you have found the lookup resource, perform a GET request to it.** **It should reply with the hidden sensor information.** diff --git a/08-coap-basic/server.c b/08-coap-basic/server.c index 6a9e01c..a3b65fc 100644 --- a/08-coap-basic/server.c +++ b/08-coap-basic/server.c @@ -23,14 +23,93 @@ static ssize_t _riot_board_handler(coap_pkt_t* pdu, uint8_t *buf, size_t len, void *ctx); +static const gpio_t leds[] = { + LED0_PIN, + LED1_PIN, + LED2_PIN, +}; + /* [TASK 2: add the prototype of your resource 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/ */ +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 */ + /* check if there is a payload with a LED status */ + 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]); + } else { + gpio_set(leds[led_number]); + } + 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; +} /* [TASK 2: declare the array of LEDs here] */ + +static ssize_t _led_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, void *ctx); + /* CoAP resources. Must be sorted by path (ASCII order). */ static const coap_resource_t _resources[] = { + /* [TASK 2: register your CoAP resource here] */ + { "/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 @@ -53,6 +132,11 @@ 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] */