/* Greedy geographic routing => computing the nexthop */ struct xy_neighbor *xy_next_hop(call_t *c, position_t *position) { struct nodedata *nodedata = get_node_private_data(c); struct xy_neighbor *neighbor = NULL, *n_hop = NULL; double dist = distance(get_node_position(c->node), position); double d = dist; uint64_t clock = get_time(); /* parse neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct xy_neighbor *) das_traverse(nodedata->neighbors)) != NULL) { #ifdef CHECK_ACTIVE_NODE if ( !is_node_alive(neighbor->id) || ((nodedata->h_timeout > 0) && (clock - neighbor->time) >= nodedata->h_timeout) ) { continue; } #else if ((nodedata->h_timeout > 0) && (clock - neighbor->time) >= nodedata->h_timeout ) { continue; } #endif /* choose next hop */ if ((d = distance(&(neighbor->position), position)) < dist) { dist = d; n_hop = neighbor; } } return n_hop; }
/* ************************************************** */ void rx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); array_t *up = get_entity_bindings_up(c); int i = up->size; /* radio sleep */ if (nodedata->sleep) { packet_dealloc(packet); return; } /* half-duplex */ if (nodedata->tx_busy != -1) { packet_dealloc(packet); return; } /* handle carrier sense */ if (nodedata->rx_busy == packet->id) { nodedata->rx_busy = -1; nodedata->rxdBm = MIN_DBM; /* log rx */ PRINT_REPLAY("radio-rx1 %"PRId64" %d\n", get_time(), c->node); /* consume energy */ battery_consume_rx(c, packet->duration); } else { packet_dealloc(packet); return; } /* check wether the reception has killed us */ if (!is_node_alive(c->node)) { packet_dealloc(packet); return; } /* drop packet depending on the FER */ if (get_random_double() < packet->PER) { packet_dealloc(packet); return; } /* forward to upper layers */ while (i--) { call_t c_up = {up->elts[i], c->node, c->entity}; packet_t *packet_up; if (i > 0) { packet_up = packet_clone(packet); } else { packet_up = packet; } RX(&c_up, packet_up); } return; }
void do_event(event_t *event) { if (ws_count) /* WORLDSENS MODE? */ worldsens_rdv_update(event); switch (event->priority) { case PRIORITY_BIRTH: node_birth(event->u.nodeid); break; case PRIORITY_MOBILITY: mobility_event(g_clock); break; case PRIORITY_RX_BEGIN: medium_cs(event->u.rx.packet, &(event->u.rx.call)); worldsens_rm_duplicate_pk(event); break; case PRIORITY_RX_END: medium_rx(event->u.rx.packet, &(event->u.rx.call)); break; case PRIORITY_TX_END: medium_tx_end(event->u.rx.packet, &(event->u.rx.call)); break; case PRIORITY_CALLBACK: if ((event->u.cb.call.node != -1) && (!is_node_alive(event->u.cb.call.node))) { break; } event->u.cb.callback(&(event->u.cb.call), event->u.cb.arg); break; case PRIORITY_MILESTONE: scheduler_stats(); if (ws_count) { /* WORLDSENS MODE? */ scheduler_add_milestone(g_clock + WORLDSENS_SYNC_PERIOD); } else { scheduler_add_milestone(g_clock + SCHEDULER_MILESTONE_PERIOD); } break; case PRIORITY_QUIT: worldsens_quit(); exception = EXCEPTION_QUIT; break; default: break; } mem_fs_dealloc(mem_event, event); dbg.c_events--; dbg.d_events++; }
int xy_is_nearest(call_t *c, position_t *sink_position) { struct nodedata *nodedata = get_node_private_data(c); struct xy_neighbor *neighbor = NULL; double dist = distance(get_node_position(c->node), sink_position); das_init_traverse(nodedata->neighbors); while ((neighbor = (struct xy_neighbor *) das_traverse(nodedata->neighbors)) != NULL) { if ((distance(&(neighbor->position), sink_position) < dist) && (is_node_alive(neighbor->id))) { return 0; } } return 1; }
/* ************************************************** */ void rx(call_t *c, packet_t *packet) { if(!is_node_alive(c->node)) return; struct nodedata *nodedata = get_node_private_data(c); struct packet_general *packetType= (struct packet_general *)(packet->data + nodedata->overhead); /*******************************HELLO 1 voisinage***************************/ switch(packetType->type) { case HELLO: { rx_hello(c,packet); break; } case LMST: { packet_lmst *lmstPacket = (packet_lmst *) (packet->data + nodedata->overhead); if(list_recherche(lmstPacket->MST,c->node)) rx_lmst(c,packet); break; }//*/ case LBOP: { packet_PROTOCOLE *data = (packet_PROTOCOLE *) (packet->data + nodedata->overhead); if(list_recherche(data->destinations,c->node)) { SHOW_GRAPH("G: %d %d\n",data->redirected_by,c->node); if(list_PACKET_recherche_tout(nodedata->paquets,data->src,data->seq)==0) PROTOCOLE_reception(c,packet); } break; } default: printf("J'ai recu un packet de type %d NON reconnu\n", packetType->type); break; } }
void tx_end(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); /* consume energy */ battery_consume_tx(c, packet->duration, nodedata->power); /* check wether the reception has killed us */ if (!is_node_alive(c->node)) { return; } /* log tx */ if (nodedata->tx_busy == packet->id) { PRINT_REPLAY("radio-tx1 %"PRId64" %d\n", get_time(), c->node); nodedata->tx_busy = -1; } return; }
/* Get the best next hop for a specific destination */ struct neighbor* get_nexthop(call_t *c, nodeid_t dst) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL, *n_hop = NULL; double dist = distance(get_node_position(c->node), get_node_position(dst)); double d = dist; if (nodedata->curr_dst != dst || (nodedata->curr_nexthop != NULL && !is_node_alive(nodedata->curr_nexthop->id))) { /* If the destination is different from the last one, * or if the current next hop is dead, reinit the * random counters (to force the selection of a * new next_hop) */ nodedata->random_counter = nodedata->random_nexthop; } if (nodedata->random_nexthop == 0) { /* We keep the current next hop if * - next hop is not randomized * - the next hop is is still alive * - the destination is the same */ if (nodedata->curr_nexthop != NULL && nodedata->curr_dst == dst && is_node_alive(nodedata->curr_nexthop->id)) { return nodedata->curr_nexthop; } /* Parse neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { /* Choose next hop (the one the nearest from the final dst) * and verify if it is still alive */ if ((d = distance(&(neighbor->position), get_node_position(dst))) < dist && is_node_alive(neighbor->id)) { dist = d; n_hop = neighbor; } } } else if (nodedata->random_counter == nodedata->random_nexthop) { void *next_hops = das_create(); int nh = 0; double nexthop_dst = 0; /* Random geographic routing : we choose randomly among * the neighbors that are nearer from the destination * than the current node. */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { /* If the neighbor happens to be the final destination, * then we just choose it as the next hop */ if (neighbor->id == dst) { n_hop = neighbor; goto out; } /* Store the neighbors that are nearer from the destination * and that are still alive */ nexthop_dst = distance(&(neighbor->position), get_node_position(dst)); if (nexthop_dst < dist && is_node_alive(neighbor->id)) { das_insert(next_hops, (void *) neighbor); } } /* Choose next hop randomly among the list */ nh = das_getsize(next_hops); if (nh > 0) { int rnd = get_random_integer_range(1, nh); while (rnd--) { neighbor = das_pop(next_hops); } n_hop = neighbor; } das_destroy(next_hops); } else /* nodedata->random_counter != nodedata->random_nexthop */ { /* Keep the current next hop */ n_hop = nodedata->curr_nexthop; } out: nodedata->random_counter--; if (nodedata->random_counter <= 0) { nodedata->random_counter = nodedata->random_nexthop; } /* Save the current next hop and destination */ nodedata->curr_nexthop = n_hop; nodedata->curr_dst = dst; return n_hop; }
/* ************************************************** */ void rx(call_t *c, packet_t *packet) { if(!is_node_alive(c->node)) return; struct nodedata *nodedata = get_node_private_data(c); struct protocoleData *entitydata = get_entity_private_data(c); array_t *up = get_entity_bindings_up(c); packet_PROTOCOLE *data = (packet_PROTOCOLE *) (packet->data + nodedata->overhead); switch(data->type) { case HELLO: { //printf("BIP - Paquet de type HELLO recu par %d depuis %d\n", c->node, data->src); rx_hello(c,packet); break; } case HELLO2: { //printf("BIP - Paquet de type HELLO2 recu par %d depuis %d\n", c->node, data->src); rx_two_hop(c,packet); break; } case APP: { //printf("DLBIP - Paquet de type APP recu par %d depuis %d ; source : %d et destine a %d\n", c->node, data->pred, data->src, data->dst); nodedata->energiesRem[data->pred] = data->energyRem; if(nodedata->lastIDs[data->src] == data->id || data->src == c->node) { break; } else { nodedata->lastIDs[data->src] = data->id; } if(data->dst == BROADCAST_ADDR) { SHOW_GRAPH("G: %d %d\n",data->pred,c->node); double cout; listeNodes* trans = data->askedToRedirect; listeNodes* trans2 = data->needsToBeCovered; while(trans != 0) { position_t p1, p2; p1.x = trans->values.x; p1.y = trans->values.y; p1.z = trans->values.z; p2.x = trans2->values.x; p2.y = trans2->values.y; p2.z = trans2->values.z; cout = getCoutFromDistance(distance(&p1, &p2), entitydata->alpha, entitydata->c); //printf("cout estime de (%d,%d)\n", ); nodedata->energiesRem[trans->values.node] -= cout; trans = trans->suiv; trans2 = trans2->suiv; } //SHOW_GRAPH("G: %d %d\n",data->pred,c->node); // faire remonter le paquet a la couche application call_t c_up = {up->elts[0], c->node, c->entity}; RX(&c_up, packet_clone(packet)); if(listeNodes_recherche(data->askedToRedirect, c->node)) // si le paquet contient des instructions pour ce noeud { forward(c, packet); } } else { printf("Message non broadcaste pas traite ... TODO\n"); } //packet_dealloc(packet); break; } default: printf("%d a recu un packet de type %d NON reconnu\n", c->node, data->type); break; } /*printf("estimation de l'energie restante depuis %d :\n", c->node); int i; for(i = 0 ; i < get_node_count() ; i++) { printf("\t%d : %.1lf\n", i, nodedata->energiesRem[i]); }*/ }