コード例 #1
0
ファイル: collect.c プロジェクト: kincki/contiki
/*---------------------------------------------------------------------------*/
int
collect_send(struct collect_conn *tc, int rexmits)
{
    struct neighbor *n;

    packetbuf_set_attr(PACKETBUF_ATTR_EPACKET_ID, tc->seqno++);
    packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &rimeaddr_node_addr);
    packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1);
    packetbuf_set_attr(PACKETBUF_ATTR_TTL, MAX_HOPLIM);
    packetbuf_set_attr(PACKETBUF_ATTR_MAX_REXMIT, rexmits);

    if(tc->rtmetric == SINK) {
        packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 0);
        if(tc->cb->recv != NULL) {
            tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
                         packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
                         packetbuf_attr(PACKETBUF_ATTR_HOPS));
        }
        return 1;
    } else {
        n = neighbor_best();
        if(n != NULL) {
#if CONTIKI_TARGET_NETSIM
            ether_set_line(n->addr.u8[0], n->addr.u8[1]);
#endif /* CONTIKI_TARGET_NETSIM */
            PRINTF("%d.%d: sending to %d.%d\n",
                   rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
                   n->addr.u8[RIMEADDR_SIZE-2], n->addr.u8[RIMEADDR_SIZE-1]);
            if(packetqueue_enqueue_packetbuf(&forwarding_queue, FORWARD_PACKET_LIFETIME,
                                             tc)) {
                send_queued_packet();
                return 1;
            } else {
                PRINTF("%d.%d: drop originated packet: no queuebuf\n",
                       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1]);
            }
        } else {
            /*      printf("Didn't find any neighbor\n");*/
            PRINTF("%d.%d: did not find any neighbor to send to\n",
                   rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1]);
            announcement_listen(1);
            if(packetqueue_enqueue_packetbuf(&forwarding_queue, FORWARD_PACKET_LIFETIME,
                                             tc)) {
                return 1;
            } else {
                PRINTF("%d.%d: drop originated packet: no queuebuf\n",
                       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1]);
            }
        }
    }
    return 0;
}
コード例 #2
0
ファイル: collect.c プロジェクト: kincki/contiki
/*---------------------------------------------------------------------------*/
static void
node_packet_timedout(struct runicast_conn *c, const rimeaddr_t *to,
                     uint8_t transmissions)
{
    struct collect_conn *tc = (struct collect_conn *)
                              ((char *)c - offsetof(struct collect_conn, runicast_conn));

    PRINTF("%d.%d: timedout after %d retransmissions: packet dropped\n",
           rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1], transmissions);

    tc->forwarding = 0;
    neighbor_timedout_etx(neighbor_find(to), transmissions);
    update_rtmetric(tc);

    /* Remove the first packet on the queue, the packet that just timed out. */
    packetqueue_dequeue(&forwarding_queue);

    /* Send the next packet in the queue, if any. */
    send_queued_packet();
}
コード例 #3
0
ファイル: collect.c プロジェクト: arbraham/hummingbird
/*---------------------------------------------------------------------------*/
static void
node_packet_sent(struct runicast_conn *c, const rimeaddr_t *to,
		 uint8_t transmissions)
{
  struct collect_conn *tc = (struct collect_conn *)
    ((char *)c - offsetof(struct collect_conn, runicast_conn));

  PRINTF("%d.%d: sent to %d.%d after %d retransmissions\n",
	 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	 to->u8[0], to->u8[1],
	 transmissions);

  
  tc->forwarding = 0;
  neighbor_update_etx(neighbor_find(to), transmissions);
  update_rtmetric(tc);

  /* Remove the first packet on the queue, the packet that was just sent. */
  packetqueue_dequeue(&forwarding_queue);

  /* Send the next packet in the queue, if any. */
  send_queued_packet();
}
コード例 #4
0
ファイル: collect.c プロジェクト: kincki/contiki
/*---------------------------------------------------------------------------*/
static void
node_packet_received(struct runicast_conn *c, const rimeaddr_t *from,
                     uint8_t seqno)
{
    struct collect_conn *tc = (struct collect_conn *)
                              ((char *)c - offsetof(struct collect_conn, runicast_conn));
    int i;

    /* To protect against forwarding duplicate packets, we keep a list
       of recently forwarded packet seqnos. If the seqno of the current
       packet exists in the list, we drop the packet. */

    for(i = 0; i < NUM_RECENT_PACKETS; i++) {
        if(recent_packets[i].seqno == packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID) &&
                rimeaddr_cmp(&recent_packets[i].originator,
                             packetbuf_addr(PACKETBUF_ADDR_ESENDER))) {
            PRINTF("%d.%d: dropping duplicate packet from %d.%d with seqno %d\n",
                   rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
                   recent_packets[i].originator.u8[RIMEADDR_SIZE-2], recent_packets[i].originator.u8[RIMEADDR_SIZE-1],
                   packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID));
            /* Drop the packet. */
            return;
        }
    }
    recent_packets[recent_packet_ptr].seqno = packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID);
    rimeaddr_copy(&recent_packets[recent_packet_ptr].originator,
                  packetbuf_addr(PACKETBUF_ADDR_ESENDER));
    recent_packet_ptr = (recent_packet_ptr + 1) % NUM_RECENT_PACKETS;

    if(tc->rtmetric == SINK) {

        /* If we are the sink, we call the receive function. */

        PRINTF("%d.%d: sink received packet from %d.%d via %d.%d\n",
               rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
               packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[RIMEADDR_SIZE-2],
               packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[RIMEADDR_SIZE-1],
               from->u8[RIMEADDR_SIZE-2], from->u8[RIMEADDR_SIZE-1]);

        if(tc->cb->recv != NULL) {
            tc->cb->recv(packetbuf_addr(PACKETBUF_ADDR_ESENDER),
                         packetbuf_attr(PACKETBUF_ATTR_EPACKET_ID),
                         packetbuf_attr(PACKETBUF_ATTR_HOPS));
        }
        return;
    } else if(packetbuf_attr(PACKETBUF_ATTR_TTL) > 1 &&
              tc->rtmetric != RTMETRIC_MAX) {

        /* If we are not the sink, we forward the packet to the best
           neighbor. */
        packetbuf_set_attr(PACKETBUF_ATTR_HOPS, packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
        packetbuf_set_attr(PACKETBUF_ATTR_TTL, packetbuf_attr(PACKETBUF_ATTR_TTL) - 1);


        PRINTF("%d.%d: packet received from %d.%d via %d.%d, forwarding %d\n",
               rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
               packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[RIMEADDR_SIZE-2],
               packetbuf_addr(PACKETBUF_ADDR_ESENDER)->u8[RIMEADDR_SIZE-1],
               from->u8[RIMEADDR_SIZE-2], from->u8[RIMEADDR_SIZE-1], tc->forwarding);

        if(packetqueue_enqueue_packetbuf(&forwarding_queue, FORWARD_PACKET_LIFETIME,
                                         tc)) {
            send_queued_packet();
        } else {
            PRINTF("%d.%d: packet dropped: no queue buffer available\n",
                   rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1]);
        }
    }

    return;
}
コード例 #5
0
ファイル: collect.c プロジェクト: kincki/contiki
/*---------------------------------------------------------------------------*/
static void
update_rtmetric(struct collect_conn *tc)
{
    struct neighbor *n;

    /* We should only update the rtmetric if we are not the sink. */
    if(tc->rtmetric != SINK) {

        /* Find the neighbor with the lowest rtmetric. */
        n = neighbor_best();

        /* If n is NULL, we have no best neighbor. */
        if(n == NULL) {

            /* If we have don't have any neighbors, we set our rtmetric to
            the maximum value to indicate that we do not have a route. */

            if(tc->rtmetric != RTMETRIC_MAX) {
                PRINTF("%d.%d: didn't find a best neighbor, setting rtmetric to max\n",
                       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1]);
            }
            tc->rtmetric = RTMETRIC_MAX;
            announcement_set_value(&tc->announcement, tc->rtmetric);
        } else {

            /* We set our rtmetric to the rtmetric of our best neighbor plus
            the expected transmissions to reach that neighbor. */
            if(n->rtmetric + neighbor_etx(n) != tc->rtmetric) {
                uint16_t old_rtmetric = tc->rtmetric;

                tc->rtmetric = n->rtmetric + neighbor_etx(n);

#if !COLLECT_ANNOUNCEMENTS
                neighbor_discovery_start(&tc->neighbor_discovery_conn, tc->rtmetric);
#else
                announcement_set_value(&tc->announcement, tc->rtmetric);
#endif /* !COLLECT_ANNOUNCEMENTS */

                PRINTF("%d.%d: new rtmetric %d\n",
                       rimeaddr_node_addr.u8[RIMEADDR_SIZE-2], rimeaddr_node_addr.u8[RIMEADDR_SIZE-1],
                       tc->rtmetric);

                /* We got a new, working, route we send any queued packets we may have. */
                if(old_rtmetric == RTMETRIC_MAX) {
                    send_queued_packet();
                }
            }
        }
    }

    /*  DEBUG_PRINTF("%d: new rtmetric %d\n", node_id, rtmetric);*/
#if CONTIKI_TARGET_NETSIM
    {
        char buf[8];
        if(tc->rtmetric == RTMETRIC_MAX) {
            strcpy(buf, " ");
        } else {
            sprintf(buf, "%.1f", (float)tc->rtmetric / NEIGHBOR_ETX_SCALE);
        }
        ether_set_text(buf);
    }
#endif
}