Merge branch 'master' of git://github.com/contiki-os/contiki into ds6_period_configurable
This commit is contained in:
commit
446208dc1c
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
||||||
[submodule "tools/mspsim"]
|
[submodule "tools/mspsim"]
|
||||||
path = tools/mspsim
|
path = tools/mspsim
|
||||||
url = https://github.com/contiki-os/mspsim.git
|
url = https://github.com/contiki-os/mspsim.git
|
||||||
|
[submodule "tools/cc2538-bsl"]
|
||||||
|
path = tools/cc2538-bsl
|
||||||
|
url = https://github.com/JelmerT/cc2538-bsl.git
|
||||||
|
|
|
@ -29,7 +29,7 @@ before_script:
|
||||||
|
|
||||||
## Clone and build cc65 when testing 6502 ports
|
## Clone and build cc65 when testing 6502 ports
|
||||||
- "[ ${BUILD_ARCH:-0} = 6502 ] && git clone \
|
- "[ ${BUILD_ARCH:-0} = 6502 ] && git clone \
|
||||||
https://github.com/oliverschmidt/cc65 /tmp/cc65 && \
|
https://github.com/cc65/cc65 /tmp/cc65 && \
|
||||||
make -C /tmp/cc65 bin apple2enh atarixl c64 c128 && sudo make -C /tmp/cc65 avail && \
|
make -C /tmp/cc65 bin apple2enh atarixl c64 c128 && sudo make -C /tmp/cc65 avail && \
|
||||||
export CC65_HOME=/tmp/cc65/ && cc65 --version || true"
|
export CC65_HOME=/tmp/cc65/ && cc65 --version || true"
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ CFLAGS += ${addprefix -I,$(SOURCEDIRS) $(CONTIKI)}
|
||||||
### Check for a git repo and pass version if found
|
### Check for a git repo and pass version if found
|
||||||
### git.exe in Windows cmd shells may require no stderr redirection
|
### git.exe in Windows cmd shells may require no stderr redirection
|
||||||
#RELSTR=${shell git describe --tags}
|
#RELSTR=${shell git describe --tags}
|
||||||
RELSTR=${shell git describe --tags 2>/dev/null}
|
RELSTR=${shell git --git-dir ${CONTIKI}/.git describe --tags 2>/dev/null}
|
||||||
ifneq ($(RELSTR),)
|
ifneq ($(RELSTR),)
|
||||||
CFLAGS += -DCONTIKI_VERSION_STRING=\"Contiki-$(RELSTR)\"
|
CFLAGS += -DCONTIKI_VERSION_STRING=\"Contiki-$(RELSTR)\"
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -115,6 +115,13 @@ struct jsontree_array {
|
||||||
JSON_TYPE_OBJECT, \
|
JSON_TYPE_OBJECT, \
|
||||||
sizeof(jsontree_pair_##name)/sizeof(struct jsontree_pair), \
|
sizeof(jsontree_pair_##name)/sizeof(struct jsontree_pair), \
|
||||||
jsontree_pair_##name }
|
jsontree_pair_##name }
|
||||||
|
|
||||||
|
#define JSONTREE_ARRAY(name, count) \
|
||||||
|
static struct jsontree_value *jsontree_value##name[count]; \
|
||||||
|
static struct jsontree_array name = { \
|
||||||
|
JSON_TYPE_ARRAY, \
|
||||||
|
count, \
|
||||||
|
jsontree_value##name }
|
||||||
|
|
||||||
void jsontree_setup(struct jsontree_context *js_ctx,
|
void jsontree_setup(struct jsontree_context *js_ctx,
|
||||||
struct jsontree_value *root, int (* putchar)(int));
|
struct jsontree_value *root, int (* putchar)(int));
|
||||||
|
|
|
@ -1155,6 +1155,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
int i;
|
int i;
|
||||||
struct log_param lp;
|
struct log_param lp;
|
||||||
cfs_offset_t bytes_left;
|
cfs_offset_t bytes_left;
|
||||||
|
int8_t need_dummy_write;
|
||||||
const char dummy[1] = { 0xff };
|
const char dummy[1] = { 0xff };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1188,6 +1189,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
#else
|
#else
|
||||||
if(FILE_MODIFIED(file) || fdp->offset < file->end) {
|
if(FILE_MODIFIED(file) || fdp->offset < file->end) {
|
||||||
#endif
|
#endif
|
||||||
|
need_dummy_write = 0;
|
||||||
for(bytes_left = size; bytes_left > 0;) {
|
for(bytes_left = size; bytes_left > 0;) {
|
||||||
lp.offset = fdp->offset;
|
lp.offset = fdp->offset;
|
||||||
lp.buf = buf;
|
lp.buf = buf;
|
||||||
|
@ -1212,13 +1214,19 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
occur while writing log records. */
|
occur while writing log records. */
|
||||||
if(fdp->offset > file->end) {
|
if(fdp->offset > file->end) {
|
||||||
file->end = fdp->offset;
|
file->end = fdp->offset;
|
||||||
|
need_dummy_write = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fdp->offset > file->end) {
|
if(need_dummy_write) {
|
||||||
/* Update the original file's end with a dummy write. */
|
/*
|
||||||
COFFEE_WRITE(dummy, 1, absolute_offset(file->page, fdp->offset));
|
* A log record has been written at an offset beyond the original
|
||||||
|
* extent's end. Consequently, we need to write a dummy value at the
|
||||||
|
* corresponding end offset in the original extent to ensure that
|
||||||
|
* the correct file size is calculated when opening the file again.
|
||||||
|
*/
|
||||||
|
COFFEE_WRITE(dummy, 1, absolute_offset(file->page, fdp->offset - 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif /* COFFEE_MICRO_LOGS */
|
#endif /* COFFEE_MICRO_LOGS */
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
|
|
||||||
#include "net/ip/psock.h"
|
#include "net/ip/psock.h"
|
||||||
|
|
||||||
|
#include "net/ip/udp-socket.h"
|
||||||
|
#include "net/ip/tcp-socket.h"
|
||||||
|
|
||||||
#include "net/rime/rime.h"
|
#include "net/rime/rime.h"
|
||||||
|
|
||||||
#include "net/netstack.h"
|
#include "net/netstack.h"
|
||||||
|
|
|
@ -82,10 +82,11 @@ void spi_init(void);
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Flush the SPI read register */
|
/* Flush the SPI read register */
|
||||||
|
#ifndef SPI_FLUSH
|
||||||
#define SPI_FLUSH() \
|
#define SPI_FLUSH() \
|
||||||
do { \
|
do { \
|
||||||
SPI_RXBUF; \
|
SPI_RXBUF; \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* SPI_H_ */
|
#endif /* SPI_H_ */
|
||||||
|
|
365
core/net/ip/tcp-socket.c
Normal file
365
core/net/ip/tcp-socket.c
Normal file
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
|
||||||
|
#include "lib/list.h"
|
||||||
|
|
||||||
|
#include "tcp-socket.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
LIST(socketlist);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS(tcp_socket_process, "TCP socket process");
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
call_event(struct tcp_socket *s, tcp_socket_event_t event)
|
||||||
|
{
|
||||||
|
if(s != NULL && s->event_callback != NULL) {
|
||||||
|
s->event_callback(s, s->ptr, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
senddata(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(s->output_data_len > 0) {
|
||||||
|
len = MIN(s->output_data_len, uip_mss());
|
||||||
|
s->output_data_send_nxt = len;
|
||||||
|
uip_send(s->output_data_ptr, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
acked(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
if(s->output_data_len > 0) {
|
||||||
|
/* Copy the data in the outputbuf down and update outputbufptr and
|
||||||
|
outputbuf_lastsent */
|
||||||
|
|
||||||
|
if(s->output_data_send_nxt > 0) {
|
||||||
|
memcpy(&s->output_data_ptr[0],
|
||||||
|
&s->output_data_ptr[s->output_data_send_nxt],
|
||||||
|
s->output_data_maxlen - s->output_data_send_nxt);
|
||||||
|
}
|
||||||
|
if(s->output_data_len < s->output_data_send_nxt) {
|
||||||
|
printf("tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n",
|
||||||
|
s->output_data_len,
|
||||||
|
s->output_data_send_nxt);
|
||||||
|
}
|
||||||
|
s->output_data_len -= s->output_data_send_nxt;
|
||||||
|
s->output_data_send_nxt = 0;
|
||||||
|
|
||||||
|
call_event(s, TCP_SOCKET_DATA_SENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
newdata(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
uint16_t len, copylen, bytesleft;
|
||||||
|
uint8_t *dataptr;
|
||||||
|
len = uip_datalen();
|
||||||
|
dataptr = uip_appdata;
|
||||||
|
|
||||||
|
/* We have a segment with data coming in. We copy as much data as
|
||||||
|
possible into the input buffer and call the input callback
|
||||||
|
function. The input callback returns the number of bytes that
|
||||||
|
should be retained in the buffer, or zero if all data should be
|
||||||
|
consumed. If there is data to be retained, the highest bytes of
|
||||||
|
data are copied down into the input buffer. */
|
||||||
|
do {
|
||||||
|
copylen = MIN(len, s->input_data_maxlen);
|
||||||
|
memcpy(s->input_data_ptr, dataptr, copylen);
|
||||||
|
if(s->input_callback) {
|
||||||
|
bytesleft = s->input_callback(s, s->ptr,
|
||||||
|
s->input_data_ptr, copylen);
|
||||||
|
} else {
|
||||||
|
bytesleft = 0;
|
||||||
|
}
|
||||||
|
if(bytesleft > 0) {
|
||||||
|
printf("tcp: newdata, bytesleft > 0 (%d) not implemented\n", bytesleft);
|
||||||
|
}
|
||||||
|
dataptr += copylen;
|
||||||
|
len -= copylen;
|
||||||
|
|
||||||
|
} while(len > 0);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
relisten(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
if(s != NULL && s->listen_port != 0) {
|
||||||
|
s->flags |= TCP_SOCKET_FLAGS_LISTENING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
appcall(void *state)
|
||||||
|
{
|
||||||
|
struct tcp_socket *s = state;
|
||||||
|
|
||||||
|
if(uip_connected()) {
|
||||||
|
/* Check if this connection originated in a local listen
|
||||||
|
socket. We do this by checking the state pointer - if NULL,
|
||||||
|
this is an incoming listen connection. If so, we need to
|
||||||
|
connect the socket to the uip_conn and call the event
|
||||||
|
function. */
|
||||||
|
if(s == NULL) {
|
||||||
|
for(s = list_head(socketlist);
|
||||||
|
s != NULL;
|
||||||
|
s = list_item_next(s)) {
|
||||||
|
if((s->flags & TCP_SOCKET_FLAGS_LISTENING) != 0 &&
|
||||||
|
s->listen_port != 0 &&
|
||||||
|
s->listen_port == uip_htons(uip_conn->lport)) {
|
||||||
|
s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
|
||||||
|
tcp_markconn(uip_conn, s);
|
||||||
|
call_event(s, TCP_SOCKET_CONNECTED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
call_event(s, TCP_SOCKET_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s == NULL) {
|
||||||
|
uip_abort();
|
||||||
|
} else {
|
||||||
|
if(uip_newdata()) {
|
||||||
|
newdata(s);
|
||||||
|
}
|
||||||
|
senddata(s);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uip_timedout()) {
|
||||||
|
call_event(s, TCP_SOCKET_TIMEDOUT);
|
||||||
|
relisten(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uip_aborted()) {
|
||||||
|
call_event(s, TCP_SOCKET_ABORTED);
|
||||||
|
relisten(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s == NULL) {
|
||||||
|
uip_abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uip_acked()) {
|
||||||
|
acked(s);
|
||||||
|
}
|
||||||
|
if(uip_newdata()) {
|
||||||
|
newdata(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uip_rexmit() ||
|
||||||
|
uip_newdata() ||
|
||||||
|
uip_acked()) {
|
||||||
|
senddata(s);
|
||||||
|
} else if(uip_poll()) {
|
||||||
|
senddata(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s->output_data_len == 0 && s->flags & TCP_SOCKET_FLAGS_CLOSING) {
|
||||||
|
s->flags &= ~TCP_SOCKET_FLAGS_CLOSING;
|
||||||
|
uip_close();
|
||||||
|
tcp_markconn(uip_conn, NULL);
|
||||||
|
call_event(s, TCP_SOCKET_CLOSED);
|
||||||
|
relisten(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uip_closed()) {
|
||||||
|
tcp_markconn(uip_conn, NULL);
|
||||||
|
call_event(s, TCP_SOCKET_CLOSED);
|
||||||
|
relisten(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(tcp_socket_process, ev, data)
|
||||||
|
{
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
while(1) {
|
||||||
|
PROCESS_WAIT_EVENT();
|
||||||
|
|
||||||
|
if(ev == tcpip_event) {
|
||||||
|
appcall(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
static uint8_t inited = 0;
|
||||||
|
if(!inited) {
|
||||||
|
list_init(socketlist);
|
||||||
|
process_start(&tcp_socket_process, NULL);
|
||||||
|
inited = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_register(struct tcp_socket *s, void *ptr,
|
||||||
|
uint8_t *input_databuf, int input_databuf_len,
|
||||||
|
uint8_t *output_databuf, int output_databuf_len,
|
||||||
|
tcp_socket_data_callback_t input_callback,
|
||||||
|
tcp_socket_event_callback_t event_callback)
|
||||||
|
{
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
s->ptr = ptr;
|
||||||
|
s->input_data_ptr = input_databuf;
|
||||||
|
s->input_data_maxlen = input_databuf_len;
|
||||||
|
s->output_data_ptr = output_databuf;
|
||||||
|
s->output_data_maxlen = output_databuf_len;
|
||||||
|
s->input_callback = input_callback;
|
||||||
|
s->event_callback = event_callback;
|
||||||
|
list_add(socketlist, s);
|
||||||
|
|
||||||
|
s->listen_port = 0;
|
||||||
|
s->flags = TCP_SOCKET_FLAGS_NONE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_connect(struct tcp_socket *s,
|
||||||
|
uip_ipaddr_t *ipaddr,
|
||||||
|
uint16_t port)
|
||||||
|
{
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PROCESS_CONTEXT_BEGIN(&tcp_socket_process);
|
||||||
|
s->c = tcp_connect(ipaddr, uip_htons(port), s);
|
||||||
|
PROCESS_CONTEXT_END();
|
||||||
|
if(s->c == NULL) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_listen(struct tcp_socket *s,
|
||||||
|
uint16_t port)
|
||||||
|
{
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->listen_port = port;
|
||||||
|
PROCESS_CONTEXT_BEGIN(&tcp_socket_process);
|
||||||
|
tcp_listen(uip_htons(port));
|
||||||
|
PROCESS_CONTEXT_END();
|
||||||
|
s->flags |= TCP_SOCKET_FLAGS_LISTENING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_unlisten(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_CONTEXT_BEGIN(&tcp_socket_process);
|
||||||
|
tcp_unlisten(uip_htons(s->listen_port));
|
||||||
|
PROCESS_CONTEXT_END();
|
||||||
|
s->listen_port = 0;
|
||||||
|
s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_send(struct tcp_socket *s,
|
||||||
|
const uint8_t *data, int datalen)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = MIN(datalen, s->output_data_maxlen - s->output_data_len);
|
||||||
|
|
||||||
|
memcpy(&s->output_data_ptr[s->output_data_len], data, len);
|
||||||
|
s->output_data_len += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_send_str(struct tcp_socket *s,
|
||||||
|
const char *str)
|
||||||
|
{
|
||||||
|
return tcp_socket_send(s, (const uint8_t *)str, strlen(str));
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_close(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->flags |= TCP_SOCKET_FLAGS_CLOSING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
tcp_socket_unregister(struct tcp_socket *s)
|
||||||
|
{
|
||||||
|
if(s == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp_socket_unlisten(s);
|
||||||
|
if(s->c != NULL) {
|
||||||
|
tcp_attach(s->c, NULL);
|
||||||
|
}
|
||||||
|
list_remove(socketlist, s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
268
core/net/ip/tcp-socket.h
Normal file
268
core/net/ip/tcp-socket.h
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TCP_SOCKET_H
|
||||||
|
#define TCP_SOCKET_H
|
||||||
|
|
||||||
|
struct tcp_socket;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TCP_SOCKET_CONNECTED,
|
||||||
|
TCP_SOCKET_CLOSED,
|
||||||
|
TCP_SOCKET_TIMEDOUT,
|
||||||
|
TCP_SOCKET_ABORTED,
|
||||||
|
TCP_SOCKET_DATA_SENT
|
||||||
|
} tcp_socket_event_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief TCP data callback function
|
||||||
|
* \param s A pointer to a TCP socket
|
||||||
|
* \param ptr A user-defined pointer
|
||||||
|
* \param input_data_ptr A pointer to the incoming data
|
||||||
|
* \param input_data_len The length of the incoming data
|
||||||
|
* \return The function should return the number of bytes to leave in the input buffer
|
||||||
|
*
|
||||||
|
* The TCP socket input callback function gets
|
||||||
|
* called whenever there is new data on the socket. The
|
||||||
|
* function can choose to either consume the data
|
||||||
|
* directly, or leave it in the buffer for later. The
|
||||||
|
* function must return the amount of data to leave in the
|
||||||
|
* buffer. I.e., if the callback function consumes all
|
||||||
|
* incoming data, it should return 0.
|
||||||
|
*/
|
||||||
|
typedef int (* tcp_socket_data_callback_t)(struct tcp_socket *s,
|
||||||
|
void *ptr,
|
||||||
|
const uint8_t *input_data_ptr,
|
||||||
|
int input_data_len);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief TCP event callback function
|
||||||
|
* \param s A pointer to a TCP socket
|
||||||
|
* \param ptr A user-defined pointer
|
||||||
|
* \param event The event number
|
||||||
|
*
|
||||||
|
* The TCP socket event callback function gets
|
||||||
|
* called whenever there is an event on a socket, such as
|
||||||
|
* the socket getting connected or closed.
|
||||||
|
*/
|
||||||
|
typedef void (* tcp_socket_event_callback_t)(struct tcp_socket *s,
|
||||||
|
void *ptr,
|
||||||
|
tcp_socket_event_t event);
|
||||||
|
|
||||||
|
struct tcp_socket {
|
||||||
|
struct tcp_socket *next;
|
||||||
|
|
||||||
|
tcp_socket_data_callback_t input_callback;
|
||||||
|
tcp_socket_event_callback_t event_callback;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
struct process *p;
|
||||||
|
|
||||||
|
uint8_t *input_data_ptr;
|
||||||
|
uint8_t *output_data_ptr;
|
||||||
|
|
||||||
|
uint16_t input_data_maxlen;
|
||||||
|
uint16_t input_data_len;
|
||||||
|
uint16_t output_data_maxlen;
|
||||||
|
uint16_t output_data_len;
|
||||||
|
uint16_t output_data_send_nxt;
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t listen_port;
|
||||||
|
struct uip_conn *c;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TCP_SOCKET_FLAGS_NONE = 0x00,
|
||||||
|
TCP_SOCKET_FLAGS_LISTENING = 0x01,
|
||||||
|
TCP_SOCKET_FLAGS_CLOSING = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Register a TCP socket
|
||||||
|
* \param s A pointer to a TCP socket
|
||||||
|
* \param ptr A user-defined pointer that will be sent to callbacks for this socket
|
||||||
|
* \param input_databuf A pointer to a memory area this socket will use for input data
|
||||||
|
* \param input_databuf_len The size of the input data buffer
|
||||||
|
* \param output_databuf A pointer to a memory area this socket will use for outgoing data
|
||||||
|
* \param output_databuf_len The size of the output data buffer
|
||||||
|
* \param data_callback A pointer to the data callback function for this socket
|
||||||
|
* \param event_callback A pointer to the event callback function for this socket
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function registers a TCP socket. The function sets
|
||||||
|
* up the output and input buffers for the socket and
|
||||||
|
* callback pointers.
|
||||||
|
*
|
||||||
|
* TCP sockets use input and output buffers for incoming
|
||||||
|
* and outgoing data. The memory for these buffers must be
|
||||||
|
* allocated by the caller. The size of the buffers
|
||||||
|
* determine the amount of data that can be received and
|
||||||
|
* sent, and the principle is that the application that
|
||||||
|
* sets up the TCP socket will know roughly how large
|
||||||
|
* these buffers should be. The rule of thumb is that the
|
||||||
|
* input buffer should be large enough to hold the largest
|
||||||
|
* application layer message that the application will
|
||||||
|
* receive and the output buffer should be large enough to
|
||||||
|
* hold the largest application layer message the
|
||||||
|
* application will send.
|
||||||
|
*
|
||||||
|
* TCP throttles incoming data so that if the input buffer
|
||||||
|
* is filled, the connection will halt until the
|
||||||
|
* application has read out the data from the input
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_register(struct tcp_socket *s, void *ptr,
|
||||||
|
uint8_t *input_databuf, int input_databuf_len,
|
||||||
|
uint8_t *output_databuf, int output_databuf_len,
|
||||||
|
tcp_socket_data_callback_t data_callback,
|
||||||
|
tcp_socket_event_callback_t event_callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Connect a TCP socket to a remote host
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \param ipaddr The IP address of the remote host
|
||||||
|
* \param port The TCP port number, in host byte order, of the remote host
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function connects a TCP socket to a remote host.
|
||||||
|
*
|
||||||
|
* When the socket has connected, the event callback will
|
||||||
|
* get called with the TCP_SOCKET_CONNECTED event. If the
|
||||||
|
* remote host does not accept the connection, the
|
||||||
|
* TCP_SOCKET_ABORTED will be sent to the callback. If the
|
||||||
|
* connection times out before conecting to the remote
|
||||||
|
* host, the TCP_SOCKET_TIMEDOUT event is sent to the
|
||||||
|
* callback.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_connect(struct tcp_socket *s,
|
||||||
|
uip_ipaddr_t *ipaddr,
|
||||||
|
uint16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Start listening on a specific port
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \param port The TCP port number, in host byte order, of the remote host
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function causes the TCP socket to start listening
|
||||||
|
* on the given TCP port.
|
||||||
|
*
|
||||||
|
* Several sockets can listen on the same port. If a
|
||||||
|
* remote host connects to the port, one of the listening
|
||||||
|
* sockets will get connected and the event callback will
|
||||||
|
* be called with the TCP_SOCKET_CONNECTED event. When the
|
||||||
|
* connection closes, the socket will go back to listening
|
||||||
|
* for new connections.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_listen(struct tcp_socket *s,
|
||||||
|
uint16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Stop listening for new connections
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function causes a listening TCP socket to stop
|
||||||
|
* listen. The socket must previously been put into listen
|
||||||
|
* mode with tcp_socket_listen().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_unlisten(struct tcp_socket *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send data on a connected TCP socket
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \param dataptr A pointer to the data to be sent
|
||||||
|
* \param datalen The length of the data to be sent
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \return The number of bytes that were successfully sent
|
||||||
|
*
|
||||||
|
* This function sends data over a connected TCP
|
||||||
|
* socket. The data is placed in the output buffer and
|
||||||
|
* sent to the remote host as soon as possiblce. When the
|
||||||
|
* data has been acknowledged by the remote host, the
|
||||||
|
* event callback is sent with the TCP_SOCKET_DATA_SENT
|
||||||
|
* event.
|
||||||
|
*/
|
||||||
|
int tcp_socket_send(struct tcp_socket *s,
|
||||||
|
const uint8_t *dataptr,
|
||||||
|
int datalen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a string on a connected TCP socket
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \param strptr A pointer to the string to be sent
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \return The number of bytes that were successfully sent
|
||||||
|
*
|
||||||
|
* This is a convenience function for sending strings on a
|
||||||
|
* TCP socket. The function calls tcp_socket_send() to
|
||||||
|
* send the string.
|
||||||
|
*/
|
||||||
|
int tcp_socket_send_str(struct tcp_socket *s,
|
||||||
|
const char *strptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Close a connected TCP socket
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function closes a connected TCP socket. When the
|
||||||
|
* socket has been successfully closed, the event callback
|
||||||
|
* is called with the TCP_SOCKET_CLOSED event.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_close(struct tcp_socket *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unregister a registered socket
|
||||||
|
* \param s A pointer to a TCP socket that must have been previously registered with tcp_socket_register()
|
||||||
|
* \retval -1 If an error occurs
|
||||||
|
* \retval 1 If the operation succeeds.
|
||||||
|
*
|
||||||
|
* This function unregisters a previously registered
|
||||||
|
* socket. This must be done if the process will be
|
||||||
|
* unloaded from memory. If the TCP socket is connected,
|
||||||
|
* the connection will be reset.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int tcp_socket_unregister(struct tcp_socket *s);
|
||||||
|
#endif /* TCP_SOCKET_H */
|
199
core/net/ip/udp-socket.c
Normal file
199
core/net/ip/udp-socket.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "udp-socket.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
PROCESS(udp_socket_process, "UDP socket process");
|
||||||
|
|
||||||
|
static uint8_t buf[UIP_BUFSIZE];
|
||||||
|
|
||||||
|
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
static uint8_t inited = 0;
|
||||||
|
if(!inited) {
|
||||||
|
inited = 1;
|
||||||
|
process_start(&udp_socket_process, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_register(struct udp_socket *c,
|
||||||
|
void *ptr,
|
||||||
|
udp_socket_input_callback_t input_callback)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
if(c == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c->ptr = ptr;
|
||||||
|
c->input_callback = input_callback;
|
||||||
|
|
||||||
|
c->p = PROCESS_CURRENT();
|
||||||
|
PROCESS_CONTEXT_BEGIN(&udp_socket_process);
|
||||||
|
c->udp_conn = udp_new(NULL, 0, c);
|
||||||
|
PROCESS_CONTEXT_END();
|
||||||
|
|
||||||
|
if(c->udp_conn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_close(struct udp_socket *c)
|
||||||
|
{
|
||||||
|
if(c == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(c->udp_conn != NULL) {
|
||||||
|
uip_udp_remove(c->udp_conn);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_bind(struct udp_socket *c,
|
||||||
|
uint16_t local_port)
|
||||||
|
{
|
||||||
|
if(c == NULL || c->udp_conn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
udp_bind(c->udp_conn, UIP_HTONS(local_port));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_connect(struct udp_socket *c,
|
||||||
|
uip_ipaddr_t *remote_addr,
|
||||||
|
uint16_t remote_port)
|
||||||
|
{
|
||||||
|
if(c == NULL || c->udp_conn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(remote_addr != NULL) {
|
||||||
|
uip_ipaddr_copy(&c->udp_conn->ripaddr, remote_addr);
|
||||||
|
}
|
||||||
|
c->udp_conn->rport = UIP_HTONS(remote_port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_send(struct udp_socket *c,
|
||||||
|
const void *data, uint16_t datalen)
|
||||||
|
{
|
||||||
|
if(c == NULL || c->udp_conn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uip_udp_packet_send(c->udp_conn, data, datalen);
|
||||||
|
return datalen;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
udp_socket_sendto(struct udp_socket *c,
|
||||||
|
const void *data, uint16_t datalen,
|
||||||
|
const uip_ipaddr_t *to,
|
||||||
|
uint16_t port)
|
||||||
|
{
|
||||||
|
if(c == NULL || c->udp_conn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->udp_conn != NULL) {
|
||||||
|
uip_udp_packet_sendto(c->udp_conn, data, datalen,
|
||||||
|
to, UIP_HTONS(port));
|
||||||
|
return datalen;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(udp_socket_process, ev, data)
|
||||||
|
{
|
||||||
|
struct udp_socket *c;
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
PROCESS_WAIT_EVENT();
|
||||||
|
if(ev == tcpip_event) {
|
||||||
|
|
||||||
|
/* An appstate pointer is passed to use from the IP stack
|
||||||
|
through the 'data' pointer. We registered this appstate when
|
||||||
|
we did the udp_new() call in udp_socket_register() as the
|
||||||
|
struct udp_socket pointer. So we extract this
|
||||||
|
pointer and use it when calling the reception callback. */
|
||||||
|
c = (struct udp_socket *)data;
|
||||||
|
|
||||||
|
/* Defensive coding: although the appstate *should* be non-null
|
||||||
|
here, we make sure to avoid the program crashing on us. */
|
||||||
|
if(c != NULL) {
|
||||||
|
|
||||||
|
/* If we were called because of incoming data, we should call
|
||||||
|
the reception callback. */
|
||||||
|
if(uip_newdata()) {
|
||||||
|
/* Copy the data from the uIP data buffer into our own
|
||||||
|
buffer to avoid the uIP buffer being messed with by the
|
||||||
|
callee. */
|
||||||
|
memcpy(buf, uip_appdata, uip_datalen());
|
||||||
|
|
||||||
|
/* Call the client process. We use the PROCESS_CONTEXT
|
||||||
|
mechanism to temporarily switch process context to the
|
||||||
|
client process. */
|
||||||
|
if(c->input_callback != NULL) {
|
||||||
|
PROCESS_CONTEXT_BEGIN(c->p);
|
||||||
|
c->input_callback(c, c->ptr,
|
||||||
|
&(UIP_IP_BUF->srcipaddr),
|
||||||
|
UIP_HTONS(UIP_IP_BUF->srcport),
|
||||||
|
&(UIP_IP_BUF->destipaddr),
|
||||||
|
UIP_HTONS(UIP_IP_BUF->destport),
|
||||||
|
buf, uip_datalen());
|
||||||
|
PROCESS_CONTEXT_END();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
193
core/net/ip/udp-socket.h
Normal file
193
core/net/ip/udp-socket.h
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UDP_SOCKET_H
|
||||||
|
#define UDP_SOCKET_H
|
||||||
|
|
||||||
|
#include "net/ip/uip.h"
|
||||||
|
|
||||||
|
struct udp_socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief A UDP socket callback function
|
||||||
|
* \param c A pointer to the struct udp_socket that received the data
|
||||||
|
* \param ptr An opaque pointer that was specified when the UDP socket was registered with udp_socket_register()
|
||||||
|
* \param source_addr The IP address from which the datagram was sent
|
||||||
|
* \param source_port The UDP port number, in host byte order, from which the datagram was sent
|
||||||
|
* \param dest_addr The IP address that this datagram was sent to
|
||||||
|
* \param dest_port The UDP port number, in host byte order, that the datagram was sent to
|
||||||
|
* \param data A pointer to the data contents of the UDP datagram
|
||||||
|
* \param datalen The length of the data being pointed to by the data pointer
|
||||||
|
*
|
||||||
|
* Each UDP socket has a callback function that is
|
||||||
|
* registered as part of the call to
|
||||||
|
* udp_socket_register(). The callback function gets
|
||||||
|
* called every time a UDP packet is received.
|
||||||
|
*/
|
||||||
|
typedef void (* udp_socket_input_callback_t)(struct udp_socket *c,
|
||||||
|
void *ptr,
|
||||||
|
const uip_ipaddr_t *source_addr,
|
||||||
|
uint16_t source_port,
|
||||||
|
const uip_ipaddr_t *dest_addr,
|
||||||
|
uint16_t dest_port,
|
||||||
|
const uint8_t *data,
|
||||||
|
uint16_t datalen);
|
||||||
|
|
||||||
|
struct udp_socket {
|
||||||
|
udp_socket_input_callback_t input_callback;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
struct process *p;
|
||||||
|
|
||||||
|
struct uip_udp_conn *udp_conn;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Register a UDP socket
|
||||||
|
* \param c A pointer to the struct udp_socket that should be registered
|
||||||
|
* \param ptr An opaque pointer that will be passed to callbacks
|
||||||
|
* \param receive_callback A function pointer to the callback function that will be called when data arrives
|
||||||
|
* \retval -1 The registration failed
|
||||||
|
* \retval 1 The registration succeeded
|
||||||
|
*
|
||||||
|
* This function registers the UDP socket with the
|
||||||
|
* system. A UDP socket must be registered before any data
|
||||||
|
* can be sent or received over the socket.
|
||||||
|
*
|
||||||
|
* The caller must allocate memory for the struct
|
||||||
|
* udp_socket that is to be registered.
|
||||||
|
*
|
||||||
|
* A UDP socket can begin to receive data by calling
|
||||||
|
* udp_socket_bind().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_register(struct udp_socket *c,
|
||||||
|
void *ptr,
|
||||||
|
udp_socket_input_callback_t receive_callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Bind a UDP socket to a local port
|
||||||
|
* \param c A pointer to the struct udp_socket that should be bound to a local port
|
||||||
|
* \param local_port The UDP port number, in host byte order, to bind the UDP socket to
|
||||||
|
* \retval -1 Binding the UDP socket to the local port failed
|
||||||
|
* \retval 1 Binding the UDP socket to the local port succeeded
|
||||||
|
*
|
||||||
|
* This function binds the UDP socket to a local port so
|
||||||
|
* that it will begin to receive data that arrives on the
|
||||||
|
* specified port. A UDP socket will receive data
|
||||||
|
* addressed to the specified port number on any IP
|
||||||
|
* address of the host.
|
||||||
|
*
|
||||||
|
* A UDP socket that is bound to a local port will use
|
||||||
|
* this port number as a source port in outgoing UDP
|
||||||
|
* messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_bind(struct udp_socket *c,
|
||||||
|
uint16_t local_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Bind a UDP socket to a remote address and port
|
||||||
|
* \param c A pointer to the struct udp_socket that should be connected
|
||||||
|
* \param remote_addr The IP address of the remote host, or NULL if the UDP socket should only be connected to a specific port
|
||||||
|
* \param remote_port The UDP port number, in host byte order, to which the UDP socket should be connected
|
||||||
|
* \retval -1 Connecting the UDP socket failed
|
||||||
|
* \retval 1 Connecting the UDP socket succeeded
|
||||||
|
*
|
||||||
|
* This function connects the UDP socket to a specific
|
||||||
|
* remote port and optional remote IP address. When a UDP
|
||||||
|
* socket is connected to a remote port and address, it
|
||||||
|
* will only receive packets that are sent from the remote
|
||||||
|
* port and address. When sending data over a connected
|
||||||
|
* UDP socket, the data will be sent to the connected
|
||||||
|
* remote address.
|
||||||
|
*
|
||||||
|
* A UDP socket can be connected to a remote port, but not
|
||||||
|
* a remote IP address, by providing a NULL parameter as
|
||||||
|
* the remote_addr parameter. This lets the UDP socket
|
||||||
|
* receive data from any IP address on the specified port.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_connect(struct udp_socket *c,
|
||||||
|
uip_ipaddr_t *remote_addr,
|
||||||
|
uint16_t remote_port);
|
||||||
|
/**
|
||||||
|
* \brief Send data on a UDP socket
|
||||||
|
* \param c A pointer to the struct udp_socket on which the data should be sent
|
||||||
|
* \param data A pointer to the data that should be sent
|
||||||
|
* \param datalen The length of the data to be sent
|
||||||
|
* \return The number of bytes sent, or -1 if an error occurred
|
||||||
|
*
|
||||||
|
* This function sends data over a UDP socket. The UDP
|
||||||
|
* socket must have been connected to a remote address and
|
||||||
|
* port with udp_socket_connect().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_send(struct udp_socket *c,
|
||||||
|
const void *data, uint16_t datalen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send data on a UDP socket to a specific address and port
|
||||||
|
* \param c A pointer to the struct udp_socket on which the data should be sent
|
||||||
|
* \param data A pointer to the data that should be sent
|
||||||
|
* \param datalen The length of the data to be sent
|
||||||
|
* \param addr The IP address to which the data should be sent
|
||||||
|
* \param port The UDP port number, in host byte order, to which the data should be sent
|
||||||
|
* \return The number of bytes sent, or -1 if an error occurred
|
||||||
|
*
|
||||||
|
* This function sends data over a UDP socket to a
|
||||||
|
* specific address and port.
|
||||||
|
*
|
||||||
|
* The UDP socket does not have to be connected to use
|
||||||
|
* this function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_sendto(struct udp_socket *c,
|
||||||
|
const void *data, uint16_t datalen,
|
||||||
|
const uip_ipaddr_t *addr, uint16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Close a UDP socket
|
||||||
|
* \param c A pointer to the struct udp_socket to be closed
|
||||||
|
* \retval -1 If closing the UDP socket failed
|
||||||
|
* \retval 1 If closing the UDP socket succeeded
|
||||||
|
*
|
||||||
|
* This function closes a UDP socket that has previously
|
||||||
|
* been registered with udp_socket_register(). All
|
||||||
|
* registered UDP sockets must be closed before exiting
|
||||||
|
* the process that registered them, or undefined behavior
|
||||||
|
* may occur.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int udp_socket_close(struct udp_socket *c);
|
||||||
|
|
||||||
|
#endif /* UDP_SOCKET_H */
|
|
@ -42,6 +42,7 @@
|
||||||
extern uint16_t uip_slen;
|
extern uint16_t uip_slen;
|
||||||
|
|
||||||
#include "net/ip/uip-udp-packet.h"
|
#include "net/ip/uip-udp-packet.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -57,6 +58,14 @@ uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
|
||||||
len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
|
len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
|
||||||
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len);
|
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len);
|
||||||
uip_process(UIP_UDP_SEND_CONN);
|
uip_process(UIP_UDP_SEND_CONN);
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_MULTICAST
|
||||||
|
/* Let the multicast engine process the datagram before we send it */
|
||||||
|
if(uip_is_addr_mcast_routable(&uip_udp_conn->ripaddr)) {
|
||||||
|
UIP_MCAST6.out();
|
||||||
|
}
|
||||||
|
#endif /* UIP_IPV6_MULTICAST */
|
||||||
|
|
||||||
#if UIP_CONF_IPV6
|
#if UIP_CONF_IPV6
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -2093,6 +2093,35 @@ CCIF extern uip_lladdr_t uip_lladdr;
|
||||||
#define uip_is_addr_mcast(a) \
|
#define uip_is_addr_mcast(a) \
|
||||||
(((a)->u8[0]) == 0xFF)
|
(((a)->u8[0]) == 0xFF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief is address a global multicast address (FFxE::/16),
|
||||||
|
* a is of type uip_ip6addr_t*
|
||||||
|
* */
|
||||||
|
#define uip_is_addr_mcast_global(a) \
|
||||||
|
((((a)->u8[0]) == 0xFF) && \
|
||||||
|
(((a)->u8[1] & 0x0F) == 0x0E))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief is address a non-routable multicast address.
|
||||||
|
* Scopes 1 (interface-local) and 2 (link-local) are non-routable
|
||||||
|
* See RFC4291 and draft-ietf-6man-multicast-scopes
|
||||||
|
* a is of type uip_ip6addr_t*
|
||||||
|
* */
|
||||||
|
#define uip_is_addr_mcast_non_routable(a) \
|
||||||
|
((((a)->u8[0]) == 0xFF) && \
|
||||||
|
(((a)->u8[1] & 0x0F) <= 0x02))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief is address a routable multicast address.
|
||||||
|
* Scope 3 (Realm-Local) or higher are routable
|
||||||
|
* Realm-Local scope is defined in draft-ietf-6man-multicast-scopes
|
||||||
|
* See RFC4291 and draft-ietf-6man-multicast-scopes
|
||||||
|
* a is of type uip_ip6addr_t*
|
||||||
|
* */
|
||||||
|
#define uip_is_addr_mcast_routable(a) \
|
||||||
|
((((a)->u8[0]) == 0xFF) && \
|
||||||
|
(((a)->u8[1] & 0x0F) > 0x02))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief is group-id of multicast address a
|
* \brief is group-id of multicast address a
|
||||||
* the all nodes group-id
|
* the all nodes group-id
|
||||||
|
|
114
core/net/ipv6/multicast/README.md
Normal file
114
core/net/ipv6/multicast/README.md
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
README file for Contiki's IPv6 multicast core
|
||||||
|
|
||||||
|
Author: George Oikonomou
|
||||||
|
|
||||||
|
What does it do
|
||||||
|
===============
|
||||||
|
These files, alongside some core modifications, add support for IPv6 multicast
|
||||||
|
to contiki's uIPv6 engine.
|
||||||
|
|
||||||
|
Currently, two modes are supported:
|
||||||
|
|
||||||
|
* 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
RPL in MOP 3 handles group management as per the RPL docs,
|
||||||
|
SMRF is a lightweight engine which handles datagram forwarding.
|
||||||
|
SMRF is documented here:
|
||||||
|
http://dx.doi.org/10.1007/s11277-013-1250-5
|
||||||
|
and here:
|
||||||
|
http://dx.doi.org/10.1109/PerComW.2012.6197494
|
||||||
|
* 'Multicast Forwarding with Trickle' according to the algorithm described
|
||||||
|
in the internet draft:
|
||||||
|
http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||||
|
The version of this draft that's currently implementated is documented
|
||||||
|
in `roll-tm.h`
|
||||||
|
|
||||||
|
More engines can (and hopefully will) be added in the future. The first
|
||||||
|
addition is most likely going to be an updated implementation of MPL
|
||||||
|
|
||||||
|
The Big Gotcha
|
||||||
|
==============
|
||||||
|
Currently we only support traffic originating and destined inside a single 6LoWPAN
|
||||||
|
To be able to send multicast traffic from the internet to 6LoWPAN nodes or the other
|
||||||
|
way round, we need border routers or other gateway devices to be able to achieve
|
||||||
|
the following:
|
||||||
|
|
||||||
|
* Add/Remove Trickle Multicast, RPL or other HBHO headers as necessary for datagrams
|
||||||
|
entering / exiting the 6LoWPAN
|
||||||
|
* Advertise multicast group membership to the internet (e.g. with MLD)
|
||||||
|
|
||||||
|
These are currently not implemented and are in the ToDo list. Contributions welcome.
|
||||||
|
|
||||||
|
Where to Start
|
||||||
|
==============
|
||||||
|
The best place in `examples/ipv6/multicast`
|
||||||
|
|
||||||
|
There is a cooja example demonstrating basic functionality
|
||||||
|
|
||||||
|
How to Use
|
||||||
|
==========
|
||||||
|
Look in `core/net/ipv6/multicast/uip-mcast6-engines.h` for a list of supported
|
||||||
|
multicast engines.
|
||||||
|
|
||||||
|
To turn on multicast support, add this line in your `project-` or `contiki-conf.h`
|
||||||
|
|
||||||
|
#define UIP_MCAST6_CONF_ENGINE xyz
|
||||||
|
|
||||||
|
where xyz is a value from `uip-mcast6-engines.h`
|
||||||
|
|
||||||
|
To disable:
|
||||||
|
|
||||||
|
#define UIP_MCAST6_CONF_ENGINE 0
|
||||||
|
|
||||||
|
You also need to make sure the multicast code gets built. Your example's
|
||||||
|
(or platform's) Makefile should include this:
|
||||||
|
|
||||||
|
MODULES += core/net/ipv6/multicast
|
||||||
|
|
||||||
|
How to extend
|
||||||
|
=============
|
||||||
|
Let's assume you want to write an engine called foo.
|
||||||
|
The multicast API defines a multicast engine driver in a fashion similar to
|
||||||
|
the various NETSTACK layer drivers. This API defines functions for basic
|
||||||
|
multicast operations (init, in, out).
|
||||||
|
In order to extend multicast with a new engine, perform the following steps:
|
||||||
|
|
||||||
|
- Open `uip-mcast6-engines.h` and assign a unique integer code to your engine
|
||||||
|
|
||||||
|
#define UIP_MCAST6_ENGINE_FOO xyz
|
||||||
|
|
||||||
|
- Include your engine's `foo.h`
|
||||||
|
|
||||||
|
- In `foo.c`, implement:
|
||||||
|
* `init()`
|
||||||
|
* `in()`
|
||||||
|
* `out()`
|
||||||
|
* Define your driver like so:
|
||||||
|
|
||||||
|
`const struct uip_mcast6_driver foo_driver = { ... }`
|
||||||
|
|
||||||
|
- If you want to maintain stats:
|
||||||
|
* Standard multicast stats are maintained in `uip_mcast6_stats`. Don't access
|
||||||
|
this struct directly, use the macros provided in `uip-mcast6-stats.h` instead
|
||||||
|
* You can add your own stats extensions. To do so, declare your own stats
|
||||||
|
struct in your engine's module, e.g `struct foo_stats`
|
||||||
|
* When you initialise the stats module with `UIP_MCAST6_STATS_INIT`, pass
|
||||||
|
a pointer to your stats variable as the macro's argument.
|
||||||
|
An example of how to extend multicast stats, look at the ROLL TM engine
|
||||||
|
|
||||||
|
- Open `uip-mcast6.h` and add a section in the `#if` spree. This aims to
|
||||||
|
configure the uIPv6 core. More specifically, you need to:
|
||||||
|
* Specify if you want to put RPL in MOP3 by defining
|
||||||
|
`RPL_CONF_MULTICAST`: 1: MOP 3, 0: non-multicast MOP
|
||||||
|
* Define your engine details
|
||||||
|
|
||||||
|
#define UIP_MCAST6 foo_driver
|
||||||
|
#define UIP_MCAST6_STATS foo_stats
|
||||||
|
typedef struct foo_stats uip_mcast6_stats_t;
|
||||||
|
|
||||||
|
* Optionally, add a configuration check block to stop builds when the
|
||||||
|
configuration is not sane.
|
||||||
|
|
||||||
|
If you need your engine to perform operations not supported by the generic
|
||||||
|
UIP_MCAST6 API, you will have to hook those in the uip core manually. As an
|
||||||
|
example, see how the core is modified so that it can deliver ICMPv6 datagrams
|
||||||
|
to the ROLL TM engine.
|
1452
core/net/ipv6/multicast/roll-tm.c
Normal file
1452
core/net/ipv6/multicast/roll-tm.c
Normal file
File diff suppressed because it is too large
Load diff
224
core/net/ipv6/multicast/roll-tm.h
Normal file
224
core/net/ipv6/multicast/roll-tm.h
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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
|
||||||
|
* Header file for IPv6 multicast according to the algorithm in the
|
||||||
|
* "MCAST Forwarding Using Trickle" internet draft.
|
||||||
|
*
|
||||||
|
* The current version of the draft can always be found in
|
||||||
|
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||||
|
*
|
||||||
|
* This implementation is based on the draft version stored in
|
||||||
|
* ROLL_TM_VER.
|
||||||
|
*
|
||||||
|
* In draft v2, the document was renamed to
|
||||||
|
* "Multicast Protocol for Low power and Lossy Networks (MPL)"
|
||||||
|
* Due to very significant changes between draft versions 1 and 2,
|
||||||
|
* MPL will be implemented as a separate engine and this file here
|
||||||
|
* will provide legacy support for Draft v1.
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ROLL_TM_H_
|
||||||
|
#define ROLL_TM_H_
|
||||||
|
|
||||||
|
#include "contiki-conf.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Protocol Constants */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define ROLL_TM_VER 1 /* Supported Draft Version */
|
||||||
|
#define ROLL_TM_ICMP_CODE 0 /* ICMPv6 code field */
|
||||||
|
#define ROLL_TM_IP_HOP_LIMIT 0xFF /* Hop limit for ICMP messages */
|
||||||
|
#define ROLL_TM_INFINITE_REDUNDANCY 0xFF
|
||||||
|
#define ROLL_TM_DGRAM_OUT 0
|
||||||
|
#define ROLL_TM_DGRAM_IN 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The draft does not currently specify a default number for the trickle
|
||||||
|
* interval nor a way to derive it. Examples however hint at 100 msec.
|
||||||
|
*
|
||||||
|
* In draft terminology, we use an 'aggressive' policy (M=0) and a conservative
|
||||||
|
* one (M=1).
|
||||||
|
*
|
||||||
|
* When experimenting with the two policies on the sky platform,
|
||||||
|
* an interval of 125ms proves to be way too low: When we have traffic,
|
||||||
|
* doublings happen after the interval end and periodics fire after point T
|
||||||
|
* within the interval (and sometimes even after interval end). When traffic
|
||||||
|
* settles down, the code compensates the offsets.
|
||||||
|
*
|
||||||
|
* We consider 125, 250ms etc because they are nice divisors of 1 sec
|
||||||
|
* (quotient is power of two). For some machines (e.g sky/msp430,
|
||||||
|
* sensinode/cc243x), this is also a nice number of clock ticks
|
||||||
|
*
|
||||||
|
* After experimentation, the values of Imin leading to best performance are:
|
||||||
|
* ContikiMAC: Imin=64 (500ms)
|
||||||
|
* Null RDC: imin=16 (125ms)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Configuration for Timer with M=0 (aggressive) */
|
||||||
|
#ifdef ROLL_TM_CONF_IMIN_0
|
||||||
|
#define ROLL_TM_IMIN_0 ROLL_TM_CONF_IMIN_0
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_IMIN_0 32 /* 250 msec */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_IMAX_0
|
||||||
|
#define ROLL_TM_IMAX_0 ROLL_TM_CONF_IMAX_0
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_IMAX_0 1 /* Imax = 500ms */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_K_0
|
||||||
|
#define ROLL_TM_K_0 ROLL_TM_CONF_K_0
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_K_0 ROLL_TM_INFINITE_REDUNDANCY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_T_ACTIVE_0
|
||||||
|
#define ROLL_TM_T_ACTIVE_0 ROLL_TM_CONF_T_ACTIVE_0
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_T_ACTIVE_0 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_T_DWELL_0
|
||||||
|
#define ROLL_TM_T_DWELL_0 ROLL_TM_CONF_T_DWELL_0
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_T_DWELL_0 11
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration for Timer with M=1 (conservative) */
|
||||||
|
#ifdef ROLL_TM_CONF_IMIN_1
|
||||||
|
#define ROLL_TM_IMIN_1 ROLL_TM_CONF_IMIN_1
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_IMIN_1 64 /* 500 msec */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_IMAX_1
|
||||||
|
#define ROLL_TM_IMAX_1 ROLL_TM_CONF_IMAX_1
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_IMAX_1 9 /* Imax = 256 secs */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_K_1
|
||||||
|
#define ROLL_TM_K_1 ROLL_TM_CONF_K_1
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_K_1 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_T_ACTIVE_1
|
||||||
|
#define ROLL_TM_T_ACTIVE_1 ROLL_TM_CONF_T_ACTIVE_1
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_T_ACTIVE_1 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROLL_TM_CONF_T_DWELL_1
|
||||||
|
#define ROLL_TM_T_DWELL_1 ROLL_TM_CONF_T_DWELL_1
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_T_DWELL_1 12
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Configuration */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Number of Sliding Windows
|
||||||
|
* In essence: How many unique sources of simultaneous multicast traffic do we
|
||||||
|
* want to support for our lowpan
|
||||||
|
* If a node is seeding two multicast streams, parametrized on different M
|
||||||
|
* values, then this seed will occupy two different sliding windows
|
||||||
|
*/
|
||||||
|
#ifdef ROLL_TM_CONF_WINS
|
||||||
|
#define ROLL_TM_WINS ROLL_TM_CONF_WINS
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_WINS 2
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Maximum Number of Buffered Multicast Messages
|
||||||
|
* This buffer is shared across all Seed IDs, therefore a new very active Seed
|
||||||
|
* may eventually occupy all slots. It would make little sense (if any) to
|
||||||
|
* define support for fewer buffered messages than seeds*2
|
||||||
|
*/
|
||||||
|
#ifdef ROLL_TM_CONF_BUFF_NUM
|
||||||
|
#define ROLL_TM_BUFF_NUM ROLL_TM_CONF_BUFF_NUM
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_BUFF_NUM 6
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Use Short Seed IDs [short: 2, long: 16 (default)]
|
||||||
|
* It can be argued that we should (and it would be easy to) support both at
|
||||||
|
* the same time but the draft doesn't list this as a MUST so we opt for
|
||||||
|
* code/ram savings
|
||||||
|
*/
|
||||||
|
#ifdef ROLL_TM_CONF_SHORT_SEEDS
|
||||||
|
#define ROLL_TM_SHORT_SEEDS ROLL_TM_CONF_SHORT_SEEDS
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_SHORT_SEEDS 0
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Destination address for our ICMPv6 advertisements. The draft gives us a
|
||||||
|
* choice between LL all-nodes or LL all-routers
|
||||||
|
*
|
||||||
|
* We use allrouters unless a conf directive chooses otherwise
|
||||||
|
*/
|
||||||
|
#ifdef ROLL_TM_CONF_DEST_ALL_NODES
|
||||||
|
#define ROLL_TM_DEST_ALL_NODES ROLL_TM_CONF_DEST_ALL_NODES
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_DEST_ALL_NODES 0
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* M param for our outgoing messages
|
||||||
|
* By default, we set the M bit (conservative). Define this as 0 to clear the
|
||||||
|
* M bit in our outgoing messages (aggressive)
|
||||||
|
*/
|
||||||
|
#ifdef ROLL_TM_CONF_SET_M_BIT
|
||||||
|
#define ROLL_TM_SET_M_BIT ROLL_TM_CONF_SET_M_BIT
|
||||||
|
#else
|
||||||
|
#define ROLL_TM_SET_M_BIT 1
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Stats datatype */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct roll_tm_stats {
|
||||||
|
UIP_MCAST6_STATS_DATATYPE icmp_in;
|
||||||
|
UIP_MCAST6_STATS_DATATYPE icmp_out;
|
||||||
|
UIP_MCAST6_STATS_DATATYPE icmp_bad;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ROLL_TM_H_ */
|
211
core/net/ipv6/multicast/smrf.c
Normal file
211
core/net/ipv6/multicast/smrf.c
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Loughborough University - Computer 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
|
||||||
|
* This file implements 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
*
|
||||||
|
* It will only work in RPL networks in MOP 3 "Storing with Multicast"
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||||
|
#include "net/ipv6/multicast/smrf.h"
|
||||||
|
#include "net/rpl/rpl.h"
|
||||||
|
#include "net/netstack.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DEBUG DEBUG_NONE
|
||||||
|
#include "net/ip/uip-debug.h"
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Macros */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* CCI */
|
||||||
|
#define SMRF_FWD_DELAY() NETSTACK_RDC.channel_check_interval()
|
||||||
|
/* Number of slots in the next 500ms */
|
||||||
|
#define SMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Internal Data */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static struct ctimer mcast_periodic;
|
||||||
|
static uint8_t mcast_len;
|
||||||
|
static uip_buf_t mcast_buf;
|
||||||
|
static uint8_t fwd_delay;
|
||||||
|
static uint8_t fwd_spread;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* uIPv6 Pointers */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
mcast_fwd(void *p)
|
||||||
|
{
|
||||||
|
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||||
|
uip_len = mcast_len;
|
||||||
|
UIP_IP_BUF->ttl--;
|
||||||
|
tcpip_output(NULL);
|
||||||
|
uip_len = 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uint8_t
|
||||||
|
in()
|
||||||
|
{
|
||||||
|
rpl_dag_t *d; /* Our DODAG */
|
||||||
|
uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */
|
||||||
|
const uip_lladdr_t *parent_lladdr; /* Our pref. parent's LL address */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch a pointer to the LL address of our preferred parent
|
||||||
|
*
|
||||||
|
* ToDo: This rpl_get_any_dag() call is a dirty replacement of the previous
|
||||||
|
* rpl_get_dag(RPL_DEFAULT_INSTANCE);
|
||||||
|
* so that things can compile with the new RPL code. This needs updated to
|
||||||
|
* read instance ID from the RPL HBHO and use the correct parent accordingly
|
||||||
|
*/
|
||||||
|
d = rpl_get_any_dag();
|
||||||
|
if(!d) {
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||||
|
return UIP_MCAST6_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve our preferred parent's LL address */
|
||||||
|
parent_ipaddr = rpl_get_parent_ipaddr(d->preferred_parent);
|
||||||
|
parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr);
|
||||||
|
|
||||||
|
if(parent_lladdr == NULL) {
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||||
|
return UIP_MCAST6_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We accept a datagram if it arrived from our preferred parent, discard
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||||
|
UIP_LLADDR_LEN)) {
|
||||||
|
PRINTF("SMRF: Routable in but SMRF ignored it\n");
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||||
|
return UIP_MCAST6_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(UIP_IP_BUF->ttl <= 1) {
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||||
|
return UIP_MCAST6_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_in_all);
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_in_unique);
|
||||||
|
|
||||||
|
/* If we have an entry in the mcast routing table, something with
|
||||||
|
* a higher RPL rank (somewhere down the tree) is a group member */
|
||||||
|
if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) {
|
||||||
|
/* If we enter here, we will definitely forward */
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_fwd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a delay (D) of at least SMRF_FWD_DELAY() to compensate for how
|
||||||
|
* contikimac handles broadcasts. We can't start our TX before the sender
|
||||||
|
* has finished its own.
|
||||||
|
*/
|
||||||
|
fwd_delay = SMRF_FWD_DELAY();
|
||||||
|
|
||||||
|
/* Finalise D: D = min(SMRF_FWD_DELAY(), SMRF_MIN_FWD_DELAY) */
|
||||||
|
#if SMRF_MIN_FWD_DELAY
|
||||||
|
if(fwd_delay < SMRF_MIN_FWD_DELAY) {
|
||||||
|
fwd_delay = SMRF_MIN_FWD_DELAY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(fwd_delay == 0) {
|
||||||
|
/* No delay required, send it, do it now, why wait? */
|
||||||
|
UIP_IP_BUF->ttl--;
|
||||||
|
tcpip_output(NULL);
|
||||||
|
UIP_IP_BUF->ttl++; /* Restore before potential upstack delivery */
|
||||||
|
} else {
|
||||||
|
/* Randomise final delay in [D , D*Spread], step D */
|
||||||
|
fwd_spread = SMRF_INTERVAL_COUNT;
|
||||||
|
if(fwd_spread > SMRF_MAX_SPREAD) {
|
||||||
|
fwd_spread = SMRF_MAX_SPREAD;
|
||||||
|
}
|
||||||
|
if(fwd_spread) {
|
||||||
|
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||||
|
mcast_len = uip_len;
|
||||||
|
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||||
|
}
|
||||||
|
PRINTF("SMRF: %u bytes: fwd in %u [%u]\n",
|
||||||
|
uip_len, fwd_delay, fwd_spread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done with this packet unless we are a member of the mcast group */
|
||||||
|
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
|
||||||
|
PRINTF("SMRF: Not a group member. No further processing\n");
|
||||||
|
return UIP_MCAST6_DROP;
|
||||||
|
} else {
|
||||||
|
PRINTF("SMRF: Ours. Deliver to upper layers\n");
|
||||||
|
UIP_MCAST6_STATS_ADD(mcast_in_ours);
|
||||||
|
return UIP_MCAST6_ACCEPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
UIP_MCAST6_STATS_INIT(NULL);
|
||||||
|
|
||||||
|
uip_mcast6_route_init();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
out()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
const struct uip_mcast6_driver smrf_driver = {
|
||||||
|
"SMRF",
|
||||||
|
init,
|
||||||
|
out,
|
||||||
|
in,
|
||||||
|
};
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* UIP_CONF_IPV6 */
|
75
core/net/ipv6/multicast/smrf.h
Normal file
75
core/net/ipv6/multicast/smrf.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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
|
||||||
|
* Header file for 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SMRF_H_
|
||||||
|
#define SMRF_H_
|
||||||
|
|
||||||
|
#include "contiki-conf.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Configuration */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Fmin */
|
||||||
|
#ifdef SMRF_CONF_MIN_FWD_DELAY
|
||||||
|
#define SMRF_MIN_FWD_DELAY SMRF_CONF_MIN_FWD_DELAY
|
||||||
|
#else
|
||||||
|
#define SMRF_MIN_FWD_DELAY 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Max Spread */
|
||||||
|
#ifdef SMRF_CONF_MAX_SPREAD
|
||||||
|
#define SMRF_MAX_SPREAD SMRF_CONF_MAX_SPREAD
|
||||||
|
#else
|
||||||
|
#define SMRF_MAX_SPREAD 4
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Stats datatype */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct smrf_stats {
|
||||||
|
uint16_t mcast_in_unique;
|
||||||
|
uint16_t mcast_in_all; /* At layer 3 */
|
||||||
|
uint16_t mcast_in_ours; /* Unique and we are a group member */
|
||||||
|
uint16_t mcast_fwd; /* Forwarded by us but we are not the seed */
|
||||||
|
uint16_t mcast_out; /* We are the seed */
|
||||||
|
uint16_t mcast_bad;
|
||||||
|
uint16_t mcast_dropped;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SMRF_H_ */
|
50
core/net/ipv6/multicast/uip-mcast6-engines.h
Normal file
50
core/net/ipv6/multicast/uip-mcast6-engines.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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
|
||||||
|
* Header file with definition of multicast engine constants
|
||||||
|
*
|
||||||
|
* When writing a new engine, add it here with a unique number and
|
||||||
|
* then modify uip-mcast6.h accordingly
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UIP_MCAST6_ENGINES_H_
|
||||||
|
#define UIP_MCAST6_ENGINES_H_
|
||||||
|
|
||||||
|
#define UIP_MCAST6_ENGINE_NONE 0 /* Selecting this disables mcast */
|
||||||
|
#define UIP_MCAST6_ENGINE_SMRF 1
|
||||||
|
#define UIP_MCAST6_ENGINE_ROLL_TM 2
|
||||||
|
|
||||||
|
#endif /* UIP_MCAST6_ENGINES_H_ */
|
133
core/net/ipv6/multicast/uip-mcast6-route.c
Normal file
133
core/net/ipv6/multicast/uip-mcast6-route.c
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Multicast routing table manipulation
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "lib/list.h"
|
||||||
|
#include "lib/memb.h"
|
||||||
|
#include "net/ip/uip.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Size of the multicast routing table */
|
||||||
|
#ifdef UIP_MCAST6_ROUTE_CONF_ROUTES
|
||||||
|
#define UIP_MCAST6_ROUTE_ROUTES UIP_MCAST6_ROUTE_CONF_ROUTES
|
||||||
|
#else
|
||||||
|
#define UIP_MCAST6_ROUTE_ROUTES 1
|
||||||
|
#endif /* UIP_CONF_DS6_MCAST_ROUTES */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
LIST(mcast_route_list);
|
||||||
|
MEMB(mcast_route_memb, uip_mcast6_route_t, UIP_MCAST6_ROUTE_ROUTES);
|
||||||
|
|
||||||
|
static uip_mcast6_route_t *locmcastrt;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_mcast6_route_t *
|
||||||
|
uip_mcast6_route_lookup(uip_ipaddr_t *group)
|
||||||
|
{
|
||||||
|
locmcastrt = NULL;
|
||||||
|
for(locmcastrt = list_head(mcast_route_list);
|
||||||
|
locmcastrt != NULL;
|
||||||
|
locmcastrt = list_item_next(locmcastrt)) {
|
||||||
|
if(uip_ipaddr_cmp(&locmcastrt->group, group)) {
|
||||||
|
return locmcastrt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_mcast6_route_t *
|
||||||
|
uip_mcast6_route_add(uip_ipaddr_t *group)
|
||||||
|
{
|
||||||
|
/* _lookup must return NULL, i.e. the prefix does not exist in our table */
|
||||||
|
locmcastrt = uip_mcast6_route_lookup(group);
|
||||||
|
if(locmcastrt == NULL) {
|
||||||
|
/* Allocate an entry and add the group to the list */
|
||||||
|
locmcastrt = memb_alloc(&mcast_route_memb);
|
||||||
|
if(locmcastrt == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
list_add(mcast_route_list, locmcastrt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reaching here means we either found the prefix or allocated a new one */
|
||||||
|
|
||||||
|
uip_ipaddr_copy(&(locmcastrt->group), group);
|
||||||
|
|
||||||
|
return locmcastrt;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_mcast6_route_rm(uip_mcast6_route_t *route)
|
||||||
|
{
|
||||||
|
/* Make sure it's actually in the list */
|
||||||
|
for(locmcastrt = list_head(mcast_route_list);
|
||||||
|
locmcastrt != NULL;
|
||||||
|
locmcastrt = list_item_next(locmcastrt)) {
|
||||||
|
if(locmcastrt == route) {
|
||||||
|
list_remove(mcast_route_list, route);
|
||||||
|
memb_free(&mcast_route_memb, route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_mcast6_route_t *
|
||||||
|
uip_mcast6_route_list_head(void)
|
||||||
|
{
|
||||||
|
return list_head(mcast_route_list);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
uip_mcast6_route_count(void)
|
||||||
|
{
|
||||||
|
return list_length(mcast_route_list);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_mcast6_route_init()
|
||||||
|
{
|
||||||
|
memb_init(&mcast_route_memb);
|
||||||
|
list_init(mcast_route_list);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* UIP_CONF_IPV6 */
|
75
core/net/ipv6/multicast/uip-mcast6-route.h
Normal file
75
core/net/ipv6/multicast/uip-mcast6-route.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Multicast routing table manipulation
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
#ifndef UIP_MCAST6_ROUTE_H_
|
||||||
|
#define UIP_MCAST6_ROUTE_H_
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "net/ip/uip.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \brief An entry in the multicast routing table */
|
||||||
|
typedef struct uip_mcast6_route {
|
||||||
|
struct uip_mcast6_route *next;
|
||||||
|
uip_ipaddr_t group;
|
||||||
|
uint32_t lifetime; /* seconds */
|
||||||
|
void *dag; /* Pointer to an rpl_dag_t struct */
|
||||||
|
} uip_mcast6_route_t;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name Multicast Routing Table Manipulation */
|
||||||
|
/** @{ */
|
||||||
|
uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group);
|
||||||
|
uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group);
|
||||||
|
void uip_mcast6_route_rm(uip_mcast6_route_t *defrt);
|
||||||
|
int uip_mcast6_route_count(void);
|
||||||
|
uip_mcast6_route_t *uip_mcast6_route_list_head(void);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Multicast routing table init routine
|
||||||
|
*
|
||||||
|
* Multicast routing tables are not necessarily required by all
|
||||||
|
* multicast engines. For instance, trickle multicast does not rely on
|
||||||
|
* the existence of a routing table. Therefore, this function here
|
||||||
|
* should be invoked by each engine's init routine only if the relevant
|
||||||
|
* functionality is required. This is also why this function should not
|
||||||
|
* get hooked into the uip-ds6 core.
|
||||||
|
*/
|
||||||
|
void uip_mcast6_route_init(void);
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* UIP_MCAST6_ROUTE_H_ */
|
49
core/net/ipv6/multicast/uip-mcast6-stats.c
Normal file
49
core/net/ipv6/multicast/uip-mcast6-stats.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* IPv6 multicast forwarding stats maintenance
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_mcast6_stats_t uip_mcast6_stats;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_mcast6_stats_init(void *stats)
|
||||||
|
{
|
||||||
|
memset(&uip_mcast6_stats, 0, sizeof(uip_mcast6_stats));
|
||||||
|
uip_mcast6_stats.engine_stats = stats;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
91
core/net/ipv6/multicast/uip-mcast6-stats.h
Normal file
91
core/net/ipv6/multicast/uip-mcast6-stats.h
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Header file for IPv6 multicast forwarding stats maintenance
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
#ifndef UIP_MCAST6_STATS_H_
|
||||||
|
#define UIP_MCAST6_STATS_H_
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "contiki-conf.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* The platform can override the stats datatype */
|
||||||
|
#ifdef UIP_MCAST6_CONF_STATS_DATATYPE
|
||||||
|
#define UIP_MCAST6_STATS_DATATYPE UIP_MCAST6_CONF_STATS_DATATYPE
|
||||||
|
#else
|
||||||
|
#define UIP_MCAST6_STATS_DATATYPE uint16_t
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef UIP_MCAST6_CONF_STATS
|
||||||
|
#define UIP_MCAST6_STATS UIP_MCAST6_CONF_STATS
|
||||||
|
#else
|
||||||
|
#define UIP_MCAST6_STATS 0
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Stats datatype */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
typedef struct uip_mcast6_stats {
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_in_unique;
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_in_all; /* At layer 3 */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_in_ours; /* Unique and we are a group member */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_fwd; /* Forwarded by us but we are not the seed */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_out; /* We are the seed */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_bad;
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_dropped;
|
||||||
|
void *engine_stats; /* Opaque pointer to an engine's additional stats */
|
||||||
|
} uip_mcast6_stats_t;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Access macros */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if UIP_MCAST6_STATS
|
||||||
|
/* Don't access this variable directly, use the macros below */
|
||||||
|
extern uip_mcast6_stats_t uip_mcast6_stats;
|
||||||
|
|
||||||
|
#define UIP_MCAST6_STATS_ADD(x) uip_mcast6_stats.x++
|
||||||
|
#define UIP_MCAST6_STATS_GET(x) uip_mcast6_stats.x
|
||||||
|
#define UIP_MCAST6_STATS_INIT(s) uip_mcast6_stats_init(s)
|
||||||
|
#else /* UIP_MCAST6_STATS */
|
||||||
|
#define UIP_MCAST6_STATS_ADD(x)
|
||||||
|
#define UIP_MCAST6_STATS_GET(x) 0
|
||||||
|
#define UIP_MCAST6_STATS_INIT(s)
|
||||||
|
#endif /* UIP_MCAST6_STATS */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Initialise multicast stats
|
||||||
|
* \param stats A pointer to a struct holding an engine's additional statistics
|
||||||
|
*/
|
||||||
|
void uip_mcast6_stats_init(void *stats);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#endif /* UIP_MCAST6_STATS_H_ */
|
162
core/net/ipv6/multicast/uip-mcast6.h
Normal file
162
core/net/ipv6/multicast/uip-mcast6.h
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Loughborough University - Computer 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
|
||||||
|
* This header file contains configuration directives for uIPv6
|
||||||
|
* multicast support.
|
||||||
|
*
|
||||||
|
* We currently support 2 engines:
|
||||||
|
* - 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
* RPL does group management as per the RPL docs, SMRF handles datagram
|
||||||
|
* forwarding
|
||||||
|
* - 'Multicast Forwarding with Trickle' according to the algorithm described
|
||||||
|
* in the internet draft:
|
||||||
|
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UIP_MCAST6_H_
|
||||||
|
#define UIP_MCAST6_H_
|
||||||
|
|
||||||
|
#include "contiki-conf.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-engines.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||||
|
#include "net/ipv6/multicast/smrf.h"
|
||||||
|
#include "net/ipv6/multicast/roll-tm.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Constants */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define UIP_MCAST6_DROP 0
|
||||||
|
#define UIP_MCAST6_ACCEPT 1
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Multicast Address Scopes (RFC 4291 & draft-ietf-6man-multicast-scopes) */
|
||||||
|
#define UIP_MCAST6_SCOPE_INTERFACE 0x01
|
||||||
|
#define UIP_MCAST6_SCOPE_LINK_LOCAL 0x02
|
||||||
|
#define UIP_MCAST6_SCOPE_REALM_LOCAL 0x03 /* draft-ietf-6man-multicast-scopes */
|
||||||
|
#define UIP_MCAST6_SCOPE_ADMIN_LOCAL 0x04
|
||||||
|
#define UIP_MCAST6_SCOPE_SITE_LOCAL 0x05
|
||||||
|
#define UIP_MCAST6_SCOPE_ORG_LOCAL 0x08
|
||||||
|
#define UIP_MCAST6_SCOPE_GLOBAL 0x0E
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Choose an engine or turn off based on user configuration */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef UIP_MCAST6_CONF_ENGINE
|
||||||
|
#define UIP_MCAST6_ENGINE UIP_MCAST6_CONF_ENGINE
|
||||||
|
#else
|
||||||
|
#define UIP_MCAST6_ENGINE UIP_MCAST6_ENGINE_NONE
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Multicast API. Similar to NETSTACK, each engine must define a driver and
|
||||||
|
* populate the fields with suitable function pointers
|
||||||
|
*/
|
||||||
|
struct uip_mcast6_driver {
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/** Initialize the multicast engine */
|
||||||
|
void (* init)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Process an outgoing datagram with a multicast IPv6 destination
|
||||||
|
* address
|
||||||
|
*
|
||||||
|
* This may be needed if the multicast engine needs to, for example,
|
||||||
|
* add IPv6 extension headers to the datagram, cache it, decide it
|
||||||
|
* needs dropped etc.
|
||||||
|
*
|
||||||
|
* It is sometimes desirable to let the engine handle datagram
|
||||||
|
* dispatch instead of letting the networking core do it. If the
|
||||||
|
* engine decides to send the datagram itself, it must afterwards
|
||||||
|
* set uip_len = 0 to prevent the networking core from sending too
|
||||||
|
*/
|
||||||
|
void (* out)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Process an incoming multicast datagram and determine whether it
|
||||||
|
* should be delivered up the stack or not.
|
||||||
|
*
|
||||||
|
* \return 0: Drop, 1: Deliver
|
||||||
|
*
|
||||||
|
* When a datagram with a multicast destination address is received,
|
||||||
|
* the forwarding logic in core is bypassed. Instead, we let the
|
||||||
|
* multicast engine handle forwarding internally if and as necessary.
|
||||||
|
* This function is where forwarding logic must be hooked in.
|
||||||
|
*
|
||||||
|
* Once the engine is done with forwarding, it must signal via the
|
||||||
|
* return value whether the datagram needs delivered up the network
|
||||||
|
* stack.
|
||||||
|
*/
|
||||||
|
uint8_t (* in)(void);
|
||||||
|
};
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Get a multicast address' scope.
|
||||||
|
* a is of type uip_ip6addr_t*
|
||||||
|
*/
|
||||||
|
#define uip_mcast6_get_address_scope(a) ((a)->u8[1] & 0x0F)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Configure multicast and core/net to play nicely with the selected engine */
|
||||||
|
#if UIP_MCAST6_ENGINE
|
||||||
|
|
||||||
|
/* Enable Multicast hooks in the uip6 core */
|
||||||
|
#define UIP_CONF_IPV6_MULTICAST 1
|
||||||
|
|
||||||
|
#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ROLL_TM
|
||||||
|
#define RPL_CONF_MULTICAST 0 /* Not used by trickle */
|
||||||
|
#define UIP_CONF_IPV6_ROLL_TM 1 /* ROLL Trickle ICMP type support */
|
||||||
|
|
||||||
|
#define UIP_MCAST6 roll_tm_driver
|
||||||
|
#elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_SMRF
|
||||||
|
#define RPL_CONF_MULTICAST 1
|
||||||
|
|
||||||
|
#define UIP_MCAST6 smrf_driver
|
||||||
|
#else
|
||||||
|
#error "Multicast Enabled with an Unknown Engine."
|
||||||
|
#error "Check the value of UIP_MCAST6_CONF_ENGINE in conf files."
|
||||||
|
#endif
|
||||||
|
#endif /* UIP_MCAST6_ENGINE */
|
||||||
|
|
||||||
|
extern const struct uip_mcast6_driver UIP_MCAST6;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Configuration Checks */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if RPL_CONF_MULTICAST && (!UIP_CONF_IPV6_RPL)
|
||||||
|
#error "The selected Multicast mode requires UIP_CONF_IPV6_RPL != 0"
|
||||||
|
#error "Check the value of UIP_CONF_IPV6_RPL in conf files."
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* UIP_MCAST6_H_ */
|
|
@ -512,6 +512,10 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if UIP_IPV6_MULTICAST
|
||||||
|
} else if(uip_is_addr_mcast_routable(dst)) {
|
||||||
|
matchaddr = uip_ds6_get_global(ADDR_PREFERRED);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
|
matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,53 @@
|
||||||
static uip_ipaddr_t tmp_ipaddr;
|
static uip_ipaddr_t tmp_ipaddr;
|
||||||
|
|
||||||
LIST(echo_reply_callback_list);
|
LIST(echo_reply_callback_list);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* List of input handlers */
|
||||||
|
LIST(input_handler_list);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uip_icmp6_input_handler_t *
|
||||||
|
input_handler_lookup(uint8_t type, uint8_t icode)
|
||||||
|
{
|
||||||
|
uip_icmp6_input_handler_t *handler = NULL;
|
||||||
|
|
||||||
|
for(handler = list_head(input_handler_list);
|
||||||
|
handler != NULL;
|
||||||
|
handler = list_item_next(handler)) {
|
||||||
|
if(handler->type == type &&
|
||||||
|
(handler->icode == icode ||
|
||||||
|
handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uint8_t
|
||||||
|
uip_icmp6_input(uint8_t type, uint8_t icode)
|
||||||
|
{
|
||||||
|
uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
|
||||||
|
|
||||||
|
if(handler == NULL) {
|
||||||
|
return UIP_ICMP6_INPUT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler->handler == NULL) {
|
||||||
|
return UIP_ICMP6_INPUT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->handler();
|
||||||
|
return UIP_ICMP6_INPUT_SUCCESS;
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_icmp6_echo_request_input(void)
|
uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
|
||||||
|
{
|
||||||
|
list_add(input_handler_list, handler);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
echo_request_input(void)
|
||||||
{
|
{
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
uint8_t temp_ext_len;
|
uint8_t temp_ext_len;
|
||||||
|
@ -275,8 +318,8 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
uip_icmp6_echo_reply_input(void)
|
echo_reply_input(void)
|
||||||
{
|
{
|
||||||
int ttl;
|
int ttl;
|
||||||
uip_ipaddr_t sender;
|
uip_ipaddr_t sender;
|
||||||
|
@ -343,6 +386,8 @@ uip_icmp6_echo_reply_input(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -362,5 +407,18 @@ uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
|
||||||
list_remove(echo_reply_callback_list, n);
|
list_remove(echo_reply_callback_list, n);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
UIP_ICMP6_HANDLER(echo_request_handler, ICMP6_ECHO_REQUEST,
|
||||||
|
UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input);
|
||||||
|
UIP_ICMP6_HANDLER(echo_reply_handler, ICMP6_ECHO_REPLY,
|
||||||
|
UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_icmp6_init()
|
||||||
|
{
|
||||||
|
/* Register Echo Request and Reply handlers */
|
||||||
|
uip_icmp6_register_input_handler(&echo_request_handler);
|
||||||
|
uip_icmp6_register_input_handler(&echo_reply_handler);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -65,6 +65,11 @@
|
||||||
#define ICMP6_REDIRECT 137 /**< Redirect */
|
#define ICMP6_REDIRECT 137 /**< Redirect */
|
||||||
|
|
||||||
#define ICMP6_RPL 155 /**< RPL */
|
#define ICMP6_RPL 155 /**< RPL */
|
||||||
|
#define ICMP6_PRIV_EXP_100 100 /**< Private Experimentation */
|
||||||
|
#define ICMP6_PRIV_EXP_101 101 /**< Private Experimentation */
|
||||||
|
#define ICMP6_PRIV_EXP_200 200 /**< Private Experimentation */
|
||||||
|
#define ICMP6_PRIV_EXP_201 201 /**< Private Experimentation */
|
||||||
|
#define ICMP6_ROLL_TM ICMP6_PRIV_EXP_200 /**< ROLL Trickle Multicast */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,24 +109,6 @@ typedef struct uip_icmp6_error{
|
||||||
|
|
||||||
/** \name ICMPv6 RFC4443 Message processing and sending */
|
/** \name ICMPv6 RFC4443 Message processing and sending */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/** \
|
|
||||||
* brief Process an echo request
|
|
||||||
*
|
|
||||||
* Perform a few checks, then send an Echo reply. The reply is
|
|
||||||
* built here.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
uip_icmp6_echo_request_input(void);
|
|
||||||
|
|
||||||
/** \
|
|
||||||
* brief Process an echo reply
|
|
||||||
*
|
|
||||||
* Perform a few checks, then call applications to inform that an echo
|
|
||||||
* reply has been received.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
uip_icmp6_echo_reply_input(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Send an icmpv6 error message
|
* \brief Send an icmpv6 error message
|
||||||
* \param type type of the error message
|
* \param type type of the error message
|
||||||
|
@ -187,8 +174,66 @@ uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
|
||||||
void
|
void
|
||||||
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
||||||
|
|
||||||
|
/* Generic ICMPv6 input handers */
|
||||||
|
typedef struct uip_icmp6_input_handler {
|
||||||
|
struct uip_icmp6_input_handler *next;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t icode;
|
||||||
|
void (*handler)(void);
|
||||||
|
} uip_icmp6_input_handler_t;
|
||||||
|
|
||||||
|
#define UIP_ICMP6_INPUT_SUCCESS 0
|
||||||
|
#define UIP_ICMP6_INPUT_ERROR 1
|
||||||
|
|
||||||
|
#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise a variable of type uip_icmp6_input_handler, to be used later as
|
||||||
|
* the argument to uip_icmp6_register_input_handler
|
||||||
|
*
|
||||||
|
* The function pointer stored in this variable will get called and will be
|
||||||
|
* expected to handle incoming ICMPv6 datagrams of the specified type/code
|
||||||
|
*
|
||||||
|
* If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function
|
||||||
|
* will handle all codes for this type. In other words, the ICMPv6
|
||||||
|
* message's code is "don't care"
|
||||||
|
*/
|
||||||
|
#define UIP_ICMP6_HANDLER(name, type, code, func) \
|
||||||
|
static uip_icmp6_input_handler_t name = { NULL, type, code, func }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Handle an incoming ICMPv6 message
|
||||||
|
* \param type The ICMPv6 message type
|
||||||
|
* \param icode The ICMPv6 message code
|
||||||
|
* \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR
|
||||||
|
*
|
||||||
|
* Generic handler for unknown ICMPv6 types. It will lookup for a registered
|
||||||
|
* function capable of handing this message type. The function must have first
|
||||||
|
* been registered with uip_icmp6_register_input_handler. The function is in
|
||||||
|
* charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to
|
||||||
|
* send whatever remains in the UIP_IP_BUF.
|
||||||
|
*
|
||||||
|
* A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be
|
||||||
|
* invoked. This is most likely because the ICMPv6 type does not have a valid
|
||||||
|
* handler associated with it.
|
||||||
|
|
||||||
|
* UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6
|
||||||
|
* type and that it was invoked. It does NOT provide any indication whatsoever
|
||||||
|
* regarding whether the handler itself succeeded.
|
||||||
|
*/
|
||||||
|
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Register a handler which can handle a specific ICMPv6 message type
|
||||||
|
* \param handler A pointer to the handler
|
||||||
|
*/
|
||||||
|
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialise the uIP ICMPv6 core
|
||||||
|
*/
|
||||||
|
void uip_icmp6_init(void);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,6 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
|
||||||
static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
|
static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
|
||||||
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
|
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
|
||||||
static uip_ds6_addr_t *addr; /** Pointer to an interface address */
|
static uip_ds6_addr_t *addr; /** Pointer to an interface address */
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/* create a llao */
|
/* create a llao */
|
||||||
static void
|
static void
|
||||||
|
@ -143,8 +141,8 @@ create_llao(uint8_t *llao, uint8_t type) {
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
void
|
static void
|
||||||
uip_nd6_ns_input(void)
|
ns_input(void)
|
||||||
{
|
{
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
PRINTF("Received NS from ");
|
PRINTF("Received NS from ");
|
||||||
|
@ -388,12 +386,26 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
void
|
/**
|
||||||
uip_nd6_na_input(void)
|
* Neighbor Advertisement Processing
|
||||||
|
*
|
||||||
|
* we might have to send a pkt that had been buffered while address
|
||||||
|
* resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT)
|
||||||
|
*
|
||||||
|
* As per RFC 4861, on link layer that have addresses, TLLAO options MUST be
|
||||||
|
* included when responding to multicast solicitations, SHOULD be included in
|
||||||
|
* response to unicast (here we assume it is for now)
|
||||||
|
*
|
||||||
|
* NA can be received after sending NS for DAD, Address resolution or NUD. Can
|
||||||
|
* be unsolicited as well.
|
||||||
|
* It can trigger update of the state of the neighbor in the neighbor cache,
|
||||||
|
* router in the router list.
|
||||||
|
* If the NS was for DAD, it means DAD failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
na_input(void)
|
||||||
{
|
{
|
||||||
uint8_t is_llchange;
|
uint8_t is_llchange;
|
||||||
uint8_t is_router;
|
uint8_t is_router;
|
||||||
|
@ -548,8 +560,8 @@ discard:
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
#if UIP_ND6_SEND_RA
|
#if UIP_ND6_SEND_RA
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
uip_nd6_rs_input(void)
|
rs_input(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
PRINTF("Received RS from");
|
PRINTF("Received RS from");
|
||||||
|
@ -761,11 +773,18 @@ uip_nd6_rs_output(void)
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Process a Router Advertisement
|
||||||
|
*
|
||||||
|
* - Possible actions when receiving a RA: add router to router list,
|
||||||
|
* recalculate reachable time, update link hop limit, update retrans timer.
|
||||||
|
* - If MTU option: update MTU.
|
||||||
|
* - If SLLAO option: update entry in neighbor cache
|
||||||
|
* - If prefix option: start autoconf, add prefix to prefix list
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
uip_nd6_ra_input(void)
|
ra_input(void)
|
||||||
{
|
{
|
||||||
PRINTF("Received RA from");
|
PRINTF("Received RA from");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
|
@ -969,6 +988,52 @@ discard:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* !UIP_CONF_ROUTER */
|
#endif /* !UIP_CONF_ROUTER */
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
/* ICMPv6 input handlers */
|
||||||
|
#if UIP_ND6_SEND_NA
|
||||||
|
UIP_ICMP6_HANDLER(ns_input_handler, ICMP6_NS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
ns_input);
|
||||||
|
UIP_ICMP6_HANDLER(na_input_handler, ICMP6_NA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
na_input);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||||
|
UIP_ICMP6_HANDLER(rs_input_handler, ICMP6_RS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
rs_input);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !UIP_CONF_ROUTER
|
||||||
|
UIP_ICMP6_HANDLER(ra_input_handler, ICMP6_RA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||||
|
ra_input);
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_nd6_init()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if UIP_ND6_SEND_NA
|
||||||
|
/* Only handle NSs if we are prepared to send out NAs */
|
||||||
|
uip_icmp6_register_input_handler(&ns_input_handler);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only handle NAs if we are prepared to send out NAs.
|
||||||
|
* This is perhaps logically incorrect, but this condition was present in
|
||||||
|
* uip_process and we keep it until proven wrong
|
||||||
|
*/
|
||||||
|
uip_icmp6_register_input_handler(&na_input_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||||
|
/* Only accept RS if we are a router and happy to send out RAs */
|
||||||
|
uip_icmp6_register_input_handler(&rs_input_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !UIP_CONF_ROUTER
|
||||||
|
/* Only process RAs if we are not a router */
|
||||||
|
uip_icmp6_register_input_handler(&ra_input_handler);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -337,34 +337,8 @@ uip_nd6_ns_input(void);
|
||||||
void
|
void
|
||||||
uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
|
uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Process a Neighbor Advertisement
|
|
||||||
*
|
|
||||||
* we might have to send a pkt that had been buffered while address
|
|
||||||
* resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT)
|
|
||||||
*
|
|
||||||
* As per RFC 4861, on link layer that have addresses, TLLAO options MUST be
|
|
||||||
* included when responding to multicast solicitations, SHOULD be included in
|
|
||||||
* response to unicast (here we assume it is for now)
|
|
||||||
*
|
|
||||||
* NA can be received after sending NS for DAD, Address resolution or NUD. Can
|
|
||||||
* be unsolicited as well.
|
|
||||||
* It can trigger update of the state of the neighbor in the neighbor cache,
|
|
||||||
* router in the router list.
|
|
||||||
* If the NS was for DAD, it means DAD failed
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
uip_nd6_na_input(void);
|
|
||||||
|
|
||||||
#if UIP_CONF_ROUTER
|
#if UIP_CONF_ROUTER
|
||||||
#if UIP_ND6_SEND_RA
|
#if UIP_ND6_SEND_RA
|
||||||
/**
|
|
||||||
* \brief Process a Router Solicitation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void uip_nd6_rs_input(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief send a Router Advertisement
|
* \brief send a Router Advertisement
|
||||||
*
|
*
|
||||||
|
@ -388,17 +362,9 @@ void uip_nd6_ra_output(uip_ipaddr_t *dest);
|
||||||
void uip_nd6_rs_output(void);
|
void uip_nd6_rs_output(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* \brief Initialise the uIP ND core
|
||||||
* \brief process a Router Advertisement
|
|
||||||
*
|
|
||||||
* - Possible actions when receiving a RA: add router to router list,
|
|
||||||
* recalculate reachable time, update link hop limit, update retrans timer.
|
|
||||||
* - If MTU option: update MTU.
|
|
||||||
* - If SLLAO option: update entry in neighbor cache
|
|
||||||
* - If prefix option: start autoconf, add prefix to prefix list
|
|
||||||
*/
|
*/
|
||||||
void
|
void uip_nd6_init(void);
|
||||||
uip_nd6_ra_input(void);
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#include "net/ipv6/uip-icmp6.h"
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -410,6 +411,8 @@ uip_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
uip_ds6_init();
|
uip_ds6_init();
|
||||||
|
uip_icmp6_init();
|
||||||
|
uip_nd6_init();
|
||||||
|
|
||||||
#if UIP_TCP
|
#if UIP_TCP
|
||||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||||
|
@ -429,6 +432,10 @@ uip_init(void)
|
||||||
uip_udp_conns[c].lport = 0;
|
uip_udp_conns[c].lport = 0;
|
||||||
}
|
}
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_MULTICAST
|
||||||
|
UIP_MCAST6.init();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_TCP && UIP_ACTIVE_OPEN
|
#if UIP_TCP && UIP_ACTIVE_OPEN
|
||||||
|
@ -1151,6 +1158,28 @@ uip_process(uint8_t flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process Packets with a routable multicast destination:
|
||||||
|
* - We invoke the multicast engine and let it do its thing
|
||||||
|
* (cache, forward etc).
|
||||||
|
* - We never execute the datagram forwarding logic in this file here. When
|
||||||
|
* the engine returns, forwarding has been handled if and as required.
|
||||||
|
* - Depending on the return value, we either discard or deliver up the stack
|
||||||
|
*
|
||||||
|
* All multicast engines must hook in here. After this function returns, we
|
||||||
|
* expect UIP_BUF to be unmodified
|
||||||
|
*/
|
||||||
|
#if UIP_CONF_IPV6_MULTICAST
|
||||||
|
if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) {
|
||||||
|
if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) {
|
||||||
|
/* Deliver up the stack */
|
||||||
|
goto process;
|
||||||
|
} else {
|
||||||
|
/* Don't deliver up the stack */
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_IPV6_CONF_MULTICAST */
|
||||||
|
|
||||||
/* TBD Some Parameter problem messages */
|
/* TBD Some Parameter problem messages */
|
||||||
if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
|
if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
|
||||||
|
@ -1220,6 +1249,10 @@ uip_process(uint8_t flag)
|
||||||
uip_ext_bitmap = 0;
|
uip_ext_bitmap = 0;
|
||||||
#endif /* UIP_CONF_ROUTER */
|
#endif /* UIP_CONF_ROUTER */
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_MULTICAST
|
||||||
|
process:
|
||||||
|
#endif
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
switch(*uip_next_hdr){
|
switch(*uip_next_hdr){
|
||||||
#if UIP_TCP
|
#if UIP_TCP
|
||||||
|
@ -1389,61 +1422,17 @@ uip_process(uint8_t flag)
|
||||||
UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
|
UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
|
||||||
#endif /*UIP_CONF_ICMP6*/
|
#endif /*UIP_CONF_ICMP6*/
|
||||||
|
|
||||||
switch(UIP_ICMP_BUF->type) {
|
/*
|
||||||
case ICMP6_NS:
|
* Search generic input handlers.
|
||||||
#if UIP_ND6_SEND_NA
|
* The handler is in charge of setting uip_len to 0
|
||||||
uip_nd6_ns_input();
|
*/
|
||||||
#else /* UIP_ND6_SEND_NA */
|
if(uip_icmp6_input(UIP_ICMP_BUF->type,
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
UIP_ICMP_BUF->icode) == UIP_ICMP6_INPUT_ERROR) {
|
||||||
uip_len = 0;
|
PRINTF("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
|
||||||
break;
|
|
||||||
case ICMP6_NA:
|
|
||||||
#if UIP_ND6_SEND_NA
|
|
||||||
uip_nd6_na_input();
|
|
||||||
#else /* UIP_ND6_SEND_NA */
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
uip_len = 0;
|
|
||||||
#endif /* UIP_ND6_SEND_NA */
|
|
||||||
break;
|
|
||||||
case ICMP6_RS:
|
|
||||||
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
|
||||||
uip_nd6_rs_input();
|
|
||||||
#else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
UIP_STAT(++uip_stat.icmp.drop);
|
||||||
|
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||||
|
UIP_LOG("icmp6: unknown ICMPv6 message.");
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
|
||||||
break;
|
|
||||||
case ICMP6_RA:
|
|
||||||
#if UIP_CONF_ROUTER
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
uip_len = 0;
|
|
||||||
#else /* UIP_CONF_ROUTER */
|
|
||||||
uip_nd6_ra_input();
|
|
||||||
#endif /* UIP_CONF_ROUTER */
|
|
||||||
break;
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
case ICMP6_RPL:
|
|
||||||
uip_rpl_input();
|
|
||||||
break;
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
case ICMP6_ECHO_REQUEST:
|
|
||||||
uip_icmp6_echo_request_input();
|
|
||||||
break;
|
|
||||||
case ICMP6_ECHO_REPLY:
|
|
||||||
/** Call echo reply input function. */
|
|
||||||
uip_icmp6_echo_reply_input();
|
|
||||||
PRINTF("Received an icmp6 echo reply\n");
|
|
||||||
UIP_STAT(++uip_stat.icmp.recv);
|
|
||||||
uip_len = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
|
|
||||||
UIP_STAT(++uip_stat.icmp.drop);
|
|
||||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
|
||||||
UIP_LOG("icmp6: unknown ICMP message.");
|
|
||||||
uip_len = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uip_len > 0) {
|
if(uip_len > 0) {
|
||||||
|
|
|
@ -212,16 +212,17 @@ packet_sent(void *ptr, int status, int num_transmissions)
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case MAC_TX_OK:
|
case MAC_TX_OK:
|
||||||
case MAC_TX_NOACK:
|
case MAC_TX_NOACK:
|
||||||
n->transmissions++;
|
n->transmissions += num_transmissions;
|
||||||
break;
|
break;
|
||||||
case MAC_TX_COLLISION:
|
case MAC_TX_COLLISION:
|
||||||
n->collisions++;
|
n->collisions += num_transmissions;
|
||||||
break;
|
break;
|
||||||
case MAC_TX_DEFERRED:
|
case MAC_TX_DEFERRED:
|
||||||
n->deferrals++;
|
n->deferrals += num_transmissions;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find out what packet this callback refers to */
|
||||||
for(q = list_head(n->queued_packet_list);
|
for(q = list_head(n->queued_packet_list);
|
||||||
q != NULL; q = list_item_next(q)) {
|
q != NULL; q = list_item_next(q)) {
|
||||||
if(queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO) ==
|
if(queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO) ==
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
* Logic for Directed Acyclic Graphs in RPL.
|
* Logic for Directed Acyclic Graphs in RPL.
|
||||||
*
|
*
|
||||||
* \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
|
* \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
|
||||||
|
* Contributors: George Oikonomou <oikonomou@users.sourceforge.net> (multicast)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
#include "net/nbr-table.h"
|
#include "net/nbr-table.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
#include "lib/list.h"
|
#include "lib/list.h"
|
||||||
#include "lib/memb.h"
|
#include "lib/memb.h"
|
||||||
#include "sys/ctimer.h"
|
#include "sys/ctimer.h"
|
||||||
|
@ -985,7 +987,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
instance->dio_redundancy != dio->dag_redund ||
|
instance->dio_redundancy != dio->dag_redund ||
|
||||||
instance->default_lifetime != dio->default_lifetime ||
|
instance->default_lifetime != dio->default_lifetime ||
|
||||||
instance->lifetime_unit != dio->lifetime_unit) {
|
instance->lifetime_unit != dio->lifetime_unit) {
|
||||||
PRINTF("RPL: DIO for DAG instance %u uncompatible with previos DIO\n",
|
PRINTF("RPL: DIO for DAG instance %u incompatible with previous DIO\n",
|
||||||
dio->instance_id);
|
dio->instance_id);
|
||||||
rpl_remove_parent(p);
|
rpl_remove_parent(p);
|
||||||
dag->used = 0;
|
dag->used = 0;
|
||||||
|
@ -1147,7 +1149,13 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
rpl_dag_t *dag, *previous_dag;
|
rpl_dag_t *dag, *previous_dag;
|
||||||
rpl_parent_t *p;
|
rpl_parent_t *p;
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
/* If the root is advertising MOP 2 but we support MOP 3 we can still join
|
||||||
|
* In that scenario, we suppress DAOs for multicast targets */
|
||||||
|
if(dio->mop < RPL_MOP_STORING_NO_MULTICAST) {
|
||||||
|
#else
|
||||||
if(dio->mop != RPL_MOP_DEFAULT) {
|
if(dio->mop != RPL_MOP_DEFAULT) {
|
||||||
|
#endif
|
||||||
PRINTF("RPL: Ignoring a DIO with an unsupported MOP: %d\n", dio->mop);
|
PRINTF("RPL: Ignoring a DIO with an unsupported MOP: %d\n", dio->mop);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1163,7 +1171,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
RPL_LOLLIPOP_INCREMENT(dag->version);
|
RPL_LOLLIPOP_INCREMENT(dag->version);
|
||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
} else {
|
} else {
|
||||||
PRINTF("RPL: Global Repair\n");
|
PRINTF("RPL: Global repair\n");
|
||||||
if(dio->prefix_info.length != 0) {
|
if(dio->prefix_info.length != 0) {
|
||||||
if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
|
if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
|
||||||
PRINTF("RPL : Prefix announced in DIO\n");
|
PRINTF("RPL : Prefix announced in DIO\n");
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
* \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
|
* \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
|
||||||
* Contributors: Niclas Finne <nfi@sics.se>, Joel Hoglund <joel@sics.se>,
|
* Contributors: Niclas Finne <nfi@sics.se>, Joel Hoglund <joel@sics.se>,
|
||||||
* Mathieu Pouillot <m.pouillot@watteco.com>
|
* Mathieu Pouillot <m.pouillot@watteco.com>
|
||||||
|
* George Oikonomou <oikonomou@users.sourceforge.net> (multicast)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#include "net/ipv6/uip-icmp6.h"
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
#include "net/packetbuf.h"
|
#include "net/packetbuf.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -86,6 +88,15 @@ static uint8_t dao_sequence = RPL_LOLLIPOP_INIT;
|
||||||
|
|
||||||
extern rpl_of_t RPL_OF;
|
extern rpl_of_t RPL_OF;
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
static uip_mcast6_route_t *mcast_group;
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Initialise RPL ICMPv6 message handlers */
|
||||||
|
UIP_ICMP6_HANDLER(dis_handler, ICMP6_RPL, RPL_CODE_DIS, dis_input);
|
||||||
|
UIP_ICMP6_HANDLER(dio_handler, ICMP6_RPL, RPL_CODE_DIO, dio_input);
|
||||||
|
UIP_ICMP6_HANDLER(dao_handler, ICMP6_RPL, RPL_CODE_DAO, dao_input);
|
||||||
|
UIP_ICMP6_HANDLER(dao_ack_handler, ICMP6_RPL, RPL_CODE_DAO_ACK, dao_ack_input);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
get_global_addr(uip_ipaddr_t *addr)
|
get_global_addr(uip_ipaddr_t *addr)
|
||||||
|
@ -163,6 +174,7 @@ dis_input(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -171,12 +183,14 @@ dis_output(uip_ipaddr_t *addr)
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
uip_ipaddr_t tmpaddr;
|
uip_ipaddr_t tmpaddr;
|
||||||
|
|
||||||
/* DAG Information Solicitation - 2 bytes reserved */
|
/*
|
||||||
/* 0 1 2 */
|
* DAG Information Solicitation - 2 bytes reserved
|
||||||
/* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 */
|
* 0 1 2
|
||||||
/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
||||||
/* | Flags | Reserved | Option(s)... */
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
|
* | Flags | Reserved | Option(s)...
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
*/
|
||||||
|
|
||||||
buffer = UIP_ICMP_PAYLOAD;
|
buffer = UIP_ICMP_PAYLOAD;
|
||||||
buffer[0] = buffer[1] = 0;
|
buffer[0] = buffer[1] = 0;
|
||||||
|
@ -236,7 +250,7 @@ dio_input(void)
|
||||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
} else {
|
} else {
|
||||||
PRINTF("RPL: Out of Memory, dropping DIO from ");
|
PRINTF("RPL: Out of memory, dropping DIO from ");
|
||||||
PRINT6ADDR(&from);
|
PRINT6ADDR(&from);
|
||||||
PRINTF(", ");
|
PRINTF(", ");
|
||||||
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
@ -378,7 +392,7 @@ dio_input(void)
|
||||||
break;
|
break;
|
||||||
case RPL_OPTION_PREFIX_INFO:
|
case RPL_OPTION_PREFIX_INFO:
|
||||||
if(len != 32) {
|
if(len != 32) {
|
||||||
PRINTF("RPL: DAG prefix info not ok, len != 32\n");
|
PRINTF("RPL: Invalid DAG prefix info, len != 32\n");
|
||||||
RPL_STAT(rpl_stats.malformed_msgs++);
|
RPL_STAT(rpl_stats.malformed_msgs++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -402,6 +416,8 @@ dio_input(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rpl_process_dio(&from, &dio);
|
rpl_process_dio(&from, &dio);
|
||||||
|
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -415,7 +431,7 @@ dio_output(rpl_instance_t *instance, uip_ipaddr_t *uc_addr)
|
||||||
#endif /* !RPL_LEAF_ONLY */
|
#endif /* !RPL_LEAF_ONLY */
|
||||||
|
|
||||||
#if RPL_LEAF_ONLY
|
#if RPL_LEAF_ONLY
|
||||||
/* In leaf mode, we send DIO message only as unicasts in response to
|
/* In leaf mode, we only send DIO messages as unicasts in response to
|
||||||
unicast DIS messages. */
|
unicast DIS messages. */
|
||||||
if(uc_addr == NULL) {
|
if(uc_addr == NULL) {
|
||||||
PRINTF("RPL: LEAF ONLY have multicast addr: skip dio_output\n");
|
PRINTF("RPL: LEAF ONLY have multicast addr: skip dio_output\n");
|
||||||
|
@ -578,10 +594,11 @@ dao_input(void)
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
int learned_from;
|
int learned_from;
|
||||||
rpl_parent_t *p;
|
rpl_parent_t *parent;
|
||||||
uip_ds6_nbr_t *nbr;
|
uip_ds6_nbr_t *nbr;
|
||||||
|
|
||||||
prefixlen = 0;
|
prefixlen = 0;
|
||||||
|
parent = NULL;
|
||||||
|
|
||||||
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr);
|
uip_ipaddr_copy(&dao_sender_addr, &UIP_IP_BUF->srcipaddr);
|
||||||
|
|
||||||
|
@ -611,15 +628,41 @@ dao_input(void)
|
||||||
sequence = buffer[pos++];
|
sequence = buffer[pos++];
|
||||||
|
|
||||||
dag = instance->current_dag;
|
dag = instance->current_dag;
|
||||||
/* Is the DAGID present? */
|
/* Is the DAG ID present? */
|
||||||
if(flags & RPL_DAO_D_FLAG) {
|
if(flags & RPL_DAO_D_FLAG) {
|
||||||
if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) {
|
if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) {
|
||||||
PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n");
|
PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos += 16;
|
pos += 16;
|
||||||
} else {
|
}
|
||||||
/* Perhaps, there are verification to do but ... */
|
|
||||||
|
learned_from = uip_is_addr_mcast(&dao_sender_addr) ?
|
||||||
|
RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO;
|
||||||
|
|
||||||
|
PRINTF("RPL: DAO from %s\n",
|
||||||
|
learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast");
|
||||||
|
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
|
||||||
|
/* Check whether this is a DAO forwarding loop. */
|
||||||
|
parent = rpl_find_parent(dag, &dao_sender_addr);
|
||||||
|
/* check if this is a new DAO registration with an "illegal" rank */
|
||||||
|
/* if we already route to this node it is likely */
|
||||||
|
if(parent != NULL &&
|
||||||
|
DAG_RANK(parent->rank, instance) < DAG_RANK(dag->rank, instance)) {
|
||||||
|
PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n",
|
||||||
|
DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance));
|
||||||
|
parent->rank = INFINITE_RANK;
|
||||||
|
parent->updated = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get the DAO from our parent, we also have a loop. */
|
||||||
|
if(parent != NULL && parent == dag->preferred_parent) {
|
||||||
|
PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n");
|
||||||
|
parent->rank = INFINITE_RANK;
|
||||||
|
parent->updated = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there are any RPL options present. */
|
/* Check if there are any RPL options present. */
|
||||||
|
@ -654,6 +697,17 @@ dao_input(void)
|
||||||
PRINT6ADDR(&prefix);
|
PRINT6ADDR(&prefix);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
if(uip_is_addr_mcast_global(&prefix)) {
|
||||||
|
mcast_group = uip_mcast6_route_add(&prefix);
|
||||||
|
if(mcast_group) {
|
||||||
|
mcast_group->dag = dag;
|
||||||
|
mcast_group->lifetime = RPL_LIFETIME(instance, lifetime);
|
||||||
|
}
|
||||||
|
goto fwd_dao;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
rep = uip_ds6_route_lookup(&prefix);
|
rep = uip_ds6_route_lookup(&prefix);
|
||||||
|
|
||||||
if(lifetime == RPL_ZERO_LIFETIME) {
|
if(lifetime == RPL_ZERO_LIFETIME) {
|
||||||
|
@ -687,34 +741,6 @@ dao_input(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
learned_from = uip_is_addr_mcast(&dao_sender_addr) ?
|
|
||||||
RPL_ROUTE_FROM_MULTICAST_DAO : RPL_ROUTE_FROM_UNICAST_DAO;
|
|
||||||
|
|
||||||
PRINTF("RPL: DAO from %s\n",
|
|
||||||
learned_from == RPL_ROUTE_FROM_UNICAST_DAO? "unicast": "multicast");
|
|
||||||
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
|
|
||||||
/* Check whether this is a DAO forwarding loop. */
|
|
||||||
p = rpl_find_parent(dag, &dao_sender_addr);
|
|
||||||
/* check if this is a new DAO registration with an "illegal" rank */
|
|
||||||
/* if we already route to this node it is likely */
|
|
||||||
if(p != NULL &&
|
|
||||||
DAG_RANK(p->rank, instance) < DAG_RANK(dag->rank, instance)) {
|
|
||||||
PRINTF("RPL: Loop detected when receiving a unicast DAO from a node with a lower rank! (%u < %u)\n",
|
|
||||||
DAG_RANK(p->rank, instance), DAG_RANK(dag->rank, instance));
|
|
||||||
p->rank = INFINITE_RANK;
|
|
||||||
p->updated = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get the DAO from our parent, we also have a loop. */
|
|
||||||
if(p != NULL && p == dag->preferred_parent) {
|
|
||||||
PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n");
|
|
||||||
p->rank = INFINITE_RANK;
|
|
||||||
p->updated = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINTF("RPL: adding DAO route\n");
|
PRINTF("RPL: adding DAO route\n");
|
||||||
|
|
||||||
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) {
|
if((nbr = uip_ds6_nbr_lookup(&dao_sender_addr)) == NULL) {
|
||||||
|
@ -740,7 +766,7 @@ dao_input(void)
|
||||||
PRINTF("RPL: Neighbor already in neighbor cache\n");
|
PRINTF("RPL: Neighbor already in neighbor cache\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl_lock_parent(p);
|
rpl_lock_parent(parent);
|
||||||
|
|
||||||
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr);
|
||||||
if(rep == NULL) {
|
if(rep == NULL) {
|
||||||
|
@ -752,6 +778,10 @@ dao_input(void)
|
||||||
rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
|
rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
|
||||||
rep->state.learned_from = learned_from;
|
rep->state.learned_from = learned_from;
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
fwd_dao:
|
||||||
|
#endif
|
||||||
|
|
||||||
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
|
if(learned_from == RPL_ROUTE_FROM_UNICAST_DAO) {
|
||||||
if(dag->preferred_parent != NULL &&
|
if(dag->preferred_parent != NULL &&
|
||||||
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
|
rpl_get_parent_ipaddr(dag->preferred_parent) != NULL) {
|
||||||
|
@ -765,6 +795,7 @@ dao_input(void)
|
||||||
dao_ack_output(instance, &dao_sender_addr, sequence);
|
dao_ack_output(instance, &dao_sender_addr, sequence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -894,6 +925,7 @@ dao_ack_input(void)
|
||||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
uip_len = 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -916,27 +948,12 @@ dao_ack_output(rpl_instance_t *instance, uip_ipaddr_t *dest, uint8_t sequence)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uip_rpl_input(void)
|
rpl_icmp6_register_handlers()
|
||||||
{
|
{
|
||||||
PRINTF("Received an RPL control message\n");
|
uip_icmp6_register_input_handler(&dis_handler);
|
||||||
switch(UIP_ICMP_BUF->icode) {
|
uip_icmp6_register_input_handler(&dio_handler);
|
||||||
case RPL_CODE_DIO:
|
uip_icmp6_register_input_handler(&dao_handler);
|
||||||
dio_input();
|
uip_icmp6_register_input_handler(&dao_ack_handler);
|
||||||
break;
|
|
||||||
case RPL_CODE_DIS:
|
|
||||||
dis_input();
|
|
||||||
break;
|
|
||||||
case RPL_CODE_DAO:
|
|
||||||
dao_input();
|
|
||||||
break;
|
|
||||||
case RPL_CODE_DAO_ACK:
|
|
||||||
dao_ack_input();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PRINTF("RPL: received an unknown ICMP6 code (%u)\n", UIP_ICMP_BUF->icode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uip_len = 0;
|
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -104,7 +104,7 @@ calculate_path_metric(rpl_parent_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reset(rpl_dag_t *sag)
|
reset(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
PRINTF("RPL: Reset MRHOF\n");
|
PRINTF("RPL: Reset MRHOF\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "sys/clock.h"
|
#include "sys/clock.h"
|
||||||
#include "sys/ctimer.h"
|
#include "sys/ctimer.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \brief Is IPv6 address addr the link-local, all-RPL-nodes
|
/** \brief Is IPv6 address addr the link-local, all-RPL-nodes
|
||||||
|
@ -177,8 +178,24 @@
|
||||||
|
|
||||||
#ifdef RPL_CONF_MOP
|
#ifdef RPL_CONF_MOP
|
||||||
#define RPL_MOP_DEFAULT RPL_CONF_MOP
|
#define RPL_MOP_DEFAULT RPL_CONF_MOP
|
||||||
|
#else /* RPL_CONF_MOP */
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
#define RPL_MOP_DEFAULT RPL_MOP_STORING_MULTICAST
|
||||||
#else
|
#else
|
||||||
#define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST
|
#define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST
|
||||||
|
#endif /* UIP_IPV6_MULTICAST_RPL */
|
||||||
|
#endif /* RPL_CONF_MOP */
|
||||||
|
|
||||||
|
/* Emit a pre-processor error if the user configured multicast with bad MOP */
|
||||||
|
#if RPL_CONF_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST)
|
||||||
|
#error "RPL Multicast requires RPL_MOP_DEFAULT==3. Check contiki-conf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Multicast Route Lifetime as a multiple of the lifetime unit */
|
||||||
|
#ifdef RPL_CONF_MCAST_LIFETIME
|
||||||
|
#define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME
|
||||||
|
#else
|
||||||
|
#define RPL_MCAST_LIFETIME 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -186,7 +203,7 @@
|
||||||
* whose integer part can be obtained by dividing the value by
|
* whose integer part can be obtained by dividing the value by
|
||||||
* RPL_DAG_MC_ETX_DIVISOR.
|
* RPL_DAG_MC_ETX_DIVISOR.
|
||||||
*/
|
*/
|
||||||
#define RPL_DAG_MC_ETX_DIVISOR 128
|
#define RPL_DAG_MC_ETX_DIVISOR 256
|
||||||
|
|
||||||
/* DIS related */
|
/* DIS related */
|
||||||
#define RPL_DIS_SEND 1
|
#define RPL_DIS_SEND 1
|
||||||
|
@ -272,6 +289,7 @@ void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
|
||||||
void dao_output(rpl_parent_t *, uint8_t lifetime);
|
void dao_output(rpl_parent_t *, uint8_t lifetime);
|
||||||
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
|
||||||
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
|
||||||
|
void rpl_icmp6_register_handlers(void);
|
||||||
|
|
||||||
/* RPL logic functions. */
|
/* RPL logic functions. */
|
||||||
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include "contiki-conf.h"
|
#include "contiki-conf.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
#include "lib/random.h"
|
#include "lib/random.h"
|
||||||
#include "sys/ctimer.h"
|
#include "sys/ctimer.h"
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ handle_periodic_timer(void *ptr)
|
||||||
rpl_recalculate_ranks();
|
rpl_recalculate_ranks();
|
||||||
|
|
||||||
/* handle DIS */
|
/* handle DIS */
|
||||||
#ifdef RPL_DIS_SEND
|
#if RPL_DIS_SEND
|
||||||
next_dis++;
|
next_dis++;
|
||||||
if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) {
|
if(rpl_get_any_dag() == NULL && next_dis >= RPL_DIS_INTERVAL) {
|
||||||
next_dis = 0;
|
next_dis = 0;
|
||||||
|
@ -220,6 +221,10 @@ static void
|
||||||
handle_dao_timer(void *ptr)
|
handle_dao_timer(void *ptr)
|
||||||
{
|
{
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
uip_mcast6_route_t *mcast_route;
|
||||||
|
uint8_t i;
|
||||||
|
#endif
|
||||||
|
|
||||||
instance = (rpl_instance_t *)ptr;
|
instance = (rpl_instance_t *)ptr;
|
||||||
|
|
||||||
|
@ -234,6 +239,31 @@ handle_dao_timer(void *ptr)
|
||||||
PRINTF("RPL: handle_dao_timer - sending DAO\n");
|
PRINTF("RPL: handle_dao_timer - sending DAO\n");
|
||||||
/* Set the route lifetime to the default value. */
|
/* Set the route lifetime to the default value. */
|
||||||
dao_output(instance->current_dag->preferred_parent, instance->default_lifetime);
|
dao_output(instance->current_dag->preferred_parent, instance->default_lifetime);
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
/* Send DAOs for multicast prefixes only if the instance is in MOP 3 */
|
||||||
|
if(instance->mop == RPL_MOP_STORING_MULTICAST) {
|
||||||
|
/* Send a DAO for own multicast addresses */
|
||||||
|
for(i = 0; i < UIP_DS6_MADDR_NB; i++) {
|
||||||
|
if(uip_ds6_if.maddr_list[i].isused
|
||||||
|
&& uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) {
|
||||||
|
dao_output_target(instance->current_dag->preferred_parent,
|
||||||
|
&uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over multicast routes and send DAOs */
|
||||||
|
mcast_route = uip_mcast6_route_list_head();
|
||||||
|
while(mcast_route != NULL) {
|
||||||
|
/* Don't send if it's also our own address, done that already */
|
||||||
|
if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) {
|
||||||
|
dao_output_target(instance->current_dag->preferred_parent,
|
||||||
|
&mcast_route->group, RPL_MCAST_LIFETIME);
|
||||||
|
}
|
||||||
|
mcast_route = list_item_next(mcast_route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
PRINTF("RPL: No suitable DAO parent\n");
|
PRINTF("RPL: No suitable DAO parent\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,9 @@
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
#define DEBUG DEBUG_NONE
|
#define DEBUG DEBUG_NONE
|
||||||
#include "net/ip/uip-debug.h"
|
#include "net/ip/uip-debug.h"
|
||||||
|
@ -105,6 +107,9 @@ rpl_purge_routes(void)
|
||||||
uip_ds6_route_t *r;
|
uip_ds6_route_t *r;
|
||||||
uip_ipaddr_t prefix;
|
uip_ipaddr_t prefix;
|
||||||
rpl_dag_t *dag;
|
rpl_dag_t *dag;
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
uip_mcast6_route_t *mcast_route;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* First pass, decrement lifetime */
|
/* First pass, decrement lifetime */
|
||||||
r = uip_ds6_route_head();
|
r = uip_ds6_route_head();
|
||||||
|
@ -146,12 +151,29 @@ rpl_purge_routes(void)
|
||||||
r = uip_ds6_route_next(r);
|
r = uip_ds6_route_next(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
mcast_route = uip_mcast6_route_list_head();
|
||||||
|
|
||||||
|
while(mcast_route != NULL) {
|
||||||
|
if(mcast_route->lifetime <= 1) {
|
||||||
|
uip_mcast6_route_rm(mcast_route);
|
||||||
|
mcast_route = uip_mcast6_route_list_head();
|
||||||
|
} else {
|
||||||
|
mcast_route->lifetime--;
|
||||||
|
mcast_route = list_item_next(mcast_route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_remove_routes(rpl_dag_t *dag)
|
rpl_remove_routes(rpl_dag_t *dag)
|
||||||
{
|
{
|
||||||
uip_ds6_route_t *r;
|
uip_ds6_route_t *r;
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
uip_mcast6_route_t *mcast_route;
|
||||||
|
#endif
|
||||||
|
|
||||||
r = uip_ds6_route_head();
|
r = uip_ds6_route_head();
|
||||||
|
|
||||||
|
@ -163,6 +185,19 @@ rpl_remove_routes(rpl_dag_t *dag)
|
||||||
r = uip_ds6_route_next(r);
|
r = uip_ds6_route_next(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RPL_CONF_MULTICAST
|
||||||
|
mcast_route = uip_mcast6_route_list_head();
|
||||||
|
|
||||||
|
while(mcast_route != NULL) {
|
||||||
|
if(mcast_route->dag == dag) {
|
||||||
|
uip_mcast6_route_rm(mcast_route);
|
||||||
|
mcast_route = uip_mcast6_route_list_head();
|
||||||
|
} else {
|
||||||
|
mcast_route = list_item_next(mcast_route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -266,6 +301,7 @@ rpl_init(void)
|
||||||
|
|
||||||
rpl_dag_init();
|
rpl_dag_init();
|
||||||
rpl_reset_periodic_timer();
|
rpl_reset_periodic_timer();
|
||||||
|
rpl_icmp6_register_handlers();
|
||||||
|
|
||||||
/* add rpl multicast address */
|
/* add rpl multicast address */
|
||||||
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
uip_create_linklocal_rplnodes_mcast(&rplmaddr);
|
||||||
|
@ -274,6 +310,8 @@ rpl_init(void)
|
||||||
#if RPL_CONF_STATS
|
#if RPL_CONF_STATS
|
||||||
memset(&rpl_stats, 0, sizeof(rpl_stats));
|
memset(&rpl_stats, 0, sizeof(rpl_stats));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RPL_OF.reset(NULL);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_CONF_IPV6 */
|
#endif /* UIP_CONF_IPV6 */
|
||||||
|
|
|
@ -189,6 +189,9 @@ struct rpl_of {
|
||||||
rpl_ocp_t ocp;
|
rpl_ocp_t ocp;
|
||||||
};
|
};
|
||||||
typedef struct rpl_of rpl_of_t;
|
typedef struct rpl_of rpl_of_t;
|
||||||
|
|
||||||
|
/* Declare the selected objective function. */
|
||||||
|
extern rpl_of_t RPL_OF;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Instance */
|
/* Instance */
|
||||||
struct rpl_instance {
|
struct rpl_instance {
|
||||||
|
|
|
@ -67,5 +67,5 @@ AR = ar65
|
||||||
|
|
||||||
ASFLAGS = -t $(TARGET)
|
ASFLAGS = -t $(TARGET)
|
||||||
CFLAGS += -t $(TARGET) -Or -W -unused-param
|
CFLAGS += -t $(TARGET) -Or -W -unused-param
|
||||||
LDFLAGS = $(STARTADDR_FLAG) -t $(TARGET) -m contiki-$(TARGET).map -D __STACKSIZE__=0x200
|
LDFLAGS = -t $(TARGET) -m contiki-$(TARGET).map -D __STACKSIZE__=0x200
|
||||||
AROPTS = a
|
AROPTS = a
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
====
|
====
|
||||||
|
|
||||||
The cpu/6502/ directory is used for targeting 6502-based machines using the
|
The cpu/6502/ directory is used for targeting 6502-based machines using the
|
||||||
cc65 compiler [http://oliverschmidt.github.io/cc65/](http://oliverschmidt.github.io/cc65/).
|
cc65 compiler [http://cc65.github.io/cc65/](http://cc65.github.io/cc65/).
|
||||||
|
|
||||||
The Contiki network configuration for 6502-based targets is loaded from a
|
The Contiki network configuration for 6502-based targets is loaded from a
|
||||||
binary configuration file (by default named contiki.cfg). It has the following
|
binary configuration file (by default named contiki.cfg). It has the following
|
||||||
|
|
|
@ -11,7 +11,7 @@ static struct {
|
||||||
} drivers[] = {
|
} drivers[] = {
|
||||||
#ifdef __APPLE2__
|
#ifdef __APPLE2__
|
||||||
{"Uthernet", 0xC080, "cs8900a.eth" },
|
{"Uthernet", 0xC080, "cs8900a.eth" },
|
||||||
{"Uthernet II", 0xC080, "w5100.eth" },
|
{"Uthernet II", 0xC084, "w5100.eth" },
|
||||||
{"LANceGS", 0xC080, "lan91c96.eth"}
|
{"LANceGS", 0xC080, "lan91c96.eth"}
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ATARI__
|
#ifdef __ATARI__
|
||||||
|
|
|
@ -202,8 +202,8 @@ fixup11:ora data ; Lobyte
|
||||||
; Calculate and set physical address
|
; Calculate and set physical address
|
||||||
jsr set_addrphysical
|
jsr set_addrphysical
|
||||||
|
|
||||||
; Move physical address shadow to $F000-$FFFF
|
; Move physical address shadow to $E000-$FFFF
|
||||||
ora #>$F000
|
ora #>$8000
|
||||||
tax
|
tax
|
||||||
|
|
||||||
; Read MAC raw 2byte packet size header
|
; Read MAC raw 2byte packet size header
|
||||||
|
|
|
@ -3,6 +3,7 @@ CPP = arm-none-eabi-cpp
|
||||||
LD = arm-none-eabi-gcc
|
LD = arm-none-eabi-gcc
|
||||||
AR = arm-none-eabi-ar
|
AR = arm-none-eabi-ar
|
||||||
OBJCOPY = arm-none-eabi-objcopy
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
|
OBJDUMP = arm-none-eabi-objdump
|
||||||
NM = arm-none-eabi-nm
|
NM = arm-none-eabi-nm
|
||||||
|
|
||||||
ifndef SOURCE_LDSCRIPT
|
ifndef SOURCE_LDSCRIPT
|
||||||
|
@ -19,6 +20,7 @@ LDFLAGS += -T $(LDSCRIPT)
|
||||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||||
LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
LDFLAGS += -Wl,-Map=$(@:.elf=-$(TARGET).map),--cref,--no-warn-mismatch
|
||||||
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
OBJCOPY_FLAGS += -O binary --gap-fill 0xff
|
||||||
|
OBJDUMP_FLAGS += --disassemble --source --disassembler-options=force-thumb
|
||||||
|
|
||||||
### Are we building with code size optimisations?
|
### Are we building with code size optimisations?
|
||||||
ifeq ($(SMALL),1)
|
ifeq ($(SMALL),1)
|
||||||
|
@ -46,7 +48,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
|
||||||
|
|
||||||
### CPU-dependent source files
|
### CPU-dependent source files
|
||||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
|
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
|
||||||
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c
|
CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
|
||||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
||||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||||
|
@ -82,6 +84,9 @@ CUSTOM_RULE_LINK=1
|
||||||
%.bin: %.elf
|
%.bin: %.elf
|
||||||
$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
|
$(OBJCOPY) $(OBJCOPY_FLAGS) $< $@
|
||||||
|
|
||||||
|
%.lst: %.elf
|
||||||
|
$(OBJDUMP) $(OBJDUMP_FLAGS) $< > $@
|
||||||
|
|
||||||
### We don't really need the .hex and .bin for the .$(TARGET) but let's make
|
### We don't really need the .hex and .bin for the .$(TARGET) but let's make
|
||||||
### sure they get built
|
### sure they get built
|
||||||
%.$(TARGET): %.elf %.hex %.bin
|
%.$(TARGET): %.elf %.hex %.bin
|
||||||
|
|
|
@ -38,7 +38,11 @@
|
||||||
*
|
*
|
||||||
* To implement the clock functionality, we use the SysTick peripheral on the
|
* To implement the clock functionality, we use the SysTick peripheral on the
|
||||||
* cortex-M3. We run the system clock at 16 MHz and we set the SysTick to give
|
* cortex-M3. We run the system clock at 16 MHz and we set the SysTick to give
|
||||||
* us 128 interrupts / sec
|
* us 128 interrupts / sec. However, the Sleep Timer counter value is used for
|
||||||
|
* the number of elapsed ticks in order to avoid a significant time drift caused
|
||||||
|
* by PM1/2. Contrary to the Sleep Timer, the SysTick peripheral is indeed
|
||||||
|
* frozen during PM1/2, so adjusting upon wake-up a tick counter based on this
|
||||||
|
* peripheral would hardly be accurate.
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
|
@ -52,14 +56,15 @@
|
||||||
#include "dev/sys-ctrl.h"
|
#include "dev/sys-ctrl.h"
|
||||||
|
|
||||||
#include "sys/energest.h"
|
#include "sys/energest.h"
|
||||||
|
#include "sys/etimer.h"
|
||||||
|
#include "sys/rtimer.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define RTIMER_CLOCK_TICK_RATIO (RTIMER_SECOND / CLOCK_SECOND)
|
||||||
#define RELOAD_VALUE (125000 - 1) /** Fire 128 times / sec */
|
#define RELOAD_VALUE (125000 - 1) /** Fire 128 times / sec */
|
||||||
|
|
||||||
static volatile clock_time_t count;
|
static volatile uint64_t rt_ticks_startup = 0, rt_ticks_epoch = 0;
|
||||||
static volatile unsigned long secs = 0;
|
|
||||||
static volatile uint8_t second_countdown = CLOCK_SECOND;
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \brief Arch-specific implementation of clock_init for the cc2538
|
* \brief Arch-specific implementation of clock_init for the cc2538
|
||||||
|
@ -75,8 +80,6 @@ static volatile uint8_t second_countdown = CLOCK_SECOND;
|
||||||
void
|
void
|
||||||
clock_init(void)
|
clock_init(void)
|
||||||
{
|
{
|
||||||
count = 0;
|
|
||||||
|
|
||||||
REG(SYSTICK_STRELOAD) = RELOAD_VALUE;
|
REG(SYSTICK_STRELOAD) = RELOAD_VALUE;
|
||||||
|
|
||||||
/* System clock source, Enable */
|
/* System clock source, Enable */
|
||||||
|
@ -109,19 +112,19 @@ clock_init(void)
|
||||||
CCIF clock_time_t
|
CCIF clock_time_t
|
||||||
clock_time(void)
|
clock_time(void)
|
||||||
{
|
{
|
||||||
return count;
|
return rt_ticks_startup / RTIMER_CLOCK_TICK_RATIO;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
clock_set_seconds(unsigned long sec)
|
clock_set_seconds(unsigned long sec)
|
||||||
{
|
{
|
||||||
secs = sec;
|
rt_ticks_epoch = (uint64_t)sec * RTIMER_SECOND;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
CCIF unsigned long
|
CCIF unsigned long
|
||||||
clock_seconds(void)
|
clock_seconds(void)
|
||||||
{
|
{
|
||||||
return secs;
|
return rt_ticks_epoch / RTIMER_SECOND;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -160,63 +163,84 @@ clock_delay(unsigned int i)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \brief Adjust the clock by moving it forward by a number of ticks
|
* \brief Update the software clock ticks and seconds
|
||||||
* \param ticks The number of ticks
|
*
|
||||||
|
* This function is used to update the software tick counters whenever the
|
||||||
|
* system clock might have changed, which can occur upon a SysTick ISR or upon
|
||||||
|
* wake-up from PM1/2.
|
||||||
|
*
|
||||||
|
* For the software clock ticks counter, the Sleep Timer counter value is used
|
||||||
|
* as the base tick value, and extended to a 64-bit value thanks to a detection
|
||||||
|
* of wraparounds.
|
||||||
|
*
|
||||||
|
* For the seconds counter, the changes of the Sleep Timer counter value are
|
||||||
|
* added to the reference time, which is either the startup time or the value
|
||||||
|
* passed to clock_set_seconds().
|
||||||
|
*
|
||||||
|
* This function polls the etimer process if an etimer has expired.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
update_ticks(void)
|
||||||
|
{
|
||||||
|
rtimer_clock_t now;
|
||||||
|
uint64_t prev_rt_ticks_startup, cur_rt_ticks_startup;
|
||||||
|
uint32_t cur_rt_ticks_startup_hi;
|
||||||
|
|
||||||
|
now = RTIMER_NOW();
|
||||||
|
prev_rt_ticks_startup = rt_ticks_startup;
|
||||||
|
|
||||||
|
cur_rt_ticks_startup_hi = prev_rt_ticks_startup >> 32;
|
||||||
|
if(now < (rtimer_clock_t)prev_rt_ticks_startup) {
|
||||||
|
cur_rt_ticks_startup_hi++;
|
||||||
|
}
|
||||||
|
cur_rt_ticks_startup = (uint64_t)cur_rt_ticks_startup_hi << 32 | now;
|
||||||
|
rt_ticks_startup = cur_rt_ticks_startup;
|
||||||
|
|
||||||
|
rt_ticks_epoch += cur_rt_ticks_startup - prev_rt_ticks_startup;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inform the etimer library that the system clock has changed and that an
|
||||||
|
* etimer might have expired.
|
||||||
|
*/
|
||||||
|
if(etimer_pending()) {
|
||||||
|
etimer_request_poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Adjust the clock following missed SysTick ISRs
|
||||||
*
|
*
|
||||||
* This function is useful when coming out of PM1/2, during which the system
|
* This function is useful when coming out of PM1/2, during which the system
|
||||||
* clock is stopped. We adjust the clock by moving it forward by a number of
|
* clock is stopped. We adjust the clock counters like after any SysTick ISR.
|
||||||
* ticks equal to the deep sleep duration. We update the seconds counter if
|
|
||||||
* we have to and we also do some housekeeping so that the next second will
|
|
||||||
* increment when it is meant to.
|
|
||||||
*
|
*
|
||||||
* \note This function is only meant to be used by lpm_exit(). Applications
|
* \note This function is only meant to be used by lpm_exit(). Applications
|
||||||
* should really avoid calling this
|
* should really avoid calling this
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clock_adjust(clock_time_t ticks)
|
clock_adjust(void)
|
||||||
{
|
{
|
||||||
/* Halt the SysTick while adjusting */
|
/* Halt the SysTick while adjusting */
|
||||||
REG(SYSTICK_STCTRL) &= ~SYSTICK_STCTRL_ENABLE;
|
REG(SYSTICK_STCTRL) &= ~SYSTICK_STCTRL_ENABLE;
|
||||||
|
|
||||||
/* Moving forward by more than a second? */
|
update_ticks();
|
||||||
secs += ticks >> 7;
|
|
||||||
|
|
||||||
/* Increment tick count */
|
|
||||||
count += ticks;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update internal second countdown so that next second change will actually
|
|
||||||
* happen when it's meant to happen.
|
|
||||||
*/
|
|
||||||
second_countdown -= ticks;
|
|
||||||
|
|
||||||
if(second_countdown == 0 || second_countdown > 128) {
|
|
||||||
secs++;
|
|
||||||
second_countdown -= 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Re-Start the SysTick */
|
/* Re-Start the SysTick */
|
||||||
REG(SYSTICK_STCTRL) |= SYSTICK_STCTRL_ENABLE;
|
REG(SYSTICK_STCTRL) |= SYSTICK_STCTRL_ENABLE;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \brief The clock Interrupt Service Routine. It polls the etimer process
|
* \brief The clock Interrupt Service Routine
|
||||||
* if an etimer has expired. It also updates the software clock tick and
|
*
|
||||||
* seconds counter since reset.
|
* It polls the etimer process if an etimer has expired. It also updates the
|
||||||
|
* software clock tick and seconds counter.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clock_isr(void)
|
clock_isr(void)
|
||||||
{
|
{
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
count++;
|
|
||||||
if(etimer_pending()) {
|
|
||||||
etimer_request_poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(--second_countdown == 0) {
|
update_ticks();
|
||||||
secs++;
|
|
||||||
second_countdown = CLOCK_SECOND;
|
|
||||||
}
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#define write_byte(b) usb_serial_writeb(b)
|
#define write_byte(b) usb_serial_writeb(b)
|
||||||
#define flush() usb_serial_flush()
|
#define flush() usb_serial_flush()
|
||||||
#else
|
#else
|
||||||
#define write_byte(b) uart_write_byte(b)
|
#define write_byte(b) uart_write_byte(DBG_CONF_UART, b)
|
||||||
#define flush()
|
#define flush()
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
99
cpu/cc2538/dev/adc.c
Normal file
99
cpu/cc2538/dev/adc.c
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||||
|
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc2538-adc
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Implementation of the cc2538 ADC driver
|
||||||
|
*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/soc-adc.h"
|
||||||
|
#include "dev/cctest.h"
|
||||||
|
#include "dev/rfcore-xreg.h"
|
||||||
|
#include "dev/adc.h"
|
||||||
|
#include "reg.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
adc_init(void)
|
||||||
|
{
|
||||||
|
/* Start conversions only manually */
|
||||||
|
REG(SOC_ADC_ADCCON1) |= SOC_ADC_ADCCON1_STSEL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int16_t
|
||||||
|
adc_get(uint8_t channel, uint8_t ref, uint8_t div)
|
||||||
|
{
|
||||||
|
uint32_t cctest_tr0, rfcore_xreg_atest;
|
||||||
|
int16_t res;
|
||||||
|
|
||||||
|
/* On-chip temperature sensor */
|
||||||
|
if(channel == SOC_ADC_ADCCON_CH_TEMP) {
|
||||||
|
/* Connect the temperature sensor to the ADC */
|
||||||
|
cctest_tr0 = REG(CCTEST_TR0);
|
||||||
|
REG(CCTEST_TR0) = cctest_tr0 | CCTEST_TR0_ADCTM;
|
||||||
|
|
||||||
|
/* Enable the temperature sensor */
|
||||||
|
rfcore_xreg_atest = REG(RFCORE_XREG_ATEST);
|
||||||
|
REG(RFCORE_XREG_ATEST) = (rfcore_xreg_atest & ~RFCORE_XREG_ATEST_ATEST_CTRL) |
|
||||||
|
RFCORE_XREG_ATEST_ATEST_CTRL_TEMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start a single extra conversion with the given parameters */
|
||||||
|
REG(SOC_ADC_ADCCON3) = (REG(SOC_ADC_ADCCON3) &
|
||||||
|
~(SOC_ADC_ADCCON3_EREF | SOC_ADC_ADCCON3_EDIV | SOC_ADC_ADCCON3_ECH)) |
|
||||||
|
ref | div | channel;
|
||||||
|
|
||||||
|
/* Poll until end of conversion */
|
||||||
|
while(!(REG(SOC_ADC_ADCCON1) & SOC_ADC_ADCCON1_EOC));
|
||||||
|
|
||||||
|
/* Read conversion result, reading SOC_ADC_ADCH last to clear
|
||||||
|
* SOC_ADC_ADCCON1.EOC */
|
||||||
|
res = REG(SOC_ADC_ADCL) & 0xfc;
|
||||||
|
res |= REG(SOC_ADC_ADCH) << 8;
|
||||||
|
|
||||||
|
/* On-chip temperature sensor */
|
||||||
|
if(channel == SOC_ADC_ADCCON_CH_TEMP) {
|
||||||
|
/* Restore the initial temperature sensor state and connection (better for
|
||||||
|
* power consumption) */
|
||||||
|
REG(RFCORE_XREG_ATEST) = rfcore_xreg_atest;
|
||||||
|
REG(CCTEST_TR0) = cctest_tr0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return conversion result */
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
75
cpu/cc2538/dev/adc.h
Normal file
75
cpu/cc2538/dev/adc.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||||
|
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc2538
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \defgroup cc2538-adc cc2538 ADC
|
||||||
|
*
|
||||||
|
* Driver for the cc2538 ADC controller
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Header file for the cc2538 ADC driver
|
||||||
|
*/
|
||||||
|
#ifndef ADC_H_
|
||||||
|
#define ADC_H_
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/soc-adc.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name ADC functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Initializes the ADC controller */
|
||||||
|
void adc_init(void);
|
||||||
|
|
||||||
|
/** \brief Performs a single conversion on a given ADC channel
|
||||||
|
* \param channel The channel used for the conversion: \c SOC_ADC_ADCCON_CH_x
|
||||||
|
* \param ref The reference voltage used for the conversion: \c SOC_ADC_ADCCON_REF_x
|
||||||
|
* \param div The decimation rate used for the conversion: \c SOC_ADC_ADCCON_DIV_x
|
||||||
|
* \return Signed 16-bit conversion result: 2's complement, ENOBs in MSBs
|
||||||
|
* \note PD[5:4] are not usable when the temperature sensor is selected.
|
||||||
|
*/
|
||||||
|
int16_t adc_get(uint8_t channel, uint8_t ref, uint8_t div);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* ADC_H_ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
|
@ -106,7 +106,7 @@ static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /** Snif */
|
||||||
#define flush() usb_serial_flush()
|
#define flush() usb_serial_flush()
|
||||||
#else
|
#else
|
||||||
#include "dev/uart.h"
|
#include "dev/uart.h"
|
||||||
#define write_byte(b) uart_write_byte(b)
|
#define write_byte(b) uart_write_byte(CC2538_RF_CONF_SNIFFER_UART, b)
|
||||||
#define flush()
|
#define flush()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
92
cpu/cc2538/dev/cctest.h
Normal file
92
cpu/cc2538/dev/cctest.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Original file:
|
||||||
|
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Port to Contiki:
|
||||||
|
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||||
|
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc2538-rfcore
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Header with declarations of CCTEST module registers.
|
||||||
|
*/
|
||||||
|
#ifndef CCTEST_H
|
||||||
|
#define CCTEST_H
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \name CCTEST register offsets
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CCTEST_IO 0x44010000 /**< Output strength control */
|
||||||
|
#define CCTEST_OBSSEL0 0x44010014 /**< Observation output 0 */
|
||||||
|
#define CCTEST_OBSSEL1 0x44010018 /**< Observation output 1 */
|
||||||
|
#define CCTEST_OBSSEL2 0x4401001C /**< Observation output 2 */
|
||||||
|
#define CCTEST_OBSSEL3 0x44010020 /**< Observation output 3 */
|
||||||
|
#define CCTEST_OBSSEL4 0x44010024 /**< Observation output 4 */
|
||||||
|
#define CCTEST_OBSSEL5 0x44010028 /**< Observation output 5 */
|
||||||
|
#define CCTEST_OBSSEL6 0x4401002C /**< Observation output 6 */
|
||||||
|
#define CCTEST_OBSSEL7 0x44010030 /**< Observation output 7 */
|
||||||
|
#define CCTEST_TR0 0x44010034 /**< Test register 0 */
|
||||||
|
#define CCTEST_USBCTRL 0x44010050 /**< USB PHY stand-by control */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name CCTEST_IO register bit fields
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CCTEST_IO_SC 0x00000001 /**< I/O strength control */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name CCTEST_OBSSELx registers bit fields
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CCTEST_OBSSEL_EN 0x00000080 /**< Observation output enable */
|
||||||
|
#define CCTEST_OBSSEL_SEL_M 0x0000007F /**< n - obs_sigs[n] output selection mask */
|
||||||
|
#define CCTEST_OBSSEL_SEL_S 0 /**< n - obs_sigs[n] output selection shift */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name CCTEST_TR0 register bit fields
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CCTEST_TR0_ADCTM 0x00000002 /**< Connect temperature sensor to ADC */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name CCTEST_USBCTRL register bit fields
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CCTEST_USBCTRL_USB_STB 0x00000001 /**< USB PHY stand-by override */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* CCTEST_H */
|
||||||
|
/** @} */
|
|
@ -575,6 +575,8 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define RFCORE_XREG_ATEST_ATEST_CTRL 0x0000003F /**< Controls the analog test mode */
|
#define RFCORE_XREG_ATEST_ATEST_CTRL 0x0000003F /**< Controls the analog test mode */
|
||||||
|
#define RFCORE_XREG_ATEST_ATEST_CTRL_DIS 0x00000000 /**< Analog test mode: disabled */
|
||||||
|
#define RFCORE_XREG_ATEST_ATEST_CTRL_TEMP 0x00000001 /**< Analog test mode: enable temperature sensor */
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name RFCORE_XREG_PTEST0 register bit masks
|
/** \name RFCORE_XREG_PTEST0 register bit masks
|
||||||
|
|
|
@ -83,6 +83,34 @@
|
||||||
#define SOC_ADC_ADCCON3_ECH 0x0000000F /**< Single channel select */
|
#define SOC_ADC_ADCCON3_ECH 0x0000000F /**< Single channel select */
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name SOC_ADC_ADCCONx registers field values
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SOC_ADC_ADCCON_REF_INT (0 << 6) /**< Internal reference */
|
||||||
|
#define SOC_ADC_ADCCON_REF_EXT_SINGLE (1 << 6) /**< External reference on AIN7 pin */
|
||||||
|
#define SOC_ADC_ADCCON_REF_AVDD5 (2 << 6) /**< AVDD5 pin */
|
||||||
|
#define SOC_ADC_ADCCON_REF_EXT_DIFF (3 << 6) /**< External reference on AIN6-AIN7 differential input */
|
||||||
|
#define SOC_ADC_ADCCON_DIV_64 (0 << 4) /**< 64 decimation rate (7 bits ENOB) */
|
||||||
|
#define SOC_ADC_ADCCON_DIV_128 (1 << 4) /**< 128 decimation rate (9 bits ENOB) */
|
||||||
|
#define SOC_ADC_ADCCON_DIV_256 (2 << 4) /**< 256 decimation rate (10 bits ENOB) */
|
||||||
|
#define SOC_ADC_ADCCON_DIV_512 (3 << 4) /**< 512 decimation rate (12 bits ENOB) */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN0 0x0 /**< AIN0 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN1 0x1 /**< AIN1 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN2 0x2 /**< AIN2 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN3 0x3 /**< AIN3 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN4 0x4 /**< AIN4 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN5 0x5 /**< AIN5 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN6 0x6 /**< AIN6 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN7 0x7 /**< AIN7 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN0_AIN1 0x8 /**< AIN0-AIN1 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN2_AIN3 0x9 /**< AIN2-AIN3 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN4_AIN5 0xA /**< AIN4-AIN5 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_AIN6_AIN7 0xB /**< AIN6-AIN7 */
|
||||||
|
#define SOC_ADC_ADCCON_CH_GND 0xC /**< GND */
|
||||||
|
#define SOC_ADC_ADCCON_CH_TEMP 0xE /**< Temperature sensor */
|
||||||
|
#define SOC_ADC_ADCCON_CH_VDD_3 0xF /**< VDD/3 */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name SOC_ADC_ADC[L:H] register bit masks
|
/** \name SOC_ADC_ADC[L:H] register bit masks
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,23 +48,6 @@
|
||||||
#define SPI_MOSI_PIN_MASK GPIO_PIN_MASK(SPI_MOSI_PIN)
|
#define SPI_MOSI_PIN_MASK GPIO_PIN_MASK(SPI_MOSI_PIN)
|
||||||
#define SPI_MISO_PORT_BASE GPIO_PORT_TO_BASE(SPI_MISO_PORT)
|
#define SPI_MISO_PORT_BASE GPIO_PORT_TO_BASE(SPI_MISO_PORT)
|
||||||
#define SPI_MISO_PIN_MASK GPIO_PIN_MASK(SPI_MISO_PIN)
|
#define SPI_MISO_PIN_MASK GPIO_PIN_MASK(SPI_MISO_PIN)
|
||||||
#define SPI_SEL_PORT_BASE GPIO_PORT_TO_BASE(SPI_SEL_PORT)
|
|
||||||
#define SPI_SEL_PIN_MASK GPIO_PIN_MASK(SPI_SEL_PIN)
|
|
||||||
|
|
||||||
/* Default: Motorola mode 3 with 8-bit data words */
|
|
||||||
#ifndef SPI_CONF_PHASE
|
|
||||||
#define SPI_CONF_PHASE SSI_CR0_SPH
|
|
||||||
#endif
|
|
||||||
#ifndef SPI_CONF_POLARITY
|
|
||||||
#define SPI_CONF_POLARITY SSI_CR0_SPO
|
|
||||||
#endif
|
|
||||||
#ifndef SPI_CONF_DATA_SIZE
|
|
||||||
#define SPI_CONF_DATA_SIZE 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SPI_CONF_DATA_SIZE < 4 || SPI_CONF_DATA_SIZE > 16
|
|
||||||
#error SPI_CONF_DATA_SIZE must be set between 4 and 16 inclusive.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize the SPI bus.
|
* \brief Initialize the SPI bus.
|
||||||
|
@ -73,12 +56,11 @@
|
||||||
* SPI_CLK_PORT SPI_CLK_PIN
|
* SPI_CLK_PORT SPI_CLK_PIN
|
||||||
* SPI_MOSI_PORT SPI_MOSI_PIN
|
* SPI_MOSI_PORT SPI_MOSI_PIN
|
||||||
* SPI_MISO_PORT SPI_MISO_PIN
|
* SPI_MISO_PORT SPI_MISO_PIN
|
||||||
* SPI_SEL_PORT SPI_SEL_PIN
|
|
||||||
*
|
*
|
||||||
* This sets the mode to Motorola SPI with the following format options:
|
* This sets the mode to Motorola SPI with the following format options:
|
||||||
* SPI_CONF_PHASE: 0 or SSI_CR0_SPH
|
* Clock phase: 1; data captured on second (rising) edge
|
||||||
* SPI_CONF_POLARITY: 0 or SSI_CR0_SPO
|
* Clock polarity: 1; clock is high when idle
|
||||||
* SPI_CONF_DATA_SIZE: 4 to 16 bits
|
* Data size: 8 bits
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
spi_init(void)
|
spi_init(void)
|
||||||
|
@ -95,31 +77,42 @@ spi_init(void)
|
||||||
ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT);
|
ioc_set_sel(SPI_CLK_PORT, SPI_CLK_PIN, IOC_PXX_SEL_SSI0_CLKOUT);
|
||||||
ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD);
|
ioc_set_sel(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_PXX_SEL_SSI0_TXD);
|
||||||
REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN;
|
REG(IOC_SSIRXD_SSI0) = (SPI_MISO_PORT * 8) + SPI_MISO_PIN;
|
||||||
ioc_set_sel(SPI_SEL_PORT, SPI_SEL_PIN, IOC_PXX_SEL_SSI0_FSSOUT);
|
|
||||||
|
|
||||||
/* Put all the SSI gpios into peripheral mode */
|
/* Put all the SSI gpios into peripheral mode */
|
||||||
GPIO_PERIPHERAL_CONTROL(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK);
|
GPIO_PERIPHERAL_CONTROL(SPI_CLK_PORT_BASE, SPI_CLK_PIN_MASK);
|
||||||
GPIO_PERIPHERAL_CONTROL(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK);
|
GPIO_PERIPHERAL_CONTROL(SPI_MOSI_PORT_BASE, SPI_MOSI_PIN_MASK);
|
||||||
GPIO_PERIPHERAL_CONTROL(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK);
|
GPIO_PERIPHERAL_CONTROL(SPI_MISO_PORT_BASE, SPI_MISO_PIN_MASK);
|
||||||
GPIO_PERIPHERAL_CONTROL(SPI_SEL_PORT_BASE, SPI_SEL_PIN_MASK);
|
|
||||||
|
|
||||||
/* Disable any pull ups or the like */
|
/* Disable any pull ups or the like */
|
||||||
ioc_set_over(SPI_CLK_PORT, SPI_CLK_PIN, IOC_OVERRIDE_DIS);
|
ioc_set_over(SPI_CLK_PORT, SPI_CLK_PIN, IOC_OVERRIDE_DIS);
|
||||||
ioc_set_over(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_OVERRIDE_DIS);
|
ioc_set_over(SPI_MOSI_PORT, SPI_MOSI_PIN, IOC_OVERRIDE_DIS);
|
||||||
ioc_set_over(SPI_MISO_PORT, SPI_MISO_PIN, IOC_OVERRIDE_DIS);
|
ioc_set_over(SPI_MISO_PORT, SPI_MISO_PIN, IOC_OVERRIDE_DIS);
|
||||||
ioc_set_over(SPI_SEL_PORT, SPI_SEL_PIN, IOC_OVERRIDE_DIS);
|
|
||||||
|
|
||||||
/* Configure the clock */
|
/* Configure the clock */
|
||||||
REG(SSI0_BASE + SSI_CPSR) = 2;
|
REG(SSI0_BASE + SSI_CPSR) = 2;
|
||||||
|
|
||||||
/* Put the ssi in Motorola SPI mode using the provided format options */
|
/* Configure the default SPI options.
|
||||||
REG(SSI0_BASE + SSI_CR0) = SPI_CONF_PHASE | SPI_CONF_POLARITY | (SPI_CONF_DATA_SIZE - 1);
|
* mode: Motorola frame format
|
||||||
|
* clock: High when idle
|
||||||
|
* data: Valid on rising edges of the clock
|
||||||
|
* bits: 8 byte data
|
||||||
|
*/
|
||||||
|
REG(SSI0_BASE + SSI_CR0) = SSI_CR0_SPH | SSI_CR0_SPO | (0x07);
|
||||||
|
|
||||||
/* Enable the SSI */
|
/* Enable the SSI */
|
||||||
REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE;
|
REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
spi_cs_init(uint8_t port, uint8_t pin)
|
||||||
|
{
|
||||||
|
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||||
|
ioc_set_over(port, pin, IOC_OVERRIDE_DIS);
|
||||||
|
GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||||
|
GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin));
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
spi_enable(void)
|
spi_enable(void)
|
||||||
{
|
{
|
||||||
/* Enable the clock for the SSI peripheral */
|
/* Enable the clock for the SSI peripheral */
|
||||||
|
@ -132,4 +125,16 @@ spi_disable(void)
|
||||||
/* Gate the clock for the SSI peripheral */
|
/* Gate the clock for the SSI peripheral */
|
||||||
REG(SYS_CTRL_RCGCSSI) &= ~1;
|
REG(SYS_CTRL_RCGCSSI) &= ~1;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void spi_set_mode(uint32_t frame_format, uint32_t clock_polarity, uint32_t clock_phase, uint32_t data_size)
|
||||||
|
{
|
||||||
|
/* Disable the SSI peripheral to configure it */
|
||||||
|
REG(SSI0_BASE + SSI_CR1) = 0;
|
||||||
|
|
||||||
|
/* Configure the SSI options */
|
||||||
|
REG(SSI0_BASE + SSI_CR0) = clock_phase | clock_polarity | frame_format | (data_size - 1);
|
||||||
|
|
||||||
|
/* Re-enable the SSI */
|
||||||
|
REG(SSI0_BASE + SSI_CR1) |= SSI_CR1_SSE;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -74,98 +74,106 @@
|
||||||
*/
|
*/
|
||||||
#define SSI_CR0_SCR_M 0x0000FF00 /**< Serial clock rate mask */
|
#define SSI_CR0_SCR_M 0x0000FF00 /**< Serial clock rate mask */
|
||||||
#define SSI_CR0_SCR_S 8 /**< Serial clock rate shift */
|
#define SSI_CR0_SCR_S 8 /**< Serial clock rate shift */
|
||||||
#define SSI_CR0_SPH 0x00000080 /**< Serial clock phase (H) */
|
|
||||||
#define SSI_CR0_SPH_M 0x00000080 /**< Serial clock phase (H) mask */
|
#define SSI_CR0_SPH_M 0x00000080 /**< Serial clock phase (H) mask */
|
||||||
#define SSI_CR0_SPH_S 7 /**< Serial clock phase (H) shift */
|
#define SSI_CR0_SPH_S 7 /**< Serial clock phase (H) shift */
|
||||||
#define SSI_CR0_SPO 0x00000040 /**< Serial clock phase (O) */
|
|
||||||
#define SSI_CR0_SPO_M 0x00000040 /**< Serial clock phase (O) mask */
|
#define SSI_CR0_SPO_M 0x00000040 /**< Serial clock phase (O) mask */
|
||||||
#define SSI_CR0_SPO_S 6 /**< Serial clock phase (O) shift */
|
#define SSI_CR0_SPO_S 6 /**< Serial clock phase (O) shift */
|
||||||
#define SSI_CR0_FRF_M 0x00000030 /**< Frame format select mask */
|
#define SSI_CR0_FRF_M 0x00000030 /**< Frame format select mask */
|
||||||
#define SSI_CR0_FRF_S 4 /**< Frame format select shift */
|
#define SSI_CR0_FRF_S 4 /**< Frame format select shift */
|
||||||
#define SSI_CR0_DSS_M 0x0000000F /**< Data size select mask */
|
#define SSI_CR0_DSS_M 0x0000000F /**< Data size select mask */
|
||||||
#define SSI_CR0_DSS_S 0 /**< Data size select shift */
|
#define SSI_CR0_DSS_S 0 /**< Data size select shift */
|
||||||
#define SSI_CR1_SOD 0x00000008 /**< Slave mode output disable */
|
|
||||||
#define SSI_CR1_SOD_M 0x00000008 /**< Slave mode output disable mask */
|
#define SSI_CR1_SOD_M 0x00000008 /**< Slave mode output disable mask */
|
||||||
#define SSI_CR1_SOD_S 3 /**< Slave mode output disable shift */
|
#define SSI_CR1_SOD_S 3 /**< Slave mode output disable shift */
|
||||||
#define SSI_CR1_MS 0x00000004 /**< Master and slave select */
|
|
||||||
#define SSI_CR1_MS_M 0x00000004 /**< Master and slave select mask */
|
#define SSI_CR1_MS_M 0x00000004 /**< Master and slave select mask */
|
||||||
#define SSI_CR1_MS_S 2 /**< Master and slave select shift */
|
#define SSI_CR1_MS_S 2 /**< Master and slave select shift */
|
||||||
#define SSI_CR1_SSE 0x00000002 /**< Synchronous serial port enable */
|
|
||||||
#define SSI_CR1_SSE_M 0x00000002 /**< Synchronous serial port enable mask */
|
#define SSI_CR1_SSE_M 0x00000002 /**< Synchronous serial port enable mask */
|
||||||
#define SSI_CR1_SSE_S 1 /**< Synchronous serial port enable shift */
|
#define SSI_CR1_SSE_S 1 /**< Synchronous serial port enable shift */
|
||||||
#define SSI_CR1_LBM 0x00000001 /**< Loop-back mode */
|
|
||||||
#define SSI_CR1_LBM_M 0x00000001 /**< Loop-back mode mask */
|
#define SSI_CR1_LBM_M 0x00000001 /**< Loop-back mode mask */
|
||||||
#define SSI_CR1_LBM_S 0 /**< Loop-back mode shift */
|
#define SSI_CR1_LBM_S 0 /**< Loop-back mode shift */
|
||||||
#define SSI_DR_DATA_M 0x0000FFFF /**< FIFO data mask */
|
#define SSI_DR_DATA_M 0x0000FFFF /**< FIFO data mask */
|
||||||
#define SSI_DR_DATA_S 0 /**< FIFO data shift */
|
#define SSI_DR_DATA_S 0 /**< FIFO data shift */
|
||||||
#define SSI_SR_BSY 0x00000010 /**< Busy bit */
|
|
||||||
#define SSI_SR_BSY_M 0x00000010 /**< Busy bit mask */
|
#define SSI_SR_BSY_M 0x00000010 /**< Busy bit mask */
|
||||||
#define SSI_SR_BSY_S 4 /**< Busy bit shift */
|
#define SSI_SR_BSY_S 4 /**< Busy bit shift */
|
||||||
#define SSI_SR_RFF 0x00000008 /**< Receive FIFO full */
|
|
||||||
#define SSI_SR_RFF_M 0x00000008 /**< Receive FIFO full mask */
|
#define SSI_SR_RFF_M 0x00000008 /**< Receive FIFO full mask */
|
||||||
#define SSI_SR_RFF_S 3 /**< Receive FIFO full shift */
|
#define SSI_SR_RFF_S 3 /**< Receive FIFO full shift */
|
||||||
#define SSI_SR_RNE 0x00000004 /**< Receive FIFO not empty */
|
|
||||||
#define SSI_SR_RNE_M 0x00000004 /**< Receive FIFO not empty mask */
|
#define SSI_SR_RNE_M 0x00000004 /**< Receive FIFO not empty mask */
|
||||||
#define SSI_SR_RNE_S 2 /**< Receive FIFO not empty shift */
|
#define SSI_SR_RNE_S 2 /**< Receive FIFO not empty shift */
|
||||||
#define SSI_SR_TNF 0x00000002 /**< Transmit FIFO not full */
|
|
||||||
#define SSI_SR_TNF_M 0x00000002 /**< Transmit FIFO not full mask */
|
#define SSI_SR_TNF_M 0x00000002 /**< Transmit FIFO not full mask */
|
||||||
#define SSI_SR_TNF_S 1 /**< Transmit FIFO not full shift */
|
#define SSI_SR_TNF_S 1 /**< Transmit FIFO not full shift */
|
||||||
#define SSI_SR_TFE 0x00000001 /**< Transmit FIFO empty */
|
|
||||||
#define SSI_SR_TFE_M 0x00000001 /**< Transmit FIFO empty mask */
|
#define SSI_SR_TFE_M 0x00000001 /**< Transmit FIFO empty mask */
|
||||||
#define SSI_SR_TFE_S 0 /**< Transmit FIFO empty shift */
|
#define SSI_SR_TFE_S 0 /**< Transmit FIFO empty shift */
|
||||||
#define SSI_CPSR_CPSDVSR_M 0x000000FF /**< Clock prescale divisor mask */
|
#define SSI_CPSR_CPSDVSR_M 0x000000FF /**< Clock prescale divisor mask */
|
||||||
#define SSI_CPSR_CPSDVSR_S 0 /**< Clock prescale divisor shift */
|
#define SSI_CPSR_CPSDVSR_S 0 /**< Clock prescale divisor shift */
|
||||||
#define SSI_IM_TXIM 0x00000008 /**< Transmit FIFO interrupt mask */
|
|
||||||
#define SSI_IM_TXIM_M 0x00000008 /**< Transmit FIFO interrupt mask mask */
|
#define SSI_IM_TXIM_M 0x00000008 /**< Transmit FIFO interrupt mask mask */
|
||||||
#define SSI_IM_TXIM_S 3 /**< Transmit FIFO interrupt mask shift */
|
#define SSI_IM_TXIM_S 3 /**< Transmit FIFO interrupt mask shift */
|
||||||
#define SSI_IM_RXIM 0x00000004 /**< Receive FIFO interrupt mask */
|
|
||||||
#define SSI_IM_RXIM_M 0x00000004 /**< Receive FIFO interrupt mask mask */
|
#define SSI_IM_RXIM_M 0x00000004 /**< Receive FIFO interrupt mask mask */
|
||||||
#define SSI_IM_RXIM_S 2 /**< Receive FIFO interrupt mask shift */
|
#define SSI_IM_RXIM_S 2 /**< Receive FIFO interrupt mask shift */
|
||||||
#define SSI_IM_RTIM 0x00000002 /**< Receive time-out interrupt mask */
|
|
||||||
#define SSI_IM_RTIM_M 0x00000002 /**< Receive time-out interrupt mask mask */
|
#define SSI_IM_RTIM_M 0x00000002 /**< Receive time-out interrupt mask mask */
|
||||||
#define SSI_IM_RTIM_S 1 /**< Receive time-out interrupt mask shift */
|
#define SSI_IM_RTIM_S 1 /**< Receive time-out interrupt mask shift */
|
||||||
#define SSI_IM_RORIM 0x00000001 /**< Receive overrun interrupt mask */
|
|
||||||
#define SSI_IM_RORIM_M 0x00000001 /**< Receive overrun interrupt mask mask */
|
#define SSI_IM_RORIM_M 0x00000001 /**< Receive overrun interrupt mask mask */
|
||||||
#define SSI_IM_RORIM_S 0 /**< Receive overrun interrupt mask shift */
|
#define SSI_IM_RORIM_S 0 /**< Receive overrun interrupt mask shift */
|
||||||
#define SSI_RIS_TXRIS 0x00000008 /**< SSITXINTR raw state */
|
|
||||||
#define SSI_RIS_TXRIS_M 0x00000008 /**< SSITXINTR raw state mask */
|
#define SSI_RIS_TXRIS_M 0x00000008 /**< SSITXINTR raw state mask */
|
||||||
#define SSI_RIS_TXRIS_S 3 /**< SSITXINTR raw state shift */
|
#define SSI_RIS_TXRIS_S 3 /**< SSITXINTR raw state shift */
|
||||||
#define SSI_RIS_RXRIS 0x00000004 /**< SSIRXINTR raw state */
|
|
||||||
#define SSI_RIS_RXRIS_M 0x00000004 /**< SSIRXINTR raw state mask */
|
#define SSI_RIS_RXRIS_M 0x00000004 /**< SSIRXINTR raw state mask */
|
||||||
#define SSI_RIS_RXRIS_S 2 /**< SSIRXINTR raw state shift */
|
#define SSI_RIS_RXRIS_S 2 /**< SSIRXINTR raw state shift */
|
||||||
#define SSI_RIS_RTRIS 0x00000002 /**< SSIRTINTR raw state */
|
|
||||||
#define SSI_RIS_RTRIS_M 0x00000002 /**< SSIRTINTR raw state mask */
|
#define SSI_RIS_RTRIS_M 0x00000002 /**< SSIRTINTR raw state mask */
|
||||||
#define SSI_RIS_RTRIS_S 1 /**< SSIRTINTR raw state shift */
|
#define SSI_RIS_RTRIS_S 1 /**< SSIRTINTR raw state shift */
|
||||||
#define SSI_RIS_RORRIS 0x00000001 /**< SSIRORINTR raw state */
|
|
||||||
#define SSI_RIS_RORRIS_M 0x00000001 /**< SSIRORINTR raw state mask */
|
#define SSI_RIS_RORRIS_M 0x00000001 /**< SSIRORINTR raw state mask */
|
||||||
#define SSI_RIS_RORRIS_S 0 /**< SSIRORINTR raw state shift */
|
#define SSI_RIS_RORRIS_S 0 /**< SSIRORINTR raw state shift */
|
||||||
#define SSI_MIS_TXMIS 0x00000008 /**< SSITXINTR masked state */
|
|
||||||
#define SSI_MIS_TXMIS_M 0x00000008 /**< SSITXINTR masked state mask */
|
#define SSI_MIS_TXMIS_M 0x00000008 /**< SSITXINTR masked state mask */
|
||||||
#define SSI_MIS_TXMIS_S 3 /**< SSITXINTR masked state shift */
|
#define SSI_MIS_TXMIS_S 3 /**< SSITXINTR masked state shift */
|
||||||
#define SSI_MIS_RXMIS 0x00000004 /**< SSIRXINTR masked state */
|
|
||||||
#define SSI_MIS_RXMIS_M 0x00000004 /**< SSIRXINTR masked state mask */
|
#define SSI_MIS_RXMIS_M 0x00000004 /**< SSIRXINTR masked state mask */
|
||||||
#define SSI_MIS_RXMIS_S 2 /**< SSIRXINTR masked state shift */
|
#define SSI_MIS_RXMIS_S 2 /**< SSIRXINTR masked state shift */
|
||||||
#define SSI_MIS_RTMIS 0x00000002 /**< SSIRTINTR masked state */
|
|
||||||
#define SSI_MIS_RTMIS_M 0x00000002 /**< SSIRTINTR masked state mask */
|
#define SSI_MIS_RTMIS_M 0x00000002 /**< SSIRTINTR masked state mask */
|
||||||
#define SSI_MIS_RTMIS_S 1 /**< SSIRTINTR masked state shift */
|
#define SSI_MIS_RTMIS_S 1 /**< SSIRTINTR masked state shift */
|
||||||
#define SSI_MIS_RORMIS 0x00000001 /**< SSIRORINTR masked state */
|
|
||||||
#define SSI_MIS_RORMIS_M 0x00000001 /**< SSIRORINTR masked state mask */
|
#define SSI_MIS_RORMIS_M 0x00000001 /**< SSIRORINTR masked state mask */
|
||||||
#define SSI_MIS_RORMIS_S 0 /**< SSIRORINTR masked state shift */
|
#define SSI_MIS_RORMIS_S 0 /**< SSIRORINTR masked state shift */
|
||||||
#define SSI_ICR_RTIC 0x00000002 /**< Receive time-out interrupt clear */
|
|
||||||
#define SSI_ICR_RTIC_M 0x00000002 /**< Receive time-out interrupt clear mask */
|
#define SSI_ICR_RTIC_M 0x00000002 /**< Receive time-out interrupt clear mask */
|
||||||
#define SSI_ICR_RTIC_S 1 /**< Receive time-out interrupt clear shift */
|
#define SSI_ICR_RTIC_S 1 /**< Receive time-out interrupt clear shift */
|
||||||
#define SSI_ICR_RORIC 0x00000001 /**< Receive overrun interrupt clear */
|
|
||||||
#define SSI_ICR_RORIC_M 0x00000001 /**< Receive overrun interrupt clear mask */
|
#define SSI_ICR_RORIC_M 0x00000001 /**< Receive overrun interrupt clear mask */
|
||||||
#define SSI_ICR_RORIC_S 0 /**< Receive overrun interrupt clear shift */
|
#define SSI_ICR_RORIC_S 0 /**< Receive overrun interrupt clear shift */
|
||||||
#define SSI_DMACTL_TXDMAE 0x00000002 /**< Transmit DMA enable */
|
|
||||||
#define SSI_DMACTL_TXDMAE_M 0x00000002 /**< Transmit DMA enable mask */
|
#define SSI_DMACTL_TXDMAE_M 0x00000002 /**< Transmit DMA enable mask */
|
||||||
#define SSI_DMACTL_TXDMAE_S 1 /**< Transmit DMA enable shift */
|
#define SSI_DMACTL_TXDMAE_S 1 /**< Transmit DMA enable shift */
|
||||||
#define SSI_DMACTL_RXDMAE 0x00000001 /**< Receive DMA enable */
|
|
||||||
#define SSI_DMACTL_RXDMAE_M 0x00000001 /**< Receive DMA enable mask */
|
#define SSI_DMACTL_RXDMAE_M 0x00000001 /**< Receive DMA enable mask */
|
||||||
#define SSI_DMACTL_RXDMAE_S 0 /**< Receive DMA enable shift */
|
#define SSI_DMACTL_RXDMAE_S 0 /**< Receive DMA enable shift */
|
||||||
#define SSI_CC_CS_M 0x00000007 /**< Baud and system clock source mask */
|
#define SSI_CC_CS_M 0x00000007 /**< Baud and system clock source mask */
|
||||||
#define SSI_CC_CS_S 0 /**< Baud and system clock source shift */
|
#define SSI_CC_CS_S 0 /**< Baud and system clock source shift */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name SSI Register Values
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SSI_CR0_SPH 0x00000080 /**< Serial clock phase (H) */
|
||||||
|
#define SSI_CR0_SPO 0x00000040 /**< Serial clock phase (O) */
|
||||||
|
#define SSI_CR0_FRF_MOTOROLA 0x00000000 /**< Motorola frame format */
|
||||||
|
#define SSI_CR0_FRF_TI 0x00000010 /**< Texas Instruments frame format */
|
||||||
|
#define SSI_CR0_FRF_MICROWIRE 0x00000020 /**< National Microwire frame format */
|
||||||
|
#define SSI_CR1_SOD 0x00000008 /**< Slave mode output disable */
|
||||||
|
#define SSI_CR1_MS 0x00000004 /**< Master and slave select */
|
||||||
|
#define SSI_CR1_SSE 0x00000002 /**< Synchronous serial port enable */
|
||||||
|
#define SSI_CR1_LBM 0x00000001 /**< Loop-back mode */
|
||||||
|
#define SSI_SR_BSY 0x00000010 /**< Busy bit */
|
||||||
|
#define SSI_SR_RFF 0x00000008 /**< Receive FIFO full */
|
||||||
|
#define SSI_SR_RNE 0x00000004 /**< Receive FIFO not empty */
|
||||||
|
#define SSI_SR_TNF 0x00000002 /**< Transmit FIFO not full */
|
||||||
|
#define SSI_SR_TFE 0x00000001 /**< Transmit FIFO empty */
|
||||||
|
#define SSI_IM_TXIM 0x00000008 /**< Transmit FIFO interrupt mask */
|
||||||
|
#define SSI_IM_RXIM 0x00000004 /**< Receive FIFO interrupt mask */
|
||||||
|
#define SSI_IM_RTIM 0x00000002 /**< Receive time-out interrupt mask */
|
||||||
|
#define SSI_IM_RORIM 0x00000001 /**< Receive overrun interrupt mask */
|
||||||
|
#define SSI_RIS_TXRIS 0x00000008 /**< SSITXINTR raw state */
|
||||||
|
#define SSI_RIS_RXRIS 0x00000004 /**< SSIRXINTR raw state */
|
||||||
|
#define SSI_RIS_RTRIS 0x00000002 /**< SSIRTINTR raw state */
|
||||||
|
#define SSI_RIS_RORRIS 0x00000001 /**< SSIRORINTR raw state */
|
||||||
|
#define SSI_MIS_TXMIS 0x00000008 /**< SSITXINTR masked state */
|
||||||
|
#define SSI_MIS_RXMIS 0x00000004 /**< SSIRXINTR masked state */
|
||||||
|
#define SSI_MIS_RTMIS 0x00000002 /**< SSIRTINTR masked state */
|
||||||
|
#define SSI_MIS_RORMIS 0x00000001 /**< SSIRORINTR masked state */
|
||||||
|
#define SSI_ICR_RTIC 0x00000002 /**< Receive time-out interrupt clear */
|
||||||
|
#define SSI_ICR_RORIC 0x00000001 /**< Receive overrun interrupt clear */
|
||||||
|
#define SSI_DMACTL_TXDMAE 0x00000002 /**< Transmit DMA enable */
|
||||||
|
#define SSI_DMACTL_RXDMAE 0x00000001 /**< Receive DMA enable */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -48,88 +48,220 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static int (* input_handler)(unsigned char c);
|
#ifndef UART0_RX_PORT
|
||||||
/*---------------------------------------------------------------------------*/
|
#define UART0_RX_PORT (-1)
|
||||||
#define UART_RX_PORT_BASE GPIO_PORT_TO_BASE(UART_RX_PORT)
|
#endif
|
||||||
#define UART_RX_PIN_MASK GPIO_PIN_MASK(UART_RX_PIN)
|
#ifndef UART0_RX_PIN
|
||||||
|
#define UART0_RX_PIN (-1)
|
||||||
|
#endif
|
||||||
|
#if UART0_RX_PORT >= 0 && UART0_RX_PIN < 0 || \
|
||||||
|
UART0_RX_PORT < 0 && UART0_RX_PIN >= 0
|
||||||
|
#error Both UART0_RX_PORT and UART0_RX_PIN must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART_TX_PORT_BASE GPIO_PORT_TO_BASE(UART_TX_PORT)
|
#ifndef UART0_TX_PORT
|
||||||
#define UART_TX_PIN_MASK GPIO_PIN_MASK(UART_TX_PIN)
|
#define UART0_TX_PORT (-1)
|
||||||
|
#endif
|
||||||
|
#ifndef UART0_TX_PIN
|
||||||
|
#define UART0_TX_PIN (-1)
|
||||||
|
#endif
|
||||||
|
#if UART0_TX_PORT >= 0 && UART0_TX_PIN < 0 || \
|
||||||
|
UART0_TX_PORT < 0 && UART0_TX_PIN >= 0
|
||||||
|
#error Both UART0_TX_PORT and UART0_TX_PIN must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART_CTS_PORT_BASE GPIO_PORT_TO_BASE(UART_CTS_PORT)
|
#if UART0_RX_PORT >= 0 && UART0_TX_PORT < 0 || \
|
||||||
#define UART_CTS_PIN_MASK GPIO_PIN_MASK(UART_CTS_PIN)
|
UART0_RX_PORT < 0 && UART0_TX_PORT >= 0
|
||||||
|
#error Both UART0_RX and UART0_TX pads must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART_RTS_PORT_BASE GPIO_PORT_TO_BASE(UART_RTS_PORT)
|
#if UART_IN_USE(0) && UART0_RX_PORT < 0
|
||||||
#define UART_RTS_PIN_MASK GPIO_PIN_MASK(UART_RTS_PIN)
|
#error Contiki is configured to use UART0, but its pads are not valid
|
||||||
/*---------------------------------------------------------------------------*/
|
#endif
|
||||||
/*
|
|
||||||
* Once we know what UART we're on, configure correct values to be written to
|
|
||||||
* the correct registers
|
|
||||||
*/
|
|
||||||
#if UART_BASE==UART_1_BASE
|
|
||||||
/* Running, in sleep, in deep sleep, enable the clock for the correct UART */
|
|
||||||
#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART1
|
|
||||||
#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART1
|
|
||||||
#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART1
|
|
||||||
|
|
||||||
#define NVIC_INT_UART NVIC_INT_UART1
|
#ifndef UART1_RX_PORT
|
||||||
#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART1_TXD
|
#define UART1_RX_PORT (-1)
|
||||||
#define IOC_UARTRXD_UART IOC_UARTRXD_UART1
|
#endif
|
||||||
#else /* Defaults for UART0 */
|
#ifndef UART1_RX_PIN
|
||||||
#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART0
|
#define UART1_RX_PIN (-1)
|
||||||
#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART0
|
#endif
|
||||||
#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART0
|
#if UART1_RX_PORT >= 0 && UART1_RX_PIN < 0 || \
|
||||||
|
UART1_RX_PORT < 0 && UART1_RX_PIN >= 0
|
||||||
|
#error Both UART1_RX_PORT and UART1_RX_PIN must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NVIC_INT_UART NVIC_INT_UART0
|
#ifndef UART1_TX_PORT
|
||||||
|
#define UART1_TX_PORT (-1)
|
||||||
|
#endif
|
||||||
|
#ifndef UART1_TX_PIN
|
||||||
|
#define UART1_TX_PIN (-1)
|
||||||
|
#endif
|
||||||
|
#if UART1_TX_PORT >= 0 && UART1_TX_PIN < 0 || \
|
||||||
|
UART1_TX_PORT < 0 && UART1_TX_PIN >= 0
|
||||||
|
#error Both UART1_TX_PORT and UART1_TX_PIN must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART0_TXD
|
#if UART1_RX_PORT >= 0 && UART1_TX_PORT < 0 || \
|
||||||
#define IOC_UARTRXD_UART IOC_UARTRXD_UART0
|
UART1_RX_PORT < 0 && UART1_TX_PORT >= 0
|
||||||
|
#error Both UART1_RX and UART1_TX pads must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UART_IN_USE(1) && UART1_RX_PORT < 0
|
||||||
|
#error Contiki is configured to use UART1, but its pads are not valid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART1_CTS_PORT
|
||||||
|
#define UART1_CTS_PORT (-1)
|
||||||
|
#endif
|
||||||
|
#ifndef UART1_CTS_PIN
|
||||||
|
#define UART1_CTS_PIN (-1)
|
||||||
|
#endif
|
||||||
|
#if UART1_CTS_PORT >= 0 && UART1_CTS_PIN < 0 || \
|
||||||
|
UART1_CTS_PORT < 0 && UART1_CTS_PIN >= 0
|
||||||
|
#error Both UART1_CTS_PORT and UART1_CTS_PIN must be valid or invalid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART1_RTS_PORT
|
||||||
|
#define UART1_RTS_PORT (-1)
|
||||||
|
#endif
|
||||||
|
#ifndef UART1_RTS_PIN
|
||||||
|
#define UART1_RTS_PIN (-1)
|
||||||
|
#endif
|
||||||
|
#if UART1_RTS_PORT >= 0 && UART1_RTS_PIN < 0 || \
|
||||||
|
UART1_RTS_PORT < 0 && UART1_RTS_PIN >= 0
|
||||||
|
#error Both UART1_RTS_PORT and UART1_RTS_PIN must be valid or invalid
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Baud rate defines used in uart_init() to set the values of UART_IBRD and
|
||||||
|
* UART_FBRD in order to achieve the configured baud rates.
|
||||||
|
*/
|
||||||
|
#define UART_CLOCK_RATE 16000000 /* 16 MHz */
|
||||||
|
#define UART_CTL_HSE_VALUE 0
|
||||||
|
#define UART_CTL_VALUE (UART_CTL_RXE | UART_CTL_TXE | (UART_CTL_HSE_VALUE << 5))
|
||||||
|
|
||||||
|
/* DIV_ROUND() divides integers while avoiding a rounding error: */
|
||||||
|
#define DIV_ROUND(num, denom) (((num) + (denom) / 2) / (denom))
|
||||||
|
|
||||||
|
#define BAUD2BRD(baud) DIV_ROUND(UART_CLOCK_RATE << (UART_CTL_HSE_VALUE + 2), (baud))
|
||||||
|
#define BAUD2IBRD(baud) (BAUD2BRD(baud) >> 6)
|
||||||
|
#define BAUD2FBRD(baud) (BAUD2BRD(baud) & 0x3f)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
int8_t port;
|
||||||
|
int8_t pin;
|
||||||
|
} uart_pad_t;
|
||||||
|
typedef struct {
|
||||||
|
uint32_t sys_ctrl_rcgcuart_uart;
|
||||||
|
uint32_t sys_ctrl_scgcuart_uart;
|
||||||
|
uint32_t sys_ctrl_dcgcuart_uart;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t ioc_uartrxd_uart;
|
||||||
|
uint32_t ioc_pxx_sel_uart_txd;
|
||||||
|
uint32_t ibrd;
|
||||||
|
uint32_t fbrd;
|
||||||
|
uart_pad_t rx;
|
||||||
|
uart_pad_t tx;
|
||||||
|
uart_pad_t cts;
|
||||||
|
uart_pad_t rts;
|
||||||
|
uint8_t nvic_int;
|
||||||
|
} uart_regs_t;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static const uart_regs_t uart_regs[UART_INSTANCE_COUNT] = {
|
||||||
|
{
|
||||||
|
.sys_ctrl_rcgcuart_uart = SYS_CTRL_RCGCUART_UART0,
|
||||||
|
.sys_ctrl_scgcuart_uart = SYS_CTRL_SCGCUART_UART0,
|
||||||
|
.sys_ctrl_dcgcuart_uart = SYS_CTRL_DCGCUART_UART0,
|
||||||
|
.base = UART_0_BASE,
|
||||||
|
.ioc_uartrxd_uart = IOC_UARTRXD_UART0,
|
||||||
|
.ioc_pxx_sel_uart_txd = IOC_PXX_SEL_UART0_TXD,
|
||||||
|
.ibrd = BAUD2IBRD(UART0_CONF_BAUD_RATE),
|
||||||
|
.fbrd = BAUD2FBRD(UART0_CONF_BAUD_RATE),
|
||||||
|
.rx = {UART0_RX_PORT, UART0_RX_PIN},
|
||||||
|
.tx = {UART0_TX_PORT, UART0_TX_PIN},
|
||||||
|
.cts = {-1, -1},
|
||||||
|
.rts = {-1, -1},
|
||||||
|
.nvic_int = NVIC_INT_UART0
|
||||||
|
}, {
|
||||||
|
.sys_ctrl_rcgcuart_uart = SYS_CTRL_RCGCUART_UART1,
|
||||||
|
.sys_ctrl_scgcuart_uart = SYS_CTRL_SCGCUART_UART1,
|
||||||
|
.sys_ctrl_dcgcuart_uart = SYS_CTRL_DCGCUART_UART1,
|
||||||
|
.base = UART_1_BASE,
|
||||||
|
.ioc_uartrxd_uart = IOC_UARTRXD_UART1,
|
||||||
|
.ioc_pxx_sel_uart_txd = IOC_PXX_SEL_UART1_TXD,
|
||||||
|
.ibrd = BAUD2IBRD(UART1_CONF_BAUD_RATE),
|
||||||
|
.fbrd = BAUD2FBRD(UART1_CONF_BAUD_RATE),
|
||||||
|
.rx = {UART1_RX_PORT, UART1_RX_PIN},
|
||||||
|
.tx = {UART1_TX_PORT, UART1_TX_PIN},
|
||||||
|
.cts = {UART1_CTS_PORT, UART1_CTS_PIN},
|
||||||
|
.rts = {UART1_RTS_PORT, UART1_RTS_PIN},
|
||||||
|
.nvic_int = NVIC_INT_UART1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static int (* input_handler[UART_INSTANCE_COUNT])(unsigned char c);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
reset(void)
|
reset(uint32_t uart_base)
|
||||||
{
|
{
|
||||||
uint32_t lchr;
|
uint32_t lchr;
|
||||||
|
|
||||||
/* Make sure the UART is disabled before trying to configure it */
|
/* Make sure the UART is disabled before trying to configure it */
|
||||||
REG(UART_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
REG(uart_base | UART_CTL) = UART_CTL_VALUE;
|
||||||
|
|
||||||
/* Clear error status */
|
/* Clear error status */
|
||||||
REG(UART_BASE | UART_ECR) = 0xFF;
|
REG(uart_base | UART_ECR) = 0xFF;
|
||||||
|
|
||||||
/* Store LCHR configuration */
|
/* Store LCHR configuration */
|
||||||
lchr = REG(UART_BASE | UART_LCRH);
|
lchr = REG(uart_base | UART_LCRH);
|
||||||
|
|
||||||
/* Flush FIFOs by clearing LCHR.FEN */
|
/* Flush FIFOs by clearing LCHR.FEN */
|
||||||
REG(UART_BASE | UART_LCRH) = 0;
|
REG(uart_base | UART_LCRH) = 0;
|
||||||
|
|
||||||
/* Restore LCHR configuration */
|
/* Restore LCHR configuration */
|
||||||
REG(UART_BASE | UART_LCRH) = lchr;
|
REG(uart_base | UART_LCRH) = lchr;
|
||||||
|
|
||||||
/* UART Enable */
|
/* UART Enable */
|
||||||
REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
REG(uart_base | UART_CTL) |= UART_CTL_UARTEN;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static bool
|
static bool
|
||||||
permit_pm1(void)
|
permit_pm1(void)
|
||||||
{
|
{
|
||||||
/* Note: UART_FR.TXFE reads 0 if the UART clock is gated. */
|
const uart_regs_t *regs;
|
||||||
return (REG(SYS_CTRL_RCGCUART) & SYS_CTRL_RCGCUART_UART) == 0 ||
|
|
||||||
(REG(UART_BASE | UART_FR) & UART_FR_TXFE) != 0;
|
for(regs = &uart_regs[0]; regs < &uart_regs[UART_INSTANCE_COUNT]; regs++) {
|
||||||
|
/* Note: UART_FR.TXFE reads 0 if the UART clock is gated. */
|
||||||
|
if((REG(SYS_CTRL_RCGCUART) & regs->sys_ctrl_rcgcuart_uart) != 0 &&
|
||||||
|
(REG(regs->base | UART_FR) & UART_FR_TXFE) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uart_init(void)
|
uart_init(uint8_t uart)
|
||||||
{
|
{
|
||||||
|
const uart_regs_t *regs;
|
||||||
|
|
||||||
|
if(uart >= UART_INSTANCE_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
regs = &uart_regs[uart];
|
||||||
|
if(regs->rx.port < 0 || regs->tx.port < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lpm_register_peripheral(permit_pm1);
|
lpm_register_peripheral(permit_pm1);
|
||||||
|
|
||||||
/* Enable clock for the UART while Running, in Sleep and Deep Sleep */
|
/* Enable clock for the UART while Running, in Sleep and Deep Sleep */
|
||||||
REG(SYS_CTRL_RCGCUART) |= SYS_CTRL_RCGCUART_UART;
|
REG(SYS_CTRL_RCGCUART) |= regs->sys_ctrl_rcgcuart_uart;
|
||||||
REG(SYS_CTRL_SCGCUART) |= SYS_CTRL_SCGCUART_UART;
|
REG(SYS_CTRL_SCGCUART) |= regs->sys_ctrl_scgcuart_uart;
|
||||||
REG(SYS_CTRL_DCGCUART) |= SYS_CTRL_DCGCUART_UART;
|
REG(SYS_CTRL_DCGCUART) |= regs->sys_ctrl_dcgcuart_uart;
|
||||||
|
|
||||||
/* Run on SYS_DIV */
|
/* Run on SYS_DIV */
|
||||||
REG(UART_BASE | UART_CC) = 0;
|
REG(regs->base | UART_CC) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register
|
* Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register
|
||||||
|
@ -139,92 +271,116 @@ uart_init(void)
|
||||||
*
|
*
|
||||||
* (port << 3) + pin
|
* (port << 3) + pin
|
||||||
*/
|
*/
|
||||||
REG(IOC_UARTRXD_UART) = (UART_RX_PORT << 3) + UART_RX_PIN;
|
REG(regs->ioc_uartrxd_uart) = (regs->rx.port << 3) + regs->rx.pin;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pad Control for the TX pin:
|
* Pad Control for the TX pin:
|
||||||
* - Set function to UART0 TX
|
* - Set function to UARTn TX
|
||||||
* - Output Enable
|
* - Output Enable
|
||||||
*/
|
*/
|
||||||
ioc_set_sel(UART_TX_PORT, UART_TX_PIN, IOC_PXX_SEL_UART_TXD);
|
ioc_set_sel(regs->tx.port, regs->tx.pin, regs->ioc_pxx_sel_uart_txd);
|
||||||
ioc_set_over(UART_TX_PORT, UART_TX_PIN, IOC_OVERRIDE_OE);
|
ioc_set_over(regs->tx.port, regs->tx.pin, IOC_OVERRIDE_OE);
|
||||||
|
|
||||||
/* Set RX and TX pins to peripheral mode */
|
/* Set RX and TX pins to peripheral mode */
|
||||||
GPIO_PERIPHERAL_CONTROL(UART_TX_PORT_BASE, UART_TX_PIN_MASK);
|
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->tx.port),
|
||||||
GPIO_PERIPHERAL_CONTROL(UART_RX_PORT_BASE, UART_RX_PIN_MASK);
|
GPIO_PIN_MASK(regs->tx.pin));
|
||||||
|
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(regs->rx.port),
|
||||||
|
GPIO_PIN_MASK(regs->rx.pin));
|
||||||
|
|
||||||
|
if(regs->cts.port >= 0 || regs->rts.port >= 0) {
|
||||||
|
/* TODO Hardware flow control */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UART Interrupt Masks:
|
* UART Interrupt Masks:
|
||||||
* Acknowledge RX and RX Timeout
|
* Acknowledge RX and RX Timeout
|
||||||
* Acknowledge Framing, Overrun and Break Errors
|
* Acknowledge Framing, Overrun and Break Errors
|
||||||
*/
|
*/
|
||||||
REG(UART_BASE | UART_IM) = UART_IM_RXIM | UART_IM_RTIM;
|
REG(regs->base | UART_IM) = UART_IM_RXIM | UART_IM_RTIM;
|
||||||
REG(UART_BASE | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM;
|
REG(regs->base | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM;
|
||||||
|
|
||||||
REG(UART_BASE | UART_IFLS) =
|
REG(regs->base | UART_IFLS) =
|
||||||
UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2;
|
UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2;
|
||||||
|
|
||||||
/* Make sure the UART is disabled before trying to configure it */
|
/* Make sure the UART is disabled before trying to configure it */
|
||||||
REG(UART_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
REG(regs->base | UART_CTL) = UART_CTL_VALUE;
|
||||||
|
|
||||||
/* Baud Rate Generation */
|
/* Baud Rate Generation */
|
||||||
REG(UART_BASE | UART_IBRD) = UART_CONF_IBRD;
|
REG(regs->base | UART_IBRD) = regs->ibrd;
|
||||||
REG(UART_BASE | UART_FBRD) = UART_CONF_FBRD;
|
REG(regs->base | UART_FBRD) = regs->fbrd;
|
||||||
|
|
||||||
/* UART Control: 8N1 with FIFOs */
|
/* UART Control: 8N1 with FIFOs */
|
||||||
REG(UART_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
|
REG(regs->base | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
|
||||||
|
|
||||||
/* UART Enable */
|
/* UART Enable */
|
||||||
REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
REG(regs->base | UART_CTL) |= UART_CTL_UARTEN;
|
||||||
|
|
||||||
/* Enable UART0 Interrupts */
|
/* Enable UART0 Interrupts */
|
||||||
nvic_interrupt_enable(NVIC_INT_UART);
|
nvic_interrupt_enable(regs->nvic_int);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uart_set_input(int (* input)(unsigned char c))
|
uart_set_input(uint8_t uart, int (* input)(unsigned char c))
|
||||||
{
|
{
|
||||||
input_handler = input;
|
if(uart >= UART_INSTANCE_COUNT) {
|
||||||
}
|
return;
|
||||||
/*---------------------------------------------------------------------------*/
|
}
|
||||||
void
|
|
||||||
uart_write_byte(uint8_t b)
|
|
||||||
{
|
|
||||||
/* Block if the TX FIFO is full */
|
|
||||||
while(REG(UART_BASE | UART_FR) & UART_FR_TXFF);
|
|
||||||
|
|
||||||
REG(UART_BASE | UART_DR) = b;
|
input_handler[uart] = input;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uart_isr(void)
|
uart_write_byte(uint8_t uart, uint8_t b)
|
||||||
{
|
{
|
||||||
|
uint32_t uart_base;
|
||||||
|
|
||||||
|
if(uart >= UART_INSTANCE_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uart_base = uart_regs[uart].base;
|
||||||
|
|
||||||
|
/* Block if the TX FIFO is full */
|
||||||
|
while(REG(uart_base | UART_FR) & UART_FR_TXFF);
|
||||||
|
|
||||||
|
REG(uart_base | UART_DR) = b;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uart_isr(uint8_t uart)
|
||||||
|
{
|
||||||
|
uint32_t uart_base;
|
||||||
uint16_t mis;
|
uint16_t mis;
|
||||||
|
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
|
uart_base = uart_regs[uart].base;
|
||||||
|
|
||||||
/* Store the current MIS and clear all flags early, except the RTM flag.
|
/* Store the current MIS and clear all flags early, except the RTM flag.
|
||||||
* This will clear itself when we read out the entire FIFO contents */
|
* This will clear itself when we read out the entire FIFO contents */
|
||||||
mis = REG(UART_BASE | UART_MIS) & 0x0000FFFF;
|
mis = REG(uart_base | UART_MIS) & 0x0000FFFF;
|
||||||
|
|
||||||
REG(UART_BASE | UART_ICR) = 0x0000FFBF;
|
REG(uart_base | UART_ICR) = 0x0000FFBF;
|
||||||
|
|
||||||
if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) {
|
if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) {
|
||||||
while(!(REG(UART_BASE | UART_FR) & UART_FR_RXFE)) {
|
while(!(REG(uart_base | UART_FR) & UART_FR_RXFE)) {
|
||||||
if(input_handler != NULL) {
|
if(input_handler[uart] != NULL) {
|
||||||
input_handler((unsigned char)(REG(UART_BASE | UART_DR) & 0xFF));
|
input_handler[uart]((unsigned char)(REG(uart_base | UART_DR) & 0xFF));
|
||||||
} else {
|
} else {
|
||||||
/* To prevent an Overrun Error, we need to flush the FIFO even if we
|
/* To prevent an Overrun Error, we need to flush the FIFO even if we
|
||||||
* don't have an input_handler. Use mis as a data trash can */
|
* don't have an input_handler. Use mis as a data trash can */
|
||||||
mis = REG(UART_BASE | UART_DR);
|
mis = REG(uart_base | UART_DR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) {
|
} else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) {
|
||||||
/* ISR triggered due to some error condition */
|
/* ISR triggered due to some error condition */
|
||||||
reset();
|
reset(uart_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define UART_ISR(u) void uart##u##_isr(void) { uart_isr(u); }
|
||||||
|
UART_ISR(0)
|
||||||
|
UART_ISR(1)
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -47,52 +47,17 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name UART instance count
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define UART_INSTANCE_COUNT 2
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name UART base addresses
|
/** \name UART base addresses
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define UART_0_BASE 0x4000C000
|
#define UART_0_BASE 0x4000C000
|
||||||
#define UART_1_BASE 0x4000D000
|
#define UART_1_BASE 0x4000D000
|
||||||
|
|
||||||
/* Default to UART 0 unless the configuration tells us otherwise */
|
|
||||||
#ifdef UART_CONF_BASE
|
|
||||||
#define UART_BASE UART_CONF_BASE
|
|
||||||
#else
|
|
||||||
#define UART_BASE UART_0_BASE
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \name Baud rate defines
|
|
||||||
*
|
|
||||||
* Used in uart_init() to set the values of UART_IBRD and UART_FBRD in order to
|
|
||||||
* achieve some standard baud rates. These defines assume that the UART is
|
|
||||||
* clocked at 16MHz and that Clock Div is 16 (UART_CTL:HSE clear)
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define UART_IBRD_115200 8 /**< IBRD value for baud rate 115200 */
|
|
||||||
#define UART_FBRD_115200 44 /**< FBRD value for baud rate 115200 */
|
|
||||||
#define UART_IBRD_230400 4 /**< IBRD value for baud rate 230400 */
|
|
||||||
#define UART_FBRD_230400 22 /**< FBRD value for baud rate 230400 */
|
|
||||||
#define UART_IBRD_460800 2 /**< IBRD value for baud rate 460800 */
|
|
||||||
#define UART_FBRD_460800 11 /**< FBRD value for baud rate 460800 */
|
|
||||||
|
|
||||||
#if UART_CONF_BAUD_RATE==115200
|
|
||||||
#define UART_CONF_IBRD UART_IBRD_115200
|
|
||||||
#define UART_CONF_FBRD UART_FBRD_115200
|
|
||||||
#elif UART_CONF_BAUD_RATE==230400
|
|
||||||
#define UART_CONF_IBRD UART_IBRD_230400
|
|
||||||
#define UART_CONF_FBRD UART_FBRD_230400
|
|
||||||
#elif UART_CONF_BAUD_RATE==460800
|
|
||||||
#define UART_CONF_IBRD UART_IBRD_460800
|
|
||||||
#define UART_CONF_FBRD UART_FBRD_460800
|
|
||||||
#else /* Bail out with an error unless the user provided custom values */
|
|
||||||
#if !(defined UART_CONF_IBRD && defined UART_CONF_FBRD)
|
|
||||||
#error "UART baud rate misconfigured and custom IBRD/FBRD values not provided"
|
|
||||||
#error "Check the value of UART_CONF_BAUD_RATE in contiki-conf.h or project-conf.h"
|
|
||||||
#error "Supported values are 115200, 230400 and 460800. Alternatively, you can"
|
|
||||||
#error "provide custom values for UART_CONF_IBRD and UART_CONF_FBRD"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name UART Register Offsets
|
/** \name UART Register Offsets
|
||||||
|
@ -366,18 +331,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \brief Initialises the UART controller, configures I/O control
|
/** \brief Initialises the UART controller, configures I/O control
|
||||||
* and interrupts */
|
* and interrupts
|
||||||
void uart_init(void);
|
* \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1)
|
||||||
|
*/
|
||||||
|
void uart_init(uint8_t uart);
|
||||||
|
|
||||||
/** \brief Sends a single character down the UART
|
/** \brief Sends a single character down the UART
|
||||||
|
* \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1)
|
||||||
* \param b The character to transmit
|
* \param b The character to transmit
|
||||||
*/
|
*/
|
||||||
void uart_write_byte(uint8_t b);
|
void uart_write_byte(uint8_t uart, uint8_t b);
|
||||||
|
|
||||||
/** \brief Assigns a callback to be called when the UART receives a byte
|
/** \brief Assigns a callback to be called when the UART receives a byte
|
||||||
|
* \param uart The UART instance to use (0 to \c UART_INSTANCE_COUNT - 1)
|
||||||
* \param input A pointer to the function
|
* \param input A pointer to the function
|
||||||
*/
|
*/
|
||||||
void uart_set_input(int (* input)(unsigned char c));
|
void uart_set_input(uint8_t uart, int (* input)(unsigned char c));
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "dev/uart.h"
|
#include "dev/uart.h"
|
||||||
|
|
||||||
#define BAUD2UBR(x) x
|
#define BAUD2UBR(x) x
|
||||||
#define uart1_set_input(f) uart_set_input(f)
|
#define uart1_set_input(f) uart_set_input(UART1_CONF_UART, f)
|
||||||
|
|
||||||
#endif /* UART1_H_ */
|
#endif /* UART1_H_ */
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ ieee_addr_cpy_to(uint8_t *dst, uint8_t len)
|
||||||
/* Reading from Info Page, we need to invert byte order */
|
/* Reading from Info Page, we need to invert byte order */
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
dst[i] = ((uint8_t *)IEEE_ADDR_LOCATION_PRIMARY)[len - 1 - i];
|
dst[i] = ((uint8_t *)IEEE_ADDR_LOCATION)[len - 1 - i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,18 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define IEEE_ADDR_LOCATION_PRIMARY 0x00280028 /**< IEEE address location */
|
#define IEEE_ADDR_LOCATION_PRIMARY 0x00280028 /**< IEEE address location */
|
||||||
|
#define IEEE_ADDR_LOCATION_SECONDARY 0x0027FFCC /**< IEEE address location */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Select which address location to use
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if IEEE_ADDR_CONF_USE_SECONDARY_LOCATION
|
||||||
|
#define IEEE_ADDR_LOCATION IEEE_ADDR_LOCATION_SECONDARY
|
||||||
|
#else
|
||||||
|
#define IEEE_ADDR_LOCATION IEEE_ADDR_LOCATION_PRIMARY
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -88,14 +88,11 @@ rtimer_clock_t lpm_stats[3];
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* Remembers what time it was when went to deep sleep
|
* Remembers what time it was when went to deep sleep
|
||||||
* This is used when coming out of PM1/2 to adjust the system clock, which
|
* This is used when coming out of PM0/1/2 to keep stats
|
||||||
* stops ticking while in those PMs
|
|
||||||
*/
|
*/
|
||||||
static rtimer_clock_t sleep_enter_time;
|
static rtimer_clock_t sleep_enter_time;
|
||||||
|
|
||||||
#define RTIMER_CLOCK_TICK_RATIO (RTIMER_SECOND / CLOCK_SECOND)
|
void clock_adjust(void);
|
||||||
|
|
||||||
void clock_adjust(clock_time_t ticks);
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Stores the currently specified MAX allowed PM */
|
/* Stores the currently specified MAX allowed PM */
|
||||||
static uint8_t max_pm;
|
static uint8_t max_pm;
|
||||||
|
@ -137,10 +134,7 @@ enter_pm0(void)
|
||||||
/* We are only interested in IRQ energest while idle or in LPM */
|
/* We are only interested in IRQ energest while idle or in LPM */
|
||||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||||
|
|
||||||
/*
|
/* Remember the current time so we can keep stats when we wake up */
|
||||||
* After PM0 we don't need to adjust the system clock. Thus, saving the time
|
|
||||||
* we enter Deep Sleep is only required if we are keeping stats.
|
|
||||||
*/
|
|
||||||
if(LPM_CONF_STATS) {
|
if(LPM_CONF_STATS) {
|
||||||
sleep_enter_time = RTIMER_NOW();
|
sleep_enter_time = RTIMER_NOW();
|
||||||
}
|
}
|
||||||
|
@ -215,10 +209,8 @@ lpm_exit()
|
||||||
RTIMER_NOW() - sleep_enter_time);
|
RTIMER_NOW() - sleep_enter_time);
|
||||||
|
|
||||||
/* Adjust the system clock, since it was not counting while we were sleeping
|
/* Adjust the system clock, since it was not counting while we were sleeping
|
||||||
* We need to convert sleep duration from rtimer ticks to clock ticks and
|
* We need to convert sleep duration from rtimer ticks to clock ticks */
|
||||||
* this will cost us some accuracy */
|
clock_adjust();
|
||||||
clock_adjust((clock_time_t)
|
|
||||||
((RTIMER_NOW() - sleep_enter_time) / RTIMER_CLOCK_TICK_RATIO));
|
|
||||||
|
|
||||||
/* Restore system clock to the 32 MHz XOSC */
|
/* Restore system clock to the 32 MHz XOSC */
|
||||||
select_32_mhz_xosc();
|
select_32_mhz_xosc();
|
||||||
|
@ -306,8 +298,10 @@ lpm_enter()
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||||
|
|
||||||
/* Remember the current time so we can adjust the clock when we wake up */
|
/* Remember the current time so we can keep stats when we wake up */
|
||||||
sleep_enter_time = RTIMER_NOW();
|
if(LPM_CONF_STATS) {
|
||||||
|
sleep_enter_time = RTIMER_NOW();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Last chance to abort entering Deep Sleep.
|
* Last chance to abort entering Deep Sleep.
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
#define set_input(f) usb_serial_set_input(f)
|
#define set_input(f) usb_serial_set_input(f)
|
||||||
#define flush() usb_serial_flush()
|
#define flush() usb_serial_flush()
|
||||||
#else
|
#else
|
||||||
#define write_byte(b) uart_write_byte(b)
|
#define write_byte(b) uart_write_byte(SLIP_ARCH_CONF_UART, b)
|
||||||
#define set_input(f) uart_set_input(f)
|
#define set_input(f) uart_set_input(SLIP_ARCH_CONF_UART, f)
|
||||||
#define flush()
|
#define flush()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,27 +41,51 @@
|
||||||
#ifndef SPI_ARCH_H_
|
#ifndef SPI_ARCH_H_
|
||||||
#define SPI_ARCH_H_
|
#define SPI_ARCH_H_
|
||||||
|
|
||||||
#include "contiki.h"
|
|
||||||
#include "dev/ssi.h"
|
#include "dev/ssi.h"
|
||||||
|
|
||||||
#define SPI_WAITFORTxREADY() do { \
|
#define SPI_WAITFORTxREADY() do { \
|
||||||
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)); \
|
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_TNF)); \
|
||||||
} while (0)
|
} while(0)
|
||||||
|
|
||||||
#define SPI_TXBUF REG(SSI0_BASE + SSI_DR)
|
#define SPI_TXBUF REG(SSI0_BASE + SSI_DR)
|
||||||
|
|
||||||
#define SPI_RXBUF REG(SSI0_BASE + SSI_DR)
|
#define SPI_RXBUF REG(SSI0_BASE + SSI_DR)
|
||||||
|
|
||||||
#define SPI_WAITFOREOTx() do { \
|
#define SPI_WAITFOREOTx() do { \
|
||||||
while(REG(SSI0_BASE + SSI_SR) & SSI_SR_BSY); \
|
while(REG(SSI0_BASE + SSI_SR) & SSI_SR_BSY); \
|
||||||
} while (0)
|
} while(0)
|
||||||
|
|
||||||
#define SPI_WAITFOREORx() do { \
|
#define SPI_WAITFOREORx() do { \
|
||||||
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE)); \
|
while(!(REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE)); \
|
||||||
} while (0)
|
} while(0)
|
||||||
|
|
||||||
|
#ifdef SPI_FLUSH
|
||||||
|
#error "You must include spi-arch.h before spi.h for the CC2538."
|
||||||
|
#endif
|
||||||
|
#define SPI_FLUSH() do { \
|
||||||
|
SPI_WAITFOREORx(); \
|
||||||
|
while (REG(SSI0_BASE + SSI_SR) & SSI_SR_RNE) { \
|
||||||
|
SPI_RXBUF; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define SPI_CS_CLR(port, pin) do { \
|
||||||
|
GPIO_CLR_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define SPI_CS_SET(port, pin) do { \
|
||||||
|
GPIO_SET_PIN(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(pin)); \
|
||||||
|
} while(0)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name Arch-specific SPI functions
|
/** \name Arch-specific SPI functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Configure a GPIO to be the chip select pin
|
||||||
|
*/
|
||||||
|
void spi_cs_init(uint8_t port, uint8_t pin);
|
||||||
|
|
||||||
/** \brief Enables the SPI peripheral
|
/** \brief Enables the SPI peripheral
|
||||||
*/
|
*/
|
||||||
void spi_enable(void);
|
void spi_enable(void);
|
||||||
|
@ -71,6 +95,27 @@ void spi_enable(void);
|
||||||
*/
|
*/
|
||||||
void spi_disable(void);
|
void spi_disable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Configure the SPI data and clock polarity and the data size.
|
||||||
|
*
|
||||||
|
* This function configures the SSI peripheral to use a particular SPI
|
||||||
|
* configuration that a slave device requires. It should always be called
|
||||||
|
* before using the SPI bus as another driver could have changed the settings.
|
||||||
|
*
|
||||||
|
* See section 19.4.4 in the CC2538 user guide for more information.
|
||||||
|
*
|
||||||
|
* \param frame_format Set the SSI frame format. Use SSI_CR0_FRF_MOTOROLA,
|
||||||
|
* SSI_CR0_FRF_TI, or SSI_CR0_FRF_MICROWIRE.
|
||||||
|
* \param clock_polarity In Motorola mode, set whether the clock is high or low
|
||||||
|
* when idle. Use SSI_CR0_SPO or 0.
|
||||||
|
* \param clock_phase In Motorola mode, select whether data is valid on the
|
||||||
|
* first or second edge of the clock. Use SSI_CR0_SPH or 0.
|
||||||
|
* \param data_size The number of bits in each "byte" of data. Must be
|
||||||
|
* between 4 and 16, inclusive.
|
||||||
|
*/
|
||||||
|
void spi_set_mode(uint32_t frame_format, uint32_t clock_polarity,
|
||||||
|
uint32_t clock_phase, uint32_t data_size);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* SPI_ARCH_H_ */
|
#endif /* SPI_ARCH_H_ */
|
||||||
|
|
|
@ -88,7 +88,8 @@ LDFLAGSNO += -D_STACK_SIZE=$(IAR_STACK_SIZE) -D_DATA16_HEAP_SIZE=$(IAR_DATA16_HE
|
||||||
|
|
||||||
CUSTOM_RULE_C_TO_O = 1
|
CUSTOM_RULE_C_TO_O = 1
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) $< -o $@
|
$(TRACE_CC)
|
||||||
|
$(Q)$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
define FINALIZE_CYGWIN_DEPENDENCY
|
define FINALIZE_CYGWIN_DEPENDENCY
|
||||||
sed -e 's/ \([A-Z]\):\\/ \/cygdrive\/\L\1\//' -e 's/\\/\//g' \
|
sed -e 's/ \([A-Z]\):\\/ \/cygdrive\/\L\1\//' -e 's/\\/\//g' \
|
||||||
|
@ -98,14 +99,16 @@ endef
|
||||||
|
|
||||||
CUSTOM_RULE_C_TO_OBJECTDIR_O = 1
|
CUSTOM_RULE_C_TO_OBJECTDIR_O = 1
|
||||||
$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
|
$(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
|
||||||
$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@
|
$(TRACE_CC)
|
||||||
|
$(Q)$(CC) $(CFLAGS) $< --dependencies=m $(@:.o=.P) -o $@
|
||||||
ifeq ($(HOST_OS),Windows)
|
ifeq ($(HOST_OS),Windows)
|
||||||
@$(FINALIZE_CYGWIN_DEPENDENCY)
|
@$(FINALIZE_CYGWIN_DEPENDENCY)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CUSTOM_RULE_C_TO_CO = 1
|
CUSTOM_RULE_C_TO_CO = 1
|
||||||
%.co: %.c
|
%.co: %.c
|
||||||
$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@
|
$(TRACE_CC)
|
||||||
|
$(Q)$(CC) $(CFLAGS) -DAUTOSTART_ENABLE $< -o $@
|
||||||
|
|
||||||
AROPTS = -o
|
AROPTS = -o
|
||||||
|
|
||||||
|
@ -175,7 +178,8 @@ PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)}
|
||||||
$(STRIP) --strip-unneeded -g -x -o $@ $<
|
$(STRIP) --strip-unneeded -g -x -o $@ $<
|
||||||
|
|
||||||
%.o: ${CONTIKI_TARGET}/loader/%.S
|
%.o: ${CONTIKI_TARGET}/loader/%.S
|
||||||
$(AS) -o $(notdir $(<:.S=.o)) $<
|
$(TRACE_AS)
|
||||||
|
$(Q)$(AS) -o $(notdir $(<:.S=.o)) $<
|
||||||
|
|
||||||
%.firmware: %.${TARGET}
|
%.firmware: %.${TARGET}
|
||||||
mv $< $@
|
mv $< $@
|
||||||
|
@ -188,7 +192,15 @@ else
|
||||||
$(OBJCOPY) $^ -O ihex $@
|
$(OBJCOPY) $^ -O ihex $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
%.mspsim: %.${TARGET}
|
$(CONTIKI)/tools/mspsim/build.xml:
|
||||||
|
@echo '----------------'
|
||||||
|
@echo 'Could not find the MSPSim build file. Did you run "git submodule update --init"?'
|
||||||
|
@echo '----------------'
|
||||||
|
|
||||||
|
$(CONTIKI)/tools/mspsim/mspsim.jar: $(CONTIKI)/tools/mspsim/build.xml
|
||||||
|
(cd $(CONTIKI)/tools/mspsim && ant jar)
|
||||||
|
|
||||||
|
%.mspsim: %.${TARGET} ${CONTIKI}/tools/mspsim/mspsim.jar
|
||||||
java -jar ${CONTIKI}/tools/mspsim/mspsim.jar -platform=${TARGET} $<
|
java -jar ${CONTIKI}/tools/mspsim/mspsim.jar -platform=${TARGET} $<
|
||||||
|
|
||||||
mspsim-maptable: contiki-${TARGET}.map
|
mspsim-maptable: contiki-${TARGET}.map
|
||||||
|
|
|
@ -83,68 +83,6 @@ msp430_init_dco(void)
|
||||||
/* DCO Internal Resistor */
|
/* DCO Internal Resistor */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* Start CPU with full speed (? good or bad?) and go downwards */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
msp430_quick_synch_dco(void) {
|
|
||||||
uint16_t last;
|
|
||||||
uint16_t diff;
|
|
||||||
uint16_t dco_reg = 0x0fff;
|
|
||||||
uint8_t current_bit = 12;
|
|
||||||
uint16_t i;
|
|
||||||
/* DELTA_2 assumes an ACLK of 32768 Hz */
|
|
||||||
#define DELTA_2 ((MSP430_CPU_SPEED) / 32768)
|
|
||||||
|
|
||||||
/* Select SMCLK clock, and capture on ACLK for TBCCR6 */
|
|
||||||
TBCTL = TBSSEL1 | TBCLR;
|
|
||||||
TBCCTL6 = CCIS0 + CM0 + CAP;
|
|
||||||
/* start the timer */
|
|
||||||
TBCTL |= MC1;
|
|
||||||
|
|
||||||
BCSCTL1 = 0x8D | 7;
|
|
||||||
DCOCTL = 0xff; /* MAX SPEED ?? */
|
|
||||||
|
|
||||||
/* IDEA: do binary search - check MSB first, etc... */
|
|
||||||
/* 1 set current bit to zero - if to slow, put back to 1 */
|
|
||||||
while(current_bit--) {
|
|
||||||
/* first set the current bit to zero and check - we know that it is
|
|
||||||
set from start so ^ works (first bit = bit 11) */
|
|
||||||
dco_reg = dco_reg ^ (1 << current_bit); /* clear bit 11..10..9.. */
|
|
||||||
|
|
||||||
/* set dco registers */
|
|
||||||
DCOCTL = dco_reg & 0xff;
|
|
||||||
BCSCTL1 = (BCSCTL1 & 0xf8) | (dco_reg >> 8);
|
|
||||||
|
|
||||||
/* some delay to make clock stable - could possibly be made using
|
|
||||||
captures too ... */
|
|
||||||
for(i=0; i < 1000; i++) {
|
|
||||||
i = i | 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* do capture... */
|
|
||||||
while(!(TBCCTL6 & CCIFG));
|
|
||||||
last = TBCCR6;
|
|
||||||
|
|
||||||
TBCCTL6 &= ~CCIFG;
|
|
||||||
/* wait for next Capture - and calculate difference */
|
|
||||||
while(!(TBCCTL6 & CCIFG));
|
|
||||||
diff = TBCCR6 - last;
|
|
||||||
|
|
||||||
/* /\* store what was run during the specific test *\/ */
|
|
||||||
/* dcos[current_bit] = dco_reg; */
|
|
||||||
/* vals[current_bit] = diff; */
|
|
||||||
|
|
||||||
/* should we keep the bit cleared or not ? */
|
|
||||||
if(diff < DELTA_2) { /* DCO is too slow - fewer ticks than desired */
|
|
||||||
/* toggle bit again to get it back to one */
|
|
||||||
dco_reg = dco_reg ^ (1 << current_bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
static void
|
static void
|
||||||
init_ports(void)
|
init_ports(void)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +162,10 @@ msp430_cpu_init(void)
|
||||||
dint();
|
dint();
|
||||||
watchdog_init();
|
watchdog_init();
|
||||||
init_ports();
|
init_ports();
|
||||||
msp430_quick_synch_dco();
|
/* set DCO to a reasonable default value (8MHz) */
|
||||||
|
msp430_init_dco();
|
||||||
|
/* calibrate the DCO step-by-step */
|
||||||
|
msp430_sync_dco();
|
||||||
eint();
|
eint();
|
||||||
#if defined(__MSP430__) && defined(__GNUC__)
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
if((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug! */
|
if((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug! */
|
||||||
|
@ -282,13 +223,10 @@ int __low_level_init(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if DCOSYNCH_CONF_ENABLED
|
|
||||||
/* this code will always start the TimerB if not already started */
|
|
||||||
void
|
void
|
||||||
msp430_sync_dco(void) {
|
msp430_sync_dco(void) {
|
||||||
uint16_t last;
|
uint16_t oldcapture;
|
||||||
uint16_t diff;
|
int16_t diff;
|
||||||
/* uint32_t speed; */
|
|
||||||
/* DELTA_2 assumes an ACLK of 32768 Hz */
|
/* DELTA_2 assumes an ACLK of 32768 Hz */
|
||||||
#define DELTA_2 ((MSP430_CPU_SPEED) / 32768)
|
#define DELTA_2 ((MSP430_CPU_SPEED) / 32768)
|
||||||
|
|
||||||
|
@ -298,36 +236,35 @@ msp430_sync_dco(void) {
|
||||||
/* start the timer */
|
/* start the timer */
|
||||||
TBCTL |= MC1;
|
TBCTL |= MC1;
|
||||||
|
|
||||||
/* wait for next Capture */
|
while(1) {
|
||||||
TBCCTL6 &= ~CCIFG;
|
/* wait for the next capture */
|
||||||
while(!(TBCCTL6 & CCIFG));
|
TBCCTL6 &= ~CCIFG;
|
||||||
last = TBCCR6;
|
while(!(TBCCTL6 & CCIFG));
|
||||||
|
oldcapture = TBCCR6;
|
||||||
|
|
||||||
TBCCTL6 &= ~CCIFG;
|
/* wait for the next capture - and calculate difference */
|
||||||
/* wait for next Capture - and calculate difference */
|
TBCCTL6 &= ~CCIFG;
|
||||||
while(!(TBCCTL6 & CCIFG));
|
while(!(TBCCTL6 & CCIFG));
|
||||||
diff = TBCCR6 - last;
|
diff = TBCCR6 - oldcapture;
|
||||||
|
|
||||||
/* Stop timer - conserves energy according to user guide */
|
/* resynchronize the DCO speed if not at target */
|
||||||
TBCTL = 0;
|
if(DELTA_2 == diff) {
|
||||||
|
break; /* if equal, leave "while(1)" */
|
||||||
/* speed = diff; */
|
} else if(DELTA_2 < diff) { /* DCO is too fast, slow it down */
|
||||||
/* speed = speed * 32768; */
|
DCOCTL--;
|
||||||
/* printf("Last TAR diff:%d target: %ld ", diff, DELTA_2); */
|
if(DCOCTL == 0xFF) { /* Did DCO roll under? */
|
||||||
/* printf("CPU Speed: %lu DCOCTL: %d\n", speed, DCOCTL); */
|
BCSCTL1--;
|
||||||
|
}
|
||||||
/* resynchronize the DCO speed if not at target */
|
} else { /* -> Select next lower RSEL */
|
||||||
if(DELTA_2 < diff) { /* DCO is too fast, slow it down */
|
DCOCTL++;
|
||||||
DCOCTL--;
|
if(DCOCTL == 0x00) { /* Did DCO roll over? */
|
||||||
if(DCOCTL == 0xFF) { /* Did DCO role under? */
|
BCSCTL1++;
|
||||||
BCSCTL1--;
|
}
|
||||||
}
|
/* -> Select next higher RSEL */
|
||||||
} else if(DELTA_2 > diff) {
|
|
||||||
DCOCTL++;
|
|
||||||
if(DCOCTL == 0x00) { /* Did DCO role over? */
|
|
||||||
BCSCTL1++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop the timer - conserves energy according to user guide */
|
||||||
|
TBCTL = 0;
|
||||||
}
|
}
|
||||||
#endif /* DCOSYNCH_CONF_ENABLED */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
* - BTN_DOWN turns on LEDS_REBOOT and causes a watchdog reboot
|
* - BTN_DOWN turns on LEDS_REBOOT and causes a watchdog reboot
|
||||||
* - BTN_UP to soft reset (SYS_CTRL_PWRDBG::FORCE_WARM_RESET)
|
* - BTN_UP to soft reset (SYS_CTRL_PWRDBG::FORCE_WARM_RESET)
|
||||||
* - BTN_LEFT and BTN_RIGHT flash the LED defined as LEDS_BUTTON
|
* - BTN_LEFT and BTN_RIGHT flash the LED defined as LEDS_BUTTON
|
||||||
|
* - ADC sensors : On-chip VDD / 3 and temperature, and ambient light sensor
|
||||||
|
* values are printed over UART periodically.
|
||||||
* - UART : Every LOOP_INTERVAL the EM will print something over the
|
* - UART : Every LOOP_INTERVAL the EM will print something over the
|
||||||
* UART. Receiving an entire line of text over UART (ending
|
* UART. Receiving an entire line of text over UART (ending
|
||||||
* in \\r) will cause LEDS_SERIAL_IN to toggle
|
* in \\r) will cause LEDS_SERIAL_IN to toggle
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
#include "dev/leds.h"
|
#include "dev/leds.h"
|
||||||
#include "dev/uart.h"
|
#include "dev/uart.h"
|
||||||
#include "dev/button-sensor.h"
|
#include "dev/button-sensor.h"
|
||||||
|
#include "dev/adc-sensor.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
#include "dev/serial-line.h"
|
#include "dev/serial-line.h"
|
||||||
#include "dev/sys-ctrl.h"
|
#include "dev/sys-ctrl.h"
|
||||||
|
@ -111,6 +114,7 @@ rt_callback(struct rtimer *t, void *ptr)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PROCESS_THREAD(cc2538_demo_process, ev, data)
|
PROCESS_THREAD(cc2538_demo_process, ev, data)
|
||||||
{
|
{
|
||||||
|
int16_t value;
|
||||||
|
|
||||||
PROCESS_EXITHANDLER(broadcast_close(&bc))
|
PROCESS_EXITHANDLER(broadcast_close(&bc))
|
||||||
|
|
||||||
|
@ -127,7 +131,18 @@ PROCESS_THREAD(cc2538_demo_process, ev, data)
|
||||||
|
|
||||||
if(ev == PROCESS_EVENT_TIMER) {
|
if(ev == PROCESS_EVENT_TIMER) {
|
||||||
leds_on(LEDS_PERIODIC);
|
leds_on(LEDS_PERIODIC);
|
||||||
printf("Counter = 0x%08x\n", counter);
|
printf("-----------------------------------------\n"
|
||||||
|
"Counter = 0x%08x\n", counter);
|
||||||
|
|
||||||
|
value = adc_sensor.value(ADC_SENSOR_VDD_3);
|
||||||
|
printf("VDD = %d mV\n", value * (3 * 1190) / (2047 << 4));
|
||||||
|
|
||||||
|
value = adc_sensor.value(ADC_SENSOR_TEMP);
|
||||||
|
printf("Temperature = %d mC\n",
|
||||||
|
25000 + ((value >> 4) - 1422) * 10000 / 42);
|
||||||
|
|
||||||
|
value = adc_sensor.value(ADC_SENSOR_ALS);
|
||||||
|
printf("Ambient light sensor = %d raw\n", value);
|
||||||
|
|
||||||
etimer_set(&et, CLOCK_SECOND);
|
etimer_set(&et, CLOCK_SECOND);
|
||||||
rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1,
|
rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1,
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#define CC2538_RF_CONF_AUTOACK 0
|
#define CC2538_RF_CONF_AUTOACK 0
|
||||||
#define NETSTACK_CONF_RDC stub_rdc_driver
|
#define NETSTACK_CONF_RDC stub_rdc_driver
|
||||||
|
|
||||||
#define UART_CONF_BAUD_RATE 460800
|
#define UART0_CONF_BAUD_RATE 460800
|
||||||
|
|
||||||
#endif /* PROJECT_CONF_H_ */
|
#endif /* PROJECT_CONF_H_ */
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,7 @@ event_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred
|
||||||
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
|
/* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Additionally, a handler function named [resource name]_event_handler must be implemented for each PERIODIC_RESOURCE defined.
|
/* Additionally, a handler function named [resource name]_event_handler must be implemented for each EVENT_RESOURCE defined.
|
||||||
* It will be called by the REST manager process with the defined period. */
|
* It will be called by the REST manager process with the defined period. */
|
||||||
void
|
void
|
||||||
event_event_handler(resource_t *r)
|
event_event_handler(resource_t *r)
|
||||||
|
|
11
examples/ipv6/multicast/Makefile
Normal file
11
examples/ipv6/multicast/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
DEFINES+=PROJECT_CONF_H=\"project-conf.h\"
|
||||||
|
UIP_CONF_IPV6=1
|
||||||
|
|
||||||
|
CONTIKI_PROJECT = root intermediate sink
|
||||||
|
all: $(CONTIKI_PROJECT)
|
||||||
|
|
||||||
|
CONTIKI = ../../..
|
||||||
|
|
||||||
|
MODULES += core/net/ipv6/multicast
|
||||||
|
|
||||||
|
include $(CONTIKI)/Makefile.include
|
64
examples/ipv6/multicast/intermediate.c
Normal file
64
examples/ipv6/multicast/intermediate.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Loughborough University - Computer 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
|
||||||
|
* This node is part of the RPL multicast example. It basically
|
||||||
|
* represents a node that does not join the multicast group
|
||||||
|
* but still knows how to forward multicast packets
|
||||||
|
* The example will work with or without any number of these nodes
|
||||||
|
*
|
||||||
|
* Also, performs some sanity checks for the contiki configuration
|
||||||
|
* and generates an error if the conf is bad
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
|
#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL
|
||||||
|
#error "This example can not work with the current contiki configuration"
|
||||||
|
#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL"
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS(mcast_intermediate_process, "Intermediate Process");
|
||||||
|
AUTOSTART_PROCESSES(&mcast_intermediate_process);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(mcast_intermediate_process, ev, data)
|
||||||
|
{
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
257
examples/ipv6/multicast/multicast.csc
Normal file
257
examples/ipv6/multicast/multicast.csc
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||||
|
<simulation>
|
||||||
|
<title>Example of a uIPv6 network with multicast support</title>
|
||||||
|
<randomseed>123456</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
org.contikios.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>50.0</transmitting_range>
|
||||||
|
<interference_range>50.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.mspmote.SkyMoteType
|
||||||
|
<identifier>sky1</identifier>
|
||||||
|
<description>root</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/multicast/root.c</source>
|
||||||
|
<commands EXPORT="discard">make root.sky TARGET=sky</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/multicast/root.sky</firmware>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.mspmote.SkyMoteType
|
||||||
|
<identifier>sky2</identifier>
|
||||||
|
<description>intermediate</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c</source>
|
||||||
|
<commands EXPORT="discard">make intermediate.sky TARGET=sky</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/multicast/intermediate.sky</firmware>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.mspmote.SkyMoteType
|
||||||
|
<identifier>sky3</identifier>
|
||||||
|
<description>sink</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/multicast/sink.c</source>
|
||||||
|
<commands EXPORT="discard">make sink.sky TARGET=sky</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/multicast/sink.sky</firmware>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>5.995813174969022</x>
|
||||||
|
<y>34.43129455447824</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky1</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>40.70237155931961</x>
|
||||||
|
<y>16.396742420332068</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>2</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky2</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>100.3720728044051</x>
|
||||||
|
<y>70.93197095432518</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>3</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky3</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>81.7376718406712</x>
|
||||||
|
<y>28.854291358797</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>4</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky3</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-26.161520836433183</x>
|
||||||
|
<y>8.116006415286686</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>5</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky3</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-34.57705675553882</x>
|
||||||
|
<y>92.87247531485058</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>6</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky3</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>39.86312587077661</x>
|
||||||
|
<y>59.603125741056246</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>7</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky2</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>1.4345607604759194</x>
|
||||||
|
<y>75.2481773153879</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>8</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky2</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.SimControl
|
||||||
|
<width>318</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>192</height>
|
||||||
|
<location_x>0</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Visualizer
|
||||||
|
<plugin_config>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.AddressVisualizerSkin</skin>
|
||||||
|
<viewport>3.914959956760176 0.0 0.0 3.914959956760176 300.2075734071477 -15.682931033747009</viewport>
|
||||||
|
</plugin_config>
|
||||||
|
<width>869</width>
|
||||||
|
<z>3</z>
|
||||||
|
<height>441</height>
|
||||||
|
<location_x>320</location_x>
|
||||||
|
<location_y>3</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
<formatted_time />
|
||||||
|
<coloring />
|
||||||
|
</plugin_config>
|
||||||
|
<width>1281</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>213</height>
|
||||||
|
<location_x>-1</location_x>
|
||||||
|
<location_y>714</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.RadioLogger
|
||||||
|
<plugin_config>
|
||||||
|
<split>117</split>
|
||||||
|
<formatted_time />
|
||||||
|
<showdups>false</showdups>
|
||||||
|
<hidenodests>false</hidenodests>
|
||||||
|
<analyzers name="6lowpan-pcap" />
|
||||||
|
</plugin_config>
|
||||||
|
<width>1280</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>268</height>
|
||||||
|
<location_x>0</location_x>
|
||||||
|
<location_y>445</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
69
examples/ipv6/multicast/project-conf.h
Normal file
69
examples/ipv6/multicast/project-conf.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Loughborough University - Computer 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
|
||||||
|
* Project specific configuration defines for the RPl multicast
|
||||||
|
* example.
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROJECT_CONF_H_
|
||||||
|
#define PROJECT_CONF_H_
|
||||||
|
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6-engines.h"
|
||||||
|
|
||||||
|
/* Change this to switch engines. Engine codes in uip-mcast6-engines.h */
|
||||||
|
#define UIP_MCAST6_CONF_ENGINE UIP_MCAST6_ENGINE_ROLL_TM
|
||||||
|
|
||||||
|
/* For Imin: Use 16 over NullRDC, 64 over Contiki MAC */
|
||||||
|
#define ROLL_TM_CONF_IMIN_1 64
|
||||||
|
|
||||||
|
#undef UIP_CONF_IPV6_RPL
|
||||||
|
#undef UIP_CONF_ND6_SEND_RA
|
||||||
|
#undef UIP_CONF_ROUTER
|
||||||
|
#define UIP_CONF_IPV6_RPL 1
|
||||||
|
#define UIP_CONF_ND6_SEND_RA 0
|
||||||
|
#define UIP_CONF_ROUTER 1
|
||||||
|
#define UIP_MCAST6_ROUTE_CONF_ROUTES 1
|
||||||
|
|
||||||
|
#undef UIP_CONF_TCP
|
||||||
|
#define UIP_CONF_TCP 0
|
||||||
|
|
||||||
|
/* Code/RAM footprint savings so that things will fit on our device */
|
||||||
|
#undef UIP_CONF_DS6_NBR_NBU
|
||||||
|
#undef UIP_CONF_DS6_ROUTE_NBU
|
||||||
|
#define UIP_CONF_DS6_NBR_NBU 10
|
||||||
|
#define UIP_CONF_DS6_ROUTE_NBU 10
|
||||||
|
|
||||||
|
#endif /* PROJECT_CONF_H_ */
|
171
examples/ipv6/multicast/root.c
Normal file
171
examples/ipv6/multicast/root.c
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Loughborough University - Computer 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
|
||||||
|
* This node is part of the RPL multicast example. It is an RPL root
|
||||||
|
* and sends a multicast message periodically. For the example to work,
|
||||||
|
* we need one of those nodes.
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-lib.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DEBUG DEBUG_PRINT
|
||||||
|
#include "net/ip/uip-debug.h"
|
||||||
|
#include "net/rpl/rpl.h"
|
||||||
|
|
||||||
|
#define MAX_PAYLOAD_LEN 120
|
||||||
|
#define MCAST_SINK_UDP_PORT 3001 /* Host byte order */
|
||||||
|
#define SEND_INTERVAL CLOCK_SECOND /* clock ticks */
|
||||||
|
#define ITERATIONS 100 /* messages */
|
||||||
|
|
||||||
|
/* Start sending messages START_DELAY secs after we start so that routing can
|
||||||
|
* converge */
|
||||||
|
#define START_DELAY 60
|
||||||
|
|
||||||
|
static struct uip_udp_conn * mcast_conn;
|
||||||
|
static char buf[MAX_PAYLOAD_LEN];
|
||||||
|
static uint32_t seq_id;
|
||||||
|
|
||||||
|
#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL
|
||||||
|
#error "This example can not work with the current contiki configuration"
|
||||||
|
#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL"
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS(rpl_root_process, "RPL ROOT, Multicast Sender");
|
||||||
|
AUTOSTART_PROCESSES(&rpl_root_process);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
multicast_send(void)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
id = uip_htonl(seq_id);
|
||||||
|
memset(buf, 0, MAX_PAYLOAD_LEN);
|
||||||
|
memcpy(buf, &id, sizeof(seq_id));
|
||||||
|
|
||||||
|
PRINTF("Send to: ");
|
||||||
|
PRINT6ADDR(&mcast_conn->ripaddr);
|
||||||
|
PRINTF(" Remote Port %u,", uip_ntohs(mcast_conn->rport));
|
||||||
|
PRINTF(" (msg=0x%08lx)", (unsigned long)uip_ntohl(*((uint32_t *)buf)));
|
||||||
|
PRINTF(" %lu bytes\n", (unsigned long)sizeof(id));
|
||||||
|
|
||||||
|
seq_id++;
|
||||||
|
uip_udp_packet_send(mcast_conn, buf, sizeof(id));
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
prepare_mcast(void)
|
||||||
|
{
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPHC will use stateless multicast compression for this destination
|
||||||
|
* (M=1, DAC=0), with 32 inline bits (1E 89 AB CD)
|
||||||
|
*/
|
||||||
|
uip_ip6addr(&ipaddr, 0xFF1E,0,0,0,0,0,0x89,0xABCD);
|
||||||
|
mcast_conn = udp_new(&ipaddr, UIP_HTONS(MCAST_SINK_UDP_PORT), NULL);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
set_own_addresses(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint8_t state;
|
||||||
|
rpl_dag_t *dag;
|
||||||
|
uip_ipaddr_t ipaddr;
|
||||||
|
|
||||||
|
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
|
||||||
|
uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
|
||||||
|
|
||||||
|
PRINTF("Our IPv6 addresses:\n");
|
||||||
|
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||||
|
state = uip_ds6_if.addr_list[i].state;
|
||||||
|
if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state
|
||||||
|
== ADDR_PREFERRED)) {
|
||||||
|
PRINTF(" ");
|
||||||
|
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
if(state == ADDR_TENTATIVE) {
|
||||||
|
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Become root of a new DODAG with ID our global v6 address */
|
||||||
|
dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr);
|
||||||
|
if(dag != NULL) {
|
||||||
|
rpl_set_prefix(dag, &ipaddr, 64);
|
||||||
|
PRINTF("Created a new RPL dag with ID: ");
|
||||||
|
PRINT6ADDR(&dag->dag_id);
|
||||||
|
PRINTF("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(rpl_root_process, ev, data)
|
||||||
|
{
|
||||||
|
static struct etimer et;
|
||||||
|
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
PRINTF("Multicast Engine: '%s'\n", UIP_MCAST6.name);
|
||||||
|
|
||||||
|
NETSTACK_MAC.off(1);
|
||||||
|
|
||||||
|
set_own_addresses();
|
||||||
|
|
||||||
|
prepare_mcast();
|
||||||
|
|
||||||
|
etimer_set(&et, START_DELAY * CLOCK_SECOND);
|
||||||
|
while(1) {
|
||||||
|
PROCESS_YIELD();
|
||||||
|
if(etimer_expired(&et)) {
|
||||||
|
if(seq_id == ITERATIONS) {
|
||||||
|
etimer_stop(&et);
|
||||||
|
} else {
|
||||||
|
multicast_send();
|
||||||
|
etimer_set(&et, SEND_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
136
examples/ipv6/multicast/sink.c
Normal file
136
examples/ipv6/multicast/sink.c
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Loughborough University - Computer 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
|
||||||
|
* This node is part of the RPL multicast example. It is a node that
|
||||||
|
* joins a multicast group and listens for messages. It also knows how
|
||||||
|
* to forward messages down the tree.
|
||||||
|
* For the example to work, we need one or more of those nodes.
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-lib.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DEBUG DEBUG_PRINT
|
||||||
|
#include "net/ip/uip-debug.h"
|
||||||
|
|
||||||
|
#define MCAST_SINK_UDP_PORT 3001 /* Host byte order */
|
||||||
|
|
||||||
|
static struct uip_udp_conn *sink_conn;
|
||||||
|
static uint16_t count;
|
||||||
|
|
||||||
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
|
#if !UIP_CONF_IPV6 || !UIP_CONF_ROUTER || !UIP_CONF_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL
|
||||||
|
#error "This example can not work with the current contiki configuration"
|
||||||
|
#error "Check the values of: UIP_CONF_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL"
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS(mcast_sink_process, "Multicast Sink");
|
||||||
|
AUTOSTART_PROCESSES(&mcast_sink_process);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
tcpip_handler(void)
|
||||||
|
{
|
||||||
|
if(uip_newdata()) {
|
||||||
|
count++;
|
||||||
|
PRINTF("In: [0x%08lx], TTL %u, total %u\n",
|
||||||
|
uip_ntohl((unsigned long) *((uint32_t *)(uip_appdata))),
|
||||||
|
UIP_IP_BUF->ttl, count);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static uip_ds6_maddr_t *
|
||||||
|
join_mcast_group(void)
|
||||||
|
{
|
||||||
|
uip_ipaddr_t addr;
|
||||||
|
uip_ds6_maddr_t *rv;
|
||||||
|
|
||||||
|
/* First, set our v6 global */
|
||||||
|
uip_ip6addr(&addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
uip_ds6_set_addr_iid(&addr, &uip_lladdr);
|
||||||
|
uip_ds6_addr_add(&addr, 0, ADDR_AUTOCONF);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPHC will use stateless multicast compression for this destination
|
||||||
|
* (M=1, DAC=0), with 32 inline bits (1E 89 AB CD)
|
||||||
|
*/
|
||||||
|
uip_ip6addr(&addr, 0xFF1E,0,0,0,0,0,0x89,0xABCD);
|
||||||
|
rv = uip_ds6_maddr_add(&addr);
|
||||||
|
|
||||||
|
if(rv) {
|
||||||
|
PRINTF("Joined multicast group ");
|
||||||
|
PRINT6ADDR(&uip_ds6_maddr_lookup(&addr)->ipaddr);
|
||||||
|
PRINTF("\n");
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(mcast_sink_process, ev, data)
|
||||||
|
{
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
PRINTF("Multicast Engine: '%s'\n", UIP_MCAST6.name);
|
||||||
|
|
||||||
|
if(join_mcast_group() == NULL) {
|
||||||
|
PRINTF("Failed to join multicast group\n");
|
||||||
|
PROCESS_EXIT();
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
sink_conn = udp_new(NULL, UIP_HTONS(0), NULL);
|
||||||
|
udp_bind(sink_conn, UIP_HTONS(MCAST_SINK_UDP_PORT));
|
||||||
|
|
||||||
|
PRINTF("Listening: ");
|
||||||
|
PRINT6ADDR(&sink_conn->ripaddr);
|
||||||
|
PRINTF(" local/remote port %u/%u\n",
|
||||||
|
UIP_HTONS(sink_conn->lport), UIP_HTONS(sink_conn->rport));
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
PROCESS_YIELD();
|
||||||
|
if(ev == tcpip_event) {
|
||||||
|
tcpip_handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
5
examples/tcp-socket/Makefile
Normal file
5
examples/tcp-socket/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
all: tcp-server
|
||||||
|
|
||||||
|
CONTIKI=../..
|
||||||
|
|
||||||
|
include $(CONTIKI)/Makefile.include
|
119
examples/tcp-socket/tcp-server.c
Normal file
119
examples/tcp-socket/tcp-server.c
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki-net.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SERVER_PORT 80
|
||||||
|
|
||||||
|
static struct tcp_socket socket;
|
||||||
|
|
||||||
|
#define INPUTBUFSIZE 400
|
||||||
|
static uint8_t inputbuf[INPUTBUFSIZE];
|
||||||
|
|
||||||
|
#define OUTPUTBUFSIZE 400
|
||||||
|
static uint8_t outputbuf[OUTPUTBUFSIZE];
|
||||||
|
|
||||||
|
PROCESS(tcp_server_process, "TCP echo process");
|
||||||
|
AUTOSTART_PROCESSES(&tcp_server_process);
|
||||||
|
static uint8_t get_received;
|
||||||
|
static int bytes_to_send;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
input(struct tcp_socket *s, void *ptr,
|
||||||
|
const uint8_t *inputptr, int inputdatalen)
|
||||||
|
{
|
||||||
|
printf("input %d bytes '%s'\n", inputdatalen, inputptr);
|
||||||
|
if(!get_received) {
|
||||||
|
/* See if we have a full GET request in the buffer. */
|
||||||
|
if(strncmp((char *)inputptr, "GET /", 5) == 0 &&
|
||||||
|
atoi((char *)&inputptr[5]) != 0) {
|
||||||
|
bytes_to_send = atoi((char *)&inputptr[5]);
|
||||||
|
printf("bytes_to_send %d\n", bytes_to_send);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf("inputptr '%.*s'\n", inputdatalen, inputptr);
|
||||||
|
/* Return the number of data bytes we received, to keep them all
|
||||||
|
in the buffer. */
|
||||||
|
return inputdatalen;
|
||||||
|
} else {
|
||||||
|
/* Discard everything */
|
||||||
|
return 0; /* all data consumed */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
event(struct tcp_socket *s, void *ptr,
|
||||||
|
tcp_socket_event_t ev)
|
||||||
|
{
|
||||||
|
printf("event %d\n", ev);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(tcp_server_process, ev, data)
|
||||||
|
{
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
tcp_socket_register(&socket, NULL,
|
||||||
|
inputbuf, sizeof(inputbuf),
|
||||||
|
outputbuf, sizeof(outputbuf),
|
||||||
|
input, event);
|
||||||
|
tcp_socket_listen(&socket, SERVER_PORT);
|
||||||
|
|
||||||
|
printf("Listening on %d\n", SERVER_PORT);
|
||||||
|
while(1) {
|
||||||
|
PROCESS_PAUSE();
|
||||||
|
|
||||||
|
if(bytes_to_send > 0) {
|
||||||
|
/* Send header */
|
||||||
|
printf("sending header\n");
|
||||||
|
tcp_socket_send_str(&socket, "HTTP/1.0 200 ok\r\nServer: Contiki tcp-socket example\r\n\r\n");
|
||||||
|
|
||||||
|
/* Send data */
|
||||||
|
printf("sending data\n");
|
||||||
|
while(bytes_to_send > 0) {
|
||||||
|
PROCESS_PAUSE();
|
||||||
|
int len, tosend;
|
||||||
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
tosend = MIN(bytes_to_send, sizeof(outputbuf));
|
||||||
|
len = tcp_socket_send(&socket, (uint8_t *)"", tosend);
|
||||||
|
bytes_to_send -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcp_socket_close(&socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -7,8 +7,9 @@ so please consult cpu/6502/README.md for further details.
|
||||||
|
|
||||||
The following Apple II Ethernet cards are supported:
|
The following Apple II Ethernet cards are supported:
|
||||||
|
|
||||||
- Uthernet: Use driver cs8900a.eth with address $C0x0 (x = 8 + slot number).
|
- Uthernet: Use driver cs8900a.eth with address $C0x0 (x = 8 + slot number).
|
||||||
- LANceGS: Use driver lan91c96.eth with address $C0x0 (x = 8 + slot number).
|
- Uthernet II: Use driver w5100.eth with address $C0x4 (x = 8 + slot number).
|
||||||
|
- LANceGS: Use driver lan91c96.eth with address $C0x0 (x = 8 + slot number).
|
||||||
|
|
||||||
In most cases it is desirable to use an emulator for the development and testing
|
In most cases it is desirable to use an emulator for the development and testing
|
||||||
of a Contiki application. AppleWin is especially well suited as it emulates the
|
of a Contiki application. AppleWin is especially well suited as it emulates the
|
||||||
|
|
|
@ -8,7 +8,8 @@ CONTIKI_TARGET_DIRS = . dev
|
||||||
|
|
||||||
CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c
|
CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c
|
||||||
CONTIKI_TARGET_SOURCEFILES += contiki-main.c
|
CONTIKI_TARGET_SOURCEFILES += contiki-main.c
|
||||||
CONTIKI_TARGET_SOURCEFILES += sensors.c smartrf-sensors.c button-sensor.c
|
CONTIKI_TARGET_SOURCEFILES += sensors.c smartrf-sensors.c
|
||||||
|
CONTIKI_TARGET_SOURCEFILES += button-sensor.c adc-sensor.c
|
||||||
|
|
||||||
TARGET_START_SOURCEFILES += startup-gcc.c
|
TARGET_START_SOURCEFILES += startup-gcc.c
|
||||||
TARGET_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(TARGET_START_SOURCEFILES)}}
|
TARGET_STARTFILES = ${addprefix $(OBJECTDIR)/,${call oname, $(TARGET_START_SOURCEFILES)}}
|
||||||
|
@ -28,3 +29,12 @@ include $(CONTIKI_CPU)/Makefile.cc2538
|
||||||
|
|
||||||
MODULES += core/net core/net/ipv6 core/net/mac core/net/ip \
|
MODULES += core/net core/net/ipv6 core/net/mac core/net/ip \
|
||||||
core/net/rpl core/net/rime core/net/mac/contikimac
|
core/net/rpl core/net/rime core/net/mac/contikimac
|
||||||
|
|
||||||
|
BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py
|
||||||
|
|
||||||
|
%.upload: %.bin
|
||||||
|
ifeq ($(wildcard $(BSL)), )
|
||||||
|
@echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?"
|
||||||
|
else
|
||||||
|
python $(BSL) -e -w -v $<
|
||||||
|
endif
|
||||||
|
|
|
@ -28,9 +28,11 @@ In terms of hardware support, the following drivers have been implemented:
|
||||||
* Random number generator
|
* Random number generator
|
||||||
* Low Power Modes
|
* Low Power Modes
|
||||||
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
* General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development.
|
||||||
|
* ADC
|
||||||
* SmartRF06 EB and BB peripherals
|
* SmartRF06 EB and BB peripherals
|
||||||
* LEDs
|
* LEDs
|
||||||
* Buttons
|
* Buttons
|
||||||
|
* ADC sensors (on-chip VDD / 3 and temperature, ambient light sensor)
|
||||||
* UART connectivity over the XDS100v3 backchannel (EB only)
|
* UART connectivity over the XDS100v3 backchannel (EB only)
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
|
@ -44,8 +46,8 @@ To start using Contiki, you will need the following:
|
||||||
Different tasks can be performed under different operating systems. The table below summarises what task can be performed on which OS:
|
Different tasks can be performed under different operating systems. The table below summarises what task can be performed on which OS:
|
||||||
|
|
||||||
Windows Linux OS-X
|
Windows Linux OS-X
|
||||||
Building Contiki Y Y N
|
Building Contiki Y Y Y
|
||||||
Node Programming Y Y N
|
Node Programming Y Y Y
|
||||||
Console output
|
Console output
|
||||||
(UART) Y Y Y
|
(UART) Y Y Y
|
||||||
(USB CDC-ACM) Y Y Y
|
(USB CDC-ACM) Y Y Y
|
||||||
|
@ -56,7 +58,7 @@ Different tasks can be performed under different operating systems. The table be
|
||||||
(UART) N Y Y
|
(UART) N Y Y
|
||||||
(USB CDC-ACM) N Y Y
|
(USB CDC-ACM) N Y Y
|
||||||
|
|
||||||
The platform has been developed and tested under Windows XP, Mac OS X 10.7 and Ubuntu 12.04 and 12.10. The matrix above has been populated based on information for those OSs.
|
The platform has been developed and tested under Windows XP, Mac OS X 10.9.1 and Ubuntu 12.04 and 12.10. The matrix above has been populated based on information for those OSs.
|
||||||
|
|
||||||
Install a Toolchain
|
Install a Toolchain
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -193,9 +195,18 @@ On Linux:
|
||||||
|
|
||||||
Software to Program the Nodes
|
Software to Program the Nodes
|
||||||
-----------------------------
|
-----------------------------
|
||||||
On Windows, nodes can be programmed with TI's ArmProgConsole or the [SmartRF Flash Programmer][smart-rf-flashprog]. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension.
|
The CC2538 can be programmed via the jtag interface or via the serial boot loader on the chip.
|
||||||
|
|
||||||
On Linux, nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension.
|
* On Windows:
|
||||||
|
* Nodes can be programmed with TI's ArmProgConsole or the [SmartRF Flash Programmer 2][smart-rf-flashprog]. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension. (jtag + serial)
|
||||||
|
* Nodes can also be programmed via the serial boot loader in the cc2538. In `tools/cc2538-bsl/` you can find `cc2538-bsl.py` this is a python script that can download firmware to your node via a serial connection. If you use this option you just need to make sure you have a working version of python installed. You can read the README in the same directory for more info. (serial)
|
||||||
|
|
||||||
|
* On Linux:
|
||||||
|
* Nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension. (jtag + serial)
|
||||||
|
* Nodes can also be programmed via the serial boot loader in the cc2538. No extra software needs to be installed. (serial)
|
||||||
|
|
||||||
|
* On OSX:
|
||||||
|
* The `cc2538-bsl.py` script in `tools/cc2538-bsl/` is the only option. No extra software needs to be installed. (serial)
|
||||||
|
|
||||||
The file with a `.cc2538dk` extension is a copy of the `.elf` file.
|
The file with a `.cc2538dk` extension is a copy of the `.elf` file.
|
||||||
|
|
||||||
|
@ -231,8 +242,12 @@ It is recommended to start with the `cc2538-demo` and `timer-test` examples unde
|
||||||
|
|
||||||
Strictly speaking, to build them you need to run `make TARGET=cc2538dk`. However, the example directories contain a `Makefile.target` which is automatically included and specifies the correct `TARGET=` argument. Thus, for examples under the `cc2538dk` directory, you can simply run `make`.
|
Strictly speaking, to build them you need to run `make TARGET=cc2538dk`. However, the example directories contain a `Makefile.target` which is automatically included and specifies the correct `TARGET=` argument. Thus, for examples under the `cc2538dk` directory, you can simply run `make`.
|
||||||
|
|
||||||
|
If you want to upload the compiled firmware to a node via the serial boot loader you need to manually enable the boot loader and then use `make cc2538-demo.upload`. On the SmartRF06 board you enable the boot loader by resetting the board (EM RESET button) while holding the `select` button. (The boot loader backdoor needs to be enabled on the chip for this to work, see README in the `tools/cc2538-bsl` directory for more info)
|
||||||
|
|
||||||
For the `cc2538-demo`, the comments at the top of `cc2538-demo.c` describe in detail what the example does.
|
For the `cc2538-demo`, the comments at the top of `cc2538-demo.c` describe in detail what the example does.
|
||||||
|
|
||||||
|
To generate an assembly listing of the compiled firmware, run `make cc2538-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean cc2538-demo.lst`.
|
||||||
|
|
||||||
Node IEEE/RIME/IPv6 Addresses
|
Node IEEE/RIME/IPv6 Addresses
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
@ -243,7 +258,7 @@ To configure the IEEE address source location (Info Page or hard-coded), use the
|
||||||
* 0: Info Page
|
* 0: Info Page
|
||||||
* 1: Hard-coded
|
* 1: Hard-coded
|
||||||
|
|
||||||
If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define.
|
If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define. If `IEEE_ADDR_CONF_HARDCODED` is defined as 0, the IEEE address can come from either the primary or secondary location in the Info Page. To use the secondary address, define `IEEE_ADDR_CONF_USE_SECONDARY_LOCATION` as 1.
|
||||||
|
|
||||||
Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example:
|
Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example:
|
||||||
|
|
||||||
|
@ -350,19 +365,33 @@ By default, everything is configured to use the UART (stdio, border router's SLI
|
||||||
|
|
||||||
You can multiplex things (for instance, SLIP as well as debugging over USB or SLIP over USB but debugging over UART and other combinations).
|
You can multiplex things (for instance, SLIP as well as debugging over USB or SLIP over USB but debugging over UART and other combinations).
|
||||||
|
|
||||||
|
Selecting UART0 and/or UART1
|
||||||
|
----------------------------
|
||||||
|
By default, everything is configured to use the UART0 (stdio, border router's SLIP, sniffer's output stream). If you want to change this, these are the relevant lines in contiki-conf.h (0: UART0, 1: UART1):
|
||||||
|
|
||||||
|
#define SERIAL_LINE_CONF_UART 0
|
||||||
|
#define SLIP_ARCH_CONF_UART 0
|
||||||
|
#define CC2538_RF_CONF_SNIFFER_UART 0
|
||||||
|
#define DBG_CONF_UART 0
|
||||||
|
#define UART1_CONF_UART 0
|
||||||
|
|
||||||
|
A single UART is available on CC2538DK, so all the configuration values above should be the same (i.e. either all 0 or all 1), but 0 and 1 could be mixed for other CC2538-based platforms supporting 2 UARTs.
|
||||||
|
|
||||||
|
The chosen UARTs must have their ports and pins defined in board.h:
|
||||||
|
|
||||||
|
#define UART0_RX_PORT GPIO_A_NUM
|
||||||
|
#define UART0_RX_PIN 0
|
||||||
|
#define UART0_TX_PORT GPIO_A_NUM
|
||||||
|
#define UART0_TX_PIN 1
|
||||||
|
|
||||||
|
Only the UART ports and pins implemented on the board can be defined.
|
||||||
|
|
||||||
UART Baud Rate
|
UART Baud Rate
|
||||||
--------------
|
--------------
|
||||||
By default, the CC2538 UART is configured with a baud rate of 115200. It is easy to increase this to 230400 by changing the value of `UART_CONF_BAUD_RATE` in `contiki-conf.h` or `project-conf.h`.
|
By default, the CC2538 UART is configured with a baud rate of 115200. It is easy to increase this to 230400 by changing the value of `UART0_CONF_BAUD_RATE` or `UART1_CONF_BAUD_RATE` in `contiki-conf.h` or `project-conf.h`, according to the UART instance used.
|
||||||
|
|
||||||
#define UART_CONF_BAUD_RATE 230400
|
#define UART0_CONF_BAUD_RATE 230400
|
||||||
|
#define UART1_CONF_BAUD_RATE 230400
|
||||||
Currently, this configuration directive only supports values 115200, 230400 and 460800. Custom baud rates can also be achieved by following the steps below:
|
|
||||||
|
|
||||||
* Configure `UART_CONF_BAUD_RATE` with an unsupported value to prevent it from auto-choosing values for IBRD and FBRD. For instance, in your project-conf.h you can do:
|
|
||||||
|
|
||||||
#define UART_CONF_BAUD_RATE 0
|
|
||||||
|
|
||||||
* Provide custom values for `UART_CONF_IBRD` and `UART_CONF_FBRD` according to the guidelines in the CC2538 User Guide.
|
|
||||||
|
|
||||||
RF and USB DMA
|
RF and USB DMA
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -40,6 +40,16 @@ typedef uint32_t rtimer_clock_t;
|
||||||
#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0)
|
#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0)
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \name Serial Boot Loader Backdoor configuration
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
||||||
|
#define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /**<Enable the boot loader backdoor */
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \name USB 'core' configuration
|
* \name USB 'core' configuration
|
||||||
*
|
*
|
||||||
|
@ -94,20 +104,53 @@ typedef uint32_t rtimer_clock_t;
|
||||||
#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */
|
#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UART_CONF_BAUD_RATE
|
#ifndef UART0_CONF_BAUD_RATE
|
||||||
#define UART_CONF_BAUD_RATE 115200 /**< Default baud rate */
|
#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART1_CONF_BAUD_RATE
|
||||||
|
#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SLIP_ARCH_CONF_USB
|
#ifndef SLIP_ARCH_CONF_USB
|
||||||
#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */
|
#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CC2538_RF_CONF_SNIFFER_USB
|
#ifndef CC2538_RF_CONF_SNIFFER_USB
|
||||||
#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */
|
#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DBG_CONF_USB
|
#ifndef DBG_CONF_USB
|
||||||
#define DBG_CONF_USB 0 /**< All debugging over UART by default */
|
#define DBG_CONF_USB 0 /**< All debugging over UART by default */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERIAL_LINE_CONF_UART
|
||||||
|
#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !SLIP_ARCH_CONF_USB
|
||||||
|
#ifndef SLIP_ARCH_CONF_UART
|
||||||
|
#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !CC2538_RF_CONF_SNIFFER_USB
|
||||||
|
#ifndef CC2538_RF_CONF_SNIFFER_UART
|
||||||
|
#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !DBG_CONF_USB
|
||||||
|
#ifndef DBG_CONF_UART
|
||||||
|
#define DBG_CONF_UART 0 /**< UART to use for debugging */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UART1_CONF_UART
|
||||||
|
#define UART1_CONF_UART 0 /**< UART to use for examples relying on
|
||||||
|
the uart1_* API */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Turn off example-provided putchars */
|
/* Turn off example-provided putchars */
|
||||||
#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1
|
#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1
|
||||||
#define SLIP_RADIO_CONF_NO_PUTCHAR 1
|
#define SLIP_RADIO_CONF_NO_PUTCHAR 1
|
||||||
|
@ -175,8 +218,32 @@ typedef uint32_t rtimer_clock_t;
|
||||||
* this
|
* this
|
||||||
*/
|
*/
|
||||||
#if SLIP_ARCH_CONF_ENABLED
|
#if SLIP_ARCH_CONF_ENABLED
|
||||||
#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB==DBG_CONF_USB)
|
#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \
|
||||||
|
(SLIP_ARCH_CONF_USB || \
|
||||||
|
SLIP_ARCH_CONF_UART == DBG_CONF_UART))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Automatic detection of whether a specific UART is in use
|
||||||
|
*/
|
||||||
|
#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u))
|
||||||
|
#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \
|
||||||
|
!SLIP_ARCH_CONF_USB && \
|
||||||
|
SLIP_ARCH_CONF_UART == (u))
|
||||||
|
#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \
|
||||||
|
!CC2538_RF_CONF_SNIFFER_USB && \
|
||||||
|
CC2538_RF_CONF_SNIFFER_UART == (u))
|
||||||
|
#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u))
|
||||||
|
#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u))
|
||||||
|
|
||||||
|
#define UART_IN_USE(u) ( \
|
||||||
|
UART_CONF_ENABLE && \
|
||||||
|
(UART_IN_USE_BY_SERIAL_LINE(u) || \
|
||||||
|
UART_IN_USE_BY_SLIP(u) || \
|
||||||
|
UART_IN_USE_BY_RF_SNIFFER(u) || \
|
||||||
|
UART_IN_USE_BY_DBG(u) || \
|
||||||
|
UART_IN_USE_BY_UART1(u)) \
|
||||||
|
)
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* board.h assumes that basic configuration is done */
|
/* board.h assumes that basic configuration is done */
|
||||||
|
@ -268,6 +335,16 @@ typedef uint32_t rtimer_clock_t;
|
||||||
#ifndef IEEE_ADDR_CONF_ADDRESS
|
#ifndef IEEE_ADDR_CONF_ADDRESS
|
||||||
#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF }
|
#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Location of the IEEE address in the InfoPage when
|
||||||
|
* IEEE_ADDR_CONF_HARDCODED is defined as 0
|
||||||
|
* 0 => Use the primary address location
|
||||||
|
* 1 => Use the secondary address location
|
||||||
|
*/
|
||||||
|
#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION
|
||||||
|
#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -153,8 +153,9 @@ main(void)
|
||||||
* slip_input_byte instead
|
* slip_input_byte instead
|
||||||
*/
|
*/
|
||||||
#if UART_CONF_ENABLE
|
#if UART_CONF_ENABLE
|
||||||
uart_init();
|
uart_init(0);
|
||||||
uart_set_input(serial_line_input_byte);
|
uart_init(1);
|
||||||
|
uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USB_SERIAL_CONF_ENABLE
|
#if USB_SERIAL_CONF_ENABLE
|
||||||
|
|
111
platform/cc2538dk/dev/adc-sensor.c
Normal file
111
platform/cc2538dk/dev/adc-sensor.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||||
|
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc2538dk-adc-sensor
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Driver for the SmartRF06EB ADC
|
||||||
|
*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "sys/clock.h"
|
||||||
|
#include "dev/ioc.h"
|
||||||
|
#include "dev/gpio.h"
|
||||||
|
#include "dev/adc.h"
|
||||||
|
#include "dev/adc-sensor.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ADC_ALS_PWR_PORT_BASE GPIO_PORT_TO_BASE(ADC_ALS_PWR_PORT)
|
||||||
|
#define ADC_ALS_PWR_PIN_MASK GPIO_PIN_MASK(ADC_ALS_PWR_PIN)
|
||||||
|
#define ADC_ALS_OUT_PIN_MASK GPIO_PIN_MASK(ADC_ALS_OUT_PIN)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
value(int type)
|
||||||
|
{
|
||||||
|
uint8_t channel;
|
||||||
|
int16_t res;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case ADC_SENSOR_VDD_3:
|
||||||
|
channel = SOC_ADC_ADCCON_CH_VDD_3;
|
||||||
|
break;
|
||||||
|
case ADC_SENSOR_TEMP:
|
||||||
|
channel = SOC_ADC_ADCCON_CH_TEMP;
|
||||||
|
break;
|
||||||
|
case ADC_SENSOR_ALS:
|
||||||
|
channel = SOC_ADC_ADCCON_CH_AIN0 + ADC_ALS_OUT_PIN;
|
||||||
|
GPIO_SET_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK);
|
||||||
|
clock_delay_usec(2000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = adc_get(channel, SOC_ADC_ADCCON_REF_INT, SOC_ADC_ADCCON_DIV_512);
|
||||||
|
|
||||||
|
if(type == ADC_SENSOR_ALS) {
|
||||||
|
GPIO_CLR_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
configure(int type, int value)
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case SENSORS_HW_INIT:
|
||||||
|
GPIO_SOFTWARE_CONTROL(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK);
|
||||||
|
GPIO_SET_OUTPUT(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK);
|
||||||
|
GPIO_CLR_PIN(ADC_ALS_PWR_PORT_BASE, ADC_ALS_PWR_PIN_MASK);
|
||||||
|
ioc_set_over(ADC_ALS_PWR_PORT, ADC_ALS_PWR_PIN, IOC_OVERRIDE_DIS);
|
||||||
|
|
||||||
|
GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, ADC_ALS_OUT_PIN_MASK);
|
||||||
|
GPIO_SET_INPUT(GPIO_A_BASE, ADC_ALS_OUT_PIN_MASK);
|
||||||
|
ioc_set_over(GPIO_A_NUM, ADC_ALS_OUT_PIN, IOC_OVERRIDE_ANA);
|
||||||
|
|
||||||
|
adc_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
status(int type)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, configure, status);
|
||||||
|
|
||||||
|
/** @} */
|
67
platform/cc2538dk/dev/adc-sensor.h
Normal file
67
platform/cc2538dk/dev/adc-sensor.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, ADVANSEE - http://www.advansee.com/
|
||||||
|
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc2538-smartrf-sensors
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \defgroup cc2538dk-adc-sensor cc2538dk ADC Driver
|
||||||
|
*
|
||||||
|
* Driver for the SmartRF06EB ADC sensors
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Header file for the cc2538dk ADC Driver
|
||||||
|
*/
|
||||||
|
#ifndef ADC_SENSOR_H_
|
||||||
|
#define ADC_SENSOR_H_
|
||||||
|
|
||||||
|
#include "lib/sensors.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** \name ADC sensors
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_SENSOR "ADC"
|
||||||
|
|
||||||
|
#define ADC_SENSOR_VDD_3 0 /**< On-chip VDD / 3 */
|
||||||
|
#define ADC_SENSOR_TEMP 1 /**< On-chip temperature */
|
||||||
|
#define ADC_SENSOR_ALS 2 /**< Ambient light sensor */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
extern const struct sensors_sensor adc_sensor;
|
||||||
|
|
||||||
|
#endif /* ADC_SENSOR_H_ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
|
@ -110,22 +110,21 @@
|
||||||
* - CTS: PB0 (Can only be used with UART1)
|
* - CTS: PB0 (Can only be used with UART1)
|
||||||
* - RTS: PD3 (Can only be used with UART1)
|
* - RTS: PD3 (Can only be used with UART1)
|
||||||
*
|
*
|
||||||
* We configure the port to use UART0. To use UART1, change UART_CONF_BASE
|
* We configure the port to use UART0. To use UART1, replace UART0_* with
|
||||||
|
* UART1_* below.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define UART_CONF_BASE UART_0_BASE
|
#define UART0_RX_PORT GPIO_A_NUM
|
||||||
|
#define UART0_RX_PIN 0
|
||||||
|
|
||||||
#define UART_RX_PORT GPIO_A_NUM
|
#define UART0_TX_PORT GPIO_A_NUM
|
||||||
#define UART_RX_PIN 0
|
#define UART0_TX_PIN 1
|
||||||
|
|
||||||
#define UART_TX_PORT GPIO_A_NUM
|
#define UART1_CTS_PORT GPIO_B_NUM
|
||||||
#define UART_TX_PIN 1
|
#define UART1_CTS_PIN 0
|
||||||
|
|
||||||
#define UART_CTS_PORT GPIO_B_NUM
|
#define UART1_RTS_PORT GPIO_D_NUM
|
||||||
#define UART_CTS_PIN 0
|
#define UART1_RTS_PIN 3
|
||||||
|
|
||||||
#define UART_RTS_PORT GPIO_D_NUM
|
|
||||||
#define UART_RTS_PIN 3
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name SmartRF Button configuration
|
/** \name SmartRF Button configuration
|
||||||
|
@ -167,6 +166,20 @@
|
||||||
#define PLATFORM_HAS_BUTTON 1
|
#define PLATFORM_HAS_BUTTON 1
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \name ADC configuration
|
||||||
|
*
|
||||||
|
* These values configure which CC2538 pins and ADC channels to use for the ADC
|
||||||
|
* inputs.
|
||||||
|
*
|
||||||
|
* ADC inputs can only be on port A.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define ADC_ALS_PWR_PORT GPIO_A_NUM /**< ALS power GPIO control port */
|
||||||
|
#define ADC_ALS_PWR_PIN 7 /**< ALS power GPIO control pin */
|
||||||
|
#define ADC_ALS_OUT_PIN 6 /**< ALS output ADC input pin on port A */
|
||||||
|
/** @} */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \name SPI configuration
|
* \name SPI configuration
|
||||||
*
|
*
|
||||||
|
@ -179,8 +192,6 @@
|
||||||
#define SPI_MOSI_PIN 4
|
#define SPI_MOSI_PIN 4
|
||||||
#define SPI_MISO_PORT GPIO_A_NUM
|
#define SPI_MISO_PORT GPIO_A_NUM
|
||||||
#define SPI_MISO_PIN 5
|
#define SPI_MISO_PIN 5
|
||||||
#define SPI_SEL_PORT GPIO_B_NUM
|
|
||||||
#define SPI_SEL_PIN 5
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,12 +42,13 @@
|
||||||
*/
|
*/
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "dev/button-sensor.h"
|
#include "dev/button-sensor.h"
|
||||||
|
#include "dev/adc-sensor.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/** \brief Exports a global symbol to be used by the sensor API */
|
/** \brief Exports a global symbol to be used by the sensor API */
|
||||||
SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor,
|
SENSORS(&button_select_sensor, &button_left_sensor, &button_right_sensor,
|
||||||
&button_up_sensor, &button_down_sensor);
|
&button_up_sensor, &button_down_sensor, &adc_sensor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|
|
@ -63,6 +63,15 @@ void cc2538_rf_err_isr(void);
|
||||||
void udma_isr(void);
|
void udma_isr(void);
|
||||||
void udma_err_isr(void);
|
void udma_err_isr(void);
|
||||||
|
|
||||||
|
/* Boot Loader Backdoor selection */
|
||||||
|
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
||||||
|
/* Backdoor enabled, on PA_3 (Select button) */
|
||||||
|
#define FLASH_CCA_BOOTLDR_CFG (FLASH_CCA_BOOTLDR_CFG_ENABLE \
|
||||||
|
| ((3 << FLASH_CCA_BOOTLDR_CFG_PORT_A_PIN_S) & FLASH_CCA_BOOTLDR_CFG_PORT_A_PIN_M))
|
||||||
|
#else
|
||||||
|
#define FLASH_CCA_BOOTLDR_CFG FLASH_CCA_BOOTLDR_CFG_DISABLE
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Link in the USB ISR only if USB is enabled */
|
/* Link in the USB ISR only if USB is enabled */
|
||||||
#if USB_SERIAL_CONF_ENABLE
|
#if USB_SERIAL_CONF_ENABLE
|
||||||
void usb_isr(void);
|
void usb_isr(void);
|
||||||
|
@ -72,16 +81,8 @@ void usb_isr(void);
|
||||||
|
|
||||||
/* Likewise for the UART[01] ISRs */
|
/* Likewise for the UART[01] ISRs */
|
||||||
#if UART_CONF_ENABLE
|
#if UART_CONF_ENABLE
|
||||||
void uart_isr(void);
|
void uart0_isr(void);
|
||||||
|
void uart1_isr(void);
|
||||||
#if UART_BASE==UART_1_BASE
|
|
||||||
#define uart0_isr default_handler
|
|
||||||
#define uart1_isr uart_isr
|
|
||||||
#else
|
|
||||||
#define uart0_isr uart_isr
|
|
||||||
#define uart1_isr default_handler
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* UART_CONF_ENABLE */
|
#else /* UART_CONF_ENABLE */
|
||||||
#define uart0_isr default_handler
|
#define uart0_isr default_handler
|
||||||
#define uart1_isr default_handler
|
#define uart1_isr default_handler
|
||||||
|
@ -95,7 +96,7 @@ extern uint8_t _text[0];
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
__attribute__ ((section(".flashcca"), used))
|
__attribute__ ((section(".flashcca"), used))
|
||||||
const flash_cca_lock_page_t __cca = {
|
const flash_cca_lock_page_t __cca = {
|
||||||
FLASH_CCA_BOOTLDR_CFG_DISABLE, /* Bootloader backdoor disabled */
|
FLASH_CCA_BOOTLDR_CFG, /* Boot loader backdoor configuration */
|
||||||
FLASH_CCA_IMAGE_VALID, /* Image valid */
|
FLASH_CCA_IMAGE_VALID, /* Image valid */
|
||||||
&_text, /* Vector table located at the start of .text */
|
&_text, /* Vector table located at the start of .text */
|
||||||
/* Unlock all pages and debug */
|
/* Unlock all pages and debug */
|
||||||
|
|
|
@ -46,4 +46,5 @@ CURSES_LIBS ?= -lncurses
|
||||||
|
|
||||||
TARGET_LIBFILES += $(CURSES_LIBS)
|
TARGET_LIBFILES += $(CURSES_LIBS)
|
||||||
|
|
||||||
MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 core/net/rime core/net/mac
|
MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 core/net/rime \
|
||||||
|
core/net/mac core/net/rpl core/ctk
|
||||||
|
|
|
@ -27,6 +27,7 @@ sky-ip/sky \
|
||||||
sky-shell/sky \
|
sky-shell/sky \
|
||||||
sky-shell-exec/sky \
|
sky-shell-exec/sky \
|
||||||
sky-shell-webserver/sky \
|
sky-shell-webserver/sky \
|
||||||
|
tcp-socket/minimal-net \
|
||||||
telnet-server/minimal-net \
|
telnet-server/minimal-net \
|
||||||
webserver/minimal-net \
|
webserver/minimal-net \
|
||||||
webserver-ipv6/exp5438 \
|
webserver-ipv6/exp5438 \
|
||||||
|
@ -34,6 +35,7 @@ webserver-ipv6/eval-adf7xxxmb4z \
|
||||||
wget/minimal-net \
|
wget/minimal-net \
|
||||||
z1/z1 \
|
z1/z1 \
|
||||||
settings-example/avr-raven \
|
settings-example/avr-raven \
|
||||||
|
ipv6/multicast/sky \
|
||||||
|
|
||||||
TOOLS=
|
TOOLS=
|
||||||
|
|
||||||
|
|
367
regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc
Normal file
367
regression-tests/11-ipv6/17-cooja-multicast-11-hops.csc
Normal file
|
@ -0,0 +1,367 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||||
|
<simulation>
|
||||||
|
<title>Multicast regression test</title>
|
||||||
|
<randomseed>123456</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
org.contikios.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>15.0</transmitting_range>
|
||||||
|
<interference_range>0.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype612</identifier>
|
||||||
|
<description>Root/sender</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/root.c</source>
|
||||||
|
<commands>make root.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype890</identifier>
|
||||||
|
<description>Intermediate</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c</source>
|
||||||
|
<commands>make intermediate.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype956</identifier>
|
||||||
|
<description>Receiver</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/sink.c</source>
|
||||||
|
<commands>make sink.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-7.983976888750106</x>
|
||||||
|
<y>0.37523218201044733</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype612</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>0.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>2</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>10.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>3</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>20.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>4</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>30.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>5</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>40.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>6</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>50.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>7</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>60.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>8</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>70.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>9</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>79.93950307524713</x>
|
||||||
|
<y>-0.043451055913349</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>10</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>90.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>11</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype890</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>99.61761525766555</x>
|
||||||
|
<y>0.37523218201044733</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>12</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype956</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>400</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Visualizer
|
||||||
|
<plugin_config>
|
||||||
|
<moterelations>true</moterelations>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||||
|
<viewport>2.388440494916608 0.0 0.0 2.388440494916608 109.06925371156906 149.10378026149033</viewport>
|
||||||
|
</plugin_config>
|
||||||
|
<width>400</width>
|
||||||
|
<z>3</z>
|
||||||
|
<height>400</height>
|
||||||
|
<location_x>1</location_x>
|
||||||
|
<location_y>1</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
<formatted_time />
|
||||||
|
<coloring />
|
||||||
|
</plugin_config>
|
||||||
|
<width>1200</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>240</height>
|
||||||
|
<location_x>400</location_x>
|
||||||
|
<location_y>160</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Notes
|
||||||
|
<plugin_config>
|
||||||
|
<notes>Enter notes here</notes>
|
||||||
|
<decorations>true</decorations>
|
||||||
|
</plugin_config>
|
||||||
|
<width>920</width>
|
||||||
|
<z>4</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>680</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<script>TIMEOUT(300000);
|
||||||
|

|
||||||
|
WAIT_UNTIL(msg.startsWith("In: "));
|
||||||
|

|
||||||
|
log.testOK(); /* Report test success and quit */</script>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>600</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>700</height>
|
||||||
|
<location_x>843</location_x>
|
||||||
|
<location_y>77</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
707
regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc
Normal file
707
regression-tests/11-ipv6/18-cooja-multicast-31-hops.csc
Normal file
|
@ -0,0 +1,707 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||||
|
<simulation>
|
||||||
|
<title>Multicast regression test</title>
|
||||||
|
<randomseed>123456</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
org.contikios.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>15.0</transmitting_range>
|
||||||
|
<interference_range>0.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype816</identifier>
|
||||||
|
<description>Root/sender</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/root.c</source>
|
||||||
|
<commands>make root.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype53</identifier>
|
||||||
|
<description>Intermediate</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/intermediate.c</source>
|
||||||
|
<commands>make intermediate.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype191</identifier>
|
||||||
|
<description>Receiver</description>
|
||||||
|
<source>[CONTIKI_DIR]/examples/ipv6/multicast/sink.c</source>
|
||||||
|
<commands>make sink.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-7.983976888750106</x>
|
||||||
|
<y>0.37523218201044733</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype816</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>0.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>2</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>10.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>3</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>20.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>4</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>30.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>5</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>40.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>6</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>50.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>7</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>60.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>8</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>70.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>9</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>79.93950307524713</x>
|
||||||
|
<y>-0.043451055913349</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>10</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>90.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>11</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>299.830399237567</x>
|
||||||
|
<y>0.21169609213234786</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>12</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype191</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>100.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>13</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>110.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>14</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>120.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>15</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>130.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>16</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>140.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>17</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>150.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>18</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>160.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>19</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>170.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>20</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>180.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>21</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>190.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>22</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>200.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>23</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>210.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>24</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>220.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>25</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>230.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>26</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>240.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>27</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>250.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>28</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>260.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>29</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>270.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>30</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>280.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>31</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>290.0</x>
|
||||||
|
<y>0.0</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>32</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype53</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>400</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Visualizer
|
||||||
|
<plugin_config>
|
||||||
|
<moterelations>true</moterelations>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
|
||||||
|
<viewport>1.1837122130192945 0.0 0.0 1.1837122130192945 27.087094588040927 150.74941275029448</viewport>
|
||||||
|
</plugin_config>
|
||||||
|
<width>400</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>400</height>
|
||||||
|
<location_x>1</location_x>
|
||||||
|
<location_y>1</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.LogListener
|
||||||
|
<plugin_config>
|
||||||
|
<filter />
|
||||||
|
<formatted_time />
|
||||||
|
<coloring />
|
||||||
|
</plugin_config>
|
||||||
|
<width>1200</width>
|
||||||
|
<z>3</z>
|
||||||
|
<height>240</height>
|
||||||
|
<location_x>400</location_x>
|
||||||
|
<location_y>160</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Notes
|
||||||
|
<plugin_config>
|
||||||
|
<notes>Enter notes here</notes>
|
||||||
|
<decorations>true</decorations>
|
||||||
|
</plugin_config>
|
||||||
|
<width>920</width>
|
||||||
|
<z>4</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>680</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<script>TIMEOUT(300000);
|
||||||
|

|
||||||
|
WAIT_UNTIL(msg.startsWith("In: "));
|
||||||
|

|
||||||
|
log.testOK(); /* Report test success and quit */</script>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>600</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>700</height>
|
||||||
|
<location_x>843</location_x>
|
||||||
|
<location_y>77</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
|
@ -7,6 +7,7 @@ cc2530dk/cc2530dk \
|
||||||
cc2530dk/border-router/cc2530dk \
|
cc2530dk/border-router/cc2530dk \
|
||||||
cc2530dk/udp-ipv6/cc2530dk \
|
cc2530dk/udp-ipv6/cc2530dk \
|
||||||
cc2530dk/sniffer/cc2530dk \
|
cc2530dk/sniffer/cc2530dk \
|
||||||
|
ipv6/multicast/cc2530dk \
|
||||||
|
|
||||||
TOOLS=
|
TOOLS=
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ webserver-ipv6/cc2538dk \
|
||||||
cc2538dk/cc2538dk \
|
cc2538dk/cc2538dk \
|
||||||
cc2538dk/udp-ipv6-echo-server/cc2538dk \
|
cc2538dk/udp-ipv6-echo-server/cc2538dk \
|
||||||
cc2538dk/sniffer/cc2538dk \
|
cc2538dk/sniffer/cc2538dk \
|
||||||
|
ipv6/multicast/econotag \
|
||||||
|
ipv6/multicast/cc2538dk \
|
||||||
|
|
||||||
TOOLS=
|
TOOLS=
|
||||||
|
|
||||||
|
|
1
tools/cc2538-bsl
Submodule
1
tools/cc2538-bsl
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1223bfe03cdb31c439f1a51593808cdabc1939d2
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
f=`basename $1`
|
|
||||||
mkdir /tmp/$$
|
|
||||||
cp $1 /tmp/$$/
|
|
||||||
cp $1 /tmp/$$/$f.orig
|
|
||||||
export INDENT_PROFILE=`dirname $0`/indent.pro
|
|
||||||
indent /tmp/$$/$f
|
|
||||||
diff /tmp/$$/$f.orig /tmp/$$/$f
|
|
||||||
rm -rf /tmp/$$
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
export INDENT_PROFILE=`dirname $0`/indent.pro
|
|
||||||
indent $*
|
|
|
@ -1,22 +0,0 @@
|
||||||
-bad
|
|
||||||
-br
|
|
||||||
-brs
|
|
||||||
-cdw
|
|
||||||
-ce
|
|
||||||
-hnl
|
|
||||||
-i2
|
|
||||||
-lp
|
|
||||||
-nbap
|
|
||||||
-nbbb
|
|
||||||
-ncdb
|
|
||||||
-ncs
|
|
||||||
-nfca
|
|
||||||
-nlps
|
|
||||||
-npcs
|
|
||||||
-nprs
|
|
||||||
-nsaf
|
|
||||||
-nsai
|
|
||||||
-nsaw
|
|
||||||
-nsc
|
|
||||||
-nut
|
|
||||||
-psl
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# This file checks your git index and runs indent on every changed *.c and *.h
|
# This file checks your git index and runs uncrustify on every changed *.c and *.h
|
||||||
# file.
|
# file.
|
||||||
#
|
#
|
||||||
# Author: Valentin Sawadski <valentin@sawadski.eu>
|
# Author: Valentin Sawadski <valentin@sawadski.eu>
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.contikios.mrm;
|
package org.contikios.mrm;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@ -50,11 +50,13 @@ import org.contikios.mrm.ChannelModel.TxPair;
|
||||||
@ClassDescription("Radio environment (MRM)")
|
@ClassDescription("Radio environment (MRM)")
|
||||||
@SupportedArguments(radioMediums = {MRM.class})
|
@SupportedArguments(radioMediums = {MRM.class})
|
||||||
public class MRMVisualizerSkin implements VisualizerSkin {
|
public class MRMVisualizerSkin implements VisualizerSkin {
|
||||||
private static Logger logger = Logger.getLogger(MRMVisualizerSkin.class);
|
|
||||||
|
private static final Logger logger = Logger.getLogger(MRMVisualizerSkin.class);
|
||||||
|
|
||||||
private Simulation simulation = null;
|
private Simulation simulation = null;
|
||||||
private Visualizer visualizer = null;
|
private Visualizer visualizer = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setActive(Simulation simulation, Visualizer vis) {
|
public void setActive(Simulation simulation, Visualizer vis) {
|
||||||
if (!(simulation.getRadioMedium() instanceof MRM)) {
|
if (!(simulation.getRadioMedium() instanceof MRM)) {
|
||||||
logger.fatal("Cannot activate MRM skin for unknown radio medium: " + simulation.getRadioMedium());
|
logger.fatal("Cannot activate MRM skin for unknown radio medium: " + simulation.getRadioMedium());
|
||||||
|
@ -64,6 +66,7 @@ public class MRMVisualizerSkin implements VisualizerSkin {
|
||||||
this.visualizer = vis;
|
this.visualizer = vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setInactive() {
|
public void setInactive() {
|
||||||
if (simulation == null) {
|
if (simulation == null) {
|
||||||
/* Skin was never activated */
|
/* Skin was never activated */
|
||||||
|
@ -71,88 +74,98 @@ public class MRMVisualizerSkin implements VisualizerSkin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Color[] getColorOf(Mote mote) {
|
public Color[] getColorOf(Mote mote) {
|
||||||
Mote selectedMote = visualizer.getSelectedMote();
|
if (visualizer.getSelectedMotes().contains(mote)) {
|
||||||
if (mote == selectedMote) {
|
return new Color[]{Color.CYAN};
|
||||||
return new Color[] { Color.CYAN };
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void paintBeforeMotes(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
final Mote selectedMote = visualizer.getSelectedMote();
|
Set<Mote> selectedMotes = visualizer.getSelectedMotes();
|
||||||
if (simulation == null
|
if (simulation == null || selectedMotes == null) {
|
||||||
|| selectedMote == null
|
|
||||||
|| selectedMote.getInterfaces().getRadio() == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Position sPos = selectedMote.getInterfaces().getPosition();
|
|
||||||
|
|
||||||
/* Paint transmission and interference range for selected mote */
|
for (final Mote selectedMote : selectedMotes) {
|
||||||
Position motePos = selectedMote.getInterfaces().getPosition();
|
if (selectedMote.getInterfaces().getRadio() == null) {
|
||||||
|
|
||||||
Point pixelCoord = visualizer.transformPositionToPixel(motePos);
|
|
||||||
int x = pixelCoord.x;
|
|
||||||
int y = pixelCoord.y;
|
|
||||||
|
|
||||||
FontMetrics fm = g.getFontMetrics();
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
|
|
||||||
MRM radioMedium = (MRM) simulation.getRadioMedium();
|
|
||||||
|
|
||||||
/* Print transmission success probabilities */
|
|
||||||
Mote[] dests = simulation.getMotes();
|
|
||||||
if (dests == null || dests.length == 0) {
|
|
||||||
String msg = "No edges";
|
|
||||||
int msgWidth = fm.stringWidth(msg);
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
g.drawString(msg, x - msgWidth/2, y + 2*Visualizer.MOTE_RADIUS + 3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g.setColor(Color.BLACK);
|
|
||||||
int edges = 0;
|
|
||||||
for (Mote d: dests) {
|
|
||||||
if (d == selectedMote) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final Radio dRadio = d.getInterfaces().getRadio();
|
final Position sPos = selectedMote.getInterfaces().getPosition();
|
||||||
TxPair txPair = new RadioPair() {
|
|
||||||
public Radio getFromRadio() {
|
|
||||||
return selectedMote.getInterfaces().getRadio();
|
|
||||||
}
|
|
||||||
public Radio getToRadio() {
|
|
||||||
return dRadio;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
double probArr[] = radioMedium.getChannelModel().getProbability(
|
|
||||||
txPair,
|
|
||||||
Double.NEGATIVE_INFINITY
|
|
||||||
);
|
|
||||||
double prob = probArr[0];
|
|
||||||
double ss = probArr[1];
|
|
||||||
|
|
||||||
if (prob == 0.0d) {
|
/* Paint transmission and interference range for selected mote */
|
||||||
continue;
|
Position motePos = selectedMote.getInterfaces().getPosition();
|
||||||
}
|
|
||||||
edges++;
|
Point pixelCoord = visualizer.transformPositionToPixel(motePos);
|
||||||
String msg = String.format("%1.1f%%, %1.2fdB", 100.0*prob, ss);
|
int x = pixelCoord.x;
|
||||||
Point pixel = visualizer.transformPositionToPixel(d.getInterfaces().getPosition());
|
int y = pixelCoord.y;
|
||||||
int msgWidth = fm.stringWidth(msg);
|
|
||||||
g.setColor(new Color(1-(float)prob, (float)prob, 0.0f));
|
FontMetrics fm = g.getFontMetrics();
|
||||||
g.drawLine(x, y, pixel.x, pixel.y);
|
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
g.drawString(msg, pixel.x - msgWidth/2, pixel.y + 2*Visualizer.MOTE_RADIUS + 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
String msg = dests.length + " edges";
|
MRM radioMedium = (MRM) simulation.getRadioMedium();
|
||||||
int msgWidth = fm.stringWidth(msg);
|
|
||||||
g.setColor(Color.BLACK);
|
/* Print transmission success probabilities */
|
||||||
g.drawString(msg, x - msgWidth/2, y + 2*Visualizer.MOTE_RADIUS + 3);
|
Mote[] dests = simulation.getMotes();
|
||||||
|
if (dests == null || dests.length == 0) {
|
||||||
|
String msg = "No edges";
|
||||||
|
int msgWidth = fm.stringWidth(msg);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawString(msg, x - msgWidth / 2, y + 2 * Visualizer.MOTE_RADIUS + 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
int edges = 0;
|
||||||
|
for (Mote d : dests) {
|
||||||
|
if (d == selectedMote) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final Radio dRadio = d.getInterfaces().getRadio();
|
||||||
|
TxPair txPair = new RadioPair() {
|
||||||
|
@Override
|
||||||
|
public Radio getFromRadio() {
|
||||||
|
return selectedMote.getInterfaces().getRadio();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Radio getToRadio() {
|
||||||
|
return dRadio;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
double probArr[] = radioMedium.getChannelModel().getProbability(
|
||||||
|
txPair,
|
||||||
|
Double.NEGATIVE_INFINITY
|
||||||
|
);
|
||||||
|
double prob = probArr[0];
|
||||||
|
double ss = probArr[1];
|
||||||
|
|
||||||
|
if (prob == 0.0d) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
edges++;
|
||||||
|
String msg = String.format("%1.1f%%, %1.2fdB", 100.0 * prob, ss);
|
||||||
|
Point pixel = visualizer.transformPositionToPixel(d.getInterfaces().getPosition());
|
||||||
|
int msgWidth = fm.stringWidth(msg);
|
||||||
|
g.setColor(new Color(1 - (float) prob, (float) prob, 0.0f));
|
||||||
|
g.drawLine(x, y, pixel.x, pixel.y);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawString(msg, pixel.x - msgWidth / 2, pixel.y + 2 * Visualizer.MOTE_RADIUS + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
String msg = dests.length + " edges";
|
||||||
|
int msgWidth = fm.stringWidth(msg);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
g.drawString(msg, x - msgWidth / 2, y + 2 * Visualizer.MOTE_RADIUS + 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void paintAfterMotes(Graphics g) {
|
public void paintAfterMotes(Graphics g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Visualizer getVisualizer() {
|
public Visualizer getVisualizer() {
|
||||||
return visualizer;
|
return visualizer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
org.contikios.cooja.Cooja.MOTETYPES = + org.contikios.cooja.mspmote.ESBMoteType org.contikios.cooja.mspmote.SkyMoteType org.contikios.cooja.mspmote.Z1MoteType org.contikios.cooja.mspmote.WismoteMoteType org.contikios.cooja.mspmote.Exp5438MoteType org.contikios.cooja.mspmote.SkyMoteType org.contikios.cooja.mspmote.CC430MoteType org.contikios.cooja.mspmote.Exp1120MoteType org.contikios.cooja.mspmote.Exp1101MoteType org.contikios.cooja.mspmote.Exp2420MoteType org.contikios.cooja.mspmote.Trxeb2520MoteType org.contikios.cooja.mspmote.Trxeb1120MoteType org.contikios.cooja.mspmote.Eth1120MoteType
|
org.contikios.cooja.Cooja.MOTETYPES = + org.contikios.cooja.mspmote.ESBMoteType org.contikios.cooja.mspmote.SkyMoteType org.contikios.cooja.mspmote.Z1MoteType org.contikios.cooja.mspmote.WismoteMoteType org.contikios.cooja.mspmote.Exp5438MoteType org.contikios.cooja.mspmote.CC430MoteType org.contikios.cooja.mspmote.Exp1120MoteType org.contikios.cooja.mspmote.Exp1101MoteType org.contikios.cooja.mspmote.Exp2420MoteType org.contikios.cooja.mspmote.Trxeb2520MoteType org.contikios.cooja.mspmote.Trxeb1120MoteType org.contikios.cooja.mspmote.Eth1120MoteType
|
||||||
org.contikios.cooja.Cooja.JARFILES = + cooja_mspsim.jar mspsim.jar coffee.jar jipv6.jar
|
org.contikios.cooja.Cooja.JARFILES = + cooja_mspsim.jar mspsim.jar coffee.jar jipv6.jar
|
||||||
org.contikios.cooja.Cooja.PLUGINS = + org.contikios.cooja.mspmote.plugins.MspCLI org.contikios.cooja.mspmote.plugins.MspCodeWatcher org.contikios.cooja.mspmote.plugins.MspStackWatcher org.contikios.cooja.mspmote.plugins.MspCycleWatcher
|
org.contikios.cooja.Cooja.PLUGINS = + org.contikios.cooja.mspmote.plugins.MspCLI org.contikios.cooja.mspmote.plugins.MspCodeWatcher org.contikios.cooja.mspmote.plugins.MspStackWatcher org.contikios.cooja.mspmote.plugins.MspCycleWatcher
|
||||||
|
|
|
@ -1659,7 +1659,6 @@ public class Cooja extends Observable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nrFrames = myDesktopPane.getAllFrames().length;
|
|
||||||
myDesktopPane.add(pluginFrame);
|
myDesktopPane.add(pluginFrame);
|
||||||
|
|
||||||
/* Set size if not already specified by plugin */
|
/* Set size if not already specified by plugin */
|
||||||
|
@ -1667,11 +1666,9 @@ public class Cooja extends Observable {
|
||||||
pluginFrame.setSize(FRAME_STANDARD_WIDTH, FRAME_STANDARD_HEIGHT);
|
pluginFrame.setSize(FRAME_STANDARD_WIDTH, FRAME_STANDARD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set location if not already visible */
|
/* Set location if not already set */
|
||||||
if (pluginFrame.getLocation().x <= 0 && pluginFrame.getLocation().y <= 0) {
|
if (pluginFrame.getLocation().x <= 0 && pluginFrame.getLocation().y <= 0) {
|
||||||
pluginFrame.setLocation(
|
pluginFrame.setLocation(determineNewPluginLocation());
|
||||||
nrFrames * FRAME_NEW_OFFSET,
|
|
||||||
nrFrames * FRAME_NEW_OFFSET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginFrame.setVisible(true);
|
pluginFrame.setVisible(true);
|
||||||
|
@ -1690,6 +1687,29 @@ public class Cooja extends Observable {
|
||||||
}.invokeAndWait();
|
}.invokeAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines suitable location for placing new plugin.
|
||||||
|
* <p>
|
||||||
|
* If possible, this is below right of the second last activated
|
||||||
|
* internfal frame (offset is determined by FRAME_NEW_OFFSET).
|
||||||
|
*
|
||||||
|
* @return Resulting placement position
|
||||||
|
*/
|
||||||
|
private Point determineNewPluginLocation() {
|
||||||
|
Point topFrameLoc;
|
||||||
|
JInternalFrame[] iframes = myDesktopPane.getAllFrames();
|
||||||
|
if (iframes.length > 1) {
|
||||||
|
topFrameLoc = iframes[1].getLocation();
|
||||||
|
} else {
|
||||||
|
topFrameLoc = new Point(
|
||||||
|
myDesktopPane.getSize().width / 2,
|
||||||
|
myDesktopPane.getSize().height / 2);
|
||||||
|
}
|
||||||
|
return new Point(
|
||||||
|
topFrameLoc.x + FRAME_NEW_OFFSET,
|
||||||
|
topFrameLoc.y + FRAME_NEW_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all mote plugins for given mote.
|
* Close all mote plugins for given mote.
|
||||||
*
|
*
|
||||||
|
|
|
@ -757,6 +757,7 @@ public class Simulation extends Observable implements Runnable {
|
||||||
Runnable removeMote = new Runnable() {
|
Runnable removeMote = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
motes.remove(mote);
|
motes.remove(mote);
|
||||||
|
motesUninit.remove(mote);
|
||||||
currentRadioMedium.unregisterMote(mote, Simulation.this);
|
currentRadioMedium.unregisterMote(mote, Simulation.this);
|
||||||
|
|
||||||
/* Dispose mote interface resources */
|
/* Dispose mote interface resources */
|
||||||
|
|
|
@ -252,7 +252,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface, PolledA
|
||||||
|
|
||||||
/** Set LQI to a value between 0 and 255.
|
/** Set LQI to a value between 0 and 255.
|
||||||
*
|
*
|
||||||
* @see se.sics.cooja.interfaces.Radio#setLQI(int)
|
* @see org.contikios.cooja.interfaces.Radio#setLQI(int)
|
||||||
*/
|
*/
|
||||||
public void setLQI(int lqi){
|
public void setLQI(int lqi){
|
||||||
if(lqi<0) {
|
if(lqi<0) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue