42#include <clmsg-discovery.h>
65 : PacketHeaderClass(
"PacketHeader/TLOHI", sizeof(
hdr_tlohi))
82 : TclClass(
"Module/UW/TLOHI")
99 switch (module->curr_state) {
104 cout << NOW <<
" MMacTLOHI(" <<
module->addr
105 << ") timer expire() current state = "
106 << module->status_info[module->curr_state]
107 << " ACK not received, next state = "
108 << module->status_info[STATE_WAIT_END_CR] << endl;
110 module->last_reason = REASON_ACK_TIMEOUT;
111 if (module->curr_tx_rounds < module->max_tx_rounds)
112 module->stateTxData();
120 cout << NOW <<
" MMacTLOHI(" <<
module->addr
121 << ") timer expire() current state = "
122 << module->status_info[module->curr_state]
123 << " CR expired, next state = "
124 << module->status_info[STATE_IDLE] << endl;
126 module->last_reason = REASON_CR_END;
133 cout << NOW <<
" MMacTLOHI(" <<
module->addr
134 << ") timer expire() current state = "
135 << module->status_info[module->curr_state]
136 << " backoff expired, next state = "
137 << module->status_info[STATE_START_CONTENTION] << endl;
139 module->last_reason = REASON_BACKOFF_TIMEOUT;
140 module->stateStartContention();
146 cout << NOW <<
" MMacTLOHI(" <<
module->addr
147 << ") timer expire() current state = "
148 << module->status_info[module->curr_state]
149 << " xACK not received, next state = "
150 << module->status_info[STATE_RECONTEND_WINDOW] << endl;
152 module->last_reason = REASON_XACK_TIMEOUT;
153 module->stateRecontendWindow();
159 cout << NOW <<
" MMacTLOHI(" <<
module->addr
160 << ") timer expire() current state = "
161 << module->status_info[module->curr_state]
162 << " contention ended, next state = "
163 << module->status_info[STATE_COUNT_CONTENDERS] << endl;
165 module->last_reason = REASON_WAIT_CR_END;
166 module->stateCountContenders();
172 cout << NOW <<
" MMacTLOHI(" <<
module->addr
173 << ") timer expire() current state = "
174 << module->status_info[module->curr_state]
175 << " sleep period expired, next state = "
176 << module->status_info[STATE_RECONTEND_WINDOW] << endl;
178 module->last_reason = REASON_SLEEP_TIMEOUT;
179 module->stateRecontendWindow();
185 cout << NOW <<
" MMacTLOHI(" <<
module->addr
186 << ") timer expire() current state = "
187 << module->status_info[module->curr_state]
188 << " recontend window expired, next state = "
189 << module->status_info[STATE_IDLE] << endl;
191 module->last_reason = REASON_RECONTEND_END;
196 cout << NOW <<
" MMacTLOHI(" <<
module->addr
197 << ") timer expire() logical error, current state = "
198 << module->status_info[module->curr_state] << endl;
208 cout << NOW <<
" MMacTLOHI(" <<
module->addr
209 << ") data timer expire() turning off DATA PHY."
210 << " Current state = " << module->status_info[module->curr_state]
226 , data_phy_timer(this)
246 , session_active(false)
247 , backoff_pending(false)
248 , tone_transmitted(false)
249 , mphy_ids_initialized(false)
250 , print_transitions(false)
251 , has_buffer_queue(false)
260 bind(
"HDR_size", (
int *) &
HDR_size);
261 bind(
"ACK_size", (
int *) &
ACK_size);
264 bind(
"debug_", (
int *) &debug_);
287 Tcl &tcl = Tcl::instance();
289 if (strcasecmp(argv[1],
"addTonePhy") == 0) {
292 dynamic_cast<MPhy_WakeUp *
>(TclObject::lookup(argv[2]));
300 cout << NOW <<
" MMacTLOHI(" << addr
301 <<
")::command() addTonePhy called, tone_phy_id = "
306 }
else if (strcasecmp(argv[1],
"addDataPhy") == 0) {
308 MPhy *data_phy =
dynamic_cast<MPhy *
>(TclObject::lookup(argv[2]));
316 cout << NOW <<
" MMacTLOHI(" << addr
317 <<
")::command() addDataPhy called, data_phy_id = "
323 }
else if (strcasecmp(argv[1],
"setDataName") == 0) {
326 }
else if (strcasecmp(argv[1],
"setMacAddr") == 0) {
327 addr = atoi(argv[2]);
329 cout <<
"T-LOHI MAC address of current node is " << addr
333 }
else if (argc == 2) {
334 if (strcasecmp(argv[1],
"setAckMode") == 0) {
337 }
else if (strcasecmp(argv[1],
"setNoAckMode") == 0) {
340 }
else if (strcasecmp(argv[1],
"setConservativeUnsyncMode") == 0) {
345 }
else if (strcasecmp(argv[1],
"setAggressiveUnsyncMode") == 0) {
358 else if (strcasecmp(argv[1],
"initialize") == 0) {
363 fout.open(
"/tmp/TLOHIstateTransitions.txt", ios_base::app);
365 }
else if (strcasecmp(argv[1],
"printTransitions") == 0) {
368 }
else if (strcasecmp(argv[1],
"getCRTime") == 0) {
373 else if (strcasecmp(argv[1],
"getQueueSize") == 0) {
374 tcl.resultf(
"%d",
Q.size());
376 }
else if (strcasecmp(argv[1],
"getTonePktsTx") == 0) {
379 }
else if (strcasecmp(argv[1],
"getTonePktsRx") == 0) {
382 }
else if (strcasecmp(argv[1],
"getUpLayersDataRx") == 0) {
387 return MMac::command(argc, argv);
400 return Module::crLayCommand(m);
408 cout <<
"MMacTLOHI(" << addr
409 <<
")::command() initialized command not called, aborting..."
443 cout << NOW <<
" MMacTLOHI(" << addr
455 system(
"rm -f /tmp/TLOHIstateTransitions.txt");
456 system(
"touch /tmp/TLOHIstateTransitions.txt");
471 "Wait for the end of Contention state";
507 cout << NOW <<
" MMacTLOHI(" << addr
508 <<
")::initMphyIds() Error, data phy name not set" << endl;
513 m.addSenderData((
const PlugIn *)
this,
520 sendSyncClMsgDown(&m);
524 DiscoveryStorage lower_layer = m.findLayer(getLayer() - 1);
528 DiscoveryStorage tone_phy_db =
529 lower_layer.findTclName(
"Module/MPhy/Underwater/WKUP");
530 DiscoveryStorage data_phy_db =
538 if (tone_phy_db.getSize() == 1)
540 if (data_phy_db.getSize() == 1)
568 Packet *temp_data_pkt;
573 temp_data_pkt = (
Q.front())->copy();
574 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
577 temp_data_pkt = Packet::alloc();
578 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
583 temp_data_pkt = Packet::alloc();
584 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
588 temp_data_pkt = Packet::alloc();
589 hdr_cmn *ch = HDR_CMN(temp_data_pkt);
594 duration = Mac2PhyTxDuration(dest_addr, temp_data_pkt);
595 Packet::free(temp_data_pkt);
602 timer.force_cancel();
612 incrTotalBackoffTimes();
613 double random = RNG::defaultrng()->uniform_double();
615 while (random == 0) {
616 random = RNG::defaultrng()->uniform_double();
624 cout << NOW <<
" MMacTLOHI(" << addr
658 incrDiscardedPktsTx();
667 hdr_cmn *ch = hdr_cmn::access(p);
669 hdr_mac *mach = HDR_MAC(p);
676 int curr_size = ch->size();
679 ch->timestamp() = tlohih->
ts;
698 mach->macSA() = addr;
712 int contenders_no = 0;
716 if (time_interval > 0) {
718 double decimal = contenders - floor(contenders);
720 contenders_no = floor(contenders);
722 contenders_no = ceil(contenders);
727 cout << NOW <<
" MMacTLOHI(" << addr
728 <<
")::countContenders() time interval = " << setprecision(12)
729 << scientific << time_interval << fixed
730 <<
" [s]; contenders = " << contenders_no << endl;
733 return (contenders_no);
759 cout << NOW <<
" MMacTLOHI(" << addr
760 <<
")::Phy2MacEndTx() DATA sent, from "
768 cout << NOW <<
" MMacTLOHI(" << addr
769 <<
")::Phy2MacEndTx() DATA sent, from "
788 cout << NOW <<
" MMacTLOHI(" << addr
789 <<
")::Phy2MacEndTx() ACK sent, from "
800 cout << NOW <<
" MMacTLOHI(" << addr
801 <<
")::Phy2MacEndTx() TONE sent, from "
809 cout << NOW <<
" MMacTLOHI(" << addr
810 <<
")::Phy2MacEndTx() logical error, current state = "
823 hdr_cmn *ch = HDR_CMN(p);
824 hdr_MPhy *ph = HDR_MPHY(p);
833 cout << NOW <<
" MMacTLOHI(" << addr
834 <<
")::Phy2MacStartRx() receiving a DATA or ACK pkt,"
835 <<
" rescheduling data_phy closure" << endl;
845 hdr_cmn *ch = HDR_CMN(p);
846 packet_t rx_pkt_type = ch->ptype();
853 hdr_mac *mach = HDR_MAC(p);
854 hdr_MPhy *ph = HDR_MPHY(p);
859 int source_mac = mach->macSA();
860 int dest_mac = mach->macDA();
862 double gen_time = ph->txtime;
863 double received_time = ph->rxtime;
864 double diff_time = received_time - gen_time;
867 double tone_time_interval = 0;
871 else if (ch->error()) {
881 cout << NOW <<
" MMacTLOHI(" << addr <<
")::Phy2MacEndRx() "
883 <<
", received a pkt type = " <<
pkt_type_info[tlohi_pkt_type]
884 <<
", src addr = " << mach->macSA()
885 <<
" dest addr = " << mach->macDA()
886 <<
", estimated distance between nodes = " << distance <<
" m "
896 (dest_mac == addr)) {
900 (dest_mac != addr)) {
911 (dest_mac != addr)) {
941 (dest_mac == addr)) {
951 (dest_mac == addr)) {
970 cout << NOW <<
" MMacTLOHI(" << addr
971 <<
")::Phy2MacEndRx() unkown State, dropping pkt"
986 hdr_cmn *ch = HDR_CMN(p);
989 cout << NOW <<
" MMacTLOHI(" << addr <<
")::Phy2MacEndRx() "
991 <<
", received a TONE pkt: error = " << ch->error() << endl;
996 double tone_time_interval = 0;
1019 cout << NOW <<
" MMacTLOHI(" << addr
1020 <<
")::Phy2MacEndRx() TONE rx. From "
1036 cout << NOW <<
" MMacTLOHI(" << addr
1037 <<
")::Phy2MacEndRx() contenders number = " << contenders
1057 cout << NOW <<
" MMacTLOHI(" << addr <<
")::Phy2MacEndRx() "
1081 Packet *tone_pkt = Packet::alloc();
1111 Packet *ack_pkt = Packet::alloc();
1132 timer.force_cancel();
1152 incrDroppedPktsTx();
1157 cout << NOW <<
" MMacTLOHI(" << addr
1174 timer.force_cancel();
1190 timer.force_cancel();
1220 timer.force_cancel();
1262 timer.force_cancel();
1276 timer.force_cancel();
1289 timer.force_cancel();
1303 timer.force_cancel();
1318 timer.force_cancel();
1324 double random = RNG::defaultrng()->uniform_double();
1327 random = RNG::defaultrng()->uniform_double();
1332 timer.resched(recontend_duration);
1342 timer.force_cancel();
1351 hdr_cmn *ch = hdr_cmn::access(data_pkt);
1354 ch->size() = ch->size() -
HDR_size;
1368 cout << NOW <<
" MMacTLOHI(" << addr <<
")::printStateInfo() "
1374 fout << left << setw(10) << NOW <<
" MMacTLOHI(" << addr
1375 <<
")::printStateInfo() "
1379 <<
". Backoff duration = " << delay << endl;
1381 fout << left << setw(10) << NOW <<
" MMacTLOHI(" << addr
1382 <<
")::printStateInfo() "
1392 std::string response;
1393 std::cout <<
"Press Enter to continue";
1394 std::getline(std::cin, response);
virtual void expire(Event *e)
Event method called when the timer expire.
Class that represents the T-LOHI MAC protocol for a node.
virtual double getCRduration()
Returns the duration of the Contention Round, where the nodes contend the channel.
virtual void initMphyIds()
Initializes the ID of the PHY layer for tone and Data.
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
double tone_data_delay
Not used anymore.
virtual void stateWaitXAck()
The node has just received a DATA packet intended for another node.
int curr_dest_addr
Current destination MAC address.
ofstream fout
Object that handle the output file for the state transition of the protocol.
virtual void exitBackoff()
Reset the timer for Backoff (i.e.
static map< TLOHI_STATUS, string > status_info
Map between the state and the textual description of the state.
int buffer_pkts
Buffer capacity in number of packets.
virtual int getTonePktsRx()
returns the number of tones received in the simulation
virtual void stateDataReceived(Packet *data_pkt)
A data packet is received.
queue< Packet * > Q
MAC queue used for packet scheduling.
int u_data_id
simulation-unique data packet ID
virtual void stateSleep()
Simulate the sleep modality of the PHY layer of the node, while the node is waiting for the DATA.
virtual void Phy2MacEndRx(Packet *p)
Method called when the Phy Layer finish to receive a Packet.
virtual void stateWaitEndContention()
The nodes waits the end of Contention listening the channel for possible contenders.
double backoff_start_time
Timestamp of the backoff start time.
virtual void recvFromUpperLayers(Packet *p)
Receives the packet from the upper layer (e.g.
bool mphy_ids_initialized
Flag that indicates if the IDs of the PHY layers is stored.
double wait_costant
Additive factor in the calculation of ACK timer.
Timer timer
timer for Contention Round
virtual void incrTonePktsTx()
Increments the number of the TONE sended.
virtual void incrCurrTxRounds()
Increments the number of times a packet has been transmitted.
virtual void stateTxAck()
The node transmit the ACK packet for a received DATA packet (in ACK_MODE modality)
virtual void rxAck(Packet *p)
Method that receive an ACK packet.
virtual int getUpLayersDataPktsRx()
TLOHI_MODE op_mode
Operational mode of the protocol.
virtual void refreshReason(TLOHI_REASON_STATUS reason)
Refresh the reason for the change of state of the protocol.
virtual void incrTonePktsRx()
Increments the number of the TONE received.
virtual void waitForUser()
Used for debug purposes (permits a step-by-step behaviour of the protocol.
static map< TLOHI_PKT_TYPE, string > pkt_type_info
Map between the pkt-type and the description of the packet.
static map< TLOHI_REASON_STATUS, string > reason_info
Map between the reason for state transitions and the description of this reason.
virtual int countContenders(double time)
Returns the number of Contenders in this Contention Round based on the number of tones received.
virtual void rxTone(Packet *p)
Method that receives a Tone.
virtual int getTonePktsTx()
returns the number of tones transmitted in the simulation
bool TxActive
Flag that indicates if a transmission is occuring.
virtual void txTone()
Send the Tone to the tone PHY layer.
virtual void stateIdle()
IDLE state of the protocol.
virtual void initData()
Initializes the information of the protocol related to the data PHY layers (i.e.
int ACK_size
Size of the ACK packet in bytes.
int txsn
Transmitted data serial number.
bool print_transitions
Flat that indicates if the modality in which the protocol write in a file the state transitions is ac...
static bool initialized
Flag that indicates if the protocol is initialized.
bool has_buffer_queue
Flag that indicates whether the node has a buffer queue.
virtual void queuePop(bool flag)
Pop the first element of the data packets queue.
int curr_contenders
Number of contenders in current Contention Round.
virtual void Phy2MacEndTx(const Packet *p)
Method called when the PHY layer finish to transmit the packet.
TLOHI_ACK_MODE ack_mode
ACK mode of the protocol.
double DATA_listen_timeout
Time needed for the reception of a DATA packet.
virtual double computeTxTime(TLOHI_PKT_TYPE type)
Computes the Transmission Time of a Packet using a CrLayer Message to ask the PHY to perform this cal...
virtual void stateStartContention()
The node starts the Contention sending a Tone.
virtual void printStateInfo(double delay=0)
Initializes the protocol at the beginning of the simulation.
double session_distance
Distance between transmitter and receiver in this session.
static int u_pkt_id
simulation-unique packet ID
double CR_duration
Contention Round Duration.
virtual void initPkt(Packet *p, TLOHI_PKT_TYPE pkt_type)
Init the packet with the MAC address of the receiver and the sender, the size of the packet and the t...
virtual void checkPhyInit()
Checks if the PHY layers (for DATA and TONE) are initialized.
virtual int crLayCommand(ClMessage *m)
Cross-Layer messages interpreter.
virtual void txData()
Send a DATA packet to the data PHY layer.
virtual void stateTxData()
The node has won the CR.
virtual void checkDataPhy()
Checks if the PHY layer for Data is active.
TLOHI_REASON_STATUS last_reason
Last reason for state transition of the protocol.
double max_prop_delay
Maximum propagation delay in the network.
virtual void stateWaitCR()
Set the duration of the timer of the duration of the Contention Round.
int max_tx_rounds
Maximum transmission round for one packet.
bool backoff_pending
Flag that indicates if a backoff timer is pending.
TLOHI_STATUS prev_state
Previous state of the protocol.
virtual void stateBackoff()
The node is in Backoff state.
virtual void incrCurrTxTries()
Increments the number of tries for the transmission of a packet.
virtual void stateWaitAck()
The node has just sent a DATA packet.
TLOHI_STATUS curr_state
Current state of the protocol.
int data_phy_id
ID of the DATA PHY layer.
virtual void refreshState(TLOHI_STATUS state)
Refresh the state of the protocol.
int curr_tx_rounds
Number of current transmission round.
string tcl_modulation
Type of modulation adopted for data PHY layer.
Packet * curr_data_pkt
Pointer to the current data packet.
int max_payload
Maximum Data payload dimension in number of bytes.
int tone_phy_id
ID of the tone PHY layer.
MMacTLOHI()
Constructor of the class.
virtual void initInfo()
Initializes the map between the protocol states and the textual description of these states.
double sleep_timeout
Duration of the sleep phase for the PHY layer.
double recontend_time
Time needed for the recontention.
int HDR_size
Dimension of the header added by T-LOHI in bytes.
virtual void rxElse(Packet *p)
Receives other types of packets.
virtual void txAck()
Send a ACK packet of the data PHY layer.
DataTimer data_phy_timer
Timer that describe the time needed to receive the packet (i.e.
virtual void stateRecontendWindow()
Calculate the duration of the RecontendWindow.
double backoff_duration
Duration of the backoff timer.
int curr_tx_tries
Number of current transmission tries.
virtual void stateCountContenders()
The node counts the contenders in the CR.
bool tone_transmitted
Flag that indicates if a tone has been transmitted.
virtual void resetSession()
Resets the variable related to the Session (i.e.
double ACK_timeout
Time needed for the reception of a ACK packet.
virtual void setDestAddr(int mac_addr)
Store the MAC address of the destination for this session.
double max_tx_tries
Maximum transmission tries for one packet.
int last_data_id_tx
Last data packet received ID.
bool session_active
Flag that indicates if a Session is active.
virtual void Phy2MacStartRx(const Packet *p)
Method called when the Phy Layer start to receive a Packet.
virtual void getBackoffTime()
Performs the calculation of the Backoff timer.
double backoff_remaining
Remaining time of the backoff (if the timer has been freezed)
virtual ~MMacTLOHI()
Destructor of the class.
Class that describes the WakeUp PHY layer for T-LOHI MAC protocol.
Class that represent the binding with the tcl configuration script.
TclObject * create(int, const char *const *)
Create the TCL object needed for the tcl language interpretation.
TLOHIModuleClass()
Constructor of the class.
Class the describe the PacketHeader for T-LOHI header.
TLOHIPktClass()
Constructor of the class.
virtual void expire(Event *e)
Event method called when the timer expire.
Struct that defines the header of T-LOHI in the packets.
int data_sn
DATA packet sequence number.
double ts
packet timestamp, i.e., its generation time)
TLOHI_PKT_TYPE pkt_type
T-LOHI packet type.
static int offset_
Required by PacketManager Header.
packet_t orig_type
Original type of the packet (i.e.
int sn
sequence number of this packet
Header of the Wake Up Tone.
double startRx_time
Start Reception Time.
double endRx_time
End Reception Time.
@ SESSION_DISTANCE_NOT_SET
TLOHIPktClass class_tlohi_pkt
TLOHIModuleClass class_module_tlohi
Provides the declaration of uw-mac-TLohi MAC protocol.
static const int prop_speed
typical sound speed in underwater scenario
TLOHI_PKT_TYPE
Enumeration that indicates the possibile type of packets in T-LOHI MAC protocol.
#define TLOHI_DROP_REASON_BUFFER_FULL
@ STATE_WAIT_END_CONTENTION
#define TLOHI_DROP_REASON_UNKNOWN_TYPE
@ CONSERVATIVE_UNSYNC_MODE
#define TLOHI_DROP_REASON_WRONG_STATE
Provides the declaration of WakeUp PHY.
@ SESSION_DISTANCE_NOT_SET
Provides the definition of the Wake Up Tone Packet Header.