DESERT 3.5.1
Loading...
Searching...
No Matches
uwtdma.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
40#include "uwtdma.h"
41#include <iostream>
42#include <stdint.h>
43#include <mac.h>
44#include <uwmmac-clmsg.h>
45#include <uwcbr-module.h>
46
50static class TDMAModuleClass : public TclClass
51{
52
53public:
58 : TclClass("Module/UW/TDMA")
59 {
60 }
65 TclObject *
66 create(int, const char *const *)
67 {
68 return (new UwTDMA());
69 }
70
72
73void
75{
76 ((UwTDMA *) module)->changeStatus();
77}
78
80 : MMac()
81 , tdma_timer(this)
82 , slot_status(UW_TDMA_STATUS_NOT_MY_SLOT)
83 , slot_duration(0)
84 , start_time(0)
85 , transceiver_status(IDLE)
86 , out_file_stats(0)
87 , guard_time(0)
88 , tot_slots(0)
89 , HDR_size(0)
90 , max_packet_per_slot(1)
91 , packet_sent_curr_slot_(0)
92 , max_queue_size(10)
93 , drop_old_(0)
94 , enable(true)
95 , name_label_("")
96 , checkPriority(0)
97{
98 bind("queue_size_", (int *) &max_queue_size);
99 bind("frame_duration", (double *) &frame_duration);
100 bind("debug_", (int *) &debug_);
101 bind("sea_trial_", (int *) &sea_trial_);
102 bind("fair_mode", (int *) &fair_mode);
103 bind("HDR_size_", (int *) &HDR_size);
104 bind("max_packet_per_slot", (int *) &max_packet_per_slot);
105 bind("drop_old_", (int *) &drop_old_);
106 bind("checkPriority_", (int *) &checkPriority);
107 bind("mac2phy_delay_", (double *) &mac2phy_delay_);
108 if (fair_mode == 1) {
109 bind("guard_time", (double *) &guard_time);
110 bind("tot_slots", (int *) &tot_slots);
111 }
112
113 if (max_queue_size < 0) {
114 cerr << NOW << " UwTDMA() not valid max_queue_size < 0!! set to 1 by default "
115 << std::endl;
116 max_queue_size = 1;
117 }
118 if (frame_duration < 0) {
119 cerr << NOW << " UwTDMA() not valid frame_duration < 0!! set to 1 by default "
120 << std::endl;
121 frame_duration = 1;
122 }
123 if (max_packet_per_slot < 0) {
124 cerr << NOW << " UwTDMA() not valid max_packet_per_slot < 0!! set to 1 by default "
125 << std::endl;
127 }
128 if (drop_old_ == 1 && checkPriority == 1) {
129 cerr << NOW << " UwTDMA() drop_old_ and checkPriority cannot be set both to 1!! "
130 << "checkPriority set to 0 by default " << std::endl;
131 checkPriority = 0;
132 }
133 if (mac2phy_delay_ <= 0) {
134 cerr << NOW << " UwTDMA() not valid mac2phy_delay_ < 0!! set to 1e-9 by default "
135 << std::endl;
136 mac2phy_delay_ = 1e-9;
137 }
138}
139
141{
142}
143
144void
146{
147 incrUpperDataRx();
148 if (buffer.size() < max_queue_size) {
149 initPkt(p);
150 if (checkPriority == 0) {
151 buffer.push_back(p);
152 } else {
153 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
154 if (uwcbrh->priority() == 0) {
155 buffer.push_back(p);
156 if (debug_)
157 std::cout << NOW << " TDMA(" << addr
158 << ")::insert packet with standard priority in the queue" << std::endl;
159 } else {
160 buffer.push_front(p);
161 if (debug_)
162 std::cout << NOW << " TDMA(" << addr
163 << ")::insert packet with high priority in the queue" << std::endl;
164 }
165 }
166
167 } else {
168 if (debug_)
169 cout << NOW << " TDMA(" << addr
170 << ")::recvFromUpperLayers() dropping pkt due to buffer full "
171 << std::endl;
172 if (drop_old_) {
173 Packet *p_old = buffer.front();
174 buffer.pop_front();
175 Packet::free(p_old);
176 initPkt(p);
177 buffer.push_back(p);
178 }else if (checkPriority == 1) {
179 hdr_uwcbr *uwcbrh = HDR_UWCBR(p);
180 if (uwcbrh->priority() == 1) {
181 Packet *p_old = buffer.back();
182 buffer.pop_back();
183 Packet::free(p_old);
184 initPkt(p);
185 buffer.push_front(p);
186 }
187 }
188 else
189 Packet::free(p);
190 }
191 txData();
192}
193
194void
196{
197 //if (transceiver_status == TRANSMITTING)
198 // transceiver_status = IDLE;
199 txData();
200}
201
202void
204{
207 if (buffer.size() > 0) {
208 Packet *p = buffer.front();
209 buffer.pop_front();
211 incrDataPktsTx();
212 }
213 } else if (debug_) {
215 std::cout << NOW << " ID " << addr << ": Wait my slot to send"
216 << std::endl;
217 else
218 std::cout << NOW << " ID " << addr
219 << ": Wait earlier packet expires to send the current one"
220 << std::endl;
221 }
222 }
223 else {
224 if (sea_trial_)
225 out_file_stats << left << "[" << getEpoch() << "]::" << NOW << "::TDMA_node("
226 << addr << ")::already_tx max packet = " << max_packet_per_slot
227 << std::endl;
228 if (debug_)
229 cout << NOW << " TDMA(" << addr
230 << ")::already_tx max packet = " << max_packet_per_slot
231 << std::endl;
232 }
233}
234
235void
237{
238 if (!sea_trial_)
239 assert(transceiver_status == IDLE);
240
242 if(sea_trial_) {
243 sendDown(p, 0.01);
244 } else {
245 MMac::Mac2PhyStartTx(p);
246 }
247
248 if (debug_ < -5)
249 std::cout << NOW << " ID " << addr << ": Sending packet" << std::endl;
250 if (sea_trial_)
251 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
252 << "::TDMA_node(" << addr << ")::PCK_SENT packet_sent_curr_slot_ = "
253 << packet_sent_curr_slot_ << " max_packet_per_slot = "
254 << max_packet_per_slot << std::endl;
255}
256
257void
258UwTDMA::Phy2MacEndTx(const Packet *p)
259{
262 if (sea_trial_)
263 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
264 << "::TDMA_node(" << addr << ")::Phy2MacEndTx(p)"
265 << std::endl;
266
267 txData();
268}
269
270void
272{
273 if (sea_trial_ != 1)
274 assert(transceiver_status != RECEIVING);
275
278}
279
280void
282{
284 hdr_cmn *ch = HDR_CMN(p);
285 hdr_mac *mach = HDR_MAC(p);
286 int dest_mac = mach->macDA();
287 int src_mac = mach->macSA();
288
289 if (ch->error()) {
290 if (debug_)
291 cout << NOW << " TDMA(" << addr
292 << ")::Phy2MacEndRx() dropping corrupted pkt from node = "
293 << src_mac << std::endl;
294
295 incrErrorPktsRx();
296 Packet::free(p);
297 } else {
298 if (dest_mac != addr && dest_mac != MAC_BROADCAST) {
300
301 if (debug_ < -5)
302 std::cout << NOW << " ID " << addr << ": packet was for "
303 << dest_mac << std::endl;
304 } else {
305 sendUp(p);
306 incrDataPktsRx();
307
308 if (debug_ < -5)
309 std::cout << NOW << " ID " << addr
310 << ": Received packet from " << src_mac
311 << std::endl;
312 if (sea_trial_)
313 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
314 << "::TDMA_node(" << addr
315 << ")::PCK_FROM:" << src_mac << std::endl;
316 }
317 }
318
320
322 txData();
323
324 } else {
325 if (debug_)
326 std::cout << NOW << " ID " << addr
327 << ": Received packet while transmitting " << std::endl;
328 if (sea_trial_) {
329 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
330 << "::TDMA_node(" << addr << ")::RCVD_PCK_WHILE_TX"
331 << std::endl;
332 sendUp(p);
333 incrDataPktsRx();
334 } else {
335 Packet::free(p);
336 }
337 }
338}
339
340void
342{
343 hdr_cmn *ch = hdr_cmn::access(p);
344 hdr_mac *mach = HDR_MAC(p);
345
346 int curr_size = ch->size();
347
348 ch->size() = curr_size + HDR_size;
349}
350
351void
353{
354 if (p != NULL)
355 Packet::free(p);
356}
357
358void
360{
365
366 if (debug_ < -5)
367 std::cout << NOW << " Off ID " << addr << " "
369 << std::endl;
370 if (sea_trial_)
371 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
372 << "::TDMA_node(" << addr << ")::Off" << std::endl;
373 } else {
376
377 if (debug_ < -5)
378 std::cout << NOW << " On ID " << addr << " "
379 << slot_duration - guard_time << " " << std::endl;
380 if (sea_trial_)
381 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
382 << "::TDMA_node(" << addr << ")::On" << std::endl;
383
384 stateTxData();
385 }
386}
387
388void
389UwTDMA::start(double delay)
390{
391
392 enable = true;
393 if (sea_trial_) {
394 std::stringstream stat_file;
395 stat_file << "./TDMA_node_" << addr << "_" << name_label_ << ".out";
396 std::cout << stat_file.str().c_str() << std::endl;
397 out_file_stats.open(stat_file.str().c_str(), std::ios_base::app);
398
399 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
400 << "::TDMA_node(" << addr << ")::Start_simulation"
401 << std::endl;
402 }
403
404 tdma_timer.sched(delay);
405
406 if (debug_ < -5)
407 std::cout << NOW << " Status " << slot_status << " on ID " << addr
408 << " " << std::endl;
409}
410
411void
413{
414 enable = false;
415 tdma_timer.cancel();
416 if (sea_trial_)
417 out_file_stats << left << "[" << getEpoch() << "]::" << NOW
418 << "::TDMA_node(" << addr << ")::TDMA_stopped_"
419 << std::endl;
420}
421
422int
423UwTDMA::command(int argc, const char *const *argv)
424{
425 Tcl &tcl = Tcl::instance();
426 if (argc == 2) {
427 if (strcasecmp(argv[1], "start") == 0) {
428 if (fair_mode == 1) {
429 if (tot_slots == 0) {
430 std::cout << "Error: number of slots set to 0" << std::endl;
431 return TCL_ERROR;
432 } else {
434 if (slot_duration - guard_time < 0) {
435 std::cout
436 << "Error: guard time or frame set incorrectly"
437 << std::endl;
438 return TCL_ERROR;
439 } else {
442 return TCL_OK;
443 }
444 }
445 }
447 return TCL_OK;
448 } else if (strcasecmp(argv[1], "stop") == 0) {
449 stop();
450 return TCL_OK;
451 } else if (strcasecmp(argv[1], "get_buffer_size") == 0) {
452 tcl.resultf("%d", buffer.size());
453 return TCL_OK;
454 } else if (strcasecmp(argv[1], "get_upper_data_pkts_rx") == 0) {
455 tcl.resultf("%d", up_data_pkts_rx);
456 return TCL_OK;
457 } else if (strcasecmp(argv[1], "get_sent_pkts") == 0) {
458 tcl.resultf("%d", data_pkts_tx);
459 return TCL_OK;
460 } else if (strcasecmp(argv[1], "get_recv_pkts") == 0) {
461 tcl.resultf("%d", data_pkts_rx);
462 return TCL_OK;
463 }
464 } else if (argc == 3) {
465 if (strcasecmp(argv[1], "setStartTime") == 0) {
466 start_time = atof(argv[2]);
467 return TCL_OK;
468 } else if (strcasecmp(argv[1], "setSlotDuration") == 0) {
469 if (fair_mode == 1) {
470 std::cout << "Fair mode is being used! Change to generic TDMA"
471 << std::endl;
472 return TCL_ERROR;
473 } else {
474 slot_duration = atof(argv[2]);
475 return TCL_OK;
476 }
477 } else if (strcasecmp(argv[1], "setGuardTime") == 0) {
478 if (fair_mode == 1) {
479 std::cout << "Fair mode is being used! Change to generic TDMA"
480 << std::endl;
481 return TCL_ERROR;
482 } else {
483 guard_time = atof(argv[2]);
484 return TCL_OK;
485 }
486 } else if (strcasecmp(argv[1], "setSlotNumber") == 0) {
487 slot_number = atoi(argv[2]);
488 return TCL_OK;
489 } else if (strcasecmp(argv[1], "setMacAddr") == 0) {
490 addr = atoi(argv[2]);
491 if (debug_)
492 cout << "TDMA MAC address of current node is " << addr
493 << std::endl;
494 return TCL_OK;
495 } else if (strcasecmp(argv[1], "setLogLabel") == 0) {
496 name_label_ = argv[2];
497 if (debug_)
498 cout << "TDMA name_label_ " << name_label_
499 << std::endl;
500 return TCL_OK;
501 }
502 }
503 return MMac::command(argc, argv);
504}
505
506int
508{
509 if (m->type() == CLMSG_UWMMAC_ENABLE) {
510 ClMsgUwMmacEnable *command = dynamic_cast<ClMsgUwMmacEnable *>(m);
511 if (command->getReqType() == ClMsgUwMmac::SET_REQ) {
512 (command->getEnable()) ? start(NOW + start_time) : stop();
513 command->setReqType(ClMsgUwMmac::SET_REPLY);
514 return 0;
515 }
516 }
517 return MMac::recvSyncClMsg(m);
518}
ClMsgUwMmacEnable should be and used to ask either to set or get the transmitting power of a specific...
Class that represent the binding of the protocol with tcl.
Definition uwtdma.cpp:51
TDMAModuleClass()
Constructor of the TDMAGenericModule class.
Definition uwtdma.cpp:57
TclObject * create(int, const char *const *)
Creates the TCL object needed for the tcl language interpretation.
Definition uwtdma.cpp:66
virtual void expire(Event *e)
Method call when the timer expire.
Definition uwtdma.cpp:74
Class that represents a TDMA Node.
Definition uwtdma.h:92
std::string name_label_
label added in the log file, empty string by default
Definition uwtdma.h:237
UwTDMA()
Constructor of the TDMA class.
Definition uwtdma.cpp:79
virtual void recvFromUpperLayers(Packet *p)
Receive the packet from the upper layer (e.g.
Definition uwtdma.cpp:145
virtual void initPkt(Packet *p)
Method called to add the MAC header size.
Definition uwtdma.cpp:341
virtual void txData()
Transmit a data packet if in my slot.
Definition uwtdma.cpp:203
int checkPriority
flag to set to 1 if UWCBR module uses packets with priority, set to 0 otherwise.
Definition uwtdma.h:238
UWTDMA_STATUS transceiver_status
Variable holding the status enum type.
Definition uwtdma.h:209
virtual void start(double delay)
Schedule the beginning of each TDMA cycle, each one after delay.
Definition uwtdma.cpp:389
int tot_slots
Number of slots in the frame (fair_mode)
Definition uwtdma.h:217
double guard_time
Guard time between slots.
Definition uwtdma.h:223
int sea_trial_
Written log variable.
Definition uwtdma.h:213
int max_packet_per_slot
max numer of packet it can transmit per slot
Definition uwtdma.h:232
int drop_old_
flag to set the drop packet policy in case of buffer overflow: if 0 (default) drops the new packet,...
Definition uwtdma.h:235
virtual void stateTxData()
Change transceiver status and and start to transmit if in my slot Used when there's spare time,...
Definition uwtdma.cpp:195
virtual void Phy2MacStartRx(const Packet *p)
Method called when the Phy Layer start to receive a Packet.
Definition uwtdma.cpp:271
virtual void rxPacketNotForMe(Packet *p)
Method called when the Packet received is determined to be not for me.
Definition uwtdma.cpp:352
int debug_
Debug variable: 0 for no info, >-5 for small info, <-5 for complete info.
Definition uwtdma.h:211
int max_queue_size
Maximum dimension of Queue.
Definition uwtdma.h:231
int HDR_size
Size of the HDR if any.
Definition uwtdma.h:221
int fair_mode
Fair modality on if 1: then only set tot_slots and common guard_time.
Definition uwtdma.h:214
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
Definition uwtdma.cpp:423
UwTDMATimer tdma_timer
TDMA timer handler.
Definition uwtdma.h:226
std::ofstream out_file_stats
File stream for the log file.
Definition uwtdma.h:228
virtual ~UwTDMA()
Destructor of the TDMA class.
Definition uwtdma.cpp:140
virtual int recvSyncClMsg(ClMessage *m)
Cross-Layer messages synchronous interpreter.
Definition uwtdma.cpp:507
virtual void Mac2PhyStartTx(Packet *p)
Method called when the Mac Layer start to transmit a Packet.
Definition uwtdma.cpp:236
virtual void Phy2MacEndTx(const Packet *p)
Method called when the Mac Layer finish to transmit a Packet.
Definition uwtdma.cpp:258
virtual void stop()
Terminate a TDMA cycle, essentially cancel the TDMA timer.
Definition uwtdma.cpp:412
unsigned long int getEpoch()
Calculate the epoch of the event.
Definition uwtdma.h:186
bool enable
Definition uwtdma.h:229
virtual void Phy2MacEndRx(Packet *p)
Method called when the Phy Layer finish to receive a Packet.
Definition uwtdma.cpp:281
int packet_sent_curr_slot_
counter of packet has been sent in the current slot
Definition uwtdma.h:233
double frame_duration
Frame duration.
Definition uwtdma.h:222
double start_time
Time to wait before starting the protocol.
Definition uwtdma.h:225
int slot_status
Is it my turn to transmit data?
Definition uwtdma.h:210
virtual void changeStatus()
Alternate TDMA status between MY_STATUS and NOT_MY_STATUS.
Definition uwtdma.cpp:359
@ RECEIVING
Definition uwtdma.h:206
@ TRANSMITTING
Definition uwtdma.h:206
@ IDLE
Definition uwtdma.h:206
double slot_duration
Slot duration.
Definition uwtdma.h:224
std::deque< Packet * > buffer
Buffer of the MAC node.
Definition uwtdma.h:227
int slot_number
set the position of the node in the frame (fair_mode) (starting from 0 to tot_slots-1)
Definition uwtdma.h:218
hdr_uwcbr describes UWCBR packets.
char & priority()
Reference to the priority_ variable.
Provides the UWCBR packets header description and the definition of the class UWCBR.
#define HDR_UWCBR(p)
TDMAModuleClass class_uwtdma
Provides the definition of the class UWTDMA.
#define UW_TDMA_STATUS_NOT_MY_SLOT
Status slot not active >
Definition uwtdma.h:53
#define UW_TDMA_STATUS_MY_SLOT
Status slot active>
Definition uwtdma.h:52