Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
fa9c25cdf5
278 changed files with 18909 additions and 1175 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -25,6 +25,7 @@
|
|||
*.c64
|
||||
*.cc2538dk
|
||||
*.remote
|
||||
*.jn516x
|
||||
*.srf06-cc26xx
|
||||
*.ev-aducrf101mkxz
|
||||
*.report
|
||||
|
|
21
.travis.yml
21
.travis.yml
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
---------------------------
|
||||
|
||||
|
|
10
apps/codeprop/Makefile.codeprop-tmp
Normal file
10
apps/codeprop/Makefile.codeprop-tmp
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "er-coap-transactions.h"
|
||||
#include "stimer.h"
|
||||
|
||||
#define COAP_OBSERVER_URL_LEN 20
|
||||
|
||||
typedef struct coap_observable {
|
||||
uint32_t observe_clock;
|
||||
struct stimer orphan_timer;
|
||||
|
@ -54,7 +56,7 @@ typedef struct coap_observable {
|
|||
typedef struct coap_observer {
|
||||
struct coap_observer *next; /* for LIST */
|
||||
|
||||
const char *url;
|
||||
char url[COAP_OBSERVER_URL_LEN];
|
||||
uip_ipaddr_t addr;
|
||||
uint16_t port;
|
||||
uint8_t token_len;
|
||||
|
@ -68,11 +70,6 @@ typedef struct coap_observer {
|
|||
} coap_observer_t;
|
||||
|
||||
list_t coap_get_observers(void);
|
||||
|
||||
coap_observer_t *coap_add_observer(uip_ipaddr_t *addr, uint16_t port,
|
||||
const uint8_t *token, size_t token_len,
|
||||
const char *url);
|
||||
|
||||
void coap_remove_observer(coap_observer_t *o);
|
||||
int coap_remove_observer_by_client(uip_ipaddr_t *addr, uint16_t port);
|
||||
int coap_remove_observer_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||
|
@ -83,6 +80,7 @@ int coap_remove_observer_by_mid(uip_ipaddr_t *addr, uint16_t port,
|
|||
uint16_t mid);
|
||||
|
||||
void coap_notify_observers(resource_t *resource);
|
||||
void coap_notify_observers_sub(resource_t *resource, const char *subpath);
|
||||
|
||||
void coap_observe_handler(resource_t *resource, void *request,
|
||||
void *response);
|
||||
|
|
|
@ -124,7 +124,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
continue;
|
||||
}
|
||||
end = attrib + strlen(attrib);
|
||||
} else {
|
||||
} else if(resource->attributes != NULL) {
|
||||
attrib = strstr(resource->attributes, filter);
|
||||
if(attrib == NULL
|
||||
|| (attrib[strlen(filter)] != '='
|
||||
|
@ -159,8 +159,8 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
#endif
|
||||
|
||||
PRINTF("res: /%s (%p)\npos: s%d, o%ld, b%d\n", resource->url, resource,
|
||||
strpos, *offset, bufpos);
|
||||
PRINTF("res: /%s (%p)\npos: s%zu, o%ld, b%zu\n", resource->url, resource,
|
||||
strpos, (long)*offset, bufpos);
|
||||
|
||||
if(strpos > 0) {
|
||||
ADD_CHAR_IF_POSSIBLE(',');
|
||||
|
@ -170,7 +170,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
ADD_STRING_IF_POSSIBLE(resource->url, >=);
|
||||
ADD_CHAR_IF_POSSIBLE('>');
|
||||
|
||||
if(resource->attributes[0]) {
|
||||
if(resource->attributes != NULL && resource->attributes[0]) {
|
||||
ADD_CHAR_IF_POSSIBLE(';');
|
||||
ADD_STRING_IF_POSSIBLE(resource->attributes, >);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ well_known_core_get_handler(void *request, void *response, uint8_t *buffer,
|
|||
}
|
||||
|
||||
if(bufpos > 0) {
|
||||
PRINTF("BUF %d: %.*s\n", bufpos, bufpos, (char *)buffer);
|
||||
PRINTF("BUF %zu: %.*s\n", bufpos, (int)bufpos, (char *)buffer);
|
||||
|
||||
coap_set_payload(response, buffer, bufpos);
|
||||
coap_set_header_content_format(response, APPLICATION_LINK_FORMAT);
|
||||
|
|
|
@ -113,15 +113,9 @@ coap_send_transaction(coap_transaction_t *t)
|
|||
(float)t->retrans_timer.timer.interval / CLOCK_SECOND);
|
||||
}
|
||||
|
||||
/*FIXME
|
||||
* Hack: Setting timer for responsible process.
|
||||
* Maybe there is a better way, but avoid posting everything to the process.
|
||||
*/
|
||||
struct process *process_actual = PROCESS_CURRENT();
|
||||
|
||||
process_current = transaction_handler_process;
|
||||
PROCESS_CONTEXT_BEGIN(transaction_handler_process);
|
||||
etimer_restart(&t->retrans_timer); /* interval updated above */
|
||||
process_current = process_actual;
|
||||
PROCESS_CONTEXT_END(transaction_handler_process);
|
||||
|
||||
t = NULL;
|
||||
} else {
|
||||
|
|
|
@ -113,19 +113,21 @@ coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
|
|||
|
||||
buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
|
||||
|
||||
/* avoids code duplication without function overhead */
|
||||
unsigned int *x = δ
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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; \
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
810
core/loader/elfloader-msp430x.c
Normal file
810
core/loader/elfloader-msp430x.c
Normal 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;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -1383,8 +1383,7 @@ out()
|
|||
|
||||
drop:
|
||||
uip_slen = 0;
|
||||
uip_len = 0;
|
||||
uip_ext_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ packetbuf_copyto(void *to)
|
|||
int i;
|
||||
char buffer[1000];
|
||||
char *bufferptr = buffer;
|
||||
int bufferlen = 0;
|
||||
|
||||
bufferptr[0] = 0;
|
||||
for(i = hdrptr; i < PACKETBUF_HDR_SIZE; ++i) {
|
||||
|
@ -149,8 +150,8 @@ packetbuf_copyto(void *to)
|
|||
PRINTF("packetbuf_write: header: %s\n", buffer);
|
||||
bufferptr = buffer;
|
||||
bufferptr[0] = 0;
|
||||
for(i = bufptr; i < buflen + bufptr; ++i) {
|
||||
bufferptr += sprintf(bufferptr, "0x%02x, ", packetbufptr[i]);
|
||||
for(i = bufptr; ((i < buflen + bufptr) && (bufferlen < (sizeof(buffer) - 10))); ++i) {
|
||||
bufferlen += sprintf(bufferptr + bufferlen, "0x%02x, ", packetbufptr[i]);
|
||||
}
|
||||
PRINTF("packetbuf_write: data: %s\n", buffer);
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ int
|
|||
route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
|
||||
uint8_t cost, uint8_t seqno)
|
||||
{
|
||||
struct route_entry *e;
|
||||
struct route_entry *e, *oldest = NULL;
|
||||
|
||||
/* Avoid inserting duplicate entries. */
|
||||
e = route_lookup(dest);
|
||||
|
@ -131,8 +131,14 @@ route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
|
|||
/* Allocate a new entry or reuse the oldest entry with highest cost. */
|
||||
e = memb_alloc(&route_mem);
|
||||
if(e == NULL) {
|
||||
/* Remove oldest entry. XXX */
|
||||
e = list_chop(route_table);
|
||||
/* Remove oldest entry. */
|
||||
for(e = list_head(route_table); e != NULL; e = list_item_next(e)) {
|
||||
if(oldest == NULL || e->time >= oldest->time) {
|
||||
oldest = e;
|
||||
}
|
||||
}
|
||||
e = oldest;
|
||||
list_remove(route_table, e);
|
||||
PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
|
||||
e->dest.u8[0], e->dest.u8[1],
|
||||
e->nexthop.u8[0], e->nexthop.u8[1],
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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 $^ $@
|
||||
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
208
cpu/native/net/linuxradio-drv.c
Normal file
208
cpu/native/net/linuxradio-drv.c
Normal 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
|
|
@ -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
|
|
@ -83,7 +83,7 @@ pollhandler(void)
|
|||
}
|
||||
#endif
|
||||
} else {
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 !!! */
|
||||
|
|
8
examples/econotag-ecc-test/Makefile
Normal file
8
examples/econotag-ecc-test/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
CONTIKI = ../..
|
||||
TARGET = econotag
|
||||
|
||||
all: econotag-ecc-test
|
||||
|
||||
APPS += ecc
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
2182
examples/econotag-ecc-test/econotag-ecc-test.c
Normal file
2182
examples/econotag-ecc-test/econotag-ecc-test.c
Normal file
File diff suppressed because it is too large
Load diff
31
examples/econotag-flash-test/Makefile
Normal file
31
examples/econotag-flash-test/Makefile
Normal 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
|
6
examples/econotag-flash-test/README
Normal file
6
examples/econotag-flash-test/README
Normal 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.
|
195
examples/econotag-flash-test/econotag-flash-test.c
Normal file
195
examples/econotag-flash-test/econotag-flash-test.c
Normal 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();
|
||||
}
|
7
examples/econotag-flash-test/econotag-flash-test.cfg
Normal file
7
examples/econotag-flash-test/econotag-flash-test.cfg
Normal 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";
|
66
examples/econotag-flash-test/econotag-flash-test.h
Normal file
66
examples/econotag-flash-test/econotag-flash-test.h
Normal 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_ */
|
15
examples/er-rest-example-raven/Makefile
Normal file
15
examples/er-rest-example-raven/Makefile
Normal 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) ***"
|
||||
|
|
@ -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);
|
||||
|
|
125
examples/er-rest-example/resources/res-temperature.c
Normal file
125
examples/er-rest-example/resources/res-temperature.c
Normal 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 */
|
|
@ -311,7 +311,7 @@ request_prefix(void)
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_send();
|
||||
uip_len = 0;
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
5
examples/jn516x/README.md
Normal file
5
examples/jn516x/README.md
Normal 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
|
||||
|
12
examples/jn516x/dr1175-sensors/Makefile
Normal file
12
examples/jn516x/dr1175-sensors/Makefile
Normal 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
|
2
examples/jn516x/dr1175-sensors/README.md
Normal file
2
examples/jn516x/dr1175-sensors/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
Sensor test for DR1175 evaluation board (light + temp/humidity).
|
||||
Reads and prints out various sensor samples every second.
|
88
examples/jn516x/dr1175-sensors/node.c
Normal file
88
examples/jn516x/dr1175-sensors/node.c
Normal 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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
47
examples/jn516x/dr1175-sensors/project-conf.h
Normal file
47
examples/jn516x/dr1175-sensors/project-conf.h
Normal 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__ */
|
11
examples/jn516x/rime/Makefile
Normal file
11
examples/jn516x/rime/Makefile
Normal 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
|
1
examples/jn516x/rime/README.md
Normal file
1
examples/jn516x/rime/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
A simple Rime + ContikiMAC code example.
|
124
examples/jn516x/rime/node.c
Normal file
124
examples/jn516x/rime/node.c
Normal 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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
68
examples/jn516x/rime/project-conf.h
Normal file
68
examples/jn516x/rime/project-conf.h
Normal 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__ */
|
43
examples/jn516x/rpl/README.md
Normal file
43
examples/jn516x/rpl/README.md
Normal 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.
|
31
examples/jn516x/rpl/border-router/Makefile
Normal file
31
examples/jn516x/rpl/border-router/Makefile
Normal 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
Loading…
Reference in a new issue