Exemple #1
0
/*
 * Unknown Protocol Handler, sends reject
 */
static void
ppp_reject_protocol(u16_t protocol, u8_t *buffer, u16_t count)
{
  u16_t	i;
  u8_t *dptr, *sptr;
  LCPPKT *pkt;
	
  /* first copy rejected packet back, start from end and work forward,
     +++ Pay attention to buffer managment when updated. Assumes fixed
     PPP blocks. */
  ANNOTATE("Rejecting Protocol\n");
  if((count + 6) > PPP_RX_BUFFER_SIZE) {
    /* This is a fatal error +++ do somthing about it. */
    ANNOTATE("Cannot Reject Protocol, PKT to big\n");
    return;
  }
  dptr = buffer + count + 6;
  sptr = buffer + count;
  for(i = 0; i < count; ++i) {
    *dptr-- = *sptr--;
  }

  pkt = (LCPPKT *)buffer;
  pkt->code = PROT_REJ;		/* Write Conf_rej */
  /*pkt->id = tid++;*/			/* write tid */
  pkt->len = uip_htons(count + 6);
  *((u16_t *)(&pkt->data)) = uip_htons(protocol);

  ahdlc_tx(LCP, buffer, 0, (u16_t)(count + 6), 0);
}
Exemple #2
0
/* scan_packet(list,buffer,len)
 *
 * list = list of supported ID's
 * *buffer pointer to the first code in the packet
 * length of the codespace
 */
