Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Oliver Schmidt 2015-10-10 18:01:14 +02:00
commit fa9c25cdf5
278 changed files with 18909 additions and 1175 deletions

1
.gitignore vendored
View file

@ -25,6 +25,7 @@
*.c64
*.cc2538dk
*.remote
*.jn516x
*.srf06-cc26xx
*.ev-aducrf101mkxz
*.report

View file

@ -17,7 +17,7 @@ before_script:
## Install msp430 toolchain
- sudo apt-get -qq install lib32z1
- $WGET http://adamdunkels.github.io/contiki-fork/mspgcc-4.7.0-compiled.tar.bz2 &&
- $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 &&
tar xjf mspgcc*.tar.bz2 -C /tmp/ &&
sudo cp -f -r /tmp/msp430/* /usr/local/ &&
rm -rf /tmp/msp430 mspgcc*.tar.bz2 &&
@ -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 &&
@ -103,6 +120,7 @@ env:
- BUILD_TYPE='collect'
- BUILD_TYPE='collect-lossy'
- BUILD_TYPE='rpl'
- BUILD_TYPE='large-rpl'
- BUILD_TYPE='rime'
- BUILD_TYPE='ipv6'
- BUILD_TYPE='ip64' MAKE_TARGETS='cooja'
@ -119,5 +137,6 @@ env:
- BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs'
- BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502'
- BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-aapcs'
- BUILD_TYPE='compile-nxp-ports' BUILD_CATEGORY='compile' BUILD_ARCH='jn516x'
- BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja'
- BUILD_TYPE='llsec' MAKE_TARGETS='cooja'

View file

@ -136,7 +136,7 @@ Contiki maintainers to look at!
All code contributions to Contiki are submitted as [Github pull
requests](https://help.github.com/articles/using-pull-requests). Pull
requests will be reviewed and accepted according to the guidelines
found in the [[Pull Request Policy]]
found in the next section.
The basic guidelines to to start a Pull-Request:
* Create a new branch for your modifications. This branch should be based on the latest contiki master branch.
@ -183,6 +183,21 @@ $ git push origin my_new_feature -f
```
* NOTE: To avoid all the pain of selectively picking commits, rebasing and force-pushing - begin your development with a branch OTHER THAN your master branch, and push changes to that branch after any local commits.
Pull Request Merging Policy
---------------------------
Pull requests (PRs) are reviewed by the [merge team](https://github.com/orgs/contiki-os/people).
Generally, PRs require two "+1" before they can be merged by someone on the merge team.
The since Contiki 3.0, the merging policy is the following:
* The PR receives **one "-1"** from a merge team member (along with specific feedback). The PR is closed. A "-1" must be accompanied with a clear explanation why the PR will not be considered for inclusion.
* The PR receives **two "+1"** from merge team members. The PR is merged.
* The PR was inactive for **two months**. A team member may either:
* Comment "Is there any interest for this PR? Is there any work pending on it? If not I will close it in **one month**." Back to initial state in case of activity, close otherwise.
* Comment "I approve this PR. If nobody disapproves within **one month**, I will merge it." Back to initial state in case of activity, merge otherwise.
There is an exception to the rule.
Code that requires esoteric expertise such as some applications, platforms or tools can be merged after a single "+1" from its domain expert.
Travis / Regression testing
---------------------------

View file

@ -0,0 +1,10 @@
codeprop-tmp_src = codeprop-tmp.c
# Enable LARGE MEMORY MODEL supports for WISMOTE and EXP5438 platform
ifeq ($(TARGET),wismote)
TARGET_MEMORY_MODEL = large
endif
ifeq ($(TARGET),exp5438)
TARGET_MEMORY_MODEL = large
endif

View file

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

View file

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

View file

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

View file

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

View file

@ -113,19 +113,21 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
/* avoids code duplication without function overhead */
unsigned int *x = &delta;
if(delta > 268) {
buffer[++written] = ((delta - 269) >> 8) & 0xff;
buffer[++written] = (delta - 269) & 0xff;
} else if(delta > 12) {
buffer[++written] = (delta - 13);
}
do {
if(*x > 268) {
buffer[++written] = (*x - 269) >> 8;
buffer[++written] = (*x - 269);
} else if(*x > 12) {
buffer[++written] = (*x - 13);
}
} while(x != &length && (x = &length));
if(length > 268) {
buffer[++written] = ((length - 269) >> 8) & 0xff;
buffer[++written] = (length - 269) & 0xff;
} else if(length > 12) {
buffer[++written] = (length - 13);
}
PRINTF("WRITTEN %u B opt header\n", 1 + written);
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],
@ -500,25 +504,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;
if(option_delta == 13) {
option_delta += current_option[0];
++current_option;
} else if(option_delta == 14) {
option_delta += 255;
option_delta += current_option[0] << 8;
++current_option;
option_delta += current_option[0];
++current_option;
}
do {
if(*x == 13) {
*x += current_option[0];
++current_option;
} else if(*x == 14) {
*x += 255;
*x += current_option[0] << 8;
++current_option;
*x += current_option[0];
++current_option;
}
} while(x != &option_length && (x = &option_length));
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;
}
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 +542,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 +579,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 +590,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 +598,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 +611,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 +627,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 +635,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 +652,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 +664,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 +757,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 +778,7 @@ coap_set_header_accept(void *packet, unsigned int accept)
{
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
coap_pkt->accept = (coap_content_format_t)accept;
coap_pkt->accept = accept;
SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
return 1;
}

View file

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

View file

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

View file

@ -293,7 +293,7 @@ PROCESS_THREAD(slip_process, ev, data)
tcpip_input();
#endif
} else {
uip_len = 0;
uip_clear_buf();
SLIP_STATISTICS(slip_ip_drop++);
}
#else /* NETSTACK_CONF_WITH_IPV6 */

View file

@ -71,12 +71,8 @@ static uint8_t round_keys[11][AES_128_KEY_LENGTH];
static uint8_t
galois_mul2(uint8_t value)
{
if(value >> 7) {
value = value << 1;
return value ^ 0x1b;
} else {
return value << 1;
}
uint8_t xor_val = (value >> 7) * 0x1b;
return ((value << 1) ^ xor_val);
}
/*---------------------------------------------------------------------------*/
static void

View file

