/* ************************************************** */ void medium_cs(packet_t *packet, call_t *c) { uint64_t clock = get_time() + packet->duration; node_t *node = get_node_by_id(c->node); entity_t *entity = get_entity_by_id(c->entity); /* check wether the node is able to receive */ if (node->state != NODE_ACTIVE) { packet_dealloc(packet); return; } /* propagation */ medium_compute_rxdBm(packet, c); /* filter */ /* edit by Loic Lemaitre */ if (node->worldsens == NODE_LOCAL) { /* WORLDSENS MODE? wsim deals with filtering */ if (packet->rxdBm == MIN_DBM) { packet_dealloc(packet); return; } } /* end of edition */ /* update noise */ #if (SNR_STEP != 0) noise_packet_cs(c, packet); #endif /*SNR_STEP*/ /* start reception */ entity->methods->antenna.cs(c, packet); /* end reception */ scheduler_add_rx_end(clock, c, packet); }
/* ************************************************** */ void rx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct _802_15_4_header *header = (struct _802_15_4_header *) packet->data; array_t *up = get_entity_bindings_up(c); int i = up->size; /* cf p171 ref 802.15.4-2006: discard packet while in backoff */ if (nodedata->state != STATE_IDLE) { packet_dealloc(packet); return; } if ((header->dst != c->node) && (header->dst != BROADCAST_ADDR)) { packet_dealloc(packet); return; } 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 rx_xy_hello(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct xy_hello_p *hello = (struct xy_hello_p *) (packet->data + nodedata->overhead); struct xy_neighbor *neighbor; /* check for existing neighbors */ das_init_traverse(nodedata->neighbors); while ((neighbor = (struct xy_neighbor *) das_traverse(nodedata->neighbors)) != NULL) { if (neighbor->id == hello->src) { neighbor->position.x = hello->position.x; neighbor->position.y = hello->position.y; neighbor->position.z = hello->position.z; neighbor->time = get_time(); packet_dealloc(packet); return; } } /* new neighbor */ neighbor = (struct xy_neighbor *) malloc(sizeof(struct xy_neighbor)); neighbor->id = hello->src; neighbor->position.x = hello->position.x; neighbor->position.y = hello->position.y; neighbor->position.z = hello->position.z; neighbor->time = get_time(); das_insert(nodedata->neighbors, (void *) neighbor); packet_dealloc(packet); return; }
void rx_source_adv(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_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}}; call_t c0 = {get_entity_bindings_down(c)->elts[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); packet_dealloc(packet); return; }
void scheduler_clean(void) { event_t *event; if (scheduler == NULL) { return; } while ((event = (event_t *) sodas_pop(scheduler)) != NULL) { switch (event->priority) { case PRIORITY_RX_END: packet_dealloc(event->u.rx.packet); break; case PRIORITY_RX_BEGIN: packet_dealloc(event->u.rx.packet); break; case PRIORITY_TX_END: packet_dealloc(event->u.rx.packet); break; default: break; } mem_fs_dealloc(mem_event, event); } sodas_destroy(scheduler); worldsens_clean(); }
/* ************************************************** */ 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; }
//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; }
int unsetnode(call_t *c) { struct nodedata *nodedata = get_node_private_data(c); packet_t *packet; while ((packet = (packet_t *) das_pop(nodedata->packets)) != NULL) { packet_dealloc(packet); } das_destroy(nodedata->packets); if (nodedata->txbuf) { packet_dealloc(nodedata->txbuf); } free(nodedata); return 0; }
/* ************************************************** */ void forward(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead); struct neighbor *n_hop = get_nexthop(c, &(header->dst_pos)); destination_t destination; /* delivers packet to application layer */ if (n_hop == NULL) { array_t *up = get_entity_bindings_up(c); int i = up->size; 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; } /* update hop count */ header->hop--; if (header->hop == 0) { nodedata->data_hop++; packet_dealloc(packet); return; } /* set mac header */ destination.id = n_hop->id; destination.position.x = -1; destination.position.y = -1; destination.position.z = -1; if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return; } /* forwarding packet */ nodedata->data_tx++; TX(&c0, packet); }
// ENVOI DE PACKET HELLO int init_one_hop(call_t *c, void *args) { struct nodedata *nodedata = get_node_private_data(c); //recuperer le support de communication DOWN entityid_t *down = get_entity_links_down(c); call_t c0 = {down[0], c->node}; //destination de paquet destination_t destination = {BROADCAST_ADDR, {-1, -1, -1}}; //creation de paquet et initialisation de son data packet_t *packet = packet_alloc(c, nodedata->overhead[0] + sizeof(struct packet_hello)); struct packet_hello *hello = (struct packet_hello *) (packet->data + nodedata->overhead[0]); //initilailser les données hello->type=HELLO; hello->source=c->node; if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return -1; } DEBUG; /*printf("Node %d (%lf %lf %lf) broadcast a packet hello, at %lf\n", c->node, //id de Noeud 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 get_time_now_second());//*/ //l'instant d'envoi. //L'envoi TX(&c0,packet); //tous c'est bien passé return 1; }
/* ************************************************** */ void tx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); array_t *down = get_entity_bindings_down(c); int i = down->size; /* radio sleep */ if (nodedata->sleep) { packet_dealloc(packet); return; } /* radio activity */ cs_init(c); nodedata->tx_busy = packet->id; /* log tx */ PRINT_REPLAY("radio-tx0 %"PRId64" %d 50\n", get_time(), c->node); /* transmit to antenna */ while (i--) { packet_t *packet_down; if (i > 0) { packet_down = packet_clone(packet); } else { packet_down = packet; } c->from = down->elts[i]; MEDIA_TX(c, packet_down); } return; }
void medium_rx(packet_t *packet, call_t *c) { node_t *node = get_node_by_id(c->node); /* check wether the node is able to receive */ if (node->state != NODE_ACTIVE) { packet_dealloc(packet); return; } /* noise & PER */ #if (SNR_STEP != 0) packet->PER = 1; noise_packet_rx(c, packet); packet->PER = 1 - packet->PER; #ifdef SNR_ERRORS modulation_errors(packet); #endif /*SNR_ERRORS*/ #else /*SNR_STEP == 0*/ packet->PER = 0; #endif /*SNR_STEP*/ /* receive */ /* edit by Loic Lemaitre */ if (node->worldsens == NODE_LOCAL) { /* WORLDSENS MODE? */ antenna_rx(c, packet); } else { worldsens_nodes_rx(c, packet); } /* end of edition */ }
void rx_sink_adv(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct sink_adv_p *sink = (struct sink_adv_p *) (packet->data + nodedata->overhead); struct sensor_data_p *data; packet_t *packet0; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; /* 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; /* check wether we have the data */ if (sink->d_seq > nodedata->d_seq[sink->metadata]) { /* our data is not up to date */ packet_dealloc(packet); return; } /* reply */ 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]; TX(&c0, packet0); packet_dealloc(packet); return; }
void rx_source_data(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct source_data_p *data = (struct source_data_p *) (packet->data + nodedata->overhead); struct gossip_data_p *gossip; packet_t *packet0; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; /* check sensor */ if (data->sensor != c->node) { /* not for us */ packet_dealloc(packet); return; } /* check data sequence */ if (data->d_seq <= nodedata->d_seq[data->metadata]) { /* old data */ packet_dealloc(packet); return; } nodedata->d_seq[data->metadata] = data->d_seq; nodedata->d_source[data->metadata] = data->source; nodedata->d_value[data->metadata] = data->d_value; /* start gossip */ packet0 = packet_create(c, nodedata->overhead + sizeof(struct gossip_data_p), -1); gossip = (struct gossip_data_p *) (packet0->data + nodedata->overhead); if (SET_HEADER(&c0, packet0, &dst) == -1) { packet_dealloc(packet); packet_dealloc(packet0); return; } gossip->type = GOSSIP_DATA_TYPE; gossip->source = data->source; gossip->metadata = data->metadata; gossip->d_seq = data->d_seq; gossip->d_value = data->d_value; TX(&c0, packet0); packet_dealloc(packet); return; }
/* ************************************************** */ void forward(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead); struct route *route = hadas_get(nodedata->routes, (void *) ((unsigned long) (header->dst))); destination_t destination; if (route == NULL) { packet_dealloc(packet); return; } destination.id = route->n_hop; if (SET_HEADER(&c0, packet, (void *) &destination) == -1) { packet_dealloc(packet); return; } TX(&c0, packet); }
void rx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct data_d_header *header = (struct data_d_header *) (packet->data + nodedata->overhead); switch (header->type) { case SOURCE_ADV_TYPE: /* for us */ rx_source_adv(c, packet); break; case SENSOR_ADV_TYPE: /* not for us */ packet_dealloc(packet); break; case SOURCE_DATA_TYPE: /* for us */ rx_source_data(c, packet); break; case SINK_ADV_TYPE: /* for us */ rx_sink_adv(c, packet); break; case SENSOR_DATA_TYPE: /* not for us */ packet_dealloc(packet); break; case HOME_ADV_TYPE: /* not for us */ packet_dealloc(packet); break; case GOSSIP_DATA_TYPE: /* for us */ rx_gossip_data(c, packet); break; default: /* not for us */ packet_dealloc(packet); break; } return; }
void medium_tx_end(packet_t *packet, call_t *c) { node_t *node = get_node_by_id(c->node); entity_t *entity = get_entity_by_id(c->entity); /* check wether the node is still active */ if (node->state == NODE_ACTIVE) { entity->methods->radio.tx_end(c, packet); } packet_dealloc(packet); return; }
/* ************************************************** */ void forward(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead); struct neighbor *n_hop = get_nexthop(c, header->dst); destination_t destination; /* No route available */ if (n_hop == NULL) { packet_dealloc(packet); return; } /* Update hop count */ header->hop--; /* Hop count reached */ if (header->hop == 0) { packet_dealloc(packet); return; } /* Set MAC header */ destination.id = n_hop->id; destination.position.x = -1; destination.position.y = -1; destination.position.z = -1; if (SET_HEADER(&c0, packet, &destination) == -1) { packet_dealloc(packet); return; } /* Forwarding packet */ PRINT_ROUTING("forward: Node %d forwards a packet " "(from %d to %d, hop limit %d)\n", c->node, header->src, header->dst, header->hop); TX(&c0, packet); }
void rx_gossip_data(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct gossip_data_p *data = (struct gossip_data_p *) (packet->data + nodedata->overhead); destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity}; /* check data sequence */ if (data->d_seq <= nodedata->d_seq[data->metadata]) { /* old data */ packet_dealloc(packet); return; } nodedata->d_seq[data->metadata] = data->d_seq; nodedata->d_source[data->metadata] = data->source; nodedata->d_value[data->metadata] = data->d_value; /* forward gossip */ if (SET_HEADER(&c0, packet, &dst) == -1) { packet_dealloc(packet); return; } TX(&c0, packet); }
/* ************************************************** */ void rx(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct data_d_header *header = (struct data_d_header *) (packet->data + nodedata->overhead); switch (header->type) { case XY_HELLO_TYPE: /* for us */ rx_xy_hello(c, packet); break; case XY_DATA_TYPE: /* for us */ rx_xy_data(c, packet); break; case XY_REQUEST_TYPE: /* for us */ rx_xy_request(c, packet); break; case XY_RESPONSE_TYPE: /* for us */ rx_xy_response(c, packet); break; case SOURCE_ADV_TYPE: /* for us */ rx_source_adv(c, packet); break; case SOURCE_DATA_TYPE: /* for us */ rx_source_data(c, packet); break; case SINK_ADV_TYPE: /* for us */ rx_sink_adv(c, packet); break; default: /* not for us */ packet_dealloc(packet); break; } return; }
/* 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; }
/* ************************************************** */ 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; struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead); switch(header->type) { case HELLO_PACKET: nodedata->hello_rx++; add_neighbor(c, header); packet_dealloc(packet); break; case DATA_PACKET : nodedata->data_rx++; if ((header->dst != BROADCAST_ADDR) && (header->dst != c->node) ) { forward(c, packet); return; } 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); } break; default : break; } return; }
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; }
/* 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; }
void rx_xy_response(call_t *c, packet_t *packet) { struct nodedata *nodedata = get_node_private_data(c); struct entitydata *entitydata = get_entity_private_data(c); struct xy_response_p *response = (struct xy_response_p *) (packet->data + nodedata->overhead); 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 (response->n_hop != c->node) { packet_dealloc(packet); return; } /* get next hop */ n_hop = xy_next_hop(c, &(response->position)); /* if I am the home node */ if (n_hop == NULL) { #ifdef LOG_APPLICATION_RESPONSE printf("[HOME] node %d : broadcasting received DATA to (sink=%d,%d,%d)\n", c->node, response->sink, response->metadata, response->r_seq); #endif packet_t *packet0; struct sensor_data_p *data; destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; /* reply */ 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 = response->metadata; data->sink = response->sink; data->r_seq = response->r_seq; data->source = response->source; data->d_seq = response->d_seq; data->d_value = response->d_value; data->delay = (get_time()-response->time)*0.000001; data->hop = response->hop; TX(&c0, packet0); entitydata->TX_sensor_data++; packet_dealloc(packet); return; } else { #ifdef LOG_APPLICATION_RESPONSE_ROUTING printf("Node %d : forwarding REPLAY to (sink=%d,%d,%d) via node %d \n", c->node, response->sink, response->metadata, response->r_seq, n_hop->id); #endif /* forward packet */ #ifdef USE_BROADCAST_COMMUNICATIONS destination_t dst = {BROADCAST_ADDR, {-1, -1, -1}}; #else destination_t dst = {n_hop->id, {-1, -1, -1}}; #endif /* forward data */ if (SET_HEADER(&c0, packet, &dst) == -1) { packet_dealloc(packet); return; } response->n_hop = n_hop->id; response->hop++; TX(&c0, packet); entitydata->TX_response++; } return; }
int state_machine(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}; uint64_t timeout; uint64_t backoff; packet_t *packet; if (nodedata->clock != get_time()) { return 0; } switch (nodedata->state) { case STATE_IDLE: if (nodedata->txbuf == NULL) { nodedata->txbuf = (packet_t *) das_pop_FIFO(nodedata->packets); if (nodedata->txbuf == NULL) { return 0; } } if (nodedata->MaxCSMABackoffs != 0) { nodedata->state = STATE_BACKOFF; nodedata->BE = nodedata->MinBE; nodedata->NB = 0; backoff = get_random_double() * (pow(2, nodedata->BE) - 1) * aUnitBackoffPeriod; nodedata->clock = get_time() + backoff; scheduler_add_callback(nodedata->clock, c, state_machine, NULL); return 0; } else { nodedata->state = STATE_TX; nodedata->clock = get_time(); scheduler_add_callback(nodedata->clock, c, state_machine, NULL); return 0; } case STATE_BACKOFF: if (check_channel_busy(c)) { if ((++nodedata->BE) > nodedata->MaxBE) { nodedata->BE = nodedata->MaxBE; } if (++nodedata->NB >= nodedata->MaxCSMABackoffs) { packet_dealloc(nodedata->txbuf); nodedata->txbuf = NULL; nodedata->state = STATE_IDLE; nodedata->clock = get_time(); state_machine(c,NULL); return 0; } backoff = get_random_double() * (pow(2, nodedata->BE) - 1) * aUnitBackoffPeriod; nodedata->clock = get_time() + backoff; scheduler_add_callback(nodedata->clock, c, state_machine, NULL); return 0; } nodedata->state = STATE_TX; nodedata->clock = get_time(); state_machine(c,NULL); return 0; case STATE_TX: packet = nodedata->txbuf; nodedata->txbuf = NULL; timeout = packet->size * 8 * radio_get_Tb(&c0) + macMinSIFSPeriod; TX(&c0, packet); nodedata->state = STATE_TXING; nodedata->clock = get_time() + timeout; scheduler_add_callback(nodedata->clock, c, state_machine, NULL); return 0; case STATE_TXING: nodedata->state = STATE_IDLE; nodedata->clock = get_time(); state_machine(c,NULL); return 0; default: break; } return 0; }
/** * Retransmit data to nodes **/ int worldsens_nodes_rx(call_t *c, packet_t *packet){ ws_rdv_t *next_rdv = worldsens_rdv_see_next(); if(next_rdv->clock == get_time()){ /* just send data (no rdv)*/ union _worldsens_pkt pkt_rx; /* compute sinr */ double sinr = packet->rxdBm - mW2dBm(*(packet->noise_mW)); /* put doubles into uint64_t variables for swap */ uint64_t *prxdBm = (uint64_t *) &(packet->rxdBm); uint64_t *pworldsens_freq = (uint64_t *) &(packet->worldsens_freq); uint64_t *psinr = (uint64_t *) &(sinr); /* forge msg */ pkt_rx.byte_rx.type = WORLDSENS_S_BYTE_RX; pkt_rx.byte_rx.seq = ws_seq++; pkt_rx.byte_rx.antenna_id = packet->antenna; pkt_rx.byte_rx.wsim_mod_id = packet->worldsens_mod; pkt_rx.byte_rx.freq = *pworldsens_freq; pkt_rx.byte_rx.data = *(packet->data); pkt_rx.byte_rx.node_id = worldsens_get_wsim_node_id(c->node); pkt_rx.byte_rx.power_dbm = *prxdBm; pkt_rx.byte_rx.sinr = *psinr; /* send data */ worldsens_packet_display(&pkt_rx); worldsens_packet_hton (&pkt_rx); if(wsens_srv_msend((char *) &pkt_rx, sizeof(struct _worldsens_s_byte_rx))){ return -1; } WSNET_S_DBG_DBG("WSNET2:: --> RX (dest ip:%d, data:0x%02x, freq:%ghz, wsim modul:%d, power:%gdbm)\n", worldsens_get_wsim_node_id(c->node), (*(packet->data)) & 0xff, packet->worldsens_freq, packet->worldsens_mod, packet->rxdBm); packet_dealloc(packet); } else { /* program new rdv and send data */ union _worldsens_pkt pkt_sr_rx; /* compute sinr */ double sinr = packet->rxdBm - mW2dBm(*(packet->noise_mW)); /* put doubles into uint64_t variables for swap */ uint64_t *prxdBm = (uint64_t *) &(packet->rxdBm); uint64_t *pworldsens_freq = (uint64_t *) &(packet->worldsens_freq); uint64_t *psinr = (uint64_t *) &(sinr); /* update next rdv */ ws_nsync = next_rdv->clock; ws_nsyncseq++; ws_synched = 0; ws_rp_updated = 1; /* forge msg */ pkt_sr_rx.byte_sr_rx.type = WORLDSENS_S_BYTE_SR_RX; pkt_sr_rx.byte_sr_rx.seq = ws_seq++; pkt_sr_rx.byte_sr_rx.rp_next = ws_nsyncseq; pkt_sr_rx.byte_sr_rx.rp_duration = ws_nsync - ws_csync; pkt_sr_rx.byte_sr_rx.antenna_id = packet->antenna; pkt_sr_rx.byte_sr_rx.wsim_mod_id = packet->worldsens_mod; pkt_sr_rx.byte_sr_rx.freq = *pworldsens_freq; pkt_sr_rx.byte_sr_rx.data = *(packet->data); pkt_sr_rx.byte_sr_rx.node_id = worldsens_get_wsim_node_id(c->node); pkt_sr_rx.byte_sr_rx.power_dbm = *prxdBm; pkt_sr_rx.byte_sr_rx.sinr = *psinr; /* send data */ worldsens_packet_display(&pkt_sr_rx); worldsens_packet_hton (&pkt_sr_rx); if(wsens_srv_msend((char *) &pkt_sr_rx, sizeof(struct _worldsens_s_byte_sr_rx))){ return -1; } WSNET_S_DBG_DBG("WSNET2:: --> RX (dest ip:%d, data:0x%02x, freq:%ghz, wsim modul:%d, power:%gdbm)\n", worldsens_get_wsim_node_id(c->node), (*(packet->data)) & 0xff, packet->worldsens_freq, packet->worldsens_mod, packet->rxdBm); WSNET_S_DBG_DBG("WSNET2:: --> RP (seq: %"PRId64") (rp seq: %"PRId64", period: %"PRId64", rp:%"PRId64")\n", ws_seq - 1, ws_nsyncseq, ws_nsync - ws_csync, ws_nsync); packet_dealloc(packet); } return 0; }