diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/Makefile.am b/DESERT_Framework/DESERT/data_link/uwtwr/Makefile.am new file mode 100644 index 00000000..18f14a49 --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/Makefile.am @@ -0,0 +1,57 @@ +# +# Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the University of Padova (SIGNET lab) nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +AM_CXXFLAGS = -Wall -ggdb3 + +lib_LTLIBRARIES = libuwtwr.la +check_PROGRAMS = + +SUBDIRS = + +TESTS = + +libuwtwr_la_SOURCES = initlib.cpp\ + uwtwr_default.tcl\ + uwtwr_AAUV.cpp\ + uwtwr_NODE.cpp\ + uwtwr_PAUV.cpp + +libuwtwr_la_CPPFLAGS = @NS_CPPFLAGS@ @NSMIRACLE_CPPFLAGS@ @DESERT_CPPFLAGS@ +libuwtwr_la_LDFLAGS = @NS_LDFLAGS@ @NSMIRACLE_LDFLAGS@ @DESERT_LDFLAGS@ +libuwtwr_la_LIBADD = @NS_LIBADD@ @NSMIRACLE_LIBADD@ @DESERT_LIBADD@ + +nodist_libuwtwr_la_SOURCES = InitTcl.cc +BUILT_SOURCES = InitTcl.cc +CLEANFILES = InitTcl.cc + +TCL_FILES = uwtwr_default.tcl + +InitTcl.cc: Makefile $(TCL_FILES) + cat $(VPATH)/$(TCL_FILES) | @TCL2CPP@ uwtwr_default > InitTcl.cc + +EXTRA_DIST = $(TCL_FILES) \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/initlib.cpp b/DESERT_Framework/DESERT/data_link/uwtwr/initlib.cpp new file mode 100644 index 00000000..40a48e72 --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/initlib.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr/initlib.cpp + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provide the initialization of the uwtwr libraries + */ + +#include +#include "uwtwr_AAUV.h" +#include "uwtwr_PAUV.h" +#include "uwtwr_NODE.h" +#include "uwtwr_cmn_hdr.h" +#include "sap.h" +#include "packet.h" + +int hdr_POLL::offset_ = 0; +int hdr_ACK_NODE::offset_ = 0; + +packet_t PT_POLL; +packet_t PT_ACK_NODE; + +/** + * Class that describe the Header of POLL Packet + */ +static class PollHeaderClass : public PacketHeaderClass +{ +public: + /** + * Constructor of the class + */ + PollHeaderClass() + : PacketHeaderClass("PacketHeader/POLL", sizeof(hdr_POLL)) + { + this->bind(); + bind_offset(&hdr_POLL::offset_); + } +} class_hdr_POLL; + +/** + * Class that describe the Header of ACK sent by the node + */ +static class AckNodeHeaderClass : public PacketHeaderClass +{ +public: + /** + * Constructor of the class + */ + AckNodeHeaderClass() + : PacketHeaderClass("PacketHeader/ACK_NODE", sizeof(hdr_ACK_NODE)) + { + this->bind(); + bind_offset(&hdr_ACK_NODE::offset_); + } +} class_hdr_ACK_NODE; + +extern EmbeddedTcl uwtwr_default; + +extern "C" int +Uwtwr_Init() +{ + PT_POLL = p_info::addPacket("UWTWR/POLL"); + PT_ACK_NODE = p_info::addPacket("UWTWR/ACK_NODE"); + uwtwr_default.load(); + return 0; +} \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.cpp b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.cpp new file mode 100644 index 00000000..eb68b2e1 --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.cpp @@ -0,0 +1,350 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr_AAUV.cpp + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provides the implementation of UWTWR_AAUV class + */ + +#include +#include "mac.h" +#include "uwcbr-module.h" +#include "uwtwr_AAUV.h" +#include "uwtwr_cmn_hdr.h" + +#include +#include +#include +#include +#include "uwphy-clmsg.h" +#include + +static class UWTWR_AAUV_Class : public TclClass +{ +public: + UWTWR_AAUV_Class() + : TclClass("Module/UW/TWR/AAUV") + { + } + TclObject * + create(int, const char *const *) + { + return (new UWTWR_AAUV()); + } +} class_uwtwr_aauv; + +bool UWTWR_AAUV::initialized = false; + +std::map + UWTWR_AAUV::status_info; + +UWTWR_AAUV::UWTWR_AAUV() + : ack_timer(this) + , polling_index(2) + , curr_poll_packet(0) + , curr_ack_packet(0) + , T_ack_timer(2) // send POLL every 2 seconds, need to be set in Tcl + , curr_state(UWTWR_AAUV_STATUS_IDLE) + , prev_state(UWTWR_AAUV_STATUS_IDLE) // not used + , TxEnabled(false) + , n_poll_tx(0) + , n_ack_rx(0) + , POLL_uid(0) + , RxAckEnabled(false) + , ack_enabled(1) + , n_dropped_ack_pkts(0) +{ + bind("T_ack_timer_", (double *) &T_ack_timer); + bind("ack_enabled_", (int *) &ack_enabled); + bind("POLL_size_", (int *) &POLL_size); +} + +UWTWR_AAUV::~UWTWR_AAUV() +{ +} + +int UWTWR_AAUV::command(int argc, const char *const * argv) +{ + Tcl &tcl = Tcl::instance(); + + if (argc == 2) { + if (strcasecmp(argv[1], "initialize") == 0) { + if (!initialized) + initInfo(); + return TCL_OK; + } else if (strcasecmp(argv[1], "run") == 0) { + stateIdle(); + return TCL_OK; + } else if (strcasecmp(argv[1], "getAckRx") == 0) { + tcl.resultf("%d", getAckRx()); + return TCL_OK; + } else if (strcasecmp(argv[1], "getDroppedAckPkts") == 0) { + tcl.resultf("%d", getDroppedAckPkts()); + return TCL_OK; + } else if (strcasecmp(argv[1], "getPollSent") == 0) { + tcl.resultf("%d", getPollSent()); + return TCL_OK; + } + } else if (argc == 3) { + if (strcasecmp(argv[1], "setMacAddr") == 0) { + addr = atoi(argv[2]); + return TCL_OK; + } + } + return MMac::command(argc, argv); +} + +int UWTWR_AAUV::crLayCommand(ClMessage *m) +{ + switch (m->type()) { + default: + return MMac::crLayCommand(m); + } +} + +void UWTWR_AAUV::ACKTimer::expire(Event *e) +{ + timer_status = UWTWR_AAUV_EXPIRED; + module->AckTOExpired(); +} + +void UWTWR_AAUV::AckTOExpired() +{ + RxAckEnabled = false; + // go back to IDLE and poll the other node + stateIdle(); +} + +// Is it not needed if no data packets to send +// void UWTWR_AAUV::recvFromUpperLayers(Packet *p) +// { +// } + +void UWTWR_AAUV::Phy2MacStartRx(const Packet *p) +{ + hdr_cmn *cmh = hdr_cmn::access(p); + hdr_MPhy *ph = hdr_MPhy::access(p); + double gen_time = ph->txtime; + double received_time = ph->rxtime; + diff_time = received_time - gen_time; + if (cmh->ptype() == PT_ACK_NODE) { + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::RX_ACK_PACKET::TOF::" << diff_time << std::endl; + } +} + +void UWTWR_AAUV::Phy2MacEndRx(Packet *p) +{ + hdr_cmn *cmh = hdr_cmn::access(p); + hdr_mac *mach = HDR_MAC(p); + hdr_MPhy *ph = hdr_MPhy::access(p); + int dest_mac = mach->macDA(); + double gen_time = ph->txtime; + double received_time = ph->rxtime; + diff_time = received_time - gen_time; + + if (cmh->error()) { + if (cmh->ptype_ == PT_ACK_NODE) { + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::PHY2MACENDRX_DROP_ACK" << std::endl; + incrDroppedAckPkts(); + } else { + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::PHY2MACENDRX_DROP_POLL" << std::endl; + incrErrorPktsRx(); + } + } else { + if ((dest_mac == addr) || (dest_mac == (int) MAC_BROADCAST)) { + if (cmh->ptype() == PT_ACK_NODE && ack_enabled) { + incrAckRx(); + curr_ack_packet = p->copy(); + Packet::free(p); + stateRxAck(); + //check ACK value and discard acked packets + } + } else { + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::PHY2MACENDRX::DROP_ACK_WRONG_DEST_" + << mach->macDA() << std::endl; + incrXCtrlPktsRx(); + drop(p, 1, UWPOLLING_AUV_DROP_REASON_WRONG_RECEIVER); + } + } +} + +void UWTWR_AAUV::Mac2PhyStartTx(Packet *p) +{ + hdr_cmn *cmh = hdr_cmn::access(p); + if (cmh->ptype() == PT_POLL) { + stateWaitAck(); + } else { + stateWaitAck(); + } + MMac::Mac2PhyStartTx(p); +} + +void UWTWR_AAUV::Phy2MacEndTx(const Packet *p) +{ + // if (debug_) + // std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + // << ")::PHYEndTx" << std::endl; +} + +void UWTWR_AAUV::stateTxPoll() +{ + if(TxEnabled) { + SetNodePoll(); + // poll when the id of node to poll is correct + if(polling_index > 0) { + refreshState(UWTWR_AAUV_STATUS_TX_POLL); + Packet *p = Packet::alloc(); + hdr_cmn *cmh = hdr_cmn::access(p); + hdr_mac *mach = HDR_MAC(p); + // hdr_POLL *pollh = HDR_POLL(p); + cmh->ptype() = PT_POLL; + + //Set the size to POLL_size with correct bytes number + cmh->size() = POLL_size; + mach->set(MF_CONTROL, addr, MAC_BROADCAST); + mach->macSA() = addr; + mach->macDA() = MAC_BROADCAST; + curr_poll_packet = p->copy(); + Packet::free(p); + hdr_POLL *pollh = HDR_POLL(curr_poll_packet); + POLL_uid++; + pollh->POLL_uid_ = POLL_uid; + pollh->id_ = curr_node_id; + + // Save info (tof) to be sent in POLL in header (easier for now) + pollh->tof_ = diff_time; + + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::STATE_TX_POLL::NODE::" << pollh->id_ + << std::endl; + TxPoll(); + // iteratively polling node 0, 1 by counting down + polling_index--; + } else { + if (debug_) + std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")::STATE_TX_POLL--->IDLE--->No node to POLL" + << std::endl; + stateIdle(); + } + } else { + if (debug_) + std::cerr << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + << ")---> going in stateTxPoll from WRONG STATE---> " + "current_state: " + << status_info[curr_state] << std::endl; + } +} + +void UWTWR_AAUV::TxPoll() +{ + // if(debug_) + // std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr << ")::TX_POLL" + // << std::endl; + incrCtrlPktsTx(); + incrPollTx(); + Mac2PhyStartTx(curr_poll_packet); +} + +void UWTWR_AAUV::SetNodePoll() +{ + if(polling_index >0) + { + if(polling_index == 2) + { + curr_node_id = 0; + } else if(polling_index == 1) + { + curr_node_id = 1; + } + } else { + polling_index += 2; + curr_node_id = 0; + } +} + +// when to set the state to idle? TCl run--idle, waitAck--idle, RxAck--idle +void UWTWR_AAUV::stateIdle() +{ + refreshState(UWTWR_AAUV_STATUS_IDLE); + // if (debug_) + // std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr << ")::IDLE STATE " + // << std::endl; + TxEnabled = true; + stateTxPoll(); +} + +void UWTWR_AAUV::initInfo() +{ + initialized = true; + + status_info[UWTWR_AAUV_STATUS_IDLE] = "Idle state"; + status_info[UWTWR_AAUV_STATUS_TX_POLL] = "Transmitting a POLL Packet"; + status_info[UWTWR_AAUV_STATUS_WAIT_ACK] = "Waiting for an ACK Packet"; + status_info[UWTWR_AAUV_STATUS_RX_ACK] = "Receiving ACK Packet"; +} + +void UWTWR_AAUV::stateWaitAck() +{ + refreshState(UWTWR_AAUV_STATUS_WAIT_ACK); + TxEnabled = false; + RxAckEnabled = true; + // if (debug_) + // std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + // << ")::scheduling_ACK_TIMER_T= " << T_ack_timer << std::endl; + ack_timer.schedule(T_ack_timer); +} + +void UWTWR_AAUV::stateRxAck() +{ + if(RxAckEnabled) { + // if (debug_) + // std::cout << POLL_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_AAUV(" << addr + // << ")::stateRxAck()ACK received" << std::endl; + refreshState(UWTWR_AAUV_STATUS_RX_ACK); + RxAckEnabled = false; + // handleAck(); + + // maybe should let ack_timer expire + // ack_timer.force_cancel(); + // stateIdle(); + } + +} \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.h b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.h new file mode 100644 index 00000000..725c24df --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_AAUV.h @@ -0,0 +1,559 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr_AAUV.h + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provide the definition of the class UWTWR + */ + +#ifndef UWTWR_AAUV_H +#define UWTWR_AAUV_H + +#include "uwtwr_cmn_hdr.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uwsmposition.h" + +#define UWPOLLING_AUV_DROP_REASON_WRONG_RECEIVER \ + "DWR" /**< Packet for another node */ + +/** + * Class that represents the UWTWR MAC layer of an Active(polling) AUV. + */ +class UWTWR_AAUV : public MMac +{ +public: + /** + * Constructor of the UWTWR_AAUV class + */ + UWTWR_AAUV(); + /** + * Destructor of the UWTWR_AAUV class + */ + virtual ~UWTWR_AAUV(); + + /** + * TCL command interpreter. It implements the following OTcl methods: + * + * @param argc Number of arguments in argv. + * @param argv Array of strings which are the command parameters + (Note that argv[0] is the name of the + object). + * @return TCL_OK or TCL_ERROR whether the command has been dispatched + successfully or + not. + */ + virtual int command(int argc, const char *const *argv); + + /** + * Cross-Layer messages interpreter + * + * @param ClMessage* an instance of ClMessage that represent the message + * received + * @return 0 if successful. + */ + virtual int crLayCommand(ClMessage *m); + +protected: + /*********************************** + | Internal variable and functions | + ***********************************/ + + enum UWTWR_AAUV_STATUS + { + UWTWR_AAUV_STATUS_IDLE = 1, + UWTWR_AAUV_STATUS_TX_POLL, + UWTWR_AAUV_STATUS_WAIT_ACK, + UWTWR_AAUV_STATUS_RX_ACK + }; /* */ + + /**< Status of the timer */ + enum UWTWR_AAUV_TIMER_STATUS { + UWTWR_AAUV_IDLE = 1, + UWTWR_AAUV_RUNNING, + UWTWR_AAUV_FROZEN, + UWTWR_AAUV_EXPIRED + }; + + /** + * Class that describes the timer in the AUV + */ + class UWTWR_AAUV_Timer : public TimerHandler + { + public: + /** + * Constructor of the UWTWR_AAUV_Timer class + * @param UWTWR_AAUV* a pointer to an object of type Uwpolling_AUV + */ + UWTWR_AAUV_Timer(UWTWR_AAUV *m) + : TimerHandler() + , start_time(0.0) + , left_duration(0.0) + , counter(0) + , module(m) + , timer_status(UWTWR_AAUV_IDLE) + { + assert(m != NULL); + // module = m; + } + + /** + * Destructor of the UWTWR_AUV_Timer class + */ + virtual ~UWTWR_AAUV_Timer() + { + } + + /** + * Freeze the timer + */ + virtual void freeze() + { + assert(timer_status == UWTWR_AAUV_RUNNING); + left_duration -= (NOW - start_time); + if (left_duration <= 0.0){ + left_duration = module->mac2phy_delay_; + } + force_cancel(); + timer_status = UWTWR_AAUV_FROZEN; + } + + /** + * unFreeze is used to resume the timer starting from the point where it + * was freezed + */ + virtual void unFreeze() + { + assert(timer_status == UWTWR_AAUV_FROZEN); + start_time = NOW; + assert(left_duration > 0); + sched(left_duration); + timer_status = UWTWR_AAUV_RUNNING; + } + + /** + * stops the timer + */ + virtual void stop() + { + timer_status = UWTWR_AAUV_IDLE; + force_cancel(); + } + + /** + * Schedules a timer + * @param double the duration of the timer + */ + virtual void schedule(double val) + { + start_time = NOW; + left_duration = val; + timer_status = UWTWR_AAUV_RUNNING; + resched(val); + } + + /** + * Checks if the timer is IDLE + * @return bool true or false + */ + bool isIdle() + { + return (timer_status == UWTWR_AAUV_IDLE); + } + + /** + * Checks if the timer is RUNNING + * @return true or false + */ + bool isRunning() + { + return (timer_status == UWTWR_AAUV_RUNNING); + } + + /** + * Checks if the timer is EXPIRED + * @return true or false + */ + + bool isExpired() + { + return (timer_status == UWTWR_AAUV_EXPIRED); + } + + /** + * Checks if the timer is FROZEN + * @return true or false + */ + bool isFrozen() + { + return (timer_status == UWTWR_AAUV_FROZEN); + } + + /** + * Checks if the timer is ACTIVE + * @return true or false + */ + bool isActive() + { + return (timer_status == UWTWR_AAUV_FROZEN || + timer_status == UWTWR_AAUV_RUNNING); + } + + /** + * Resets the counter of the timer + */ + void + resetCounter() + { + counter = 0; + } + + /** + * Increments the counter of the timer + */ + void + incrCounter() + { + ++counter; + } + + /** + * Returns the counter of the timer + * @return the value of the counter of the timer + */ + int + getCounter() + { + return counter; + } + + /** + * Returns the left duration of the timer + * @return the value of the counter of the timer + */ + double getDuration() + { + return left_duration; + } + + protected: + double start_time; /**< Start Time of the timer */ + double left_duration; /**< Left duration of the timer */ + int counter; /**< counter of the timer */ + UWTWR_AAUV *module; /* Pointer to an object of type UWTWR_AAUV */ + UWTWR_AAUV_TIMER_STATUS timer_status; /**< Timer status */ + }; + + /** + * Class (inherited from UWTWR_AAUV_Timer) used to handle the timer of + * Ack packet + * When the AUV give the POLL packet to a node, he set up the timer in which + * the node has to transmit + * his packet. The duration of the timer is calculated based on the RTT + * between the AUV and the node and + * the duration of the transmission of a packet + */ + // maybe needed for handling turnaround time? + class PollTimer : public UWTWR_AAUV_Timer + { + public: + /** + * Conscructor of PollTimer class + */ + PollTimer(UWTWR_AAUV *m) + : UWTWR_AAUV_Timer(m) + { + } + + /** + * Destructor of PollTimer class + * @param UWTWR_AAUV* Pointer of an object of type Uwpolling_AUV + */ + virtual ~PollTimer() + { + } + + protected: + /** + * Method call when the timer expire + * @param Event* pointer to an object of type Event + */ + virtual void expire(Event *e); + }; + + class ACKTimer : public UWTWR_AAUV_Timer + { + public: + /** + * Conscructor of ACKTimer class + */ + ACKTimer(UWTWR_AAUV *m) + : UWTWR_AAUV_Timer(m) + { + } + + /** + * Destructor of ACKTimer class + * @param UWTWR_AAUV* Pointer of an object of type Uwpolling_AUV + */ + virtual ~ACKTimer() + { + } + + protected: + /** + * Method call when the timer expire + * @param Event* pointer to an object of type Event + */ + virtual void expire(Event *e); + }; + + // /** + // * Receive the packet from the upper layer (e.g. IP) + // * @param Packet* pointer to the packet received + // * + // */ + // virtual void recvFromUpperLayers(Packet *p); + + /** + * Method called when the Phy Layer finish to receive a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacEndRx(Packet *p); + + /** + * Method called when the Phy Layer start to receive a Packet + * @param const Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacStartRx(const Packet *p); + + /** + * Method called when the Mac Layer start to transmit a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in transmission + */ + virtual void Mac2PhyStartTx(Packet *p); + + /** + * Method called when the PHY Layer finish to transmit a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in transmission + */ + virtual void Phy2MacEndTx(const Packet *p); + + /** + * Increases the number of Ack packets received. Used for statistical + * purposes + */ + inline void incrAckRx() + { + n_ack_rx++; + } + + /** + * Increases the number of wrong ACK packet received. + * Used for statistical purposes + */ + inline void incrDroppedAckPkts() + { + n_dropped_ack_pkts++; + } + + /** + * Returns the number of ACK received during the simulation + * @return int n_probe_rx the number of PROBE received + */ + inline int getAckRx() + { + return n_ack_rx; + } + + /** + * Return the number of ACK packets discarded because of wrong CRC + * @return int N_dropped_probe_pkts number of PROBE pkts dropped + */ + inline int getDroppedAckPkts() + { + return n_dropped_ack_pkts; + } + + /** + * Refresh the state of the protocol + * @param UWTWR_AAUV_STATUS current state of the protcol + */ + virtual void refreshState(UWTWR_AAUV_STATUS state) + { + prev_state = curr_state; + curr_state = state; + } + + /** + * IDLE state. Each variable is resetted + */ + virtual void stateIdle(); + + /** + * State of the protocol in which a POLL packet is initialized + */ + virtual void stateTxPoll(); + + /** + * ACK TIMER is Expired. In this method the reception of ACK is disabled. + */ + virtual void AckTOExpired(); + + /** + * State of the protcol in which the ACK timer is set up + */ + virtual void stateWaitAck(); + + /** + * Handle the recption of an ACK from the node + */ + virtual void stateRxAck(); + + /** + * Initializes the protocol at the beginning of the simulation. This method + * is called by + * a command in tcl. + * @param double delay + * @see command method + */ + virtual void initInfo(); + + /** + * Transmisssion of the POLL packet + */ + virtual void TxPoll(); + + /** + * Method for setting the id of node polled + */ + virtual void SetNodePoll(); + + /** + * Incrase the number of POLL transmitted + */ + inline void incrPollTx() + { + n_poll_tx++; + } + + /** + * Return the number of POLL packets sent during the simulation + * @return int n_poll_tx number of POLL packets sent during the simulation + */ + inline int getPollSent() + { + return n_poll_tx; + } + + /** + * Calculate the epoch of the event. Used in sea-trial mode + * @return the epoch of the system + */ + inline unsigned long int getEpoch() + { + unsigned long int timestamp = + (unsigned long int) (std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count() ); + return timestamp; + } + // which time to return? + // inline unsigned long int + // getEpoch() + // { + // return time(NULL); + // } + + + // timers + // PollTimer poll_timer; /**< POLL Timer */ + ACKTimer ack_timer; /**< ACK Timer */ + + int polling_index; /**< Index of the node that the AUV is polling */ + + // pointer to packets + Packet *curr_poll_packet; /**< Pointer to the current POLL packet >*/ + Packet *curr_ack_packet; /**< Pointer to the current ACK packet*/ + + // packet size + int POLL_size; /**< Size of the POLL pkt */ + int ACK_size; /**< Size of the ACK pkt */ + + // input parameters via TCL + double T_ack_timer; /** Duration of ACK_TIMER + T_ack_timer = T_ack + RTT + T_guard */ + + // states of protocol + UWTWR_AAUV_STATUS curr_state, + prev_state; /* */ + + // mapping + static std::map status_info; + /** Map the UWTWR_AAUV_AUV_STATUS to the + description of each state */ + + static bool initialized; /**< Indicate if the protocol has been initialized or not */ + + bool TxEnabled; /**< true if the AUV is enabled to receive POLL + packets, false otherwise */ + + bool RxAckEnabled; /**< True if the ack reception is enabled */ + + uint curr_node_id; /**< ID of the node polled */ + + // statistics + int n_ack_rx; /**< Number of ack packets received */ + int n_poll_tx; /**< Number of POLL packets sent */ + uint POLL_uid; /**< POLL Unique ID */ + + int n_dropped_ack_pkts; /** +#include +#include + +static class UWTWR_NODE_Class : public TclClass +{ +public: + UWTWR_NODE_Class() + : TclClass("Module/UW/TWR/NODE") + { + } + TclObject * + create(int, const char *const *) + { + return (new UWTWR_NODE()); + } +} class_uwtwr_node; + +bool UWTWR_NODE::initialized = false; +std::map + UWTWR_NODE::status_info; +std::map + UWTWR_NODE::pkt_type_info; + +UWTWR_NODE::UWTWR_NODE() + : node_id(0) + , RxPollEnabled(true) + , T_backoff(0.1) + , AUV_mac_addr(0) + , n_ack_sent(0) + , n_times_polled(0) + , ACK_uid(0) + , curr_poll_pkt(0) + , curr_ack_pkt(0) + , backoff_timer(this) + , n_poll_dropped(0) + , curr_state(UWTWR_NODE_STATUS_IDLE) + , prev_state(UWTWR_NODE_STATUS_IDLE) + +{ + bind("node_id_", (uint *) &node_id); + bind("T_backoff_", (double *) &T_backoff); + bind("ACK_size_", (int *) &ACK_size); +} + +UWTWR_NODE::~UWTWR_NODE() +{ +} + +int UWTWR_NODE::command(int argc, const char *const *argv) +{ + Tcl &tcl = Tcl::instance(); + // look at uwpolling_NODE.cpp + if (argc == 2) { + if (strcasecmp(argv[1], "initialize") == 0) { + if (!initialized) + initInfo(); + return TCL_OK; + } else if (strcasecmp(argv[1], "getAckSent") == 0) { + tcl.resultf("%d", getAckSent()); + return TCL_OK; + } else if (strcasecmp(argv[1], "getTimesPolled") == 0) { + tcl.resultf("%d", getTimesPolled()); + return TCL_OK; + }else if (strcasecmp(argv[1], "getPollDropped") == 0) { + tcl.resultf("%d", getPollDropped()); + return TCL_OK; + } + } else if (argc == 3) { + if (strcasecmp(argv[1], "setMacAddr") == 0) { + addr = atoi(argv[2]); + return TCL_OK; + } + } + return MMac::command(argc, argv); +} + +int UWTWR_NODE::crLayCommand(ClMessage *m) +{ + switch (m->type()) { + default: + return MMac::crLayCommand(m); + } +} + +void UWTWR_NODE::initInfo() +{ + initialized = true; + + status_info[UWTWR_NODE_STATUS_IDLE] = "Idle state"; + status_info[UWTWR_NODE_STATUS_RX_POLL] = "Receiving a POLL Packet"; + status_info[UWTWR_NODE_STATUS_TX_ACK] = "Transmitting ACK Packet"; + + pkt_type_info[UWTWR_POLL_PKT] = "Poll packet"; + pkt_type_info[UWTWR_ACK_PKT] = "Ack packet"; +} + +// // To be implemented +// void UWTWR_NODE::recvFromUpperLayers(Packet *p) +// { +// } + +void UWTWR_NODE::BackOffTimer::expire(Event *e) +{ + if (module->debug_) + std::cout << module->ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << module->addr + << ")::BACKOFF_TIMER::EXPIRED" << std::endl; + timer_status = UWTWR_NODE_EXPIRED; + if (module->polled) { + module->BackOffTimerExpired(); + } +} + +void UWTWR_NODE::BackOffTimerExpired() +{ + if (polled) { + stateTxAck(); + } else { + if (debug_) { + std::cout << std::setprecision(10) << NOW << "UWTWR_NODE(" << addr + << ") Backoff timer expired but node not polled" + << std::endl; + } + } +} + +void UWTWR_NODE::Mac2PhyStartTx(Packet *p) +{ + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::MAC2PHYSTARTTX::ACK_PACKET" << std::endl; + MMac::Mac2PhyStartTx(p); +} + +void UWTWR_NODE::Phy2MacEndTx(const Packet *p) +{ + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::MAC2PHYENDTX::ACK_PACKET" << std::endl; + stateIdle(); +} + +void UWTWR_NODE::Phy2MacStartRx(const Packet *p) +{ + hdr_cmn *cmh = hdr_cmn::access(p); + if (cmh->ptype() == PT_POLL) { + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::PHY2MACSTARTRX::POLL_PACKET" << std::endl; + } +} + +void UWTWR_NODE::Phy2MacEndRx(Packet *p) +{ + hdr_cmn *ch = HDR_CMN(p); + hdr_mac *mach = HDR_MAC(p); + int dest_mac = mach->macDA(); + + if (ch->error()) { + if (ch->ptype() == PT_POLL) { + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::PHY2MACENDRX::DROP_POLL" << std::endl; + incrPollDropped(); + } + drop(p, 1, UWTWR_NODE_DROP_REASON_ERROR); + } else if ((dest_mac == addr) || (dest_mac == (int) MAC_BROADCAST)) { + if (ch->ptype() == PT_POLL) { + hdr_POLL *pollh = HDR_POLL(p); + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::PHY2MACENDRX::RX_POLL::POLLED_NODE= " + << pollh->id_ << std::endl; + curr_poll_pkt = p->copy(); + Packet::free(p); + stateRxPoll(); + } else { + drop(p, 1, UWTWR_NODE_DROP_REASON_UNKNOWN_TYPE); + } + } else { + incrXCtrlPktsRx(); + if (ch->ptype() == PT_POLL) { + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::PHY2MACENDRX::WARNING!!POLL packet not in " + "broadcast!!" + << std::endl; + } + drop(p, 1, UWTWR_NODE_DROP_REASON_WRONG_RECEIVER); + } +} + +void UWTWR_NODE::initPkt(UWTWR_NODE_PKT_TYPE pkt_type) +{ + if(pkt_type == UWTWR_ACK_PKT) { + Packet *p = Packet::alloc(); + hdr_ACK_NODE *ackh = HDR_ACK_NODE(p); + hdr_cmn *ch = hdr_cmn::access(p); + hdr_mac *mach = HDR_MAC(p); + ch->ptype() = PT_ACK_NODE; + mach->ftype() = MF_CONTROL; + mach->macDA() = AUV_mac_addr; + mach->macSA() = addr; + // set size of ACK pkt (10B) + ch->size() = ACK_size; + // ch->size() = sizeof(hdr_ACK_NODE); + ackh->id_node_ = node_id; + // save the ACK_uid to ACK pkt + ackh->ACK_uid_ = ACK_uid; + curr_ack_pkt = p->copy(); + Packet::free(p); + } +} + +void UWTWR_NODE::stateTxAck() +{ + if (polled) { + refreshState(UWTWR_NODE_STATUS_TX_ACK); + initPkt(UWTWR_ACK_PKT); + hdr_ACK_NODE *ackh = HDR_ACK_NODE(curr_ack_pkt); + // ACK_uid++; + // ackh->ACK_uid_ = ACK_uid; + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::STATE_TX_ACK_ID_" << ACK_uid + << std::endl; + TxAck(); + } +} + +void UWTWR_NODE::TxAck() +{ + incrCtrlPktsTx(); + incrAckSent(); + Mac2PhyStartTx(curr_ack_pkt); +} + + +void UWTWR_NODE::stateRxPoll() +{ + if (RxPollEnabled) { + refreshState(UWTWR_NODE_STATUS_RX_POLL); + + hdr_POLL *pollh = HDR_POLL(curr_poll_pkt); + hdr_mac *mach = HDR_MAC(curr_poll_pkt); + AUV_mac_addr = mach->macSA(); + // Save the RX POLL id as the corresponding ACK id + ACK_uid = pollh->POLL_uid_; + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::STATE_RX_POLL::Node_POLLED = " << pollh->id_ + << " rx from MAC=" << AUV_mac_addr <id_; + if (node_id == (uint) polled_node) { + // correct node is polled + polled = true; + + Packet::free(curr_poll_pkt); + incrTimesPolled(); + // schedule backoff time + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr + << ")::scheduling_BACKOFF_TIMER_T= " << T_backoff << std::endl; + backoff_timer.schedule(T_backoff); + RxPollEnabled = false; + // stateTxAck(); + } else { + drop(curr_poll_pkt, 1, UWTWR_NODE_DROP_REASON_NOT_POLLED); + } + } else { + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UTWR_NODE(" << addr + << ")::STATE_RX_POLL::NODE_NOT_POLLED" << std::endl; + drop(curr_poll_pkt, 1, UWTWR_NODE_DROP_REASON_WRONG_STATE); + } +} + +void UWTWR_NODE::stateIdle() +{ + if (debug_) + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_NODE(" << addr << ")::IDLE_STATE" + << std::endl; + refreshState(UWTWR_NODE_STATUS_IDLE); + polled = false; + RxPollEnabled = true; + backoff_timer.force_cancel(); +} + +void UWTWR_NODE::waitForUser() +{ + std::string response; + std::cout << "Press Enter to continue"; + std::getline(std::cin, response); +} \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_NODE.h b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_NODE.h new file mode 100644 index 00000000..ebfb8bbd --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_NODE.h @@ -0,0 +1,507 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr_NDOE.h + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provide the definition of the class UWTWR + */ + +#ifndef UWTWR_NODE_H +#define UWTWR_NODE_H + +#include "uwtwr_cmn_hdr.h" +#include "mmac.h" + +#include +#include +#include +#include +#include +#include + +#define UWTWR_NODE_DROP_REASON_ERROR "DERR" /**< Packet corrupted */ +#define UWTWR_NODE_DROP_REASON_UNKNOWN_TYPE "DUT" /**< Packet type unknown */ +#define UWTWR_NODE_DROP_REASON_WRONG_RECEIVER "DWR" /**< The packet is for another node */ +#define UWTWR_NODE_DROP_REASON_NOT_POLLED "DNP" /**< The node is not in the polling list */ +#define UWTWR_NODE_DROP_REASON_WRONG_STATE "DWS" /**< The node cannot receive this kind of packet in this state */ +/** + * Class that represents the UWTWR MAC layer of a node. + */ +class UWTWR_NODE : public MMac +{ +public: + /** + * Constructor of the UWTWR_NODE class + */ + UWTWR_NODE(); + /** + * Destructor of the UWTWR_NODE class + */ + virtual ~UWTWR_NODE(); + /** + * TCL command interpreter. It implements the following OTcl methods: + * + * @param argc Number of arguments in argv. + * @param argv Array of strings which are the command parameters (Note that + *argv[0] is the name of the object). + * @return TCL_OK or TCL_ERROR whether the command has been dispatched + *successfully or not. + * + **/ + virtual int command(int argc, const char *const *argv); + /** + * Cross-Layer messages interpreter + * + * @param ClMessage* an instance of ClMessage that represent the message + * received + * @return 0 if successful. + */ + virtual int crLayCommand(ClMessage *m); + +protected: + /**< Variable that represents the status of the protocol machine state */ + enum UWTWR_NODE_STATUS + { + UWTWR_NODE_STATUS_IDLE = 1, + UWTWR_NODE_STATUS_RX_POLL, + UWTWR_NODE_STATUS_TX_ACK + }; /* */ + + /**< Type of the packet */ + enum UWTWR_NODE_PKT_TYPE + { + UWTWR_ACK_PKT = 1, + UWTWR_POLL_PKT, + }; + + /**< Status of the timer */ + enum UWTWR_NODE_TIMER_STATUS + { + UWTWR_NODE_IDLE = 1, + UWTWR_NODE_RUNNING, + UWTWR_NODE_FROZEN, + UWTWR_NODE_EXPIRED + }; + + /** + * Class that describes the timer in the NODE + */ + class UWTWR_NODE_Timer : public TimerHandler + { + public: + /** + * Constructor of the UWTWR_NODE_Timer class + * @param UWTWR_AUV* a pointer to an object of type UWTWR_AUV + */ + UWTWR_NODE_Timer(UWTWR_NODE *m) + : TimerHandler() + , start_time(0.0) + , left_duration(0.0) + , counter(0) + , module(m) + , timer_status(UWTWR_NODE_IDLE) + { + assert(m != NULL); + } + + /** + * Destructor of the UWTWR_NODE_Timer class + */ + virtual ~UWTWR_NODE_Timer() + { + } + + /** + * Freeze the timer + */ + virtual void freeze() + { + assert(timer_status == UWTWR_NODE_RUNNING); + left_duration -= (NOW - start_time); + if (left_duration <= 0.0) { + left_duration = module->mac2phy_delay_; + } + force_cancel(); + timer_status = UWTWR_NODE_FROZEN; + } + + /** + * unFreeze is used to resume the timer starting from the point where it + * was freezed + */ + virtual void unFreeze() + { + assert(timer_status == UWTWR_NODE_FROZEN); + start_time = NOW; + assert(left_duration > 0); + sched(left_duration); + timer_status = UWTWR_NODE_RUNNING; + } + + /** + * stops the timer + */ + virtual void stop() + { + timer_status = UWTWR_NODE_IDLE; + force_cancel(); + } + + /** + * Schedules a timer + * @param double the duration of the timer + */ + virtual void schedule(double val) + { + start_time = NOW; + left_duration = val; + timer_status = UWTWR_NODE_RUNNING; + resched(val); + } + + /** + * Checks if the timer is IDLE + * @return true or false + */ + bool isIdle() + { + return (timer_status == UWTWR_NODE_IDLE); + } + + /** + * Checks if the timer is RUNNING + * @return true or false + */ + bool isRunning() + { + return (timer_status == UWTWR_NODE_RUNNING); + } + + /** + * Checks if the timer is EXPIRED + * @return true or false + */ + bool isExpired() + { + return (timer_status == UWTWR_NODE_EXPIRED); + } + + /** + * Checks if the timer is FROZEN + * @return true or false + */ + bool isFrozen() + { + return (timer_status == UWTWR_NODE_FROZEN); + } + + /** + * Checks if the timer is ACTIVE + * @return true or false + */ + bool isActive() + { + return (timer_status == UWTWR_NODE_FROZEN || + timer_status == UWTWR_NODE_RUNNING); + } + + /** + * Resets the counter of the timer + */ + void resetCounter() + { + counter = 0; + } + + /** + * Increments the counter of the timer + */ + void incrCounter() + { + ++counter; + } + + /** + * Returns the counter of the timer + * @return the value of the counter of the timer + */ + int getCounter() + { + return counter; + } + + /** + * Returns the counter of the timer + * @return the value of the counter of the timer + */ + double getDuration() + { + return left_duration; + } + + protected: + double start_time; /**< Start Time of the timer */ + double left_duration; /**< Left duration of the timer */ + int counter; /**< counter of the timer */ + UWTWR_NODE *module; /**< Pointer to an object of type UWTWR_AUV */ + UWTWR_NODE_TIMER_STATUS timer_status; /**< Timer status */ + }; + + /** + * Class (inherited from UWTWR_NODE_Timer) used to handle the time of + * backoff of the node before transmitting the ACK packet. After receiving + * a POLL + * the node set this timer. When the timer expire, the node transmit the + * ACK + */ + class BackOffTimer : public UWTWR_NODE_Timer + { + public: + /** + * Conscructor of BackOffTimer class + * @param UWTWR_NODE* pointer to an object of type UWTWR_NODE + */ + BackOffTimer(UWTWR_NODE *m) + : UWTWR_NODE_Timer(m) + { + } + + /** + * Destructor of BackOffTimer class + */ + virtual ~BackOffTimer() + { + } + + protected: + /** + * Method call when the timer expire + * @param Eevent* pointer to an object of type Event + */ + virtual void expire(Event *e); + }; + + // /** + // * Receive the packet from the upper layer (e.g. IP) + // * @param Packet* pointer to the packet received + // * + // */ + // virtual void recvFromUpperLayers(Packet *p); + + /** + * Method called when the Mac Layer start to transmit a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in transmission + */ + virtual void Mac2PhyStartTx(Packet *p); + + /** + * Method called when the PHY Layer finish to transmit a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in transmission + */ + virtual void Phy2MacEndTx(const Packet *p); + + /** + * Method called when the Phy Layer start to receive a Packet + * @param const Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacStartRx(const Packet *p); + + /** + * Method called when the Phy Layer finish to receive a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacEndRx(Packet *p); + + /** + * Inits the packet with the MAC address of the receiver and the sender, + * the size of the packet and the type + * @param UWTWR_NODE_PKT_TYPE the type of the packet + */ + virtual void initPkt(UWTWR_NODE_PKT_TYPE pkt_type); + + /** + * Initializes the protocol at the beginning of the simulation. This method + * is called by + * a command in tcl. + * @param double delay + * @see command method + */ + virtual void initInfo(); + + /** + * Refresh the state of the protocol + * @param UWTWR_NODE_STATUS current state of the protcol + */ + virtual void refreshState(UWTWR_NODE_STATUS state) + { + prev_state = curr_state; + curr_state = state; + } + + /** + * Increment the number of sent ACK packets + */ + virtual void incrAckSent() + { + n_ack_sent++; + } + + /** + * Increments the number of times that the node has been polled by the AUV + */ + virtual void incrTimesPolled() + { + n_times_polled++; + } + + /** + * Increments the number of POLL packets dropped because of erroneous CRC + */ + inline void incrPollDropped() + { + n_poll_dropped++; + } + + /** + * Return the number of ACK packets sent during the simulation + * @return int n_ack_tx number of ACK packets sent during the simulation + */ + inline int getAckSent() + { + return n_ack_sent; + } + + /** + * Return the number of times the node are polled by the AUV + * @return int n_times_polled number of times polled + */ + inline int getTimesPolled() + { + return n_times_polled; + } + + /** + * Return the number of POLL dropped by the node because of erroneous CRC + * @return int n_poll_dropped number of POLL dropped by the NODE + */ + inline int getPollDropped() + { + return n_poll_dropped; + } + + /** + * Used for debug purposes. (Permit to have a "step by step" behaviour of + * the protocol) + */ + virtual void waitForUser(); + + /** + * IDLE state. Each variable is resetted + */ + virtual void stateIdle(); + + /** + * Handle the recption of an POLL from the node + */ + virtual void stateRxPoll(); + + /** + * Handle the transmission of an ACK from the node + */ + virtual void stateTxAck(); + + /** + * Method called by the Expire event of the timer. Here we call the + * stateTxAck method + */ + virtual void BackOffTimerExpired(); + + /** + * The ACK Packet is sended down to the PHY layer + */ + virtual void TxAck(); + + /** + * Calculate the epoch of the event. Used in sea-trial mode + * @return the epoch of the system + */ + inline unsigned long int getEpoch() + { + unsigned long int timestamp = + (unsigned long int) (std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count() ); + return timestamp; + } + + /************************* + * input values from TCL * + *************************/ + uint node_id; /**< Unique Node ID */ + + double T_backoff; /**< Backoff time chosen */ + + int AUV_mac_addr; /**< MAC address of the AUV from which it receives poll*/ + uint n_ack_sent; /**< Number of ACK packets sent to the AUV */ + int n_times_polled; /**< Number of times that the node has been polled by + the AUV */ + int n_poll_dropped; /**< Number of POLL packet dropped */ + + static bool initialized; /**< true if the protocol is initialized, + false otherwise */ + + bool polled; /**< true if the node is polled, false otherwise */ + + bool RxPollEnabled; /**< true if the node is enabled to receive the + POLL, false otherwise */ + + uint ACK_uid; /**< ACK Unique ID */ + + // packet size + int POLL_size; /**< Size of the POLL pkt */ + int ACK_size; /**< Size of the ACK pkt */ + + Packet *curr_poll_pkt; /**< Pointer ot the current POLL packet */ + Packet *curr_ack_pkt; /**< Pointer to the current ACK packet */ + + UWTWR_NODE_STATUS curr_state; /**< Current state of the protocol */ + UWTWR_NODE_STATUS prev_state; /**< Previous state of the protocol */ + + static std::map status_info; /**< Textual info of the state */ + static std::map pkt_type_info; /**< Textual info of the type of the packet */ + + BackOffTimer backoff_timer; /**< Backoff timer */ +}; + +#endif \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.cpp b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.cpp new file mode 100644 index 00000000..efa1d0d1 --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.cpp @@ -0,0 +1,201 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr_PAUV.cpp + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provides the implementation of UWTWR_PAUV class + */ + +#include "uwtwr_PAUV.h" +#include "uwtwr_cmn_hdr.h" +#include "mac.h" +#include "mmac.h" + +#include "uwcbr-module.h" +#include "rng.h" + +#include +#include +#include +#include + +static class UWTWR_PAUV_Class : public TclClass +{ +public: + UWTWR_PAUV_Class() + : TclClass("Module/UW/TWR/PAUV") + { + } + TclObject * + create(int, const char *const *) + { + return (new UWTWR_PAUV()); + } +} class_uwtwr_pauv; + +bool UWTWR_PAUV::initialized = false; +std::map UWTWR_PAUV::status_info; + +UWTWR_PAUV::UWTWR_PAUV() + : curr_state(UWTWR_PAUV_STATUS_IDLE) + , prev_state(UWTWR_PAUV_STATUS_IDLE) + , n_poll_rx(0) + , n_ack_rx(0) + , n_poll_dropped(0) + , n_ack_dropped(0) +{} + +UWTWR_PAUV::~UWTWR_PAUV() +{ +} + +int UWTWR_PAUV::command(int argc, const char *const *argv) +{ + Tcl &tcl = Tcl::instance(); + if (argc == 2) { + if (strcasecmp(argv[1], "initialize") == 0) { + if (!initialized) + initInfo(); + return TCL_OK; + } else if (strcasecmp(argv[1], "getPollDropped") == 0) { + tcl.resultf("%d", getPollDropped()); + return TCL_OK; + } else if (strcasecmp(argv[1], "getAckDropped") == 0) { + tcl.resultf("%d", getDroppedAckPkts()); + return TCL_OK; + } + } else if (argc == 3) { + if (strcasecmp(argv[1], "setMacAddr") == 0) { + addr = atoi(argv[2]); + return TCL_OK; + } + } + return MMac::command(argc, argv); +} + +int UWTWR_PAUV::crLayCommand(ClMessage *m) +{ + switch (m->type()) { + default: + return MMac::crLayCommand(m); + } +} + +void UWTWR_PAUV::initInfo() +{ + initialized = true; + status_info[UWTWR_PAUV_STATUS_IDLE] = "Idle state"; + status_info[UWTWR_PAUV_STATUS_RX_POLL] = "Receiving a POLL Packet"; + status_info[UWTWR_PAUV_STATUS_RX_ACK] = "Receiving ACK Packet"; +} + +void UWTWR_PAUV::Phy2MacStartRx(const Packet *p) +{ + hdr_cmn *ch = HDR_CMN(p); + if (ch->ptype() == PT_POLL) { + hdr_POLL *pollh = HDR_POLL(p); + if (debug_) { + std::cout << pollh->POLL_uid_ << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + << ")::PHY2MACSTARTRX::RX_POLL::POLLED_NODE::" + << pollh->id_ << "::LAST_TOF::" << pollh->tof_ + << "::AAUV_POS_X::" << NOW << "::AAUV_POS_Y::" << NOW <ACK_uid_; + if (debug_) { + std::cout << ACK_uid << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + << ")::PHY2MACSTARTRX::RX_ACK::ACK_NODE::" + << ackh->id_node() << "::NONE::" << 0 + << "::NONE::" << 0 << "::NONE::" << 0 << std::endl; + } + } +} + +void UWTWR_PAUV::Phy2MacEndRx(Packet *p) +{ + hdr_cmn *ch = HDR_CMN(p); + hdr_mac *mach = HDR_MAC(p); + int dest_mac = mach->macDA(); + if (ch->error()) { + if (ch->ptype() == PT_POLL) { + if (debug_) + std::cout << getEpoch() << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + << ")::PHY2MACENDRX_DROP_POLL" << std::endl; + incrPollDropped(); + } else { + if (debug_) + std::cout << getEpoch() << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + << ")::PHY2MACENDRX_DROP_ACK" << std::endl; + incrDroppedAckPkts(); + } + } else { + if (ch->ptype() == PT_POLL) { + hdr_POLL *pollh = HDR_POLL(p); + // if (debug_) { + // std::cout << getEpoch() << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + // << ")::PHY2MACENDRX::RX_POLL::POLLED_NODE= " + // << pollh->id_ << std::endl; + // } + incrPollRx(); + stateRxPoll(); + } else { + hdr_ACK_NODE *ackh = HDR_ACK_NODE(p); + // if (debug_) { + // std::cout << getEpoch() << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr + // << ")::PHY2MACENDRX::RX_ACK::ACK_NODE= " + // << ackh->id_node() << std::endl; + // } + incrAckRx(); + stateRxAck(); + } + } +} + +void UWTWR_PAUV::stateRxPoll() +{ + refreshState(UWTWR_PAUV_STATUS_RX_POLL); + stateIdle(); +} + +void UWTWR_PAUV::stateRxAck() +{ + refreshState(UWTWR_PAUV_STATUS_RX_ACK); + stateIdle(); +} + +void UWTWR_PAUV::stateIdle() +{ + // if (debug_) + // std::cout << getEpoch() << "::" << std::setprecision(10) << NOW << "::UWTWR_PAUV(" << addr << ")::IDLE_STATE" + // << std::endl; + refreshState(UWTWR_PAUV_STATUS_IDLE); +} \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.h b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.h new file mode 100644 index 00000000..4387c011 --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_PAUV.h @@ -0,0 +1,244 @@ +// +// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the University of Padova (SIGNET lab) nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/** + * @file uwtwr_PAUV.h + * @author Yuehan Jiang + * @version 1.0.0 + * + * @brief Provide the definition of the class UWTWR + */ + +#ifndef UWTWR_PAUV_H +#define UWTWR_PAUV_H + +#include "uwtwr_cmn_hdr.h" +#include "mmac.h" + +#include +#include +#include +#include +#include +#include +#include + +/** + * Class that represents the UWTWR MAC layer of a node. + */ +class UWTWR_PAUV : public MMac +{ +public: + /** + * Constructor of the UWTWR_PAUV class + */ + UWTWR_PAUV(); + /** + * Destructor of the UWTWR_PAUV class + */ + virtual ~UWTWR_PAUV(); + /** + * TCL command interpreter. It implements the following OTcl methods: + * + * @param argc Number of arguments in argv. + * @param argv Array of strings which are the command parameters (Note that + *argv[0] is the name of the object). + * @return TCL_OK or TCL_ERROR whether the command has been dispatched + *successfully or not. + * + **/ + virtual int command(int argc, const char *const *argv); + /** + * Cross-Layer messages interpreter + * + * @param ClMessage* an instance of ClMessage that represent the message + * received + * @return 0 if successful. + */ + virtual int crLayCommand(ClMessage *M); + +protected: + /**< Variable that represents the status of the protocol machine state */ + enum UWTWR_PAUV_STATUS + { + UWTWR_PAUV_STATUS_IDLE = 1, + UWTWR_PAUV_STATUS_RX_POLL, + UWTWR_PAUV_STATUS_RX_ACK + }; + + /** + * Method called when the Phy Layer start to receive a Packet + * @param const Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacStartRx(const Packet *p); + + /** + * Method called when the Phy Layer finish to receive a Packet + * @param Packet* Pointer to an Packet object that represent the + * Packet in reception + */ + virtual void Phy2MacEndRx(Packet *p); + + /** + * Initializes the protocol at the beginning of the simulation. This method + * is called by + * a command in tcl. + * @param double delay + * @see command method + */ + virtual void initInfo(); + + /** + * Refresh the state of the protocol + * @param UWTWR_PAUV_STATUS current state of the protcol + */ + virtual void refreshState(UWTWR_PAUV_STATUS state) + { + prev_state = curr_state; + curr_state = state; + } + + /** + * Increases the number of Poll packets received. Used for statistical + * purposes + */ + inline void incrPollRx() + { + n_poll_rx++; + } + + /** + * Increases the number of Ack packets received. Used for statistical + * purposes + */ + inline void incrAckRx() + { + n_ack_rx++; + } + + /** + * Returns the number of Poll received during the simulation + * @return int n_ppll_rx the number of PROBE received + */ + inline int getPollRx() + { + return n_poll_rx; + } + + /** + * Returns the number of ACK received during the simulation + * @return int n_probe_rx the number of PROBE received + */ + inline int getAckRx() + { + return n_ack_rx; + } + + /** + * Increments the number of POLL packets dropped because of erroneous CRC + */ + inline void incrPollDropped() + { + n_poll_dropped++; + } + + /** + * Increases the number of wrong ACK packet received. + * Used for statistical purposes + */ + inline void incrDroppedAckPkts() + { + n_ack_dropped++; + } + + /** + * Return the number of POLL dropped by the PAUV because of erroneous CRC + * @return itn n_poll_dropped number of POLL dropped + */ + inline int getPollDropped() + { + return n_poll_dropped; + } + + /** + * Return the number of ACK packets discarded because of wrong CRC + * @return int N_dropped_probe_pkts number of PROBE pkts dropped + */ + inline int getDroppedAckPkts() + { + return n_ack_dropped; + } + + /** + * IDLE state. Each variable is resetted + */ + virtual void stateIdle(); + + /** + * Handle the recption of an POLL from the PAUV + */ + virtual void stateRxPoll(); + + /** + * Handle the recption of an ack from the PAUV + */ + virtual void stateRxAck(); + + /** + * Calculate the epoch of the event. Used in sea-trial mode + * @return the epoch of the system + */ + inline unsigned long int getEpoch() + { + unsigned long int timestamp = + (unsigned long int) (std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count() ); + return timestamp; + } + + /************************* + * input values from TCL * + *************************/ + static bool initialized; /**< true if the protocol is initialized, + false otherwise */ + + UWTWR_PAUV_STATUS curr_state; /**< Current state of the protocol */ + UWTWR_PAUV_STATUS prev_state; /**< Previous state of the protocol */ + + static std::map status_info; /**< Textual info of the state */ + + uint ACK_uid; /**< ACK Unique ID */ + + int n_ack_rx; /**< Number of ack packets received */ + int n_poll_rx; /**< Number of POLL packets received */ + int n_poll_dropped; /**< Number of POLL packet dropped */ + int n_ack_dropped; /** +#include +#include + +#include + +#define HDR_POLL(p) \ + (hdr_POLL::access(p)) /**< alias defined to access the POLL HEADER */ +#define HDR_ACK_NODE(p) \ + (hdr_ACK_NODE::access(p)) /**< alias defined to access the ACK SINK HEADER*/ + +extern packet_t PT_POLL; +extern packet_t PT_ACK_NODE; + +// To be implemented +/** Single location of the POLL vector. Each POLL_ID represent a polled node */ +typedef struct POLL_ID { + int id_; /**< ID of the node */ + double t_wait_; /**< Time that a node has to wait before being polled */ +} id_poll; + +/** + * Header of the POLL message + */ +typedef struct hdr_POLL { + int id_; /**< ID of the POLLED node */ + uint POLL_uid_; /**< POLL packet unique ID */ + uint16_t POLL_time_; /**< Time needed by the AUV to poll all the nodes */ + static int offset_; /**< Required by the PacketHeaderManager. */ + + // Info to be sent in a POLL + double tof_; /**< TOF from last received ACK >*/ + + + /** + * Reference to the id_ variable + */ + int & + ID() + { + return (id_); + } + /** + * Reference to the POLL_uid_ variable + */ + uint & + POLL_uid() + { + return (POLL_uid_); + } + + /** + * Reference to the POLL_time variable + */ + uint16_t & + POLL_time() + { + return (POLL_time_); + } + + /** + * Reference to the offset variable + */ + inline static int & + offset() + { + return offset_; + } + + inline static struct hdr_POLL * + access(const Packet *p) + { + return (struct hdr_POLL *) p->access(offset_); + } + +} hdr_POLL; + +/** + * Header of the ACK sent by the NODE + */ +typedef struct hdr_ACK_NODE { + // std::vector id_ack_; /**< ACK is the id of the wrong packets */ + uint id_node_; /**< ID of the node */ + uint ACK_uid_; /**< Unique ID of the ACK packet */ + static int offset_; /**< Required by the PacketHeaderManager. */ + + // /** + // * Reference to the id_ack_ variable + // */ + // std::vector & + // id_ack() + // { + // return (id_ack_); + // } + + /** + * Reference to id_node variable + */ + uint & + id_node() + { + return (id_node_); + } + + /** + * Reference to ACK_uid_ variable + */ + uint & + ACK_uid() + { + return (ACK_uid_); + } + + /** + * Reference to the offset variable + */ + inline static int & + offset() + { + return offset_; + } + + inline static struct hdr_ACK_NODE * + access(const Packet *p) + { + return (struct hdr_ACK_NODE *) p->access(offset_); + } +} hdr_ACK_NODE; + +#endif \ No newline at end of file diff --git a/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_default.tcl b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_default.tcl new file mode 100644 index 00000000..321103ec --- /dev/null +++ b/DESERT_Framework/DESERT/data_link/uwtwr/uwtwr_default.tcl @@ -0,0 +1,40 @@ +# +# Copyright (c) 2017 Regents of the SIGNET lab, University of Padova. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the University of Padova (SIGNET lab) nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: Yuehan Jiang +# version: 1.0.0 + +PacketHeaderManager set tab_(PacketHeader/POLL) 1 +PacketHeaderManager set tab_(PacketHeader/ACK_NODE) 1 + +Module/UW/TWR/AAUV set T_ack_timer_ 1 +Module/UW/TWR/AAUV set ack_enabled_ 1 +Module/UW/TWR/AAUV set POLL_size_ 14 + +Module/UW/TWR/NODE set T_backoff_ 0.1 +Module/UW/TWR/NODE set ACK_size_ 10 diff --git a/DESERT_Framework/DESERT/samples/desert_samples/MAC/test_uwtwr.tcl b/DESERT_Framework/DESERT/samples/desert_samples/MAC/test_uwtwr.tcl new file mode 100644 index 00000000..df417602 --- /dev/null +++ b/DESERT_Framework/DESERT/samples/desert_samples/MAC/test_uwtwr.tcl @@ -0,0 +1,488 @@ +# +# Copyright (c) 2015 Regents of the SIGNET lab, University of Padova. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the University of Padova (SIGNET lab) nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: Yuehan Jiang +# Version: 1.0.0 + + +# This script is used to test UW-TWR protocol +# There are 2 static nodes at (0,0,-100) and (0,100,-100) +# and an active AUV making a trajectory described in the Waypoints +# and a passive AUV static at (60,50,-50) +# Mobility model of DESERT: uwsmposition + + +# Stack of the nodes Stack of the AAUV Stack of the PAUV +# +-----------------------+ +-----------------------+ +-----------------------+ +# | 7. UW/CBR (tx) | | 7. UW/CBR(rx) | | 7. UW/CBR(rx) | +# +-----------------------+ +-----------------------+ +-----------------------+ +# | 6. UW/UDP | | 6. UW/UDP | | 6. UW/UDP | +# +-----------------------+ +-----------------------+ +-----------------------+ +# | 5. UW/staticROUTING | | 5. UW/staticROUTING | | 5. UW/staticROUTING | +# +-----------------------+ +-----------------------+ +-----------------------+ +# | 4. UW/IP | | 4. UW/IP | | 4. UW/IP | +# +-----------------------+ +-----------------------+ +-----------------------+ +# | 3. UW/MLL | | 3. UWMLL | | 3. UWMLL | +# +-----------------------+ +-----------------------+ +-----------------------+ +# |2. UW/TWR/NODE | | 2. UW/TWR/AAUV | | 2. UW/TWR/PAUV | +# +.......................+ +.......................+ +.......................+ +# : 1 Module/UW/PHYSICAL : : 1. Module/UW/PHYSICAL : : 1. Module/UW/PHYSICAL : +# +.......................+ +.......................+ +.......................+ +# | | +# +-------------------------------------------------------------+ +# | UnderwaterChannel | +# +-------------------------------------------------------------+ + +###################################### +# Flags to enable or disable options # +###################################### +set opt(verbose) 1 +set opt(trace_files) 0 +set opt(bash_parameters) 1 + + +##################### +# Library Loading # +##################### +load libMiracle.so +load libmphy.so +load libmmac.so +load libMiracleBasicMovement.so +load libUwmStd.so +load libuwip.so +load libuwstaticrouting.so +load libuwmll.so +load libuwudp.so +load libuwcbr.so +load libuwphy_clmsgs.so + +load libuwinterference.so +load libuwstats_utilities.so +load libuwphysical.so +load libuwsmposition.so +load libuwtwr.so + +set ns [new Simulator] +$ns use-Miracle + +################## +# Tcl variables # +################## +set opt(start_clock) [clock seconds] +set opt(nn) 2 ;#NUMBER OF SENSOR NODES +set opt(total_nn) [expr $opt(nn) + 2] ;# +1 AAUV +1 PAUV +set opt(pktsize) 125 ; #POLL and ACK size are defined in UWTWR MAC protocol +set opt(starttime) 0.1 +set opt(stoptime) 550.0 +set opt(txduration) [expr $opt(stoptime) - $opt(starttime)] +set opt(cbr_period) 1; #? +set opt(speed) 0.5;#[expr $opt(knots) * 0.51444444444] ;#Speed of the AUV in m/s + +set opt(txpower) 156.0 ;#Power transmitted in dB re uPa +set opt(rngstream) 1 + +set opt(maxinterval_) 100.0; #? +set opt(freq) 150000.0 +set opt(bw) 60000.0 +set opt(bitrate) 200.0 +set opt(rngstream) 1 + + +######################################## +# Random Number Generators +######################################## + +global defaultRNG +for {set k 0} {$k < $opt(rngstream)} {incr k} { + $defaultRNG next-substream +} + +#set opt(tracefilename) "/tmp/${argv0}.tr" +set opt(tracefilename) "/dev/null" +set opt(tracefile) [open $opt(tracefilename) w] + +#set opt(cltracefilename) "/tmp/${argv0}.cltr" +set opt(cltracefilename) "/dev/null" +set opt(cltracefile) [open $opt(cltracefilename) w] + +######################### +# Module Configuration # +######################### + +MPropagation/Underwater set practicalSpreading_ 1.8 +MPropagation/Underwater set debug_ 0 +MPropagation/Underwater set windspeed_ 1 + +set channel [new Module/UnderwaterChannel] +set propagation [new MPropagation/Underwater] +set data_mask [new MSpectralMask/Rect] +$data_mask setFreq $opt(freq) +$data_mask setBandwidth $opt(bw) + +#CBR MODULE +Module/UW/CBR set packetSize_ $opt(pktsize) +Module/UW/CBR set period_ $opt(cbr_period) +Module/UW/CBR set PoissonTraffic_ 1 +Module/UW/CBR set drop_out_of_order_ 0 +Module/UW/CBR set debug_ 0 + +#TWR MODULE +Module/UW/TWR/AAUV set T_ack_timer_ 2 +Module/UW/TWR/AAUV set debug_ 1 + +Module/UW/TWR/NODE set T_backoff_ 0.01 +Module/UW/TWR/NODE set debug_ 1 + +Module/UW/TWR/PAUV set debug_ 1 + +#PHY MODULE +Module/UW/PHYSICAL set BitRate_ $opt(bitrate) +Module/UW/PHYSICAL set AcquisitionThreshold_dB_ 10.0 +Module/UW/PHYSICAL set RxSnrPenalty_dB_ 0 +Module/UW/PHYSICAL set TxSPLMargin_dB_ 0 +Module/UW/PHYSICAL set MaxTxSPL_dB_ 156 +Module/UW/PHYSICAL set MinTxSPL_dB_ 10 +Module/UW/PHYSICAL set MaxTxRange_ 1000 +Module/UW/PHYSICAL set PER_target_ 0 +Module/UW/PHYSICAL set CentralFreqOptimization_ 0 +Module/UW/PHYSICAL set BandwidthOptimization_ 0 +Module/UW/PHYSICAL set SPLOptimization_ 0 +Module/UW/PHYSICAL set debug_ 0 + + +################################ +# Procedure(s) to create nodes # +################################ + +proc createNode { id } { + + global channel propagation data_mask ns cbr position node udp portnum ipr ipif channel_estimator + global phy_data posdb opt rvposx rvposy rvposz mhrouting mll mac woss_utilities woss_creator db_manager + global node_coordinates + + set node($id) [$ns create-M_Node $opt(tracefile) $opt(cltracefile)] + + set cbr($id) [new Module/UW/CBR] + set udp($id) [new Module/UW/UDP] + set ipr($id) [new Module/UW/StaticRouting] + set ipif($id) [new Module/UW/IP] + set mll($id) [new Module/UW/MLL] + set mac($id) [new Module/UW/TWR/NODE] + set phy_data($id) [new Module/UW/PHYSICAL] + + $node($id) addModule 7 $cbr($id) 1 "CBR" + $node($id) addModule 6 $udp($id) 1 "PRT" + $node($id) addModule 5 $ipr($id) 1 "IPR" + $node($id) addModule 4 $ipif($id) 1 "IPF" + $node($id) addModule 3 $mll($id) 1 "MLL" + $node($id) addModule 2 $mac($id) 1 "MAC" + $node($id) addModule 1 $phy_data($id) 1 "PHY" + + $node($id) setConnection $cbr($id) $udp($id) 0 + $node($id) setConnection $udp($id) $ipr($id) 0 + $node($id) setConnection $ipr($id) $ipif($id) 0 + $node($id) setConnection $ipif($id) $mll($id) 0 + $node($id) setConnection $mll($id) $mac($id) 0 + $node($id) setConnection $mac($id) $phy_data($id) 1 + $node($id) addToChannel $channel $phy_data($id) 1 + + + set portnum($id) [$udp($id) assignPort $cbr($id) ] + + #Set the IP address of the node + $ipif($id) addr [expr $id +1] + + set position($id) [new "Position/BM"] + $node($id) addPosition $position($id) + set posdb($id) [new "PlugIn/PositionDB"] + $node($id) addPlugin $posdb($id) 20 "PDB" + $posdb($id) addpos [$ipif($id) addr] $position($id) + + #Setup positions + $position($id) setX_ 0 + $position($id) setY_ [expr $id*100] + $position($id) setZ_ -100 + + puts "node $id at ([$position($id) getX_], [$position($id) getY_], [$position($id) getZ_])" + + #Interference model + set interf_data($id) [new "Module/UW/INTERFERENCE"] + $interf_data($id) set maxinterval_ $opt(maxinterval_) + $interf_data($id) set debug_ 0 + + #Propagation model + $phy_data($id) setSpectralMask $data_mask + $phy_data($id) setInterference $interf_data($id) + $phy_data($id) setPropagation $propagation + $phy_data($id) setInterferenceModel "MEANPOWER" + $phy_data($id) set debug_ 0 + + $mac($id) set node_id_ [expr $id] + $mac($id) initialize + +} + +proc createAAUV { } { + global channel propagation smask data_mask ns cbr_aauv position_aauv node_aauv udp_aauv portnum_aauv + global phy_data_aauv posdb_aauv opt mll_aauv mac_aauv ipr_aauv ipif_aauv bpsk interf_data_aauv channel_estimator + global woss_utilities woss_creator db_manager propagation_aauv + + set node_aauv [$ns create-M_Node $opt(tracefile) $opt(cltracefile)] + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + set cbr_aauv($cnt) [new Module/UW/CBR] + } + set udp_aauv [new Module/UW/UDP] + set ipr_aauv [new Module/UW/StaticRouting] + set ipif_aauv [new Module/UW/IP] + set mll_aauv [new Module/UW/MLL] + set mac_aauv [new Module/UW/TWR/AAUV] + set phy_data_aauv [new Module/UW/PHYSICAL] + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + $node_aauv addModule 7 $cbr_aauv($cnt) 0 "CBR" + } + $node_aauv addModule 6 $udp_aauv 0 "PRT" + $node_aauv addModule 5 $ipr_aauv 0 "IPR" + $node_aauv addModule 4 $ipif_aauv 0 "IPF" + $node_aauv addModule 3 $mll_aauv 0 "MLL" + $node_aauv addModule 2 $mac_aauv 1 "MAC" + $node_aauv addModule 1 $phy_data_aauv 1 "PHY" + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + $node_aauv setConnection $cbr_aauv($cnt) $udp_aauv 1 + } + $node_aauv setConnection $udp_aauv $ipr_aauv 0 + $node_aauv setConnection $ipr_aauv $ipif_aauv 0 + $node_aauv setConnection $ipif_aauv $mll_aauv 0 + $node_aauv setConnection $mll_aauv $mac_aauv 0 + $node_aauv setConnection $mac_aauv $phy_data_aauv 1 + $node_aauv addToChannel $channel $phy_data_aauv 1 + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + set portnum_aauv($cnt) [$udp_aauv assignPort $cbr_aauv($cnt)] + } + + set position_aauv [new "Position/UWSM"] + $position_aauv set debug_ 0 + $node_aauv addPosition $position_aauv + + #Setup positions + $position_aauv setX_ 30 + $position_aauv setY_ 20 + $position_aauv setZ_ -100 + + puts "node aauv at ([$position_aauv getX_], [$position_aauv getY_], [$position_aauv getZ_])" + + $ipif_aauv addr 253 + + set interf_data_aauv [new Module/UW/INTERFERENCE] + $interf_data_aauv set maxinterval_ $opt(maxinterval_) + $interf_data_aauv set debug_ 0 + + $phy_data_aauv setSpectralMask $data_mask + $phy_data_aauv setPropagation $propagation + $phy_data_aauv setInterference $interf_data_aauv + $phy_data_aauv setInterferenceModel "MEANPOWER" + + $mac_aauv initialize + +} + +proc createPAUV { } { + + global channel propagation smask data_mask ns cbr_pauv position_pauv node_pauv udp_pauv portnum_pauv interf_data_pauv + global phy_data_pauv posdb_pauv opt mll_pauv mac_pauv ipr_pauv ipif_pauv bpsk interf_pauv channel_estimator + global woss_utilities woss_creator propagation_pauv db_manager + + set node_pauv [$ns create-M_Node $opt(tracefile) $opt(cltracefile)] + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + set cbr_pauv($cnt) [new Module/UW/CBR] + } + set cbr_pauv(101) [new Module/UW/CBR] + + set udp_pauv [new Module/UW/UDP] + set ipr_pauv [new Module/UW/StaticRouting] + set ipif_pauv [new Module/UW/IP] + set mll_pauv [new Module/UW/MLL] + set mac_pauv [new Module/UW/TWR/PAUV] + set phy_data_pauv [new Module/UW/PHYSICAL] + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + $node_pauv addModule 7 $cbr_pauv($cnt) 0 "CBR" + } + $node_pauv addModule 7 $cbr_pauv(101) 0 "CBR" + $node_pauv addModule 6 $udp_pauv 0 "PRT" + $node_pauv addModule 5 $ipr_pauv 0 "IPR" + $node_pauv addModule 4 $ipif_pauv 0 "IPF" + $node_pauv addModule 3 $mll_pauv 0 "MLL" + $node_pauv addModule 2 $mac_pauv 1 "MAC" + $node_pauv addModule 1 $phy_data_pauv 1 "PHY" + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + $node_pauv setConnection $cbr_pauv($cnt) $udp_pauv 1 + } + $node_pauv setConnection $cbr_pauv(101) $udp_pauv 1 + + $node_pauv setConnection $udp_pauv $ipr_pauv 0 + $node_pauv setConnection $ipr_pauv $ipif_pauv 0 + $node_pauv setConnection $ipif_pauv $mll_pauv 0 + $node_pauv setConnection $mll_pauv $mac_pauv 0 + $node_pauv setConnection $mac_pauv $phy_data_pauv 1 + $node_pauv addToChannel $channel $phy_data_pauv 1 + + for { set cnt 0} {$cnt < $opt(nn)} {incr cnt} { + set portnum_pauv($cnt) [$udp_pauv assignPort $cbr_pauv($cnt)] + } + set portnum_pauv(101) [$udp_pauv assignPort $cbr_pauv(101)] + + set position_pauv [new "Position/UWSM"] + $position_pauv set debug_ 0 + $node_pauv addPosition $position_pauv + + #Setup positions + $position_pauv setX_ 60 + $position_pauv setY_ 50 + $position_pauv setZ_ -50 + + puts "node pauv at ([$position_pauv getX_], [$position_pauv getY_], [$position_pauv getZ_])" + + $ipif_pauv addr 252 + + set interf_data_pauv [new Module/UW/INTERFERENCE] + $interf_data_pauv set maxinterval_ $opt(maxinterval_) + $interf_data_pauv set debug_ 0 + + $phy_data_pauv setSpectralMask $data_mask + $phy_data_pauv setPropagation $propagation + $phy_data_pauv setInterference $interf_data_pauv + $phy_data_pauv setInterferenceModel "MEANPOWER" + + $mac_pauv initialize + +} + +############################### +# create nodes, aauv, pauv +############################### +createAAUV +for {set id1 0} {$id1 < $opt(nn)} {incr id1} { + createNode $id1 +} +createPAUV + +############################### +# routing of nodes +############################### +proc connectNodes {id1} { + + global ipif ipr portnum cbr cbr_pauv ipif_aauv portnum_aauv ipr_pauv + global ipif_pauv portnum_pauv ipr_aauv + # how to set destAddr_? + $cbr($id1) set destAddr_ [$ipif_aauv addr] + $cbr($id1) set destPort_ $portnum_aauv($id1) + $cbr($id1) set destAddr_ [$ipif_pauv addr] + $cbr($id1) set destPort_ $portnum_pauv($id1) + + # $cbr(101) set destAddr_ [$id1 addr] + # $cbr(101) set destPort_ $id1(101) + # $cbr(101) set destAddr_ [$ipif_pauv addr] + # $cbr(101) set destPort_ $portnum_pauv(101) +} + +################################ +#Setup flows +################################ +for {set id1 0} {$id1 < $opt(nn)} {incr id1} { + connectNodes $id1 +} + +################## +# ARP tables # +################## +for {set id1 0} {$id1 < $opt(nn)} {incr id1} { + for {set id2 0} {$id2 < $opt(nn)} {incr id2} { + $mll($id1) addentry [$ipif($id2) addr] [$mac($id2) addr] + } + $mll($id1) addentry [$ipif_aauv addr] [$mac_aauv addr] + $mll($id1) addentry [$ipif_pauv addr] [$mac_pauv addr] + $mll_pauv addentry [$ipif($id1) addr] [$mac($id1) addr] + $mll_aauv addentry [$ipif($id1) addr] [$mac($id1) addr] +} +$mll_pauv addentry [$ipif_pauv addr] [$mac_pauv addr] +$mll_pauv addentry [$ipif_aauv addr] [$mac_aauv addr] +$mll_aauv addentry [$ipif_pauv addr] [$mac_pauv addr] +$mll_aauv addentry [$ipif_aauv addr] [$mac_aauv addr] + +################################ +#Start cbr(s) +################################ + +$ns at [expr $opt(starttime) + 5] "$mac_aauv run" + +set opt(waypoint_file) "../dbs/wp_path/twr_aauv_wp_squa_ccw.csv" +set fp [open $opt(waypoint_file) r] +set file_data [read $fp] +set data [split $file_data "\n"] +set dist 20 +set opt(t_wp) [expr $dist / $opt(speed)]; +puts "t wp $opt(t_wp)" +set t 360 +set opt(n_run) 1 +for {set id1 0} {$id1 < $opt(n_run)} {incr id1} { + foreach line $data { + if {[regexp {^(.*),(.*)$} $line -> x y]} { + $ns at $t "$position_aauv setdest $x $y -100 $opt(speed)" + set t [expr $t + $opt(t_wp)] + } + } +} + +set opt(stoptime) [expr $t + 1] +puts "stop $opt(stoptime)" + + +proc finish { } { + puts "End of simulation" + set opt(end_clock) [clock seconds] + # puts "done in [expr $opt(end_clock) - $opt(start_clock)] seconds!" + + # $ns flush-trace + # close $opt(tracefile) +} + +################### +# start simulation +################### + +puts -nonewline "\nSimulating...\n" + +$ns at [expr $opt(stoptime) + 60.0] "finish; $ns halt" + +$ns run \ No newline at end of file diff --git a/DESERT_Framework/DESERT/samples/desert_samples/dbs/uwtwr_wp/readme.txt b/DESERT_Framework/DESERT/samples/desert_samples/dbs/uwtwr_wp/readme.txt new file mode 100644 index 00000000..fe28244e --- /dev/null +++ b/DESERT_Framework/DESERT/samples/desert_samples/dbs/uwtwr_wp/readme.txt @@ -0,0 +1 @@ +This folder contains waypoint path than can be used in test_uwtwr.tcl.