@ -114,7 +114,6 @@ mic(const uint8_t *m, uint8_t m_len,
}
if(m_len > 0) {
m = a + a_len;
pos = 0;
while(pos < m_len) {
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {

View file

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

View file

@ -0,0 +1,810 @@
/*
* Copyright (c) 2015, Indian Institute of Science
* 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
* MSP430x elfloader.
* \author
* Sumankumar Panchal <suman@ece.iisc.ernet.in>
*
*/
#include "contiki.h"
#include "loader/elfloader.h"
#include "loader/elfloader-arch.h"
#include "cfs/cfs.h"
#include "loader/symtab.h"
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "dev/flash.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) do {} while(0)
#endif
#define EI_NIDENT 16
struct elf32_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ident bytes */
elf32_half e_type; /* file type */
elf32_half e_machine; /* target machine */
elf32_word e_version; /* file version */
elf32_addr e_entry; /* start address */
elf32_off e_phoff; /* phdr file offset */
elf32_off e_shoff; /* shdr file offset */
elf32_word e_flags; /* file flags */
elf32_half e_ehsize; /* sizeof ehdr */
elf32_half e_phentsize; /* sizeof phdr */
elf32_half e_phnum; /* number phdrs */
elf32_half e_shentsize; /* sizeof shdr */
elf32_half e_shnum; /* number shdrs */
elf32_half e_shstrndx; /* shdr string index */
};
/* Values for e_type. */
#define ET_NONE 0 /* Unknown type. */
#define ET_REL 1 /* Relocatable. */
#define ET_EXEC 2 /* Executable. */
#define ET_DYN 3 /* Shared object. */
#define ET_CORE 4 /* Core file. */
struct elf32_shdr {
elf32_word sh_name; /* section name */
elf32_word sh_type; /* SHT_... */
elf32_word sh_flags; /* SHF_... */
elf32_addr sh_addr; /* virtual address */
elf32_off sh_offset; /* file offset */
elf32_word sh_size; /* section size */
elf32_word sh_link; /* misc info */
elf32_word sh_info; /* misc info */
elf32_word sh_addralign; /* memory alignment */
elf32_word sh_entsize; /* entry size if table */
};
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
struct elf32_rel {
elf32_addr r_offset; /* Location to be relocated. */
elf32_word r_info; /* Relocation type and symbol index. */
};
struct elf32_sym {
elf32_word st_name; /* String table index of name. */
elf32_addr st_value; /* Symbol value. */
elf32_word st_size; /* Size of associated object. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
elf32_half st_shndx; /* Section index of symbol. */
};
#define ELF32_R_SYM(info) ((info) >> 8)
struct relevant_section {
unsigned char number;
unsigned int offset;
char *address;
};
char elfloader_unknown[30]; /* Name that caused link error. */
struct process *const *elfloader_autostart_processes;
static struct relevant_section bss, data, rodata, rodatafar, text, textfar;
static const unsigned char elf_magic_header[] =
{ 0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */
0x01, /* Only 32-bit objects. */
0x01, /* Only LSB data. */
0x01, /* Only ELF version 1. */
};
/* relocation type */
#define R_MSP430_NONE 0
#define R_MSP430_32 1
#define R_MSP430_10_PCREL 2
#define R_MSP430_16 3
#define R_MSP430_16_PCREL 4
#define R_MSP430_16_BYTE 5
#define R_MSP430_16_PCREL_BYTE 6
#define R_MSP430_2X_PCREL 7
#define R_MSP430_RL_PCREL 8
#define R_MSP430X_SRC_BYTE 9
#define R_MSP430X_SRC 10
#define R_MSP430X_DST_BYTE 11
#define R_MSP430X_DST 12
#define R_MSP430X_DST_2ND_BYTE 13
#define R_MSP430X_DST_2ND 14
#define R_MSP430X_PCREL_SRC_BYTE 15
#define R_MSP430X_PCREL_SRC 16
#define R_MSP430X_PCREL_DST_BYTE 17
#define R_MSP430X_PCREL_DST 18
#define R_MSP430X_PCREL_DST_2ND 19
#define R_MSP430X_PCREL_DST_2ND_BYTE 20
#define R_MSP430X_S_BYTE 21
#define R_MSP430X_S 22
#define R_MSP430X_D_BYTE 23
#define R_MSP430X_D 24
#define R_MSP430X_PCREL_D 25
#define R_MSP430X_INDXD 26
#define R_MSP430X_PCREL_INDXD 27
#define R_MSP430_10 28
#define ELF32_R_TYPE(info) ((unsigned char)(info))
static uint16_t datamemory_aligned[ELFLOADER_DATAMEMORY_SIZE / 2 + 1];
static uint8_t *datamemory = (uint8_t *)datamemory_aligned;
#if ELFLOADER_CONF_TEXT_IN_ROM
static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = { 0 };
#else /* ELFLOADER_CONF_TEXT_IN_ROM */
static char textmemory[ELFLOADER_TEXTMEMORY_SIZE];
#endif /* ELFLOADER_CONF_TEXT_IN_ROM */
/*---------------------------------------------------------------------------*/
static void
seek_read(int fd, unsigned int offset, char *buf, int len)
{
cfs_seek(fd, offset, CFS_SEEK_SET);
cfs_read(fd, buf, len);
#if DEBUG
{
int i;
PRINTF("seek_read: Read len %d from offset %d\n",
len, offset);
for(i = 0; i < len; ++i) {
PRINTF("%02x ", buf[i]);
}
printf("\n");
}
#endif /* DEBUG */
}
/*---------------------------------------------------------------------------*/
static void *
find_local_symbol(int fd, const char *symbol,
unsigned int symtab, unsigned short symtabsize,
unsigned int strtab)
{
struct elf32_sym s;
unsigned int a;
char name[30];
struct relevant_section *sect;
for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) {
seek_read(fd, a, (char *)&s, sizeof(s));
if(s.st_name != 0) {
seek_read(fd, strtab + s.st_name, name, sizeof(name));
if(strcmp(name, symbol) == 0) {
if(s.st_shndx == bss.number) {
sect = &bss;
} else if(s.st_shndx == data.number) {
sect = &data;
} else if(s.st_shndx == rodatafar.number) {
sect = &rodatafar;
} else if(s.st_shndx == textfar.number) {
sect = &textfar;
} else {
return NULL;
}
return &(sect->address[s.st_value]);
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
static int
relocate_section(int fd,
unsigned int section, unsigned short size,
unsigned int sectionaddr,
char *sectionbase,
unsigned int strs,
unsigned int strtab,
unsigned int symtab, unsigned short symtabsize,
unsigned char using_relas)
{
/*
* sectionbase added; runtime start address of current section
*/
struct elf32_rela rela; /* Now used both for rel and rela data! */
int rel_size = 0;
struct elf32_sym s;
unsigned int a;
char name[30];
char *addr;
struct relevant_section *sect;
/* determine correct relocation entry sizes */
if(using_relas) {
rel_size = sizeof(struct elf32_rela);
} else {
rel_size = sizeof(struct elf32_rel);
}
for(a = section; a < section + size; a += rel_size) {
seek_read(fd, a, (char *)&rela, rel_size);
seek_read(fd,
symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info),
(char *)&s, sizeof(s));
if(s.st_name != 0) {
seek_read(fd, strtab + s.st_name, name, sizeof(name));
PRINTF("name: %s\n", name);
addr = (char *)symtab_lookup(name);
if(addr == NULL) {
PRINTF("name not found in global: %s\n", name);
addr = find_local_symbol(fd, name, symtab, symtabsize, strtab);
PRINTF("found address %p\n", addr);
}
if(addr == NULL) {
if(s.st_shndx == bss.number) {
sect = &bss;
} else if(s.st_shndx == data.number) {
sect = &data;
} else if(s.st_shndx == rodatafar.number) {
sect = &rodatafar;
} else if(s.st_shndx == textfar.number) {
sect = &textfar;
} else {
PRINTF("elfloader unknown name: '%30s'\n", name);
memcpy(elfloader_unknown, name, sizeof(elfloader_unknown));
elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0;
return ELFLOADER_SYMBOL_NOT_FOUND;
}
addr = sect->address;
}
} else {
if(s.st_shndx == bss.number) {
sect = &bss;
} else if(s.st_shndx == data.number) {
sect = &data;
} else if(s.st_shndx == rodatafar.number) {
sect = &rodatafar;
} else if(s.st_shndx == textfar.number) {
sect = &textfar;
} else {
return ELFLOADER_SEGMENT_NOT_FOUND;
}
addr = sect->address;
}
if(!using_relas) {
/* copy addend to rela structure */
seek_read(fd, sectionaddr + rela.r_offset, (char *)&rela.r_addend, 4);
}
elfloader_arch_relocate(fd, sectionaddr, sectionbase, &rela, addr);
}
return ELFLOADER_OK;
}
/*---------------------------------------------------------------------------*/
static void *
find_program_processes(int fd,
unsigned int symtab, unsigned short size,
unsigned int strtab)
{
struct elf32_sym s;
unsigned int a;
char name[30];
for(a = symtab; a < symtab + size; a += sizeof(s)) {
seek_read(fd, a, (char *)&s, sizeof(s));
if(s.st_name != 0) {
seek_read(fd, strtab + s.st_name, name, sizeof(name));
if(strcmp(name, "autostart_processes") == 0) {
return &data.address[s.st_value];
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
elfloader_init(void)
{
elfloader_autostart_processes = NULL;
}
/*---------------------------------------------------------------------------*/
int
elfloader_load(int fd)
{
struct elf32_ehdr ehdr;
struct elf32_shdr shdr;
struct elf32_shdr strtable;
unsigned int strs;
unsigned int shdrptr;
unsigned int nameptr;
char name[17];
int i;
unsigned short shdrnum, shdrsize;
unsigned char using_relas = -1;
unsigned short textoff = 0, textfaroff = 0, textsize, textfarsize,
textrelaoff = 0, textrelasize, textfarrelaoff = 0, textfarrelasize;
unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize;
unsigned short rodataoff = 0, rodatafaroff = 0, rodatasize, rodatafarsize,
rodatarelaoff = 0, rodatarelasize, rodatafarrelaoff = 0,
rodatafarrelasize;
unsigned short symtaboff = 0, symtabsize;
unsigned short strtaboff = 0, strtabsize;
unsigned short bsssize = 0;
struct process **process;
int ret;
elfloader_unknown[0] = 0;
/* The ELF header is located at the start of the buffer. */
seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr));
/* Make sure that we have a correct and compatible ELF header. */
if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
PRINTF("ELF header problems\n");
return ELFLOADER_BAD_ELF_HEADER;
}
/* Grab the section header. */
shdrptr = ehdr.e_shoff;
seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr));
/* Get the size and number of entries of the section header. */
shdrsize = ehdr.e_shentsize;
shdrnum = ehdr.e_shnum;
PRINTF("Section header: size %d num %d\n", shdrsize, shdrnum);
/* The string table section: holds the names of the sections. */
seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
(char *)&strtable, sizeof(strtable));
/*
* Get a pointer to the actual table of strings. This table holds
* the names of the sections, not the names of other symbols in the
* file (these are in the sybtam section).
*/
strs = strtable.sh_offset;
PRINTF("Strtable offset %d\n", strs);
/*
* Go through all sections and pick out the relevant ones. The
* ".text" and ".far.text" segments holds the actual code from
* the ELF file. The ".data" segment contains initialized data.
* The ".bss" segment holds the size of the unitialized data segment.
* The ".rodata" and ".far.rodata" segments contains constant data.
* The ".rela[a].text" and ".rela[a].far.text" segments contains
* relocation information for the contents of the ".text" and
* ".far.text" segments, respectively. The ".rela[a].rodata" and
* ".rela[a].far.rodata" segments contains relocation information
* for the contents of the ".rodata" and ".far.rodata" segments,
* respectively. The ".rela[a].data" segment contains relocation
* information for the contents of the ".data" segment. The ".symtab"
* segment contains the symbol table for this file. The ".strtab"
* segment points to the actual string names used by the symbol table.
*
* In addition to grabbing pointers to the relevant sections, we
* also save the section number for resolving addresses in the
* relocator code.
*/
/*
* Initialize the segment sizes to zero so that we can check if
* their sections was found in the file or not.
*/
textsize = textfarsize = textrelasize = textfarrelasize =
datasize = datarelasize = rodatasize = rodatafarsize =
rodatarelasize = rodatafarrelasize = symtabsize = strtabsize = 0;
bss.number = data.number = rodata.number = rodatafar.number =
text.number = textfar.number = -1;
shdrptr = ehdr.e_shoff;
for(i = 0; i < shdrnum; ++i) {
seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr));
/* The name of the section is contained in the strings table. */
nameptr = strs + shdr.sh_name;
seek_read(fd, nameptr, name, sizeof(name));
PRINTF("Section shdrptr 0x%x, %d + %d type %d\n",
shdrptr,
strs, shdr.sh_name,
(int)shdr.sh_type);
/*
* Match the name of the section with a predefined set of names
* (.text, .far.text, .data, .bss, .rodata, .far.rodata, .rela.text, .rela.far.text,
* .rela.data, .rela.rodata, .rela.far.rodata, .symtab, and .strtab).
*/
if(shdr.sh_type == SHT_SYMTAB) {
PRINTF("symtab\n");
symtaboff = shdr.sh_offset;
symtabsize = shdr.sh_size;
} else if(shdr.sh_type == SHT_STRTAB) {
PRINTF("strtab\n");
strtaboff = shdr.sh_offset;
strtabsize = shdr.sh_size;
} else if(strncmp(name, ".text", 5) == 0) {
textoff = shdr.sh_offset;
textsize = shdr.sh_size;
text.number = i;
text.offset = textoff;
} else if(strncmp(name, ".far.text", 9) == 0) {
textfaroff = shdr.sh_offset;
textfarsize = shdr.sh_size;
textfar.number = i;
textfar.offset = textfaroff;
} else if(strncmp(name, ".rel.text", 9) == 0) {
using_relas = 0;
textrelaoff = shdr.sh_offset;
textrelasize = shdr.sh_size;
} else if(strncmp(name, ".rela.text", 10) == 0) {
using_relas = 1;
textrelaoff = shdr.sh_offset;
textrelasize = shdr.sh_size;
} else if(strncmp(name, ".rela.far.text", 14) == 0) {
using_relas = 1;
textfarrelaoff = shdr.sh_offset;
textfarrelasize = shdr.sh_size;
} else if(strncmp(name, ".data", 5) == 0) {
dataoff = shdr.sh_offset;
datasize = shdr.sh_size;
data.number = i;
data.offset = dataoff;
} else if(strncmp(name, ".rodata", 7) == 0) {
/* read-only data handled the same way as regular text section */
rodataoff = shdr.sh_offset;
rodatasize = shdr.sh_size;
rodata.number = i;
rodata.offset = rodataoff;
} else if(strncmp(name, ".far.rodata", 11) == 0) {
rodatafaroff = shdr.sh_offset;
rodatafarsize = shdr.sh_size;
rodatafar.number = i;
rodatafar.offset = rodataoff;
} else if(strncmp(name, ".rel.rodata", 11) == 0) {
/* using elf32_rel instead of rela */
using_relas = 0;
rodatarelaoff = shdr.sh_offset;
rodatarelasize = shdr.sh_size;
} else if(strncmp(name, ".rela.rodata", 12) == 0) {
using_relas = 1;
rodatarelaoff = shdr.sh_offset;
rodatarelasize = shdr.sh_size;
} else if(strncmp(name, ".rela.far.rodata", 16) == 0) {
using_relas = 1;
rodatafarrelaoff = shdr.sh_offset;
rodatafarrelasize = shdr.sh_size;
} else if(strncmp(name, ".rel.data", 9) == 0) {
/* using elf32_rel instead of rela */
using_relas = 0;
datarelaoff = shdr.sh_offset;
datarelasize = shdr.sh_size;
} else if(strncmp(name, ".rela.data", 10) == 0) {
using_relas = 1;
datarelaoff = shdr.sh_offset;
datarelasize = shdr.sh_size;
} else if(strncmp(name, ".bss", 4) == 0) {
bsssize = shdr.sh_size;
bss.number = i;
bss.offset = 0;
}
/* Move on to the next section header. */
shdrptr += shdrsize;
}
if(symtabsize == 0) {
return ELFLOADER_NO_SYMTAB;
}
if(strtabsize == 0) {
return ELFLOADER_NO_STRTAB;
}
if(textfarsize == 0) {
return ELFLOADER_NO_TEXT;
}
PRINTF("before allocate ram\n");
bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize);
data.address = (char *)bss.address + bsssize;
PRINTF("before allocate rom\n");
textfar.address = (char *)elfloader_arch_allocate_rom(textfarsize + rodatafarsize);
rodatafar.address = (char *)textfar.address + textfarsize;
PRINTF("bss base address: bss.address = 0x%08x\n", bss.address);
PRINTF("data base address: data.address = 0x%08x\n", data.address);
PRINTF("textfar base address: textfar.address = 0x%08x\n", textfar.address);
PRINTF("rodatafar base address: rodatafar.address = 0x%08x\n", rodatafar.address);
/* If we have text segment relocations, we process them. */
PRINTF("elfloader: relocate textfar\n");
if(textfarrelasize > 0) {
ret = relocate_section(fd,
textfarrelaoff, textfarrelasize,
textfaroff,
textfar.address,
strs,
strtaboff,
symtaboff, symtabsize, using_relas);
if(ret != ELFLOADER_OK) {
return ret;
}
}
/* If we have any rodata segment relocations, we process them too. */
PRINTF("elfloader: relocate rodata\n");
if(rodatafarrelasize > 0) {
ret = relocate_section(fd,
rodatafarrelaoff, rodatafarrelasize,
rodatafaroff,
rodatafar.address,
strs,
strtaboff,
symtaboff, symtabsize, using_relas);
if(ret != ELFLOADER_OK) {
PRINTF("elfloader: data failed\n");
return ret;
}
}
/* If we have any data segment relocations, we process them too. */
PRINTF("elfloader: relocate data\n");
if(datarelasize > 0) {
ret = relocate_section(fd,
datarelaoff, datarelasize,
dataoff,
data.address,
strs,
strtaboff,
symtaboff, symtabsize, using_relas);
if(ret != ELFLOADER_OK) {
PRINTF("elfloader: data failed\n");
return ret;
}
}
/* Write text and rodata segment into flash and data segment into RAM. */
elfloader_arch_write_rom(fd, textfaroff, textfarsize, textfar.address);
elfloader_arch_write_rom(fd, rodatafaroff, rodatafarsize, rodatafar.address);
memset(bss.address, 0, bsssize);
seek_read(fd, dataoff, data.address, datasize);
PRINTF("elfloader: autostart search\n");
process = (struct process **)find_local_symbol(fd, "autostart_processes",
symtaboff, symtabsize, strtaboff);
if(process != NULL) {
PRINTF("elfloader: autostart found\n");
elfloader_autostart_processes = process;
return ELFLOADER_OK;
} else {
PRINTF("elfloader: no autostart\n");
process = (struct process **)find_program_processes(fd, symtaboff,
symtabsize, strtaboff);
if(process != NULL) {
PRINTF("elfloader: FOUND PRG\n");
}
return ELFLOADER_NO_STARTPOINT;
}
}
/*---------------------------------------------------------------------------*/
void *
elfloader_arch_allocate_ram(int size)
{
return datamemory;
}
/*---------------------------------------------------------------------------*/
void *
elfloader_arch_allocate_rom(int size)
{
#if ELFLOADER_CONF_TEXT_IN_ROM
/* Return an 512-byte aligned pointer. */
return (char *)
((unsigned long)&textmemory[0] & 0xfffffe00) +
(((unsigned long)&textmemory[0] & 0x1ff) == 0 ? 0 : 0x200);
#else /* ELFLOADER_CONF_TEXT_IN_ROM */
return textmemory;
#endif /* ELFLOADER_CONF_TEXT_IN_ROM */
}
/*---------------------------------------------------------------------------*/
#define READSIZE 32
void
elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem)
{
#if ELFLOADER_CONF_TEXT_IN_ROM
int i;
unsigned int ptr;
unsigned short *flashptr;
flash_setup();
flashptr = (unsigned short *)mem;
cfs_seek(fd, textoff, CFS_SEEK_SET);
for(ptr = 0; ptr < size; ptr += READSIZE) {
/* Read data from file into RAM. */
cfs_read(fd, (unsigned char *)datamemory, READSIZE);
/* Clear flash page on 512 byte boundary. */
if((((unsigned short)flashptr) & 0x01ff) == 0) {
flash_clear(flashptr);
}
/*
* Burn data from RAM into flash ROM. Flash is burned one 16-bit
* word at a time, so we need to be careful when incrementing
* pointers. The flashptr is already a short pointer, so
* incrementing it by one will actually increment the address by
* two.
*/
for(i = 0; i < READSIZE / 2; ++i) {
flash_write(flashptr, ((unsigned short *)datamemory)[i]);
++flashptr;
}
}
flash_done();
#else /* ELFLOADER_CONF_TEXT_IN_ROM */
cfs_seek(fd, textoff, CFS_SEEK_SET);
cfs_read(fd, (unsigned char *)mem, size);
#endif /* ELFLOADER_CONF_TEXT_IN_ROM */
}
/*---------------------------------------------------------------------------*/
/* Relocate an MSP430X ELF section. */
void
elfloader_arch_relocate(int fd, unsigned int sectionoffset,
char *sectionaddr,
struct elf32_rela *rela, char *addr)
{
unsigned int type;
unsigned char instr[2];
type = ELF32_R_TYPE(rela->r_info);
addr += rela->r_addend;
switch(type) {
case R_MSP430_16:
case R_MSP430_16_PCREL:
case R_MSP430_16_BYTE:
case R_MSP430_16_PCREL_BYTE:
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430_32:
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_S:
case R_MSP430X_S_BYTE:
/* src(19:16) located at positions 11:8 of opcode */
/* src(15:0) located just after opcode */
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_read(fd, instr, 2);
instr[1] = (int)(instr[1]) & 0xf0 | (((long int)addr >> 8) & 0x0f00);
instr[0] = (int)(instr[0]) & 0xff;
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, instr, 2);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_D:
case R_MSP430X_PCREL_D:
case R_MSP430X_D_BYTE:
/* dst(19:16) located at positions 3:0 of opcode */
/* dst(15:0) located just after opcode */
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_read(fd, instr, 2);
instr[1] = (int)(instr[1]) & 0xff;
instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f);
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, instr, 2);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_PCREL_SRC_BYTE:
case R_MSP430X_SRC_BYTE:
case R_MSP430X_PCREL_SRC:
case R_MSP430X_SRC:
/* src(19:16) located at positions 10:7 of extension word */
/* src(15:0) located just after opcode */
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_read(fd, instr, 2);
/* 4 most-significant bits */
instr[1] = (int)(instr[1]) & 0xf8 | (((long int)addr >> 9) & 0x0780);
instr[0] = (int)(instr[0]) & 0x7f | (((long int)addr >> 9) & 0x0780);
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, instr, 2);
/* 16 least-significant bits */
cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_DST_BYTE:
case R_MSP430X_PCREL_DST_BYTE:
case R_MSP430X_DST:
case R_MSP430X_PCREL_DST:
/* dst(19:16) located at positions 3:0 of extension word */
/* dst(15:0) located just after opcode */
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_read(fd, instr, 2);
instr[1] = (int)(instr[1]) & 0xff;
instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f);
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, instr, 2);
cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_DST_2ND:
case R_MSP430X_PCREL_DST_2ND:
case R_MSP430X_DST_2ND_BYTE:
case R_MSP430X_PCREL_DST_2ND_BYTE:
/* dst(19:16) located at positions 3:0 of extension word */
/* dst(15:0) located after src(15:0) */
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_read(fd, instr, 2);
instr[1] = (int)(instr[1]) & 0xff;
instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f);
cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
cfs_write(fd, instr, 2);
cfs_seek(fd, sectionoffset + rela->r_offset + 0x06, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
case R_MSP430X_INDXD:
case R_MSP430X_PCREL_INDXD:
cfs_seek(fd, sectionoffset + rela->r_offset + 0x02, CFS_SEEK_SET);
cfs_write(fd, (char *)&addr, 2);
break;
default:
PRINTF("Unknown relocation type!\n");
break;
}
}
/*---------------------------------------------------------------------------*/

