Merge branch 'master' of ssh://contiki.git.sourceforge.net/gitroot/contiki/contiki
This commit is contained in:
commit
485ef0cd79
|
@ -206,7 +206,7 @@ handle_incoming_data(void)
|
|||
}
|
||||
|
||||
} else {
|
||||
error = MEMORY_ALLOC_ERR;
|
||||
error = MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -58,7 +58,7 @@ LIST(observers_list);
|
|||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
coap_observer_t *
|
||||
coap_add_observer(const char *url, uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len)
|
||||
coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url)
|
||||
{
|
||||
coap_observer_t *o = memb_alloc(&observers_memb);
|
||||
|
||||
|
@ -173,7 +173,7 @@ coap_observe_handler(resource_t *resource, void *request, void *response)
|
|||
{
|
||||
if (IS_OPTION((coap_packet_t *)request, COAP_OPTION_TOKEN))
|
||||
{
|
||||
if (coap_add_observer(resource->url, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, ((coap_packet_t *)request)->token, ((coap_packet_t *)request)->token_len))
|
||||
if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, ((coap_packet_t *)request)->token, ((coap_packet_t *)request)->token_len, resource->url))
|
||||
{
|
||||
coap_set_header_observe(response, 0);
|
||||
coap_set_payload(response, (uint8_t *)content, snprintf(content, sizeof(content), "Added as observer %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS));
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef struct coap_observer {
|
|||
} coap_observer_t;
|
||||
|
||||
list_t coap_get_observers(void);
|
||||
coap_observer_t *coap_add_observer(const char *url, 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);
|
||||
|
|
|
@ -745,7 +745,7 @@ coap_set_header_uri_query(void *packet, const char *query)
|
|||
/*- PAYLOAD -------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
int
|
||||
coap_get_payload(void *packet, const uint8_t **payload)
|
||||
coap_get_payload(void *packet, uint8_t **payload)
|
||||
{
|
||||
if (((coap_packet_t *)packet)->payload) {
|
||||
*payload = ((coap_packet_t *)packet)->payload;
|
||||
|
@ -757,11 +757,11 @@ coap_get_payload(void *packet, const uint8_t **payload)
|
|||
}
|
||||
|
||||
int
|
||||
coap_set_payload(void *packet, uint8_t *payload, size_t length)
|
||||
coap_set_payload(void *packet, const void *payload, size_t length)
|
||||
{
|
||||
PRINTF("setting payload (%u/%u)\n", length, REST_MAX_CHUNK_SIZE);
|
||||
|
||||
((coap_packet_t *)packet)->payload = payload;
|
||||
((coap_packet_t *)packet)->payload = (uint8_t *) payload;
|
||||
((coap_packet_t *)packet)->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
|
||||
|
||||
return ((coap_packet_t *)packet)->payload_len;
|
||||
|
|
|
@ -226,7 +226,7 @@ typedef enum
|
|||
NO_ERROR,
|
||||
|
||||
/* Memory errors */
|
||||
MEMORY_ALLOC_ERR,
|
||||
MEMORY_ALLOCATION_ERROR,
|
||||
MEMORY_BOUNDARY_EXCEEDED,
|
||||
|
||||
/* CoAP errors */
|
||||
|
@ -278,7 +278,7 @@ int coap_set_header_block(void *packet, uint32_t num, uint8_t more, uint16_t siz
|
|||
int coap_get_header_uri_query(void *packet, const char **query); /*CAUTION in-place string might not be 0-terminated */
|
||||
int coap_set_header_uri_query(void *packet, const char *query);
|
||||
|
||||
int coap_get_payload(void *packet, const uint8_t **payload);
|
||||
int coap_set_payload(void *packet, uint8_t *payload, size_t length);
|
||||
int coap_get_payload(void *packet, uint8_t **payload);
|
||||
int coap_set_payload(void *packet, const void *payload, size_t length);
|
||||
|
||||
#endif /* COAP_03_H_ */
|
||||
|
|
|
@ -100,7 +100,7 @@ handle_incoming_data(void)
|
|||
if (coap_error_code==NO_ERROR)
|
||||
{
|
||||
|
||||
/*TODO duplicates suppression, if required */
|
||||
/*TODO duplicates suppression, if required by application */
|
||||
|
||||
PRINTF(" Parsed: v %u, t %u, oc %u, c %u, mid %u\n", message->version, message->type, message->option_count, message->code, message->mid);
|
||||
PRINTF(" URL: %.*s\n", message->uri_path_len, message->uri_path);
|
||||
|
@ -112,10 +112,10 @@ handle_incoming_data(void)
|
|||
/* Use transaction buffer for response to confirmable request. */
|
||||
if ( (transaction = coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) )
|
||||
{
|
||||
static uint32_t block_num = 0;
|
||||
static uint16_t block_size = REST_MAX_CHUNK_SIZE;
|
||||
static uint32_t block_offset = 0;
|
||||
static int32_t new_offset = 0;
|
||||
uint32_t block_num = 0;
|
||||
uint16_t block_size = REST_MAX_CHUNK_SIZE;
|
||||
uint32_t block_offset = 0;
|
||||
int32_t new_offset = 0;
|
||||
|
||||
/* prepare response */
|
||||
if (message->type==COAP_TYPE_CON)
|
||||
|
@ -143,17 +143,14 @@ handle_incoming_data(void)
|
|||
block_size = MIN(block_size, REST_MAX_CHUNK_SIZE);
|
||||
new_offset = block_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
block_size = REST_MAX_CHUNK_SIZE;
|
||||
new_offset = 0;
|
||||
}
|
||||
|
||||
/* Invoke resource handler. */
|
||||
if (service_cbk)
|
||||
{
|
||||
/* Call REST framework and check if found and allowed. */
|
||||
if (service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset))
|
||||
{
|
||||
if (coap_error_code==NO_ERROR)
|
||||
{
|
||||
/* Apply blockwise transfers. */
|
||||
if ( IS_OPTION(message, COAP_OPTION_BLOCK2) )
|
||||
|
@ -190,22 +187,27 @@ handle_incoming_data(void)
|
|||
coap_set_header_block2(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE);
|
||||
coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE));
|
||||
} /* if (blockwise request) */
|
||||
} /* no errors/hooks */
|
||||
} /* successful service callback */
|
||||
|
||||
/* Serialize response. */
|
||||
if (coap_error_code==NO_ERROR)
|
||||
{
|
||||
if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0)
|
||||
{
|
||||
coap_error_code = PACKET_SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
coap_error_code = INTERNAL_SERVER_ERROR_5_00;
|
||||
coap_error_message = "Service callback undefined";
|
||||
} /* if (service callback) */
|
||||
|
||||
/* serialize Response. */
|
||||
if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0)
|
||||
{
|
||||
coap_error_code = PACKET_SERIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
coap_error_code = MEMORY_ALLOC_ERR;
|
||||
coap_error_code = MEMORY_ALLOCATION_ERROR;
|
||||
coap_error_message = "Transaction buffer allocation failed";
|
||||
} /* if (transaction buffer) */
|
||||
}
|
||||
|
@ -221,11 +223,7 @@ handle_incoming_data(void)
|
|||
{
|
||||
PRINTF("Received RST\n");
|
||||
/* Cancel possible subscriptions. */
|
||||
if (IS_OPTION(message, COAP_OPTION_TOKEN))
|
||||
{
|
||||
PRINTF(" Token 0x%02X%02X\n", message->token[0], message->token[1]);
|
||||
coap_remove_observer_by_token(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->token, message->token_len);
|
||||
}
|
||||
coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->mid);
|
||||
}
|
||||
|
||||
if ( (transaction = coap_get_transaction_by_mid(message->mid)) )
|
||||
|
@ -241,12 +239,20 @@ handle_incoming_data(void)
|
|||
}
|
||||
} /* if (ACKed transaction) */
|
||||
transaction = NULL;
|
||||
}
|
||||
|
||||
} /* Request or Response */
|
||||
|
||||
} /* if (parsed correctly) */
|
||||
|
||||
if (coap_error_code==NO_ERROR) {
|
||||
if (coap_error_code==NO_ERROR)
|
||||
{
|
||||
if (transaction) coap_send_transaction(transaction);
|
||||
}
|
||||
else if (coap_error_code==MANUAL_RESPONSE)
|
||||
{
|
||||
PRINTF("Clearing transaction for manual response");
|
||||
coap_clear_transaction(transaction);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINTF("ERROR %u: %s\n", coap_error_code, coap_error_message);
|
||||
|
|
|
@ -58,7 +58,7 @@ LIST(observers_list);
|
|||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
coap_observer_t *
|
||||
coap_add_observer(const char *url, uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len)
|
||||
coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len, const char *url)
|
||||
{
|
||||
coap_observer_t *o = memb_alloc(&observers_memb);
|
||||
|
||||
|
@ -69,6 +69,7 @@ coap_add_observer(const char *url, uip_ipaddr_t *addr, uint16_t port, const uint
|
|||
o->port = port;
|
||||
o->token_len = token_len;
|
||||
memcpy(o->token, token, token_len);
|
||||
o->last_mid = 0;
|
||||
|
||||
stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL);
|
||||
|
||||
|
@ -107,6 +108,7 @@ coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port)
|
|||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
int
|
||||
coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token, size_t token_len)
|
||||
{
|
||||
|
@ -116,7 +118,7 @@ coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token,
|
|||
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 && memcmp(obs->token, token, token_len)==0)
|
||||
if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->token_len==token_len && memcmp(obs->token, token, token_len)==0)
|
||||
{
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
|
@ -124,8 +126,9 @@ coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, uint8_t *token,
|
|||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
int
|
||||
coap_remove_observer_by_url(const char *url)
|
||||
coap_remove_observer_by_url(uip_ipaddr_t *addr, uint16_t port, const char *url)
|
||||
{
|
||||
int removed = 0;
|
||||
coap_observer_t* obs = NULL;
|
||||
|
@ -133,7 +136,25 @@ coap_remove_observer_by_url(const char *url)
|
|||
for (obs = (coap_observer_t*)list_head(observers_list); obs; obs = obs->next)
|
||||
{
|
||||
PRINTF("Remove check URL %p\n", url);
|
||||
if (obs->url==url || memcmp(obs->url, url, strlen(obs->url))==0)
|
||||
if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && (obs->url==url || memcmp(obs->url, url, strlen(obs->url))==0))
|
||||
{
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
int
|
||||
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; obs = obs->next)
|
||||
{
|
||||
PRINTF("Remove check MID %u\n", mid);
|
||||
if (uip_ipaddr_cmp(&obs->addr, addr) && obs->port==port && obs->last_mid==mid)
|
||||
{
|
||||
coap_remove_observer(obs);
|
||||
removed++;
|
||||
|
@ -177,6 +198,9 @@ coap_notify_observers(const char *url, int type, uint32_t observe, uint8_t *payl
|
|||
PRINTF(":%u\n", obs->port);
|
||||
PRINTF(" %.*s\n", payload_len, payload);
|
||||
|
||||
/* Update last MID for RST matching. */
|
||||
obs->last_mid = transaction->mid;
|
||||
|
||||
coap_send_transaction(transaction);
|
||||
}
|
||||
}
|
||||
|
@ -189,17 +213,21 @@ 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;
|
||||
|
||||
static char content[26];
|
||||
static char content[16];
|
||||
|
||||
if (coap_res && coap_res->code<128) /* response without error code */
|
||||
if (coap_req->code==COAP_GET && coap_res->code<128) /* GET request and response without error code */
|
||||
{
|
||||
if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE))
|
||||
{
|
||||
|
||||
if (coap_add_observer(resource->url, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len))
|
||||
if (coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, coap_req->token, coap_req->token_len, resource->url))
|
||||
{
|
||||
coap_set_header_observe(coap_res, 0);
|
||||
coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added as observer %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS));
|
||||
/*
|
||||
* For demonstration purposes only. A subscription should return the same representation as a normal GET.
|
||||
* TODO: Comment the following line for any real application.
|
||||
*/
|
||||
coap_set_payload(coap_res, content, snprintf(content, sizeof(content), "Added %u/%u", list_length(observers_list), COAP_MAX_OBSERVERS));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -210,7 +238,7 @@ coap_observe_handler(resource_t *resource, void *request, void *response)
|
|||
else /* if (observe) */
|
||||
{
|
||||
/* Remove client if it is currently observing. */
|
||||
coap_remove_observer_by_client(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport);
|
||||
coap_remove_observer_by_url(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, resource->url);
|
||||
} /* if (observe) */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,17 +61,19 @@ typedef struct coap_observer {
|
|||
uint16_t port;
|
||||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
uint16_t last_mid;
|
||||
struct stimer refresh_timer;
|
||||
} coap_observer_t;
|
||||
|
||||
list_t coap_get_observers(void);
|
||||
|
||||
coap_observer_t *coap_add_observer(const char *url, uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, size_t token_len);
|
||||
void coap_remove_observer(coap_observer_t *o);
|
||||
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_url(const char *url);
|
||||
int coap_remove_observer_by_url(uip_ipaddr_t *addr, uint16_t port, const char *url);
|
||||
int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid);
|
||||
|
||||
void coap_notify_observers(const char *url, int type, uint32_t observe, uint8_t *payload, size_t payload_len);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "er-coap-07-separate.h"
|
||||
#include "er-coap-07-transactions.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
|
@ -53,20 +54,66 @@
|
|||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void coap_separate_handler(resource_t *resource, void *request, void *response)
|
||||
int coap_separate_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;
|
||||
|
||||
PRINTF("Separate response for /%s \n", resource->url);
|
||||
PRINTF("Separate response for /%s MID %u\n", resource->url, coap_res->mid);
|
||||
|
||||
/* Only ack CON requests. */
|
||||
if (coap_req->type==COAP_TYPE_CON)
|
||||
{
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_res->mid);
|
||||
|
||||
/* send separate ACK. */
|
||||
coap_packet_t ack[1];
|
||||
/* ACK with empty code (0) */
|
||||
coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
|
||||
/* Should only overwrite Header which is already parsed to request. */
|
||||
coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata + uip_ext_len), coap_serialize_message(ack, (uip_appdata + uip_ext_len)));
|
||||
/* Serializing into IPBUF: Only overwrites header parts that are already parsed into the request struct. */
|
||||
coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, (uip_appdata), coap_serialize_message(ack, uip_appdata));
|
||||
|
||||
/* Change response to separate response. */
|
||||
coap_res->type = COAP_TYPE_CON;
|
||||
coap_res->mid = coap_get_mid();
|
||||
|
||||
/* Update MID in transaction for identification. */
|
||||
t->mid = coap_res->mid;
|
||||
}
|
||||
|
||||
/* Pre-handlers could skip the handling by returning 0. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
coap_separate_response(void *response, coap_separate_t *separate_store)
|
||||
{
|
||||
coap_packet_t *const coap_res = (coap_packet_t *) response;
|
||||
coap_transaction_t *const t = coap_get_transaction_by_mid(coap_res->mid);
|
||||
|
||||
if (t)
|
||||
{
|
||||
uip_ipaddr_copy(&separate_store->addr, &t->addr);
|
||||
separate_store->port = t->port;
|
||||
|
||||
separate_store->mid = coap_res->mid;
|
||||
separate_store->type = coap_res->type;
|
||||
|
||||
memcpy(separate_store->token, coap_res->token, coap_res->token_len);
|
||||
separate_store->token_len = coap_res->token_len;
|
||||
|
||||
separate_store->block2_num = coap_res->block2_num;
|
||||
separate_store->block2_more = coap_res->block2_more;
|
||||
separate_store->block2_size = coap_res->block2_size;
|
||||
separate_store->block2_offset = coap_res->block2_offset;
|
||||
|
||||
/* Signal the engine to skip automatic response and clear transaction by engine. */
|
||||
coap_error_code = MANUAL_RESPONSE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,28 @@
|
|||
|
||||
#include "er-coap-07.h"
|
||||
|
||||
void coap_separate_handler(resource_t *resource, void *request, void *response);
|
||||
typedef struct coap_separate {
|
||||
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
|
||||
coap_message_type_t type;
|
||||
uint16_t mid;
|
||||
|
||||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
|
||||
uint32_t block2_num;
|
||||
uint8_t block2_more;
|
||||
uint16_t block2_size;
|
||||
uint32_t block2_offset;
|
||||
|
||||
/* Add fields for addition information to be saved here, e.g.: */
|
||||
char buffer[17];
|
||||
|
||||
} coap_separate_t;
|
||||
|
||||
int coap_separate_handler(resource_t *resource, void *request, void *response);
|
||||
int coap_separate_response(void *response, coap_separate_t *separate_store);
|
||||
|
||||
#endif /* COAP_SEPARATE_H_ */
|
||||
|
|
|
@ -87,6 +87,8 @@ coap_new_transaction(uint16_t mid, uip_ipaddr_t *addr, uint16_t port)
|
|||
/* save client address */
|
||||
uip_ipaddr_copy(&t->addr, addr);
|
||||
t->port = port;
|
||||
|
||||
list_add(transactions_list, t); /* List itself makes sure same element is not added twice. */
|
||||
}
|
||||
|
||||
return t;
|
||||
|
@ -122,8 +124,6 @@ coap_send_transaction(coap_transaction_t *t)
|
|||
etimer_restart(&t->retrans_timer); /* interval updated above */
|
||||
process_current = process_actual;
|
||||
|
||||
list_add(transactions_list, t); /* List itself makes sure same element is not added twice. */
|
||||
|
||||
t = NULL;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -140,15 +140,13 @@ typedef enum {
|
|||
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
|
||||
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
|
||||
|
||||
/* Memory errors */
|
||||
IMPLEMENTATION_ERROR = 192,
|
||||
MEMORY_ALLOC_ERR = 193,
|
||||
MEMORY_BOUNDARY_EXCEEDED = 194,
|
||||
/* Erbium errors */
|
||||
MEMORY_ALLOCATION_ERROR = 192,
|
||||
PACKET_SERIALIZATION_ERROR,
|
||||
|
||||
/* Erbium hooks */
|
||||
MANUAL_RESPONSE
|
||||
|
||||
/* CoAP errors */
|
||||
UNIMPLEMENTED_CRITICAL_OPTION,
|
||||
UNKNOWN_CRITICAL_OPTION,
|
||||
PACKET_SERIALIZATION_ERROR
|
||||
} coap_status_t;
|
||||
|
||||
/* CoAP header options */
|
||||
|
|
|
@ -60,7 +60,7 @@ LIST(restful_periodic_services);
|
|||
|
||||
|
||||
void
|
||||
rest_init_framework(void)
|
||||
rest_init_engine(void)
|
||||
{
|
||||
list_init(restful_services);
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ periodic_resource_t periodic_resource_##name = {NULL, &resource_##name, period,
|
|||
/*
|
||||
* Initializes REST framework and starts HTTP or COAP process
|
||||
*/
|
||||
void rest_init_framework(void);
|
||||
void rest_init_engine(void);
|
||||
|
||||
/*
|
||||
* Resources wanted to be accessible should be activated with the following code.
|
||||
|
|
|
@ -283,7 +283,7 @@ generate_file_stats(void *arg)
|
|||
{
|
||||
struct httpd_state *s = (struct httpd_state *)arg;
|
||||
#if WEBSERVER_CONF_LOADTIME
|
||||
static const char httpd_cgi_filestat1[] HTTPD_STRING_ATTR = "<p align=\"right\"><br><br><i>This page has been sent %u times (%1u.%u sec)</i></body></html>";
|
||||
static const char httpd_cgi_filestat1[] HTTPD_STRING_ATTR = "<p align=\"right\"><br><br><i>This page has been sent %u times (%1u.%02u sec)</i></body></html>";
|
||||
#else
|
||||
static const char httpd_cgi_filestat1[] HTTPD_STRING_ATTR = "<p align=\"right\"><br><br><i>This page has been sent %u times</i></body></html>";
|
||||
#endif
|
||||
|
@ -301,7 +301,7 @@ generate_file_stats(void *arg)
|
|||
#if WEBSERVER_CONF_LOADTIME
|
||||
s->pagetime = clock_time() - s->pagetime;
|
||||
numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat1, httpd_fs_open(s->filename, 0),
|
||||
(unsigned int)s->pagetime/CLOCK_SECOND,(unsigned int)s->pagetime%CLOCK_SECOND);
|
||||
(unsigned int)s->pagetime/CLOCK_SECOND,(100*((unsigned int)s->pagetime%CLOCK_SECOND))/CLOCK_SECOND);
|
||||
#else
|
||||
numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat1, httpd_fs_open(s->filename, 0));
|
||||
#endif
|
||||
|
@ -433,10 +433,12 @@ PT_THREAD(processes(struct httpd_state *s, char *ptr))
|
|||
#endif /* WEBSERVER_CONF_PROCESSES */
|
||||
|
||||
#if WEBSERVER_CONF_ADDRESSES || WEBSERVER_CONF_NEIGHBORS || WEBSERVER_CONF_ROUTES
|
||||
static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = "<code>";
|
||||
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "</code>[Room for %u more]";
|
||||
static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "<br>";
|
||||
static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)<br>";
|
||||
#if WEBSERVER_CONF_SHOW_ROOM
|
||||
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "[Room for %u more]\n";
|
||||
#else
|
||||
static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "[Table is full]\n";
|
||||
#endif
|
||||
static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "[None]\n";
|
||||
#endif
|
||||
|
||||
#if WEBSERVER_CONF_ADDRESSES
|
||||
|
@ -447,16 +449,21 @@ static unsigned short
|
|||
make_addresses(void *p)
|
||||
{
|
||||
uint8_t i,j=0;
|
||||
uint16_t numprinted;
|
||||
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
||||
uint16_t numprinted = 0;
|
||||
for (i=0; i<UIP_DS6_ADDR_NB;i++) {
|
||||
if (uip_ds6_if.addr_list[i].isused) {
|
||||
j++;
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr, uip_appdata + numprinted);
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb);
|
||||
*((char *)uip_appdata+numprinted++) = '\n';
|
||||
}
|
||||
}
|
||||
#if WEBSERVER_CONF_SHOW_ROOM
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf, UIP_DS6_ADDR_NB-j);
|
||||
#else
|
||||
if(UIP_DS6_ADDR_NB == j) {
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf);
|
||||
}
|
||||
#endif
|
||||
return numprinted;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -477,17 +484,55 @@ extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
|
|||
static unsigned short
|
||||
make_neighbors(void *p)
|
||||
{
|
||||
uint8_t i,j=0;
|
||||
uint16_t numprinted;
|
||||
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
||||
for (i=0; i<UIP_DS6_NBR_NB;i++) {
|
||||
uint8_t i,j;
|
||||
uint16_t numprinted=0;
|
||||
struct httpd_state *s=p;
|
||||
/* Span generator calls over tcp segments */
|
||||
/* Note retransmissions will execute thise code multiple times for a segment */
|
||||
i=s->starti;j=s->startj;
|
||||
for (;i<UIP_DS6_NBR_NB;i++) {
|
||||
if (uip_ds6_nbr_cache[i].isused) {
|
||||
j++;
|
||||
|
||||
#if WEBSERVER_CONF_NEIGHBOR_STATUS
|
||||
static const char httpd_cgi_nbrs1[] HTTPD_STRING_ATTR = " INCOMPLETE";
|
||||
static const char httpd_cgi_nbrs2[] HTTPD_STRING_ATTR = " REACHABLE";
|
||||
static const char httpd_cgi_nbrs3[] HTTPD_STRING_ATTR = " STALE";
|
||||
static const char httpd_cgi_nbrs4[] HTTPD_STRING_ATTR = " DELAY";
|
||||
static const char httpd_cgi_nbrs5[] HTTPD_STRING_ATTR = " NBR_PROBE";
|
||||
{uint16_t k=numprinted+25;
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted);
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrb);
|
||||
while (numprinted < k) {*((char *)uip_appdata+numprinted++) = ' ';}
|
||||
switch (uip_ds6_nbr_cache[i].state) {
|
||||
case NBR_INCOMPLETE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs1);break;
|
||||
case NBR_REACHABLE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs2);break;
|
||||
case NBR_STALE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs3);break;
|
||||
case NBR_DELAY: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs4);break;
|
||||
case NBR_PROBE: numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_nbrs5);break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_nbr_cache[i].ipaddr, uip_appdata + numprinted);
|
||||
#endif
|
||||
*((char *)uip_appdata+numprinted++) = '\n';
|
||||
|
||||
/* If buffer near full, send it and wait for the next call. Could be a retransmission, or the next segment */
|
||||
if(numprinted > (uip_mss() - 50)) {
|
||||
s->savei=i;s->savej=j;
|
||||
return numprinted;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if WEBSERVER_CONF_SHOW_ROOM
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_NBR_NB-j);
|
||||
#else
|
||||
if(UIP_DS6_NBR_NB == j) {
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Signal that this was the last segment */
|
||||
s->savei = 0;
|
||||
return numprinted;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -496,7 +541,13 @@ PT_THREAD(neighbors(struct httpd_state *s, char *ptr))
|
|||
{
|
||||
PSOCK_BEGIN(&s->sout);
|
||||
|
||||
PSOCK_GENERATOR_SEND(&s->sout, make_neighbors, s->u.ptr);
|
||||
/* Send as many TCP segments as needed for the neighbor table */
|
||||
/* Move to next seqment after each successful transmission */
|
||||
s->starti=s->startj=0;
|
||||
do {
|
||||
PSOCK_GENERATOR_SEND(&s->sout, make_neighbors, (void *)s);
|
||||
s->starti=s->savei+1;s->startj=s->savej;
|
||||
} while(s->savei);
|
||||
|
||||
PSOCK_END(&s->sout);
|
||||
}
|
||||
|
@ -508,27 +559,57 @@ extern uip_ds6_route_t uip_ds6_routing_table[];
|
|||
static unsigned short
|
||||
make_routes(void *p)
|
||||
{
|
||||
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via ";
|
||||
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus<br>";
|
||||
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")<br>";
|
||||
uint8_t i,j=0;
|
||||
uint16_t numprinted;
|
||||
numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh);
|
||||
for (i=0; i<UIP_DS6_ROUTE_NB;i++) {
|
||||
static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "/%u (via ";
|
||||
static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus\n";
|
||||
static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")\n";
|
||||
uint8_t i,j;
|
||||
uint16_t numprinted=0;
|
||||
struct httpd_state *s=p;
|
||||
/* Span generator calls over tcp segments */
|
||||
/* Note retransmissions will execute thise code multiple times for a segment */
|
||||
i=s->starti;j=s->startj;
|
||||
for (;i<UIP_DS6_ROUTE_NB;i++) {
|
||||
if (uip_ds6_routing_table[i].isused) {
|
||||
j++;
|
||||
|
||||
#if WEBSERVER_CONF_ROUTE_LINKS
|
||||
static const char httpd_cgi_rtesl1[] HTTPD_STRING_ATTR = "<a href=http://[";
|
||||
static const char httpd_cgi_rtesl2[] HTTPD_STRING_ATTR = "]/status.shtml>";
|
||||
static const char httpd_cgi_rtesl3[] HTTPD_STRING_ATTR = "</a>";
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl1);
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl2);
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtesl3);
|
||||
#else
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].ipaddr, uip_appdata + numprinted);
|
||||
#endif
|
||||
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes1, uip_ds6_routing_table[i].length);
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_routing_table[i].nexthop, uip_appdata + numprinted);
|
||||
if(uip_ds6_routing_table[i].state.lifetime < 3600) {
|
||||
if(1 || uip_ds6_routing_table[i].state.lifetime < 3600) {
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes2, (long unsigned int)uip_ds6_routing_table[i].state.lifetime);
|
||||
} else {
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_rtes3);
|
||||
}
|
||||
/* If buffer nearly full, send it and wait for the next call. Could be a retransmission, or the next segment */
|
||||
if(numprinted > (uip_mss() - 200)) {
|
||||
s->savei=i;s->savej=j;
|
||||
return numprinted;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j==0) numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrn);
|
||||
#if WEBSERVER_CONF_SHOW_ROOM
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf,UIP_DS6_ROUTE_NB-j);
|
||||
#else
|
||||
if(UIP_DS6_ROUTE_NB == j) {
|
||||
numprinted += httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_addrf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Signal that this was the last segment */
|
||||
s->savei = 0;
|
||||
return numprinted;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -537,7 +618,13 @@ PT_THREAD(routes(struct httpd_state *s, char *ptr))
|
|||
{
|
||||
PSOCK_BEGIN(&s->sout);
|
||||
|
||||
PSOCK_GENERATOR_SEND(&s->sout, make_routes, s->u.ptr);
|
||||
/* Send as many TCP segments as needed for the route table */
|
||||
/* Move to next seqment after each successful transmission */
|
||||
s->starti=s->startj=0;
|
||||
do {
|
||||
PSOCK_GENERATOR_SEND(&s->sout, make_routes, s);
|
||||
s->starti=s->savei+1;s->startj=s->savej;
|
||||
} while(s->savei);
|
||||
|
||||
PSOCK_END(&s->sout);
|
||||
}
|
||||
|
@ -548,18 +635,15 @@ PT_THREAD(routes(struct httpd_state *s, char *ptr))
|
|||
static unsigned short
|
||||
generate_sensor_readings(void *arg)
|
||||
{
|
||||
uint16_t numprinted;
|
||||
uint16_t numprinted=0;
|
||||
uint16_t days,h,m,s;
|
||||
unsigned long seconds=clock_seconds();
|
||||
static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR = "[Updated %d seconds ago]<br><br>";
|
||||
static const char httpd_cgi_sensor1[] HTTPD_STRING_ATTR = "<pre><em>Temperature:</em> %s\n";
|
||||
static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR = "[Updated %d seconds ago]\n";
|
||||
static const char httpd_cgi_sensor1[] HTTPD_STRING_ATTR = "<em>Temperature:</em> %s\n";
|
||||
static const char httpd_cgi_sensor2[] HTTPD_STRING_ATTR = "<em>Battery :</em> %s\n";
|
||||
// static const char httpd_cgi_sensr12[] HTTPD_STRING_ATTR = "<em>Temperature:</em> %s <em>Battery:</em> %s<br>";
|
||||
static const char httpd_cgi_sensor3[] HTTPD_STRING_ATTR = "<em>Uptime :</em> %02d:%02d:%02d\n";
|
||||
static const char httpd_cgi_sensor3d[] HTTPD_STRING_ATTR = "<em>Uptime :</em> %u days %02u:%02u:%02u\n";
|
||||
// static const char httpd_cgi_sensor4[] HTTPD_STRING_ATTR = "<em>Sleeping time :</em> %02d:%02d:%02d (%d%%)<br>";
|
||||
|
||||
numprinted=0;
|
||||
/* Generate temperature and voltage strings for each platform */
|
||||
#if CONTIKI_TARGET_AVR_ATMEGA128RFA1
|
||||
{uint8_t i;
|
||||
|
@ -623,12 +707,16 @@ generate_sensor_readings(void *arg)
|
|||
#elif CONTIKI_TARGET_REDBEE_ECONOTAG
|
||||
//#include "adc.h"
|
||||
{
|
||||
#if 0
|
||||
/* Scan ADC channels if not already being done elsewhere */
|
||||
uint8_t c;
|
||||
adc_reading[8]=0;
|
||||
adc_init();
|
||||
while (adc_reading[8]==0) adc_service();
|
||||
//for (c=0; c<NUM_ADC_CHAN; c++) printf("%u %04u\r\n", c, adc_reading[c]);
|
||||
adc_disable();
|
||||
#endif
|
||||
|
||||
snprintf(sensor_extvoltage, sizeof(sensor_extvoltage),"%u mV",1200*0xfff/adc_reading[8]);
|
||||
|
||||
static const char httpd_cgi_sensorv[] HTTPD_STRING_ATTR = "<em>ADC chans :</em> %u %u %u %u %u %u %u %u \n";
|
||||
|
@ -641,11 +729,14 @@ uint8_t c;
|
|||
if (last_tempupdate) {
|
||||
numprinted =httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_sensor0,(unsigned int) (seconds-last_tempupdate));
|
||||
}
|
||||
if (sensor_temperature[0]!='N') {
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor1, sensor_temperature);
|
||||
}
|
||||
|
||||
#if CONTIKI_TARGET_REDBEE_ECONOTAG
|
||||
/* Econotag at 3v55 with 10 ohms to LiFePO4 battery: 3680mv usb 3106 battery (meter 3.08). Take 3500 as breakpoint for USB connected */
|
||||
/* Econotag at 3v55 with 10 ohms to LiFePO4 battery: 3680mv usb 3573 2 Fresh alkaline AAs. Take 3590 as threshold for USB connected */
|
||||
static const char httpd_cgi_sensor2u[] HTTPD_STRING_ATTR = "<em>Vcc (USB) :</em> %s\n";
|
||||
if(adc_reading[8]<1404) {
|
||||
if(adc_reading[8]<1368) {
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor2u, sensor_extvoltage);
|
||||
} else {
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor2, sensor_extvoltage);
|
||||
|
@ -653,7 +744,6 @@ uint8_t c;
|
|||
#else
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor2, sensor_extvoltage);
|
||||
#endif
|
||||
// numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensr12, sensor_temperature,sensor_extvoltage);
|
||||
|
||||
#if RADIOSTATS
|
||||
/* Remember radioontime for display below - slow connection might make it report longer than cpu ontime! */
|
||||
|
@ -667,14 +757,20 @@ uint8_t c;
|
|||
h=h-days*24;
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor3d, days,h,m,s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (sleepseconds) {
|
||||
uint8_t p1;
|
||||
p1=100UL*sleepseconds/seconds;h=sleepseconds/3600;s=sleepseconds-h*3600;m=s/60;s=s-m*60;
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor4, h,m,s,p1);
|
||||
return numprinted;
|
||||
}
|
||||
#endif
|
||||
#if WEBSERVER_CONF_STATISTICS
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static unsigned short
|
||||
generate_stats(void *arg)
|
||||
{
|
||||
uint16_t numprinted;
|
||||
uint16_t h,m,s;
|
||||
uint8_t p1,p2;
|
||||
uint32_t seconds=clock_seconds();
|
||||
|
||||
static const char httpd_cgi_stats[] HTTPD_STRING_ATTR = "\n<big><b>Statistics</b></big>\n";
|
||||
numprinted=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_stats);
|
||||
|
||||
#if ENERGEST_CONF_ON
|
||||
{uint8_t p1,p2;
|
||||
|
@ -733,23 +829,11 @@ uint8_t c;
|
|||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor21,
|
||||
rimestats.tx,rimestats.rx,rimestats.lltx-rimestats.tx,rimestats.llrx-rimestats.rx);
|
||||
#endif
|
||||
static const char httpd_cgi_sensor99[] HTTPD_STRING_ATTR = "</pre>";
|
||||
numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor99);
|
||||
|
||||
return numprinted;
|
||||
|
||||
}
|
||||
#if RADIOSTATS
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static unsigned short
|
||||
generate_radio_stats(void *arg)
|
||||
{
|
||||
uint16_t numprinted;
|
||||
uint16_t h,m,s;
|
||||
uint8_t p1,p2;
|
||||
unsigned long seconds=clock_seconds();
|
||||
static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR = "<em>Radio on time :</em> %02d:%02d:%02d (%d.%02d%%)<br>";
|
||||
static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR = "<em>Packets:</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n";
|
||||
/* From RF230 statistics */
|
||||
static const char httpd_cgi_sensor10[] HTTPD_STRING_ATTR = "<em>Radio on (RF230BB) :</em> %02d:%02d:%02d (%d.%02d%%)\n";
|
||||
static const char httpd_cgi_sensor11[] HTTPD_STRING_ATTR = "<em>Packets: (RF230BB) :</em> Tx=%5d Rx=%5d TxL=%5d RxL=%5d RSSI=%2ddBm\n";
|
||||
|
||||
s=(10000UL*savedradioontime)/seconds;
|
||||
p1=s/100;
|
||||
|
@ -772,7 +856,7 @@ generate_radio_stats(void *arg)
|
|||
numprinted+=httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, httpd_cgi_sensor11,\
|
||||
RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail,p1);
|
||||
#endif
|
||||
|
||||
#endif /* RADIOSTATS */
|
||||
return numprinted;
|
||||
}
|
||||
#endif
|
||||
|
@ -783,8 +867,8 @@ PT_THREAD(sensor_readings(struct httpd_state *s, char *ptr))
|
|||
PSOCK_BEGIN(&s->sout);
|
||||
|
||||
PSOCK_GENERATOR_SEND(&s->sout, generate_sensor_readings, s);
|
||||
#if RADIOSTATS
|
||||
PSOCK_GENERATOR_SEND(&s->sout, generate_radio_stats, s);
|
||||
#if WEBSERVER_CONF_STATISTICS
|
||||
PSOCK_GENERATOR_SEND(&s->sout, generate_stats, s);
|
||||
#endif
|
||||
|
||||
PSOCK_END(&s->sout);
|
||||
|
@ -971,15 +1055,40 @@ PT_THREAD(ajax_call(struct httpd_state *s, char *ptr))
|
|||
SENSORS_DEACTIVATE(acc_sensor);
|
||||
|
||||
#elif CONTIKI_TARGET_REDBEE_ECONOTAG
|
||||
#if 0
|
||||
/* Scan ADC channels if not already done elsewhere */
|
||||
{ uint8_t c;
|
||||
adc_reading[8]=0;
|
||||
adc_init();
|
||||
while (adc_reading[8]==0) adc_service();
|
||||
adc_disable();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
numprinted = snprintf(buf, sizeof(buf),"b(%u);adc(%u,%u,%u,%u,%u,%u,%u,%u);",
|
||||
1200*0xfff/adc_reading[8],adc_reading[0],adc_reading[1],adc_reading[2],adc_reading[3],adc_reading[4],adc_reading[5],adc_reading[6],adc_reading[7]);
|
||||
#else
|
||||
// numprinted = snprintf(buf, sizeof(buf),"b(%u);",1200*0xfff/adc_reading[8]);
|
||||
numprinted = snprintf(buf, sizeof(buf),"b(%u);adc(%u,%u,%u);",1200*0xfff/adc_reading[8],adc_reading[1],adc_reading[7],adc_reading[8]);
|
||||
#endif
|
||||
}
|
||||
if (iter<3) {
|
||||
static const char httpd_cgi_ajax11[] HTTPD_STRING_ATTR = "wt('Econtag [";
|
||||
static const char httpd_cgi_ajax12[] HTTPD_STRING_ATTR = "]');";
|
||||
numprinted += httpd_snprintf(buf+numprinted, sizeof(buf)-numprinted,httpd_cgi_ajax11);
|
||||
#if WEBSERVER_CONF_PRINTADDR
|
||||
/* Note address table is filled from the end down */
|
||||
{int i;
|
||||
for (i=0; i<UIP_DS6_ADDR_NB;i++) {
|
||||
if (uip_ds6_if.addr_list[i].isused) {
|
||||
numprinted += httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr, buf + numprinted);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
numprinted += httpd_snprintf(buf+numprinted, sizeof(buf)-numprinted,httpd_cgi_ajax12);
|
||||
}
|
||||
|
||||
#elif CONTIKI_TARGET_MINIMAL_NET
|
||||
static uint16_t c0=0x3ff,c1=0x3ff,c2=0x3ff,c3=0x3ff,c4=0x3ff,c5=0x3ff,c6=0x3ff,c7=0x3ff;
|
||||
numprinted = snprintf(buf, sizeof(buf), "t(%d);b(%u);v(%u);",273+(rand()&0x3f),3300-iter/10,iter);
|
||||
|
|
|
@ -93,8 +93,11 @@
|
|||
#define WEBSERVER_CONF_PROCESSES 0
|
||||
#define WEBSERVER_CONF_ADDRESSES 1
|
||||
#define WEBSERVER_CONF_NEIGHBORS 1
|
||||
#define WEBSERVER_CONF_ROUTES 1
|
||||
#define WEBSERVER_CONF_NEIGHBOR_STATUS 0
|
||||
#define WEBSERVER_CONF_ROUTES 0
|
||||
#define WEBSERVER_CONF_ROUTE_LINKS 0
|
||||
#define WEBSERVER_CONF_SENSORS 0
|
||||
#define WEBSERVER_CONF_STATISTICS 0
|
||||
#define WEBSERVER_CONF_TICTACTOE 0 //Needs passquery of at least 10 chars
|
||||
#define WEBSERVER_CONF_AJAX 0
|
||||
//#define WEBSERVER_CONF_PASSQUERY 10
|
||||
|
@ -114,6 +117,7 @@ extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
|
|||
/* Include referrer in log */
|
||||
#define WEBSERVER_CONF_REFERER 0
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
#elif WEBSERVER_CONF_NANO==2
|
||||
/* webserver-mini having more content */
|
||||
#define WEBSERVER_CONF_CONNS 2
|
||||
|
@ -136,28 +140,32 @@ extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
|
|||
#define WEBSERVER_CONF_PROCESSES 1
|
||||
#define WEBSERVER_CONF_ADDRESSES 1
|
||||
#define WEBSERVER_CONF_NEIGHBORS 1
|
||||
#define WEBSERVER_CONF_NEIGHBOR_STATUS 1
|
||||
#define WEBSERVER_CONF_ROUTES 1
|
||||
#define WEBSERVER_CONF_ROUTE_LINKS 1
|
||||
#define WEBSERVER_CONF_SENSORS 1
|
||||
#define WEBSERVER_CONF_STATISTICS 1
|
||||
//#define WEBSERVER_CONF_TICTACTOE 1 //Needs passquery of at least 10 chars
|
||||
#define WEBSERVER_CONF_AJAX 1
|
||||
#define WEBSERVER_CONF_SHOW_ROOM 0
|
||||
//#define WEBSERVER_CONF_PASSQUERY 10
|
||||
#if WEBSERVER_CONF_PASSQUERY
|
||||
extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
|
||||
#endif
|
||||
/* Enable specific file types */
|
||||
#define WEBSERVER_CONF_JPG 1
|
||||
#define WEBSERVER_CONF_PNG 1
|
||||
#define WEBSERVER_CONF_GIF 1
|
||||
#define WEBSERVER_CONF_JPG 0
|
||||
#define WEBSERVER_CONF_PNG 0
|
||||
#define WEBSERVER_CONF_GIF 0
|
||||
#define WEBSERVER_CONF_TXT 1
|
||||
#define WEBSERVER_CONF_CSS 1
|
||||
#define WEBSERVER_CONF_BIN 1
|
||||
#define WEBSERVER_CONF_CSS 0
|
||||
#define WEBSERVER_CONF_BIN 0
|
||||
|
||||
/* Log page accesses */
|
||||
#define WEBSERVER_CONF_LOG 1
|
||||
#define WEBSERVER_CONF_LOG 0
|
||||
/* Include referrer in log */
|
||||
#define WEBSERVER_CONF_REFERER 1
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
#elif WEBSERVER_CONF_NANO==3
|
||||
/* webserver-mini having all content */
|
||||
#define WEBSERVER_CONF_CONNS 6
|
||||
|
@ -181,7 +189,12 @@ extern char httpd_query[WEBSERVER_CONF_PASSQUERY];
|
|||
#define WEBSERVER_CONF_ADDRESSES 1
|
||||
#define WEBSERVER_CONF_NEIGHBORS 1
|
||||
#define WEBSERVER_CONF_ROUTES 1
|
||||
#define WEBSERVER_CONF_NEIGHBORS 1
|
||||
#define WEBSERVER_CONF_NEIGHBOR_STATUS 1
|
||||
#define WEBSERVER_CONF_ROUTES 1
|
||||
#define WEBSERVER_CONF_ROUTE_LINKS 1
|
||||
#define WEBSERVER_CONF_SENSORS 1
|
||||
#define WEBSERVER_CONF_STATISTICS 1
|
||||
#define WEBSERVER_CONF_TICTACTOE 1 //Needs passquery of at least 10 chars
|
||||
#define WEBSERVER_CONF_AJAX 1
|
||||
#define WEBSERVER_CONF_PASSQUERY 10
|
||||
|
@ -272,6 +285,9 @@ struct httpd_state {
|
|||
#if WEBSERVER_CONF_LOADTIME
|
||||
clock_time_t pagetime;
|
||||
#endif
|
||||
#if WEBSERVER_CONF_NEIGHBORS || WEBSERVER_CONF_ROUTES
|
||||
uint8_t starti,savei,startj,savej;
|
||||
#endif
|
||||
#if WEBSERVER_CONF_CGI
|
||||
union {
|
||||
unsigned short count;
|
||||
|
|
|
@ -535,6 +535,12 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_
|
|||
struct hdr *chdr;
|
||||
#endif /* WITH_CONTIKIMAC_HEADER */
|
||||
|
||||
/* Exit if RDC and radio were explicitly turned off */
|
||||
if (!contikimac_is_on && !contikimac_keep_radio_on) {
|
||||
PRINTF("contikimac: radio is turned off\n");
|
||||
return MAC_TX_ERR_FATAL;
|
||||
}
|
||||
|
||||
if(packetbuf_totlen() == 0) {
|
||||
PRINTF("contikimac: send_packet data len 0\n");
|
||||
return MAC_TX_ERR_FATAL;
|
||||
|
|
|
@ -14,7 +14,11 @@ CFLAGSWERROR=-Werror -pedantic -std=c99 -Werror
|
|||
endif
|
||||
CFLAGSNO = -Wall -g -I/usr/local/include $(CFLAGSWERROR)
|
||||
CFLAGS += $(CFLAGSNO) -O
|
||||
ifeq ($(HOST_OS),Linux)
|
||||
LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
|
||||
else
|
||||
LDFLAGS = -Wl
|
||||
endif
|
||||
|
||||
### Compilation rules
|
||||
|
||||
|
|
|
@ -40,7 +40,12 @@
|
|||
|
||||
static void *main_fiber;
|
||||
|
||||
#elif defined(__linux)
|
||||
#elif defined(__linux) || defined(__APPLE__)
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* Avoid deprecated error on Darwin */
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
|
|
@ -10,7 +10,11 @@ OBJCOPY = objcopy
|
|||
STRIP = strip
|
||||
CFLAGSNO = -Wall -g -I/usr/local/include
|
||||
CFLAGS += $(CFLAGSNO)
|
||||
ifeq ($(HOST_OS),Linux)
|
||||
LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
|
||||
else
|
||||
LDFLAGS = -Wl
|
||||
endif
|
||||
|
||||
### Compilation rules
|
||||
|
||||
|
|
|
@ -47,11 +47,12 @@
|
|||
#define REST_RES_HELLO 1
|
||||
#define REST_RES_MIRROR 0 /* causes largest code size */
|
||||
#define REST_RES_CHUNKS 1
|
||||
#define REST_RES_POLLING 1
|
||||
#define REST_RES_SEPARATE 1
|
||||
#define REST_RES_PUSHING 1
|
||||
#define REST_RES_EVENT 1
|
||||
#define REST_RES_LEDS 1
|
||||
#define REST_RES_TOGGLE 1
|
||||
#define REST_RES_LIGHT 1
|
||||
#define REST_RES_LIGHT 0
|
||||
#define REST_RES_BATTERY 1
|
||||
|
||||
|
||||
|
@ -149,8 +150,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
|
|||
/* The ETag and Token is copied to the header. */
|
||||
uint8_t opaque[] = {0x0A, 0xBC, 0xDE};
|
||||
|
||||
/* Strings are not copied and should be static or in program memory (char *str = "string in .text";).
|
||||
* They must be '\0'-terminated as the setters use strlen(). */
|
||||
/* Strings are not copied, so use static string buffers or strings in .text memory (char *str = "string in .text";). */
|
||||
static char location[] = {'/','f','/','a','?','k','&','e', 0};
|
||||
|
||||
/* Getter for the header option Content-Type. If the option is not set, text/plain is returned by default. */
|
||||
|
@ -313,8 +313,8 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
|
|||
REST.set_response_status(response, REST.status.BAD_OPTION);
|
||||
/* A block error message should not exceed the minimum block size (16). */
|
||||
|
||||
const char error_msg[] = "BlockOutOfScope";
|
||||
REST.set_response_payload(response, (uint8_t *)error_msg, sizeof(error_msg)-1);
|
||||
const char *error_msg = "BlockOutOfScope";
|
||||
REST.set_response_payload(response, error_msg, strlen(error_msg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -349,22 +349,95 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre
|
|||
}
|
||||
#endif
|
||||
|
||||
#if REST_RES_POLLING
|
||||
#if REST_RES_SEPARATE && WITH_COAP > 3
|
||||
/* Required to manually (=not by the engine) handle the response transaction. */
|
||||
#include "er-coap-07-separate.h"
|
||||
#include "er-coap-07-transactions.h"
|
||||
/*
|
||||
* CoAP-specific example for separate responses.
|
||||
* This resource is .
|
||||
*/
|
||||
RESOURCE(separate, METHOD_GET, "debug/separate", "title=\"Separate demo\"");
|
||||
|
||||
static uint8_t separate_active = 0;
|
||||
static coap_separate_t separate_store[1];
|
||||
|
||||
void
|
||||
separate_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
{
|
||||
/*
|
||||
* Example allows only one open separate response.
|
||||
* For multiple, the application must manage the list of stores.
|
||||
*/
|
||||
if (separate_active)
|
||||
{
|
||||
REST.set_response_status(response, REST.status.SERVICE_UNAVAILABLE);
|
||||
const char *msg = "AlreadyInUse";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
separate_active = 1;
|
||||
|
||||
/* Take over and skip response by engine. */
|
||||
coap_separate_response(response, separate_store);
|
||||
|
||||
/*
|
||||
* At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2).
|
||||
* Extend the store, if the application requires additional information from this handler.
|
||||
* buffer is an example field for custom information.
|
||||
*/
|
||||
snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
separate_finalize_handler()
|
||||
{
|
||||
if (separate_active)
|
||||
{
|
||||
coap_transaction_t *transaction = NULL;
|
||||
if ( (transaction = coap_new_transaction(separate_store->mid, &separate_store->addr, separate_store->port)) )
|
||||
{
|
||||
coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */
|
||||
coap_init_message(response, separate_store->type, CONTENT_2_05, separate_store->mid);
|
||||
|
||||
coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer));
|
||||
|
||||
/* Warning: No check for serialization error. */
|
||||
transaction->packet_len = coap_serialize_message(response, transaction->packet);
|
||||
coap_send_transaction(transaction);
|
||||
/* The engine will clear the transaction (right after send for NON, after acked for CON). */
|
||||
|
||||
separate_active = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Set timer for retry, send error message, ...
|
||||
* The example simply waits for another button press.
|
||||
*/
|
||||
}
|
||||
} /* if (separate_active) */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if REST_RES_PUSHING
|
||||
/*
|
||||
* Example for a periodic resource.
|
||||
* It takes an additional period parameter, which defines the interval to call [name]_periodic_handler().
|
||||
* A default post_handler takes care of subscriptions by managing a list of subscribers to notify.
|
||||
*/
|
||||
PERIODIC_RESOURCE(polling, METHOD_GET, "debug/poll", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND);
|
||||
PERIODIC_RESOURCE(pushing, METHOD_GET, "debug/push", "title=\"Periodic demo\";rt=\"Observable\"", 5*CLOCK_SECOND);
|
||||
|
||||
void
|
||||
polling_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
|
||||
pushing_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);
|
||||
|
||||
/* Usually, a CoAP server would response with the current resource representation. */
|
||||
const char msg[] = "It's periodic!";
|
||||
REST.set_response_payload(response, (uint8_t *)msg, sizeof(msg)-1);
|
||||
/* Usually, a CoAP server would response with the resource representation matching the periodic_handler. */
|
||||
const char *msg = "It's periodic!";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
|
||||
/* A post_handler that handles subscriptions will be called for periodic resources by the REST framework. */
|
||||
}
|
||||
|
@ -374,7 +447,7 @@ polling_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
* It will be called by the REST manager process with the defined period.
|
||||
*/
|
||||
int
|
||||
polling_periodic_handler(resource_t *r)
|
||||
pushing_periodic_handler(resource_t *r)
|
||||
{
|
||||
static uint32_t periodic_i = 0;
|
||||
static char content[16];
|
||||
|
@ -402,10 +475,9 @@ void
|
|||
event_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);
|
||||
|
||||
/* Usually, a CoAP server would response with the current resource representation. */
|
||||
const char msg[] = "It's eventful!";
|
||||
REST.set_response_payload(response, (uint8_t *)msg, sizeof(msg)-1);
|
||||
const char *msg = "It's eventful!";
|
||||
REST.set_response_payload(response, (uint8_t *)msg, strlen(msg));
|
||||
|
||||
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
|
||||
}
|
||||
|
@ -527,8 +599,8 @@ light_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred
|
|||
else
|
||||
{
|
||||
REST.set_response_status(response, REST.status.UNSUPPORTED_MADIA_TYPE);
|
||||
const char msg[] = "Supporting content-types text/plain, application/xml, and application/json";
|
||||
REST.set_response_payload(response, (uint8_t *)msg, sizeof(msg)-1);
|
||||
const char *msg = "Supporting content-types text/plain, application/xml, and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_LIGHT */
|
||||
|
@ -561,8 +633,8 @@ battery_handler(void* request, void* response, uint8_t *buffer, uint16_t preferr
|
|||
else
|
||||
{
|
||||
REST.set_response_status(response, REST.status.UNSUPPORTED_MADIA_TYPE);
|
||||
const char msg[] = "Supporting content-types text/plain and application/json";
|
||||
REST.set_response_payload(response, (uint8_t *)msg, sizeof(msg)-1);
|
||||
const char *msg = "Supporting content-types text/plain and application/json";
|
||||
REST.set_response_payload(response, msg, strlen(msg));
|
||||
}
|
||||
}
|
||||
#endif /* PLATFORM_HAS_BATTERY */
|
||||
|
@ -594,8 +666,8 @@ PROCESS_THREAD(rest_server_example, ev, data)
|
|||
configure_routing();
|
||||
#endif
|
||||
|
||||
/* Initialize the REST framework. */
|
||||
rest_init_framework();
|
||||
/* Initialize the REST engine. */
|
||||
rest_init_engine();
|
||||
|
||||
/* Activate the application-specific resources. */
|
||||
#if REST_RES_HELLO
|
||||
|
@ -607,9 +679,14 @@ PROCESS_THREAD(rest_server_example, ev, data)
|
|||
#if REST_RES_CHUNKS
|
||||
rest_activate_resource(&resource_chunks);
|
||||
#endif
|
||||
#if REST_RES_POLLING
|
||||
rest_activate_periodic_resource(&periodic_resource_polling);
|
||||
#if REST_RES_PUSHING
|
||||
rest_activate_periodic_resource(&periodic_resource_pushing);
|
||||
#endif
|
||||
#if REST_RES_SEPARATE && WITH_COAP > 3
|
||||
rest_set_pre_handler(&resource_separate, coap_separate_handler);
|
||||
rest_activate_resource(&resource_separate);
|
||||
#endif
|
||||
|
||||
#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT
|
||||
SENSORS_ACTIVATE(button_sensor);
|
||||
rest_activate_event_resource(&resource_event);
|
||||
|
@ -634,11 +711,17 @@ PROCESS_THREAD(rest_server_example, ev, data)
|
|||
/* Define application-specific events here. */
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
#if defined (PLATFORM_HAS_BUTTON) && REST_RES_EVENT
|
||||
#if defined (PLATFORM_HAS_BUTTON)
|
||||
if (ev == sensors_event && data == &button_sensor) {
|
||||
PRINTF("BUTTON\n");
|
||||
#if REST_RES_EVENT
|
||||
/* Call the event_handler for this application-specific event. */
|
||||
event_event_handler(&resource_event);
|
||||
#endif
|
||||
#if REST_RES_SEPARATE && WITH_COAP>3
|
||||
/* Also call the separate response example handler. */
|
||||
separate_finalize_handler();
|
||||
#endif
|
||||
}
|
||||
#endif /* PLATFORM_HAS_BUTTON */
|
||||
} /* while (1) */
|
||||
|
|
|
@ -127,7 +127,11 @@ slip_config_handle_arguments(int argc, char **argv)
|
|||
fprintf(stderr,"usage: %s [options] ipaddress\n", prog);
|
||||
fprintf(stderr,"example: border-router.native -L -v2 -s ttyUSB1 aaaa::1/64\n");
|
||||
fprintf(stderr,"Options are:\n");
|
||||
#ifdef linux
|
||||
fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200,921600 (default 115200)\n");
|
||||
#else
|
||||
fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default 115200)\n");
|
||||
#endif
|
||||
fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n");
|
||||
fprintf(stderr," -L Log output format (adds time stamps)\n");
|
||||
fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n");
|
||||
|
@ -175,9 +179,11 @@ exit(1);
|
|||
case 115200:
|
||||
slip_config_b_rate = B115200;
|
||||
break;
|
||||
#ifdef linux
|
||||
case 921600:
|
||||
slip_config_b_rate = B921600;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
err(1, "unknown baudrate %d", baudrate);
|
||||
break;
|
||||
|
|
|
@ -125,13 +125,17 @@ void
|
|||
ifconf(const char *tundev, const char *ipaddr)
|
||||
{
|
||||
#ifdef linux
|
||||
ssystem("ifconfig %s inet `hostname` up", tundev);
|
||||
ssystem("ifconfig %s inet6 `hostname` up", tundev);
|
||||
ssystem("ifconfig %s add %s", tundev, ipaddr);
|
||||
#elif defined(__APPLE__)
|
||||
ssystem("ifconfig %s inet6 %s up", tundev, ipaddr);
|
||||
ssystem("sysctl -w net.inet.ip.forwarding=1");
|
||||
#else
|
||||
ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr);
|
||||
ssystem("ifconfig %s inet6 `hostname` %s up", tundev, ipaddr);
|
||||
ssystem("sysctl -w net.inet.ip.forwarding=1");
|
||||
#endif /* !linux */
|
||||
|
||||
/* Print the configuration to the console. */
|
||||
ssystem("ifconfig %s\n", tundev);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -74,6 +74,13 @@ AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process);
|
|||
#else
|
||||
/* Use simple webserver with only one page */
|
||||
#include "httpd-simple.h"
|
||||
|
||||
#define WEBSERVER_CONF_LOADTIME 0
|
||||
#define WEBSERVER_CONF_FILESTATS 0
|
||||
#define WEBSERVER_CONF_NEIGHBOR_STATUS 0
|
||||
#define WEBSERVER_CONF_ROUTE_LINKS 0
|
||||
#define BUF_USES_STACK 1
|
||||
|
||||
PROCESS(webserver_nogui_process, "Web server");
|
||||
PROCESS_THREAD(webserver_nogui_process, ev, data)
|
||||
{
|
||||
|
@ -92,11 +99,19 @@ AUTOSTART_PROCESSES(&border_router_process,&webserver_nogui_process);
|
|||
|
||||
static const char *TOP = "<html><head><title>ContikiRPL</title></head><body>\n";
|
||||
static const char *BOTTOM = "</body></html>\n";
|
||||
static char buf[128];
|
||||
#if BUF_USES_STACK
|
||||
static char *bufptr, *bufend;
|
||||
#define ADD(...) do { \
|
||||
bufptr += snprintf(bufptr, bufend - bufptr, __VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
static char buf[256];
|
||||
static int blen;
|
||||
#define ADD(...) do { \
|
||||
blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
ipaddr_add(const uip_ipaddr_t *addr)
|
||||
|
@ -106,15 +121,12 @@ ipaddr_add(const uip_ipaddr_t *addr)
|
|||
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
|
||||
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||
if(a == 0 && f >= 0) {
|
||||
if(f++ == 0 && sizeof(buf) - blen >= 2) {
|
||||
buf[blen++] = ':';
|
||||
buf[blen++] = ':';
|
||||
}
|
||||
if(f++ == 0) ADD("::");
|
||||
} else {
|
||||
if(f > 0) {
|
||||
f = -1;
|
||||
} else if(i > 0 && blen < sizeof(buf)) {
|
||||
buf[blen++] = ':';
|
||||
} else if(i > 0) {
|
||||
ADD(":");
|
||||
}
|
||||
ADD("%x", a);
|
||||
}
|
||||
|
@ -125,46 +137,130 @@ static
|
|||
PT_THREAD(generate_routes(struct httpd_state *s))
|
||||
{
|
||||
static int i;
|
||||
#if BUF_USES_STACK
|
||||
char buf[256];
|
||||
#endif
|
||||
#if WEBSERVER_CONF_LOADTIME
|
||||
static clock_time_t numticks;
|
||||
numticks = clock_time();
|
||||
#endif
|
||||
|
||||
PSOCK_BEGIN(&s->sout);
|
||||
|
||||
SEND_STRING(&s->sout, TOP);
|
||||
|
||||
#if BUF_USES_STACK
|
||||
bufptr = buf;bufend=bufptr+sizeof(buf);
|
||||
#else
|
||||
blen = 0;
|
||||
#endif
|
||||
ADD("Neighbors<pre>");
|
||||
for(i = 0; i < UIP_DS6_NBR_NB; i++) {
|
||||
if(uip_ds6_nbr_cache[i].isused) {
|
||||
|
||||
#if WEBSERVER_CONF_NEIGHBOR_STATUS
|
||||
#if BUF_USES_STACK
|
||||
{char* j=bufptr+25;
|
||||
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
|
||||
while (bufptr < j) ADD(" ");
|
||||
switch (uip_ds6_nbr_cache[i].state) {
|
||||
case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
|
||||
case NBR_REACHABLE: ADD(" REACHABLE");break;
|
||||
case NBR_STALE: ADD(" STALE");break;
|
||||
case NBR_DELAY: ADD(" DELAY");break;
|
||||
case NBR_PROBE: ADD(" NBR_PROBE");break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{uint8_t j=blen+25;
|
||||
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
|
||||
while (blen < j) ADD(" ");
|
||||
switch (uip_ds6_nbr_cache[i].state) {
|
||||
case NBR_INCOMPLETE: ADD(" INCOMPLETE");break;
|
||||
case NBR_REACHABLE: ADD(" REACHABLE");break;
|
||||
case NBR_STALE: ADD(" STALE");break;
|
||||
case NBR_DELAY: ADD(" DELAY");break;
|
||||
case NBR_PROBE: ADD(" NBR_PROBE");break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
|
||||
#endif
|
||||
|
||||
ADD("\n");
|
||||
#if BUF_USES_STACK
|
||||
if(bufptr > bufend - 45) {
|
||||
SEND_STRING(&s->sout, buf);
|
||||
bufptr = buf; bufend = bufptr + sizeof(buf);
|
||||
}
|
||||
#else
|
||||
if(blen > sizeof(buf) - 45) {
|
||||
SEND_STRING(&s->sout, buf);
|
||||
blen = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ADD("</pre>Routes<pre>");
|
||||
SEND_STRING(&s->sout, buf);
|
||||
#if BUF_USES_STACK
|
||||
bufptr = buf; bufend = bufptr + sizeof(buf);
|
||||
#else
|
||||
blen = 0;
|
||||
#endif
|
||||
for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
|
||||
if(uip_ds6_routing_table[i].isused) {
|
||||
#if BUF_USES_STACK
|
||||
#if WEBSERVER_CONF_ROUTE_LINKS
|
||||
ADD("<a href=http://[");
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
ADD("]/status.shtml>");
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
ADD("</a>");
|
||||
#else
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
#endif
|
||||
#else
|
||||
#if WEBSERVER_CONF_ROUTE_LINKS
|
||||
ADD("<a href=http://[");
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
ADD("]/status.shtml>");
|
||||
SEND_STRING(&s->sout, buf); //TODO: why tunslip6 needs an output here, wpcapslip does not
|
||||
blen = 0;
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
ADD("</a>");
|
||||
#else
|
||||
ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
|
||||
#endif
|
||||
#endif
|
||||
ADD("/%u (via ", uip_ds6_routing_table[i].length);
|
||||
ipaddr_add(&uip_ds6_routing_table[i].nexthop);
|
||||
if(uip_ds6_routing_table[i].state.lifetime < 600) {
|
||||
if(1 || (uip_ds6_routing_table[i].state.lifetime < 600)) {
|
||||
ADD(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
|
||||
} else {
|
||||
ADD(")\n");
|
||||
}
|
||||
SEND_STRING(&s->sout, buf);
|
||||
#if BUF_USES_STACK
|
||||
bufptr = buf; bufend = bufptr + sizeof(buf);
|
||||
#else
|
||||
blen = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
ADD("</pre>");
|
||||
//if(blen > 0) {
|
||||
SEND_STRING(&s->sout, buf);
|
||||
// blen = 0;
|
||||
//}
|
||||
|
||||
#if WEBSERVER_CONF_FILESTATS
|
||||
static uint16_t numtimes;
|
||||
ADD("<br><i>This page sent %u times</i>",++numtimes);
|
||||
#endif
|
||||
|
||||
#if WEBSERVER_CONF_LOADTIME
|
||||
numticks = clock_time() - numticks + 1;
|
||||
ADD(" <i>(%u.%02u sec)</i>",numticks/CLOCK_SECOND,(100*(numticks%CLOCK_SECOND))/CLOCK_SECOND));
|
||||
#endif
|
||||
|
||||
SEND_STRING(&s->sout, buf);
|
||||
SEND_STRING(&s->sout, BOTTOM);
|
||||
|
||||
PSOCK_END(&s->sout);
|
||||
|
@ -173,6 +269,7 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||
httpd_simple_script_t
|
||||
httpd_simple_get_script(const char *name)
|
||||
{
|
||||
|
||||
return generate_routes;
|
||||
}
|
||||
|
||||
|
@ -226,19 +323,26 @@ PROCESS_THREAD(border_router_process, ev, data)
|
|||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/* While waiting for the prefix to be sent through the SLIP connection, the future
|
||||
* border router can join an existing DAG as a parent or child, or acquire a default
|
||||
* router that will later take precedence over the SLIP fallback interface.
|
||||
* Prevent that by turning the radio off until we are initialized as a DAG root.
|
||||
*/
|
||||
prefix_set = 0;
|
||||
NETSTACK_MAC.off(0);
|
||||
|
||||
PROCESS_PAUSE();
|
||||
|
||||
SENSORS_ACTIVATE(button_sensor);
|
||||
|
||||
PRINTF("RPL-Border router started\n");
|
||||
|
||||
#if 0
|
||||
/* The border router runs with a 100% duty cycle in order to ensure high
|
||||
packet reception rates.
|
||||
Note if the MAC RDC is not turned off now, aggressive power management of the
|
||||
cpu will interfere with establishing the SLIP connection */
|
||||
NETSTACK_MAC.off(1);
|
||||
#endif
|
||||
|
||||
/* Request prefix until it has been received */
|
||||
while(!prefix_set) {
|
||||
|
@ -253,6 +357,11 @@ PROCESS_THREAD(border_router_process, ev, data)
|
|||
PRINTF("created a new RPL dag\n");
|
||||
}
|
||||
|
||||
/* Now turn the radio on, but disable radio duty cycling.
|
||||
* Since we are the DAG root, reception delays would constrain mesh throughbut.
|
||||
*/
|
||||
NETSTACK_MAC.off(1);
|
||||
|
||||
#if DEBUG || 1
|
||||
print_local_addresses();
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,10 @@ ifndef CONTIKI
|
|||
$(error CONTIKI not defined! You must specify where CONTIKI resides!)
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
AROPTS = rc
|
||||
endif
|
||||
|
||||
CONTIKI_TARGET_DIRS = .
|
||||
CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o}
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ ifndef CONTIKI
|
|||
$(error CONTIKI not defined! You must specify where CONTIKI resides!)
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
AROPTS = rc
|
||||
endif
|
||||
|
||||
ifdef UIP_CONF_IPV6
|
||||
CFLAGS += -DWITH_UIP6=1
|
||||
endif
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
*
|
||||
* This file is part of the uIP TCP/IP stack.
|
||||
*
|
||||
* $Id: tunslip6.c,v 1.6 2010/11/29 18:14:54 joxe Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -596,6 +595,54 @@ ifconf(const char *tundev, const char *ipaddr)
|
|||
ssystem("ifconfig %s inet `hostname` up", tundev);
|
||||
if (timestamp) stamptime();
|
||||
ssystem("ifconfig %s add %s", tundev, ipaddr);
|
||||
|
||||
/* radvd needs a link local address for routing */
|
||||
#if 0
|
||||
/* fe80::1/64 is good enough */
|
||||
ssystem("ifconfig %s add fe80::1/64", tundev);
|
||||
#elif 1
|
||||
/* Generate a link local address a la sixxs/aiccu */
|
||||
/* First a full parse, stripping off the prefix length */
|
||||
{
|
||||
char lladdr[40];
|
||||
char c, *ptr=(char *)ipaddr;
|
||||
uint16_t digit,ai,a[8],cc,scc,i;
|
||||
for(ai=0; ai<8; ai++) {
|
||||
a[ai]=0;
|
||||
}
|
||||
ai=0;
|
||||
cc=scc=0;
|
||||
while(c=*ptr++) {
|
||||
if(c=='/') break;
|
||||
if(c==':') {
|
||||
if(cc)
|
||||
scc = ai;
|
||||
cc = 1;
|
||||
if(++ai>7) break;
|
||||
} else {
|
||||
cc=0;
|
||||
digit = c-'0';
|
||||
if (digit > 9)
|
||||
digit = 10 + (c & 0xdf) - 'A';
|
||||
a[ai] = (a[ai] << 4) + digit;
|
||||
}
|
||||
}
|
||||
/* Get # elided and shift what's after to the end */
|
||||
cc=8-ai;
|
||||
for(i=0;i<cc;i++) {
|
||||
if ((8-i-cc) <= scc) {
|
||||
a[7-i] = 0;
|
||||
} else {
|
||||
a[7-i] = a[8-i-cc];
|
||||
a[8-i-cc]=0;
|
||||
}
|
||||
}
|
||||
sprintf(lladdr,"fe80::%x:%x:%x:%x",a[1]&0xfefd,a[2],a[3],a[7]);
|
||||
if (timestamp) stamptime();
|
||||
ssystem("ifconfig %s add %s/64", tundev, lladdr);
|
||||
}
|
||||
#endif /* link local */
|
||||
|
||||
#else
|
||||
if (timestamp) stamptime();
|
||||
ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr);
|
||||
|
@ -684,7 +731,7 @@ main(int argc, char **argv)
|
|||
fprintf(stderr,"usage: %s [options] ipaddress\n", prog);
|
||||
fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n");
|
||||
fprintf(stderr,"Options are:\n");
|
||||
fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default)\n");
|
||||
fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 default),230400,460800,921600\n");
|
||||
fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n");
|
||||
fprintf(stderr," -L Log output format (adds time stamps)\n");
|
||||
fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n");
|
||||
|
@ -733,6 +780,15 @@ exit(1);
|
|||
case 115200:
|
||||
b_rate = B115200;
|
||||
break;
|
||||
case 230400:
|
||||
b_rate = B230400;
|
||||
break;
|
||||
case 460800:
|
||||
b_rate = B460800;
|
||||
break;
|
||||
case 921600:
|
||||
b_rate = B921600;
|
||||
break;
|
||||
default:
|
||||
err(1, "unknown baudrate %d", baudrate);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue