Exemple #1
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
    uip_ipaddr_t ipaddr;
    struct uip_ds6_addr *root_if;

    PROCESS_BEGIN();

    PROCESS_PAUSE();

    SENSORS_ACTIVATE(button_sensor);

    PRINTF("UDP server started\n");

#if UIP_CONF_ROUTER
    uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
    /* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
    uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
    root_if = uip_ds6_addr_lookup(&ipaddr);
    if(root_if != NULL) {
        rpl_dag_t *dag;
        rpl_set_root((uip_ip6addr_t *)&ipaddr);
        dag = rpl_get_dag(RPL_ANY_INSTANCE);
        uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
        rpl_set_prefix(dag, &ipaddr, 64);
        PRINTF("created a new RPL dag\n");
    } else {
        PRINTF("failed to create a new RPL DAG\n");
    }
#endif /* UIP_CONF_ROUTER */

    print_local_addresses();

    /* The data sink runs with a 100% duty cycle in order to ensure high
       packet reception rates. */
    NETSTACK_RDC.off(1);

    server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
    udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));

    PRINTF("Created a server connection with remote address ");
    PRINT6ADDR(&server_conn->ripaddr);
    PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport),
           UIP_HTONS(server_conn->rport));

    while(1) {
        PROCESS_YIELD();
        if(ev == tcpip_event) {
            tcpip_handler();
        } else if (ev == sensors_event && data == &button_sensor) {
            PRINTF("Initiaing global repair\n");
            rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE));
        }
    }

    PROCESS_END();
}
Exemple #2
0
void
rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
{
  rpl_dag_t *dag;
  rpl_parent_t *p;

  /* This only handles one DODAG - if multiple we need to check all */
  dag = rpl_get_dag(RPL_ANY_INSTANCE);
  if(dag == NULL) {
    return;
  }

  /* if this is our default route then clean the dag->def_route state */
  if(dag->def_route != NULL &&
     uip_ipaddr_cmp(&dag->def_route->ipaddr, &nbr->ipaddr)) {
    dag->def_route = NULL;
  }

  if(!nbr->isused) {
    PRINTF("RPL: Removing neighbor ");
    PRINT6ADDR(&nbr->ipaddr);
    PRINTF("\n");
    p = rpl_find_parent(dag, &nbr->ipaddr);
    if(p != NULL) {
      p->rank = INFINITE_RANK;
      /* Trigger DAG rank recalculation. */
      p->updated = 1;
    }
  }
}
void
rpl_recalculate_ranks(void)
{
  rpl_dag_t *dag;
  rpl_parent_t *p;

  /*
   * We recalculate ranks when we receive feedback from the system rather
   * than RPL protocol messages. This periodical recalculation is called
   * from a timer in order to keep the stack depth reasonably low.
   */
  dag = rpl_get_dag(RPL_ANY_INSTANCE);
  if(dag != NULL) {
    for(p = list_head(dag->parents); p != NULL; p = p->next) {
      if(p->updated) {
	p->updated = 0;
	rpl_process_parent_event(dag, p);
	/*
	 * Stop calculating here because the parent list may have changed.
	 * If more ranks need to be recalculated, it will be taken care of
	 * in subsequent calls to this functions.
	 */
	break;
      }
    }
  }
}
rpl_dag_t *
rpl_set_root(uip_ipaddr_t *dag_id)
{
  rpl_dag_t *dag;
  int version;

  version = -1;
  dag = rpl_get_dag(RPL_DEFAULT_INSTANCE);
  if(dag != NULL) {
    PRINTF("RPL: Dropping a joined DAG when setting this node as root");
    version = dag->version;
    rpl_free_dag(dag);
  }

  dag = rpl_alloc_dag(RPL_DEFAULT_INSTANCE);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG\n");
    return NULL;
  }

  dag->joined = 1;
  dag->version = version + 1;
  dag->grounded = RPL_GROUNDED;
  dag->mop = RPL_MOP_DEFAULT;
  dag->of = &RPL_OF;
  dag->preferred_parent = NULL;
  dag->dtsn_out = 1; /* Trigger DAOs from the beginning. */

  memcpy(&dag->dag_id, dag_id, sizeof(dag->dag_id));

  dag->dio_intdoubl = DEFAULT_DIO_INTERVAL_DOUBLINGS;
  dag->dio_intmin = DEFAULT_DIO_INTERVAL_MIN;
  dag->dio_redundancy = DEFAULT_DIO_REDUNDANCY;
  dag->max_rankinc = DEFAULT_MAX_RANKINC;
  dag->min_hoprankinc = DEFAULT_MIN_HOPRANKINC;

  dag->default_lifetime = RPL_DEFAULT_LIFETIME;
  dag->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;

  dag->rank = ROOT_RANK(dag);

  dag->of->update_metric_container(dag);

  PRINTF("RPL: Node set to be a DAG root with DAG ID ");
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

  ANNOTATE("#A root=%u\n",dag->dag_id.u8[sizeof(dag->dag_id) - 1]);


  rpl_reset_dio_timer(dag, 1);

  return dag;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(border_router_process, ev, data)
{
  static struct etimer et;
  rpl_dag_t *dag;

  PROCESS_BEGIN();
  prefix_set = 0;

  PROCESS_PAUSE();

#if WEBSERVER
  process_start(&webserver_nogui_process, NULL);
#endif

  //SENSORS_ACTIVATE(button_sensor);

  PRINTF("RPL-Border router started\n");

  /* Request prefix until it has been received */
  while(!prefix_set) {
    etimer_set(&et, CLOCK_SECOND);
    request_prefix();
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  dag = rpl_set_root((uip_ip6addr_t *)dag_id);
  if(dag != NULL) {
    rpl_set_prefix(dag, &prefix, 64);
    PRINTF("created a new RPL dag\n");
  }

#if DEBUG || 1
  print_local_addresses();
#endif

  /* The border router runs with a 100% duty cycle in order to ensure high
     packet reception rates. */
  NETSTACK_MAC.off(1);

  static struct etimer t;
  etimer_set(&t, 10*CLOCK_SECOND);
  while(1) {
    PROCESS_YIELD();
    //if (ev == sensors_event && data == &button_sensor) {
    if (etimer_expired(&t)) {
      PRINTF("Initiating global repair\n");
      rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE));
      etimer_reset(&t);
    }
  }

  PROCESS_END();
}
static void
handle_periodic_timer(void *ptr)
{
  rpl_purge_routes();
  rpl_recalculate_ranks();

  /* handle DIS */
#ifdef RPL_DIS_SEND
  next_dis++;
  if(rpl_get_dag(RPL_ANY_INSTANCE) == NULL && next_dis >= RPL_DIS_INTERVAL) {
    next_dis = 0;
    dis_output(NULL);
  }
#endif
  ctimer_reset(&periodic_timer);
}
Exemple #7
0
static void
rpl_link_neighbor_callback(const rimeaddr_t *addr, int known, int etx)
{
  uip_ipaddr_t ipaddr;
  rpl_dag_t *dag;
  rpl_parent_t *parent;

  uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
  uip_ds6_set_addr_iid(&ipaddr, (uip_lladdr_t *)addr);
  PRINTF("RPL: Neighbor ");
  PRINT6ADDR(&ipaddr);
  PRINTF(" is %sknown. ETX = %u\n", known ? "" : "no longer ", NEIGHBOR_INFO_FIX2ETX(etx));

  dag = rpl_get_dag(RPL_DEFAULT_INSTANCE);
  if(dag == NULL) {
    return;
  }

  parent = rpl_find_parent(dag, &ipaddr);
  if(parent == NULL) {
    if(!known) {
      PRINTF("RPL: Deleting routes installed by DAOs received from ");
      PRINT6ADDR(&ipaddr);
      PRINTF("\n");
      uip_ds6_route_rm_by_nexthop(&ipaddr);
    }
    return;
  }

  /* Trigger DAG rank recalculation. */
  parent->updated = 1;

  parent->link_metric = etx;

  if(dag->of->parent_state_callback != NULL) {
    dag->of->parent_state_callback(parent, known, etx);
  }

  if(!known) {
    PRINTF("RPL: Removing parent ");
    PRINT6ADDR(&parent->addr);
    PRINTF(" because of bad connectivity (ETX %d)\n", etx);
    parent->rank = INFINITE_RANK;
  }
}
/*---------------------------------------------------------------------------*/
static void
create_rpl_dag(uip_ipaddr_t *ipaddr)
{
  struct uip_ds6_addr *root_if;

  root_if = uip_ds6_addr_lookup(ipaddr);
  if(root_if != NULL) {
    rpl_dag_t *dag;
    uip_ipaddr_t prefix;
    
    rpl_set_root(ipaddr);
    dag = rpl_get_dag(RPL_ANY_INSTANCE);
    uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
    rpl_set_prefix(dag, &prefix, 64);
    PRINTF("created a new RPL dag\n");
  } else {
    PRINTF("failed to create a new RPL DAG\n");
  }
}
void
collect_common_net_print(void)
{
  rpl_dag_t *dag;
  int i;
  dag = rpl_get_dag(RPL_ANY_INSTANCE);
  if(dag->preferred_parent != NULL) {
    PRINTF("Preferred parent: ");
    PRINT6ADDR(&dag->preferred_parent->addr);
    PRINTF("\n");
  }
  PRINTF("Route entries:\n");
  for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
    if(uip_ds6_routing_table[i].isused) {
      PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr);
      PRINTF("\n");
    }
  }
  PRINTF("---\n");
}
void
rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
{
  rpl_dag_t *dag;
  rpl_parent_t *p;

  if(dio->mop != RPL_MOP_DEFAULT) {
    PRINTF("RPL: Ignoring a DIO with an unsupported MOP: %d\n", dio->mop);
    return;
  }

// LVD 24/03/2011
  instanceID = dio->instance_id;
  
  dag = rpl_get_dag(dio->instance_id);
  if(dag == NULL) {
    /* Join the first possible DAG of this RPL instance. */
    if(dio->rank != INFINITE_RANK) {
      join_dag(from, dio);
    } else {
      PRINTF("RPL: Ignoring DIO from node with infinite rank: ");
      PRINT6ADDR(from);
      PRINTF("\n");
    }
    return;
  }

  if(memcmp(&dag->dag_id, &dio->dag_id, sizeof(dag->dag_id))) {
    PRINTF("RPL: Ignoring DIO for another DAG within our instance\n");
    return;
  }

  if(dio->version > dag->version) {
    if(dag->rank == ROOT_RANK(dag)) {
      PRINTF("RPL: Root received inconsistent DIO version number\n");
      dag->version = dio->version + 1;
      rpl_reset_dio_timer(dag, 1);
    } else {
      global_repair(from, dag, dio);
    }
    return;
  } else if(dio->version < dag->version) {
    /* Inconsistency detected - someone is still on old version */
    PRINTF("RPL: old version received => inconsistency detected\n");
    rpl_reset_dio_timer(dag, 1);
    return;
  }

  if(dio->rank == INFINITE_RANK) {
    rpl_reset_dio_timer(dag, 1);
  } else if(dio->rank < ROOT_RANK(dag)) {
    PRINTF("RPL: Ignoring DIO with too low rank: %u\n",
           (unsigned)dio->rank);
    return;
  }

  if(dag->rank == ROOT_RANK(dag)) {
    if(dio->rank != INFINITE_RANK) {
      dag->dio_counter++;
    }
    return;
  }

  /*
   * At this point, we know that this DIO pertains to a DAG that
   * we are already part of. We consider the sender of the DIO to be
   * a candidate parent, and let rpl_process_parent_event decide
   * whether to keep it in the set.
   */

  p = rpl_find_parent(dag, from);
  if(p == NULL) {
    if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS) {
      /* Make room for a new parent. */
      remove_worst_parent(dag, dio->rank);
    }
    
    /* Add the DIO sender as a candidate parent. */
    p = rpl_add_parent(dag, dio, from);
    if(p == NULL) {
      PRINTF("RPL: Failed to add a new parent (");
      PRINT6ADDR(from);
      PRINTF(")\n");
      return;
    }

    PRINTF("RPL: New candidate parent with rank %u: ", (unsigned)p->rank);
    PRINT6ADDR(from);
    PRINTF("\n");
  } else if(DAG_RANK(p->rank, dag) == DAG_RANK(dio->rank, dag)) {
    PRINTF("RPL: Received consistent DIO\n");
    dag->dio_counter++;
  }
  
  /* We have allocated a candidate parent; process the DIO further. */

  memcpy(&p->mc, &dio->mc, sizeof(p->mc));    
  p->rank = dio->rank;
  if(rpl_process_parent_event(dag, p) == 0) {
    /* The candidate parent no longer exists. */
    return;
  }
  
  if(should_send_dao(dag, dio, p)) {
    rpl_schedule_dao(dag);
  }
  
  p->dtsn = dio->dtsn;
}
/*---------------------------------------------------------------------------*/
void
collect_common_send(void)
{
  static uint8_t seqno;
  struct {
    uint8_t seqno;
    uint8_t for_alignment;
    struct collect_view_data_msg msg;
  } msg;
  /* struct collect_neighbor *n; */
  uint16_t parent_etx;
  uint16_t rtmetric;
  uint16_t num_neighbors;
  uint16_t beacon_interval;
  rpl_parent_t *preferred_parent;
  rimeaddr_t parent;
  rpl_dag_t *dag;

  if(client_conn == NULL) {
    /* Not setup yet */
    return;
  }
  memset(&msg, 0, sizeof(msg));
  seqno++;
  if(seqno == 0) {
    /* Wrap to 128 to identify restarts */
    seqno = 128;
  }
  msg.seqno = seqno;

  rimeaddr_copy(&parent, &rimeaddr_null);
  parent_etx = 0;

  dag = rpl_get_dag(RPL_DEFAULT_INSTANCE);
  if(dag != NULL) {
    preferred_parent = dag->preferred_parent;
    if(preferred_parent != NULL) {
      uip_ds6_nbr_t *nbr;
      nbr = uip_ds6_nbr_lookup(&preferred_parent->addr);
      if(nbr != NULL) {
        /* Use parts of the IPv6 address as the parent address, in reversed byte order. */
        parent.u8[RIMEADDR_SIZE - 1] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 2];
        parent.u8[RIMEADDR_SIZE - 2] = nbr->ipaddr.u8[sizeof(uip_ipaddr_t) - 1];
        parent_etx = neighbor_info_get_metric((rimeaddr_t *) &nbr->lladdr) / 2;
      }
    }
    rtmetric = dag->rank;
    beacon_interval = (uint16_t) ((2L << dag->dio_intcurrent) / 1000);
    num_neighbors = RPL_PARENT_COUNT(dag);
  } else {
    rtmetric = 0;
    beacon_interval = 0;
    num_neighbors = 0;
  }

  /* num_neighbors = collect_neighbor_list_num(&tc.neighbor_list); */
  collect_view_construct_message(&msg.msg, &parent,
                                 parent_etx, rtmetric,
                                 num_neighbors, beacon_interval);

  uip_udp_packet_sendto(client_conn, &msg, sizeof(msg),
                        &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
}