View file

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

View file

@ -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,30 +185,17 @@ check_for_tcp_syn(void)
static void
packet_input(void)
{
#if UIP_CONF_IP_FORWARD
if(uip_len > 0) {
#if UIP_CONF_IP_FORWARD
tcpip_is_forwarding = 1;
if(uip_fw_forward() == UIP_FW_LOCAL) {
if(uip_fw_forward() != UIP_FW_LOCAL) {
tcpip_is_forwarding = 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
PRINTF("tcpip packet_input forward output len %d\n", uip_len);
tcpip_output();
#endif
#endif /* UIP_CONF_TCP_SPLIT */
}
return;
}
tcpip_is_forwarding = 0;
}
#else /* UIP_CONF_IP_FORWARD */
if(uip_len > 0) {
#endif /* UIP_CONF_IP_FORWARD */
check_for_tcp_syn();
uip_input();
if(uip_len > 0) {
@ -215,14 +204,13 @@ packet_input(void)
#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
@ -529,10 +517,7 @@ void
tcpip_input(void)
{
process_post_synch(&tcpip_process, PACKET_INPUT, NULL);
uip_len = 0;
#if NETSTACK_CONF_WITH_IPV6
uip_ext_len = 0;
#endif /*NETSTACK_CONF_WITH_IPV6*/
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
@ -548,13 +533,13 @@ tcpip_ipv6_output(void)
if(uip_len > UIP_LINK_MTU) {
UIP_LOG("tcpip_ipv6_output: Packet to big");
uip_len = 0;
uip_clear_buf();
return;
}
if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){
UIP_LOG("tcpip_ipv6_output: Destination address unspecified");
uip_len = 0;
uip_clear_buf();
return;
}
@ -591,7 +576,7 @@ tcpip_ipv6_output(void)
#else
PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
#endif /* !UIP_FALLBACK_INTERFACE */
uip_len = 0;
uip_clear_buf();
return;
}
@ -643,7 +628,7 @@ tcpip_ipv6_output(void)
#if UIP_CONF_IPV6_RPL
if(rpl_update_header_final(nexthop)) {
uip_len = 0;
uip_clear_buf();
return;
}
#endif /* UIP_CONF_IPV6_RPL */
@ -651,7 +636,7 @@ tcpip_ipv6_output(void)
if(nbr == NULL) {
#if UIP_ND6_SEND_NA
if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
uip_len = 0;
uip_clear_buf();
return;
} else {
#if UIP_CONF_IPV6_QUEUE_PKT
@ -675,7 +660,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
@ -689,7 +678,7 @@ tcpip_ipv6_output(void)
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len);
}
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
uip_len = 0;
uip_clear_buf();
return;
}
/* Send in parallel if we are running NUD (nbc state is either STALE,
@ -719,15 +708,13 @@ tcpip_ipv6_output(void)
}
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
uip_len = 0;
uip_clear_buf();
return;
}
return;
}
/* Multicast IP destination address. */
tcpip_output(NULL);
uip_len = 0;
uip_ext_len = 0;
uip_clear_buf();
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/

View file

@ -38,6 +38,7 @@
*/
#include "net/ip/uip-debug.h"
#include "net/ip/ip64-addr.h"
/*---------------------------------------------------------------------------*/
void
@ -53,20 +54,38 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
return;
}
#if NETSTACK_CONF_WITH_IPV6
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) {
PRINTA("::");
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) {
if(f++ == 0) {
PRINTA("::");
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTA(":");
}
PRINTA("%x", a);
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTA(":");
}
PRINTA("%x", a);
}
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);

View file

@ -54,9 +54,9 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
if(data != NULL) {
uip_udp_conn = c;
uip_slen = len;
memcpy(&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);
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);
#if UIP_CONF_IPV6_MULTICAST

View file

@ -1326,6 +1326,22 @@ extern uint8_t uip_ext_len;
extern uint16_t uip_urglen, uip_surglen;
#endif /* UIP_URGDATA > 0 */
/*
* Clear uIP buffer
*
* This function clears the uIP buffer by reseting the uip_len and
* uip_ext_len pointers.
*/
#if NETSTACK_CONF_WITH_IPV6
#define uip_clear_buf() { \
uip_len = 0; \
uip_ext_len = 0; \
}
#else /*NETSTACK_CONF_WITH_IPV6*/
#define uip_clear_buf() { \
uip_len = 0; \
}
#endif /*NETSTACK_CONF_WITH_IPV6*/
/**
* Representation of a uIP TCP connection.

View file

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

View file

@ -59,7 +59,7 @@ input_callback(void)
/*PRINTF("SIN: %u\n", uip_len);*/
if(uip_buf[0] == '!') {
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
uip_len = 0;
uip_clear_buf();
#if 0
if(uip_buf[1] == 'P') {
uip_ipaddr_t prefix;
@ -87,7 +87,7 @@ input_callback(void)
slip_send();
}
uip_len = 0;
uip_clear_buf();
} else {
/* Save the last sender received over SLIP to avoid bouncing the
@ -101,7 +101,7 @@ input_callback(void)
uip_len = len;
/* PRINTF("send len %d\n", len); */
} else {
uip_len = 0;
uip_clear_buf();
}
}
}

