Example #1
0
/*---------------------------------------------------------------------------*/
struct neighbor *
neighbor_best(void)
{
  int found;
  /*  int lowest, best;*/
  struct neighbor *n, *best;
  uint16_t rtmetric;

  rtmetric = RTMETRIC_MAX;
  best = NULL;
  found = 0;

  /*  PRINTF("%d: ", node_id);*/
  
  /* Find the lowest rtmetric. */
  for(n = list_head(neighbors_list); n != NULL; n = n->next) {
    if(!rimeaddr_cmp(&n->addr, &rimeaddr_null) &&
       rtmetric > n->rtmetric + neighbor_etx(n)) {
      rtmetric = n->rtmetric + neighbor_etx(n);
      best = n;
    }
  }

  return best;
}
Example #2
0
/*---------------------------------------------------------------------------*/
struct neighbor *
neighbor_best(void)
{
  struct neighbor *n = NULL;
  struct neighbor *best = NULL;
  uint16_t rtmetric = RTMETRIC_MAX;

  /* Find lowest rtmetric + etx. */
  for(n = list_head(neighbors_list); n != NULL; n = n->next) {
	  PRINTF("%u.%u: neighbor_best: neighbor %u.%u with rtmetric %u and etx %u\n",
			  rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
			  n->addr.u8[0], n->addr.u8[1],
			  n->rtmetric,
			  neighbor_etx(n));
    if(  !rimeaddr_cmp(&n->addr, &rimeaddr_null)
      && rtmetric > n->rtmetric + neighbor_etx(n)) {
      rtmetric = n->rtmetric + neighbor_etx(n);
      best = n;
    }
  }

  if (last_best == NULL) {
	  // printf("%d: first parent %d (rtmetric %u)\n", rimeaddr_node_addr.u8[0], best->addr.u8[0], rtmetric);
	  last_best = best;
  } else {
	  if (! (rtmetric + 2 < last_best->rtmetric + neighbor_etx(last_best))) {
		  /* No improvement in rtmetric, so we keep the current best. */
		  best = last_best;
	  } else {
		  /* Improvement in rtmetric, so we switch to new best. */
		  // printf("%d: new parent %d (rtmetric %u), old parent %d (rtmetric %u)\n", rimeaddr_node_addr.u8[0], best->addr.u8[0], rtmetric, last_best->addr.u8[0], last_best->rtmetric + neighbor_etx(last_best));
		  last_best = best;
	  }
  }

  return best;
}
Example #3
0
/*---------------------------------------------------------------------------*/
void
neighbor_add(const rimeaddr_t *addr, uint8_t nrtmetric, uint8_t netx)
{
  uint16_t rtmetric;
  uint16_t etx;
  struct neighbor *n, *max;
  int i;

  PRINTF("neighbor_add: adding %d.%d\n", addr->u8[0], addr->u8[1]);
  
  /* Check if the neighbor is already on the list. */
  for(n = list_head(neighbors_list); n != NULL; n = n->next) {
    if(rimeaddr_cmp(&n->addr, &rimeaddr_null) ||
       rimeaddr_cmp(&n->addr, addr)) {
      PRINTF("neighbor_add: already on list %d.%d\n", addr->u8[0], addr->u8[1]);
      break;
    }
  }

  /* If the neighbor was not on the list, we try to allocate memory
     for it. */
  if(n == NULL) {
    PRINTF("neighbor_add: not on list, allocating %d.%d\n", addr->u8[0], addr->u8[1]);
    n = memb_alloc(&neighbors_mem);
    if(n != NULL) {
      list_add(neighbors_list, n);
    }
  }
  
  /* If we could not allocate memory, we try to recycle an old
     neighbor */
  if(n == NULL) {
    PRINTF("neighbor_add: not on list, not allocated, recycling %d.%d\n", addr->u8[0], addr->u8[1]);
   /* Find the first unused entry or the used entry with the highest
     rtmetric and highest etx. */
    rtmetric = 0;
    etx = 0;
    max = NULL;

    for(n = list_head(neighbors_list); n != NULL; n = n->next) {
      if(!rimeaddr_cmp(&n->addr, &rimeaddr_null)) {
	if(n->rtmetric > rtmetric) {
	  rtmetric = n->rtmetric;
	  etx = neighbor_etx(n);
	  max = n;
	} else if(n->rtmetric == rtmetric) {
	  if(neighbor_etx(n) > etx) {
	    rtmetric = n->rtmetric;
	    etx = neighbor_etx(n);
	    max = n;
	    /*	PRINTF("%d: found worst neighbor %d with rtmetric %d, signal %d\n",
		node_id, neighbors[n].nodeid, rtmetric, signal);*/
	  }
	}
      }
    }
    n = max;
  }


  /*  PRINTF("%d: adding neighbor %d with rtmetric %d, signal %d at %d\n",
      node_id, neighbors[n].nodeid, rtmetric, signal, n);*/
  if(n != NULL) {
    n->time = 0;
    rimeaddr_copy(&n->addr, addr);
    n->rtmetric = nrtmetric;
    for(i = 0; i < NEIGHBOR_NUM_ETXS; ++i) {
      n->etxs[i] = netx;
    }
    n->etxptr = 0;
  }
}
Example #4
0
/*---------------------------------------------------------------------------*/
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
}