/* ************************************************** */ void medium_compute_rxdBm(packet_t *packet, call_t *c) { call_t c0 = {packet->antenna, packet->node, -1}; double rxdBm = packet->txdBm; position_t *pos_tx = get_node_position(packet->node); position_t *pos_rx = get_node_position(c->node); /* antenna tx white noise */ rxdBm += antenna_get_loss(&c0); /* antenna tx gain (TODO: angle au moment de l'?mission) */ rxdBm += antenna_gain_tx(&c0, pos_rx); /* propagation */ c0.entity = propagation_entity->id; if (c->node != packet->node) { rxdBm = propagation_entity->methods->propagation.propagation(&c0, packet, packet->node, c->node, rxdBm); } /* TODO: add shadowing & fading only if > MIN_DBM */ /* antenna rx gain */ rxdBm += antenna_gain_rx(c, pos_tx); /* antenna rx white noise */ rxdBm += antenna_get_loss(c); /* rx power */ packet->rxdBm = rxdBm; packet->rxmW = dBm2mW(rxdBm); }
/* Find all the neighbors (i.e. nodes in range) of the current node */ int find_neighbors(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL; nodeid_t i; double dist = 0; int nb_neigh = 0; /* Parse all the nodes in the simulation: and find the ones * that are in range of that node */ for(i = 0; i < get_node_count(); i++) { /* Do not include myself */ if (i == c->node) { continue; } dist = distance(get_node_position(c->node), get_node_position(i)); if (dist <= nodedata->range) { /* Add the node in the list of neighbors */ neighbor = (struct neighbor *) malloc(sizeof(struct neighbor)); neighbor->id = i; neighbor->position.x = get_node_position(i)->x; neighbor->position.y = get_node_position(i)->y; neighbor->position.z = get_node_position(i)->z; neighbor->time = get_time(); //PRINT_ROUTING("Node %d is added to neighbor list of node %d\n", // neighbor->id, c->node); das_insert(nodedata->neighbors, (void *) neighbor); nb_neigh++; } } return nb_neigh; }
/* ************************************************** */ int set_header(call_t *c, packet_t *packet, destination_t *dst) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *n_hop = get_nexthop(c, &(dst->position)); destination_t destination; struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; /* if no route, return -1 */ if (dst->id != BROADCAST_ADDR && n_hop == NULL) { nodedata->data_noroute++; return -1; } else if (dst->id == BROADCAST_ADDR) { n_hop->id = BROADCAST_ADDR; } /* set routing header */ header->dst = dst->id; header->dst_pos.x = dst->position.x; header->dst_pos.y = dst->position.y; header->dst_pos.z = dst->position.z; header->src = c->node; header->src_pos.x = get_node_position(c->node)->x; header->src_pos.y = get_node_position(c->node)->y; header->src_pos.z = get_node_position(c->node)->z; header->type = DATA_PACKET; header->hop = nodedata->hop; /* Set mac header */ destination.id = n_hop->id; destination.position.x = -1; destination.position.y = -1; destination.position.z = -1; return SET_HEADER(&c0, packet, &destination); }
/* ************************************************** */ int setnode(call_t *c, void *params) { int id, found = 0; double x, y, z; struct entitydata *entitydata = get_entity_private_data(c); char str[128]; /* position at the beginning */ fseek(entitydata->file, 0L, SEEK_SET); while (fgets(str, 128, entitydata->file) != NULL) { sscanf(str, "%d %lf %lf %lf\n", &id, &x, &y, &z); if (id == c->node) { found = 1; get_node_position(c->node)->x = x; get_node_position(c->node)->y = y; get_node_position(c->node)->z = z; break; } } if (found == 0) { fprintf(stderr, "filestatic: node %d position not found (setnode())\n", c->node); return -1; } return 0; }
/* *********************************************** */ int set_header( call_t *c , packet_t * packet , destination_t * dst ) { struct nodedata *nodedata = get_node_private_data(c); struct protocoleData *entitydata =get_entity_private_data(c); packet_PROTOCOLE *data = (packet_PROTOCOLE *) (packet->data + nodedata->overhead); //augmenter le nbr d'evenement nodedata->nbr_evenement++; if(entitydata->debug) DBG("RBOP - %d SET HEADER \n",c->node); //Fixé le rayon if(nodedata->range<0) { listeNodes *tmp=nodedata->oneHopNeighbourhood; position_t pos1 = *get_node_position(c->node); double distMax = 0; while(tmp) { if(list_recherche(nodedata->RNG,tmp->values.node)) { position_t pos2= {tmp->values.x,tmp->values.y,tmp->values.z}; double dist=distance(&pos1,&pos2); if(distMax<dist) distMax=dist; } tmp=tmp->suiv; } set_range_Tr(c,distMax); nodedata->range=get_range_Tr(c); if(entitydata->debug) DBG("RBOP - %d FIXE RANGE TO %.2lf \n",c->node,get_range_Tr(c)); } //remplissage de data data->type=RBOP; data->src=c->node; data->src_pos=*get_node_position(c->node); data->seq=nodedata->nbr_evenement; data->redirected_by=c->node; data->destinations=Nullptr(list); list_copy(&data->destinations,nodedata->RNG); list_PACKET_insert_tout(&nodedata->paquets,data->src,data->seq,data->redirected_by); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}}; return SET_HEADER(&c0, packet, &destination); }
/* ************************************************** */ int bootstrap(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); PRINT_REPLAY("mobility %"PRId64" %d %lf %lf %lf\n", get_time(), c->node, get_node_position(c->node)->x, get_node_position(c->node)->y, get_node_position(c->node)->z); nodedata->lupdate = get_time(); nodedata->nupdate = get_time() + nodedata->pausetime; return 0; }
int log_energymap(call_t *c) { struct entitydata *entitydata = get_entity_private_data(c); int i = get_node_count(); FILE *file = NULL; char file_map[100]; double time = get_time() * 0.000001; /* create file */ sprintf(file_map, "%s/%s.%.0lf.data", entitydata->directory, entitydata->map_prefix, time); if ((file = fopen(file_map, "w+")) == NULL) { fprintf(stderr, "My monitor: can not open file %s in monitor_event()\n", file_map); return -1; } /* log energy map */ while (i--) { call_t c0 = {-1, i, -1}; position_t *position = get_node_position(c0.node); fprintf(file, "%d %lf %lf %lf %lf\n", c0.node, position->x, position->y, position->z, battery_status(&c0)); } /* log virtual nodes for the 4 area corners */ fprintf(file, "%d %lf %lf %lf %lf\n", -1, 0.0, 0.0, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, get_topology_area()->x, 0.0, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, 0.0, get_topology_area()->y, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, get_topology_area()->x, get_topology_area()->y, 0.0, 1.0); fclose(file); return 0; }
/* 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; }
double setRangeToFarestNeighbour(call_t *c, graphe* g, arbre* bipTree) { struct nodedata *nodedata = get_node_private_data(c); struct protocoleData *entitydata = get_entity_private_data(c); // calcul de la distance entre ce noeud et son voisin 1-hop (dans l'arbre de BIP) le plus eloigne list *fils = 0; double distMax = 0, dist; position_t pos; arbre_get_fils(&fils, bipTree, c->node); while(fils != 0) { pos = listeNodes_getPos(nodedata->oneHopNeighbourhood, fils->val); dist = distance(get_node_position(c->node), &pos); if(dist > distMax) { distMax = dist; } fils = fils->suiv; } // set le range du module propagation a la valeur desiree set_range_Tr(c, distMax); //printf("rayon d'emission de %d fixe a %lf\n", c->node, macdata->range); return distMax; }
/* ************************************************** */ double propagation(call_t *c, packet_t *packet, nodeid_t src, nodeid_t dst, double rxdBm) { struct entitydata *entitydata = get_entity_private_data(c); double dist = distance(get_node_position(src), get_node_position(dst)); /* * Pr_dBm(d) = Pr_dBm(d0) - 10 * beta * log10(d/d0) * * Note: rxdBm = [Pt + Gt + Gr]_dBm, and L = 1 * * cf p102-104 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996. * */ if (dist <= 1) { return entitydata->Pr0 + rxdBm; } else { return entitydata->Pr0 + rxdBm - 10.0 * entitydata->pathloss * log10(dist); } }
//RECEPTION et REPONDRE AU PACKET HELLO int rx_one_hop(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); //RECEPTION DE PACKET HELLO struct packet_hello *hello = (struct packet_hello *) (packet->data + nodedata->overhead[0]); DEBUG; /*printf("NOde %d a recu un HELLO de %d (%lf %lf %lf) at %lf\n",c->node, hello->source, get_node_position(hello->source)->x,get_node_position(hello->source)->y,get_node_position(hello->source)->z, get_time_now_second());//*/ //l'ajoute de voisin if(!list_recherche(nodedata->N1,hello->source)) list_insert(&nodedata->N1,hello->source); //REPONSE DE PAKET HELLO //recuperer le support de communication MAC entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node}; //destination de paquet destination_t destination = {hello->source, {get_node_position(hello->source)->x,get_node_position(hello->source)->y,get_node_position(hello->source)->z}}; //creation de paquet et initialisation de son data packet_t *rpacket = packet_alloc(c, nodedata->overhead[0] + sizeof(struct packet_hello)); struct packet_hello *rhello = (struct packet_hello *) (rpacket->data + nodedata->overhead[0]); //initilailser les données rhello->type = REP_HELLO; rhello->source = c->node; if (SET_HEADER(&c0, rpacket, &destination) == -1) { packet_dealloc(rpacket); return -1; } DEBUG; /*printf("Node %d (%lf %lf %lf) repond a %d packet hello, at %lf\n", c->node, //id de Noeud de noeud encours get_node_position(c->node)->x,get_node_position(c->node)->y,get_node_position(c->node)->z, //la postion x, y,z de Noeud hello->source, //id de noued de destination get_time_now_second()); //*/ //l'instant d'envoi. //L'envoi TX(&c0,rpacket); //liberer le packet packet_dealloc(packet); //tous c'est bien passé return 1; }
/* ************************************************** */ double compute_freespace(struct entitydata *entitydata, nodeid_t src, nodeid_t dst, double rxdBm) { /* * Pt * Gt * Gr * lambda^2 * Pr(d) = ------------------------- * (4 * pi * d)^2 * L * * Note: rxdBm = [Pt + Gt + Gr]_dBm, and L = 1 * * cf p71 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996. * */ double dist = distance(get_node_position(src), get_node_position(dst)); if (dist == 0) { return (rxdBm); } else { return (rxdBm + 2 * mW2dBm(entitydata->factor / dist)); } }
/* ************************************************** */ double compute_logdistance_pathloss(struct entitydata *entitydata, nodeid_t src, nodeid_t dst, double rxdBm) { /* * Pr_dBm(d) = Pr_dBm(d0) - 10 * beta * log10(d/d0) * * Note: rxdBm = [Pt + Gt + Gr]_dBm, and L = 1 * * cf p102-104 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996. * */ double dist; if (rxdBm != entitydata->last_rxdBm) { entitydata->Pr0 = freespace(entitydata, entitydata->dist0, dBm2mW(rxdBm)); entitydata->last_rxdBm = rxdBm; } dist = distance(get_node_position(src), get_node_position(dst)); return mW2dBm(entitydata->Pr0) - 10.0 * entitydata->pathloss * log10(dist/entitydata->dist0); }
/* ************************************************** */ void xy_stats(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); position_t *position = get_node_position(c->node); if (nodedata->type == INLINE_NODE) { printf("INLINE node %d (%lf,%lf,%lf) Group_id=%d Neighbors=%d\n", c->node, position->x, position->y, position->z, nodedata->group_id, das_getsize(nodedata->neighbors)); } else { printf("SENSOR node %d (%lf,%lf,%lf) Neighbors=%d\n", c->node, position->x, position->y, position->z, das_getsize(nodedata->neighbors)); } }
/* ************************************************** */ void update_position(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); while (nodedata->lupdate < get_time()) { if (nodedata->nupdate <= get_time()) { nodedata->lupdate = nodedata->nupdate; nodedata->nupdate += nodedata->pausetime; get_node_position(c->node)->x = get_random_x_position(); get_node_position(c->node)->y = get_random_y_position(); get_node_position(c->node)->z = get_random_z_position(); PRINT_REPLAY("mobility %"PRId64" %d %lf %lf %lf\n", nodedata->lupdate, c->node, get_node_position(c->node)->x, get_node_position(c->node)->y, get_node_position(c->node)->z); } else { nodedata->lupdate = get_time(); break; } } return; }
//INITIALISATION DE NOEUD DE FICHIER XML int setnode(call_t *c, void *params) { struct nodedata *nodedata = malloc(sizeof(struct nodedata)); nodedata->overhead = -1; nodedata->range = -1; //les packets nodedata->paquets = Nullptr(list_PACKET); //les voisinages nodedata->oneHopNeighbourhood = Nullptr(listeNodes); nodedata->RNG = Nullptr(list); //STATS nodedata->nbr_evenement = 0; set_node_private_data(c, nodedata); SHOW_GRAPH("N: %d %lf %f\n",c->node,get_node_position(c->node)->x,get_node_position(c->node)->y); return 0; }
/* ************************************************** */ int setnode(call_t *c, void *params) { struct nodedata *nodedata = malloc(sizeof(struct nodedata)); param_t *param; uint64_t min_pausetime, max_pausetime; /* default values */ get_node_position(c->node)->x = get_random_x_position(); get_node_position(c->node)->y = get_random_y_position(); get_node_position(c->node)->z = get_random_z_position(); nodedata->pausetime = 2000000000; min_pausetime = 0; max_pausetime = 0; /* get parameters */ das_init_traverse(params); while ((param = (param_t *) das_traverse(params)) != NULL) { if (!strcmp(param->key, "x")) { if (get_param_x_position(param->value, &(get_node_position(c->node)->x))) { goto error; } } if (!strcmp(param->key, "y")) { if (get_param_y_position(param->value, &(get_node_position(c->node)->y))) { goto error; } } if (!strcmp(param->key, "z")) { if (get_param_z_position(param->value, &(get_node_position(c->node)->z))) { goto error; } } if (!strcmp(param->key, "pausetime")) { if (get_param_time(param->value, &(nodedata->pausetime))) { goto error; } } if (!strcmp(param->key, "min-pausetime")) { if (get_param_time(param->value, &min_pausetime)) { goto error; } } if (!strcmp(param->key, "max-pausetime")) { if (get_param_time(param->value, &max_pausetime)) { goto error; } } } if (min_pausetime < max_pausetime ) { nodedata->pausetime = get_random_time_range(min_pausetime, max_pausetime); } set_node_private_data(c, nodedata); return 0; error: free(nodedata); return -1; }
/* ************************************************** */ double propagation(call_t *c, packet_t *packet, nodeid_t src, nodeid_t dst, double rxdBm) { struct entitydata *entitydata = get_entity_private_data(c); double dist, powerloss_dbm; /* * Pr_dBm(d) = Pr_dBm(d0) - 10 * beta * log10(d/d0) + X * * Note: rxdBm = [Pt + Gt + Gr]_dBm, L = 1, and X a normal distributed RV (in dBm) * * cf p104-105 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996. * */ if (rxdBm != entitydata->last_rxdBm) { entitydata->Pr0 = freespace(c, packet, entitydata->dist0, dBm2mW(rxdBm)); entitydata->last_rxdBm = rxdBm; } dist = distance(get_node_position(src), get_node_position(dst)); powerloss_dbm = -10.0 * entitydata->pathloss * log10(dist/entitydata->dist0) + normal(0.0, entitydata->deviation); return mW2dBm(entitydata->Pr0) + powerloss_dbm; }
/* ************************************************** */ double compute_tworayground(struct entitydata *entitydata, nodeid_t src, nodeid_t dst, double rxdBm) { /* * Cross over distance: * * 4 * pi * ht * hr * dc = ------------------ * lambda * Pt * Gt * Gr * (ht * hr)^2 * Case 1: d >= dc => Pr(d) = ----------------------------- * d^4 * L * * Pt * Gt * Gr * lambda^2 * Case 2: d < dc => Pr(d) = ------------------------- * (4 * pi * d)^2 * L * * Note: rxmW = Pt * Gt * Gr, and L = 1 * * cf p89 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996. * */ double dist; dist = distance(get_node_position(src), get_node_position(dst)); if (dist == 0) { return rxdBm; } else if (dist < entitydata->crossover_distance) { /* uses friis formula for distance < crossover distance or if (ht == hr == 0) */ return (rxdBm + 2 * mW2dBm(entitydata->factor / dist)); } else { /* else two-ray ground model is more accurate for distance > crossover distance */ return (rxdBm + mW2dBm(entitydata->ht * entitydata->ht * entitydata->hr * entitydata->hr / pow(dist, 4.0))); } }
// initialisation des noeuds a partir du fichier xml int setnode(call_t *c, void *params) { struct nodedata *nodedata = malloc(sizeof(struct nodedata)); struct protocoleData *entitydata = malloc(sizeof(struct protocoleData)); nodedata->overhead = -1; nodedata->oneHopNeighbourhood = 0; nodedata->twoHopNeighbourhood = 0; nodedata->g2hop = malloc(sizeof(graphe)); initGraphe(nodedata->g2hop, c->node); nodedata->BIP_tree = 0; nodedata->nbr_evenement = 0; //STATS nodedata->lastIDs = malloc(get_node_count()*sizeof(int)); nodedata->energiesRem = malloc(get_node_count()*sizeof(double)); set_node_private_data(c, nodedata); SHOW_GRAPH("N: %d %lf %f\n",c->node,get_node_position(c->node)->x,get_node_position(c->node)->y); // printf("Node %d at ( %.1lf ; %.1lf ; %.1lf )\n", c->node,get_node_position(c->node)->x,get_node_position(c->node)->y,get_node_position(c->node)->z); return 0; }
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; }
int advert_callback(call_t *c, void *args) { struct nodedata *nodedata = get_node_private_data(c); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}}; packet_t *packet = packet_create(c, nodedata->overhead + sizeof(struct routing_header), -1); struct routing_header *header = (struct routing_header*) (packet->data + nodedata->overhead); /* set mac header */ if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return -1; } /* set routing header */ header->dst = BROADCAST_ADDR; header->dst_pos.x = -1; header->dst_pos.y = -1; header->dst_pos.z = -1; header->src = c->node; header->src_pos.x = get_node_position(c->node)->x; header->src_pos.y = get_node_position(c->node)->y; header->src_pos.z = get_node_position(c->node)->z; header->type = HELLO_PACKET; header->hop = 1; /* send hello */ TX(&c0, packet); nodedata->hello_tx++; /* check neighbors timeout */ das_selective_delete(nodedata->neighbors, neighbor_timeout, (void *) c); /* schedules hello */ scheduler_add_callback(get_time() + nodedata->period, c, advert_callback, NULL); return 0; }
/* Periodic exchange of hello packets */ int hello_callback(call_t *c, void *args) { struct entitydata *entitydata = get_entity_private_data(c); struct nodedata *nodedata = get_node_private_data(c); entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}}; packet_t *packet = packet_create(c, nodedata->overhead + sizeof(struct xy_hello_p), -1); struct xy_hello_p *hello = (struct xy_hello_p *) (packet->data + nodedata->overhead); position_t *pos = get_node_position(c->node); /* set mac header */ if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return -1; } /* set header */ hello->type = XY_HELLO_TYPE; hello->src = c->node; hello->position.x = pos->x; hello->position.y = pos->y; hello->position.z = pos->z; TX(&c0, packet); entitydata->TX_hello++; /* check neighbors timeout */ if (nodedata->h_timeout > 0) { das_selective_delete(nodedata->neighbors, neighbor_timeout, (void *) c); } /* schedules hello */ if (nodedata->h_nbr > 0) { nodedata->h_nbr --; } if (nodedata->h_nbr == -1 || nodedata->h_nbr > 0) { scheduler_add_callback(get_time() + nodedata->h_period, c, hello_callback, NULL); } return 0; }
/* ************************************************** */ struct neighbor* get_nexthop(call_t *c, position_t *dst) { struct nodedata *nodedata = get_node_private_data(c); struct neighbor *neighbor = NULL, *n_hop = NULL; uint64_t clock = get_time(); double dist = distance(get_node_position(c->node), dst); double d = dist; /* parse neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct neighbor *) das_traverse(nodedata->neighbors)) != NULL) { if ((nodedata->timeout > 0) && (clock - neighbor->time) >= nodedata->timeout ) { continue; } /* choose next hop */ if ((d = distance(&(neighbor->position), dst)) < dist) { dist = d; n_hop = neighbor; } } return n_hop; }
/* received a request from a sensor */ void rx_xy_request(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct entitydata *entitydata = get_entity_private_data(c); struct xy_request_p *request = (struct xy_request_p *) (packet->data + nodedata->overhead); position_t rdv_position; struct xy_neighbor *n_hop; entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; /* are we the next hop */ if (request->n_hop != c->node) { packet_dealloc(packet); return; } /* do we have the requested data (or some more recent data) ? */ if (request->d_seq <= nodedata->d_seq[request->metadata]) { packet_t *packet0; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; n_hop = xy_next_hop(c, &(request->position)); if (n_hop == NULL) { struct sensor_data_p *data; packet0 = packet_create(c, nodedata->overhead + sizeof(struct sensor_data_p), -1); data = (struct sensor_data_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } data->type = SENSOR_DATA_TYPE; data->metadata = request->metadata; data->sink = request->sink; data->r_seq = request->r_seq; data->source = nodedata->d_source[request->metadata]; data->d_seq = nodedata->d_seq[request->metadata]; data->d_value = nodedata->d_value[request->metadata]; data->delay = nodedata->d_time[request->metadata]; data->hop = nodedata->d_hop[request->metadata]; #ifdef LOG_APPLICATION_REQUEST printf("[XY] Node %d (%lf,%lf) : broadcasting DATA REPLY (%d,%d,%d) to sink %d (%lf,%lf)\n", c->node, (get_node_position(c->node))->x, (get_node_position(c->node))->y, nodedata->d_source[request->metadata], request->metadata, nodedata->d_seq[request->metadata], request->sink, (get_node_position(request->sink))->x, (get_node_position(request->sink))->y); #endif TX(&c0, packet0); entitydata->TX_sensor_data++; packet_dealloc(packet); return; } else { struct xy_response_p *response; /* reply */ packet0 = packet_create(c, nodedata->overhead + sizeof(struct xy_response_p), -1); response = (struct xy_response_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } response->type = XY_RESPONSE_TYPE; response->n_hop = n_hop->id; response->metadata = request->metadata; response->sink = request->sink; response->r_seq = request->r_seq; response->source = nodedata->d_source[request->metadata]; response->d_seq = nodedata->d_seq[request->metadata]; response->d_value = nodedata->d_value[request->metadata]; response->time = nodedata->d_time[request->metadata]; response->hop = nodedata->d_hop[request->metadata]; response->position.x = request->position.x; response->position.y = request->position.y; response->position.z = request->position.z; TX(&c0, packet0); entitydata->TX_response++; packet_dealloc(packet); return; } } /* forwards the query towards the specified direction */ else { switch(request->direction){ case DIRECTION_EAST: rdv_position.x = (get_topology_area())->x; rdv_position.y = (get_node_position(c->node))->y; rdv_position.z = 0.0; break; case DIRECTION_WEST: rdv_position.x = 0.0; rdv_position.y = (get_node_position(c->node))->y; rdv_position.z = 0.0; break; default: #ifdef LOG_APPLICATION_REQUEST_ROUTING printf("[XY] Node %d (%lf,%lf) received a DATA with incorrect forwarding direction (%c) !\n",c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,request->direction); #endif packet_dealloc(packet); return; } /* get next hop */ n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { #ifdef LOG_APPLICATION_REQUEST_ROUTING printf("[XY] node %d (%lf,%lf) : forwarding request towards direction %c via node %d \n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,request->direction,n_hop->id); #endif destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; /* forward data */ if (SET_HEADER(&c0, packet, &dst) == -1) { packet_dealloc(packet); return; } request->n_hop = n_hop->id; TX(&c0, packet); entitydata->TX_query++; } else { #ifdef LOG_APPLICATION_REQUEST_ROUTING printf("[XY] node %d (%lf,%lf) : no path towards %c direction\n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,request->direction); #endif } } return; }
/* Received a request from a sink */ void rx_sink_adv(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct entitydata *entitydata = get_entity_private_data(c); struct sink_adv_p *sink = (struct sink_adv_p *) (packet->data + nodedata->overhead); entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; /* starts home node election */ if (sink->home == -1) { packet_t *packet0; struct home_adv_p *adv; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; /* check request sequence */ if (sink->r_seq <= nodedata->r_seq[sink->sink]) { /* old request */ packet_dealloc(packet); return; } nodedata->r_seq[sink->sink] = sink->r_seq; packet0 = packet_create(c, nodedata->overhead + sizeof(struct home_adv_p), -1); adv = (struct home_adv_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } adv->type = HOME_ADV_TYPE; adv->sensor = c->node; adv->sink = sink->sink; adv->r_seq = sink->r_seq; TX(&c0, packet0); entitydata->TX_home_adv++; packet_dealloc(packet); return; } else if (sink->home == c->node) { /* do we have the requested data (or some more recent data) ? */ if (sink->d_seq <= nodedata->d_seq[sink->metadata]) { packet_t *packet0; struct sensor_data_p *data; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; packet0 = packet_create(c, nodedata->overhead + sizeof(struct sensor_data_p), -1); data = (struct sensor_data_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } data->type = SENSOR_DATA_TYPE; data->metadata = sink->metadata; data->sink = sink->sink; data->r_seq = sink->r_seq; data->source = nodedata->d_source[sink->metadata]; data->d_seq = nodedata->d_seq[sink->metadata]; data->d_value = nodedata->d_value[sink->metadata]; data->delay = (get_time()-nodedata->d_time[sink->metadata])*0.000001; data->hop = nodedata->d_hop[sink->metadata]; #ifdef LOG_APPLICATION_REQUEST printf("[XY] Home-Node %d (%lf,%lf) : broadcasting DATA REPLY (%d,%d,%d) to sink %d (%lf,%lf)\n", c->node, (get_node_position(c->node))->x, (get_node_position(c->node))->y, nodedata->d_source[sink->metadata], sink->metadata, nodedata->d_seq[sink->metadata], sink->sink,(get_node_position(sink->sink))->x, (get_node_position(sink->sink))->y); #endif TX(&c0, packet0); entitydata->TX_sensor_data++; packet_dealloc(packet); return; } else { position_t rdv_position; struct xy_neighbor *n_hop = NULL; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; /* forwards the query to EAST direction */ rdv_position.x = (get_topology_area())->x; rdv_position.y = (get_node_position(c->node))->y; rdv_position.z = -1; n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { packet_t *packet0 = packet_create(c, nodedata->overhead + sizeof(struct xy_request_p), -1); struct xy_request_p *request = (struct xy_request_p *) (packet0->data + nodedata->overhead); position_t *pos = get_node_position(c->node); /* create request */ if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } request->type = XY_REQUEST_TYPE; request->n_hop = n_hop->id; request->sink = sink->sink; request->r_seq = sink->r_seq; request->metadata = sink->metadata; request->d_seq = sink->d_seq; request->position.x = pos->x; request->position.y = pos->y; request->position.z = pos->z; request->direction = DIRECTION_EAST; #ifdef LOG_APPLICATION_REQUEST_ROUTING printf("[XY] Node %d (%lf,%lf) : forwarding REQUEST(sink=%d,%d,%d) to EAST direction via node %d (%lf,%lf)\n", c->node, get_node_position(c->node)->x, get_node_position(c->node)->y, sink->sink, sink->metadata, sink->r_seq, n_hop->id, get_node_position(n_hop->id)->x, get_node_position(n_hop->id)->y); #endif TX(&c0, packet0); entitydata->TX_query++; } else { #ifdef LOG_APPLICATION_REQUEST printf("[XY] Node %d : no path towards EAST direction\n", c->node); #endif } /* forwards the query to WEST direction */ rdv_position.x = 0.0; rdv_position.y = (get_node_position(c->node))->y; rdv_position.z = -1; n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { packet_t *packet0 = packet_create(c, nodedata->overhead + sizeof(struct xy_request_p), -1); struct xy_request_p *request = (struct xy_request_p *) (packet0->data + nodedata->overhead); position_t *pos = get_node_position(c->node); /* create request */ if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } request->type = XY_REQUEST_TYPE; request->n_hop = n_hop->id; request->sink = sink->sink; request->r_seq = sink->r_seq; request->metadata = sink->metadata; request->d_seq = sink->d_seq; request->position.x = pos->x; request->position.y = pos->y; request->position.z = pos->z; request->direction = DIRECTION_WEST; #ifdef LOG_APPLICATION_REQUEST_ROUTING printf("[XY] Node %d (%lf,%lf) : forwarding REQUEST(sink=%d,%d,%d) to WEST direction via node %d (%lf,%lf)\n", c->node, get_node_position(c->node)->x, get_node_position(c->node)->y, sink->sink, sink->metadata, sink->r_seq, n_hop->id, get_node_position(n_hop->id)->x, get_node_position(n_hop->id)->y); #endif TX(&c0, packet0); entitydata->TX_query++; } else { #ifdef LOG_APPLICATION_REQUEST printf("[XY] Node %d : no path towards WEST direction\n", c->node); #endif } packet_dealloc(packet); return; } } else { packet_dealloc(packet); return; } }
/* Received a DATA report from a sensor */ void rx_xy_data(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct entitydata *entitydata = get_entity_private_data(c); struct xy_data_p *data = (struct xy_data_p *) (packet->data + nodedata->overhead); position_t rdv_position; struct xy_neighbor *n_hop; /* stores the received data */ if (data->d_seq > nodedata->d_seq[data->metadata]) { nodedata->d_seq[data->metadata] = data->d_seq; nodedata->d_source[data->metadata] = data->source; nodedata->d_value[data->metadata] = data->d_value; nodedata->d_hop[data->metadata] = data->hop; nodedata->d_time[data->metadata] = data->time; } /* check sensor */ if (data->n_hop != c->node) { /* not for us */ packet_dealloc(packet); return; } #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] Node %d (%lf,%lf) received a DATA from sensor %d => replication towards %c direction\n",c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,data->source,data->direction); #endif /* replicates the DATA towards the choosed direction */ switch(data->direction){ case DIRECTION_NORTH: rdv_position.x = (get_node_position(c->node))->x; rdv_position.y = 0.0; rdv_position.z = 0.0; break; case DIRECTION_SOUTH: rdv_position.x = (get_node_position(c->node))->x; rdv_position.y = (get_topology_area())->y; rdv_position.z = 0.0; break; default: #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] Node %d (%lf,%lf) received a DATA from source %d with incorrect forwarding direction (%d) !\n",c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,data->source,data->direction); #endif packet_dealloc(packet); return; } /* get next hop */ n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] node %d (%lf,%lf) : forwardind data towards direction %c via node %d \n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,data->direction,n_hop->id); #endif destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; /* forward data */ if (SET_HEADER(&c0, packet, &dst) == -1) { packet_dealloc(packet); return; } data->n_hop = n_hop->id; data->hop++; TX(&c0, packet); entitydata->TX_data++; } else { #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] node %d (%lf,%lf) : no path towards %c direction\n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,data->direction); #endif } return; }
/* received a DATA report from a source node => forwarding towards the rendez-vous area */ void rx_source_data(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct entitydata *entitydata = get_entity_private_data(c); struct source_data_p *data = (struct source_data_p *) (packet->data + nodedata->overhead); position_t rdv_position; struct xy_neighbor *n_hop; /* stores the received data */ if (data->d_seq > nodedata->d_seq[data->metadata]) { nodedata->d_seq[data->metadata] = data->d_seq; nodedata->d_source[data->metadata] = data->source; nodedata->d_value[data->metadata] = data->d_value; nodedata->d_hop[data->metadata] = 1; nodedata->d_time[data->metadata] = get_time(); } /* check sensor */ if (data->sensor != c->node) { /* not for us */ packet_dealloc(packet); return; } #ifdef LOG_APPLICATION_DISSEMINATION printf("[XY] Node %d (%lf,%lf) received a new DATA from source %d => replication towards north and south directions\n",c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y,data->source); #endif /* replicates data towards north direction */ rdv_position.x = (get_node_position(c->node))->x; rdv_position.y = 0.0; rdv_position.z = 0.0; /* get next hop */ n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; packet_t *packet0 = packet_create(c, nodedata->overhead + sizeof(struct xy_data_p), -1); struct xy_data_p *disseminate = (struct xy_data_p *) (packet0->data + nodedata->overhead); entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; /* forward data */ if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet0); packet_dealloc(packet); return; } disseminate->type = XY_DATA_TYPE; disseminate->n_hop = n_hop->id; disseminate->source = data->source; disseminate->metadata = data->metadata; disseminate->d_seq = data->d_seq; disseminate->d_value = data->d_value; disseminate->hop = 2; disseminate->time = get_time(); disseminate->direction = DIRECTION_NORTH; TX(&c0, packet0); entitydata->TX_data++; } else { #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] node %d (%lf,%lf) : no path towards NORTH direction\n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y); #endif } /* replicates data towards south direction */ rdv_position.x = (get_node_position(c->node))->x; rdv_position.y = (get_topology_area())->y; rdv_position.z = 0.0; /* get next hop */ n_hop = xy_next_hop(c, &rdv_position); if (n_hop != NULL) { destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; packet_t *packet0 = packet_create(c, nodedata->overhead + sizeof(struct xy_data_p), -1); struct xy_data_p *disseminate = (struct xy_data_p *) (packet0->data + nodedata->overhead); entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node, c->entity}; /* forward data */ if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet0); packet_dealloc(packet); return; } disseminate->type = XY_DATA_TYPE; disseminate->n_hop = n_hop->id; disseminate->source = data->source; disseminate->metadata = data->metadata; disseminate->d_seq = data->d_seq; disseminate->d_value = data->d_value; disseminate->hop = 2; disseminate->time = get_time(); disseminate->direction = DIRECTION_SOUTH; TX(&c0, packet0); entitydata->TX_data++; } else { #ifdef LOG_APPLICATION_DISSEMINATION_ROUTING printf("[XY] node %d (%lf,%lf) : no path towards SOUTH direction\n", c->node,(get_node_position(c->node))->x,(get_node_position(c->node))->y); #endif } packet_dealloc(packet); 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; }
/* ************************************************** */ int bootstrap(call_t *c) { PRINT_REPLAY("mobility %"PRId64" %d %lf %lf %lf\n", get_time(), c->node, get_node_position(c->node)->x, get_node_position(c->node)->y, get_node_position(c->node)->z); return 0; }