View file

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

View file

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

View file

@ -229,7 +229,7 @@ time_exceeded(void)
/* We don't send out ICMP errors for ICMP messages (unless they are pings). */
if(ICMPBUF->proto == UIP_PROTO_ICMP &&
ICMPBUF->type != ICMP_ECHO) {
uip_len = 0;
uip_clear_buf();
return;
}
/* Copy fields from packet header into payload of this ICMP packet. */

View file

@ -714,7 +714,7 @@ uip_process(uint8_t flag)
}
/* Reset the length variables. */
uip_len = 0;
uip_clear_buf();
uip_slen = 0;
#if UIP_TCP
@ -1594,7 +1594,7 @@ uip_process(uint8_t flag)
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_connr->len = 0;
uip_len = 0;
uip_clear_buf();
uip_slen = 0;
UIP_APPCALL();
goto appsend;
@ -1939,7 +1939,7 @@ uip_process(uint8_t flag)
return;
drop:
uip_len = 0;
uip_clear_buf();
uip_flags = 0;
return;
}

View file

@ -284,10 +284,10 @@ uip_arp_arpin(void)
{
if(uip_len < sizeof(struct arp_hdr)) {
uip_len = 0;
uip_clear_buf();
return;
}
uip_len = 0;
uip_clear_buf();
switch(BUF->opcode) {
case UIP_HTONS(ARP_REQUEST):

View file

@ -1383,8 +1383,7 @@ out()
drop:
uip_slen = 0;
uip_len = 0;
uip_ext_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
static uint8_t

View file

@ -81,7 +81,7 @@ mcast_fwd(void *p)
uip_len = mcast_len;
UIP_IP_BUF->ttl--;
tcpip_output(NULL);
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
static uint8_t

View file

@ -1455,7 +1455,7 @@ output(const uip_lladdr_t *localdest)
* IPv6/HC1/HC06/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
*/
int estimated_fragments = ((int)uip_len) / ((int)MAC_MAX_PAYLOAD - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
int freebuf = queuebuf_numfree() - 1;
PRINTFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {

View file

@ -367,6 +367,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
num_routes++;
PRINTF("uip_ds6_route_add num %d\n", num_routes);
/* lock this entry so that nexthop is not removed */
nbr_table_lock(nbr_routes, routes);
}
uip_ipaddr_copy(&(r->ipaddr), ipaddr);
@ -423,7 +426,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route)
list_remove(route->neighbor_routes->route_list, neighbor_route);
if(list_head(route->neighbor_routes->route_list) == NULL) {
/* If this was the only route using this neighbor, remove the
neibhor from the table */
neighbor from the table - this implicitly unlocks nexthop */
PRINTF("uip_ds6_route_rm: removing neighbor too\n");
nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
}

View file

@ -275,6 +275,7 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
PRINTF("Adding prefix ");
PRINT6ADDR(&locprefix->ipaddr);
PRINTF("length %u, vlifetime%lu\n", ipaddrlen, interval);
return locprefix;
}
return NULL;
}

View file

@ -210,12 +210,12 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
/* check if originating packet is not an ICMP error*/
if (uip_ext_len) {
if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){
uip_len = 0;
uip_clear_buf();
return;
}
} else {
if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){
uip_len = 0;
uip_clear_buf();
return;
}
}
@ -250,7 +250,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
/* the source should not be unspecified nor multicast, the check for
multicast is done in uip_process */
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){
uip_len = 0;
uip_clear_buf();
return;
}
@ -260,7 +260,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr);
} else {
uip_len = 0;
uip_clear_buf();
return;
}
} else {
@ -385,7 +385,7 @@ echo_reply_input(void)
}
}
uip_len = 0;
uip_clear_buf();
return;
}
/*---------------------------------------------------------------------------*/

View file

@ -127,9 +127,21 @@ static uip_ds6_addr_t *addr; /** Pointer to an interface address */
#if !UIP_CONF_ROUTER // TBD see if we move it to ra_input
static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */
static uip_ipaddr_t ipaddr;
#endif
#if (!UIP_CONF_ROUTER || UIP_ND6_SEND_RA)
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
@ -189,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);
lladdr, UIP_LLADDR_LEN) != 0) {
memcpy(lladdr, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
nbr->state = NBR_STALE;
} else {
if(nbr->state == NBR_INCOMPLETE) {
@ -321,7 +332,7 @@ create_na:
return;
discard:
uip_len = 0;
uip_clear_buf();
return;
}
#endif /* UIP_ND6_SEND_NA */
@ -360,7 +371,7 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
}
if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
PRINTF("Dropping NS due to no suitable source address\n");
uip_len = 0;
uip_clear_buf();
return;
}
UIP_IP_BUF->len[1] =
@ -557,7 +568,7 @@ na_input(void)
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
discard:
uip_len = 0;
uip_clear_buf();
return;
}
#endif /* UIP_ND6_SEND_NA */
@ -619,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;
@ -646,7 +657,7 @@ rs_input(void)
uip_ds6_send_ra_sollicited();
discard:
uip_len = 0;
uip_clear_buf();
return;
}
@ -687,7 +698,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
nd6_opt_offset = UIP_ND6_RA_LEN;
#if !UIP_CONF_ROUTER
/* Prefix list */
for(prefix = uip_ds6_prefix_list;
prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) {
@ -704,7 +714,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
}
}
#endif /* !UIP_CONF_ROUTER */
/* Source link-layer option */
create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO);
@ -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) {
@ -1029,7 +1038,7 @@ ra_input(void)
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
discard:
uip_len = 0;
uip_clear_buf();
return;
}
#endif /* !UIP_CONF_ROUTER */

View file

@ -538,8 +538,7 @@ remove_ext_hdr(void)
uip_ext_len, uip_len);
if(uip_len < UIP_IPH_LEN + uip_ext_len) {
PRINTF("ERROR: uip_len too short compared to ext len\n");
uip_ext_len = 0;
uip_len = 0;
uip_clear_buf();
return;
}
memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len,
@ -825,8 +824,7 @@ uip_reass_over(void)
* any RFC, we decided not to include it as it reduces the size of
* the packet.
*/
uip_len = 0;
uip_ext_len = 0;
uip_clear_buf();
memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
and dest address*/
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0);
@ -971,7 +969,7 @@ uip_process(uint8_t flag)
} else if(flag == UIP_TIMER) {
/* Reset the length variables. */
#if UIP_TCP
uip_len = 0;
uip_clear_buf();
uip_slen = 0;
/* Increase the initial sequence number. */
@ -1456,7 +1454,7 @@ uip_process(uint8_t flag)
UIP_STAT(++uip_stat.icmp.drop);
UIP_STAT(++uip_stat.icmp.typeerr);
UIP_LOG("icmp6: unknown ICMPv6 message.");
uip_len = 0;
uip_clear_buf();
}
if(uip_len > 0) {
@ -1978,7 +1976,7 @@ uip_process(uint8_t flag)
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_connr->len = 0;
uip_len = 0;
uip_clear_buf();
uip_slen = 0;
UIP_APPCALL();
goto appsend;
@ -2310,8 +2308,7 @@ uip_process(uint8_t flag)
return;
drop:
uip_len = 0;
uip_ext_len = 0;
uip_clear_buf();
uip_ext_bitmap = 0;
uip_flags = 0;
return;

View file

@ -507,14 +507,16 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
#endif
int strobes;
uint8_t got_strobe_ack = 0;
int len;
uint8_t is_broadcast = 0;
uint8_t is_known_receiver = 0;
uint8_t collisions;
int transmit_len;
int ret;
uint8_t contikimac_was_on;
#if !RDC_CONF_HARDWARE_ACK
int len;
uint8_t seqno;
#endif
/* Exit if RDC and radio were explicitly turned off */
if(!contikimac_is_on && !contikimac_keep_radio_on) {
@ -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;

View file

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

View file

@ -40,6 +40,18 @@
#include "lib/list.h"
#include "net/nbr-table.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#include "sys/ctimer.h"
static void handle_periodic_timer(void *ptr);
static struct ctimer periodic_timer;
static uint8_t initialized = 0;
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/* List of link-layer addresses of the neighbors, used as key in the tables */
typedef struct nbr_table_key {
struct nbr_table_key *next;
@ -143,6 +155,7 @@ static int
nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value)
{
int item_index = index_from_item(table, item);
if(table != NULL && item_index != -1) {
if(value) {
bitmap[item_index] |= 1 << table->index;
@ -229,6 +242,13 @@ nbr_table_allocate(void)
int
nbr_table_register(nbr_table_t *table, nbr_table_callback *callback)
{
#if DEBUG
if(!initialized) {
initialized = 1;
/* schedule a debug printout per minute */
ctimer_set(&periodic_timer, CLOCK_SECOND * 60, handle_periodic_timer, NULL);
}
#endif
if(num_tables < MAX_NUM_TABLES) {
table->index = num_tables++;
table->callback = callback;
@ -331,6 +351,10 @@ nbr_table_remove(nbr_table_t *table, void *item)
int
nbr_table_lock(nbr_table_t *table, void *item)
{
#if DEBUG
int i = index_from_item(table, item);
PRINTF("*** Lock %d\n", i);
#endif
return nbr_set_bit(locked_map, table, item, 1);
}
/*---------------------------------------------------------------------------*/
@ -338,6 +362,10 @@ nbr_table_lock(nbr_table_t *table, void *item)
int
nbr_table_unlock(nbr_table_t *table, void *item)
{
#if DEBUG
int i = index_from_item(table, item);
PRINTF("*** Unlock %d\n", i);
#endif
return nbr_set_bit(locked_map, table, item, 0);
}
/*---------------------------------------------------------------------------*/
@ -348,3 +376,25 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item)
nbr_table_key_t *key = key_from_item(table, item);
return key != NULL ? &key->lladdr : NULL;
}
/*---------------------------------------------------------------------------*/
#if DEBUG
static void
handle_periodic_timer(void *ptr)
{
int i, j;
/* Printout all neighbors and which tables they are used in */
PRINTF("NBR TABLE:\n");
for(i = 0; i < NBR_TABLE_MAX_NEIGHBORS; i++) {
if(used_map[i] > 0) {
PRINTF(" %02d %02d",i , key_from_index(i)->lladdr.u8[LINKADDR_SIZE - 1]);
for(j = 0; j < num_tables; j++) {
PRINTF(" [%d:%d]", (used_map[i] & (1 << j)) != 0,
(locked_map[i] & (1 << j)) != 0);
}
PRINTF("\n");
}
}
ctimer_reset(&periodic_timer);
}
#endif

View file

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

View file

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

View file

@ -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) {
@ -1408,10 +1406,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
p->dtsn = dio->dtsn;
}
/*---------------------------------------------------------------------------*/
void
rpl_lock_parent(rpl_parent_t *p)
{
nbr_table_lock(rpl_parents, p);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -175,7 +175,7 @@ dis_input(void)
}
}
}
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
void
@ -256,7 +256,8 @@ dio_input(void)
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
return;
goto discard;
}
} else {
PRINTF("RPL: Neighbor already in neighbor cache\n");
@ -306,7 +307,7 @@ dio_input(void)
if(len + i > buffer_length) {
PRINTF("RPL: Invalid DIO packet\n");
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2);
@ -316,7 +317,7 @@ dio_input(void)
if(len < 6) {
PRINTF("RPL: Invalid DAG MC, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
dio.mc.type = buffer[i + 2];
dio.mc.flags = buffer[i + 3] << 1;
@ -342,14 +343,14 @@ dio_input(void)
dio.mc.obj.energy.energy_est = buffer[i + 7];
} else {
PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type);
return;
goto discard;
}
break;
case RPL_OPTION_ROUTE_INFO:
if(len < 9) {
PRINTF("RPL: Invalid destination prefix option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
/* The flags field includes the preference value. */
@ -365,7 +366,7 @@ dio_input(void)
} else {
PRINTF("RPL: Invalid route info option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
break;
@ -373,7 +374,7 @@ dio_input(void)
if(len != 16) {
PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len);
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
/* Path control field not yet implemented - at i + 2 */
@ -395,7 +396,7 @@ dio_input(void)
if(len != 32) {
PRINTF("RPL: Invalid DAG prefix info, len != 32\n");
RPL_STAT(rpl_stats.malformed_msgs++);
return;
goto discard;
}
dio.prefix_info.length = buffer[i + 2];
dio.prefix_info.flags = buffer[i + 3];
@ -418,7 +419,8 @@ dio_input(void)
rpl_process_dio(&from, &dio);
uip_len = 0;
discard:
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
void
@ -622,7 +624,7 @@ dao_input(void)
if(instance == NULL) {
PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n",
instance_id);
return;
goto discard;
}
lifetime = instance->default_lifetime;
@ -637,7 +639,7 @@ dao_input(void)
if(flags & RPL_DAO_D_FLAG) {
if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) {
PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n");
return;
goto discard;
}
pos += 16;
}
@ -658,7 +660,7 @@ dao_input(void)
DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance));
parent->rank = INFINITE_RANK;
parent->flags |= RPL_PARENT_FLAG_UPDATED;
return;
goto discard;
}
/* If we get the DAO from our parent, we also have a loop. */
@ -666,7 +668,7 @@ dao_input(void)
PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n");
parent->rank = INFINITE_RANK;
parent->flags |= RPL_PARENT_FLAG_UPDATED;
return;
goto discard;
}
}
@ -743,7 +745,7 @@ dao_input(void)
dao_ack_output(instance, &dao_sender_addr, sequence);
}
}
return;
goto discard;
}
PRINTF("RPL: adding DAO route\n");
@ -765,19 +767,17 @@ dao_input(void)
PRINTF(", ");
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTF("\n");
return;
goto discard;
}
} else {
PRINTF("RPL: Neighbor already in neighbor cache\n");
}
rpl_lock_parent(parent);
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
if(rep == NULL) {
RPL_STAT(rpl_stats.mem_overflows++);
PRINTF("RPL: Could not add a route after receiving a DAO\n");
return;
goto discard;
}
rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
@ -801,7 +801,9 @@ fwd_dao:
dao_ack_output(instance, &dao_sender_addr, sequence);
}
}
uip_len = 0;
discard:
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
void
@ -914,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];
@ -931,7 +929,7 @@ dao_ack_input(void)
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n");
#endif /* DEBUG */
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
void

View file

@ -303,9 +303,6 @@ uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
int prefix_len, uip_ipaddr_t *next_hop);
void rpl_purge_routes(void);
/* Lock a parent in the neighbor cache. */
void rpl_lock_parent(rpl_parent_t *p);
/* Objective function. */
rpl_of_t *rpl_find_of(rpl_ocp_t);

View file

@ -89,11 +89,17 @@ rpl_set_mode(enum rpl_mode m)
} else if(m == RPL_MODE_FEATHER) {
PRINTF("RPL: switching to feather mode\n");
mode = m;
if(default_instance != NULL) {
PRINTF("rpl_set_mode: RPL sending DAO with zero lifetime\n");
if(default_instance->current_dag != NULL) {
dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME);
}
rpl_cancel_dao(default_instance);
} else {
PRINTF("rpl_set_mode: no default instance\n");
}
mode = m;
} else {
mode = m;
}

View file

@ -108,7 +108,6 @@ struct rpl_dag;
#define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2
struct rpl_parent {
struct rpl_parent *next;
struct rpl_dag *dag;
#if RPL_DAG_MC != RPL_DAG_MC_NONE
rpl_metric_container_t mc;

View file

@ -123,6 +123,17 @@
#define CC_NO_VA_ARGS CC_CONF_VA_ARGS
#endif
/** \def CC_ACCESS_NOW(x)
* This macro ensures that the access to a non-volatile variable can
* not be reordered or optimized by the compiler.
* See also https://lwn.net/Articles/508991/ - In Linux the macro is
* called ACCESS_ONCE
* The type must be passed, because the typeof-operator is a gcc
* extension
*/
#define CC_ACCESS_NOW(type, variable) (*(volatile type *)&(variable))
#ifndef NULL
#define NULL 0
#endif /* NULL */

View file

@ -98,9 +98,16 @@ ctimer_init(void)
void
ctimer_set(struct ctimer *c, clock_time_t t,
void (*f)(void *), void *ptr)
{
ctimer_set_with_process(c, t, f, ptr, PROCESS_CURRENT());
}
/*---------------------------------------------------------------------------*/
void
ctimer_set_with_process(struct ctimer *c, clock_time_t t,
void (*f)(void *), void *ptr, struct process *p)
{
PRINTF("ctimer_set %p %u\n", c, (unsigned)t);
c->p = PROCESS_CURRENT();
c->p = p;
c->f = f;
c->ptr = ptr;
if(initialized) {

View file

@ -109,10 +109,28 @@ void ctimer_restart(struct ctimer *c);
* sometime in the future. When the callback timer expires,
* the callback function f will be called with ptr as argument.
*
* This essentially does ctimer_set_process(c, t, f, ptr, PROCESS_CURRENT());
*
*/
void ctimer_set(struct ctimer *c, clock_time_t t,
void (*f)(void *), void *ptr);
/**
* \brief Set a callback timer.
* \param c A pointer to the callback timer.
* \param t The interval before the timer expires.
* \param f A function to be called when the timer expires.
* \param ptr An opaque pointer that will be supplied as an argument to the callback function.
* \param p A pointer to the process the timer belongs to
*
* This function is used to set a callback timer for a time
* sometime in the future. When the callback timer expires,
* the callback function f will be called with ptr as argument.
*
*/
void ctimer_set_with_process(struct ctimer *c, clock_time_t t,
void (*f)(void *), void *ptr, struct process *p);
/**
* \brief Stop a pending callback timer.
* \param c A pointer to the pending callback timer.

View file

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

View file

@ -181,6 +181,14 @@ etimer_set(struct etimer *et, clock_time_t interval)
}
/*---------------------------------------------------------------------------*/
void
etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval)
{
timer_reset(&et->timer);
et->timer.interval = interval;
add_timer(et);
}
/*---------------------------------------------------------------------------*/
void
etimer_reset(struct etimer *et)
{
timer_reset(&et->timer);

View file

@ -114,6 +114,19 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval);
*/
CCIF void etimer_reset(struct etimer *et);
/**
* \brief Reset an event timer with a new interval.
* \param et A pointer to the event timer.
* \param interval The interval before the timer expires.
*
* This function very similar to etimer_reset. Opposed to
* etimer_reset it is possible to change the timout.
* This allows accurate, non-periodic timers without drift.
*
* \sa etimer_reset()
*/
void etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval);
/**
* \brief Restart an event timer from the current point in time
* \param et A pointer to the event timer.

View file

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

View file

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

View file

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

View file

@ -552,7 +552,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 +1446,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 +1489,8 @@ rf230_read(void *buf, unsigned short bufsize)
memcpy(buf,framep,len-AUX_LEN+CHECKSUM_LEN);
rf230_last_correlation = rxframe[rxframe_head].lqi;
/* Clear the length field to allow buffering of the next packet */
rxframe[rxframe_head].length=0;
rxframe_head++;
if (rxframe_head >= RF230_CONF_RX_BUFFERS) {
rxframe_head=0;
}
/* If another packet has been buffered, schedule another receive poll */
if (rxframe[rxframe_head].length) {
rf230_interrupt();
}
else {
rf230_pending = 0;
}
/* Prepare to receive another packet */
flushrx();
/* Point to the checksum */
framep+=len-AUX_LEN;

View file

@ -128,8 +128,7 @@ periph_permit_pm1(void)
static void
enter_pm0(void)
{
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
/* We are only interested in IRQ energest while idle or in LPM */
ENERGEST_IRQ_RESTORE(irq_energest);
@ -147,8 +146,7 @@ enter_pm0(void)
/* Remember IRQ energest for next pass */
ENERGEST_IRQ_SAVE(irq_energest);
ENERGEST_ON(ENERGEST_TYPE_CPU);
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
}
/*---------------------------------------------------------------------------*/
static void
@ -238,8 +236,7 @@ lpm_exit()
/* Remember IRQ energest for next pass */
ENERGEST_IRQ_SAVE(irq_energest);
ENERGEST_ON(ENERGEST_TYPE_CPU);
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
}
/*---------------------------------------------------------------------------*/
void
@ -312,8 +309,7 @@ lpm_enter()
/* We are only interested in IRQ energest while idle or in LPM */
ENERGEST_IRQ_RESTORE(irq_energest);
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
/* Remember the current time so we can keep stats when we wake up */
if(LPM_CONF_STATS) {
@ -339,8 +335,7 @@ lpm_enter()
/* Remember IRQ energest for next pass */
ENERGEST_IRQ_SAVE(irq_energest);
ENERGEST_ON(ENERGEST_TYPE_CPU);
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
} else {
/* All clear. Assert WFI and drop to PM1/2. This is now un-interruptible */
assert_wfi();

View file

@ -42,8 +42,61 @@
* \file
* Implementation of the CC13xx/CC26xx watchdog driver.
*/
#include "watchdog.h"
#include "contiki.h"
#include "dev/watchdog.h"
#include "ti-lib.h"
#include <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
#ifdef CONTIKI_WATCHDOG_CONF_TIMER_TOP
#define CONTIKI_WATCHDOG_TIMER_TOP CONTIKI_WATCHDOG_CONF_TIMER_TOP
#else
#define CONTIKI_WATCHDOG_TIMER_TOP 0xFFFFF
#endif
#ifdef CONTIKI_WATCHDOG_CONF_LOCK_CONFIG
#define CONTIKI_WATCHDOG_LOCK_CONFIG CONTIKI_WATCHDOG_CONF_LOCK_CONFIG
#else
#define CONTIKI_WATCHDOG_LOCK_CONFIG 1
#endif
#define LOCK_INTERRUPTS_DISABLED 0x01
#define LOCK_REGISTERS_UNLOCKED 0x02
/*---------------------------------------------------------------------------*/
static uint32_t
unlock_config(void)
{
uint32_t ret = 0;
bool int_status;
if(CONTIKI_WATCHDOG_LOCK_CONFIG) {
int_status = ti_lib_int_master_disable();
if(ti_lib_watchdog_lock_state()) {
ret |= LOCK_REGISTERS_UNLOCKED;
ti_lib_watchdog_unlock();
}
ret |= (int_status) ? (0) : (LOCK_INTERRUPTS_DISABLED);
}
return ret;
}
/*---------------------------------------------------------------------------*/
static void
lock_config(uint32_t status)
{
if(CONTIKI_WATCHDOG_LOCK_CONFIG) {
if(status & LOCK_REGISTERS_UNLOCKED) {
ti_lib_watchdog_lock();
}
if(status & LOCK_INTERRUPTS_DISABLED) {
ti_lib_int_master_enable();
}
}
}
/*---------------------------------------------------------------------------*/
/**
* \brief Initialises the CC26xx WDT
@ -54,7 +107,8 @@
void
watchdog_init(void)
{
ti_lib_watchdog_reload_set(0xFFFFF);
ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP);
lock_config(LOCK_REGISTERS_UNLOCKED);
}
/*---------------------------------------------------------------------------*/
/**
@ -63,7 +117,12 @@ watchdog_init(void)
void
watchdog_start(void)
{
uint32_t lock_status = unlock_config();
watchdog_periodic();
ti_lib_watchdog_reset_enable();
lock_config(lock_status);
}
/*---------------------------------------------------------------------------*/
/**
@ -72,9 +131,23 @@ watchdog_start(void)
void
watchdog_periodic(void)
{
ti_lib_watchdog_reload_set(CONTIKI_WATCHDOG_TIMER_TOP);
ti_lib_watchdog_int_clear();
}
/*---------------------------------------------------------------------------*/
/**
* \brief Stops the WDT such that it won't timeout and cause MCU reset
*/
void
watchdog_stop(void)
{
uint32_t lock_status = unlock_config();
ti_lib_watchdog_reset_disable();
lock_config(lock_status);
}
/*---------------------------------------------------------------------------*/
/**
* \brief Manually trigger a WDT reboot
*/

View file

@ -202,8 +202,7 @@ wake_up(void)
/* Remember IRQ energest for next pass */
ENERGEST_IRQ_SAVE(irq_energest);
ENERGEST_ON(ENERGEST_TYPE_CPU);
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
/* Sync so that we get the latest values before adjusting recharge settings */
ti_lib_sys_ctrl_aon_sync();
@ -396,8 +395,7 @@ lpm_drop()
/* We are only interested in IRQ energest while idle or in LPM */
ENERGEST_IRQ_RESTORE(irq_energest);
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
/* Sync the AON interface to ensure all writes have gone through. */
ti_lib_sys_ctrl_aon_sync();
@ -429,8 +427,7 @@ lpm_drop()
void
lpm_sleep(void)
{
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
/* We are only interested in IRQ energest while idle or in LPM */
ENERGEST_IRQ_RESTORE(irq_energest);
@ -443,8 +440,7 @@ lpm_sleep(void)
/* Remember IRQ energest for next pass */
ENERGEST_IRQ_SAVE(irq_energest);
ENERGEST_ON(ENERGEST_TYPE_CPU);
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
}
/*---------------------------------------------------------------------------*/
void

View file

@ -805,7 +805,7 @@ transmit(unsigned short transmit_len)
cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
/* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */
rf_core_cmd_done_en();
rf_core_cmd_done_en(true);
ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status);

View file

@ -687,7 +687,7 @@ transmit(unsigned short transmit_len)
rx_off_prop();
/* Enable the LAST_COMMAND_DONE interrupt to wake us up */
rf_core_cmd_done_en();
rf_core_cmd_done_en(false);
ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status);

View file

@ -378,11 +378,12 @@ rf_core_setup_interrupts()
}
/*---------------------------------------------------------------------------*/
void
rf_core_cmd_done_en()
rf_core_cmd_done_en(bool fg)
{
uint32_t irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE;
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ENABLED_IRQS;
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS +
IRQ_LAST_COMMAND_DONE;
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS | irq;
}
/*---------------------------------------------------------------------------*/
void

View file

@ -331,17 +331,19 @@ uint8_t rf_core_boot(void);
void rf_core_setup_interrupts(void);
/**
* \brief Enable the LAST_CMD_DONE interrupt.
* \brief Enable interrupt on command done.
* \param fg set true to enable irq on foreground command done and false for
* background commands or if not in ieee mode.
*
* This is used within TX routines in order to be able to sleep the CM3 and
* wake up after TX has finished
*
* \sa rf_core_cmd_done_dis()
*/
void rf_core_cmd_done_en(void);
void rf_core_cmd_done_en(bool fg);
/**
* \brief Disable the LAST_CMD_DONE interrupt.
* \brief Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
*
* This is used within TX routines after TX has completed
*

View file

@ -90,6 +90,12 @@ clock_seconds(void)
return seconds;
}
void
clock_set_seconds(unsigned long sec)
{
seconds = sec;
}
void
clock_wait(clock_time_t t)
{

View file

@ -325,6 +325,17 @@ static const int XTAL32_EN = 0;
#define pack_XTAL_CNTL(ctune4pf, ctune, ftune, ibias) \
(*CRM_XTAL_CNTL = ((ctune4pf << 25) | (ctune << 21) | ( ftune << 16) | (ibias << 8) | 0x52))
#define soft_reset() \
__asm__ __volatile__ ( \
"ldr r0, [%[sw]] \n\t" \
"str r0, [%[sw]] \n\t" \
: /* out */ \
: /* in */ \
[sw] "l" (CRM_SW_RST) \
: /* clobber list */ \
"r0", "memory" \
);
#endif /* REG_NO_COMPAT */
#endif

View file

@ -78,5 +78,6 @@ extern nvmErr_t (*nvm_write)(nvmInterface_t nvmInterface, nvmType_t nvmType ,voi
/* SST flash has 32 sectors 4096 bytes each */
/* bit 0 is the first sector, bit 31 is the last */
extern nvmErr_t (*nvm_erase)(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield);
extern nvmErr_t (*nvm_verify)(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes);
extern void(*nvm_setsvar)(uint32_t zero_for_awesome);
#endif //NVM_H

View file

@ -51,6 +51,10 @@ nvmErr_t (*nvm_erase)
(nvmInterface_t nvmInterface, nvmType_t nvmType ,uint32_t sectorBitfield)
= (void*) 0x00006e05;
nvmErr_t (*nvm_verify)
(nvmInterface_t nvmInterface, nvmType_t nvmType, void *pSrc, uint32_t address, uint32_t numBytes)
= (void*) 0x00006f85;
void(*nvm_setsvar)
(uint32_t zero_for_awesome)
= (void *)0x00007085;

View file

@ -39,6 +39,10 @@ MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \
UIPDRIVERS = me.c me_tabs.c slip.c crc16.c
ELFLOADER = elfloader.c elfloader-msp430.c symtab.c
ifeq ($(TARGET_MEMORY_MODEL),large)
ELFLOADER = elfloader-msp430x.c symtab.c
endif
CONTIKI_TARGET_SOURCEFILES += $(MSP430) \
$(SYSAPPS) $(ELFLOADER) \
$(UIPDRIVERS)
@ -151,10 +155,16 @@ endif
ifndef IAR
ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion)))
ifdef CPU_HAS_MSP430X
TARGET_MEMORY_MODEL ?= medium
ifeq ($(TARGET_MEMORY_MODEL),large)
CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL)
CFLAGS += -mcode-region=far -mdata-region=far -msr20 -mc20 -md20
LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -mcode-region=far -mdata-region=far -msr20 -mc20 -md20
else
TARGET_MEMORY_MODEL = medium
CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL)
CFLAGS += -ffunction-sections -fdata-sections -mcode-region=any
LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections
endif
endif
endif
endif

View file

@ -25,7 +25,7 @@ LDFLAGS += -Wl,-flat_namespace
CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR
else
ifeq ($(HOST_OS),Linux)
LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,-export-dynamic
endif
endif

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2013, Google
* 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.
*
* Author: Vladimir Pouzanov <farcaller@gmail.com>
*
*/
#include "contiki.h"
#include "contiki-conf.h"
#if defined(linux) && NETSTACK_CONF_WITH_IPV6
#include "linuxradio-drv.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
#include <sys/ioctl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <linux/sockios.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static int sockfd = -1;
static char *sockbuf;
static int buflen;
#define MAX_PACKET_SIZE 256
static int
init(void)
{
sockbuf = malloc(MAX_PACKET_SIZE);
if(sockbuf == 0) {
return 1;
}
return 0;
}
static int
prepare(const void *payload, unsigned short payload_len)
{
if(payload_len > MAX_PACKET_SIZE) {
return 0;
}
memcpy(sockbuf, payload, payload_len);
buflen = payload_len;
return 0;
}
static int
transmit(unsigned short transmit_len)
{
int sent = 0;
sent = send(sockfd, sockbuf, buflen, 0);
if(sent < 0) {
perror("linuxradio send()");
return RADIO_TX_ERR;
}
buflen = 0;
return RADIO_TX_OK;
}
static int
my_send(const void *payload, unsigned short payload_len)
{
int ret = -1;
if(prepare(payload, payload_len)) {
return ret;
}
ret = transmit(payload_len);
return ret;
}
static int
my_read(void *buf, unsigned short buf_len)
{
return 0;
}
static int
channel_clear(void)
{
return 1;
}
static int
receiving_packet(void)
{
return 0;
}
static int
pending_packet(void)
{
return 0;
}
static int
set_fd(fd_set *rset, fd_set *wset)
{
FD_SET(sockfd, rset);
return 1;
}
static void
handle_fd(fd_set *rset, fd_set *wset)
{
if(FD_ISSET(sockfd, rset)) {
int bytes = read(sockfd, sockbuf, MAX_PACKET_SIZE);
buflen = bytes;
memcpy(packetbuf_dataptr(), sockbuf, bytes);
packetbuf_set_datalen(bytes);
NETSTACK_RDC.input();
}
}
static const struct select_callback linuxradio_sock_callback = { set_fd, handle_fd };
static int
on(void)
{
struct ifreq ifr;
int err;
struct sockaddr_ll sll;
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154));
if(sockfd < 0) {
perror("linuxradio socket()");
return 0;
} else {
strncpy((char *)ifr.ifr_name, NETSTACK_CONF_LINUXRADIO_DEV, IFNAMSIZ);
err = ioctl(sockfd, SIOCGIFINDEX, &ifr);
if(err == -1) {
perror("linuxradio ioctl()");
return 0;
}
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_IEEE802154);
if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
perror("linuxradio bind()");
return 0;
}
select_set_callback(sockfd, &linuxradio_sock_callback);
return 1;
}
}
static int
off(void)
{
close(sockfd);
sockfd = -1;
return 1;
}
const struct radio_driver linuxradio_driver =
{
init,
prepare,
transmit,
my_send,
my_read,
channel_clear,
receiving_packet,
pending_packet,
on,
off,
};
#endif

View file

@ -1,15 +1,18 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* Copyright (c) 2013, Google
* 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.
@ -26,15 +29,15 @@
* 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.
* Author: Vladimir Pouzanov <farcaller@gmail.com>
*
*/
#ifndef LIGHT_H_
#define LIGHT_H_
void sensors_light_init(void);
#ifndef __LINUXRADIO_DRV_H__
#define __LINUXRADIO_DRV_H__
unsigned sensors_light1(void);
unsigned sensors_light2(void);
#include "dev/radio.h"
#endif /* LIGHT_H_ */
extern const struct radio_driver linuxradio_driver;
#endif

View file

@ -83,7 +83,7 @@ pollhandler(void)
}
#endif
} else {
uip_len = 0;
uip_clear_buf();
}
}
}

View file

@ -103,7 +103,7 @@ pollhandler(void)
}
#endif /* !NETSTACK_CONF_WITH_IPV6 */
} else {
uip_len = 0;
uip_clear_buf();
}
}
#endif
@ -146,7 +146,7 @@ pollhandler(void)
#endif /* !NETSTACK_CONF_WITH_IPV6 */
} else {
bail:
uip_len = 0;
uip_clear_buf();
}
}
#endif

View file

