54 #include "dev/radio-sensor.h"
56 #include "lib/random.h"
62 static const struct packetbuf_attrlist attributes[] =
73 #define NUM_RECENT_PACKETS 16
75 struct recent_packet {
76 struct collect_conn *conn;
77 linkaddr_t originator;
81 static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
82 static uint8_t recent_packet_ptr;
105 uint8_t flags, dummy;
109 #define ACK_FLAGS_CONGESTED 0x80
110 #define ACK_FLAGS_DROPPED 0x40
111 #define ACK_FLAGS_LIFETIME_EXCEEDED 0x20
112 #define ACK_FLAGS_RTMETRIC_NEEDS_UPDATE 0x10
126 #ifdef COLLECT_CONF_MAX_MAC_REXMITS
127 #define MAX_MAC_REXMITS COLLECT_CONF_MAX_MAC_REXMITS
129 #define MAX_MAC_REXMITS 2
132 #ifdef COLLECT_CONF_MAX_ACK_MAC_REXMITS
133 #define MAX_ACK_MAC_REXMITS COLLECT_CONF_MAX_ACK_MAC_REXMITS
135 #define MAX_ACK_MAC_REXMITS 5
138 #define REXMIT_TIME (CLOCK_SECOND * 32 / NETSTACK_RDC_CHANNEL_CHECK_RATE)
139 #define FORWARD_PACKET_LIFETIME_BASE REXMIT_TIME * 2
140 #define MAX_SENDING_QUEUE 3 * QUEUEBUF_NUM / 4
141 #define MIN_AVAILABLE_QUEUE_ENTRIES 4
142 #define KEEPALIVE_REXMITS 8
143 #define MAX_REXMITS 31
151 #define RTMETRIC_SINK 0
152 #define RTMETRIC_MAX COLLECT_MAX_DEPTH
158 #define SIGNIFICANT_RTMETRIC_PARENT_CHANGE (COLLECT_LINK_ESTIMATE_UNIT + \
159 COLLECT_LINK_ESTIMATE_UNIT / 2)
163 #ifdef COLLECT_CONF_MAX_HOPLIM
164 #define MAX_HOPLIM COLLECT_CONF_MAX_HOPLIM
166 #define MAX_HOPLIM 15
174 #ifdef COLLECT_CONF_PROACTIVE_PROBING_INTERVAL
175 #define PROACTIVE_PROBING_INTERVAL (random_rand() % (2 * COLLECT_CONF_PROACTIVE_PROBING_INTERVAL))
177 #define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
179 #define PROACTIVE_PROBING_REXMITS 15
184 #ifdef ANNOUNCEMENT_CONF_PERIOD
185 #define ANNOUNCEMENT_SCAN_TIME ANNOUNCEMENT_CONF_PERIOD
187 #define ANNOUNCEMENT_SCAN_TIME CLOCK_SECOND
217 #define PRINTF(...) printf(__VA_ARGS__)
223 static void send_queued_packet(
struct collect_conn *c);
224 static void retransmit_callback(
void *ptr);
225 static void retransmit_not_sent_callback(
void *ptr);
226 static void set_keepalive_timer(
struct collect_conn *c);
236 rtmetric_compute(
struct collect_conn *tc)
238 struct collect_neighbor *n;
239 uint16_t rtmetric = RTMETRIC_MAX;
248 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
253 rtmetric = RTMETRIC_MAX;
257 rtmetric = collect_neighbor_rtmetric_link_estimate(n);
269 bump_advertisement(
struct collect_conn *c)
271 #if !COLLECT_ANNOUNCEMENTS
272 neighbor_discovery_start(&c->neighbor_discovery_conn, c->rtmetric);
286 update_parent(
struct collect_conn *tc)
288 struct collect_neighbor *current;
289 struct collect_neighbor *best;
292 current = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
296 best = collect_neighbor_list_best(&tc->neighbor_list);
316 linkaddr_t previous_parent;
322 if(current ==
NULL) {
324 PRINTF(
"update_parent: new parent %d.%d\n",
325 best->addr.u8[0], best->addr.u8[1]);
328 bump_advertisement(tc);
331 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(best));
333 if(collect_neighbor_rtmetric_link_estimate(best) +
334 SIGNIFICANT_RTMETRIC_PARENT_CHANGE <
335 collect_neighbor_rtmetric_link_estimate(current)) {
338 PRINTF(
"update_parent: new parent %d.%d (%d) old parent %d.%d (%d)\n",
339 best->addr.u8[0], best->addr.u8[1],
340 collect_neighbor_rtmetric(best),
341 tc->parent.u8[0], tc->parent.u8[1],
342 collect_neighbor_rtmetric(current));
347 bump_advertisement(tc);
350 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(best));
364 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(current));
381 PRINTF(
"#L %d 0\n", previous_parent.u8[0]);
383 PRINTF(
"#L %d 1\n", tc->parent.u8[0]);
390 PRINTF(
"#L %d 0\n", tc->parent.u8[0]);
407 update_rtmetric(
struct collect_conn *tc)
409 PRINTF(
"update_rtmetric: tc->rtmetric %d\n", tc->rtmetric);
412 if(tc->rtmetric != RTMETRIC_SINK) {
413 uint16_t old_rtmetric, new_rtmetric;
416 old_rtmetric = tc->rtmetric;
422 new_rtmetric = rtmetric_compute(tc);
425 if(new_rtmetric == RTMETRIC_SINK) {
431 new_rtmetric = RTMETRIC_MAX;
436 tc->rtmetric = new_rtmetric;
440 #if COLLECT_ANNOUNCEMENTS
443 neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
447 PRINTF(
"%d.%d: new rtmetric %d\n",
452 if(old_rtmetric == RTMETRIC_MAX && new_rtmetric != RTMETRIC_MAX) {
453 PRINTF(
"Sending queued packet because rtmetric was max\n");
454 send_queued_packet(tc);
457 if(old_rtmetric != new_rtmetric) {
458 PRINTF(
"#A rt=%d,p=%d\n", tc->rtmetric, tc->parent.u8[0]);
465 enqueue_dummy_packet(
struct collect_conn *c,
int rexmits)
467 struct collect_neighbor *n;
470 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, c->eseqno - 1);
472 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
473 packetbuf_set_attr(PACKETBUF_ATTR_TTL, 1);
474 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
476 PRINTF(
"%d.%d: enqueueing dummy packet %d, max_rexmits %d\n",
478 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
479 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
484 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
487 FORWARD_PACKET_LIFETIME_BASE * rexmits,
494 send_packet(
struct collect_conn *c,
struct collect_neighbor *n)
498 PRINTF(
"Sending packet to %d.%d, %d transmissions\n",
499 n->addr.u8[0], n->addr.u8[1],
505 time = 16 * REXMIT_TIME;
507 retransmit_not_sent_callback, c);
510 unicast_send(&c->unicast_conn, &n->addr);
514 proactive_probing_callback(
void *ptr)
516 struct collect_conn *c = ptr;
519 ctimer_set(&c->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
520 proactive_probing_callback, ptr);
524 if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
534 struct collect_neighbor *n;
537 for(n =
list_head(collect_neighbor_list(&c->neighbor_list));
539 if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
540 collect_link_estimate_num_estimates(&n->le) == 0) {
541 linkaddr_t current_parent;
543 PRINTF(
"proactive_probing_callback: found neighbor with no link estimate, %d.%d\n",
544 n->addr.u8[LINKADDR_SIZE - 2], n->addr.u8[LINKADDR_SIZE - 1]);
548 if(enqueue_dummy_packet(c, PROACTIVE_PROBING_REXMITS)) {
549 send_queued_packet(c);
556 PRINTF(
"%d.%d: nothing on queue\n",
570 send_queued_packet(
struct collect_conn *c)
573 struct collect_neighbor *n;
575 struct data_msg_hdr hdr;
581 PRINTF(
"%d.%d: queue, c is sending\n",
590 PRINTF(
"%d.%d: nothing on queue\n",
600 queuebuf_to_packetbuf(q);
604 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
612 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
614 n->addr.u8[0], n->addr.u8[1],
615 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
625 c->transmissions = 0;
630 c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
636 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
638 max_mac_rexmits = c->max_rexmits > MAX_MAC_REXMITS?
639 MAX_MAC_REXMITS : c->max_rexmits;
640 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
641 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
647 memset(&hdr, 0,
sizeof(hdr));
648 hdr.rtmetric = c->rtmetric;
655 #if COLLECT_ANNOUNCEMENTS
656 #if COLLECT_CONF_WITH_LISTEN
659 ctimer_set(&c->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
660 send_queued_packet, c);
678 retransmit_current_packet(
struct collect_conn *c)
681 struct collect_neighbor *n;
683 struct data_msg_hdr hdr;
690 PRINTF(
"%d.%d: nothing on queue\n",
703 queuebuf_to_packetbuf(q);
717 PRINTF(
"parent change from %d.%d to %d.%d after %d tx\n",
718 c->current_parent.u8[0], c->current_parent.u8[1],
719 c->parent.u8[0], c->parent.u8[1],
723 c->transmissions = 0;
725 n = collect_neighbor_list_find(&c->neighbor_list, &c->current_parent);
733 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
735 n->addr.u8[0], n->addr.u8[1],
736 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
740 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
741 max_mac_rexmits = c->max_rexmits - c->transmissions > MAX_MAC_REXMITS?
742 MAX_MAC_REXMITS : c->max_rexmits - c->transmissions;
743 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
744 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
748 memset(&hdr, 0,
sizeof(hdr));
749 hdr.rtmetric = c->rtmetric;
760 send_next_packet(
struct collect_conn *tc)
764 tc->seqno = (tc->seqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
769 tc->transmissions = 0;
771 PRINTF(
"sending next packet, seqno %d, queue len %d\n",
775 send_queued_packet(tc);
779 handle_ack(
struct collect_conn *tc)
782 struct collect_neighbor *n;
784 PRINTF(
"handle_ack: sender %d.%d current_parent %d.%d, id %d seqno %d\n",
785 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
786 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
787 tc->current_parent.u8[0], tc->current_parent.u8[1],
788 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID), tc->seqno);
790 &tc->current_parent) &&
791 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
808 if(tc->transmissions == 0) {
809 tc->transmissions = MAX_MAC_REXMITS;
811 PRINTF(
"Updating link estimate with %d transmissions\n",
813 n = collect_neighbor_list_find(&tc->neighbor_list,
814 packetbuf_addr(PACKETBUF_ADDR_SENDER));
817 collect_neighbor_tx(n, tc->transmissions);
818 collect_neighbor_update_rtmetric(n, msg.rtmetric);
822 PRINTF(
"%d.%d: ACK from %d.%d after %d transmissions, flags %02x, rtmetric %d\n",
824 tc->current_parent.u8[0], tc->current_parent.u8[1],
835 if(msg.flags & ACK_FLAGS_CONGESTED) {
836 PRINTF(
"ACK flag indicated parent was congested.\n");
838 collect_neighbor_set_congested(n);
839 collect_neighbor_tx(n, tc->max_rexmits * 2);
843 if((msg.flags & ACK_FLAGS_DROPPED) == 0) {
845 send_next_packet(tc);
850 if((msg.flags & ACK_FLAGS_LIFETIME_EXCEEDED)) {
851 send_next_packet(tc);
856 PRINTF(
"ACK flag indicated packet was dropped by parent.\n");
857 collect_neighbor_tx(n, tc->max_rexmits);
862 retransmit_callback, tc);
868 if(msg.flags & ACK_FLAGS_RTMETRIC_NEEDS_UPDATE) {
869 bump_advertisement(tc);
871 set_keepalive_timer(tc);
878 send_ack(
struct collect_conn *tc,
const linkaddr_t *to,
int flags)
881 uint16_t packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
886 memset(ack, 0,
sizeof(
struct ack_msg));
887 ack->rtmetric = tc->rtmetric;
890 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, to);
891 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_ACK);
892 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 0);
893 packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 0);
894 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, packet_seqno);
895 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
896 unicast_send(&tc->unicast_conn, to);
898 PRINTF(
"%d.%d: collect: Sending ACK to %d.%d for %d (epacket_id %d)\n",
900 to->u8[0], to->u8[1], packet_seqno,
901 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
903 RIMESTATS_ADD(acktx);
908 add_packet_to_recent_packets(
struct collect_conn *tc)
915 recent_packets[recent_packet_ptr].eseqno =
916 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
918 packetbuf_addr(PACKETBUF_ADDR_ESENDER));
919 recent_packets[recent_packet_ptr].conn = tc;
920 recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;
925 node_packet_received(
struct unicast_conn *c,
const linkaddr_t *from)
927 struct collect_conn *tc = (
struct collect_conn *)
928 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
930 struct data_msg_hdr hdr;
931 uint8_t ackflags = 0;
932 struct collect_neighbor *n;
938 PRINTF(
"node_packet_received: from %d.%d rtmetric %d\n",
939 from->u8[0], from->u8[1], hdr.rtmetric);
940 n = collect_neighbor_list_find(&tc->neighbor_list,
941 packetbuf_addr(PACKETBUF_ADDR_SENDER));
943 collect_neighbor_update_rtmetric(n, hdr.rtmetric);
951 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
952 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
954 uint8_t packet_seqno;
960 linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
961 packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
969 ackflags |= ACK_FLAGS_CONGESTED;
972 for(i = 0; i < NUM_RECENT_PACKETS; i++) {
973 if(recent_packets[i].conn == tc &&
974 recent_packets[i].eseqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
976 packetbuf_addr(PACKETBUF_ADDR_ESENDER))) {
979 PRINTF(
"%d.%d: found duplicate packet from %d.%d with seqno %d, via %d.%d\n",
981 recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1],
982 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
983 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
984 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]);
985 send_ack(tc, &ack_to, ackflags);
993 if(tc->rtmetric == RTMETRIC_SINK) {
996 add_packet_to_recent_packets(tc);
1000 q = queuebuf_new_from_packetbuf();
1002 send_ack(tc, &ack_to, 0);
1003 queuebuf_to_packetbuf(q);
1006 PRINTF(
"%d.%d: collect: could not send ACK to %d.%d for %d: no queued buffers\n",
1008 ack_to.u8[0], ack_to.u8[1],
1014 PRINTF(
"%d.%d: sink received packet %d from %d.%d via %d.%d\n",
1016 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1017 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
1018 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1019 from->u8[0], from->u8[1]);
1024 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1025 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1026 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1029 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) > 1 &&
1030 tc->rtmetric != RTMETRIC_MAX) {
1039 if(hdr.rtmetric <= tc->rtmetric) {
1040 ackflags |= ACK_FLAGS_RTMETRIC_NEEDS_UPDATE;
1043 packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
1044 packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
1045 packetbuf_set_attr(PACKETBUF_ATTR_TTL,
1046 packetbuf_attr(PACKETBUF_ATTR_TTL) - 1);
1049 PRINTF(
"%d.%d: packet received from %d.%d via %d.%d, sending %d, max_rexmits %d\n",
1051 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
1052 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1053 from->u8[0], from->u8[1], tc->sending,
1054 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1063 if(
packetqueue_len(&tc->send_queue) <= MAX_SENDING_QUEUE - MIN_AVAILABLE_QUEUE_ENTRIES &&
1065 FORWARD_PACKET_LIFETIME_BASE *
1066 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1068 add_packet_to_recent_packets(tc);
1069 send_ack(tc, &ack_to, ackflags);
1070 send_queued_packet(tc);
1072 send_ack(tc, &ack_to,
1073 ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
1074 PRINTF(
"%d.%d: packet dropped: no queue buffer available\n",
1078 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
1079 PRINTF(
"%d.%d: packet dropped: ttl %d\n",
1081 packetbuf_attr(PACKETBUF_ATTR_TTL));
1082 send_ack(tc, &ack_to, ackflags |
1083 ACK_FLAGS_DROPPED | ACK_FLAGS_LIFETIME_EXCEEDED);
1086 }
else if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1087 PACKETBUF_ATTR_PACKET_TYPE_ACK) {
1088 PRINTF(
"Collect: incoming ack %d from %d.%d (%d.%d) seqno %d (%d)\n",
1089 packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE),
1090 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
1091 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
1092 tc->current_parent.u8[0],
1093 tc->current_parent.u8[1],
1094 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID),
1103 timedout(
struct collect_conn *tc)
1105 struct collect_neighbor *n;
1106 PRINTF(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1108 tc->current_parent.u8[0], tc->current_parent.u8[1],
1110 PRINTF(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1112 tc->current_parent.u8[0], tc->current_parent.u8[1],
1116 n = collect_neighbor_list_find(&tc->neighbor_list,
1117 &tc->current_parent);
1119 collect_neighbor_tx_fail(n, tc->max_rexmits);
1121 update_rtmetric(tc);
1122 send_next_packet(tc);
1123 set_keepalive_timer(tc);
1127 node_packet_sent(
struct unicast_conn *c,
int status,
int transmissions)
1129 struct collect_conn *tc = (
struct collect_conn *)
1130 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
1133 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1134 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
1136 tc->transmissions += transmissions;
1137 PRINTF(
"tx %d\n", tc->transmissions);
1138 PRINTF(
"%d.%d: MAC sent %d transmissions to %d.%d, status %d, total transmissions %d\n",
1141 tc->current_parent.u8[0], tc->current_parent.u8[1],
1142 status, tc->transmissions);
1143 if(tc->transmissions >= tc->max_rexmits) {
1147 clock_time_t time = REXMIT_TIME / 2 + (
random_rand() % (REXMIT_TIME / 2));
1148 PRINTF(
"retransmission time %lu\n", time);
1150 retransmit_callback, tc);
1164 retransmit_not_sent_callback(
void *ptr)
1166 struct collect_conn *c = ptr;
1168 PRINTF(
"retransmit not sent, %d transmissions\n", c->transmissions);
1169 c->transmissions += MAX_MAC_REXMITS + 1;
1170 retransmit_callback(c);
1181 retransmit_callback(
void *ptr)
1183 struct collect_conn *c = ptr;
1185 PRINTF(
"retransmit, %d transmissions\n", c->transmissions);
1186 if(c->transmissions >= c->max_rexmits) {
1191 retransmit_current_packet(c);
1195 #if !COLLECT_ANNOUNCEMENTS
1197 adv_received(
struct neighbor_discovery_conn *c,
const linkaddr_t *from,
1200 struct collect_conn *tc = (
struct collect_conn *)
1201 ((
char *)c - offsetof(
struct collect_conn, neighbor_discovery_conn));
1202 struct collect_neighbor *n;
1204 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1207 collect_neighbor_list_add(&tc->neighbor_list, from, rtmetric);
1208 if(rtmetric == RTMETRIC_MAX) {
1209 bump_advertisement(tc);
1220 if(rtmetric == RTMETRIC_MAX &&
1221 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1222 bump_advertisement(tc);
1224 collect_neighbor_update_rtmetric(n, rtmetric);
1225 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1227 n->addr.u8[0], n->addr.u8[1], rtmetric);
1230 update_rtmetric(tc);
1234 received_announcement(
struct announcement *a,
const linkaddr_t *from,
1235 uint16_t
id, uint16_t value)
1237 struct collect_conn *tc = (
struct collect_conn *)
1238 ((
char *)a - offsetof(
struct collect_conn,
announcement));
1239 struct collect_neighbor *n;
1241 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1246 if(value < tc->rtmetric) {
1247 collect_neighbor_list_add(&tc->neighbor_list, from, value);
1248 PRINTF(
"%d.%d: new neighbor %d.%d, rtmetric %d\n",
1250 from->u8[0], from->u8[1], value);
1252 if(value == RTMETRIC_MAX && tc->rtmetric != RTMETRIC_MAX) {
1253 bump_advertisement(tc);
1264 if(value == RTMETRIC_MAX &&
1265 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1266 bump_advertisement(tc);
1268 collect_neighbor_update_rtmetric(n, value);
1269 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1271 n->addr.u8[0], n->addr.u8[1], value);
1274 update_rtmetric(tc);
1276 #if ! COLLECT_CONF_WITH_LISTEN
1277 if(value == RTMETRIC_MAX &&
1278 tc->rtmetric != RTMETRIC_MAX) {
1287 static const struct unicast_callbacks unicast_callbacks = {node_packet_received,
1289 #if !COLLECT_ANNOUNCEMENTS
1290 static const struct neighbor_discovery_callbacks neighbor_discovery_callbacks =
1291 { adv_received,
NULL};
1295 collect_open(
struct collect_conn *tc, uint16_t channels,
1297 const struct collect_callbacks *cb)
1299 unicast_open(&tc->unicast_conn, channels + 1, &unicast_callbacks);
1300 channel_set_attributes(channels + 1, attributes);
1301 tc->rtmetric = RTMETRIC_MAX;
1303 tc->is_router = is_router;
1307 collect_neighbor_list_new(&tc->neighbor_list);
1308 tc->send_queue.list = &(tc->send_queue_list);
1309 tc->send_queue.memb = &send_queue_memb;
1310 collect_neighbor_init();
1312 #if !COLLECT_ANNOUNCEMENTS
1313 neighbor_discovery_open(&tc->neighbor_discovery_conn, channels,
1316 #ifdef COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
1317 COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME,
1321 &neighbor_discovery_callbacks);
1322 neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
1325 received_announcement);
1326 #if ! COLLECT_CONF_WITH_LISTEN
1333 ctimer_set(&tc->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
1334 proactive_probing_callback, tc);
1339 send_keepalive(
void *ptr)
1341 struct collect_conn *c = ptr;
1343 set_keepalive_timer(c);
1347 if(enqueue_dummy_packet(c, KEEPALIVE_REXMITS)) {
1348 PRINTF(
"%d.%d: sending keepalive\n",
1350 send_queued_packet(c);
1356 set_keepalive_timer(
struct collect_conn *c)
1358 if(c->keepalive_period != 0) {
1359 ctimer_set(&c->keepalive_timer, (c->keepalive_period / 2) +
1368 collect_set_keepalive(
struct collect_conn *c, clock_time_t period)
1370 c->keepalive_period = period;
1371 set_keepalive_timer(c);
1375 collect_close(
struct collect_conn *tc)
1377 #if COLLECT_ANNOUNCEMENTS
1380 neighbor_discovery_close(&tc->neighbor_discovery_conn);
1382 unicast_close(&tc->unicast_conn);
1389 collect_set_sink(
struct collect_conn *tc,
int should_be_sink)
1391 if(should_be_sink) {
1393 tc->rtmetric = RTMETRIC_SINK;
1394 PRINTF(
"collect_set_sink: tc->rtmetric %d\n", tc->rtmetric);
1395 bump_advertisement(tc);
1405 tc->rtmetric = RTMETRIC_MAX;
1407 #if COLLECT_ANNOUNCEMENTS
1410 update_rtmetric(tc);
1412 bump_advertisement(tc);
1415 PRINTF(
"#A rt=0,p=0\n");
1420 collect_send(
struct collect_conn *tc,
int rexmits)
1422 struct collect_neighbor *n;
1425 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno);
1435 tc->eseqno = (tc->eseqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
1437 if(tc->eseqno == 0) {
1438 tc->eseqno = ((int)(1 << COLLECT_PACKET_ID_BITS)) / 2;
1441 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
1442 packetbuf_set_attr(PACKETBUF_ATTR_TTL, MAX_HOPLIM);
1443 if(rexmits > MAX_REXMITS) {
1444 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, MAX_REXMITS);
1446 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
1449 PRINTF(
"%d.%d: originating packet %d, max_rexmits %d\n",
1451 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1452 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1454 if(tc->rtmetric == RTMETRIC_SINK) {
1455 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
1456 if(tc->cb->recv !=
NULL) {
1457 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1458 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1459 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1468 FORWARD_PACKET_LIFETIME_BASE *
1469 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1471 send_queued_packet(tc);
1474 PRINTF(
"%d.%d: drop originated packet: no queuebuf\n",
1476 PRINTF(
"%d.%d: drop originated packet: no queuebuf\n",
1482 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
1484 PRINTF(
"%d.%d: sending to %d.%d\n",
1486 n->addr.u8[0], n->addr.u8[1]);
1488 PRINTF(
"%d.%d: did not find any neighbor to send to\n",
1490 #if COLLECT_ANNOUNCEMENTS
1491 #if COLLECT_CONF_WITH_LISTEN
1494 ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
1495 send_queued_packet, tc);
1521 collect_depth(
struct collect_conn *tc)
1523 return tc->rtmetric;
1527 collect_parent(
struct collect_conn *tc)
1529 return &tc->current_parent;
1533 collect_purge(
struct collect_conn *tc)
1535 collect_neighbor_list_purge(&tc->neighbor_list);
1537 update_rtmetric(tc);
1539 PRINTF(
"#L %d 0\n", tc->parent.u8[0]);
1545 collect_print_stats(
void)
1547 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",
1548 stats.foundroute, stats.newparent, stats.routelost,
1549 stats.acksent, stats.datasent, stats.datarecv,
1550 stats.ackrecv, stats.badack, stats.duprecv,
1551 stats.qdrop, stats.rtdrop, stats.ttldrop, stats.ackdrop,
void announcement_remove(struct announcement *a)
Remove a previously registered announcement.
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
void announcement_register(struct announcement *a, uint16_t id, announcement_callback_t callback)
Register an announcement.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
const linkaddr_t linkaddr_null
The null Rime address.
Header file for hop-by-hop reliable data collection
void * list_item_next(void *item)
Get the next item following this item.
Header file for the packetqueue module
struct packetqueue_item * packetqueue_first(struct packetqueue *q)
Access the first item on the packet buffer.
#define NULL
The null pointer.
Header file for the Collect link estimate
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Header file for the Rime stack
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
CCIF clock_time_t clock_time(void)
Get the current clock time.
Representation of an item in a packet queue.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
void * list_head(list_t list)
Get a pointer to the first element of a list.
#define MEMB(name, structure, num)
Declare a memory block.
int packetqueue_len(struct packetqueue *q)
Get the length of the packet queue.
void announcement_listen(int time)
Listen for announcements for a specific amount of announcement periods.
struct queuebuf * packetqueue_queuebuf(struct packetqueue_item *i)
Access the queuebuf in a packet queue item.
int packetqueue_enqueue_packetbuf(struct packetqueue *q, clock_time_t lifetime, void *ptr)
Enqueue a packetbuf on a packet queue.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
Header file for the Contiki radio neighborhood management
void packetbuf_clear(void)
Clear and reset the packetbuf.
Representation of an announcement.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
void announcement_bump(struct announcement *a)
Bump an announcement.
void packetqueue_dequeue(struct packetqueue *q)
Remove the first item on the packet buffer.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
void announcement_set_value(struct announcement *a, uint16_t value)
Set the value of an announcement.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
unsigned short random_rand(void)
Generate the next state and return the upper part of it.
int packetbuf_hdrreduce(int size)
Reduce the header in the packetbuf, for incoming packets.
Include file for the Contiki low-layer network stack (NETSTACK)
#define CLOCK_SECOND
A second, measured in system clock time.