55 #include "dev/radio-sensor.h"
57 #include "lib/random.h"
63 static const struct packetbuf_attrlist attributes[] =
74 #define NUM_RECENT_PACKETS 16
76 struct recent_packet {
77 struct collect_conn *conn;
78 rimeaddr_t originator;
82 static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
83 static uint8_t recent_packet_ptr;
106 uint8_t
flags, dummy;
110 #define ACK_FLAGS_CONGESTED 0x80
111 #define ACK_FLAGS_DROPPED 0x40
112 #define ACK_FLAGS_LIFETIME_EXCEEDED 0x20
113 #define ACK_FLAGS_RTMETRIC_NEEDS_UPDATE 0x10
127 #define MAX_MAC_REXMITS 2
128 #define MAX_ACK_MAC_REXMITS 5
129 #define REXMIT_TIME CLOCK_SECOND * 4
130 #define FORWARD_PACKET_LIFETIME_BASE REXMIT_TIME * 2
131 #define MAX_SENDING_QUEUE 3 * QUEUEBUF_NUM / 4
132 #define MIN_AVAILABLE_QUEUE_ENTRIES 4
133 #define KEEPALIVE_REXMITS 8
134 #define MAX_REXMITS 31
142 #define RTMETRIC_SINK 0
143 #define RTMETRIC_MAX COLLECT_MAX_DEPTH
149 #define SIGNIFICANT_RTMETRIC_PARENT_CHANGE (COLLECT_LINK_ESTIMATE_UNIT + \
150 COLLECT_LINK_ESTIMATE_UNIT / 2)
154 #define MAX_HOPLIM 15
161 #define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
162 #define PROACTIVE_PROBING_REXMITS 15
167 #ifdef ANNOUNCEMENT_CONF_PERIOD
168 #define ANNOUNCEMENT_SCAN_TIME ANNOUNCEMENT_CONF_PERIOD
170 #define ANNOUNCEMENT_SCAN_TIME CLOCK_SECOND
200 #define PRINTF(...) printf(__VA_ARGS__)
206 static void send_queued_packet(
struct collect_conn *c);
207 static void retransmit_callback(
void *ptr);
208 static void retransmit_not_sent_callback(
void *ptr);
209 static void set_keepalive_timer(
struct collect_conn *c);
219 rtmetric_compute(
struct collect_conn *tc)
221 struct collect_neighbor *n;
222 uint16_t rtmetric = RTMETRIC_MAX;
231 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
236 rtmetric = RTMETRIC_MAX;
240 rtmetric = collect_neighbor_rtmetric_link_estimate(n);
252 bump_advertisement(
struct collect_conn *c)
254 #if !COLLECT_ANNOUNCEMENTS
255 neighbor_discovery_start(&c->neighbor_discovery_conn, c->rtmetric);
269 update_parent(
struct collect_conn *tc)
271 struct collect_neighbor *current;
272 struct collect_neighbor *best;
275 current = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
279 best = collect_neighbor_list_best(&tc->neighbor_list);
299 rimeaddr_t previous_parent;
305 if(current ==
NULL) {
307 PRINTF(
"update_parent: new parent %d.%d\n",
308 best->addr.u8[0], best->addr.u8[1]);
311 bump_advertisement(tc);
314 printf(
"#A e=%d\n", collect_neighbor_link_estimate(best));
316 if(collect_neighbor_rtmetric_link_estimate(best) +
317 SIGNIFICANT_RTMETRIC_PARENT_CHANGE <
318 collect_neighbor_rtmetric_link_estimate(current)) {
321 PRINTF(
"update_parent: new parent %d.%d (%d) old parent %d.%d (%d)\n",
322 best->addr.u8[0], best->addr.u8[1],
323 collect_neighbor_rtmetric(best),
324 tc->parent.u8[0], tc->parent.u8[1],
325 collect_neighbor_rtmetric(current));
330 bump_advertisement(tc);
333 printf(
"#A e=%d\n", collect_neighbor_link_estimate(best));
347 printf(
"#A e=%d\n", collect_neighbor_link_estimate(current));
364 printf(
"#L %d 0\n", previous_parent.u8[0]);
366 printf(
"#L %d 1\n", tc->parent.u8[0]);
373 printf(
"#L %d 0\n", tc->parent.u8[0]);
390 update_rtmetric(
struct collect_conn *tc)
392 PRINTF(
"update_rtmetric: tc->rtmetric %d\n", tc->rtmetric);
395 if(tc->rtmetric != RTMETRIC_SINK) {
396 uint16_t old_rtmetric, new_rtmetric;
399 old_rtmetric = tc->rtmetric;
405 new_rtmetric = rtmetric_compute(tc);
408 if(new_rtmetric == RTMETRIC_SINK) {
414 new_rtmetric = RTMETRIC_MAX;
419 tc->rtmetric = new_rtmetric;
423 #if COLLECT_ANNOUNCEMENTS
426 neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
430 PRINTF(
"%d.%d: new rtmetric %d\n",
435 if(old_rtmetric == RTMETRIC_MAX && new_rtmetric != RTMETRIC_MAX) {
436 PRINTF(
"Sending queued packet because rtmetric was max\n");
437 send_queued_packet(tc);
440 if(old_rtmetric != new_rtmetric) {
441 printf(
"#A rt=%d,p=%d\n", tc->rtmetric, tc->parent.u8[0]);
448 enqueue_dummy_packet(
struct collect_conn *c,
int rexmits)
450 struct collect_neighbor *n;
453 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, c->eseqno - 1);
455 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
456 packetbuf_set_attr(PACKETBUF_ATTR_TTL, 1);
457 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
459 PRINTF(
"%d.%d: enqueueing dummy packet %d, max_rexmits %d\n",
461 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
462 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
467 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
470 FORWARD_PACKET_LIFETIME_BASE * rexmits,
477 send_packet(
struct collect_conn *c,
struct collect_neighbor *n)
481 PRINTF(
"Sending packet to %d.%d, %d transmissions\n",
482 n->addr.u8[0], n->addr.u8[1],
488 time = 16 * REXMIT_TIME;
490 retransmit_not_sent_callback, c);
493 unicast_send(&c->unicast_conn, &n->addr);
497 proactive_probing_callback(
void *ptr)
499 struct collect_conn *c = ptr;
502 ctimer_set(&c->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
503 proactive_probing_callback, ptr);
507 if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
517 struct collect_neighbor *n;
520 for(n =
list_head(collect_neighbor_list(&c->neighbor_list));
522 if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
523 collect_link_estimate_num_estimates(&n->le) == 0) {
524 rimeaddr_t current_parent;
526 PRINTF(
"proactive_probing_callback: found neighbor with no link estimate, %d.%d\n",
527 n->addr.u8[RIMEADDR_SIZE - 2], n->addr.u8[RIMEADDR_SIZE - 1]);
531 if(enqueue_dummy_packet(c, PROACTIVE_PROBING_REXMITS)) {
532 send_queued_packet(c);
539 PRINTF(
"%d.%d: nothing on queue\n",
553 send_queued_packet(
struct collect_conn *c)
556 struct collect_neighbor *n;
558 struct data_msg_hdr hdr;
564 PRINTF(
"%d.%d: queue, c is sending\n",
573 PRINTF(
"%d.%d: nothing on queue\n",
583 queuebuf_to_packetbuf(q);
587 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
595 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
597 n->addr.u8[0], n->addr.u8[1],
598 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
608 c->transmissions = 0;
613 c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
619 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
621 max_mac_rexmits = c->max_rexmits > MAX_MAC_REXMITS?
622 MAX_MAC_REXMITS : c->max_rexmits;
623 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
624 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
630 memset(&hdr, 0,
sizeof(hdr));
631 hdr.rtmetric = c->rtmetric;
638 #if COLLECT_ANNOUNCEMENTS
639 #if COLLECT_CONF_WITH_LISTEN
642 ctimer_set(&c->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
643 send_queued_packet, c);
659 retransmit_current_packet(
struct collect_conn *c)
662 struct collect_neighbor *n;
664 struct data_msg_hdr hdr;
671 PRINTF(
"%d.%d: nothing on queue\n",
684 queuebuf_to_packetbuf(q);
698 PRINTF(
"parent change from %d.%d to %d.%d after %d tx\n",
699 c->current_parent.u8[0], c->current_parent.u8[1],
700 c->parent.u8[0], c->parent.u8[1],
704 c->transmissions = 0;
706 n = collect_neighbor_list_find(&c->neighbor_list, &c->current_parent);
714 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
716 n->addr.u8[0], n->addr.u8[1],
717 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
721 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
722 max_mac_rexmits = c->max_rexmits - c->transmissions > MAX_MAC_REXMITS?
723 MAX_MAC_REXMITS : c->max_rexmits - c->transmissions;
724 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
725 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
729 memset(&hdr, 0,
sizeof(hdr));
730 hdr.rtmetric = c->rtmetric;
741 send_next_packet(
struct collect_conn *tc)
745 tc->seqno = (tc->seqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
750 tc->transmissions = 0;
752 PRINTF(
"sending next packet, seqno %d, queue len %d\n",
756 send_queued_packet(tc);
760 handle_ack(
struct collect_conn *tc)
764 struct collect_neighbor *n;
766 PRINTF(
"handle_ack: sender %d.%d current_parent %d.%d, id %d seqno %d\n",
767 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
768 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
769 tc->current_parent.u8[0], tc->current_parent.u8[1],
770 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID), tc->seqno);
772 &tc->current_parent) &&
773 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
783 memcpy(&rtmetric, &msg->rtmetric,
sizeof(uint16_t));
791 if(tc->transmissions == 0) {
792 tc->transmissions = MAX_MAC_REXMITS;
794 PRINTF(
"Updating link estimate with %d transmissions\n",
796 n = collect_neighbor_list_find(&tc->neighbor_list,
797 packetbuf_addr(PACKETBUF_ADDR_SENDER));
800 collect_neighbor_tx(n, tc->transmissions);
801 collect_neighbor_update_rtmetric(n, rtmetric);
805 PRINTF(
"%d.%d: ACK from %d.%d after %d transmissions, flags %02x, rtmetric %d\n",
807 tc->current_parent.u8[0], tc->current_parent.u8[1],
818 if(msg->flags & ACK_FLAGS_CONGESTED) {
819 PRINTF(
"ACK flag indicated parent was congested.\n");
820 collect_neighbor_set_congested(n);
821 collect_neighbor_tx(n, tc->max_rexmits * 2);
824 if((msg->flags & ACK_FLAGS_DROPPED) == 0) {
826 send_next_packet(tc);
831 if((msg->flags & ACK_FLAGS_LIFETIME_EXCEEDED)) {
832 send_next_packet(tc);
837 PRINTF(
"ACK flag indicated packet was dropped by parent.\n");
838 collect_neighbor_tx(n, tc->max_rexmits);
842 REXMIT_TIME + (random_rand() % (REXMIT_TIME)),
843 retransmit_callback, tc);
849 if(msg->flags & ACK_FLAGS_RTMETRIC_NEEDS_UPDATE) {
850 bump_advertisement(tc);
852 set_keepalive_timer(tc);
859 send_ack(
struct collect_conn *tc,
const rimeaddr_t *to,
int flags)
862 uint16_t packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
867 memset(ack, 0,
sizeof(
struct ack_msg));
868 ack->rtmetric = tc->rtmetric;
871 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, to);
872 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_ACK);
873 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 0);
874 packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 0);
875 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, packet_seqno);
876 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
877 unicast_send(&tc->unicast_conn, to);
879 PRINTF(
"%d.%d: collect: Sending ACK to %d.%d for %d (epacket_id %d)\n",
881 to->u8[0], to->u8[1], packet_seqno,
882 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
884 RIMESTATS_ADD(acktx);
889 add_packet_to_recent_packets(
struct collect_conn *tc)
896 recent_packets[recent_packet_ptr].eseqno =
897 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
899 packetbuf_addr(PACKETBUF_ADDR_ESENDER));
900 recent_packets[recent_packet_ptr].conn = tc;
901 recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;
906 node_packet_received(
struct unicast_conn *c,
const rimeaddr_t *from)
908 struct collect_conn *tc = (
struct collect_conn *)
909 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
911 struct data_msg_hdr hdr;
912 uint8_t ackflags = 0;
913 struct collect_neighbor *n;
919 PRINTF(
"node_packet_received: from %d.%d rtmetric %d\n",
920 from->u8[0], from->u8[1], hdr.rtmetric);
921 n = collect_neighbor_list_find(&tc->neighbor_list,
922 packetbuf_addr(PACKETBUF_ADDR_SENDER));
924 collect_neighbor_update_rtmetric(n, hdr.rtmetric);
932 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
933 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
935 uint8_t packet_seqno;
941 rimeaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
942 packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
950 ackflags |= ACK_FLAGS_CONGESTED;
953 for(i = 0; i < NUM_RECENT_PACKETS; i++) {
954 if(recent_packets[i].conn == tc &&
955 recent_packets[i].eseqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
957 packetbuf_addr(PACKETBUF_ADDR_ESENDER))) {
960 PRINTF(
"%d.%d: found duplicate packet from %d.%d with seqno %d, via %d.%d\n",
962 recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1],
963 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
964 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
965 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]);
966 send_ack(tc, &ack_to, ackflags);
974 if(tc->rtmetric == RTMETRIC_SINK) {
977 add_packet_to_recent_packets(tc);
981 q = queuebuf_new_from_packetbuf();
983 send_ack(tc, &ack_to, 0);
984 queuebuf_to_packetbuf(q);
987 PRINTF(
"%d.%d: collect: could not send ACK to %d.%d for %d: no queued buffers\n",
989 ack_to.u8[0], ack_to.u8[1],
995 PRINTF(
"%d.%d: sink received packet %d from %d.%d via %d.%d\n",
997 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
998 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
999 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1000 from->u8[0], from->u8[1]);
1005 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1006 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1007 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1010 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) > 1 &&
1011 tc->rtmetric != RTMETRIC_MAX) {
1020 if(hdr.rtmetric <= tc->rtmetric) {
1021 ackflags |= ACK_FLAGS_RTMETRIC_NEEDS_UPDATE;
1024 packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
1025 packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
1026 packetbuf_set_attr(PACKETBUF_ATTR_TTL,
1027 packetbuf_attr(PACKETBUF_ATTR_TTL) - 1);
1030 PRINTF(
"%d.%d: packet received from %d.%d via %d.%d, sending %d, max_rexmits %d\n",
1032 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
1033 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1034 from->u8[0], from->u8[1], tc->sending,
1035 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1044 if(
packetqueue_len(&tc->send_queue) <= MAX_SENDING_QUEUE - MIN_AVAILABLE_QUEUE_ENTRIES &&
1046 FORWARD_PACKET_LIFETIME_BASE *
1047 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1049 add_packet_to_recent_packets(tc);
1050 send_ack(tc, &ack_to, ackflags);
1051 send_queued_packet(tc);
1053 send_ack(tc, &ack_to,
1054 ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
1055 PRINTF(
"%d.%d: packet dropped: no queue buffer available\n",
1059 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
1060 PRINTF(
"%d.%d: packet dropped: ttl %d\n",
1062 packetbuf_attr(PACKETBUF_ATTR_TTL));
1063 send_ack(tc, &ack_to, ackflags |
1064 ACK_FLAGS_DROPPED | ACK_FLAGS_LIFETIME_EXCEEDED);
1067 }
else if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1068 PACKETBUF_ATTR_PACKET_TYPE_ACK) {
1069 PRINTF(
"Collect: incoming ack %d from %d.%d (%d.%d) seqno %d (%d)\n",
1070 packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE),
1071 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
1072 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
1073 tc->current_parent.u8[0],
1074 tc->current_parent.u8[1],
1075 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID),
1084 timedout(
struct collect_conn *tc)
1086 struct collect_neighbor *n;
1087 PRINTF(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1089 tc->current_parent.u8[0], tc->current_parent.u8[1],
1091 printf(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1093 tc->current_parent.u8[0], tc->current_parent.u8[1],
1097 n = collect_neighbor_list_find(&tc->neighbor_list,
1098 &tc->current_parent);
1100 collect_neighbor_tx_fail(n, tc->max_rexmits);
1102 update_rtmetric(tc);
1103 send_next_packet(tc);
1104 set_keepalive_timer(tc);
1108 node_packet_sent(
struct unicast_conn *c,
int status,
int transmissions)
1110 struct collect_conn *tc = (
struct collect_conn *)
1111 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
1114 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1115 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
1117 tc->transmissions += transmissions;
1118 PRINTF(
"tx %d\n", tc->transmissions);
1119 PRINTF(
"%d.%d: MAC sent %d transmissions to %d.%d, status %d, total transmissions %d\n",
1122 tc->current_parent.u8[0], tc->current_parent.u8[1],
1123 status, tc->transmissions);
1124 if(tc->transmissions >= tc->max_rexmits) {
1128 clock_time_t time = REXMIT_TIME / 2 + (random_rand() % (REXMIT_TIME / 2));
1129 PRINTF(
"retransmission time %lu\n", time);
1131 retransmit_callback, tc);
1145 retransmit_not_sent_callback(
void *ptr)
1147 struct collect_conn *c = ptr;
1149 PRINTF(
"retransmit not sent, %d transmissions\n", c->transmissions);
1150 c->transmissions += MAX_MAC_REXMITS + 1;
1151 retransmit_callback(c);
1162 retransmit_callback(
void *ptr)
1164 struct collect_conn *c = ptr;
1166 PRINTF(
"retransmit, %d transmissions\n", c->transmissions);
1167 if(c->transmissions >= c->max_rexmits) {
1172 retransmit_current_packet(c);
1176 #if !COLLECT_ANNOUNCEMENTS
1178 adv_received(
struct neighbor_discovery_conn *c,
const rimeaddr_t *from,
1181 struct collect_conn *tc = (
struct collect_conn *)
1182 ((
char *)c - offsetof(
struct collect_conn, neighbor_discovery_conn));
1183 struct collect_neighbor *n;
1185 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1188 collect_neighbor_list_add(&tc->neighbor_list, from, rtmetric);
1189 if(rtmetric == RTMETRIC_MAX) {
1190 bump_advertisement(tc);
1201 if(rtmetric == RTMETRIC_MAX &&
1202 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1203 bump_advertisement(tc);
1205 collect_neighbor_update_rtmetric(n, rtmetric);
1206 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1208 n->addr.u8[0], n->addr.u8[1], rtmetric);
1211 update_rtmetric(tc);
1215 received_announcement(
struct announcement *a,
const rimeaddr_t *from,
1216 uint16_t
id, uint16_t value)
1218 struct collect_conn *tc = (
struct collect_conn *)
1219 ((
char *)a - offsetof(
struct collect_conn,
announcement));
1220 struct collect_neighbor *n;
1222 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1227 if(value < tc->rtmetric) {
1228 collect_neighbor_list_add(&tc->neighbor_list, from, value);
1229 PRINTF(
"%d.%d: new neighbor %d.%d, rtmetric %d\n",
1231 from->u8[0], from->u8[1], value);
1233 if(value == RTMETRIC_MAX && tc->rtmetric != RTMETRIC_MAX) {
1234 bump_advertisement(tc);
1245 if(value == RTMETRIC_MAX &&
1246 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1247 bump_advertisement(tc);
1249 collect_neighbor_update_rtmetric(n, value);
1250 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1252 n->addr.u8[0], n->addr.u8[1], value);
1255 update_rtmetric(tc);
1257 #if ! COLLECT_CONF_WITH_LISTEN
1258 if(value == RTMETRIC_MAX &&
1259 tc->rtmetric != RTMETRIC_MAX) {
1266 static const struct unicast_callbacks unicast_callbacks = {node_packet_received,
1268 #if !COLLECT_ANNOUNCEMENTS
1269 static const struct neighbor_discovery_callbacks neighbor_discovery_callbacks =
1270 { adv_received,
NULL};
1274 collect_open(
struct collect_conn *tc, uint16_t channels,
1276 const struct collect_callbacks *cb)
1278 unicast_open(&tc->unicast_conn, channels + 1, &unicast_callbacks);
1279 channel_set_attributes(channels + 1, attributes);
1280 tc->rtmetric = RTMETRIC_MAX;
1282 tc->is_router = is_router;
1286 collect_neighbor_list_new(&tc->neighbor_list);
1287 tc->send_queue.list = &(tc->send_queue_list);
1288 tc->send_queue.memb = &send_queue_memb;
1289 collect_neighbor_init();
1291 #if !COLLECT_ANNOUNCEMENTS
1292 neighbor_discovery_open(&tc->neighbor_discovery_conn, channels,
1295 #ifdef COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
1296 COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME,
1300 &neighbor_discovery_callbacks);
1301 neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
1304 received_announcement);
1305 #if ! COLLECT_CONF_WITH_LISTEN
1310 ctimer_set(&tc->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
1311 proactive_probing_callback, tc);
1316 send_keepalive(
void *ptr)
1318 struct collect_conn *c = ptr;
1320 set_keepalive_timer(c);
1324 if(enqueue_dummy_packet(c, KEEPALIVE_REXMITS)) {
1325 PRINTF(
"%d.%d: sending keepalive\n",
1327 send_queued_packet(c);
1333 set_keepalive_timer(
struct collect_conn *c)
1335 if(c->keepalive_period != 0) {
1336 ctimer_set(&c->keepalive_timer, (c->keepalive_period / 2) +
1337 (random_rand() % (c->keepalive_period / 2)),
1345 collect_set_keepalive(
struct collect_conn *c, clock_time_t period)
1347 c->keepalive_period = period;
1348 set_keepalive_timer(c);
1352 collect_close(
struct collect_conn *tc)
1354 #if COLLECT_ANNOUNCEMENTS
1357 neighbor_discovery_close(&tc->neighbor_discovery_conn);
1359 unicast_close(&tc->unicast_conn);
1366 collect_set_sink(
struct collect_conn *tc,
int should_be_sink)
1368 if(should_be_sink) {
1370 tc->rtmetric = RTMETRIC_SINK;
1371 PRINTF(
"collect_set_sink: tc->rtmetric %d\n", tc->rtmetric);
1372 bump_advertisement(tc);
1382 tc->rtmetric = RTMETRIC_MAX;
1384 #if COLLECT_ANNOUNCEMENTS
1387 update_rtmetric(tc);
1389 bump_advertisement(tc);
1392 printf(
"#A rt=0,p=0\n");
1397 collect_send(
struct collect_conn *tc,
int rexmits)
1399 struct collect_neighbor *n;
1402 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno);
1412 tc->eseqno = (tc->eseqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
1414 if(tc->eseqno == 0) {
1415 tc->eseqno = ((int)(1 << COLLECT_PACKET_ID_BITS)) / 2;
1418 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
1419 packetbuf_set_attr(PACKETBUF_ATTR_TTL, MAX_HOPLIM);
1420 if(rexmits > MAX_REXMITS) {
1421 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, MAX_REXMITS);
1423 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
1426 PRINTF(
"%d.%d: originating packet %d, max_rexmits %d\n",
1428 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1429 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1431 if(tc->rtmetric == RTMETRIC_SINK) {
1432 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
1433 if(tc->cb->recv !=
NULL) {
1434 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1435 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1436 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1445 FORWARD_PACKET_LIFETIME_BASE *
1446 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1448 send_queued_packet(tc);
1451 PRINTF(
"%d.%d: drop originated packet: no queuebuf\n",
1453 printf(
"%d.%d: drop originated packet: no queuebuf\n",
1459 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
1461 PRINTF(
"%d.%d: sending to %d.%d\n",
1463 n->addr.u8[0], n->addr.u8[1]);
1465 PRINTF(
"%d.%d: did not find any neighbor to send to\n",
1467 #if COLLECT_ANNOUNCEMENTS
1468 #if COLLECT_CONF_WITH_LISTEN
1471 ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
1472 send_queued_packet, tc);
1496 collect_depth(
struct collect_conn *tc)
1498 return tc->rtmetric;
1502 collect_parent(
struct collect_conn *tc)
1504 return &tc->current_parent;
1508 collect_purge(
struct collect_conn *tc)
1510 collect_neighbor_list_purge(&tc->neighbor_list);
1512 update_rtmetric(tc);
1514 printf(
"#L %d 0\n", tc->parent.u8[0]);
1520 collect_print_stats(
void)
1522 PRINTF(
"collect stats foundroute %lu newparent %lu routelost %lu acksent %lu datasent %lu datarecv %lu ackrecv %lu badack %lu duprecv %lu qdrop %lu rtdrop %lu ttldrop %lu ackdrop %lu timedout %lu\n",
1523 stats.foundroute, stats.newparent, stats.routelost,
1524 stats.acksent, stats.datasent, stats.datarecv,
1525 stats.ackrecv, stats.badack, stats.duprecv,
1526 stats.qdrop, stats.rtdrop, stats.ttldrop, stats.ackdrop,