@ -118,6 +118,7 @@ void cc2520_set_cca_threshold(int value);
CC2520_SPI_ENABLE(); \
SPI_WRITE((CC2520_INS_MEMRD | ((adr>>8)&0xFF))); \
SPI_WRITE((adr & 0xFF)); \
(void)SPI_RXBUF; \
SPI_READ(data); \
CC2520_SPI_DISABLE(); \
} while(0)

View file

@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED
uip_buf[1] = 'P';
uip_len = 2;
slip_send();
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
/* Set our prefix when we receive one over SLIP */

View file

@ -59,7 +59,7 @@ slip_input_callback(void)
PRINTF("SIN: %u\n", uip_len);
if((char)uip_buf[0] == '!') {
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
uip_len = 0;
uip_clear_buf();
if((char)uip_buf[1] == 'P') {
uip_ipaddr_t prefix;
/* Here we set a prefix !!! */

View file

@ -0,0 +1,8 @@
CONTIKI = ../..
TARGET = econotag
all: econotag-ecc-test
APPS += ecc
include $(CONTIKI)/Makefile.include

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
CONTIKI = ../..
LIBMC1322X = ../../../libmc1322x
CONTIKI_PROJECT = econotag-flash-test
TARGET = econotag
CLEAN = *.d $(CONTIKI_PROJECT)_e_$(TARGET).bin $(CONTIKI_PROJECT)_e_$(TARGET).txt $(CONTIKI_PROJECT)_e_$(TARGET).pbm
all: $(CONTIKI_PROJECT) blast
CFLAGS += -DFLASH_CONF_B1=30
CFLAGS += -DFLASH_CONF_B2=10
APPS += flash
flash:
$(LIBMC1322X)/tools/mc1322x-load \
-f $(LIBMC1322X)/tests/flasher_$(TARGET).bin \
-s $(CONTIKI_PROJECT)_e_$(TARGET).bin \
-c 'sudo $(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 reset' \
-t /dev/ttyUSB1 -l
clear:
$(LIBMC1322X)/tools/ftditools/bbmc -l $(TARGET) -i 0 erase
blast: $(CONTIKI)/tools/blaster/blaster
$(CONTIKI)/tools/blaster/blaster $(CONTIKI_PROJECT).cfg
$(CONTIKI)/tools/blaster/blaster: $(CONTIKI)/tools/blaster/blaster.c
(cd $(CONTIKI)/tools/blaster && $(MAKE))
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,6 @@
Its important to use -l as a flash parameter for mc1322xload.
Use "make flash" to start upload. Maybe u need
to change the location of libmc1322x in Makefile.
With "make clear" you can erase all flash data.

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2014, Lars Schmertmann <SmallLars@t-online.de>.
* 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 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Flash test
*
* This file contains tests for econotag flash app
*
* \author
* Lars Schmertmann <SmallLars@t-online.de>
*/
#include "flash.h"
#include "contiki.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "../../tools/blaster/blaster.h"
#include "econotag-flash-test.h"
void
output_result(uint32_t i, uint32_t fail)
{
if(fail) {
printf(" Test %u failed!\n", i);
} else { printf(" Test %u succeed!\n", i);
}
}
void
test_flash_1()
{
uint8_t buffer[12];
uint32_t check_int, my_int = 12345678;
flash_setVar("Hello World!", RES_MY_STRING_1, LEN_MY_STRING_1);
flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1);
output_result(1, memcmp(buffer, "Hello World!", 12));
flash_setVar("Heureka!", RES_MY_STRING_2, LEN_MY_STRING_2);
flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1);
output_result(2, memcmp(buffer, "Hello World!", 12));
flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2);
output_result(3, memcmp(buffer, "Heureka!", 8));
flash_setVar(&my_int, RES_MY_INTEGER, LEN_MY_INTEGER);
flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER);
output_result(4, check_int != my_int);
flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1);
output_result(5, memcmp(buffer, "Hello World!", 12));
flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2);
output_result(6, memcmp(buffer, "Heureka!", 8));
}
void
test_flash_2()
{
uint8_t buffer[12];
uint32_t check_int, my_int = 12345678;
flash_getVar(&check_int, RES_MY_INTEGER, LEN_MY_INTEGER);
output_result(1, check_int != my_int);
flash_getVar(buffer, RES_MY_STRING_1, LEN_MY_STRING_1);
output_result(2, memcmp(buffer, "Hello World!", 12));
flash_getVar(buffer, RES_MY_STRING_2, LEN_MY_STRING_2);
output_result(3, memcmp(buffer, "Heureka!", 8));
/* Block 1 max usage is 30 Byte -> Optimisation in Makefile */
output_result(4, flash_setVar("test", 0, 1) != gNvmErrInvalidPointer_c);
output_result(5, flash_setVar("test", 30, 1) != gNvmErrInvalidPointer_c);
output_result(6, flash_setVar("test", 29, 2) != gNvmErrAddressSpaceOverflow_c);
/* Block 2 max usage is 10 Byte -> Optimisation in Makefile */
output_result(7, flash_setVar("test", 4096, 1) != gNvmErrInvalidPointer_c);
output_result(8, flash_setVar("test", 4096 + 10, 1) != gNvmErrInvalidPointer_c);
output_result(9, flash_setVar("test", 4096 + 9, 2) != gNvmErrAddressSpaceOverflow_c);
}
void
test_flash_blaster()
{
uint8_t buffer[64];
flash_getVar(buffer, RES_NAME, LEN_NAME);
output_result(1, memcmp(buffer, "Econotag Flash Test Device", 27));
flash_getVar(buffer, RES_MODEL, LEN_MODEL);
output_result(2, memcmp(buffer, "Model 1234 for testing purposes only", 37));
}
void
test_flash_stack()
{
uint8_t buffer[32];
flash_stack_init();
output_result(1, flash_stack_size() != 0);
flash_stack_push("Hello World!", 12);
output_result(2, flash_stack_size() != 12);
flash_stack_read(buffer, 0, 12);
output_result(3, memcmp(buffer, "Hello World!", 12));
flash_stack_push("I love Contiki!", 15);
output_result(4, flash_stack_size() != 27);
flash_stack_read(buffer, 0, 12);
output_result(5, memcmp(buffer, "Hello World!", 12));
flash_stack_read(buffer, 12, 15);
output_result(6, memcmp(buffer, "I love Contiki!", 15));
flash_stack_init();
output_result(7, flash_stack_size() != 0);
uint32_t i;
for(i = 1; i < 256; i++) {
flash_stack_push("I love Contiki! ", 16);
}
output_result(8, flash_stack_size() != 4080);
output_result(9, flash_stack_push("1I love Contiki! ", 17) != gNvmErrAddressSpaceOverflow_c);
}
/* Start Process */
PROCESS(server_firmware, "Server Firmware");
AUTOSTART_PROCESSES(&server_firmware);
PROCESS_THREAD(server_firmware, ev, data) {
PROCESS_BEGIN();
if(flash_cmp("\001", RES_DONTCLEAR, LEN_DONTCLEAR)) {
printf("Initializing flash ... ");
flash_init();
printf("DONE\n");
flash_setVar("\001", RES_DONTCLEAR, LEN_DONTCLEAR);
printf("Starting flash tests 1:\n");
test_flash_1();
int i;
for(i = 0; i < 1024; i++) {
printf("Reboot ...\r");
}
soft_reset();
} else {
printf("Initialization not wished\n");
}
printf("Starting flash tests 2:\n");
test_flash_2();
printf("Starting flash stack tests:\n");
test_flash_stack();
printf("Starting flash blaster tests:\n");
test_flash_blaster();
PROCESS_END();
}

View file

@ -0,0 +1,7 @@
input = "econotag-flash-test_econotag";
output = "econotag-flash-test_e_econotag";
eui = [ 0x2, 0x0, 0x0, 0x0, 0x12, 0x34, 0x56, 0x78 ];
uuid = "cbf9889f-dc0e-4c18-9aa9-93509a6c102a";
psk = "yCh0OXnSkFT-eXKE";
name = "Econotag Flash Test Device";
model = "Model 1234 for testing purposes only";

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2014, Lars Schmertmann <SmallLars@t-online.de>.
* 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 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Flash Management
*
* This file contains Pointers for manual flash management.
*
* \author
* Lars Schmertmann <SmallLars@t-online.de>
*/
#ifndef ECONOTAG_FLASH_TEST_H_
#define ECONOTAG_FLASH_TEST_H_
/* Pointer for Block 1 --------------- */
#define RES_DONTCLEAR 1
#define LEN_DONTCLEAR 1
#define RES_MY_STRING_1 2
#define LEN_MY_STRING_1 12
#define RES_MY_STRING_2 14
#define LEN_MY_STRING_2 8
/* Pointer for Block 2 --------------- */
#define RES_MY_INTEGER (4096 + 1)
#define LEN_MY_INTEGER 4
/* ------------------------------------ */
#endif /* ECONOTAG_FLASH_TEST_H_ */

View file

@ -0,0 +1,15 @@
TARGET=avr-raven
APPS += raven-lcd-interface
export
CONTIKI=../..
ER_REST_EXAMPLE=$(CONTIKI)/examples/er-rest-example
all %:
@(cd $(ER_REST_EXAMPLE) && $(MAKE) $@)
@echo
@echo "*** Binaries can be found in $(ER_REST_EXAMPLE) ***"

View file

@ -79,11 +79,17 @@ extern resource_t res_leds, res_toggle;
#include "dev/light-sensor.h"
extern resource_t res_light;
#endif
/*
#if PLATFORM_HAS_BATTERY
#include "dev/battery-sensor.h"
extern resource_t res_battery;
#endif
#if PLATFORM_HAS_TEMPERATURE
#include "dev/temperature-sensor.h"
extern resource_t res_temperature;
#endif
/*
extern resource_t res_battery;
#endif
#if PLATFORM_HAS_RADIO
#include "dev/radio-sensor.h"
extern resource_t res_radio;
@ -141,11 +147,15 @@ PROCESS_THREAD(er_example_server, ev, data)
rest_activate_resource(&res_light, "sensors/light");
SENSORS_ACTIVATE(light_sensor);
#endif
/*
#if PLATFORM_HAS_BATTERY
rest_activate_resource(&res_battery, "sensors/battery");
SENSORS_ACTIVATE(battery_sensor);
#endif
#if PLATFORM_HAS_TEMPERATURE
rest_activate_resource(&res_temperature, "sensors/temperature");
SENSORS_ACTIVATE(temperature_sensor);
#endif
/*
#if PLATFORM_HAS_RADIO
rest_activate_resource(&res_radio, "sensors/radio");
SENSORS_ACTIVATE(radio_sensor);

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* 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
* Example of an observable "on-change" temperature resource
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
* \author
* Cristiano De Alti <cristiano_dealti@hotmail.com>
*/
#include "contiki.h"
#if PLATFORM_HAS_TEMPERATURE
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "rest-engine.h"
#include "dev/temperature-sensor.h"
static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset);
static void res_periodic_handler(void);
#define MAX_AGE 60
#define INTERVAL_MIN 5
#define INTERVAL_MAX (MAX_AGE - 1)
#define CHANGE 1
static int32_t interval_counter = INTERVAL_MIN;
static int temperature_old = INT_MIN;
PERIODIC_RESOURCE(res_temperature,
"title=\"Temperature\";rt=\"Temperature\";obs",
res_get_handler,
NULL,
NULL,
NULL,
CLOCK_SECOND,
res_periodic_handler);
static void
res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
/*
* For minimal complexity, request query and options should be ignored for GET on observable resources.
* Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers().
* This would be a TODO in the corresponding files in contiki/apps/erbium/!
*/
int temperature = temperature_sensor.value(0);
unsigned int accept = -1;
REST.get_header_accept(request, &accept);
if(accept == -1 || accept == REST.type.TEXT_PLAIN) {
REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", temperature);
REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer));
} else if(accept == REST.type.APPLICATION_JSON) {
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'temperature':%d}", temperature);
REST.set_response_payload(response, buffer, strlen((char *)buffer));
} else {
REST.set_response_status(response, REST.status.NOT_ACCEPTABLE);
const char *msg = "Supporting content-types text/plain and application/json";
REST.set_response_payload(response, msg, strlen(msg));
}
REST.set_header_max_age(response, MAX_AGE);
/* The REST.subscription_handler() will be called for observable resources by the REST framework. */
}
/*
* Additionally, a handler function named [resource name]_handler must be implemented for each PERIODIC_RESOURCE.
* It will be called by the REST manager process with the defined period.
*/
static void
res_periodic_handler()
{
int temperature = temperature_sensor.value(0);
++interval_counter;
if((abs(temperature - temperature_old) >= CHANGE && interval_counter >= INTERVAL_MIN) ||
interval_counter >= INTERVAL_MAX) {
interval_counter = 0;
temperature_old = temperature;
/* Notify the registered observers which will trigger the res_get_handler to create the response. */
REST.notify_subscribers(&res_temperature);
}
}
#endif /* PLATFORM_HAS_TEMPERATURE */

