Make phase module use neighbor-table.

This commit is contained in:
Simon Duquennoy 2013-07-03 19:14:10 +02:00
parent cfb3bbdad9
commit 5a1d8d8006
3 changed files with 35 additions and 94 deletions

View file

@ -255,16 +255,6 @@ static struct compower_activity current_packet;
#include "net/mac/phase.h"
#ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
#endif
#ifndef MAX_PHASE_NEIGHBORS
#define MAX_PHASE_NEIGHBORS 30
#endif
PHASE_LIST(phase_list, MAX_PHASE_NEIGHBORS);
#endif /* WITH_PHASE_OPTIMIZATION */
#define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
@ -665,7 +655,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
if(!is_broadcast && !is_receiver_awake) {
#if WITH_PHASE_OPTIMIZATION
ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
CYCLE_TIME, GUARD_TIME,
mac_callback, mac_callback_ptr, buf_list);
if(ret == PHASE_DEFERRED) {
@ -865,7 +855,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
if(!is_broadcast) {
if(collisions == 0 && is_receiver_awake == 0) {
phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
phase_update(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
encounter_time, ret);
}
}
@ -1049,7 +1039,7 @@ init(void)
contikimac_is_on = 1;
#if WITH_PHASE_OPTIMIZATION
phase_init(&phase_list);
phase_init();
#endif /* WITH_PHASE_OPTIMIZATION */
}

View file

