42 #include "sys/clock.h"
45 #include "net/nbr-table.h"
47 #if PHASE_CONF_DRIFT_CORRECT
48 #define PHASE_DRIFT_CORRECT PHASE_CONF_DRIFT_CORRECT
50 #define PHASE_DRIFT_CORRECT 0
55 #if PHASE_DRIFT_CORRECT
59 struct timer noacks_timer;
62 struct phase_queueitem {
64 mac_callback_t mac_callback;
65 void *mac_callback_ptr;
67 struct rdc_buf_list *buf_list;
70 #define PHASE_DEFER_THRESHOLD 1
71 #define PHASE_QUEUESIZE 8
75 #define MAX_NOACKS_TIME CLOCK_SECOND * 30
77 MEMB(queued_packets_memb,
struct phase_queueitem, PHASE_QUEUESIZE);
78 NBR_TABLE(
struct phase, nbr_phase);
83 #define PRINTF(...) printf(__VA_ARGS__)
84 #define PRINTDEBUG(...) printf(__VA_ARGS__)
87 #define PRINTDEBUG(...)
91 phase_update(
const linkaddr_t *neighbor, rtimer_clock_t time,
97 e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
100 #if PHASE_DRIFT_CORRECT
101 e->drift = time-e->time;
109 PRINTF(
"phase noacks %d to %d.%d\n", e->noacks, neighbor->u8[0], neighbor->u8[1]);
112 timer_set(&e->noacks_timer, MAX_NOACKS_TIME);
114 if(e->noacks >= MAX_NOACKS ||
timer_expired(&e->noacks_timer)) {
115 PRINTF(
"drop %d\n", neighbor->u8[0]);
116 nbr_table_remove(nbr_phase, e);
125 e = nbr_table_add_lladdr(nbr_phase, neighbor);
128 #if PHASE_DRIFT_CORRECT
138 send_packet(
void *ptr)
140 struct phase_queueitem *p = ptr;
142 if(p->buf_list ==
NULL) {
143 queuebuf_to_packetbuf(p->q);
145 NETSTACK_RDC.send(p->mac_callback, p->mac_callback_ptr);
147 NETSTACK_RDC.send_list(p->mac_callback, p->mac_callback_ptr, p->buf_list);
154 phase_wait(
const linkaddr_t *neighbor, rtimer_clock_t cycle_time,
155 rtimer_clock_t guard_time,
156 mac_callback_t mac_callback,
void *mac_callback_ptr,
157 struct rdc_buf_list *buf_list)
165 e = nbr_table_get_from_lladdr(nbr_phase, neighbor);
167 rtimer_clock_t wait, now, expected, sync;
168 clock_time_t ctimewait;
186 sync = (e ==
NULL) ? now : e->time;
188 #
if PHASE_DRIFT_CORRECT
191 if(e->drift > cycle_time) {
192 s = e->drift % cycle_time / (e->drift / cycle_time);
193 s = s * (now - sync) / cycle_time;
200 if(!(cycle_time & (cycle_time - 1))) {
202 wait = (rtimer_clock_t)((sync - now) & (cycle_time - 1));
205 wait = cycle_time - (rtimer_clock_t)((now - sync) % cycle_time);
208 if(wait < guard_time) {
212 ctimewait = (
CLOCK_SECOND * (wait - guard_time)) / RTIMER_ARCH_SECOND;
214 if(ctimewait > PHASE_DEFER_THRESHOLD) {
215 struct phase_queueitem *p;
219 if(buf_list ==
NULL) {
220 p->q = queuebuf_new_from_packetbuf();
222 p->mac_callback = mac_callback;
223 p->mac_callback_ptr = mac_callback_ptr;
224 p->buf_list = buf_list;
225 ctimer_set(&p->timer, ctimewait, send_packet, p);
226 return PHASE_DEFERRED;
230 expected = now + wait - guard_time;
231 if(!RTIMER_CLOCK_LT(expected, now)) {
233 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), expected));
235 return PHASE_SEND_NOW;
237 return PHASE_UNKNOWN;
244 nbr_table_register(nbr_phase,
NULL);