View file

@ -311,7 +311,7 @@ request_prefix(void)
uip_buf[1] = 'P';
uip_len = 2;
slip_send();
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
void

View file

@ -59,7 +59,7 @@ slip_input_callback(void)
// PRINTF("SIN: %u\n", uip_len);
if(uip_buf[0] == '!') {
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
uip_len = 0;
uip_clear_buf();
if(uip_buf[1] == 'P') {
uip_ipaddr_t prefix;
/* Here we set a prefix !!! */
@ -85,7 +85,7 @@ slip_input_callback(void)
slip_send();
}
uip_len = 0;
uip_clear_buf();
}
/* Save the last sender received over SLIP to avoid bouncing the
packet back if no route is found */

View file

@ -162,7 +162,7 @@ slip_input_callback(void)
{
PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]);
cmd_input(uip_buf, uip_len);
uip_len = 0;
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
static void

View file

@ -0,0 +1,5 @@
Examples for the JN516x platform.
* dr1175: simple Contiki application for the DR1175 evaluation board. Prints out sensor values periodically.
* rime: simple Rime example. Works with ContikiMAC (default) or NullRDC
* RPL: RPL examples, including border router, simple node, and coap resources. More information under rpl/README.md

View file

@ -0,0 +1,12 @@
CONTIKI=../../..
CONTIKI_PROJECT = node
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
TARGET ?= jn516x
JN516x_WITH_DR1175 = 1
CONTIKI_WITH_RIME = 1
all: $(CONTIKI_PROJECT)
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,2 @@
Sensor test for DR1175 evaluation board (light + temp/humidity).
Reads and prints out various sensor samples every second.

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* 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.
*
*/
/**
* \author Atis Elsts <atis.elsts@sics.se>
* \file
* Sensor test for DR1175 evaluation board (light + temp/humidity).
*/
#include "contiki.h"
#include "light-sensor.h"
#include "ht-sensor.h"
#include "leds.h"
/*---------------------------------------------------------------------------*/
PROCESS(test_process, "Sensor test process");
AUTOSTART_PROCESSES(&test_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(test_process, ev, data)
{
static struct etimer et;
static uint8_t led_status;
uint8_t r, g, b;
int val;
PROCESS_BEGIN();
puts("initializing sensors...");
/* Make sensor active for measuring */
SENSORS_ACTIVATE(light_sensor);
SENSORS_ACTIVATE(ht_sensor);
/* Set level for LEDSs */
leds_set_level(255, LEDS_RED | LEDS_GREEN | LEDS_BLUE | LEDS_WHITE);
while(1) {
etimer_set(&et, CLOCK_SECOND * 1);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
puts("reading sensors...");
val = ht_sensor.value(HT_SENSOR_HUM);
printf("humidity: %d\n", val);
val = ht_sensor.value(HT_SENSOR_TEMP);
printf("temperature: %d\n", val);
led_status++;
r = ((led_status & 0x1) ? LEDS_RED : 0);
g = ((led_status & 0x2) ? LEDS_GREEN : 0);
b = ((led_status & 0x4) ? LEDS_BLUE : 0);
leds_toggle((leds_get() ^ (r | g | b)) | LEDS_WHITE);
puts("");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* 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.
*
*/
/**
* \author Atis Elsts <atis.elsts@sics.se>
*/
#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__
#undef NETSTACK_CONF_RDC
#undef NETSTACK_CONF_FRAMER
#undef NETSTACK_CONF_MAC
#undef NETSTACK_CONF_NETWORK
#define NETSTACK_CONF_RDC nullrdc_driver
#define NETSTACK_CONF_FRAMER framer_802154
#define NETSTACK_CONF_MAC csma_driver
#define NETSTACK_CONF_NETWORK rime_driver
#endif /* __PROJECT_CONF_H__ */

View file

@ -0,0 +1,11 @@
CONTIKI=../../..
CONTIKI_PROJECT = node
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
TARGET ?= jn516x
CONTIKI_WITH_RIME = 1
all: $(CONTIKI_PROJECT)
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1 @@
A simple Rime + ContikiMAC code example.

124
examples/jn516x/rime/node.c Normal file
View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* 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.
*
*/
/**
* \author Atis Elsts <atis.elsts@sics.se>
* \file
* ContikiMAC + Rime stack test for JN516x platform.
*/
#include "contiki-conf.h"
#include "net/rime/rime.h"
#if 0
#define RX_ADDR1 140
#define RX_ADDR2 228
#else
#define RX_ADDR1 7
#define RX_ADDR2 0
#endif
#define MAX_RETRANSMISSIONS 4
/*---------------------------------------------------------------------------*/
PROCESS(unicast_test_process, "ContikiMAC Node");
AUTOSTART_PROCESSES(&unicast_test_process);
static void
recv_runicast(struct runicast_conn *c, const linkaddr_t *from, uint8_t seqno)
{
printf("runicast message received from %d.%d, seqno %d, len %d: '%s'\n",
from->u8[0], from->u8[1], seqno, packetbuf_datalen(), (char *)packetbuf_dataptr());
}
static void
sent_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions)
{
printf("runicast message sent to %d.%d, retransmissions %d\n",
to->u8[0], to->u8[1], retransmissions);
}
static void
timedout_runicast(struct runicast_conn *c, const linkaddr_t *to, uint8_t retransmissions)
{
printf("runicast message timed out when sending to %d.%d, retransmissions %d\n",
to->u8[0], to->u8[1], retransmissions);
}
static const struct runicast_callbacks runicast_callbacks = { recv_runicast,
sent_runicast,
timedout_runicast };
static struct runicast_conn runicast;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(unicast_test_process, ev, data)
{
PROCESS_BEGIN();
puts("unicast test start");
runicast_open(&runicast, 144, &runicast_callbacks);
/* Receiver node: do nothing */
if(linkaddr_node_addr.u8[0] == RX_ADDR1 &&
linkaddr_node_addr.u8[1] == RX_ADDR2) {
puts("wait forever");
}
while(1) {
static struct etimer et;
static int seqno;
etimer_set(&et, CLOCK_SECOND * 5);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
if(linkaddr_node_addr.u8[0] == RX_ADDR1 &&
linkaddr_node_addr.u8[1] == RX_ADDR2) {
puts("tick...");
continue;
}
if(!runicast_is_transmitting(&runicast)) {
linkaddr_t recv = { 0 };
static char buffer[100] = "hello";
packetbuf_copyfrom(buffer, sizeof(buffer));
recv.u8[0] = RX_ADDR1;
recv.u8[1] = RX_ADDR2;
printf("%u.%u: sending runicast to address %u.%u\n",
linkaddr_node_addr.u8[0],
linkaddr_node_addr.u8[1],
recv.u8[0],
recv.u8[1]);
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, ++seqno);
runicast_send(&runicast, &recv, MAX_RETRANSMISSIONS);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2015, SICS Swedish ICT.
* 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.
*
*/
/**
* \author Atis Elsts <atis.elsts@sics.se>
*/
#ifndef __PROJECT_CONF_H__
#define __PROJECT_CONF_H__
#undef NETSTACK_CONF_RDC
#undef NETSTACK_CONF_FRAMER
#undef NETSTACK_CONF_MAC
#undef NETSTACK_CONF_NETWORK
#if 1
#define NETSTACK_CONF_RDC contikimac_driver
#define NETSTACK_CONF_FRAMER contikimac_framer
#else
#define NETSTACK_CONF_RDC nullrdc_driver
#define NETSTACK_CONF_FRAMER framer_802154
#endif
#define NETSTACK_CONF_MAC csma_driver
#define NETSTACK_CONF_NETWORK rime_driver
#undef UIP_CONF_IPV6
#define UIP_CONF_IPV6 0
#undef RF_CHANNEL
#define RF_CHANNEL 25
#undef MICROMAC_CONF_CHANNEL
#define MICROMAC_CONF_CHANNEL RF_CHANNEL
#undef CC2420_CONF_CHANNEL
#define CC2420_CONF_CHANNEL RF_CHANNEL
#undef MICROMAC_CONF_AUTOACK
#define MICROMAC_CONF_AUTOACK 1
#endif /* __PROJECT_CONF_H__ */

View file

@ -0,0 +1,43 @@
# HOWTO - Setting up the RPL Border router and other nodes
In this folder we have a fully functional demonstrator with the components:
1. **RPL border router**: to start the wireless network and connect it to other networks.
2. and a **wireless node** that acts as a basic RPL node by default (but can optionally be used configured as DAG Root)
## RICH RPL Border Router
Setup the UART flow-control mode for the router from border-router/project-conf.h
* Enable either **HW flow control**
```C
#define UART_HW_FLOW_CTRL 1
#define UART_XONXOFF_FLOW_CTRL 0
```
* or **SW flow control**
```C
#define UART_HW_FLOW_CTRL 0
#define UART_XONXOFF_FLOW_CTRL 1
```
* You can disable both, but it is not recommended.
Compile and flash a node with the rpl-border-router.jn516x.bin image. Either a USB dongle or a dev-board would work.
From a Linux terminal, go to `contiki/examples/jn516x/rpl/border-router` and do either
`make connect-router-hw` if you have **HW flow control**
or `make connect-router-sw` if you have **SW flow control**
This will start a tunnel interface (tun0) on the host machine.
All traffic towards our network (prefix aaaa::1/64) will now be routed to the border router.
## RPL Node
The directory contiki-private/examples/jn516x/rpl/node contains a basic RICH node running TSCH and RPL.
You can compile and program more NXP nodes to run this, forming a larger network.
You should be able to ping the nodes (you can obtain their IPv6 address either directly from their log output
or by enabling DEBUG output in rpl-icmp6.c and looking at DAO prefixes being added.
## RPL+CoAP Nodes
coap-*-node are example nodes that expose their sensors as CoAP resources. See README.md files from the sub-directories
for more details.

View file

@ -0,0 +1,31 @@
CONTIKI_PROJECT = border-router
all: $(CONTIKI_PROJECT)
TARGET ?= jn516x
CONTIKI=../../../..
CONTIKI_WITH_IPV6 = 1
PROJECTDIRS += .. ../tools
PROJECT_SOURCEFILES += rpl-tools.c
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
PROJECT_SOURCEFILES += slip-bridge.c slip.c
ifeq ($(PREFIX),)
PREFIX = aaaa::1/64
endif
include $(CONTIKI)/Makefile.include
#using XON/XOFF flow control
connect-router-sw: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -X -B 1000000 $(PREFIX)
#using hw flow control
connect-router-hw: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -H -B 1000000 $(PREFIX)
#using no flow control
connect-router-no: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -B 1000000 $(PREFIX)

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