Merge branch 'contiki' into osd

This commit is contained in:
Harald Pichler 2015-02-10 15:13:21 +01:00
commit 6730ec16c8
11 changed files with 159 additions and 39 deletions

View file

@ -74,6 +74,7 @@ typedef struct uip_ds6_nbr {
uint8_t nscount; uint8_t nscount;
uint8_t isrouter; uint8_t isrouter;
uint8_t state; uint8_t state;
uint16_t link_metric;
#if UIP_CONF_IPV6_QUEUE_PKT #if UIP_CONF_IPV6_QUEUE_PKT
struct uip_packetqueue_handle packethandle; struct uip_packetqueue_handle packethandle;
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4 #define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4

View file

@ -269,9 +269,16 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
one first. */ one first. */
r = uip_ds6_route_lookup(ipaddr); r = uip_ds6_route_lookup(ipaddr);
if(r != NULL) { 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 "); PRINTF("uip_ds6_route_add: old route for ");
PRINT6ADDR(ipaddr); PRINT6ADDR(ipaddr);
PRINTF(" found, deleting it\n"); PRINTF(" found, deleting it\n");
uip_ds6_route_rm(r); uip_ds6_route_rm(r);
} }
{ {

View file

@ -47,6 +47,7 @@
#include "net/rpl/rpl-private.h" #include "net/rpl/rpl-private.h"
#include "net/ip/uip.h" #include "net/ip/uip.h"
#include "net/ipv6/uip-nd6.h" #include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-ds6-nbr.h"
#include "net/nbr-table.h" #include "net/nbr-table.h"
#include "net/ipv6/multicast/uip-mcast6.h" #include "net/ipv6/multicast/uip-mcast6.h"
#include "lib/list.h" #include "lib/list.h"
@ -79,6 +80,19 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
/* Allocate instance table. */ /* Allocate instance table. */
rpl_instance_t instance_table[RPL_MAX_INSTANCES]; rpl_instance_t instance_table[RPL_MAX_INSTANCES];
rpl_instance_t *default_instance; 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 static void
nbr_callback(void *ptr) nbr_callback(void *ptr)
@ -113,9 +127,11 @@ rpl_get_parent_rank(uip_lladdr_t *addr)
uint16_t uint16_t
rpl_get_parent_link_metric(const uip_lladdr_t *addr) 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); uip_ds6_nbr_t *nbr;
if(p != NULL) { nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr);
return p->link_metric;
if(nbr != NULL) {
return nbr->link_metric;
} else { } else {
return 0; return 0;
} }
@ -568,10 +584,17 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
if(p == NULL) { if(p == NULL) {
PRINTF("RPL: rpl_add_parent p NULL\n"); PRINTF("RPL: rpl_add_parent p NULL\n");
} else { } else {
uip_ds6_nbr_t *nbr;
nbr = rpl_get_nbr(p);
p->dag = dag; p->dag = dag;
p->rank = dio->rank; p->rank = dio->rank;
p->dtsn = dio->dtsn; 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 #if RPL_DAG_MC != RPL_DAG_MC_NONE
memcpy(&p->mc, &dio->mc, sizeof(p->mc)); memcpy(&p->mc, &dio->mc, sizeof(p->mc));
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #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); remove_parents(dag, 0);
dag->version = dio->version; 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->instance->of->reset(dag);
dag->min_rank = INFINITE_RANK; dag->min_rank = INFINITE_RANK;
RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out); RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out);

View file

