DESERT 3.5.1
Loading...
Searching...
No Matches
uw-csma-aloha-trigger-node.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
39
41
42static class UwCsmaAloha_Trigger_NODEModuleClass : public TclClass
43{
44public:
46 : TclClass("Module/UW/CSMA_ALOHA/TRIGGER/NODE")
47 {
48 }
49
50 TclObject *
51 create(int, const char *const *)
52 {
53 return (new UwCsmaAloha_Trigger_NODE());
54 }
56
57void
59{
61
62 if (module->curr_state == UW_CS_ALOHA_TRIG_NODE_STATE_LISTEN) {
63
64 if (module->debug_)
65 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << module->addr
66 << ") timer expire() current state = "
67 << module->status_info[module->curr_state]
68 << "; listening period expired, next state = "
69 << module->status_info[UW_CS_ALOHA_TRIG_NODE_STATE_TX_DATA]
70 << endl;
71
72 module->refreshReason(UW_CS_ALOHA_TRIG_NODE_REASON_LISTEN_TIMEOUT);
73 module->stateTxData();
74 } else {
75 if (module->debug_)
76 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << module->addr
77 << ")::ListenTimer::expired() " << endl;
78 }
79}
80
81void
82UwCsmaAloha_Trigger_NODE::TransmissionTimer::expire(Event *e)
83{
84 timer_status = UW_CS_ALOHA_TRIG_NODE_EXPIRED;
85 if (module->can_transmit == true) {
86 if (module->debug_)
87 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << module->addr
88 << ") Transmission timer expire() current state = "
89 << module->status_info[module->curr_state] << endl;
90 module->can_transmit = false;
91 } else {
92 if (module->debug_)
93 std::cerr << "Transmission Timer expired, can_transmit == false"
94 << std::endl;
95 }
96}
97
98const double UwCsmaAloha_Trigger_NODE::prop_speed = 1500.0;
101
102map<UwCsmaAloha_Trigger_NODE::UW_CS_ALOHA_TRIG_NODE_STATUS, string>
104map<UwCsmaAloha_Trigger_NODE::UW_CS_ALOHA_TRIG_NODE_REASON_STATUS, string>
106
108 : listen_timer(this)
109 , tx_timer(this)
110 , u_data_id(0)
112 , curr_data_pkt(0)
114 , has_buffer_queue(false)
115 , can_transmit(false)
120{
121 u_pkt_id = 0;
122 mac2phy_delay_ = 1e-19;
123
124 bind("HDR_size_", (int *) &HDR_size);
125 bind("debug_", (double *) &debug_);
126 bind("max_payload_", (int *) &max_payload);
127 bind("buffer_pkts_", (int *) &buffer_pkts);
128 bind("listen_time_", &listen_time);
129 bind("tx_timer_duration_", (int *) &tx_timer_duration);
130
131 if (buffer_pkts > 0)
132 has_buffer_queue = true;
133 if (listen_time <= 0.0)
134 listen_time = 1e-19;
135}
136
140
141// TCL command interpreter
142
143int
144UwCsmaAloha_Trigger_NODE::command(int argc, const char *const *argv)
145{
146 Tcl &tcl = Tcl::instance();
147 if (argc == 2) {
148 if (strcasecmp(argv[1], "initialize") == 0) {
149 initInfo();
150 return TCL_OK;
151 } else if (strcasecmp(argv[1], "getQueueSize") == 0) {
152 tcl.resultf("%d", Q.size());
153 return TCL_OK;
154 }
155 }
156 return MMac::command(argc, argv);
157}
158
159int
161{
162 switch (m->type()) {
163
164 default:
165 return Module::crLayCommand(m);
166 }
167}
168
169void
171{
172
173 initialized = true;
174
176 status_info[UW_CS_ALOHA_TRIG_NODE_STATE_TX_DATA] = "Transmit DATA state";
177 status_info[UW_CS_ALOHA_TRIG_NODE_STATE_DATA_RX] = "DATA received state";
178 status_info[UW_CS_ALOHA_TRIG_NODE_STATE_LISTEN] = "Listening channel state";
179 status_info[UW_CS_ALOHA_TRIG_NODE_STATE_RX_IDLE] = "Start rx Idle state";
181 "Start rx Listen state";
183 "Check Listen timeout state";
185 "Wrong Pkt Rx state";
187 "Received a TRIGGER packet from AUV";
188
190 "DATA pending from upper layers";
195 "DATA pending, listening to channel";
197 "DATA pending, end of listening period";
200 "Received an erroneous pkt";
202 "Listen to channel pending";
205 "Received a TRIGGER packet from AUV";
207 "TRIGGER received ---> Listen to the channel";
208}
209
210void
212{
213 if ((has_buffer_queue == true) && ((Q.size()) < (buffer_pkts)) ||
214 (has_buffer_queue == false)) {
215 initPkt(p);
216 Q.push(p);
218 waitStartTime();
219
222 stateListen();
223 } else {
224 if (debug_)
225 cerr << showpoint << NOW << " " << __PRETTY_FUNCTION__
226 << " transmitting packet" << endl;
227 }
228 } else {
229 incrDiscardedPktsTx();
231 }
232}
233
234void
236{
237 hdr_cmn *ch = hdr_cmn::access(p);
238 int curr_size = ch->size();
239
240 ch->size() = curr_size + HDR_size;
242 u_data_id++;
243}
244
245void
247{
248 if (debug_)
249 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
250 << ")::Mac2PhyStartTx() start tx packet" << endl;
251
252 MMac::Mac2PhyStartTx(p);
253}
254
255void
257{
258
259 if (debug_)
260 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
261 << ")::Phy2MacEndTx() end tx packet" << endl;
262
263 switch (curr_state) {
264
267
268 if (debug_)
269 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
270 << ")::Phy2MacEndTx() DATA sent, from "
271 << status_info[curr_state] << " to "
273
274 stateIdle();
275 } break;
276
277 default: {
278 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
279 << ")::Phy2MacEndTx() logical error, current state = "
280 << status_info[curr_state] << endl;
281 } break;
282 }
283}
284
285void
287{
288 if (debug_)
289 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
290 << ")::Phy2MacStartRx() rx Packet " << endl;
291
293
294 switch (curr_state) {
295
297 stateRxIdle();
298 break;
299
302 break;
303 default: {
304 if (debug_)
305 std::cerr << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
306 << ")::Phy2MacStartRx() logical warning, current "
307 "state = "
308 << status_info[curr_state] << std::endl;
309 }
310 }
311}
312
313void
315{
316 hdr_cmn *ch = HDR_CMN(p);
317 packet_t rx_pkt_type = ch->ptype();
318 hdr_mac *mach = HDR_MAC(p);
319 hdr_MPhy *ph = HDR_MPHY(p);
320
321 int dest_mac = mach->macDA();
322
323 double gen_time = ph->txtime;
324 double received_time = ph->rxtime;
325 double diff_time = received_time - gen_time;
326
327 double distance = diff_time * prop_speed;
328
329 if (debug_)
330 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
331 << ")::Phy2MacEndRx() " << status_info[curr_state]
332 << ", received a pkt type = " << ch->ptype()
333 << ", src addr = " << mach->macSA()
334 << " dest addr = " << mach->macDA()
335 << ", estimated distance between nodes = " << distance << " m "
336 << endl;
337
338 if (ch->error()) {
339
340 if (debug_)
341 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
342 << ")::Phy2MacEndRx() dropping corrupted pkt " << endl;
343 incrErrorPktsRx();
344
348 } else {
349 if (dest_mac == (int) addr || dest_mac == (int) MAC_BROADCAST) {
350 if (rx_pkt_type == (int) PT_MMAC_TRIGGER) {
353 } else {
356 }
357 } else {
360 }
361 }
362}
363
364void
366{
367 if (debug_)
368 cout << NOW << "Csma_Aloha_NODE(" << addr
369 << ")::stateRxTrigger---> can_transmit" << can_transmit << endl;
370 if (can_transmit == false) {
372 can_transmit = true;
374 if (!Q.empty()) {
376 stateListen();
377 }
378 } else {
379 if (debug_)
380 cout << NOW << "Csma_Aloha_NODE(" << addr
381 << ")::stateRxTrigger---> can_transmit already true " << endl;
382 }
383 Packet::free(p);
384}
385
386void
388{
389 Packet *data_pkt = curr_data_pkt->copy();
390 queuePop();
391
392 incrDataPktsTx();
393 Mac2PhyStartTx(data_pkt);
394}
395
396void
398{
399 if (debug_)
400 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
401 << ")::stateRxPacketNotForMe() pkt for another address. Dropping "
402 "pkt"
403 << endl;
404 if (p != NULL)
405 Packet::free(p);
406
408
409 switch (prev_state) {
410
412 stateIdle();
413 break;
414
417 break;
418
419 default:
420 if (debug_)
421 cerr << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
422 << ")::stateRxPacketNotForMe() logical error, prev state "
423 "= "
424 << status_info[prev_state] << endl;
425 // exit(1);
426 }
427}
428
429void
431{
433
434 if (debug_)
435 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
436 << ")::stateCheckListenExpired()" << endl;
437 if (listen_timer.isActive()) {
440 } else if (listen_timer.isExpired()) {
444 stateTxData();
445 else
446 stateListen();
447 } else {
448 if (debug_)
449 cerr << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
450 << ")::stateCheckListenExpired() listen_timer logical error, "
451 "current timer state = "
452 << status_info[curr_state] << endl;
453 }
454}
455
456void
460
461void
463{
465
467
468 if (debug_)
469 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
470 << ")::stateIdle() queue size = " << Q.size() << endl;
472 if (can_transmit) {
473 if (!Q.empty()) {
475 stateListen();
476 }
477 }
479}
480
481void
486
487void
489{
492
494
495 double time =
496 listen_time * RNG::defaultrng()->uniform_double() + wait_costant;
497
498 if (debug_)
499 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
500 << ")::stateListen() listen time = " << time << endl;
501
503}
504
505void
510
511void
513{
514 if (can_transmit) {
516
517 if (debug_)
518 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
519 << ")::stateTxData() " << endl;
520
521 curr_data_pkt = Q.front();
522
523 if (data_sn_queue.front() != last_sent_data_id) {
525 }
527 txData();
528 } else {
529 if (debug_)
530 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
531 << ")::stateTxData() ---> Not Allowed To Transmit " << endl;
532 }
533}
534
535void
537{
539
540 if (debug_)
541 cout << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
542 << ")::stateRxData() " << endl;
544
545 switch (prev_state) {
546
548 hdr_cmn *ch = hdr_cmn::access(data_pkt);
549 ch->size() = ch->size() - HDR_size;
550 incrDataPktsRx();
551 sendUp(data_pkt);
552 stateIdle();
553 } break;
554
556 hdr_cmn *ch = hdr_cmn::access(data_pkt);
557 ch->size() = ch->size() - HDR_size;
558 incrDataPktsRx();
559 sendUp(data_pkt);
561 } break;
562
563 default:
564
565 if (debug_)
566 cerr << NOW << " UwCsmaAloha_Trigger_NODE(" << addr
567 << ")::stateRxData() logical error, prev state = "
568 << status_info[prev_state] << endl;
569 }
570}
571
572void
574{
575 std::string response;
576 std::cout << "Press Enter to continue";
577 std::getline(std::cin, response);
578}
TclObject * create(int, const char *const *)
UwCsmaAloha_Trigger_NODE *UW_CS_ALOHA_TRIG_NODE_TIMER_STATUS timer_status
< Pointer of an object of type UwCsmaAloha_Triggered
void incrCounter()
Increments the counter of the timer.
virtual void expire(Event *e)
Method called when the timer expire.
Class that describes a CsmaAloha_TRIGGERED module of the node.
static bool initialized
true if the protocol is initialized
virtual int crLayCommand(ClMessage *m)
Cross-Layer messages interpreter.
double wait_costant
Adding factor in the calculation of the listen time.
static const double prop_speed
Typical sound propagation speed in underwater enviroment.
UW_CS_ALOHA_TRIG_NODE_STATUS prev_state
Previous state of the protocol.
virtual void stateRxData(Packet *p)
State in which a DATA packet is received.
virtual void refreshState(UW_CS_ALOHA_TRIG_NODE_STATUS state)
Refresh the State of the protocol.
UW_CS_ALOHA_TRIG_NODE_REASON_STATUS last_reason
Reason for the state transitions.
double listen_time
Time in which the node sense the channel.
virtual void waitForUser()
Used for debug purposes.
bool has_buffer_queue
flag that indicates if a node has a buffer where store DATA packets
virtual void Phy2MacStartRx(const Packet *p)
Method called when the Phy Layer start to receive a Packet.
UW_CS_ALOHA_TRIG_NODE_STATUS prev_prev_state
Previous previous state of the protocol.
UwCsmaAloha_Trigger_NODE()
Constructor of the UwCsmaAloha_Trigger_NODE class.
virtual void stateRxIdle()
A reception is occuring while the protocol is in IDLE state.
int buffer_pkts
Length of the data buffer in number of packets.
std::queue< int > data_sn_queue
Queue of the sequence number of the packets.
static map< UW_CS_ALOHA_TRIG_NODE_STATUS, string > status_info
Textual description of the protocol states.
int tx_timer_duration
Duration of the time in which the node is allowed to transmit.
virtual void stateRxListen()
State in which a reception is occuring while the node is listening the channel.
virtual void Mac2PhyStartTx(Packet *p)
Pass the packet to the PHY layer.
virtual void stateTxData()
State in which the protocol allows the node to transmit a data packet.
virtual void Phy2MacEndRx(Packet *p)
Method called when the Phy Layer finish to receive a Packet.
virtual void Phy2MacEndTx(const Packet *p)
Method called when the PHY layer finish to transmit the packet.
int HDR_size
Size (in bytes) of the header added by the protocol.
virtual ~UwCsmaAloha_Trigger_NODE()
Destructor of the UwCsmaAloha_Trigger_NODE class.
virtual void txData()
Transmits the DATA packet (calling Mac2PhyStartTx) and increment the counter of transmitted data pack...
virtual void stateIdle()
IDLE state.
static map< UW_CS_ALOHA_TRIG_NODE_REASON_STATUS, string > reason_info
Textual description of the protocol reason for the change of the state.
int max_payload
Maximum dimension of the data payload in bytes.
static int u_pkt_id
simulation-unique packet ID
std::queue< Packet * > Q
Packet queue.
int last_sent_data_id
ID of the last sent packet.
Packet * curr_data_pkt
Pointer to the current data packet.
virtual void stateRxTrigger(Packet *p)
State of the protocol in which a TRIGGER packet is received.
virtual void recvFromUpperLayers(Packet *p)
Receives the packet from the upper layer (e.g.
UW_CS_ALOHA_TRIG_NODE_STATUS curr_state
Current state of the protocol.
virtual void incrUpperDataRx()
Increase the number of Data packet Received from the Upper layers.
virtual void initInfo()
Initializes the protocol at the beginning of the simulation.
virtual void stateCheckListenExpired()
Checks if the Listen period is expired.
bool can_transmit
Flag that indicates if the node can transmit data packets to the sink.
virtual void stateCheckTxTimerExpired()
Checks if the Time period is expired.
virtual void stateListen()
State in which the node is listening the channel.
virtual void initPkt(Packet *p)
Init the packet with the MAC address of the receiver and the sender, the size of the packet and the t...
virtual void stateRxPacketNotForMe(Packet *p)
state in which a wrong Packet is received
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
virtual void queuePop(bool flag=true)
Pop the first element of the data packet queue.
int last_data_id_rx
ID of the last DATA packet received.
virtual void refreshReason(UW_CS_ALOHA_TRIG_NODE_REASON_STATUS reason)
Refresh the reason for the change of state.
UwCsmaAloha_Trigger_NODEModuleClass class_module_uw_csma_aloha_triggered_node
#define UW_CS_ALOHA_TRIG_NODE_DROP_REASON_BUFFER_FULL
The Buffer of DATA packets is full.
#define UW_CS_ALOHA_TRIG_NODE_DROP_REASON_ERROR
Packet corrupted.
@ NOT_SET
Definition uwaloha.cpp:44