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
*.log
*.elf
*.zip
*.d
*.ihex
*.pyc
@ -24,6 +25,7 @@
*.c64
*.cc2538dk
*.remote
*.jn516x
*.srf06-cc26xx
*.ev-aducrf101mkxz
*.report

View file

@ -36,6 +36,7 @@ before_script:
tar xjf arm-2008q3*.tar.bz2 -C /tmp/ &&
sudo cp -f -r /tmp/arm-2008q3/* /usr/ &&
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 ;
fi
@ -73,6 +74,22 @@ before_script:
cc65 --version ;
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
- if [ ${BUILD_CATEGORY:-sim} = sim ] ; then
java -version &&
@ -120,5 +137,6 @@ env:
- 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-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='llsec' MAKE_TARGETS='cooja'

View file

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

View file

@ -58,9 +58,9 @@ LIST(observers_list);
/*---------------------------------------------------------------------------*/
/*- Internal API ------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
coap_observer_t *
coap_add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
size_t token_len, const char *uri)
static coap_observer_t *
add_observer(uip_ipaddr_t *addr, uint16_t port, const uint8_t *token,
size_t token_len, const char *uri, int uri_len)
{
/* Remove existing observe relationship, if any. */
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);
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);
o->port = port;
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
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 */
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;
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 */
url_len = strlen(url);
for(obs = (coap_observer_t *)list_head(observers_list); obs;
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;
/*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 */
notification->mid = transaction->mid;
resource->get_handler(NULL, notification,
resource->get_handler(request, notification,
transaction->packet + COAP_MAX_HEADER_SIZE,
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_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(IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) {
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,
resource->url);
coap_req->uri_path, coap_req->uri_path_len);
if(obs) {
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.
* Uncomment if you want an information about the avaiable observers.
*/
/*
* coap_set_payload(coap_res,
* content,
* snprintf(content, sizeof(content), "Added %u/%u",
* list_length(observers_list),
* COAP_MAX_OBSERVERS));
*/
#if 0
static char content[16];
coap_set_payload(coap_res,
content,
snprintf(content, sizeof(content), "Added %u/%u",
list_length(observers_list),
COAP_MAX_OBSERVERS));
#endif
} else {
coap_res->code = SERVICE_UNAVAILABLE_5_03;
coap_set_payload(coap_res, "TooManyObservers", 16);

View file

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

View file

@ -124,7 +124,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
continue;
}
end = attrib + strlen(attrib);
} else {
} else if(resource->attributes != NULL) {
attrib = strstr(resource->attributes, filter);
if(attrib == NULL
|| (attrib[strlen(filter)] != '='
@ -159,8 +159,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
}
#endif
PRINTF("res: /%s (%p)\npos: s%d, o%ld, b%d\n", resource->url, resource,
strpos, *offset, bufpos);
PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource,
strpos, (long)*offset, bufpos);
if(strpos > 0) {
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_CHAR_IF_POSSIBLE('>');
if(resource->attributes[0]) {
if(resource->attributes != NULL && resource->attributes[0]) {
ADD_CHAR_IF_POSSIBLE(';');
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) {
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_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);
}
/*FIXME
* 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;
PROCESS_CONTEXT_BEGIN(transaction_handler_process);
etimer_restart(&t->retrans_timer); /* interval updated above */
process_current = process_actual;
PROCESS_CONTEXT_END(transaction_handler_process);
t = NULL;
} 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);
/* avoids code duplication without function overhead */
unsigned int *x = &delta;
do {
if(*x > 268) {
buffer[++written] = (*x - 269) >> 8;
buffer[++written] = (*x - 269);
} else if(*x > 12) {
buffer[++written] = (*x - 13);
if(delta > 268) {
buffer[++written] = ((delta - 269) >> 8) & 0xff;
buffer[++written] = (delta - 269) & 0xff;
} else if(delta > 12) {
buffer[++written] = (delta - 13);
}
} while(x != &length && (x = &length));
PRINTF("WRITTEN %u B opt header\n", 1 + written);
if(length > 268) {
buffer[++written] = ((length - 269) >> 8) & 0xff;
buffer[++written] = (length - 269) & 0xff;
} else if(length > 12) {
buffer[++written] = (length - 13);
}
PRINTF("WRITTEN %zu B opt header\n", 1 + written);
return ++written;
}
@ -148,7 +150,7 @@ coap_serialize_int_option(unsigned int number, unsigned int current_number,
if(0xFFFFFFFF & value) {
++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 = 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;
PRINTF("ARRAY type %u, len %u, full [%.*s]\n", number, length, length,
array);
PRINTF("ARRAY type %u, len %zu, full [%.*s]\n", number, length,
(int)length, array);
if(split_char != '\0') {
int j;
@ -185,7 +187,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
size_t temp_length;
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) {
part_end = array + j;
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);
i += temp_length;
PRINTF("OPTION type %u, delta %u, len %u, part [%.*s]\n", number,
number - current_number, i, temp_length, part_start);
PRINTF("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number,
number - current_number, i, (int)temp_length, part_start);
++j; /* skip the splitter */
current_number = number;
@ -208,7 +210,7 @@ coap_serialize_array_option(unsigned int number, unsigned int current_number,
memcpy(&buffer[i], array, 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);
}
@ -332,7 +334,7 @@ coap_serialize_message(void *packet, uint8_t *buffer)
/* empty packet, dont need to do more stuff */
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;
}
@ -368,6 +370,7 @@ coap_serialize_message(void *packet, uint8_t *buffer)
"Location-Path");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_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,
"Content-Format");
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",
coap_pkt->payload_len + option - buffer, option - buffer,
coap_pkt->payload_len);
(unsigned int)(coap_pkt->payload_len + option - buffer),
(unsigned int)(option - buffer),
(unsigned int)coap_pkt->payload_len);
PRINTF("Dump [0x%02X %02X %02X %02X %02X %02X %02X %02X]\n",
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_pkt->type = (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0])
>> COAP_HEADER_TYPE_POSITION;
coap_pkt->token_len =
MIN(COAP_TOKEN_LEN,
(COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->
buffer[0]) >> COAP_HEADER_TOKEN_LEN_POSITION);
coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0])
>> COAP_HEADER_TOKEN_LEN_POSITION;
coap_pkt->code = coap_pkt->buffer[1];
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;
}
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;
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;
++current_option;
/* avoids code duplication without function overhead */
unsigned int *x = &option_delta;
do {
if(*x == 13) {
*x += current_option[0];
if(option_delta == 13) {
option_delta += current_option[0];
++current_option;
} else if(*x == 14) {
*x += 255;
*x += current_option[0] << 8;
} else if(option_delta == 14) {
option_delta += 255;
option_delta += current_option[0] << 8;
++current_option;
*x += current_option[0];
option_delta += current_option[0];
++current_option;
}
if(option_length == 13) {
option_length += current_option[0];
++current_option;
} else if(option_length == 14) {
option_length += 255;
option_length += current_option[0] << 8;
++current_option;
option_length += current_option[0];
++current_option;
}
} while(x != &option_length && (x = &option_length));
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);
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:
coap_pkt->max_age = coap_parse_int_option(current_option,
option_length);
PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
PRINTF("Max-Age [%lu]\n", (unsigned long)coap_pkt->max_age);
break;
case COAP_OPTION_ETAG:
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_len = option_length;
#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_error_message = "This is a constrained server (Contiki)";
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;
#endif
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)";
return PROXYING_NOT_SUPPORTED_5_05;
break;
@ -588,7 +601,8 @@ coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
case COAP_OPTION_URI_HOST:
coap_pkt->uri_host = (char *)current_option;
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;
case COAP_OPTION_URI_PORT:
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_pkt->uri_path_len), current_option,
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;
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((char **)&(coap_pkt->uri_query),
&(coap_pkt->uri_query_len), current_option,
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);
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_pkt->location_path_len), current_option,
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);
break;
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_pkt->location_query_len), current_option,
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);
break;
case COAP_OPTION_OBSERVE:
coap_pkt->observe = coap_parse_int_option(current_option,
option_length);
PRINTF("Observe [%lu]\n", coap_pkt->observe);
PRINTF("Observe [%lu]\n", (unsigned long)coap_pkt->observe);
break;
case COAP_OPTION_BLOCK2:
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_num & 0x07);
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);
break;
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_num & 0x07);
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);
break;
case COAP_OPTION_SIZE2:
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;
case COAP_OPTION_SIZE1:
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;
default:
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_pkt->content_format = (coap_content_format_t)format;
coap_pkt->content_format = format;
SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
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_pkt->accept = (coap_content_format_t)accept;
coap_pkt->accept = accept;
SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
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 */
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;
uint8_t etag_len;
uint8_t etag[COAP_ETAG_LEN];
@ -111,7 +111,7 @@ typedef struct {
size_t uri_path_len;
const char *uri_path;
int32_t observe;
coap_content_format_t accept;
uint16_t accept;
uint8_t if_match_len;
uint8_t if_match[COAP_ETAG_LEN];
uint32_t block2_num;
@ -135,13 +135,13 @@ typedef struct {
/* option format serialization */
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
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); \
current_number = number; \
}
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
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[1], \
coap_pkt->field[2], \
@ -156,18 +156,18 @@ typedef struct {
}
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
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); \
current_number = number; \
}
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) \
{ \
PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
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; \
if(coap_pkt->field##_more) { block |= 0x8; } \
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); \
current_number = number; \
}

