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; }
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 */ }