/* ************************************************** */ void do_end(void) { int i = get_node_count(); /* unsetnode */ while (i--) { int j; node_t *node = get_node_by_id(i); if ((node->state == NODE_DEAD) || (node->state == NODE_UNDEF)) { continue; } for (j = 0; j < bundles.elts[node->bundle].entity.size; j++) { entity_t *entity = get_entity_by_id(bundles.elts[node->bundle].entity.elts[j]); call_t c = {entity->id, node->id, -1}; if ((entity)->unsetnode) { (entity)->unsetnode(&c); } } } /* unsetnode */ i = entities.size; while (i--) { entity_t *entity = get_entity_by_id(i); call_t c = {entity->id, -1, -1}; if ((entity)->destroy) { (entity)->destroy(&c); } } }
/* ************************************************** */ int parse_measure(void) { int i, j, k; if (measures.size != 0) { int cnt = 0; if ((measures.elts = (measure_t *) malloc(sizeof(measure_t) * measures.size)) == NULL) { fprintf(stderr, "config: malloc error (parse_measure())\n"); return -1; } for (i = 0 ; i < entities.size ; i++) { entity_t *entity = get_entity_by_id(i); for (j = 0; j < entity->model->measure.count; j++) { measure_t *measure; for (k = 0 ; k < cnt; k++) { if (strcmp(entity->model->measure.exported[j], get_measure_by_id(k)->name) == 0) { fprintf(stderr, "config: measure %s exported more than once (parse_measure())\n", entity->model->measure.exported[j]); return -1; } } measure = get_measure_by_id(cnt); measure->id = cnt++; measure->name = entity->model->measure.exported[j]; measure->entity = entity; print_measure(measure); } } } return 0; }
/* ************************************************** */ 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 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; }
/** * Deal with data sent by a node */ static void worldsens_tx_byte(struct _worldsens_c_byte_tx *pkt){ uint64_t tx_start = ws_csync + pkt->period; uint64_t tx_end = tx_start + pkt->duration; /* create packet */ packet_t *packet; node_t *node = get_node_by_id(worldsens_get_wsnet_node_id(pkt->node_id)); entity_t *entity = get_entity_by_id(pkt->antenna_id); call_t c = {entity->id, node->id, -1}; /* put uint64_t into doubles to retrieve double value after swap */ double *power_dbm = (double *) &(pkt->power_dbm); double *freq = (double *) &(pkt->freq); packet = packet_alloc(&c, 1); packet->clock0 = tx_start; /* tx start */ packet->clock1 = tx_end; /* tx end */ packet->duration = pkt->duration; packet->node = node->id; /* source */ packet->antenna = pkt->antenna_id; packet->worldsens_mod = pkt->wsim_mod_id; /* radio modulation in wsim. Better when it matches with wsnet modulation... */ packet->channel = 0; /* TODO: handle channel from wsim radio */ packet->worldsens_freq = *freq; packet->txdBm = *power_dbm; packet->Tb = pkt->duration / packet->real_size; *(packet->data) = pkt->data; if (pkt->wsnet_mod_id == -1) packet->modulation = ws_default_mod; else packet->modulation = pkt->wsnet_mod_id; /* modulation we are using in wsnet for calculation */ /* log informations*/ int iii; WSNET_S_DBG_DBG ("WSNET2:: <-- TX (%"PRId64") (src ip:%d,size:%d,data", packet->clock0, pkt->node_id, packet->size); for(iii=0; iii<packet->size; iii++) { WSNET_S_DBG_DBG(":%02x", packet->data[ iii ] & 0xff); } WSNET_S_DBG_DBG (",duration:%"PRId64",freq:%ghz,wsim modul:%d,tx:%lgdbm)\n", packet->duration, packet->worldsens_freq, packet->worldsens_mod, packet->txdBm); /* proceed TX */ MEDIA_TX(&c, packet); /* reply by sending a backtrack or a rp reminder */ worldsens_send_reply(); return; }
/* edit by Christophe Savigny <*****@*****.**> */ int modulation_bit_per_symbol(entityid_t modulation){ entity_t *entity = get_entity_by_id(modulation); call_t c = {modulation, -1, -1}; return entity->methods->modulation.bit_per_symbol(&c); }
/* ************************************************** */ double do_modulate(entityid_t modulation, double rxmW, double noise) { entity_t *entity = get_entity_by_id(modulation); call_t c = {modulation, -1, -1}; double snr = noise ? (rxmW / noise) : MAX_SNR; return entity->methods->modulation.modulate(&c, snr); }
/** * Forge response to a node connect request */ static void worldsens_rx_connect_req(struct _worldsens_c_connect_req *pkt, struct sockaddr_in *addr) { node_t *node = get_node_by_id(worldsens_register_node_infos(pkt->node_id)); bundle_t *bundle = get_bundle_by_id(node->bundle); entity_t *entity; union _worldsens_pkt pkt0; int offset = 0; int i; int nb_mod = 0; if (node->worldsens != NODE_DISCONNECTED) { //PRINT_WORLDSENS("wsnet:worldsens_rx_connect_req (%"PRId64"): node %d not disconnected!\n", get_time(), node->id); return; } /* forge response*/ pkt0.cnx_rsp_ok.type = WORLDSENS_S_CONNECT_RSP_OK; pkt0.cnx_rsp_ok.seq = ws_seq; pkt0.cnx_rsp_ok.rp_next = ws_nsyncseq; pkt0.cnx_rsp_ok.rp_duration = ws_nsync - ws_csync; pkt0.cnx_rsp_ok.n_antenna_id = bundle->antenna.size; pkt0.cnx_rsp_ok.n_measure_id = measures.size; /* pkt->cnx_rsp_ok.names_and_ids format: */ /*|***************antennas***************|**************modulations*************|***************measures***************|*/ /*|ant id1|ant name1|ant id2|ant name2|..|mod id1|mod name1|mod id2|mod name2|..|mea id1|mea name1|mea id2|mea name2|..|*/ /* *********************************************************************************************************************/ /* forge list of available antennas */ for (i = 0; i < bundle->antenna.size; i++) { entity = get_entity_by_id(bundle->antenna.elts[i]); /* PRINT_WORLDSENS("wsnet: worldsens_rx_connect_req (%"PRId64"): antenna '%s' (id %d) available\n", get_time(), entity->name, entity->id); */ *((uint32_t *) (pkt0.cnx_rsp_ok.names_and_ids + offset)) = entity->id; offset += sizeof(uint32_t); strcpy(pkt0.cnx_rsp_ok.names_and_ids + offset, entity->name); offset += strlen(entity->name) + 1; } /* forge list of available modulations */ das_init_traverse(modulation_entities); while ((entity = (entity_t *) das_traverse(modulation_entities)) != NULL) { /*PRINT_WORLDSENS("wsnet: worldsens_rx_connect_req (%"PRId64"): modulation '%s' (id %d) available\n", get_time(), entity->library.name, entity->id); */ *((uint32_t *) (pkt0.cnx_rsp_ok.names_and_ids + offset)) = entity->id; offset += sizeof(uint32_t); strcpy(pkt0.cnx_rsp_ok.names_and_ids + offset, entity->library.name); offset += strlen(entity->library.name) + 1; nb_mod++; if ((nb_mod == 1) || (strcmp(entity->library.name, "modulation_none") == 0)) { ws_default_mod = entity->id; } } pkt0.cnx_rsp_ok.n_modulation_id = nb_mod; /* forge list of available measure */ for (i = 0; i < measures.size; i++) { measure_t *measure = get_measure_by_id(i); /* PRINT_WORLDSENS("wsnet: worldsens_rx_connect_req (%"PRId64"): measure '%s' (id %d) available\n", get_time(), measure->name, measure->id); */ *((uint32_t *) (pkt0.cnx_rsp_ok.names_and_ids + offset)) = measure->id; offset += sizeof(uint32_t); strcpy(pkt0.cnx_rsp_ok.names_and_ids + offset, measure->name); offset += strlen(measure->name) + 1; } /* give birth to node */ ws_connected++; node->worldsens = NODE_CONNECTED; node_birth(node->id); WSNET_S_DBG_DBG("WSNET2:: <-- CONNECT(%d/%d) (ip: %d)\n", ws_connected, ws_count, pkt->node_id); WSNET_S_DBG_DBG("WSNET2:: --> RP (seq: %"PRId64") (rp seq: %"PRId64", period: %"PRId64", rp:%"PRId64")\n", ws_seq, ws_nsyncseq, ws_nsync - ws_csync, ws_nsync); /* send response */ worldsens_packet_display(&pkt0); worldsens_packet_hton(&pkt0); wsens_srv_send(addr, (char *) &pkt0, sizeof(struct _worldsens_s_connect_rsp_ok)); }
void MEDIA_TX(call_t *c, packet_t *packet) { int i = get_node_count(); node_t *node = get_node_by_id(c->node); uint64_t clock; /* check wether node is active */ if (node->state != NODE_ACTIVE) { packet_dealloc(packet); return; } /* edit by Loic Lemaitre */ if (node->worldsens == NODE_LOCAL) { /* WORLDSENS MODE? -> radio part is simulated in wsim */ /* fill packet info */ packet->node = c->node; packet->antenna = c->from; packet->txdBm = radio_get_power(c); packet->channel = radio_get_channel(c); packet->modulation = radio_get_modulation(c); packet->Tb = radio_get_Tb(c); //packet->duration = packet->size * packet->Tb * 8; /* edit by Quentin Lampin <*****@*****.**> */ packet->duration = packet->real_size * packet->Tb; /* end of edition */ packet->clock0 = get_time(); packet->clock1 = packet->clock0 + packet->duration; /* scheduler tx_end event */ scheduler_add_tx_end(packet->clock1, c, packet); } /* end of edition */ /* scheduler rx_begin event */ #ifdef N_DAS_O if (propagation_range) { void *rx_nodes; node_t *rx_node; rx_nodes = spadas_rangesearch(location, NULL, &(node->position), propagation_range); while ((rx_node = (node_t *) das_pop(rx_nodes)) != NULL) { double derive = distance(&(node->position), &(rx_node->position)) / 0.3; bundle_t *bundle = get_bundle_by_id(rx_node->bundle); int i; if (rx_node->state == NODE_DEAD) { continue; } for (i = 0; i < bundle->antenna.size; i++) { entity_t *entity = get_entity_by_id(bundle->antenna.elts[i]); call_t c0 = {entity->id, rx_node->id, -1}; packet_t *packet_rx = packet_rxclone(packet); clock = packet->clock0 + ((uint64_t) derive); packet_rx->clock0 = clock; packet_rx->clock1 = clock + packet->duration; scheduler_add_rx_begin(clock, &c0, packet_rx); } } das_destroy(rx_nodes); } else { while (i--) { node_t *rx_node = get_node_by_id(i); double derive = distance(&(node->position), &(rx_node->position)) / 0.3; bundle_t *bundle = get_bundle_by_id(rx_node->bundle); int i; if (rx_node->state == NODE_DEAD) { continue; } for (i = 0; i < bundle->antenna.size; i++) { entity_t *entity = get_entity_by_id(bundle->antenna.elts[i]); call_t c0 = {entity->id, rx_node->id, -1}; packet_t *packet_rx = packet_rxclone(packet); clock = packet->clock0 + ((uint64_t) derive); packet_rx->clock0 = clock; packet_rx->clock1 = clock + packet->duration; scheduler_add_rx_begin(clock, &c0, packet_rx); } } } #else /* N_DAS_O */ while (i--) { node_t *rx_node = get_node_by_id(i); double dist = distance(&(node->position), &(rx_node->position)); double derive = dist / 0.3; bundle_t *bundle = get_bundle_by_id(rx_node->bundle); int i; if (rx_node->state == NODE_DEAD) { continue; } if ((propagation_range) && (dist > propagation_range)) { continue; } for (i = 0; i < bundle->antenna.size; i++) { entity_t *entity = get_entity_by_id(bundle->antenna.elts[i]); call_t c0 = {entity->id, rx_node->id, -1}; packet_t *packet_rx = packet_rxclone(packet); clock = packet->clock0 + ((uint64_t) derive); packet_rx->clock0 = clock; packet_rx->clock1 = clock + packet->duration; scheduler_add_rx_begin(clock, &c0, packet_rx); } } #endif /* N_DAS_O */ }