View file

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

View file

@ -70,6 +70,15 @@ LIST(restful_periodic_services);
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);
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;
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);
resource; resource = resource->next) {
/* if the web service handles that kind of requests and urls matches */
if((REST.get_url(request, &url) == strlen(resource->url)
|| (REST.get_url(request, &url) > strlen(resource->url)
&& (resource->flags & HAS_SUB_RESOURCES)))
&& strncmp(resource->url, url, strlen(resource->url)) == 0) {
res_url_len = strlen(resource->url);
if((url_len == res_url_len
|| (url_len > res_url_len
&& (resource->flags & HAS_SUB_RESOURCES)
&& url[res_url_len] == '/'))
&& strncmp(resource->url, url, res_url_len) == 0) {
found = 1;
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)
{
int numregs;
int flags;
int i;
int bufptr;
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;
for(i = 0; i < numregs; ++i) {

View file

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

View file

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

View file

@ -128,8 +128,8 @@ memcpy_misaligned(void *dest, const void *source, int len)
int i;
uint8_t *destptr;
const uint8_t *sourceptr;
if(((int)dest & 1) == 1 ||
((int)source & 1) == 1) {
if(((uintptr_t)dest & 1) == 1 ||
((uintptr_t)source & 1) == 1) {
destptr = dest;
sourceptr = source;
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. */
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);
trickle_send(&trickle);
}
@ -157,7 +157,7 @@ recv_trickle(struct trickle_conn *c)
msg->netcmd[len] = 0;
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. */
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. */
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);*/
unicast_send(&uc, &addr);
@ -160,7 +160,7 @@ recv_uc(struct unicast_conn *c, const linkaddr_t *from)
msg->sendcmd[len] = 0;
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. */
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. */
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
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) {
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;
linkaddr_copy((linkaddr_t *)&msg.originator, originator);
msg.seqno = seqno;

View file

@ -158,7 +158,6 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data)
static char *command;
static struct process *started_process;
char command_copy[MAX_COMMANDLENGTH];
int ret;
if(ev == shell_event_input) {
goto exit;
@ -172,7 +171,7 @@ PROCESS_THREAD(shell_repeat_server_process, ev, data)
data == &shell_repeat_process);
{
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);
if(started_process != NULL &&
@ -202,11 +201,10 @@ repeat_print_usage(void)
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_repeat_process, ev, data)
{
static int reps, period, period_left;
static int reps, period;
static char command[MAX_COMMANDLENGTH];
static struct etimer etimer;
static int i;
static clock_time_t start_time;
const char *args, *next;
if(ev == shell_event_input) {
@ -258,7 +256,6 @@ PROCESS_THREAD(shell_repeat_process, ev, data)
/* printf("repeats %d period %d command '%s'\n",
reps, period, command);*/
start_time = clock_time();
etimer_set(&etimer, CLOCK_SECOND * period);
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 process *started_process;
const char *args, *next;
int ret;
/* if(ev == shell_event_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, */
/* 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);
if(started_process != NULL &&

View file

@ -51,7 +51,7 @@
#define SHELL_VARS_RAM_END SHELL_VARS_CONF_RAM_END
#else /* SHELL_VARS_CONF_RAM_BEGIN */
#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 */
/*---------------------------------------------------------------------------*/
@ -77,8 +77,8 @@ PROCESS_THREAD(shell_vars_process, ev, data)
for(i = 0; i < symbols_nelts; ++i) {
if(symbols[i].name != NULL &&
(unsigned int)symbols[i].value >= SHELL_VARS_RAM_BEGIN &&
(unsigned int)symbols[i].value <= SHELL_VARS_RAM_END) {
(uintptr_t)symbols[i].value >= SHELL_VARS_RAM_BEGIN &&
(uintptr_t)symbols[i].value <= SHELL_VARS_RAM_END) {
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)
{
return (c == ISO_space ||
@ -255,7 +255,7 @@ htmlparser_init(void)
#endif /* WWW_CONF_FORMS */
}
/*-----------------------------------------------------------------------------------*/
static char CC_FASTCALL
static char
lowercase(char c)
{
/* XXX: This is a *brute force* approach to lower-case
@ -276,7 +276,7 @@ endtagfound(void)
s.tagattrparam[s.tagattrparamptr] = 0;
}
/*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL
static void
switch_majorstate(unsigned char 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)
{
if(s.wordlen < WWW_CONF_WEBPAGE_WIDTH - 1 && c < 0x80) {
@ -320,7 +320,7 @@ newline(void)
htmlparser_newline();
}
/*-----------------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL
static unsigned char
find_tag(char *tag)
{
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)
{
static uint8_t i;

View file

@ -200,7 +200,7 @@ window_copy(int curptr, const char *data, unsigned char datalen)
len = windowend - windowstart;
}
strncpy(windowptr + windowstart, data, len);
strncpy((char *)(windowptr + windowstart), data, len);
windowstart += len;
return curptr + datalen;
@ -217,7 +217,7 @@ senddata(void)
windowstart = s.getrequestptr;
curptr = 0;
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, s.file, (unsigned char)strlen(s.file));
@ -479,6 +479,11 @@ webclient_appcall(void *state)
if(uip_closed()) {
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) {
case HTTPFLAG_HTTPS:
/* Send some info to the user. */

View file

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

View file

@ -80,7 +80,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen)
*dest = ISO_slash;
strncpy(dest + 1, wwwroot, wwwrootlen);
len = 0;
from = source; to = dest + wwwrootlen;
from = (unsigned char *)source; to = (unsigned char *)dest + wwwrootlen;
maxlen -= 2 + wwwrootlen;
do {
c = *(from++);
@ -139,7 +139,7 @@ urlconv_tofilename(char *dest, char *source, unsigned char maxlen)
}
} while(c);
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 {
++to;
*to = 0;

View file

@ -192,10 +192,24 @@
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#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.
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
#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 */
/*---------------------------------------------------------------------------*/

View file

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

View file

@ -185,7 +185,7 @@ unsigned short ctk_screensaver_timeout = (5*60);
static struct timer timer;
#endif /* CTK_CONF_SCREENSAVER */
static void CC_FASTCALL
static void
textentry_input(ctk_arch_key_t c,
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
*/
/*---------------------------------------------------------------------------*/
static void CC_FASTCALL
static void
do_redraw_all(unsigned char clipy1, unsigned char clipy2)
{
#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.
*/
/*---------------------------------------------------------------------------*/
static void CC_FASTCALL
static void
add_redrawwidget(struct ctk_widget *w)
{
static unsigned char i;
@ -852,7 +852,9 @@ add_redrawwidget(struct ctk_widget *w)
static void
widget_redraw(struct ctk_widget *widget)
{
#if CTK_CONF_WINDOWS
struct ctk_window *window;
#endif /* CTK_CONF_WINDOWS */
if(mode != CTK_MODE_NORMAL || widget == NULL) {
return;
@ -870,8 +872,8 @@ widget_redraw(struct ctk_widget *widget)
if(menus.open == NULL)
#endif /* CTK_CONF_MENUS */
{
window = widget->window;
#if CTK_CONF_WINDOWS
window = widget->window;
if(window == dialog) {
ctk_draw_widget(widget, CTK_FOCUS_DIALOG, 0, height);
} else if(dialog == NULL &&
@ -921,7 +923,7 @@ ctk_widget_redraw(struct ctk_widget *widget)
* \param widget The widget to be added.
*/
/*---------------------------------------------------------------------------*/
void CC_FASTCALL
void
ctk_widget_add(CC_REGISTER_ARG struct ctk_window *window,
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.
*/
/*---------------------------------------------------------------------------*/
static void CC_FASTCALL
static void
select_widget(struct ctk_widget *focus)
{
struct ctk_window *window;
@ -1001,7 +1003,7 @@ select_widget(struct ctk_widget *focus)
#define DOWN 1
#define LEFT 2
#define RIGHT 3
static void CC_FASTCALL
static void
switch_focus_widget(unsigned char direction)
{
#if CTK_CONF_WINDOWS
@ -1126,7 +1128,7 @@ switch_menu_item(unsigned char updown)
}
#endif /* CTK_CONF_MENUS */
/*---------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL
static unsigned char
activate(CC_REGISTER_ARG struct ctk_widget *w)
{
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 */
/*---------------------------------------------------------------------------*/
static void CC_FASTCALL
static void
textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t)
{
register char *cptr, *cptr2;

View file

@ -743,7 +743,7 @@ void ctk_icon_add(struct ctk_widget *icon, struct process *p);
*/
#define CTK_WIDGET_ADD(win, 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);
/**

View file

@ -48,14 +48,11 @@
/*---------------------------------------------------------------------------*/
static void
set_nonce(uint8_t *iv,
set_iv(uint8_t *iv,
uint8_t flags,
const uint8_t *nonce,
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;
memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
iv[14] = 0;
@ -73,7 +70,7 @@ ctr_step(const uint8_t *nonce,
uint8_t a[AES_128_BLOCK_SIZE];
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);
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
@ -82,8 +79,8 @@ ctr_step(const uint8_t *nonce,
}
/*---------------------------------------------------------------------------*/
static void
mic(const uint8_t *m, uint8_t m_len,
const uint8_t *nonce,
mic(const uint8_t *nonce,
const uint8_t *m, uint8_t m_len,
const uint8_t *a, uint8_t a_len,
uint8_t *result,
uint8_t mic_len)
@ -92,10 +89,10 @@ mic(const uint8_t *m, uint8_t m_len,
uint8_t pos;
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);
if(a_len > 0) {
if(a_len) {
x[1] = x[1] ^ a_len;
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[i - 2];
@ -113,8 +110,7 @@ mic(const uint8_t *m, uint8_t m_len,
}
}
if(m_len > 0) {
m = a + a_len;
if(m_len) {
pos = 0;
while(pos < m_len) {
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
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 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) {
AES_128.set_key((uint8_t*)key);
static void
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 = {
mic,
ctr,
set_key
set_key,
aead
};
/*---------------------------------------------------------------------------*/

View file

@ -56,33 +56,25 @@
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.
* \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.
*/
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()
* \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);
/**
* \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;

View file

@ -38,6 +38,7 @@
*/
#include "lib/ringbuf.h"
#include <sys/cc.h>
/*---------------------------------------------------------------------------*/
void
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) {
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;
}
/*---------------------------------------------------------------------------*/
@ -84,8 +92,17 @@ ringbuf_get(struct ringbuf *r)
most platforms, but C does not guarantee this.
*/
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;
} else {
return -1;

View file

@ -34,6 +34,20 @@
#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_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) {
if(uip_ds6_if.addr_list[i].isused
#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
) {
if(!*count) {

View file

@ -155,6 +155,7 @@ unsigned char tcpip_is_forwarding; /* Forwarding right now? */
PROCESS(tcpip_process, "TCP/IP stack");
/*---------------------------------------------------------------------------*/
#if UIP_TCP || UIP_CONF_IP_FORWARD
static void
start_periodic_tcp_timer(void)
{
@ -162,6 +163,7 @@ start_periodic_tcp_timer(void)
etimer_restart(&periodic);
}
}
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
/*---------------------------------------------------------------------------*/
static void
check_for_tcp_syn(void)
@ -183,11 +185,17 @@ check_for_tcp_syn(void)
static void
packet_input(void)
{
if(uip_len > 0) {
#if UIP_CONF_IP_FORWARD
if(uip_len > 0) {
tcpip_is_forwarding = 1;
if(uip_fw_forward() == UIP_FW_LOCAL) {
if(uip_fw_forward() != UIP_FW_LOCAL) {
tcpip_is_forwarding = 0;
return;
}
tcpip_is_forwarding = 0;
#endif /* UIP_CONF_IP_FORWARD */
check_for_tcp_syn();
uip_input();
if(uip_len > 0) {
@ -196,33 +204,13 @@ packet_input(void)
#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;
}
#else /* UIP_CONF_IP_FORWARD */
if(uip_len > 0) {
check_for_tcp_syn();
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
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTF("tcpip packet_input output len %d\n", uip_len);
tcpip_output();
#endif
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* UIP_CONF_TCP_SPLIT */
}
}
#endif /* UIP_CONF_IP_FORWARD */
}
/*---------------------------------------------------------------------------*/
#if UIP_TCP
@ -584,7 +572,16 @@ tcpip_ipv6_output(void)
/* This should be copied from the ext header... */
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
PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
#endif /* !UIP_FALLBACK_INTERFACE */
@ -672,7 +669,11 @@ tcpip_ipv6_output(void)
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
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 */
} else {
#if UIP_ND6_SEND_NA
@ -719,7 +720,6 @@ tcpip_ipv6_output(void)
uip_clear_buf();
return;
}
return;
}
/* Multicast IP destination address. */
tcpip_output(NULL);

View file

@ -38,6 +38,7 @@
*/
#include "net/ip/uip-debug.h"
#include "net/ip/ip64-addr.h"
/*---------------------------------------------------------------------------*/
void
@ -53,6 +54,23 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
return;
}
#if NETSTACK_CONF_WITH_IPV6
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
/*
* Printing IPv4-mapped addresses is done according to RFC 3513 [1]
*
* "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) {
@ -68,6 +86,7 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
PRINTA("%x", a);
}
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
#endif /* NETSTACK_CONF_WITH_IPV6 */

View file

@ -54,7 +54,7 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
if(data != NULL) {
uip_udp_conn = c;
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?
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len);
uip_process(UIP_UDP_SEND_CONN);

View file

@ -1429,7 +1429,13 @@ extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
struct uip_fallback_interface {
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
@ -2016,8 +2022,9 @@ CCIF extern uip_lladdr_t uip_lladdr;
(((a)->u8[15]) == 0x02))
/**
* \brief Checks whether the address a is link local.
* a is of type uip_ipaddr_t
* \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_linklocal(a) \
((a)->u8[0] == 0xfe && \
@ -2070,15 +2077,6 @@ CCIF extern uip_lladdr_t uip_lladdr;
(((b)->u8[13]) = ((a)->u8[13])); \
(((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
* a type is uip_ipaddr_t

View file

@ -40,4 +40,9 @@
#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 */

View file

@ -84,7 +84,7 @@ init(void)
printf("ip64-eth-interface: init\n");
}
/*---------------------------------------------------------------------------*/
static void
static int
output(void)
{
int len, ret;
@ -114,7 +114,7 @@ output(void)
printf("Create request\n");
len = ip64_arp_create_arp_request(ip64_packet_buffer,
&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);
}
/*---------------------------------------------------------------------------*/
static void
static int
output(void)
{
int len;
@ -138,8 +138,10 @@ output(void)
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
uip_len = len;
slip_send();
return len;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
const struct uip_fallback_interface ip64_slip_interface = {

View file

@ -188,7 +188,7 @@ ip64_init(void)
PRINTF("ip64_init\n");
IP64_ETH_DRIVER.init();
#if IP64_CONF_DHCP
#if IP64_DHCP
ip64_ipv4_dhcp_init();
#endif /* IP64_CONF_DHCP */
@ -894,14 +894,14 @@ ip64_hostaddr_is_configured(void)
static void
interface_init(void)
{
IP64_CONF_UIP_FALLBACK_INTERFACE.init();
IP64_UIP_FALLBACK_INTERFACE.init();
}
/*---------------------------------------------------------------------------*/
static void
interface_output(void)
{
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 = {

View file

@ -71,7 +71,18 @@ extern uint16_t ip64_packet_buffer_maxlen;
#define IP64_INPUT 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 */

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[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->len = 1; /* TCP length of the SYN is one. */
@ -1367,10 +1372,10 @@ uip_process(uint8_t flag)
uip_connr->len = 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[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);
/* Parse the TCP MSS option, if present. */

View file

@ -1100,7 +1100,7 @@ icmp_input()
uint16_t val;
#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 ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(" to ");

View file

@ -635,7 +635,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr)
iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
&UIP_IP_BUF->srcipaddr, &uip_lladdr);
/* 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[2] == 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,
&UIP_IP_BUF->destipaddr, (uip_lladdr_t *)link_destaddr);
/* 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[2] == 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 ||
UIP_IP_BUF->tcflow != 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_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_lladdr_t *)link_destaddr) ||
(UIP_IP_BUF->proto != UIP_PROTO_ICMP6 &&
@ -1443,7 +1443,7 @@ output(const uip_lladdr_t *localdest)
#else /* USE_FRAMER_HDRLEN */
framer_hdrlen = 21;
#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 SICSLOWPAN_CONF_FRAG
@ -1455,7 +1455,7 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* 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;
PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {

View file

@ -83,7 +83,9 @@ static uip_ipaddr_t loc_fipaddr;
/* Pointers used in this file */
static uip_ds6_addr_t *locaddr;
static uip_ds6_maddr_t *locmaddr;
#if UIP_DS6_AADDR_NB
static uip_ds6_aaddr_t *locaaddr;
#endif /* UIP_DS6_AADDR_NB */
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;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if(locaddr->isused && (state == -1 || locaddr->state == state)
&& (uip_is_addr_link_local(&locaddr->ipaddr))) {
&& (uip_is_addr_linklocal(&locaddr->ipaddr))) {
return locaddr;
}
}
@ -408,7 +410,7 @@ uip_ds6_get_global(int8_t state)
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if(locaddr->isused && (state == -1 || locaddr->state == state)
&& !(uip_is_addr_link_local(&locaddr->ipaddr))) {
&& !(uip_is_addr_linklocal(&locaddr->ipaddr))) {
return locaddr;
}
}
@ -458,6 +460,7 @@ uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr)
uip_ds6_aaddr_t *
uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
{
#if UIP_DS6_AADDR_NB
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,
@ -466,6 +469,7 @@ uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
return locaaddr;
}
#endif /* UIP_DS6_AADDR_NB */
return NULL;
}
@ -483,11 +487,13 @@ uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr)
uip_ds6_aaddr_t *
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,
UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaaddr) == FOUND) {
return locaaddr;
}
#endif /* UIP_DS6_AADDR_NB */
return NULL;
}
@ -499,13 +505,13 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
uint8_t n = 0;
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 */
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
/* Only preferred global (not link-local) addresses */
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);
if(n >= best) {
best = n;
@ -608,7 +614,7 @@ uip_ds6_dad(uip_ds6_addr_t *addr)
int
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");
return 0;
}

View file

@ -216,9 +216,15 @@ typedef struct uip_ds6_netif {
uint32_t reachable_time; /* in msec */
uint32_t retrans_timer; /* in msec */
uint8_t maxdadns;
#if 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];
#endif /* UIP_DS6_AADDR_NB */
#if UIP_DS6_MADDR_NB
uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];
#endif /* UIP_DS6_MADDR_NB */
} uip_ds6_netif_t;
/** \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 */
#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 */
static void
@ -191,15 +201,14 @@ ns_input(void)
#endif /*UIP_CONF_IPV6_CHECKS */
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) {
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
0, NBR_STALE);
uip_lladdr_t lladdr_aligned;
extract_lladdr_aligned(&lladdr_aligned);
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
} else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
UIP_LLADDR_LEN);
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
nbr->state = NBR_STALE;
} else {
if(nbr->state == NBR_INCOMPLETE) {
@ -621,18 +630,18 @@ rs_input(void)
goto discard;
} else {
#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) {
/* we need to add the neighbor */
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
} else {
/* If LL address changed, set neighbor state to stale */
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
uip_ds6_nbr_get_ll(nbr), UIP_LLADDR_LEN) != 0) {
uip_ds6_nbr_t nbr_data = *nbr;
uip_ds6_nbr_rm(nbr);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], 0, NBR_STALE);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 0, NBR_STALE);
nbr->reachable = nbr_data.reachable;
nbr->sendns = nbr_data.sendns;
nbr->nscount = nbr_data.nscount;
@ -823,7 +832,7 @@ ra_input(void)
#if UIP_CONF_IPV6_CHECKS
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)) {
PRINTF("RA received is bad");
goto discard;
@ -859,9 +868,9 @@ ra_input(void)
nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF;
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
if(nbr == NULL) {
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr,
(uip_lladdr_t *)&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
1, NBR_STALE);
uip_lladdr_t lladdr_aligned;
extract_lladdr_aligned(&lladdr_aligned);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned, 1, NBR_STALE);
} else {
uip_lladdr_t *lladdr = (uip_lladdr_t *)uip_ds6_nbr_get_ll(nbr);
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;
if((uip_ntohl(nd6_opt_prefix_info->validlt) >=
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 */
if(nd6_opt_prefix_info->flagsreserved1 & UIP_ND6_RA_FLAG_ONLINK) {
prefix =

View file

@ -288,7 +288,10 @@ struct uip_icmp6_conn uip_icmp6_conns;
/*---------------------------------------------------------------------------*/
/* 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
uip_add32(uint8_t *op32, uint16_t op16)
{
@ -315,8 +318,8 @@ uip_add32(uint8_t *op32, uint16_t op16)
}
}
}
#endif /* UIP_ARCH_ADD32 && UIP_TCP */
#endif /* UIP_ARCH_ADD32 */
#endif /* UIP_TCP */
#if ! UIP_ARCH_CHKSUM
/*---------------------------------------------------------------------------*/
@ -1203,8 +1206,8 @@ uip_process(uint8_t flag)
if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
!uip_ds6_is_my_maddr(&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_link_local(&UIP_IP_BUF->srcipaddr) &&
!uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) &&
!uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) &&
!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
@ -1238,7 +1241,7 @@ uip_process(uint8_t flag)
UIP_STAT(++uip_stat.ip.forwarded);
goto send;
} 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_loopback(&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;
/* 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[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);
/* Parse the TCP MSS option, if present. */

View file

@ -55,7 +55,8 @@ anti_replay_set_counter(void)
{
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_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
* CCM* convenience functions for LLSEC use
* \author
* 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 <string.h>
/*---------------------------------------------------------------------------*/
void ccm_star_mic_packetbuf(const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len)
static const uint8_t *
get_extended_address(const linkaddr_t *addr)
#if LINKADDR_SIZE == 2
{
uint8_t *dataptr = packetbuf_dataptr();
uint8_t data_len = packetbuf_datalen();
uint8_t *headerptr = packetbuf_hdrptr();
uint8_t header_len = packetbuf_hdrlen();
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
/* workaround for short addresses: derive EUI64 as in RFC 6282 */
static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 ,
0xFF , 0xFE , 0x00 , 0x00 , 0x00 } };
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[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);
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
* CCM* convenience functions for MAC security
* \author
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef CCM_STAR_PACKETBUF_H_
#define CCM_STAR_PACKETBUF_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);
#include "lib/ccm-star.h"
/**
* \brief Calls CCM_STAR.ctr with parameters appropriate for LLSEC.
*/
void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address);
void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward);
#endif /* CCM_STAR_PACKETBUF_H_ */

View file

@ -48,10 +48,6 @@
* for incoming packets. Likewise, all NETSTACK_NETWORK protocols
* 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"
typedef void (* llsec_on_bootstrapped_t)(void);
/**
* The structure of a link layer security driver.
*/
struct llsec_driver {
char *name;
/** Bootstraps link layer security and thereafter starts upper layers. */
void (* bootstrap)(llsec_on_bootstrapped_t on_bootstrapped);
/** Inits link layer security. */
void (* init)(void);
/** Secures outgoing frames before passing them to NETSTACK_MAC. */
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;
* filters out injected or replayed frames.
*/
void (* input)(void);
/** Returns the security-related overhead per frame in bytes */
uint8_t (* get_overhead)(void);
};
#endif /* LLSEC_H_ */

View file

@ -47,6 +47,7 @@
#include "net/llsec/llsec802154.h"
#include "net/llsec/ccm-star-packetbuf.h"
#include "net/mac/frame802154.h"
#include "net/mac/framer-802154.h"
#include "net/netstack.h"
#include "net/packetbuf.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);
/*---------------------------------------------------------------------------*/
static const uint8_t *
get_extended_address(const linkaddr_t *addr)
#if LINKADDR_SIZE == 2
static int
aead(uint8_t hdrlen, int forward)
{
/* workaround for short addresses: derive EUI64 as in RFC 6282 */
static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 ,
0xFF , 0xFE , 0x00 , 0x00 , 0x00 } };
uint8_t totlen;
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
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
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);
}
/*---------------------------------------------------------------------------*/
static int
on_frame_created(void)
create(void)
{
uint8_t *dataptr = packetbuf_dataptr();
uint8_t data_len = packetbuf_datalen();
int result;
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);
add_security_header();
result = framer_802154.create();
if(result == FRAMER_FAILED) {
return result;
}
return 1;
aead(result, 1);
return result;
}
/*---------------------------------------------------------------------------*/
static void
input(void)
static int
parse(void)
{
uint8_t generated_mic[LLSEC802154_MIC_LENGTH];
uint8_t *received_mic;
int result;
const linkaddr_t *sender;
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) {
PRINTF("noncoresec: received frame with wrong security level\n");
return;
return FRAMER_FAILED;
}
sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
if(linkaddr_cmp(sender, &linkaddr_node_addr)) {
PRINTF("noncoresec: frame from ourselves\n");
return;
return FRAMER_FAILED;
}
data_len -= LLSEC802154_MIC_LENGTH;
packetbuf_set_datalen(data_len);
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
#if WITH_ENCRYPTION
ccm_star_ctr_packetbuf(get_extended_address(sender));
#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",
if(!aead(result, 0)) {
PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n",
anti_replay_get_counter());
return;
return FRAMER_FAILED;
}
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);
if(!info) {
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)) {
nbr_table_remove(anti_replay_table, info);
PRINTF("noncoresec: could not lock\n");
return;
return FRAMER_FAILED;
}
anti_replay_init_info(info);
@ -187,34 +216,44 @@ input(void)
if(anti_replay_was_replayed(info)) {
PRINTF("noncoresec: received replayed frame %"PRIu32"\n",
anti_replay_get_counter());
return;
return FRAMER_FAILED;
}
}
NETSTACK_NETWORK.input();
}
/*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return SECURITY_HEADER_LENGTH + LLSEC802154_MIC_LENGTH;
return result;
}
/*---------------------------------------------------------------------------*/
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);
nbr_table_register(anti_replay_table, NULL);
on_bootstrapped();
}
/*---------------------------------------------------------------------------*/
const struct llsec_driver noncoresec_driver = {
"noncoresec",
bootstrap,
init,
send,
on_frame_created,
input,
get_overhead
input
};
/*---------------------------------------------------------------------------*/
const struct framer noncoresec_framer = {
length,
create,
parse
};
/*---------------------------------------------------------------------------*/

