DESERT 3.5.1
Loading...
Searching...
No Matches
uwhmmphysical.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2021 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
39#include "uwhmmphysical.h"
40#include "mclink.h"
41#include "uwphy-clmsg.h"
42#include "uwstats-utilities.h"
43#include "mac.h"
44#include "clmsg-stats.h"
45#include <phymac-clmsg.h>
46#include <string.h>
47#include <rng.h>
48#include <packet.h>
49#include <module.h>
50#include <tclcl.h>
51#include <iostream>
52
53#define DEBUG(level,text) {if (debug_ >= level) {std::cout << NOW << " UwHMMPhysical error: "<< text << std::endl;}}
54
55Stats*
57{
58 return new UwHMMPhysicalStats( *this );
59}
60
61void
62UwHMMPhysicalStats::updateStats(int mod_id, int stck_id, double rx_pwr, double noise_pwr, double interf_pwr,
63 double sinr, double ber, double per, bool error, MCLink::ChState channel_state)
64{
65 UwPhysicalStats::updateStats(mod_id, stck_id, rx_pwr, noise_pwr, interf_pwr, sinr, ber, per, error);
67}
68
69static class UwHMMPhysicalClass : public TclClass
70{
71public:
73 : TclClass("Module/UW/HMMPHYSICAL")
74 {
75 }
76 TclObject *
77 create(int argc, const char *const * argv)
78 {
79 return (new UnderwaterHMMPhysical);
80 }
82
84 : link_map()
85 , pkts_tot_good(0)
86 , pkts_tot_medium(0)
87 , pkts_tot_bad(0)
88{
89 delete stats_ptr;
90 stats_ptr = new UwHMMPhysicalStats();
91}
92
94{
95 delete stats_ptr;
96 stats_ptr = nullptr;
97}
98
99int
100UnderwaterHMMPhysical::command(int argc, const char *const *argv)
101{
102 Tcl &tcl = Tcl::instance();
103
104 if (argc == 2) {
105 if (strcasecmp(argv[1], "getPktsTotBad") == 0) {
106 tcl.resultf("%d", getPktsTotBad());
107 return TCL_OK;
108 }
109 if (strcasecmp(argv[1], "getPktsTotMedium") == 0) {
110 tcl.resultf("%d", getPktsTotMedium());
111 return TCL_OK;
112 }
113 if (strcasecmp(argv[1], "getPktsTotGood") == 0) {
114 tcl.resultf("%d", getPktsTotGood());
115 return TCL_OK;
116 }
117 }
118 if (strcasecmp(argv[1], "setMCLink") == 0) {
119 if (argc == 4) {
120
121 auto link = dynamic_cast<MCLink *>(TclObject::lookup(argv[3]));
122 if (link) {
123 setMCLink(std::stoi(argv[2]), link);
124 return TCL_OK;
125 }
126 std::cerr << "TCL: failed cast on MCLink" << std::endl;
127 return TCL_ERROR;
128 }
129 std::cerr << "TCL error: setMCLink mac MCLink" << std::endl;
130 return TCL_ERROR;
131 }
132 return UnderwaterPhysical::command(argc, argv);
133} /* UnderwaterHMMPhysical::command */
134
135void
137{
138 link_map[mac] = link;
139} /* UnderwaterHMMPhysical::setMCLink */
140
141
142void
144 hdr_cmn *ch = HDR_CMN(p);
145 hdr_MPhy *ph = HDR_MPHY(p);
146 hdr_mac *mach = HDR_MAC(p);
147 const int mac_addr = mach->macSA();
148
149 if (PktRx != 0) {
150 if (PktRx == p) {
151
152 /* HMM model */
153 auto link = link_map.find(mac_addr);
154 if (link != link_map.end()) {
155 auto ch_state = (*link->second).updateChState();
156 bool error_hmm = false;
157 double ber_hmm = (*link->second).getBER();
158 double per_hmm = ber2per(ber_hmm,p);
159 double chance_hmm = RNG::defaultrng()->uniform_double();
160 if (per_hmm > chance_hmm) {
161 error_hmm = true;
162 }
163 incrTotPkts(ch_state);
164 /* end HMM model */
165
166 /* interference model as in UwPhysical
167 with zeroed Pn since channel noise is already modelled by HMM */
168 counter interferent_pkts;
169 int nbits = ch->size() * 8;
170 double interf_power = 0.0;
171 double perr_interf = 0.0;
172 double sinr = ph->Pr / ph->Pn;
173 bool error_interf = false;
174 double chance_interf = RNG::defaultrng()->uniform_double();
175
176 if (interference_) {
177 if (Interference_Model == "CHUNK") {
178 const PowerChunkList &power_chunk_list =
179 interference_->getInterferencePowerChunkList(p);
180 for (PowerChunkList::const_iterator itInterf =
181 power_chunk_list.begin();
182 itInterf != power_chunk_list.end();
183 itInterf++) {
184 int nbits2 = itInterf->second * BitRate_;
185 interf_power = itInterf->first;
186 if (interf_power > 0.0) {
187 perr_interf = getPER(
188 ph->Pr / interf_power, nbits2, p);
189 chance_interf = RNG::defaultrng()->uniform_double();
190 error_interf = chance_interf < perr_interf;
191 if (error_interf) {
192 break;
193 }
194 }
195 }
196 } else if (Interference_Model == "MEANPOWER") {
197 interf_power = interference_->getInterferencePower(p);
198 sinr = ph->Pr / (ph->Pn + interf_power);
199 if (interf_power > 0.0) {
200 perr_interf = getPER(
201 ph->Pr / interf_power, nbits, p);
202 error_interf = chance_interf < perr_interf;
203 }
204 } else {
205 std::cerr << "Please choose the interference model "
206 "CHUNK or MEANPOWER"
207 << std::endl;
208 exit(1);
209 }
210 interferent_pkts = interference_->getCounters(p);
211
212 } else {
213 interf_power = ph->Pi;
214 sinr = ph->Pr / (ph->Pn + ph->Pi);
215 if (interf_power > 0.0) {
216 perr_interf = getPER(ph->Pr / ph->Pi, nbits, p);
217 error_interf = chance_interf < perr_interf;
218 }
219 } /* end of interference model */
220
221 /* update and trigger the modules that collect the stats */
222 auto uwphystats = dynamic_cast<UwHMMPhysicalStats *>(stats_ptr);
223 if (uwphystats) {
224 uwphystats->updateStats(getId(),getStackId(), ph->Pr,
225 ph->Pn, interf_power, sinr, ber_hmm, per_hmm,
226 (error_hmm || error_interf),ch_state);
227 }
228
230 sendSyncClMsg(&m);
231
232 if (time_ready_to_end_rx_ > Scheduler::instance().clock()) {
233 Rx_Time_ = Rx_Time_ + ph->duration - time_ready_to_end_rx_ +
234 Scheduler::instance().clock();
235 } else {
236 Rx_Time_ += ph->duration;
237 }
239 Scheduler::instance().clock() + ph->duration;
240 Energy_Rx_ += consumedEnergyRx(ph->duration);
241
242 ch->error() = (error_hmm || error_interf);
243
244 /* update counters of UwPhysical */
245 if (error_interf) {
246 if (mach->ftype() != MF_CONTROL) {
247 incrErrorPktsInterf();
249 if (interferent_pkts.second >= 1) {
251 } else {
252 if (interferent_pkts.first > 0) {
254 }
255 }
256 } else if (mach->ftype() == MF_CONTROL) {
259 if (interferent_pkts.first > 0) {
261 }
262 }
263 if (error_hmm) {
264 incrErrorPktsNoise();
265 }
266 } else if (error_hmm) { //only HMM error, no interference
267 incrErrorPktsNoise();
268 if (mach->ftype() != MF_CONTROL) {
270 } else if (mach->ftype() == MF_CONTROL) {
272 }
273 } /* done update UwPhysical counters */
274
275 sendUp(p);
276 PktRx = 0;
277 } else {
278 DEBUG(-100,"McLink not set for origin MAC: "<< mac_addr)
279 UnderwaterPhysical::endRx(p); // if no MCLink was set for this MAC the regular UwPhysical model is used
280 }
281 } else {
282 dropPacket(p);
283 }
284 } else {
285 dropPacket(p);
286 }
287} /* UnderwaterHMMPhysical::endRx */
288
289double
290UnderwaterHMMPhysical::ber2per(double ber, Packet * p) {
291 if (HDR_CMN(p)->size() > 0 && ber >= 0 && ber <=1) {
292 return 1-pow(1-ber, 8*(HDR_CMN(p)->size()));
293 }
294 DEBUG(0, "called ber2per() with invalid packet size or BER")
295 return 0;
296}
UnderwaterHMMPhysical models an hidden Markov Model phy channel.
virtual double ber2per(double ber, Packet *p)
Returns the packet error rate by using the BER from HMM and the size of a packet.
virtual void endRx(Packet *p) override
Handles the end of a packet reception.
int getPktsTotMedium() const
void incrTotPkts(MCLink::ChState ch_state)
increase the counter of packets sent taking into account the channel state
void setMCLink(int mac, MCLink *link)
Adds the Markov Chain transition matrix for each source MAC.
virtual ~UnderwaterHMMPhysical()
Destructor of UnderwaterHMMPhysical class.
virtual int command(int, const char *const *)
TCL command interpreter.
UnderwaterHMMPhysical()
Constructor of UnderwaterHMMPhysical class.
std::map< int, MCLink * > link_map
maps source mac to associated MCLink
virtual void endRx(Packet *p)
Handles the end of a packet reception.
void incrTot_pkts_lost()
Increment the number of packets discarded.
Definition uwphysical.h:295
std::string Interference_Model
Interference calcuation mode chosen: CHUNK model or MEANPOWER model.
Definition uwphysical.h:463
virtual double consumedEnergyRx(const double &_duration)
Compute the energy (in Joule) spent by the modem in reception.
Definition uwphysical.h:200
uwinterference * interference_
Pointer to the interference model module.
Definition uwphysical.h:467
void incrErrorCtrlPktsInterf()
Increment the number of CTRL packets discarded due to interference.
Definition uwphysical.h:313
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.
Definition uwphysical.h:441
void incrCollisionCTRL()
Increment the number of CTRL pkts discarded due to a collision.
Definition uwphysical.h:331
void incrCollisionDATAvsCTRL()
Increment the number of collisions DATA/CTRL.
Definition uwphysical.h:322
double time_ready_to_end_rx_
Used to keep track of the arrival time.
Definition uwphysical.h:430
double Rx_Time_
Time (in seconds) spent by the node in reception.
Definition uwphysical.h:435
virtual int command(int, const char *const *)
TCL command interpreter.
void incrCollisionDATA()
Increment the number of DATA pkts discarded due to a collision.
Definition uwphysical.h:340
void incrTotCrtl_pkts_lost()
Increment the number of CTRL packets discarded.
Definition uwphysical.h:304
TclObject * create(int argc, const char *const *argv)
virtual Stats * clone() const
Virtual method used by the Module class in order to copy its stats an a generic fashion,...
MCLink::ChState channel_state
HMM channel state.
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, MCLink::ChState channel_state=MCLink::ChState::NOT_DEFINED)
Method to update stats with the param of 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 counter getCounters(Packet *p)
Returns the counters of collisions.
virtual double getInterferencePower(Packet *p)
Compute the average interference power for the given packet.
UwHMMPhysicalClass class_module_uwhmmphysical
Definition of UwHMMPhysical class.
std::pair< int, int > counter
counter of collisions
Definition of ClMsgUwMmac class.
Utilities to manage stats.
#define DEBUG(level, text)