Merge with updated master.

This commit is contained in:
Marco Grella 2015-11-11 13:42:35 +01:00
commit 41f9ca08e2
507 changed files with 63538 additions and 42206 deletions

14
.gitattributes vendored Normal file
View file

@ -0,0 +1,14 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto whitespace=trailing-space
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text
*.java text
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.ihex binary
*.s37 binary

2
.gitignore vendored
View file

@ -3,6 +3,7 @@
*.png *.png
*.log *.log
*.elf *.elf
*.zip
*.d *.d
*.ihex *.ihex
*.pyc *.pyc
@ -24,6 +25,7 @@
*.c64 *.c64
*.cc2538dk *.cc2538dk
*.remote *.remote
*.jn516x
*.srf06-cc26xx *.srf06-cc26xx
*.ev-aducrf101mkxz *.ev-aducrf101mkxz
*.report *.report

View file

@ -36,6 +36,7 @@ before_script:
tar xjf arm-2008q3*.tar.bz2 -C /tmp/ && tar xjf arm-2008q3*.tar.bz2 -C /tmp/ &&
sudo cp -f -r /tmp/arm-2008q3/* /usr/ && sudo cp -f -r /tmp/arm-2008q3/* /usr/ &&
rm -rf /tmp/arm-2008q3 arm-2008q3*.tar.bz2 && rm -rf /tmp/arm-2008q3 arm-2008q3*.tar.bz2 &&
sudo apt-get -qq install libconfig-dev uuid-dev libqrencode-dev &&
arm-none-eabi-gcc --version ; arm-none-eabi-gcc --version ;
fi fi
@ -73,6 +74,22 @@ before_script:
cc65 --version ; cc65 --version ;
fi fi
## Install NXP toolchain
- if [ ${BUILD_ARCH:-0} = jn516x ] ; then
$WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part1.tar.bz2 &&
$WGET http://simonduq.github.io/resources/ba-elf-gcc-4.7.4-part2.tar.bz2 &&
$WGET http://simonduq.github.io/resources/jn516x-sdk-4163.tar.bz2 &&
mkdir /tmp/jn516x-sdk /tmp/ba-elf-gcc &&
tar xjf jn516x-sdk-*.tar.bz2 -C /tmp/jn516x-sdk &&
tar xjf ba-elf-gcc-*part1.tar.bz2 -C /tmp/ba-elf-gcc &&
tar xjf ba-elf-gcc-*part2.tar.bz2 -C /tmp/ba-elf-gcc &&
sudo cp -f -r /tmp/jn516x-sdk /usr/ &&
sudo cp -f -r /tmp/ba-elf-gcc /usr/ &&
export PATH=/usr/ba-elf-gcc/bin:$PATH &&
rm -rf /tmp/ba-elf-gcc* /tmp/jn516x-sdk* &&
ba-elf-gcc --version ;
fi
## Compile cooja.jar only when it's going to be needed ## Compile cooja.jar only when it's going to be needed
- if [ ${BUILD_CATEGORY:-sim} = sim ] ; then - if [ ${BUILD_CATEGORY:-sim} = sim ] ; then
java -version && java -version &&
@ -120,5 +137,6 @@ env:
- BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs' - BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs'
- BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502' - BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502'
- BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs' - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs'
- BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x'
- BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja' - BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja'
- BUILD_TYPE='llsec' MAKE_TARGETS='cooja' - BUILD_TYPE='llsec' MAKE_TARGETS='cooja'

View file

@ -24,7 +24,7 @@ static char send_udp = 0;
static const char *prompt = "contiki> "; static const char *prompt = "contiki> ";
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static char * CC_FASTCALL static char *
n(uint16_t num, char *ptr) n(uint16_t num, char *ptr)
{ {
uint16_t d; uint16_t d;

View file

@ -58,9 +58,9 @@ LIST(observers_list);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/*- Internal API ------------------------------------------------------------*/ /*- Internal API ------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
coap_observer_t * static coap_observer_t *
coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token, add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
size_t token_len, const char *uri) size_t token_len, const char *uri, int uri_len)
{ {
/* Remove existing observe relationship, if any. */ /* Remove existing observe relationship, if any. */
coap_remove_observer_by_uri(addr, port, uri); coap_remove_observer_by_uri(addr, port, uri);
@ -68,7 +68,12 @@ coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
coap_observer_t *o = memb_alloc(&observers_memb); coap_observer_t *o = memb_alloc(&observers_memb);
if(o) { if(o) {
o->url = uri; int max = sizeof(o->url) - 1;
if(max > uri_len) {
max = uri_len;
}
memcpy(o->url, uri, max);
o->url[max] = 0;
uip_ipaddr_copy(&o->addr, addr); uip_ipaddr_copy(&o->addr, addr);
o->port = port; o->port = port;
o->token_len = token_len; o->token_len = token_len;
@ -177,18 +182,47 @@ coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port, uint16_t mid)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
coap_notify_observers(resource_t *resource) coap_notify_observers(resource_t *resource)
{
coap_notify_observers_sub(resource, NULL);
}
void
coap_notify_observers_sub(resource_t *resource, const char *subpath)
{ {
/* build notification */ /* build notification */
coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */ coap_packet_t notification[1]; /* this way the packet can be treated as pointer as usual */
coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0); coap_packet_t request[1]; /* this way the packet can be treated as pointer as usual */
coap_observer_t *obs = NULL; coap_observer_t *obs = NULL;
int url_len, obs_url_len;
char url[COAP_OBSERVER_URL_LEN];
PRINTF("Observe: Notification from %s\n", resource->url); url_len = strlen(resource->url);
strncpy(url, resource->url, COAP_OBSERVER_URL_LEN - 1);
if(url_len < COAP_OBSERVER_URL_LEN - 1 && subpath != NULL) {
strncpy(&url[url_len], subpath, COAP_OBSERVER_URL_LEN - url_len - 1);
}
/* Ensure url is null terminated because strncpy does not guarantee this */
url[COAP_OBSERVER_URL_LEN - 1] = '\0';
/* url now contains the notify URL that needs to match the observer */
PRINTF("Observe: Notification from %s\n", url);
coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0);
/* create a "fake" request for the URI */
coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0);
coap_set_header_uri_path(request, url);
/* iterate over observers */ /* iterate over observers */
url_len = strlen(url);
for(obs = (coap_observer_t *)list_head(observers_list); obs; for(obs = (coap_observer_t *)list_head(observers_list); obs;
obs = obs->next) { obs = obs->next) {
if(obs->url == resource->url) { /* using RESOURCE url pointer as handle */ obs_url_len = strlen(obs->url);
/* Do a match based on the parent/sub-resource match so that it is
possible to do parent-node observe */
if((obs_url_len == url_len
|| (obs_url_len > url_len
&& (resource->flags & HAS_SUB_RESOURCES)
&& obs->url[url_len] == '/'))
&& strncmp(url, obs->url, url_len) == 0) {
coap_transaction_t *transaction = NULL; coap_transaction_t *transaction = NULL;
/*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */ /*TODO implement special transaction for CON, sharing the same buffer to allow for more observers */
@ -209,7 +243,7 @@ coap_notify_observers(resource_t *resource)
/* prepare response */ /* prepare response */
notification->mid = transaction->mid; notification->mid = transaction->mid;
resource->get_handler(NULL, notification, resource->get_handler(request, notification,
transaction->packet + COAP_MAX_HEADER_SIZE, transaction->packet + COAP_MAX_HEADER_SIZE,
REST_MAX_CHUNK_SIZE, NULL); REST_MAX_CHUNK_SIZE, NULL);
@ -234,14 +268,12 @@ coap_observe_handler(resource_t *resource, void *request, void *response)
coap_packet_t *const coap_res = (coap_packet_t *)response; coap_packet_t *const coap_res = (coap_packet_t *)response;
coap_observer_t * obs; coap_observer_t * obs;
static char content[16];
if(coap_req->code == COAP_GET && coap_res->code < 128) { /* GET request and 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(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) {
if(coap_req->observe == 0) { if(coap_req->observe == 0) {
obs = coap_add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, obs = add_observer(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
coap_req->token, coap_req->token_len, coap_req->token, coap_req->token_len,
resource->url); coap_req->uri_path, coap_req->uri_path_len);
if(obs) { if(obs) {
coap_set_header_observe(coap_res, (obs->obs_counter)++); coap_set_header_observe(coap_res, (obs->obs_counter)++);
/* /*
@ -249,13 +281,14 @@ coap_observe_handler(resource_t *resource, void *request, void *response)
* A subscription should return the same representation as a normal GET. * A subscription should return the same representation as a normal GET.
* Uncomment if you want an information about the avaiable observers. * Uncomment if you want an information about the avaiable observers.
*/ */
/* #if 0
* coap_set_payload(coap_res, static char content[16];
* content, coap_set_payload(coap_res,
* snprintf(content, sizeof(content), "Added %u/%u", content,
* list_length(observers_list), snprintf(content, sizeof(content), "Added %u/%u",
* COAP_MAX_OBSERVERS)); list_length(observers_list),
*/ COAP_MAX_OBSERVERS));
#endif
} else { } else {
coap_res->code = SERVICE_UNAVAILABLE_5_03; coap_res->code = SERVICE_UNAVAILABLE_5_03;
coap_set_payload(coap_res, "TooManyObservers", 16); coap_set_payload(coap_res, "TooManyObservers", 16);

View file

@ -43,6 +43,8 @@
#include "er-coap-transactions.h" #include "er-coap-transactions.h"
#include "stimer.h" #include "stimer.h"
#define COAP_OBSERVER_URL_LEN 20
typedef struct coap_observable { typedef struct coap_observable {
uint32_t observe_clock; uint32_t observe_clock;
struct stimer orphan_timer; struct stimer orphan_timer;
@ -54,7 +56,7 @@ typedef struct coap_observable {
typedef struct coap_observer { typedef struct coap_observer {
struct coap_observer *next; /* for LIST */ struct coap_observer *next; /* for LIST */
const char *url; char url[COAP_OBSERVER_URL_LEN];
uip_ipaddr_t addr; uip_ipaddr_t addr;
uint16_t port; uint16_t port;
uint8_t token_len; uint8_t token_len;
@ -68,11 +70,6 @@ typedef struct coap_observer {
} coap_observer_t; } coap_observer_t;
list_t coap_get_observers(void); 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,
const char *url);
void coap_remove_observer(coap_observer_t *o); 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_client(uip_ipaddr_t *addr, uint16_t port);
int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port, int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
@ -83,6 +80,7 @@ int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port,
uint16_t mid); uint16_t mid);
void coap_notify_observers(resource_t *resource); void coap_notify_observers(resource_t *resource);
void coap_notify_observers_sub(resource_t *resource, const char *subpath);
void coap_observe_handler(resource_t *resource, void *request, void coap_observe_handler(resource_t *resource, void *request,
void *response); void *response);

View file

@ -124,7 +124,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
continue; continue;
} }
end = attrib + strlen(attrib); end = attrib + strlen(attrib);
} else { } else if(resource->attributes != NULL) {
attrib = strstr(resource->attributes, filter); attrib = strstr(resource->attributes, filter);
if(attrib == NULL if(attrib == NULL
|| (attrib[strlen(filter)] != '=' || (attrib[strlen(filter)] != '='
@ -159,8 +159,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
} }
#endif #endif
PRINTF("res: /%s (%p)\npos: s%d, o%ld, b%d\n", resource->url, resource, PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource,
strpos, *offset, bufpos); strpos, (long)*offset, bufpos);
if(strpos > 0) { if(strpos > 0) {
ADD_CHAR_IF_POSSIBLE(','); ADD_CHAR_IF_POSSIBLE(',');
@ -170,7 +170,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
ADD_STRING_IF_POSSIBLE(resource->url, >=); ADD_STRING_IF_POSSIBLE(resource->url, >=);
ADD_CHAR_IF_POSSIBLE('>'); ADD_CHAR_IF_POSSIBLE('>');
if(resource->attributes[0]) { if(resource->attributes != NULL && resource->attributes[0]) {
ADD_CHAR_IF_POSSIBLE(';'); ADD_CHAR_IF_POSSIBLE(';');
ADD_STRING_IF_POSSIBLE(resource->attributes, >); ADD_STRING_IF_POSSIBLE(resource->attributes, >);
} }
@ -183,7 +183,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
} }
if(bufpos > 0) { if(bufpos > 0) {
PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *)buffer); PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer);
coap_set_payload(response, buffer, bufpos); coap_set_payload(response, buffer, bufpos);
coap_set_header_content_format(response, APPLICATION_LINK_FORMAT); coap_set_header_content_format(response, APPLICATION_LINK_FORMAT);

View file

@ -113,15 +113,9 @@ coap_send_transaction(coap_transaction_t *t)
(float)t->retrans_timer.timer.interval / CLOCK_SECOND); (float)t->retrans_timer.timer.interval / CLOCK_SECOND);
} }
/*FIXME PROCESS_CONTEXT_BEGIN(transaction_handler_process);
* Hack: Setting timer for responsible process.
* Maybe there is a better way, but avoid posting everything to the process.
*/
struct process *process_actual = PROCESS_CURRENT();
process_current = transaction_handler_process;
etimer_restart(&t->retrans_timer); /* interval updated above */ etimer_restart(&t->retrans_timer); /* interval updated above */
process_current = process_actual; PROCESS_CONTEXT_END(transaction_handler_process);
t = NULL; t = NULL;
} else { } else {

View file

@ -113,19 +113,21 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length); buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
/* avoids code duplication without function overhead */ if(delta > 268) {
unsigned int *x = &delta; buffer[++written] = ((delta - 269) >> 8) & 0xff;
buffer[++written] = (delta - 269) & 0xff;
} else if(delta > 12) {
buffer[++written] = (delta - 13);
}
do { if(length > 268) {
if(*x > 268) { buffer[++written] = ((length - 269) >> 8) & 0xff;
buffer[++written] = (*x - 269) >> 8; buffer[++written] = (length - 269) & 0xff;
buffer[++written] = (*x - 269); } else if(length > 12) {
} else if(*x > 12) { buffer[++written] = (length - 13);
buffer[++written] = (*x - 13); }
}
} while(x != &length && (x = &length));
PRINTF("WRITTEN %u B opt header\n", 1 + written); PRINTF("WRITTEN %zu B opt header\n", 1 + written);
return ++written; return ++written;
} }
@ -148,7 +150,7 @@ coap_serialize_int_option(unsigned int number, unsigned int current_number,
if(0xFFFFFFFF & value) { if(0xFFFFFFFF & value) {
++i; ++i;
} }
PRINTF("OPTION %u (delta %u, len %u)\n", number, number - current_number, PRINTF("OPTION %u (delta %u, len %zu)\n", number, number - current_number,
i); i);
i = coap_set_option_header(number - current_number, i, buffer); i = coap_set_option_header(number - current_number, i, buffer);
@ -175,8 +177,8 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
{ {
size_t i = 0; size_t i = 0;
PRINTF("ARRAY type %u, len %u, full [%.*s]\n", number, length, length, PRINTF("ARRAY type %u, len %zu, full [%.*s]\n", number, length,
array); (int)length, array);
if(split_char != '\0') { if(split_char != '\0') {
int j; int j;
@ -185,7 +187,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
size_t temp_length; size_t temp_length;
for(j = 0; j <= length + 1; ++j) { for(j = 0; j <= length + 1; ++j) {
PRINTF("STEP %u/%u (%c)\n", j, length, array[j]); PRINTF("STEP %u/%zu (%c)\n", j, length, array[j]);
if(array[j] == split_char || j == length) { if(array[j] == split_char || j == length) {
part_end = array + j; part_end = array + j;
temp_length = part_end - part_start; temp_length = part_end - part_start;
@ -195,8 +197,8 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
memcpy(&buffer[i], part_start, temp_length); memcpy(&buffer[i], part_start, temp_length);
i += temp_length; i += temp_length;
PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number, PRINTF("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number,
number - current_number, i, temp_length, part_start); number - current_number, i, (int)temp_length, part_start);
++j; /* skip the splitter */ ++j; /* skip the splitter */
current_number = number; current_number = number;
@ -208,7 +210,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
memcpy(&buffer[i], array, length); memcpy(&buffer[i], array, length);
i += length; i += length;
PRINTF("OPTION type %u, delta %u, len %u\n", number, PRINTF("OPTION type %u, delta %u, len %zu\n", number,
number - current_number, length); number - current_number, length);
} }
@ -332,7 +334,7 @@ coap_serialize_message(void *packet, uint8_t *buffer)
/* empty packet, dont need to do more stuff */ /* empty packet, dont need to do more stuff */
if(!coap_pkt->code) { if(!coap_pkt->code) {
PRINTF("-Done serializing empty message at %p-\n", option); PRINTF("-Done serializing empty message at %p-\n", coap_pkt->buffer);
return 4; return 4;
} }
@ -368,6 +370,7 @@ coap_serialize_message(void *packet, uint8_t *buffer)
"Location-Path"); "Location-Path");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/', COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/',
"Uri-Path"); "Uri-Path");
PRINTF("Serialize content format: %d\n", coap_pkt->content_format);
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format, COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
"Content-Format"); "Content-Format");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age"); COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age");
@ -403,8 +406,9 @@ coap_serialize_message(void *packet, uint8_t *buffer)
} }
PRINTF("-Done %u B (header len %u, payload len %u)-\n", PRINTF("-Done %u B (header len %u, payload len %u)-\n",
coap_pkt->payload_len + option - buffer, option - buffer, (unsigned int)(coap_pkt->payload_len + option - buffer),
coap_pkt->payload_len); (unsigned int)(option - buffer),
(unsigned int)coap_pkt->payload_len);
PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n", PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
coap_pkt->buffer[0], coap_pkt->buffer[0],
@ -451,10 +455,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
>> COAP_HEADER_VERSION_POSITION; >> COAP_HEADER_VERSION_POSITION;
coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0]) coap_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
>> COAP_HEADER_TYPE_POSITION; >> COAP_HEADER_TYPE_POSITION;
coap_pkt->token_len = coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])
MIN(COAP_TOKEN_LEN, >> COAP_HEADER_TOKEN_LEN_POSITION;
(COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->
buffer[0]) >> COAP_HEADER_TOKEN_LEN_POSITION);
coap_pkt->code = coap_pkt->buffer[1]; coap_pkt->code = coap_pkt->buffer[1];
coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3]; coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
@ -463,6 +465,11 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
return BAD_REQUEST_4_00; return BAD_REQUEST_4_00;
} }
if(coap_pkt->token_len > COAP_TOKEN_LEN) {
coap_error_message = "Token Length must not be more than 8";
return BAD_REQUEST_4_00;
}
uint8_t *current_option = data + COAP_HEADER_LEN; uint8_t *current_option = data + COAP_HEADER_LEN;
memcpy(coap_pkt->token, current_option, coap_pkt->token_len); memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
@ -500,25 +507,31 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
option_length = current_option[0] & 0x0F; option_length = current_option[0] & 0x0F;
++current_option; ++current_option;
/* avoids code duplication without function overhead */ if(option_delta == 13) {
unsigned int *x = &option_delta; option_delta += current_option[0];
++current_option;
} else if(option_delta == 14) {
option_delta += 255;
option_delta += current_option[0] << 8;
++current_option;
option_delta += current_option[0];
++current_option;
}
do { if(option_length == 13) {
if(*x == 13) { option_length += current_option[0];
*x += current_option[0]; ++current_option;
++current_option; } else if(option_length == 14) {
} else if(*x == 14) { option_length += 255;
*x += 255; option_length += current_option[0] << 8;
*x += current_option[0] << 8; ++current_option;
++current_option; option_length += current_option[0];
*x += current_option[0]; ++current_option;
++current_option; }
}
} while(x != &option_length && (x = &option_length));
option_number += option_delta; option_number += option_delta;
PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta, PRINTF("OPTION %u (delta %u, len %zu): ", option_number, option_delta,
option_length); option_length);
SET_OPTION(coap_pkt, option_number); SET_OPTION(coap_pkt, option_number);
@ -532,7 +545,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
case COAP_OPTION_MAX_AGE: case COAP_OPTION_MAX_AGE:
coap_pkt->max_age = coap_parse_int_option(current_option, coap_pkt->max_age = coap_parse_int_option(current_option,
option_length); option_length);
PRINTF("Max-Age [%lu]\n", coap_pkt->max_age); PRINTF("Max-Age [%lu]\n", (unsigned long)coap_pkt->max_age);
break; break;
case COAP_OPTION_ETAG: case COAP_OPTION_ETAG:
coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length); coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
@ -569,7 +582,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_pkt->proxy_uri = (char *)current_option; coap_pkt->proxy_uri = (char *)current_option;
coap_pkt->proxy_uri_len = option_length; coap_pkt->proxy_uri_len = option_length;
#endif #endif
PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len, PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (int)coap_pkt->proxy_uri_len,
coap_pkt->proxy_uri); coap_pkt->proxy_uri);
coap_error_message = "This is a constrained server (Contiki)"; coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05; return PROXYING_NOT_SUPPORTED_5_05;
@ -580,7 +593,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_pkt->proxy_scheme_len = option_length; coap_pkt->proxy_scheme_len = option_length;
#endif #endif
PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n", PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme); (int)coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
coap_error_message = "This is a constrained server (Contiki)"; coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05; return PROXYING_NOT_SUPPORTED_5_05;
break; break;
@ -588,7 +601,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
case COAP_OPTION_URI_HOST: case COAP_OPTION_URI_HOST:
coap_pkt->uri_host = (char *)current_option; coap_pkt->uri_host = (char *)current_option;
coap_pkt->uri_host_len = option_length; coap_pkt->uri_host_len = option_length;
PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host); PRINTF("Uri-Host [%.*s]\n", (int)coap_pkt->uri_host_len,
coap_pkt->uri_host);
break; break;
case COAP_OPTION_URI_PORT: case COAP_OPTION_URI_PORT:
coap_pkt->uri_port = coap_parse_int_option(current_option, coap_pkt->uri_port = coap_parse_int_option(current_option,
@ -600,14 +614,14 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_merge_multi_option((char **)&(coap_pkt->uri_path), coap_merge_multi_option((char **)&(coap_pkt->uri_path),
&(coap_pkt->uri_path_len), current_option, &(coap_pkt->uri_path_len), current_option,
option_length, '/'); option_length, '/');
PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path); PRINTF("Uri-Path [%.*s]\n", (int)coap_pkt->uri_path_len, coap_pkt->uri_path);
break; break;
case COAP_OPTION_URI_QUERY: case COAP_OPTION_URI_QUERY:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */ /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **)&(coap_pkt->uri_query), coap_merge_multi_option((char **)&(coap_pkt->uri_query),
&(coap_pkt->uri_query_len), current_option, &(coap_pkt->uri_query_len), current_option,
option_length, '&'); option_length, '&');
PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len, PRINTF("Uri-Query [%.*s]\n", (int)coap_pkt->uri_query_len,
coap_pkt->uri_query); coap_pkt->uri_query);
break; break;
@ -616,7 +630,7 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_merge_multi_option((char **)&(coap_pkt->location_path), coap_merge_multi_option((char **)&(coap_pkt->location_path),
&(coap_pkt->location_path_len), current_option, &(coap_pkt->location_path_len), current_option,
option_length, '/'); option_length, '/');
PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len, PRINTF("Location-Path [%.*s]\n", (int)coap_pkt->location_path_len,
coap_pkt->location_path); coap_pkt->location_path);
break; break;
case COAP_OPTION_LOCATION_QUERY: case COAP_OPTION_LOCATION_QUERY:
@ -624,14 +638,14 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_merge_multi_option((char **)&(coap_pkt->location_query), coap_merge_multi_option((char **)&(coap_pkt->location_query),
&(coap_pkt->location_query_len), current_option, &(coap_pkt->location_query_len), current_option,
option_length, '&'); option_length, '&');
PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len, PRINTF("Location-Query [%.*s]\n", (int)coap_pkt->location_query_len,
coap_pkt->location_query); coap_pkt->location_query);
break; break;
case COAP_OPTION_OBSERVE: case COAP_OPTION_OBSERVE:
coap_pkt->observe = coap_parse_int_option(current_option, coap_pkt->observe = coap_parse_int_option(current_option,
option_length); option_length);
PRINTF("Observe [%lu]\n", coap_pkt->observe); PRINTF("Observe [%lu]\n", (unsigned long)coap_pkt->observe);
break; break;
case COAP_OPTION_BLOCK2: case COAP_OPTION_BLOCK2:
coap_pkt->block2_num = coap_parse_int_option(current_option, coap_pkt->block2_num = coap_parse_int_option(current_option,
@ -641,7 +655,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F) coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
<< (coap_pkt->block2_num & 0x07); << (coap_pkt->block2_num & 0x07);
coap_pkt->block2_num >>= 4; coap_pkt->block2_num >>= 4;
PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num, PRINTF("Block2 [%lu%s (%u B/blk)]\n",
(unsigned long)coap_pkt->block2_num,
coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size); coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
break; break;
case COAP_OPTION_BLOCK1: case COAP_OPTION_BLOCK1:
@ -652,16 +667,17 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F) coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
<< (coap_pkt->block1_num & 0x07); << (coap_pkt->block1_num & 0x07);
coap_pkt->block1_num >>= 4; coap_pkt->block1_num >>= 4;
PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num, PRINTF("Block1 [%lu%s (%u B/blk)]\n",
(unsigned long)coap_pkt->block1_num,
coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size); coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
break; break;
case COAP_OPTION_SIZE2: case COAP_OPTION_SIZE2:
coap_pkt->size2 = coap_parse_int_option(current_option, option_length); coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
PRINTF("Size2 [%lu]\n", coap_pkt->size2); PRINTF("Size2 [%lu]\n", (unsigned long)coap_pkt->size2);
break; break;
case COAP_OPTION_SIZE1: case COAP_OPTION_SIZE1:
coap_pkt->size1 = coap_parse_int_option(current_option, option_length); coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
PRINTF("Size1 [%lu]\n", coap_pkt->size1); PRINTF("Size1 [%lu]\n", (unsigned long)coap_pkt->size1);
break; break;
default: default:
PRINTF("unknown (%u)\n", option_number); PRINTF("unknown (%u)\n", option_number);
@ -744,7 +760,7 @@ 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 = format;
SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT); SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
return 1; return 1;
} }
@ -765,7 +781,7 @@ 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 = accept;
SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT); SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
return 1; return 1;
} }

