diff --git a/projects/test_beacon/main.c b/projects/test_beacon/main.c index eafd39d9d3..aa37ff4e0d 100644 --- a/projects/test_beacon/main.c +++ b/projects/test_beacon/main.c @@ -62,7 +62,9 @@ void table(char *str){ } void candidates(char *str){ + puts("++++++++++++candidates++++++++"); show_candidates(); + puts("++++++++++++end++++++++"); } const shell_command_t shell_commands[] = { diff --git a/sys/net/sixlowpan/rpl/etx_beaconing.c b/sys/net/sixlowpan/rpl/etx_beaconing.c index 398218c2d9..4837ebdac8 100644 --- a/sys/net/sixlowpan/rpl/etx_beaconing.c +++ b/sys/net/sixlowpan/rpl/etx_beaconing.c @@ -17,25 +17,35 @@ #include "sys/net/sixlowpan/sixlowmac.h" #include "sys/net/sixlowpan/ieee802154_frame.h" -#include "rpl_structs.h" #include "rpl_dodag.h" //For debugging purposes +#define ENABLE_DEBUG #include -//#define ENABLE_DEBUG -char etx_radio_buf[ETX_RADIO_STACKSIZE] = { 0 }; -char etx_update_buf[ETX_UPDT_STACKSIZE] = { 0 }; - -int etx_beacon_pid = 0; -int etx_radio_pid = 0; -int etx_update_pid = 0; +//prototytpes +static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate); +static void etx_set_packets_received(void); //Buffer +char etx_beacon_buf[ETX_BEACON_STACKSIZE] = { 0 }; +char etx_radio_buf[ETX_RADIO_STACKSIZE] = { 0 }; +char etx_clock_buf[ETX_CLOCK_STACKSIZE] = { 0 }; + uint8_t etx_send_buf[ETX_BUF_SIZE] = { 0 }; uint8_t etx_rec_buf[ETX_BUF_SIZE] = { 0 }; -char etx_beacon_buf[ETX_BEACON_STACKSIZE] = { 0 }; +//PIDs +int etx_beacon_pid = 0; +int etx_radio_pid = 0; +int etx_clock_pid = 0; + +/* + * xxx If you get a -Wmissing-braces warning here: + * A -Wmissing-braces warning at this point is a gcc-bug! + * Please delete this information once it's fixed + * See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 + */ //Message queue for radio msg_t msg_que[ETX_RCV_QUEUE_SIZE] = { 0 }; @@ -44,7 +54,12 @@ msg_t msg_que[ETX_RCV_QUEUE_SIZE] = { 0 }; * u-seconds and a node computes the ETX value by comparing the the received * probes vs the expected probes from a neighbor every ETX_ROUND intervals. */ -static uint8_t rounds = 0; +static uint8_t cur_round = 0; + +/* + * If we have not yet reached WINDOW intervals, won't calculate the ETX just yet + */ +static char reached_window = 0; /* * This could (and should) be done differently, once the RPL implementation @@ -54,11 +69,23 @@ static uint8_t rounds = 0; * needing them to be in our parent array, so we have another array here in * which we put all necessary info for up to RPL_MAX_CANDIDATE_NEIGHBORS * candidates. + * + * xxx If you get a -Wmissing-braces warning here: + * A -Wmissing-braces warning at this point is a gcc-bug! + * Please delete this information once it's fixed + * See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 */ -//Candidate array for candidate<==>parent matching -//Throws a warning, but this is the correct way to initialize! -static rpl_candidate_neighbor_t candidates[RPL_MAX_CANDIDATE_NEIGHBORS] = { 0 }; +//Candidate array +static etx_neighbor_t candidates[RPL_MAX_CANDIDATE_NEIGHBORS] = { 0 }; +/* + * Each time we send a beacon packet we need to reset some values for the + * current 'round' (a round being the time between each sent beacon packet). + * + * In this time, no packet may be handled, otherwise it could assume values + * from the last round to count for this round. + */ +//mutex_t etx_mutex; //Transceiver command for sending ETX probes transceiver_command_t tcmd; @@ -76,28 +103,33 @@ static etx_probe_t * get_etx_rec_buf(void) { } void show_candidates(void) { - rpl_candidate_neighbor_t * candidate; - rpl_candidate_neighbor_t *end; + etx_neighbor_t * candidate; + etx_neighbor_t *end; for (candidate = &candidates[0], end = candidates + RPL_MAX_CANDIDATE_NEIGHBORS; candidate < end; candidate++) { - DEBUG("Candidates Addr:%d\n" + if (candidate->used == 0) { + break; + } + printf("Candidates Addr:%d\n" "\t cur_etx:%f\n" "\t packets_rx:%d\n" + "\t packets_tx:%d\n" "\t used:%d\n", candidate->addr.uint8[ETX_IPV6_LAST_BYTE], candidate->cur_etx, candidate->packets_rx, + etx_count_packet_tx(candidate), candidate->used); } } void etx_init_beaconing(ipv6_addr_t * address) { + //mutex_init(&etx_mutex); own_address = address; //set code puts("ETX BEACON INIT"); - etx_send_buf[0] = ETX_BEACON; + etx_send_buf[0] = ETX_PKT_OPTVAL; - thread_print_all(); etx_beacon_pid = thread_create(etx_beacon_buf, ETX_BEACON_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, etx_beacon, "etx_beacon"); @@ -106,16 +138,9 @@ void etx_init_beaconing(ipv6_addr_t * address) { PRIORITY_MAIN - 1, CREATE_STACKTEST, etx_radio, "etx_radio"); - /* - * Maybe this should not be in a seperate thread resource-wise, but the - * motive was to delay beacon-sending as little as possible, as this would - * derail beaconing from the intended ETX_INTERVAL. - */ - - etx_update_pid = thread_create(etx_update_buf, ETX_UPDT_STACKSIZE, + etx_clock_pid = thread_create(etx_clock_buf, ETX_CLOCK_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, - etx_update, "etx_update"); - + etx_clock, "etx_clock"); //register at transceiver transceiver_register(TRANSCEIVER_CC1100, etx_radio_pid); puts("...[DONE]"); @@ -128,61 +153,61 @@ void etx_beacon(void) { * ETX_INTERVAL between the wakeups. It takes the old jittervalue in account * and modifies the time to wait accordingly. */ - etx_probe_t *etx_p = get_etx_send_buf(); - - /* - * The jittercorrection and jitter variables keep usecond values divided - * through 1000 to fit into uint8 variables. - * - * That is why they are multiplied by 1000 when used for hwtimer_wait. - */ - uint8_t jittercorrection = ETX_DEF_JIT_CORRECT; - uint8_t jitter = (uint8_t) (rand() % ETX_JITTER_MOD); - + uint8_t * etx_data = &etx_send_buf[ETX_PKT_DATA]; uint8_t p_length = 0; + /* + * xxx If you get a -Wmissing-braces warning here: + * A -Wmissing-braces warning at this point is a gcc-bug! + * Please delete this information once it's fixed + * See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 + */ ieee_802154_long_t empty_addr = { 0 }; - while (true) { - - if (rounds == ETX_ROUNDS) { - //calculate the ETX values and update the parents - thread_wakeup(etx_update_pid); - rounds = 1; - } else { - rounds++; + //Build first etx packet + for (uint8_t i = 0; i < RPL_MAX_CANDIDATE_NEIGHBORS; i++) { + if (candidates[i].used != 0) { + etx_data[i * ETX_TUPLE_SIZE] = + candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE]; + etx_data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET] = + etx_count_packet_tx(&candidates[i]); + p_length = p_length + ETX_TUPLE_SIZE; } + } + etx_send_buf[ETX_PKT_LEN] = p_length; + while (true) { + thread_sleep(); + //mutex_lock(&etx_mutex); + send_ieee802154_frame(&empty_addr, &etx_send_buf[0], + etx_send_buf[ETX_PKT_LEN] + ETX_PKT_HDR_LEN, 1); + DEBUG("sent beacon!\n"); + etx_set_packets_received(); + cur_round++; + if (cur_round == ETX_WINDOW) { + if (reached_window != 1) { + //first round is through + reached_window = 1; + } + cur_round = 0; + } + //mutex_unlock(&etx_mutex,0); //Build etx packet p_length = 0; for (uint8_t i = 0; i < RPL_MAX_CANDIDATE_NEIGHBORS; i++) { if (candidates[i].used != 0) { - etx_p->data[i * ETX_TUPLE_SIZE] = + etx_data[i * ETX_TUPLE_SIZE] = candidates[i].addr.uint8[ETX_IPV6_LAST_BYTE]; - etx_p->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET] = - candidates[i].packets_tx; + etx_data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET] = + etx_count_packet_tx(&candidates[i]); p_length = p_length + ETX_PKT_HDR_LEN; } } - etx_p->length = p_length; - - send_ieee802154_frame(&empty_addr, &etx_send_buf[0], - get_etx_send_buf()->length + ETX_PKT_HDR_LEN, 1); - puts("sent beacon!"); - //vtimer_usleep(((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection*MS + jitter*MS); - /// TODO once vtimer works as intended, replace the hwtimer here with - /// the vtimer. Right now vtimer bugs, so we have hwtimer here. - hwtimer_wait( - HWTIMER_TICKS(((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection*MS + jitter*MS)); - - jittercorrection = (ETX_MAX_JITTER) - jitter; - - //the jitter is a value between 0 and ETX_MAX_JITTER - jitter = (uint8_t) (rand() % ETX_JITTER_MOD); + etx_send_buf[ETX_PKT_LEN] = p_length; } } -rpl_candidate_neighbor_t * etx_find_candidate(ipv6_addr_t * address) { +etx_neighbor_t * etx_find_candidate(ipv6_addr_t * address) { /* * find the candidate with address address and returns it, or returns NULL * if no candidate having this address was found. @@ -196,16 +221,55 @@ rpl_candidate_neighbor_t * etx_find_candidate(ipv6_addr_t * address) { return NULL ; } +void etx_clock(void) { + /* + * Manages the etx_beacon thread to wake up every full second +- jitter + */ + + /* + * The jittercorrection and jitter variables keep usecond values divided + * through 1000 to fit into uint8 variables. + * + * That is why they are multiplied by 1000 when used for hwtimer_wait. + */ + uint8_t jittercorrection = ETX_DEF_JIT_CORRECT; + uint8_t jitter = (uint8_t) (rand() % ETX_JITTER_MOD); + + while (true) { + thread_wakeup(etx_beacon_pid); + + /* + * Vtimer is buggy, but I seem to have no hwtimers left, so using this + * for now. + */ + vtimer_usleep( + ((ETX_INTERVAL - ETX_MAX_JITTER)*MS)+ jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST); + + //hwtimer_wait( + // HWTIMER_TICKS(((ETX_INTERVAL - ETX_MAX_JITTER)*MS) + jittercorrection*MS + jitter*MS - ETX_CLOCK_ADJUST)); + + jittercorrection = (ETX_MAX_JITTER) - jitter; + jitter = (uint8_t) (rand() % ETX_JITTER_MOD); + } +} + double etx_get_metric(ipv6_addr_t * address) { - rpl_candidate_neighbor_t * candidate = etx_find_candidate(address); + etx_neighbor_t * candidate = etx_find_candidate(address); if (candidate != NULL ) { - return candidate->packets_rx / (double) ETX_ROUNDS; + if (etx_count_packet_tx(candidate) > 0) { + //this means the current etx_value is not outdated + return candidate->cur_etx; + } else { + //The last time I received a packet is too long ago to give a + //good estimate of the etx value + return 0; + } } return 0; } -rpl_candidate_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { - puts("add candidate"); +etx_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { + DEBUG("add candidate\n"); /* * Pre-Condition: etx_add_candidate should only be called when the * candidate is not yet in the list. @@ -227,8 +291,8 @@ rpl_candidate_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { * Returns the pointer to the candidate if it was added, or a NULL-pointer * otherwise. */ - rpl_candidate_neighbor_t * candidate; - rpl_candidate_neighbor_t * end; + etx_neighbor_t * candidate; + etx_neighbor_t * end; for (candidate = &candidates[0], end = candidates + RPL_MAX_CANDIDATE_NEIGHBORS; candidate < end; @@ -238,9 +302,9 @@ rpl_candidate_neighbor_t * etx_add_candidate(ipv6_addr_t * address) { continue; } else { //We still have a free place add the new candidate + memset(candidate, 0, sizeof(*candidate)); candidate->addr = *address; candidate->cur_etx = 0; - candidate->packets_tx = 0; candidate->packets_rx = 0; candidate->used = 1; return candidate; @@ -255,15 +319,14 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) { * If the candidate address is unknown, try to add it to my struct. */ - etx_probe_t * probe = get_etx_rec_buf(); - - DEBUG("ETX beacon package received with following values:\n" + DEBUG( + "ETX beacon package received with following values:\n" "\tPackage Option:%x\n" "\t Data Length:%u\n" - "\tSource Address:%d\n\n", probe->code, probe->length, + "\tSource Address:%d\n\n", etx_rec_buf[ETX_PKT_OPT], etx_rec_buf[ETX_PKT_LEN], candidate_address->uint8[ETX_IPV6_LAST_BYTE]); - rpl_candidate_neighbor_t* candidate = etx_find_candidate(candidate_address); + etx_neighbor_t* candidate = etx_find_candidate(candidate_address); if (candidate == NULL ) { //Candidate was not found in my list, I should add it candidate = etx_add_candidate(candidate_address); @@ -274,23 +337,30 @@ void etx_handle_beacon(ipv6_addr_t * candidate_address) { } } - //I have received 1 more packet from this candidate - candidate->packets_tx = candidate->packets_tx + 1; + //I have received 1 packet from this candidate in this round + //This value will be reset by etx_update to 0 + candidate->tx_cur_round = 1; // If i find my address in this probe, update the packet_rx value for // this candidate. - for (uint8_t i = 0; i < probe->length / ETX_TUPLE_SIZE; i++) { - DEBUG("\tIPv6 short Addr:%u\n" - "\tPackets f. Addr:%u\n\n", probe->data[i * ETX_TUPLE_SIZE], - probe->data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]); + uint8_t datalength = etx_rec_buf[ETX_PKT_LEN]; + uint8_t * rec_data = &etx_rec_buf[ETX_PKT_DATA]; - if (probe->data[i * ETX_TUPLE_SIZE] + for (uint8_t i = 0; i < datalength / ETX_TUPLE_SIZE; i++) { + DEBUG("\tIPv6 short Addr:%u\n" + "\tPackets f. Addr:%u\n\n", rec_data[i * ETX_TUPLE_SIZE], + rec_data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]); + + if (rec_data[i * ETX_TUPLE_SIZE] == own_address->uint8[ETX_IPV6_LAST_BYTE]) { - candidate->packets_rx = probe->data[i * ETX_TUPLE_SIZE + candidate->packets_rx = rec_data[i * ETX_TUPLE_SIZE + ETX_PKT_REC_OFFSET]; } } + + //Last, update the ETX value for this candidate + etx_update(candidate); } void etx_radio(void) { @@ -314,7 +384,7 @@ void etx_radio(void) { read_802154_frame(p->data, &frame, p->length); - if (frame.payload[0] == ETX_BEACON) { + if (frame.payload[0] == ETX_PKT_OPTVAL) { //copy to receive buffer memcpy(etx_rec_buf, &frame.payload[0], frame.payload_len); @@ -323,7 +393,9 @@ void etx_radio(void) { //up to 8 bits candidate_addr.uint8[ETX_IPV6_LAST_BYTE] = (uint8_t) p->src; //handle the beacon + //mutex_lock(&etx_mutex); etx_handle_beacon(&candidate_addr); + //mutex_unlock(&etx_mutex,0); } p->processing--; @@ -337,39 +409,105 @@ void etx_radio(void) { } } -void etx_update(void) { +void etx_update(etx_neighbor_t * candidate) { + DEBUG("update!\n"); /* - * Update the current ETX values, then - * reset the received packet count for the candidates. - * - * This thread should never take very long, as it has to be done in less - * than (ETX_INTERVAL - maximum jitter), otherwise the ETX calculation might - * be faulty. TODO delete this once mutexes are in place - * + * Update the current ETX value of a candidate */ - rpl_candidate_neighbor_t * candidate; - rpl_candidate_neighbor_t * end; + double d_f; + double d_r; - while (true) { - //good night - thread_sleep(); - //Wait a tiny bit to allow for the last packet to be processed - hwtimer_wait(HWTIMER_TICKS(200)); + if (reached_window != 1 || candidate == NULL ) { + //We will wait at least ETX_WINDOW beacons until we decide to + //calculate an ETX value, so that we have a good estimate + return; + } - for (candidate = &candidates[0], end = candidates - + RPL_MAX_CANDIDATE_NEIGHBORS; candidate < end; - candidate++) { + /* + * Calculate d_f (the forward PDR) from ME to this candidate. + */ + d_f = candidate->packets_rx / (double) ETX_WINDOW; - if (candidate->used != 0) { - //update its ETX-metric and packet count TODO mutex this - //TODO probably better to change floating point-math to integer - //based math - candidate->cur_etx = - candidate->packets_rx / (double) ETX_ROUNDS; - candidate->packets_rx = 0; - DEBUG( - "Updated ETX Metric to %f for candidate used was on %d", - candidate->cur_etx, candidate->used); + /* + * Calculate d_r (the backwards PDR) from this candidate to ME + */ + d_r = etx_count_packet_tx(candidate) / (double) ETX_WINDOW; + + /* + * Calculate the current ETX value for my link to this candidate. + */ + if (d_f * d_r != 0) { + candidate->cur_etx = 1 / (d_f * d_r); + } else { + candidate->cur_etx = 0; + } + + DEBUG( + "Estimated ETX Metric is %f for candidate w/ addr %d\n" + "Estimated PDR_forward is %f\n" + "Estimated PDR_backwrd is %f\n" + "\n" + "Received Packets: %d\n" + "Sent Packets : %d\n\n", + candidate->cur_etx, candidate->addr.uint8[ETX_IPV6_LAST_BYTE], + d_f, d_r, candidate->packets_rx, etx_count_packet_tx(candidate)); +} + +static uint8_t etx_count_packet_tx(etx_neighbor_t * candidate) { + /* + * Counts the number of packets that were received for this candidate + * in the last ETX_WINDOW intervals. + */ + puts("counting packets"); + uint8_t pkt_count = 0; + DEBUG("["); + for (uint8_t i = 0; i < ETX_WINDOW; i++) { + if (i != cur_round) { + pkt_count = pkt_count + candidate->packets_tx[i]; +#ifdef ENABLE_DEBUG //so ugly delete TODO + DEBUG("%d",candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { + DEBUG(","); + } +#endif + } else { + //Check if I received something for the current round + if (candidate->tx_cur_round == 0) { + //Didn't receive a packet, zero the field and don't add + candidate->packets_tx[i] = 0; +#ifdef ENABLE_DEBUG + DEBUG("%d",candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { + DEBUG(","); + } +#endif + } else { + DEBUG("Received packet in ROUND%d!\n", i); + //Add 1 and set field + pkt_count = pkt_count + 1; + candidate->packets_tx[i] = 1; +#ifdef ENABLE_DEBUG + DEBUG("%d",candidate->packets_tx[i]); + if (i < ETX_WINDOW - 1) { + DEBUG(","); + } +#endif + } + } + } + DEBUG("]\n"); + return pkt_count; +} + +static void etx_set_packets_received(void) { + /* + * Set for all candidates if they received a packet this round or not + */ + for (uint8_t i = 0; i < RPL_MAX_CANDIDATE_NEIGHBORS; i++) { + if (candidates[i].used) { + if (candidates[i].tx_cur_round != 0) { + candidates[i].packets_tx[cur_round] = 1; + candidates[i].tx_cur_round = 0; } } } diff --git a/sys/net/sixlowpan/rpl/etx_beaconing.h b/sys/net/sixlowpan/rpl/etx_beaconing.h index 8dcf3b30b4..a2dbfd751f 100644 --- a/sys/net/sixlowpan/rpl/etx_beaconing.h +++ b/sys/net/sixlowpan/rpl/etx_beaconing.h @@ -12,9 +12,9 @@ #include "sys/net/sixlowpan/sixlowip.h" //4908 is available stack size -#define ETX_BEACON_STACKSIZE 2000 //TODO debug stacksize, set for production -#define ETX_RADIO_STACKSIZE 2000 //TODO debug stacksize, set for production -#define ETX_UPDT_STACKSIZE 908 //TODO debug stacksize, set for production +#define ETX_BEACON_STACKSIZE 4500 //TODO debug stacksize, set for production +#define ETX_RADIO_STACKSIZE 4500 //TODO debug stacksize, set for production +#define ETX_CLOCK_STACKSIZE 4500 //TODO debug stacksize, set for production //[option|length|ipaddr.|packetcount] with up to 15 ipaddr|packetcount pairs @@ -25,8 +25,6 @@ //Constants for packets -//ETX beaconing type (XXX ATTENTION! this is non-standard) -#define ETX_BEACON 0x20//Non-standard way of saying this is an etx-pkt. //ETX Interval parameters #define MS 1000 @@ -39,21 +37,14 @@ * and 5 (For ETX_MAX_JITTER) unless those values are adjusted too. */ #define ETX_INTERVAL (1000) -#define ETX_ROUNDS (10) //10 is the default value -#define ETX_PKT_HDR_LEN (2) //Option type + Length (1 Byte each) +#define ETX_WINDOW (10) //10 is the default value #define ETX_TUPLE_SIZE (2) //1 Byte for Addr, 1 Byte for packets rec. #define ETX_PKT_REC_OFFSET (ETX_TUPLE_SIZE - 1) //Offset in a tuple of (addr,pkt_rec), will always be the last byte #define ETX_IPV6_LAST_BYTE (15) //The last byte for an ipv6 address #define ETX_MAX_JITTER (ETX_INTERVAL / 5) //The default value is 20% of ETX_INTERVAL #define ETX_JITTER_MOD (ETX_MAX_JITTER + 1) //The modulo value for jitter computation #define ETX_DEF_JIT_CORRECT (ETX_MAX_JITTER / 2) //Default Jitter correction value (normally ETX_MAX_JITTER / 2) - -//prototypes -void etx_init_beaconing(ipv6_addr_t * address); -void etx_beacon(void); -double etx_get_metric(ipv6_addr_t * address); -void etx_update(void); -void etx_radio(void); +#define ETX_CLOCK_ADJUST (52500) //Adjustment for clockthread computations to stay close/near ETX_INTERVAL /* * The ETX beaconing packet consists of: @@ -76,11 +67,33 @@ void etx_radio(void); * If the length of this packet says 0, it has received no other beaconing * packets itself so far. */ -typedef struct __attribute__((packed)) { +typedef struct __attribute__((packed)) etx_probe_t{ uint8_t code; uint8_t length; uint8_t* data; } etx_probe_t; +typedef struct etx_neighbor_t { + ipv6_addr_t addr; //The address of this node + uint8_t tx_cur_round; //The indicator for receiving a packet from this candidate this round + uint8_t packets_tx[10]; //The packets this node has transmitted TO ME + uint8_t packets_rx; //The packets this node has received FROM ME + double cur_etx; //The currently calculated ETX-value + uint8_t used; //The indicator if this node is active or not +} etx_neighbor_t; + +//prototypes +void etx_init_beaconing(ipv6_addr_t * address); +void etx_beacon(void); +void etx_clock(void); +double etx_get_metric(ipv6_addr_t * address); +void etx_update(etx_neighbor_t * neighbor); +void etx_radio(void); + +#define ETX_PKT_OPT (0) //Position of Option-Type-Byte +#define ETX_PKT_OPTVAL (0x20) //Non-standard way of saying this is an ETX-Packet. +#define ETX_PKT_LEN (1) //Position of Length-Byte +#define ETX_PKT_HDR_LEN (2) //Option type + Length (1 Byte each) +#define ETX_PKT_DATA (2) //Begin of Data Bytes #endif /* ETX_BEACONING_H_ */ diff --git a/sys/net/sixlowpan/rpl/of_mrhof.c b/sys/net/sixlowpan/rpl/of_mrhof.c index c76082c892..1eeac0d8dc 100644 --- a/sys/net/sixlowpan/rpl/of_mrhof.c +++ b/sys/net/sixlowpan/rpl/of_mrhof.c @@ -2,6 +2,8 @@ #include #include "of_mrhof.h" +#include "etx_beaconing.h" + // Function Prototypes static uint16_t calc_rank(rpl_parent_t *, uint16_t); static rpl_parent_t *which_parent(rpl_parent_t *, rpl_parent_t *); @@ -39,7 +41,7 @@ static uint16_t calc_path_cost(rpl_parent_t * parent) { return DEFAULT_MIN_HOP_RANK_INCREASE; } - double etx_value = etx_get_metric(parent->addr); + double etx_value = etx_get_metric(&(parent->addr)); if (etx_value != 0) { /* * (ETX_for_link_to_neighbor * 128) + Rank_of_that_neighbor diff --git a/sys/net/sixlowpan/rpl/rpl_structs.h b/sys/net/sixlowpan/rpl/rpl_structs.h index a71d600514..94851bd17c 100644 --- a/sys/net/sixlowpan/rpl/rpl_structs.h +++ b/sys/net/sixlowpan/rpl/rpl_structs.h @@ -204,14 +204,6 @@ typedef struct __attribute__((packed)) rpl_opt_transit_t { struct rpl_dodag_t; -typedef struct rpl_candidate_neighbor_t { - ipv6_addr_t addr; //The address of this node - uint8_t packets_tx; //The packets this node has transmitted TO ME - uint8_t packets_rx; //The packets this node has received FROM ME - double cur_etx; //The currently calculated ETX-value - uint8_t used; //The indicator if this node is active or not -} rpl_candidate_neighbor_t; - typedef struct rpl_parent_t { ipv6_addr_t addr; uint16_t rank; diff --git a/sys/net/sixlowpan/rpl/trickle.c b/sys/net/sixlowpan/rpl/trickle.c index eca3eb66fc..8a7d3d6b3c 100644 --- a/sys/net/sixlowpan/rpl/trickle.c +++ b/sys/net/sixlowpan/rpl/trickle.c @@ -5,9 +5,10 @@ #include "trickle.h" #include "sys/net/sixlowpan/rpl/rpl.h" -char timer_over_buf[TRICKLE_TIMER_STACKSIZE]; -char interval_over_buf[TRICKLE_INTERVAL_STACKSIZE]; -char dao_delay_over_buf[DAO_DELAY_STACKSIZE]; +//TODO in pointer umwandeln, speicher mit malloc holen +char * timer_over_buf; +char * interval_over_buf; +char * dao_delay_over_buf; char routing_table_buf[RT_STACKSIZE]; int timer_over_pid; int interval_over_pid; @@ -50,6 +51,24 @@ void reset_trickletimer(void){ } void init_trickle(void){ + puts("trickle init!"); + //malloc thread stacks + timer_over_buf = malloc(TRICKLE_TIMER_STACKSIZE*sizeof(char)); + if(timer_over_buf == NULL){ + puts("[ERROR] Could not allocate enough memory for timer_over_buf!"); + return; + } + interval_over_buf = malloc(TRICKLE_INTERVAL_STACKSIZE*sizeof(char)); + if(interval_over_buf == NULL){ + puts("[ERROR] Could not allocate enough memory for interval_over_buf!"); + return; + } + dao_delay_over_buf = malloc(DAO_DELAY_STACKSIZE*sizeof(char)); + if(dao_delay_over_buf == NULL){ + puts("[ERROR] Could not allocate enough memory for interval_over_buf!"); + return; + } + //Create threads ack_received = true; timer_over_pid = thread_create(timer_over_buf, TRICKLE_TIMER_STACKSIZE,