Simplified Erbium support for separate responses.

This commit is contained in:
Matthias Kovatsch 2012-01-31 04:38:07 +01:00
parent b44d125d80
commit 4a02790c76
10 changed files with 238 additions and 77 deletions

View file

@ -47,11 +47,12 @@
#define REST_RES_HELLO 1
#define REST_RES_MIRROR 0 /* causes largest code size */
#define REST_RES_CHUNKS 1
#define REST_RES_POLLING 1
#define REST_RES_POLLING 0
#define REST_RES_SEPARATE 1
#define REST_RES_EVENT 1
#define REST_RES_LEDS 1
#define REST_RES_TOGGLE 1
#define REST_RES_LIGHT 1
#define REST_RES_LIGHT 0
#define REST_RES_BATTERY 1
@ -149,8 +150,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
/* The ETag and Token is copied to the header. */
uint8_t opaque[] = {0x0A, 0xBC, 0xDE};
/* Strings are not copied and should be static or in program memory (char *str = "string in .text";).
* They must be '\0'-terminated as the setters use strlen(). */
/* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */
static char location[] = {'/','f','/','a','?','k','&','e', 0};
/* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */
@ -390,6 +390,79 @@ polling_periodic_handler(resource_t *r)
}
#endif
#if REST_RES_SEPARATE && 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"
/*
* CoAP-specific example for separate responses.
* This resource is .
*/
RESOURCE(separate, METHOD_GET, "debug/separate", "title=\"Separate demo\"");
static uint8_t separate_active = 0;
static coap_separate_t separate_store[1];
void
separate_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)
{
REST.set_response_status(response, REST.status.SERVICE_UNAVAILABLE);
const char msg[] = "AlreadyInUse";
REST.set_response_payload(response, (uint8_t *)msg, sizeof(msg)-1);
}
else
{
separate_active = 1;
/* Take over and skip response by engine. */
coap_separate_response(response, separate_store);
/*
* 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");
}
}
void
separate_finalize_handler()
{
if (separate_active)
{
coap_transaction_t *transaction = NULL;
if ( (transaction = coap_new_transaction(separate_store->mid, &separate_store->addr, separate_store->port)) )
{
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
coap_init_message(response, separate_store->type, CONTENT_2_05, separate_store->mid);
coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer));
/* 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). */
separate_active = 0;
}
else
{
/*
* Set timer for retry, send error message, ...
* The example simply waits for another button press.
*/
}
} /* if (separate_active) */
}
#endif
#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT
/*
* Example for an event resource.
@ -594,8 +667,8 @@ PROCESS_THREAD(rest_server_example, ev, data)
configure_routing();
#endif
/* Initialize the REST framework. */
rest_init_framework();
/* Initialize the REST engine. */
rest_init_engine();
/* Activate the application-specific resources. */
#if REST_RES_HELLO
@ -610,6 +683,11 @@ PROCESS_THREAD(rest_server_example, ev, data)
#if REST_RES_POLLING
rest_activate_periodic_resource(&periodic_resource_polling);
#endif
#if REST_RES_SEPARATE && WITH_COAP > 3
rest_set_pre_handler(&resource_separate, coap_separate_handler);
rest_activate_resource(&resource_separate);
#endif
#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT
SENSORS_ACTIVATE(button_sensor);
rest_activate_event_resource(&resource_event);
@ -634,11 +712,17 @@ PROCESS_THREAD(rest_server_example, ev, data)
/* Define application-specific events here. */
while(1) {
PROCESS_WAIT_EVENT();
#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT
#if defined (PLATFORM_HAS_BUTTON)
if (ev == sensors_event && data == &button_sensor) {
PRINTF("BUTTON\n");
#if REST_RES_EVENT
/* Call the event_handler for this application-specific event. */
event_event_handler(&resource_event);
#endif
#if REST_RES_SEPARATE && WITH_COAP>3
/* Also call the separate response example handler. */
separate_finalize_handler();
#endif
}
#endif /* PLATFORM_HAS_BUTTON */
} /* while (1) */