View file

@ -93,7 +93,7 @@ typedef struct {
uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */ uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */
coap_content_format_t content_format; /* parse options once and store; allows setting options in random order */ uint16_t content_format; /* parse options once and store; allows setting options in random order */
uint32_t max_age; uint32_t max_age;
uint8_t etag_len; uint8_t etag_len;
uint8_t etag[COAP_ETAG_LEN]; uint8_t etag[COAP_ETAG_LEN];
@ -111,7 +111,7 @@ typedef struct {
size_t uri_path_len; size_t uri_path_len;
const char *uri_path; const char *uri_path;
int32_t observe; int32_t observe;
coap_content_format_t accept; uint16_t accept;
uint8_t if_match_len; uint8_t if_match_len;
uint8_t if_match[COAP_ETAG_LEN]; uint8_t if_match[COAP_ETAG_LEN];
uint32_t block2_num; uint32_t block2_num;
@ -135,13 +135,13 @@ typedef struct {
/* option format serialization */ /* option format serialization */
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \ #define COAP_SERIALIZE_INT_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \ if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%u]\n", coap_pkt->field); \ PRINTF(text " [%u]\n", (unsigned int)coap_pkt->field); \
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \ option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
current_number = number; \ current_number = number; \
} }
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \ #define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \ if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \ PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", (unsigned int)coap_pkt->field##_len, \
coap_pkt->field[0], \ coap_pkt->field[0], \
coap_pkt->field[1], \ coap_pkt->field[1], \
coap_pkt->field[2], \ coap_pkt->field[2], \
@ -156,18 +156,18 @@ typedef struct {
} }
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \ #define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
if(IS_OPTION(coap_pkt, number)) { \ if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \ PRINTF(text " [%.*s]\n", (int)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); \ option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \
current_number = number; \ current_number = number; \
} }
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \ #define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) \ 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); \ PRINTF(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
uint32_t block = coap_pkt->field##_num << 4; \ uint32_t block = coap_pkt->field##_num << 4; \
if(coap_pkt->field##_more) { block |= 0x8; } \ if(coap_pkt->field##_more) { block |= 0x8; } \
block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \ block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \
PRINTF(text " encoded: 0x%lX\n", block); \ PRINTF(text " encoded: 0x%lX\n", (unsigned long)block); \
option += coap_serialize_int_option(number, current_number, option, block); \ option += coap_serialize_int_option(number, current_number, option, block); \
current_number = number; \ current_number = number; \
} }

View file