u16_t
scan_packet(u16_t protocol, u8_t *list, u8_t *buffer, u8_t *options, u16_t len)
{
  u8_t *tlist, *bptr;
  u8_t *tptr;
  u8_t bad = 0;
  u8_t i, j, good;

  bptr = tptr = options;
  /* scan through the packet and see if it has any unsupported codes */
  while(bptr < options + len) {
    /* get code and see if it matches somwhere in the list, if not
       we don't support it */
    i = *bptr++;
    
    /*    ANNOTATE("%x - ",i);*/
    tlist = list;
      good = 0;
      while(*tlist) {
	/*	ANNOTATE("%x ",*tlist);*/
	if(i == *tlist++) {
	  good = 1;
	  break;
	}
      }
      if(!good) {
	/* we don't understand it, write it back */
	bad = 1;
	*tptr++ = i;
	j = *tptr++ = *bptr++;
	for(i = 0; i < j - 2; ++i) {
	  *tptr++ = *bptr++;
	}
      } else {
	/* advance over to next option */
	bptr += *bptr - 1;
      }
  }
  
  /* Bad? if we we need to send a config Reject */
  if(bad) {
    /* write the config Rej packet we've built above, take on the header */
    bptr = buffer;
    *bptr++ = CONF_REJ;		/* Write Conf_rej */
    bptr++;			/* skip over ID */
    *bptr++ = 0;
    *bptr = tptr - buffer;
    /* length right here? */
		
    /* write the reject frame */
    ANNOTATE("Writing Reject frame --\n");
    ahdlc_tx(protocol, buffer, 0, (u16_t)(tptr - buffer), 0);
    ANNOTATE("\nEnd writing reject \n");
    
  }		
  return bad;
}
Exemple #3
0
void
dump_ppp_packet(u8_t *buffer, u16_t len)
{
  int i;

  ANNOTATE("\n");
  for(i = 0;i < len; ++i) {
    if((i & 0x1f) == 0x10) {
      ANNOTATE("\n");
    }
    ANNOTATE("0x%02x ",buffer[i]);
  }
  ANNOTATE("\n\n");
}
Exemple #4
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
                  uint8_t metric)
{
  if(uip_ds6_list_loop
     ((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
      sizeof(uip_ds6_route_t), ipaddr, length,
      (uip_ds6_element_t **)&locroute) == FREESPACE) {
    locroute->isused = 1;
    uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
    locroute->length = length;
    uip_ipaddr_copy(&(locroute->nexthop), nexthop);
    locroute->metric = metric;

#ifdef UIP_DS6_ROUTE_STATE_TYPE
    memset(&locroute->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif

    PRINTF("DS6: adding route: ");
    PRINT6ADDR(ipaddr);
    PRINTF(" via ");
    PRINT6ADDR(nexthop);
    PRINTF("\n");
    ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
  }

  return locroute;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
  uip_ds6_defrt_t *d;

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

  /* Make sure that the defrt is in the list before we remove it. */
  for(d = list_head(defaultrouterlist);
      d != NULL;
      d = list_item_next(d)) {
    if(d == defrt) {
      PRINTF("Removing default route\n");
      list_remove(defaultrouterlist, defrt);
      memb_free(&defaultroutermemb, defrt);
      ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
#if UIP_DS6_NOTIFICATIONS
      call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
			  &defrt->ipaddr, &defrt->ipaddr);
#endif
      return;
    }
  }
#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */

}
Exemple #6
0
/*---------------------------------------------------------------------------*/
void
rpl_remove_routes_by_nexthop(struct in6_addr *nexthop, rpl_dag_t *dag)
{
  /*  uip_ds6_route_t *r;

  r = uip_ds6_route_list_head();

  while(r != NULL) {
    if(uip_ipaddr_cmp(&r->nexthop, nexthop) &&
       r->state.dag == dag) {
      uip_ds6_route_rm(r);
      r = uip_ds6_route_list_head();
    } else {
      r = list_item_next(r);
    }
  }
  ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
  */
#if 0
  uip_ds6_route_t *locroute;

  for(locroute = uip_ds6_routing_table;
      locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
      locroute++) {
    if(locroute->isused
        && uip_ipaddr_cmp(&locroute->nexthop, nexthop)
        && locroute->state.dag == dag) {
      locroute->isused = 0;
    }
  }
  ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#endif /* 0 */
}
Exemple #7
0
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
  if(uip_ds6_list_loop
     ((uip_ds6_element_t *)uip_ds6_defrt_list, UIP_DS6_DEFRT_NB,
      sizeof(uip_ds6_defrt_t), ipaddr, 128,
      (uip_ds6_element_t **)&locdefrt) == FREESPACE) {
    locdefrt->isused = 1;
    uip_ipaddr_copy(&locdefrt->ipaddr, ipaddr);
    if(interval != 0) {
      stimer_set(&locdefrt->lifetime, interval);
      locdefrt->isinfinite = 0;
    } else {
      locdefrt->isinfinite = 1;
    }

    PRINTF("Adding defrouter with ip addr ");
    PRINT6ADDR(&locdefrt->ipaddr);
    PRINTF("\n");

    ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);

    return locdefrt;
  }
  return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
  uip_ds6_defrt_t *d;

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

  PRINTF("uip_ds6_defrt_add\n");
  d = uip_ds6_defrt_lookup(ipaddr);
  if(d == NULL) {
    d = memb_alloc(&defaultroutermemb);
    if(d == NULL) {
      PRINTF("uip_ds6_defrt_add: could not add default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF(", out of memory\n");
      return NULL;
    } else {
      PRINTF("uip_ds6_defrt_add: adding default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF("\n");
    }

    list_push(defaultrouterlist, d);
  }

  if(ipaddr == NULL) {
    /* A special case: if uip_ds6_defrt_add() is called with a NULL
       route, this is an indication that we want to force packets to
       go out to the fallback interface. If so, we add an unspecified
       route to the list of default routes. uip_ds6_defrt_choose()
       will trap this and ensure that packets go to the fallback
       interface. */
    uip_create_unspecified(&d->ipaddr);
    ipaddr = &d->ipaddr;
  } else {
    uip_ipaddr_copy(&d->ipaddr, ipaddr);
  }

  if(interval != 0) {
    stimer_set(&d->lifetime, interval);
    d->isinfinite = 0;
  } else {
    d->isinfinite = 1;
  }

  ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);

#if UIP_DS6_NOTIFICATIONS
  call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
#endif

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

  return d;
}
void
printip(uip_ipaddr_t ip2)
{
#if (UIP_LOGGING == 1) && (DEBUG & DEBUG_ANNOTATE)
  unsigned char *ip = (unsigned char *)ip2.u8;
  ANNOTATE(" %d:%d:%d:%d ",ip[0],ip[1],ip[2],ip[3]);
#endif
}
Exemple #10
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
  if(defrt != NULL) {
    defrt->isused = 0;
    ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
  }
  return;
}
/*---------------------------------------------------------------------------*/
void
ipv6cp_init(void)
{
  ANNOTATE("ipv6cp init\n");
  ipv6cp_state = 0;
  ppp_retry = 0;
  pppif.ipaddr.u16[0] = pppif.ipaddr.u16[1] = 0;
  TIMER_expire();
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
  uip_ds6_defrt_t *d;

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

  PRINTF("uip_ds6_defrt_add\n");
  d = uip_ds6_defrt_lookup(ipaddr);
  if(d == NULL) {
    d = memb_alloc(&defaultroutermemb);
    if(d == NULL) {
      PRINTF("uip_ds6_defrt_add: could not add default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF(", out of memory\n");
      return NULL;
    } else {
      PRINTF("uip_ds6_defrt_add: adding default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF("\n");
    }

    list_push(defaultrouterlist, d);
  }

  uip_ipaddr_copy(&d->ipaddr, ipaddr);

//ADILA EDIT 03/11/14
//d->parentCh = cc2420_get_channel();
/*if(d->parentCh == 0) {
d->parentCh = 26;
}*/
//printf("\n\nINITIALISE D->PARENTCH %d\n\n", d->parentCh);
//-------------------

  if(interval != 0) {
    stimer_set(&d->lifetime, interval);
    d->isinfinite = 0;
  } else {
    d->isinfinite = 1;
  }

  ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);

#if UIP_DS6_NOTIFICATIONS
  call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
#endif

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

  return d;
}
Exemple #13
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
  if(route != NULL && route->routes != NULL) {

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

    list_remove(route->routes->route_list, route);
    if(list_head(route->routes->route_list) == NULL) {
      /* If this was the only route using this neighbor, remove the
         neibhor from the table */
      PRINTF("uip_ds6_route_rm: removing neighbor too\n");
      nbr_table_remove(nbr_routes, route->routes->route_list);
    }
    memb_free(&routememb, 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
#if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
    /* we need to check if this was the last route towards "nexthop" */
    /* if so - remove that link (annotation) */
    uip_ds6_route_t *r;
    for(r = uip_ds6_route_head();
        r != NULL;
        r = uip_ds6_route_next(r)) {
      uip_ipaddr_t *nextr, *nextroute;
      nextr = uip_ds6_route_nexthop(r);
      nextroute = uip_ds6_route_nexthop(route);
      if(nextr != NULL &&
         nextroute != NULL &&
         uip_ipaddr_cmp(nextr, nextroute)) {
        /* we found another link using the specific nexthop, so keep the #L */
        return;
      }
    }
    ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]);
#endif
  }

