Merge with updated master.
This commit is contained in:
commit
41f9ca08e2
14
.gitattributes
vendored
Normal file
14
.gitattributes
vendored
Normal 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
2
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
*.png
|
||||
*.log
|
||||
*.elf
|
||||
*.zip
|
||||
*.d
|
||||
*.ihex
|
||||
*.pyc
|
||||
|
@ -24,6 +25,7 @@
|
|||
*.c64
|
||||
*.cc2538dk
|
||||
*.remote
|
||||
*.jn516x
|
||||
*.srf06-cc26xx
|
||||
*.ev-aducrf101mkxz
|
||||
*.report
|
||||
|
|
18
.travis.yml
18
.travis.yml
|
@ -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'
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 = δ
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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; \
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#define HAVE_ALLOCA 0
|
||||
#else
|
||||
#define HAVE_ALLOCA 1
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG 0
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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, "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 ");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -273,7 +273,6 @@ parse(void)
|
|||
const struct framer framer_802154 = {
|
||||
hdr_length,
|
||||
create,
|
||||
framer_canonical_create_and_secure,
|
||||
parse
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -99,6 +99,5 @@ parse(void)
|
|||
const struct framer framer_nullmac = {
|
||||
hdr_length,
|
||||
create,
|
||||
framer_canonical_create_and_secure,
|
||||
parse
|
||||
};
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
p->rank = dio->rank;
|
||||
|
||||
/* Parent info has been updated, trigger rank recalculation */
|
||||
p->flags |= RPL_PARENT_FLAG_UPDATED;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 $^ $@
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
1064
cpu/cc2538/dev/bignum-driver.c
Normal file
1064
cpu/cc2538/dev/bignum-driver.c
Normal file
File diff suppressed because it is too large
Load diff
462
cpu/cc2538/dev/bignum-driver.h
Normal file
462
cpu/cc2538/dev/bignum-driver.h
Normal 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_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
200
cpu/cc2538/dev/ecc-algorithm.c
Normal file
200
cpu/cc2538/dev/ecc-algorithm.c
Normal 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
178
cpu/cc2538/dev/ecc-algorithm.h
Normal file
178
cpu/cc2538/dev/ecc-algorithm.h
Normal 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_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
91
cpu/cc2538/dev/ecc-curve.c
Normal file
91
cpu/cc2538/dev/ecc-curve.c
Normal 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
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
65
cpu/cc2538/dev/ecc-curve.h
Normal file
65
cpu/cc2538/dev/ecc-curve.h
Normal 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
559
cpu/cc2538/dev/ecc-driver.c
Normal 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
227
cpu/cc2538/dev/ecc-driver.h
Normal 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
Loading…
Reference in a new issue