diff --git a/examples/osd/arduino-merkurboard/project-conf.h b/examples/osd/arduino-merkurboard/project-conf.h index 491c0c530..957c568ad 100644 --- a/examples/osd/arduino-merkurboard/project-conf.h +++ b/examples/osd/arduino-merkurboard/project-conf.h @@ -36,6 +36,9 @@ //#define PLATFORM_HAS_BUTTON 1 #define PLATFORM_HAS_BATTERY 1 + +#define LOOP_INTERVAL (30 * CLOCK_SECOND) + /* Save energy */ //#define RDC_CONF_PT_YIELD_OFF diff --git a/examples/osd/arduino-merkurboard/sketch.pde b/examples/osd/arduino-merkurboard/sketch.pde index b1acb9318..337949c84 100644 --- a/examples/osd/arduino-merkurboard/sketch.pde +++ b/examples/osd/arduino-merkurboard/sketch.pde @@ -34,12 +34,11 @@ void setup (void) rest_activate_resource (&res_cputemp, "s/cputemp"); // NETSTACK_MAC.off(1); - // mcu_sleep_set(48); + mcu_sleep_set(128); } void loop (void) { - mcu_sleep_off(); - - mcu_sleep_on(); + + } diff --git a/examples/osd/arduino-rfid-rc522/resources/res-event.c b/examples/osd/arduino-rfid-rc522/resources/res-event.c new file mode 100644 index 000000000..9785f5c64 --- /dev/null +++ b/examples/osd/arduino-rfid-rc522/resources/res-event.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "dev/button-sensor.h" +#include "Arduino.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(void); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; +// Init array that will store new NUID +extern byte nuidPICC[4]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "NUID %02X%02X%02X%02X",nuidPICC[0],nuidPICC[1],nuidPICC[2],nuidPICC[3])); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "{\"NUID\": \"%02X%02X%02X%02X\"}",nuidPICC[0],nuidPICC[1],nuidPICC[2],nuidPICC[3])); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "Supporting content-types text/plain and application/json")); + } + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ + + // tell client when to schedule re-registration: 1 Hour + REST.set_header_max_age(response, /* uint32_t, Seconds */ 3600); +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler(void) +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/osd/arduino-rfid-rc522/resources/res-separate.c b/examples/osd/arduino-rfid-rc522/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/osd/arduino-rfid-rc522/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/osd/arduino-rfid-rc522/sketch.pde b/examples/osd/arduino-rfid-rc522/sketch.pde index 6e51c7475..459966dc6 100644 --- a/examples/osd/arduino-rfid-rc522/sketch.pde +++ b/examples/osd/arduino-rfid-rc522/sketch.pde @@ -44,7 +44,12 @@ extern "C" { #include "rest-engine.h" #include "net/netstack.h" -extern resource_t res_led, res_battery, res_cputemp; +extern resource_t + res_led, + res_event, + res_separate, + res_battery, + res_cputemp; uint8_t led_pin=4; uint8_t led_status; @@ -61,7 +66,7 @@ MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class MFRC522::MIFARE_Key key; // Init array that will store new NUID -byte nuidPICC[3]; +byte nuidPICC[4]; void setup (void) { @@ -78,9 +83,10 @@ void setup (void) } // init coap resourcen rest_init_engine (); - rest_activate_resource (&res_led, "s/led"); + rest_activate_resource (&res_led, "s/led"); rest_activate_resource (&res_battery, "s/battery"); rest_activate_resource (&res_cputemp, "s/cputemp"); + rest_activate_resource (&res_event, "s/rfid"); // NETSTACK_MAC.off(1); } @@ -105,6 +111,15 @@ void printDec(byte *buffer, byte bufferSize) { } } +void coap_rfid (void) +{ + /* Call the event_handler for this application-specific event. */ + res_event.trigger(); + + /* Also call the separate response example handler. */ + res_separate.resume(); +} + void loop (void) { // Look for new cards @@ -136,7 +151,7 @@ void loop (void) for (byte i = 0; i < 4; i++) { nuidPICC[i] = rfid.uid.uidByte[i]; } - + coap_rfid(); Serial1.println(F("The NUID tag is:")); Serial1.print(F("In hex: ")); printHex(rfid.uid.uidByte, rfid.uid.size);