@ -48,15 +48,15 @@
struct powertrace_sniff_stats { struct powertrace_sniff_stats {
struct powertrace_sniff_stats *next; struct powertrace_sniff_stats *next;
uint32_t num_input, num_output; unsigned long num_input, num_output;
uint32_t input_txtime, input_rxtime; unsigned long input_txtime, input_rxtime;
uint32_t output_txtime, output_rxtime; unsigned long output_txtime, output_rxtime;
#if NETSTACK_CONF_WITH_IPV6 #if NETSTACK_CONF_WITH_IPV6
uint16_t proto; /* includes proto + possibly flags */ uint16_t proto; /* includes proto + possibly flags */
#endif #endif
uint16_t channel; uint16_t channel;
uint32_t last_input_txtime, last_input_rxtime; unsigned long last_input_txtime, last_input_rxtime;
uint32_t last_output_txtime, last_output_rxtime; unsigned long last_output_txtime, last_output_rxtime;
}; };
#define INPUT 1 #define INPUT 1
@ -72,17 +72,17 @@ PROCESS(powertrace_process, "Periodic power output");
void void
powertrace_print(char *str) powertrace_print(char *str)
{ {
static uint32_t last_cpu, last_lpm, last_transmit, last_listen; static unsigned long last_cpu, last_lpm, last_transmit, last_listen;
static uint32_t last_idle_transmit, last_idle_listen; static unsigned long last_idle_transmit, last_idle_listen;
uint32_t cpu, lpm, transmit, listen; unsigned long cpu, lpm, transmit, listen;
uint32_t all_cpu, all_lpm, all_transmit, all_listen; unsigned long all_cpu, all_lpm, all_transmit, all_listen;
uint32_t idle_transmit, idle_listen; unsigned long idle_transmit, idle_listen;
uint32_t all_idle_transmit, all_idle_listen; unsigned long all_idle_transmit, all_idle_listen;
static uint32_t seqno; static unsigned long seqno;
uint32_t time, all_time, radio, all_radio; unsigned long time, all_time, radio, all_radio;
struct powertrace_sniff_stats *s; struct powertrace_sniff_stats *s;
@ -287,13 +287,8 @@ output_sniffer(int mac_status)
static void static void
sniffprint(char *prefix, int seqno) sniffprint(char *prefix, int seqno)
{ {
const linkaddr_t *sender, *receiver, *esender, *ereceiver; const linkaddr_t *esender;
sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
receiver = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
esender = packetbuf_addr(PACKETBUF_ADDR_ESENDER); esender = packetbuf_addr(PACKETBUF_ADDR_ESENDER);
ereceiver = packetbuf_addr(PACKETBUF_ADDR_ERECEIVER);
printf("%lu %s %d %u %d %d %d.%d %u %u\n", printf("%lu %s %d %u %d %d %d.%d %u %u\n",
clock_time(), clock_time(),

View file

@ -70,6 +70,15 @@ LIST(restful_periodic_services);
void void
rest_init_engine(void) rest_init_engine(void)
{ {
/* avoid initializing twice */
static uint8_t initialized = 0;
if(initialized) {
PRINTF("REST engine process already running - double initialization?\n");
return;
}
initialized = 1;
list_init(restful_services); list_init(restful_services);
REST.set_service_callback(rest_invoke_restful_service); REST.set_service_callback(rest_invoke_restful_service);
@ -124,15 +133,19 @@ rest_invoke_restful_service(void *request, void *response, uint8_t *buffer,
resource_t *resource = NULL; resource_t *resource = NULL;
const char *url = NULL; const char *url = NULL;
int url_len, res_url_len;
url_len = REST.get_url(request, &url);
for(resource = (resource_t *)list_head(restful_services); for(resource = (resource_t *)list_head(restful_services);
resource; resource = resource->next) { resource; resource = resource->next) {
/* if the web service handles that kind of requests and urls matches */ /* if the web service handles that kind of requests and urls matches */
if((REST.get_url(request, &url) == strlen(resource->url) res_url_len = strlen(resource->url);
|| (REST.get_url(request, &url) > strlen(resource->url) if((url_len == res_url_len
&& (resource->flags & HAS_SUB_RESOURCES))) || (url_len > res_url_len
&& strncmp(resource->url, url, strlen(resource->url)) == 0) { && (resource->flags & HAS_SUB_RESOURCES)
&& url[res_url_len] == '/'))
&& strncmp(resource->url, url, res_url_len) == 0) {
found = 1; found = 1;
rest_resource_flags_t method = REST.get_method_type(request); rest_resource_flags_t method = REST.get_method_type(request);

View file

@ -332,14 +332,10 @@ static void
parse_incoming_packet(const uint8_t *buf, int len) parse_incoming_packet(const uint8_t *buf, int len)
{ {
int numregs; int numregs;
int flags;
int i; int i;
int bufptr; int bufptr;
numregs = buf[MSG_NUMREGS_OFFSET]; numregs = buf[MSG_NUMREGS_OFFSET];
flags = buf[MSG_FLAGS_OFFSET];
/* printf("parse_incoming_packet Numregs %d flags %d\n", numregs, flags);*/
bufptr = MSG_ADDRS_OFFSET; bufptr = MSG_ADDRS_OFFSET;
for(i = 0; i < numregs; ++i) { for(i = 0; i < numregs; ++i) {

View file

@ -50,6 +50,7 @@
#define HAVE_ALLOCA 0 #define HAVE_ALLOCA 0
#else #else
#define HAVE_ALLOCA 1 #define HAVE_ALLOCA 1
#include <alloca.h>
#endif #endif
#define DEBUG 0 #define DEBUG 0

View file

@ -71,7 +71,7 @@ PROCESS_THREAD(shell_poke_process, ev, data)
PROCESS_EXIT(); PROCESS_EXIT();
} }
address = (uint8_t *)(int)shell_strtolong(args, &next); address = (uint8_t *)(uintptr_t)shell_strtolong(args, &next);
if(next == args) { if(next == args) {
shell_output_str(&poke_command, "usage 1", ""); shell_output_str(&poke_command, "usage 1", "");
PROCESS_EXIT(); PROCESS_EXIT();
@ -106,7 +106,7 @@ PROCESS_THREAD(shell_peek_process, ev, data)
PROCESS_EXIT(); PROCESS_EXIT();
} }
address = (uint8_t *)(int)shell_strtolong(args, &next); address = (uint8_t *)(uintptr_t)shell_strtolong(args, &next);
if(next == args) { if(next == args) {
shell_output_str(&peek_command, "usage 1", ""); shell_output_str(&peek_command, "usage 1", "");
PROCESS_EXIT(); PROCESS_EXIT();

View file

@ -128,8 +128,8 @@ memcpy_misaligned(void *dest, const void *source, int len)
int i; int i;
uint8_t *destptr; uint8_t *destptr;
const uint8_t *sourceptr; const uint8_t *sourceptr;
if(((int)dest & 1) == 1 || if(((uintptr_t)dest & 1) == 1 ||
((int)source & 1) == 1) { ((uintptr_t)source & 1) == 1) {
destptr = dest; destptr = dest;
sourceptr = source; sourceptr = source;
for(i = 0; i < len; ++i) { for(i = 0; i < len; ++i) {

View file

@ -129,7 +129,7 @@ PROCESS_THREAD(shell_netcmd_process, ev, data)
/* Terminate the string with a NUL character. */ /* Terminate the string with a NUL character. */
msg->netcmd[len] = 0; msg->netcmd[len] = 0;
msg->crc = crc16_data(msg->netcmd, len, 0); msg->crc = crc16_data((unsigned char *)msg->netcmd, len, 0);
printf("netcmd sending '%s'\n", msg->netcmd); printf("netcmd sending '%s'\n", msg->netcmd);
trickle_send(&trickle); trickle_send(&trickle);
} }
@ -157,7 +157,7 @@ recv_trickle(struct trickle_conn *c)
msg->netcmd[len] = 0; msg->netcmd[len] = 0;
memcpy(&crc, &msg->crc, sizeof(crc)); memcpy(&crc, &msg->crc, sizeof(crc));
if(crc == crc16_data(msg->netcmd, len, 0)) { if(crc == crc16_data((unsigned char *)msg->netcmd, len, 0)) {
/* Start the server process with the incoming command. */ /* Start the server process with the incoming command. */
process_start(&shell_netcmd_server_process, (void *)msg->netcmd); process_start(&shell_netcmd_server_process, (void *)msg->netcmd);
} }

View file

@ -133,7 +133,7 @@ PROCESS_THREAD(shell_sendcmd_process, ev, data)
/* Terminate the string with a NUL character. */ /* Terminate the string with a NUL character. */
msg->sendcmd[len] = 0; msg->sendcmd[len] = 0;
msg->crc = crc16_data(msg->sendcmd, len, 0); msg->crc = crc16_data((unsigned char *)msg->sendcmd, len, 0);
/* printf("sendcmd sending '%s'\n", msg->sendcmd);*/ /* printf("sendcmd sending '%s'\n", msg->sendcmd);*/
unicast_send(&uc, &addr); unicast_send(&uc, &addr);
@ -160,7 +160,7 @@ recv_uc(struct unicast_conn *c, const linkaddr_t *from)
msg->sendcmd[len] = 0; msg->sendcmd[len] = 0;
memcpy(&crc, &msg->crc, sizeof(crc)); memcpy(&crc, &msg->crc, sizeof(crc));
if(crc == crc16_data(msg->sendcmd, len, 0)) { if(crc == crc16_data((unsigned char *)msg->sendcmd, len, 0)) {
/* Start the server process with the incoming command. */ /* Start the server process with the incoming command. */
process_start(&shell_sendcmd_server_process, (void *)msg->sendcmd); process_start(&shell_sendcmd_server_process, (void *)msg->sendcmd);
} }

View file

@ -301,7 +301,7 @@ recv_collect(const linkaddr_t *originator, uint8_t seqno, uint8_t hops)
/* Copy the collect message header. */ /* Copy the collect message header. */
memcpy(&collect_msg, packetbuf_dataptr(), sizeof(collect_msg)); memcpy(&collect_msg, packetbuf_dataptr(), sizeof(collect_msg));
dataptr = ((struct collect_msg *)packetbuf_dataptr())->data; dataptr = (char *)((struct collect_msg *)packetbuf_dataptr())->data;
#if TIMESYNCH_CONF_ENABLED #if TIMESYNCH_CONF_ENABLED
latency = timesynch_time() - collect_msg.timestamp; latency = timesynch_time() - collect_msg.timestamp;
@ -321,7 +321,7 @@ recv_collect(const linkaddr_t *originator, uint8_t seqno, uint8_t hops)
if(packetbuf_datalen() >= COLLECT_MSG_HDRSIZE) { if(packetbuf_datalen() >= COLLECT_MSG_HDRSIZE) {
len = packetbuf_datalen() - COLLECT_MSG_HDRSIZE; len = packetbuf_datalen() - COLLECT_MSG_HDRSIZE;
if(collect_msg.crc == crc16_data(dataptr, len, 0)) { if(collect_msg.crc == crc16_data((unsigned char *)dataptr, len, 0)) {
msg.len = 5 + (packetbuf_datalen() - COLLECT_MSG_HDRSIZE) / 2; msg.len = 5 + (packetbuf_datalen() - COLLECT_MSG_HDRSIZE) / 2;
linkaddr_copy((linkaddr_t *)&msg.originator, originator); linkaddr_copy((linkaddr_t *)&msg.originator, originator);
msg.seqno = seqno; msg.seqno = seqno;

View file

@ -158,7 +158,6 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data)
static char *command; static char *command;
static struct process *started_process; static struct process *started_process;
char command_copy[MAX_COMMANDLENGTH]; char command_copy[MAX_COMMANDLENGTH];
int ret;
if(ev == shell_event_input) { if(ev == shell_event_input) {
goto exit; goto exit;
@ -172,7 +171,7 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data)
data == &shell_repeat_process); data == &shell_repeat_process);
{ {
strncpy(command_copy, command, MAX_COMMANDLENGTH); strncpy(command_copy, command, MAX_COMMANDLENGTH);
ret = shell_start_command(command_copy, (int)strlen(command_copy), shell_start_command(command_copy, (int)strlen(command_copy),
&repeat_command, &started_process); &repeat_command, &started_process);
if(started_process != NULL && if(started_process != NULL &&
@ -202,11 +201,10 @@ repeat_print_usage(void)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_repeat_process, ev, data) PROCESS_THREAD(shell_repeat_process, ev, data)
{ {
static int reps, period, period_left; static int reps, period;
static char command[MAX_COMMANDLENGTH]; static char command[MAX_COMMANDLENGTH];
static struct etimer etimer; static struct etimer etimer;
static int i; static int i;
static clock_time_t start_time;
const char *args, *next; const char *args, *next;
if(ev == shell_event_input) { if(ev == shell_event_input) {
@ -258,7 +256,6 @@ PROCESS_THREAD(shell_repeat_process, ev, data)
/* printf("repeats %d period %d command '%s'\n", /* printf("repeats %d period %d command '%s'\n",
reps, period, command);*/ reps, period, command);*/
start_time = clock_time();
etimer_set(&etimer, CLOCK_SECOND * period); etimer_set(&etimer, CLOCK_SECOND * period);
for(i = 0; reps == 0 || i < reps; ++i) { for(i = 0; reps == 0 || i < reps; ++i) {
@ -291,7 +288,6 @@ PROCESS_THREAD(shell_randwait_process, ev, data)
static struct etimer etimer; static struct etimer etimer;
static struct process *started_process; static struct process *started_process;
const char *args, *next; const char *args, *next;
int ret;
/* if(ev == shell_event_input) { /* if(ev == shell_event_input) {
struct shell_input *input; struct shell_input *input;
@ -339,7 +335,7 @@ PROCESS_THREAD(shell_randwait_process, ev, data)
/* printf("Starting '%s' child %p (%s)\n", command, randwait_command.child, */ /* printf("Starting '%s' child %p (%s)\n", command, randwait_command.child, */
/* randwait_command.child == NULL? "null": randwait_command.child->command); */ /* randwait_command.child == NULL? "null": randwait_command.child->command); */
ret = shell_start_command(command, (int)strlen(command), shell_start_command(command, (int)strlen(command),
randwait_command.child, &started_process); randwait_command.child, &started_process);
if(started_process != NULL && if(started_process != NULL &&

View file

@ -51,7 +51,7 @@
#define SHELL_VARS_RAM_END SHELL_VARS_CONF_RAM_END #define SHELL_VARS_RAM_END SHELL_VARS_CONF_RAM_END
#else /* SHELL_VARS_CONF_RAM_BEGIN */ #else /* SHELL_VARS_CONF_RAM_BEGIN */
#define SHELL_VARS_RAM_BEGIN 0 #define SHELL_VARS_RAM_BEGIN 0
#define SHELL_VARS_RAM_END (unsigned int)-1 #define SHELL_VARS_RAM_END (uintptr_t)-1
#endif /* SHELL_VARS_CONF_RAM_BEGIN */ #endif /* SHELL_VARS_CONF_RAM_BEGIN */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -77,8 +77,8 @@ PROCESS_THREAD(shell_vars_process, ev, data)
for(i = 0; i < symbols_nelts; ++i) { for(i = 0; i < symbols_nelts; ++i) {
if(symbols[i].name != NULL && if(symbols[i].name != NULL &&
(unsigned int)symbols[i].value >= SHELL_VARS_RAM_BEGIN && (uintptr_t)symbols[i].value >= SHELL_VARS_RAM_BEGIN &&
(unsigned int)symbols[i].value <= SHELL_VARS_RAM_END) { (uintptr_t)symbols[i].value <= SHELL_VARS_RAM_END) {
shell_output_str(&vars_command, (char *)symbols[i].name, ""); shell_output_str(&vars_command, (char *)symbols[i].name, "");
} }
} }

View file

@ -222,7 +222,7 @@ static const char *tags[] = {
}; };
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL static unsigned char
iswhitespace(char c) iswhitespace(char c)
{ {
return (c == ISO_space || return (c == ISO_space ||
@ -255,7 +255,7 @@ htmlparser_init(void)
#endif /* WWW_CONF_FORMS */ #endif /* WWW_CONF_FORMS */
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static char CC_FASTCALL static char
lowercase(char c) lowercase(char c)
{ {
/* XXX: This is a *brute force* approach to lower-case /* XXX: This is a *brute force* approach to lower-case
@ -276,7 +276,7 @@ endtagfound(void)
s.tagattrparam[s.tagattrparamptr] = 0; s.tagattrparam[s.tagattrparamptr] = 0;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
switch_majorstate(unsigned char newstate) switch_majorstate(unsigned char newstate)
{ {
if(s.majorstate != newstate) { if(s.majorstate != newstate) {
@ -286,7 +286,7 @@ switch_majorstate(unsigned char newstate)
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
add_char(unsigned char c) add_char(unsigned char c)
{ {
if(s.wordlen < WWW_CONF_WEBPAGE_WIDTH - 1 && c < 0x80) { if(s.wordlen < WWW_CONF_WEBPAGE_WIDTH - 1 && c < 0x80) {
@ -320,7 +320,7 @@ newline(void)
htmlparser_newline(); htmlparser_newline();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL static unsigned char
find_tag(char *tag) find_tag(char *tag)
{ {
static unsigned char first, last, i, tabi; static unsigned char first, last, i, tabi;
@ -521,7 +521,7 @@ parse_tag(void)
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static uint16_t CC_FASTCALL static uint16_t
parse_word(char *data, uint8_t dlen) parse_word(char *data, uint8_t dlen)
{ {
static uint8_t i; static uint8_t i;

View file

@ -200,7 +200,7 @@ window_copy(int curptr, const char *data, unsigned char datalen)
len = windowend - windowstart; len = windowend - windowstart;
} }
strncpy(windowptr + windowstart, data, len); strncpy((char *)(windowptr + windowstart), data, len);
windowstart += len; windowstart += len;
return curptr + datalen; return curptr + datalen;
@ -217,7 +217,7 @@ senddata(void)
windowstart = s.getrequestptr; windowstart = s.getrequestptr;
curptr = 0; curptr = 0;
windowend = windowstart + uip_mss(); windowend = windowstart + uip_mss();
windowptr = (char *)uip_appdata - windowstart; windowptr = (unsigned char *)uip_appdata - windowstart;
curptr = window_copy(curptr, http_get, sizeof(http_get) - 1); curptr = window_copy(curptr, http_get, sizeof(http_get) - 1);
curptr = window_copy(curptr, s.file, (unsigned char)strlen(s.file)); curptr = window_copy(curptr, s.file, (unsigned char)strlen(s.file));
@ -479,6 +479,11 @@ webclient_appcall(void *state)
if(uip_closed()) { if(uip_closed()) {
tcp_markconn(uip_conn, NULL); tcp_markconn(uip_conn, NULL);
/* Client requested close takes precedence over server initiated close. */
if(s.state == WEBCLIENT_STATE_CLOSE) {
webclient_closed();
return;
}
switch(s.httpflag) { switch(s.httpflag) {
case HTTPFLAG_HTTPS: case HTTPFLAG_HTTPS:
/* Send some info to the user. */ /* Send some info to the user. */

View file

@ -34,12 +34,14 @@
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h>
#include "ctk/ctk.h" #include "ctk/ctk.h"
#include "ctk/ctk-textentry-cmdline.h" #include "ctk/ctk-textentry-cmdline.h"
#include "contiki-net.h" #include "contiki-net.h"
#include "lib/petsciiconv.h" #include "lib/petsciiconv.h"
#include "sys/arg.h" #include "sys/arg.h"
#include "sys/log.h"
#if WWW_CONF_WITH_WGET #if WWW_CONF_WITH_WGET
#include "program-handler.h" #include "program-handler.h"
#endif /* WWW_CONF_WITH_WGET */ #endif /* WWW_CONF_WITH_WGET */
@ -50,13 +52,8 @@
#include "www.h" #include "www.h"
#if 1 /* Explicitly declare itoa as it is non-standard and not necessarily in stdlib.h */
#define PRINTF(x) char *itoa(int value, char *str, int base);
#else
#include <stdio.h>
#define PRINTF(x) printf x
#endif
/* The array that holds the current URL. */ /* The array that holds the current URL. */
static char url[WWW_CONF_MAX_URLLEN + 1]; static char url[WWW_CONF_MAX_URLLEN + 1];
@ -196,7 +193,7 @@ PROCESS(www_process, "Web browser");
AUTOSTART_PROCESSES(&www_process); AUTOSTART_PROCESSES(&www_process);
static void CC_FASTCALL formsubmit(struct inputattrib *trigger); static void formsubmit(struct inputattrib *trigger);
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* make_window() /* make_window()
@ -232,7 +229,7 @@ redraw_window(void)
ctk_window_redraw(&mainwindow); ctk_window_redraw(&mainwindow);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static char * CC_FASTCALL static char *
add_pageattrib(unsigned size) add_pageattrib(unsigned size)
{ {
char *ptr; char *ptr;
@ -246,7 +243,7 @@ add_pageattrib(unsigned size)
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if WWW_CONF_FORMS #if WWW_CONF_FORMS
static void CC_FASTCALL static void
add_forminput(struct inputattrib *inputptr) add_forminput(struct inputattrib *inputptr)
{ {
inputptr->nextptr = NULL; inputptr->nextptr = NULL;
@ -285,13 +282,24 @@ start_loading(void)
clear_page(); clear_page();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
show_statustext(char *text) show_statustext(char *text)
{ {
ctk_label_set_text(&statustext, text); ctk_label_set_text(&statustext, text);
CTK_WIDGET_REDRAW(&statustext); CTK_WIDGET_REDRAW(&statustext);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void
end_page(char *status, void *focus)
{
show_statustext(status);
petsciiconv_topetscii(webpageptr - x, x);
CTK_WIDGET_FOCUS(&mainwindow, focus);
redraw_window();
log_message("Page attribs free: ", itoa(pageattribs + sizeof(pageattribs) - pageattribptr,
pageattribs + sizeof(pageattribs) - 5, 10));
}
/*-----------------------------------------------------------------------------------*/
/* open_url(): /* open_url():
* *
* Called when the URL present in the global "url" variable should be * Called when the URL present in the global "url" variable should be
@ -389,7 +397,7 @@ open_url(void)
* Will format a link from the current web pages so that it suits the * Will format a link from the current web pages so that it suits the
* open_url() function. * open_url() function.
*/ */
static void CC_FASTCALL static void
set_link(char *link) set_link(char *link)
{ {
register char *urlptr; register char *urlptr;
@ -609,7 +617,7 @@ PROCESS_THREAD(www_process, ev, data)
* "url" variable and the visible "editurl" (which is shown in the URL * "url" variable and the visible "editurl" (which is shown in the URL
* text entry widget in the browser window). * text entry widget in the browser window).
*/ */
static void CC_FASTCALL static void
set_url(char *host, uint16_t port, char *file) set_url(char *host, uint16_t port, char *file)
{ {
char *urlptr; char *urlptr;
@ -660,10 +668,7 @@ webclient_timedout(void)
void void
webclient_closed(void) webclient_closed(void)
{ {
show_statustext("Stopped"); end_page("Stopped", &downbutton);
petsciiconv_topetscii(webpageptr - x, x);
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
redraw_window();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* webclient_connected(): /* webclient_connected():
@ -710,6 +715,7 @@ webclient_datahandler(char *data, uint16_t len)
" Would you like to download instead?"); " Would you like to download instead?");
CTK_WIDGET_ADD(&mainwindow, &wgetnobutton); CTK_WIDGET_ADD(&mainwindow, &wgetnobutton);
CTK_WIDGET_ADD(&mainwindow, &wgetyesbutton); CTK_WIDGET_ADD(&mainwindow, &wgetyesbutton);
CTK_WIDGET_FOCUS(&mainwindow, &wgetyesbutton);
redraw_window(); redraw_window();
#endif /* CTK_CONF_WINDOWS */ #endif /* CTK_CONF_WINDOWS */
#endif /* WWW_CONF_WITH_WGET || WWW_CONF_WGET_EXEC */ #endif /* WWW_CONF_WITH_WGET || WWW_CONF_WGET_EXEC */
@ -721,14 +727,11 @@ webclient_datahandler(char *data, uint16_t len)
if(data == NULL) { if(data == NULL) {
loading = 0; loading = 0;
show_statustext("Done"); end_page("Done", &urlentry);
petsciiconv_topetscii(webpageptr - x, x);
CTK_WIDGET_FOCUS(&mainwindow, &urlentry);
redraw_window();
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
unsigned char border) unsigned char border)
{ {
@ -842,7 +845,9 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
void void
htmlparser_newline(void) htmlparser_newline(void)
{ {
#ifdef WITH_PETSCII
char *wptr; char *wptr;
#endif /* WITH_PETSCII */
if(++newlines > 2) { if(++newlines > 2) {
return; return;
@ -862,8 +867,10 @@ htmlparser_newline(void)
++y; ++y;
x = 0; x = 0;
#ifdef WITH_PETSCII
wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH; wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH;
petsciiconv_topetscii(wptr, WWW_CONF_WEBPAGE_WIDTH); petsciiconv_topetscii(wptr, WWW_CONF_WEBPAGE_WIDTH);
#endif /* WITH_PETSCII */
if(y == WWW_CONF_WEBPAGE_HEIGHT) { if(y == WWW_CONF_WEBPAGE_HEIGHT) {
loading = 0; loading = 0;
@ -935,7 +942,7 @@ htmlparser_inputfield(unsigned char type, unsigned char size, char *text, char *
} }
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
add_query(char delimiter, char *string) add_query(char delimiter, char *string)
{ {
static char *query; static char *query;
@ -963,7 +970,7 @@ add_query(char delimiter, char *string)
query += length; query += length;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL static void
formsubmit(struct inputattrib *trigger) formsubmit(struct inputattrib *trigger)
{ {
struct inputattrib *input; struct inputattrib *input;

View file

@ -1,3 +1,3 @@
<html><head><link rel="stylesheet" type="text/css" href="s.css"></head><body><center> <html><head><link rel="stylesheet" type="text/css" href="s.css"></head><body><center>
%! tictac %! tictac
</center></body></html> </center></body></html>

View file

@ -1,3 +1,3 @@
<html><head><link rel="stylesheet" type="text/css" href="s.css"></head><body><center> <html><head><link rel="stylesheet" type="text/css" href="s.css"></head><body><center>
%! tictac %! tictac
</center></body></html> </center></body></html>

View file

@ -80,7 +80,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen)
*dest = ISO_slash; *dest = ISO_slash;
strncpy(dest + 1, wwwroot, wwwrootlen); strncpy(dest + 1, wwwroot, wwwrootlen);
len = 0; len = 0;
from = source; to = dest + wwwrootlen; from = (unsigned char *)source; to = (unsigned char *)dest + wwwrootlen;
maxlen -= 2 + wwwrootlen; maxlen -= 2 + wwwrootlen;
do { do {
c = *(from++); c = *(from++);
@ -139,7 +139,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen)
} }
} while(c); } while(c);
if(*to == ISO_slash && (len + sizeof(http_index_htm) - 3) < maxlen) { if(*to == ISO_slash && (len + sizeof(http_index_htm) - 3) < maxlen) {
strcpy(to, http_index_htm); // add index.htm strcpy((char *)to, http_index_htm); // add index.htm
} else { } else {
++to; ++to;
*to = 0; *to = 0;

View file

@ -192,10 +192,24 @@
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 #define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */ #endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/* UIP_CONF_ND6_SEND_RA enables standard IPv6 Router Advertisement.
* We enable it by default when IPv6 is used without RPL. */
#ifndef UIP_CONF_ND6_SEND_RA
#define UIP_CONF_ND6_SEND_RA (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL)
#endif /* UIP_CONF_ND6_SEND_RA */
/* UIP_CONF_ND6_SEND_NA enables standard IPv6 Neighbor Discovery Protocol. /* UIP_CONF_ND6_SEND_NA enables standard IPv6 Neighbor Discovery Protocol.
This is unneeded when RPL is used. Disable to save ROM and a little RAM. */ We enable it by default when IPv6 is used without RPL.
With RPL, the neighbor cache (link-local IPv6 <-> MAC address mapping)
is fed whenever receiving DIO and DAO messages. This is always sufficient
for RPL routing, i.e. to send to the preferred parent or any child.
Link-local unicast to other neighbors may, however, not be possible if
we never receive any DIO from them. This may happen if the link from the
neighbor to us is weak, if DIO transmissions are suppressed (Trickle
timer) or if the neighbor chooses not to transmit DIOs because it is
a leaf node or for any reason. */
#ifndef UIP_CONF_ND6_SEND_NA #ifndef UIP_CONF_ND6_SEND_NA
#define UIP_CONF_ND6_SEND_NA 1 #define UIP_CONF_ND6_SEND_NA (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL)
#endif /* UIP_CONF_ND6_SEND_NA */ #endif /* UIP_CONF_ND6_SEND_NA */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -155,14 +155,14 @@ ctk_filedialog_eventhandler(struct ctk_filedialog_state *s,
} }
return 1; return 1;
} else if(ev == ctk_signal_keypress) { } else if(ev == ctk_signal_keypress) {
if((ctk_arch_key_t)data == CH_CURS_UP) { if((char)(size_t)data == CH_CURS_UP) {
clearptr(); clearptr();
if(fileptr > 0) { if(fileptr > 0) {
--fileptr; --fileptr;
} }
showptr(); showptr();
return 1; return 1;
} else if((ctk_arch_key_t)data == CH_CURS_DOWN) { } else if((char)(size_t)data == CH_CURS_DOWN) {
clearptr(); clearptr();
if(fileptr < FILES_HEIGHT - 1) { if(fileptr < FILES_HEIGHT - 1) {
++fileptr; ++fileptr;

View file

@ -185,7 +185,7 @@ unsigned short ctk_screensaver_timeout = (5*60);
static struct timer timer; static struct timer timer;
#endif /* CTK_CONF_SCREENSAVER */ #endif /* CTK_CONF_SCREENSAVER */
static void CC_FASTCALL static void
textentry_input(ctk_arch_key_t c, textentry_input(ctk_arch_key_t c,
CC_REGISTER_ARG struct ctk_textentry *t); CC_REGISTER_ARG struct ctk_textentry *t);
@ -555,7 +555,7 @@ ctk_menu_remove(struct ctk_menu *menu)
* \param clipy2 The lower bound of the clip interval * \param clipy2 The lower bound of the clip interval
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void CC_FASTCALL static void
do_redraw_all(unsigned char clipy1, unsigned char clipy2) do_redraw_all(unsigned char clipy1, unsigned char clipy2)
{ {
#if CTK_CONF_WINDOWS #if CTK_CONF_WINDOWS
@ -818,7 +818,7 @@ ctk_menuitem_add(CC_REGISTER_ARG struct ctk_menu *menu, char *name)
* \param w The widget that should be redrawn. * \param w The widget that should be redrawn.
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void CC_FASTCALL static void
add_redrawwidget(struct ctk_widget *w) add_redrawwidget(struct ctk_widget *w)
{ {
static unsigned char i; static unsigned char i;
@ -852,7 +852,9 @@ add_redrawwidget(struct ctk_widget *w)
static void static void
widget_redraw(struct ctk_widget *widget) widget_redraw(struct ctk_widget *widget)
{ {
#if CTK_CONF_WINDOWS
struct ctk_window *window; struct ctk_window *window;
#endif /* CTK_CONF_WINDOWS */
if(mode != CTK_MODE_NORMAL || widget == NULL) { if(mode != CTK_MODE_NORMAL || widget == NULL) {
return; return;
@ -870,8 +872,8 @@ widget_redraw(struct ctk_widget *widget)
if(menus.open == NULL) if(menus.open == NULL)
#endif /* CTK_CONF_MENUS */ #endif /* CTK_CONF_MENUS */
{ {
window = widget->window;
#if CTK_CONF_WINDOWS #if CTK_CONF_WINDOWS
window = widget->window;
if(window == dialog) { if(window == dialog) {
ctk_draw_widget(widget, CTK_FOCUS_DIALOG, 0, height); ctk_draw_widget(widget, CTK_FOCUS_DIALOG, 0, height);
} else if(dialog == NULL && } else if(dialog == NULL &&
@ -921,7 +923,7 @@ ctk_widget_redraw(struct ctk_widget *widget)
* \param widget The widget to be added. * \param widget The widget to be added.
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void CC_FASTCALL void
ctk_widget_add(CC_REGISTER_ARG struct ctk_window *window, ctk_widget_add(CC_REGISTER_ARG struct ctk_window *window,
CC_REGISTER_ARG struct ctk_widget *widget) CC_REGISTER_ARG struct ctk_widget *widget)
{ {
@ -973,7 +975,7 @@ ctk_desktop_height(struct ctk_desktop *d)
* \param focus The widget to be focused. * \param focus The widget to be focused.
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void CC_FASTCALL static void
select_widget(struct ctk_widget *focus) select_widget(struct ctk_widget *focus)
{ {
struct ctk_window *window; struct ctk_window *window;
@ -1001,7 +1003,7 @@ select_widget(struct ctk_widget *focus)
#define DOWN 1 #define DOWN 1
#define LEFT 2 #define LEFT 2
#define RIGHT 3 #define RIGHT 3
static void CC_FASTCALL static void
switch_focus_widget(unsigned char direction) switch_focus_widget(unsigned char direction)
{ {
#if CTK_CONF_WINDOWS #if CTK_CONF_WINDOWS
@ -1126,7 +1128,7 @@ switch_menu_item(unsigned char updown)
} }
#endif /* CTK_CONF_MENUS */ #endif /* CTK_CONF_MENUS */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL static unsigned char
activate(CC_REGISTER_ARG struct ctk_widget *w) activate(CC_REGISTER_ARG struct ctk_widget *w)
{ {
if(w->type == CTK_WIDGET_BUTTON) { if(w->type == CTK_WIDGET_BUTTON) {
@ -1183,7 +1185,7 @@ ctk_textentry_input_null(ctk_arch_key_t c, struct ctk_textentry *t)
} }
#endif /* SDCC */ #endif /* SDCC */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void CC_FASTCALL static void
textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t) textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t)
{ {
register char *cptr, *cptr2; register char *cptr, *cptr2;

View file

@ -743,8 +743,8 @@ void ctk_icon_add(struct ctk_widget *icon, struct process *p);
*/ */
#define CTK_WIDGET_ADD(win, widg) \ #define CTK_WIDGET_ADD(win, widg) \
ctk_widget_add(win, (struct ctk_widget *)widg) ctk_widget_add(win, (struct ctk_widget *)widg)
CCIF void CC_FASTCALL ctk_widget_add(struct ctk_window *window, CCIF void ctk_widget_add(struct ctk_window *window,
struct ctk_widget *widget); struct ctk_widget *widget);
/** /**
* Set focus to a widget. * Set focus to a widget.

View file

@ -48,14 +48,11 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
set_nonce(uint8_t *iv, set_iv(uint8_t *iv,
uint8_t flags, uint8_t flags,
const uint8_t *nonce, const uint8_t *nonce,
uint8_t counter) uint8_t counter)
{ {
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
iv[0] = flags; iv[0] = flags;
memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH); memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
iv[14] = 0; iv[14] = 0;
@ -73,7 +70,7 @@ ctr_step(const uint8_t *nonce,
uint8_t a[AES_128_BLOCK_SIZE]; uint8_t a[AES_128_BLOCK_SIZE];
uint8_t i; uint8_t i;
set_nonce(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter); set_iv(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter);
AES_128.encrypt(a); AES_128.encrypt(a);
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
@ -82,9 +79,9 @@ ctr_step(const uint8_t *nonce,
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
mic(const uint8_t *m, uint8_t m_len, mic(const uint8_t *nonce,
const uint8_t *nonce, const uint8_t *m, uint8_t m_len,
const uint8_t *a, uint8_t a_len, const uint8_t *a, uint8_t a_len,
uint8_t *result, uint8_t *result,
uint8_t mic_len) uint8_t mic_len)
{ {
@ -92,10 +89,10 @@ mic(const uint8_t *m, uint8_t m_len,
uint8_t pos; uint8_t pos;
uint8_t i; uint8_t i;
set_nonce(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len); set_iv(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len);
AES_128.encrypt(x); AES_128.encrypt(x);
if(a_len > 0) { if(a_len) {
x[1] = x[1] ^ a_len; x[1] = x[1] ^ a_len;
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) { for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[i - 2]; x[i] ^= a[i - 2];
@ -113,8 +110,7 @@ mic(const uint8_t *m, uint8_t m_len,
} }
} }
if(m_len > 0) { if(m_len) {
m = a + a_len;
pos = 0; pos = 0;
while(pos < m_len) { while(pos < m_len) {
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
@ -131,7 +127,7 @@ mic(const uint8_t *m, uint8_t m_len,
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
ctr(uint8_t *m, uint8_t m_len, const uint8_t* nonce) ctr(const uint8_t *nonce, uint8_t *m, uint8_t m_len)
{ {
uint8_t pos; uint8_t pos;
uint8_t counter; uint8_t counter;
@ -144,13 +140,38 @@ ctr(uint8_t *m, uint8_t m_len, const uint8_t* nonce)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void set_key(const uint8_t *key) { static void
AES_128.set_key((uint8_t*)key); set_key(const uint8_t *key)
{
AES_128.set_key(key);
}
/*---------------------------------------------------------------------------*/
static void
aead(const uint8_t* nonce,
uint8_t* m, uint8_t m_len,
const uint8_t* a, uint8_t a_len,
uint8_t *result, uint8_t mic_len,
int forward)
{
if(!forward) {
/* decrypt */
ctr(nonce, m, m_len);
}
mic(nonce,
m, m_len,
a, a_len,
result,
mic_len);
if(forward) {
/* encrypt */
ctr(nonce, m, m_len);
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
const struct ccm_star_driver ccm_star_driver = { const struct ccm_star_driver ccm_star_driver = {
mic, set_key,
ctr, aead
set_key
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -55,34 +55,26 @@
*/ */
struct ccm_star_driver { struct ccm_star_driver {
/**
* \brief Generates a MIC over the data supplied.
* \param data The data buffer to read.
* \param data_length The data buffer length.
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
* \param result The generated MIC will be put here
* \param mic_len The size of the MIC to be generated. <= 16.
*/
void (* mic)(const uint8_t* data, uint8_t data_length,
const uint8_t* nonce,
const uint8_t* add, uint8_t add_len,
uint8_t *result,
uint8_t mic_len);
/** /**
* \brief XORs the frame in the packetbuf with the key stream. * \brief Sets the key in use. Default implementation calls AES_128.set_key().
* \param data The data buffer to read. * \param key The key to use.
* \param data_length The data buffer length.
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
*/
void (* ctr)( uint8_t* data, uint8_t data_length,
const uint8_t* nonce);
/**
* \brief Sets the key in use. Default implementation calls AES_128.set_key()
* \param key The key to use.
*/ */
void (* set_key)(const uint8_t* key); void (* set_key)(const uint8_t* key);
/**
* \brief Combines authentication and encryption.
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
* \param m message to encrypt or decrypt
* \param a Additional authenticated data
* \param result The generated MIC will be put here
* \param mic_len The size of the MIC to be generated. <= 16.
* \param forward != 0 if used in forward direction.
*/
void (* aead)(const uint8_t* nonce,
uint8_t* m, uint8_t m_len,
const uint8_t* a, uint8_t a_len,
uint8_t *result, uint8_t mic_len,
int forward);
}; };
extern const struct ccm_star_driver CCM_STAR; extern const struct ccm_star_driver CCM_STAR;

View file

@ -38,6 +38,7 @@
*/ */
#include "lib/ringbuf.h" #include "lib/ringbuf.h"
#include <sys/cc.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
ringbuf_init(struct ringbuf *r, uint8_t *dataptr, uint8_t size) ringbuf_init(struct ringbuf *r, uint8_t *dataptr, uint8_t size)
@ -63,8 +64,15 @@ ringbuf_put(struct ringbuf *r, uint8_t c)
if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) { if(((r->put_ptr - r->get_ptr) & r->mask) == r->mask) {
return 0; return 0;
} }
r->data[r->put_ptr] = c; /*
r->put_ptr = (r->put_ptr + 1) & r->mask; * CC_ACCESS_NOW is used because the compiler is allowed to reorder
* the access to non-volatile variables.
* In this case a reader might read from the moved index/ptr before
* its value (c) is written. Reordering makes little sense, but
* better safe than sorry.
*/
CC_ACCESS_NOW(uint8_t, r->data[r->put_ptr]) = c;
CC_ACCESS_NOW(uint8_t, r->put_ptr) = (r->put_ptr + 1) & r->mask;
return 1; return 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -84,8 +92,17 @@ ringbuf_get(struct ringbuf *r)
most platforms, but C does not guarantee this. most platforms, but C does not guarantee this.
*/ */
if(((r->put_ptr - r->get_ptr) & r->mask) > 0) { if(((r->put_ptr - r->get_ptr) & r->mask) > 0) {
c = r->data[r->get_ptr]; /*
r->get_ptr = (r->get_ptr + 1) & r->mask; * CC_ACCESS_NOW is used because the compiler is allowed to reorder
* the access to non-volatile variables.
* In this case the memory might be freed and overwritten by
* increasing get_ptr before the value was copied to c.
* Opposed to the put-operation this would even make sense,
* because the register used for mask can be reused to save c
* (on some architectures).
*/
c = CC_ACCESS_NOW(uint8_t, r->data[r->get_ptr]);
CC_ACCESS_NOW(uint8_t, r->get_ptr) = (r->get_ptr + 1) & r->mask;
return c; return c;
} else { } else {
return -1; return -1;

View file

@ -34,6 +34,20 @@
#include "net/ip/uip.h" #include "net/ip/uip.h"
/**
* \brief Is IPv4-mapped Address
*
* See https://tools.ietf.org/html/rfc6890#page-14
*/
#define ip64_addr_is_ipv4_mapped_addr(a) \
((((a)->u16[0]) == 0) && \
(((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0xFFFF))
void ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src); void ip64_addr_copy4(uip_ip4addr_t *dest, const uip_ip4addr_t *src);
void ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src); void ip64_addr_copy6(uip_ip6addr_t *dest, const uip_ip6addr_t *src);

View file

@ -501,7 +501,7 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
for(i = 0; i < UIP_DS6_ADDR_NB; ++i) { for(i = 0; i < UIP_DS6_ADDR_NB; ++i) {
if(uip_ds6_if.addr_list[i].isused if(uip_ds6_if.addr_list[i].isused
#if !RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS #if !RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS
&& uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr) && uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)
#endif #endif
) { ) {
if(!*count) { if(!*count) {

View file

@ -155,6 +155,7 @@ unsigned char tcpip_is_forwarding; /* Forwarding right now? */
PROCESS(tcpip_process, "TCP/IP stack"); PROCESS(tcpip_process, "TCP/IP stack");
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UIP_TCP || UIP_CONF_IP_FORWARD
static void static void
start_periodic_tcp_timer(void) start_periodic_tcp_timer(void)
{ {
@ -162,6 +163,7 @@ start_periodic_tcp_timer(void)
etimer_restart(&periodic); etimer_restart(&periodic);
} }
} }
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
check_for_tcp_syn(void) check_for_tcp_syn(void)
@ -183,30 +185,17 @@ check_for_tcp_syn(void)
static void static void
packet_input(void) packet_input(void)
{ {
#if UIP_CONF_IP_FORWARD
if(uip_len > 0) { if(uip_len > 0) {
#if UIP_CONF_IP_FORWARD
tcpip_is_forwarding = 1; tcpip_is_forwarding = 1;
if(uip_fw_forward() == UIP_FW_LOCAL) { if(uip_fw_forward() != UIP_FW_LOCAL) {
tcpip_is_forwarding = 0; tcpip_is_forwarding = 0;
check_for_tcp_syn(); return;
uip_input();
if(uip_len > 0) {
#if UIP_CONF_TCP_SPLIT
uip_split_output();
#else /* UIP_CONF_TCP_SPLIT */
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
PRINTF("tcpip packet_input forward output len %d\n", uip_len);
tcpip_output();
#endif
#endif /* UIP_CONF_TCP_SPLIT */
}
} }
tcpip_is_forwarding = 0; tcpip_is_forwarding = 0;
} #endif /* UIP_CONF_IP_FORWARD */
#else /* UIP_CONF_IP_FORWARD */
if(uip_len > 0) {
check_for_tcp_syn(); check_for_tcp_syn();
uip_input(); uip_input();
if(uip_len > 0) { if(uip_len > 0) {
@ -215,14 +204,13 @@ packet_input(void)
#else /* UIP_CONF_TCP_SPLIT */ #else /* UIP_CONF_TCP_SPLIT */
#if NETSTACK_CONF_WITH_IPV6 #if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output(); tcpip_ipv6_output();
#else #else /* NETSTACK_CONF_WITH_IPV6 */
PRINTF("tcpip packet_input output len %d\n", uip_len); PRINTF("tcpip packet_input output len %d\n", uip_len);
tcpip_output(); tcpip_output();
#endif #endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* UIP_CONF_TCP_SPLIT */ #endif /* UIP_CONF_TCP_SPLIT */
} }
} }
#endif /* UIP_CONF_IP_FORWARD */
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if UIP_TCP #if UIP_TCP
@ -584,7 +572,16 @@ tcpip_ipv6_output(void)
/* This should be copied from the ext header... */ /* This should be copied from the ext header... */
UIP_IP_BUF->proto = proto; UIP_IP_BUF->proto = proto;
} }
UIP_FALLBACK_INTERFACE.output(); /* Inform the other end that the destination is not reachable. If it's
* not informed routes might get lost unexpectedly until there's a need
* to send a new packet to the peer */
if(UIP_FALLBACK_INTERFACE.output() < 0) {
PRINTF("FALLBACK: output error. Reporting DST UNREACH\n");
uip_icmp6_error_output(ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, 0);
uip_flags = 0;
tcpip_ipv6_output();
return;
}
#else #else
PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
#endif /* !UIP_FALLBACK_INTERFACE */ #endif /* !UIP_FALLBACK_INTERFACE */
@ -672,7 +669,11 @@ tcpip_ipv6_output(void)
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000); stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
nbr->nscount = 1; nbr->nscount = 1;
/* Send the first NS try from here (multicast destination IP address). */
} }
#else /* UIP_ND6_SEND_NA */
uip_len = 0;
return;
#endif /* UIP_ND6_SEND_NA */ #endif /* UIP_ND6_SEND_NA */
} else { } else {
#if UIP_ND6_SEND_NA #if UIP_ND6_SEND_NA
@ -719,7 +720,6 @@ tcpip_ipv6_output(void)
uip_clear_buf(); uip_clear_buf();
return; return;
} }
return;
} }
/* Multicast IP destination address. */ /* Multicast IP destination address. */
tcpip_output(NULL); tcpip_output(NULL);

View file

@ -38,6 +38,7 @@
*/ */
#include "net/ip/uip-debug.h" #include "net/ip/uip-debug.h"
#include "net/ip/ip64-addr.h"
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -53,20 +54,38 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
return; return;
} }
#if NETSTACK_CONF_WITH_IPV6 #if NETSTACK_CONF_WITH_IPV6
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { if(ip64_addr_is_ipv4_mapped_addr(addr)) {
a = (addr->u8[i] << 8) + addr->u8[i + 1]; /*
if(a == 0 && f >= 0) { * Printing IPv4-mapped addresses is done according to RFC 3513 [1]
if(f++ == 0) { *
PRINTA("::"); * "An alternative form that is sometimes more
* convenient when dealing with a mixed environment
* of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d,
* where the 'x's are the hexadecimal values of the
* six high-order 16-bit pieces of the address, and
* the 'd's are the decimal values of the four
* low-order 8-bit pieces of the address (standard
* IPv4 representation)."
*
* [1] https://tools.ietf.org/html/rfc3513#page-5
*/
PRINTA("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]);
} else {
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) {
PRINTA("::");
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTA(":");
}
PRINTA("%x", a);
} }
} else { }
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTA(":");
}
PRINTA("%x", a);
}
} }
#else /* NETSTACK_CONF_WITH_IPV6 */ #else /* NETSTACK_CONF_WITH_IPV6 */
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);

View file

@ -54,9 +54,9 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
if(data != NULL) { if(data != NULL) {
uip_udp_conn = c; uip_udp_conn = c;
uip_slen = len; uip_slen = len;
memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data,
len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN? len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len); UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len);
uip_process(UIP_UDP_SEND_CONN); uip_process(UIP_UDP_SEND_CONN);
#if UIP_CONF_IPV6_MULTICAST #if UIP_CONF_IPV6_MULTICAST

View file

@ -1429,7 +1429,13 @@ extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
struct uip_fallback_interface { struct uip_fallback_interface {
void (*init)(void); void (*init)(void);
void (*output)(void); /**
* \retval >=0
* in case of success
* \retval <0
* in case of failure
*/
int (*output)(void);
}; };
#if UIP_CONF_ICMP6 #if UIP_CONF_ICMP6
@ -2016,8 +2022,9 @@ CCIF extern uip_lladdr_t uip_lladdr;
(((a)->u8[15]) == 0x02)) (((a)->u8[15]) == 0x02))
/** /**
* \brief Checks whether the address a is link local. * \brief is addr (a) a link local unicast address, see RFC3513
* a is of type uip_ipaddr_t * i.e. is (a) on prefix FE80::/10
* a is of type uip_ipaddr_t*
*/ */
#define uip_is_addr_linklocal(a) \ #define uip_is_addr_linklocal(a) \
((a)->u8[0] == 0xfe && \ ((a)->u8[0] == 0xfe && \
@ -2070,15 +2077,6 @@ CCIF extern uip_lladdr_t uip_lladdr;
(((b)->u8[13]) = ((a)->u8[13])); \ (((b)->u8[13]) = ((a)->u8[13])); \
(((b)->u16[7]) = ((a)->u16[7])) (((b)->u16[7]) = ((a)->u16[7]))
/**
* \brief is addr (a) a link local unicast address, see RFC3513
* i.e. is (a) on prefix FE80::/10
* a is of type uip_ipaddr_t*
*/
#define uip_is_addr_link_local(a) \
((((a)->u8[0]) == 0xFE) && \
(((a)->u8[1]) == 0x80))
/** /**
* \brief was addr (a) forged based on the mac address m * \brief was addr (a) forged based on the mac address m
* a type is uip_ipaddr_t * a type is uip_ipaddr_t

View file

@ -35,9 +35,14 @@
#include "ip64-tap-driver.h" #include "ip64-tap-driver.h"
#include "ip64-eth-interface.h" #include "ip64-eth-interface.h"
#define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface #define IP64_CONF_UIP_FALLBACK_INTERFACE ip64_eth_interface
#define IP64_CONF_INPUT ip64_eth_interface_input #define IP64_CONF_INPUT ip64_eth_interface_input
#define IP64_CONF_ETH_DRIVER ip64_tap_driver #define IP64_CONF_ETH_DRIVER ip64_tap_driver
/*
* In contrast to the mandatory parameters above, IP64_CONF_DHCP is an
* optional configuration parameter. The default value is set in ip64.h
*/
/* #define IP64_CONF_DHCP 1 */
#endif /* IP64_CONF_H */ #endif /* IP64_CONF_H */

View file

@ -84,7 +84,7 @@ init(void)
printf("ip64-eth-interface: init\n"); printf("ip64-eth-interface: init\n");
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static int
output(void) output(void)
{ {
int len, ret; int len, ret;
@ -114,7 +114,7 @@ output(void)
printf("Create request\n"); printf("Create request\n");
len = ip64_arp_create_arp_request(ip64_packet_buffer, len = ip64_arp_create_arp_request(ip64_packet_buffer,
&ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]); &ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]);
IP64_ETH_DRIVER.output(ip64_packet_buffer, len); return IP64_ETH_DRIVER.output(ip64_packet_buffer, len);
} }
} }
} }

View file

@ -115,7 +115,7 @@ init(void)
slip_set_input_callback(input_callback); slip_set_input_callback(input_callback);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static int
output(void) output(void)
{ {
int len; int len;
@ -138,8 +138,10 @@ output(void)
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len); memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
uip_len = len; uip_len = len;
slip_send(); slip_send();
return len;
} }
} }
return 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
const struct uip_fallback_interface ip64_slip_interface = { const struct uip_fallback_interface ip64_slip_interface = {

View file

@ -188,7 +188,7 @@ ip64_init(void)
PRINTF("ip64_init\n"); PRINTF("ip64_init\n");
IP64_ETH_DRIVER.init(); IP64_ETH_DRIVER.init();
#if IP64_CONF_DHCP #if IP64_DHCP
ip64_ipv4_dhcp_init(); ip64_ipv4_dhcp_init();
#endif /* IP64_CONF_DHCP */ #endif /* IP64_CONF_DHCP */
@ -894,14 +894,14 @@ ip64_hostaddr_is_configured(void)
static void static void
interface_init(void) interface_init(void)
{ {
IP64_CONF_UIP_FALLBACK_INTERFACE.init(); IP64_UIP_FALLBACK_INTERFACE.init();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
interface_output(void) interface_output(void)
{ {
PRINTF("ip64: interface_output len %d\n", uip_len); PRINTF("ip64: interface_output len %d\n", uip_len);
IP64_CONF_UIP_FALLBACK_INTERFACE.output(); IP64_UIP_FALLBACK_INTERFACE.output();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
const struct uip_fallback_interface ip64_uip_fallback_interface = { const struct uip_fallback_interface ip64_uip_fallback_interface = {

View file

@ -36,12 +36,12 @@
void ip64_init(void); void ip64_init(void);
int ip64_6to4(const uint8_t *ipv6packet, const uint16_t ipv6len, int ip64_6to4(const uint8_t *ipv6packet, const uint16_t ipv6len,
uint8_t *resultpacket); uint8_t *resultpacket);
int ip64_4to6(const uint8_t *ipv4packet, const uint16_t ipv4len, int ip64_4to6(const uint8_t *ipv4packet, const uint16_t ipv4len,
uint8_t *resultpacket); uint8_t *resultpacket);
void ip64_set_ipv4_address(const uip_ip4addr_t *ipv4addr, void ip64_set_ipv4_address(const uip_ip4addr_t *ipv4addr,
const uip_ip4addr_t *netmask); const uip_ip4addr_t *netmask);
void ip64_set_ipv6_address(const uip_ip6addr_t *ipv6addr); void ip64_set_ipv6_address(const uip_ip6addr_t *ipv6addr);
const uip_ip4addr_t *ip64_get_hostaddr(void); const uip_ip4addr_t *ip64_get_hostaddr(void);
@ -71,7 +71,18 @@ extern uint16_t ip64_packet_buffer_maxlen;
#define IP64_INPUT IP64_CONF_INPUT #define IP64_INPUT IP64_CONF_INPUT
#endif /* IP64_CONF_INPUT */ #endif /* IP64_CONF_INPUT */
#ifndef IP64_CONF_UIP_FALLBACK_INTERFACE
#error IP64_CONF_UIP_FALLBACK_INTERFACE must be #defined in ip64-conf.h
#else /* IP64_CONF_UIP_FALLBACK_INTERFACE */
#define IP64_UIP_FALLBACK_INTERFACE IP64_CONF_UIP_FALLBACK_INTERFACE
#endif /* IP64_CONF_UIP_FALLBACK_INTERFACE */
#ifdef IP64_CONF_DHCP
#define IP64_DHCP IP64_CONF_DHCP
#else /* IP64_CONF_DHCP */
/* Enable DHCP per default */
#define IP64_DHCP 1
#endif /* IP64_CONF_DHCP */
#endif /* IP64_H */ #endif /* IP64_H */

View file

@ -436,6 +436,11 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport)
conn->snd_nxt[2] = iss[2]; conn->snd_nxt[2] = iss[2];
conn->snd_nxt[3] = iss[3]; conn->snd_nxt[3] = iss[3];
conn->rcv_nxt[0] = 0;
conn->rcv_nxt[1] = 0;
conn->rcv_nxt[2] = 0;
conn->rcv_nxt[3] = 0;
conn->initialmss = conn->mss = UIP_TCP_MSS; conn->initialmss = conn->mss = UIP_TCP_MSS;
conn->len = 1; /* TCP length of the SYN is one. */ conn->len = 1; /* TCP length of the SYN is one. */
@ -1367,10 +1372,10 @@ uip_process(uint8_t flag)
uip_connr->len = 1; uip_connr->len = 1;
/* rcv_nxt should be the seqno from the incoming packet + 1. */ /* rcv_nxt should be the seqno from the incoming packet + 1. */
uip_connr->rcv_nxt[3] = BUF->seqno[3];
uip_connr->rcv_nxt[2] = BUF->seqno[2];
uip_connr->rcv_nxt[1] = BUF->seqno[1];
uip_connr->rcv_nxt[0] = BUF->seqno[0]; uip_connr->rcv_nxt[0] = BUF->seqno[0];
uip_connr->rcv_nxt[1] = BUF->seqno[1];
uip_connr->rcv_nxt[2] = BUF->seqno[2];
uip_connr->rcv_nxt[3] = BUF->seqno[3];
uip_add_rcv_nxt(1); uip_add_rcv_nxt(1);
/* Parse the TCP MSS option, if present. */ /* Parse the TCP MSS option, if present. */

View file

@ -1100,7 +1100,7 @@ icmp_input()
uint16_t val; uint16_t val;
#if UIP_CONF_IPV6_CHECKS #if UIP_CONF_IPV6_CHECKS
if(!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) { if(!uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) {
PRINTF("ROLL TM: ICMPv6 In, bad source "); PRINTF("ROLL TM: ICMPv6 In, bad source ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(" to "); PRINTF(" to ");

View file

@ -635,7 +635,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr)
iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT, iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
&UIP_IP_BUF->srcipaddr, &uip_lladdr); &UIP_IP_BUF->srcipaddr, &uip_lladdr);
/* No context found for this address */ /* No context found for this address */
} else if(uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && } else if(uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) &&
UIP_IP_BUF->destipaddr.u16[1] == 0 && UIP_IP_BUF->destipaddr.u16[1] == 0 &&
UIP_IP_BUF->destipaddr.u16[2] == 0 && UIP_IP_BUF->destipaddr.u16[2] == 0 &&
UIP_IP_BUF->destipaddr.u16[3] == 0) { UIP_IP_BUF->destipaddr.u16[3] == 0) {
@ -686,7 +686,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr)
iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT, iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
&UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr); &UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr);
/* No context found for this address */ /* No context found for this address */
} else if(uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && } else if(uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) &&
UIP_IP_BUF->destipaddr.u16[1] == 0 && UIP_IP_BUF->destipaddr.u16[1] == 0 &&
UIP_IP_BUF->destipaddr.u16[2] == 0 && UIP_IP_BUF->destipaddr.u16[2] == 0 &&
UIP_IP_BUF->destipaddr.u16[3] == 0) { UIP_IP_BUF->destipaddr.u16[3] == 0) {
@ -1087,9 +1087,9 @@ compress_hdr_hc1(linkaddr_t *link_destaddr)
if(UIP_IP_BUF->vtc != 0x60 || if(UIP_IP_BUF->vtc != 0x60 ||
UIP_IP_BUF->tcflow != 0 || UIP_IP_BUF->tcflow != 0 ||
UIP_IP_BUF->flow != 0 || UIP_IP_BUF->flow != 0 ||
!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) || !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) ||
!uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) || !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) ||
!uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) || !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) ||
!uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr, !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr,
(uip_lladdr_t *)link_destaddr) || (uip_lladdr_t *)link_destaddr) ||
(UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 &&
@ -1443,7 +1443,7 @@ output(const uip_lladdr_t *localdest)
#else /* USE_FRAMER_HDRLEN */ #else /* USE_FRAMER_HDRLEN */
framer_hdrlen = 21; framer_hdrlen = 21;
#endif /* USE_FRAMER_HDRLEN */ #endif /* USE_FRAMER_HDRLEN */
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen - NETSTACK_LLSEC.get_overhead(); max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) {
#if SICSLOWPAN_CONF_FRAG #if SICSLOWPAN_CONF_FRAG
@ -1455,7 +1455,7 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers. * IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch. * The following fragments contain only the fragn dispatch.
*/ */
int estimated_fragments = ((int)uip_len) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1; int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
int freebuf = queuebuf_numfree() - 1; int freebuf = queuebuf_numfree() - 1;
PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf); PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) { if(freebuf < estimated_fragments) {

View file

@ -83,7 +83,9 @@ static uip_ipaddr_t loc_fipaddr;
/* Pointers used in this file */ /* Pointers used in this file */
static uip_ds6_addr_t *locaddr; static uip_ds6_addr_t *locaddr;
static uip_ds6_maddr_t *locmaddr; static uip_ds6_maddr_t *locmaddr;
#if UIP_DS6_AADDR_NB
static uip_ds6_aaddr_t *locaaddr; static uip_ds6_aaddr_t *locaaddr;
#endif /* UIP_DS6_AADDR_NB */
static uip_ds6_prefix_t *locprefix; static uip_ds6_prefix_t *locprefix;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -389,7 +391,7 @@ uip_ds6_get_link_local(int8_t state)
for(locaddr = uip_ds6_if.addr_list; for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if(locaddr->isused && (state == -1 || locaddr->state == state) if(locaddr->isused && (state == -1 || locaddr->state == state)
&& (uip_is_addr_link_local(&locaddr->ipaddr))) { && (uip_is_addr_linklocal(&locaddr->ipaddr))) {
return locaddr; return locaddr;
} }
} }
@ -408,7 +410,7 @@ uip_ds6_get_global(int8_t state)
for(locaddr = uip_ds6_if.addr_list; for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if(locaddr->isused && (state == -1 || locaddr->state == state) if(locaddr->isused && (state == -1 || locaddr->state == state)
&& !(uip_is_addr_link_local(&locaddr->ipaddr))) { && !(uip_is_addr_linklocal(&locaddr->ipaddr))) {
return locaddr; return locaddr;
} }
} }
@ -458,6 +460,7 @@ uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr)
uip_ds6_aaddr_t * uip_ds6_aaddr_t *
uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr) uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
{ {
#if UIP_DS6_AADDR_NB
if(uip_ds6_list_loop if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB, ((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
sizeof(uip_ds6_aaddr_t), ipaddr, 128, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
@ -466,6 +469,7 @@ uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr); uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
return locaaddr; return locaaddr;
} }
#endif /* UIP_DS6_AADDR_NB */
return NULL; return NULL;
} }
@ -483,11 +487,13 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr)
uip_ds6_aaddr_t * uip_ds6_aaddr_t *
uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr) uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
{ {
#if UIP_DS6_AADDR_NB
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list, if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list,
UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128, UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaaddr) == FOUND) { (uip_ds6_element_t **)&locaaddr) == FOUND) {
return locaaddr; return locaaddr;
} }
#endif /* UIP_DS6_AADDR_NB */
return NULL; return NULL;
} }
@ -499,13 +505,13 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
uint8_t n = 0; uint8_t n = 0;
uip_ds6_addr_t *matchaddr = NULL; uip_ds6_addr_t *matchaddr = NULL;
if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) { if(!uip_is_addr_linklocal(dst) && !uip_is_addr_mcast(dst)) {
/* find longest match */ /* find longest match */
for(locaddr = uip_ds6_if.addr_list; for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) { locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
/* Only preferred global (not link-local) addresses */ /* Only preferred global (not link-local) addresses */
if(locaddr->isused && locaddr->state == ADDR_PREFERRED && if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
!uip_is_addr_link_local(&locaddr->ipaddr)) { !uip_is_addr_linklocal(&locaddr->ipaddr)) {
n = get_match_length(dst, &locaddr->ipaddr); n = get_match_length(dst, &locaddr->ipaddr);
if(n >= best) { if(n >= best) {
best = n; best = n;
@ -608,7 +614,7 @@ uip_ds6_dad(uip_ds6_addr_t *addr)
int int
uip_ds6_dad_failed(uip_ds6_addr_t *addr) uip_ds6_dad_failed(uip_ds6_addr_t *addr)
{ {
if(uip_is_addr_link_local(&addr->ipaddr)) { if(uip_is_addr_linklocal(&addr->ipaddr)) {
PRINTF("Contiki shutdown, DAD for link local address failed\n"); PRINTF("Contiki shutdown, DAD for link local address failed\n");
return 0; return 0;
} }

View file

@ -216,9 +216,15 @@ typedef struct uip_ds6_netif {
uint32_t reachable_time; /* in msec */ uint32_t reachable_time; /* in msec */
uint32_t retrans_timer; /* in msec */ uint32_t retrans_timer; /* in msec */
uint8_t maxdadns; uint8_t maxdadns;
#if UIP_DS6_ADDR_NB
uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB]; uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB];
#endif /* UIP_DS6_ADDR_NB */
#if UIP_DS6_AADDR_NB
uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB]; uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB];
#endif /* UIP_DS6_AADDR_NB */
#if UIP_DS6_MADDR_NB
uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB]; uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];
#endif /* UIP_DS6_MADDR_NB */
} uip_ds6_netif_t; } uip_ds6_netif_t;
/** \brief Generic type for a DS6, to use a common loop though all DS */ /** \brief Generic type for a DS6, to use a common loop though all DS */

View file

@ -132,6 +132,16 @@ static uip_ipaddr_t ipaddr;
static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
#endif #endif
#if UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
/*------------------------------------------------------------------*/
/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */
static void
extract_lladdr_aligned(uip_lladdr_t *dest) {
if(dest != NULL && nd6_opt_llao != NULL) {
memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
}
}
#endif /* UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER */
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* create a llao */ /* create a llao */
static void static void
@ -191,15 +201,14 @@ ns_input(void)
#endif /*UIP_CONF_IPV6_CHECKS */ #endif /*UIP_CONF_IPV6_CHECKS */
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) { if(nbr == NULL) {
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_lladdr_t lladdr_aligned;
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], extract_lladdr_aligned(&lladdr_aligned);
0, NBR_STALE); uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
} else { } else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
lladdr, UIP_LLADDR_LEN) != 0) { lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
UIP_LLADDR_LEN);
nbr->state = NBR_STALE; nbr->state = NBR_STALE;
} else { } else {
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
@ -621,18 +630,18 @@ rs_input(void)
goto discard; goto discard;
} else { } else {
#endif /*UIP_CONF_IPV6_CHECKS */ #endif /*UIP_CONF_IPV6_CHECKS */
uip_lladdr_t lladdr_aligned;
extract_lladdr_aligned(&lladdr_aligned);
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) { if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
/* we need to add the neighbor */ /* we need to add the neighbor */
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
} else { } else {
/* If LL address changed, set neighbor state to stale */ /* If LL address changed, set neighbor state to stale */
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) { uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
uip_ds6_nbr_t nbr_data = *nbr; uip_ds6_nbr_t nbr_data = *nbr;
uip_ds6_nbr_rm(nbr); uip_ds6_nbr_rm(nbr);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
nbr->reachable = nbr_data.reachable; nbr->reachable = nbr_data.reachable;
nbr->sendns = nbr_data.sendns; nbr->sendns = nbr_data.sendns;
nbr->nscount = nbr_data.nscount; nbr->nscount = nbr_data.nscount;
@ -823,7 +832,7 @@ ra_input(void)
#if UIP_CONF_IPV6_CHECKS #if UIP_CONF_IPV6_CHECKS
if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) ||
(!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) || (!uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) ||
(UIP_ICMP_BUF->icode != 0)) { (UIP_ICMP_BUF->icode != 0)) {
PRINTF("RA received is bad"); PRINTF("RA received is bad");
goto discard; goto discard;
@ -859,9 +868,9 @@ ra_input(void)
nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF; nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF;
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr); nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) { if(nbr == NULL) {
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, uip_lladdr_t lladdr_aligned;
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], extract_lladdr_aligned(&lladdr_aligned);
1, NBR_STALE); nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE);
} else { } else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr); uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
if(nbr->state == NBR_INCOMPLETE) { if(nbr->state == NBR_INCOMPLETE) {
@ -886,7 +895,7 @@ ra_input(void)
nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF; nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF;
if((uip_ntohl(nd6_opt_prefix_info->validlt) >= if((uip_ntohl(nd6_opt_prefix_info->validlt) >=
uip_ntohl(nd6_opt_prefix_info->preferredlt)) uip_ntohl(nd6_opt_prefix_info->preferredlt))
&& (!uip_is_addr_link_local(&nd6_opt_prefix_info->prefix))) { && (!uip_is_addr_linklocal(&nd6_opt_prefix_info->prefix))) {
/* on-link flag related processing */ /* on-link flag related processing */
if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) { if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) {
prefix = prefix =

View file

@ -288,7 +288,10 @@ struct uip_icmp6_conn uip_icmp6_conns;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Functions */ /* Functions */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if (!UIP_ARCH_ADD32 && UIP_TCP) #if UIP_TCP
#if UIP_ARCH_ADD32
void uip_add32(uint8_t *op32, uint16_t op16);
#else /* UIP_ARCH_ADD32 */
void void
uip_add32(uint8_t *op32, uint16_t op16) uip_add32(uint8_t *op32, uint16_t op16)
{ {
@ -315,8 +318,8 @@ uip_add32(uint8_t *op32, uint16_t op16)
} }
} }
} }
#endif /* UIP_ARCH_ADD32 */
#endif /* UIP_ARCH_ADD32 && UIP_TCP */ #endif /* UIP_TCP */
#if ! UIP_ARCH_CHKSUM #if ! UIP_ARCH_CHKSUM
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -1203,8 +1206,8 @@ uip_process(uint8_t flag)
if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) && if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) { !uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) && if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr) &&
!uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) && !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) &&
!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) && !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) &&
!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) && !uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) { !uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
@ -1238,7 +1241,7 @@ uip_process(uint8_t flag)
UIP_STAT(++uip_stat.ip.forwarded); UIP_STAT(++uip_stat.ip.forwarded);
goto send; goto send;
} else { } else {
if((uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr)) && if((uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr)) &&
(!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) && (!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) &&
(!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) && (!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) &&
(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) && (!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) &&
@ -1745,10 +1748,10 @@ uip_process(uint8_t flag)
uip_connr->len = 1; uip_connr->len = 1;
/* rcv_nxt should be the seqno from the incoming packet + 1. */ /* rcv_nxt should be the seqno from the incoming packet + 1. */
uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0]; uip_connr->rcv_nxt[0] = UIP_TCP_BUF->seqno[0];
uip_connr->rcv_nxt[1] = UIP_TCP_BUF->seqno[1];
uip_connr->rcv_nxt[2] = UIP_TCP_BUF->seqno[2];
uip_connr->rcv_nxt[3] = UIP_TCP_BUF->seqno[3];
uip_add_rcv_nxt(1); uip_add_rcv_nxt(1);
/* Parse the TCP MSS option, if present. */ /* Parse the TCP MSS option, if present. */

View file

@ -55,7 +55,8 @@ anti_replay_set_counter(void)
{ {
frame802154_frame_counter_t reordered_counter; frame802154_frame_counter_t reordered_counter;
reordered_counter.u32 = LLSEC802154_HTONL(++counter); ++counter;
reordered_counter.u32 = LLSEC802154_HTONL(counter);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]);

View file

@ -1,52 +1,78 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/** /**
* \file * \file
* CCM* convenience functions for LLSEC use * CCM* convenience functions for LLSEC use
* \author * \author
* Justin King-Lacroix <justin.kinglacroix@gmail.com> * Justin King-Lacroix <justin.kinglacroix@gmail.com>
* Konrad Krentz <konrad.krentz@gmail.com>
*/ */
#include "lib/ccm-star.h" #include "llsec/ccm-star-packetbuf.h"
#include "net/linkaddr.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include <string.h> #include <string.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void ccm_star_mic_packetbuf(const uint8_t *extended_source_address, static const uint8_t *
uint8_t *result, get_extended_address(const linkaddr_t *addr)
uint8_t mic_len) #if LINKADDR_SIZE == 2
{ {
uint8_t *dataptr = packetbuf_dataptr(); /* workaround for short addresses: derive EUI64 as in RFC 6282 */
uint8_t data_len = packetbuf_datalen(); static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 ,
uint8_t *headerptr = packetbuf_hdrptr(); 0xFF , 0xFE , 0x00 , 0x00 , 0x00 } };
uint8_t header_len = packetbuf_hdrlen();
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
memcpy(nonce, extended_source_address, 8); template.u16[3] = LLSEC802154_HTONS(addr->u16);
return template.u8;
}
#else /* LINKADDR_SIZE == 2 */
{
return addr->u8;
}
#endif /* LINKADDR_SIZE == 2 */
/*---------------------------------------------------------------------------*/
void
ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward)
{
const linkaddr_t *source_addr;
source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER);
memcpy(nonce, get_extended_address(source_addr), 8);
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2)) {
CCM_STAR.mic(dataptr, data_len, nonce, headerptr, header_len, result, mic_len);
} else {
CCM_STAR.mic(dataptr, 0, nonce, headerptr, packetbuf_totlen(), result, mic_len);
}
}
/*---------------------------------------------------------------------------*/
void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address)
{
uint8_t *dataptr = packetbuf_dataptr();
uint8_t data_len = packetbuf_datalen();
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
memcpy(nonce, extended_source_address, 8);
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
CCM_STAR.ctr(dataptr, data_len, nonce);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -1,24 +1,48 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/** /**
* \file * \file
* CCM* convenience functions for MAC security * CCM* convenience functions for MAC security
* \author * \author
* Justin King-Lacroix <justin.kinglacroix@gmail.com> * Justin King-Lacroix <justin.kinglacroix@gmail.com>
* Konrad Krentz <konrad.krentz@gmail.com>
*/ */
#ifndef CCM_STAR_PACKETBUF_H_ #ifndef CCM_STAR_PACKETBUF_H_
#define CCM_STAR_PACKETBUF_H_ #define CCM_STAR_PACKETBUF_H_
/** #include "lib/ccm-star.h"
* \brief Calls CCM_STAR.mic with parameters appropriate for LLSEC.
*/
void ccm_star_mic_packetbuf(const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len);
/** void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward);
* \brief Calls CCM_STAR.ctr with parameters appropriate for LLSEC.
*/
void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address);
#endif /* CCM_STAR_PACKETBUF_H_ */ #endif /* CCM_STAR_PACKETBUF_H_ */

View file

@ -48,10 +48,6 @@
* for incoming packets. Likewise, all NETSTACK_NETWORK protocols * for incoming packets. Likewise, all NETSTACK_NETWORK protocols
* invoke NETSTACK_LLSEC.send(...) for outgoing packets. * invoke NETSTACK_LLSEC.send(...) for outgoing packets.
* *
* The bootstrap function of llsec_drivers can be used to defer the start
* of upper layers so as to bootstrap pairwise keys. Only contiki-sky-main.c
* supports this at the moment.
*
* @{ * @{
*/ */
@ -60,35 +56,23 @@
#include "net/mac/mac.h" #include "net/mac/mac.h"
typedef void (* llsec_on_bootstrapped_t)(void);
/** /**
* The structure of a link layer security driver. * The structure of a link layer security driver.
*/ */
struct llsec_driver { struct llsec_driver {
char *name; char *name;
/** Bootstraps link layer security and thereafter starts upper layers. */ /** Inits link layer security. */
void (* bootstrap)(llsec_on_bootstrapped_t on_bootstrapped); void (* init)(void);
/** Secures outgoing frames before passing them to NETSTACK_MAC. */ /** Secures outgoing frames before passing them to NETSTACK_MAC. */
void (* send)(mac_callback_t sent_callback, void *ptr); void (* send)(mac_callback_t sent_callback, void *ptr);
/**
* Once the NETSTACK_FRAMER wrote the headers, the LLSEC driver
* can generate a MIC over the entire frame.
* \return Returns != 0 <-> success
*/
int (* on_frame_created)(void);
/** /**
* Decrypts incoming frames; * Decrypts incoming frames;
* filters out injected or replayed frames. * filters out injected or replayed frames.
*/ */
void (* input)(void); void (* input)(void);
/** Returns the security-related overhead per frame in bytes */
uint8_t (* get_overhead)(void);
}; };
#endif /* LLSEC_H_ */ #endif /* LLSEC_H_ */

View file

@ -47,6 +47,7 @@
#include "net/llsec/llsec802154.h" #include "net/llsec/llsec802154.h"
#include "net/llsec/ccm-star-packetbuf.h" #include "net/llsec/ccm-star-packetbuf.h"
#include "net/mac/frame802154.h" #include "net/mac/frame802154.h"
#include "net/mac/framer-802154.h"
#include "net/netstack.h" #include "net/netstack.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/nbr-table.h" #include "net/nbr-table.h"
@ -80,81 +81,109 @@ static uint8_t key[16] = NONCORESEC_KEY;
NBR_TABLE(struct anti_replay_info, anti_replay_table); NBR_TABLE(struct anti_replay_info, anti_replay_table);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static const uint8_t * static int
get_extended_address(const linkaddr_t *addr) aead(uint8_t hdrlen, int forward)
#if LINKADDR_SIZE == 2
{ {
/* workaround for short addresses: derive EUI64 as in RFC 6282 */ uint8_t totlen;
static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 , uint8_t nonce[CCM_STAR_NONCE_LENGTH];
0xFF , 0xFE , 0x00 , 0x00 , 0x00 } }; uint8_t *m;
uint8_t m_len;
uint8_t *a;
uint8_t a_len;
uint8_t *result;
uint8_t generated_mic[LLSEC802154_MIC_LENGTH];
uint8_t *mic;
template.u16[3] = LLSEC802154_HTONS(addr->u16); ccm_star_packetbuf_set_nonce(nonce, forward);
totlen = packetbuf_totlen();
a = packetbuf_hdrptr();
#if WITH_ENCRYPTION
a_len = hdrlen;
m = a + a_len;
m_len = totlen - hdrlen;
#else /* WITH_ENCRYPTION */
a_len = totlen;
m = NULL;
m_len = 0;
#endif /* WITH_ENCRYPTION */
return template.u8; mic = a + totlen;
result = forward ? mic : generated_mic;
CCM_STAR.aead(nonce,
m, m_len,
a, a_len,
result, LLSEC802154_MIC_LENGTH,
forward);
if(forward) {
packetbuf_set_datalen(packetbuf_datalen() + LLSEC802154_MIC_LENGTH);
return 1;
} else {
return (memcmp(generated_mic, mic, LLSEC802154_MIC_LENGTH) == 0);
}
} }
#else /* LINKADDR_SIZE == 2 */ /*---------------------------------------------------------------------------*/
static void
add_security_header(void)
{ {
return addr->u8; if(!packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
anti_replay_set_counter();
}
} }
#endif /* LINKADDR_SIZE == 2 */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
send(mac_callback_t sent, void *ptr) send(mac_callback_t sent, void *ptr)
{ {
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
anti_replay_set_counter();
NETSTACK_MAC.send(sent, ptr); NETSTACK_MAC.send(sent, ptr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int static int
on_frame_created(void) create(void)
{ {
uint8_t *dataptr = packetbuf_dataptr(); int result;
uint8_t data_len = packetbuf_datalen();
ccm_star_mic_packetbuf(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
#if WITH_ENCRYPTION
ccm_star_ctr_packetbuf(get_extended_address(&linkaddr_node_addr));
#endif /* WITH_ENCRYPTION */
packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH);
return 1; add_security_header();
result = framer_802154.create();
if(result == FRAMER_FAILED) {
return result;
}
aead(result, 1);
return result;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static int
input(void) parse(void)
{ {
uint8_t generated_mic[LLSEC802154_MIC_LENGTH]; int result;
uint8_t *received_mic;
const linkaddr_t *sender; const linkaddr_t *sender;
struct anti_replay_info* info; struct anti_replay_info* info;
uint8_t *dataptr = packetbuf_dataptr();
uint8_t data_len = packetbuf_datalen(); result = framer_802154.parse();
if(result == FRAMER_FAILED) {
return result;
}
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) { if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) {
PRINTF("noncoresec: received frame with wrong security level\n"); PRINTF("noncoresec: received frame with wrong security level\n");
return; return FRAMER_FAILED;
} }
sender = packetbuf_addr(PACKETBUF_ADDR_SENDER); sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
if(linkaddr_cmp(sender, &linkaddr_node_addr)) { if(linkaddr_cmp(sender, &linkaddr_node_addr)) {
PRINTF("noncoresec: frame from ourselves\n"); PRINTF("noncoresec: frame from ourselves\n");
return; return FRAMER_FAILED;
} }
data_len -= LLSEC802154_MIC_LENGTH; packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
packetbuf_set_datalen(data_len);
#if WITH_ENCRYPTION if(!aead(result, 0)) {
ccm_star_ctr_packetbuf(get_extended_address(sender)); PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n",
#endif /* WITH_ENCRYPTION */
ccm_star_mic_packetbuf(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH);
received_mic = dataptr + data_len;
if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) {
PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n",
anti_replay_get_counter()); anti_replay_get_counter());
return; return FRAMER_FAILED;
} }
info = nbr_table_get_from_lladdr(anti_replay_table, sender); info = nbr_table_get_from_lladdr(anti_replay_table, sender);
@ -162,7 +191,7 @@ input(void)
info = nbr_table_add_lladdr(anti_replay_table, sender); info = nbr_table_add_lladdr(anti_replay_table, sender);
if(!info) { if(!info) {
PRINTF("noncoresec: could not get nbr_table_item\n"); PRINTF("noncoresec: could not get nbr_table_item\n");
return; return FRAMER_FAILED;
} }
/* /*
@ -179,7 +208,7 @@ input(void)
if(!nbr_table_lock(anti_replay_table, info)) { if(!nbr_table_lock(anti_replay_table, info)) {
nbr_table_remove(anti_replay_table, info); nbr_table_remove(anti_replay_table, info);
PRINTF("noncoresec: could not lock\n"); PRINTF("noncoresec: could not lock\n");
return; return FRAMER_FAILED;
} }
anti_replay_init_info(info); anti_replay_init_info(info);
@ -187,34 +216,44 @@ input(void)
if(anti_replay_was_replayed(info)) { if(anti_replay_was_replayed(info)) {
PRINTF("noncoresec: received replayed frame %"PRIu32"\n", PRINTF("noncoresec: received replayed frame %"PRIu32"\n",
anti_replay_get_counter()); anti_replay_get_counter());
return; return FRAMER_FAILED;
} }
} }
NETSTACK_NETWORK.input(); return result;
}
/*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return SECURITY_HEADER_LENGTH + LLSEC802154_MIC_LENGTH;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
bootstrap(llsec_on_bootstrapped_t on_bootstrapped) input(void)
{
NETSTACK_NETWORK.input();
}
/*---------------------------------------------------------------------------*/
static int
length(void)
{
add_security_header();
return framer_802154.length() + LLSEC802154_MIC_LENGTH;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{ {
CCM_STAR.set_key(key); CCM_STAR.set_key(key);
nbr_table_register(anti_replay_table, NULL); nbr_table_register(anti_replay_table, NULL);
on_bootstrapped();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
const struct llsec_driver noncoresec_driver = { const struct llsec_driver noncoresec_driver = {
"noncoresec", "noncoresec",
bootstrap, init,
send, send,
on_frame_created, input
input, };
get_overhead /*---------------------------------------------------------------------------*/
const struct framer noncoresec_framer = {
length,
create,
parse
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -56,6 +56,7 @@
#include "net/llsec/llsec.h" #include "net/llsec/llsec.h"
extern const struct llsec_driver noncoresec_driver; extern const struct llsec_driver noncoresec_driver;
extern const struct framer noncoresec_framer;
#endif /* NONCORESEC_H_ */ #endif /* NONCORESEC_H_ */

View file

@ -49,9 +49,9 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
bootstrap(llsec_on_bootstrapped_t on_bootstrapped) init(void)
{ {
on_bootstrapped();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
@ -61,31 +61,17 @@ send(mac_callback_t sent, void *ptr)
NETSTACK_MAC.send(sent, ptr); NETSTACK_MAC.send(sent, ptr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int
on_frame_created(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static void static void
input(void) input(void)
{ {
NETSTACK_NETWORK.input(); NETSTACK_NETWORK.input();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
const struct llsec_driver nullsec_driver = { const struct llsec_driver nullsec_driver = {
"nullsec", "nullsec",
bootstrap, init,
send, send,
on_frame_created, input
input,
get_overhead
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -73,6 +73,8 @@ extern const struct framer DECORATED_FRAMER;
#define PRINTF(...) #define PRINTF(...)
#endif #endif
static void pad(void);
/* 2-byte header for recovering padded packets. /* 2-byte header for recovering padded packets.
Wireshark will not understand such packets at present. */ Wireshark will not understand such packets at present. */
struct hdr { struct hdr {
@ -99,7 +101,8 @@ create(void)
} }
chdr = packetbuf_hdrptr(); chdr = packetbuf_hdrptr();
chdr->id = CONTIKIMAC_ID; chdr->id = CONTIKIMAC_ID;
chdr->len = 0; chdr->len = packetbuf_datalen();
pad();
hdr_len = DECORATED_FRAMER.create(); hdr_len = DECORATED_FRAMER.create();
if(hdr_len < 0) { if(hdr_len < 0) {
@ -107,6 +110,8 @@ create(void)
return FRAMER_FAILED; return FRAMER_FAILED;
} }
packetbuf_compact();
return hdr_len + sizeof(struct hdr); return hdr_len + sizeof(struct hdr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -117,7 +122,7 @@ pad(void)
uint8_t *ptr; uint8_t *ptr;
uint8_t zeroes_count; uint8_t zeroes_count;
transmit_len = packetbuf_totlen(); transmit_len = packetbuf_totlen() + hdr_length();
if(transmit_len < SHORTEST_PACKET_SIZE) { if(transmit_len < SHORTEST_PACKET_SIZE) {
/* Padding required */ /* Padding required */
zeroes_count = SHORTEST_PACKET_SIZE - transmit_len; zeroes_count = SHORTEST_PACKET_SIZE - transmit_len;
@ -128,30 +133,6 @@ pad(void)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int static int
create_and_secure(void)
{
struct hdr *chdr;
int hdr_len;
hdr_len = create();
if(hdr_len < 0) {
return FRAMER_FAILED;
}
packetbuf_compact();
if(!NETSTACK_LLSEC.on_frame_created()) {
PRINTF("contikimac-framer: securing failed\n");
return FRAMER_FAILED;
}
chdr = (struct hdr *)(((uint8_t *) packetbuf_dataptr()) - sizeof(struct hdr));
chdr->len = packetbuf_datalen();
pad();
return hdr_len;
}
/*---------------------------------------------------------------------------*/
static int
parse(void) parse(void)
{ {
int hdr_len; int hdr_len;
@ -174,7 +155,6 @@ parse(void)
} }
packetbuf_set_datalen(chdr->len); packetbuf_set_datalen(chdr->len);
chdr->len = 0;
return hdr_len + sizeof(struct hdr); return hdr_len + sizeof(struct hdr);
} }
@ -182,7 +162,6 @@ parse(void)
const struct framer contikimac_framer = { const struct framer contikimac_framer = {
hdr_length, hdr_length,
create, create,
create_and_secure,
parse parse
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -507,14 +507,16 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
#endif #endif
int strobes; int strobes;
uint8_t got_strobe_ack = 0; uint8_t got_strobe_ack = 0;
int len;
uint8_t is_broadcast = 0; uint8_t is_broadcast = 0;
uint8_t is_known_receiver = 0; uint8_t is_known_receiver = 0;
uint8_t collisions; uint8_t collisions;
int transmit_len; int transmit_len;
int ret; int ret;
uint8_t contikimac_was_on; uint8_t contikimac_was_on;
#if !RDC_CONF_HARDWARE_ACK
int len;
uint8_t seqno; uint8_t seqno;
#endif
/* Exit if RDC and radio were explicitly turned off */ /* Exit if RDC and radio were explicitly turned off */
if(!contikimac_is_on && !contikimac_keep_radio_on) { if(!contikimac_is_on && !contikimac_keep_radio_on) {
@ -558,7 +560,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) { if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) {
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
if(NETSTACK_FRAMER.create_and_secure() < 0) { if(NETSTACK_FRAMER.create() < 0) {
PRINTF("contikimac: framer failed\n"); PRINTF("contikimac: framer failed\n");
return MAC_TX_ERR_FATAL; return MAC_TX_ERR_FATAL;
} }
@ -655,11 +657,11 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
or rx cycle */ or rx cycle */
on(); on();
} }
seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
#endif #endif
watchdog_periodic(); watchdog_periodic();
t0 = RTIMER_NOW(); t0 = RTIMER_NOW();
seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
for(strobes = 0, collisions = 0; for(strobes = 0, collisions = 0;
got_strobe_ack == 0 && collisions == 0 && got_strobe_ack == 0 && collisions == 0 &&
RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {
@ -672,7 +674,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
break; break;
} }
#if !RDC_CONF_HARDWARE_ACK
len = 0; len = 0;
#endif
{ {
rtimer_clock_t wt; rtimer_clock_t wt;
@ -801,6 +805,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
struct rdc_buf_list *next; struct rdc_buf_list *next;
int ret; int ret;
int is_receiver_awake; int is_receiver_awake;
int pending;
if(buf_list == NULL) { if(buf_list == NULL) {
return; return;
@ -825,7 +830,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
} }
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
if(NETSTACK_FRAMER.create_and_secure() < 0) { if(NETSTACK_FRAMER.create() < 0) {
PRINTF("contikimac: framer failed\n"); PRINTF("contikimac: framer failed\n");
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
return; return;
@ -845,7 +850,9 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
/* Prepare the packetbuf */ /* Prepare the packetbuf */
queuebuf_to_packetbuf(curr->buf); queuebuf_to_packetbuf(curr->buf);
pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
/* Send the current packet */ /* Send the current packet */
ret = send_packet(sent, ptr, curr, is_receiver_awake); ret = send_packet(sent, ptr, curr, is_receiver_awake);
if(ret != MAC_TX_DEFERRED) { if(ret != MAC_TX_DEFERRED) {
@ -862,7 +869,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
/* The transmission failed, we stop the burst */ /* The transmission failed, we stop the burst */
next = NULL; next = NULL;
} }
} while((next != NULL) && packetbuf_attr(PACKETBUF_ATTR_PENDING)); } while((next != NULL) && pending);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Timer callback triggered when receiving a burst, after having /* Timer callback triggered when receiving a burst, after having
@ -911,8 +918,6 @@ input_packet(void)
broadcast address. */ broadcast address. */
/* If FRAME_PENDING is set, we are receiving a packets in a burst */ /* If FRAME_PENDING is set, we are receiving a packets in a burst */
/* TODO To prevent denial-of-sleep attacks, the transceiver should
be disabled upon receipt of an unauthentic frame. */
we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING);
if(we_are_receiving_burst) { if(we_are_receiving_burst) {
on(); on();

View file

@ -171,8 +171,10 @@ transmit_packet_list(void *ptr)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
free_packet(struct neighbor_queue *n, struct rdc_buf_list *p) free_packet(struct neighbor_queue *n, struct rdc_buf_list *p, int status)
{ {
clock_time_t tx_delay;
if(p != NULL) { if(p != NULL) {
/* Remove packet from list and deallocate */ /* Remove packet from list and deallocate */
list_remove(n->queued_packet_list, p); list_remove(n->queued_packet_list, p);
@ -188,8 +190,8 @@ free_packet(struct neighbor_queue *n, struct rdc_buf_list *p)
n->collisions = 0; n->collisions = 0;
n->deferrals = 0; n->deferrals = 0;
/* Set a timer for next transmissions */ /* Set a timer for next transmissions */
ctimer_set(&n->transmit_timer, default_timebase(), tx_delay = (status == MAC_TX_OK) ? 0 : default_timebase();
transmit_packet_list, n); ctimer_set(&n->transmit_timer, tx_delay, transmit_packet_list, n);
} else { } else {
/* This was the last packet in the queue, we free the neighbor */ /* This was the last packet in the queue, we free the neighbor */
ctimer_stop(&n->transmit_timer); ctimer_stop(&n->transmit_timer);
@ -293,7 +295,7 @@ packet_sent(void *ptr, int status, int num_transmissions)
} else { } else {
PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n", PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n",
status, n->transmissions, n->collisions); status, n->transmissions, n->collisions);
free_packet(n, q); free_packet(n, q, status);
mac_call_sent_callback(sent, cptr, status, num_tx); mac_call_sent_callback(sent, cptr, status, num_tx);
} }
} else { } else {
@ -302,7 +304,7 @@ packet_sent(void *ptr, int status, int num_transmissions)
} else { } else {
PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status); PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status);
} }
free_packet(n, q); free_packet(n, q, status);
mac_call_sent_callback(sent, cptr, status, num_tx); mac_call_sent_callback(sent, cptr, status, num_tx);
} }
} else { } else {

View file

@ -273,7 +273,6 @@ parse(void)
const struct framer framer_802154 = { const struct framer framer_802154 = {
hdr_length, hdr_length,
create, create,
framer_canonical_create_and_secure,
parse parse
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -99,6 +99,5 @@ parse(void)
const struct framer framer_nullmac = { const struct framer framer_nullmac = {
hdr_length, hdr_length,
create, create,
framer_canonical_create_and_secure,
parse parse
}; };

View file

@ -47,13 +47,8 @@ struct framer {
int (* length)(void); int (* length)(void);
int (* create)(void); int (* create)(void);
/** Creates the frame and calls LLSEC.on_frame_created() */
int (* create_and_secure)(void);
int (* parse)(void); int (* parse)(void);
}; };
int framer_canonical_create_and_secure(void);
#endif /* FRAMER_H_ */ #endif /* FRAMER_H_ */

View file

@ -48,6 +48,7 @@
#if CONTIKI_TARGET_COOJA #if CONTIKI_TARGET_COOJA
#include "lib/simEnvChange.h" #include "lib/simEnvChange.h"
#include "sys/cooja_mt.h"
#endif /* CONTIKI_TARGET_COOJA */ #endif /* CONTIKI_TARGET_COOJA */
#define DEBUG 0 #define DEBUG 0
@ -120,7 +121,7 @@ send_one_packet(mac_callback_t sent, void *ptr)
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
#endif /* NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW */ #endif /* NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW */
if(NETSTACK_FRAMER.create_and_secure() < 0) { if(NETSTACK_FRAMER.create() < 0) {
/* Failed to allocate space for headers */ /* Failed to allocate space for headers */
PRINTF("nullrdc: send failed, too large header\n"); PRINTF("nullrdc: send failed, too large header\n");
ret = MAC_TX_ERR_FATAL; ret = MAC_TX_ERR_FATAL;
@ -302,8 +303,7 @@ packet_input(void)
} }
#endif /* RDC_WITH_DUPLICATE_DETECTION */ #endif /* RDC_WITH_DUPLICATE_DETECTION */
#endif /* NULLRDC_802154_AUTOACK */ #endif /* NULLRDC_802154_AUTOACK */
/* TODO We may want to acknowledge only authentic frames */
#if NULLRDC_SEND_802154_ACK #if NULLRDC_SEND_802154_ACK
{ {
frame802154_t info154; frame802154_t info154;

View file

@ -219,6 +219,11 @@ phase_wait(const linkaddr_t *neighbor, rtimer_clock_t cycle_time,
if(buf_list == NULL) { if(buf_list == NULL) {
packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
p->q = queuebuf_new_from_packetbuf(); p->q = queuebuf_new_from_packetbuf();
if(p->q == NULL) {
/* memory allocation failed */
memb_free(&queued_packets_memb, p);
return PHASE_UNKNOWN;
}
} }
p->mac_callback = mac_callback; p->mac_callback = mac_callback;
p->mac_callback_ptr = mac_callback_ptr; p->mac_callback_ptr = mac_callback_ptr;

View file

@ -141,6 +141,7 @@ packetbuf_copyto(void *to)
int i; int i;
char buffer[1000]; char buffer[1000];
char *bufferptr = buffer; char *bufferptr = buffer;
int bufferlen = 0;
bufferptr[0] = 0; bufferptr[0] = 0;
for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) { for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) {
@ -149,8 +150,8 @@ packetbuf_copyto(void *to)
PRINTF("packetbuf_write: header: %s\n", buffer); PRINTF("packetbuf_write: header: %s\n", buffer);
bufferptr = buffer; bufferptr = buffer;
bufferptr[0] = 0; bufferptr[0] = 0;
for(i = bufptr; i < buflen + bufptr; ++i) { for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < (sizeof(buffer) - 10))); ++i) {
bufferptr += sprintf(bufferptr, "0x%02x, ", packetbufptr[i]); bufferlen += sprintf(bufferptr + bufferlen, "0x%02x, ", packetbufptr[i]);
} }
PRINTF("packetbuf_write: data: %s\n", buffer); PRINTF("packetbuf_write: data: %s\n", buffer);
} }

View file

@ -121,7 +121,7 @@ int
route_add(const linkaddr_t *dest, const linkaddr_t *nexthop, route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
uint8_t cost, uint8_t seqno) uint8_t cost, uint8_t seqno)
{ {
struct route_entry *e; struct route_entry *e, *oldest = NULL;
/* Avoid inserting duplicate entries. */ /* Avoid inserting duplicate entries. */
e = route_lookup(dest); e = route_lookup(dest);
@ -131,8 +131,14 @@ route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
/* Allocate a new entry or reuse the oldest entry with highest cost. */ /* Allocate a new entry or reuse the oldest entry with highest cost. */
e = memb_alloc(&route_mem); e = memb_alloc(&route_mem);
if(e == NULL) { if(e == NULL) {
/* Remove oldest entry. XXX */ /* Remove oldest entry. */
e = list_chop(route_table); for(e = list_head(route_table); e != NULL; e = list_item_next(e)) {
if(oldest == NULL || e->time >= oldest->time) {
oldest = e;
}
}
e = oldest;
list_remove(route_table, e);
PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n", PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
e->dest.u8[0], e->dest.u8[1], e->dest.u8[0], e->dest.u8[1],
e->nexthop.u8[0], e->nexthop.u8[1], e->nexthop.u8[0], e->nexthop.u8[1],

View file

@ -112,10 +112,10 @@ send(void *ptr)
PRINTF("%d.%d: stunicast: resend to %d.%d\n", PRINTF("%d.%d: stunicast: resend to %d.%d\n",
linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1], linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1],
c->receiver.u8[0], c->receiver.u8[1]); c->receiver.u8[0], c->receiver.u8[1]);
if(c->buf) { if(c->buf) {
queuebuf_to_packetbuf(c->buf); queuebuf_to_packetbuf(c->buf);
unicast_send(&c->c, &c->receiver); unicast_send(&c->c, &c->receiver);
stunicast_set_timer(c, CLOCK_SECOND); ctimer_restart(&c->t);
} }
/* if(c->u->sent != NULL) { /* if(c->u->sent != NULL) {
c->u->sent(c); c->u->sent(c);

View file

@ -121,6 +121,18 @@
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0 #define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0
#endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */ #endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */
/*
* Maximum lifetime of a DAG
* When a DODAG is not updated since RPL_CONF_DAG_LIFETIME times the DODAG
* maximum DIO interval the DODAG is removed from the list of DODAGS of the
* related instance, except if it is the currently joined DODAG.
*/
#ifdef RPL_CONF_DAG_LIFETIME
#define RPL_DAG_LIFETIME RPL_CONF_DAG_LIFETIME
#else
#define RPL_DAG_LIFETIME 3
#endif /* RPL_CONF_DAG_LIFETIME */
/* /*
* *
*/ */

View file

@ -71,7 +71,7 @@ get_global_address(void)
state = uip_ds6_if.addr_list[i].state; state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && if(uip_ds6_if.addr_list[i].isused &&
state == ADDR_PREFERRED && state == ADDR_PREFERRED &&
!uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)) { !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
ipaddr = &uip_ds6_if.addr_list[i].ipaddr; ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
} }
} }
@ -190,7 +190,7 @@ rpl_dag_root_init_dag_immediately(void)
state = uip_ds6_if.addr_list[i].state; state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && if(uip_ds6_if.addr_list[i].isused &&
state == ADDR_PREFERRED && state == ADDR_PREFERRED &&
!uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)) { !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
ipaddr = &uip_ds6_if.addr_list[i].ipaddr; ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
} }
} }

View file

@ -938,6 +938,15 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_parent_t *p; rpl_parent_t *p;
rpl_of_t *of; rpl_of_t *of;
/* Determine the objective function by using the
objective code point of the DIO. */
of = rpl_find_of(dio->ocp);
if(of == NULL) {
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF: %u\n",
dio->instance_id, dio->ocp);
return;
}
dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id); dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
if(dag == NULL) { if(dag == NULL) {
PRINTF("RPL: Failed to allocate a DAG object!\n"); PRINTF("RPL: Failed to allocate a DAG object!\n");
@ -958,17 +967,6 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
p->dtsn = dio->dtsn; p->dtsn = dio->dtsn;
PRINTF("succeeded\n"); PRINTF("succeeded\n");
/* Determine the objective function by using the
objective code point of the DIO. */
of = rpl_find_of(dio->ocp);
if(of == NULL) {
PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
dio->instance_id);
rpl_remove_parent(p);
instance->used = 0;
return;
}
/* Autoconfigure an address if this node does not already have an address /* Autoconfigure an address if this node does not already have an address
with this prefix. */ with this prefix. */
if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
@ -1062,6 +1060,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_move_parent(previous_dag, dag, p); rpl_move_parent(previous_dag, dag, p);
} }
} }
p->rank = dio->rank;
/* Determine the objective function by using the /* Determine the objective function by using the
objective code point of the DIO. */ objective code point of the DIO. */
@ -1336,6 +1335,12 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
return; return;
} }
/* The DIO comes from a valid DAG, we can refresh its lifetime */
dag->lifetime = (1UL << (instance->dio_intmin + instance->dio_intdoubl)) / 1000;
PRINTF("Set dag ");
PRINT6ADDR(&dag->dag_id);
PRINTF(" lifetime to %ld\n", dag->lifetime);
/* /*
* At this point, we know that this DIO pertains to a DAG that * At this point, we know that this DIO pertains to a DAG that
* we are already part of. We consider the sender of the DIO to be * we are already part of. We consider the sender of the DIO to be
@ -1370,10 +1375,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
if(dag->joined) { if(dag->joined) {
instance->dio_counter++; instance->dio_counter++;
} }
} else {
p->rank=dio->rank;
} }
} }
p->rank = dio->rank;
/* Parent info has been updated, trigger rank recalculation */ /* Parent info has been updated, trigger rank recalculation */
p->flags |= RPL_PARENT_FLAG_UPDATED; p->flags |= RPL_PARENT_FLAG_UPDATED;

View file

@ -109,7 +109,7 @@ get_global_addr(uip_ipaddr_t *addr)
state = uip_ds6_if.addr_list[i].state; state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused && if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
if(!uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)) { if(!uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
memcpy(addr, &uip_ds6_if.addr_list[i].ipaddr, sizeof(uip_ipaddr_t)); memcpy(addr, &uip_ds6_if.addr_list[i].ipaddr, sizeof(uip_ipaddr_t));
return 1; return 1;
} }
@ -916,15 +916,11 @@ dao_ack_input(void)
{ {
#if DEBUG #if DEBUG
unsigned char *buffer; unsigned char *buffer;
uint8_t buffer_length;
uint8_t instance_id;
uint8_t sequence; uint8_t sequence;
uint8_t status; uint8_t status;
buffer = UIP_ICMP_PAYLOAD; buffer = UIP_ICMP_PAYLOAD;
buffer_length = uip_len - uip_l3_icmp_hdr_len;
instance_id = buffer[0];
sequence = buffer[2]; sequence = buffer[2];
status = buffer[3]; status = buffer[3];

View file

@ -284,6 +284,7 @@ rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *);
rpl_instance_t *rpl_alloc_instance(uint8_t); rpl_instance_t *rpl_alloc_instance(uint8_t);
void rpl_free_dag(rpl_dag_t *); void rpl_free_dag(rpl_dag_t *);
void rpl_free_instance(rpl_instance_t *); void rpl_free_instance(rpl_instance_t *);
void rpl_purge_dags(void);
/* DAG parent management function. */ /* DAG parent management function. */
rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *); rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);

View file

@ -66,6 +66,7 @@ static uint8_t dio_send_ok;
static void static void
handle_periodic_timer(void *ptr) handle_periodic_timer(void *ptr)
{ {
rpl_purge_dags();
rpl_purge_routes(); rpl_purge_routes();
rpl_recalculate_ranks(); rpl_recalculate_ranks();

View file

@ -300,6 +300,34 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
rpl_purge_dags(void)
{
rpl_instance_t *instance;
rpl_instance_t *end;
int i;
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
instance < end; ++instance) {
if(instance->used) {
for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
if(instance->dag_table[i].used) {
if(instance->dag_table[i].lifetime == 0) {
if(!instance->dag_table[i].joined) {
PRINTF("Removing dag ");
PRINT6ADDR(&instance->dag_table[i].dag_id);
PRINTF("\n");
rpl_free_dag(&instance->dag_table[i]);
}
} else {
instance->dag_table[i].lifetime--;
}
}
}
}
}
}
/*---------------------------------------------------------------------------*/
void
rpl_init(void) rpl_init(void)
{ {
uip_ipaddr_t rplmaddr; uip_ipaddr_t rplmaddr;

View file

@ -142,6 +142,7 @@ struct rpl_dag {
rpl_rank_t rank; rpl_rank_t rank;
struct rpl_instance *instance; struct rpl_instance *instance;
rpl_prefix_t prefix_info; rpl_prefix_t prefix_info;
uint32_t lifetime;
}; };
typedef struct rpl_dag rpl_dag_t; typedef struct rpl_dag rpl_dag_t;
typedef struct rpl_instance rpl_instance_t; typedef struct rpl_instance rpl_instance_t;

View file

@ -67,24 +67,14 @@
#define CC_FUNCTION_POINTER_ARGS 0 #define CC_FUNCTION_POINTER_ARGS 0
#endif /* CC_CONF_FUNCTION_POINTER_ARGS */ #endif /* CC_CONF_FUNCTION_POINTER_ARGS */
/**
* Configure if the C compiler supports fastcall function
* declarations.
*/
#ifdef CC_CONF_FASTCALL
#define CC_FASTCALL CC_CONF_FASTCALL
#else /* CC_CONF_FASTCALL */
#define CC_FASTCALL
#endif /* CC_CONF_FASTCALL */
/** /**
* Configure if the C compiler have problems with const function pointers * Configure if the C compiler have problems with const function pointers
*/ */
#ifdef CC_CONF_CONST_FUNCTION_BUG #ifdef CC_CONF_CONST_FUNCTION_BUG
#define CC_CONST_FUNCTION #define CC_CONST_FUNCTION
#else /* CC_CONF_FASTCALL */ #else /* CC_CONF_CONST_FUNCTION_BUG */
#define CC_CONST_FUNCTION const #define CC_CONST_FUNCTION const
#endif /* CC_CONF_FASTCALL */ #endif /* CC_CONF_CONST_FUNCTION_BUG */
/** /**
* Configure work-around for unsigned char bugs with sdcc. * Configure work-around for unsigned char bugs with sdcc.
@ -123,6 +113,17 @@
#define CC_NO_VA_ARGS CC_CONF_VA_ARGS #define CC_NO_VA_ARGS CC_CONF_VA_ARGS
#endif #endif
/** \def CC_ACCESS_NOW(x)
* This macro ensures that the access to a non-volatile variable can
* not be reordered or optimized by the compiler.
* See also https://lwn.net/Articles/508991/ - In Linux the macro is
* called ACCESS_ONCE
* The type must be passed, because the typeof-operator is a gcc
* extension
*/
#define CC_ACCESS_NOW(type, variable) (*(volatile type *)&(variable))
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif /* NULL */ #endif /* NULL */

View file

@ -105,6 +105,21 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI
energest_current_time[type]); \ energest_current_time[type]); \
energest_current_mode[type] = 0; \ energest_current_mode[type] = 0; \
} while(0) } while(0)
#define ENERGEST_SWITCH(type_off, type_on) do { \
rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \
if(energest_current_mode[type_off] != 0) { \
if (energest_local_variable_now < energest_current_time[type_off]) { \
energest_total_time[type_off].current += RTIMER_ARCH_SECOND; \
} \
energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \
energest_current_time[type_off]); \
energest_current_mode[type_off] = 0; \
} \
energest_current_time[type_on] = energest_local_variable_now; \
energest_current_mode[type_on] = 1; \
} while(0)
#else #else
#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \ #define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \
energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \ energest_total_time[type].current += (rtimer_clock_t)(RTIMER_NOW() - \
@ -117,13 +132,24 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI
energest_current_time[type]); \ energest_current_time[type]); \
energest_current_mode[type] = 0; \ energest_current_mode[type] = 0; \
} while(0) } while(0)
#endif
#define ENERGEST_SWITCH(type_off, type_on) do { \
rtimer_clock_t energest_local_variable_now = RTIMER_NOW(); \
if(energest_current_mode[type_off] != 0) { \
energest_total_time[type_off].current += (rtimer_clock_t)(energest_local_variable_now - \
energest_current_time[type_off]); \
energest_current_mode[type_off] = 0; \
} \
energest_current_time[type_on] = energest_local_variable_now; \
energest_current_mode[type_on] = 1; \
} while(0)
#endif
#else /* ENERGEST_CONF_ON */ #else /* ENERGEST_CONF_ON */
#define ENERGEST_ON(type) do { } while(0) #define ENERGEST_ON(type) do { } while(0)
#define ENERGEST_OFF(type) do { } while(0) #define ENERGEST_OFF(type) do { } while(0)
#define ENERGEST_OFF_LEVEL(type,level) do { } while(0) #define ENERGEST_OFF_LEVEL(type,level) do { } while(0)
#define ENERGEST_SWITCH(type_off, type_on) do { } while(0)
#endif /* ENERGEST_CONF_ON */ #endif /* ENERGEST_CONF_ON */
#endif /* ENERGEST_H_ */ #endif /* ENERGEST_H_ */

View file

@ -162,9 +162,11 @@ PT_THREAD(driver_thread(struct pt *pt))
#include "sys/pt.h" #include "sys/pt.h"
struct pt_sem { struct pt_sem {
unsigned int count; unsigned int head, tail;
}; };
#define PT_SEM_COUNT(s) ((s)->head - (s)->tail)
/** /**
* Initialize a semaphore * Initialize a semaphore
* *
@ -179,7 +181,11 @@ struct pt_sem {
* \param c (unsigned int) The initial count of the semaphore. * \param c (unsigned int) The initial count of the semaphore.
* \hideinitializer * \hideinitializer
*/ */
#define PT_SEM_INIT(s, c) (s)->count = c #define PT_SEM_INIT(s, c) \
do { \
(s)->tail = 0; \
(s)->head = (c); \
} while(0)
/** /**
* Wait for a semaphore * Wait for a semaphore
@ -199,8 +205,8 @@ struct pt_sem {
*/ */
#define PT_SEM_WAIT(pt, s) \ #define PT_SEM_WAIT(pt, s) \
do { \ do { \
PT_WAIT_UNTIL(pt, (s)->count > 0); \ PT_WAIT_UNTIL(pt, PT_SEM_COUNT(s) > 0); \
--(s)->count; \ ++(s)->tail; \
} while(0) } while(0)
/** /**
@ -218,7 +224,7 @@ struct pt_sem {
* *
* \hideinitializer * \hideinitializer
*/ */
#define PT_SEM_SIGNAL(pt, s) ++(s)->count #define PT_SEM_SIGNAL(pt, s) (++(s)->head)
#endif /* PT_SEM_H_ */ #endif /* PT_SEM_H_ */

View file

@ -51,7 +51,6 @@ typedef uint32_t u32_t;
typedef int32_t s32_t; typedef int32_t s32_t;
#define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_REGISTER_ARGS 1
#define CC_CONF_FASTCALL __fastcall__
#define ARCH_DOESNT_NEED_ALIGNED_STRUCTS 1 #define ARCH_DOESNT_NEED_ALIGNED_STRUCTS 1

View file

@ -66,9 +66,13 @@ high-level configuration macros may be set:
- Default: 0 - Default: 0
- Purpose: Enable UDP support and initialize resolver process on startup. - Purpose: Enable UDP support and initialize resolver process on startup.
- WITH_80COL
- Default: 0
- Purpose: Enable 80 column screen.
- WITH_GUI - WITH_GUI
- Default: 0 - Default: 0
- Purpose: Initialize the the CTK process on startup. - Purpose: Initialize the CTK process on startup.
- WITH_MOUSE - WITH_MOUSE
- Default: 0 - Default: 0

View file

@ -43,7 +43,7 @@
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if LOG_CONF_ENABLED #if LOG_CONF_ENABLED
static char * CC_FASTCALL static char *
ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer) ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer)
{ {
char *ptr = buffer; char *ptr = buffer;
@ -59,7 +59,7 @@ ipaddrtoa(uip_ipaddr_t *ipaddr, char *buffer)
} }
#endif /* LOG_CONF_ENABLED */ #endif /* LOG_CONF_ENABLED */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
struct ethernet_config * CC_FASTCALL struct ethernet_config *
config_read(char *filename) config_read(char *filename)
{ {
static struct { static struct {

View file

@ -35,6 +35,6 @@
#ifndef CONFIG_H_ #ifndef CONFIG_H_
#define CONFIG_H_ #define CONFIG_H_
struct ethernet_config * CC_FASTCALL config_read(char *filename); struct ethernet_config * config_read(char *filename);
#endif /* CONFIG_H_ */ #endif /* CONFIG_H_ */

View file

@ -58,7 +58,7 @@ struct {
} *module; } *module;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void CC_FASTCALL void
ethernet_init(struct ethernet_config *config) ethernet_init(struct ethernet_config *config)
{ {
static const char signature[4] = {0x65, 0x74, 0x68, 0x01}; static const char signature[4] = {0x65, 0x74, 0x68, 0x01};

View file

@ -35,7 +35,7 @@
#ifndef ETHERNET_H_ #ifndef ETHERNET_H_
#define ETHERNET_H_ #define ETHERNET_H_
void CC_FASTCALL ethernet_init(struct ethernet_config *config); void ethernet_init(struct ethernet_config *config);
uint16_t ethernet_poll(void); uint16_t ethernet_poll(void);
void ethernet_send(void); void ethernet_send(void);
void ethernet_exit(void); void ethernet_exit(void);

View file

@ -139,10 +139,10 @@ ifndef NOAVRSIZE
avr-size -C --mcu=$(MCU) $@ avr-size -C --mcu=$(MCU) $@
endif endif
%.hex: %.out %.hex: %.$(TARGET)
$(OBJCOPY) $^ -j .text -j .data -O ihex $@ $(OBJCOPY) $^ -j .text -j .data -O ihex $@
%.ihex: %.out %.ihex: %.$(TARGET)
$(OBJCOPY) $^ -O ihex $@ $(OBJCOPY) $^ -O ihex $@
# Add a namelist to the kernel # Add a namelist to the kernel
@ -160,7 +160,7 @@ endif
#%.hex: %.elf #%.hex: %.elf
# $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@ # $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@
%.eep: %.out %.eep: %.$(TARGET)
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex $^ $@ --change-section-lma .eeprom=0 -O ihex $^ $@

View file

@ -12,7 +12,6 @@
/* MCUSR is a deprecated name but older avr-libc versions may define it */ /* MCUSR is a deprecated name but older avr-libc versions may define it */
#if !defined (MCUCSR) #if !defined (MCUCSR)
# if defined (MCUSR) # if defined (MCUSR)
# warning *** MCUCSR not defined, using MCUSR instead ***
# define MCUCSR MCUSR # define MCUCSR MCUSR
# endif # endif
#endif #endif

View file

@ -751,7 +751,8 @@ HAL_RF230_ISR()
#endif #endif
#endif #endif
} else if (interrupt_source & HAL_TRX_END_MASK){ }
if (interrupt_source & HAL_TRX_END_MASK){
INTERRUPTDEBUG(11); INTERRUPTDEBUG(11);
state = hal_subregister_read(SR_TRX_STATUS); state = hal_subregister_read(SR_TRX_STATUS);
@ -778,16 +779,20 @@ HAL_RF230_ISR()
} }
} else if (interrupt_source & HAL_TRX_UR_MASK){ }
if (interrupt_source & HAL_TRX_UR_MASK){
INTERRUPTDEBUG(13); INTERRUPTDEBUG(13);
; ;
} else if (interrupt_source & HAL_PLL_UNLOCK_MASK){ }
if (interrupt_source & HAL_PLL_UNLOCK_MASK){
INTERRUPTDEBUG(14); INTERRUPTDEBUG(14);
; ;
} else if (interrupt_source & HAL_PLL_LOCK_MASK){ }
if (interrupt_source & HAL_PLL_LOCK_MASK){
INTERRUPTDEBUG(15); INTERRUPTDEBUG(15);
; ;
} else if (interrupt_source & HAL_BAT_LOW_MASK){ }
if (interrupt_source & HAL_BAT_LOW_MASK){
/* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */ /* Disable BAT_LOW interrupt to prevent endless interrupts. The interrupt */
/* will continously be asserted while the supply voltage is less than the */ /* will continously be asserted while the supply voltage is less than the */
/* user-defined voltage threshold. */ /* user-defined voltage threshold. */
@ -796,9 +801,6 @@ HAL_RF230_ISR()
hal_register_write(RG_IRQ_MASK, trx_isr_mask); hal_register_write(RG_IRQ_MASK, trx_isr_mask);
INTERRUPTDEBUG(16); INTERRUPTDEBUG(16);
; ;
} else {
INTERRUPTDEBUG(99);
;
} }
} }
#endif /* defined(__AVR_ATmega128RFA1__) */ #endif /* defined(__AVR_ATmega128RFA1__) */

View file

@ -237,6 +237,8 @@ typedef enum{
PROCESS(rf230_process, "RF230 driver"); PROCESS(rf230_process, "RF230 driver");
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int rf230_interrupt(void);
static int rf230_on(void); static int rf230_on(void);
static int rf230_off(void); static int rf230_off(void);
@ -552,7 +554,19 @@ rf230_is_ready_to_send() {
static void static void
flushrx(void) flushrx(void)
{ {
/* Clear the length field to allow buffering of the next packet */
rxframe[rxframe_head].length=0; rxframe[rxframe_head].length=0;
rxframe_head++;
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
rxframe_head=0;
}
/* If another packet has been buffered, schedule another receive poll */
if (rxframe[rxframe_head].length) {
rf230_interrupt();
}
else {
rf230_pending = 0;
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
@ -1434,6 +1448,7 @@ rf230_read(void *buf, unsigned short bufsize)
#if RADIOALWAYSON && DEBUGFLOWSIZE #if RADIOALWAYSON && DEBUGFLOWSIZE
if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off? if (RF230_receive_on==0) {if (debugflow[debugflowsize-1]!='z') DEBUGFLOW('z');} //cxmac calls with radio off?
#endif #endif
flushrx();
return 0; return 0;
} }
@ -1476,19 +1491,8 @@ rf230_read(void *buf, unsigned short bufsize)
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN); memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
rf230_last_correlation = rxframe[rxframe_head].lqi; rf230_last_correlation = rxframe[rxframe_head].lqi;
/* Clear the length field to allow buffering of the next packet */ /* Prepare to receive another packet */
rxframe[rxframe_head].length=0; flushrx();
rxframe_head++;
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
rxframe_head=0;
}
/* If another packet has been buffered, schedule another receive poll */
if (rxframe[rxframe_head].length) {
rf230_interrupt();
}
else {
rf230_pending = 0;
}
/* Point to the checksum */ /* Point to the checksum */
framep+=len-AUX_LEN; framep+=len-AUX_LEN;

View file

@ -67,7 +67,6 @@
/* MCUSR is a deprecated name but older avr-libc versions may define it */ /* MCUSR is a deprecated name but older avr-libc versions may define it */
#if !defined (MCUCSR) #if !defined (MCUCSR)
# if defined (MCUSR) # if defined (MCUSR)
# warning *** MCUCSR not defined, using MCUSR instead ***
# define MCUCSR MCUSR # define MCUCSR MCUSR
# endif # endif
#endif #endif

View file

@ -38,7 +38,6 @@
#endif #endif
#define CC_CONF_FUNCTION_POINTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CC_CONF_FASTCALL
#define CC_CONF_VA_ARGS 1 #define CC_CONF_VA_ARGS 1
#define CC_CONF_UNSIGNED_CHAR_BUGS 0 #define CC_CONF_UNSIGNED_CHAR_BUGS 0
#define CC_CONF_REGISTER_ARGS 0 #define CC_CONF_REGISTER_ARGS 0

View file

@ -22,6 +22,10 @@ LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
OBJCOPY_FLAGS += -O binary --gap-fill 0xff OBJCOPY_FLAGS += -O binary --gap-fill 0xff
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
ifdef WERROR
CFLAGS += -Werror
endif
### Are we building with code size optimisations? ### Are we building with code size optimisations?
ifeq ($(SMALL),1) ifeq ($(SMALL),1)
CFLAGS += -Os CFLAGS += -Os
@ -51,6 +55,8 @@ CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ccm.c sha256.c CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ccm.c sha256.c
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c
CONTIKI_CPU_SOURCEFILES += ecc-curve.c
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.c CONTIKI_CPU_SOURCEFILES += i2c.c cc2538-temp-sensor.c vdd3-sensor.c

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,462 @@
/*
* Original file:
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Port to Contiki:
* Authors: Andreas Dröscher <contiki@anticat.ch>
* Hu Luo
* Hossein Shafagh <shafagh@inf.ethz.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-pka
* @{
*
* \defgroup cc2538-bignum cc2538 BigNum math function driver
*
* Driver for the cc2538 BigNum math functions of the PKC engine
* @{
*
* \file
* Header file for the cc2538 BigNum driver
*
* bignum_subtract_start bignum_subtract_get_result (subtraction)
* bignum_add_start bignum_add_get_result (addition)
* bignum_mod_start bignum_mod_get_result (modulo)
* bignum_exp_mod_start bignum_exp_mod_get_result (modular exponentiation operation)
* bignum_inv_mod_start bignum_inv_mod_get_result (inverse modulo operation)
* bignum_mul_start bignum_mul_get_result (multiplication)
* bignum_divide_start bignum_divide_get_result (division)
* bignum_cmp_start bignum_cmp_get_result (comparison)
*/
#ifndef BIGNUM_DRIVER_H_
#define BIGNUM_DRIVER_H_
#include "contiki.h"
#include "pka.h"
#include <stdint.h>
/** @} */
/*---------------------------------------------------------------------------*/
/** \brief Starts the big number modulus operation.
*
* \param number Pointer to the big number on which modulo operation
* needs to be carried out.
* \param number_size Size of the big number \sa number in 32-bit word.
* \param modulus Pointer to the divisor.
* \param modulus_size Size of the divisor \sa modulus.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the modulo operation on the big num \sa number
* using the divisor \sa modulus. The PKA RAM location where the result
* will be available is stored in \sa result_vector.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_mod_start(const uint32_t *number,
const uint8_t number_size,
const uint32_t *modulus,
const uint8_t modulus_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of the big number modulus operation.
*
* \param buffer Pointer to buffer where the result needs to
* be stored.
* \param buffer_size Size of the provided buffer in 32 bit size word.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumModStart().
*
* This function gets the result of the big number modulus operation which was
* previously started using the function \sa PKABigNumModStart().
*
* \retval PKA_STATUS_SUCCESS if successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length
* of the result.
*/
uint8_t bignum_mod_get_result(uint32_t *buffer,
const uint8_t buffer_size,
const uint32_t result_vector);
/** \brief Starts the comparison of two big numbers.
*
* \param number1 Pointer to the first big number.
* \param number2 Pointer to the second big number.
* \param size Size of the big number in 32 bit size word.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the comparison of two big numbers pointed by
* \e number1 and \e number2.
* Note this function expects the size of the two big numbers equal.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_cmp_start(const uint32_t *number1,
const uint32_t *number2,
uint8_t size,
struct process *process);
/** \brief Gets the result of the comparison operation of two big numbers.
*
* This function provides the results of the comparison of two big numbers
* which was started using the \sa PKABigNumCmpStart().
*
* \retval PKA_STATUS_OPERATION_INPRG if the operation is in progress.
* \retval PKA_STATUS_SUCCESS if the two big numbers are equal.
* \retval PKA_STATUS_A_GR_B if the first number is greater than the second.
* \retval PKA_STATUS_A_LT_B if the first number is less than the second.
*/
uint8_t bignum_cmp_get_result(void);
/** \brief Starts the big number inverse modulo operation.
*
* \param number Pointer to the buffer containing the big number
* (dividend).
* \param number_size Size of the \e number in 32 bit word.
* \param modulus Pointer to the buffer containing the modulus.
* \param modulus_size Size of the modulus in 32 bit word.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the the inverse modulo operation on \e number
* using the divisor \e modulus.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_inv_mod_start(const uint32_t *number,
const uint8_t number_size,
const uint32_t *modulus,
const uint8_t modulus_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of the big number inverse modulo operation.
*
* \param buffer Pointer to buffer where the result needs to be
* stored.
* \param buffer_size Size of the provided buffer in 32 bit size
* word.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumInvModStart().
*
* This function gets the result of the big number inverse modulo operation
* previously started using the function \sa PKABigNumInvModStart().
*
* \retval PKA_STATUS_SUCCESS if the operation is successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
* then the result.
*/
uint8_t bignum_inv_mod_get_result(uint32_t *buffer,
const uint8_t buffer_size,
const uint32_t result_vector);
/** \brief Starts the big number multiplication.
*
* \param multiplicand Pointer to the buffer containing the big
* number multiplicand.
* \param multiplicand_size Size of the multiplicand in 32-bit word.
* \param multiplier Pointer to the buffer containing the big
* number multiplier.
* \param multiplier_size Size of the multiplier in 32-bit word.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the multiplication of the two big numbers.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_mul_start(const uint32_t *multiplicand,
const uint8_t multiplicand_size,
const uint32_t *multiplier,
const uint8_t multiplier_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the results of the big number multiplication.
*
* \param buffer Pointer to buffer where the result needs to be stored.
* \param buffer_size Address of the variable containing the length of the
* buffer. After the operation, the actual length of the resultant is
* stored at this address.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumMultiplyStart().
*
* This function gets the result of the multiplication of two big numbers
* operation previously started using the function \sa
* PKABigNumMultiplyStart().
*
* \retval PKA_STATUS_SUCCESS if the operation is successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_FAILURE if the operation is not successful.
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
* then the length of the result.
*/
uint8_t bignum_mul_get_result(uint32_t *buffer,
uint32_t *buffer_size,
const uint32_t result_vector);
/** \brief Starts the addition of two big number.
*
* \param number1 Pointer to the buffer containing the first big mumber.
* \param number1_size Size of the first big number in 32-bit word.
* \param number2 Pointer to the buffer containing the second big number.
* \param number2_size Size of the second big number in 32-bit word.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the addition of the two big numbers.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_add_start(const uint32_t *number1,
const uint8_t number1_size,
const uint32_t *number2,
const uint8_t number2_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of the addition operation on two big number.
*
* \param buffer Pointer to buffer where the result
* needs to be stored.
* \param buffer_size Address of the variable containing the length of
* the buffer. After the operation the actual length of the
* resultant is stored at this address.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumAddStart().
*
* This function gets the result of the addition operation on two big numbers,
* previously started using the function \sa PKABigNumAddStart().
*
* \retval PKA_STATUS_SUCCESS if the operation is successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_FAILURE if the operation is not successful.
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
* then the length of the result.
*/
uint8_t bignum_add_get_result(uint32_t *buffer,
uint32_t *buffer_size,
const uint32_t result_vector);
/** \brief Starts the substract of two big number.
*
* \param number1 Pointer to the buffer containing the first big mumber.
* \param number1_size Size of the first big number in 32-bit word.
* \param number2 Pointer to the buffer containing the second big number.
* \param number2_size Size of the second big number in 32-bit word.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the substraction of the two big numbers.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_subtract_start(const uint32_t *number1,
const uint8_t number1_size,
const uint32_t *number2,
const uint8_t number2_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of big number subtract.
*
* \param buffer Pointer to store the result of subtraction.
* \param buffer_size Address of the variable containing the length of the
* buffer. After the operation, the actual length of the resultant is
* stored at this address.
* \param result_vector Address of the result location which
* was provided by the start function PKABigNumSubtractStart().
*
* This function gets the result of PKABigNumSubtractStart().
*
* \retval PKA_STATUS_SUCCESS if the operation is successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_FAILURE if the operation is not successful.
*/
uint8_t bignum_subtract_get_result(uint32_t *buffer,
uint32_t *buffer_size,
const uint32_t result_vector);
/** \brief Starts the big number moduluar Exponentiation operation.
*
* \param number Pointer to the Exponent on which moduluar Exponentiation operation
* needs to be carried out.
* \param number_size Size of the the Exponent number number in 32-bit word.
* \param modulus Pointer to the divisor.
* \param modulus_size Size of the divisor modulus.
* \param base Pointer to the Base.
* \param base_size Size of the divisor base.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the moduluar Exponentiation operation on the base num base
* using the Exponent number and the Modulus num modulus. The PKA RAM location where the result
* will be available is stored in \sa result_vector.
* IMPORTANT = Modulus and Based should have buffers of the same length!
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_exp_mod_start(const uint32_t *number,
const uint8_t number_size,
const uint32_t *modulus,
const uint8_t modulus_size,
const uint32_t *base,
const uint8_t base_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of the big number modulus operation result.
*
* \param buffer Pointer to buffer where the result needs to
* be stored.
* \param buffer_size Size of the provided buffer in 32 bit size word.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumExpModStart().
*
* This function gets the result of the big number modulus operation which was
* previously started using the function \sa PKABigNumExpModStart().
*
* \retval PKA_STATUS_SUCCESS if successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_BUF_UNDERFLOW if the \e size is less than the length
* of the result.
*
* \note
* - 0 < number_size <= Max_Len
* - 1 < modulus_size <=Max_Len
* - modulus must be odd and modulus > 232
* - base < modulus
*/
uint8_t bignum_exp_mod_get_result(uint32_t *buffer,
const uint8_t buffer_size,
const uint32_t result_vector);
/** \brief Starts the big number Divide.
*
* \param dividend Pointer to the buffer containing the big
* number dividend.
* \param dividend_size Size of the dividend in 32-bit word.
* \param divisor Pointer to the buffer containing the big
* number divisor.
* \param divisor_size Size of the divisor in 32-bit word.
* \param result_vector Pointer to the result vector location
* which will be set by this function.
* \param process Process to be polled upon completion of the
* operation, or \c NULL
*
* This function starts the divide of the two big numbers.
*
* \retval PKA_STATUS_SUCCESS if successful in starting the operation.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy doing
* some other operation.
*/
uint8_t bignum_divide_start(const uint32_t *dividend,
const uint8_t dividend_size,
const uint32_t *divisor,
const uint8_t divisor_size,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the results of the big number Divide.
*
* \param buffer Pointer to buffer where the result needs to be stored.
* \param buffer_size Address of the variable containing the length of the
* buffer. After the operation, the actual length of the resultant is
* stored at this address.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKABigNumMultiplyStart().
*
* This function gets the result of the Divide of two big numbers
* operation previously started using the function \sa
* PKABigNumDivideStart().
*
* \retval PKA_STATUS_SUCCESS if the operation is successful.
* \retval PKA_STATUS_OPERATION_INPRG if the PKA hw module is busy performing
* the operation.
* \retval PKA_STATUS_RESULT_0 if the result is all zeroes.
* \retval PKA_STATUS_FAILURE if the operation is not successful.
* \retval PKA_STATUS_BUF_UNDERFLOW if the length of the provided buffer is less
* then the length of the result.
*/
uint8_t bignum_divide_get_result(uint32_t *buffer,
uint32_t *buffer_size,
const uint32_t result_vector);
/** @} */
#endif /* BIGNUM_DRIVER_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,200 @@
/*
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
* All rights reserved.
*
* Author: Andreas Dröscher <contiki@anticat.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \addtogroup c2538-ecc-algo
* @{
*
* \file
* Implementation of the cc2538 ECC Algorithms
*/
#include <contiki.h>
#include <process.h>
#include <limits.h>
#include <stdio.h>
#include "ecc-algorithm.h"
#include "ecc-driver.h"
#include "pka.h"
#define CHECK_RESULT(...) \
state->result = __VA_ARGS__; \
if(state->result) { \
printf("Line: %u Error: %u\n", __LINE__, (unsigned int)state->result); \
PT_EXIT(&state->pt); \
}
PT_THREAD(ecc_compare(ecc_compare_state_t *state)) {
PT_BEGIN(&state->pt);
CHECK_RESULT(bignum_cmp_start(state->a, state->b, state->size, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->result = bignum_cmp_get_result();
PT_END(&state->pt);
}
PT_THREAD(ecc_multiply(ecc_multiply_state_t *state)) {
PT_BEGIN(&state->pt);
CHECK_RESULT(ecc_mul_start(state->secret, &state->point_in, state->curve_info, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(ecc_mul_get_result(&state->point_out, state->rv));
PT_END(&state->pt);
}
PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state)) {
/* Executed Every Time */
uint8_t size = state->curve_info->size;
const uint32_t *ord = state->curve_info->n;
ec_point_t point;
memcpy(point.x, state->curve_info->x, sizeof(point.x));
memcpy(point.y, state->curve_info->y, sizeof(point.y));
PT_BEGIN(&state->pt);
/* Invert k_e mod n */
CHECK_RESULT(bignum_inv_mod_start(state->k_e, size, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_inv_mod_get_result(state->k_e_inv, size, state->rv));
/* Calculate Point R = K_e * GeneratorPoint */
CHECK_RESULT(ecc_mul_start(state->k_e, &point, state->curve_info, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(ecc_mul_get_result(&state->point_r, state->rv));
/* Calculate signature using big math functions
* d*r (r is the x coordinate of PointR) */
CHECK_RESULT(bignum_mul_start(state->secret, size, state->point_r.x, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->len = 24;
CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv));
/* d*r mod n */
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
/* hash + d*r */
CHECK_RESULT(bignum_add_start(state->hash, size, state->signature_s, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->len = 24;
CHECK_RESULT(bignum_add_get_result(state->signature_s, &state->len, state->rv));
/* hash + d*r mod n */
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
/* k_e_inv * (hash + d*r) */
CHECK_RESULT(bignum_mul_start(state->k_e_inv, size, state->signature_s, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->len = 24;
CHECK_RESULT(bignum_mul_get_result(state->signature_s, &state->len, state->rv));
/* k_e_inv * (hash + d*r) mod n */
CHECK_RESULT(bignum_mod_start(state->signature_s, state->len, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_mod_get_result(state->signature_s, size, state->rv));
PT_END(&state->pt);
}
PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state)) {
/* Executed Every Time */
uint8_t size = state->curve_info->size;
const uint32_t *ord = state->curve_info->n;
ec_point_t point;
memcpy(point.x, state->curve_info->x, sizeof(point.x));
memcpy(point.y, state->curve_info->y, sizeof(point.y));
PT_BEGIN(&state->pt);
/* Invert s mod n */
CHECK_RESULT(bignum_inv_mod_start(state->signature_s, size, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_inv_mod_get_result(state->s_inv, size, state->rv));
/* Calculate u1 = s_inv * hash */
CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->hash, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->len = 24;
CHECK_RESULT(bignum_mul_get_result(state->u1, &state->len, state->rv));
/* Calculate u1 = s_inv * hash mod n */
CHECK_RESULT(bignum_mod_start(state->u1, state->len, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_mod_get_result(state->u1, size, state->rv));
/* Calculate u2 = s_inv * r */
CHECK_RESULT(bignum_mul_start(state->s_inv, size, state->signature_r, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->len = 24;
CHECK_RESULT(bignum_mul_get_result(state->u2, &state->len, state->rv));
/* Calculate u2 = s_inv * r mod n */
CHECK_RESULT(bignum_mod_start(state->u2, state->len, ord, size, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(bignum_mod_get_result(state->u2, size, state->rv));
/* Calculate p1 = u1 * A */
CHECK_RESULT(ecc_mul_start(state->u1, &point, state->curve_info, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(ecc_mul_get_result(&state->p1, state->rv));
/* Calculate p2 = u1 * B */
CHECK_RESULT(ecc_mul_start(state->u2, &state->public, state->curve_info, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(ecc_mul_get_result(&state->p2, state->rv));
/* Calculate P = p1 + p2 */
CHECK_RESULT(ecc_add_start(&state->p1, &state->p2, state->curve_info, &state->rv, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
CHECK_RESULT(ecc_add_get_result(&state->p1, state->rv));
/* Verify Result */
CHECK_RESULT(bignum_cmp_start(state->signature_r, state->p1.x, size, state->process));
PT_WAIT_UNTIL(&state->pt, pka_check_status());
state->result = bignum_cmp_get_result();
if((state->result == PKA_STATUS_A_GR_B) || (state->result == PKA_STATUS_A_LT_B)) {
state->result = PKA_STATUS_SIGNATURE_INVALID;
}
PT_END(&state->pt);
}
/**
* @}
* @}
*/

View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
* All rights reserved.
*
* Author: Andreas Dröscher <contiki@anticat.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-ecc
* @{
*
* \defgroup cc2538-ecc-algo cc2538 ECC Algorithms
*
* This is a implementation of ECDH, ECDSA sign and ECDSA verify. It
* uses ecc-driver to communicate with the PKA. It uses continuations
* to free the main CPU / thread while the PKA is calculating.
*
* \note
* Only one request can be processed at a time.
* Maximal supported key length is 384bit (12 words).
* @{
*
* \file
* Header file for the cc2538 ECC Algorithms
*/
#ifndef ECC_ALGORITHM_H_
#define ECC_ALGORITHM_H_
#include "bignum-driver.h"
#include "ecc-driver.h"
typedef struct {
/* Containers for the State */
struct pt pt;
struct process *process;
/* Input Variables */
uint32_t a[12]; /**< Left Number */
uint32_t b[12]; /**< Right Number */
uint8_t size; /**< Length of a and b */
/* Output Variables */
uint8_t result; /**< Result Code */
} ecc_compare_state_t;
/**
* \brief Do a compare of two big numbers
*
* This function can be used for ECDH as well as
* Calculating a Public Key for ECDSA
*/
PT_THREAD(ecc_compare(ecc_compare_state_t *state));
typedef struct {
/* Containers for the State */
struct pt pt;
struct process *process;
/* Input Variables */
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
ec_point_t point_in; /**< Generator Point */
uint32_t secret[12]; /**< Secret */
/* Variables Holding intermediate data (initialized/used internally) */
uint32_t rv; /**< Address of Next Result in PKA SRAM */
/* Output Variables */
uint8_t result; /**< Result Code */
ec_point_t point_out; /**< Generated Point */
} ecc_multiply_state_t;
/**
* \brief Do a Multiplication on a EC
*
* This function can be used for ECDH as well as
* Calculating a Public Key for ECDSA
*/
PT_THREAD(ecc_multiply(ecc_multiply_state_t *state));
typedef struct {
/* Containers for the State */
struct pt pt;
struct process *process;
/* Input Variables */
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
uint32_t secret[12]; /**< Secret Key */
uint32_t k_e[12]; /**< Ephemeral Key */
uint32_t hash[12]; /**< Hash to be signed */
/* Variables Holding intermediate data (initialized/used internally) */
uint32_t rv; /**< Address of Next Result in PKA SRAM */
uint32_t k_e_inv[12]; /**< Inverted ephemeral Key */
uint32_t len; /**< Length of intermediate Result */
/* Output Variables */
uint8_t result; /**< Result Code */
ec_point_t point_r; /**< Signature R (x coordinate) */
uint32_t signature_s[24]; /**< Signature S */
} ecc_dsa_sign_state_t;
/**
* \brief Sign a Hash
*
* This function has to be called several times until the
* pt state is EXIT
* If the result code is 0 (SUCCESS) the signature can be
* read from point_r and signature_s
*/
PT_THREAD(ecc_dsa_sign(ecc_dsa_sign_state_t *state));
typedef struct {
/* Containers for the State */
struct pt pt;
struct process *process;
/* Input Variables */
ecc_curve_info_t *curve_info; /**< Curve defining the CyclicGroup */
uint32_t signature_r[12]; /**< Signature R */
uint32_t signature_s[12]; /**< Signature S */
uint32_t hash[12]; /**< Hash to be signed */
ec_point_t public; /**< Signature R (x coordinate) */
/* Variables Holding intermediate data (initialized/used internally) */
uint32_t rv; /**< Address of Next Result in PKA SRAM */
uint32_t s_inv[12]; /**< Inverted ephemeral Key */
uint32_t u1[24]; /**< Intermediate result */
uint32_t u2[24]; /**< Intermediate result */
ec_point_t p1; /**< Intermediate result */
ec_point_t p2; /**< Intermediate result */
uint32_t len; /**< Length of intermediate Result */
/* Output Variables */
uint8_t result; /**< Result Code */
} ecc_dsa_verify_state_t;
/**
* \brief Verify Signature
*
* This function has to be called several times until the
* pt state is EXIT
* If the result code is 0 (SUCCESS) the verification
* was success full.
* \note some error codes signal internal errors
* and others signal falls signatures.
*/
PT_THREAD(ecc_dsa_verify(ecc_dsa_verify_state_t *state));
#endif /* ECC_ALGORITHM_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2014, Institute for Pervasive Computing, ETH Zurich.
* All rights reserved.
*
* Author: Andreas Dröscher <contiki@anticat.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \addtogroup c2538-ecc-curves
* @{
*/
#include <contiki.h>
#include <ecc-driver.h>
/* [NIST P-256, X9.62 prime256v1] */
static const uint32_t nist_p_256_p[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF };
static const uint32_t nist_p_256_n[8] = { 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF };
static const uint32_t nist_p_256_a[8] = { 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF };
static const uint32_t nist_p_256_b[8] = { 0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0,
0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8 };
static const uint32_t nist_p_256_x[8] = { 0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81,
0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2 };
static const uint32_t nist_p_256_y[8] = { 0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357,
0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2 };
ecc_curve_info_t nist_p_256 = {
.name = "NIST P-256",
.size = 8,
.prime = nist_p_256_p,
.n = nist_p_256_n,
.a = nist_p_256_a,
.b = nist_p_256_b,
.x = nist_p_256_x,
.y = nist_p_256_y
};
/* [NIST P-192, X9.62 prime192v1] */
static const uint32_t nist_p_192_p[6] = { 0xffffffff, 0xffffffff, 0xfffffffe, 0xffffffff,
0xffffffff, 0xffffffff };
static const uint32_t nist_p_192_a[6] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff,
0xffffffff, 0xffffffff };
static const uint32_t nist_p_192_b[6] = { 0xc146b9b1, 0xfeb8deec, 0x72243049, 0x0fa7e9ab,
0xe59c80e7, 0x64210519 };
static const uint32_t nist_p_192_x[6] = { 0x82ff1012, 0xf4ff0afd, 0x43a18800, 0x7cbf20eb,
0xb03090f6, 0x188da80e };
static const uint32_t nist_p_192_y[6] = { 0x1e794811, 0x73f977a1, 0x6b24cdd5, 0x631011ed,
0xffc8da78, 0x07192b95 };
static const uint32_t nist_p_192_n[6] = { 0xb4d22831, 0x146bc9b1, 0x99def836, 0xffffffff,
0xffffffff, 0xffffffff };
ecc_curve_info_t nist_p_192 = {
.name = "NIST P-192",
.size = 6,
.prime = nist_p_192_p,
.n = nist_p_192_n,
.a = nist_p_192_a,
.b = nist_p_192_b,
.x = nist_p_192_x,
.y = nist_p_192_y
};
/**
* @}
* @}
*/

View file

@ -0,0 +1,65 @@
/*
* Original file:
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Port to Contiki:
* Copyright (c) 2014 Andreas Dröscher <contiki@anticat.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup cc2538-ecc
* @{
*
* \defgroup cc2538-ecc-curves cc2538 NIST curves
*
* NIST curves for various key sizes
* @{
*
* \file
* NIST curves for various key sizes
*/
#ifndef ECC_CURVE_H_
#define ECC_CURVE_H_
/*
* NIST P-256, X9.62 prime256v1
*/
ecc_curve_info_t nist_p_256;
/*
* NIST P-192, X9.62 prime192v1
*/
ecc_curve_info_t nist_p_192;
#endif /* CURVE_INFO_H_ */
/**
* @}
* @}
*/

Some files were not shown because too many files have changed in this diff Show more