Merge branch 'osd' of https://github.com/osdomotics/osd-contiki into osd
This commit is contained in:
commit
117f737f8d
11 changed files with 159 additions and 39 deletions
|
@ -74,6 +74,7 @@ typedef struct uip_ds6_nbr {
|
|||
uint8_t nscount;
|
||||
uint8_t isrouter;
|
||||
uint8_t state;
|
||||
uint16_t link_metric;
|
||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||
struct uip_packetqueue_handle packethandle;
|
||||
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
|
||||
|
|
|
@ -269,9 +269,16 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
|||
one first. */
|
||||
r = uip_ds6_route_lookup(ipaddr);
|
||||
if(r != NULL) {
|
||||
uip_ipaddr_t *current_nexthop;
|
||||
current_nexthop = uip_ds6_route_nexthop(r);
|
||||
if(uip_ipaddr_cmp(nexthop, current_nexthop)) {
|
||||
/* no need to update route - already correct! */
|
||||
return r;
|
||||
}
|
||||
PRINTF("uip_ds6_route_add: old route for ");
|
||||
PRINT6ADDR(ipaddr);
|
||||
PRINTF(" found, deleting it\n");
|
||||
|
||||
uip_ds6_route_rm(r);
|
||||
}
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
#include "net/ipv6/uip-ds6-nbr.h"
|
||||
#include "net/nbr-table.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||
#include "lib/list.h"
|
||||
|
@ -79,6 +80,19 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
|
|||
/* Allocate instance table. */
|
||||
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
||||
rpl_instance_t *default_instance;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
rpl_get_nbr(rpl_parent_t *parent)
|
||||
{
|
||||
linkaddr_t *lladdr = NULL;
|
||||
lladdr = nbr_table_get_lladdr(rpl_parents, parent);
|
||||
if(lladdr != NULL) {
|
||||
return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
nbr_callback(void *ptr)
|
||||
|
@ -113,9 +127,11 @@ rpl_get_parent_rank(uip_lladdr_t *addr)
|
|||
uint16_t
|
||||
rpl_get_parent_link_metric(const uip_lladdr_t *addr)
|
||||
{
|
||||
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (const linkaddr_t *)addr);
|
||||
if(p != NULL) {
|
||||
return p->link_metric;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr);
|
||||
|
||||
if(nbr != NULL) {
|
||||
return nbr->link_metric;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -568,10 +584,17 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
|||
if(p == NULL) {
|
||||
PRINTF("RPL: rpl_add_parent p NULL\n");
|
||||
} else {
|
||||
uip_ds6_nbr_t *nbr;
|
||||
nbr = rpl_get_nbr(p);
|
||||
|
||||
p->dag = dag;
|
||||
p->rank = dio->rank;
|
||||
p->dtsn = dio->dtsn;
|
||||
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||
|
||||
/* Check whether we have a neighbor that has not gotten a link metric yet */
|
||||
if(nbr != NULL && nbr->link_metric == 0) {
|
||||
nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||
}
|
||||
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||
|
@ -1037,6 +1060,14 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
|||
|
||||
remove_parents(dag, 0);
|
||||
dag->version = dio->version;
|
||||
|
||||
/* copy parts of the configuration so that it propagates in the network */
|
||||
dag->instance->dio_intdoubl = dio->dag_intdoubl;
|
||||
dag->instance->dio_intmin = dio->dag_intmin;
|
||||
dag->instance->dio_redundancy = dio->dag_redund;
|
||||
dag->instance->default_lifetime = dio->default_lifetime;
|
||||
dag->instance->lifetime_unit = dio->lifetime_unit;
|
||||
|
||||
dag->instance->of->reset(dag);
|
||||
dag->min_rank = INFINITE_RANK;
|
||||
RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out);
|
||||
|
|
|
@ -90,16 +90,22 @@ typedef uint16_t rpl_path_metric_t;
|
|||
static rpl_path_metric_t
|
||||
calculate_path_metric(rpl_parent_t *p)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr;
|
||||
if(p == NULL) {
|
||||
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||
}
|
||||
|
||||
nbr = rpl_get_nbr(p);
|
||||
if(nbr == NULL) {
|
||||
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||
}
|
||||
#if RPL_DAG_MC == RPL_DAG_MC_NONE
|
||||
return p->rank + (uint16_t)p->link_metric;
|
||||
{
|
||||
return p->rank + (uint16_t)nbr->link_metric;
|
||||
}
|
||||
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||
return p->mc.obj.etx + (uint16_t)p->link_metric;
|
||||
return p->mc.obj.etx + (uint16_t)nbr->link_metric;
|
||||
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
|
||||
return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric;
|
||||
return p->mc.obj.energy.energy_est + (uint16_t)nbr->link_metric;
|
||||
#else
|
||||
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
|
||||
#endif /* RPL_DAG_MC */
|
||||
|
@ -114,9 +120,18 @@ reset(rpl_dag_t *dag)
|
|||
static void
|
||||
neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
||||
{
|
||||
uint16_t recorded_etx = p->link_metric;
|
||||
uint16_t recorded_etx = 0;
|
||||
uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
|
||||
uint16_t new_etx;
|
||||
uip_ds6_nbr_t *nbr = NULL;
|
||||
|
||||
nbr = rpl_get_nbr(p);
|
||||
if(nbr == NULL) {
|
||||
/* No neighbor for this parent - something bad has occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
recorded_etx = nbr->link_metric;
|
||||
|
||||
/* Do not penalize the ETX when collisions or transmission errors occur. */
|
||||
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
|
||||
|
@ -139,7 +154,8 @@ neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
|||
(unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
|
||||
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
|
||||
(unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
|
||||
p->link_metric = new_etx;
|
||||
/* update the link metric for this nbr */
|
||||
nbr->link_metric = new_etx;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,14 +164,15 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
|||
{
|
||||
rpl_rank_t new_rank;
|
||||
rpl_rank_t rank_increase;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
|
||||
if(p == NULL) {
|
||||
if(p == NULL || (nbr = rpl_get_nbr(p)) == NULL) {
|
||||
if(base_rank == 0) {
|
||||
return INFINITE_RANK;
|
||||
}
|
||||
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||
} else {
|
||||
rank_increase = p->link_metric;
|
||||
rank_increase = nbr->link_metric;
|
||||
if(base_rank == 0) {
|
||||
base_rank = p->rank;
|
||||
}
|
||||
|
|
|
@ -126,26 +126,34 @@ static rpl_parent_t *
|
|||
best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||
{
|
||||
rpl_rank_t r1, r2;
|
||||
rpl_dag_t *dag;
|
||||
rpl_dag_t *dag;
|
||||
uip_ds6_nbr_t *nbr1, *nbr2;
|
||||
nbr1 = rpl_get_nbr(p1);
|
||||
nbr2 = rpl_get_nbr(p2);
|
||||
|
||||
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
|
||||
|
||||
if(nbr1 == NULL || nbr2 == NULL) {
|
||||
return dag->preferred_parent;
|
||||
}
|
||||
|
||||
PRINTF("RPL: Comparing parent ");
|
||||
PRINT6ADDR(rpl_get_parent_ipaddr(p1));
|
||||
PRINTF(" (confidence %d, rank %d) with parent ",
|
||||
p1->link_metric, p1->rank);
|
||||
nbr1->link_metric, p1->rank);
|
||||
PRINT6ADDR(rpl_get_parent_ipaddr(p2));
|
||||
PRINTF(" (confidence %d, rank %d)\n",
|
||||
p2->link_metric, p2->rank);
|
||||
nbr2->link_metric, p2->rank);
|
||||
|
||||
|
||||
r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||
p1->link_metric;
|
||||
nbr1->link_metric;
|
||||
r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||
p2->link_metric;
|
||||
nbr2->link_metric;
|
||||
/* Compare two parents by looking both and their rank and at the ETX
|
||||
for that parent. We choose the parent that has the most
|
||||
favourable combination. */
|
||||
|
||||
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
|
||||
if(r1 < r2 + MIN_DIFFERENCE &&
|
||||
r1 > r2 - MIN_DIFFERENCE) {
|
||||
return dag->preferred_parent;
|
||||
|
|
|
@ -114,7 +114,6 @@ struct rpl_parent {
|
|||
rpl_metric_container_t mc;
|
||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||
rpl_rank_t rank;
|
||||
uint16_t link_metric;
|
||||
uint8_t dtsn;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
@ -251,7 +250,7 @@ rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
|
|||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
||||
void rpl_dag_init(void);
|
||||
|
||||
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
|
||||
|
||||
/**
|
||||
* RPL modes
|
||||
|
|
28
examples/ipv6/native-border-router/README.md
Normal file
28
examples/ipv6/native-border-router/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
This code connects a 802.15.4 radio over TTY with the full uIPv6 stack of
|
||||
Contiki including 6LoWPAN and 802.15.4 framing / parsing. The native border
|
||||
router also acts as a RPL Root and handles the routing and maintains the RPL
|
||||
network. Finally the native border router connects the full 6LoWPAN/RPL
|
||||
network to the host (linux/os-x) network stack making it possible for
|
||||
applications on the host to transparently reach all the nodes in the
|
||||
6LoWPAN/RPL network.
|
||||
|
||||
This is designed to interact with the a ../slip-radio example running on a
|
||||
mote that is either directly USB/TTY connected, or is remote via a TCP
|
||||
connect. What's on the SLIP interface is really not Serial Line IP, but SLIP
|
||||
framed 15.4 packets.
|
||||
|
||||
The border router supports a number of commands on it's stdin.
|
||||
Each are prefixed by !:
|
||||
* !G - global RPL repair root.
|
||||
* !M - set MAC address (if coming from RADIO, i.e. SLIP link)
|
||||
* !C - show channel (if coming from RADIO, i.e. SLIP link)
|
||||
* !D - sensor data received
|
||||
* !Q - exit
|
||||
|
||||
Queries are prefixed by ?:
|
||||
* ?M is used for requesting the MAC address from the radio in order to use it for uIP6 and its stateless address auto configuration of its IPv6 address. This will make the native border router have the address that correspond to the MAC address of the slip-radio. (response is !M from the slip-radio)
|
||||
|
||||
* ?C is used for requesting the currently used channel for the slip-radio. The response is !C with a channel number (from the slip-radio).
|
||||
|
||||
* !C is used for setting the channel of the slip-radio (useful if the motes are using another channel than the one used in the slip-radio).
|
||||
|
6
examples/ipv6/slip-radio/README.md
Normal file
6
examples/ipv6/slip-radio/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
This project is intended to run on a mode that is connected to a native host system
|
||||
by SLIP. The SLIP is really SERIAL LINE 15.4, as this just turns the mote into a smart
|
||||
radio, running the RPL and 6lowpan stack on the Host. This goes with native-border-router.
|
||||
|
||||
|
||||
|
|
@ -5,10 +5,14 @@ CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
|
|||
CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c \
|
||||
mmem.c contiki-rcb-main.c
|
||||
|
||||
MODULES += core/net core/net/mac core/net/mac/sicslowmac core/net/mac/contikimac \
|
||||
core/net/mac/cxmac core/net/rime core/net/ipv4 core/net/ip \
|
||||
core/net/ipv6 core/net/rpl core/net/llsec
|
||||
|
||||
CONTIKIAVR=$(CONTIKI)/cpu/avr
|
||||
CONTIKIBOARD=.
|
||||
|
||||
CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2
|
||||
CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 -DNETSTACK_CONF_WITH_RIME=1 -DNETSTACK_CONF_WITH_IPV6=1
|
||||
|
||||
MCU=atmega1281
|
||||
AVRDUDE_PROGRAMMER=jtag2
|
||||
|
|
|
@ -92,11 +92,24 @@ void clock_adjust_ticks(clock_time_t howmany);
|
|||
#define CCIF
|
||||
#define CLIF
|
||||
|
||||
//#define NETSTACK_CONF_WITH_IPV6 1 //Let makefile determine this so ipv4 hello-world will compile
|
||||
|
||||
#define LINKADDR_CONF_SIZE 8
|
||||
#define PACKETBUF_CONF_HDR_SIZE 0
|
||||
#define PACKETBUF_CONF_HDR_SIZE 48 /* Choose a buffersize != 0 for the messages which should be sended over the wireless interface */
|
||||
|
||||
/* Uncomment this lines to activate the specific drivers */
|
||||
//#define NETSTACK_CONF_NETWORK rime_driver
|
||||
//#define NETSTACK_CONF_MAC nullmac_driver
|
||||
//#define NETSTACK_CONF_RDC sicslowmac_driver
|
||||
//#define NETSTACK_CONF_FRAMER framer_802154 /* Framer for 802.15.4 Medium Access Control */
|
||||
#define NETSTACK_CONF_RADIO rf230_driver /* Select the wireless driver, otherwise contiki would operate with the "nulldriver" which does nothing */
|
||||
|
||||
#define RF230_CONF_AUTOACK 1
|
||||
#define CXMAC_CONF_ANNOUNCEMENTS 10
|
||||
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
|
||||
|
||||
/* 211 bytes per queue buffer. Burst mode will need 15 for a 1280 byte MTU */
|
||||
#define QUEUEBUF_CONF_NUM 15
|
||||
/* 54 bytes per queue ref buffer */
|
||||
#define QUEUEBUF_CONF_REF_NUM 2
|
||||
/* 0 for IPv6, or 1 for HC1, 2 for HC01 */
|
||||
#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0
|
||||
#define SICSLOWPAN_CONF_COMPRESSION_HC1 1
|
||||
|
@ -124,18 +137,16 @@ void clock_adjust_ticks(clock_time_t howmany);
|
|||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||
#define UIP_CONF_ND6_MAX_PREFIXES 3
|
||||
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
|
||||
#if NETSTACK_CONF_WITH_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined
|
||||
#define UIP_CONF_ICMP6 1
|
||||
#if NETSTACK_CONF_WITH_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined
|
||||
#define UIP_CONF_ICMP6 1
|
||||
#endif
|
||||
|
||||
#define UIP_CONF_UDP 1
|
||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||
|
||||
#define UIP_CONF_TCP 0
|
||||
#define UIP_CONF_TCP 1
|
||||
#define UIP_CONF_TCP_SPLIT 0
|
||||
|
||||
|
||||
|
||||
/* These names are deprecated, use C99 names. */
|
||||
/*typedef unsigned char u8_t;
|
||||
typedef unsigned short u16_t;
|
||||
|
|
|
@ -109,17 +109,18 @@ init_lowlevel(void)
|
|||
rs232_redirect_stdout(RS232_PORT_1);
|
||||
|
||||
DDRE |= LED1 | LED2 | LED3;
|
||||
|
||||
ctimer_init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static struct etimer et;
|
||||
PROCESS_THREAD(rcb_leds, ev, data)
|
||||
{
|
||||
uint8_t error;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
if((error = icmp6_new(NULL)) == 0) {
|
||||
while(1) {
|
||||
PROCESS_YIELD();
|
||||
|
||||
|
@ -134,7 +135,6 @@ PROCESS_THREAD(rcb_leds, ev, data)
|
|||
LEDOff(LED2);
|
||||
}
|
||||
}
|
||||
}
|
||||
PROCESS_END();
|
||||
}
|
||||
|
||||
|
@ -142,14 +142,10 @@ PROCESS_THREAD(rcb_leds, ev, data)
|
|||
int
|
||||
main(void)
|
||||
{
|
||||
//calibrate_rc_osc_32k(); //CO: Had to comment this out
|
||||
|
||||
/* Initialize hardware */
|
||||
init_lowlevel();
|
||||
|
||||
init_lowlevel();
|
||||
/* Clock */
|
||||
clock_init();
|
||||
|
||||
LEDOff(LED1 | LED2);
|
||||
|
||||
/* Process subsystem */
|
||||
|
@ -157,17 +153,29 @@ main(void)
|
|||
|
||||
/* Register initial processes */
|
||||
procinit_init();
|
||||
|
||||
/* It is very important to do the NETSTACK_* initializations right here
|
||||
* to enable the PROCESS_YIELD** functionality.
|
||||
* The receive process is an single protothread which handles the
|
||||
* received packets. This process needs PROCESS_YIELD_UNTIL().
|
||||
**/
|
||||
/* Start radio and radio receive process */
|
||||
NETSTACK_RADIO.init();
|
||||
/* Initialize stack protocols */
|
||||
queuebuf_init();
|
||||
NETSTACK_RDC.init();
|
||||
NETSTACK_MAC.init();
|
||||
NETSTACK_NETWORK.init();
|
||||
|
||||
/* Autostart processes */
|
||||
autostart_start(autostart_processes);
|
||||
|
||||
printf_P(PSTR("\n********BOOTING CONTIKI*********\n"));
|
||||
|
||||
printf_P(PSTR("System online.\n"));
|
||||
|
||||
/* Main scheduler loop */
|
||||
while(1) {
|
||||
process_run();
|
||||
process_run();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue