diff --git a/core/net/mac/contikimac.c b/core/net/mac/contikimac.c index 9021fda21..66faafa5f 100644 --- a/core/net/mac/contikimac.c +++ b/core/net/mac/contikimac.c @@ -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 */ } diff --git a/core/net/mac/phase.c b/core/net/mac/phase.c index ac29c4afa..f7e48bcab 100644 --- a/core/net/mac/phase.c +++ b/core/net/mac/phase.c @@ -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); } /*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/phase.h b/core/net/mac/phase.h index 8025d2c13..c605d7565 100644 --- a/core/net/mac/phase.h +++ b/core/net/mac/phase.h @@ -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 */