48 instant_noise_power(0),
59 Stats(mod_id,stck_id),
62 instant_noise_power(0),
74 double sinr,
double ber,
double per,
bool error)
99 : TclClass(
"Module/UW/PHYSICAL")
110 : modulation_name_(
"BPSK")
111 , time_ready_to_end_rx_(0)
118 , Interference_Model(
"CHUNK")
119 , tot_ctrl_pkts_lost(0)
121 , Transmitted_bytes_(0)
122 , errorCtrlPktsInterf(0)
123 , collisionDataCTRL(0)
126 , interference_(nullptr)
129 bind(
"rx_power_consumption_", &
rx_power_);
130 bind(
"tx_power_consumption_", &
tx_power_);
143 Tcl &tcl = Tcl::instance();
146 if (strcasecmp(argv[1],
"getTxTime") == 0) {
150 }
else if (strcasecmp(argv[1],
"getRxTime") == 0) {
154 }
else if (strcasecmp(argv[1],
"getConsumedEnergyTx") == 0) {
158 }
else if (strcasecmp(argv[1],
"getConsumedEnergyRx") == 0) {
163 }
else if (strcasecmp(argv[1],
"getTransmittedBytes") == 0) {
167 }
else if (strcasecmp(argv[1],
"getTotPktsLost") == 0) {
170 }
else if (strcasecmp(argv[1],
"getCollisionsDATAvsCTRL") == 0) {
173 }
else if (strcasecmp(argv[1],
"getCollisionsCTRL") == 0) {
176 }
else if (strcasecmp(argv[1],
"getCollisionsDATA") == 0) {
179 }
else if (strcasecmp(argv[1],
"getTotCtrlPktsLost") == 0) {
182 }
else if (strcasecmp(argv[1],
"getErrorCtrlPktsInterf") == 0) {
186 }
else if (argc == 3) {
187 if (strcasecmp(argv[1],
"modulation") == 0) {
194 std::cerr <<
"Empty or wrong name for the modulation scheme"
199 }
else if (strcasecmp(argv[1],
"setInterferenceModel") == 0) {
203 std::cerr <<
"Empty or wrong name of the Interference Model: "
204 "CHUNK or MEANPOWER are valid interference models"
209 }
else if (strcasecmp(argv[1],
"setInterference") == 0) {
218 return UnderwaterMPhyBpsk::command(argc, argv);
223 hdr_cmn *ch = HDR_CMN(p);
224 hdr_MPhy *ph = HDR_MPHY(p);
226 if (ch->direction() == hdr_cmn::UP)
228 ph->dstSpectralMask = getRxSpectralMask(p);
229 ph->dstPosition = getPosition();
230 ph->dstAntenna = getRxAntenna(p);
232 assert(ph->dstSpectralMask);
233 assert(ph->dstPosition);
235 ph->Pr = getRxPower(p);
238 p->txinfo_.CPThresh = 0;
242 ph->Pn = getNoisePower(p);
250 ph->worth_tracing =
true;
254 PacketEvent *pe =
new PacketEvent(p);
255 Scheduler::instance().schedule(&rxtimer, pe, ph->duration);
277 ph->rxtime = ph->txtime;
279 ph->worth_tracing =
false;
281 ph->srcSpectralMask = getTxSpectralMask(p);
282 ph->srcAntenna = getTxAntenna(p);
283 ph->srcPosition = getPosition();
284 ph->dstSpectralMask = 0;
287 ph->modulationType = getModulationType(p);
288 ph->duration = getTxDuration(p);
290 ph->Pt = getTxPower(p);
292 assert(ph->srcSpectralMask);
293 assert(ph->srcPosition);
294 assert(ph->duration > 0);
297 PacketEvent *pe =
new PacketEvent(p->copy());
298 Scheduler::instance().schedule(&txtimer, pe, ph->duration);
306 hdr_cmn *ch = HDR_CMN(p);
307 hdr_MPhy *ph = HDR_MPHY(p);
314 return UnderwaterMPhyBpsk::endTx(p);
320 hdr_mac *mach = HDR_MAC(p);
321 hdr_MPhy *ph = HDR_MPHY(p);
323 static int mac_addr = -1;
325 ClMsgPhy2MacAddr msg;
327 mac_addr = msg.getAddr();
329 if ((PktRx == 0) && (txPending ==
false)) {
332 double snr_dB = 10 * log10(ph->Pr / ph->Pn);
334 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
336 <<
"snr_dB = " << snr_dB
337 <<
"; AcquisitionThreshold_dB_ = "
338 << getAcquisitionThreshold() <<
" pr "
339 << 10 * log10(ph->Pr) <<
" pn " << 10 * log10(ph->Pn)
340 <<
" end " << NOW + ph->duration <<
" src "
341 << HDR_CMN(p)->prev_hop_ <<
" dest "
342 << HDR_CMN(p)->next_hop() <<
" size "
343 << HDR_CMN(p)->size() << std::endl;
344 if (snr_dB > getAcquisitionThreshold()) {
345 if (ph->modulationType == modid) {
351 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
353 <<
" sync on PktRx = " << PktRx <<
" end "
354 << NOW + HDR_CMN(p)->txtime() <<
" src "
355 << HDR_CMN(p)->prev_hop_ <<
" dest "
356 << HDR_CMN(p)->next_hop() <<
" size "
357 << HDR_CMN(p)->size() << std::endl;
361 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
362 <<
")::startRx() dropping pkt, wrong mod id"
364 if ((mach->macDA() == mac_addr) &&
365 (mach->ftype() != MF_CONTROL)) {
367 }
else if ((mach->macDA() == mac_addr) &&
368 (mach->ftype() == MF_CONTROL)) {
374 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
375 <<
")::startRx() dropping pkt, below threshold"
377 incrErrorPktsNoise();
378 if (mach->ftype() != MF_CONTROL) {
380 }
else if (mach->ftype() == MF_CONTROL) {
384 }
else if (txPending ==
true) {
386 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
387 <<
")::startRx() dropping pkt, tx pending" << std::endl;
388 if (mach->ftype() != MF_CONTROL) {
391 if (mach->ftype() == MF_CONTROL) {
395 if (mach->ftype() != MF_CONTROL) {
397 }
else if (mach->ftype() == MF_CONTROL) {
405 hdr_cmn *ch = HDR_CMN(p);
406 hdr_MPhy *ph = HDR_MPHY(p);
407 hdr_mac *mach = HDR_MAC(p);
410 static int mac_addr = -1;
412 ClMsgPhy2MacAddr msg;
414 mac_addr = msg.getAddr();
421 int nbits = ch->size() * 8;
422 double x = RNG::defaultrng()->uniform_double();
425 double interference_power = 0;
428 const PowerChunkList &power_chunk_list =
430 if (power_chunk_list.size() < 1) {
432 sinr = ph->Pr / ph->Pn;
433 per_ni =
getPER(sinr, nbits, p);
434 ber_ni =
getPER(sinr, 1, p);
435 error_ni = x <= per_ni;
437 for (PowerChunkList::const_iterator itInterf =
438 power_chunk_list.begin();
439 itInterf != power_chunk_list.end();
441 int nbits2 = itInterf->second * BitRate_;
442 interference_power = itInterf->first;
443 sinr = ph->Pr / (ph->Pn + itInterf->first);
444 per_ni =
getPER(sinr, nbits2, p);
445 ber_ni =
getPER(sinr, 1, p);
446 x = RNG::defaultrng()->uniform_double();
447 error_ni = x <= per_ni;
455 sinr = ph->Pr / (ph->Pn + interference_power);
456 per_ni =
getPER(sinr, nbits, p);
457 ber_ni =
getPER(sinr, 1, p);
458 error_ni = x <= per_ni;
460 std::cerr <<
"Please choose the right interference model "
461 "to use: CHUNK or MEANPOWER"
468 interference_power = ph->Pi;
469 sinr = ph->Pr / (ph->Pn + ph->Pi);
470 per_ni =
getPER(sinr, nbits, p);
471 ber_ni =
getPER(sinr, 1, p);
472 error_ni = x <= per_ni;
475 if (interference_power < (ph->Pn / 10)) {
482 uwphystats->
updateStats(getId(),getStackId(), ph->Pr,
483 ph->Pn, interference_power, sinr, ber_ni, per_ni,
484 (error_n > 0 || error_ni > 0));
491 Scheduler::instance().clock();
496 Scheduler::instance().clock() + ph->duration;
498 ch->error() = error_n || error_ni;
503 << NOW <<
" UnderwaterPhysical(" << mac_addr
504 <<
")::endRx() packet " << ch->uid()
505 <<
" contains errors due to noise and interference."
508 }
else if (error_n == 1) {
510 std::cout << NOW <<
" UnderwaterPhysical(" << mac_addr
511 <<
")::endRx() packet " << ch->uid()
512 <<
" contains errors due to noise." << std::endl;
517 incrErrorPktsNoise();
518 if (mach->ftype() != MF_CONTROL) {
520 }
else if (mach->ftype() == MF_CONTROL) {
523 }
else if (error_ni) {
524 if (mach->ftype() != MF_CONTROL) {
525 incrErrorPktsInterf();
527 if (interferent_pkts.second >= 1) {
530 if (interferent_pkts.first > 0) {
534 }
else if (mach->ftype() == MF_CONTROL) {
537 if (interferent_pkts.first > 0) {
555 double snr_with_penalty = _snr * pow(10, RxSnrPenalty_dB_ / 10.0);
559 ber_ = 0.5 * erfc(sqrt(snr_with_penalty));
561 ber_ = 0.5 * exp(-snr_with_penalty / 2);
564 ber_ = (1 / this->
log2(M)) *
568 ber_ = (1 / this->
log2(M)) *
572 ber_ = (1 / this->
log2(M)) *
576 if (_nbits == 1) {
return ber_;}
578 return 1 - pow(1 - ber_, _nbits);
591 if (m->type() == CLMSG_STATS)
594 (
dynamic_cast<ClMsgStats*
>(m))->setStats(stats_ptr);
597 return UnderwaterMPhyBpsk::recvSyncClMsg(m);
602 Packet *temp = Packet::alloc();
603 hdr_MPhy *ph = HDR_MPHY(temp);
604 ph->dstSpectralMask = getRxSpectralMask(temp);
605 ph->dstPosition = getPosition();
606 ph->dstAntenna = getRxAntenna(temp);
607 assert(ph->dstSpectralMask);
608 assert(ph->dstPosition);
610 ph->srcSpectralMask = getTxSpectralMask(temp);
611 ph->srcAntenna = getTxAntenna(temp);
612 ph->srcPosition = getPosition();
613 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...
virtual void endRx(Packet *p)
Handles the end of a packet reception.
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.
UnderwaterPhysical()
Constructor of UnderwaterPhysical class.
int recvSyncClMsg(ClMessage *m)
recv syncronous cross layer messages to require an operation from another module
double tx_power_
Power required 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.
std::string modulation_name_
Modulation scheme name.
double Get_Energy_Rx()
Returns the energy (in Joule) spent by the node in reception.
int getError_CtrlPktsInterf()
virtual void endTx(Packet *p)
Handles the end of a packet transmission.
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.
virtual void updateInstantaneousStats()
Update the stats before sending them through crosslayer message.
virtual void startRx(Packet *p)
Handles the start of a reception.
virtual void recv(Packet *)
recv method.
const double log2(const double &_input) const
double Get_Rx_Time()
Returns the time (in seconds) spent by the node in reception.
double Energy_Tx_
Energy (in Joule) spent by the node in transmission.
double Get_Energy_Tx()
Returns the energy (in Joule) spent by the node in transmission.
double rx_power_
Power required in reception.
void incrCollisionCTRL()
Increment the number of CTRL pkts discarded due to a collision.
void incrCollisionDATAvsCTRL()
Increment the number of collisions DATA/CTRL.
double Get_Transmitted_bytes()
Returns the number of bytes transmitted.
double time_ready_to_end_rx_
Used to keep track of the arrival time.
int getTot_CtrlPkts_lost()
double Get_Tx_Time()
Returns the time (in seconds) spent by the node in transmission.
int getCollisionsDATAvsCTRL()
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 ~UnderwaterPhysical()
Destructor of UnderwaterPhysical class.
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 *)
UwPhysicalStats()
Constructor of UwPhysicalStats class.
double last_per
BER of the last received packet.
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,...
bool has_error
PER of the last received packet.
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.