Fixed ETX calculations
This commit is contained in:
parent
7e54f7ea5f
commit
b22e80b806
@ -62,7 +62,9 @@ void table(char *str){
|
||||
}
|
||||
|
||||
void candidates(char *str){
|
||||
puts("++++++++++++candidates++++++++");
|
||||
show_candidates();
|
||||
puts("++++++++++++end++++++++");
|
||||
}
|
||||
|
||||
const shell_command_t shell_commands[] = {
|
||||
|
||||
@ -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 <debug.h>
|
||||
//#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_ */
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include <stdio.h>
|
||||
#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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user