View file

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

View file

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

View file

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

View file

@ -507,14 +507,16 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
#endif
int strobes;
uint8_t got_strobe_ack = 0;
int len;
uint8_t is_broadcast = 0;
uint8_t is_known_receiver = 0;
uint8_t collisions;
int transmit_len;
int ret;
uint8_t contikimac_was_on;
#if !RDC_CONF_HARDWARE_ACK
int len;
uint8_t seqno;
#endif
/* Exit if RDC and radio were explicitly turned off */
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)) {
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");
return MAC_TX_ERR_FATAL;
}
@ -655,11 +657,11 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
or rx cycle */
on();
}
seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
#endif
watchdog_periodic();
t0 = RTIMER_NOW();
seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
for(strobes = 0, collisions = 0;
got_strobe_ack == 0 && collisions == 0 &&
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;
}
#if !RDC_CONF_HARDWARE_ACK
len = 0;
#endif
{
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;
int ret;
int is_receiver_awake;
int pending;
if(buf_list == NULL) {
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_MAC_ACK, 1);
if(NETSTACK_FRAMER.create_and_secure() < 0) {
if(NETSTACK_FRAMER.create() < 0) {
PRINTF("contikimac: framer failed\n");
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
return;
@ -846,6 +851,8 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
/* Prepare the packetbuf */
queuebuf_to_packetbuf(curr->buf);
pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
/* Send the current packet */
ret = send_packet(sent, ptr, curr, is_receiver_awake);
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 */
next = NULL;
}
} while((next != NULL) && packetbuf_attr(PACKETBUF_ATTR_PENDING));
} while((next != NULL) && pending);
}
/*---------------------------------------------------------------------------*/
/* Timer callback triggered when receiving a burst, after having
@ -911,8 +918,6 @@ input_packet(void)
broadcast address. */
/* 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);
if(we_are_receiving_burst) {
on();

View file

@ -171,8 +171,10 @@ transmit_packet_list(void *ptr)
}
/*---------------------------------------------------------------------------*/
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) {
/* Remove packet from list and deallocate */
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->deferrals = 0;
/* Set a timer for next transmissions */
ctimer_set(&n->transmit_timer, default_timebase(),
transmit_packet_list, n);
tx_delay = (status == MAC_TX_OK) ? 0 : default_timebase();
ctimer_set(&n->transmit_timer, tx_delay, transmit_packet_list, n);
} else {
/* This was the last packet in the queue, we free the neighbor */
ctimer_stop(&n->transmit_timer);
@ -293,7 +295,7 @@ packet_sent(void *ptr, int status, int num_transmissions)
} else {
PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n",
status, n->transmissions, n->collisions);
free_packet(n, q);
free_packet(n, q, status);
mac_call_sent_callback(sent, cptr, status, num_tx);
}
} else {
@ -302,7 +304,7 @@ packet_sent(void *ptr, int status, int num_transmissions)
} else {
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);
}
} else {

View file

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

View file

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

View file

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

View file

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

View file

@ -219,6 +219,11 @@ phase_wait(const linkaddr_t *neighbor, rtimer_clock_t cycle_time,
if(buf_list == NULL) {
packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
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_ptr = mac_callback_ptr;

View file

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

View file

@ -121,7 +121,7 @@ int
route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
uint8_t cost, uint8_t seqno)
{
struct route_entry *e;
struct route_entry *e, *oldest = NULL;
/* Avoid inserting duplicate entries. */
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. */
e = memb_alloc(&route_mem);
if(e == NULL) {
/* Remove oldest entry. XXX */
e = list_chop(route_table);
/* Remove oldest entry. */
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",
e->dest.u8[0], e->dest.u8[1],
e->nexthop.u8[0], e->nexthop.u8[1],

View file

@ -115,7 +115,7 @@ send(void *ptr)
if(c->buf) {
queuebuf_to_packetbuf(c->buf);
unicast_send(&c->c, &c->receiver);
stunicast_set_timer(c, CLOCK_SECOND);
ctimer_restart(&c->t);
}
/* if(c->u->sent != NULL) {
c->u->sent(c);

View file

@ -121,6 +121,18 @@
#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0
#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;
if(uip_ds6_if.addr_list[i].isused &&
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;
}
}
@ -190,7 +190,7 @@ rpl_dag_root_init_dag_immediately(void)
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
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;
}
}

View file

@ -938,6 +938,15 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
rpl_parent_t *p;
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);
if(dag == NULL) {
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;
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
with this prefix. */
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);
}
}
p->rank = dio->rank;
/* Determine the objective function by using the
objective code point of the DIO. */
@ -1336,6 +1335,12 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
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
* 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) {
instance->dio_counter++;
}
} else {
}
}
p->rank = dio->rank;
}
}
/* Parent info has been updated, trigger rank recalculation */
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;
if(uip_ds6_if.addr_list[i].isused &&
(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));
return 1;
}
@ -916,15 +916,11 @@ dao_ack_input(void)
{
#if DEBUG
unsigned char *buffer;
uint8_t buffer_length;
uint8_t instance_id;
uint8_t sequence;
uint8_t status;
buffer = UIP_ICMP_PAYLOAD;
buffer_length = uip_len - uip_l3_icmp_hdr_len;
instance_id = buffer[0];
sequence = buffer[2];
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);
void rpl_free_dag(rpl_dag_t *);
void rpl_free_instance(rpl_instance_t *);
void rpl_purge_dags(void);
/* DAG parent management function. */
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
handle_periodic_timer(void *ptr)
{
rpl_purge_dags();
rpl_purge_routes();
rpl_recalculate_ranks();

View file

@ -300,6 +300,34 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
}
/*---------------------------------------------------------------------------*/
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)
{
uip_ipaddr_t rplmaddr;

View file

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

View file

@ -67,24 +67,14 @@
#define CC_FUNCTION_POINTER_ARGS 0
#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
*/
#ifdef CC_CONF_CONST_FUNCTION_BUG
#define CC_CONST_FUNCTION
#else /* CC_CONF_FASTCALL */
#else /* CC_CONF_CONST_FUNCTION_BUG */
#define CC_CONST_FUNCTION const
#endif /* CC_CONF_FASTCALL */
#endif /* CC_CONF_CONST_FUNCTION_BUG */
/**
* Configure work-around for unsigned char bugs with sdcc.
@ -123,6 +113,17 @@
#define CC_NO_VA_ARGS CC_CONF_VA_ARGS
#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
#define NULL 0
#endif /* NULL */

View file

@ -105,6 +105,21 @@ extern energest_t energest_leveldevice_current_leveltime[ENERGEST_CONF_LEVELDEVI
energest_current_time[type]); \
energest_current_mode[type] = 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
#define ENERGEST_OFF(type) if(energest_current_mode[type] != 0) do { \
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_mode[type] = 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 */
#define ENERGEST_ON(type) do { } while(0)
#define ENERGEST_OFF(type) 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_H_ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -35,7 +35,7 @@
#ifndef 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);
void ethernet_send(void);
void ethernet_exit(void);

View file

@ -139,10 +139,10 @@ ifndef NOAVRSIZE
avr-size -C --mcu=$(MCU) $@
endif
%.hex: %.out
%.hex: %.$(TARGET)
$(OBJCOPY) $^ -j .text -j .data -O ihex $@
%.ihex: %.out
%.ihex: %.$(TARGET)
$(OBJCOPY) $^ -O ihex $@
# Add a namelist to the kernel
@ -160,7 +160,7 @@ endif
#%.hex: %.elf
# $(OBJCOPY) -R .eeprom -R .fuse -R .signature $^ -O ihex $@
%.eep: %.out
%.eep: %.$(TARGET)
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--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 */
#if !defined (MCUCSR)
# if defined (MCUSR)
# warning *** MCUCSR not defined, using MCUSR instead ***
# define MCUCSR MCUSR
# endif
#endif

View file

@ -751,7 +751,8 @@ HAL_RF230_ISR()
#endif
#endif
} else if (interrupt_source & HAL_TRX_END_MASK){
}
if (interrupt_source & HAL_TRX_END_MASK){
INTERRUPTDEBUG(11);
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);
;
} else if (interrupt_source & HAL_PLL_UNLOCK_MASK){
}
if (interrupt_source & HAL_PLL_UNLOCK_MASK){
INTERRUPTDEBUG(14);
;
} else if (interrupt_source & HAL_PLL_LOCK_MASK){
}
if (interrupt_source & HAL_PLL_LOCK_MASK){
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 */
/* will continously be asserted while the supply voltage is less than the */
/* user-defined voltage threshold. */
@ -796,9 +801,6 @@ HAL_RF230_ISR()
hal_register_write(RG_IRQ_MASK, trx_isr_mask);
INTERRUPTDEBUG(16);
;
} else {
INTERRUPTDEBUG(99);
;
}
}
#endif /* defined(__AVR_ATmega128RFA1__) */

