53 #include "dev/radio-sensor.h"
55 #include "lib/random.h"
61 static const struct packetbuf_attrlist attributes[] =
72 #define NUM_RECENT_PACKETS 16
74 struct recent_packet {
75 struct collect_conn *conn;
76 linkaddr_t originator;
80 static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
81 static uint8_t recent_packet_ptr;
104 uint8_t flags, dummy;
108 #define ACK_FLAGS_CONGESTED 0x80
109 #define ACK_FLAGS_DROPPED 0x40
110 #define ACK_FLAGS_LIFETIME_EXCEEDED 0x20
111 #define ACK_FLAGS_RTMETRIC_NEEDS_UPDATE 0x10
125 #ifdef COLLECT_CONF_MAX_MAC_REXMITS
126 #define MAX_MAC_REXMITS COLLECT_CONF_MAX_MAC_REXMITS
128 #define MAX_MAC_REXMITS 2
131 #ifdef COLLECT_CONF_MAX_ACK_MAC_REXMITS
132 #define MAX_ACK_MAC_REXMITS COLLECT_CONF_MAX_ACK_MAC_REXMITS
134 #define MAX_ACK_MAC_REXMITS 5
137 #define REXMIT_TIME (CLOCK_SECOND * 32 / NETSTACK_RDC_CHANNEL_CHECK_RATE)
138 #define FORWARD_PACKET_LIFETIME_BASE REXMIT_TIME * 2
139 #define MAX_SENDING_QUEUE 3 * QUEUEBUF_NUM / 4
140 #define MIN_AVAILABLE_QUEUE_ENTRIES 4
141 #define KEEPALIVE_REXMITS 8
142 #define MAX_REXMITS 31
150 #define RTMETRIC_SINK 0
151 #define RTMETRIC_MAX COLLECT_MAX_DEPTH
157 #define SIGNIFICANT_RTMETRIC_PARENT_CHANGE (COLLECT_LINK_ESTIMATE_UNIT + \
158 COLLECT_LINK_ESTIMATE_UNIT / 2)
162 #ifdef COLLECT_CONF_MAX_HOPLIM
163 #define MAX_HOPLIM COLLECT_CONF_MAX_HOPLIM
165 #define MAX_HOPLIM 15
173 #ifdef COLLECT_CONF_PROACTIVE_PROBING_INTERVAL
174 #define PROACTIVE_PROBING_INTERVAL (random_rand() % (2 * COLLECT_CONF_PROACTIVE_PROBING_INTERVAL))
176 #define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
178 #define PROACTIVE_PROBING_REXMITS 15
183 #ifdef ANNOUNCEMENT_CONF_PERIOD
184 #define ANNOUNCEMENT_SCAN_TIME ANNOUNCEMENT_CONF_PERIOD
186 #define ANNOUNCEMENT_SCAN_TIME CLOCK_SECOND
216 #define PRINTF(...) printf(__VA_ARGS__)
225 static void set_keepalive_timer(
struct collect_conn *c);
237 struct collect_neighbor *n;
238 uint16_t rtmetric = RTMETRIC_MAX;
247 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
252 rtmetric = RTMETRIC_MAX;
256 rtmetric = collect_neighbor_rtmetric_link_estimate(n);
270 #if !COLLECT_ANNOUNCEMENTS
271 neighbor_discovery_start(&c->neighbor_discovery_conn, c->rtmetric);
287 struct collect_neighbor *current;
288 struct collect_neighbor *best;
291 current = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
295 best = collect_neighbor_list_best(&tc->neighbor_list);
315 linkaddr_t previous_parent;
321 if(current ==
NULL) {
323 PRINTF(
"update_parent: new parent %d.%d\n",
324 best->addr.u8[0], best->addr.u8[1]);
330 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(best));
332 if(collect_neighbor_rtmetric_link_estimate(best) +
333 SIGNIFICANT_RTMETRIC_PARENT_CHANGE <
334 collect_neighbor_rtmetric_link_estimate(current)) {
337 PRINTF(
"update_parent: new parent %d.%d (%d) old parent %d.%d (%d)\n",
338 best->addr.u8[0], best->addr.u8[1],
339 collect_neighbor_rtmetric(best),
340 tc->parent.u8[0], tc->parent.u8[1],
341 collect_neighbor_rtmetric(current));
349 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(best));
363 PRINTF(
"#A e=%d\n", collect_neighbor_link_estimate(current));
380 PRINTF(
"#L %d 0\n", previous_parent.u8[0]);
382 PRINTF(
"#L %d 1\n", tc->parent.u8[0]);
389 PRINTF(
"#L %d 0\n", tc->parent.u8[0]);
408 PRINTF(
"update_rtmetric: tc->rtmetric %d\n", tc->rtmetric);
411 if(tc->rtmetric != RTMETRIC_SINK) {
412 uint16_t old_rtmetric, new_rtmetric;
415 old_rtmetric = tc->rtmetric;
424 if(new_rtmetric == RTMETRIC_SINK) {
430 new_rtmetric = RTMETRIC_MAX;
435 tc->rtmetric = new_rtmetric;
439 #if COLLECT_ANNOUNCEMENTS
442 neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
446 PRINTF(
"%d.%d: new rtmetric %d\n",
451 if(old_rtmetric == RTMETRIC_MAX && new_rtmetric != RTMETRIC_MAX) {
452 PRINTF(
"Sending queued packet because rtmetric was max\n");
456 if(old_rtmetric != new_rtmetric) {
457 PRINTF(
"#A rt=%d,p=%d\n", tc->rtmetric, tc->parent.u8[0]);
464 enqueue_dummy_packet(
struct collect_conn *c,
int rexmits)
466 struct collect_neighbor *n;
469 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, c->eseqno - 1);
471 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
472 packetbuf_set_attr(PACKETBUF_ATTR_TTL, 1);
473 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
475 PRINTF(
"%d.%d: enqueueing dummy packet %d, max_rexmits %d\n",
477 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
478 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
483 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
486 FORWARD_PACKET_LIFETIME_BASE * rexmits,
493 send_packet(
struct collect_conn *c,
struct collect_neighbor *n)
497 PRINTF(
"Sending packet to %d.%d, %d transmissions\n",
498 n->addr.u8[0], n->addr.u8[1],
504 time = 16 * REXMIT_TIME;
509 unicast_send(&c->unicast_conn, &n->addr);
513 proactive_probing_callback(
void *ptr)
515 struct collect_conn *c = ptr;
518 ctimer_set(&c->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
519 proactive_probing_callback, ptr);
523 if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
533 struct collect_neighbor *n;
536 for(n =
list_head(collect_neighbor_list(&c->neighbor_list));
538 if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
539 collect_link_estimate_num_estimates(&n->le) == 0) {
540 linkaddr_t current_parent;
542 PRINTF(
"proactive_probing_callback: found neighbor with no link estimate, %d.%d\n",
543 n->addr.u8[LINKADDR_SIZE - 2], n->addr.u8[LINKADDR_SIZE - 1]);
547 if(enqueue_dummy_packet(c, PROACTIVE_PROBING_REXMITS)) {
555 PRINTF(
"%d.%d: nothing on queue\n",
572 struct collect_neighbor *n;
574 struct data_msg_hdr hdr;
580 PRINTF(
"%d.%d: queue, c is sending\n",
589 PRINTF(
"%d.%d: nothing on queue\n",
599 queuebuf_to_packetbuf(q);
603 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
611 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
613 n->addr.u8[0], n->addr.u8[1],
614 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
624 c->transmissions = 0;
629 c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
635 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
637 max_mac_rexmits = c->max_rexmits > MAX_MAC_REXMITS?
638 MAX_MAC_REXMITS : c->max_rexmits;
639 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
640 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
646 memset(&hdr, 0,
sizeof(hdr));
647 hdr.rtmetric = c->rtmetric;
654 #if COLLECT_ANNOUNCEMENTS
655 #if COLLECT_CONF_WITH_LISTEN
658 ctimer_set(&c->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
680 struct collect_neighbor *n;
682 struct data_msg_hdr hdr;
689 PRINTF(
"%d.%d: nothing on queue\n",
702 queuebuf_to_packetbuf(q);
716 PRINTF(
"parent change from %d.%d to %d.%d after %d tx\n",
717 c->current_parent.u8[0], c->current_parent.u8[1],
718 c->parent.u8[0], c->parent.u8[1],
722 c->transmissions = 0;
724 n = collect_neighbor_list_find(&c->neighbor_list, &c->current_parent);
732 PRINTF(
"%d.%d: sending packet to %d.%d with eseqno %d\n",
734 n->addr.u8[0], n->addr.u8[1],
735 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
739 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
740 max_mac_rexmits = c->max_rexmits - c->transmissions > MAX_MAC_REXMITS?
741 MAX_MAC_REXMITS : c->max_rexmits - c->transmissions;
742 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
743 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
747 memset(&hdr, 0,
sizeof(hdr));
748 hdr.rtmetric = c->rtmetric;
759 send_next_packet(
struct collect_conn *tc)
763 tc->seqno = (tc->seqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
768 tc->transmissions = 0;
770 PRINTF(
"sending next packet, seqno %d, queue len %d\n",
778 handle_ack(
struct collect_conn *tc)
781 struct collect_neighbor *n;
783 PRINTF(
"handle_ack: sender %d.%d current_parent %d.%d, id %d seqno %d\n",
784 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
785 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
786 tc->current_parent.u8[0], tc->current_parent.u8[1],
787 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID), tc->seqno);
789 &tc->current_parent) &&
790 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
807 if(tc->transmissions == 0) {
808 tc->transmissions = MAX_MAC_REXMITS;
810 PRINTF(
"Updating link estimate with %d transmissions\n",
812 n = collect_neighbor_list_find(&tc->neighbor_list,
813 packetbuf_addr(PACKETBUF_ADDR_SENDER));
816 collect_neighbor_tx(n, tc->transmissions);
817 collect_neighbor_update_rtmetric(n, msg.rtmetric);
821 PRINTF(
"%d.%d: ACK from %d.%d after %d transmissions, flags %02x, rtmetric %d\n",
823 tc->current_parent.u8[0], tc->current_parent.u8[1],
834 if(msg.flags & ACK_FLAGS_CONGESTED) {
835 PRINTF(
"ACK flag indicated parent was congested.\n");
837 collect_neighbor_set_congested(n);
838 collect_neighbor_tx(n, tc->max_rexmits * 2);
842 if((msg.flags & ACK_FLAGS_DROPPED) == 0) {
844 send_next_packet(tc);
849 if((msg.flags & ACK_FLAGS_LIFETIME_EXCEEDED)) {
850 send_next_packet(tc);
855 PRINTF(
"ACK flag indicated packet was dropped by parent.\n");
856 collect_neighbor_tx(n, tc->max_rexmits);
867 if(msg.flags & ACK_FLAGS_RTMETRIC_NEEDS_UPDATE) {
870 set_keepalive_timer(tc);
877 send_ack(
struct collect_conn *tc,
const linkaddr_t *to,
int flags)
880 uint16_t packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
885 memset(ack, 0,
sizeof(
struct ack_msg));
886 ack->rtmetric = tc->rtmetric;
889 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, to);
890 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_ACK);
891 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 0);
892 packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 0);
893 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, packet_seqno);
894 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
895 unicast_send(&tc->unicast_conn, to);
897 PRINTF(
"%d.%d: collect: Sending ACK to %d.%d for %d (epacket_id %d)\n",
899 to->u8[0], to->u8[1], packet_seqno,
900 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
902 RIMESTATS_ADD(acktx);
907 add_packet_to_recent_packets(
struct collect_conn *tc)
914 recent_packets[recent_packet_ptr].eseqno =
915 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
917 packetbuf_addr(PACKETBUF_ADDR_ESENDER));
918 recent_packets[recent_packet_ptr].conn = tc;
919 recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;
924 node_packet_received(
struct unicast_conn *c,
const linkaddr_t *from)
926 struct collect_conn *tc = (
struct collect_conn *)
927 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
929 struct data_msg_hdr hdr;
930 uint8_t ackflags = 0;
931 struct collect_neighbor *n;
937 PRINTF(
"node_packet_received: from %d.%d rtmetric %d\n",
938 from->u8[0], from->u8[1], hdr.rtmetric);
939 n = collect_neighbor_list_find(&tc->neighbor_list,
940 packetbuf_addr(PACKETBUF_ADDR_SENDER));
942 collect_neighbor_update_rtmetric(n, hdr.rtmetric);
950 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
951 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
954 uint8_t packet_seqno;
961 linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
963 packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
972 ackflags |= ACK_FLAGS_CONGESTED;
975 for(i = 0; i < NUM_RECENT_PACKETS; i++) {
976 if(recent_packets[i].conn == tc &&
977 recent_packets[i].eseqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
979 packetbuf_addr(PACKETBUF_ADDR_ESENDER))) {
982 PRINTF(
"%d.%d: found duplicate packet from %d.%d with seqno %d, via %d.%d\n",
984 recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1],
985 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
986 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
987 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]);
988 send_ack(tc, &ack_to, ackflags);
996 if(tc->rtmetric == RTMETRIC_SINK) {
999 add_packet_to_recent_packets(tc);
1003 q = queuebuf_new_from_packetbuf();
1005 send_ack(tc, &ack_to, 0);
1006 queuebuf_to_packetbuf(q);
1009 PRINTF(
"%d.%d: collect: could not send ACK to %d.%d for %d: no queued buffers\n",
1011 ack_to.u8[0], ack_to.u8[1],
1017 PRINTF(
"%d.%d: sink received packet %d from %d.%d via %d.%d\n",
1019 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1020 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
1021 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1022 from->u8[0], from->u8[1]);
1027 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1028 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1029 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1032 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) > 1 &&
1033 tc->rtmetric != RTMETRIC_MAX) {
1042 if(hdr.rtmetric <= tc->rtmetric) {
1043 ackflags |= ACK_FLAGS_RTMETRIC_NEEDS_UPDATE;
1046 packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
1047 packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
1048 packetbuf_set_attr(PACKETBUF_ATTR_TTL,
1049 packetbuf_attr(PACKETBUF_ATTR_TTL) - 1);
1052 PRINTF(
"%d.%d: packet received from %d.%d via %d.%d, sending %d, max_rexmits %d\n",
1054 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
1055 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
1056 from->u8[0], from->u8[1], tc->sending,
1057 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1066 if(
packetqueue_len(&tc->send_queue) <= MAX_SENDING_QUEUE - MIN_AVAILABLE_QUEUE_ENTRIES &&
1068 FORWARD_PACKET_LIFETIME_BASE *
1069 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1071 add_packet_to_recent_packets(tc);
1072 send_ack(tc, &ack_to, ackflags);
1075 send_ack(tc, &ack_to,
1076 ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
1077 PRINTF(
"%d.%d: packet dropped: no queue buffer available\n",
1081 }
else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
1082 PRINTF(
"%d.%d: packet dropped: ttl %d\n",
1084 packetbuf_attr(PACKETBUF_ATTR_TTL));
1085 send_ack(tc, &ack_to, ackflags |
1086 ACK_FLAGS_DROPPED | ACK_FLAGS_LIFETIME_EXCEEDED);
1089 }
else if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1090 PACKETBUF_ATTR_PACKET_TYPE_ACK) {
1091 PRINTF(
"Collect: incoming ack %d from %d.%d (%d.%d) seqno %d (%d)\n",
1092 packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE),
1093 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
1094 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
1095 tc->current_parent.u8[0],
1096 tc->current_parent.u8[1],
1097 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID),
1106 timedout(
struct collect_conn *tc)
1108 struct collect_neighbor *n;
1109 PRINTF(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1111 tc->current_parent.u8[0], tc->current_parent.u8[1],
1113 PRINTF(
"%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
1115 tc->current_parent.u8[0], tc->current_parent.u8[1],
1119 n = collect_neighbor_list_find(&tc->neighbor_list,
1120 &tc->current_parent);
1122 collect_neighbor_tx_fail(n, tc->max_rexmits);
1125 send_next_packet(tc);
1126 set_keepalive_timer(tc);
1130 node_packet_sent(
struct unicast_conn *c,
int status,
int transmissions)
1132 struct collect_conn *tc = (
struct collect_conn *)
1133 ((
char *)c - offsetof(
struct collect_conn, unicast_conn));
1136 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
1137 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
1139 tc->transmissions += transmissions;
1140 PRINTF(
"tx %d\n", tc->transmissions);
1141 PRINTF(
"%d.%d: MAC sent %d transmissions to %d.%d, status %d, total transmissions %d\n",
1144 tc->current_parent.u8[0], tc->current_parent.u8[1],
1145 status, tc->transmissions);
1146 if(tc->transmissions >= tc->max_rexmits) {
1150 clock_time_t time = REXMIT_TIME / 2 + (
random_rand() % (REXMIT_TIME / 2));
1151 PRINTF(
"retransmission time %lu\n", time);
1169 struct collect_conn *c = ptr;
1171 PRINTF(
"retransmit not sent, %d transmissions\n", c->transmissions);
1172 c->transmissions += MAX_MAC_REXMITS + 1;
1186 struct collect_conn *c = ptr;
1188 PRINTF(
"retransmit, %d transmissions\n", c->transmissions);
1189 if(c->transmissions >= c->max_rexmits) {
1198 #if !COLLECT_ANNOUNCEMENTS
1200 adv_received(
struct neighbor_discovery_conn *c,
const linkaddr_t *from,
1203 struct collect_conn *tc = (
struct collect_conn *)
1204 ((
char *)c - offsetof(
struct collect_conn, neighbor_discovery_conn));
1205 struct collect_neighbor *n;
1207 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1210 collect_neighbor_list_add(&tc->neighbor_list, from, rtmetric);
1211 if(rtmetric == RTMETRIC_MAX) {
1223 if(rtmetric == RTMETRIC_MAX &&
1224 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1227 collect_neighbor_update_rtmetric(n, rtmetric);
1228 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1230 n->addr.u8[0], n->addr.u8[1], rtmetric);
1237 received_announcement(
struct announcement *a,
const linkaddr_t *from,
1238 uint16_t
id, uint16_t value)
1240 struct collect_conn *tc = (
struct collect_conn *)
1241 ((
char *)a - offsetof(
struct collect_conn,
announcement));
1242 struct collect_neighbor *n;
1244 n = collect_neighbor_list_find(&tc->neighbor_list, from);
1249 if(value < tc->rtmetric) {
1250 collect_neighbor_list_add(&tc->neighbor_list, from, value);
1251 PRINTF(
"%d.%d: new neighbor %d.%d, rtmetric %d\n",
1253 from->u8[0], from->u8[1], value);
1255 if(value == RTMETRIC_MAX && tc->rtmetric != RTMETRIC_MAX) {
1267 if(value == RTMETRIC_MAX &&
1268 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
1271 collect_neighbor_update_rtmetric(n, value);
1272 PRINTF(
"%d.%d: updating neighbor %d.%d, etx %d\n",
1274 n->addr.u8[0], n->addr.u8[1], value);
1279 #if ! COLLECT_CONF_WITH_LISTEN
1280 if(value == RTMETRIC_MAX &&
1281 tc->rtmetric != RTMETRIC_MAX) {
1290 static const struct unicast_callbacks unicast_callbacks = {node_packet_received,
1292 #if !COLLECT_ANNOUNCEMENTS
1293 static const struct neighbor_discovery_callbacks neighbor_discovery_callbacks =
1294 { adv_received,
NULL};
1298 collect_open(
struct collect_conn *tc, uint16_t channels,
1300 const struct collect_callbacks *cb)
1302 unicast_open(&tc->unicast_conn, channels + 1, &unicast_callbacks);
1303 channel_set_attributes(channels + 1, attributes);
1304 tc->rtmetric = RTMETRIC_MAX;
1306 tc->is_router = is_router;
1310 collect_neighbor_list_new(&tc->neighbor_list);
1311 tc->send_queue.list = &(tc->send_queue_list);
1312 tc->send_queue.memb = &send_queue_memb;
1313 collect_neighbor_init();
1315 #if !COLLECT_ANNOUNCEMENTS
1316 neighbor_discovery_open(&tc->neighbor_discovery_conn, channels,
1319 #ifdef COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
1320 COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME,
1324 &neighbor_discovery_callbacks);
1325 neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
1328 received_announcement);
1329 #if ! COLLECT_CONF_WITH_LISTEN
1336 ctimer_set(&tc->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
1337 proactive_probing_callback, tc);
1342 send_keepalive(
void *ptr)
1344 struct collect_conn *c = ptr;
1346 set_keepalive_timer(c);
1350 if(enqueue_dummy_packet(c, KEEPALIVE_REXMITS)) {
1351 PRINTF(
"%d.%d: sending keepalive\n",
1359 set_keepalive_timer(
struct collect_conn *c)
1361 if(c->keepalive_period != 0) {
1362 ctimer_set(&c->keepalive_timer, (c->keepalive_period / 2) +
1371 collect_set_keepalive(
struct collect_conn *c, clock_time_t period)
1373 c->keepalive_period = period;
1374 set_keepalive_timer(c);
1378 collect_close(
struct collect_conn *tc)
1380 #if COLLECT_ANNOUNCEMENTS
1383 neighbor_discovery_close(&tc->neighbor_discovery_conn);
1385 unicast_close(&tc->unicast_conn);
1392 collect_set_sink(
struct collect_conn *tc,
int should_be_sink)
1394 if(should_be_sink) {
1396 tc->rtmetric = RTMETRIC_SINK;
1397 PRINTF(
"collect_set_sink: tc->rtmetric %d\n", tc->rtmetric);
1408 tc->rtmetric = RTMETRIC_MAX;
1410 #if COLLECT_ANNOUNCEMENTS
1418 PRINTF(
"#A rt=0,p=0\n");
1423 collect_send(
struct collect_conn *tc,
int rexmits)
1425 struct collect_neighbor *n;
1428 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno);
1438 tc->eseqno = (tc->eseqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
1440 if(tc->eseqno == 0) {
1441 tc->eseqno = ((int)(1 << COLLECT_PACKET_ID_BITS)) / 2;
1444 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
1445 packetbuf_set_attr(PACKETBUF_ATTR_TTL, MAX_HOPLIM);
1446 if(rexmits > MAX_REXMITS) {
1447 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, MAX_REXMITS);
1449 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
1452 PRINTF(
"%d.%d: originating packet %d, max_rexmits %d\n",
1454 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1455 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
1457 if(tc->rtmetric == RTMETRIC_SINK) {
1458 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
1459 if(tc->cb->recv !=
NULL) {
1460 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
1461 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
1462 packetbuf_attr(PACKETBUF_ATTR_HOPS));
1471 FORWARD_PACKET_LIFETIME_BASE *
1472 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
1477 PRINTF(
"%d.%d: drop originated packet: no queuebuf\n",
1479 PRINTF(
"%d.%d: drop originated packet: no queuebuf\n",
1485 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
1487 PRINTF(
"%d.%d: sending to %d.%d\n",
1489 n->addr.u8[0], n->addr.u8[1]);
1491 PRINTF(
"%d.%d: did not find any neighbor to send to\n",
1493 #if COLLECT_ANNOUNCEMENTS
1494 #if COLLECT_CONF_WITH_LISTEN
1497 ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
1524 collect_depth(
struct collect_conn *tc)
1526 return tc->rtmetric;
1530 collect_parent(
struct collect_conn *tc)
1532 return &tc->current_parent;
1536 collect_purge(
struct collect_conn *tc)
1538 collect_neighbor_list_purge(&tc->neighbor_list);
1542 PRINTF(
"#L %d 0\n", tc->parent.u8[0]);
1548 collect_print_stats(
void)
1550 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",
1551 stats.foundroute, stats.newparent, stats.routelost,
1552 stats.acksent, stats.datasent, stats.datarecv,
1553 stats.ackrecv, stats.badack, stats.duprecv,
1554 stats.qdrop, stats.rtdrop, stats.ttldrop, stats.ackdrop,
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
void announcement_bump(struct announcement *a)
Bump an announcement.
Header file for the Collect link estimate
Representation of an announcement.
static void send_queued_packet(struct collect_conn *c)
This function is called when a queued packet should be sent out.
static void retransmit_not_sent_callback(void *ptr)
This function is called from a ctimer that is setup when a packet is first transmitted.
void announcement_set_value(struct announcement *a, uint16_t value)
Set the value of an announcement.
#define MEMB(name, structure, num)
Declare a memory block.
void packetbuf_clear(void)
Clear and reset the packetbuf.
CCIF clock_time_t clock_time(void)
Get the current clock time.
static void retransmit_callback(void *ptr)
This function is called from a ctimer that is setup when a packet is sent.
Header file for the packetqueue module
void * list_item_next(void *item)
Get the next item following this item.
static uint16_t rtmetric_compute(struct collect_conn *tc)
This function computes the current rtmetric by adding the last known rtmetric from our parent with th...
static void update_rtmetric(struct collect_conn *tc)
This function is called whenever there is a chance that the routing metric has changed.
void announcement_register(struct announcement *a, uint16_t id, announcement_callback_t callback)
Register an announcement.
const linkaddr_t linkaddr_null
The null Rime address.
struct packetqueue_item * packetqueue_first(struct packetqueue *q)
Access the first item on the packet buffer.
Header file for the Contiki radio neighborhood management
void * list_head(list_t list)
Get a pointer to the first element of a list.
Header file for the Rime stack
#define NULL
The null pointer.
int packetqueue_enqueue_packetbuf(struct packetqueue *q, clock_time_t lifetime, void *ptr)
Enqueue a packetbuf on a packet queue.
unsigned short random_rand(void)
Generates a new random number using the cc2538 RNG.
void packetqueue_dequeue(struct packetqueue *q)
Remove the first item on the packet buffer.
struct queuebuf * packetqueue_queuebuf(struct packetqueue_item *i)
Access the queuebuf in a packet queue item.
static void update_parent(struct collect_conn *tc)
This function is called to update the current parent node.
void announcement_listen(int time)
Listen for announcements for a specific amount of announcement periods.
#define CLOCK_SECOND
A second, measured in system clock time.
Header file for hop-by-hop reliable data collection
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Representation of an item in a packet queue.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void announcement_remove(struct announcement *a)
Remove a previously registered announcement.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
static void retransmit_current_packet(struct collect_conn *c)
This function is called to retransmit the first packet on the send queue.
int packetqueue_len(struct packetqueue *q)
Get the length of the packet queue.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
static void bump_advertisement(struct collect_conn *c)
This function is called when the route advertisements need to be transmitted more rapidly...
int packetbuf_hdrreduce(int size)
Reduce the header in the packetbuf, for incoming packets.
Include file for the Contiki low-layer network stack (NETSTACK)