/*---------------------------------------------------------------------------*/ 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 = RPL_INIT_LINK_METRIC; #if RPL_DAG_MC != RPL_DAG_MC_NONE memcpy(&p->mc, &dio->mc, sizeof(p->mc)); #endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */ list_add(dag->parents, p); return p; }
static void parent_state_callback(rpl_parent_t *parent, int known, int etx) { rpl_dag_t *dag; dag = (rpl_dag_t *)parent->dag; if(!known) { if(RPL_PARENT_COUNT(dag) == 1) { /* Our last parent has disappeared, set the path ETX to INFINITE_RANK. */ min_path_cost = INFINITE_RANK; } } }
/*---------------------------------------------------------------------------*/ 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; }
static void send_packet(void *ptr) { static uint16_t seqno = 0; struct app_msg msg; 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(sender_conn == NULL) return; memset(&msg, 0, sizeof(msg)); seqno++; msg.seqno = seqno; rimeaddr_copy(&parent, &rimeaddr_null); parent_etx = 0; // Let's suppose we have only one instance. dag = rpl_get_any_dag(); if( dag != NULL) { preferred_parent = dag->preferred_parent; if(preferred_parent != NULL) { uip_ds6_nbr_t *nbr; nbr = uip_ds6_nbr_lookup(&preferred_parent->next); 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 = rpl_get_parent_rank((rimeaddr_t *)uip_ds6_nbr_get_ll(nbr)) / 2; } } rtmetric = dag->rank; beacon_interval = (uint16_t)((2L<<dag->instance->dio_intcurrent) / 1000); num_neighbors = RPL_PARENT_COUNT(dag); } else { rtmetric = 0; beacon_interval = 0; num_neighbors = 0; } msg.parent_etx = parent_etx; msg.rtmetric = rtmetric; msg.num_neighbors = num_neighbors; msg.beacon_interval = beacon_interval; memset(msg.data, 11, sizeof(msg.data) - 2); msg.data[10] = seqno; uip_udp_packet_sendto(sender_conn, &msg, sizeof(msg), &sink_ipaddr, UIP_HTONS(UDP_SINK_PORT)); PRINTF("DATA send NO %d to %d * msg size %u\n", seqno, sink_ipaddr.u8[sizeof(sink_ipaddr.u8) - 1], sizeof(msg)); PRINTF("Sink addr : "); PRINT6ADDR(&sink_ipaddr); PRINTF("\n"); }
/*---------------------------------------------------------------------------*/ void rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) { rpl_instance_t *instance; rpl_dag_t *dag, *previous_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; } dag = get_dag(dio->instance_id, &dio->dag_id); instance = rpl_get_instance(dio->instance_id); if(dag != NULL && instance != NULL) { if(lollipop_greater_than(dio->version, dag->version)) { if(dag->rank == ROOT_RANK(instance)) { PRINTF("RPL: Root received inconsistent DIO version number\n"); dag->version = dio->version; RPL_LOLLIPOP_INCREMENT(dag->version); rpl_reset_dio_timer(instance); } else { PRINTF("RPL: Global Repair\n"); if(dio->prefix_info.length != 0) { if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { PRINTF("RPL : Prefix announced in DIO\n"); rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); } } global_repair(from, dag, dio); } return; } if(lollipop_greater_than(dag->version, dio->version)) { /* The DIO sender is on an older version of the DAG. */ PRINTF("RPL: old version received => inconsistency detected\n"); if(dag->joined) { rpl_reset_dio_timer(instance); return; } } } if(dio->rank == INFINITE_RANK) { PRINTF("RPL: Ignoring DIO from node with infinite rank: "); PRINT6ADDR(from); PRINTF("\n"); return; } if(instance == NULL) { PRINTF("RPL: New instance detected: Joining...\n"); rpl_join_instance(from, dio); return; } if(dag == NULL) { PRINTF("RPL: Adding new DAG to known instance.\n"); rpl_add_dag(from, dio); return; } if(dio->rank < ROOT_RANK(instance)) { PRINTF("RPL: Ignoring DIO with too low rank: %u\n", (unsigned)dio->rank); return; } else if(dio->rank == INFINITE_RANK && dag->joined) { rpl_reset_dio_timer(instance); } /* Prefix Information Option treated to add new prefix */ if(dio->prefix_info.length != 0) { if(dio->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS) { PRINTF("RPL : Prefix announced in DIO\n"); rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); } } if(dag->rank == ROOT_RANK(instance)) { if(dio->rank != INFINITE_RANK) { instance->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) { previous_dag = find_parent_dag(instance, from); if(previous_dag == NULL) { if(RPL_PARENT_COUNT(dag) == RPL_MAX_PARENTS_PER_DAG) { /* 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 { p = rpl_find_parent(previous_dag, from); if(p != NULL) { rpl_move_parent(previous_dag, dag, p); } } } else { if(p->rank == dio->rank) { PRINTF("RPL: Received consistent DIO\n"); if(dag->joined) { instance->dio_counter++; } } else { p->rank=dio->rank; } } PRINTF("RPL: preferred DAG "); PRINT6ADDR(&instance->current_dag->dag_id); PRINTF(", rank %u, min_rank %u, ", instance->current_dag->rank, instance->current_dag->min_rank); PRINTF("parent rank %u, parent etx %u, link metric %u, instance etx %u\n", p->rank, p->mc.obj.etx, p->link_metric, instance->mc.obj.etx); /* We have allocated a candidate parent; process the DIO further. */ memcpy(&p->mc, &dio->mc, sizeof(p->mc)); if(rpl_process_parent_event(instance, p) == 0) { PRINTF("RPL: The candidate parent is rejected\n"); return; } /* We don't use route control, so we can have only one official parent. */ if(dag->joined && p == dag->preferred_parent) { if(should_send_dao(instance, dio, p)) { RPL_LOLLIPOP_INCREMENT(instance->dtsn_out); rpl_schedule_dao(instance); } /* We received a new DIO from our preferred parent. * Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */ uip_ds6_defrt_add(from, RPL_LIFETIME(instance, instance->default_lifetime)); } p->dtsn = dio->dtsn; }
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)); }
/*-----------------------------------------------------------------------*/ void collect_common_send(void) { static uint8_t seqno; struct { uint8_t seqno; uint8_t for_alignment; struct collect_view_data_msg msg; uint8_t hop_count; uint8_t lifetime; uint16_t data[72]; } msg; 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(sender_conn == NULL) { return; } memset(&msg, 0, sizeof(msg)); seqno++; if(seqno == 0) { seqno = 128; /* Wrap to 128 to identify restarts */ } msg.seqno = seqno; rimeaddr_copy(&parent, &rimeaddr_null); parent_etx = 0; /* Let's suppose we have only one instance. */ dag = rpl_get_any_dag(); 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->instance->dio_intcurrent) / 1000); num_neighbors = RPL_PARENT_COUNT(dag); } else { rtmetric = 0; beacon_interval = 0; num_neighbors = 0; } collect_view_construct_message(&msg.msg, &parent, parent_etx, rtmetric, num_neighbors, beacon_interval); memset(msg.data, 12, sizeof(msg.data)); // PRINTF("The size of the packet is: %d\n", sizeof(msg)); PRINTF("DATA send NO %d to %d\n", seqno, sink_ipaddr.u8[sizeof(sink_ipaddr.u8) - 1]); // printf("Send a message: %u \n", seqno); uip_udp_packet_sendto(sender_conn, &msg, sizeof(msg), &sink_ipaddr, UIP_HTONS(UDP_SINK_PORT)); // PRINTF("The size of the packet is: %u\n", sizeof(msg)); }
/* * this function produce a string @buf in form of json data * example of buf: * * {'clk':%d,'syn':%d,'cpu':%d,'lpm':%d,'tras':%d,'lst':%d, * 'parent':%s,'etx':%d,'rt':%d,\'nbr':%d,'bea_itv':%d,'sen':%d} * */ void collectd_prepare_data() { uint16_t parent_etx; uint16_t rtmetric; uint16_t num_neighbors; uint16_t beacon_interval; rpl_parent_t *preferred_parent; uip_lladdr_t lladdr_parent; rpl_dag_t *dag; //copied from collect-view.c static unsigned long last_cpu, last_lpm, last_transmit, last_listen; unsigned long cpu, lpm, transmit, listen; u16_t clock, timesynch_time; clock = clock_time(); #if TIMESYNCH_CONF_ENABLED timesynch_time = timesynch_time(); #else /* TIMESYNCH_CONF_ENABLED */ timesynch_time = 0; #endif /* TIMESYNCH_CONF_ENABLED */ /*save to buf */ blen = 0; ADD("{'clk':%u,'syn':%u,", clock, timesynch_time); energest_flush(); cpu = energest_type_time(ENERGEST_TYPE_CPU) - last_cpu; lpm = energest_type_time(ENERGEST_TYPE_LPM) - last_lpm; transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT) - last_transmit; listen = energest_type_time(ENERGEST_TYPE_LISTEN) - last_listen; /* Make sure that the values are within 16 bits. If they are larger, we scale them down to fit into 16 bits. */ //TODO: why do i need to scale down to 16 bit? while(cpu >= 65536ul || lpm >= 65536ul || transmit >= 65536ul || listen >= 65536ul) { cpu /= 2; lpm /= 2; transmit /= 2; listen /= 2; } /* prepare for next calling */ last_cpu = energest_type_time(ENERGEST_TYPE_CPU); last_lpm = energest_type_time(ENERGEST_TYPE_LPM); last_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT); last_listen = energest_type_time(ENERGEST_TYPE_LISTEN); /* save to buf */ ADD("'cpu':%u,'lpm':%u,'tras':%u,'lst':%u,", (u16_t)cpu, (u16_t)lpm, (u16_t)transmit, (u16_t)listen); /* initial value, if there's not any dag */ parent_etx = 0; rtmetric = 0; beacon_interval = 0; num_neighbors = 0; /* Let's suppose we have only one instance */ dag = rpl_get_any_dag(); 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) { //PRINT6ADDR(&nbr->lladdr); memcpy(&lladdr_parent, &nbr->lladdr, sizeof(uip_lladdr_t)); parent_etx = neighbor_info_get_metric((rimeaddr_t *) &nbr->lladdr) / 2; } } rtmetric = dag->rank; beacon_interval = (uint16_t) ((2L << dag->instance->dio_intcurrent) / 1000); num_neighbors = RPL_PARENT_COUNT(dag); } char lladdr_parent_str[30]; u8_t lladdr_str_len; lladdr_str_len = lladdr_print(&lladdr_parent, lladdr_parent_str, 30); ADD("'parent':'%s',", lladdr_parent_str); ADD("'etx':%u,'rt':%u,'nbr':%u,'bea_itv':%u,", parent_etx, rtmetric, num_neighbors, beacon_interval); //collectd_arch_read_sensors(); #if CONTIKI_TARGET_SKY u8_t sensors[MAX_SENSORS_BUF_SIZE]; //PRINTF("oh,sky\n"); if (collect_view_arch_read_sensors(sensors, MAX_SENSORS_BUF_SIZE) >= 0) { ADD("'sen':'%s',", sensors); } #endif ADD("}"); }
/*---------------------------------------------------------------------------*/ void collect_common_send(void) { /*For send regular packets*/ static uint8_t seqno; struct { /*Changed*/ uint8_t instance_id; //RPL_SECOND_INSTANCE uint8_t for_alignment; uint8_t seqno; uint8_t for_alignment1; 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_instance_t *instance; //changed 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.instance_id = RPL_SECOND_INSTANCE ; msg.seqno = seqno; rimeaddr_copy(&parent, &rimeaddr_null); parent_etx = 0; /* Let's suppose we have only one instance */ /*Changed*/ instance = rpl_get_instance(RPL_DEFAULT_INSTANCE); dag = instance->current_dag; if(dag != NULL) { preferred_parent = dag->preferred_parent; if(preferred_parent != NULL) { uip_ds6_nbr_t *nbr; nbr = uip_ds6_nbr_lookup(rpl_get_parent_ipaddr(preferred_parent)); 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 = rpl_get_parent_rank((rimeaddr_t *) uip_ds6_nbr_get_ll(nbr)) / 2; } } rtmetric = dag->rank; beacon_interval = (uint16_t) ((2L << dag->instance->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); printf ("msg send, %d, %d\n", msg.instance_id, msg.seqno); uip_udp_packet_sendto(client_conn, &msg, sizeof(msg), &server_ipaddr, UIP_HTONS(UDP_SERVER_PORT)); }