/* ************************************************** */ int parse_simulation(xmlNodeSetPtr nodeset) { xmlAttrPtr attr; uint64_t duration; if (nodeset == NULL) { fprintf(stderr, "config: schema must require one '" XML_E_SIMULATION "' (parse_simulation())\n"); return -1; } /* retrieve @nodes / @duration / @x / @y / @z */ for (attr = nodeset->nodeTab[0]->properties ; attr ; attr = attr->next) { if (! strcmp((char *) attr->name, XML_A_NODES)) { /* xsd: 1 <= @nodes <= 65535 */ nodes.size = strtoll((char *) attr->children->content, NULL, 10); } else if (! strcmp((char *) attr->name, XML_A_DURATION)) { /* xsd: 0 <= @duration */ get_param_time((char *) attr->children->content, &duration); scheduler_set_end(duration); } else if (! strcmp((char *) attr->name, XML_A_X)) { /* xsd: 0 <= @x */ get_topology_area()->x = strtod((char *) attr->children->content, NULL); } else if (! strcmp((char *) attr->name, XML_A_Y)) { /* xsd: 0 <= @y */ get_topology_area()->y = strtod((char *) attr->children->content, NULL); } else if (! strcmp((char *) attr->name, XML_A_Z)) { /* xsd: 0 <= @z */ get_topology_area()->z = strtod((char *) attr->children->content, NULL); } } print_simulation(); 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; }
/* ************************************************** */ void print_simulation(void) { fprintf(stderr, "\nSimulation will run using:\n"); fprintf(stderr, " nodes : %d\n", nodes.size); fprintf(stderr, " (x,y,z) : (%lf, %lf, %lf)\n", get_topology_area()->x, get_topology_area()->y, get_topology_area()->z); if (scheduler_get_end()) { fprintf(stderr, " duration : %" PRId64 "ns\n", scheduler_get_end()); } else { fprintf(stderr, " duration : unlimited\n"); } }
double get_random_z_position(void) { uniform_args_t *args; if ((args = (uniform_args_t *) mem_fs_alloc(mem_rng)) == NULL) { printf("Error: Error while allocating memory for rng. Exiting!\n"); exit(-1); } args->a = 0; args->b = get_topology_area()->z; double result = get_random_double_gsl((void *)DEFAULT_RNG, UNIFORM, args); mem_fs_dealloc(mem_rng, args); return result; }
double get_random_z_position_gsl(void *rng_id, int distribution_type, void *parameters) { int attempts = 0; double max = get_topology_area()->z; distribution_function_t distribution = get_distribution_function_by_type(distribution_type); double result = distribution(rng_id, parameters); while(result > max && (attempts < rng_retry_attempts || rng_retry_attempts <= -1)){ result = distribution(rng_id, parameters); if(rng_retry_attempts > -1){ attempts++; } } if(attempts == rng_retry_attempts){ printf("Error: Too many attempts to get a valid value from the rng %p." "Check the distribution parameters. Exiting!\n", rng_id); exit(-1); } return result; }
/* 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; }