#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
  return;
}
Exemple #14
0
/*---------------------------------------------------------------------------*/
static void
new_dio_interval(rpl_instance_t *instance, int isReset)
{
  uint32_t time;
  clock_time_t ticks;

  /* TODO: too small timer intervals for many cases */
  time = 1UL << instance->dio_intcurrent;

  /* Convert from milliseconds to CLOCK_TICKS. */
  ticks = (time * CLOCK_SECOND) / 1000;
  instance->dio_next_delay = ticks;

  /* random number between I/2 and I */
  ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;

  /* opt trickle*/
  /*
  if (isReset == 1) {
    ticks * (uint32_t)random_rand() / RANDOM_RAND_MAX;  
  }
  else {
    ticks = ticks / 2 + (ticks / 2 * (uint32_t)random_rand()) / RANDOM_RAND_MAX;
  }
  */
  

  /*
   * The intervals must be equally long among the nodes for Trickle to
   * operate efficiently. Therefore we need to calculate the delay between
   * the randomized time and the start time of the next interval.
   */
  instance->dio_next_delay -= ticks;
  instance->dio_send = 1;

#if RPL_CONF_STATS
  /* keep some stats */
  instance->dio_totint++;
  instance->dio_totrecv += instance->dio_counter;
  ANNOTATE("#A rank=%u.%u(%u),stats=%d %d %d %d,color=%s\n",
	   DAG_RANK(instance->current_dag->rank, instance),
           (10 * (instance->current_dag->rank % instance->min_hoprankinc)) / instance->min_hoprankinc,
           instance->current_dag->version,
           instance->dio_totint, instance->dio_totsend,
           instance->dio_totrecv,instance->dio_intcurrent,
	   instance->current_dag->rank == ROOT_RANK(instance) ? "BLUE" : "ORANGE");
#endif /* RPL_CONF_STATS */

  /* reset the redundancy counter */
  instance->dio_counter = 0;

  /* schedule the timer */
  PRINTF("RPL: Scheduling DIO timer %lu ticks in future (Interval)\n", ticks);
  ctimer_set(&instance->dio_timer, ticks, &handle_dio_timer, instance);
}
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;
}
Exemple #16
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{
  for(locroute = uip_ds6_routing_table;
      locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
      locroute++) {
    if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, nexthop)) {
      locroute->isused = 0;
    }
  }
  ANNOTATE("#L %u 0\n",nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
Exemple #17
0
/*---------------------------------------------------------------------------*/
void
rpl_remove_parent(rpl_dag_t *dag, rpl_parent_t *parent)
{
  rpl_nullify_parent(dag, parent);

  PRINTF("RPL: Removing parent ");
  PRINT6ADDR(&parent->addr);
  PRINTF("\n");
  ANNOTATE("#L %u 0\n", parent->addr.u8[sizeof(uip_ipaddr_t) - 1]);

  list_remove(dag->parents, parent);
  memb_free(&parent_memb, parent);
}
Exemple #18
0
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, uip_ipaddr_t *nexthop,
                  uint8_t metric)
{
  loc_loop_state = uip_ds6_list_loop
     ((uip_ds6_element_t *)uip_ds6_routing_table, UIP_DS6_ROUTE_NB,
      sizeof(uip_ds6_route_t), ipaddr, length,
      (uip_ds6_element_t **)&locroute);

#ifdef UIP_DS6_ROUTE_STATE_CLEAN
  if (loc_loop_state == NOSPACE) {
    for(locroute = uip_ds6_routing_table;
        locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
        ++locroute) {
      if(locroute->isused
          && (UIP_DS6_ROUTE_STATE_CLEAN(&locroute->state))) {
        uip_ds6_route_rm(locroute);
        loc_loop_state = FREESPACE;
        break;
      }
    }
  }
  if (loc_loop_state == NOSPACE) {
    locroute = NULL;
  }
#endif /* UIP_DS6_ROUTE_STATE_TYPE */

  if (loc_loop_state == FREESPACE) {
    locroute->isused = 1;
    uip_ipaddr_copy(&(locroute->ipaddr), ipaddr);
    locroute->length = length;
    uip_ipaddr_copy(&(locroute->nexthop), nexthop);
    locroute->metric = metric;

#ifdef UIP_DS6_ROUTE_STATE_TYPE
    memset (&(locroute->state),0,sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif

    PRINTF("DS6: adding route: ");
    PRINT6ADDR(ipaddr);
    PRINTF(" via ");
    PRINT6ADDR(nexthop);
    PRINTF("\n");
    ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
  }

  return locroute;
}
Exemple #19
0
/*---------------------------------------------------------------------------*/
void
rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag)
{
  uip_ds6_route_t *r;

  r = uip_ds6_route_head();

  while(r != NULL) {
    if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) &&
        r->state.dag == dag) {
      r->state.lifetime = 0;
    }
    r = uip_ds6_route_next(r);
  }
  ANNOTATE("#L %u 0\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
}
Exemple #20
0
/* Remove DAG parents with a rank that is at least the same as minimum_rank. */
static void
remove_parents(rpl_dag_t *dag, rpl_rank_t minimum_rank)
{
  rpl_parent_t *p, *p2;

  PRINTF("RPL: Removing parents (minimum rank %u)\n",
	minimum_rank);

  for(p = list_head(dag->parents); p != NULL; p = p2) {
    p2 = p->next;
    if(p->rank >= minimum_rank) {
      rpl_remove_parent(dag, p);
      ANNOTATE("#L %u 0\n", p->addr.u8[sizeof(uip_ipaddr_t) - 1]);
    }
  }
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
  uip_ds6_defrt_t *d;

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

  PRINTF("uip_ds6_defrt_add\n");
  d = uip_ds6_defrt_lookup(ipaddr);
  if(d == NULL) {
    d = memb_alloc(&defaultroutermemb);
    if(d == NULL) {
      PRINTF("uip_ds6_defrt_add: could not add default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF(", out of memory\n");
      return NULL;
    } else {
      PRINTF("uip_ds6_defrt_add: adding default route to ");
      PRINT6ADDR(ipaddr);
      PRINTF("\n");
    }

    list_push(defaultrouterlist, d);
  }

  uip_ipaddr_copy(&d->ipaddr, ipaddr);
  if(interval != 0) {
    stimer_set(&d->lifetime, interval);
    d->isinfinite = 0;
  } else {
    d->isinfinite = 1;
  }

  ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);

#if UIP_DS6_NOTIFICATIONS
  call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
#endif

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

  return d;
}
/*---------------------------------------------------------------------------*/
void
ipcp_init(void)
{
  ANNOTATE("ipcp init\n");
  ipcp_state = 0;
  ppp_retry = 0;
  pppif.ipaddr.u16[0] = pppif.ipaddr.u16[1] = 0;

  //disable for gprs modem
  #if 0
  pppif.ipaddr.u8[0]=UIP_IPADDR0;
  pppif.ipaddr.u8[1]=UIP_IPADDR1;
  pppif.ipaddr.u8[2]=UIP_IPADDR2;
  pppif.ipaddr.u8[3]=UIP_IPADDR3;
  #endif

  TIMER_expire();
}
Exemple #23
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
  route->isused = 0;
