43#include <phymac-clmsg.h>
52 , instant_noise_power(0)
53 , last_interf_power(0)
61 : Stats(mod_id, stck_id)
65 , instant_noise_power(0)
66 , last_interf_power(0)
76 double noise_pwr,
double interf_pwr,
double sinr,
double ber,
77 double per,
bool error)
101 : TclClass(
"Module/UW/PHYSICAL")
112 : modulation_name_(
"BPSK")
113 , time_ready_to_end_rx_(0)
118 , Transmitted_bytes_(0)
122 , tot_ctrl_pkts_lost(0)
123 , errorCtrlPktsInterf(0)
124 , collisionDataCTRL(0)
127 , Interference_Model(
"CHUNK")
128 , interference_(nullptr)
130 bind(
"rx_power_consumption_", &
rx_power_);
131 bind(
"tx_power_consumption_", &
tx_power_);
144 Tcl &tcl = Tcl::instance();
147 if (strcasecmp(argv[1],
"getTxTime") == 0) {
150 }
else if (strcasecmp(argv[1],
"getRxTime") == 0) {
153 }
else if (strcasecmp(argv[1],
"getConsumedEnergyTx") == 0) {
156 }
else if (strcasecmp(argv[1],
"getConsumedEnergyRx") == 0) {
159 }
else if (strcasecmp(argv[1],
"getTransmittedBytes") == 0) {
162 }
else if (strcasecmp(argv[1],
"getTotPktsLost") == 0) {
165 }
else if (strcasecmp(argv[1],
"getCollisionsDATAvsCTRL") == 0) {
168 }
else if (strcasecmp(argv[1],
"getCollisionsCTRL") == 0) {
171 }
else if (strcasecmp(argv[1],
"getCollisionsDATA") == 0) {
174 }
else if (strcasecmp(argv[1],
"getTotCtrlPktsLost") == 0) {
177 }
else if (strcasecmp(argv[1],
"getErrorCtrlPktsInterf") == 0) {
181 }
else if (argc == 3) {
182 if (strcasecmp(argv[1],
"modulation") == 0) {
189 tcl.result(
"Empty or wrong name for the modulation scheme");
194 }
else if (strcasecmp(argv[1],
"setInterferenceModel") == 0) {
199 "Empty or wrong name of the Interference Model: "
200 "CHUNK or MEANPOWER are valid interference models");
205 }
else if (strcasecmp(argv[1],
"setInterference") == 0) {
215 return UnderwaterMPhyBpsk::command(argc, argv);
221 hdr_cmn *ch = HDR_CMN(p);
222 hdr_MPhy *ph = HDR_MPHY(p);
224 if (ch->direction() == hdr_cmn::UP) {
225 ph->dstSpectralMask = getRxSpectralMask(p);
226 ph->dstPosition = getPosition();
227 ph->dstAntenna = getRxAntenna(p);
229 assert(ph->dstSpectralMask);
230 assert(ph->dstPosition);
232 ph->Pr = getRxPower(p);
235 p->txinfo_.CPThresh = 0;
238 ph->Pn = getNoisePower(p);
245 ph->worth_tracing =
true;
248 PacketEvent *pe =
new PacketEvent(p);
249 Scheduler::instance().schedule(&rxtimer, pe, ph->duration);
265 ph->rxtime = ph->txtime;
267 ph->worth_tracing =
false;
269 ph->srcSpectralMask = getTxSpectralMask(p);
270 ph->srcAntenna = getTxAntenna(p);
271 ph->srcPosition = getPosition();
272 ph->dstSpectralMask = 0;
275 ph->modulationType = getModulationType(p);
276 ph->duration = getTxDuration(p);
278 ph->Pt = getTxPower(p);
280 assert(ph->srcSpectralMask);
281 assert(ph->srcPosition);
282 assert(ph->duration > 0);
285 PacketEvent *pe =
new PacketEvent(p->copy());
286 Scheduler::instance().schedule(&txtimer, pe, ph->duration);
295 hdr_cmn *ch = HDR_CMN(p);
296 hdr_MPhy *ph = HDR_MPHY(p);
303 return UnderwaterMPhyBpsk::endTx(p);
309 hdr_mac *mach = HDR_MAC(p);
310 hdr_MPhy *ph = HDR_MPHY(p);
312 static int mac_addr = -1;
314 ClMsgPhy2MacAddr msg;
316 mac_addr = msg.getAddr();
318 if ((PktRx == 0) && (txPending ==
false)) {
321 std::stringstream log_sstr;
322 double snr_dB = 10 * log10(ph->Pr / ph->Pn);
324 log_sstr <<
"startRx(Packet *)::"
325 <<
"snr_dB = " << snr_dB
326 <<
"; AcquisitionThreshold_dB_ = " << getAcquisitionThreshold()
327 <<
" pr " << 10 * log10(ph->Pr) <<
" pn " << 10 * log10(ph->Pn)
328 <<
" end " << NOW + ph->duration <<
" src "
329 << HDR_CMN(p)->prev_hop_ <<
" dest " << HDR_CMN(p)->next_hop()
330 <<
" size " << HDR_CMN(p)->size();
331 printOnLog(Logger::LogLevel::DEBUG,
"UWPHY", log_sstr.str());
333 if (snr_dB > getAcquisitionThreshold()) {
334 if (ph->modulationType == modid) {
341 log_sstr <<
"startRx(Packet *)::"
342 <<
"sync on PktRx = " << PktRx <<
" end "
343 << NOW + HDR_CMN(p)->txtime() <<
" src "
344 << HDR_CMN(p)->prev_hop_ <<
" dest "
345 << HDR_CMN(p)->next_hop() <<
" size "
346 << HDR_CMN(p)->size();
347 printOnLog(Logger::LogLevel::DEBUG,
"UWPHY", log_sstr.str());
351 printOnLog(Logger::LogLevel::DEBUG,
353 "startRx(Packet *)::dropping pkt, wrong modid");
355 if ((mach->macDA() == mac_addr) &&
356 (mach->ftype() != MF_CONTROL)) {
358 }
else if ((mach->macDA() == mac_addr) &&
359 (mach->ftype() == MF_CONTROL)) {
364 printOnLog(Logger::LogLevel::DEBUG,
366 "startRx(Packet *)::dropping pkt, below threshold");
368 incrErrorPktsNoise();
369 if (mach->ftype() != MF_CONTROL) {
371 }
else if (mach->ftype() == MF_CONTROL) {
375 }
else if (txPending ==
true) {
376 printOnLog(Logger::LogLevel::DEBUG,
378 "startRx(Packet *)::dropping pkt, tx pending");
380 if (mach->ftype() != MF_CONTROL) {
383 if (mach->ftype() == MF_CONTROL) {
387 if (mach->ftype() != MF_CONTROL) {
389 }
else if (mach->ftype() == MF_CONTROL) {
398 hdr_cmn *ch = HDR_CMN(p);
399 hdr_MPhy *ph = HDR_MPHY(p);
400 hdr_mac *mach = HDR_MAC(p);
403 ClMsgPhy2MacAddr msg;
411 int nbits = ch->size() * 8;
412 double x = RNG::defaultrng()->uniform_double();
415 double interference_power = 0;
418 const PowerChunkList &power_chunk_list =
420 if (power_chunk_list.size() < 1) {
422 sinr = ph->Pr / ph->Pn;
423 per_ni =
getPER(sinr, nbits, p);
424 ber_ni =
getPER(sinr, 1, p);
425 error_ni = x <= per_ni;
427 for (PowerChunkList::const_iterator itInterf =
428 power_chunk_list.begin();
429 itInterf != power_chunk_list.end();
431 int nbits2 = itInterf->second * BitRate_;
432 interference_power = itInterf->first;
433 sinr = ph->Pr / (ph->Pn + itInterf->first);
434 per_ni =
getPER(sinr, nbits2, p);
435 ber_ni =
getPER(sinr, 1, p);
436 x = RNG::defaultrng()->uniform_double();
437 error_ni = x <= per_ni;
445 sinr = ph->Pr / (ph->Pn + interference_power);
446 per_ni =
getPER(sinr, nbits, p);
447 ber_ni =
getPER(sinr, 1, p);
448 error_ni = x <= per_ni;
450 printOnLog(Logger::LogLevel::ERROR,
452 "endRx(Packet *)::Please choose the right "
453 "interference model "
454 "to use: CHUNK or MEANPOWER");
461 interference_power = ph->Pi;
462 sinr = ph->Pr / (ph->Pn + ph->Pi);
463 per_ni =
getPER(sinr, nbits, p);
464 ber_ni =
getPER(sinr, 1, p);
465 error_ni = x <= per_ni;
468 if (interference_power < (ph->Pn / 10)) {
483 (error_n > 0 || error_ni > 0));
490 Scheduler::instance().clock();
495 Scheduler::instance().clock() + ph->duration;
497 ch->error() = error_n || error_ni;
501 printOnLog(Logger::LogLevel::ERROR,
503 "endRx(Packet *)::packet " +
504 to_string(ch->uid()) +
505 " contains errors due to noise and "
508 }
else if (error_n == 1) {
510 printOnLog(Logger::LogLevel::ERROR,
512 "endRx(Packet *)::packet " +
513 to_string(ch->uid()) +
514 " contains errors due to noise");
519 incrErrorPktsNoise();
520 if (mach->ftype() != MF_CONTROL) {
522 }
else if (mach->ftype() == MF_CONTROL) {
525 }
else if (error_ni) {
526 if (mach->ftype() != MF_CONTROL) {
527 incrErrorPktsInterf();
529 if (interferent_pkts.second >= 1) {
532 if (interferent_pkts.first > 0) {
536 }
else if (mach->ftype() == MF_CONTROL) {
539 if (interferent_pkts.first > 0) {
557 double snr_with_penalty = _snr * pow(10, RxSnrPenalty_dB_ / 10.0);
561 ber_ = 0.5 * erfc(sqrt(snr_with_penalty));
563 ber_ = 0.5 * exp(-snr_with_penalty / 2);
566 ber_ = (1 / this->
log2(M)) *
570 ber_ = (1 / this->
log2(M)) *
574 ber_ = (1 / this->
log2(M)) *
582 return 1 - pow(1 - ber_, _nbits);
595 if (m->type() == CLMSG_STATS) {
597 (
dynamic_cast<ClMsgStats *
>(m))->setStats(stats_ptr);
600 return UnderwaterMPhyBpsk::recvSyncClMsg(m);
606 Packet *temp = Packet::alloc();
607 hdr_MPhy *ph = HDR_MPHY(temp);
608 ph->dstSpectralMask = getRxSpectralMask(temp);
609 ph->dstPosition = getPosition();
610 ph->dstAntenna = getRxAntenna(temp);
611 assert(ph->dstSpectralMask);
612 assert(ph->dstPosition);
614 ph->srcSpectralMask = getTxSpectralMask(temp);
615 ph->srcAntenna = getTxAntenna(temp);
616 ph->srcPosition = getPosition();
617 assert(ph->srcSpectralMask);
ClMessage_t CLMSG_UWPHY_LOSTPKT
ClMsgUwPhyGetLostPkts should be used by a layer to ask the phy how many packets it discarded from the...
void incrTot_pkts_lost()
Increment the number of packets discarded.
std::string Interference_Model
Interference calcuation mode chosen: CHUNK model or MEANPOWER model.
int getCollisionsDATAvsCTRL() const
UnderwaterPhysical()
Constructor of UnderwaterPhysical class.
double tx_power_
Power required in transmission.
double get_prob_error_symbol_mpsk(const double &_snr, const uint32_t _M) const
double Tx_Time_
Time (in seconds) spent by the node in transmission.
uwinterference * interference_
Pointer to the interference module.
std::string modulation_name_
Modulation scheme name.
virtual double consumedEnergyTx(const double &_duration) const
Compute the energy (in Joule) spent by the modem in transmission.
virtual int command(int, const char *const *) override
TCL command interpreter.
double Get_Energy_Rx() const
Returns the energy (in Joule) spent by the node in reception.
int getCollisionsCTRL() const
void incrErrorCtrlPktsInterf()
Increment the number of CTRL packets discarded due to interference.
int getError_CtrlPktsInterf() const
int getTot_CtrlPkts_lost() const
double Energy_Rx_
Energy (in Joule) spent by the node in transmission.
double Transmitted_bytes_
Number of bytes transmitted.
virtual void updateInstantaneousStats()
Update the stats before sending them through crosslayer message.
double Get_Energy_Tx() const
Returns the energy (in Joule) spent by the node in transmission.
virtual void endTx(Packet *p) override
Handles the end of a packet transmission.
virtual void recv(Packet *) override
recv method.
double Energy_Tx_
Energy (in Joule) spent by the node in transmission.
double rx_power_
Power required in reception.
virtual void startRx(Packet *p) override
Handles the start of a reception.
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 rx time.
virtual double consumedEnergyRx(const double &_duration) const
Compute the energy (in Joule) spent by the modem in reception.
int recvSyncClMsg(ClMessage *m) override
recv syncronous cross layer messages to require an operation from another module
double Get_Tx_Time() const
Returns the time (in seconds) spent by the node in transmission.
int getTot_pkts_lost() const
virtual void endRx(Packet *p) override
Handles the end of a packet reception.
double log2(const double &_input) const
double Rx_Time_
Time (in seconds) spent by the node in reception.
virtual ~UnderwaterPhysical()
Destructor of UnderwaterPhysical class.
void incrCollisionDATA()
Increment the number of DATA pkts discarded due to a collision.
virtual double getPER(double snr, int nbits, Packet *_p)
Returns the packet error rate by using the length of a packet and the information contained in the pa...
void incrTotCrtl_pkts_lost()
Increment the number of CTRL packets discarded.
int getCollisionsDATA() const
double Get_Transmitted_bytes() const
Returns the number of bytes transmitted.
double Get_Rx_Time() const
Returns the time (in seconds) spent by the node in reception.
TclObject * create(int, const char *const *)
UwPhysicalStats()
Constructor of UwPhysicalStats class.
double last_per
BER of the last received packet.
double last_rx_power
True if last packet wasn't correctly received.
virtual void updateStats(int mod_id, int stck_id, double rx_pwr, double noise_pwr, double interf_pwr, double sinr, double ber, double per, bool error)
Method to update stats with the param of last received packet.
virtual Stats * clone() const
Virtual method used by the Module class in order to copy its stats an a generic fashion,...
double last_ber
SINR of the last received packet.
double last_noise_power
Power of the last received packet.
double last_interf_power
Noise power measured on query.
double last_sinr
Interference power of the last rx packet.
double instant_noise_power
Noise power of the last received packet.
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.
std::pair< int, int > counter
counter of collisions
Definition of ClMsgUwMmac class.
UwPhysicalClass class_module_uwphysical
Definition of UwPhysical class.
Utilities to manage stats.