DESERT 3.5.1
Loading...
Searching...
No Matches
uw-phy-WakeUp.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 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 "bpsk.h" */
40
41#include <iostream>
42
43#include "uw-phy-WakeUp.h"
44#include <rng.h>
45#include <underwater-mpropagation.h>
46#include <uwlib.h>
47
48enum {
57
58};
59
63static class MPhy_WakeUpClass : public TclClass
64{
65public:
70 : TclClass("Module/MPhy/Underwater/WKUP")
71 {
72 }
78 TclObject *
79 create(int, const char *const *)
80 {
81 return (new MPhy_WakeUp);
82 }
84
89static class WkUpPktClass : public PacketHeaderClass
90{
91public:
96 : PacketHeaderClass("PacketHeader/WKUP", sizeof(hdr_wkup))
97 {
98 bind_offset(&hdr_wkup::offset_);
99 bind();
100 }
102
103bool MPhy_WakeUp::initialized = false;
104int MPhy_WakeUp::modid = -1;
105
107 : PktRx(0)
108 , txActive(false)
109 , droppedPktsTxPending(0)
110{
111 if (!initialized) {
112 modid = MPhy::registerModulationType(UW_WAKEUP_MODNAME);
113 initialized = true;
114 }
115 bind("AcquisitionThreshold_dB_", (double *) &AcquisitionThreshold_dB_);
116 bind("ToneDuration_", (double *) &ToneDuration_);
117 bind("MaxTxRange_", (double *) &MaxTxRange_);
118}
119
123
124int
125MPhy_WakeUp::command(int argc, const char *const *argv)
126{
127 // printf("MPhy::command -- %s (%d)\n", argv[1], argc);
128 Tcl &tcl = Tcl::instance();
129
130 if (argc == 2) {
131 if (strcasecmp(argv[1], "getDroppedPktsTxPending") == 0) {
132 tcl.resultf("%d", getDroppedPktsTxPending());
133 return TCL_OK;
134 }
135 }
136 return (MPhy::command(argc, argv));
137}
138
139int
141{
142 assert(initialized);
143 return modid;
144}
145
146double
148{
149 hdr_MPhy *ph = HDR_MPHY(p);
150
151 assert(propagation_);
152
153 // This assumes that the noise SPD is flat within the signal
154 // bandwidth. Not really a very accurate model, of course you can do
155 // better than this.
156
157 double freq = ph->srcSpectralMask->getFreq();
158 double bw = ph->srcSpectralMask->getBandwidth();
159
160 // std::cerr << " txbw " << ph->srcSpectralMask->getBandwidth()
161 // << " rxbw " << ph->dstSpectralMask->getBandwidth()
162 // << " txf " << ph->srcSpectralMask->getFreq()
163 // << " rxf " << ph->dstSpectralMask->getFreq()
164 // << std::endl;
165
166 UnderwaterMPropagation *uwmp =
167 dynamic_cast<UnderwaterMPropagation *>(propagation_);
168 assert(uwmp);
169 double noiseSPDdBperHz = uwmp->uw.getNoise(freq / 1000.0);
170 double noisepow = bw * pow(10, noiseSPDdBperHz / 10.0);
171
172 return (noisepow);
173}
174
175MSpectralMask *
177{
178 return spectralmask_;
179}
180
181void
183{
184 if (debug_)
185 cout << NOW << " MPhy_WakeUp::startTx() tx a TONE";
186
187 // we abort any ongoing rx activity
188 if (PktRx != 0) {
189 hdr_MPhy *ph = HDR_MPHY(PktRx);
190 hdr_wkup *wkuph = HDR_WKUP(PktRx);
191
192 // drp_rsn_map[ph->txtime][ph->rxtime] =
193 // WKUP_DROPPED_REASON_TX_PENDING;
194
195 wkuph->startRx_time = WKUP_DISCARD;
196 wkuph->endRx_time = WKUP_DISCARD;
197
198 if (debug_)
199 cout << ", aborting ongoing rx at time = " << ph->rxtime;
200 }
201 if (debug_)
202 cout << endl;
203
204 txActive = true;
205 PktRx = 0;
206 sendDown(p);
207}
208
209void
211{
212 // Notify the MAC
213 txActive = false;
214 Phy2MacEndTx(p);
215}
216
217void
219{
220 hdr_MPhy *ph = HDR_MPHY(p);
221 double rx_time = ph->rxtime;
222 double tx_time = ph->txtime;
223
224 if (ph->modulationType == modid) {
225 hdr_wkup *wkuph = HDR_WKUP(p);
226 double snr_dB = 10 * log10(ph->Pr / ph->Pn);
227
228 if ((PktRx == 0) && (txActive == false)) {
229
230 wkuph->startRx_time = ph->rxtime;
231 wkuph->endRx_time = ph->rxtime + getTxDuration(p);
232
233 // std::cerr << "snr_dB: " << snr_dB << " AcquisitionThreshold_dB_:
234 // " << AcquisitionThreshold_dB_ ;
235
236 if (snr_dB > AcquisitionThreshold_dB_) {
237
238 if (debug_)
239 cout << NOW << " MPhy_WakeUp::startRx() rx a TONE" << endl;
240
241 // ideal synchronization
242 PktRx = p;
243
244 // Notify the MAC
245 Phy2MacStartRx(p);
246 return;
247 } else { // below threshold
248 if (debug_)
249 cout << NOW << " MPhy_WakeUp::startRx() rx a TONE but "
250 "below threshold"
251 << endl;
252
253 wkuph->startRx_time = WKUP_DISCARD;
255
256 // drp_rsn_map[tx_time][rx_time] =
257 // WKUP_DROPPED_REASON_NOISE;
258 return;
259 }
260 } else if ((PktRx != 0) && (txActive == false)) {
261
262 if (snr_dB > AcquisitionThreshold_dB_) {
263 // This is a wakeup tone packet so we chain-sync on it
264
265 hdr_MPhy *phrx = HDR_MPHY(PktRx);
266 // drp_rsn_map[phrx->txtime][phrx->rxtime] =
267 // WKUP_DROPPED_REASON_CHAIN_SYNC;
268
269 PktRx = p;
270
271 if (debug_)
272 cout << NOW
273 << " MPhy_WakeUp::startRx() rx a chain-synched TONE"
274 << endl;
275
276 wkuph->startRx_time = ph->rxtime;
277 wkuph->endRx_time = ph->rxtime + getTxDuration(p);
278 return;
279 } else { // below threshold
280 if (debug_)
281 cout << NOW << " MPhy_WakeUp::startRx() rx a TONE but "
282 "below threshold"
283 << endl;
284
285 wkuph->startRx_time = WKUP_DISCARD;
287
288 // drp_rsn_map[tx_time][rx_time] =
289 // WKUP_DROPPED_REASON_NOISE;
290 return;
291 }
292 } else if (txActive == true) { // we have to discard this pkt
293 if (debug_)
294 cout << NOW << " MPhy_WakeUp::startRx() rx a TONE but while tx"
295 << endl;
296
297 wkuph->startRx_time = WKUP_DISCARD;
298 wkuph->endRx_time = WKUP_DISCARD;
299
300 // drp_rsn_map[tx_time][rx_time] =
301 // WKUP_DROPPED_REASON_TX_PENDING;
302 return;
303 }
304 } else {
305 if (debug_)
306 cout << NOW << " MPhy_WakeUp::startRx() rx a PKT but wrong MODID"
307 << endl;
308
309 // drp_rsn_map[tx_time][rx_time] =
310 // WKUP_DROPPED_REASON_WRONG_MODID;
311 // wrong modid we have to discard this pkt
312 }
313}
314
315void
317{
318 hdr_cmn *ch = HDR_CMN(p);
319 hdr_MPhy *ph = HDR_MPHY(p);
320
321 if (ph->modulationType == modid) {
322
323 hdr_wkup *wkuph = HDR_WKUP(p);
324
325 if (wkuph->startRx_time == WKUP_DISCARD) {
326 // checkDropReason(p);
327 dropPacket(p);
328 return;
329 }
330
331 double per_ni; // packet error rate due to noise and/or interference
332 double per_n; // packet error rate due to noise only
333
334 int nbits = 1;
335 per_n = getPER(ph->Pr / ph->Pn, nbits);
336 per_ni = getPER(ph->Pr / (ph->Pn + ph->Pi), nbits);
337 // per_ni = -1;
338 // per_n = -1;
339
340 double x = RNG::defaultrng()->uniform_double();
341 bool error_ni = x <= per_ni;
342 bool error_n = x <= per_n;
343
344 ch->error() = error_ni || error_n;
345
346 if (error_n) {
347 incrErrorPktsNoise();
348 } else if (error_ni) {
349 incrErrorPktsInterf();
350 }
351
352 if (PktRx == p) {
353 // always send up; the PHY is not responsible for discarding
354 // erroneous packets
355 sendUp(p);
356 PktRx = 0; // We can now sync onto another packet
357 } else if (PktRx != 0) {
358 hdr_wkup *rxwkuph = HDR_WKUP(PktRx);
359 hdr_cmn *rxch = HDR_CMN(PktRx);
360 // if no errors are found we refresh the time interval
361 if (ch->error() == false) {
362 double min_start_time =
363 min(wkuph->startRx_time, rxwkuph->startRx_time);
364 double max_end_time =
365 max(wkuph->endRx_time, rxwkuph->endRx_time);
366 rxwkuph->startRx_time = min_start_time;
367 rxwkuph->endRx_time = max_end_time;
368 }
369 // we must discard this pkt and sendUp the last only
370 // checkDropReason(p);
371 dropPacket(p);
372 } else {
373 // anything else, for debug purposes
374 // checkDropReason(p);
375 dropPacket(p);
376 }
377 } else {
378 // wrong mod-id ==> discard pkt
379 // checkDropReason(p);
380 dropPacket(p);
381 }
382}
383
384// void MPhy_WakeUp::checkDropReason(Packet* p) {
385// hdr_MPhy* ph = HDR_MPHY(p);
386//
387// cout.precision(16);
388//
389// if (debug_) cout << NOW << " MPhy_WakeUp::checkDropReason() pkt txtime = "
390// << ph->txtime << "; rxtime = "
391// << ph->rxtime << endl;
392//
393// map<double, map<double, int> >::iterator it = drp_rsn_map.find(ph->txtime);
394// map<double,int>::iterator it2;
395//
396// if ( it != drp_rsn_map.end() ) {
397// it2 = it->second.find(ph->rxtime);
398//
399// if ( it2 == it->second.end() ) {
400// cout << NOW << " MPhy_WakeUp::checkDropReason() ERROR, can't find
401// rx time" << endl;
402// exit(1);
403// }
404// }
405// else {
406// cout << NOW << " MPhy_WakeUp::checkDropReason() ERROR, can't find tx
407// time" << endl;
408// exit(1);
409// }
410//
411// if (it2->second == WKUP_DROPPED_REASON_CHAIN_SYNC) return;
412// else if (it2->second == WKUP_DROPPED_REASON_WRONG_MODID) {
413// if (debug_) cout << NOW << " MPhy_WakeUp::checkDropReason() pkt
414// dropped due to wrong mod id" << endl;
415//
416// incrDroppedPktsWrongModId();
417// }
418// else if (it2->second == WKUP_DROPPED_REASON_NOISE) {
419// if (debug_) cout << NOW << " MPhy_WakeUp::checkDropReason() pkt
420// dropped due to noise" << endl;
421//
422// incrDroppedPktsNoise();
423// }
424// else if (it2->second == WKUP_DROPPED_REASON_DEAFNESS) {
425// if (debug_) cout << NOW << " MPhy_WakeUp::checkDropReason() pkt
426// dropped due to deafness conditions" << endl;
427//
428// incrDroppedPktsDeaf();
429// }
430// else if (it2->second == WKUP_DROPPED_REASON_TX_PENDING) {
431// if (debug_) cout << NOW << " MPhy_WakeUp::checkDropReason() pkt
432// dropped due to tx pending" << endl;
433//
434// incrDroppedPktsTxPending();
435// }
436// else {
437// cout << NOW << " MPhy_Bpsk::checkDropReason() wrong reason!" << endl;
438// exit(1);
439// }
440// }
441
442void
444{
445 // hdr_MPhy* ph = HDR_MPHY(p);
446 //
447 // map<double, map<double, int> >::iterator it =
448 // drp_rsn_map.find(ph->txtime);
449 //
450 // if ( it != drp_rsn_map.end() ) {
451 // it->second.erase(ph->rxtime);
452 //
453 // }
454 // else {
455 // cout << NOW << " MPhy_WakeUp::dropPacket() ERROR, can't find tx
456 // time" << endl;
457 // exit(1);
458 // }
459 //
460 // if ( it->second.size() == 0 ) drp_rsn_map.erase(ph->txtime);
461 //
462 Packet::free(p);
463}
464
465double
466MPhy_WakeUp::getPER(double snr, int nbits)
467{
468 double ber = 0.5 * erfc(sqrt(snr * 0.5));
469 double per = 1 - pow(1 - ber, nbits);
470 return per;
471}
472
473void
475{
476 std::string response;
477 std::cout << "Press Enter to continue";
478 std::getline(std::cin, response);
479}
Class that represents the binding with the tcl configuration script.
MPhy_WakeUpClass()
Constructor of the class.
TclObject * create(int, const char *const *)
Creates the TCL object needed for the tcl language interpretation.
Class that describes the WakeUp PHY layer for T-LOHI MAC protocol.
virtual double getTxDuration(Packet *p)
Returns the duration of the transmission for the specified packet.
virtual void endRx(Packet *p)
Notify to the MAC protocol that the reception is finished and send the packet to it.
virtual void endTx(Packet *p)
Notify to the MAC protocol that the transmission has been finished.
virtual ~MPhy_WakeUp()
Class destructor.
MPhy_WakeUp()
Class contructor.
Packet * PktRx
Pointer to the packeti in reception.
double MaxTxRange_
Maximum Transmission Range.
virtual void startRx(Packet *p)
Notify to the MAC protocol the start of a reception.
virtual double getPER(double snr, int nbits)
Returns the PER for a certain SNR and a dimension of packet.
virtual MSpectralMask * getTxSpectralMask(Packet *p)
Gets the Transmission Spectral Mask for the Packet p.
virtual void waitForUser()
Used for debug purposes.
virtual double getNoisePower(Packet *p)
Returns the Power of the noise for a packet.
virtual int getDroppedPktsTxPending()
Gets the number of Tx Pending dropped packets.
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
static bool initialized
used to register the modulation type only once
double ToneDuration_
predefined tone duration
virtual void startTx(Packet *p)
Starts to transmit a Packet.
virtual int getModulationType(Packet *)
Returns the Modulation type.
static int modid
modulation type id
double AcquisitionThreshold_dB_
How many dB over noise are required for a signal to trigger acquisition (i.e., a RX attempt)
virtual void dropPacket(Packet *p)
Drops a packet.
Class that describes the PacketHeader for WakeUp Tone class.
WkUpPktClass()
Constructor of the class.
Header of the Wake Up Tone.
double startRx_time
Start Reception Time.
static int offset_
Required by PacketManagerHeader class.
double endRx_time
End Reception Time.
WkUpPktClass class_wkup_pkt
MPhy_WakeUpClass class_MPhy_WakeUp
@ WKUP_DROPPED_REASON_CHAIN_SYNC
@ WKUP_DROPPED_REASON_NOISE
@ WKUP_DISCARD
@ WKUP_BELOW_THRESHOLD
@ WKUP_DROPPED_REASON_NOT_SET
@ WKUP_DROPPED_REASON_WRONG_MODID
@ WKUP_DROPPED_REASON_TX_PENDING
@ WKUP_DROPPED_REASON_DEAFNESS
Provides the declaration of WakeUp PHY.
#define UW_WAKEUP_MODNAME
#define HDR_WKUP(P)