Beispiel #1
0
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
rpl_get_parent_ipaddr(rpl_parent_t *p)
{
  rimeaddr_t *lladdr = nbr_table_get_lladdr(rpl_parents, p);

  return uip_ds6_nbr_ipaddr_from_lladdr((uip_lladdr_t *)lladdr);
}
Beispiel #2
0
/*---------------------------------------------------------------------------*/
void
rpl_print_neighbor_list()
{
  if(default_instance != NULL && default_instance->current_dag != NULL &&
      default_instance->of != NULL && default_instance->of->calculate_rank != NULL) {
    int curr_dio_interval = default_instance->dio_intcurrent;
    int curr_rank = default_instance->current_dag->rank;
    rpl_parent_t *p = nbr_table_head(rpl_parents);
    clock_time_t now = clock_time();

    printf("RPL: rank %u dioint %u, %u nbr(s)\n", curr_rank, curr_dio_interval, uip_ds6_nbr_num());
    while(p != NULL) {
      uip_ds6_nbr_t *nbr = rpl_get_nbr(p);
      printf("RPL: nbr %3u %5u, %5u => %5u %c%c (last tx %u min ago)\n",
          nbr_table_get_lladdr(rpl_parents, p)->u8[7],
          p->rank, nbr ? nbr->link_metric : 0,
          default_instance->of->calculate_rank(p, 0),
          default_instance->current_dag == p->dag ? 'd' : ' ',
          p == default_instance->current_dag->preferred_parent ? '*' : ' ',
          (unsigned)((now - p->last_tx_time) / (60 * CLOCK_SECOND)));
      p = nbr_table_next(rpl_parents, p);
    }
    printf("RPL: end of list\n");
  }
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
static uip_lladdr_t *
uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route)
{
  if(route != NULL) {
    return (uip_lladdr_t *)nbr_table_get_lladdr(nbr_routes, route->routes);
  } else {
    return NULL;
  }
}
Beispiel #4
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
rpl_get_nbr(rpl_parent_t *parent)
{
  linkaddr_t *lladdr = NULL;
  lladdr = nbr_table_get_lladdr(rpl_parents, parent);
  if(lladdr != NULL) {
    return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
  } else {
    return NULL;
  }
}
Beispiel #5
0
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
rpl_get_nbr(rpl_parent_t *parent)
{
  linkaddr_t *lladdr = NULL;
  lladdr = nbr_table_get_lladdr(rpl_parents, parent);
  if(lladdr != NULL) {
    return uip_ds6_nbr_ll_lookup((uip_lladdr_t*) lladdr);
  } else {
    return NULL;
  }
}
Beispiel #6
0
/*---------------------------------------------------------------------------*/
static void
handle_probing_timer(void *ptr)
{
  rpl_instance_t *instance = (rpl_instance_t *)ptr;
  rpl_parent_t *probing_target = RPL_PROBING_SELECT_FUNC(instance->current_dag);

  /* Perform probing */
  if(probing_target != NULL && rpl_get_parent_ipaddr(probing_target) != NULL) {
    PRINTF("RPL: probing %3u\n",
        nbr_table_get_lladdr(rpl_parents, probing_target)->u8[7]);
    /* Send probe, e.g. unicast DIO or DIS */
    RPL_PROBING_SEND_FUNC(instance, rpl_get_parent_ipaddr(probing_target));
  }

  /* Schedule next probing */
  rpl_schedule_probing(instance);

#if DEBUG
  rpl_print_neighbor_list();
#endif
}
Beispiel #7
0
/*---------------------------------------------------------------------------*/
static void
eb_input(struct input_packet *current_input)
{
  /* PRINTF("TSCH: EB received\n"); */
  frame802154_t frame;
  /* Verify incoming EB (does its ASN match our Rx time?),
   * and update our join priority. */
  struct ieee802154_ies eb_ies;

  if(tsch_packet_parse_eb(current_input->payload, current_input->len,
                          &frame, &eb_ies, NULL, 1)) {
    /* PAN ID check and authentication done at rx time */

#if TSCH_AUTOSELECT_TIME_SOURCE
    if(!tsch_is_coordinator) {
      /* Maintain EB received counter for every neighbor */
      struct eb_stat *stat = (struct eb_stat *)nbr_table_get_from_lladdr(eb_stats, &frame.src_addr);
      if(stat == NULL) {
        stat = (struct eb_stat *)nbr_table_add_lladdr(eb_stats, &frame.src_addr);
      }
      if(stat != NULL) {
        stat->rx_count++;
        stat->jp = eb_ies.join_priority;
        best_neighbor_eb_count = MAX(best_neighbor_eb_count, stat->rx_count);
      }
      /* Select best time source */
      struct eb_stat *best_stat = NULL;
      stat = nbr_table_head(eb_stats);
      while(stat != NULL) {
        /* Is neighbor eligible as a time source? */
        if(stat->rx_count > best_neighbor_eb_count / 2) {
          if(best_stat == NULL ||
             stat->jp < best_stat->jp) {
            best_stat = stat;
          }
        }
        stat = nbr_table_next(eb_stats, stat);
      }
      /* Update time source */
      if(best_stat != NULL) {
        tsch_queue_update_time_source(nbr_table_get_lladdr(eb_stats, best_stat));
        tsch_join_priority = best_stat->jp + 1;
      }
    }
#endif

    struct tsch_neighbor *n = tsch_queue_get_time_source();
    /* Did the EB come from our time source? */
    if(n != NULL && linkaddr_cmp((linkaddr_t *)&frame.src_addr, &n->addr)) {
      /* Check for ASN drift */
      int32_t asn_diff = ASN_DIFF(current_input->rx_asn, eb_ies.ie_asn);
      if(asn_diff != 0) {
        /* We disagree with our time source's ASN -- leave the network */
        PRINTF("TSCH:! ASN drifted by %ld, leaving the network\n", asn_diff);
        tsch_disassociate();
      }

      if(eb_ies.ie_join_priority >= TSCH_MAX_JOIN_PRIORITY) {
        /* Join priority unacceptable. Leave network. */
        PRINTF("TSCH:! EB JP too high %u, leaving the network\n",
               eb_ies.ie_join_priority);
        tsch_disassociate();
      } else {
#if TSCH_AUTOSELECT_TIME_SOURCE
        /* Update join priority */
        if(tsch_join_priority != eb_ies.ie_join_priority + 1) {
          PRINTF("TSCH: update JP from EB %u -> %u\n",
                 tsch_join_priority, eb_ies.ie_join_priority + 1);
          tsch_join_priority = eb_ies.ie_join_priority + 1;
        }
#endif /* TSCH_AUTOSELECT_TIME_SOURCE */
      }
    }
  }
}
Beispiel #8
0
/*---------------------------------------------------------------------------*/
const uip_lladdr_t *
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
{
  return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
  struct uip_ds6_route_neighbor_route *neighbor_route;
#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
  if(route != NULL && route->neighbor_routes != NULL) {

    PRINTF("uip_ds6_route_rm: removing route: ");
    PRINT6ADDR(&route->ipaddr);
    PRINTF("\n");

    /* Remove the route from the route list */
    list_remove(routelist, route);

    /* Find the corresponding neighbor_route and remove it. */
    for(neighbor_route = list_head(route->neighbor_routes->route_list);
        neighbor_route != NULL && neighbor_route->route != route;
        neighbor_route = list_item_next(neighbor_route));

    if(neighbor_route == NULL) {
      PRINTF("uip_ds6_route_rm: neighbor_route was NULL for ");
      uip_debug_ipaddr_print(&route->ipaddr);
      PRINTF("\n");
    }
    list_remove(route->neighbor_routes->route_list, neighbor_route);
    if(list_head(route->neighbor_routes->route_list) == NULL) {
      /* If this was the only route using this neighbor, remove the
         neighbor from the table - this implicitly unlocks nexthop */
#if (DEBUG) & DEBUG_ANNOTATE
      uip_ipaddr_t *nexthop = uip_ds6_route_nexthop(route);
      if(nexthop != NULL) {
        ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
      }
#endif /* (DEBUG) & DEBUG_ANNOTATE */
      PRINTF("uip_ds6_route_rm: removing neighbor too\n");
      nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
#ifdef NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK
      NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK(
          (const linkaddr_t *)nbr_table_get_lladdr(nbr_routes, route->neighbor_routes->route_list));
#endif
    }
    memb_free(&routememb, route);
    memb_free(&neighborroutememb, neighbor_route);

    num_routes--;

    PRINTF("uip_ds6_route_rm num %d\n", num_routes);

#if UIP_DS6_NOTIFICATIONS
    call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
        &route->ipaddr, uip_ds6_route_nexthop(route));
#endif

#ifdef NETSTACK_CONF_ROUTE_REMOVED_CALLBACK
NETSTACK_CONF_ROUTE_REMOVED_CALLBACK(&route->ipaddr);
#endif /* NETSTACK_CONF_ROUTE_REMOVED_CALLBACK*/
  }

#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */

  return;
}