diff --git a/projects/test_rpl/Jamfile b/projects/test_rpl/Jamfile new file mode 100644 index 0000000000..2041c4ce0c --- /dev/null +++ b/projects/test_rpl/Jamfile @@ -0,0 +1,10 @@ +SubDir TOP projects test_rpl ; + +Module test_rpl : main.c : 6lowpan auto_init uart0 posix_io ; + +UseModule test_rpl ; +UseModule cc110x_ng ; +UseModule rpl ; +UseModule 6lowpan ; +UseModule vtimer ; +UseModule auto_init ; diff --git a/projects/test_rpl/main.c b/projects/test_rpl/main.c new file mode 100644 index 0000000000..8aec2d47a7 --- /dev/null +++ b/projects/test_rpl/main.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include "sys/net/sixlowpan/sixlowip.h" +#include "sys/net/sixlowpan/sixlowpan.h" +#include "sys/net/sixlowpan/rpl/rpl.h" + +void main(void) +{ + uint16_t root = 0x0001; + ipv6_addr_t std_addr; + uint16_t r_addr = root; + ipv6_init_address(&std_addr, 0xABCD,0,0,0,0x1234,0xFFFF,0xFEDC,r_addr); + sixlowpan_init(TRANSCEIVER_CC1100, r_addr, 0); + rpl_init(); + if(root == 0x0001){ + rpl_init_root(); + } + printf("RPL INIT FINISHED\n"); + while(1); +} + diff --git a/projects/test_rpl/tests/hello-world b/projects/test_rpl/tests/hello-world new file mode 100755 index 0000000000..acde8265fe --- /dev/null +++ b/projects/test_rpl/tests/hello-world @@ -0,0 +1,13 @@ +#!/usr/bin/expect + +set timeout 5 + +spawn pseudoterm $env(PORT) + +expect { + "Hello World!" {} + timeout { exit 1 } +} + +puts "\nTest successful!\n" + diff --git a/sys/Jamfile b/sys/Jamfile index e874226861..89c36c15f1 100644 --- a/sys/Jamfile +++ b/sys/Jamfile @@ -44,5 +44,6 @@ SubInclude TOP sys net ; SubInclude TOP sys lib ; SubInclude TOP sys shell ; SubInclude TOP sys net sixlowpan ; +SubInclude TOP sys net sixlowpan rpl ; SubInclude TOP sys net destiny ; SubInclude TOP sys net net_help ; diff --git a/sys/net/sixlowpan/rpl/Jamfile b/sys/net/sixlowpan/rpl/Jamfile new file mode 100644 index 0000000000..75a43ccf3e --- /dev/null +++ b/sys/net/sixlowpan/rpl/Jamfile @@ -0,0 +1,3 @@ +SubDir TOP sys net sixlowpan rpl ; + +Module rpl : rpl.c of0.c rpl_dodag.c : 6lowpan vtimer transceiver auto_init net_help ; diff --git a/sys/net/sixlowpan/rpl/objective_functions.c b/sys/net/sixlowpan/rpl/objective_functions.c new file mode 100644 index 0000000000..96cb486731 --- /dev/null +++ b/sys/net/sixlowpan/rpl/objective_functions.c @@ -0,0 +1,6 @@ +#include "objective_functions.h" + +void of0(){ + + +} diff --git a/sys/net/sixlowpan/rpl/objective_functions.h b/sys/net/sixlowpan/rpl/objective_functions.h new file mode 100644 index 0000000000..a6acfb0a3c --- /dev/null +++ b/sys/net/sixlowpan/rpl/objective_functions.h @@ -0,0 +1,3 @@ +#include + +void of0(); diff --git a/sys/net/sixlowpan/rpl/of0.c b/sys/net/sixlowpan/rpl/of0.c new file mode 100644 index 0000000000..c42b620d3b --- /dev/null +++ b/sys/net/sixlowpan/rpl/of0.c @@ -0,0 +1,44 @@ +#include +#include "of0.h" + +rpl_of_t rpl_of0 = { + 0, + calc_rank, + which_parent, + which_dodag, + reset, + NULL +}; + +static void reset(rpl_dodag_t *dodag){ + //Nothing to do in OF0 +} + +static uint16_t calc_rank(rpl_parent_t * parent, uint16_t base_rank){ + if(base_rank == 0) { + if(parent == NULL) { + return INFINITE_RANK; + } + base_rank = parent->rank; + } + + uint16_t add; + if(parent != NULL){ + add = parent->dodag->minhoprankincrease; + } + else{ + add = DEFAULT_MIN_HOP_RANK_INCREASE; + } + if( base_rank + add < base_rank ){ + return INFINITE_RANK; + } + return base_rank + add; +} + +static rpl_parent_t * which_parent(rpl_parent_t *p1, rpl_parent_t *p2){ + return p1; +} + +static rpl_dodag_t * which_dodag(rpl_dodag_t *d1, rpl_dodag_t *d2){ + return d1; +} diff --git a/sys/net/sixlowpan/rpl/of0.h b/sys/net/sixlowpan/rpl/of0.h new file mode 100644 index 0000000000..9061370efb --- /dev/null +++ b/sys/net/sixlowpan/rpl/of0.h @@ -0,0 +1,6 @@ +#include "rpl_structs.h" + +static uint16_t calc_rank(rpl_parent_t *, uint16_t); +static rpl_parent_t *which_parent(rpl_parent_t *, rpl_parent_t *); +static rpl_dodag_t *which_dodag(rpl_dodag_t *, rpl_dodag_t *); +static void reset(rpl_dodag_t *); diff --git a/sys/net/sixlowpan/rpl/rpl.c b/sys/net/sixlowpan/rpl/rpl.c new file mode 100644 index 0000000000..937531e052 --- /dev/null +++ b/sys/net/sixlowpan/rpl/rpl.c @@ -0,0 +1,313 @@ +#include +#include +#include "rpl.h" + +#include "sys/net/sixlowpan/sixlowmac.h" +#include "sys/net/sixlowpan/sixlowip.h" +#include "sys/net/sixlowpan/sixlowpan.h" + +//global variables for own rpl status: +bool root = false; +ipv6_addr_t dodagid; +uint8_t rpl_instance_id; + +//counters +uint8_t act_dodag_version = 240; +uint8_t dao_sequence = 240; +uint8_t path_sequence = 240; +//other global variables + +//ipv6_addr_t parents[10]; +//rpl_instance_t instances[5]; +uint16_t packet_length; + +//Unbenutzte buffer auskommentiert, damit keine warnings erscheinen +static struct ipv6_hdr_t* ipv6_buf; +static struct icmpv6_hdr_t* icmp_buf; +static struct rpl_dio_t *rpl_dio_buf; +//static struct rpl_dis_t *rpl_dis_buf; +static struct rpl_dao_t *rpl_dao_buf; +//static struct rpl_dao_ack_t * rpl_dao_ack_buf; +static struct rpl_opt_t *rpl_opt_buf; +static struct rpl_opt_dodag_conf_t * rpl_opt_dodag_conf_buf; + + +static struct rpl_dio_t* get_rpl_dio_buf(){ + return ((struct rpl_dio_t*)&(buffer[LLHDR_ICMPV6HDR_LEN])); +} + +static struct rpl_dao_t* get_rpl_dao_buf(){ + return ((struct rpl_dao_t*)&(buffer[LLHDR_ICMPV6HDR_LEN])); +} +/*static struct rpl_dao_ack_t* get_rpl_dao_ack_buf(){ + return ((struct rpl_dao_ack_t*)&(buffer[LLHDR_ICMPV6HDR_LEN])); +} +static struct rpl_dis_t* get_rpl_dis_buf(){ + return ((struct rpl_dis_t*)&(buffer[LLHDR_ICMPV6HDR_LEN])); +}*/ +static struct rpl_opt_t* get_rpl_opt_buf(uint8_t rpl_msg_len){ + return ((struct rpl_opt_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +static struct rpl_opt_dodag_conf_t* get_rpl_opt_dodag_conf_buf(uint8_t rpl_msg_len){ + return ((struct rpl_opt_dodag_conf_t*)&(buffer[LLHDR_ICMPV6HDR_LEN + rpl_msg_len])); +} + +void rpl_init(){ + //TODO: initialize trickle + turn_on_rpl_handler(); + + +} + +void rpl_init_root(){ + rpl_instance_t *inst; + rpl_dodag_t *dodag; + + inst = rpl_new_instance(RPL_DEFAULT_INSTANCE); + inst->id = RPL_DEFAULT_INSTANCE; + + dodag = rpl_new_dodag(RPL_DEFAULT_INSTANCE); + if(dodag != NULL) { + ipv6_addr_t id; + ipv6_addr_t mcast; + ipv6_set_all_nds_mcast_addr(&mcast); + ipv6_get_saddr(&id, &mcast); + + //TODO: dodag->of = + dodag->dodag_id = id; + dodag->instance = inst; + dodag->mop = RPL_DEFAULT_MOP; + dodag->dtsn = 1; + dodag->dio_interval_doubling = DEFAULT_DIO_INTERVAL_DOUBLINGS; + dodag->dio_min = DEFAULT_DIO_INTERVAL_MIN; + dodag->dio_redundancy = DEFAULT_DIO_REDUNDANCY_CONSTANT; + dodag->maxrankincrease = 0; + dodag->minhoprankincrease = DEFAULT_MIN_HOP_RANK_INCREASE; + dodag->default_lifetime = RPL_DEFAULT_LIFETIME; + dodag->lifetime_unit = RPL_LIFETIME_UNIT; + dodag->version = 0; + dodag->grounded = RPL_GROUNDED; + dodag->my_rank = RPL_ROOT_RANK; + dodag->joined = 1; + dodag->my_preferred_parent = NULL; + } + + send_DIO(); + +} + + +void send_DIO(){ + rpl_dodag_t * mydodag; + ipv6_buf = get_ipv6_buf(); + icmp_buf = get_icmpv6_buf(ipv6_ext_hdr_len); + packet_length = 0; + + mydodag = rpl_get_my_dodag(); + if(mydodag == NULL){ + printf("Error, trying to send DIO without being part of a dodag. This should not happen\n"); + return; + } + + icmp_buf->type = ICMP_RPL_CONTROL; + icmp_buf->code = ICMP_CODE_DIO; + ipv6_buf->version_trafficclass = IPV6_VER; + ipv6_buf->trafficclass_flowlabel = 0; + ipv6_buf->flowlabel = 0; + ipv6_buf->nextheader = PROTO_NUM_ICMPV6; + ipv6_buf->hoplimit = 1; + + ipv6_set_all_nds_mcast_addr(&ipv6_buf->destaddr); + ipv6_get_saddr(&(ipv6_buf->srcaddr), &(ipv6_buf->destaddr)); + + rpl_dio_buf = get_rpl_dio_buf(); + memset(rpl_dio_buf, 0, sizeof(*rpl_dio_buf)); + rpl_dio_buf->rpl_instanceid = mydodag->instance->id; + rpl_dio_buf->version_number = mydodag->version; + rpl_dio_buf->rank = mydodag->my_rank; + rpl_dio_buf->g_mop_prf = mydodag->grounded | (mydodag->mop << RPL_MOP_SHIFT); + rpl_dio_buf->dtsn = mydodag->dtsn; + rpl_dio_buf->flags = 0; + rpl_dio_buf->reserved = 0; + rpl_dio_buf->dodagid = mydodag->dodag_id; + printf("Send DIO with DODAGID: \n"); + ipv6_print_addr(&rpl_dio_buf->dodagid); + + int opt_hdr_len = 0; + //DODAG Configuration Option! + rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(DIO_BASE_LEN); + rpl_opt_dodag_conf_buf->type = RPL_OPT_DODAG_CONF; + rpl_opt_dodag_conf_buf->length = RPL_OPT_DODAG_CONF_LEN; + rpl_opt_dodag_conf_buf->flags_a_pcs = 0; + rpl_opt_dodag_conf_buf->DIOIntDoubl = mydodag->dio_interval_doubling; + rpl_opt_dodag_conf_buf->DIOIntMin = mydodag->dio_min; + rpl_opt_dodag_conf_buf->DIORedun = mydodag->dio_redundancy; + rpl_opt_dodag_conf_buf->MaxRankIncrease = mydodag->maxrankincrease; + rpl_opt_dodag_conf_buf->MinHopRankIncrease = mydodag->minhoprankincrease; + rpl_opt_dodag_conf_buf->ocp = mydodag->of->ocp; + rpl_opt_dodag_conf_buf->reserved = 0; + rpl_opt_dodag_conf_buf->default_lifetime = mydodag->default_lifetime; + rpl_opt_dodag_conf_buf->lifetime_unit = mydodag->lifetime_unit; + + + opt_hdr_len += RPL_OPT_LEN + RPL_OPT_DODAG_CONF_LEN; + + + ipv6_buf->length = ICMPV6_HDR_LEN + DIO_BASE_LEN + opt_hdr_len; + //ipv6_buf->length = ICMPV6_HDR_LEN + DIO_BASE_LEN;// + RPL_OPT_LEN + RPL_OPT_DODAG_CONF_LEN; + lowpan_init((ieee_802154_long_t*)&(ipv6_buf->destaddr.uint16[4]),(uint8_t*)ipv6_buf); + printf("sent DIO\n"); +} + +void rpl_icmp_handler(uint8_t code){ + //pakettypen unterscheiden + switch(code) { + case(ICMP_CODE_DIS):{ + break; + } + case(ICMP_CODE_DIO):{ + recv_rpl_dio(); + break; + } + case(ICMP_CODE_DAO):{ + recv_rpl_dao(); + break; + } + case(ICMP_CODE_DAO_ACK):{ + break; + } + default: + return; + } +} + + +void recv_rpl_dio(void){ + ipv6_buf = get_ipv6_buf(); + + rpl_dio_buf = get_rpl_dio_buf(); + + int len = DIO_BASE_LEN; + printf("Received DIO with DODAGID:\n"); + ipv6_print_addr(&rpl_dio_buf->dodagid); + printf("Rank: %d \n", rpl_dio_buf->rank); + + //rpl_get_dodag(); + + uint8_t mop = (rpl_dio_buf->g_mop_prf >> RPL_MOP_SHIFT ) | 0x7; + if(mop != RPL_DEFAULT_MOP){ + //not supported yet + } + + while(len < (ipv6_buf->length - LLHDR_ICMPV6HDR_LEN) ){ + rpl_opt_buf = get_rpl_opt_buf(len); + switch(rpl_opt_buf->type){ + + case(RPL_OPT_PAD1):{ + len += 1; + break; + } + case(RPL_OPT_PADN):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_DAG_METRIC_CONTAINER):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_ROUTE_INFO):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_DODAG_CONF):{ + if(rpl_opt_buf->length != RPL_OPT_DODAG_CONF_LEN){ + //error malformed + } + len += RPL_OPT_DODAG_CONF_LEN +2; + rpl_opt_dodag_conf_buf = get_rpl_opt_dodag_conf_buf(len); + break; + } + case(RPL_OPT_PREFIX_INFO):{ + if(rpl_opt_buf->length != RPL_OPT_PREFIX_INFO_LEN){ + //error malformed + } + len += RPL_OPT_PREFIX_INFO_LEN +2; + break; + } + default: + //unsupported option -> error + break; + } + } + + + + //handle Packet... + + //bin ich schon in einem DODAG? + + //kein DODAG: + //will ich dem DODAG beitreten? + + //im DODAG: + //will ich das DODAG wechseln? + //brauche ich für die entscheidung mehr Infos, die im DIO nicht enthalten waren? + //DIS an entsprechenden Knoten senden! + + //wechseln: + //war ich schon zuvor in dem DODAG? + //ja: + //Regeln beachten bei Wechsel + + //nein: + + //normal beitreten + //-> nur in Parents eintragen + + +} + +void recv_rpl_dao(void){ + ipv6_buf = get_ipv6_buf(); + + rpl_dao_buf = get_rpl_dao_buf(); + int len = DAO_BASE_LEN; + while(len < (ipv6_buf->length - LLHDR_ICMPV6HDR_LEN) ){ + rpl_opt_buf = get_rpl_opt_buf(len); + switch(rpl_opt_buf->type){ + + case(RPL_OPT_PAD1):{ + len += 1; + break; + } + case(RPL_OPT_PADN):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_DAG_METRIC_CONTAINER):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_TARGET):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_TRANSIT):{ + len += rpl_opt_buf->length +2; + break; + } + case(RPL_OPT_TARGET_DESC):{ + len += rpl_opt_buf->length +2; + break; + } + + default: + break; + } + } + //für mich? + //ja: verarbeiten + //nein: weiterleiten + +} diff --git a/sys/net/sixlowpan/rpl/rpl.h b/sys/net/sixlowpan/rpl/rpl.h new file mode 100644 index 0000000000..32b4975800 --- /dev/null +++ b/sys/net/sixlowpan/rpl/rpl.h @@ -0,0 +1,13 @@ +#include +#include +#include +#include "sys/net/sixlowpan/sixlowip.h" +#include "rpl_dodag.h" + +void rpl_init(); +void rpl_init_root(); + +void rpl_icmp_handler(uint8_t code); +void recv_rpl_dio(void); +void recv_rpl_dao(void); +void send_DIO(void); diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.c b/sys/net/sixlowpan/rpl/rpl_dodag.c new file mode 100644 index 0000000000..0fe2153259 --- /dev/null +++ b/sys/net/sixlowpan/rpl/rpl_dodag.c @@ -0,0 +1,95 @@ +#include +#include + +#include "rpl_dodag.h" + +rpl_instance_t instances[RPL_MAX_INSTANCES]; +rpl_dodag_t dodags[RPL_MAX_DODAGS]; +rpl_parent_t parents[RPL_MAX_PARENTS]; + +rpl_instance_t *rpl_new_instance(uint8_t instanceid){ + rpl_instance_t *inst; + rpl_instance_t *end ; + for(inst=&instances[0], end = inst+RPL_MAX_INSTANCES; inst < end;inst++){ + if(inst->used == 0){ + memset(inst, 0, sizeof(*inst)); + return inst; + } + } + return NULL; +} +rpl_instance_t *rpl_get_instance(uint8_t instanceid){ + for(int i=0;iused == 0){ + memset(dodag, 0,sizeof(*dodag)); + dodag->instance = inst; + dodag->my_rank = INFINITE_RANK; + dodag->used = 1; + return dodag; + } + } + return NULL; + +} + +rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id){ + for(int i=0;iuint32[i] != id2->uint32[i]){ + return false; + } + } + return true; +} diff --git a/sys/net/sixlowpan/rpl/rpl_dodag.h b/sys/net/sixlowpan/rpl/rpl_dodag.h new file mode 100644 index 0000000000..ed6d09ab59 --- /dev/null +++ b/sys/net/sixlowpan/rpl/rpl_dodag.h @@ -0,0 +1,14 @@ +#include "rpl_structs.h" + +rpl_instance_t *rpl_new_instance(uint8_t instanceid); +rpl_instance_t *rpl_get_instance(uint8_t instanceid); +rpl_instance_t *rpl_get_my_instance(); +rpl_dodag_t *rpl_new_dodag(uint8_t instanceid); +rpl_dodag_t *rpl_get_dodag(ipv6_addr_t *id); +rpl_dodag_t *rpl_get_my_dodag(); +rpl_parent_t *rpl_new_parent(rpl_dodag_t * dodag, ipv6_addr_t address); +void rpl_del_dodag(rpl_dodag_t *dodag); +void rpl_leave_dodag(rpl_dodag_t * dodag); +void rpl_join_dodag(); +bool rpl_equal_dodag_id(ipv6_addr_t *id1, ipv6_addr_t *id2); + diff --git a/sys/net/sixlowpan/rpl/rpl_structs.h b/sys/net/sixlowpan/rpl/rpl_structs.h new file mode 100644 index 0000000000..25eeabef39 --- /dev/null +++ b/sys/net/sixlowpan/rpl/rpl_structs.h @@ -0,0 +1,180 @@ +#include "sys/net/sixlowpan/sixlowip.h" + +// Modes of Operation + +#define NO_DOWNWARD_ROUTES 0x00 +#define NON_STORING_MODE 0x01 +#define STORING_MODE_NO_MC 0x02 +#define STORING_MODE_MC 0x03 + +//ICMP type +#define ICMP_RPL_CONTROL 155 +#define RPL_SEQUENCE_WINDOW 16 +#define ICMP_CODE_DIS 0x00 +#define ICMP_CODE_DIO 0x01 +#define ICMP_CODE_DAO 0x02 +#define ICMP_CODE_DAO_ACK 0x03 +//packet base lengths +#define DIO_BASE_LEN 24 +#define DIS_BASE_LEN 2 +#define DAO_BASE_LEN 4 +#define DAO_D_LEN 24 +#define DAO_ACK_LEN 4 +#define DAO_ACK_D_LEN 24 +#define RPL_OPT_LEN 2 +#define RPL_OPT_DODAG_CONF_LEN 14 +#define RPL_OPT_PREFIX_INFO_LEN 30 + +//message options +#define RPL_OPT_PAD1 0 +#define RPL_OPT_PADN 1 +#define RPL_OPT_DAG_METRIC_CONTAINER 2 +#define RPL_OPT_ROUTE_INFO 3 +#define RPL_OPT_DODAG_CONF 4 +#define RPL_OPT_TARGET 5 +#define RPL_OPT_TRANSIT 6 +#define RPL_OPT_SOLICITED_INFO 7 +#define RPL_OPT_PREFIX_INFO 8 +#define RPL_OPT_TARGET_DESC 9 + +//Counters +#define RPL_COUNTER_MAX 255 +#define RPL_COUNTER_LOWER_REGION 127 +#define RPL_COUNTER_SEQ_WINDOW 16 +#define RPL_COUNTER_INIT RPL_COUNTER_MAX - RPL_COUNTER_SEQ_WINDOW + 1 +#define RPL_COUNTER_INCREMENT(counter) (counter > RPL_COUNTER_LOWER_REGION ? (counter == RPL_COUNTER_MAX ? counter=0 : ++counter) : (counter == RPL_COUNTER_LOWER_REGION ? counter=0 : ++counter)) +#define RPL_COUNTER_IS_INIT(counter) (counter > RPL_COUNTER_LOWER_REGION) +#define RPL_COUNTER_GREATER_THAN_LOCAL(A,B) (((A B) && (A-B < RPL_COUNTER_SEQ_WINDOW))) +#define RPL_COUNTER_GREATER_THAN(A,B) ((A>RPL_COUNTER_LOWER_REGION) ? ((B > RPL_COUNTER_LOWER_REGION ) ? RPL_COUNTER_GREATER_THAN_LOCAL(A,B) : 0): (( B>RPL_COUNTER_LOWER_REGION ) ? 1: RPL_COUNTER_GREATER_THAN_LOCAL(A,B))) + +// Default values + +#define RPL_DEFAULT_MOP STORING_MODE_NO_MC + +// RPL Constants and Variables + +#define BASE_RANK 0 +#define ROOT_RANK 1 +#define INFINITE_RANK 0xFFFF +#define RPL_DEFAULT_INSTANCE 0 +#define DEFAULT_PATH_CONTROL_SIZE 0 +#define DEFAULT_DIO_INTERVAL_MIN 3 +#define DEFAULT_DIO_INTERVAL_DOUBLINGS 20 +#define DEFAULT_DIO_REDUNDANCY_CONSTANT 10 +#define DEFAULT_MIN_HOP_RANK_INCREASE 256 +#define DEFAULT_DAO_DELAY 1 + +//others + +#define RPL_MAX_DODAGS 3 +#define RPL_MAX_INSTANCES 1 +#define RPL_MAX_PARENTS 5 +#define RPL_ROOT_RANK 1 +#define RPL_DEFAULT_LIFETIME 0xff +#define RPL_LIFETIME_UNIT 0xffff +#define RPL_GROUNDED 1 +#define RPL_MOP_SHIFT 3 + +struct __attribute__((packed)) rpl_dio_t{ + uint8_t rpl_instanceid; + uint8_t version_number; + uint16_t rank; + uint8_t g_mop_prf; + uint8_t dtsn; + uint8_t flags; + uint8_t reserved; + ipv6_addr_t dodagid; +}; + +struct __attribute__((packed)) rpl_dis_t{ + uint8_t flags; + uint8_t reserved; +}; + +struct __attribute__((packed)) rpl_dao_t{ + uint8_t rpl_instanceid; + uint8_t k_d_flags; + uint8_t reserved; + uint8_t dao_sequence; +}; + +struct __attribute__((packed)) rpl_dao_ack_t{ + uint8_t rpl_instanceid; + uint8_t d_reserved; + uint8_t dao_sequence; + uint8_t status; +}; + +//may be present in dao or dao_ack packets +struct __attribute__((packed)) dodag_id_t{ + ipv6_addr_t dodagid; +}; +typedef struct __attribute__((packed)) rpl_opt_t { + uint8_t type; + uint8_t length; +} rpl_opt_t; + +typedef struct __attribute__((packed)) rpl_opt_dodag_conf_t { + uint8_t type; + uint8_t length; + uint8_t flags_a_pcs; + uint8_t DIOIntDoubl; + uint8_t DIOIntMin; + uint8_t DIORedun; + uint16_t MaxRankIncrease; + uint16_t MinHopRankIncrease; + uint16_t ocp; + uint8_t reserved; + uint8_t default_lifetime; + uint16_t lifetime_unit; +} rpl_opt_dodag_conf_t; + +struct rpl_dodag_t; + +typedef struct rpl_parent_t { + ipv6_addr_t addr; + uint16_t rank; + struct rpl_dodag_t *dodag; +} rpl_parent_t; + +struct rpl_of_t; + +typedef struct rpl_instance_t { + struct rpl_dodag_t *current_dodoag; + uint8_t id; + uint8_t used; + uint8_t joined; + +} rpl_instance_t; + +typedef struct rpl_dodag_t { + rpl_instance_t *instance; + ipv6_addr_t dodag_id; + uint8_t used; + uint8_t mop; + uint8_t dtsn; + uint8_t dio_interval_doubling; + uint8_t dio_min; + uint8_t dio_redundancy; + uint16_t maxrankincrease; + uint8_t minhoprankincrease; + uint8_t default_lifetime; + uint8_t lifetime_unit; + uint8_t version; + uint8_t grounded; + uint16_t my_rank; + uint8_t joined; + rpl_parent_t *my_preferred_parent; + struct rpl_of_t *of; + +} rpl_dodag_t; + +typedef struct rpl_of_t { + uint16_t ocp; + uint16_t (*calc_rank)(rpl_parent_t *, uint16_t); + rpl_parent_t *(*which_parent)(rpl_parent_t *, rpl_parent_t *); + rpl_dodag_t *(*which_dodag)(rpl_dodag_t *, rpl_dodag_t *); + void (*reset)(struct rpl_dodag_t *); + void (*parent_state_callback)(rpl_parent_t *, int, int); +} rpl_of_t; + diff --git a/sys/net/sixlowpan/rpl/trickle.c b/sys/net/sixlowpan/rpl/trickle.c new file mode 100644 index 0000000000..a9932b4eb4 --- /dev/null +++ b/sys/net/sixlowpan/rpl/trickle.c @@ -0,0 +1,56 @@ +#include +#include "sys/net/sixlowpan/sixlowip.h" + +#define ICMP_RPL_CM 155 + + +int test(void) +{ + ipv6_addr_t std_addr; + struct icmpv6_hdr_t icmphdr; + icmphdr.type = ICMP_RPL_CM; + + int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, 0, CREATE_SLEEPING, trickle_increment_counter, "count"); + hwtimer_init(); + +} + +//struct für trickle parameter?? +int reset_trickletimer(void){a + I = Imin; + c = 0; + //t = rand[I/2, I); + //start timer + + +} + +int init_trickle(int Imin, int Imax, int k){ + +//k = redundancy +// set 3 "constants" + +} + +int trickle_increment_counter(void){ + //call this function, when received DIO message + c++; +} + +int trickle_timer_over_callback(void) +{ + + if(c < k){ + + //send DIO message + + } +} + +int trickle_intervall_over_callback(void){ + I = I*2; + if(I > Imax) I=Imax; + c=0; + //start timer + +} diff --git a/sys/net/sixlowpan/rpl/trickle.h b/sys/net/sixlowpan/rpl/trickle.h new file mode 100644 index 0000000000..6ef350a2ce --- /dev/null +++ b/sys/net/sixlowpan/rpl/trickle.h @@ -0,0 +1,6 @@ +void reset_trickletimer(void); +void init_trickle(int Imin, int Imax, int k); +void increment_trickle_counter(void); +void trickle_timer_over_callback(void); +void trickke_intervall_over_callback(void); + diff --git a/sys/net/sixlowpan/sixlowip.c b/sys/net/sixlowpan/sixlowip.c index c277ccd97b..e4f369676c 100644 --- a/sys/net/sixlowpan/sixlowip.c +++ b/sys/net/sixlowpan/sixlowip.c @@ -11,6 +11,7 @@ #include "sys/net/destiny/socket.h" #include "sys/net/net_help/net_help.h" #include "sys/net/net_help/msg_help.h" +#include "sys/net/sixlowpan/rpl/rpl.h" uint8_t buffer[BUFFER_SIZE]; msg_t msg_queue[IP_PKT_RECV_BUF_SIZE]; @@ -20,6 +21,7 @@ uint8_t ipv6_ext_hdr_len; uint8_t *nextheader; iface_t iface; uint8_t iface_addr_list_count = 0; +uint8_t rpl_handler_flag = 0; int udp_packet_handler_pid = 0; int tcp_packet_handler_pid = 0; //uint8_t *udp_packet_buffer; @@ -100,6 +102,14 @@ int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) { recv_nbr_adv(); break; } + case(ICMP_RPL_CONTROL):{ + printf("INFO: packet type: RPL message\n"); + if(rpl_handler_flag) + rpl_icmp_handler(hdr->code); + else + printf("INFO: no RPL packt handling activated, packet will be dropped\n"); + break; + } default: return -1; } @@ -107,6 +117,10 @@ int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr) { return 0; } +void turn_on_rpl_handler(){ + rpl_handler_flag = 1; +} + void ipv6_process(void){ msg_t m_recv, m_send; msg_init_queue(msg_queue, IP_PKT_RECV_BUF_SIZE); diff --git a/sys/net/sixlowpan/sixlowip.h b/sys/net/sixlowpan/sixlowip.h index 6113ea9f94..2be33dbcfd 100644 --- a/sys/net/sixlowpan/sixlowip.h +++ b/sys/net/sixlowpan/sixlowip.h @@ -131,6 +131,7 @@ struct ipv6_hdr_t* get_ipv6_buf(void); uint8_t * get_payload_buf(uint8_t ext_len); int icmpv6_demultiplex(const struct icmpv6_hdr_t *hdr); +void turn_on_rpl_handler(void); void ipv6_init_iface_as_router(void); uint8_t ipv6_is_router(void); void ipv6_set_ll_prefix(ipv6_addr_t *ipaddr);