@ -40,11 +40,24 @@
#include "net/mac/phase.h"
#include "net/packetbuf.h"
#include "sys/clock.h"
#include "lib/memb.h"
#include "sys/ctimer.h"
#include "net/queuebuf.h"
#include "dev/watchdog.h"
#include "dev/leds.h"
#include "net/neighbor-table.h"
#if PHASE_CONF_DRIFT_CORRECT
#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
#else
#define PHASE_DRIFT_CORRECT 0
#endif
struct phase {
rtimer_clock_t time;
#if PHASE_DRIFT_CORRECT
rtimer_clock_t drift;
#endif
uint8_t noacks;
struct timer noacks_timer;
};
struct phase_queueitem {
struct ctimer timer;
@ -62,6 +75,7 @@ struct phase_queueitem {
#define MAX_NOACKS_TIME CLOCK_SECOND * 30
MEMB(queued_packets_memb, struct phase_queueitem, PHASE_QUEUESIZE);
NEIGHBOR_TABLE(struct phase, nbr_phase);
#define DEBUG 0
#if DEBUG
@ -73,38 +87,14 @@ MEMB(queued_packets_memb, struct phase_queueitem, PHASE_QUEUESIZE);
#define PRINTDEBUG(...)
#endif
/*---------------------------------------------------------------------------*/
struct phase *
find_neighbor(const struct phase_list *list, const rimeaddr_t *addr)
{
struct phase *e;
for(e = list_head(*list->list); e != NULL; e = list_item_next(e)) {
if(rimeaddr_cmp(addr, &e->neighbor)) {
return e;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
phase_remove(const struct phase_list *list, const rimeaddr_t *neighbor)
{
struct phase *e;
e = find_neighbor(list, neighbor);
if(e != NULL) {
list_remove(*list->list, e);
memb_free(list->memb, e);
}
}
/*---------------------------------------------------------------------------*/
void
phase_update(const struct phase_list *list,
const rimeaddr_t *neighbor, rtimer_clock_t time,
phase_update(const rimeaddr_t *neighbor, rtimer_clock_t time,
int mac_status)
{
struct phase *e;
/* If we have an entry for this neighbor already, we renew it. */
e = find_neighbor(list, neighbor);
e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
if(e != NULL) {
if(mac_status == MAC_TX_OK) {
#if PHASE_DRIFT_CORRECT
@ -123,8 +113,7 @@ phase_update(const struct phase_list *list,
}
if(e->noacks >= MAX_NOACKS || timer_expired(&e->noacks_timer)) {
PRINTF("drop %d\n", neighbor->u8[0]);
list_remove(*list->list, e);
memb_free(list->memb, e);
nbr_table_remove(nbr_phase, e);
return;
}
} else if(mac_status == MAC_TX_OK) {
@ -133,20 +122,14 @@ phase_update(const struct phase_list *list,
} else {
/* No matching phase was found, so we allocate a new one. */
if(mac_status == MAC_TX_OK && e == NULL) {
e = memb_alloc(list->memb);
if(e == NULL) {
PRINTF("phase alloc NULL\n");
/* We could not allocate memory for this phase, so we drop
the last item on the list and reuse it for our phase. */
e = list_chop(*list->list);
}
rimeaddr_copy(&e->neighbor, neighbor);
e->time = time;
e = nbr_table_add_lladdr(nbr_phase, neighbor);
if(e) {
e->time = time;
#if PHASE_DRIFT_CORRECT
e->drift = 0;
#endif
e->noacks = 0;
list_push(*list->list, e);
}
}
}
}
@ -168,8 +151,7 @@ send_packet(void *ptr)
}
/*---------------------------------------------------------------------------*/
phase_status_t
phase_wait(struct phase_list *list,
const rimeaddr_t *neighbor, rtimer_clock_t cycle_time,
phase_wait(const rimeaddr_t *neighbor, rtimer_clock_t cycle_time,
rtimer_clock_t guard_time,
mac_callback_t mac_callback, void *mac_callback_ptr,
struct rdc_buf_list *buf_list)
@ -180,7 +162,7 @@ phase_wait(struct phase_list *list,
phase for this particular neighbor. If so, we can compute the
time for the next expected phase and setup a ctimer to switch on
the radio just before the phase. */
e = find_neighbor(list, neighbor);
e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
if(e != NULL) {
rtimer_clock_t wait, now, expected, sync;
clock_time_t ctimewait;
@ -242,15 +224,12 @@ phase_wait(struct phase_list *list,
p->buf_list = buf_list;
ctimer_set(&p->timer, ctimewait, send_packet, p);
return PHASE_DEFERRED;
} else {
memb_free(&queued_packets_memb, p);
}
}
expected = now + wait - guard_time;
if(!RTIMER_CLOCK_LT(expected, now)) {
/* Wait until the receiver is expected to be awake */
// printf("%d ",expected%cycle_time); //for spreadsheet export
while(RTIMER_CLOCK_LT(RTIMER_NOW(), expected));
}
return PHASE_SEND_NOW;
@ -259,10 +238,9 @@ phase_wait(struct phase_list *list,
}
/*---------------------------------------------------------------------------*/
void
phase_init(struct phase_list *list)
phase_init(void)
{
list_init(*list->list);
memb_init(list->memb);
memb_init(&queued_packets_memb);
nbr_table_register(nbr_phase, NULL);
}
/*---------------------------------------------------------------------------*/

View file

@ -47,28 +47,6 @@
#include "lib/memb.h"
#include "net/netstack.h"
#if PHASE_CONF_DRIFT_CORRECT
#define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
#else
#define PHASE_DRIFT_CORRECT 0
#endif
struct phase {
struct phase *next;
rimeaddr_t neighbor;
rtimer_clock_t time;
#if PHASE_DRIFT_CORRECT
rtimer_clock_t drift;
#endif
uint8_t noacks;
struct timer noacks_timer;
};
struct phase_list {
list_t *list;
struct memb *memb;
};
typedef enum {
PHASE_UNKNOWN,
PHASE_SEND_NOW,
@ -76,18 +54,13 @@ typedef enum {
} phase_status_t;
#define PHASE_LIST(name, num) LIST(phase_list_list); \
MEMB(phase_list_memb, struct phase, num); \
struct phase_list name = { &phase_list_list, &phase_list_memb }
void phase_init(struct phase_list *list);
phase_status_t phase_wait(struct phase_list *list, const rimeaddr_t *neighbor,
void phase_init(void);
phase_status_t phase_wait(const rimeaddr_t *neighbor,
rtimer_clock_t cycle_time, rtimer_clock_t wait_before,
mac_callback_t mac_callback, void *mac_callback_ptr,
struct rdc_buf_list *buf_list);
void phase_update(const struct phase_list *list, const rimeaddr_t *neighbor,
void phase_update(const rimeaddr_t *neighbor,
rtimer_clock_t time, int mac_status);
void phase_remove(const struct phase_list *list, const rimeaddr_t *neighbor);
void phase_remove(const rimeaddr_t *neighbor);
#endif /* PHASE_H */