diff --git a/examples/er-rest-example/Makefile b/examples/er-rest-example/Makefile index 29fb071f1..4b9be1a03 100644 --- a/examples/er-rest-example/Makefile +++ b/examples/er-rest-example/Makefile @@ -1,5 +1,5 @@ -all: rest-server-example coap-client-example -# Use this target explicitly if requried: plugtest-server +all: er-example-server er-example-client +# Use this target explicitly if requried: er-plugtest-server CONTIKI=../.. CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/er-rest-example/README b/examples/er-rest-example/README index 39b364d6d..2d2f3ccfe 100644 --- a/examples/er-rest-example/README +++ b/examples/er-rest-example/README @@ -1,35 +1,38 @@ -This is the new example for the Erbium REST Engine -================================================== +A Quick Introduction to the Erbium (Er) REST Engine +=================================================== EXAMPLE FILES ------------- -rest-server-example.c: A RESTful server example showing how to use the REST layer to develop server-side applications (at the moment only CoAP is implemented for the REST Engine). -coap-client-example.c: A CoAP client that polls the /toggle resource every 10 seconds and cycles through 4 resources on button press (target address is hard-coded). +er-example-server.c: A RESTful server example showing how to use the REST layer to develop server-side applications (at the moment only CoAP is implemented for the REST Engine). +er-example-client.c: A CoAP client that polls the /actuators/toggle resource every 10 seconds and cycles through 4 resources on button press (target address is hard-coded). +er-plugtest-server.c: The server used for draft compliance testing at ETSI IoT CoAP Plugtest in Paris, France, March 2012 (configured for minimal-net). PRELIMINARIES ------------- -a) Make sure rpl-border-router has the same stack and fits into mote memory: - Disable RDC in border-router project-conf.h +- Make sure rpl-border-router has the same stack and fits into mote memory: + You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver -b) For convenience, define the Cooja addresses in /etc/hosts +- For convenience, define the Cooja addresses in /etc/hosts aaaa::0212:7401:0001:0101 cooja1 aaaa::0212:7402:0002:0202 cooja2 ... -c) Get the Copper CoAP browser from https://addons.mozilla.org/en-US/firefox/addon/copper-270430/ -d) Optional: Save your target as default target +- Get the Copper (Cu) CoAP user-agent from https://addons.mozilla.org/en-US/firefox/addon/copper-270430/ +- Optional: Save your target as default target $ make TARGET=sky savetarget COOJA HOWTO ----------- Server only: -1) $ make TARGET=cooja rest-server-example.csc +1) $ make TARGET=cooja server-only.csc 2) Open new terminal 3) $ make connect-router-cooja 4) Start Copper and discover resources at coap://cooja2:5683/ +- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after requesting /test/separate +- Do the same when observing /test/event With client: -1) $ make TARGET=cooja coap-client-server-example.csc +1) $ make TARGET=cooja server-client.csc 2) Open new terminal 3) $ make connect-router-cooja 4) Wait until red LED toggles on mote 2 (server) @@ -39,7 +42,7 @@ TMOTES HOWTO ------------ Server: 1) Connect two Tmote Skys (check with $ make TARGET=sky sky-motelist) -2) $ make TARGET=sky rest-server-example.upload MOTE=2 +2) $ make TARGET=sky er-example-server.upload MOTE=2 3) $ make TARGET=sky login MOTE=2 4) Press reset button, get address, abort with Ctrl+C: Line: "Tentative link-local IPv6 address fe80:0000:0000:0000:____:____:____:____" @@ -50,27 +53,27 @@ Server: 8) Start Copper and discover resources at coap://[aaaa::____:____:____:____]:5683/ Add a client: -1) Change the hard-coded server address in coap-client-example.c to aaaa::____:____:____:____ +1) Change the hard-coded server address in er-example-client.c to aaaa::____:____:____:____ 2) Connect a third Tmote Sky -3) $ make TARGET=sky coap-client-example.upload MOTE=3 +3) $ make TARGET=sky er-example-client.upload MOTE=3 DETAILS ------- -The Erbium CoAP currently implements draft 08 (name "er-coap-07" stems from last technical draft changes). -Central features are commented in rest-server-example.c. +Erbium currently implements draft 08 (name "er-coap-07" stems from last technical draft changes). +Central features are commented in er-example-server.c. In general, apps/er-coap-07 supports: * All draft 08 header options * CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) -* Blockwise Transfers (note REST_MAX_CHUNK_SIZE) -* Separate Responses (see rest_set_pre_handler() and coap_separate_handler()) -* Resource discovery +* Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) +* Separate Responses (no rest_set_pre_handler() required anymore, note coap_separate_accept(), _reject(), and _resume()) +* Resource Discovery * Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) REST IMPLEMENTATIONS -------------------- -The Makefile uses WITH_COAP to configure different implementations for the Erbium REST Engine. -* WITH_COAP=7 uses Erbium CoAP 07 apps/er-coap-07/. - The default port for coap-07 is 5683. +The Makefile uses WITH_COAP to configure different implementations for the Erbium (Er) REST Engine. +* WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. + The default port for coap-07/-08 is 5683. * WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. The default port for coap-03 is 61616. er-coap-03 produces some warnings, as it not fully maintained anymore. @@ -78,6 +81,6 @@ The Makefile uses WITH_COAP to configure different implementations for the Erbiu TODOs ----- -* Blockwise uploads (for POST/PUT payload) +* Observe client * Multiple If-Match ETags * (Message deduplication) diff --git a/examples/er-rest-example/er-example-client.c b/examples/er-rest-example/er-example-client.c index 1f8ac1806..d1d543cf0 100644 --- a/examples/er-rest-example/er-example-client.c +++ b/examples/er-rest-example/er-example-client.c @@ -31,7 +31,7 @@ /** * \file - * CoAP client example + * Erbium (Er) CoAP client example * \author * Matthias Kovatsch */ diff --git a/examples/er-rest-example/er-example-server.c b/examples/er-rest-example/er-example-server.c index a062fd009..45bbea68b 100644 --- a/examples/er-rest-example/er-example-server.c +++ b/examples/er-rest-example/er-example-server.c @@ -31,7 +31,7 @@ /** * \file - * Example for the CoAP REST Engine + * Erbium (Er) REST Engine example (with CoAP-specific code) * \author * Matthias Kovatsch */ @@ -88,7 +88,7 @@ #elif WITH_COAP == 7 #include "er-coap-07.h" #else -#warning "REST example without CoAP" +#warning "Erbium example without CoAP-specifc functionality" #endif /* CoAP-specific example */ #define DEBUG 0 @@ -102,7 +102,7 @@ #define PRINTLLADDR(addr) #endif - +/******************************************************************************/ #if REST_RES_HELLO /* * Resources are defined by the RESOURCE macro. @@ -140,6 +140,7 @@ helloworld_handler(void* request, void* response, uint8_t *buffer, uint16_t pref } #endif +/******************************************************************************/ #if REST_RES_MIRROR /* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */ RESOURCE(mirror, METHOD_GET | METHOD_POST | METHOD_PUT | METHOD_DELETE, "debug/mirror", "title=\"Returns your decoded message\";rt=\"Debug\""); @@ -290,6 +291,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre } #endif /* REST_RES_MIRROR */ +/******************************************************************************/ #if REST_RES_CHUNKS /* * For data larger than REST_MAX_CHUNK_SIZE (e.g., stored in flash) resources must be aware of the buffer limitation @@ -298,7 +300,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre * These chunk-wise resources must set the offset value to its new position or -1 of the end is reached. * (The offset for CoAP's blockwise transfer can go up to 2'147'481'600 = ~2047 M for block size 2048 (reduced to 1024 in observe-03.) */ -RESOURCE(chunks, METHOD_GET, "debug/chunks", "title=\"Blockwise demo\";rt=\"Data\""); +RESOURCE(chunks, METHOD_GET, "test/chunks", "title=\"Blockwise demo\";rt=\"Data\""); #define CHUNKS_TOTAL 2050 @@ -349,7 +351,8 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre } #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_SEPARATE && WITH_COAP > 3 +/******************************************************************************/ +#if REST_RES_SEPARATE && defined (PLATFORM_HAS_BUTTON) && WITH_COAP > 3 /* Required to manually (=not by the engine) handle the response transaction. */ #include "er-coap-07-separate.h" #include "er-coap-07-transactions.h" @@ -359,7 +362,7 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre * The pre-handler takes care of the empty ACK and updates the MID and message type for CON requests. * The resource handler must store all information that required to finalize the response later. */ -RESOURCE(separate, METHOD_GET, "debug/separate", "title=\"Separate demo\""); +RESOURCE(separate, METHOD_GET, "test/separate", "title=\"Separate demo\""); /* A structure to store the required information */ typedef struct application_separate_store { @@ -439,13 +442,14 @@ separate_finalize_handler() } #endif +/******************************************************************************/ #if REST_RES_PUSHING /* * Example for a periodic resource. * It takes an additional period parameter, which defines the interval to call [name]_periodic_handler(). * A default post_handler takes care of subscriptions by managing a list of subscribers to notify. */ -PERIODIC_RESOURCE(pushing, METHOD_GET, "debug/push", "title=\"Periodic demo\";obs", 5*CLOCK_SECOND); +PERIODIC_RESOURCE(pushing, METHOD_GET, "test/push", "title=\"Periodic demo\";obs", 5*CLOCK_SECOND); void pushing_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) @@ -483,7 +487,8 @@ pushing_periodic_handler(resource_t *r) } #endif -#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT +/******************************************************************************/ +#if REST_RES_EVENT && defined (PLATFORM_HAS_BUTTON) /* * Example for an event resource. * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). @@ -524,7 +529,9 @@ event_event_handler(resource_t *r) } #endif /* PLATFORM_HAS_BUTTON */ +/******************************************************************************/ #if defined (PLATFORM_HAS_LEDS) +/******************************************************************************/ #if REST_RES_LEDS /*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/ RESOURCE(leds, METHOD_POST | METHOD_PUT , "actuators/leds", "title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\""); @@ -574,6 +581,7 @@ leds_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_ } #endif +/******************************************************************************/ #if REST_RES_TOGGLE /* A simple actuator example. Toggles the red led */ RESOURCE(toggle, METHOD_GET | METHOD_PUT | METHOD_POST, "actuators/toggle", "title=\"Red LED\";rt=\"Control\""); @@ -585,7 +593,8 @@ toggle_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre #endif #endif /* PLATFORM_HAS_LEDS */ -#if defined (PLATFORM_HAS_LIGHT) && REST_RES_LIGHT +/******************************************************************************/ +#if REST_RES_LIGHT && defined (PLATFORM_HAS_LIGHT) /* A simple getter example. Returns the reading from light sensor with a simple etag */ RESOURCE(light, METHOD_GET, "sensors/light", "title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\""); void @@ -627,7 +636,8 @@ light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred } #endif /* PLATFORM_HAS_LIGHT */ -#if defined (PLATFORM_HAS_BATTERY) && REST_RES_BATTERY +/******************************************************************************/ +#if REST_RES_BATTERY && defined (PLATFORM_HAS_BATTERY) /* A simple getter example. Returns the reading from light sensor with a simple etag */ RESOURCE(battery, METHOD_GET, "sensors/battery", "title=\"Battery status\";rt=\"Battery\""); void @@ -661,14 +671,16 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr } #endif /* PLATFORM_HAS_BATTERY */ -PROCESS(rest_server_example, "Rest Server Example"); + + +PROCESS(rest_server_example, "Erbium Example Server"); AUTOSTART_PROCESSES(&rest_server_example); PROCESS_THREAD(rest_server_example, ev, data) { PROCESS_BEGIN(); - PRINTF("Rest Example\n"); + PRINTF("Starting Erbium Example Server\n"); #ifdef RF_CHANNEL PRINTF("RF channel: %u\n", RF_CHANNEL); @@ -683,7 +695,7 @@ PROCESS_THREAD(rest_server_example, ev, data) PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); /* if static routes are used rather than RPL */ -#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) +#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) set_global_address(); configure_routing(); #endif diff --git a/examples/er-rest-example/server-client.csc b/examples/er-rest-example/server-client.csc index 583dd8af4..8c45fdf02 100644 --- a/examples/er-rest-example/server-client.csc +++ b/examples/er-rest-example/server-client.csc @@ -45,11 +45,11 @@ se.sics.cooja.mspmote.SkyMoteType - skyweb - CoAP Server - [CONTIKI_DIR]/examples/er-rest-example/rest-server-example.c - make rest-server-example.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/rest-server-example.sky + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky se.sics.cooja.interfaces.Position se.sics.cooja.interfaces.RimeAddress se.sics.cooja.interfaces.IPAddress @@ -68,11 +68,11 @@ se.sics.cooja.mspmote.SkyMoteType - sky1 - CoAP Client - [CONTIKI_DIR]/examples/er-rest-example/coap-client-example.c - make coap-client-example.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/coap-client-example.sky + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky se.sics.cooja.interfaces.Position se.sics.cooja.interfaces.RimeAddress se.sics.cooja.interfaces.IPAddress @@ -115,7 +115,7 @@ se.sics.cooja.mspmote.interfaces.MspMoteID 2 - skyweb + server @@ -129,7 +129,7 @@ se.sics.cooja.mspmote.interfaces.MspMoteID 3 - sky1 + client diff --git a/examples/er-rest-example/server-only.csc b/examples/er-rest-example/server-only.csc index 837e3d1d4..d5eee34d6 100644 --- a/examples/er-rest-example/server-only.csc +++ b/examples/er-rest-example/server-only.csc @@ -45,11 +45,11 @@ se.sics.cooja.mspmote.SkyMoteType - skyweb - Rest - [CONTIKI_DIR]/examples/er-rest-example/rest-server-example.c - make rest-server-example.sky TARGET=sky - [CONTIKI_DIR]/examples/er-rest-example/rest-server-example.sky + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky se.sics.cooja.interfaces.Position se.sics.cooja.interfaces.RimeAddress se.sics.cooja.interfaces.IPAddress @@ -92,7 +92,7 @@ se.sics.cooja.mspmote.interfaces.MspMoteID 2 - skyweb + server