00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "contiki.h"
00047
00048 #include "net/rime.h"
00049 #include "net/rime/collect.h"
00050 #include "net/rime/collect-neighbor.h"
00051 #include "net/rime/collect-link-estimate.h"
00052
00053 #include "net/packetqueue.h"
00054
00055 #include "dev/radio-sensor.h"
00056
00057 #include "lib/random.h"
00058
00059 #include <string.h>
00060 #include <stdio.h>
00061 #include <stddef.h>
00062
00063 static const struct packetbuf_attrlist attributes[] =
00064 {
00065 COLLECT_ATTRIBUTES
00066 PACKETBUF_ATTR_LAST
00067 };
00068
00069
00070
00071
00072
00073
00074 #define NUM_RECENT_PACKETS 16
00075
00076 struct recent_packet {
00077 struct collect_conn *conn;
00078 rimeaddr_t originator;
00079 uint8_t eseqno;
00080 };
00081
00082 static struct recent_packet recent_packets[NUM_RECENT_PACKETS];
00083 static uint8_t recent_packet_ptr;
00084
00085
00086
00087
00088
00089
00090 struct data_msg_hdr {
00091 uint8_t flags, dummy;
00092 uint16_t rtmetric;
00093 };
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 struct ack_msg {
00106 uint8_t flags, dummy;
00107 uint16_t rtmetric;
00108 };
00109
00110 #define ACK_FLAGS_CONGESTED 0x80
00111 #define ACK_FLAGS_DROPPED 0x40
00112 #define ACK_FLAGS_LIFETIME_EXCEEDED 0x20
00113 #define ACK_FLAGS_RTMETRIC_NEEDS_UPDATE 0x10
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define MAX_MAC_REXMITS 2
00128 #define MAX_ACK_MAC_REXMITS 5
00129 #define REXMIT_TIME CLOCK_SECOND * 4
00130 #define FORWARD_PACKET_LIFETIME_BASE REXMIT_TIME * 2
00131 #define MAX_SENDING_QUEUE 3 * QUEUEBUF_NUM / 4
00132 #define MIN_AVAILABLE_QUEUE_ENTRIES 4
00133 #define KEEPALIVE_REXMITS 8
00134 #define MAX_REXMITS 31
00135
00136 MEMB(send_queue_memb, struct packetqueue_item, MAX_SENDING_QUEUE);
00137
00138
00139
00140
00141
00142 #define RTMETRIC_SINK 0
00143 #define RTMETRIC_MAX COLLECT_MAX_DEPTH
00144
00145
00146
00147
00148
00149 #define SIGNIFICANT_RTMETRIC_PARENT_CHANGE (COLLECT_LINK_ESTIMATE_UNIT + \
00150 COLLECT_LINK_ESTIMATE_UNIT / 2)
00151
00152
00153
00154 #define MAX_HOPLIM 15
00155
00156
00157
00158
00159
00160
00161 #define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
00162 #define PROACTIVE_PROBING_REXMITS 15
00163
00164
00165
00166
00167 #ifdef ANNOUNCEMENT_CONF_PERIOD
00168 #define ANNOUNCEMENT_SCAN_TIME ANNOUNCEMENT_CONF_PERIOD
00169 #else
00170 #define ANNOUNCEMENT_SCAN_TIME CLOCK_SECOND
00171 #endif
00172
00173
00174
00175 struct {
00176 uint32_t foundroute;
00177 uint32_t newparent;
00178 uint32_t routelost;
00179
00180 uint32_t acksent;
00181 uint32_t datasent;
00182
00183 uint32_t datarecv;
00184 uint32_t ackrecv;
00185 uint32_t badack;
00186 uint32_t duprecv;
00187
00188 uint32_t qdrop;
00189 uint32_t rtdrop;
00190 uint32_t ttldrop;
00191 uint32_t ackdrop;
00192 uint32_t timedout;
00193 } stats;
00194
00195
00196 #define DRAW_TREE 0
00197 #define DEBUG 0
00198 #if DEBUG
00199 #include <stdio.h>
00200 #define PRINTF(...) printf(__VA_ARGS__)
00201 #else
00202 #define PRINTF(...)
00203 #endif
00204
00205
00206 static void send_queued_packet(struct collect_conn *c);
00207 static void retransmit_callback(void *ptr);
00208 static void retransmit_not_sent_callback(void *ptr);
00209 static void set_keepalive_timer(struct collect_conn *c);
00210
00211
00212
00213
00214
00215
00216
00217
00218 static uint16_t
00219 rtmetric_compute(struct collect_conn *tc)
00220 {
00221 struct collect_neighbor *n;
00222 uint16_t rtmetric = RTMETRIC_MAX;
00223
00224
00225
00226
00227
00228
00229
00230
00231 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
00232
00233
00234
00235 if(n == NULL) {
00236 rtmetric = RTMETRIC_MAX;
00237 } else {
00238
00239
00240 rtmetric = collect_neighbor_rtmetric_link_estimate(n);
00241 }
00242
00243 return rtmetric;
00244 }
00245
00246
00247
00248
00249
00250
00251 static void
00252 bump_advertisement(struct collect_conn *c)
00253 {
00254 #if !COLLECT_ANNOUNCEMENTS
00255 neighbor_discovery_start(&c->neighbor_discovery_conn, c->rtmetric);
00256 #else
00257 announcement_bump(&c->announcement);
00258 #endif
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268 static void
00269 update_parent(struct collect_conn *tc)
00270 {
00271 struct collect_neighbor *current;
00272 struct collect_neighbor *best;
00273
00274
00275 current = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
00276
00277
00278
00279 best = collect_neighbor_list_best(&tc->neighbor_list);
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 if(best != NULL) {
00299 rimeaddr_t previous_parent;
00300
00301 if(DRAW_TREE) {
00302 rimeaddr_copy(&previous_parent, &tc->parent);
00303 }
00304
00305 if(current == NULL) {
00306
00307 PRINTF("update_parent: new parent %d.%d\n",
00308 best->addr.u8[0], best->addr.u8[1]);
00309 rimeaddr_copy(&tc->parent, &best->addr);
00310 stats.foundroute++;
00311 bump_advertisement(tc);
00312 } else {
00313 if(DRAW_TREE) {
00314 printf("#A e=%d\n", collect_neighbor_link_estimate(best));
00315 }
00316 if(collect_neighbor_rtmetric_link_estimate(best) +
00317 SIGNIFICANT_RTMETRIC_PARENT_CHANGE <
00318 collect_neighbor_rtmetric_link_estimate(current)) {
00319
00320
00321 PRINTF("update_parent: new parent %d.%d (%d) old parent %d.%d (%d)\n",
00322 best->addr.u8[0], best->addr.u8[1],
00323 collect_neighbor_rtmetric(best),
00324 tc->parent.u8[0], tc->parent.u8[1],
00325 collect_neighbor_rtmetric(current));
00326 rimeaddr_copy(&tc->parent, &best->addr);
00327 stats.newparent++;
00328
00329
00330 bump_advertisement(tc);
00331
00332 if(DRAW_TREE) {
00333 printf("#A e=%d\n", collect_neighbor_link_estimate(best));
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 }
00345 } else {
00346 if(DRAW_TREE) {
00347 printf("#A e=%d\n", collect_neighbor_link_estimate(current));
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 }
00359 }
00360 }
00361 if(DRAW_TREE) {
00362 if(!rimeaddr_cmp(&previous_parent, &tc->parent)) {
00363 if(!rimeaddr_cmp(&previous_parent, &rimeaddr_null)) {
00364 printf("#L %d 0\n", previous_parent.u8[0]);
00365 }
00366 printf("#L %d 1\n", tc->parent.u8[0]);
00367 }
00368 }
00369 } else {
00370
00371 if(!rimeaddr_cmp(&tc->parent, &rimeaddr_null)) {
00372 if(DRAW_TREE) {
00373 printf("#L %d 0\n", tc->parent.u8[0]);
00374 }
00375 stats.routelost++;
00376 }
00377 rimeaddr_copy(&tc->parent, &rimeaddr_null);
00378 }
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 static void
00390 update_rtmetric(struct collect_conn *tc)
00391 {
00392 PRINTF("update_rtmetric: tc->rtmetric %d\n", tc->rtmetric);
00393
00394
00395 if(tc->rtmetric != RTMETRIC_SINK) {
00396 uint16_t old_rtmetric, new_rtmetric;
00397
00398
00399 old_rtmetric = tc->rtmetric;
00400
00401
00402 update_parent(tc);
00403
00404
00405 new_rtmetric = rtmetric_compute(tc);
00406
00407
00408 if(new_rtmetric == RTMETRIC_SINK) {
00409
00410
00411
00412
00413
00414 new_rtmetric = RTMETRIC_MAX;
00415 }
00416
00417
00418
00419 tc->rtmetric = new_rtmetric;
00420
00421 if(tc->is_router) {
00422
00423 #if COLLECT_ANNOUNCEMENTS
00424 announcement_set_value(&tc->announcement, tc->rtmetric);
00425 #else
00426 neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
00427 #endif
00428
00429 }
00430 PRINTF("%d.%d: new rtmetric %d\n",
00431 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00432 tc->rtmetric);
00433
00434
00435 if(old_rtmetric == RTMETRIC_MAX && new_rtmetric != RTMETRIC_MAX) {
00436 PRINTF("Sending queued packet because rtmetric was max\n");
00437 send_queued_packet(tc);
00438 }
00439 if(DRAW_TREE) {
00440 if(old_rtmetric != new_rtmetric) {
00441 printf("#A rt=%d,p=%d\n", tc->rtmetric, tc->parent.u8[0]);
00442 }
00443 }
00444 }
00445 }
00446
00447 static int
00448 enqueue_dummy_packet(struct collect_conn *c, int rexmits)
00449 {
00450 struct collect_neighbor *n;
00451
00452 packetbuf_clear();
00453 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, c->eseqno - 1);
00454 packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr);
00455 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
00456 packetbuf_set_attr(PACKETBUF_ATTR_TTL, 1);
00457 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
00458
00459 PRINTF("%d.%d: enqueueing dummy packet %d, max_rexmits %d\n",
00460 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00461 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
00462 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
00463
00464
00465 packetbuf_hdralloc(sizeof(struct data_msg_hdr));
00466
00467 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
00468 if(n != NULL) {
00469 return packetqueue_enqueue_packetbuf(&c->send_queue,
00470 FORWARD_PACKET_LIFETIME_BASE * rexmits,
00471 c);
00472 }
00473 return 0;
00474 }
00475
00476 static void
00477 send_packet(struct collect_conn *c, struct collect_neighbor *n)
00478 {
00479 clock_time_t time;
00480
00481 PRINTF("Sending packet to %d.%d, %d transmissions\n",
00482 n->addr.u8[0], n->addr.u8[1],
00483 c->transmissions);
00484
00485
00486
00487
00488 time = 16 * REXMIT_TIME;
00489 ctimer_set(&c->retransmission_timer, time,
00490 retransmit_not_sent_callback, c);
00491 c->send_time = clock_time();
00492
00493 unicast_send(&c->unicast_conn, &n->addr);
00494 }
00495
00496 static void
00497 proactive_probing_callback(void *ptr)
00498 {
00499 struct collect_conn *c = ptr;
00500 struct packetqueue_item *i;
00501
00502 ctimer_set(&c->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
00503 proactive_probing_callback, ptr);
00504
00505
00506
00507 if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
00508
00509
00510 i = packetqueue_first(&c->send_queue);
00511 if(i == NULL) {
00512
00513
00514
00515
00516
00517 struct collect_neighbor *n;
00518
00519
00520 for(n = list_head(collect_neighbor_list(&c->neighbor_list));
00521 n != NULL; n = list_item_next(n)) {
00522 if(n->rtmetric + COLLECT_LINK_ESTIMATE_UNIT < c->rtmetric &&
00523 collect_link_estimate_num_estimates(&n->le) == 0) {
00524 rimeaddr_t current_parent;
00525
00526 PRINTF("proactive_probing_callback: found neighbor with no link estimate, %d.%d\n",
00527 n->addr.u8[RIMEADDR_SIZE - 2], n->addr.u8[RIMEADDR_SIZE - 1]);
00528
00529 rimeaddr_copy(¤t_parent, &c->parent);
00530 rimeaddr_copy(&c->parent, &n->addr);
00531 if(enqueue_dummy_packet(c, PROACTIVE_PROBING_REXMITS)) {
00532 send_queued_packet(c);
00533 }
00534 rimeaddr_copy(&c->parent, ¤t_parent);
00535 return;
00536 }
00537 }
00538 }
00539 PRINTF("%d.%d: nothing on queue\n",
00540 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00541 return;
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552 static void
00553 send_queued_packet(struct collect_conn *c)
00554 {
00555 struct queuebuf *q;
00556 struct collect_neighbor *n;
00557 struct packetqueue_item *i;
00558 struct data_msg_hdr hdr;
00559 int max_mac_rexmits;
00560
00561
00562
00563 if(c->sending) {
00564 PRINTF("%d.%d: queue, c is sending\n",
00565 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00566 return;
00567 }
00568
00569
00570
00571 i = packetqueue_first(&c->send_queue);
00572 if(i == NULL) {
00573 PRINTF("%d.%d: nothing on queue\n",
00574 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00575
00576 return;
00577 }
00578
00579
00580 q = packetqueue_queuebuf(i);
00581 if(q != NULL) {
00582
00583 queuebuf_to_packetbuf(q);
00584
00585
00586
00587 n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
00588
00589 if(n != NULL) {
00590
00591
00592
00593
00594
00595 PRINTF("%d.%d: sending packet to %d.%d with eseqno %d\n",
00596 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00597 n->addr.u8[0], n->addr.u8[1],
00598 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
00599
00600
00601 c->sending = 1;
00602
00603
00604 rimeaddr_copy(&c->current_parent, &c->parent);
00605
00606
00607
00608 c->transmissions = 0;
00609
00610
00611
00612
00613 c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
00614
00615
00616
00617
00618
00619 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
00620
00621 max_mac_rexmits = c->max_rexmits > MAX_MAC_REXMITS?
00622 MAX_MAC_REXMITS : c->max_rexmits;
00623 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
00624 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
00625
00626 stats.datasent++;
00627
00628
00629
00630 memset(&hdr, 0, sizeof(hdr));
00631 hdr.rtmetric = c->rtmetric;
00632 memcpy(packetbuf_dataptr(), &hdr, sizeof(struct data_msg_hdr));
00633
00634
00635 send_packet(c, n);
00636
00637 } else {
00638 #if COLLECT_ANNOUNCEMENTS
00639 #if COLLECT_CONF_WITH_LISTEN
00640 PRINTF("listen\n");
00641 announcement_listen(1);
00642 ctimer_set(&c->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
00643 send_queued_packet, c);
00644 #else
00645 announcement_set_value(&c->announcement, RTMETRIC_MAX);
00646 announcement_bump(&c->announcement);
00647 #endif
00648 #endif
00649 }
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658 static void
00659 retransmit_current_packet(struct collect_conn *c)
00660 {
00661 struct queuebuf *q;
00662 struct collect_neighbor *n;
00663 struct packetqueue_item *i;
00664 struct data_msg_hdr hdr;
00665 int max_mac_rexmits;
00666
00667
00668
00669 i = packetqueue_first(&c->send_queue);
00670 if(i == NULL) {
00671 PRINTF("%d.%d: nothing on queue\n",
00672 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00673
00674 return;
00675 }
00676
00677
00678 q = packetqueue_queuebuf(i);
00679 if(q != NULL) {
00680
00681 update_rtmetric(c);
00682
00683
00684 queuebuf_to_packetbuf(q);
00685
00686
00687
00688
00689
00690 if(!rimeaddr_cmp(&c->current_parent, &c->parent)) {
00691
00692
00693
00694
00695
00696
00697
00698 PRINTF("parent change from %d.%d to %d.%d after %d tx\n",
00699 c->current_parent.u8[0], c->current_parent.u8[1],
00700 c->parent.u8[0], c->parent.u8[1],
00701 c->transmissions);
00702
00703 rimeaddr_copy(&c->current_parent, &c->parent);
00704 c->transmissions = 0;
00705 }
00706 n = collect_neighbor_list_find(&c->neighbor_list, &c->current_parent);
00707
00708 if(n != NULL) {
00709
00710
00711
00712
00713
00714 PRINTF("%d.%d: sending packet to %d.%d with eseqno %d\n",
00715 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00716 n->addr.u8[0], n->addr.u8[1],
00717 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
00718
00719
00720 c->sending = 1;
00721 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 1);
00722 max_mac_rexmits = c->max_rexmits - c->transmissions > MAX_MAC_REXMITS?
00723 MAX_MAC_REXMITS : c->max_rexmits - c->transmissions;
00724 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, max_mac_rexmits);
00725 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, c->seqno);
00726
00727
00728
00729 memset(&hdr, 0, sizeof(hdr));
00730 hdr.rtmetric = c->rtmetric;
00731 memcpy(packetbuf_dataptr(), &hdr, sizeof(struct data_msg_hdr));
00732
00733
00734 send_packet(c, n);
00735 }
00736 }
00737
00738 }
00739
00740 static void
00741 send_next_packet(struct collect_conn *tc)
00742 {
00743
00744 packetqueue_dequeue(&tc->send_queue);
00745 tc->seqno = (tc->seqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
00746
00747
00748 ctimer_stop(&tc->retransmission_timer);
00749 tc->sending = 0;
00750 tc->transmissions = 0;
00751
00752 PRINTF("sending next packet, seqno %d, queue len %d\n",
00753 tc->seqno, packetqueue_len(&tc->send_queue));
00754
00755
00756 send_queued_packet(tc);
00757 }
00758
00759 static void
00760 handle_ack(struct collect_conn *tc)
00761 {
00762 struct ack_msg *msg;
00763 uint16_t rtmetric;
00764 struct collect_neighbor *n;
00765
00766 PRINTF("handle_ack: sender %d.%d current_parent %d.%d, id %d seqno %d\n",
00767 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
00768 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
00769 tc->current_parent.u8[0], tc->current_parent.u8[1],
00770 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID), tc->seqno);
00771 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
00772 &tc->current_parent) &&
00773 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == tc->seqno) {
00774
00775
00776
00777
00778
00779
00780
00781 stats.ackrecv++;
00782 msg = packetbuf_dataptr();
00783 memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
00784
00785
00786
00787
00788
00789
00790
00791 if(tc->transmissions == 0) {
00792 tc->transmissions = MAX_MAC_REXMITS;
00793 }
00794 PRINTF("Updating link estimate with %d transmissions\n",
00795 tc->transmissions);
00796 n = collect_neighbor_list_find(&tc->neighbor_list,
00797 packetbuf_addr(PACKETBUF_ADDR_SENDER));
00798
00799 if(n != NULL) {
00800 collect_neighbor_tx(n, tc->transmissions);
00801 collect_neighbor_update_rtmetric(n, rtmetric);
00802 update_rtmetric(tc);
00803 }
00804
00805 PRINTF("%d.%d: ACK from %d.%d after %d transmissions, flags %02x, rtmetric %d\n",
00806 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00807 tc->current_parent.u8[0], tc->current_parent.u8[1],
00808 tc->transmissions,
00809 msg->flags,
00810 rtmetric);
00811
00812
00813
00814
00815
00816
00817
00818 if(msg->flags & ACK_FLAGS_CONGESTED) {
00819 PRINTF("ACK flag indicated parent was congested.\n");
00820 collect_neighbor_set_congested(n);
00821 collect_neighbor_tx(n, tc->max_rexmits * 2);
00822 update_rtmetric(tc);
00823 }
00824 if((msg->flags & ACK_FLAGS_DROPPED) == 0) {
00825
00826 send_next_packet(tc);
00827 } else {
00828
00829
00830
00831 if((msg->flags & ACK_FLAGS_LIFETIME_EXCEEDED)) {
00832 send_next_packet(tc);
00833 } else {
00834
00835
00836
00837 PRINTF("ACK flag indicated packet was dropped by parent.\n");
00838 collect_neighbor_tx(n, tc->max_rexmits);
00839 update_rtmetric(tc);
00840
00841 ctimer_set(&tc->retransmission_timer,
00842 REXMIT_TIME + (random_rand() % (REXMIT_TIME)),
00843 retransmit_callback, tc);
00844 }
00845 }
00846
00847
00848
00849 if(msg->flags & ACK_FLAGS_RTMETRIC_NEEDS_UPDATE) {
00850 bump_advertisement(tc);
00851 }
00852 set_keepalive_timer(tc);
00853 } else {
00854 stats.badack++;
00855 }
00856 }
00857
00858 static void
00859 send_ack(struct collect_conn *tc, const rimeaddr_t *to, int flags)
00860 {
00861 struct ack_msg *ack;
00862 uint16_t packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
00863
00864 packetbuf_clear();
00865 packetbuf_set_datalen(sizeof(struct ack_msg));
00866 ack = packetbuf_dataptr();
00867 memset(ack, 0, sizeof(struct ack_msg));
00868 ack->rtmetric = tc->rtmetric;
00869 ack->flags = flags;
00870
00871 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, to);
00872 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_TYPE, PACKETBUF_ATTR_PACKET_TYPE_ACK);
00873 packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, 0);
00874 packetbuf_set_attr(PACKETBUF_ATTR_ERELIABLE, 0);
00875 packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, packet_seqno);
00876 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS, MAX_ACK_MAC_REXMITS);
00877 unicast_send(&tc->unicast_conn, to);
00878
00879 PRINTF("%d.%d: collect: Sending ACK to %d.%d for %d (epacket_id %d)\n",
00880 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
00881 to->u8[0], to->u8[1], packet_seqno,
00882 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
00883
00884 RIMESTATS_ADD(acktx);
00885 stats.acksent++;
00886 }
00887
00888 static void
00889 add_packet_to_recent_packets(struct collect_conn *tc)
00890 {
00891
00892
00893
00894
00895 if(packetbuf_datalen() > sizeof(struct data_msg_hdr)) {
00896 recent_packets[recent_packet_ptr].eseqno =
00897 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
00898 rimeaddr_copy(&recent_packets[recent_packet_ptr].originator,
00899 packetbuf_addr(PACKETBUF_ADDR_ESENDER));
00900 recent_packets[recent_packet_ptr].conn = tc;
00901 recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;
00902 }
00903 }
00904
00905 static void
00906 node_packet_received(struct unicast_conn *c, const rimeaddr_t *from)
00907 {
00908 struct collect_conn *tc = (struct collect_conn *)
00909 ((char *)c - offsetof(struct collect_conn, unicast_conn));
00910 int i;
00911 struct data_msg_hdr hdr;
00912 uint8_t ackflags = 0;
00913 struct collect_neighbor *n;
00914
00915 memcpy(&hdr, packetbuf_dataptr(), sizeof(struct data_msg_hdr));
00916
00917
00918
00919 PRINTF("node_packet_received: from %d.%d rtmetric %d\n",
00920 from->u8[0], from->u8[1], hdr.rtmetric);
00921 n = collect_neighbor_list_find(&tc->neighbor_list,
00922 packetbuf_addr(PACKETBUF_ADDR_SENDER));
00923 if(n != NULL) {
00924 collect_neighbor_update_rtmetric(n, hdr.rtmetric);
00925 update_rtmetric(tc);
00926 }
00927
00928
00929
00930
00931
00932 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
00933 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
00934 rimeaddr_t ack_to;
00935 uint8_t packet_seqno;
00936
00937 stats.datarecv++;
00938
00939
00940
00941 rimeaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
00942 packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
00943
00944
00945
00946 if(DRAW_TREE) {
00947 printf("#A s=%d\n", packetqueue_len(&tc->send_queue));
00948 }
00949 if(packetqueue_len(&tc->send_queue) >= MAX_SENDING_QUEUE / 2) {
00950 ackflags |= ACK_FLAGS_CONGESTED;
00951 }
00952
00953 for(i = 0; i < NUM_RECENT_PACKETS; i++) {
00954 if(recent_packets[i].conn == tc &&
00955 recent_packets[i].eseqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
00956 rimeaddr_cmp(&recent_packets[i].originator,
00957 packetbuf_addr(PACKETBUF_ADDR_ESENDER))) {
00958
00959
00960 PRINTF("%d.%d: found duplicate packet from %d.%d with seqno %d, via %d.%d\n",
00961 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00962 recent_packets[i].originator.u8[0], recent_packets[i].originator.u8[1],
00963 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
00964 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
00965 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1]);
00966 send_ack(tc, &ack_to, ackflags);
00967 stats.duprecv++;
00968 return;
00969 }
00970 }
00971
00972
00973
00974 if(tc->rtmetric == RTMETRIC_SINK) {
00975 struct queuebuf *q;
00976
00977 add_packet_to_recent_packets(tc);
00978
00979
00980
00981 q = queuebuf_new_from_packetbuf();
00982 if(q != NULL) {
00983 send_ack(tc, &ack_to, 0);
00984 queuebuf_to_packetbuf(q);
00985 queuebuf_free(q);
00986 } else {
00987 PRINTF("%d.%d: collect: could not send ACK to %d.%d for %d: no queued buffers\n",
00988 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
00989 ack_to.u8[0], ack_to.u8[1],
00990 packet_seqno);
00991 stats.ackdrop++;
00992 }
00993
00994
00995 PRINTF("%d.%d: sink received packet %d from %d.%d via %d.%d\n",
00996 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00997 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
00998 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
00999 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
01000 from->u8[0], from->u8[1]);
01001
01002 packetbuf_hdrreduce(sizeof(struct data_msg_hdr));
01003
01004 if(packetbuf_datalen() > 0 && tc->cb->recv != NULL) {
01005 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
01006 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
01007 packetbuf_attr(PACKETBUF_ATTR_HOPS));
01008 }
01009 return;
01010 } else if(packetbuf_attr(PACKETBUF_ATTR_TTL) > 1 &&
01011 tc->rtmetric != RTMETRIC_MAX) {
01012
01013
01014
01015
01016
01017
01018
01019
01020 if(hdr.rtmetric <= tc->rtmetric) {
01021 ackflags |= ACK_FLAGS_RTMETRIC_NEEDS_UPDATE;
01022 }
01023
01024 packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
01025 packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
01026 packetbuf_set_attr(PACKETBUF_ATTR_TTL,
01027 packetbuf_attr(PACKETBUF_ATTR_TTL) - 1);
01028
01029
01030 PRINTF("%d.%d: packet received from %d.%d via %d.%d, sending %d, max_rexmits %d\n",
01031 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01032 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[0],
01033 packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[1],
01034 from->u8[0], from->u8[1], tc->sending,
01035 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
01036
01037
01038
01039
01040
01041
01042
01043
01044 if(packetqueue_len(&tc->send_queue) <= MAX_SENDING_QUEUE - MIN_AVAILABLE_QUEUE_ENTRIES &&
01045 packetqueue_enqueue_packetbuf(&tc->send_queue,
01046 FORWARD_PACKET_LIFETIME_BASE *
01047 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
01048 tc)) {
01049 add_packet_to_recent_packets(tc);
01050 send_ack(tc, &ack_to, ackflags);
01051 send_queued_packet(tc);
01052 } else {
01053 send_ack(tc, &ack_to,
01054 ackflags | ACK_FLAGS_DROPPED | ACK_FLAGS_CONGESTED);
01055 PRINTF("%d.%d: packet dropped: no queue buffer available\n",
01056 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01057 stats.qdrop++;
01058 }
01059 } else if(packetbuf_attr(PACKETBUF_ATTR_TTL) <= 1) {
01060 PRINTF("%d.%d: packet dropped: ttl %d\n",
01061 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01062 packetbuf_attr(PACKETBUF_ATTR_TTL));
01063 send_ack(tc, &ack_to, ackflags |
01064 ACK_FLAGS_DROPPED | ACK_FLAGS_LIFETIME_EXCEEDED);
01065 stats.ttldrop++;
01066 }
01067 } else if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
01068 PACKETBUF_ATTR_PACKET_TYPE_ACK) {
01069 PRINTF("Collect: incoming ack %d from %d.%d (%d.%d) seqno %d (%d)\n",
01070 packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE),
01071 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],
01072 packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1],
01073 tc->current_parent.u8[0],
01074 tc->current_parent.u8[1],
01075 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID),
01076 tc->seqno);
01077 handle_ack(tc);
01078 stats.ackrecv++;
01079 }
01080 return;
01081 }
01082
01083 static void
01084 timedout(struct collect_conn *tc)
01085 {
01086 struct collect_neighbor *n;
01087 PRINTF("%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
01088 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], tc->transmissions,
01089 tc->current_parent.u8[0], tc->current_parent.u8[1],
01090 tc->max_rexmits);
01091 printf("%d.%d: timedout after %d retransmissions to %d.%d (max retransmissions %d): packet dropped\n",
01092 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], tc->transmissions,
01093 tc->current_parent.u8[0], tc->current_parent.u8[1],
01094 tc->max_rexmits);
01095
01096 tc->sending = 0;
01097 n = collect_neighbor_list_find(&tc->neighbor_list,
01098 &tc->current_parent);
01099 if(n != NULL) {
01100 collect_neighbor_tx_fail(n, tc->max_rexmits);
01101 }
01102 update_rtmetric(tc);
01103 send_next_packet(tc);
01104 set_keepalive_timer(tc);
01105 }
01106
01107 static void
01108 node_packet_sent(struct unicast_conn *c, int status, int transmissions)
01109 {
01110 struct collect_conn *tc = (struct collect_conn *)
01111 ((char *)c - offsetof(struct collect_conn, unicast_conn));
01112
01113
01114 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
01115 PACKETBUF_ATTR_PACKET_TYPE_DATA) {
01116
01117 tc->transmissions += transmissions;
01118 PRINTF("tx %d\n", tc->transmissions);
01119 PRINTF("%d.%d: MAC sent %d transmissions to %d.%d, status %d, total transmissions %d\n",
01120 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01121 transmissions,
01122 tc->current_parent.u8[0], tc->current_parent.u8[1],
01123 status, tc->transmissions);
01124 if(tc->transmissions >= tc->max_rexmits) {
01125 timedout(tc);
01126 stats.timedout++;
01127 } else {
01128 clock_time_t time = REXMIT_TIME / 2 + (random_rand() % (REXMIT_TIME / 2));
01129 PRINTF("retransmission time %lu\n", time);
01130 ctimer_set(&tc->retransmission_timer, time,
01131 retransmit_callback, tc);
01132 }
01133 }
01134 }
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 static void
01145 retransmit_not_sent_callback(void *ptr)
01146 {
01147 struct collect_conn *c = ptr;
01148
01149 PRINTF("retransmit not sent, %d transmissions\n", c->transmissions);
01150 c->transmissions += MAX_MAC_REXMITS + 1;
01151 retransmit_callback(c);
01152 }
01153
01154
01155
01156
01157
01158
01159
01160
01161 static void
01162 retransmit_callback(void *ptr)
01163 {
01164 struct collect_conn *c = ptr;
01165
01166 PRINTF("retransmit, %d transmissions\n", c->transmissions);
01167 if(c->transmissions >= c->max_rexmits) {
01168 timedout(c);
01169 stats.timedout++;
01170 } else {
01171 c->sending = 0;
01172 retransmit_current_packet(c);
01173 }
01174 }
01175
01176 #if !COLLECT_ANNOUNCEMENTS
01177 static void
01178 adv_received(struct neighbor_discovery_conn *c, const rimeaddr_t *from,
01179 uint16_t rtmetric)
01180 {
01181 struct collect_conn *tc = (struct collect_conn *)
01182 ((char *)c - offsetof(struct collect_conn, neighbor_discovery_conn));
01183 struct collect_neighbor *n;
01184
01185 n = collect_neighbor_list_find(&tc->neighbor_list, from);
01186
01187 if(n == NULL) {
01188 collect_neighbor_list_add(&tc->neighbor_list, from, rtmetric);
01189 if(rtmetric == RTMETRIC_MAX) {
01190 bump_advertisement(tc);
01191 }
01192 } else {
01193
01194
01195
01196
01197
01198
01199
01200
01201 if(rtmetric == RTMETRIC_MAX &&
01202 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
01203 bump_advertisement(tc);
01204 }
01205 collect_neighbor_update_rtmetric(n, rtmetric);
01206 PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n",
01207 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01208 n->addr.u8[0], n->addr.u8[1], rtmetric);
01209 }
01210
01211 update_rtmetric(tc);
01212 }
01213 #else
01214 static void
01215 received_announcement(struct announcement *a, const rimeaddr_t *from,
01216 uint16_t id, uint16_t value)
01217 {
01218 struct collect_conn *tc = (struct collect_conn *)
01219 ((char *)a - offsetof(struct collect_conn, announcement));
01220 struct collect_neighbor *n;
01221
01222 n = collect_neighbor_list_find(&tc->neighbor_list, from);
01223
01224 if(n == NULL) {
01225
01226
01227 if(value < tc->rtmetric) {
01228 collect_neighbor_list_add(&tc->neighbor_list, from, value);
01229 PRINTF("%d.%d: new neighbor %d.%d, rtmetric %d\n",
01230 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01231 from->u8[0], from->u8[1], value);
01232 }
01233 if(value == RTMETRIC_MAX && tc->rtmetric != RTMETRIC_MAX) {
01234 bump_advertisement(tc);
01235 }
01236 } else {
01237
01238
01239
01240
01241
01242
01243
01244
01245 if(value == RTMETRIC_MAX &&
01246 collect_neighbor_rtmetric(n) != RTMETRIC_MAX) {
01247 bump_advertisement(tc);
01248 }
01249 collect_neighbor_update_rtmetric(n, value);
01250 PRINTF("%d.%d: updating neighbor %d.%d, etx %d\n",
01251 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01252 n->addr.u8[0], n->addr.u8[1], value);
01253 }
01254
01255 update_rtmetric(tc);
01256
01257 #if ! COLLECT_CONF_WITH_LISTEN
01258 if(value == RTMETRIC_MAX &&
01259 tc->rtmetric != RTMETRIC_MAX) {
01260 announcement_bump(&tc->announcement);
01261 }
01262 #endif
01263 }
01264 #endif
01265
01266 static const struct unicast_callbacks unicast_callbacks = {node_packet_received,
01267 node_packet_sent};
01268 #if !COLLECT_ANNOUNCEMENTS
01269 static const struct neighbor_discovery_callbacks neighbor_discovery_callbacks =
01270 { adv_received, NULL};
01271 #endif
01272
01273 void
01274 collect_open(struct collect_conn *tc, uint16_t channels,
01275 uint8_t is_router,
01276 const struct collect_callbacks *cb)
01277 {
01278 unicast_open(&tc->unicast_conn, channels + 1, &unicast_callbacks);
01279 channel_set_attributes(channels + 1, attributes);
01280 tc->rtmetric = RTMETRIC_MAX;
01281 tc->cb = cb;
01282 tc->is_router = is_router;
01283 tc->seqno = 10;
01284 tc->eseqno = 0;
01285 LIST_STRUCT_INIT(tc, send_queue_list);
01286 collect_neighbor_list_new(&tc->neighbor_list);
01287 tc->send_queue.list = &(tc->send_queue_list);
01288 tc->send_queue.memb = &send_queue_memb;
01289 collect_neighbor_init();
01290
01291 #if !COLLECT_ANNOUNCEMENTS
01292 neighbor_discovery_open(&tc->neighbor_discovery_conn, channels,
01293 CLOCK_SECOND * 4,
01294 CLOCK_SECOND * 60,
01295 #ifdef COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
01296 COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME,
01297 #else
01298 CLOCK_SECOND * 600UL,
01299 #endif
01300 &neighbor_discovery_callbacks);
01301 neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
01302 #else
01303 announcement_register(&tc->announcement, channels,
01304 received_announcement);
01305 #if ! COLLECT_CONF_WITH_LISTEN
01306 announcement_set_value(&tc->announcement, RTMETRIC_MAX);
01307 #endif
01308 #endif
01309
01310 ctimer_set(&tc->proactive_probing_timer, PROACTIVE_PROBING_INTERVAL,
01311 proactive_probing_callback, tc);
01312
01313 }
01314
01315 static void
01316 send_keepalive(void *ptr)
01317 {
01318 struct collect_conn *c = ptr;
01319
01320 set_keepalive_timer(c);
01321
01322
01323 if(c->sending == 0 && packetqueue_len(&c->send_queue) == 0) {
01324 if(enqueue_dummy_packet(c, KEEPALIVE_REXMITS)) {
01325 PRINTF("%d.%d: sending keepalive\n",
01326 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01327 send_queued_packet(c);
01328 }
01329 }
01330 }
01331
01332 static void
01333 set_keepalive_timer(struct collect_conn *c)
01334 {
01335 if(c->keepalive_period != 0) {
01336 ctimer_set(&c->keepalive_timer, (c->keepalive_period / 2) +
01337 (random_rand() % (c->keepalive_period / 2)),
01338 send_keepalive, c);
01339 } else {
01340 ctimer_stop(&c->keepalive_timer);
01341 }
01342 }
01343
01344 void
01345 collect_set_keepalive(struct collect_conn *c, clock_time_t period)
01346 {
01347 c->keepalive_period = period;
01348 set_keepalive_timer(c);
01349 }
01350
01351 void
01352 collect_close(struct collect_conn *tc)
01353 {
01354 #if COLLECT_ANNOUNCEMENTS
01355 announcement_remove(&tc->announcement);
01356 #else
01357 neighbor_discovery_close(&tc->neighbor_discovery_conn);
01358 #endif
01359 unicast_close(&tc->unicast_conn);
01360 while(packetqueue_first(&tc->send_queue) != NULL) {
01361 packetqueue_dequeue(&tc->send_queue);
01362 }
01363 }
01364
01365 void
01366 collect_set_sink(struct collect_conn *tc, int should_be_sink)
01367 {
01368 if(should_be_sink) {
01369 tc->is_router = 1;
01370 tc->rtmetric = RTMETRIC_SINK;
01371 PRINTF("collect_set_sink: tc->rtmetric %d\n", tc->rtmetric);
01372 bump_advertisement(tc);
01373
01374
01375 while(packetqueue_len(&tc->send_queue) > 0) {
01376 packetqueue_dequeue(&tc->send_queue);
01377 }
01378
01379
01380 ctimer_stop(&tc->retransmission_timer);
01381 } else {
01382 tc->rtmetric = RTMETRIC_MAX;
01383 }
01384 #if COLLECT_ANNOUNCEMENTS
01385 announcement_set_value(&tc->announcement, tc->rtmetric);
01386 #endif
01387 update_rtmetric(tc);
01388
01389 bump_advertisement(tc);
01390
01391 if(DRAW_TREE) {
01392 printf("#A rt=0,p=0\n");
01393 }
01394 }
01395
01396 int
01397 collect_send(struct collect_conn *tc, int rexmits)
01398 {
01399 struct collect_neighbor *n;
01400 int ret;
01401
01402 packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->eseqno);
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 tc->eseqno = (tc->eseqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
01413
01414 if(tc->eseqno == 0) {
01415 tc->eseqno = ((int)(1 << COLLECT_PACKET_ID_BITS)) / 2;
01416 }
01417 packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr);
01418 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
01419 packetbuf_set_attr(PACKETBUF_ATTR_TTL, MAX_HOPLIM);
01420 if(rexmits > MAX_REXMITS) {
01421 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, MAX_REXMITS);
01422 } else {
01423 packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);
01424 }
01425
01426 PRINTF("%d.%d: originating packet %d, max_rexmits %d\n",
01427 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01428 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
01429 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT));
01430
01431 if(tc->rtmetric == RTMETRIC_SINK) {
01432 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
01433 if(tc->cb->recv != NULL) {
01434 tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
01435 packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
01436 packetbuf_attr(PACKETBUF_ATTR_HOPS));
01437 }
01438 return 1;
01439 } else {
01440
01441
01442 packetbuf_hdralloc(sizeof(struct data_msg_hdr));
01443
01444 if(packetqueue_enqueue_packetbuf(&tc->send_queue,
01445 FORWARD_PACKET_LIFETIME_BASE *
01446 packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
01447 tc)) {
01448 send_queued_packet(tc);
01449 ret = 1;
01450 } else {
01451 PRINTF("%d.%d: drop originated packet: no queuebuf\n",
01452 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01453 printf("%d.%d: drop originated packet: no queuebuf\n",
01454 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01455 }
01456
01457
01458 n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
01459 if(n != NULL) {
01460 PRINTF("%d.%d: sending to %d.%d\n",
01461 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
01462 n->addr.u8[0], n->addr.u8[1]);
01463 } else {
01464 PRINTF("%d.%d: did not find any neighbor to send to\n",
01465 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01466 #if COLLECT_ANNOUNCEMENTS
01467 #if COLLECT_CONF_WITH_LISTEN
01468 PRINTF("listen\n");
01469 announcement_listen(1);
01470 ctimer_set(&tc->transmit_after_scan_timer, ANNOUNCEMENT_SCAN_TIME,
01471 send_queued_packet, tc);
01472 #else
01473 announcement_set_value(&tc->announcement, RTMETRIC_MAX);
01474 announcement_bump(&tc->announcement);
01475 #endif
01476 #endif
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489 }
01490 }
01491 return ret;
01492 }
01493
01494 int
01495 collect_depth(struct collect_conn *tc)
01496 {
01497 return tc->rtmetric;
01498 }
01499
01500 const rimeaddr_t *
01501 collect_parent(struct collect_conn *tc)
01502 {
01503 return &tc->current_parent;
01504 }
01505
01506 void
01507 collect_purge(struct collect_conn *tc)
01508 {
01509 collect_neighbor_list_purge(&tc->neighbor_list);
01510 rimeaddr_copy(&tc->parent, &rimeaddr_null);
01511 update_rtmetric(tc);
01512 if(DRAW_TREE) {
01513 printf("#L %d 0\n", tc->parent.u8[0]);
01514 }
01515 rimeaddr_copy(&tc->parent, &rimeaddr_null);
01516 }
01517
01518 void
01519 collect_print_stats(void)
01520 {
01521 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",
01522 stats.foundroute, stats.newparent, stats.routelost,
01523 stats.acksent, stats.datasent, stats.datarecv,
01524 stats.ackrecv, stats.badack, stats.duprecv,
01525 stats.qdrop, stats.rtdrop, stats.ttldrop, stats.ackdrop,
01526 stats.timedout);
01527 }
01528
01529