collect.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rimecollect
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006, Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the Institute nor the names of its contributors
00019  *    may be used to endorse or promote products derived from this software
00020  *    without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * This file is part of the Contiki operating system.
00035  *
00036  * $Id: collect.c,v 1.73 2011/01/18 16:05:53 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Tree-based hop-by-hop reliable data collection
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
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 /* The recent_packets list holds the sequence number, the originator,
00071    and the connection for packets that have been recently
00072    forwarded. This list is maintained to avoid forwarding duplicate
00073    packets. */
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 /* This is the header of data packets. The header comtains the routing
00087    metric of the last hop sender. This is used to avoid routing loops:
00088    if a node receives a packet with a lower routing metric than its
00089    own, it drops the packet. */
00090 struct data_msg_hdr {
00091   uint8_t flags, dummy;
00092   uint16_t rtmetric;
00093 };
00094 
00095 
00096 /* This is the header of ACK packets. It contains a flags field that
00097    indicates if the node is congested (ACK_FLAGS_CONGESTED), if the
00098    packet was dropped (ACK_FLAGS_DROPPED), if a packet was dropped due
00099    to its lifetime was exceeded (ACK_FLAGS_LIFETIME_EXCEEDED), and if
00100    an outdated rtmetric was detected
00101    (ACK_FLAGS_RTMETRIC_NEEDS_UPDATE). The flags can contain any
00102    combination of the flags. The ACK header also contains the routing
00103    metric of the node that sends tha ACK. This is used to keep an
00104    up-to-date routing state in the network. */
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 /* These are configuration knobs that normally should not be
00117    tweaked. MAX_MAC_REXMITS defines how many times the underlying CSMA
00118    MAC layer should attempt to resend a data packet before giving
00119    up. The MAX_ACK_MAC_REXMITS defines how many times the MAC layer
00120    should resend ACK packets. The REXMIT_TIME is the lowest
00121    retransmission timeout at the network layer. It is exponentially
00122    increased for every new network layer retransmission. The
00123    FORWARD_PACKET_LIFETIME is the maximum time a packet is held in the
00124    forwarding queue before it is removed. The MAX_SENDING_QUEUE
00125    specifies the maximum length of the output queue. If the queue is
00126    full, incoming packets are dropped instead of being forwarded. */
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 /* These specifiy the sink's routing metric (0) and the maximum
00139    routing metric. If a node has routing metric zero, it is the
00140    sink. If a node has the maximum routing metric, it has no route to
00141    a sink. */
00142 #define RTMETRIC_SINK              0
00143 #define RTMETRIC_MAX               COLLECT_MAX_DEPTH
00144 
00145 /* Here we define what we mean with a significantly improved
00146    rtmetric. This is used to determine when a new parent should be
00147    chosen over an old parent and when to begin more rapidly advertise
00148    a new rtmetric. */
00149 #define SIGNIFICANT_RTMETRIC_PARENT_CHANGE (COLLECT_LINK_ESTIMATE_UNIT +  \
00150                                             COLLECT_LINK_ESTIMATE_UNIT / 2)
00151 
00152 /* This defines the maximum hops that a packet can take before it is
00153    dropped. */
00154 #define MAX_HOPLIM                 15
00155 
00156 
00157 /* Proactive probing: when there are no packets in the send
00158    queue, the system periodically sends a dummy packet to potential
00159    parents, i.e., neighbors with a lower rtmetric than we have but for
00160    which we do not yet have a link quality estimate. */
00161 #define PROACTIVE_PROBING_INTERVAL (random_rand() % CLOCK_SECOND * 60)
00162 #define PROACTIVE_PROBING_REXMITS  15
00163 
00164 /* The ANNOUNCEMENT_SCAN_TIME defines for how long the Collect
00165    implementation should listen for announcements from other nodes
00166    when it requires a route. */
00167 #ifdef ANNOUNCEMENT_CONF_PERIOD
00168 #define ANNOUNCEMENT_SCAN_TIME ANNOUNCEMENT_CONF_PERIOD
00169 #else /* ANNOUNCEMENT_CONF_PERIOD */
00170 #define ANNOUNCEMENT_SCAN_TIME CLOCK_SECOND
00171 #endif /* ANNOUNCEMENT_CONF_PERIOD */
00172 
00173 
00174 /* Statistics structure */
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 /* Debug definition: draw routing tree in Cooja. */
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 /* Forward declarations. */
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  * This function computes the current rtmetric by adding the last
00214  * known rtmetric from our parent with the link estimate to the
00215  * parent.
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   /* This function computes the current rtmetric for this node. It
00225      uses the rtmetric of the parent node in the tree and adds the
00226      current link estimate from us to the parent node. */
00227 
00228   /* The collect connection structure stores the address of its
00229      current parent. We look up the neighbor identification struct in
00230      the collect-neighbor list. */
00231   n = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
00232 
00233   /* If n is NULL, we have no best neighbor. Thus our rtmetric is
00234      then COLLECT_RTMETRIC_MAX. */
00235   if(n == NULL) {
00236     rtmetric = RTMETRIC_MAX;
00237   } else {
00238     /* Our rtmetric is the rtmetric of our parent neighbor plus
00239        the expected transmissions to reach that neighbor. */
00240     rtmetric = collect_neighbor_rtmetric_link_estimate(n);
00241   }
00242 
00243   return rtmetric;
00244 }
00245 /*---------------------------------------------------------------------------*/
00246 /**
00247  * This function is called when the route advertisements need to be
00248  * transmitted more rapidly.
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 /* !COLLECT_ANNOUNCEMENTS */
00259 }
00260 /*---------------------------------------------------------------------------*/
00261 /**
00262  * This function is called to update the current parent node. The
00263  * parent may change if new routing information has been found, for
00264  * example if a new node with a lower rtmetric and link estimate has
00265  * appeared.
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   /* We grab the collect_neighbor struct of our current parent. */
00275   current = collect_neighbor_list_find(&tc->neighbor_list, &tc->parent);
00276 
00277   /* We call the collect_neighbor module to find the current best
00278      parent. */
00279   best = collect_neighbor_list_best(&tc->neighbor_list);
00280 
00281   /* We check if we need to switch parent. Switching parent is done in
00282      the following situations:
00283 
00284      * We do not have a current parent.
00285      * The best parent is significantly better than the current parent.
00286 
00287      If we do not have a current parent, and have found a best parent,
00288      we simply use the new best parent.
00289 
00290      If we already have a current parent, but have found a new parent
00291      that is better, we employ a heuristic to avoid switching parents
00292      too often. The new parent must be significantly better than the
00293      current parent. Being "significantly better" is defined as having
00294      an rtmetric that is has a difference of at least 1.5 times the
00295      COLLECT_LINK_ESTIMATE_UNIT. This is derived from the experience
00296      by Gnawali et al (SenSys 2009). */
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       /* New parent. */
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         /* We switch parent. */
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         /* Since we now have a significantly better or worse rtmetric than
00329            we had before, we let our neighbors know this quickly. */
00330         bump_advertisement(tc);
00331 
00332         if(DRAW_TREE) {
00333           printf("#A e=%d\n", collect_neighbor_link_estimate(best));
00334           /*          {
00335             int i;
00336             int etx = 0;
00337             printf("#A l=");
00338             for(i = 0; i < 8; i++) {
00339               printf("%d ", best->le.history[(best->le.historyptr - 1 - i) & 7]);
00340               etx += current->le.history[i];
00341             }
00342             printf("\n");
00343             }*/
00344         }
00345       } else {
00346         if(DRAW_TREE) {
00347           printf("#A e=%d\n", collect_neighbor_link_estimate(current));
00348           /*          {
00349             int i;
00350             int etx = 0;
00351             printf("#A l=");
00352             for(i = 0; i < 8; i++) {
00353               printf("%d ", current->le.history[(current->le.historyptr - 1 - i) & 7]);
00354               etx += current->le.history[i];
00355             }
00356             printf("\n");
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     /* No parent. */
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  * This function is called whenever there is a chance that the routing
00383  * metric has changed. The function goes through the list of neighbors
00384  * to compute the new routing metric. If the metric has changed, it
00385  * notifies neighbors.
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   /* We should only update the rtmetric if we are not the sink. */
00395   if(tc->rtmetric != RTMETRIC_SINK) {
00396     uint16_t old_rtmetric, new_rtmetric;
00397 
00398     /* We remember the current (old) rtmetric for later. */
00399     old_rtmetric = tc->rtmetric;
00400 
00401     /* We may need to update our parent node so we do that now. */
00402     update_parent(tc);
00403 
00404     /* We compute the new rtmetric. */
00405     new_rtmetric = rtmetric_compute(tc);
00406 
00407     /* We sanity check our new rtmetric. */
00408     if(new_rtmetric == RTMETRIC_SINK) {
00409       /* Defensive programming: if the new rtmetric somehow got to be
00410          the rtmetric of the sink, there is a bug somewhere. To avoid
00411          destroying the network, we simply will not assume this new
00412          rtmetric. Instead, we set our rtmetric to maximum, to
00413          indicate that we have no sane route. */
00414       new_rtmetric = RTMETRIC_MAX;
00415     }
00416 
00417     /* We set our new rtmetric in the collect conn structure. Then we
00418        decide how we should announce this new rtmetric. */
00419     tc->rtmetric = new_rtmetric;
00420 
00421     if(tc->is_router) {
00422       /* If we are a router, we update our advertised rtmetric. */
00423 #if COLLECT_ANNOUNCEMENTS
00424       announcement_set_value(&tc->announcement, tc->rtmetric);
00425 #else /* COLLECT_ANNOUNCEMENTS */
00426       neighbor_discovery_set_val(&tc->neighbor_discovery_conn, tc->rtmetric);
00427 #endif /* COLLECT_ANNOUNCEMENTS */
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     /* We got a new, working, route we send any queued packets we may have. */
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   /* Allocate space for the header. */
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   /* Defensive programming: if a bug in the MAC/RDC layers will cause
00485      it to not call us back, we'll set up the retransmission timer
00486      with a high timeout, so that we can cancel the transmission and
00487      send a new one. */
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   /* Only do proactive link probing if we are not the sink and if we
00506      have a route. */
00507   if(c->rtmetric != RTMETRIC_SINK && c->rtmetric != RTMETRIC_MAX) {
00508   /* Grab the first packet on the send queue to see if the queue is
00509      empty or not. */
00510   i = packetqueue_first(&c->send_queue);
00511   if(i == NULL) {
00512     /* If there are no packets to send, we go through the list of
00513        neighbors to find a potential parent for which we do not have a
00514        link estimate and send a dummy packet to it. This allows us to
00515        quickly gauge the link quality of neighbors that we do not
00516        currently use as parents. */
00517       struct collect_neighbor *n;
00518 
00519       /* Find the neighbor with the lowest number of estimates. */
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(&current_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, &current_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  * This function is called when a queued packet should be sent
00547  * out. The function takes the first packet on the output queue, adds
00548  * the necessary packet attributes, and sends the packet to the
00549  * next-hop neighbor.
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   /* If we are currently sending a packet, we do not attempt to send
00562      another one. */
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   /* Grab the first packet on the send queue. */
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   /* We should send the first packet from the queue. */
00580   q = packetqueue_queuebuf(i);
00581   if(q != NULL) {
00582     /* Place the queued packet into the packetbuf. */
00583     queuebuf_to_packetbuf(q);
00584 
00585     /* Pick the neighbor to which to send the packet. We use the
00586        parent in the n->parent. */
00587     n = collect_neighbor_list_find(&c->neighbor_list, &c->parent);
00588 
00589     if(n != NULL) {
00590 
00591       /* If the connection had a neighbor, we construct the packet
00592          buffer attributes and set the appropriate flags in the
00593          Collect connection structure and send the packet. */
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       /* Mark that we are currently sending a packet. */
00601       c->sending = 1;
00602 
00603       /* Remember the parent that we sent this packet to. */
00604       rimeaddr_copy(&c->current_parent, &c->parent);
00605 
00606       /* This is the first time we transmit this packet, so set
00607          transmissions to zero. */
00608       c->transmissions = 0;
00609 
00610       /* Remember that maximum amount of retransmissions we should
00611          make. This is stored inside a packet attribute in the packet
00612          on the send queue. */
00613       c->max_rexmits = packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT);
00614 
00615       /* Set the packet attributes: this packet wants an ACK, so we
00616          sent the PACKETBUF_ATTR_RELIABLE flag; the MAC should retry
00617          MAX_MAC_REXMITS times; and the PACKETBUF_ATTR_PACKET_ID is
00618          set to the current sequence number on the connection. */
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       /* Copy our rtmetric into the packet header of the outgoing
00629          packet. */
00630       memset(&hdr, 0, sizeof(hdr));
00631       hdr.rtmetric = c->rtmetric;
00632       memcpy(packetbuf_dataptr(), &hdr, sizeof(struct data_msg_hdr));
00633 
00634       /* Send the packet. */
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 /* COLLECT_CONF_WITH_LISTEN */
00645       announcement_set_value(&c->announcement, RTMETRIC_MAX);
00646       announcement_bump(&c->announcement);
00647 #endif /* COLLECT_CONF_WITH_LISTEN */
00648 #endif /* COLLECT_ANNOUNCEMENTS */
00649     }
00650   }
00651 }
00652 /*---------------------------------------------------------------------------*/
00653 /**
00654  * This function is called to retransmit the first packet on the send
00655  * queue.
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   /* Grab the first packet on the send queue, which is the one we are
00668      about to retransmit. */
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     /* No packet on the queue, so there is nothing for us to send. */
00674     return;
00675   }
00676 
00677   /* Get hold of the queuebuf. */
00678   q = packetqueue_queuebuf(i);
00679   if(q != NULL) {
00680 
00681     update_rtmetric(c);
00682     
00683     /* Place the queued packet into the packetbuf. */
00684     queuebuf_to_packetbuf(q);
00685 
00686     /* Pick the neighbor to which to send the packet. If we have found
00687        a better parent while we were transmitting this packet, we
00688        chose that neighbor instead. If so, we need to attribute the
00689        transmissions we made for the parent to that neighbor. */
00690     if(!rimeaddr_cmp(&c->current_parent, &c->parent)) {
00691       /*      struct collect_neighbor *current_neighbor;
00692       current_neighbor = collect_neighbor_list_find(&c->neighbor_list,
00693                                                     &c->current_parent);
00694       if(current_neighbor != NULL) {
00695         collect_neighbor_tx(current_neighbor, c->max_rexmits);
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       /* If the connection had a neighbor, we construct the packet
00711          buffer attributes and set the appropriate flags in the
00712          Collect connection structure and send the packet. */
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       /* Mark that we are currently sending a packet. */
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       /* Copy our rtmetric into the packet header of the outgoing
00728          packet. */
00729       memset(&hdr, 0, sizeof(hdr));
00730       hdr.rtmetric = c->rtmetric;
00731       memcpy(packetbuf_dataptr(), &hdr, sizeof(struct data_msg_hdr));
00732 
00733       /* Send the packet. */
00734       send_packet(c, n);
00735     }
00736   }
00737 
00738 }
00739 /*---------------------------------------------------------------------------*/
00740 static void
00741 send_next_packet(struct collect_conn *tc)
00742 {
00743   /* Remove the first packet on the queue, the packet that was just sent. */
00744   packetqueue_dequeue(&tc->send_queue);
00745   tc->seqno = (tc->seqno + 1) % (1 << COLLECT_PACKET_ID_BITS);
00746 
00747   /* Cancel retransmission timer. */
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   /* Send the next packet in the queue, if any. */
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     /*    printf("rtt %d / %d = %d.%02d\n",
00776            (int)(clock_time() - tc->send_time),
00777            (int)CLOCK_SECOND,
00778            (int)((clock_time() - tc->send_time) / CLOCK_SECOND),
00779            (int)(((100 * (clock_time() - tc->send_time)) / CLOCK_SECOND) % 100));*/
00780     
00781     stats.ackrecv++;
00782     msg = packetbuf_dataptr();
00783     memcpy(&rtmetric, &msg->rtmetric, sizeof(uint16_t));
00784 
00785     /* It is possible that we receive an ACK for a packet that we
00786        think we have not yet sent: if our transmission was received by
00787        the other node, but the link-layer ACK was lost, our
00788        transmission counter may still be zero. If this is the case, we
00789        play it safe by believing that we have sent MAX_MAC_REXMITS
00790        transmissions. */
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     /* The ack contains information about the state of the packet and
00813        of the node that received it. We do different things depending
00814        on whether or not the packet was dropped. First, we check if
00815        the receiving node was congested. If so, we add a maximum
00816        transmission number to its routing metric, which increases the
00817        chance that another parent will be chosen. */
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       /* If the packet was successfully received, we send the next packet. */
00826       send_next_packet(tc);
00827     } else {
00828       /* If the packet was lost due to its lifetime being exceeded,
00829          there is not much more we can do with the packet, so we send
00830          the next one instead. */
00831       if((msg->flags & ACK_FLAGS_LIFETIME_EXCEEDED)) {
00832         send_next_packet(tc);
00833       } else {
00834         /* If the packet was dropped, but without the node being
00835            congested or the packets lifetime being exceeded, we
00836            penalize the parent and try sending the packet again. */
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     /* Our neighbor's rtmetric needs to be updated, so we bump our
00848        advertisements. */
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   /* Remember that we have seen this packet for later, but only if
00892      it has a length that is larger than zero. Packets with size
00893      zero are keepalive or proactive link estimate probes, so we do
00894      not record them in our history. */
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   /* First update the neighbors rtmetric with the information in the
00918      packet header. */
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   /* To protect against sending duplicate packets, we keep a list of
00929      recently forwarded packet seqnos. If the seqno of the current
00930      packet exists in the list, we immediately send an ACK and drop
00931      the packet. */
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     /* Remember to whom we should send the ACK, since we reuse the
00940        packet buffer and its attributes when sending the ACK. */
00941     rimeaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
00942     packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
00943 
00944     /* If the queue is more than half filled, we add the CONGESTED
00945        flag to our outgoing acks. */
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         /* This is a duplicate of a packet we recently received, so we
00959            just send an ACK. */
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     /* If we are the sink, the packet has reached its final
00973        destination and we call the receive function. */
00974     if(tc->rtmetric == RTMETRIC_SINK) {
00975       struct queuebuf *q;
00976 
00977       add_packet_to_recent_packets(tc);
00978 
00979       /* We first send the ACK. We copy the data packet to a queuebuf
00980          first. */
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       /* Call receive function. */
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       /* If we are not the sink, we forward the packet to our best
01013          neighbor. First, we make sure that the packet comes from a
01014          neighbor that has a higher rtmetric than we have. If not, we
01015          have a loop and we inform the sender that its rtmetric needs
01016          to be updated. Second, we set our rtmetric in the outgoing
01017          packet to let the next hop know what our rtmetric is. Third,
01018          we update the hop count and ttl. */
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       /* We try to enqueue the packet on the outgoing packet queue. If
01038          we are able to enqueue the packet, we send a positive ACK. If
01039          we are unable to enqueue the packet, we send a negative ACK
01040          to inform the sender that the packet was dropped due to
01041          memory problems. We first check the size of our sending queue
01042          to ensure that we always have entries for packets that
01043          are originated by this node. */
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   /* For data packets, we record the number of transmissions */
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  * This function is called from a ctimer that is setup when a packet
01138  * is first transmitted. If the MAC layer signals that the packet is
01139  * sent, the ctimer will be stopped before this function is called. If
01140  * this function ends up being called, we add the maximum number of
01141  * MAC layer transmissions to the transmission count, and call the
01142  * retransmit function.
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  * This function is called from a ctimer that is setup when a packet
01156  * is sent. The purpose of this function is to either retransmit the
01157  * current packet, or timeout the packet. The descision is made
01158  * depending on how many times the packet has been transmitted. The
01159  * ctimer is set up in the function node_packet_sent().
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     /* Check if the advertised rtmetric has changed to
01194        RTMETRIC_MAX. This may indicate that the neighbor has lost its
01195        routes or that it has rebooted. In either case, we bump our
01196        advertisement rate to allow our neighbor to receive a new
01197        rtmetric from us. If our neighbor already happens to have an
01198        rtmetric of RTMETRIC_MAX recorded, it may mean that our
01199        neighbor does not hear our advertisements. If this is the case,
01200        we should not bump our advertisement rate. */
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     /* Only add neighbors that have an rtmetric that is lower than
01226        ours. */
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     /* Check if the advertised rtmetric has changed to
01238        RTMETRIC_MAX. This may indicate that the neighbor has lost its
01239        routes or that it has rebooted. In either case, we bump our
01240        advertisement rate to allow our neighbor to receive a new
01241        rtmetric from us. If our neighbor already happens to have an
01242        rtmetric of RTMETRIC_MAX recorded, it may mean that our
01243        neighbor does not hear our advertisements. If this is the case,
01244        we should not bump our advertisement rate. */
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 /* COLLECT_CONF_WITH_LISTEN */
01263 }
01264 #endif /* !COLLECT_ANNOUNCEMENTS */
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 /* !COLLECT_ANNOUNCEMENTS */
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 /* !COLLECT_ANNOUNCEMENTS */
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 /* COLLECT_CONF_WITH_LISTEN */
01308 #endif /* !COLLECT_ANNOUNCEMENTS */
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   /* Send keepalive message only if there are no pending transmissions. */
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 /* COLLECT_ANNOUNCEMENTS */
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     /* Purge the outgoing packet queue. */
01375     while(packetqueue_len(&tc->send_queue) > 0) {
01376       packetqueue_dequeue(&tc->send_queue);
01377     }
01378 
01379     /* Stop the retransmission timer. */
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 /* COLLECT_ANNOUNCEMENTS */
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   /* Increase the sequence number for the packet we send out. We
01405      employ a trick that allows us to see that a node has been
01406      rebooted: if the sequence number wraps to 0, we set it to half of
01407      the sequence number space. This allows us to detect reboots,
01408      since if a sequence number is less than half of the sequence
01409      number space, the data comes from a node that was recently
01410      rebooted. */
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     /* Allocate space for the header. */
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 /* COLLECT_CONF_WITH_LISTEN */
01473       announcement_set_value(&tc->announcement, RTMETRIC_MAX);
01474       announcement_bump(&tc->announcement);
01475 #endif /* COLLECT_CONF_WITH_LISTEN */
01476 #endif /* COLLECT_ANNOUNCEMENTS */
01477 
01478       /*      if(packetqueue_enqueue_packetbuf(&tc->send_queue,
01479                                        FORWARD_PACKET_LIFETIME_BASE *
01480                                        packetbuf_attr(PACKETBUF_ATTR_MAX_REXMIT),
01481                                        tc)) {
01482         return 1;
01483       } else {
01484         PRINTF("%d.%d: drop originated packet: no queuebuf\n",
01485                rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
01486         printf("%d.%d: drop originated packet: no queuebuf\n",
01487                rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
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 /** @} */

Generated on Mon Apr 11 14:23:30 2011 for Contiki 2.5 by  doxygen 1.6.1