@ -90,16 +90,22 @@ typedef uint16_t rpl_path_metric_t;
static rpl_path_metric_t static rpl_path_metric_t
calculate_path_metric(rpl_parent_t *p) calculate_path_metric(rpl_parent_t *p)
{ {
uip_ds6_nbr_t *nbr;
if(p == NULL) { if(p == NULL) {
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR; 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 #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 #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 #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 #else
#error "Unsupported RPL_DAG_MC configured. See rpl.h." #error "Unsupported RPL_DAG_MC configured. See rpl.h."
#endif /* RPL_DAG_MC */ #endif /* RPL_DAG_MC */
@ -114,9 +120,18 @@ reset(rpl_dag_t *dag)
static void static void
neighbor_link_callback(rpl_parent_t *p, int status, int numtx) 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 packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
uint16_t new_etx; 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. */ /* Do not penalize the ETX when collisions or transmission errors occur. */
if(status == MAC_TX_OK || status == MAC_TX_NOACK) { 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)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR), (unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
(unsigned)(packet_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 new_rank;
rpl_rank_t rank_increase; 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) { if(base_rank == 0) {
return INFINITE_RANK; return INFINITE_RANK;
} }
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR; rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
} else { } else {
rank_increase = p->link_metric; rank_increase = nbr->link_metric;
if(base_rank == 0) { if(base_rank == 0) {
base_rank = p->rank; base_rank = p->rank;
} }

View file

@ -127,25 +127,33 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
{ {
rpl_rank_t r1, r2; 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 "); PRINTF("RPL: Comparing parent ");
PRINT6ADDR(rpl_get_parent_ipaddr(p1)); PRINT6ADDR(rpl_get_parent_ipaddr(p1));
PRINTF(" (confidence %d, rank %d) with parent ", PRINTF(" (confidence %d, rank %d) with parent ",
p1->link_metric, p1->rank); nbr1->link_metric, p1->rank);
PRINT6ADDR(rpl_get_parent_ipaddr(p2)); PRINT6ADDR(rpl_get_parent_ipaddr(p2));
PRINTF(" (confidence %d, rank %d)\n", 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 + 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 + 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 /* Compare two parents by looking both and their rank and at the ETX
for that parent. We choose the parent that has the most for that parent. We choose the parent that has the most
favourable combination. */ favourable combination. */
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
if(r1 < r2 + MIN_DIFFERENCE && if(r1 < r2 + MIN_DIFFERENCE &&
r1 > r2 - MIN_DIFFERENCE) { r1 > r2 - MIN_DIFFERENCE) {
return dag->preferred_parent; return dag->preferred_parent;

View file

@ -114,7 +114,6 @@ struct rpl_parent {
rpl_metric_container_t mc; rpl_metric_container_t mc;
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
rpl_rank_t rank; rpl_rank_t rank;
uint16_t link_metric;
uint8_t dtsn; uint8_t dtsn;
uint8_t flags; 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); rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr); uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
void rpl_dag_init(void); void rpl_dag_init(void);
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
/** /**
* RPL modes * RPL modes

View 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).

View 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.

View file

@ -5,10 +5,14 @@ CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o
CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c \ CONTIKI_TARGET_SOURCEFILES += rs232.c cfs-eeprom.c eeprom.c random.c \
mmem.c contiki-rcb-main.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 CONTIKIAVR=$(CONTIKI)/cpu/avr
CONTIKIBOARD=. 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 MCU=atmega1281
AVRDUDE_PROGRAMMER=jtag2 AVRDUDE_PROGRAMMER=jtag2

View file

@ -92,11 +92,24 @@ void clock_adjust_ticks(clock_time_t howmany);
#define CCIF #define CCIF
#define CLIF #define CLIF
//#define NETSTACK_CONF_WITH_IPV6 1 //Let makefile determine this so ipv4 hello-world will compile
#define LINKADDR_CONF_SIZE 8 #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 */ /* 0 for IPv6, or 1 for HC1, 2 for HC01 */
#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 #define SICSLOWPAN_CONF_COMPRESSION_IPV6 0
#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 #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_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3 #define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ND6_MAX_DEFROUTERS 2
#if NETSTACK_CONF_WITH_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined #if NETSTACK_CONF_WITH_IPV6 //tcpip.c error on ipv4 build if UIP_CONF_ICMP6 defined
#define UIP_CONF_ICMP6 1 #define UIP_CONF_ICMP6 1
#endif #endif
#define UIP_CONF_UDP 1 #define UIP_CONF_UDP 1
#define UIP_CONF_UDP_CHECKSUMS 1 #define UIP_CONF_UDP_CHECKSUMS 1
#define UIP_CONF_TCP 0 #define UIP_CONF_TCP 1
#define UIP_CONF_TCP_SPLIT 0 #define UIP_CONF_TCP_SPLIT 0
/* These names are deprecated, use C99 names. */ /* These names are deprecated, use C99 names. */
/*typedef unsigned char u8_t; /*typedef unsigned char u8_t;
typedef unsigned short u16_t; typedef unsigned short u16_t;

View file

@ -109,17 +109,18 @@ init_lowlevel(void)
rs232_redirect_stdout(RS232_PORT_1); rs232_redirect_stdout(RS232_PORT_1);
DDRE |= LED1 | LED2 | LED3; DDRE |= LED1 | LED2 | LED3;
ctimer_init();
} }
static struct etimer et; static struct etimer et;
PROCESS_THREAD(rcb_leds, ev, data) PROCESS_THREAD(rcb_leds, ev, data)
{ {
uint8_t error;
PROCESS_BEGIN(); PROCESS_BEGIN();
if((error = icmp6_new(NULL)) == 0) {
while(1) { while(1) {
PROCESS_YIELD(); PROCESS_YIELD();
@ -134,7 +135,6 @@ PROCESS_THREAD(rcb_leds, ev, data)
LEDOff(LED2); LEDOff(LED2);
} }
} }
}
PROCESS_END(); PROCESS_END();
} }
@ -142,14 +142,10 @@ PROCESS_THREAD(rcb_leds, ev, data)
int int
main(void) main(void)
{ {
//calibrate_rc_osc_32k(); //CO: Had to comment this out
/* Initialize hardware */ /* Initialize hardware */
init_lowlevel(); init_lowlevel();
/* Clock */ /* Clock */
clock_init(); clock_init();
LEDOff(LED1 | LED2); LEDOff(LED1 | LED2);
/* Process subsystem */ /* Process subsystem */
@ -158,11 +154,23 @@ main(void)
/* Register initial processes */ /* Register initial processes */
procinit_init(); 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 processes */
autostart_start(autostart_processes); autostart_start(autostart_processes);
printf_P(PSTR("\n********BOOTING CONTIKI*********\n")); printf_P(PSTR("\n********BOOTING CONTIKI*********\n"));
printf_P(PSTR("System online.\n")); printf_P(PSTR("System online.\n"));
/* Main scheduler loop */ /* Main scheduler loop */