Beispiel #1
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;
}
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;
}
/* ************************************************** */
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;
}
Beispiel #4
0
/* ************************************************** */
int event_callback(call_t *c, void *data) {
    struct _env_data *entitydata = get_entity_private_data(c);    
    struct _collec_event *event = (struct _collec_event *) data;
    call_t c0;
    array_t *app_layer = NULL;
    int type, value;

    /* Execute the event using an IOCTL */
    type = event->event_type;
    value = event->event_value;
    c0.node = event->node_id;
    app_layer = get_application_entities(&c0);
    c0.entity = app_layer->elts[0];
    IOCTL(&c0, type, &value, 0);
    DBG("Time %"PRId64", IOCTL for node %d, type %d, value %d\n", 
         event->time, event->node_id, type, value);

    /* Delete the event */
    free(event);

    /* Schedule the next event */
    event = (struct _collec_event *) sodas_pop(entitydata->events);
    if (event == NULL) {
        DBG("No more events in queue\n");
        return 0;
    }

    scheduler_add_callback(event->time, c, event_callback, event);
    return 0;
}
/* ************************************************** */
int setnode(call_t *c, void *params) {
    struct entitydata *entitydata = get_entity_private_data(c);
    struct nodedata *nodedata = malloc(sizeof(struct nodedata));
    char str[128];
    int id, dst, n_hop;
    
    /* extract routing table from file */
    nodedata->routes = hadas_create(route_hash, route_equal);
    
    /* extract routing table from file */
    fseek(entitydata->file, 0L, SEEK_SET);
    while (fgets(str, 128, entitydata->file) != NULL) {
        if (sscanf(str, "%d %d %d\n",  &id, &dst, &n_hop) != 3) {
            fprintf(stderr, "filestatic: unable to read route in setnode()\n");
            goto error;
        }
        
        if (id == c->node) {
            struct route *route = (struct route *) malloc(sizeof(struct route));
            route->dst = dst;
            route->n_hop = n_hop;
            hadas_insert(nodedata->routes, (void *) ((unsigned long) (route->dst)), (void *) route);
        }
    }
    
    nodedata->overhead = -1;
    set_node_private_data(c, nodedata);
    return 0;

 error:
    free(entitydata);
    return -1;
}
/* ************************************************** */
double interfere(call_t *c, int channel0, int channel1) {
    struct entitydata *entitydata = get_entity_private_data(c);
    if (channel0 == channel1) {
        return 1;
    } else {
        return entitydata->factor;
    }
}
Beispiel #7
0
/* ************************************************** */
double modulate(call_t *c, double snr) {
    struct entitydata *entitydata = get_entity_private_data(c);
    if (snr >= entitydata->step) {
        return 0;
    } else {
        return 0.5;
    }
}
/* *********************************************** */
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 destroy(call_t *c) {
    struct entitydata *entitydata = get_entity_private_data(c);

    if (entitydata->file != NULL) {
        fclose(entitydata->file);
    }

    free(entitydata);
    return 0;
}
Beispiel #10
0
/* ************************************************** */
void register_callback(call_t *c, callback_t callback, void *arg) {
    struct entitydata *entitydata = get_entity_private_data(c);
    struct monitor_callback *call = malloc(sizeof(struct monitor_callback));
    call->callback = callback;
    call->c.entity = c->from;
    call->c.node = c->node;
    call->c.from = -1;
    call->arg = arg;
    das_insert(entitydata->callbacks, (void *) call);
    return;
}
Beispiel #11
0
/* ************************************************** */
void monitor_death(call_t *c) {
    struct entitydata *entitydata = get_entity_private_data(c);
    
    /* log node death */
    entitydata->nbr_nodes--;
    
    /* log active nodes number */
    log_activenodes(c);
    
    /* monitor */
    monitor_event(c);
}
void tx( call_t *c , packet_t * packet )
{
    struct nodedata *nodedata = get_node_private_data(c);
    struct protocoleData *entitydata = get_entity_private_data(c);
    if(entitydata->debug)
        DBG("LBOP BROADCAST - ON %d  WITH RANGE %.2lf At %lf \n",c->node,get_range_Tr(c), get_time_now_second());

    entityid_t *down = get_entity_links_down(c);
    call_t c0 = {down[0], c->node};

    TX(&c0,packet);
}
/* ************************************************** */
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 rx_dBm = rxdBm;
    
    switch(entitydata->propagation){
      case FREESPACE    : rx_dBm = compute_freespace(entitydata, src, dst, rxdBm); break;
      case TWORAYGROUND : rx_dBm = compute_tworayground(entitydata, src, dst, rxdBm); break;
      case LOGDISTANCE  : rx_dBm = compute_logdistance_pathloss(entitydata, src, dst, rxdBm); break;
      case LOGNORMAL    : rx_dBm = compute_lognormal_shadowing(entitydata, src, dst, rxdBm); break;
      default : rx_dBm = rxdBm; /* should not happen */
    }
    return rx_dBm + compute_fading(entitydata);
}
Beispiel #14
0
/* ************************************************** */
void monitor_event(call_t *c) {
    struct entitydata *entitydata = get_entity_private_data(c);
    struct monitor_callback *callback;
    
    /* log energy map */
    log_energymap(c);
    
    /* call callbacks */
    das_init_traverse(entitydata->callbacks);
    while ((callback = (struct monitor_callback *) das_traverse(entitydata->callbacks)) != NULL) {
        callback->callback(&(callback->c), callback->arg);
    }    
}
Beispiel #15
0
/* ************************************************** */
double freespace(call_t *c, packet_t *packet, double dist, double rxmW) {
    struct entitydata *entitydata = get_entity_private_data(c);
    /*
     *           Pt * Gt * Gr * lambda^2
     *  Pr(d) = -------------------------
     *             (4 * pi * d)^2 * L
     *
     *  Note: rxmW = Pt * Gt * Gr, and L = 1
     *
     *  cf p71 ref "Wireless Communications: Principles and Practice", Theodore Rappaport, 1996.
     *  
     */
    return (rxmW * entitydata->factor*entitydata->factor / pow(dist, 2));
}
/* ************************************************** */
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 success = *(entitydata->success + (src * entitydata->node_cnt) + dst);

    if (success == 1) {
        return rxdBm;
    } else if (success == 0) {
        return MIN_DBM;
    } else if (get_random_double() <= success) {
        return rxdBm;        
    } else {
        return MIN_DBM;
    }
}
Beispiel #17
0
int destroy(call_t *c) {
  struct entitydata *entitydata = get_entity_private_data(c);

  long int total = entitydata->TX_hello + entitydata->TX_data + entitydata->TX_query + entitydata->TX_response + entitydata->TX_sensor_adv + entitydata->TX_sensor_data + entitydata->TX_home_adv;

  double total_virtual = entitydata->TX_hello*0.5 + entitydata->TX_data + entitydata->TX_query + entitydata->TX_response + entitydata->TX_sensor_adv*0.5 + entitydata->TX_sensor_data + entitydata->TX_home_adv*0.5;

  long int total_octets = entitydata->TX_hello*sizeof(struct xy_hello_p) + entitydata->TX_data*sizeof(struct xy_data_p) + entitydata->TX_query*sizeof(struct xy_request_p) + entitydata->TX_response*sizeof(struct xy_response_p) + entitydata->TX_sensor_adv*sizeof(struct sensor_adv_p) + entitydata->TX_sensor_data*sizeof(struct sensor_data_p) + entitydata->TX_home_adv*sizeof(struct home_adv_p);
  
  printf("[ENERGY] HELLO %d DATA %d QUERY %d RESPONSE %d SENSOR_ADV %d SENSOR_DATA %d HOME_ADV %d TOTAL %ld TOTAL_VIRTUAL %lf TOTAL_OCTETS %ld\n", entitydata->TX_hello, entitydata->TX_data, entitydata->TX_query, entitydata->TX_response, entitydata->TX_sensor_adv, entitydata->TX_sensor_data, entitydata->TX_home_adv, total, total_virtual, total_octets);

  free(entitydata);
  return 0;
}
Beispiel #18
0
/* ************************************************** */
int bootstrap(call_t *c) {
    struct entitydata *entitydata = get_entity_private_data(c);

    /* log initial active nodes number */
    log_activenodes(c);

    /* log initial energy map */
    log_energymap(c);

    if (entitydata->map_period > 0) {
        scheduler_add_callback(entitydata->map_period, c, map_callback, NULL);
    }
    
    return 0;
}
Beispiel #19
0
int destroy(call_t *c) {
    struct _env_data *entitydata = get_entity_private_data(c);
    struct _collec_event *event;

    /* Free the pending events */
    while ((event = (struct _collec_event *)
                sodas_pop(entitydata->events)) != NULL) {
        free(event);
    }

    /* Free the event list */
    sodas_destroy(entitydata->events);

    free(entitydata);
    return 0;
}
int bootstrap(call_t *c) {
    struct nodedata *nodedata = get_node_private_data(c);
    struct protocoleData *entitydata = get_entity_private_data(c);

    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};
    /* get mac header overhead */
    nodedata->overhead = GET_HEADER_SIZE(&c0);

    broadcast_hello(c, NULL);
    uint64_t at=get_time_now()+time_seconds_to_nanos(3);
    scheduler_add_callback(at, c, init_rbop, NULL);



    return 0;
}
Beispiel #21
0
/* ************************************************** */
int bootstrap(call_t *c) {
    struct _env_data *entitydata = get_entity_private_data(c);
    struct _collec_event *event = NULL;

    /* Get the first event */
    event = (struct _collec_event *) sodas_pop(entitydata->events);

    if (event == NULL) {
        DBG("ERROR: no events in queue\n");
        return 0;
    }

    /* Schedule the first event */
    scheduler_add_callback(event->time, c, event_callback, event);

    return 0;
}
Beispiel #22
0
int destroy(call_t *c) {
    struct entitydata *entitydata = get_entity_private_data(c);
    struct monitor_callback *callback;
    long time = (long) (get_time() * 0.000001);
    
    fprintf(entitydata->filenode, "%ld %d\n", time, entitydata->nbr_nodes);

    while ((callback = (struct monitor_callback *) das_pop(entitydata->callbacks)) != NULL) {
        free(callback);
    }
    das_destroy(entitydata->callbacks);
    if (entitydata->filenode) {
        fclose(entitydata->filenode);
    }
    free(entitydata);
    return 0;
}
Beispiel #23
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;
}
Beispiel #24
0
/* ************************************************** */
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);
    }
}
void forward(call_t* c, packet_t *packet)
{
	struct nodedata *nodedata = get_node_private_data(c);
    struct protocoleData *entitydata = get_entity_private_data(c);
	array_t *down = get_entity_bindings_down(c);
	packet_PROTOCOLE *data = (packet_PROTOCOLE *) (packet->data + nodedata->overhead);
	
	//printf("%d doit relayer depuis %d\n", c->node, data->pred);
	
	// construire le bip tree pour relayer a partir des infos du paquet
	int indice = listeNodes_get_index(data->askedToRedirect, c->node);
	graphe* g = purgeGraphe(c, listeNodes_get(data->needsToBeCovered, indice), data->src, data->pred);
	arbre* bipTree = computeBIPtree(c, g, data->askedToRedirect, data->needsToBeCovered, 0);
	
	if(entitydata->debug)
	{
		printf("%d relai depuis %d :\n", c->node, data->pred);
		arbre_affiche(bipTree);
	}
	
	// relayer le paquet
	destination_t dst = {-1,{-1,-1,-1}};
	double cout = setRangeToFarestNeighbour(c, g, bipTree);
	
	
	//listeNodes_detruire(&data->askedToRedirect);
	data->askedToRedirect = 0;
	//listeNodes_detruire(&data->needsToBeCovered);
	data->needsToBeCovered = 0;
	data->pred = c->node;
	
	//call_t c0 = {-1,c->node,-1};
	//data->energyRem = battery_remaining(&c0) - cout;
	//nodedata->energiesRem[c->node] = data->energyRem;
	
	setRelayNodes(c, g, bipTree, &data->askedToRedirect, &data->needsToBeCovered, c->node);
	call_t c_down = {down->elts[0], c->node, c->entity};
	SET_HEADER(&c_down, packet, &dst);
	tx(c, packet);
	arbre_detruire(&bipTree);
	deleteGraphe(g);
	free(g);
}
int bootstrap(call_t *c) {
    struct nodedata *nodedata = get_node_private_data(c);
    struct protocoleData *entitydata = get_entity_private_data(c);
	
    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};
	/* get mac header overhead */
    nodedata->overhead = GET_HEADER_SIZE(&c0);
	
	int i;
	for(i = 0 ; i < get_node_count() ; i++)
	{
		nodedata->lastIDs[i] = -1;
		nodedata->energiesRem[i] = battery_remaining(c) - 2*getCoutFromDistance(getRange(c), entitydata->alpha, entitydata->c);
	}
	
	broadcast_hello(c, NULL);
    uint64_t at=get_time_now()+time_seconds_to_nanos(2);
    scheduler_add_callback(at, c, broadcast_hello2, NULL);
	
    return 0;
}
Beispiel #27
0
/* ************************************************** */
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;
}
Beispiel #28
0
/* ************************************************** */
void rx_source_adv(call_t *c, packet_t *packet) {
    struct nodedata *nodedata = get_node_private_data(c);
    struct entitydata *entitydata = get_entity_private_data(c);
    struct source_adv_p *source = (struct source_adv_p *) (packet->data + nodedata->overhead);
    struct sensor_adv_p *sensor;
    packet_t *packet0;
    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};

    /* check adv sequence */
    if (source->s_seq <= nodedata->s_seq[source->source]) {
        /* old request */
        packet_dealloc(packet);
        return;
    }
    nodedata->s_seq[source->source] = source->s_seq;
    
    /* reply */
    packet0 = packet_create(c, nodedata->overhead + sizeof(struct sensor_adv_p), -1);
    sensor = (struct sensor_adv_p *) (packet0->data + nodedata->overhead);
    if (SET_HEADER(&c0, packet0, &dst) == -1) {
        packet_dealloc(packet);
        packet_dealloc(packet0);
        return;
    }
    sensor->type   = SENSOR_ADV_TYPE;
    sensor->sensor = c->node;
    sensor->source = source->source;
    sensor->s_seq  = source->s_seq;

    TX(&c0, packet0);
    entitydata->TX_sensor_adv++;

    packet_dealloc(packet);
    return;
}
Beispiel #29
0
int destroy(call_t *c) {
    free(get_entity_private_data(c));
    return 0;
}
Beispiel #30
0
/* 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;
}