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.