#if (DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
  /* we need to check if this was the last route towards "nexthop" */
  /* if so - remove that link (annotation) */
  for(locroute = uip_ds6_routing_table;
      locroute < uip_ds6_routing_table + UIP_DS6_ROUTE_NB;
      locroute++) {
    if(locroute->isused && uip_ipaddr_cmp(&locroute->nexthop, &route->nexthop))      {
      /* we found another link using the specific nexthop, so keep the #L */
      return;
    }
  }
  ANNOTATE("#L %u 0\n",route->nexthop.u8[sizeof(uip_ipaddr_t) - 1]);
#endif
}
static void
new_dio_interval(rpl_dag_t *dag)
{
  uint32_t time;

  /* TODO: too small timer intervals for many cases */
  time = 1UL << dag->dio_intcurrent;

  /* Convert from milliseconds to CLOCK_TICKS. */
  time = (time * CLOCK_SECOND) / 1000;

  dag->dio_next_delay = time;

  /* random number between I/2 and I */
  time = time >> 1;
  time += (time * random_rand()) / RANDOM_RAND_MAX;

  /*
   * The intervals must be equally long among the nodes for Trickle to
   * operate efficiently. Therefore we need to calculate the delay between
   * the randomized time and the start time of the next interval.
   */
  dag->dio_next_delay -= time;
  dag->dio_send = 1;

#if RPL_CONF_STATS
  /* keep some stats */
  dag->dio_totint++;
  dag->dio_totrecv += dag->dio_counter;
  ANNOTATE("#A rank=Xu.Xu(Xu),stats=Xd Xd Xd Xd,color=Xs");//, DAG_RANK(dag->rank, dag), (10 * (dag->rank % dag->min_hoprankinc)) / dag->min_hoprankinc, dag->version, dag->dio_totint, dag->dio_totsend, dag->dio_totrecv,dag->dio_intcurrent, dag->rank == ROOT_RANK(dag) ? "BLUE" : "ORANGE");
#endif /* RPL_CONF_STATS */

  /* reset the redundancy counter */
  dag->dio_counter = 0;

  /* schedule the timer */
  PRINTF("RPL: Scheduling DIO timer Xlu ticks in future (Interval)");
  PRINTF_DEC(time);
  ctimer_set(&dag->dio_timer, time, &handle_dio_timer, dag);
}
Exemple #25
0
/*---------------------------------------------------------------------------*/
rpl_parent_t *
rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
{
  rpl_parent_t *p;

  if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) {
    return NULL;
  }

  p = memb_alloc(&parent_memb);
  if(p == NULL) {
    RPL_STAT(rpl_stats.mem_overflows++);
    return NULL;
  }
  memcpy(&p->addr, addr, sizeof(p->addr));
  p->dag = dag;
  p->rank = dio->rank;
  p->dtsn = dio->dtsn;
  p->link_metric = INITIAL_LINK_METRIC;
  memcpy(&p->mc, &dio->mc, sizeof(p->mc));
  list_add(dag->parents, p);
  ANNOTATE("#L %u 1\n", p->addr.u8[sizeof(uip_ipaddr_t) - 1]);
  return p;
}
/*---------------------------------------------------------------------------*/
void
ipv6cp_task(u8_t *buffer)
{
  u8_t *bptr;
  u16_t	t;
  IPCPPKT *pkt;

  /* IPCP tx not up and hasn't timed out then lets see if we need to
     send a request */
  if(!(ipv6cp_state & IPV6CP_TX_UP) && !(ipv6cp_state & IPV6CP_TX_TIMEOUT)) {
    /* Check if we have a request pending */
    /*t=get_seconds()-ipv6cp_tx_time;*/
#if 1//0//phlb modify
    if(TIMER_timeout(IPV6CP_TIMEOUT)) {
#else
    if((clock_seconds() - prev_ipv6cp_seconds) > IPV6CP_TIMEOUT) {
      prev_ipv6cp_seconds = clock_seconds();
#endif

      /*
       * No pending request, lets build one
       */
      pkt=(IPCPPKT *)buffer;		
      
      /* Configure-Request only here, write id */
      pkt->code = CONF_REQ;
      pkt->id = ppp_id;
			
      bptr = (u8_t*)&pkt->data;       

      /*
       * Write options, we want IP address, and DNS addresses if set.
       */
			
      /* Write zeros for IP address the first time */
      *bptr++ = 0x01;//IPV6CP_IPADDRESS;
      *bptr++ = 0x0a;//10
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[8];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[9];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[10];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[11];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[12];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[13];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[14];
      *bptr++ = ((u8_t*)uip_hostaddr.u8)[15];
      
#ifdef IPV6CP_GET_PRI_DNS
      if(!(ipv6cp_state & IPCP_PRI_DNS_BIT)) {
	/* Write zeros for IP address the first time */
	*bptr++ = IPV6CP_PRIMARY_DNS;
	*bptr++ = 0x6;
	*bptr++ = ((u8_t*)pri_dns_addr.u8)[0];
	*bptr++ = ((u8_t*)pri_dns_addr.u8)[1];
	*bptr++ = ((u8_t*)pri_dns_addr.u8)[2];
	*bptr++ = ((u8_t*)pri_dns_addr.u8)[3];
      }
#endif
#ifdef IPV6CP_GET_SEC_DNS
      if(!(ipv6cp_state & IPV6CP_SEC_DNS_BIT)) {
	/* Write zeros for IP address the first time */
	*bptr++ = IPV6CP_SECONDARY_DNS;
	*bptr++ = 0x6;
	*bptr++ = ((u8_t*)sec_dns_addr)[0];
	*bptr++ = ((u8_t*)sec_dns_addr)[1];
	*bptr++ = ((u8_t*)sec_dns_addr)[2];
	*bptr++ = ((u8_t*)sec_dns_addr)[3];
      }
#endif
      /* Write length */
      t = bptr - buffer;
      /* length here -  code and ID + */
      pkt->len = uip_htons(t);	
      
      ANNOTATE("\n**Sending IPV6CP Request packet\n");
      
      /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */
      ahdlc_tx(IPV6CP, 0, buffer, 0, t);

      /* Set timer */
      /*ipv6cp_tx_time=get_seconds();*/
      TIMER_set();
      /* Inc retry */
      /*ipv6cp_retry++;*/
     // ppp_retry++;
      /*
       * Have we timed out? (combide the timers?)
       */
      if(ppp_retry > IPV6CP_RETRY_COUNT)
	      ipv6cp_state |= IPV6CP_TX_TIMEOUT;	
      }
  }
}
/*
 * IPCP RX protocol Handler
 */
void
ipv6cp_rx(u8_t *buffer, u16_t count)
{
  u8_t *bptr = buffer;
//  IPCPPKT *pkt=(IPCPPKT *)buffer;
  u16_t len;

  ANNOTATE("IPV6CP len %d\n",count);
	
  switch(*bptr++) {

  case CONF_REQ:
    /* parce request and see if we can ACK it */
    ++bptr;
    len = (*bptr++ << 8);
    len |= *bptr++;
    /* len-=2; */

    ANNOTATE("check lcplist\n");
    if(scan_packet(IPV6CP, ipv6cplist, buffer, bptr, (u16_t)(len - 4))) {
      UIP_LOG("option was bad\n");
    } else {
      ANNOTATE("IPV6CP options are good\n");
      /*
       * Parse out the results
       */
      /* lets try to implement what peer wants */
      /* Reject any protocol not */
      /* Error? if we we need to send a config Reject ++++ this is
	 good for a subroutine*/
      //GD-2011-09-15 None of the IPv6CP options are supported with current implementation.
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
      /* All we should get is the peer IP address */
      if(IPV6CP_IPADDRESS == *bptr++) {
	         /* dump length */
	         ++bptr;
         #ifdef IPV6CP_GET_PEER_IP
	         ((u8_t*)peer_ip_addr.u8)[0] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[1] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[2] = *bptr++;
	         ((u8_t*)peer_ip_addr.u8)[3] = *bptr++;
	         ANNOTATE("Peer IP ");
	         /*	printip(peer_ip_addr);*/
	         ANNOTATE("\n");
         #else
	         bptr += 18;
         #endif
      } else {
	      UIP_LOG("HMMMM this shouldn't happen IPV6CP1\n");
      }
#endif
      
#if 0			
      if(error) {
	      /* write the config NAK packet we've built above, take on the header */
	      bptr = buffer;
	      *bptr++ = CONF_NAK;		/* Write Conf_rej */
	      *bptr++;
	      /*tptr++;*/  /* skip over ID */

	      /* Write new length */
	      *bptr++ = 0;
	      *bptr = tptr - buffer;
	      
	      /* write the reject frame */
	      UIP_LOG("Writing NAK frame \n");
	      ahdlc_tx(IPV6CP, buffer, (u16_t)(tptr - buffer));
	      ANNOTATE("- End NAK Write frame\n");
	      
      } else {
      }
#endif
         /*
          * If we get here then we are OK, lets send an ACK and tell the rest
          * of our modules our negotiated config.
          */
         ipv6cp_state |= IPV6CP_RX_UP;
         ipv6cp_state &= ~IPV6CP_TX_UP;//phlb force send request with ipv6cp task
         ANNOTATE("Send IPV6CP ACK!\n");
         bptr = buffer;
         *bptr++ = CONF_ACK;		/* Write Conf_ACK */
         bptr++;				/* Skip ID (send same one) */
         /*
          * Set stuff
          */
         ppp_flags |= tflag;
         ANNOTATE("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer));
	   
         /* write the ACK frame */
         ANNOTATE("Writing ACK frame \n");
         /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen);	*/
         ahdlc_tx(IPV6CP, 0, buffer, 0, count /*bptr-buffer*/);
         ANNOTATE("- End ACK Write frame\n");
	   
         /* expire the timer to make things happen after a state change */
         TIMER_expire(); //timer_expire(); //modify phlb uncomment
	   
         /*			} */
    }
    break;
    
    //
  case CONF_ACK:			/* config Ack */
       ANNOTATE("CONF ACK\n");
       /*
        * Parse out the results
        *
        * Dump the ID and get the length.
        */
       /* dump the ID */
       bptr++;

       /* get the length */
       len = (*bptr++ << 8);
       len |= *bptr++;
   #if 0 //modify phlb 
       /* Parse ACK and set data */
       while(bptr < buffer + len) {
         switch(*bptr++) {
         case IPV6CP_IPADDRESS:
	   /* dump length */
	   bptr++;		
	   ((u8_t*)ipaddr)[0] = *bptr++;
	   ((u8_t*)ipaddr)[1] = *bptr++;
	   ((u8_t*)ipaddr)[2] = *bptr++;
	   ((u8_t*)ipaddr)[3] = *bptr++;
	   break;
         case IPV6CP_PRIMARY_DNS:
	   bptr++;
	   ((u8_t*)pri_dns_addr)[0] = *bptr++;
	   ((u8_t*)pri_dns_addr)[1] = *bptr++;
	   ((u8_t*)pri_dns_addr)[2] = *bptr++;
	   ((u8_t*)pri_dns_addr)[3] = *bptr++;
	   break;
         case IPV6CP_SECONDARY_DNS:
	   bptr++;
	   ((u8_t*)sec_dns_addr)[0] = *bptr++;
	   ((u8_t*)sec_dns_addr)[1] = *bptr++;
	   ((u8_t*)sec_dns_addr)[2] = *bptr++;
	   ((u8_t*)sec_dns_addr)[3] = *bptr++;
	   break;
         default:
	   UIP_LOG("IPV6CP CONFIG_ACK problem1\n");
         }
       }
   #endif
       ipv6cp_state |= IPV6CP_TX_UP;
       //ipv6cp_state &= ~IPV6CP_RX_UP;
       ANNOTATE("were up! \n");
       printip(pppif.ipaddr);
   #ifdef IPV6CP_GET_PRI_DNS
       printip(pri_dns_addr);
   #endif
   #ifdef IPV6CP_GET_SEC_DNS
       printip(sec_dns_addr);
   #endif
       ANNOTATE("\n");
		   
       /* expire the timer to make things happen after a state change */
       TIMER_expire();
    break;

    //
  case CONF_NAK:			/* Config Nack */
    UIP_LOG("CONF NAK\n");
    /* dump the ID */
    bptr++;
    /* get the length */
    len = (*bptr++ << 8);
    len |= *bptr++;

    /* Parse ACK and set data */
    while(bptr < buffer + len) {
      switch(*bptr++) {
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
               case IPV6CP_IPADDRESS:
	         /* dump length */
	         bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[0] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[1] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[2] = *bptr++;
	         ((u8_t*)pppif.ipaddr.u8)[3] = *bptr++;
	         uip_fw_register( &pppif );
	         ANNOTATE("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr.u8)[0], ((u8_t*)pppif.ipaddr.u8)[1], ((u8_t*)pppif.ipaddr.u8)[2], ((u8_t*)pppif.ipaddr.u8)[3]); 
	         break;
#endif
         #ifdef IPV6CP_GET_PRI_DNS
               case IPV6CP_PRIMARY_DNS:
	         bptr++;
	         ((u8_t*)pri_dns_addr)[0] = *bptr++;
	         ((u8_t*)pri_dns_addr)[1] = *bptr++;
	         ((u8_t*)pri_dns_addr)[2] = *bptr++;
	         ((u8_t*)pri_dns_addr)[3] = *bptr++;
	         break;
         #endif
         #ifdef IPV6CP_GET_SEC_DNS
               case IPV6CP_SECONDARY_DNS:
	         bptr++;
	         ((u8_t*)sec_dns_addr)[0] = *bptr++;
	         ((u8_t*)sec_dns_addr)[1] = *bptr++;
	         ((u8_t*)sec_dns_addr)[2] = *bptr++;
	         ((u8_t*)sec_dns_addr)[3] = *bptr++;
	         break;
         #endif

            //
            default:
	            UIP_LOG("IPCP CONFIG_ACK problem 2\n");
          }
       }
       ppp_id++;
       printip(pppif.ipaddr);
   #ifdef IPV6CP_GET_PRI_DNS
       printip(pri_dns_addr);
   #endif
   #ifdef IPV6CP_GET_PRI_DNS
       printip(sec_dns_addr);
   #endif
       ANNOTATE("\n");
       /* expire the timer to make things happen after a state change */
       TIMER_expire();
       break;

     case CONF_REJ:			/* Config Reject */
       ANNOTATE("CONF REJ\n");
       /* Remove the offending options*/
       ppp_id++;
       /* dump the ID */
       bptr++;
       /* get the length */
       len = (*bptr++ << 8);
       len |= *bptr++;

       /* Parse ACK and set data */
       while(bptr < buffer + len) {
         switch(*bptr++) {
#if 0
#warning option implementation example based on IPCP IPv4 address configuration.
            case IPV6CP_IPADDRESS:
	         ipv6cp_state |= IPV6CP_IP_BIT;
	         bptr += 5;
	         break;
#endif

         #ifdef IPV6CP_GET_PRI_DNS
            case IPV6CP_PRIMARY_DNS:
	         ipv6cp_state |= IPV6CP_PRI_DNS_BIT;
	         bptr += 5;
	         break;
         #endif

         #ifdef IPV6CP_GET_PRI_DNS
             case IPV6CP_SECONDARY_DNS:
	         ipv6cp_state |= IPV6CP_SEC_DNS_BIT;
	         bptr += 5;
	         break;
         #endif

            default:
	         UIP_LOG("IPV6CP this shoudln't happen 3\n");
         }
    }
    /* expire the timer to make things happen after a state change */
    /*timer_expire(); */
    break;

    default:
      UIP_LOG("-Unknown 4\n");
  }
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
		  uip_ipaddr_t *nexthop)
{
  uip_ds6_route_t *r;
  struct uip_ds6_route_neighbor_route *nbrr;

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

  /* Get link-layer address of next hop, make sure it is in neighbor table */
  const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
  if(nexthop_lladdr == NULL) {
    PRINTF("uip_ds6_route_add: neighbor link-local address unknown for ");
    PRINT6ADDR(nexthop);
    PRINTF("\n");
    return NULL;
  }

  /* First make sure that we don't add a route twice. If we find an
     existing route for our destination, we'll delete the old
     one first. */
  r = uip_ds6_route_lookup(ipaddr);
  if(r != NULL) {
    PRINTF("uip_ds6_route_add: old route for ");
    PRINT6ADDR(ipaddr);
    PRINTF(" found, deleting it\n");
    uip_ds6_route_rm(r);
  }
  {
    struct uip_ds6_route_neighbor_routes *routes;
    /* If there is no routing entry, create one. We first need to
       check if we have room for this route. If not, we remove the
       least recently used one we have. */

    if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
      /* Removing the oldest route entry from the route table. The
         least recently used route is the first route on the list. */
      uip_ds6_route_t *oldest;

      oldest = list_tail(routelist); /* uip_ds6_route_head(); */
      PRINTF("uip_ds6_route_add: dropping route to ");
      PRINT6ADDR(&oldest->ipaddr);
      PRINTF("\n");
      uip_ds6_route_rm(oldest);
    }


    /* Every neighbor on our neighbor table holds a struct
       uip_ds6_route_neighbor_routes which holds a list of routes that
       go through the neighbor. We add our route entry to this list.

       We first check to see if we already have this neighbor in our
       nbr_route table. If so, the neighbor already has a route entry
       list.
    */
    routes = nbr_table_get_from_lladdr(nbr_routes,
                                       (linkaddr_t *)nexthop_lladdr);

    if(routes == NULL) {
      /* If the neighbor did not have an entry in our neighbor table,
         we create one. The nbr_table_add_lladdr() function returns a
         pointer to a pointer that we may use for our own purposes. We
         initialize this pointer with the list of routing entries that
         are attached to this neighbor. */
      routes = nbr_table_add_lladdr(nbr_routes,
                                    (linkaddr_t *)nexthop_lladdr);
      if(routes == NULL) {
        /* This should not happen, as we explicitly deallocated one
           route table entry above. */
        PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n");
        return NULL;
      }
      LIST_STRUCT_INIT(routes, route_list);
    }

    /* Allocate a routing entry and populate it. */
    r = memb_alloc(&routememb);

    if(r == NULL) {
      /* This should not happen, as we explicitly deallocated one
         route table entry above. */
      PRINTF("uip_ds6_route_add: could not allocate route\n");
      return NULL;
    }

    /* add new routes first - assuming that there is a reason to add this
       and that there is a packet coming soon. */
    list_push(routelist, r);

    nbrr = memb_alloc(&neighborroutememb);
    if(nbrr == NULL) {
      /* This should not happen, as we explicitly deallocated one
         route table entry above. */
      PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n");
      memb_free(&routememb, r);
      return NULL;
    }

    nbrr->route = r;
    /* Add the route to this neighbor */
    list_add(routes->route_list, nbrr);
    r->neighbor_routes = routes;
    num_routes++;

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

  uip_ipaddr_copy(&(r->ipaddr), ipaddr);
  r->length = length;

#ifdef UIP_DS6_ROUTE_STATE_TYPE
  memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif

  PRINTF("uip_ds6_route_add: adding route: ");
  PRINT6ADDR(ipaddr);
  PRINTF(" via ");
  PRINT6ADDR(nexthop);
  PRINTF("\n");
  ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);

#if UIP_DS6_NOTIFICATIONS
  call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
#endif

#if DEBUG != DEBUG_NONE
  assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
  return r;
}
Exemple #29
0
/*---------------------------------------------------------------------------*/
void
rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
{
  rpl_instance_t *instance;
  rpl_dag_t *dag;
  rpl_parent_t *p;
  rpl_of_t *of;

  dag = rpl_alloc_dag(dio->instance_id, &dio->dag_id);
  if(dag == NULL) {
    PRINTF("RPL: Failed to allocate a DAG object!\n");
    return;
  }

  instance = dag->instance;

  p = rpl_add_parent(dag, dio, from);
  PRINTF("RPL: Adding ");
  PRINT6ADDR(from);
  PRINTF(" as a parent: ");
  if(p == NULL) {
    PRINTF("failed\n");
    instance->used = 0;
    return;
  }
  p->dtsn = dio->dtsn;
  PRINTF("succeeded\n");

  /* Determine the objective function by using the
     objective code point of the DIO. */
  of = rpl_find_of(dio->ocp);
  if(of == NULL) {
    PRINTF("RPL: DIO for DAG instance %u does not specify a supported OF\n",
        dio->instance_id);
    rpl_remove_parent(p);
    instance->used = 0;
    return;
  }

  /* Autoconfigure an address if this node does not already have an address
     with this prefix. */
  if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) {
    check_prefix(NULL, &dio->prefix_info);
  }

  dag->joined = 1;
  dag->preference = dio->preference;
  dag->grounded = dio->grounded;
  dag->version = dio->version;

  instance->of = of;
  instance->mop = dio->mop;
  instance->current_dag = dag;
  instance->dtsn_out = RPL_LOLLIPOP_INIT;

  instance->max_rankinc = dio->dag_max_rankinc;
  instance->min_hoprankinc = dio->dag_min_hoprankinc;
  instance->dio_intdoubl = dio->dag_intdoubl;
  instance->dio_intmin = dio->dag_intmin;
  instance->dio_intcurrent = instance->dio_intmin + instance->dio_intdoubl;
  instance->dio_redundancy = dio->dag_redund;
  instance->default_lifetime = dio->default_lifetime;
  instance->lifetime_unit = dio->lifetime_unit;

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

  /* Copy prefix information from the DIO into the DAG object. */
  memcpy(&dag->prefix_info, &dio->prefix_info, sizeof(rpl_prefix_t));

  rpl_set_preferred_parent(dag, p);
  instance->of->update_metric_container(instance);
  dag->rank = instance->of->calculate_rank(p, 0);
  /* So far this is the lowest rank we are aware of. */
  dag->min_rank = dag->rank;

  if(default_instance == NULL) {
    default_instance = instance;
  }

  PRINTF("RPL: Joined DAG with instance ID %u, rank %hu, DAG ID ",
         dio->instance_id, dag->rank);
  PRINT6ADDR(&dag->dag_id);
  PRINTF("\n");

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

  rpl_reset_dio_timer(instance);
  rpl_set_default_route(instance, from);

  if(instance->mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
    rpl_schedule_dao(instance);
  } else {
    PRINTF("RPL: The DIO does not meet the prerequisites for sending a DAO\n");
  }
}
Exemple #30
0
/*---------------------------------------------------------------------------*/
rpl_dag_t *
rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id)
{
  rpl_dag_t *dag;
  rpl_instance_t *instance;
  uint8_t version;
  int i;

#if CETIC_6LBR
  version = nvm_data.rpl_version_id;
  RPL_LOLLIPOP_INCREMENT(version);
  nvm_data.rpl_version_id = version;
  store_nvm_config();
#else
  version = RPL_LOLLIPOP_INIT;
#endif
  instance = rpl_get_instance(instance_id);
  if(instance != NULL) {
    for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; ++i) {
      dag = &instance->dag_table[i];
      if(dag->used) {
        if(uip_ipaddr_cmp(&dag->dag_id, dag_id)) {
          version = dag->version;
          RPL_LOLLIPOP_INCREMENT(version);
#if CETIC_6LBR
          nvm_data.rpl_version_id = version;
          store_nvm_config();
#endif
        }
        if(dag == dag->instance->current_dag) {
          PRINTF("RPL: Dropping a joined DAG when setting this node as root");
          rpl_set_default_route(instance, NULL);
          dag->instance->current_dag = NULL;
        } else {
          PRINTF("RPL: Dropping a DAG when setting this node as root");
        }
        rpl_free_dag(dag);
      }
    }
  }

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

  instance = dag->instance;

  dag->version = version;
  dag->joined = 1;
  dag->grounded = RPL_GROUNDED;
  dag->preference = RPL_PREFERENCE;
  instance->mop = RPL_MOP_DEFAULT;
  instance->of = &RPL_OF;
  rpl_set_preferred_parent(dag, NULL);

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

  instance->dio_intdoubl = RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_intmin = RPL_DIO_INTERVAL_MIN;
  /* The current interval must differ from the minimum interval in order to
     trigger a DIO timer reset. */
  instance->dio_intcurrent = RPL_DIO_INTERVAL_MIN +
    RPL_DIO_INTERVAL_DOUBLINGS;
  instance->dio_redundancy = RPL_DIO_REDUNDANCY;
  instance->max_rankinc = RPL_MAX_RANKINC;
  instance->min_hoprankinc = RPL_MIN_HOPRANKINC;
  instance->default_lifetime = RPL_DEFAULT_LIFETIME;
  instance->lifetime_unit = RPL_DEFAULT_LIFETIME_UNIT;

  dag->rank = ROOT_RANK(instance);

  if(instance->current_dag != dag && instance->current_dag != NULL) {
    /* Remove routes installed by DAOs. */
    rpl_remove_routes(instance->current_dag);

    instance->current_dag->joined = 0;
  }

  instance->current_dag = dag;
  instance->dtsn_out = RPL_LOLLIPOP_INIT;
  instance->of->update_metric_container(instance);
  default_instance = instance;

  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(instance);

  return dag;
}