View file

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

View file

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

View file

@ -38,7 +38,6 @@
#endif
#define CC_CONF_FUNCTION_POINTER_ARGS 1
#define CC_CONF_FASTCALL
#define CC_CONF_VA_ARGS 1
#define CC_CONF_UNSIGNED_CHAR_BUGS 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
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
ifdef WERROR
CFLAGS += -Werror
endif
### Are we building with code size optimisations?
ifeq ($(SMALL),1)
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 += crypto.c aes.c ccm.c sha256.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 += slip-arch.c slip.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_ */
/**
* @}
* @}
*/

559
cpu/cc2538/dev/ecc-driver.c Normal file
View file

@ -0,0 +1,559 @@
/*
* 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
* @{
*
* \file
* Implementation of the cc2538 ECC driver
*/
#include "ecc-driver.h"
#include "reg.h"
#include "dev/nvic.h"
#define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; }
/*---------------------------------------------------------------------------*/
uint8_t
ecc_mul_start(uint32_t *scalar, ec_point_t *ec_point,
ecc_curve_info_t *curve, uint32_t *result_vector,
struct process *process)
{
uint8_t extraBuf;
uint32_t offset;
int i;
/* Check for the arguments. */
ASSERT(NULL != scalar);
ASSERT(NULL != ec_point);
ASSERT(NULL != ec_point->x);
ASSERT(NULL != ec_point->y);
ASSERT(NULL != curve);
ASSERT(curve->size <= PKA_MAX_CURVE_SIZE);
ASSERT(NULL != result_vector);
offset = 0;
/* Make sure no PKA operation is in progress. */
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Calculate the extra buffer requirement. */
extraBuf = 2 + curve->size % 2;
/* Update the A ptr with the offset address of the PKA RAM location
* where the scalar will be stored. */
REG(PKA_APTR) = offset >> 2;
/* Load the scalar in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++;
}
/* Determine the offset for the next data. */
offset += 4 * (i + (curve->size % 2));
/* Update the B ptr with the offset address of the PKA RAM location
* where the curve parameters will be stored. */
REG(PKA_BPTR) = offset >> 2;
/* Write curve parameter 'p' as 1st part of vector B immediately
* following vector A at PKA RAM */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
}
/* Determine the offset for the next data. */
offset += 4 * (i + extraBuf);
/* Copy curve parameter 'a' in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
}
/* Determine the offset for the next data. */
offset += 4 * (i + extraBuf);
/* Copy curve parameter 'b' in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i];
}
/* Determine the offset for the next data. */
offset += 4 * (i + extraBuf);
/* Update the C ptr with the offset address of the PKA RAM location
* where the x, y will be stored. */
REG(PKA_CPTR) = offset >> 2;
/* Write elliptic curve point.x co-ordinate value. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->x[i];
}
/* Determine the offset for the next data. */
offset += 4 * (i + extraBuf);
/* Write elliptic curve point.y co-ordinate value. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point->y[i];
}
/* Determine the offset for the next data. */
offset += 4 * (i + extraBuf);
/* Update the result location. */
*result_vector = PKA_RAM_BASE + offset;
/* Load D ptr with the result location in PKA RAM. */
REG(PKA_DPTR) = offset >> 2;
/* Load length registers. */
REG(PKA_ALENGTH) = curve->size;
REG(PKA_BLENGTH) = curve->size;
/* set the PKA function to ECC-MULT and start the operation. */
REG(PKA_FUNCTION) = 0x0000D000;
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
}
return PKA_STATUS_SUCCESS;
}
/*---------------------------------------------------------------------------*/
uint8_t
ecc_mul_get_result(ec_point_t *ec_point,
uint32_t result_vector)
{
int i;
uint32_t addr;
uint32_t regMSWVal;
uint32_t len;
/* Check for the arguments. */
ASSERT(NULL != ec_point);
ASSERT(NULL != ec_point->x);
ASSERT(NULL != ec_point->y);
ASSERT(result_vector > PKA_RAM_BASE);
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
/* Verify that the operation is completed. */
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {
/* Get the MSW register value. */
regMSWVal = REG(PKA_MSW);
/* Check to make sure that the result vector is not all zeroes. */
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
return PKA_STATUS_RESULT_0;
}
/* Get the length of the result */
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
- ((result_vector - PKA_RAM_BASE) >> 2);
addr = result_vector;
/* copy the x co-ordinate value of the result from vector D into
* the \e ec_point. */
for(i = 0; i < len; i++) {
ec_point->x[i] = REG(addr + 4 * i);
}
addr += 4 * (i + 2 + len % 2);
/* copy the y co-ordinate value of the result from vector D into
* the \e ec_point. */
for(i = 0; i < len; i++) {
ec_point->y[i] = REG(addr + 4 * i);
}
return PKA_STATUS_SUCCESS;
} else {
return PKA_STATUS_FAILURE;
}
}
/*---------------------------------------------------------------------------*/
uint8_t
ecc_mul_gen_pt_start(uint32_t *scalar, ecc_curve_info_t *curve,
uint32_t *result_vector, struct process *process)
{
uint8_t extraBuf;
uint32_t offset;
int i;
/* check for the arguments. */
ASSERT(NULL != scalar);
ASSERT(NULL != curve);
ASSERT(curve->size <= PKA_MAX_CURVE_SIZE);
ASSERT(NULL != result_vector);
offset = 0;
/* Make sure no operation is in progress. */
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Calculate the extra buffer requirement. */
extraBuf = 2 + curve->size % 2;
/* Update the A ptr with the offset address of the PKA RAM location
* where the scalar will be stored. */
REG(PKA_APTR) = offset >> 2;
/* Load the scalar in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = *scalar++;
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + (curve->size % 2));
/* Update the B ptr with the offset address of the PKA RAM location
* where the curve parameters will be stored. */
REG(PKA_BPTR) = offset >> 2;
/* Write curve parameter 'p' as 1st part of vector B. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Write curve parameter 'a' in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* write curve parameter 'b' in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->b[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Update the C ptr with the offset address of the PKA RAM location
* where the x, y will be stored. */
REG(PKA_CPTR) = offset >> 2;
/* Write x co-ordinate value of the Generator point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->x[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Write y co-ordinate value of the Generator point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->y[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Update the result location. */
*result_vector = PKA_RAM_BASE + offset;
/* Load D ptr with the result location in PKA RAM. */
REG(PKA_DPTR) = offset >> 2;
/* Load length registers. */
REG(PKA_ALENGTH) = curve->size;
REG(PKA_BLENGTH) = curve->size;
/* Set the PKA function to ECC-MULT and start the operation. */
REG(PKA_FUNCTION) = 0x0000D000;
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
}
return PKA_STATUS_SUCCESS;
}
/*---------------------------------------------------------------------------*/
uint8_t
ecc_mul_gen_pt_get_result(ec_point_t *ec_point,
uint32_t result_vector)
{
int i;
uint32_t regMSWVal;
uint32_t addr;
uint32_t len;
/* Check for the arguments. */
ASSERT(NULL != ec_point);
ASSERT(NULL != ec_point->x);
ASSERT(NULL != ec_point->y);
ASSERT(result_vector > PKA_RAM_BASE);
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
/* Verify that the operation is completed. */
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {
/* Get the MSW register value. */
regMSWVal = REG(PKA_MSW);
/* Check to make sure that the result vector is not all zeroes. */
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
return PKA_STATUS_RESULT_0;
}
/* Get the length of the result. */
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
- ((result_vector - PKA_RAM_BASE) >> 2);
addr = result_vector;
/* Copy the x co-ordinate value of the result from vector D into the
* EC point. */
for(i = 0; i < len; i++) {
ec_point->x[i] = REG(addr + 4 * i);
}
addr += 4 * (i + 2 + len % 2);
/* Copy the y co-ordinate value of the result from vector D into the
* EC point. */
for(i = 0; i < len; i++) {
ec_point->y[i] = REG(addr + 4 * i);
}
return PKA_STATUS_SUCCESS;
} else {
return PKA_STATUS_FAILURE;
}
}
/*---------------------------------------------------------------------------*/
uint8_t
ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2,
ecc_curve_info_t *curve, uint32_t *result_vector,
struct process *process)
{
uint8_t extraBuf;
uint32_t offset;
int i;
/* Check for the arguments. */
ASSERT(NULL != ec_point1);
ASSERT(NULL != ec_point1->x);
ASSERT(NULL != ec_point1->y);
ASSERT(NULL != ec_point2);
ASSERT(NULL != ec_point2->x);
ASSERT(NULL != ec_point2->y);
ASSERT(NULL != curve);
ASSERT(NULL != result_vector);
offset = 0;
/* Make sure no operation is in progress. */
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Calculate the extra buffer requirement. */
extraBuf = 2 + curve->size % 2;
/* Update the A ptr with the offset address of the PKA RAM location
* where the first ecPt will be stored. */
REG(PKA_APTR) = offset >> 2;
/* Load the x co-ordinate value of the first EC point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->x[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Load the y co-ordinate value of the first EC point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point1->y[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Update the B ptr with the offset address of the PKA RAM location
* where the curve parameters will be stored. */
REG(PKA_BPTR) = offset >> 2;
/* Write curve parameter 'p' as 1st part of vector B */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->prime[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Write curve parameter 'a'. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = (uint32_t)curve->a[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Update the C ptr with the offset address of the PKA RAM location
* where the ecPt2 will be stored. */
REG(PKA_CPTR) = offset >> 2;
/* Load the x co-ordinate value of the second EC point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->x[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Load the y co-ordinate value of the second EC point in PKA RAM. */
for(i = 0; i < curve->size; i++) {
REG(PKA_RAM_BASE + offset + 4 * i) = ec_point2->y[i];
}
/* Determine the offset in PKA RAM for the next data. */
offset += 4 * (i + extraBuf);
/* Copy the result vector location. */
*result_vector = PKA_RAM_BASE + offset;
/* Load D ptr with the result location in PKA RAM. */
REG(PKA_DPTR) = offset >> 2;
/* Load length registers. */
REG(PKA_BLENGTH) = curve->size;
/* Set the PKA Function to ECC-ADD and start the operation. */
REG(PKA_FUNCTION) = 0x0000B000;
/* Enable Interrupt */
if(process != NULL) {
pka_register_process_notification(process);
nvic_interrupt_unpend(NVIC_INT_PKA);
nvic_interrupt_enable(NVIC_INT_PKA);
}
return PKA_STATUS_SUCCESS;
}
/*---------------------------------------------------------------------------*/
uint8_t
ecc_add_get_result(ec_point_t *ec_point, uint32_t result_vector)
{
uint32_t regMSWVal;
uint32_t addr;
int i;
uint32_t len;
/* Check for the arguments. */
ASSERT(NULL != ec_point);
ASSERT(NULL != ec_point->x);
ASSERT(NULL != ec_point->y);
ASSERT(result_vector > PKA_RAM_BASE);
ASSERT(result_vector < (PKA_RAM_BASE + PKA_RAM_SIZE));
if((REG(PKA_FUNCTION) & PKA_FUNCTION_RUN) != 0) {
return PKA_STATUS_OPERATION_INPRG;
}
/* Disable Interrupt */
nvic_interrupt_disable(NVIC_INT_PKA);
pka_register_process_notification(NULL);
if(REG(PKA_SHIFT) == 0x00000000) {
/* Get the MSW register value. */
regMSWVal = REG(PKA_MSW);
/* Check to make sure that the result vector is not all zeroes. */
if(regMSWVal & PKA_MSW_RESULT_IS_ZERO) {
return PKA_STATUS_RESULT_0;
}
/* Get the length of the result. */
len = ((regMSWVal & PKA_MSW_MSW_ADDRESS_M) + 1)
- ((result_vector - PKA_RAM_BASE) >> 2);
addr = result_vector;
/* Copy the x co-ordinate value of result from vector D into the
* the output EC Point. */
for(i = 0; i < len; i++) {
ec_point->x[i] = REG(addr + 4 * i);
}
addr += 4 * (i + 2 + len % 2);
/* Copy the y co-ordinate value of result from vector D into the
* the output EC Point. */
for(i = 0; i < len; i++) {
ec_point->y[i] = REG(addr + 4 * i);
}
return PKA_STATUS_SUCCESS;
} else {
return PKA_STATUS_FAILURE;
}
}
/** @} */

227
cpu/cc2538/dev/ecc-driver.h Normal file
View file

@ -0,0 +1,227 @@
/*
* 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-pka
* @{
*
* \defgroup cc2538-ecc cc2538 ECC driver
*
* Driver for the cc2538 ECC mode of the PKC engine
* @{
*
* \file
* Header file for the cc2538 ECC driver
*/
#ifndef ECC_DRIVER_H_
#define ECC_DRIVER_H_
#include "contiki.h"
#include "pka.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \name ECC structures
* @{
*/
typedef struct {
const char *name; /**< Name of the curve. */
const uint8_t size; /**< Size of the curve in 32-bit word. */
const uint32_t *prime; /**< The prime that defines the field of the curve. */
const uint32_t *n; /**< Order of the curve. */
const uint32_t *a; /**< Co-efficient a of the equation. */
const uint32_t *b; /**< co-efficient b of the equation. */
const uint32_t *x; /**< x co-ordinate value of the generator point. */
const uint32_t *y; /**< y co-ordinate value of the generator point. */
} ecc_curve_info_t;
typedef struct {
uint32_t x[12]; /**< Pointer to value of the x co-ordinate. */
uint32_t y[12]; /**< Pointer to value of the y co-ordinate. */
} ec_point_t;
/** @} */
/*---------------------------------------------------------------------------*/
/** \name ECC functions
* \note Not all sequencer functions are implemented in this driver
* look at the CC2538 manual for a complete list.
* @{
*/
/** \brief Starts ECC Multiplication.
*
* \param scalar Pointer to the buffer containing the scalar
* value to be multiplied.
* \param ec_point Pointer to the structure containing the
* elliptic curve point to be multiplied. The point should be
* on the given curve.
* \param curve Pointer to the structure containing the curve
* info.
* \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 Elliptical curve cryptography (ECC) point
* multiplication operation on the EC point and the scalar value.
*
* \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 ecc_mul_start(uint32_t *scalar,
ec_point_t *ec_point,
ecc_curve_info_t *curve,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of ECC Multiplication
*
* \param ec_point Pointer to the structure where the resultant EC
* point will be stored. The callee is responsible to allocate the
* space for the ec point structure and the x and y co-ordinate as well.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKAECCMultiplyStart().
*
* This function gets the result of ecc point multiplication operation on the
* ec point and the scalar value, previously started using the function
* \sa PKAECCMultiplyStart().
*
* \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 ecc_mul_get_result(ec_point_t *ec_point,
uint32_t result_vector);
/** \brief Starts the ECC Multiplication with Generator point.
*
* \param scalar Pointer to the buffer containing the
* scalar value.
* \param curve Pointer to the structure containing the curve
* info.
* \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 ecc point multiplication operation of the
* scalar value with the well known generator point of the given curve.
*
* \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 ecc_mul_gen_pt_start(uint32_t *scalar,
ecc_curve_info_t *curve,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of ECC Multiplication with Generator point.
*
* \param ec_point Pointer to the structure where the resultant EC
* point will be stored. The callee is responsible to allocate the
* space for the ec point structure and the x and y co-ordinate as well.
* \param result_vector Address of the result location which
* was provided by the start function \sa PKAECCMultGenPtStart().
*
* This function gets the result of ecc point multiplication operation on the
* scalar point and the known generator point on the curve, previously started
* using the function \sa PKAECCMultGenPtStart().
*
* \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 ecc_mul_gen_pt_get_result(ec_point_t *ec_point,
uint32_t result_vector);
/** \brief Starts the ECC Addition.
*
* \param ec_point1 Pointer to the structure containing the first
* ecc point.
* \param ec_point2 Pointer to the structure containing the
* second ecc point.
* \param curve Pointer to the structure containing the curve
* info.
* \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 ecc point addition operation on the
* two given ec points and generates the resultant ecc point.
*
* \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 ecc_add_start(ec_point_t *ec_point1, ec_point_t *ec_point2,
ecc_curve_info_t *curve,
uint32_t *result_vector,
struct process *process);
/** \brief Gets the result of the ECC Addition
*
* \param ptOutEcPt Pointer to the structure where the resultant
* point will be stored. The callee is responsible to allocate memory,
* for the ec point structure including the memory for x and y
* co-ordinate values.
* \param ui32ResultLoc Address of the result location which
* was provided by the function \sa PKAECCAddStart().
*
* This function gets the result of ecc point addition operation on the
* on the two given ec points, previously started using the function \sa
* PKAECCAddStart().
*
* \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 ecc_add_get_result(ec_point_t *ptOutEcPt, uint32_t ui32ResultLoc);
/** @} */
#endif /* ECC_DRIVER_H_ */
/**
* @}
* @}
*/

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