49 : TclClass(
"Module/UW/OFDM/PHY")
61 bufferSize_(50), buffered_pkt_num(0), current_rcvs(0), nodeNum_(-1), centerFreq_(0),
62 subCarrier_(-1), nodeID_(-1), tx_busy_(0), powerScaling(1)
76 Tcl &tcl = Tcl::instance();
79 if (strcasecmp(argv[1],
"getTotalDelay") == 0)
85 else if (strcasecmp(argv[1],
"getNodeNum") == 0)
90 else if (strcasecmp(argv[1],
"getSubCarNum") == 0)
95 else if (strcasecmp(argv[1],
"showSubCar") == 0)
100 else if (strcasecmp(argv[1],
"getNodeID") == 0)
105 else if (strcasecmp(argv[1],
"getSentUpPkts") == 0)
110 else if (strcasecmp(argv[1],
"getLowSnrPktLost") == 0)
115 else if (strcasecmp(argv[1],
"getNoiseErrPktLost") == 0)
120 else if (strcasecmp(argv[1],
"getCollErrPktLost") == 0)
125 else if (strcasecmp(argv[1],
"getTxPenPktLost") == 0)
130 else if (strcasecmp(argv[1],
"getTxPenCtrlLost") == 0)
135 else if (strcasecmp(argv[1],
"getFreqCollPktLost") == 0)
140 else if (strcasecmp(argv[1],
"getModErrPktLost") == 0)
145 else if (strcasecmp(argv[1],
"getTransmissionTime") == 0)
150 else if (strcasecmp(argv[1],
"getCtrlFCollPktLost") == 0)
155 else if (strcasecmp(argv[1],
"getCtrlCerrPktLost") == 0)
160 else if (strcasecmp(argv[1],
"getPhyPktSent") == 0)
168 if (strcasecmp(argv[1],
"setNodeNum") == 0)
173 else if (strcasecmp(argv[1],
"setSubCarNum") == 0)
178 else if (strcasecmp(argv[1],
"setNodeID") == 0)
183 else if (strcasecmp(argv[1],
"setBufferSize") == 0)
191 if (strcasecmp(argv[1],
"setBrokenCar") == 0)
199 if (strcasecmp(argv[1],
"init_ofdm_node") == 0)
201 init_ofdm_node(atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
224 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_ <<
")::init_ofdm_node Node created" << std::endl;
239 hdr_cmn *ch = HDR_CMN(p);
240 hdr_MPhy *ph = HDR_MPHY(p);
241 hdr_mac *mach = HDR_MAC(p);
246 if (ch->direction() == hdr_cmn::UP)
249 ph->dstSpectralMask = getRxSpectralMask(p);
250 ph->dstPosition = getPosition();
251 ph->dstAntenna = getRxAntenna(p);
253 assert(ph->dstSpectralMask);
254 assert(ph->dstPosition);
256 ph->Pr = getRxPower(p);
259 p->txinfo_.CPThresh = 0;
262 cerr <<
"UwOFDMPhy ERROR: buffer overflow" << endl;
265 }
else if (ph->Pr > 0) {
269 ph->Pn = getNoisePower(p);
280 " duration is " +
dtos(ph->duration),
284 ph->worth_tracing =
true;
287 PacketEvent *pe =
new PacketEvent(p);
288 Scheduler::instance().schedule(&rxtimer, pe, ph->duration);
308 std::cerr << NOW <<
" UwOFDMPhy(" <<
nodeID_
309 <<
")::recv ATTENTION: KILLING RECEIVING PACKETS TO TRANSMIT "
318 ph->rxtime = ph->txtime;
321 ph->worth_tracing =
false;
323 ph->srcSpectralMask = getTxSpectralMask(p);
324 ph->srcAntenna = getTxAntenna(p);
325 ph->srcPosition = getPosition();
326 ph->dstSpectralMask = 0;
329 ph->modulationType = getModulationType(p);
334 int usedCarriers = 0;
341 ph->Pt = getTxPower(p) * usedCarriers /
subCarrier_;
344 ph->Pt = getTxPower(p);
346 assert(ph->srcSpectralMask);
347 assert(ph->srcPosition);
348 assert(ph->duration > 0);
351 Packet *pnew = Packet::alloc();
353 PacketEvent *pe =
new PacketEvent(p->copy());
356 " duration is " +
dtos(ph->duration),
359 Scheduler::instance().schedule(&txtimer, pe, (ph->duration));
361 temptxtime = ph->duration;
362 totTransTime += Scheduler::instance().clock() - ch->timestamp();
365 Scheduler::instance().clock(),
nodeID_);
370 std::cerr << NOW <<
" UwOFDMPhy(" <<
nodeID_
371 <<
")::recv() ERROR sending while receiving " << std::endl;
379 hdr_cmn *ch = HDR_CMN(p);
380 hdr_MPhy *ph = HDR_MPHY(p);
398 return UnderwaterMPhyBpsk::endTx(p);
403 hdr_mac *mach = HDR_MAC(p);
404 hdr_MPhy *ph = HDR_MPHY(p);
407 hdr_cmn *ch = HDR_CMN(p);
409 std::ofstream myfile;
412 static int mac_addr = -1;
414 ClMsgPhy2MacAddr msg;
416 mac_addr = msg.getAddr();
420 Scheduler::instance().clock(),
nodeID_);
425 std::to_string(overlapping),
"startRx", NOW,
nodeID_);
427 if (txPending ==
false &&
tx_busy_ ==
false && overlapping ==
false)
432 double snr_dB = 10 * log10(ph->Pr / ph->Pn);
434 if (snr_dB > getAcquisitionThreshold())
436 if (ph->modulationType == modid)
442 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_ <<
")::StartRx() Adding packet " << p
443 <<
" seq_num " << ch->uid() <<
" isnative " << ofdmph->
nativeOFDM
444 <<
" ph->Pr " << ph->Pn <<
" ph->Pn " << ph->Pn << std::endl;
462 if ((mach->macDA() == mac_addr) && (mach->ftype() != MF_CONTROL)){
465 }
else if ((mach->macDA() == mac_addr) && (mach->ftype() == MF_CONTROL)) {
474 incrErrorPktsNoise();
475 if (mach->ftype() != MF_CONTROL) {
478 }
else if (mach->ftype() == MF_CONTROL) {
482 }
else if (txPending ==
true ||
tx_busy_ ==
true) {
486 if (mach->ftype() == MF_DATA) {
490 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
491 <<
")::startRx() [PROBLEM] Dropping DATA that was for me seq_num "
492 << ch->uid() <<
" src = " << mach->macSA() <<
" bc txpending" << std::endl;
496 if (mach->ftype() == MF_RTS || mach->ftype() == MF_CTS) {
505 if (mach->ftype() == MF_DATA) {
508 std::cerr << NOW <<
" UwOFDMPhy(" <<
nodeID_
509 <<
")::startRx() [PROBLEM] Dropping DATA that was for me seq_num "
510 << ch->uid() <<
" src = " << mach->macSA() <<
" bc freqcollisions" << std::endl;
512 }
else if (mach->ftype() == MF_RTS || mach->ftype() == MF_CTS) {
527 hdr_cmn *ch = HDR_CMN(p);
528 hdr_MPhy *ph = HDR_MPHY(p);
529 hdr_mac *mach = HDR_MAC(p);
533 static int mac_addr = -1;
534 ClMsgPhy2MacAddr msg;
537 mac_addr = msg.getAddr();
539 bool pktfound =
false;
543 "EndRx()", Scheduler::instance().clock(),
nodeID_);
547 hdr_cmn *chx = HDR_CMN(&*x);
548 hdr_mac *machx = HDR_MAC(&*x);
550 if ((chx->uid() == ch->uid()) && (ch->ptype() == chx->ptype())
551 && (mach->macDA() == machx->macDA()) && (mach->macSA() == machx->macSA()))
554 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_ <<
")::EndRx() Packet found in pktqueue_. current_p "
555 << current_p <<
" isNative " << ofdmph->
nativeOFDM <<
" seq_num " << ch->uid()
556 <<
" dest " << mach->macDA() << std::endl;
569 ch = HDR_CMN(current_p);
570 ph = HDR_MPHY(current_p);
571 mach = HDR_MAC(current_p);
580 int nbits = ch->size() * 8;
581 double interference_power;
582 double x = RNG::defaultrng()->uniform_double();
584 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
585 <<
")::EndRx() FOUND IN QUEUE packet seq_num " << ch->uid()
586 <<
" isnative " << ofdmph->
nativeOFDM <<
" ph->Pr " << ph->Pn
587 <<
" ph->Pn " << ph->Pn << std::endl;
593 std::cout << NOW <<
" UwOFDMPhy::endRx(" <<
nodeID_
594 <<
") getOFDMPER with noise. ph->Pr " << ph->Pr
595 <<
" Ph->Pn " << ph->Pn << std::endl;
597 per_n =
getOFDMPER(ph->Pr / ph->Pn, nbits, current_p);
600 std::cout << NOW <<
" UwOFDMPhy::endRx(" <<
nodeID_
601 <<
") getPER with noise. ph->Pr " << ph->Pr <<
" Ph->Pn " << ph->Pn << std::endl;
602 per_n =
getPER(ph->Pr / ph->Pn, nbits, p);
605 bool error_n = x <= per_n;
625 per_ni =
getOFDMPER(ph->Pr / (ph->Pn + interference_power), nbits, p);
627 per_ni =
getPER(ph->Pr / (ph->Pn + interference_power), nbits, p);
628 error_ni = x <= per_ni;
631 std::cout <<
"Interference from x = " << x <<
" interf_power = "
632 << interference_power <<
" per_ni " << per_ni << std::endl;
634 std::cerr <<
"Please choose only MEANPOWER as "
643 per_ni =
getOFDMPER(ph->Pr / (ph->Pn + ph->Pi),
646 per_ni =
getPER(ph->Pr / (ph->Pn + ph->Pi),
648 error_ni = x <= per_ni;
654 Scheduler::instance().clock();
663 ch->error() = error_ni || error_n;
667 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
668 <<
")::endRx() error due to noise. PER = " << per_n << std::endl;
670 if (mach->ftype() == MF_DATA) {
673 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
674 <<
")::endRx() [PROBLEM] Dropping DATA for me seq_num "
675 << ch->uid() <<
" src = " << mach->macSA() <<
" bc noise" << std::endl;
681 << NOW <<
" UwOFDMPhy(" <<
nodeID_
682 <<
")::endRx() error due to interference. PER = " << per_ni
683 <<
" Interference Power " << interference_power << std::endl;
684 if (mach->ftype() == MF_DATA)
688 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
689 <<
")::endRx() [PROBLEM] Dropping DATA for me seq_num "
690 << ch->uid() <<
" src = " << mach->macSA() <<
" bc interference"
691 <<
" pwr " << ph->Pr <<
" noise " << ph->Pn <<
" interf_pwr "
692 << interference_power << std::endl;
700 << NOW <<
" UwOFDMPhy(" <<
nodeID_
701 <<
")::endRx() packet " << ch->uid()
702 <<
" contains errors due to noise and interference."
705 else if (error_n == 1)
707 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
708 <<
")::endRx() packet " << ch->uid()
709 <<
" contains errors due to noise." << std::endl;
714 incrErrorPktsNoise();
716 if (mach->ftype() != MF_CONTROL) {
719 }
else if (mach->ftype() == MF_CONTROL) {
722 }
else if (error_ni) {
724 if (mach->ftype() != MF_CONTROL) {
726 incrErrorPktsInterf();
729 if (interferent_pkts.second >= 1) {
732 if (interferent_pkts.first > 0) {
736 }
else if (mach->ftype() == MF_CONTROL) {
742 if (interferent_pkts.first > 0) {
753 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
754 <<
")::EndRx() Packet UP DONE" << std::endl;
782 std::cerr << NOW <<
" UwOFDMPhy(" <<
nodeID_
783 <<
")::interruptReceptions() pktqueue size " <<
pktqueue_.size()
789 hdr_cmn *ch = HDR_CMN(p);
790 hdr_MPhy *ph = HDR_MPHY(p);
803 if (ofdmph->
carMod[i] ==
"BPSK")
806 else if (ofdmph->
carMod[i] ==
"QPSK")
812 std::cerr <<
"UwOFDMPhy(" <<
nodeID_ <<
")::getTxDuration() ERROR: USED BANDWIDTH = 0" << std::endl;
819 BitRate_ = ph->srcSpectralMask->getBandwidth() / 2.0;
821 new_BitRate_ = used_bw / ofdmph->
carrierNum * BitRate_;
823 double txtime = (ch->size() * 8.0 / new_BitRate_);
826 cerr <<
" ch->size(): " << ch->size() <<
" bitrate: " << BitRate_ << std::endl;
832 cerr << showpoint << NOW <<
" " << __PRETTY_FUNCTION__
833 <<
" packet size: " << ch->size()
834 <<
" tx duration: " << txtime
835 <<
" new_bitrate: " << new_BitRate_
839 " new_brate " +
dtos(new_BitRate_),
"getTxDuration", NOW,
nodeID_);
847 hdr_MPhy *ph = HDR_MPHY(p);
848 MSpectralMask *sm = getRxSpectralMask(p);
852 int ncarriers = sm->getBandwidth() / ofdmph->
carrierSize;
853 double snr_with_penalty = _snr * pow(10, RxSnrPenalty_dB_ / 10.0);
855 int usedCarriers = 0;
863 if (ofdmph->
carMod[i] ==
"BPSK")
865 tber_ = 0.5 * erfc(sqrt(snr_with_penalty));
867 else if (ofdmph->
carMod[i] ==
"QPSK")
869 tber_ = erfc(sqrt(snr_with_penalty));
871 else if (ofdmph->
carMod[i] ==
"BFSK")
873 tber_ = 0.5 * exp(-snr_with_penalty / 2);
875 else if (ofdmph->
carMod[i] ==
"8PSK")
878 tber_ = (1 / this->
log2(M)) *
881 else if (ofdmph->
carMod[i] ==
"16PSK")
884 tber_ = (1 / this->
log2(M)) *
887 else if (ofdmph->
carMod[i] ==
"32PSK")
890 tber_ = (1 / this->
log2(M)) *
894 ber_ += tber_ * ofdmph->
carriers[i];
895 usedCarriers += ofdmph->
carriers[i];
897 ber_ = ber_ / usedCarriers;
902 double per = 1 - pow(1 - ber_, _nbits);
904 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_ <<
")::getOFDMPER BER = " << ber_ <<
" PER = " << per << std::endl;
914 double actualBand = 0;
915 hdr_MPhy *ph = HDR_MPHY(p);
919 MSpectralMask *sm = getRxSpectralMask(p);
926 double noiseOFDM = getNoisePower(p) * actualBand / sm->getBandwidth();
928 std::cout << NOW <<
" UwOFDMPhy::getOFDMNoisePower actualBand " << actualBand
929 <<
" noisePower " << getNoisePower(p) <<
" noiseOFDM " << noiseOFDM << std::endl;
937 hdr_MPhy *ph = HDR_MPHY(_p);
938 double x_src = (ph->srcPosition)->getX();
939 double y_src = (ph->srcPosition)->getY();
940 double z_src = (ph->srcPosition)->getZ();
941 double x_dst = (ph->dstPosition)->getX();
942 double y_dst = (ph->dstPosition)->getY();
943 double z_dst = (ph->dstPosition)->getZ();
944 return sqrt(pow(x_src - x_dst, 2.0) + pow(y_src - y_dst, 2.0) +
945 pow(z_src - z_dst, 2.0));
954 return (dist / 1500);
968 std::cout <<
"carrier[" << i <<
"]=" << ofdmph2->
carriers[i] << std::endl;
981 std::cout <<
"WARNING: OFDM node receiving NON OFDM packet" << std::endl;
993 hdr_MPhy *ph = HDR_MPHY(p);
995 MSpectralMask *txsm = ph->srcSpectralMask;
996 MSpectralMask *rxsm = getRxSpectralMask(p);
997 double newPktStart = txsm->getFreq() - txsm->getBandwidth() / 2;
998 double newPktEnd = txsm->getFreq() + txsm->getBandwidth() / 2;
999 double nodeStart = rxsm->getFreq() - rxsm->getBandwidth() / 2;
1000 double nodeEnd = rxsm->getFreq() + rxsm->getBandwidth() / 2;
1001 double carsize = rxsm->getBandwidth() /
subCarrier_;
1005 std::cout << NOW <<
" incoming Pkt Start and End: " << newPktStart <<
" " << newPktEnd << std::endl;
1006 std::cout << NOW <<
" node Start and End: " << nodeStart <<
" " << nodeEnd << std::endl;
1011 for (
double s = nodeStart; s < nodeEnd; s = s + carsize)
1012 if ((newPktStart <= s + carsize) && (newPktEnd > s))
1015 std::cout << NOW <<
" 1 Added " << std::endl;
1023 std::cout << NOW <<
" End createOFDMhdr function" << std::endl;
1143 std::cout <<
"showSubCar() unimplemented\n"
1151 std::cerr <<
"setSubCar() unimplemented\n"
1163 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
1164 <<
")::recvSyncClMsg [get] tx_busy_ to send back is " <<
tx_busy_ << std::endl;
1171 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_
1172 <<
")::recvSyncClMsg [set] tx_busy_ received is " <<
tx_busy_ << std::endl;
1176 return UnderwaterMPhyBpsk::recvSyncClMsg(m);
1180 std::cout << NOW <<
" UwOFDMPhy(" <<
nodeID_ <<
")::plotPktQueue()" << std::endl;
1183 hdr_cmn *ch = HDR_CMN(&*x);
1184 hdr_MPhy *ph = HDR_MPHY(&*x);
1186 hdr_mac *mach = HDR_MAC(&*x);
1187 std::cout <<
"Packet " << &*x <<
" seq_num " << ch->uid()
1188 <<
" native " << ofdmph->
nativeOFDM <<
" ph->Pr " << ph->Pn
1189 <<
" ph->Pn " << ph->Pn <<
" MACDE " << mach->macDA()
1190 <<
" MACSRC " << mach->macSA() << std::endl;
ClMessage_t CLMSG_UWPHY_TX_BUSY
ClMsgUwPhyTxBusy should be and used to ask either to set or get the transmitting busy variable of a s...
void initDisplayer(int n, std::string pn, int pactive)
void printStatus(std::string st, std::string fxName, double now, int addr)
void incrTot_pkts_lost()
Increment the number of packets discarded.
std::string Interference_Model
Interference calcuation mode chosen: CHUNK model or MEANPOWER model.
virtual double consumedEnergyTx(const double &_duration)
Compute the energy (in Joule) spent by the modem in transmission.
virtual double consumedEnergyRx(const double &_duration)
Compute the energy (in Joule) spent by the modem in reception.
double Tx_Time_
Time (in seconds) spent by the node in transmission.
uwinterference * interference_
Pointer to the interference model module.
void incrErrorCtrlPktsInterf()
Increment the number of CTRL packets discarded due to interference.
virtual double getPER(double snr, int nbits, Packet *)
Returns the packet error rate by using the length of a packet and the information contained in the pa...
double Energy_Rx_
Energy (in Joule) spent by the node in transmission.
double Transmitted_bytes_
Number of bytes transmitted.
const double log2(const double &_input) const
double Energy_Tx_
Energy (in Joule) spent by the node in transmission.
void incrCollisionCTRL()
Increment the number of CTRL pkts discarded due to a collision.
void incrCollisionDATAvsCTRL()
Increment the number of collisions DATA/CTRL.
double time_ready_to_end_rx_
Used to keep track of the arrival time.
const double get_prob_error_symbol_mpsk(const double &_snr, const uint32_t _M) const
double Rx_Time_
Time (in seconds) spent by the node in reception.
virtual int command(int, const char *const *)
TCL command interpreter.
void incrCollisionDATA()
Increment the number of DATA pkts discarded due to a collision.
void incrTotCrtl_pkts_lost()
Increment the number of CTRL packets discarded.
TclObject * create(int, const char *const *)
int getModErrPktLost() const
int getTxPenPktLost() const
virtual void startRx(Packet *p)
Handles the start of a packet reception.
virtual double getDistance(Packet *)
Return the distance between source and destination.
virtual double getOFDMPER(double _snr, int _nbits, Packet *)
Returns the packet error rate by using the length of a packet and the information contained in the pa...
int getCollErrPktLost() const
UwOFDMPhy()
Constructor of UwOFDMPhy class.
int tx_busy_
transmission power might be carried out just by re-setting this value.
double getTxDuration(Packet *p)
Computes the transmission time duration depending on the used carriers.
virtual int getTotalDelay()
returns total delay
int getCtrlFCollPktLost() const
virtual int command(int, const char *const *)
TCL command interpreter.
virtual ~UwOFDMPhy()
Destructor of UwOFDMPhy class.
void init_ofdm_node(int nn, int cf, int scn, int ID)
std::vector< Packet > pktqueue_
void setBrokenCar(int, int)
void interruptReceptions()
Interrupts reception if MAC has other priorities Theoretically should never be called.
void plotPktQueue()
Plots pktqueue elements.
virtual double getOFDMNoisePower(Packet *p)
Handles the end of a transmission, redefined to scale the power into the carriers.
int getFreqCollPktLost() const
bool freqOverlap(Packet *, bool)
virtual double getPropagationDelay(Packet *)
Return the propagation delay for the packet.
virtual void endTx(Packet *p)
Handles the end of a transmission, redefined to scale the power into the carriers.
int getTxPenCtrlLost() const
double getTransmissionTime() const
void createOFDMhdr(Packet *p)
Creates an OFDM header for non-OFDM packets.
virtual void recv(Packet *)
recv method.
std::vector< double > brokenCarriers_
virtual void endRx(Packet *p)
Handles the end of a packet reception.
int getLowSnrPktLost() const
int getPhyPktSent() const
int getCtrlCErrPktLost() const
int getNoiseErrPktLost() const
int recvSyncClMsg(ClMessage *m)
Handles receiving messages from the MAC layer.
virtual counter getCounters(Packet *p)
Returns the counters of collisions.
virtual void addToInterference(Packet *p)
Add a packet to the interference calculation.
virtual double getInterferencePower(Packet *p)
Compute the average interference power for the given packet.
Header of the OFDM message with fields to implement a multi carrier system.
int carriers[MAX_CARRIERS]
string carMod[MAX_CARRIERS]
std::pair< int, int > counter
counter of collisions
UwOFDMPhyClass class_module_uwofdmphy
Definition of UwOFDMPhy class. Your can find the brief description of this physical layer in the pape...
#define HDR_OFDM(p)
alias defined to access the PROBE HEADER
Definition of ClMsgUwMmac class.