Used Uncrustify and fixed Travis build errors.
This commit is contained in:
parent
3dd5bd7a37
commit
bb737f85ae
4
apps/er-coap/er-coap-conf.h
Executable file → Normal file
4
apps/er-coap/er-coap-conf.h
Executable file → Normal file
|
@ -60,12 +60,12 @@
|
|||
|
||||
/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */
|
||||
#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */
|
||||
#define COAP_MAX_HEADER_SIZE (4 + COAP_TOKEN_LEN + 3 + 1+COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
|
||||
#define COAP_MAX_HEADER_SIZE (4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
|
||||
#endif /* COAP_MAX_HEADER_SIZE */
|
||||
|
||||
/* Number of observer slots (each takes abot xxx bytes) */
|
||||
#ifndef COAP_MAX_OBSERVERS
|
||||
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS-1
|
||||
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1
|
||||
#endif /* COAP_MAX_OBSERVERS */
|
||||
|
||||
/* Interval in seconds in which NON notifies are changed to CON notifies to check client. */
|
||||
|
|
0
apps/er-coap/er-coap-constants.h
Executable file → Normal file
0
apps/er-coap/er-coap-constants.h
Executable file → Normal file
161
apps/er-coap/er-coap-engine.c
Executable file → Normal file
161
apps/er-coap/er-coap-engine.c
Executable file → Normal file
|
@ -41,8 +41,17 @@
|
|||
#include <string.h>
|
||||
#include "er-coap-engine.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
PROCESS(coap_engine, "CoAP Engine");
|
||||
|
||||
|
@ -60,7 +69,7 @@ coap_receive(void)
|
|||
erbium_status_code = NO_ERROR;
|
||||
|
||||
PRINTF("handle_incoming_data(): received uip_datalen=%u \n",
|
||||
(uint16_t) uip_datalen());
|
||||
(uint16_t)uip_datalen());
|
||||
|
||||
/* static declaration reduces stack peaks and program code size */
|
||||
static coap_packet_t message[1]; /* this way the packet can be treated as pointer as usual */
|
||||
|
@ -91,8 +100,8 @@ coap_receive(void)
|
|||
|
||||
/* use transaction buffer for response to confirmable request */
|
||||
if((transaction =
|
||||
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport))) {
|
||||
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport))) {
|
||||
uint32_t block_num = 0;
|
||||
uint16_t block_size = REST_MAX_CHUNK_SIZE;
|
||||
uint32_t block_offset = 0;
|
||||
|
@ -107,16 +116,14 @@ coap_receive(void)
|
|||
/* unreliable NON requests are answered with a NON as well */
|
||||
coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
|
||||
coap_get_mid());
|
||||
/* mirror token */
|
||||
}
|
||||
|
||||
/* mirror token */
|
||||
if(message->token_len) {
|
||||
coap_set_token(response, message->token, message->token_len);
|
||||
/* get offset for blockwise transfers */
|
||||
}
|
||||
|
||||
/* get offset for blockwise transfers */
|
||||
if(coap_get_header_block2
|
||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||
PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n",
|
||||
block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset);
|
||||
block_size = MIN(block_size, REST_MAX_CHUNK_SIZE);
|
||||
|
@ -128,12 +135,12 @@ coap_receive(void)
|
|||
|
||||
/* call REST framework and check if found and allowed */
|
||||
if(service_cbk
|
||||
(message, response, transaction->packet + COAP_MAX_HEADER_SIZE,
|
||||
block_size, &new_offset)) {
|
||||
(message, response, transaction->packet + COAP_MAX_HEADER_SIZE,
|
||||
block_size, &new_offset)) {
|
||||
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
|
||||
//TODO coap_handle_blockwise(request, response, start_offset, end_offset);
|
||||
/* TODO coap_handle_blockwise(request, response, start_offset, end_offset); */
|
||||
|
||||
/* resource is unaware of Block1 */
|
||||
if(IS_OPTION(message, COAP_OPTION_BLOCK1)
|
||||
|
@ -144,14 +151,14 @@ coap_receive(void)
|
|||
erbium_status_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoBlock1Support";
|
||||
|
||||
/* client requested Block2 transfer */
|
||||
/* client requested Block2 transfer */
|
||||
} else if(IS_OPTION(message, COAP_OPTION_BLOCK2)) {
|
||||
|
||||
/* unchanged new_offset indicates that resource is unaware of blockwise transfer */
|
||||
if(new_offset == block_offset) {
|
||||
PRINTF
|
||||
("Blockwise: unaware resource with payload length %u/%u\n",
|
||||
response->payload_len, block_size);
|
||||
response->payload_len, block_size);
|
||||
if(block_offset >= response->payload_len) {
|
||||
PRINTF
|
||||
("handle_incoming_data(): block_offset >= response->payload_len\n");
|
||||
|
@ -169,7 +176,7 @@ coap_receive(void)
|
|||
block_offset, block_size));
|
||||
} /* if(valid offset) */
|
||||
|
||||
/* resource provides chunk-wise data */
|
||||
/* resource provides chunk-wise data */
|
||||
} else {
|
||||
PRINTF("Blockwise: blockwise resource, new offset %ld\n",
|
||||
new_offset);
|
||||
|
@ -184,11 +191,11 @@ coap_receive(void)
|
|||
}
|
||||
} /* if(resource aware of blockwise) */
|
||||
|
||||
/* Resource requested Block2 transfer */
|
||||
/* Resource requested Block2 transfer */
|
||||
} else if(new_offset != 0) {
|
||||
PRINTF
|
||||
("Blockwise: no block option for blockwise resource, using block size %u\n",
|
||||
REST_MAX_CHUNK_SIZE);
|
||||
REST_MAX_CHUNK_SIZE);
|
||||
|
||||
coap_set_header_block2(response, 0, new_offset != -1,
|
||||
REST_MAX_CHUNK_SIZE);
|
||||
|
@ -197,9 +204,9 @@ coap_receive(void)
|
|||
REST_MAX_CHUNK_SIZE));
|
||||
} /* blockwise transfer handling */
|
||||
} /* no errors/hooks */
|
||||
} /* successful service callback */
|
||||
|
||||
/* serialize response */
|
||||
/* successful service callback */
|
||||
/* serialize response */
|
||||
}
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
if((transaction->packet_len = coap_serialize_message(response,
|
||||
transaction->
|
||||
|
@ -208,18 +215,16 @@ coap_receive(void)
|
|||
erbium_status_code = PACKET_SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
erbium_status_code = NOT_IMPLEMENTED_5_01;
|
||||
coap_error_message = "NoServiceCallbck"; /* no 'a' to fit into 16 bytes */
|
||||
} /* if(service callback) */
|
||||
|
||||
} else {
|
||||
erbium_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_error_message = "NoFreeTraBuffer";
|
||||
} /* if(transaction buffer) */
|
||||
|
||||
/* handle responses */
|
||||
/* handle responses */
|
||||
} else {
|
||||
|
||||
if(message->type == COAP_TYPE_CON && message->code == 0) {
|
||||
|
@ -249,14 +254,14 @@ coap_receive(void)
|
|||
}
|
||||
/* if(ACKed transaction) */
|
||||
transaction = NULL;
|
||||
|
||||
} /* request or response */
|
||||
} /* parsed correctly */
|
||||
|
||||
/* if(parsed correctly) */
|
||||
if(erbium_status_code == NO_ERROR) {
|
||||
if(transaction)
|
||||
if(transaction) {
|
||||
coap_send_transaction(transaction);
|
||||
}
|
||||
} else if(erbium_status_code == MANUAL_RESPONSE) {
|
||||
PRINTF("Clearing transaction for manual response");
|
||||
coap_clear_transaction(transaction);
|
||||
|
@ -272,9 +277,8 @@ coap_receive(void)
|
|||
} else if(erbium_status_code >= 192) {
|
||||
/* set to sendable error code */
|
||||
erbium_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
/* reuse input buffer for error message */
|
||||
}
|
||||
|
||||
/* reuse input buffer for error message */
|
||||
coap_init_message(message, reply_type, erbium_status_code,
|
||||
message->mid);
|
||||
coap_set_payload(message, coap_error_message,
|
||||
|
@ -304,8 +308,8 @@ coap_set_service_callback(service_callback_t callback)
|
|||
rest_resource_flags_t
|
||||
coap_get_rest_method(void *packet)
|
||||
{
|
||||
return (rest_resource_flags_t) (1 <<
|
||||
(((coap_packet_t *) packet)->code - 1));
|
||||
return (rest_resource_flags_t)(1 <<
|
||||
(((coap_packet_t *)packet)->code - 1));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Server Part -------------------------------------------------------------*/
|
||||
|
@ -346,15 +350,15 @@ coap_blocking_request_callback(void *callback_data, void *response)
|
|||
{
|
||||
struct request_state_t *state = (struct request_state_t *)callback_data;
|
||||
|
||||
state->response = (coap_packet_t *) response;
|
||||
state->response = (coap_packet_t *)response;
|
||||
process_poll(state->process);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PT_THREAD(coap_blocking_request
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t * remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t * request,
|
||||
blocking_response_handler request_callback))
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t *remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t *request,
|
||||
blocking_response_handler request_callback))
|
||||
{
|
||||
PT_BEGIN(&state->pt);
|
||||
|
||||
|
@ -381,7 +385,6 @@ PT_THREAD(coap_blocking_request
|
|||
coap_set_header_block2(request, state->block_num, 0,
|
||||
REST_MAX_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
state->transaction->packet_len = coap_serialize_message(request,
|
||||
state->
|
||||
transaction->
|
||||
|
@ -454,49 +457,51 @@ const struct rest_implementation coap_rest_implementation = {
|
|||
coap_observe_handler,
|
||||
|
||||
{
|
||||
CONTENT_2_05,
|
||||
CREATED_2_01,
|
||||
CHANGED_2_04,
|
||||
DELETED_2_02,
|
||||
VALID_2_03,
|
||||
BAD_REQUEST_4_00,
|
||||
UNAUTHORIZED_4_01,
|
||||
BAD_OPTION_4_02,
|
||||
FORBIDDEN_4_03,
|
||||
NOT_FOUND_4_04,
|
||||
METHOD_NOT_ALLOWED_4_05,
|
||||
NOT_ACCEPTABLE_4_06,
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13,
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15,
|
||||
INTERNAL_SERVER_ERROR_5_00,
|
||||
NOT_IMPLEMENTED_5_01,
|
||||
BAD_GATEWAY_5_02,
|
||||
SERVICE_UNAVAILABLE_5_03,
|
||||
GATEWAY_TIMEOUT_5_04,
|
||||
PROXYING_NOT_SUPPORTED_5_05},
|
||||
CONTENT_2_05,
|
||||
CREATED_2_01,
|
||||
CHANGED_2_04,
|
||||
DELETED_2_02,
|
||||
VALID_2_03,
|
||||
BAD_REQUEST_4_00,
|
||||
UNAUTHORIZED_4_01,
|
||||
BAD_OPTION_4_02,
|
||||
FORBIDDEN_4_03,
|
||||
NOT_FOUND_4_04,
|
||||
METHOD_NOT_ALLOWED_4_05,
|
||||
NOT_ACCEPTABLE_4_06,
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13,
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15,
|
||||
INTERNAL_SERVER_ERROR_5_00,
|
||||
NOT_IMPLEMENTED_5_01,
|
||||
BAD_GATEWAY_5_02,
|
||||
SERVICE_UNAVAILABLE_5_03,
|
||||
GATEWAY_TIMEOUT_5_04,
|
||||
PROXYING_NOT_SUPPORTED_5_05
|
||||
},
|
||||
|
||||
{
|
||||
TEXT_PLAIN,
|
||||
TEXT_XML,
|
||||
TEXT_CSV,
|
||||
TEXT_HTML,
|
||||
IMAGE_GIF,
|
||||
IMAGE_JPEG,
|
||||
IMAGE_PNG,
|
||||
IMAGE_TIFF,
|
||||
AUDIO_RAW,
|
||||
VIDEO_RAW,
|
||||
APPLICATION_LINK_FORMAT,
|
||||
APPLICATION_XML,
|
||||
APPLICATION_OCTET_STREAM,
|
||||
APPLICATION_RDF_XML,
|
||||
APPLICATION_SOAP_XML,
|
||||
APPLICATION_ATOM_XML,
|
||||
APPLICATION_XMPP_XML,
|
||||
APPLICATION_EXI,
|
||||
APPLICATION_FASTINFOSET,
|
||||
APPLICATION_SOAP_FASTINFOSET,
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_X_OBIX_BINARY}
|
||||
TEXT_PLAIN,
|
||||
TEXT_XML,
|
||||
TEXT_CSV,
|
||||
TEXT_HTML,
|
||||
IMAGE_GIF,
|
||||
IMAGE_JPEG,
|
||||
IMAGE_PNG,
|
||||
IMAGE_TIFF,
|
||||
AUDIO_RAW,
|
||||
VIDEO_RAW,
|
||||
APPLICATION_LINK_FORMAT,
|
||||
APPLICATION_XML,
|
||||
APPLICATION_OCTET_STREAM,
|
||||
APPLICATION_RDF_XML,
|
||||
APPLICATION_SOAP_XML,
|
||||
APPLICATION_ATOM_XML,
|
||||
APPLICATION_XMPP_XML,
|
||||
APPLICATION_EXI,
|
||||
APPLICATION_FASTINFOSET,
|
||||
APPLICATION_SOAP_FASTINFOSET,
|
||||
APPLICATION_JSON,
|
||||
APPLICATION_X_OBIX_BINARY
|
||||
}
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
26
apps/er-coap/er-coap-engine.h
Executable file → Normal file
26
apps/er-coap/er-coap-engine.h
Executable file → Normal file
|
@ -63,23 +63,23 @@ struct request_state_t {
|
|||
uint32_t block_num;
|
||||
};
|
||||
|
||||
typedef void (*blocking_response_handler) (void *response);
|
||||
typedef void (*blocking_response_handler)(void *response);
|
||||
|
||||
PT_THREAD(coap_blocking_request
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t * remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t * request,
|
||||
blocking_response_handler request_callback));
|
||||
(struct request_state_t *state, process_event_t ev,
|
||||
uip_ipaddr_t *remote_ipaddr, uint16_t remote_port,
|
||||
coap_packet_t *request,
|
||||
blocking_response_handler request_callback));
|
||||
|
||||
#define COAP_BLOCKING_REQUEST(server_addr, server_port, request, chunk_handler) \
|
||||
{ \
|
||||
static struct request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_addr, server_port, \
|
||||
request, chunk_handler) \
|
||||
); \
|
||||
}
|
||||
{ \
|
||||
static struct request_state_t request_state; \
|
||||
PT_SPAWN(process_pt, &request_state.pt, \
|
||||
coap_blocking_request(&request_state, ev, \
|
||||
server_addr, server_port, \
|
||||
request, chunk_handler) \
|
||||
); \
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* ER_COAP_ENGINE_H_ */
|
||||
|
|
53
apps/er-coap/er-coap-observe.c
Executable file → Normal file
53
apps/er-coap/er-coap-observe.c
Executable file → Normal file
|
@ -40,8 +40,17 @@
|
|||
#include <string.h>
|
||||
#include "er-coap-observe.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS);
|
||||
|
@ -50,7 +59,7 @@ LIST(observers_list);
|
|||
/*- Internal API ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_observer_t *
|
||||
coap_add_observer(uip_ipaddr_t * addr, uint16_t port, const uint8_t * token,
|
||||
coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
|
||||
size_t token_len, const char *uri)
|
||||
{
|
||||
/* Remove existing observe relationship, if any. */
|
||||
|
@ -77,7 +86,7 @@ coap_add_observer(uip_ipaddr_t * addr, uint16_t port, const uint8_t * token,
|
|||
/*- Removal -----------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_remove_observer(coap_observer_t * o)
|
||||
coap_remove_observer(coap_observer_t *o)
|
||||
{
|
||||
PRINTF("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||
o->token[1]);
|
||||
|
@ -87,12 +96,12 @@ coap_remove_observer(coap_observer_t * o)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_client(uip_ipaddr_t * addr, uint16_t port)
|
||||
coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
for(obs = (coap_observer_t *) list_head(observers_list); obs;
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check client ");
|
||||
PRINT6ADDR(addr);
|
||||
|
@ -106,13 +115,13 @@ coap_remove_observer_by_client(uip_ipaddr_t * addr, uint16_t port)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_token(uip_ipaddr_t * addr, uint16_t port,
|
||||
uint8_t * token, size_t token_len)
|
||||
coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
uint8_t *token, size_t token_len)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
for(obs = (coap_observer_t *) list_head(observers_list); obs;
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port
|
||||
|
@ -126,13 +135,13 @@ coap_remove_observer_by_token(uip_ipaddr_t * addr, uint16_t port,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_uri(uip_ipaddr_t * addr, uint16_t port,
|
||||
coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
||||
const char *uri)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
for(obs = (coap_observer_t *) list_head(observers_list); obs;
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check URL %p\n", uri);
|
||||
if((addr == NULL
|
||||
|
@ -146,12 +155,12 @@ coap_remove_observer_by_uri(uip_ipaddr_t * addr, uint16_t port,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_remove_observer_by_mid(uip_ipaddr_t * addr, uint16_t port, uint16_t mid)
|
||||
coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t *obs = NULL;
|
||||
|
||||
for(obs = (coap_observer_t *) list_head(observers_list); obs;
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
PRINTF("Remove check MID %u\n", mid);
|
||||
if(uip_ipaddr_cmp(&obs->addr, addr) && obs->port == port
|
||||
|
@ -166,7 +175,7 @@ coap_remove_observer_by_mid(uip_ipaddr_t * addr, uint16_t port, uint16_t mid)
|
|||
/*- Notification ------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_notify_observers(resource_t * resource)
|
||||
coap_notify_observers(resource_t *resource)
|
||||
{
|
||||
/* build notification */
|
||||
coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */
|
||||
|
@ -176,7 +185,7 @@ coap_notify_observers(resource_t * resource)
|
|||
PRINTF("Observe: Notification from %s\n", resource->url);
|
||||
|
||||
/* iterate over observers */
|
||||
for(obs = (coap_observer_t *) list_head(observers_list); obs;
|
||||
for(obs = (coap_observer_t *)list_head(observers_list); obs;
|
||||
obs = obs->next) {
|
||||
if(obs->url == resource->url) { /* using RESOURCE url pointer as handle */
|
||||
coap_transaction_t *transaction = NULL;
|
||||
|
@ -184,7 +193,7 @@ coap_notify_observers(resource_t * resource)
|
|||
/*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */
|
||||
|
||||
if((transaction =
|
||||
coap_new_transaction(coap_get_mid(), &obs->addr, obs->port))) {
|
||||
coap_new_transaction(coap_get_mid(), &obs->addr, obs->port))) {
|
||||
PRINTF(" Observer ");
|
||||
PRINT6ADDR(&obs->addr);
|
||||
PRINTF(":%u\n", obs->port);
|
||||
|
@ -199,8 +208,9 @@ coap_notify_observers(resource_t * resource)
|
|||
transaction->packet + COAP_MAX_HEADER_SIZE,
|
||||
REST_MAX_CHUNK_SIZE, NULL);
|
||||
|
||||
if(notification->code < BAD_REQUEST_4_00)
|
||||
if(notification->code < BAD_REQUEST_4_00) {
|
||||
coap_set_header_observe(notification, (obs->obs_counter)++);
|
||||
}
|
||||
coap_set_token(notification, obs->token, obs->token_len);
|
||||
|
||||
/* TODO use resource-specific COAP_OBSERVE_REFRESH_INTERVAL for CON to check client interest */
|
||||
|
@ -215,10 +225,10 @@ coap_notify_observers(resource_t * resource)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_observe_handler(resource_t * resource, void *request, void *response)
|
||||
coap_observe_handler(resource_t *resource, void *request, void *response)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_res = (coap_packet_t *) response;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_packet_t *const coap_res = (coap_packet_t *)response;
|
||||
|
||||
static char content[16];
|
||||
|
||||
|
@ -248,7 +258,8 @@ coap_observe_handler(resource_t * resource, void *request, void *response)
|
|||
coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport, coap_req->token,
|
||||
coap_req->token_len);
|
||||
} /* if(observe) */
|
||||
/* if(observe) */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
20
apps/er-coap/er-coap-observe.h
Executable file → Normal file
20
apps/er-coap/er-coap-observe.h
Executable file → Normal file
|
@ -69,22 +69,22 @@ typedef struct coap_observer {
|
|||
|
||||
list_t coap_get_observers(void);
|
||||
|
||||
coap_observer_t *coap_add_observer(uip_ipaddr_t * addr, uint16_t port,
|
||||
const uint8_t * token, size_t token_len,
|
||||
coap_observer_t *coap_add_observer(uip_ipaddr_t *addr, uint16_t port,
|
||||
const uint8_t *token, size_t token_len,
|
||||
const char *url);
|
||||
|
||||
void coap_remove_observer(coap_observer_t * o);
|
||||
int coap_remove_observer_by_client(uip_ipaddr_t * addr, uint16_t port);
|
||||
int coap_remove_observer_by_token(uip_ipaddr_t * addr, uint16_t port,
|
||||
uint8_t * token, size_t token_len);
|
||||
int coap_remove_observer_by_uri(uip_ipaddr_t * addr, uint16_t port,
|
||||
void coap_remove_observer(coap_observer_t *o);
|
||||
int coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port);
|
||||
int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
uint8_t *token, size_t token_len);
|
||||
int coap_remove_observer_by_uri(uip_ipaddr_t *addr, uint16_t port,
|
||||
const char *uri);
|
||||
int coap_remove_observer_by_mid(uip_ipaddr_t * addr, uint16_t port,
|
||||
int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port,
|
||||
uint16_t mid);
|
||||
|
||||
void coap_notify_observers(resource_t * resource);
|
||||
void coap_notify_observers(resource_t *resource);
|
||||
|
||||
void coap_observe_handler(resource_t * resource, void *request,
|
||||
void coap_observe_handler(resource_t *resource, void *request,
|
||||
void *response);
|
||||
|
||||
#endif /* COAP_OBSERVE_H_ */
|
||||
|
|
36
apps/er-coap/er-coap-res-well-known-core.c
Executable file → Normal file
36
apps/er-coap/er-coap-res-well-known-core.c
Executable file → Normal file
|
@ -39,15 +39,24 @@
|
|||
#include <string.h>
|
||||
#include "er-coap-engine.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Resource Handlers -------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
well_known_core_get_handler(void *request, void *response, uint8_t * buffer,
|
||||
uint16_t preferred_size, int32_t * offset)
|
||||
well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t strpos = 0; /* position in overall string (which is larger than the buffer) */
|
||||
size_t bufpos = 0; /* position within buffer (bytes written) */
|
||||
|
@ -82,22 +91,24 @@ well_known_core_get_handler(void *request, void *response, uint8_t * buffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
for(resource = (resource_t *) list_head(rest_get_resources()); resource;
|
||||
for(resource = (resource_t *)list_head(rest_get_resources()); resource;
|
||||
resource = resource->next) {
|
||||
#if COAP_LINK_FORMAT_FILTERING
|
||||
/* Filtering */
|
||||
if(len) {
|
||||
if(strcmp(filter, "href") == 0) {
|
||||
attrib = strstr(resource->url, value);
|
||||
if(attrib == NULL || (value[-1] == '/' && attrib != resource->url))
|
||||
if(attrib == NULL || (value[-1] == '/' && attrib != resource->url)) {
|
||||
continue;
|
||||
}
|
||||
end = attrib + strlen(attrib);
|
||||
} else {
|
||||
attrib = strstr(resource->attributes, filter);
|
||||
if(attrib == NULL
|
||||
|| (attrib[strlen(filter)] != '='
|
||||
&& attrib[strlen(filter)] != '"'))
|
||||
&& attrib[strlen(filter)] != '"')) {
|
||||
continue;
|
||||
}
|
||||
attrib += strlen(filter) + 2;
|
||||
end = strchr(attrib, '"');
|
||||
}
|
||||
|
@ -119,8 +130,9 @@ well_known_core_get_handler(void *request, void *response, uint8_t * buffer,
|
|||
}
|
||||
PRINTF("Filter: res has prefix %s\n", found);
|
||||
if(lastchar != '*'
|
||||
&& (found[len] != '"' && found[len] != ' ' && found[len] != '\0'))
|
||||
&& (found[len] != '"' && found[len] != ' ' && found[len] != '\0')) {
|
||||
continue;
|
||||
}
|
||||
PRINTF("Filter: res has match\n");
|
||||
}
|
||||
#endif
|
||||
|
@ -151,8 +163,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t * buffer,
|
|||
preferred_size - bufpos + 1,
|
||||
"%s",
|
||||
resource->url +
|
||||
((*offset - (int32_t) strpos >
|
||||
0) ? (*offset - (int32_t) strpos) : 0));
|
||||
((*offset - (int32_t)strpos >
|
||||
0) ? (*offset - (int32_t)strpos) : 0));
|
||||
/* native requires these casts */
|
||||
if(bufpos >= preferred_size) {
|
||||
PRINTF("res: BREAK at %s (%p)\n", resource->url, resource);
|
||||
|
@ -177,8 +189,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t * buffer,
|
|||
bufpos += snprintf((char *)buffer + bufpos,
|
||||
preferred_size - bufpos + 1,
|
||||
resource->attributes
|
||||
+ (*offset - (int32_t) strpos > 0 ?
|
||||
*offset - (int32_t) strpos : 0));
|
||||
+ (*offset - (int32_t)strpos > 0 ?
|
||||
*offset - (int32_t)strpos : 0));
|
||||
if(bufpos > preferred_size) {
|
||||
PRINTF("res: BREAK at %s (%p)\n", resource->url, resource);
|
||||
break;
|
||||
|
|
22
apps/er-coap/er-coap-separate.c
Executable file → Normal file
22
apps/er-coap/er-coap-separate.c
Executable file → Normal file
|
@ -41,8 +41,17 @@
|
|||
#include "er-coap-separate.h"
|
||||
#include "er-coap-transactions.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Separate Response API ---------------------------------------------------*/
|
||||
|
@ -58,7 +67,7 @@
|
|||
void
|
||||
coap_separate_reject()
|
||||
{
|
||||
// TODO: Accept string pointer for custom error message
|
||||
/* TODO: Accept string pointer for custom error message */
|
||||
erbium_status_code = SERVICE_UNAVAILABLE_5_03;
|
||||
coap_error_message = "AlreadyInUse";
|
||||
}
|
||||
|
@ -75,9 +84,9 @@ coap_separate_reject()
|
|||
* then retry later.
|
||||
*/
|
||||
void
|
||||
coap_separate_accept(void *request, coap_separate_t * separate_store)
|
||||
coap_separate_accept(void *request, coap_separate_t *separate_store)
|
||||
{
|
||||
coap_packet_t *const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_req->mid);
|
||||
|
||||
PRINTF("Separate ACCEPT: /%.*s MID %u\n", coap_req->uri_path_len,
|
||||
|
@ -112,7 +121,6 @@ coap_separate_accept(void *request, coap_separate_t * separate_store)
|
|||
|
||||
/* signal the engine to skip automatic response and clear transaction by engine */
|
||||
erbium_status_code = MANUAL_RESPONSE;
|
||||
|
||||
} else {
|
||||
PRINTF("ERROR: Response transaction for separate request not found!\n");
|
||||
erbium_status_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
|
@ -120,7 +128,7 @@ coap_separate_accept(void *request, coap_separate_t * separate_store)
|
|||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_separate_resume(void *response, coap_separate_t * separate_store,
|
||||
coap_separate_resume(void *response, coap_separate_t *separate_store,
|
||||
uint8_t code)
|
||||
{
|
||||
coap_init_message(response, separate_store->type, code,
|
||||
|
|
7
apps/er-coap/er-coap-separate.h
Executable file → Normal file
7
apps/er-coap/er-coap-separate.h
Executable file → Normal file
|
@ -55,14 +55,13 @@ typedef struct coap_separate {
|
|||
/* separate + blockwise is untested! */
|
||||
uint32_t block2_num;
|
||||
uint16_t block2_size;
|
||||
|
||||
} coap_separate_t;
|
||||
|
||||
int coap_separate_handler(resource_t * resource, void *request,
|
||||
int coap_separate_handler(resource_t *resource, void *request,
|
||||
void *response);
|
||||
void coap_separate_reject();
|
||||
void coap_separate_accept(void *request, coap_separate_t * separate_store);
|
||||
void coap_separate_resume(void *response, coap_separate_t * separate_store,
|
||||
void coap_separate_accept(void *request, coap_separate_t *separate_store);
|
||||
void coap_separate_resume(void *response, coap_separate_t *separate_store,
|
||||
uint8_t code);
|
||||
|
||||
#endif /* COAP_SEPARATE_H_ */
|
||||
|
|
25
apps/er-coap/er-coap-transactions.c
Executable file → Normal file
25
apps/er-coap/er-coap-transactions.c
Executable file → Normal file
|
@ -41,8 +41,17 @@
|
|||
#include "er-coap-transactions.h"
|
||||
#include "er-coap-observe.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS);
|
||||
|
@ -58,9 +67,8 @@ coap_register_as_transaction_handler()
|
|||
{
|
||||
transaction_handler_process = PROCESS_CURRENT();
|
||||
}
|
||||
|
||||
coap_transaction_t *
|
||||
coap_new_transaction(uint16_t mid, uip_ipaddr_t * addr, uint16_t port)
|
||||
coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port)
|
||||
{
|
||||
coap_transaction_t *t = memb_alloc(&transactions_memb);
|
||||
|
||||
|
@ -79,7 +87,7 @@ coap_new_transaction(uint16_t mid, uip_ipaddr_t * addr, uint16_t port)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_send_transaction(coap_transaction_t * t)
|
||||
coap_send_transaction(coap_transaction_t *t)
|
||||
{
|
||||
PRINTF("Sending transaction %u\n", t->mid);
|
||||
|
||||
|
@ -137,7 +145,7 @@ coap_send_transaction(coap_transaction_t * t)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_clear_transaction(coap_transaction_t * t)
|
||||
coap_clear_transaction(coap_transaction_t *t)
|
||||
{
|
||||
if(t) {
|
||||
PRINTF("Freeing transaction %u: %p\n", t->mid, t);
|
||||
|
@ -147,13 +155,12 @@ coap_clear_transaction(coap_transaction_t * t)
|
|||
memb_free(&transactions_memb, t);
|
||||
}
|
||||
}
|
||||
|
||||
coap_transaction_t *
|
||||
coap_get_transaction_by_mid(uint16_t mid)
|
||||
{
|
||||
coap_transaction_t *t = NULL;
|
||||
|
||||
for(t = (coap_transaction_t *) list_head(transactions_list); t; t = t->next) {
|
||||
for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) {
|
||||
if(t->mid == mid) {
|
||||
PRINTF("Found transaction for MID %u: %p\n", t->mid, t);
|
||||
return t;
|
||||
|
@ -167,7 +174,7 @@ coap_check_transactions()
|
|||
{
|
||||
coap_transaction_t *t = NULL;
|
||||
|
||||
for(t = (coap_transaction_t *) list_head(transactions_list); t; t = t->next) {
|
||||
for(t = (coap_transaction_t *)list_head(transactions_list); t; t = t->next) {
|
||||
if(etimer_expired(&t->retrans_timer)) {
|
||||
++(t->retrans_counter);
|
||||
PRINTF("Retransmitting %u (%u)\n", t->mid, t->retrans_counter);
|
||||
|
|
6
apps/er-coap/er-coap-transactions.h
Executable file → Normal file
6
apps/er-coap/er-coap-transactions.h
Executable file → Normal file
|
@ -69,10 +69,10 @@ typedef struct coap_transaction {
|
|||
|
||||
void coap_register_as_transaction_handler();
|
||||
|
||||
coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t * addr,
|
||||
coap_transaction_t *coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr,
|
||||
uint16_t port);
|
||||
void coap_send_transaction(coap_transaction_t * t);
|
||||
void coap_clear_transaction(coap_transaction_t * t);
|
||||
void coap_send_transaction(coap_transaction_t *t);
|
||||
void coap_clear_transaction(coap_transaction_t *t);
|
||||
coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid);
|
||||
|
||||
void coap_check_transactions();
|
||||
|
|
342
apps/er-coap/er-coap.c
Executable file → Normal file
342
apps/er-coap/er-coap.c
Executable file → Normal file
|
@ -40,11 +40,21 @@
|
|||
#include <stdio.h>
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
|
||||
#include "er-coap.h"
|
||||
#include "er-coap-transactions.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*- Variables ---------------------------------------------------------------*/
|
||||
|
@ -71,7 +81,7 @@ coap_log_2(uint16_t value)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint32_t
|
||||
coap_parse_int_option(uint8_t * bytes, size_t length)
|
||||
coap_parse_int_option(uint8_t *bytes, size_t length)
|
||||
{
|
||||
uint32_t var = 0;
|
||||
int i = 0;
|
||||
|
@ -96,7 +106,7 @@ coap_option_nibble(unsigned int value)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
coap_set_option_header(unsigned int delta, size_t length, uint8_t * buffer)
|
||||
coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
|
||||
{
|
||||
size_t written = 0;
|
||||
|
||||
|
@ -121,39 +131,45 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t * buffer)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
coap_serialize_int_option(unsigned int number, unsigned int current_number,
|
||||
uint8_t * buffer, uint32_t value)
|
||||
uint8_t *buffer, uint32_t value)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
if(0xFF000000 & value)
|
||||
if(0xFF000000 & value) {
|
||||
++i;
|
||||
if(0xFFFF0000 & value)
|
||||
}
|
||||
if(0xFFFF0000 & value) {
|
||||
++i;
|
||||
if(0xFFFFFF00 & value)
|
||||
}
|
||||
if(0xFFFFFF00 & value) {
|
||||
++i;
|
||||
if(0xFFFFFFFF & value)
|
||||
}
|
||||
if(0xFFFFFFFF & value) {
|
||||
++i;
|
||||
|
||||
}
|
||||
PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number,
|
||||
i);
|
||||
|
||||
i = coap_set_option_header(number - current_number, i, buffer);
|
||||
|
||||
if(0xFF000000 & value)
|
||||
buffer[i++] = (uint8_t) (value >> 24);
|
||||
if(0xFFFF0000 & value)
|
||||
buffer[i++] = (uint8_t) (value >> 16);
|
||||
if(0xFFFFFF00 & value)
|
||||
buffer[i++] = (uint8_t) (value >> 8);
|
||||
if(0xFFFFFFFF & value)
|
||||
buffer[i++] = (uint8_t) (value);
|
||||
|
||||
if(0xFF000000 & value) {
|
||||
buffer[i++] = (uint8_t)(value >> 24);
|
||||
}
|
||||
if(0xFFFF0000 & value) {
|
||||
buffer[i++] = (uint8_t)(value >> 16);
|
||||
}
|
||||
if(0xFFFFFF00 & value) {
|
||||
buffer[i++] = (uint8_t)(value >> 8);
|
||||
}
|
||||
if(0xFFFFFFFF & value) {
|
||||
buffer[i++] = (uint8_t)(value);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static size_t
|
||||
coap_serialize_array_option(unsigned int number, unsigned int current_number,
|
||||
uint8_t * buffer, uint8_t * array, size_t length,
|
||||
uint8_t *buffer, uint8_t *array, size_t length,
|
||||
char split_char)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
@ -199,7 +215,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
coap_merge_multi_option(char **dst, size_t * dst_len, uint8_t * option,
|
||||
coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option,
|
||||
size_t option_len, char separator)
|
||||
{
|
||||
/* merge multiple options */
|
||||
|
@ -246,13 +262,11 @@ coap_get_variable(const char *buffer, size_t length, const char *name,
|
|||
if(value_end == NULL) {
|
||||
value_end = end;
|
||||
}
|
||||
|
||||
*output = start;
|
||||
|
||||
return (value_end - start);
|
||||
return value_end - start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -280,7 +294,7 @@ void
|
|||
coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
|
||||
uint16_t mid)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
/* Important thing */
|
||||
memset(coap_pkt, 0, sizeof(coap_packet_t));
|
||||
|
@ -291,9 +305,9 @@ coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
size_t
|
||||
coap_serialize_message(void *packet, uint8_t * buffer)
|
||||
coap_serialize_message(void *packet, uint8_t *buffer)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
uint8_t *option;
|
||||
unsigned int current_number = 0;
|
||||
|
||||
|
@ -312,8 +326,8 @@ coap_serialize_message(void *packet, uint8_t * buffer)
|
|||
coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK
|
||||
& (coap_pkt->token_len) << COAP_HEADER_TOKEN_LEN_POSITION;
|
||||
coap_pkt->buffer[1] = coap_pkt->code;
|
||||
coap_pkt->buffer[2] = (uint8_t) ((coap_pkt->mid) >> 8);
|
||||
coap_pkt->buffer[3] = (uint8_t) (coap_pkt->mid);
|
||||
coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
|
||||
coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
|
||||
|
||||
/* set Token */
|
||||
PRINTF("Token (len %u)", coap_pkt->token_len);
|
||||
|
@ -339,7 +353,7 @@ coap_serialize_message(void *packet, uint8_t * buffer)
|
|||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
|
||||
content_format -
|
||||
coap_pkt->
|
||||
content_format /* hack to get a zero field */ ,
|
||||
content_format /* hack to get a zero field */,
|
||||
"If-None-Match");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
|
||||
|
@ -392,13 +406,13 @@ coap_serialize_message(void *packet, uint8_t * buffer)
|
|||
coap_pkt->buffer[3],
|
||||
coap_pkt->buffer[4],
|
||||
coap_pkt->buffer[5], coap_pkt->buffer[6], coap_pkt->buffer[7]
|
||||
);
|
||||
);
|
||||
|
||||
return (option - buffer) + coap_pkt->payload_len; /* packet length */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_send_message(uip_ipaddr_t * addr, uint16_t port, uint8_t * data,
|
||||
coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
/* configure connection to reply to client */
|
||||
|
@ -414,9 +428,9 @@ coap_send_message(uip_ipaddr_t * addr, uint16_t port, uint8_t * data,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
coap_status_t
|
||||
coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
||||
coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
/* initialize packet */
|
||||
memset(coap_pkt, 0, sizeof(coap_packet_t));
|
||||
|
@ -448,7 +462,7 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
|
||||
coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
|
||||
coap_pkt->token[5], coap_pkt->token[6], coap_pkt->token[7]
|
||||
); /*FIXME always prints 8 bytes */
|
||||
); /*FIXME always prints 8 bytes */
|
||||
|
||||
/* parse options */
|
||||
memset(coap_pkt->options, 0, sizeof(coap_pkt->options));
|
||||
|
@ -467,9 +481,8 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
/* also for receiving, the Erbium upper bound is REST_MAX_CHUNK_SIZE */
|
||||
if(coap_pkt->payload_len > REST_MAX_CHUNK_SIZE) {
|
||||
coap_pkt->payload_len = REST_MAX_CHUNK_SIZE;
|
||||
/* null-terminate payload */
|
||||
}
|
||||
|
||||
/* null-terminate payload */
|
||||
coap_pkt->payload[coap_pkt->payload_len] = '\0';
|
||||
|
||||
break;
|
||||
|
@ -502,7 +515,7 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
|
||||
SET_OPTION(coap_pkt, option_number);
|
||||
|
||||
switch (option_number) {
|
||||
switch(option_number) {
|
||||
case COAP_OPTION_CONTENT_FORMAT:
|
||||
coap_pkt->content_format = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
|
@ -520,7 +533,7 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
|
||||
coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
|
||||
coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
|
||||
); /*FIXME always prints 8 bytes */
|
||||
); /*FIXME always prints 8 bytes */
|
||||
break;
|
||||
case COAP_OPTION_ACCEPT:
|
||||
coap_pkt->accept = coap_parse_int_option(current_option, option_length);
|
||||
|
@ -536,7 +549,7 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
coap_pkt->if_match[3], coap_pkt->if_match[4],
|
||||
coap_pkt->if_match[5], coap_pkt->if_match[6],
|
||||
coap_pkt->if_match[7]
|
||||
); /* FIXME always prints 8 bytes */
|
||||
); /* FIXME always prints 8 bytes */
|
||||
break;
|
||||
case COAP_OPTION_IF_NONE_MATCH:
|
||||
coap_pkt->if_none_match = 1;
|
||||
|
@ -663,7 +676,7 @@ coap_parse_message(void *packet, uint8_t * data, uint16_t data_len)
|
|||
int
|
||||
coap_get_query_variable(void *packet, const char *name, const char **output)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
|
||||
return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
|
||||
|
@ -671,11 +684,10 @@ coap_get_query_variable(void *packet, const char *name, const char **output)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
coap_get_post_variable(void *packet, const char *name, const char **output)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(coap_pkt->payload_len) {
|
||||
return coap_get_variable((const char *)coap_pkt->payload,
|
||||
|
@ -688,7 +700,7 @@ int
|
|||
coap_set_status_code(void *packet, unsigned int code)
|
||||
{
|
||||
if(code <= 0xFF) {
|
||||
((coap_packet_t *) packet)->code = (uint8_t) code;
|
||||
((coap_packet_t *)packet)->code = (uint8_t)code;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -696,9 +708,9 @@ coap_set_status_code(void *packet, unsigned int code)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_set_token(void *packet, const uint8_t * token, size_t token_len)
|
||||
coap_set_token(void *packet, const uint8_t *token, size_t token_len)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
|
||||
memcpy(coap_pkt->token, token, coap_pkt->token_len);
|
||||
|
@ -711,21 +723,20 @@ coap_set_token(void *packet, const uint8_t * token, size_t token_len)
|
|||
int
|
||||
coap_get_header_content_format(void *packet, unsigned int *format)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*format = coap_pkt->content_format;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_content_format(void *packet, unsigned int format)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->content_format = (coap_content_format_t) format;
|
||||
coap_pkt->content_format = (coap_content_format_t)format;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
|
||||
return 1;
|
||||
}
|
||||
|
@ -733,42 +744,39 @@ coap_set_header_content_format(void *packet, unsigned int format)
|
|||
int
|
||||
coap_get_header_accept(void *packet, unsigned int *accept)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*accept = coap_pkt->accept;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_accept(void *packet, unsigned int accept)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->accept = (coap_content_format_t) accept;
|
||||
coap_pkt->accept = (coap_content_format_t)accept;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_max_age(void *packet, uint32_t * age)
|
||||
coap_get_header_max_age(void *packet, uint32_t *age)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
|
||||
*age = COAP_DEFAULT_MAX_AGE;
|
||||
} else {
|
||||
*age = coap_pkt->max_age;
|
||||
}
|
||||
return 1;
|
||||
} return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_max_age(void *packet, uint32_t age)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->max_age = age;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
|
||||
|
@ -776,21 +784,20 @@ coap_set_header_max_age(void *packet, uint32_t age)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_etag(void *packet, const uint8_t ** etag)
|
||||
coap_get_header_etag(void *packet, const uint8_t **etag)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*etag = coap_pkt->etag;
|
||||
return coap_pkt->etag_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_etag(void *packet, const uint8_t * etag, size_t etag_len)
|
||||
coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
|
||||
memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
|
||||
|
@ -801,21 +808,20 @@ coap_set_header_etag(void *packet, const uint8_t * etag, size_t etag_len)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/*FIXME support multiple ETags */
|
||||
int
|
||||
coap_get_header_if_match(void *packet, const uint8_t ** etag)
|
||||
coap_get_header_if_match(void *packet, const uint8_t **etag)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*etag = coap_pkt->if_match;
|
||||
return coap_pkt->if_match_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_if_match(void *packet, const uint8_t * etag, size_t etag_len)
|
||||
coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
|
||||
memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
|
||||
|
@ -827,33 +833,31 @@ coap_set_header_if_match(void *packet, const uint8_t * etag, size_t etag_len)
|
|||
int
|
||||
coap_get_header_if_none_match(void *packet)
|
||||
{
|
||||
return IS_OPTION((coap_packet_t *) packet,
|
||||
return IS_OPTION((coap_packet_t *)packet,
|
||||
COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_if_none_match(void *packet)
|
||||
{
|
||||
SET_OPTION((coap_packet_t *) packet, COAP_OPTION_IF_NONE_MATCH);
|
||||
SET_OPTION((coap_packet_t *)packet, COAP_OPTION_IF_NONE_MATCH);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_proxy_uri(void *packet, const char **uri)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*uri = coap_pkt->proxy_uri;
|
||||
return coap_pkt->proxy_uri_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_proxy_uri(void *packet, const char *uri)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
/*TODO Provide alternative that sets Proxy-Scheme and Uri-* options and provide er-coap-conf define */
|
||||
|
||||
|
@ -867,19 +871,18 @@ coap_set_header_proxy_uri(void *packet, const char *uri)
|
|||
int
|
||||
coap_get_header_uri_host(void *packet, const char **host)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*host = coap_pkt->uri_host;
|
||||
return coap_pkt->uri_host_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_uri_host(void *packet, const char *host)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->uri_host = host;
|
||||
coap_pkt->uri_host_len = strlen(host);
|
||||
|
@ -891,19 +894,18 @@ coap_set_header_uri_host(void *packet, const char *host)
|
|||
int
|
||||
coap_get_header_uri_path(void *packet, const char **path)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*path = coap_pkt->uri_path;
|
||||
return coap_pkt->uri_path_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_uri_path(void *packet, const char *path)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
while(path[0] == '/')
|
||||
++path;
|
||||
|
@ -918,19 +920,18 @@ coap_set_header_uri_path(void *packet, const char *path)
|
|||
int
|
||||
coap_get_header_uri_query(void *packet, const char **query)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*query = coap_pkt->uri_query;
|
||||
return coap_pkt->uri_query_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_uri_query(void *packet, const char *query)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
while(query[0] == '?')
|
||||
++query;
|
||||
|
@ -945,19 +946,18 @@ coap_set_header_uri_query(void *packet, const char *query)
|
|||
int
|
||||
coap_get_header_location_path(void *packet, const char **path)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*path = coap_pkt->location_path;
|
||||
return coap_pkt->location_path_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_location_path(void *packet, const char *path)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
char *query;
|
||||
|
||||
|
@ -969,31 +969,29 @@ coap_set_header_location_path(void *packet, const char *path)
|
|||
coap_pkt->location_path_len = query - path;
|
||||
} else {
|
||||
coap_pkt->location_path_len = strlen(path);
|
||||
}
|
||||
} coap_pkt->location_path = path;
|
||||
|
||||
coap_pkt->location_path = path;
|
||||
|
||||
if(coap_pkt->location_path_len > 0)
|
||||
if(coap_pkt->location_path_len > 0) {
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
|
||||
}
|
||||
return coap_pkt->location_path_len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_location_query(void *packet, const char **query)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*query = coap_pkt->location_query;
|
||||
return coap_pkt->location_query_len;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_location_query(void *packet, const char *query)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
while(query[0] == '?')
|
||||
++query;
|
||||
|
@ -1006,21 +1004,20 @@ coap_set_header_location_query(void *packet, const char *query)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_observe(void *packet, uint32_t * observe)
|
||||
coap_get_header_observe(void *packet, uint32_t *observe)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*observe = coap_pkt->observe;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_observe(void *packet, uint32_t observe)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->observe = observe;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
|
||||
|
@ -1028,40 +1025,44 @@ coap_set_header_observe(void *packet, uint32_t observe)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_block2(void *packet, uint32_t * num, uint8_t * more,
|
||||
uint16_t * size, uint32_t * offset)
|
||||
coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint16_t *size, uint32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* pointers may be NULL to get only specific block parameters */
|
||||
if(num != NULL)
|
||||
if(num != NULL) {
|
||||
*num = coap_pkt->block2_num;
|
||||
if(more != NULL)
|
||||
}
|
||||
if(more != NULL) {
|
||||
*more = coap_pkt->block2_more;
|
||||
if(size != NULL)
|
||||
}
|
||||
if(size != NULL) {
|
||||
*size = coap_pkt->block2_size;
|
||||
if(offset != NULL)
|
||||
}
|
||||
if(offset != NULL) {
|
||||
*offset = coap_pkt->block2_offset;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
|
||||
uint16_t size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(size < 16)
|
||||
if(size < 16) {
|
||||
return 0;
|
||||
if(size > 2048)
|
||||
}
|
||||
if(size > 2048) {
|
||||
return 0;
|
||||
if(num > 0x0FFFFF)
|
||||
}
|
||||
if(num > 0x0FFFFF) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
coap_pkt->block2_num = num;
|
||||
coap_pkt->block2_more = more ? 1 : 0;
|
||||
coap_pkt->block2_size = size;
|
||||
|
@ -1071,40 +1072,44 @@ coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_block1(void *packet, uint32_t * num, uint8_t * more,
|
||||
uint16_t * size, uint32_t * offset)
|
||||
coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint16_t *size, uint32_t *offset)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* pointers may be NULL to get only specific block parameters */
|
||||
if(num != NULL)
|
||||
if(num != NULL) {
|
||||
*num = coap_pkt->block1_num;
|
||||
if(more != NULL)
|
||||
}
|
||||
if(more != NULL) {
|
||||
*more = coap_pkt->block1_more;
|
||||
if(size != NULL)
|
||||
}
|
||||
if(size != NULL) {
|
||||
*size = coap_pkt->block1_size;
|
||||
if(offset != NULL)
|
||||
}
|
||||
if(offset != NULL) {
|
||||
*offset = coap_pkt->block1_offset;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
|
||||
uint16_t size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(size < 16)
|
||||
if(size < 16) {
|
||||
return 0;
|
||||
if(size > 2048)
|
||||
}
|
||||
if(size > 2048) {
|
||||
return 0;
|
||||
if(num > 0x0FFFFF)
|
||||
}
|
||||
if(num > 0x0FFFFF) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
coap_pkt->block1_num = num;
|
||||
coap_pkt->block1_more = more;
|
||||
coap_pkt->block1_size = size;
|
||||
|
@ -1114,21 +1119,20 @@ coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_size2(void *packet, uint32_t * size)
|
||||
coap_get_header_size2(void *packet, uint32_t *size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*size = coap_pkt->size2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_size2(void *packet, uint32_t size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->size2 = size;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_SIZE2);
|
||||
|
@ -1136,21 +1140,20 @@ coap_set_header_size2(void *packet, uint32_t size)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_header_size1(void *packet, uint32_t * size)
|
||||
coap_get_header_size1(void *packet, uint32_t *size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1))
|
||||
if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
*size = coap_pkt->size1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_header_size1(void *packet, uint32_t size)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->size1 = size;
|
||||
SET_OPTION(coap_pkt, COAP_OPTION_SIZE1);
|
||||
|
@ -1158,9 +1161,9 @@ coap_set_header_size1(void *packet, uint32_t size)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_payload(void *packet, const uint8_t ** payload)
|
||||
coap_get_payload(void *packet, const uint8_t **payload)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
if(coap_pkt->payload) {
|
||||
*payload = coap_pkt->payload;
|
||||
|
@ -1170,13 +1173,12 @@ coap_get_payload(void *packet, const uint8_t ** payload)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
coap_set_payload(void *packet, const void *payload, size_t length)
|
||||
{
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) packet;
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||
|
||||
coap_pkt->payload = (uint8_t *) payload;
|
||||
coap_pkt->payload = (uint8_t *)payload;
|
||||
coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
|
||||
|
||||
return coap_pkt->payload_len;
|
||||
|
|
115
apps/er-coap/er-coap.h
Executable file → Normal file
115
apps/er-coap/er-coap.h
Executable file → Normal file
|
@ -40,7 +40,7 @@
|
|||
#define ER_COAP_H_
|
||||
|
||||
#include <stddef.h> /* for size_t */
|
||||
#include "net/uip.h"
|
||||
#include "contiki-net.h"
|
||||
#include "er-coap-constants.h"
|
||||
#include "er-coap-conf.h"
|
||||
|
||||
|
@ -69,7 +69,7 @@ enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
|||
#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
/* parsed message struct */
|
||||
|
@ -123,48 +123,47 @@ typedef struct {
|
|||
|
||||
uint16_t payload_len;
|
||||
uint8_t *payload;
|
||||
|
||||
} coap_packet_t;
|
||||
|
||||
/* option format serialization */
|
||||
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
|
||||
if (IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text" [%u]\n", coap_pkt->field); \
|
||||
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
|
||||
if (IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text" %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
|
||||
coap_pkt->field[0], \
|
||||
coap_pkt->field[1], \
|
||||
coap_pkt->field[2], \
|
||||
coap_pkt->field[3], \
|
||||
coap_pkt->field[4], \
|
||||
coap_pkt->field[5], \
|
||||
coap_pkt->field[6], \
|
||||
coap_pkt->field[7] \
|
||||
); /* FIXME always prints 8 bytes */ \
|
||||
option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
|
||||
if (IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text" [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
|
||||
option += coap_serialize_array_option(number, current_number, option, (uint8_t *) coap_pkt->field, coap_pkt->field##_len, splitter); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
|
||||
if (IS_OPTION(coap_pkt, number)) \
|
||||
{ \
|
||||
PRINTF(text" [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
|
||||
uint32_t block = coap_pkt->field##_num << 4; \
|
||||
if (coap_pkt->field##_more) block |= 0x8; \
|
||||
block |= 0xF & coap_log_2(coap_pkt->field##_size/16); \
|
||||
PRINTF(text" encoded: 0x%lX\n", block); \
|
||||
option += coap_serialize_int_option(number, current_number, option, block); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " [%u]\n", coap_pkt->field); \
|
||||
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
|
||||
coap_pkt->field[0], \
|
||||
coap_pkt->field[1], \
|
||||
coap_pkt->field[2], \
|
||||
coap_pkt->field[3], \
|
||||
coap_pkt->field[4], \
|
||||
coap_pkt->field[5], \
|
||||
coap_pkt->field[6], \
|
||||
coap_pkt->field[7] \
|
||||
); /* FIXME always prints 8 bytes */ \
|
||||
option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
|
||||
option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) \
|
||||
{ \
|
||||
PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
|
||||
uint32_t block = coap_pkt->field##_num << 4; \
|
||||
if(coap_pkt->field##_more) { block |= 0x8; } \
|
||||
block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \
|
||||
PRINTF(text " encoded: 0x%lX\n", block); \
|
||||
option += coap_serialize_int_option(number, current_number, option, block); \
|
||||
current_number = number; \
|
||||
}
|
||||
|
||||
/* to store error code and human-readable payload */
|
||||
extern coap_status_t erbium_status_code;
|
||||
|
@ -175,10 +174,10 @@ uint16_t coap_get_mid(void);
|
|||
|
||||
void coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
|
||||
uint16_t mid);
|
||||
size_t coap_serialize_message(void *packet, uint8_t * buffer);
|
||||
void coap_send_message(uip_ipaddr_t * addr, uint16_t port, uint8_t * data,
|
||||
size_t coap_serialize_message(void *packet, uint8_t *buffer);
|
||||
void coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
|
||||
uint16_t length);
|
||||
coap_status_t coap_parse_message(void *request, uint8_t * data,
|
||||
coap_status_t coap_parse_message(void *request, uint8_t *data,
|
||||
uint16_t data_len);
|
||||
|
||||
int coap_get_query_variable(void *packet, const char *name,
|
||||
|
@ -190,7 +189,7 @@ int coap_get_post_variable(void *packet, const char *name,
|
|||
|
||||
int coap_set_status_code(void *packet, unsigned int code);
|
||||
|
||||
int coap_set_token(void *packet, const uint8_t * token, size_t token_len);
|
||||
int coap_set_token(void *packet, const uint8_t *token, size_t token_len);
|
||||
|
||||
int coap_get_header_content_format(void *packet, unsigned int *format);
|
||||
int coap_set_header_content_format(void *packet, unsigned int format);
|
||||
|
@ -198,14 +197,14 @@ int coap_set_header_content_format(void *packet, unsigned int format);
|
|||
int coap_get_header_accept(void *packet, unsigned int *accept);
|
||||
int coap_set_header_accept(void *packet, unsigned int accept);
|
||||
|
||||
int coap_get_header_max_age(void *packet, uint32_t * age);
|
||||
int coap_get_header_max_age(void *packet, uint32_t *age);
|
||||
int coap_set_header_max_age(void *packet, uint32_t age);
|
||||
|
||||
int coap_get_header_etag(void *packet, const uint8_t ** etag);
|
||||
int coap_set_header_etag(void *packet, const uint8_t * etag, size_t etag_len);
|
||||
int coap_get_header_etag(void *packet, const uint8_t **etag);
|
||||
int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len);
|
||||
|
||||
int coap_get_header_if_match(void *packet, const uint8_t ** etag);
|
||||
int coap_set_header_if_match(void *packet, const uint8_t * etag,
|
||||
int coap_get_header_if_match(void *packet, const uint8_t **etag);
|
||||
int coap_set_header_if_match(void *packet, const uint8_t *etag,
|
||||
size_t etag_len);
|
||||
|
||||
int coap_get_header_if_none_match(void *packet);
|
||||
|
@ -232,26 +231,26 @@ int coap_set_header_location_path(void *packet, const char *path); /* also split
|
|||
int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_location_query(void *packet, const char *query);
|
||||
|
||||
int coap_get_header_observe(void *packet, uint32_t * observe);
|
||||
int coap_get_header_observe(void *packet, uint32_t *observe);
|
||||
int coap_set_header_observe(void *packet, uint32_t observe);
|
||||
|
||||
int coap_get_header_block2(void *packet, uint32_t * num, uint8_t * more,
|
||||
uint16_t * size, uint32_t * offset);
|
||||
int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint16_t *size, uint32_t *offset);
|
||||
int coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
|
||||
uint16_t size);
|
||||
|
||||
int coap_get_header_block1(void *packet, uint32_t * num, uint8_t * more,
|
||||
uint16_t * size, uint32_t * offset);
|
||||
int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint16_t *size, uint32_t *offset);
|
||||
int coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
|
||||
uint16_t size);
|
||||
|
||||
int coap_get_header_size2(void *packet, uint32_t * size);
|
||||
int coap_get_header_size2(void *packet, uint32_t *size);
|
||||
int coap_set_header_size2(void *packet, uint32_t size);
|
||||
|
||||
int coap_get_header_size1(void *packet, uint32_t * size);
|
||||
int coap_get_header_size1(void *packet, uint32_t *size);
|
||||
int coap_set_header_size1(void *packet, uint32_t size);
|
||||
|
||||
int coap_get_payload(void *packet, const uint8_t ** payload);
|
||||
int coap_get_payload(void *packet, const uint8_t **payload);
|
||||
int coap_set_payload(void *packet, const void *payload, size_t length);
|
||||
|
||||
#endif /* ER_COAP_H_ */
|
||||
|
|
0
apps/rest-engine/rest-constants.h
Executable file → Normal file
0
apps/rest-engine/rest-constants.h
Executable file → Normal file
32
apps/rest-engine/rest-engine.c
Executable file → Normal file
32
apps/rest-engine/rest-engine.c
Executable file → Normal file
|
@ -42,8 +42,17 @@
|
|||
#include "contiki.h"
|
||||
#include "rest-engine.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
PROCESS(rest_engine_process, "REST Engine");
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -82,7 +91,7 @@ rest_init_engine(void)
|
|||
* *.c file in the ./resources/ sub-directory (see example Makefile).
|
||||
*/
|
||||
void
|
||||
rest_activate_resource(resource_t * resource, char *path)
|
||||
rest_activate_resource(resource_t *resource, char *path)
|
||||
{
|
||||
resource->url = path;
|
||||
list_add(restful_services, resource);
|
||||
|
@ -107,8 +116,8 @@ rest_get_resources(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rest_invoke_restful_service(void *request, void *response, uint8_t * buffer,
|
||||
uint16_t buffer_size, int32_t * offset)
|
||||
rest_invoke_restful_service(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t buffer_size, int32_t *offset)
|
||||
{
|
||||
uint8_t found = 0;
|
||||
uint8_t allowed = 1;
|
||||
|
@ -116,7 +125,7 @@ rest_invoke_restful_service(void *request, void *response, uint8_t * buffer,
|
|||
resource_t *resource = NULL;
|
||||
const char *url = NULL;
|
||||
|
||||
for(resource = (resource_t *) list_head(restful_services);
|
||||
for(resource = (resource_t *)list_head(restful_services);
|
||||
resource; resource = resource->next) {
|
||||
|
||||
/* if the web service handles that kind of requests and urls matches */
|
||||
|
@ -128,7 +137,7 @@ rest_invoke_restful_service(void *request, void *response, uint8_t * buffer,
|
|||
rest_resource_flags_t method = REST.get_method_type(request);
|
||||
|
||||
PRINTF("/%s, method %u, resource->flags %u\n", resource->url,
|
||||
(uint16_t) method, resource->flags);
|
||||
(uint16_t)method, resource->flags);
|
||||
|
||||
if((method & METHOD_GET) && resource->get_handler != NULL) {
|
||||
/* call handler function */
|
||||
|
@ -151,7 +160,6 @@ rest_invoke_restful_service(void *request, void *response, uint8_t * buffer,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
REST.set_response_status(response, REST.status.NOT_FOUND);
|
||||
} else if(allowed) {
|
||||
|
@ -160,7 +168,6 @@ rest_invoke_restful_service(void *request, void *response, uint8_t * buffer,
|
|||
REST.subscription_handler(resource, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
return found & allowed;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -175,7 +182,7 @@ PROCESS_THREAD(rest_engine_process, ev, data)
|
|||
periodic_resource_t *periodic_resource = NULL;
|
||||
|
||||
for(periodic_resource =
|
||||
(periodic_resource_t *) list_head(restful_periodic_services);
|
||||
(periodic_resource_t *)list_head(restful_periodic_services);
|
||||
periodic_resource; periodic_resource = periodic_resource->next) {
|
||||
if(periodic_resource->periodic_handler && periodic_resource->period) {
|
||||
PRINTF("Periodic: Set timer for /%s to %lu\n",
|
||||
|
@ -184,13 +191,12 @@ PROCESS_THREAD(rest_engine_process, ev, data)
|
|||
periodic_resource->period);
|
||||
}
|
||||
}
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
|
||||
if(ev == PROCESS_EVENT_TIMER) {
|
||||
for(periodic_resource =
|
||||
(periodic_resource_t *) list_head(restful_periodic_services);
|
||||
(periodic_resource_t *)list_head(restful_periodic_services);
|
||||
periodic_resource; periodic_resource = periodic_resource->next) {
|
||||
if(periodic_resource->period
|
||||
&& etimer_expired(&periodic_resource->periodic_timer)) {
|
||||
|
@ -199,7 +205,7 @@ PROCESS_THREAD(rest_engine_process, ev, data)
|
|||
periodic_resource->resource->url, periodic_resource->period);
|
||||
|
||||
/* Call the periodic_handler function, which was checked during adding to list. */
|
||||
(periodic_resource->periodic_handler) ();
|
||||
(periodic_resource->periodic_handler)();
|
||||
|
||||
etimer_reset(&periodic_resource->periodic_timer);
|
||||
}
|
||||
|
|
107
apps/rest-engine/rest-engine.h
Executable file → Normal file
107
apps/rest-engine/rest-engine.h
Executable file → Normal file
|
@ -50,7 +50,7 @@
|
|||
#define REGISTERED_ENGINE_HELIUM http_rest_implementation
|
||||
|
||||
/* sanity check for configured implementation */
|
||||
#if !defined(REST) || (REST!=REGISTERED_ENGINE_ERBIUM && REST!=REGISTERED_ENGINE_HELIUM)
|
||||
#if !defined(REST) || (REST != REGISTERED_ENGINE_ERBIUM && REST != REGISTERED_ENGINE_HELIUM)
|
||||
#error "Define a valid REST Engine implementation (REST define)!"
|
||||
#endif
|
||||
|
||||
|
@ -63,27 +63,26 @@
|
|||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b)? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
|
||||
struct resource_s;
|
||||
struct periodic_resource_s;
|
||||
|
||||
/* signatures of handler functions */
|
||||
typedef void (*restful_handler) (void *request, void *response,
|
||||
uint8_t * buffer, uint16_t preferred_size,
|
||||
int32_t * offset);
|
||||
typedef void (*restful_final_handler) (struct resource_s * resource,
|
||||
void *request, void *response);
|
||||
typedef void (*restful_periodic_handler) (void);
|
||||
typedef void (*restful_response_handler) (void *data, void *response);
|
||||
typedef void (*restful_trigger_handler) (void);
|
||||
typedef void (*restful_handler)(void *request, void *response,
|
||||
uint8_t *buffer, uint16_t preferred_size,
|
||||
int32_t *offset);
|
||||
typedef void (*restful_final_handler)(struct resource_s *resource,
|
||||
void *request, void *response);
|
||||
typedef void (*restful_periodic_handler)(void);
|
||||
typedef void (*restful_response_handler)(void *data, void *response);
|
||||
typedef void (*restful_trigger_handler)(void);
|
||||
|
||||
/* signature of the rest-engine service function */
|
||||
typedef int (*service_callback_t) (void *request, void *response,
|
||||
uint8_t * buffer, uint16_t preferred_size,
|
||||
int32_t * offset);
|
||||
typedef int (*service_callback_t)(void *request, void *response,
|
||||
uint8_t *buffer, uint16_t preferred_size,
|
||||
int32_t *offset);
|
||||
|
||||
/* data structure representing a resource in REST */
|
||||
struct resource_s {
|
||||
|
@ -117,16 +116,16 @@ typedef struct periodic_resource_s periodic_resource_t;
|
|||
* Resources are statically defined for the sake of efficiency and better memory management.
|
||||
*/
|
||||
#define RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \
|
||||
resource_t name = {NULL, NULL, NO_FLAGS, attributes, get_handler, post_handler, put_handler, delete_handler, {NULL}}
|
||||
resource_t name = { NULL, NULL, NO_FLAGS, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } }
|
||||
|
||||
#define PARENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler) \
|
||||
resource_t name = {NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler, post_handler, put_handler, delete_handler, {NULL}}
|
||||
resource_t name = { NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler, post_handler, put_handler, delete_handler, { NULL } }
|
||||
|
||||
#define SEPARATE_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, resume_handler) \
|
||||
resource_t name = {NULL, NULL, IS_SEPARATE, attributes, get_handler, post_handler, put_handler, delete_handler, { .resume = resume_handler }}
|
||||
resource_t name = { NULL, NULL, IS_SEPARATE, attributes, get_handler, post_handler, put_handler, delete_handler, { .resume = resume_handler } }
|
||||
|
||||
#define EVENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, event_handler) \
|
||||
resource_t name = {NULL, NULL, IS_OBSERVABLE, attributes, get_handler, post_handler, put_handler, delete_handler, { .trigger = event_handler }}
|
||||
resource_t name = { NULL, NULL, IS_OBSERVABLE, attributes, get_handler, post_handler, put_handler, delete_handler, { .trigger = event_handler } }
|
||||
|
||||
/*
|
||||
* Macro to define a periodic resource.
|
||||
|
@ -135,87 +134,87 @@ typedef struct periodic_resource_s periodic_resource_t;
|
|||
* The subscriber list will be maintained by the final_handler rest_subscription_handler() (see rest-mapping header file).
|
||||
*/
|
||||
#define PERIODIC_RESOURCE(name, attributes, get_handler, post_handler, put_handler, delete_handler, period, periodic_handler) \
|
||||
periodic_resource_t periodic_##name; \
|
||||
resource_t name = {NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes, get_handler, post_handler, put_handler, delete_handler, { .periodic = &periodic_##name }}; \
|
||||
periodic_resource_t periodic_##name = {NULL, &name, period, {{0}}, periodic_handler};
|
||||
periodic_resource_t periodic_##name; \
|
||||
resource_t name = { NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes, get_handler, post_handler, put_handler, delete_handler, { .periodic = &periodic_##name } }; \
|
||||
periodic_resource_t periodic_##name = { NULL, &name, period, { { 0 } }, periodic_handler };
|
||||
|
||||
struct rest_implementation {
|
||||
char *name;
|
||||
|
||||
/** Initialize the REST implementation. */
|
||||
void (*init) (void);
|
||||
void (*init)(void);
|
||||
|
||||
/** Register the RESTful service callback at implementation. */
|
||||
void (*set_service_callback) (service_callback_t callback);
|
||||
void (*set_service_callback)(service_callback_t callback);
|
||||
|
||||
/** Get request URI path. */
|
||||
int (*get_url) (void *request, const char **url);
|
||||
int (*get_url)(void *request, const char **url);
|
||||
|
||||
/** Get the method of a request. */
|
||||
rest_resource_flags_t (*get_method_type) (void *request);
|
||||
rest_resource_flags_t (*get_method_type)(void *request);
|
||||
|
||||
/** Set the status code of a response. */
|
||||
int (*set_response_status) (void *response, unsigned int code);
|
||||
int (*set_response_status)(void *response, unsigned int code);
|
||||
|
||||
/** Get the content-type of a request. */
|
||||
int (*get_header_content_type) (void *request,
|
||||
unsigned int *content_format);
|
||||
int (*get_header_content_type)(void *request,
|
||||
unsigned int *content_format);
|
||||
|
||||
/** Set the Content-Type of a response. */
|
||||
int (*set_header_content_type) (void *response,
|
||||
unsigned int content_format);
|
||||
int (*set_header_content_type)(void *response,
|
||||
unsigned int content_format);
|
||||
|
||||
/** Get the Accept types of a request. */
|
||||
int (*get_header_accept) (void *request, unsigned int *accept);
|
||||
int (*get_header_accept)(void *request, unsigned int *accept);
|
||||
|
||||
/** Get the Length option of a request. */
|
||||
int (*get_header_length) (void *request, uint32_t * size);
|
||||
int (*get_header_length)(void *request, uint32_t *size);
|
||||
|
||||
/** Set the Length option of a response. */
|
||||
int (*set_header_length) (void *response, uint32_t size);
|
||||
int (*set_header_length)(void *response, uint32_t size);
|
||||
|
||||
/** Get the Max-Age option of a request. */
|
||||
int (*get_header_max_age) (void *request, uint32_t * age);
|
||||
int (*get_header_max_age)(void *request, uint32_t *age);
|
||||
|
||||
/** Set the Max-Age option of a response. */
|
||||
int (*set_header_max_age) (void *response, uint32_t age);
|
||||
int (*set_header_max_age)(void *response, uint32_t age);
|
||||
|
||||
/** Set the ETag option of a response. */
|
||||
int (*set_header_etag) (void *response, const uint8_t * etag,
|
||||
size_t length);
|
||||
int (*set_header_etag)(void *response, const uint8_t *etag,
|
||||
size_t length);
|
||||
|
||||
/** Get the If-Match option of a request. */
|
||||
int (*get_header_if_match) (void *request, const uint8_t ** etag);
|
||||
int (*get_header_if_match)(void *request, const uint8_t **etag);
|
||||
|
||||
/** Get the If-Match option of a request. */
|
||||
int (*get_header_if_none_match) (void *request);
|
||||
int (*get_header_if_none_match)(void *request);
|
||||
|
||||
/** Get the Host option of a request. */
|
||||
int (*get_header_host) (void *request, const char **host);
|
||||
int (*get_header_host)(void *request, const char **host);
|
||||
|
||||
/** Set the location option of a response. */
|
||||
int (*set_header_location) (void *response, const char *location);
|
||||
int (*set_header_location)(void *response, const char *location);
|
||||
|
||||
/** Get the payload option of a request. */
|
||||
int (*get_request_payload) (void *request, const uint8_t ** payload);
|
||||
int (*get_request_payload)(void *request, const uint8_t **payload);
|
||||
|
||||
/** Set the payload option of a response. */
|
||||
int (*set_response_payload) (void *response, const void *payload,
|
||||
size_t length);
|
||||
int (*set_response_payload)(void *response, const void *payload,
|
||||
size_t length);
|
||||
|
||||
/** Get the query string of a request. */
|
||||
int (*get_query) (void *request, const char **value);
|
||||
int (*get_query)(void *request, const char **value);
|
||||
|
||||
/** Get the value of a request query key-value pair. */
|
||||
int (*get_query_variable) (void *request, const char *name,
|
||||
const char **value);
|
||||
|
||||
/** Get the value of a request POST key-value pair. */
|
||||
int (*get_post_variable) (void *request, const char *name,
|
||||
int (*get_query_variable)(void *request, const char *name,
|
||||
const char **value);
|
||||
|
||||
/** Get the value of a request POST key-value pair. */
|
||||
int (*get_post_variable)(void *request, const char *name,
|
||||
const char **value);
|
||||
|
||||
/** Send the payload to all subscribers of the resource at url. */
|
||||
void (*notify_subscribers) (resource_t * resource);
|
||||
void (*notify_subscribers)(resource_t *resource);
|
||||
|
||||
/** The handler for resource subscriptions. */
|
||||
restful_final_handler subscription_handler;
|
||||
|
@ -235,8 +234,8 @@ extern const struct rest_implementation REST;
|
|||
* This function dispatches the corresponding RESTful service.
|
||||
*/
|
||||
int rest_invoke_restful_service(void *request, void *response,
|
||||
uint8_t * buffer, uint16_t buffer_size,
|
||||
int32_t * offset);
|
||||
uint8_t *buffer, uint16_t buffer_size,
|
||||
int32_t *offset);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initializes REST framework and starts the HTTP or CoAP process.
|
||||
|
@ -251,7 +250,7 @@ void rest_init_engine(void);
|
|||
* \param path
|
||||
* The local URI path where to provide the resource.
|
||||
*/
|
||||
void rest_activate_resource(resource_t * resource, char *path);
|
||||
void rest_activate_resource(resource_t *resource, char *path);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Returns the list of registered RESTful resources.
|
||||
|
|
|
@ -13,7 +13,15 @@ CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
|
|||
|
||||
# automatically build RESTful resources
|
||||
REST_RESOURCES_DIR = ./resources
|
||||
ifndef TARGET
|
||||
REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c'))
|
||||
else
|
||||
ifeq ($(TARGET), native)
|
||||
REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c'))
|
||||
else
|
||||
REST_RESOURCES_FILES = $(notdir $(shell find $(REST_RESOURCES_DIR) -name '*.c' ! -name 'res-plugtest*'))
|
||||
endif
|
||||
endif
|
||||
|
||||
PROJECTDIRS += $(REST_RESOURCES_DIR)
|
||||
PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES)
|
||||
|
|
27
examples/er-rest-example/er-example-client.c
Executable file → Normal file
27
examples/er-rest-example/er-example-client.c
Executable file → Normal file
|
@ -44,15 +44,23 @@
|
|||
#include "er-coap-engine.h"
|
||||
#include "dev/button-sensor.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/* FIXME: This server address is hard-coded for Cooja and link-local for unconnected border router. */
|
||||
#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xfe80, 0, 0, 0, 0x0212, 0x7402, 0x0002, 0x0202) /* cooja2 */
|
||||
//#define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1)
|
||||
/* #define SERVER_NODE(ipaddr) uip_ip6addr(ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x1) */
|
||||
|
||||
#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT+1)
|
||||
#define LOCAL_PORT UIP_HTONS(COAP_DEFAULT_PORT + 1)
|
||||
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
|
||||
#define TOGGLE_INTERVAL 10
|
||||
|
@ -60,7 +68,6 @@
|
|||
PROCESS(er_example_client, "Erbium Example Client");
|
||||
AUTOSTART_PROCESSES(&er_example_client);
|
||||
|
||||
|
||||
uip_ipaddr_t server_ipaddr;
|
||||
static struct etimer et;
|
||||
|
||||
|
@ -68,7 +75,7 @@ static struct etimer et;
|
|||
#define NUMBER_OF_URLS 4
|
||||
/* leading and ending slashes only for demo purposes, get cropped automatically when setting the Uri-Path */
|
||||
char *service_urls[NUMBER_OF_URLS] =
|
||||
{ ".well-known/core", "/actuators/toggle", "battery/", "error/in//path" };
|
||||
{ ".well-known/core", "/actuators/toggle", "battery/", "error/in//path" };
|
||||
#if PLATFORM_HAS_BUTTON
|
||||
static int uri_switch = 0;
|
||||
#endif
|
||||
|
@ -83,8 +90,6 @@ client_chunk_handler(void *response)
|
|||
|
||||
printf("|%.*s", len, (char *)chunk);
|
||||
}
|
||||
|
||||
|
||||
PROCESS_THREAD(er_example_client, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
@ -115,8 +120,7 @@ PROCESS_THREAD(er_example_client, ev, data)
|
|||
|
||||
const char msg[] = "Toggle!";
|
||||
|
||||
coap_set_payload(request, (uint8_t *) msg, sizeof(msg) - 1);
|
||||
|
||||
coap_set_payload(request, (uint8_t *)msg, sizeof(msg) - 1);
|
||||
|
||||
PRINT6ADDR(&server_ipaddr);
|
||||
PRINTF(" : %u\n", UIP_HTONS(REMOTE_PORT));
|
||||
|
@ -148,7 +152,6 @@ PROCESS_THREAD(er_example_client, ev, data)
|
|||
|
||||
uri_switch = (uri_switch + 1) % NUMBER_OF_URLS;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
0
examples/er-rest-example/er-example-server.c
Executable file → Normal file
0
examples/er-rest-example/er-example-server.c
Executable file → Normal file
1
examples/er-rest-example/er-plugtest-server.c
Executable file → Normal file
1
examples/er-rest-example/er-plugtest-server.c
Executable file → Normal file
|
@ -122,7 +122,6 @@ PROCESS_THREAD(plugtest_server, ev, data)
|
|||
/* Define application-specific events here. */
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
|
||||
} /* while (1) */
|
||||
|
||||
PROCESS_END();
|
||||
|
|
19
examples/er-rest-example/er-plugtest.h
Executable file → Normal file
19
examples/er-rest-example/er-plugtest.h
Executable file → Normal file
|
@ -39,18 +39,27 @@
|
|||
#ifndef __ER_PLUGTEST_H__
|
||||
#define __ER_PLUGTEST_H__
|
||||
|
||||
#if !defined (CONTIKI_TARGET_NATIVE)
|
||||
#if !defined(CONTIKI_TARGET_NATIVE)
|
||||
#warning "Should only be compiled for native!"
|
||||
#endif
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
/* double expansion */
|
||||
#define TO_STRING2(x) #x
|
||||
#define TO_STRING2(x) # x
|
||||
#define TO_STRING(x) TO_STRING2(x)
|
||||
|
||||
#define MAX_PLUGFEST_PAYLOAD 64+1 /* +1 for the terminating zero, which is not transmitted */
|
||||
#define MAX_PLUGFEST_PAYLOAD 64 + 1 /* +1 for the terminating zero, which is not transmitted */
|
||||
#define MAX_PLUGFEST_BODY 2048
|
||||
#define CHUNKS_TOTAL 2012
|
||||
|
||||
|
|
28
examples/er-rest-example/project-conf.h
Executable file → Normal file
28
examples/er-rest-example/project-conf.h
Executable file → Normal file
|
@ -41,18 +41,18 @@
|
|||
|
||||
/* Custom channel and PAN ID configuration for your project. */
|
||||
/*
|
||||
#undef RF_CHANNEL
|
||||
#define RF_CHANNEL 26
|
||||
#undef RF_CHANNEL
|
||||
#define RF_CHANNEL 26
|
||||
|
||||
#undef IEEE802154_CONF_PANID
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
*/
|
||||
#undef IEEE802154_CONF_PANID
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
*/
|
||||
|
||||
/* IP buffer size must match all other hops, in particular the border router. */
|
||||
/*
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
*/
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
*/
|
||||
|
||||
/* Disabling RDC for demo purposes. Core updates often require more memory. */
|
||||
/* For projects, optimize memory and enable RDC again. */
|
||||
|
@ -69,9 +69,9 @@
|
|||
|
||||
/* Estimate your header size, especially when using Proxy-Uri. */
|
||||
/*
|
||||
#undef COAP_MAX_HEADER_SIZE
|
||||
#define COAP_MAX_HEADER_SIZE 70
|
||||
*/
|
||||
#undef COAP_MAX_HEADER_SIZE
|
||||
#define COAP_MAX_HEADER_SIZE 70
|
||||
*/
|
||||
|
||||
/* Multiplies with chunk size, be aware of memory constraints. */
|
||||
#undef COAP_MAX_OPEN_TRANSACTIONS
|
||||
|
@ -79,9 +79,9 @@
|
|||
|
||||
/* Must be <= open transactions, default is COAP_MAX_OPEN_TRANSACTIONS-1. */
|
||||
/*
|
||||
#undef COAP_MAX_OBSERVERS
|
||||
#define COAP_MAX_OBSERVERS 2
|
||||
*/
|
||||
#undef COAP_MAX_OBSERVERS
|
||||
#define COAP_MAX_OBSERVERS 2
|
||||
*/
|
||||
|
||||
/* Filtering .well-known/core per query can be disabled to save space. */
|
||||
#undef COAP_LINK_FORMAT_FILTERING
|
||||
|
|
19
examples/er-rest-example/resources/res-battery.c
Executable file → Normal file
19
examples/er-rest-example/resources/res-battery.c
Executable file → Normal file
|
@ -44,30 +44,30 @@
|
|||
#include "rest-engine.h"
|
||||
#include "dev/battery-sensor.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
||||
RESOURCE(battery,
|
||||
"title=\"Battery status\";rt=\"Battery\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Battery status\";rt=\"Battery\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int battery = battery_sensor.value(0);
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
if(accept==-1 || accept==REST.type.TEXT_PLAIN) {
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", battery);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept==REST.type.APPLICATION_JSON) {
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'battery':%d}", battery);
|
||||
|
||||
|
@ -78,5 +78,4 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_HAS_BATTERY */
|
||||
|
|
28
examples/er-rest-example/resources/res-chunks.c
Executable file → Normal file
28
examples/er-rest-example/resources/res-chunks.c
Executable file → Normal file
|
@ -39,7 +39,7 @@
|
|||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* For data larger than REST_MAX_CHUNK_SIZE (e.g., when stored in flash) resources must be aware of the buffer limitation
|
||||
|
@ -49,21 +49,21 @@ static void res_get_handler(void* request, void* response, uint8_t *buffer, uint
|
|||
* (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(res_chunks,
|
||||
"title=\"Blockwise demo\";rt=\"Data\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Blockwise demo\";rt=\"Data\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
#define CHUNKS_TOTAL 2050
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int32_t strpos = 0;
|
||||
|
||||
/* Check the offset for boundaries of the resource data. */
|
||||
if(*offset>=CHUNKS_TOTAL) {
|
||||
if(*offset >= CHUNKS_TOTAL) {
|
||||
REST.set_response_status(response, REST.status.BAD_OPTION);
|
||||
/* A block error message should not exceed the minimum block size (16). */
|
||||
|
||||
|
@ -73,27 +73,25 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
|
||||
/* Generate data until reaching CHUNKS_TOTAL. */
|
||||
while (strpos<preferred_size) {
|
||||
strpos += snprintf((char *)buffer+strpos, preferred_size-strpos+1, "|%ld|", *offset);
|
||||
while(strpos < preferred_size) {
|
||||
strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1, "|%ld|", *offset);
|
||||
}
|
||||
|
||||
/* snprintf() does not adjust return value if truncated by size. */
|
||||
if(strpos > preferred_size) {
|
||||
strpos = preferred_size;
|
||||
/* Truncate if above CHUNKS_TOTAL bytes. */
|
||||
}
|
||||
|
||||
/* Truncate if above CHUNKS_TOTAL bytes. */
|
||||
if(*offset+(int32_t)strpos > CHUNKS_TOTAL) {
|
||||
if(*offset + (int32_t)strpos > CHUNKS_TOTAL) {
|
||||
strpos = CHUNKS_TOTAL - *offset;
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
|
||||
/* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
|
||||
*offset += strpos;
|
||||
|
||||
/* Signal end of resource representation. */
|
||||
if(*offset>=CHUNKS_TOTAL) {
|
||||
if(*offset >= CHUNKS_TOTAL) {
|
||||
*offset = -1;
|
||||
}
|
||||
}
|
||||
|
|
32
examples/er-rest-example/resources/res-event.c
Executable file → Normal file
32
examples/er-rest-example/resources/res-event.c
Executable file → Normal file
|
@ -40,10 +40,19 @@
|
|||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_event_handler();
|
||||
|
||||
/*
|
||||
|
@ -52,12 +61,12 @@ static void res_event_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);
|
||||
"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.
|
||||
|
@ -65,14 +74,13 @@ EVENT_RESOURCE(res_event,
|
|||
static int32_t event_counter = 0;
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu", event_counter));
|
||||
|
||||
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Additionally, res_event_handler must be implemented for each EVENT_RESOURCE.
|
||||
* It is called through <res_name>.trigger(), usually from the server process.
|
||||
|
@ -84,7 +92,7 @@ res_event_handler()
|
|||
++event_counter;
|
||||
|
||||
/* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */
|
||||
if (1) {
|
||||
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. */
|
||||
|
|
30
examples/er-rest-example/resources/res-hello.c
Executable file → Normal file
30
examples/er-rest-example/resources/res-hello.c
Executable file → Normal file
|
@ -40,7 +40,7 @@
|
|||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* A handler function named [resource name]_handler must be implemented for each RESOURCE.
|
||||
|
@ -49,31 +49,33 @@ static void res_get_handler(void* request, void* response, uint8_t *buffer, uint
|
|||
* If a smaller block size is requested for CoAP, the REST framework automatically splits the data.
|
||||
*/
|
||||
RESOURCE(res_hello,
|
||||
"title=\"Hello world: ?len=0..\";rt=\"Text\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Hello world: ?len=0..\";rt=\"Text\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *len = NULL;
|
||||
/* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */
|
||||
char const * const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy";
|
||||
char const *const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy";
|
||||
int length = 12; /* |<-------->| */
|
||||
|
||||
/* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */
|
||||
if(REST.get_query_variable(request, "len", &len)) {
|
||||
length = atoi(len);
|
||||
if(length<0) length = 0;
|
||||
if(length>REST_MAX_CHUNK_SIZE) length = REST_MAX_CHUNK_SIZE;
|
||||
if(length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
if(length > REST_MAX_CHUNK_SIZE) {
|
||||
length = REST_MAX_CHUNK_SIZE;
|
||||
}
|
||||
memcpy(buffer, message, length);
|
||||
} else {
|
||||
memcpy(buffer, message, length);
|
||||
}
|
||||
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */
|
||||
REST.set_header_etag(response, (uint8_t *) &length, 1);
|
||||
} REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /* text/plain is the default, hence this option could be omitted. */
|
||||
REST.set_header_etag(response, (uint8_t *)&length, 1);
|
||||
REST.set_response_payload(response, buffer, length);
|
||||
}
|
||||
|
|
48
examples/er-rest-example/resources/res-leds.c
Executable file → Normal file
48
examples/er-rest-example/resources/res-leds.c
Executable file → Normal file
|
@ -44,21 +44,30 @@
|
|||
#include "rest-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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_post_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*A simple actuator example, depending on the color query parameter and post variable mode, corresponding led is activated or deactivated*/
|
||||
RESOURCE(res_leds,
|
||||
"title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"",
|
||||
NULL,
|
||||
res_post_put_handler,
|
||||
res_post_put_handler,
|
||||
NULL);
|
||||
"title=\"LEDs: ?color=r|g|b, POST/PUT mode=on|off\";rt=\"Control\"",
|
||||
NULL,
|
||||
res_post_put_handler,
|
||||
res_post_put_handler,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_post_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char *color = NULL;
|
||||
|
@ -66,39 +75,34 @@ res_post_put_handler(void* request, void* response, uint8_t *buffer, uint16_t pr
|
|||
uint8_t led = 0;
|
||||
int success = 1;
|
||||
|
||||
if((len=REST.get_query_variable(request, "color", &color))) {
|
||||
if((len = REST.get_query_variable(request, "color", &color))) {
|
||||
PRINTF("color %.*s\n", len, color);
|
||||
|
||||
if(strncmp(color, "r", len)==0) {
|
||||
if(strncmp(color, "r", len) == 0) {
|
||||
led = LEDS_RED;
|
||||
} else if(strncmp(color,"g", len)==0) {
|
||||
} else if(strncmp(color, "g", len) == 0) {
|
||||
led = LEDS_GREEN;
|
||||
} else if(strncmp(color,"b", len)==0) {
|
||||
} else if(strncmp(color, "b", len) == 0) {
|
||||
led = LEDS_BLUE;
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
|
||||
if(success && (len=REST.get_post_variable(request, "mode", &mode))) {
|
||||
} if(success && (len = REST.get_post_variable(request, "mode", &mode))) {
|
||||
PRINTF("mode %s\n", mode);
|
||||
|
||||
if(strncmp(mode, "on", len)==0) {
|
||||
if(strncmp(mode, "on", len) == 0) {
|
||||
leds_on(led);
|
||||
} else if(strncmp(mode, "off", len)==0) {
|
||||
} else if(strncmp(mode, "off", len) == 0) {
|
||||
leds_off(led);
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
|
||||
if(!success) {
|
||||
} if(!success) {
|
||||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_HAS_LEDS */
|
||||
|
|
21
examples/er-rest-example/resources/res-light.c
Executable file → Normal file
21
examples/er-rest-example/resources/res-light.c
Executable file → Normal file
|
@ -44,18 +44,18 @@
|
|||
#include "rest-engine.h"
|
||||
#include "dev/light-sensor.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading from light sensor with a simple etag */
|
||||
RESOURCE(res_light,
|
||||
"title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Photosynthetic and solar light (supports JSON)\";rt=\"LightSensor\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
uint16_t light_photosynthetic = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC);
|
||||
uint16_t light_solar = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR);
|
||||
|
@ -63,17 +63,17 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
if(accept==-1 || accept==REST.type.TEXT_PLAIN) {
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%u;%u", light_photosynthetic, light_solar);
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept==REST.type.APPLICATION_XML) {
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "<light photosynthetic=\"%u\" solar=\"%u\"/>", light_photosynthetic, light_solar);
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else if(accept==REST.type.APPLICATION_JSON) {
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'light':{'photosynthetic':%u,'solar':%u}}", light_photosynthetic, light_solar);
|
||||
|
||||
|
@ -84,5 +84,4 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_HAS_LIGHT */
|
||||
|
|
138
examples/er-rest-example/resources/res-mirror.c
Executable file → Normal file
138
examples/er-rest-example/resources/res-mirror.c
Executable file → Normal file
|
@ -40,27 +40,36 @@
|
|||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/uip-debug.h"
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#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_any_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* This resource mirrors the incoming request. It shows how to access the options and how to set them for the response. */
|
||||
RESOURCE(res_mirror,
|
||||
"title=\"Returns your decoded message\";rt=\"Debug\"",
|
||||
res_any_handler,
|
||||
res_any_handler,
|
||||
res_any_handler,
|
||||
res_any_handler);
|
||||
"title=\"Returns your decoded message\";rt=\"Debug\"",
|
||||
res_any_handler,
|
||||
res_any_handler,
|
||||
res_any_handler,
|
||||
res_any_handler);
|
||||
|
||||
static void
|
||||
res_any_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_any_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* The ETag and Token is copied to the header. */
|
||||
uint8_t opaque[] = {0x0A, 0xBC, 0xDE};
|
||||
uint8_t opaque[] = { 0x0A, 0xBC, 0xDE };
|
||||
|
||||
/* 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};
|
||||
static char location[] = { '/', 'f', '/', 'a', '?', 'k', '&', 'e', 0 };
|
||||
|
||||
/* No default my be assumed for the Content-Format. (Unsigned -1 means all bits set.) */
|
||||
unsigned int content_format = -1;
|
||||
|
@ -81,80 +90,71 @@ res_any_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
* The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework.
|
||||
* Add +1 to fill the complete buffer, as the payload does not need a terminating '\0'. */
|
||||
if(REST.get_header_content_type(request, &content_format)) {
|
||||
strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE+1, "CF %u\n", content_format);
|
||||
strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE + 1, "CF %u\n", content_format);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_accept(request, &content_format))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ac %u\n", content_format);
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_accept(request, &content_format))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ac %u\n", content_format);
|
||||
/* Some getters such as for ETag or Location are omitted, as these options should not appear in a request.
|
||||
* Max-Age might appear in HTTP requests or used for special purposes in CoAP. */
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "MA %lu\n", longint);
|
||||
/* For HTTP this is the Length option, for CoAP it is the Size option. */
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "SZ %lu\n", longint);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UH %.*s\n", len, str);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_url(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UP %.*s\n", len, str);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "UQ %.*s\n", len, str);
|
||||
/* Undefined request options for debugging: actions not required for normal RESTful Web service. */
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LP %.*s\n", len, str);
|
||||
}
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "LQ %.*s\n", len, str);
|
||||
/* CoAP-specific example: actions not required for normal RESTful Web service. */
|
||||
}
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *)request;
|
||||
|
||||
/* Some getters such as for ETag or Location are omitted, as these options should not appear in a request.
|
||||
* Max-Age might appear in HTTP requests or used for special purposes in CoAP. */
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "MA %lu\n", longint);
|
||||
}
|
||||
/* For HTTP this is the Length option, for CoAP it is the Size option. */
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_length(request, &longint)) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "SZ %lu\n", longint);
|
||||
}
|
||||
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UH %.*s\n", len, str);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_url(request, &str))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UP %.*s\n", len, str);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &str))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UQ %.*s\n", len, str);
|
||||
}
|
||||
|
||||
/* Undefined request options for debugging: actions not required for normal RESTful Web service. */
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LP %.*s\n", len, str);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LQ %.*s\n", len, str);
|
||||
}
|
||||
|
||||
/* CoAP-specific example: actions not required for normal RESTful Web service. */
|
||||
coap_packet_t *const coap_pkt = (coap_packet_t *) request;
|
||||
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && coap_pkt->token_len>0) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "To 0x");
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_pkt->token_len > 0) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "To 0x");
|
||||
int index = 0;
|
||||
for(index = 0; index<coap_pkt->token_len; ++index) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%02X", coap_pkt->token[index]);
|
||||
for(index = 0; index < coap_pkt->token_len; ++index) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->token[index]);
|
||||
}
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n");
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n");
|
||||
}
|
||||
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ob %lu\n", coap_pkt->observe);
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "Ob %lu\n", coap_pkt->observe);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "ET 0x");
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "ET 0x");
|
||||
int index = 0;
|
||||
for(index = 0; index<coap_pkt->etag_len; ++index) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%02X", coap_pkt->etag[index]);
|
||||
for(index = 0; index < coap_pkt->etag_len; ++index) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%02X", coap_pkt->etag[index]);
|
||||
}
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n");
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "\n");
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) { /* This getter allows NULL pointers to get only a subset of the block parameters. */
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) { /* This getter allows NULL pointers to get only a subset of the block parameters. */
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
|
||||
}
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size);
|
||||
}
|
||||
|
||||
|
||||
if(strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) {
|
||||
strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s", len, bytes);
|
||||
if(strpos <= REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) {
|
||||
strpos += snprintf((char *)buffer + strpos, REST_MAX_CHUNK_SIZE - strpos + 1, "%.*s", len, bytes);
|
||||
}
|
||||
|
||||
|
||||
if(strpos >= REST_MAX_CHUNK_SIZE) {
|
||||
buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* '»' to indicate truncation */
|
||||
buffer[REST_MAX_CHUNK_SIZE - 1] = 0xBB; /* '»' to indicate truncation */
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
|
||||
PRINTF("/mirror options received: %s\n", buffer);
|
||||
|
|
19
examples/er-rest-example/resources/res-plugtest-create1.c
Executable file → Normal file
19
examples/er-rest-example/resources/res-plugtest-create1.c
Executable file → Normal file
|
@ -41,20 +41,20 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create1,
|
||||
"title=\"Creates on PUT\"",
|
||||
NULL,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler);
|
||||
"title=\"Creates on PUT\"",
|
||||
NULL,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler);
|
||||
|
||||
static uint8_t create1_exists = 0;
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create1 PUT");
|
||||
|
||||
|
@ -70,9 +70,8 @@ res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create1 DELETE ");
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
|
|
14
examples/er-rest-example/resources/res-plugtest-create2.c
Executable file → Normal file
14
examples/er-rest-example/resources/res-plugtest-create2.c
Executable file → Normal file
|
@ -41,17 +41,17 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create2,
|
||||
"title=\"Creates on POST\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Creates on POST\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create2 ");
|
||||
|
||||
|
|
19
examples/er-rest-example/resources/res-plugtest-create3.c
Executable file → Normal file
19
examples/er-rest-example/resources/res-plugtest-create3.c
Executable file → Normal file
|
@ -41,20 +41,20 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_create3,
|
||||
"title=\"Default test resource\"",
|
||||
NULL,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler);
|
||||
"title=\"Default test resource\"",
|
||||
NULL,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler);
|
||||
|
||||
static uint8_t create3_exists = 0;
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create3 PUT ");
|
||||
|
||||
|
@ -70,9 +70,8 @@ res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/create3 DELETE ");
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
|
|
20
examples/er-rest-example/resources/res-plugtest-large-create.c
Executable file → Normal file
20
examples/er-rest-example/resources/res-plugtest-large-create.c
Executable file → Normal file
|
@ -41,22 +41,22 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* Large resource that can be created using POST method
|
||||
*/
|
||||
RESOURCE(res_plugtest_large_create,
|
||||
"title=\"Large resource that can be created using POST method\";rt=\"block\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Large resource that can be created using POST method\";rt=\"block\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
uint8_t *incoming = NULL;
|
||||
size_t len = 0;
|
||||
|
@ -70,12 +70,12 @@ res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t prefer
|
|||
return;
|
||||
}
|
||||
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) {
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) {
|
||||
if(coap_req->block1_num * coap_req->block1_size + len <= 2048) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "/nirvana");
|
||||
coap_set_header_block1(response, coap_req->block1_num, 0,
|
||||
coap_req->block1_size);
|
||||
coap_req->block1_size);
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
const char *error_msg = "2048B max.";
|
||||
|
|
43
examples/er-rest-example/resources/res-plugtest-large-update.c
Executable file → Normal file
43
examples/er-rest-example/resources/res-plugtest-large-update.c
Executable file → Normal file
|
@ -41,23 +41,23 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(
|
||||
res_plugtest_large_update,
|
||||
"title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
NULL);
|
||||
res_plugtest_large_update,
|
||||
"title=\"Large resource that can be updated using PUT method\";rt=\"block\";sz=\"" TO_STRING(MAX_PLUGFEST_BODY) "\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
NULL);
|
||||
|
||||
static int32_t large_update_size = 0;
|
||||
static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 };
|
||||
static unsigned int large_update_ct = APPLICATION_OCTET_STREAM;
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Check the offset for boundaries of the resource data. */
|
||||
if(*offset >= large_update_size) {
|
||||
|
@ -70,7 +70,7 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
|
||||
REST.set_response_payload(response, large_update_store + *offset,
|
||||
MIN(large_update_size - *offset, preferred_size));
|
||||
MIN(large_update_size - *offset, preferred_size));
|
||||
REST.set_header_content_type(response, large_update_ct);
|
||||
|
||||
/* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
|
||||
|
@ -81,11 +81,10 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
*offset = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
uint8_t *incoming = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
|
@ -98,25 +97,25 @@ res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
return;
|
||||
}
|
||||
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **) &incoming))) {
|
||||
if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) {
|
||||
if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) {
|
||||
memcpy(
|
||||
large_update_store + coap_req->block1_num * coap_req->block1_size,
|
||||
incoming, len);
|
||||
large_update_store + coap_req->block1_num * coap_req->block1_size,
|
||||
incoming, len);
|
||||
large_update_size = coap_req->block1_num * coap_req->block1_size + len;
|
||||
large_update_ct = ct;
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
coap_set_header_block1(response, coap_req->block1_num, 0,
|
||||
coap_req->block1_size);
|
||||
coap_req->block1_size);
|
||||
} else {
|
||||
REST.set_response_status(response,
|
||||
REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
REST.status.REQUEST_ENTITY_TOO_LARGE);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.",
|
||||
sizeof(large_update_store)));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.",
|
||||
sizeof(large_update_store)));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
24
examples/er-rest-example/resources/res-plugtest-large.c
Executable file → Normal file
24
examples/er-rest-example/resources/res-plugtest-large.c
Executable file → Normal file
|
@ -41,17 +41,17 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_large,
|
||||
"title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Large resource\";rt=\"block\";sz=\"" TO_STRING(CHUNKS_TOTAL) "\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
int32_t strpos = 0;
|
||||
|
||||
|
@ -67,20 +67,18 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
|
||||
/* Generate data until reaching CHUNKS_TOTAL. */
|
||||
while(strpos < preferred_size) {
|
||||
strpos += snprintf((char *) buffer + strpos, preferred_size - strpos + 1,
|
||||
"|%ld|", *offset);
|
||||
strpos += snprintf((char *)buffer + strpos, preferred_size - strpos + 1,
|
||||
"|%ld|", *offset);
|
||||
}
|
||||
|
||||
/* snprintf() does not adjust return value if truncated by size. */
|
||||
if(strpos > preferred_size) {
|
||||
strpos = preferred_size;
|
||||
/* Truncate if above CHUNKS_TOTAL bytes. */
|
||||
}
|
||||
|
||||
/* Truncate if above CHUNKS_TOTAL bytes. */
|
||||
if(*offset + (int32_t) strpos > CHUNKS_TOTAL) {
|
||||
if(*offset + (int32_t)strpos > CHUNKS_TOTAL) {
|
||||
strpos = CHUNKS_TOTAL - *offset;
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strpos);
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
|
||||
|
|
34
examples/er-rest-example/resources/res-plugtest-links.c
Executable file → Normal file
34
examples/er-rest-example/resources/res-plugtest-links.c
Executable file → Normal file
|
@ -41,29 +41,29 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_link1,
|
||||
"rt=\"Type1 Type2\";if=\"If1\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"rt=\"Type1 Type2\";if=\"If1\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
RESOURCE(res_plugtest_link2,
|
||||
"rt=\"Type2 Type3\";if=\"If2\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"rt=\"Type2 Type3\";if=\"If2\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
RESOURCE(res_plugtest_link3,
|
||||
"rt=\"Type1 Type3\";if=\"foo\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"rt=\"Type1 Type3\";if=\"foo\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
const char *msg = "Dummy link";
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
|
|
18
examples/er-rest-example/resources/res-plugtest-locquery.c
Executable file → Normal file
18
examples/er-rest-example/resources/res-plugtest-locquery.c
Executable file → Normal file
|
@ -41,22 +41,22 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_locquery,
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF(
|
||||
"/location-query POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
"/location-query POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "?first=1&second=2");
|
||||
|
|
26
examples/er-rest-example/resources/res-plugtest-longpath.c
Executable file → Normal file
26
examples/er-rest-example/resources/res-plugtest-longpath.c
Executable file → Normal file
|
@ -41,28 +41,28 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_longpath,
|
||||
"title=\"Long path resource\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Long path resource\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/seg1/seg2/seg3 GET ");
|
||||
/* Code 2.05 CONTENT is default. */
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
|
||||
|
||||
PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
}
|
||||
|
|
38
examples/er-rest-example/resources/res-plugtest-multi.c
Executable file → Normal file
38
examples/er-rest-example/resources/res-plugtest-multi.c
Executable file → Normal file
|
@ -41,42 +41,42 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_multi,
|
||||
"title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Resource providing text/plain and application/xml\";ct=\"0 41\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
PRINTF("/multi-format GET (%s %u) ", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("/multi-format GET (%s %u) ", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
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, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code,
|
||||
coap_req->mid, accept != -1 ? "\nAccept: 0" : ""));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u%s", coap_req->type, coap_req->code,
|
||||
coap_req->mid, accept != -1 ? "\nAccept: 0" : ""));
|
||||
PRINTF("PLAIN\n");
|
||||
} else if(accept == REST.type.APPLICATION_XML) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_XML);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"<status type=\"%u\" code=\"%u\" mid=\"%u\" accept=\"%u\"/>",
|
||||
coap_req->type, coap_req->code, coap_req->mid, accept));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"<status type=\"%u\" code=\"%u\" mid=\"%u\" accept=\"%u\"/>",
|
||||
coap_req->type, coap_req->code, coap_req->mid, accept));
|
||||
PRINTF("XML\n");
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
|
|
40
examples/er-rest-example/resources/res-plugtest-obs.c
Executable file → Normal file
40
examples/er-rest-example/resources/res-plugtest-obs.c
Executable file → Normal file
|
@ -42,19 +42,19 @@
|
|||
#include "er-coap-observe.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_periodic_handler(void);
|
||||
|
||||
PERIODIC_RESOURCE(res_plugtest_obs,
|
||||
"title=\"Observable resource which changes every 5 seconds\";obs",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler,
|
||||
5*CLOCK_SECOND,
|
||||
res_periodic_handler);
|
||||
"title=\"Observable resource which changes every 5 seconds\";obs",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
res_delete_handler,
|
||||
5 * CLOCK_SECOND,
|
||||
res_periodic_handler);
|
||||
|
||||
static int32_t obs_counter = 0;
|
||||
static char obs_content[MAX_PLUGFEST_BODY];
|
||||
|
@ -69,15 +69,13 @@ obs_purge_list()
|
|||
PRINTF("### SERVER ACTION ### Purging obs list");
|
||||
coap_remove_observer_by_uri(NULL, 0, res_plugtest_obs.url);
|
||||
}
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/* Keep server log clean from ticking events */
|
||||
if(request != NULL) {
|
||||
PRINTF("/obs GET\n");
|
||||
}
|
||||
|
||||
REST.set_header_content_type(response, obs_format);
|
||||
REST.set_header_max_age(response, 5);
|
||||
|
||||
|
@ -87,13 +85,12 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
} else {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(response, obs_content,
|
||||
snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter));
|
||||
snprintf(obs_content, MAX_PLUGFEST_PAYLOAD, "TICK %lu", obs_counter));
|
||||
}
|
||||
/* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */
|
||||
}
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
uint8_t *incoming = NULL;
|
||||
unsigned int ct = -1;
|
||||
|
@ -107,16 +104,15 @@ res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
obs_format = ct;
|
||||
} else {
|
||||
obs_content_len = REST.get_request_payload(request,
|
||||
(const uint8_t **) &incoming);
|
||||
(const uint8_t **)&incoming);
|
||||
memcpy(obs_content, incoming, obs_content_len);
|
||||
res_periodic_handler();
|
||||
}
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
}
|
||||
|
||||
static void
|
||||
res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
PRINTF("/obs DELETE\n");
|
||||
|
||||
|
@ -124,7 +120,6 @@ res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t pref
|
|||
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
|
||||
* It will be called by the REST manager process with the defined period.
|
||||
|
@ -134,7 +129,7 @@ res_periodic_handler()
|
|||
{
|
||||
++obs_counter;
|
||||
|
||||
//PRINTF("TICK %u for /%s\n", obs_counter, r->url);
|
||||
/* PRINTF("TICK %u for /%s\n", obs_counter, r->url); */
|
||||
|
||||
if(obs_status == 1) {
|
||||
|
||||
|
@ -156,6 +151,5 @@ res_periodic_handler()
|
|||
} else {
|
||||
/* Notify the registered observers with the given message type, observe option, and payload. */
|
||||
REST.notify_subscribers(&res_plugtest_obs);
|
||||
}
|
||||
obs_status = 0;
|
||||
} obs_status = 0;
|
||||
}
|
||||
|
|
24
examples/er-rest-example/resources/res-plugtest-path.c
Executable file → Normal file
24
examples/er-rest-example/resources/res-plugtest-path.c
Executable file → Normal file
|
@ -41,18 +41,18 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
PARENT_RESOURCE(res_plugtest_path,
|
||||
"title=\"Path test resource\";ct=\"40\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Path test resource\";ct=\"40\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer,
|
||||
uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
|
||||
const char *uri_path = NULL;
|
||||
|
@ -61,12 +61,12 @@ res_get_handler(void* request, void* response, uint8_t *buffer,
|
|||
|
||||
if(len == base_len) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT);
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"</path/sub1>,</path/sub2>,</path/sub3>");
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"</path/sub1>,</path/sub2>,</path/sub3>");
|
||||
} else {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path);
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "/%.*s", len, uri_path);
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *) buffer));
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
}
|
||||
|
|
35
examples/er-rest-example/resources/res-plugtest-query.c
Executable file → Normal file
35
examples/er-rest-example/resources/res-plugtest-query.c
Executable file → Normal file
|
@ -41,35 +41,34 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_query,
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Resource accepting query parameters\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
int len = 0;
|
||||
const char *query = NULL;
|
||||
|
||||
PRINTF(
|
||||
"/query GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
"/query GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if((len = REST.get_query(request, &query))) {
|
||||
PRINTF("Query: %.*s\n", len, query);
|
||||
}
|
||||
|
||||
/* Code 2.05 CONTENT is default. */REST.set_header_content_type(response,
|
||||
REST.type.TEXT_PLAIN);
|
||||
} /* Code 2.05 CONTENT is default. */
|
||||
REST.set_header_content_type(response,
|
||||
REST.type.TEXT_PLAIN);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type,
|
||||
coap_req->code, coap_req->mid, len, query));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u\nQuery: %.*s", coap_req->type,
|
||||
coap_req->code, coap_req->mid, len, query));
|
||||
}
|
||||
|
|
44
examples/er-rest-example/resources/res-plugtest-separate.c
Executable file → Normal file
44
examples/er-rest-example/resources/res-plugtest-separate.c
Executable file → Normal file
|
@ -43,21 +43,20 @@
|
|||
#include "er-coap-separate.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
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);
|
||||
|
||||
PERIODIC_RESOURCE(res_plugtest_separate,
|
||||
"title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
3*CLOCK_SECOND,
|
||||
res_resume_handler);
|
||||
"title=\"Resource which cannot be served immediately and which cannot be acknowledged in a piggy-backed way\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
3 * CLOCK_SECOND,
|
||||
res_resume_handler);
|
||||
|
||||
/* A structure to store the required information */
|
||||
typedef struct application_separate_store
|
||||
{
|
||||
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.: */
|
||||
|
@ -68,9 +67,9 @@ static uint8_t separate_active = 0;
|
|||
static application_separate_store_t separate_store[1];
|
||||
|
||||
void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/separate ");
|
||||
if(separate_active) {
|
||||
|
@ -85,13 +84,12 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
/* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */
|
||||
|
||||
snprintf(separate_store->buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code,
|
||||
coap_req->mid);
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code,
|
||||
coap_req->mid);
|
||||
}
|
||||
|
||||
PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
}
|
||||
|
||||
static void
|
||||
res_resume_handler()
|
||||
{
|
||||
|
@ -99,10 +97,10 @@ res_resume_handler()
|
|||
PRINTF("/separate ");
|
||||
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))) {
|
||||
&separate_store->request_metadata.addr,
|
||||
separate_store->request_metadata.port))) {
|
||||
PRINTF(
|
||||
"RESPONSE (%s %u)\n", separate_store->request_metadata.type==COAP_TYPE_CON?"CON":"NON", separate_store->request_metadata.mid);
|
||||
"RESPONSE (%s %u)\n", separate_store->request_metadata.type == COAP_TYPE_CON ? "CON" : "NON", separate_store->request_metadata.mid);
|
||||
|
||||
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
|
||||
|
@ -111,19 +109,19 @@ res_resume_handler()
|
|||
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
coap_set_payload(response, separate_store->buffer,
|
||||
strlen(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);
|
||||
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);
|
||||
transaction->packet);
|
||||
coap_send_transaction(transaction);
|
||||
/* The engine will clear the transaction (right after send for NON, after acked for CON). */
|
||||
|
||||
|
|
107
examples/er-rest-example/resources/res-plugtest-test.c
Executable file → Normal file
107
examples/er-rest-example/resources/res-plugtest-test.c
Executable file → Normal file
|
@ -41,10 +41,10 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_test, "title=\"Default test resource\"", res_get_handler, res_post_handler, res_put_handler, res_delete_handler);
|
||||
|
||||
|
@ -68,21 +68,19 @@ test_update_etag()
|
|||
|
||||
PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", test_etag_len, test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]);
|
||||
}
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
if(test_change) {
|
||||
test_update_etag();
|
||||
}
|
||||
|
||||
PRINTF("/test GET (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("/test GET (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if((len = coap_get_header_etag(request, &bytes)) > 0
|
||||
&& len == test_etag_len
|
||||
&& memcmp(test_etag, bytes, len) == 0) {
|
||||
&& len == test_etag_len
|
||||
&& memcmp(test_etag, bytes, len) == 0) {
|
||||
PRINTF("validate ");
|
||||
REST.set_response_status(response, REST.status.NOT_MODIFIED);
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
|
@ -95,70 +93,67 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
REST.set_header_max_age(response, 30);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code, coap_req->mid));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/test POST (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("/test POST (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
REST.set_header_location(response, "/location1/location2/location3");
|
||||
}
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/test PUT (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("/test PUT (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if(coap_get_header_if_none_match(request)) {
|
||||
if(test_none_match_okay) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
if(coap_get_header_if_none_match(request)) {
|
||||
if(test_none_match_okay) {
|
||||
REST.set_response_status(response, REST.status.CREATED);
|
||||
|
||||
test_none_match_okay = 0;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n");
|
||||
} else {
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
|
||||
test_none_match_okay = 1;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n");
|
||||
}
|
||||
} else if(((len = coap_get_header_if_match(request, &bytes)) > 0
|
||||
&& (len == test_etag_len
|
||||
&& memcmp(test_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
test_update_etag();
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
|
||||
if(len > 0) {
|
||||
test_change = 1;
|
||||
PRINTF("### SERVER ACTION ### Resource will change\n");
|
||||
}
|
||||
test_none_match_okay = 0;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will FAIL\n");
|
||||
} else {
|
||||
PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
|
||||
len,
|
||||
test_etag_len,
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]);
|
||||
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
|
||||
test_none_match_okay = 1;
|
||||
PRINTF("### SERVER ACTION ### If-None-Match will SUCCEED\n");
|
||||
}
|
||||
} else if(((len = coap_get_header_if_match(request, &bytes)) > 0
|
||||
&& (len == test_etag_len
|
||||
&& memcmp(test_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
test_update_etag();
|
||||
REST.set_header_etag(response, test_etag, test_etag_len);
|
||||
|
||||
REST.set_response_status(response, REST.status.CHANGED);
|
||||
|
||||
if(len > 0) {
|
||||
test_change = 1;
|
||||
PRINTF("### SERVER ACTION ### Resource will change\n");
|
||||
}
|
||||
} else {
|
||||
PRINTF("Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
|
||||
len,
|
||||
test_etag_len,
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
test_etag[0], test_etag[1], test_etag[2], test_etag[3], test_etag[4], test_etag[5], test_etag[6], test_etag[7]);
|
||||
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_delete_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_delete_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/test DELETE (%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("/test DELETE (%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
REST.set_response_status(response, REST.status.DELETED);
|
||||
}
|
||||
|
|
58
examples/er-rest-example/resources/res-plugtest-validate.c
Executable file → Normal file
58
examples/er-rest-example/resources/res-plugtest-validate.c
Executable file → Normal file
|
@ -41,21 +41,20 @@
|
|||
#include "er-coap.h"
|
||||
#include "er-plugtest.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
RESOURCE(res_plugtest_validate,
|
||||
"title=\"Validation test resource\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
NULL);
|
||||
"title=\"Validation test resource\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
res_put_handler,
|
||||
NULL);
|
||||
|
||||
static uint8_t validate_etag[8] = { 0 };
|
||||
static uint8_t validate_etag_len = 1;
|
||||
static uint8_t validate_change = 1;
|
||||
|
||||
|
||||
static const uint8_t *bytes = NULL;
|
||||
static size_t len = 0;
|
||||
|
||||
|
@ -70,23 +69,21 @@ validate_update_etag()
|
|||
validate_change = 0;
|
||||
|
||||
PRINTF("### SERVER ACTION ### Changed ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
|
||||
validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
validate_etag_len, validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
}
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
if(validate_change) {
|
||||
validate_update_etag();
|
||||
}
|
||||
|
||||
PRINTF("/validate GET");
|
||||
PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if((len = coap_get_header_etag(request, &bytes)) > 0
|
||||
&& len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) {
|
||||
&& len == validate_etag_len && memcmp(validate_etag, bytes, len) == 0) {
|
||||
PRINTF("validate ");
|
||||
REST.set_response_status(response, REST.status.NOT_MODIFIED);
|
||||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
|
@ -99,26 +96,25 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
REST.set_header_max_age(response, 30);
|
||||
REST.set_response_payload(
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *) buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code,
|
||||
coap_req->mid));
|
||||
response,
|
||||
buffer,
|
||||
snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD,
|
||||
"Type: %u\nCode: %u\nMID: %u", coap_req->type, coap_req->code,
|
||||
coap_req->mid));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
coap_packet_t * const coap_req = (coap_packet_t *) request;
|
||||
coap_packet_t *const coap_req = (coap_packet_t *)request;
|
||||
|
||||
PRINTF("/validate PUT ");
|
||||
PRINTF("(%s %u)\n", coap_req->type==COAP_TYPE_CON?"CON":"NON", coap_req->mid);
|
||||
PRINTF("(%s %u)\n", coap_req->type == COAP_TYPE_CON ? "CON" : "NON", coap_req->mid);
|
||||
|
||||
if(((len = coap_get_header_if_match(request, &bytes)) > 0
|
||||
&& (len == validate_etag_len
|
||||
&& memcmp(validate_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
&& memcmp(validate_etag, bytes, len) == 0))
|
||||
|| len == 0) {
|
||||
validate_update_etag();
|
||||
REST.set_header_etag(response, validate_etag, validate_etag_len);
|
||||
|
||||
|
@ -130,11 +126,11 @@ res_put_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
}
|
||||
} else {
|
||||
PRINTF(
|
||||
"Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ",
|
||||
len,
|
||||
validate_etag_len,
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
"Check %u/%u\n [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n [0x%02X%02X%02X%02X%02X%02X%02X%02X] ",
|
||||
len,
|
||||
validate_etag_len,
|
||||
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
|
||||
validate_etag[0], validate_etag[1], validate_etag[2], validate_etag[3], validate_etag[4], validate_etag[5], validate_etag[6], validate_etag[7]);
|
||||
|
||||
REST.set_response_status(response, PRECONDITION_FAILED_4_12);
|
||||
}
|
||||
|
|
21
examples/er-rest-example/resources/res-push.c
Executable file → Normal file
21
examples/er-rest-example/resources/res-push.c
Executable file → Normal file
|
@ -40,17 +40,17 @@
|
|||
#include "rest-engine.h"
|
||||
#include "er-coap.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_periodic_handler(void);
|
||||
|
||||
PERIODIC_RESOURCE(res_push,
|
||||
"title=\"Periodic demo\";obs",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
5*CLOCK_SECOND,
|
||||
res_periodic_handler);
|
||||
"title=\"Periodic demo\";obs",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
5 * CLOCK_SECOND,
|
||||
res_periodic_handler);
|
||||
|
||||
/*
|
||||
* Use local resource state that is accessed by res_get_handler() and altered by res_periodic_handler() or PUT or POST.
|
||||
|
@ -58,7 +58,7 @@ PERIODIC_RESOURCE(res_push,
|
|||
static int32_t event_counter = 0;
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/*
|
||||
* For minimal complexity, request query and options should be ignored for GET on observable resources.
|
||||
|
@ -66,12 +66,11 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
* This would be a TODO in the corresponding files in contiki/apps/erbium/!
|
||||
*/
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
REST.set_header_max_age(response, res_push.periodic->period/CLOCK_SECOND);
|
||||
REST.set_header_max_age(response, res_push.periodic->period / CLOCK_SECOND);
|
||||
REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "VERY LONG EVENT %lu", event_counter));
|
||||
|
||||
/* The REST.subscription_handler() will be called for observable resources by the REST framework. */
|
||||
}
|
||||
|
||||
/*
|
||||
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
|
||||
* It will be called by the REST manager process with the defined period.
|
||||
|
|
30
examples/er-rest-example/resources/res-radio.c
Executable file → Normal file
30
examples/er-rest-example/resources/res-radio.c
Executable file → Normal file
|
@ -44,18 +44,18 @@
|
|||
#include "rest-engine.h"
|
||||
#include "dev/radio-sensor.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple getter example. Returns the reading of the rssi/lqi from radio sensor */
|
||||
RESOURCE(res_radio,
|
||||
"title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"RADIO: ?p=lqi|rssi\";rt=\"RadioSensor\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char *p = NULL;
|
||||
|
@ -65,25 +65,23 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
unsigned int accept = -1;
|
||||
REST.get_header_accept(request, &accept);
|
||||
|
||||
if((len=REST.get_query_variable(request, "p", &p))) {
|
||||
if(strncmp(p, "lqi", len)==0) {
|
||||
if((len = REST.get_query_variable(request, "p", &p))) {
|
||||
if(strncmp(p, "lqi", len) == 0) {
|
||||
param = RADIO_SENSOR_LAST_VALUE;
|
||||
} else if(strncmp(p,"rssi", len)==0) {
|
||||
} else if(strncmp(p, "rssi", len) == 0) {
|
||||
param = RADIO_SENSOR_LAST_PACKET;
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
} else {
|
||||
success = 0;
|
||||
}
|
||||
|
||||
if(success) {
|
||||
if(accept==-1 || accept==REST.type.TEXT_PLAIN) {
|
||||
} if(success) {
|
||||
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", radio_sensor.value(param));
|
||||
|
||||
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
|
||||
} else if(accept==REST.type.APPLICATION_JSON) {
|
||||
} else if(accept == REST.type.APPLICATION_JSON) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
|
||||
if(param == RADIO_SENSOR_LAST_VALUE) {
|
||||
|
@ -91,7 +89,6 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
} else if(param == RADIO_SENSOR_LAST_PACKET) {
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'rssi':%d}", radio_sensor.value(param));
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
} else {
|
||||
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
|
||||
|
@ -102,5 +99,4 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
REST.set_response_status(response, REST.status.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_HAS_RADIO */
|
||||
|
|
24
examples/er-rest-example/resources/res-separate.c
Executable file → Normal file
24
examples/er-rest-example/resources/res-separate.c
Executable file → Normal file
|
@ -41,16 +41,16 @@
|
|||
#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_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);
|
||||
"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 {
|
||||
|
@ -60,7 +60,6 @@ typedef struct application_separate_store {
|
|||
|
||||
/* 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
|
||||
|
@ -69,13 +68,13 @@ 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)
|
||||
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) {
|
||||
if(separate_active >= COAP_MAX_OPEN_SEPARATE) {
|
||||
coap_separate_reject();
|
||||
} else {
|
||||
++separate_active;
|
||||
|
@ -92,13 +91,12 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
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)) ) {
|
||||
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. */
|
||||
|
@ -117,7 +115,7 @@ res_resume_handler()
|
|||
coap_send_transaction(transaction);
|
||||
/* The engine will clear the transaction (right after send for NON, after acked for CON). */
|
||||
|
||||
//FIXME there could me more!
|
||||
/* FIXME there could me more! */
|
||||
separate_active = 0;
|
||||
} else {
|
||||
/*
|
||||
|
|
22
examples/er-rest-example/resources/res-sub.c
Executable file → Normal file
22
examples/er-rest-example/resources/res-sub.c
Executable file → Normal file
|
@ -39,21 +39,21 @@
|
|||
#include <string.h>
|
||||
#include "rest-engine.h"
|
||||
|
||||
static void res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/*
|
||||
* Example for a resource that also handles all its sub-resources.
|
||||
* Use REST.get_url() to multiplex the handling of the request depending on the Uri-Path.
|
||||
*/
|
||||
PARENT_RESOURCE(res_sub,
|
||||
"title=\"Sub-resource demo\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Sub-resource demo\"",
|
||||
res_get_handler,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
|
||||
|
||||
|
@ -61,11 +61,9 @@ res_get_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
int len = REST.get_url(request, &uri_path);
|
||||
int base_len = strlen(res_sub.url);
|
||||
|
||||
if(len==base_len) {
|
||||
if(len == base_len) {
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Request any sub-resource of /%s", res_sub.url);
|
||||
} else {
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len-base_len, uri_path+base_len);
|
||||
}
|
||||
|
||||
REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, ".%.*s", len - base_len, uri_path + base_len);
|
||||
} REST.set_response_payload(response, buffer, strlen((char *)buffer));
|
||||
}
|
||||
|
|
15
examples/er-rest-example/resources/res-toggle.c
Executable file → Normal file
15
examples/er-rest-example/resources/res-toggle.c
Executable file → Normal file
|
@ -45,20 +45,19 @@
|
|||
#include "rest-engine.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
static void res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
static void res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
|
||||
|
||||
/* A simple actuator example. Toggles the red led */
|
||||
RESOURCE(res_toggle,
|
||||
"title=\"Red LED\";rt=\"Control\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
"title=\"Red LED\";rt=\"Control\"",
|
||||
NULL,
|
||||
res_post_handler,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
static void
|
||||
res_post_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
res_post_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
leds_invert(LEDS_RED);
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_HAS_LEDS */
|
||||
|
|
Loading…
Reference in a new issue