--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/uan/uan-cw-example.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+
+/**
+ * \file uan-cw-example.cc
+ * \ingroup uan
+ *
+ * This example showcases the "CW-MAC" described in System Design Considerations for Undersea Networks
+ * article in the IEEE Journal on Selected Areas of Communications 2008 by Nathan Parrish, Leonard Tracy
+ * and Sumit Roy. The MAC protocol is implemented in the class UanMacCw. CW-MAC is similar in nature
+ * to the IEEE 802.11 DCF with a constant backoff window. It requires two parameters to be set,
+ * the slot time and the contention window size. The contention window size is the backoff window
+ * size in slots, and the slot time is the duration of each slot. These parameters should be set
+ * according to the overall network size, internode spacing and the number of nodes in the network.
+ *
+ * This example deploys nodes randomly (according to RNG seed of course) in a finite square region with
+ * the X and Y coordinates of the nodes distributed uniformly. The CW parameter is varied throughout
+ * the simulation in order to show the variation in throughput with respect to changes in CW.
+ */
+
+#include "uan-cw-example.h"
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/uan-module.h"
+#include "ns3/node-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/helper-module.h"
+
+#include <fstream>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE("UanCwExample");
+
+Experiment::Experiment ()
+ : m_numNodes (15),
+ m_dataRate (80),
+ m_depth (70),
+ m_boundary (500),
+ m_packetSize (32),
+ m_bytesTotal (0),
+ m_cwMin (10),
+ m_cwMax (400),
+ m_cwStep (10),
+ m_avgs (3),
+ m_slotTime (Seconds (0.2)),
+ m_simTime (Seconds (1000)),
+ m_gnudatfile ("uan-cw-example.gpl"),
+ m_asciitracefile ("uan-cw-example.asc"),
+ m_bhCfgFile ("uan-apps/dat/default.cfg")
+{
+}
+
+void
+Experiment::ResetData ()
+{
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Resetting data");
+ m_throughputs.push_back (m_bytesTotal * 8.0 / m_simTime.GetSeconds ());
+ m_bytesTotal = 0;
+}
+
+void
+Experiment::IncrementCw (uint32_t cw)
+{
+ NS_ASSERT (m_throughputs.size () == m_avgs);
+
+ double avgThroughput = 0.0;
+ for (uint32_t i=0; i<m_avgs; i++)
+ {
+ avgThroughput += m_throughputs[i];
+ }
+ avgThroughput /= m_avgs;
+ m_data.Add (cw, avgThroughput);
+ m_throughputs.clear ();
+
+ Config::Set ("/NodeList/*/DeviceList/*/Mac/CW", UintegerValue (cw + m_cwStep));
+
+ SeedManager::SetRun (SeedManager::GetRun () + 1);
+
+ NS_LOG_DEBUG ("Average for cw=" << cw << " over " << m_avgs << " runs: " << avgThroughput);
+}
+void
+Experiment::UpdatePositions (NodeContainer &nodes)
+{
+
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Updating positions");
+ NodeContainer::Iterator it = nodes.Begin ();
+ UniformVariable uv (0, m_boundary);
+ for (; it != nodes.End (); it++)
+ {
+ Ptr<MobilityModel> mp = (*it)->GetObject<MobilityModel> ();
+ mp->SetPosition (Vector (uv.GetValue (), uv.GetValue (), 70.0));
+ }
+}
+
+void
+Experiment::ReceivePacket (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+
+ while (packet = socket->Recv())
+ {
+ m_bytesTotal += packet->GetSize ();
+ }
+ packet = 0;
+}
+
+Gnuplot2dDataset
+Experiment::Run (UanHelper &uan)
+{
+ //uan.SetMac ("ns3::UanMacCw", "CW", UintegerValue (m_cwMin), "SlotTime", TimeValue (m_slotTime));
+ uan.SetMac ("ns3::UanMacAloha");
+ NodeContainer nc = NodeContainer ();
+ NodeContainer sink = NodeContainer ();
+ nc.Create (m_numNodes);
+ sink.Create (1);
+
+ PacketSocketHelper socketHelper;
+ socketHelper.Install (nc);
+ socketHelper.Install (sink);
+
+#ifdef UAN_PROP_BH_INSTALLED
+ Ptr<UanPropModelBh> prop = CreateObjectWithAttributes<UanPropModelBh> ("ConfigFile", StringValue ("exbhconfig.cfg"));
+#else
+ Ptr<UanPropModelIdeal> prop = CreateObjectWithAttributes<UanPropModelIdeal> ();
+#endif //UAN_PROP_BH_INSTALLED
+ Ptr<UanChannel> channel = CreateObjectWithAttributes<UanChannel> ("PropagationModel", PointerValue (prop));
+
+ //Create net device and nodes with UanHelper
+ NetDeviceContainer devices = uan.Install (nc, channel);
+ NetDeviceContainer sinkdev = uan.Install (sink, channel);
+
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> pos = CreateObject<ListPositionAllocator> ();
+
+ {
+ UniformVariable urv (0, m_boundary);
+ pos->Add (Vector (m_boundary / 2.0, m_boundary / 2.0, m_depth));
+ double rsum = 0;
+
+ double minr = 2 * m_boundary;
+ for (uint32_t i = 0; i < m_numNodes; i++)
+ {
+ double x = urv.GetValue ();
+ double y = urv.GetValue ();
+ double newr = sqrt ((x - m_boundary / 2.0) * (x - m_boundary / 2.0)
+ + (y - m_boundary / 2.0) * (y - m_boundary / 2.0));
+ rsum += newr;
+ minr = std::min (minr, newr);
+ pos->Add (Vector (x, y, m_depth));
+
+ }
+ NS_LOG_DEBUG ("Mean range from gateway: " << rsum / m_numNodes
+ << " min. range " << minr);
+
+ mobility.SetPositionAllocator (pos);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (sink);
+
+ NS_LOG_DEBUG ("Position of sink: "
+ << sink.Get (0)->GetObject<MobilityModel> ()->GetPosition ());
+ mobility.Install (nc);
+
+ PacketSocketAddress socket;
+ socket.SetSingleDevice (sinkdev.Get(0)->GetIfIndex ());
+ socket.SetPhysicalAddress (sinkdev.Get(0)->GetAddress ());
+ socket.SetProtocol (0);
+
+ OnOffHelper app ("ns3::PacketSocketFactory", Address (socket));
+ app.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ app.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ app.SetAttribute ("DataRate", DataRateValue (m_dataRate));
+ app.SetAttribute ("PacketSize", UintegerValue (m_packetSize));
+
+ ApplicationContainer apps = app.Install (nc);
+ apps.Start (Seconds (0.5));
+ Time nextEvent = Seconds (0.5);
+
+
+ for (uint32_t cw = m_cwMin; cw <= m_cwMax; cw += m_cwStep)
+ {
+
+ for (uint32_t an = 0; an < m_avgs; an++)
+ {
+ nextEvent += m_simTime;
+ Simulator::Schedule (nextEvent, &Experiment::ResetData, this);
+ Simulator::Schedule (nextEvent, &Experiment::UpdatePositions, this, nc);
+ }
+ Simulator::Schedule (nextEvent, &Experiment::IncrementCw, this, cw);
+ }
+ apps.Stop (nextEvent + m_simTime);
+
+ Ptr<Node> sinkNode = sink.Get (0);
+ TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory");
+ if (sinkNode->GetObject<SocketFactory> (psfid) == 0)
+ {
+ Ptr<PacketSocketFactory> psf = CreateObject<PacketSocketFactory> ();
+ sinkNode->AggregateObject (psf);
+ }
+ Ptr<Socket> sinkSocket = Socket::CreateSocket (sinkNode, psfid);
+ sinkSocket->Bind (socket);
+ sinkSocket->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
+
+ m_bytesTotal = 0;
+
+ std::ofstream ascii (m_asciitracefile.c_str ());
+ if (!ascii.is_open ())
+ {
+ NS_FATAL_ERROR ("Could not open ascii trace file: "
+ << m_asciitracefile);
+ }
+ uan.EnableAsciiAll (ascii);
+
+ Simulator::Run ();
+ sinkNode = 0;
+ sinkSocket = 0;
+ pos = 0;
+ channel = 0;
+ prop = 0;
+ for (uint32_t i=0; i < nc.GetN (); i++)
+ {
+ nc.Get (i) = 0;
+ }
+ for (uint32_t i=0; i < sink.GetN (); i++)
+ {
+ sink.Get (i) = 0;
+ }
+
+ for (uint32_t i=0; i < devices.GetN (); i++)
+ {
+ devices.Get (i) = 0;
+ }
+ for (uint32_t i=0; i < sinkdev.GetN (); i++)
+ {
+ sinkdev.Get (i) = 0;
+ }
+
+ Simulator::Destroy ();
+ return m_data;
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+
+ LogComponentEnable ("UanCwExample", LOG_LEVEL_ALL);
+
+ Experiment exp;
+
+ std::string gnudatfile ("cwexpgnuout.dat");
+ std::string perModel = "ns3::UanPhyPerGenDefault";
+ std::string sinrModel = "ns3::UanPhyCalcSinrDefault";
+
+ CommandLine cmd;
+ cmd.AddValue ("NumNodes", "Number of transmitting nodes", exp.m_numNodes);
+ cmd.AddValue ("Depth", "Depth of transmitting and sink nodes", exp.m_depth);
+ cmd.AddValue ("RegionSize", "Size of boundary in meters", exp.m_boundary);
+ cmd.AddValue ("PacketSize", "Generated packet size in bytes", exp.m_packetSize);
+ cmd.AddValue ("DataRate", "DataRate in bps", exp.m_dataRate);
+ cmd.AddValue ("CwMin", "Min CW to simulate", exp.m_cwMin);
+ cmd.AddValue ("CwMax", "Max CW to simulate", exp.m_cwMax);
+ cmd.AddValue ("SlotTime", "Slot time duration", exp.m_slotTime);
+ cmd.AddValue ("Averages", "Number of topologies to test for each cw point", exp.m_avgs);
+ cmd.AddValue ("GnuFile", "Name for GNU Plot output", exp.m_gnudatfile);
+ cmd.AddValue ("PerModel", "PER model name", perModel);
+ cmd.AddValue ("SinrModel", "SINR model name", sinrModel);
+ cmd.Parse (argc, argv);
+
+ ObjectFactory obf;
+ obf.SetTypeId (perModel);
+ Ptr<UanPhyPer> per = obf.Create<UanPhyPer> ();
+ obf.SetTypeId (sinrModel);
+ Ptr<UanPhyCalcSinr> sinr = obf.Create<UanPhyCalcSinr> ();
+
+ UanHelper uan;
+ UanTxMode mode;
+ mode = UanTxModeFactory::CreateMode (UanTxMode::FSK, exp.m_dataRate,
+ exp.m_dataRate, 12000,
+ exp.m_dataRate, 2,
+ "Default mode");
+ UanModesList myModes;
+ myModes.AppendMode (mode);
+
+ uan.SetPhy ("ns3::UanPhyGen",
+ "PerModel", PointerValue (per),
+ "SinrModel", PointerValue (sinr),
+ "SupportedModes", UanModesListValue (myModes));
+
+ Gnuplot gp;
+ Gnuplot2dDataset ds;
+ ds = exp.Run (uan);
+
+ gp.AddDataset (ds);
+
+ std::ofstream of (exp.m_gnudatfile.c_str ());
+ if (!of.is_open ())
+ {
+ NS_FATAL_ERROR ("Can not open GNU Plot outfile: " << exp.m_gnudatfile);
+ }
+ gp.GenerateOutput (of);
+
+ per = 0;
+ sinr = 0;
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/uan/uan-cw-example.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANCWEXAMPLE_H
+#define UANCWEXAMPLE_H
+
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+/**
+ * \class Experiment
+ * \brief Helper class for UAN CW MAC example
+ *
+ */
+class Experiment
+{
+public:
+ Gnuplot2dDataset Run (UanHelper &uan);
+ void ReceivePacket (Ptr<Socket> socket);
+ void UpdatePositions (NodeContainer &nodes);
+ void ResetData ();
+ void IncrementCw (uint32_t cw);
+ uint32_t m_numNodes;
+ uint32_t m_dataRate;
+ double m_depth;
+ double m_boundary;
+ uint32_t m_packetSize;
+ uint32_t m_bytesTotal;
+ uint32_t m_cwMin;
+ uint32_t m_cwMax;
+ uint32_t m_cwStep;
+ uint32_t m_avgs;
+
+ Time m_slotTime;
+ Time m_simTime;
+
+ std::string m_gnudatfile;
+ std::string m_asciitracefile;
+ std::string m_bhCfgFile;
+
+ Gnuplot2dDataset m_data;
+ std::vector<double> m_throughputs;
+
+ Experiment ();
+};
+
+#endif //UANCWEXAMPLE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/uan/uan-rc-example.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+/**
+ * \file uan-rc-example.cc
+ * \ingroup UAN
+ * This example uses UanMacRc and UanMacRcGw which combined form a system
+ * using what is reffered to as RC-MAC. Details of RC-MAC will be published
+ * soon. In brief terms, RC-MAC is a dual channel protocol wherein the
+ * available bandwidth is dynamically divided into two channels,
+ * a reservation channel and a data channel. The network is assumed
+ * to consist of a single gateway node which services several
+ * non-gateway nodes.
+ *
+ * Time is divided into cycles. The non-gateway nodes transmit RTS packets
+ * on the reservation channel in parallel to scheduled data transmissions
+ * (scheduled in the previous cycle), and the gateway stores these requests
+ * for the duration of the cycle. At the start of the next cycle
+ * the gateway node transmits a CTS which contains packet transmission times
+ * for reserved packets as well as bandwidth allocation information
+ *
+ * This script deploys a single gateway node (current UanMacRc only supports
+ * a single gateway) in the center of a region and then distributes
+ * non-gateway nodes around the gateway with a uniformly distributed range
+ * between each node and the gateway.
+ *
+ * The script supports two simulation types. By default the gateway
+ * dynamically determines the optimal parameter settings and
+ * simulations are run with varying number of nodes (SimMin to SimMax as
+ * set by the command line). If DoNode=0 is given as a command line option
+ * then the mac parameter "a" (approximate expected number of successful
+ * RTS arrivals per cycle) is varied as the simulation parameter.
+ *
+ * For questions about this MAC protocol email "lentracy@gmail.com"
+ */
+
+#include "uan-rc-example.h"
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/uan-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/node-module.h"
+#include "ns3/log.h"
+#include "ns3/config.h"
+#include "ns3/callback.h"
+#include "ns3/contrib-module.h"
+
+#include <fstream>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("UanRcExample");
+
+
+Experiment::Experiment ()
+ : m_simMin (1),
+ m_simMax (1),
+ m_simStep (1),
+ m_numRates (1023),
+ m_totalRate (4096),
+ m_maxRange (3000),
+ m_numNodes (15),
+ m_pktSize (1000),
+ m_doNode (true),
+ m_sifs (Seconds (0.05)),
+ m_simTime (Seconds (5000)),
+ m_gnuplotfile ("uan-rc-example.gpl"),
+ m_bytesTotal (0)
+{
+}
+
+void
+Experiment::ReceivePacket (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+ while (packet = socket->Recv ())
+ {
+ m_bytesTotal += packet->GetSize ();
+ }
+}
+
+UanTxMode
+Experiment::CreateMode (uint32_t kass,
+ uint32_t fc,
+ bool upperblock,
+ std::string name)
+{
+
+ std::ostringstream buf;
+ buf << name << " " << kass;
+
+ uint32_t rate = m_totalRate/(m_numRates+1)* (kass);
+ uint32_t bw = kass * m_totalRate / (m_numRates+1);
+ uint32_t fcmode;
+ if(upperblock)
+ fcmode = (m_totalRate - bw)/2 + fc;
+ else
+ fcmode = (uint32_t)((-((double) m_totalRate ) + (double) bw)/2.0 + (double) fc);
+
+
+ uint32_t phyrate = m_totalRate;
+
+ UanTxMode mode;
+ mode = UanTxModeFactory::CreateMode (UanTxMode::OTHER,
+ rate,
+ phyrate,
+ fcmode,
+ bw,
+ 2,
+ buf.str());
+ return mode;
+}
+
+//Creates m_numRates different modes each dividing m_totalRate Hz (assumes 1 bit per hz)
+//centered at frequency fc
+void
+Experiment::CreateDualModes (uint32_t fc)
+{
+
+
+ for (uint32_t i=1; i < m_numRates+1; i++)
+ {
+ m_controlModes.AppendMode (CreateMode (i, fc, false, "control "));
+ }
+ for (uint32_t i=m_numRates; i > 0; i--)
+ {
+ m_dataModes.AppendMode (CreateMode (i, fc, true, "data "));
+ }
+}
+
+uint32_t
+Experiment::Run (UanHelper &uan, uint32_t param)
+{
+
+ m_bytesTotal=0;
+
+ uint32_t nNodes;
+ uint32_t a;
+ if(m_doNode)
+ {
+ a=0;
+ nNodes = param;
+ }
+ else
+ {
+ nNodes = m_numNodes;
+ a = param;
+ }
+ Time pDelay = Seconds((double) m_maxRange / 1500.0);
+
+ uan.SetMac ("ns3::UanMacRcGw",
+ "NumberOfRates", UintegerValue (m_numRates),
+ "NumberOfNodes", UintegerValue (nNodes),
+ "MaxReservations", UintegerValue (a),
+ "RetryRate", DoubleValue(1/30.0),
+ "SIFS", TimeValue (m_sifs),
+ "MaxPropDelay", TimeValue (pDelay),
+ "FrameSize", UintegerValue (m_pktSize));
+ Ptr<UanChannel> chan = CreateObject<UanChannel>();
+
+ NodeContainer sink;
+ sink.Create(1);
+ NetDeviceContainer sinkDev = uan.Install(sink, chan);
+
+ uan.SetMac ("ns3::UanMacRc",
+ "NumberOfRates", UintegerValue (m_numRates),
+ "MaxPropDelay", TimeValue (pDelay),
+ "RetryRate", DoubleValue(1.0/100.0));
+ NodeContainer nodes;
+ nodes.Create (nNodes);
+ NetDeviceContainer devices = uan.Install (nodes, chan);
+
+ MobilityHelper mobility;
+ uint32_t depth = 70;
+ Ptr<ListPositionAllocator> pos = CreateObject<ListPositionAllocator> ();
+
+ UniformVariable urv (0,m_maxRange);
+ UniformVariable utheta (0, 2.0*M_PI);
+ pos->Add (Vector (m_maxRange, m_maxRange, depth));
+
+ for (uint32_t i=0; i<nNodes; i++)
+ {
+ double theta = utheta.GetValue ();
+ double r = urv.GetValue ();
+
+ double x = m_maxRange + r*std::cos (theta);
+ double y = m_maxRange + r*std::sin (theta);
+
+ pos->Add (Vector (x, y, depth));
+
+ }
+
+ mobility.SetPositionAllocator (pos);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (sink);
+ mobility.Install (nodes);
+
+ PacketSocketHelper pktskth;
+ pktskth.Install (nodes);
+ pktskth.Install (sink);
+
+ PacketSocketAddress socket;
+ socket.SetSingleDevice (sinkDev.Get(0)->GetIfIndex ());
+ socket.SetPhysicalAddress (sinkDev.Get(0)->GetAddress ());
+ socket.SetProtocol (0);
+
+ OnOffHelper app ("ns3::PacketSocketFactory", Address (socket));
+ app.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ app.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ app.SetAttribute ("DataRate", DataRateValue (m_totalRate));
+ app.SetAttribute ("PacketSize", UintegerValue (m_pktSize));
+
+ ApplicationContainer apps = app.Install (nodes);
+
+ apps.Start (Seconds (0.5));
+ apps.Stop (m_simTime + Seconds(0.5));
+
+ Ptr<Node> sinkNode = sink.Get (0);
+ TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory");
+
+ Ptr<Socket> sinkSocket = Socket::CreateSocket(sinkNode, psfid);
+ sinkSocket->Bind(socket);
+ sinkSocket->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
+
+ Simulator::Stop (m_simTime + Seconds(0.6));
+
+ chan = 0;
+ sinkNode = 0;
+ sinkSocket = 0;
+ pos = 0;
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return m_bytesTotal;
+}
+int
+main(int argc, char *argv[])
+{
+
+ LogComponentEnable ("UanRcExample", LOG_LEVEL_ALL);
+
+ Experiment exp;
+
+ CommandLine cmd;
+ cmd.AddValue ("TotalRate", "Total channel capacity", exp.m_totalRate);
+ cmd.AddValue ("NumberRates", "Number of divided rates ( (NumberRates+1)%TotalRate should be 0)", exp.m_numRates);
+ cmd.AddValue ("MaxRange", "Maximum range between gateway and acoustic node", exp.m_maxRange);
+ cmd.AddValue ("SimMin", "Minimum parameter to test (nodes if DoNode=1, \"a\" param otherwise)", exp.m_simMin);
+ cmd.AddValue ("SimMax", "Maximum parameter to test (nodes if DoNode=1, \"a\" param otherwise)", exp.m_simMax);
+ cmd.AddValue ("SimStep", "Ammount to increment param per trial", exp.m_simStep);
+ cmd.AddValue ("DataFile", "Filename for GnuPlot", exp.m_gnuplotfile);
+ cmd.AddValue ("NumberNodes", "Number of nodes (invalid for doNode=1)", exp.m_numNodes);
+ cmd.AddValue ("SIFS", "SIFS time duration", exp.m_sifs);
+ cmd.AddValue ("PktSize", "Packet size in bytes", exp.m_pktSize);
+ cmd.AddValue ("SimTime", "Simulation time per trial", exp.m_simTime);
+ cmd.AddValue ("DoNode", "1 for do max nodes simulation (invalidates AMin and AMax values)", exp.m_doNode);
+ cmd.Parse (argc, argv);
+
+
+
+ exp.CreateDualModes (12000);
+
+ UanHelper uan;
+ uan.SetPhy ("ns3::UanPhyDual",
+ "SupportedModesPhy1", UanModesListValue (exp.m_dataModes),
+ "SupportedModesPhy2", UanModesListValue (exp.m_controlModes));
+
+ Gnuplot2dDataset ds;
+ for (uint32_t param=exp.m_simMin; param<=exp.m_simMax; param += exp.m_simStep)
+ {
+ uint32_t bytesRx = exp.Run (uan, param);
+ NS_LOG_DEBUG ("param=" << param << ": Received " << bytesRx << " bytes at sink");
+
+ double util = bytesRx*8.0/(exp.m_simTime.GetSeconds ()*exp.m_totalRate);
+
+ ds.Add (param, util);
+
+ SeedManager::SetRun (SeedManager::GetRun () + 1);
+ }
+
+ Gnuplot gp;
+ gp.AddDataset (ds);
+ std::ofstream of (exp.m_gnuplotfile.c_str ());
+ if (!of.is_open ())
+ {
+ NS_FATAL_ERROR ("Can not open GNU Plot outfile: " << exp.m_gnuplotfile);
+ }
+ gp.GenerateOutput (of);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/uan/uan-rc-example.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANRCEXAMPLE_H
+#define UANRCEXAMPLE_H
+
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/contrib-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/uan-module.h"
+
+using namespace ns3;
+
+class Experiment
+{
+public:
+ uint32_t m_simMin;
+ uint32_t m_simMax;
+ uint32_t m_simStep;
+ uint32_t m_numRates;
+ uint32_t m_totalRate;
+ uint32_t m_maxRange;
+ uint32_t m_numNodes;
+ uint32_t m_pktSize;
+ bool m_doNode;
+ Time m_sifs;
+ Time m_simTime;
+
+ std::string m_gnuplotfile;
+
+ uint32_t m_bytesTotal;
+
+ UanModesList m_dataModes;
+ UanModesList m_controlModes;
+
+ void ReceivePacket (Ptr<Socket> socket);
+ UanTxMode CreateMode (uint32_t kass,
+ uint32_t fc,
+ bool upperblock,
+ std::string name);
+ void CreateDualModes (uint32_t fc);
+ uint32_t Run (UanHelper &uan, uint32_t param);
+
+ Experiment();
+
+};
+
+#endif //UANRCEXAMPLE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/uan/wscript Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,11 @@
+
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_program('uan-cw-example', ['core', 'simulator', 'mobility', 'uan'])
+ obj.source = 'uan-cw-example.cc'
+
+ obj = bld.create_ns3_program('uan-rc-example', ['core', 'simulator', 'mobility', 'uan'])
+ obj.source = 'uan-rc-example.cc'
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-address.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-address.h"
+#include "ns3/address.h"
+
+namespace ns3 {
+
+UanAddress::UanAddress ()
+{
+ m_address = 255;
+}
+
+UanAddress::UanAddress (uint8_t addr)
+ : m_address (addr)
+{
+}
+
+UanAddress::~UanAddress ()
+{
+}
+
+uint8_t
+UanAddress::GetType (void)
+{
+ static uint8_t type = Address::Register ();
+ return type;
+}
+
+Address
+UanAddress::ConvertTo (void) const
+{
+ return Address (GetType (), &m_address, 1);
+}
+
+UanAddress
+UanAddress::ConvertFrom (const Address &address)
+{
+ NS_ASSERT (IsMatchingType (address));
+ UanAddress uAddr;
+ address.CopyTo (&uAddr.m_address);
+ return uAddr;
+}
+
+uint8_t
+UanAddress::GetAsInt (void) const
+{
+ return m_address;
+}
+bool
+UanAddress::IsMatchingType (const Address &address)
+{
+ return address.CheckCompatible (GetType (), 1);
+}
+
+UanAddress::operator Address () const
+{
+ return ConvertTo ();
+}
+
+void
+UanAddress::CopyFrom (const uint8_t *pBuffer)
+{
+ m_address = *pBuffer;
+}
+
+void
+UanAddress::CopyTo (uint8_t *pBuffer)
+{
+ *pBuffer = m_address;
+
+}
+
+UanAddress
+UanAddress::GetBroadcast ()
+{
+ return UanAddress (255);
+}
+UanAddress
+UanAddress::Allocate ()
+{
+ static uint8_t nextAllocated = 0;
+
+ uint32_t address = nextAllocated++;
+ if (nextAllocated == 255)
+ {
+ nextAllocated = 0;
+ }
+
+ return UanAddress (address);
+}
+
+bool
+operator == (const UanAddress &a, const UanAddress &b)
+{
+ return a.m_address == b.m_address;
+}
+
+bool
+operator != (const UanAddress &a, const UanAddress &b)
+{
+ return !(a == b);
+}
+
+std::ostream&
+operator<< (std::ostream& os, const UanAddress & address)
+{
+ os << (int) address.m_address;
+ return os;
+}
+std::istream&
+operator>> (std::istream& is, UanAddress & address)
+{
+ int x;
+ is >> x;
+ NS_ASSERT (0 <= x);
+ NS_ASSERT (x <= 255);
+ address.m_address = x;
+ return is;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-address.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANADDRESS_H
+#define UANADDRESS_H
+
+#include "ns3/address.h"
+#include <iostream>
+
+namespace ns3 {
+
+/**
+ * \class UanAddress
+ *
+ * A class used for addressing UAN MAC's. This implementation uses a simple 8 bit
+ * flat addressing scheme. It is unlikely that perceived underwater networks will
+ * soon exceed 200 nodes (or the overlapping of two underwater networks - the ocean is big),
+ * so this should provide adequate addressing for most applications.
+ */
+class UanAddress
+{
+public:
+ UanAddress ();
+ /**
+ * \param addr byte address to assign to this address
+ * \brief Create UanAddress object with address addr
+ */
+ UanAddress (uint8_t addr);
+ virtual ~UanAddress ();
+
+ /**
+ * \param address Address to convert to UAN address
+ * \returns UanAddress from Address
+ */
+ static UanAddress ConvertFrom (const Address &address);
+
+ /**
+ * \param address Address to test
+ * \returns True if address given is consistant with UanAddress
+ */
+ static bool IsMatchingType (const Address &address);
+
+ /**
+ * \brief Create UanAddress object with broadcast address
+ */
+ operator Address () const;
+
+ /**
+ * \param pBuffer Buffer to extract address from
+ * \brief Sets address to address stored in parameter
+ */
+ void CopyFrom (const uint8_t *pBuffer);
+
+ /**
+ * \param pBuffer
+ * \brief Writes address to buffer parameter
+ */
+ void CopyTo (uint8_t *pBuffer);
+
+ /**
+ * \returns 8 bit integer version of address
+ */
+ uint8_t GetAsInt (void) const;
+
+ /**
+ * \returns Broadcast address: 255
+ */
+ static UanAddress GetBroadcast (void);
+
+ /**
+ * \brief Allocates UanAddress from 0-254 (will wrap back to 0 if more than 255 are allocated)
+ */
+ static UanAddress Allocate ();
+
+
+private:
+ uint8_t m_address;
+
+ static uint8_t GetType (void);
+ Address ConvertTo (void) const;
+
+ friend bool operator == (const UanAddress &a, const UanAddress &b);
+ friend bool operator != (const UanAddress &a, const UanAddress &b);
+ friend std::ostream& operator<< (std::ostream& os, const UanAddress & address);
+ friend std::istream& operator>> (std::istream& is, UanAddress & address);
+
+};
+
+
+/**
+ * \brief Returns true if byte address a is equal to byte address b
+ */
+bool operator == (const UanAddress &a, const UanAddress &b);
+
+/**
+ * \brief Returns true if byte address a is unequal to byte address b
+ */
+bool operator != (const UanAddress &a, const UanAddress &b);
+
+/**
+ * \brief Writes param address to stream os as 8 bit integer
+ */
+std::ostream& operator<< (std::ostream& os, const UanAddress & address);
+
+/**
+ * \brief Inputs param address from stream is as 8 bit integer
+ */
+std::istream& operator>> (std::istream& is, UanAddress & address);
+
+} // namespace ns3
+
+#endif // UANADDRESS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-channel.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/mobility-model.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
+#include "ns3/log.h"
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+
+#include "uan-channel.h"
+#include "uan-phy.h"
+#include "uan-prop-model.h"
+#include "uan-tx-mode.h"
+#include "uan-net-device.h"
+#include "uan-transducer.h"
+#include "uan-noise-model-default.h"
+#include "uan-prop-model-ideal.h"
+
+NS_LOG_COMPONENT_DEFINE ("UanChannel");
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED ( UanChannel);
+
+TypeId
+UanChannel::GetTypeId ()
+{
+ static TypeId tid =
+ TypeId ("ns3::UanChannel")
+ .SetParent<Channel> ()
+ .AddConstructor<UanChannel> ()
+ .AddAttribute ("PropagationModel",
+ "A pointer to the propagation model.",
+ PointerValue (CreateObject<UanPropModelIdeal> ()),
+ MakePointerAccessor (&UanChannel::m_prop),
+ MakePointerChecker<UanPropModel> ())
+ .AddAttribute ("NoiseModel",
+ "A pointer to the model of the channel ambient noise.",
+ PointerValue (CreateObject<UanNoiseModelDefault> ()),
+ MakePointerAccessor (&UanChannel::m_noise),
+ MakePointerChecker<UanNoiseModel> ())
+ ;
+
+ return tid;
+}
+
+UanChannel::UanChannel ()
+ : Channel (),
+ m_prop (0)
+{
+}
+
+UanChannel::~UanChannel ()
+{
+}
+void
+UanChannel::DoDispose ()
+{
+ UanDeviceList::iterator it = m_devList.begin ();
+ for (; it != m_devList.end (); it++)
+ {
+ it->first = 0;
+ it->second = 0;
+ }
+ m_devList.clear ();
+ m_prop = 0;
+ m_noise = 0;
+ Channel::DoDispose ();
+}
+void
+UanChannel::SetPropagationModel (Ptr<UanPropModel> prop)
+{
+ NS_LOG_DEBUG ("Set Prop Model " << this);
+ m_prop = prop;
+}
+
+uint32_t
+UanChannel::GetNDevices () const
+{
+ return m_devList.size ();
+}
+
+Ptr<NetDevice>
+UanChannel::GetDevice (uint32_t i) const
+{
+ return m_devList[i].first;
+}
+
+void
+UanChannel::AddDevice (Ptr<UanNetDevice> dev, Ptr<UanTransducer> trans)
+{
+ NS_LOG_DEBUG ("Adding dev/trans pair number " << m_devList.size ());
+ m_devList.push_back (std::make_pair (dev, trans));
+}
+
+void
+UanChannel::TxPacket (Ptr<UanTransducer> src, Ptr<Packet> packet,
+ double txPowerDb, UanTxMode txMode)
+{
+ Ptr<MobilityModel> senderMobility = 0;
+
+ NS_LOG_DEBUG ("Channel scheduling");
+ for (UanDeviceList::const_iterator i = m_devList.begin (); i
+ != m_devList.end (); i++)
+ {
+
+ if (src == i->second)
+ {
+ senderMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
+ break;
+ }
+ }
+ NS_ASSERT (senderMobility != 0);
+ uint32_t j = 0;
+ UanDeviceList::const_iterator i = m_devList.begin ();
+ for (; i != m_devList.end (); i++)
+ {
+ if (src != i->second)
+ {
+ NS_LOG_DEBUG ("Scheduling " << i->first->GetMac ()->GetAddress ());
+ Ptr<MobilityModel> rcvrMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
+ Time delay = m_prop->GetDelay (senderMobility, rcvrMobility, txMode);
+ UanPdp pdp = m_prop->GetPdp (senderMobility, rcvrMobility, txMode);
+ double rxPowerDb = txPowerDb + m_prop->GetPathLossDb (senderMobility,
+ rcvrMobility,
+ txMode);
+
+ NS_LOG_DEBUG ("txPowerDb=" << txPowerDb << "dB, rxPowerDb="
+ << rxPowerDb << "distance="
+ << senderMobility->GetDistanceFrom (rcvrMobility)
+ << "m, delay=" << delay);
+
+ uint32_t dstNodeId = i->first->GetNode ()->GetId ();
+ Ptr<Packet> copy = packet->Copy ();
+ Simulator::ScheduleWithContext (dstNodeId, delay,
+ &UanChannel::SendUp,
+ this,
+ j,
+ copy,
+ rxPowerDb,
+ txMode,
+ pdp);
+ }
+ j++;
+ }
+}
+
+void
+UanChannel::SetNoiseModel (Ptr<UanNoiseModel> noise)
+{
+ NS_ASSERT (noise);
+ m_noise = noise;
+}
+void
+UanChannel::SendUp (uint32_t i, Ptr<Packet> packet, double rxPowerDb,
+ UanTxMode txMode, UanPdp pdp)
+{
+ NS_LOG_DEBUG ("Channel: In sendup");
+ m_devList[i].second->Receive (packet, rxPowerDb, txMode, pdp);
+}
+
+double
+UanChannel::GetNoiseDbHz (double fKhz)
+{
+ NS_ASSERT (m_noise);
+ double noise = m_noise->GetNoiseDbHz (fKhz);
+ return noise;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-channel.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANCHANNEL_H
+#define UANCHANNEL_H
+
+#include "ns3/net-device.h"
+#include "ns3/channel.h"
+#include "ns3/packet.h"
+#include "ns3/uan-prop-model.h"
+#include "ns3/uan-noise-model.h"
+
+#include <list>
+#include <vector>
+
+namespace ns3 {
+
+class UanNetDevice;
+class UanPhy;
+class UanTransducer;
+class UanTxMode;
+
+/**
+ * \class UanChannel
+ * \brief Channel class used by UAN devices
+ */
+class UanChannel : public Channel
+{
+public:
+ /**
+ * \brief UanDeviceList is a standard template vector of pairs (UanNetDevice, UanTransducer)
+ */
+ typedef std::vector<std::pair<Ptr<UanNetDevice>, Ptr<UanTransducer> > > UanDeviceList;
+
+
+ UanChannel ();
+ virtual ~UanChannel ();
+
+ static TypeId GetTypeId ();
+
+ // Methods inherrited from base class
+ virtual uint32_t GetNDevices (void) const;
+ virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+ /**
+ * \param src Transducer transmitting packet
+ * \param packet Packet to be transmitted
+ * \param txPowerDb Transmission power in dB
+ * \param txmode UanTxMode defining modulation of transmitted packet
+ * Send a packet out on the channel
+ */
+ void TxPacket (Ptr<UanTransducer> src, Ptr<Packet> packet, double txPowerDb,
+ UanTxMode txmode);
+
+ /**
+ * \param dev Net Device of node
+ * \param trans Transducer of net device attached to this channel
+ *
+ * Adds device to receiver list for this channel
+ */
+ void AddDevice (Ptr<UanNetDevice> dev, Ptr<UanTransducer> trans);
+
+ /**
+ * \param prop Propagation model this channel will use for path loss/propagation delay
+ */
+ void SetPropagationModel (Ptr<UanPropModel> prop);
+
+ /**
+ * \param noise Noise model this channel will use to determine ambient channel noise.
+ *
+ */
+ void SetNoiseModel (Ptr<UanNoiseModel> noise);
+
+ /**
+ * \param fKhz Frequency in kHz
+ * \returns Ambient noise in dB/Hz on channel at a frequency
+ */
+ double GetNoiseDbHz (double fKhz);
+
+private:
+ UanDeviceList m_devList;
+ Ptr<UanPropModel> m_prop;
+ Ptr<UanNoiseModel> m_noise;
+
+ void SendUp (uint32_t i, Ptr<Packet> packet, double rxPowerDb, UanTxMode txMode, UanPdp pdp);
+protected:
+ virtual void DoDispose ();
+};
+
+}
+
+#endif // UANCHANNEL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-header-common.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-header-common.h"
+#include "uan-address.h"
+
+namespace ns3 {
+
+UanHeaderCommon::UanHeaderCommon ()
+{
+}
+
+UanHeaderCommon::UanHeaderCommon (const UanAddress src, const UanAddress dest, uint8_t type)
+ : Header (),
+ m_dest (dest),
+ m_src (src),
+ m_type (type)
+{
+
+}
+
+TypeId
+UanHeaderCommon::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderCommon")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderCommon> ()
+ ;
+ return tid;
+}
+
+TypeId
+UanHeaderCommon::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+UanHeaderCommon::~UanHeaderCommon ()
+{
+}
+
+
+void
+UanHeaderCommon::SetDest (UanAddress dest)
+{
+ m_dest = dest;
+}
+void
+UanHeaderCommon::SetSrc (UanAddress src)
+{
+ m_src = src;
+}
+
+void
+UanHeaderCommon::SetType (uint8_t type)
+{
+ m_type = type;
+}
+
+UanAddress
+UanHeaderCommon::GetDest (void) const
+{
+ return m_dest;
+}
+UanAddress
+UanHeaderCommon::GetSrc (void) const
+{
+ return m_src;
+}
+uint8_t
+UanHeaderCommon::GetType (void) const
+{
+ return m_type;
+}
+
+// Inherrited methods
+
+uint32_t
+UanHeaderCommon::GetSerializedSize (void) const
+{
+ return 1 + 1 + 1;
+}
+
+void
+UanHeaderCommon::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_src.GetAsInt ());
+ start.WriteU8 (m_dest.GetAsInt ());
+ start.WriteU8 (m_type);
+}
+
+uint32_t
+UanHeaderCommon::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+
+ m_src = UanAddress (rbuf.ReadU8 ());
+ m_dest = UanAddress (rbuf.ReadU8 ());
+ m_type = rbuf.ReadU8 ();
+
+ return rbuf.GetDistanceFrom (start);
+}
+
+void
+UanHeaderCommon::Print (std::ostream &os) const
+{
+ os << "UAN src=" << m_src << " dest=" << m_dest << " type=" << (uint32_t) m_type;
+}
+
+
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-header-common.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANHEADERCOMMON_H
+#define UANHEADERCOMMON_H
+
+#include "ns3/header.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "uan-address.h"
+
+namespace ns3 {
+
+/**
+ * \class UanHeaderCommon
+ *
+ * Header includes 1 byte src address, 1 byte dest address,
+ * and a 1 byte type field.
+ */
+class UanHeaderCommon : public ns3::Header
+{
+public:
+ UanHeaderCommon ();
+ /**
+ * \brief Create UanHeaderCommon object with given source and destination address and header type
+ * \param src Source address defined in header
+ * \param dest Destination address defined in header
+ * \param type Header type
+ */
+ UanHeaderCommon (const UanAddress src, const UanAddress dest, uint8_t type);
+ virtual ~UanHeaderCommon ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param dest Address of destination node
+ */
+ void SetDest (UanAddress dest);
+ /**
+ * \param src Address of packet source node
+ */
+ void SetSrc (UanAddress src);
+ /**
+ * \param type Value to set 1 byte type field to. Value has protocol specific meaning
+ */
+ void SetType (uint8_t type);
+
+ /**
+ * \returns UanAddress in destination field
+ */
+ UanAddress GetDest (void) const;
+ /**
+ * \returns UanAddress in source field
+ */
+ UanAddress GetSrc (void) const;
+ /**
+ * \returns value of type field
+ */
+ uint8_t GetType (void) const;
+
+
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+private:
+ UanAddress m_dest;
+ UanAddress m_src;
+ uint8_t m_type;
+
+
+};
+
+}
+
+#endif // UANHEADERCOMMON_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-header-rc.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,624 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+
+#include "uan-header-rc.h"
+
+#include <set>
+
+namespace ns3 {
+
+UanHeaderRcData::UanHeaderRcData ()
+ : Header (),
+ m_frameNo (0),
+ m_propDelay (Seconds (0))
+{
+}
+
+UanHeaderRcData::UanHeaderRcData (uint8_t frameNo, Time propDelay)
+ : Header (),
+ m_frameNo (frameNo),
+ m_propDelay (propDelay)
+{
+
+}
+
+UanHeaderRcData::~UanHeaderRcData ()
+{
+}
+
+
+TypeId
+UanHeaderRcData::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderRcData")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderRcData> ()
+ ;
+ return tid;
+}
+
+void
+UanHeaderRcData::SetFrameNo (uint8_t no)
+{
+ m_frameNo = no;
+}
+
+void
+UanHeaderRcData::SetPropDelay (Time propDelay)
+{
+ m_propDelay = propDelay;
+}
+
+uint8_t
+UanHeaderRcData::GetFrameNo (void) const
+{
+ return m_frameNo;
+}
+
+Time
+UanHeaderRcData::GetPropDelay (void) const
+{
+ return m_propDelay;
+}
+
+uint32_t
+UanHeaderRcData::GetSerializedSize (void) const
+{
+ return 1 + 2;
+}
+
+void
+UanHeaderRcData::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_frameNo);
+ start.WriteU16 ( (uint16_t)(1000.0 * m_propDelay.GetSeconds () + 0.5));
+}
+uint32_t
+UanHeaderRcData::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+
+ m_frameNo = start.ReadU8 ();
+ m_propDelay = Seconds ( ((double) start.ReadU16 ()) / 1000.0 );
+
+ return rbuf.GetDistanceFrom (start);
+}
+
+void
+UanHeaderRcData::Print (std::ostream &os) const
+{
+ os << "Frame No=" << (uint32_t) m_frameNo << " Prop Delay=" << m_propDelay.GetSeconds ();
+}
+
+TypeId
+UanHeaderRcData::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+
+UanHeaderRcRts::UanHeaderRcRts ()
+ : Header (),
+ m_frameNo (0),
+ m_noFrames (0),
+ m_length (0),
+ m_timeStamp (Seconds (0)),
+ m_retryNo (0)
+{
+
+}
+
+UanHeaderRcRts::UanHeaderRcRts (uint8_t frameNo, uint8_t retryNo, uint8_t noFrames, uint16_t length, Time timeStamp)
+ : Header (),
+ m_frameNo (frameNo),
+ m_noFrames (noFrames),
+ m_length (length),
+ m_timeStamp (timeStamp),
+ m_retryNo (retryNo)
+{
+
+}
+
+UanHeaderRcRts::~UanHeaderRcRts ()
+{
+
+}
+
+TypeId
+UanHeaderRcRts::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderRcRts")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderRcRts> ()
+ ;
+ return tid;
+
+}
+
+void
+UanHeaderRcRts::SetFrameNo (uint8_t no)
+{
+ m_frameNo = no;
+}
+
+void
+UanHeaderRcRts::SetNoFrames (uint8_t no)
+{
+ m_noFrames = no;
+}
+
+void
+UanHeaderRcRts::SetLength (uint16_t length)
+{
+ m_length = length;
+}
+void
+UanHeaderRcRts::SetTimeStamp (Time timeStamp)
+{
+ m_timeStamp = timeStamp;
+}
+
+void
+UanHeaderRcRts::SetRetryNo (uint8_t no)
+{
+ m_retryNo = no;
+}
+uint8_t
+UanHeaderRcRts::GetNoFrames () const
+{
+ return m_noFrames;
+}
+
+uint16_t
+UanHeaderRcRts::GetLength () const
+{
+ return m_length;
+}
+
+Time
+UanHeaderRcRts::GetTimeStamp (void) const
+{
+ return m_timeStamp;
+}
+
+uint8_t
+UanHeaderRcRts::GetRetryNo (void) const
+{
+ return m_retryNo;
+}
+
+uint8_t
+UanHeaderRcRts::GetFrameNo (void) const
+{
+ return m_frameNo;
+}
+
+uint32_t
+UanHeaderRcRts::GetSerializedSize (void) const
+{
+ return 1 + 1 + 1 + 4 + 2;
+}
+
+void
+UanHeaderRcRts::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_frameNo);
+ start.WriteU8 (m_retryNo);
+ start.WriteU8 (m_noFrames);
+ start.WriteU16 (m_length);
+ start.WriteU32 ((uint32_t)(m_timeStamp.GetSeconds () * 1000.0 + 0.5));
+ // start.WriteU16(uint16_t (m_timeStamp.GetSeconds ()*1000));
+}
+
+uint32_t
+UanHeaderRcRts::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+ m_frameNo = rbuf.ReadU8 ();
+ m_retryNo = rbuf.ReadU8 ();
+ m_noFrames = rbuf.ReadU8 ();
+ m_length = rbuf.ReadU16 ();
+ m_timeStamp = Seconds ( ((double) rbuf.ReadU32 ()) / 1000.0 );
+ // m_timeStamp = Seconds ( rbuf.ReadU16 ()/1000 );
+ return rbuf.GetDistanceFrom (start);
+}
+
+void
+UanHeaderRcRts::Print (std::ostream &os) const
+{
+ os << "Frame #=" << (uint32_t) m_frameNo << " Retry #=" << (uint32_t) m_retryNo << " Num Frames=" << (uint32_t) m_noFrames << "Length=" << m_length << " Time Stamp=" << m_timeStamp.GetSeconds ();
+}
+
+TypeId
+UanHeaderRcRts::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+
+
+
+UanHeaderRcCtsGlobal::UanHeaderRcCtsGlobal ()
+ : Header (),
+ m_retryRate (0),
+ m_rateNum (0)
+{
+
+}
+
+UanHeaderRcCtsGlobal::UanHeaderRcCtsGlobal (Time wt, Time ts, uint16_t rate, uint16_t retryRate)
+ : Header (),
+ m_timeStampTx (ts),
+ m_winTime (wt),
+ m_retryRate (retryRate),
+ m_rateNum (rate)
+{
+
+}
+
+UanHeaderRcCtsGlobal::~UanHeaderRcCtsGlobal ()
+{
+
+}
+
+TypeId
+UanHeaderRcCtsGlobal::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderRcCtsGlobal")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderRcCtsGlobal> ()
+ ;
+ return tid;
+
+}
+
+
+void
+UanHeaderRcCtsGlobal::SetRateNum (uint16_t rate)
+{
+ m_rateNum = rate;
+}
+
+void
+UanHeaderRcCtsGlobal::SetRetryRate (uint16_t rate)
+{
+ m_retryRate = rate;
+}
+
+void
+UanHeaderRcCtsGlobal::SetWindowTime (Time t)
+{
+ m_winTime = t;
+}
+
+void
+UanHeaderRcCtsGlobal::SetTxTimeStamp (Time t)
+{
+ m_timeStampTx = t;
+}
+
+Time
+UanHeaderRcCtsGlobal::GetWindowTime (void) const
+{
+ return m_winTime;
+}
+
+Time
+UanHeaderRcCtsGlobal::GetTxTimeStamp (void) const
+{
+ return m_timeStampTx;
+}
+
+uint16_t
+UanHeaderRcCtsGlobal::GetRetryRate (void) const
+{
+ return m_retryRate;
+}
+
+uint16_t
+UanHeaderRcCtsGlobal::GetRateNum (void) const
+{
+ return m_rateNum;
+}
+uint32_t
+UanHeaderRcCtsGlobal::GetSerializedSize (void) const
+{
+ return 4 + 4 + 2 + 2;
+}
+
+void
+UanHeaderRcCtsGlobal::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU16 (m_rateNum);
+ start.WriteU16 (m_retryRate);
+ start.WriteU32 ( (uint32_t)(m_timeStampTx.GetSeconds () * 1000.0 + 0.5));
+ start.WriteU32 ( (uint32_t)(m_winTime.GetSeconds () * 1000.0 + 0.5));
+}
+
+uint32_t
+UanHeaderRcCtsGlobal::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+ m_rateNum = rbuf.ReadU16 ();
+ m_retryRate = rbuf.ReadU16 ();
+ m_timeStampTx = Seconds ( ( (double) rbuf.ReadU32 ()) / 1000.0 );
+ m_winTime = Seconds ( ( (double) rbuf.ReadU32 ()) / 1000.0 );
+ return rbuf.GetDistanceFrom (start);
+
+}
+
+void
+UanHeaderRcCtsGlobal::Print (std::ostream &os) const
+{
+ os << "CTS Global (Rate #=" << m_rateNum << ", Retry Rate=" << m_retryRate << ", TX Time=" << m_timeStampTx.GetSeconds () << ", Win Time=" << m_winTime.GetSeconds () << ")";
+}
+
+TypeId
+UanHeaderRcCtsGlobal::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+UanHeaderRcCts::UanHeaderRcCts ()
+ : Header (),
+ m_frameNo (0),
+ m_timeStampRts (Seconds (0)),
+ m_retryNo (0),
+ m_delay (Seconds (0)),
+ m_address (UanAddress::GetBroadcast ())
+{
+
+}
+
+UanHeaderRcCts::UanHeaderRcCts (uint8_t frameNo, uint8_t retryNo, Time ts, Time delay, UanAddress addr)
+ : Header (),
+ m_frameNo (frameNo),
+ m_timeStampRts (ts),
+ m_retryNo (retryNo),
+ m_delay (delay),
+ m_address (addr)
+{
+
+}
+
+UanHeaderRcCts::~UanHeaderRcCts ()
+{
+
+}
+
+TypeId
+UanHeaderRcCts::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderRcCts")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderRcCts> ()
+ ;
+ return tid;
+
+}
+
+void
+UanHeaderRcCts::SetFrameNo (uint8_t frameNo)
+{
+ m_frameNo = frameNo;
+}
+
+void
+UanHeaderRcCts::SetRtsTimeStamp (Time timeStamp)
+{
+ m_timeStampRts = timeStamp;
+}
+
+
+void
+UanHeaderRcCts::SetDelayToTx (Time delay)
+{
+ m_delay = delay;
+}
+
+void
+UanHeaderRcCts::SetRetryNo (uint8_t no)
+{
+ m_retryNo = no;
+}
+
+void
+UanHeaderRcCts::SetAddress (UanAddress addr)
+{
+ m_address = addr;
+}
+uint8_t
+UanHeaderRcCts::GetFrameNo () const
+{
+ return m_frameNo;
+}
+
+Time
+UanHeaderRcCts::GetRtsTimeStamp (void) const
+{
+ return m_timeStampRts;
+}
+
+Time
+UanHeaderRcCts::GetDelayToTx (void) const
+{
+ return m_delay;
+}
+
+uint8_t
+UanHeaderRcCts::GetRetryNo () const
+{
+ return m_retryNo;
+}
+
+UanAddress
+UanHeaderRcCts::GetAddress () const
+{
+ return m_address;
+}
+
+uint32_t
+UanHeaderRcCts::GetSerializedSize (void) const
+{
+ return 1 + 1 + 1 + 4 + 4;
+}
+
+
+void
+UanHeaderRcCts::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_address.GetAsInt ());
+ start.WriteU8 (m_frameNo);
+ start.WriteU8 (m_retryNo);
+ start.WriteU32 ((uint32_t)(m_timeStampRts.GetSeconds () * 1000.0 + 0.5));
+ start.WriteU32 ((uint32_t)(m_delay.GetSeconds () * 1000.0 + 0.5));
+}
+
+uint32_t
+UanHeaderRcCts::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+ m_address = UanAddress (rbuf.ReadU8 ());
+ m_frameNo = rbuf.ReadU8 ();
+ m_retryNo = rbuf.ReadU8 ();
+ m_timeStampRts = Seconds ( ( (double) rbuf.ReadU32 ()) / 1000.0 );
+ m_delay = Seconds ( ( (double) rbuf.ReadU32 ()) / 1000.0 );
+
+ return rbuf.GetDistanceFrom (start);
+}
+
+void
+UanHeaderRcCts::Print (std::ostream &os) const
+{
+ os << "CTS (Addr=" << m_address << " Frame #=" << (uint32_t) m_frameNo << " Retry #=" << (uint32_t) m_retryNo << " RTS Rx Timestamp=" << m_timeStampRts.GetSeconds () << " Delay until TX=" << m_delay.GetSeconds () << ")";
+}
+
+TypeId
+UanHeaderRcCts::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+UanHeaderRcAck::UanHeaderRcAck ()
+ : m_frameNo (0)
+{
+}
+
+UanHeaderRcAck::~UanHeaderRcAck ()
+{
+ m_nackedFrames.clear ();
+}
+
+TypeId
+UanHeaderRcAck::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanHeaderRcAck")
+ .SetParent<Header> ()
+ .AddConstructor<UanHeaderRcAck> ()
+ ;
+ return tid;
+}
+
+void
+UanHeaderRcAck::SetFrameNo (uint8_t noFrames)
+{
+ m_frameNo = noFrames;
+}
+
+void
+UanHeaderRcAck::AddNackedFrame (uint8_t frame)
+{
+ m_nackedFrames.insert (frame);
+}
+
+const std::set<uint8_t> &
+UanHeaderRcAck::GetNackedFrames (void) const
+{
+ return m_nackedFrames;
+}
+
+uint8_t
+UanHeaderRcAck::GetFrameNo (void) const
+{
+ return m_frameNo;
+}
+
+uint8_t
+UanHeaderRcAck::GetNoNacks (void) const
+{
+ return m_nackedFrames.size ();
+}
+
+uint32_t
+UanHeaderRcAck::GetSerializedSize (void) const
+{
+ return 1 + 1 + GetNoNacks ();
+}
+
+void
+UanHeaderRcAck::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU8 (m_frameNo);
+ start.WriteU8 (GetNoNacks ());
+ std::set<uint8_t>::iterator it = m_nackedFrames.begin ();
+ for (; it != m_nackedFrames.end (); it++)
+ {
+ start.WriteU8 (*it);
+ }
+}
+
+uint32_t
+UanHeaderRcAck::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator rbuf = start;
+ m_frameNo = rbuf.ReadU8 ();
+ uint8_t noAcks = rbuf.ReadU8 ();
+ m_nackedFrames.clear ();
+ for (uint32_t i = 0; i < noAcks; i++)
+ {
+ m_nackedFrames.insert (rbuf.ReadU8 ());
+ }
+ return rbuf.GetDistanceFrom (start);
+}
+
+void
+UanHeaderRcAck::Print (std::ostream &os) const
+{
+ os << "# Frames=" << (uint32_t) m_frameNo << " # nacked=" << (uint32_t) GetNoNacks () << " Nacked: ";
+ if (GetNoNacks () > 0)
+ {
+ std::set<uint8_t>::iterator it = m_nackedFrames.begin ();
+ os << (uint32_t) *it;
+ it++;
+ for (; it != m_nackedFrames.end (); it++)
+ {
+ os << ", " << (uint32_t) *it;
+ }
+ }
+}
+
+TypeId
+UanHeaderRcAck::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-header-rc.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,375 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+
+#ifndef UANHEADERRC_H
+#define UANHEADERRC_H
+
+#include "ns3/header.h"
+#include "ns3/nstime.h"
+#include "ns3/uan-address.h"
+
+#include <set>
+
+namespace ns3 {
+
+/**
+ * \class UanHeaderRcData
+ *
+ * \brief Extra data header information
+ *
+ * Adds prop. delay measure, and frame number info to
+ * transmitted data packet
+ */
+class UanHeaderRcData : public ns3::Header
+{
+public:
+ UanHeaderRcData ();
+ /**
+ * \param frameNum Data frame # of reservation being transmitted
+ * \param propDelay Measured propagation delay found in handshaking
+ * \note Prop. delay is transmitted with 16 bits and ms accuracy
+ */
+ UanHeaderRcData (uint8_t frameNum, Time propDelay);
+ virtual ~UanHeaderRcData ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param frameNum Data frame # of reservation being transmitted
+ */
+ void SetFrameNo (uint8_t frameNum);
+ /**
+ * \param propDelay Measured propagation delay found in handshaking
+ * \note Prop. delay is transmitted with 16 bits and ms accuracy
+ */
+ void SetPropDelay (Time propDelay);
+ /**
+ * \returns Data frame # of reservation being transmitted
+ */
+ uint8_t GetFrameNo (void) const;
+ /**
+ * \returns Measured propagation delay found in handshaking
+ * \note Prop. delay is transmitted with 16 bits and ms accuracy
+ */
+ Time GetPropDelay (void) const;
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+
+private:
+ uint8_t m_frameNo;
+ Time m_propDelay;
+};
+
+/**
+ * \class UanHeaderRcRts
+ *
+ * \brief RTS header
+ *
+ * Contains frame #, retry #, # frames, length, and timestamp
+ */
+class UanHeaderRcRts : public ns3::Header
+{
+public:
+ UanHeaderRcRts ();
+ /**
+ * \param frameNo Reservation frame #
+ * \param retryNo Retry # of RTS packet
+ * \param noFrames # of data frames in reservation
+ * \param length # of bytes (including headers) in data
+ * \param ts RTS TX timestamp
+ * \note Timestamp is serialized into 32 bits with ms accuracy
+ */
+ UanHeaderRcRts (uint8_t frameNo, uint8_t retryNo, uint8_t noFrames, uint16_t length, Time ts);
+ virtual ~UanHeaderRcRts ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param fno TX frame #
+ */
+ void SetFrameNo (uint8_t fno);
+ /**
+ * \param no Number of data frames included in this reservation request
+ */
+ void SetNoFrames (uint8_t no);
+ /**
+ * \param timeStamp RTS transmission time
+ */
+ void SetTimeStamp (Time timeStamp);
+ /**
+ * \param length Total number of data bytes in reservation (including headers)
+ * \note Timestamp is serialized with 32 bits in ms precision
+ */
+ void SetLength (uint16_t length);
+ /**
+ * \param no Retry number of this RTS (Used to match timestamp to correctly received RTS)
+ */
+ void SetRetryNo (uint8_t no);
+
+ /**
+ * \returns Frame #
+ */
+ uint8_t GetFrameNo (void) const;
+ /**
+ * \returns # of data frames in reservation
+ */
+ uint8_t GetNoFrames (void) const;
+ /**
+ * \returns TX time of the RTS packet
+ * \note Timestamp is serialized with 32 bits in ms precision
+ */
+ Time GetTimeStamp (void) const;
+ /**
+ * \returns Total # of bytes in data packets for reservation (including headers)
+ */
+ uint16_t GetLength (void) const;
+ /**
+ * \returns Retry number of this RTS packet
+ */
+ uint8_t GetRetryNo (void) const;
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+
+private:
+ uint8_t m_frameNo;
+ uint8_t m_noFrames;
+ uint16_t m_length;
+ Time m_timeStamp;
+ uint8_t m_retryNo;
+};
+
+/**
+ * \class UanHeaderRcCtsGlobal
+ *
+ * \brief Cycle broadcast information for
+ */
+
+
+class UanHeaderRcCtsGlobal : public Header
+{
+public:
+ /**
+ * \brief Create UanHeaderRcCtsGlobal with fields zeroed out
+ */
+ UanHeaderRcCtsGlobal ();
+ /**
+ * \brief Create object with given window time, time stamp, rate, and retry rate.
+ * \param wt Window time
+ * \param ts Timestamp
+ * \param rate Rate number
+ * \param retryRate Retry rate value
+ */
+ UanHeaderRcCtsGlobal (Time wt, Time ts, uint16_t rate, uint16_t retryRate);
+ ~UanHeaderRcCtsGlobal ();
+
+ static TypeId GetTypeId ();
+
+ /**
+ * \param rate Rate number corresponding to data rate of current cycle
+ */
+ void SetRateNum (uint16_t rate);
+ /**
+ * \param rate Retry rate number for current cycle
+ */
+ void SetRetryRate (uint16_t rate);
+ /**
+ * \param t Time duration following blocking time to allow RTS transmissions
+ */
+ void SetWindowTime (Time t);
+
+ /**
+ * \param timeStamp Time of CTS transmission
+ */
+ void SetTxTimeStamp (Time timeStamp);
+
+ /**
+ * \returns Rate # corresponding to data rate of current cycle
+ */
+ uint16_t GetRateNum (void) const;
+ /**
+ * \returns retry rate # of retry rate for current cycle
+ */
+ uint16_t GetRetryRate (void) const;
+ /**
+ * \returns Time duration after blocking time allowed for RTS transmissions
+ */
+ Time GetWindowTime (void) const;
+ /**
+ * \returns Timestamp of CTS transmission
+ */
+ Time GetTxTimeStamp (void) const;
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+
+private:
+ Time m_timeStampTx;
+ Time m_winTime;
+ uint16_t m_retryRate;
+ uint16_t m_rateNum;
+};
+/**
+ * \class UanHeaderRcCts
+ *
+ * \brief CTS header
+ *
+ * Includes RTS RX time, CTS TX time, delay until TX, RTS blocking period,
+ * RTS tx period, rate #, and retry rate #
+ */
+
+class UanHeaderRcCts : public ns3::Header
+{
+public:
+ UanHeaderRcCts ();
+ /**
+ * \param frameNo Resrvation frame # being cleared
+ * \param retryNo Retry # of received RTS packet
+ * \param rtsTs RX time of RTS packet at gateway
+ * \param delay Delay until transmission
+ * \param addr Destination of CTS packet
+ * \note Times are serialized, with ms precission, into 32 bit fields.
+ */
+ UanHeaderRcCts (uint8_t frameNo, uint8_t retryNo, Time rtsTs, Time delay, UanAddress addr);
+ virtual ~UanHeaderRcCts ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param frameNo Frame # of RTS being cleared
+ */
+ void SetFrameNo (uint8_t frameNo);
+ /**
+ * \param timeStamp Time of RTS reception
+ */
+ void SetRtsTimeStamp (Time timeStamp);
+ /**
+ * \param delay Time duration, from CTS TX, before first data frame arrival
+ */
+ void SetDelayToTx (Time delay);
+ /**
+ * \param no Retry number of RTS frame being cleared
+ */
+ void SetRetryNo (uint8_t no);
+ /**
+ * \param addr Destination for scheduling info
+ */
+ void SetAddress (UanAddress addr);
+
+ /**
+ * \returns Frame # of RTS being cleared
+ */
+ uint8_t GetFrameNo (void) const;
+ /**
+ * \returns RX time of RTS being cleared
+ */
+ Time GetRtsTimeStamp (void) const;
+ /**
+ * \returns Delay from TX time of CTS packet until arrival of first data frame
+ */
+ Time GetDelayToTx (void) const;
+ /**
+ * \returns Retry # of RTS packet being cleared
+ */
+ uint8_t GetRetryNo (void) const;
+ /**
+ * \returns Destination for scheduling info
+ */
+ UanAddress GetAddress (void) const;
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+
+private:
+ uint8_t m_frameNo;
+ Time m_timeStampRts;
+ uint8_t m_retryNo;
+ Time m_delay;
+ UanAddress m_address;
+};
+
+/**
+ * \class UanHeaderRcAck
+ * \brief Header used for ACK packets by protocol ns3::UanMacRc
+ */
+class UanHeaderRcAck : public Header
+{
+public:
+ UanHeaderRcAck ();
+ virtual ~UanHeaderRcAck ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param frameNo Frame # of reservation being acknowledged
+ */
+ void SetFrameNo (uint8_t frameNo);
+ /**
+ * \param frame Data frame # being nacked
+ */
+ void AddNackedFrame (uint8_t frame);
+
+ /**
+ * \returns Set of nacked frames
+ */
+ const std::set<uint8_t> &GetNackedFrames (void) const;
+ /**
+ * \returns Reservation frame # being acknowledged.
+ */
+ uint8_t GetFrameNo (void) const;
+ /**
+ * \returns Number of data frames being NACKED
+ */
+ uint8_t GetNoNacks (void) const;
+
+ // Inherrited methods
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+ virtual TypeId GetInstanceTypeId (void) const;
+
+private:
+ uint8_t m_frameNo;
+ std::set<uint8_t> m_nackedFrames;
+
+};
+
+}
+
+#endif // UANHEADERRC_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-aloha.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-mac-aloha.h"
+#include "uan-tx-mode.h"
+#include "uan-address.h"
+#include "ns3/log.h"
+#include "uan-phy.h"
+#include "uan-header-common.h"
+
+#include <iostream>
+NS_LOG_COMPONENT_DEFINE ("UanMacAloha");
+
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (UanMacAloha);
+
+UanMacAloha::UanMacAloha ()
+ : UanMac ()
+{
+}
+
+UanMacAloha::~UanMacAloha ()
+{
+}
+
+void
+UanMacAloha::DoDispose ()
+{
+ m_phy = 0;
+ UanMac::DoDispose ();
+}
+
+TypeId
+UanMacAloha::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanMacAloha")
+ .SetParent<Object> ()
+ .AddConstructor<UanMacAloha> ()
+ ;
+ return tid;
+}
+
+Address
+UanMacAloha::GetAddress (void)
+{
+ return m_address;
+}
+
+void
+UanMacAloha::SetAddress (UanAddress addr)
+{
+ m_address=addr;
+}
+bool
+UanMacAloha::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
+{
+ NS_LOG_DEBUG ("" << Simulator::Now ().GetSeconds () << " MAC " << UanAddress::ConvertFrom (GetAddress ()) << " Queueing packet for " << UanAddress::ConvertFrom (dest));
+
+ if (!m_phy->IsStateTx ())
+ {
+ UanAddress src = UanAddress::ConvertFrom (GetAddress ());
+ UanAddress udest = UanAddress::ConvertFrom (dest);
+
+ UanHeaderCommon header;
+ header.SetSrc (src);
+ header.SetDest (udest);
+ header.SetType (0);
+
+ packet->AddHeader (header);
+ m_phy->SendPacket (packet, protocolNumber);
+ return true;
+ }
+ else
+ return false;
+}
+
+void
+UanMacAloha::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress& > cb)
+{
+ m_forUpCb = cb;
+}
+void
+UanMacAloha::AttachPhy (Ptr<UanPhy> phy)
+{
+ m_phy = phy;
+ m_phy->SetReceiveOkCallback (MakeCallback (&UanMacAloha::RxPacketGood, this));
+ m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacAloha::RxPacketError, this));
+
+}
+void
+UanMacAloha::RxPacketGood (Ptr<Packet> pkt, double sinr, UanTxMode txMode)
+{
+ UanHeaderCommon header;
+ pkt->RemoveHeader (header);
+ NS_LOG_DEBUG ("Receiving packet from " << header.GetSrc () << " For " << header.GetDest ());
+
+ if (header.GetDest () == GetAddress () || header.GetDest () == UanAddress::GetBroadcast ())
+ {
+ m_forUpCb (pkt, header.GetSrc ());
+ }
+
+}
+
+void
+UanMacAloha::RxPacketError (Ptr<Packet> pkt, double sinr)
+{
+ NS_LOG_DEBUG ("" << Simulator::Now () << " MAC " << UanAddress::ConvertFrom (GetAddress ()) << " Received packet in error with sinr " << sinr);
+}
+
+Address
+UanMacAloha::GetBroadcast (void) const
+{
+ UanAddress broadcast (255);
+ return broadcast;
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-aloha.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANMACALOHA_H
+#define UANMACALOHA_H
+
+#include "uan-mac.h"
+#include "uan-address.h"
+
+namespace ns3
+{
+
+
+class UanPhy;
+class UanTxMode;
+
+/**
+ * \class UanMacAloha
+ * \brief ALOHA MAC Protocol
+ *
+ * The simplest MAC protocol for wireless networks. Packets enqueued
+ * are immediately transmitted. This MAC attaches a UanHeaderCommon
+ * to outgoing packets for address information. (The type field is not used)
+ */
+class UanMacAloha : public ns3::UanMac
+{
+public:
+ UanMacAloha ();
+ virtual ~UanMacAloha ();
+ static TypeId GetTypeId (void);
+
+
+ //Inheritted functions
+ Address GetAddress (void);
+ virtual void SetAddress (UanAddress addr);
+ virtual bool Enqueue (Ptr<Packet> pkt, const Address &dest, uint16_t protocolNumber);
+ virtual void SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress& > cb);
+ virtual void AttachPhy (Ptr<UanPhy> phy);
+ virtual Address GetBroadcast (void) const;
+
+private:
+ UanAddress m_address;
+ Ptr<UanPhy> m_phy;
+ Callback<void, Ptr<Packet>, const UanAddress& > m_forUpCb;
+
+ /**
+ * \brief Receive packet from lower layer (passed to PHY as callback)
+ * \param pkt Packet being received
+ * \param sinr SINR of received packet
+ * \param txMode Mode of received packet
+ */
+ void RxPacketGood (Ptr<Packet> pkt, double sinr, UanTxMode txMode);
+
+ /**
+ * \brief Packet received at lower layer in error
+ * \param pkt Packet received in error
+ * \param sinr SINR of received packet
+ */
+ void RxPacketError (Ptr<Packet> pkt, double sinr);
+protected:
+ virtual void DoDispose ();
+};
+
+}
+
+#endif // UANMACALOHA_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-cw.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-mac-cw.h"
+#include "ns3/attribute.h"
+#include "ns3/uinteger.h"
+#include "ns3/double.h"
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+#include "ns3/uan-header-common.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("UanMacCw");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanMacCw);
+
+UanMacCw::UanMacCw ()
+ : UanMac (),
+ m_phy (0),
+ m_pktTx (0),
+ m_state (IDLE)
+
+{
+}
+
+UanMacCw::~UanMacCw ()
+{
+}
+
+void
+UanMacCw::DoDispose ()
+{
+ m_pktTx = 0;
+ m_phy = 0;
+ m_sendEvent.Cancel ();
+ m_txEndEvent.Cancel ();
+ UanMac::DoDispose ();
+}
+
+TypeId
+UanMacCw::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanMacCw")
+ .SetParent<Object> ()
+ .AddConstructor<UanMacCw> ()
+ .AddAttribute ("CW",
+ "The MAC parameter CW",
+ UintegerValue (10),
+ MakeUintegerAccessor (&UanMacCw::m_cw),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("SlotTime",
+ "Time slot duration for MAC backoff",
+ TimeValue (MilliSeconds (20)),
+ MakeTimeAccessor (&UanMacCw::m_slotTime),
+ MakeTimeChecker ())
+ .AddTraceSource ("Enqueue",
+ "A packet arrived at the MAC for transmission",
+ MakeTraceSourceAccessor (&UanMacCw::m_enqueueLogger))
+ .AddTraceSource ("Dequeue",
+ "A was passed down to the PHY from the MAC",
+ MakeTraceSourceAccessor (&UanMacCw::m_dequeueLogger))
+ .AddTraceSource ("RX",
+ "A packet was destined for this MAC and was received",
+ MakeTraceSourceAccessor (&UanMacCw::m_rxLogger))
+
+ ;
+ return tid;
+}
+
+Address
+UanMacCw::GetAddress ()
+{
+ return this->m_address;
+}
+
+void
+UanMacCw::SetAddress (UanAddress addr)
+{
+ m_address = addr;
+}
+
+bool
+UanMacCw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
+{
+
+ switch (m_state)
+ {
+ case CCABUSY:
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " MAC " << GetAddress () << " Starting enqueue CCABUSY");
+ if (m_txEndEvent.IsRunning () == TX)
+ {
+ NS_LOG_DEBUG ("State is TX");
+ }
+ else
+ {
+ NS_LOG_DEBUG ("State is not TX");
+ }
+
+ NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
+ return false;
+ case RUNNING:
+ NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue RUNNING");
+ NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
+ return false;
+ case TX:
+ case IDLE:
+ {
+ NS_ASSERT (!m_pktTx);
+
+ UanHeaderCommon header;
+ header.SetDest (UanAddress::ConvertFrom (dest));
+ header.SetSrc (m_address);
+ header.SetType (0);
+ packet->AddHeader (header);
+
+ m_enqueueLogger (packet, protocolNumber);
+
+ if (m_phy->IsStateBusy ())
+ {
+ m_pktTx = packet;
+ m_pktTxProt = protocolNumber;
+ m_state = CCABUSY;
+ UniformVariable rv (0,m_cw);
+ uint32_t cw = (uint32_t) rv.GetValue ();
+ m_savedDelayS = Seconds ((double)(cw) * m_slotTime.GetSeconds ());
+ m_sendTime = Simulator::Now () + m_savedDelayS;
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while busy: (Chose CW " << cw << ", Sending at " << m_sendTime.GetSeconds () << " Packet size: " << packet->GetSize ());
+ NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () >= 1 || m_phy->IsStateTx ());
+ }
+ else
+ {
+ NS_ASSERT (m_state != TX);
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << ": Addr " << GetAddress () << ": Enqueuing new packet while idle (sending)");
+ NS_ASSERT (m_phy->GetTransducer ()->GetArrivalList ().size () == 0 && !m_phy->IsStateTx ());
+ m_state = TX;
+ m_phy->SendPacket (packet,protocolNumber);
+
+ }
+ break;
+ }
+ default:
+ NS_LOG_DEBUG ("MAC " << GetAddress () << " Starting enqueue SOMETHING ELSE");
+ return false;
+ }
+
+ return true;
+
+
+}
+
+void
+UanMacCw::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
+{
+ m_forwardUpCb = cb;
+}
+
+void
+UanMacCw::AttachPhy (Ptr<UanPhy> phy)
+{
+ m_phy = phy;
+ m_phy->SetReceiveOkCallback (MakeCallback (&UanMacCw::PhyRxPacketGood, this));
+ m_phy->SetReceiveErrorCallback (MakeCallback (&UanMacCw::PhyRxPacketError, this));
+ m_phy->RegisterListener (this);
+}
+
+Address
+UanMacCw::GetBroadcast (void) const
+{
+ return UanAddress::GetBroadcast ();
+}
+
+
+void
+UanMacCw::NotifyRxStart (void)
+{
+ if (m_state == RUNNING)
+ {
+
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
+ SaveTimer ();
+ m_state = CCABUSY;
+ }
+
+}
+void
+UanMacCw::NotifyRxEndOk (void)
+{
+ if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
+ {
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
+ m_state = RUNNING;
+ StartTimer ();
+
+ }
+
+}
+void
+UanMacCw::NotifyRxEndError (void)
+{
+ if (m_state == CCABUSY && !m_phy->IsStateCcaBusy ())
+ {
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
+ m_state = RUNNING;
+ StartTimer ();
+
+ }
+
+}
+void
+UanMacCw::NotifyCcaStart (void)
+{
+ if (m_state == RUNNING)
+ {
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel busy");
+ m_state = CCABUSY;
+ SaveTimer ();
+
+ }
+
+}
+void
+UanMacCw::NotifyCcaEnd (void)
+{
+ if (m_state == CCABUSY)
+ {
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle");
+ m_state = RUNNING;
+ StartTimer ();
+
+ }
+
+}
+void
+UanMacCw::NotifyTxStart (Time duration)
+{
+
+ if (m_txEndEvent.IsRunning ())
+ {
+ Simulator::Cancel (m_txEndEvent);
+ }
+
+ m_txEndEvent = Simulator::Schedule (duration, &UanMacCw::EndTx, this);
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " scheduling TxEndEvent with delay " << duration.GetSeconds ());
+ if (m_state == RUNNING)
+ {
+ NS_ASSERT (0);
+ m_state = CCABUSY;
+ SaveTimer ();
+
+ }
+
+}
+
+void
+UanMacCw::EndTx (void)
+{
+ NS_ASSERT (m_state == TX || m_state == CCABUSY);
+ if (m_state == TX)
+ {
+ m_state = IDLE;
+ }
+ else if (m_state == CCABUSY)
+ {
+ if (m_phy->IsStateIdle ())
+ {
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << ": Switching to channel idle (After TX!)");
+ m_state = RUNNING;
+ StartTimer ();
+ }
+ }
+ else
+ {
+ NS_FATAL_ERROR ("In strange state at UanMacCw EndTx");
+ }
+}
+void
+UanMacCw::SetCw (uint32_t cw)
+{
+ m_cw = cw;
+}
+void
+UanMacCw::SetSlotTime (Time duration)
+{
+ m_slotTime = duration;
+}
+uint32_t
+UanMacCw::GetCw (void)
+{
+ return m_cw;
+}
+Time
+UanMacCw::GetSlotTime (void)
+{
+ return m_slotTime;
+}
+void
+UanMacCw::PhyRxPacketGood (Ptr<Packet> packet, double sinr, UanTxMode mode)
+{
+ UanHeaderCommon header;
+ packet->RemoveHeader (header);
+
+ if (header.GetDest () == m_address)
+ {
+ m_forwardUpCb (packet, header.GetSrc ());
+ }
+}
+void
+UanMacCw::PhyRxPacketError (Ptr<Packet> packet, double sinr)
+{
+
+}
+void
+UanMacCw::SaveTimer (void)
+{
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now ()).GetSeconds () << ")");
+ NS_ASSERT (m_pktTx);
+ NS_ASSERT (m_sendTime >= Simulator::Now ());
+ m_savedDelayS = m_sendTime - Simulator::Now ();
+ Simulator::Cancel (m_sendEvent);
+
+
+}
+void
+UanMacCw::StartTimer (void)
+{
+
+ m_sendTime = Simulator::Now () + m_savedDelayS;
+ if (m_sendTime == Simulator::Now ())
+ {
+ SendPacket ();
+ }
+ else
+ {
+ m_sendEvent = Simulator::Schedule (m_savedDelayS, &UanMacCw::SendPacket, this);
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Starting timer (New send time = " << this->m_sendTime.GetSeconds () << ")");
+ }
+}
+
+void
+UanMacCw::SendPacket (void)
+{
+ NS_LOG_DEBUG ("Time " << Simulator::Now ().GetSeconds () << " Addr " << GetAddress () << " Transmitting ");
+ NS_ASSERT (m_state == RUNNING);
+ m_state = TX;
+ m_phy->SendPacket (m_pktTx,m_pktTxProt);
+ m_pktTx = 0;
+ m_sendTime = Seconds (0);
+ m_savedDelayS = Seconds (0);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-cw.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANMACCW_H
+#define UANMACCW_H
+
+#include "ns3/uan-mac.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/uan-phy.h"
+#include "ns3/uan-tx-mode.h"
+#include "ns3/uan-address.h"
+
+
+namespace ns3 {
+
+/**
+ * \class UanMacCw
+ * \brief CW-MAC A MAC protocol similar in idea to the 802.11 DCF with constant backoff window
+ *
+ * For more information on this MAC protocol, see:
+ * Parrish, N.; Tracy, L.; Roy, S.; Arabshahi, P.; Fox, W.,
+ * "System Design Considerations for Undersea Networks: Link and Multiple Access Protocols,"
+ * Selected Areas in Communications, IEEE Journal on , vol.26, no.9, pp.1720-1730, December 2008
+ */
+class UanMacCw : public ns3::UanMac,
+ public ns3::UanPhyListener
+{
+public:
+ UanMacCw ();
+ virtual ~UanMacCw ();
+ static TypeId GetTypeId (void);
+
+ /**
+ * \param cw Contention window size
+ */
+ virtual void SetCw (uint32_t cw);
+ /**
+ * \param duration Slot time duration
+ */
+ virtual void SetSlotTime (Time duration);
+ /**
+ * \returns Contention window size
+ */
+ virtual uint32_t GetCw (void);
+ /**
+ * \returns slot time duration
+ */
+ virtual Time GetSlotTime (void);
+
+ // Inherited methods
+ virtual Address GetAddress ();
+ virtual void SetAddress (UanAddress addr);
+ virtual bool Enqueue (Ptr<Packet> pkt, const Address &dest, uint16_t protocolNumber);
+ virtual void SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb);
+ virtual void AttachPhy (Ptr<UanPhy> phy);
+ virtual Address GetBroadcast (void) const;
+
+ // PHY listeners
+ /// Function called by UanPhy object to notify of packet reception
+ virtual void NotifyRxStart (void);
+ /// Function called by UanPhy object to notify of packet received successfully
+ virtual void NotifyRxEndOk (void);
+ /// Function called by UanPhy object to notify of packet received in error
+ virtual void NotifyRxEndError (void);
+ /// Function called by UanPhy object to notify of channel sensed busy
+ virtual void NotifyCcaStart (void);
+ /// Function called by UanPhy object to notify of channel no longer sensed busy
+ virtual void NotifyCcaEnd (void);
+ /// Function called by UanPhy object to notify of outgoing transmission start
+ virtual void NotifyTxStart (Time duration);
+private:
+ typedef enum {
+ IDLE, CCABUSY, RUNNING, TX
+ } State;
+
+ Callback <void, Ptr<Packet>, const UanAddress& > m_forwardUpCb;
+ UanAddress m_address;
+ Ptr<UanPhy> m_phy;
+ TracedCallback<Ptr<const Packet>, UanTxMode > m_rxLogger;
+ TracedCallback<Ptr<const Packet>, uint16_t > m_enqueueLogger;
+ TracedCallback<Ptr<const Packet>, uint16_t > m_dequeueLogger;
+
+ // Mac parameters
+ uint32_t m_cw;
+ Time m_slotTime;
+
+ // State variables
+ Time m_sendTime;
+ Time m_savedDelayS;
+ Ptr<Packet> m_pktTx;
+ uint16_t m_pktTxProt;
+ EventId m_sendEvent;
+ EventId m_txEndEvent;
+ State m_state;
+
+ void PhyRxPacketGood (Ptr<Packet> packet, double sinr, UanTxMode mode);
+ void PhyRxPacketError (Ptr<Packet> packet, double sinr);
+ void SaveTimer (void);
+ void StartTimer (void);
+ void SendPacket (void);
+ void EndTx (void);
+protected:
+ virtual void DoDispose ();
+};
+
+}
+
+#endif // UANMACCW_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-rc-gw.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,718 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-mac-rc-gw.h"
+#include "uan-mac-rc.h"
+#include "uan-header-common.h"
+#include "uan-header-rc.h"
+#include "uan-phy.h"
+#include "uan-tx-mode.h"
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/nstime.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+
+#include <utility>
+#include <set>
+#include <map>
+#include <vector>
+#include <algorithm>
+
+NS_LOG_COMPONENT_DEFINE ("UanMacRcGw");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanMacRcGw);
+
+bool
+operator < (UanAddress &a, UanAddress &b)
+{
+ return a.GetAsInt () < b.GetAsInt ();
+}
+
+
+UanMacRcGw::UanMacRcGw ()
+ : UanMac (),
+ m_state (IDLE),
+ m_currentRateNum (0)
+{
+ UanHeaderCommon ch;
+ UanHeaderRcRts rts;
+ UanHeaderRcCts cts;
+ UanHeaderRcAck ack;
+ UanHeaderRcCtsGlobal ctsg;
+
+ m_rtsSize = ch.GetSerializedSize () + rts.GetSerializedSize ();
+ m_ctsSizeN = cts.GetSerializedSize ();
+ m_ctsSizeG = ch.GetSerializedSize () + ctsg.GetSerializedSize ();
+ m_ackSize = ch.GetSerializedSize () + ack.GetSerializedSize ();
+
+ NS_LOG_DEBUG ("Gateway initialized");
+}
+
+UanMacRcGw::~UanMacRcGw ()
+{
+}
+
+void
+UanMacRcGw::DoDispose ()
+{
+ m_propDelay.clear ();
+ std::map<UanAddress, AckData>::iterator it = m_ackData.begin ();
+ for (; it != m_ackData.end (); it++)
+ {
+ it->second.rxFrames.clear ();
+ }
+ m_ackData.clear ();
+ m_requests.clear ();
+ m_sortedRes.clear ();
+ UanMac::DoDispose ();
+}
+TypeId
+UanMacRcGw::GetTypeId (void)
+{
+ TypeId tid = TypeId ("ns3::UanMacRcGw")
+ .SetParent<UanMac> ()
+ .AddConstructor<UanMacRcGw> ()
+ .AddAttribute ("MaxReservations",
+ "Maximum number of reservations to accept per cycle",
+ UintegerValue (10),
+ MakeUintegerAccessor (&UanMacRcGw::m_maxRes),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("NumberOfRates",
+ "Number of rates per Phy layer",
+ UintegerValue (1023),
+ MakeUintegerAccessor (&UanMacRcGw::m_numRates),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("RetryRate",
+ "Number of retry rates per second at non-gateway nodes",
+ DoubleValue (1 / 10.0),
+ MakeDoubleAccessor (&UanMacRcGw::m_retryRate),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxPropDelay",
+ "Maximum propagation delay between gateway and non-gateway nodes",
+ TimeValue (Seconds (2)),
+ MakeTimeAccessor (&UanMacRcGw::m_maxDelta),
+ MakeTimeChecker ())
+ .AddAttribute ("SIFS",
+ "Spacing between frames to account for timing error and processing delay",
+ TimeValue (Seconds (0.2)),
+ MakeTimeAccessor (&UanMacRcGw::m_sifs),
+ MakeTimeChecker ())
+ .AddAttribute ("NumberOfNodes",
+ "Number of non-gateway nodes in this gateway's neighborhood",
+ UintegerValue (10),
+ MakeUintegerAccessor (&UanMacRcGw::m_numNodes),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MinRetryRate",
+ "Smallest allowed RTS retry rate",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&UanMacRcGw::m_minRetryRate),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RetryStep",
+ "Retry rate increment",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&UanMacRcGw::m_retryStep),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("NumberOfRetryRates",
+ "Number of retry rates",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UanMacRcGw::m_numRetryRates),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("TotalRate",
+ "Total available channel rate in bps (for a single channel, without splitting reservation channel)",
+ UintegerValue (4096),
+ MakeUintegerAccessor (&UanMacRcGw::m_totalRate),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("RateStep",
+ "Increments available for rate assignment in bps",
+ UintegerValue (4),
+ MakeUintegerAccessor (&UanMacRcGw::m_rateStep),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("FrameSize",
+ "Size of data frames in bytes",
+ UintegerValue (1000),
+ MakeUintegerAccessor (&UanMacRcGw::m_frameSize),
+ MakeUintegerChecker<uint32_t> ())
+ .AddTraceSource ("RX",
+ "A packet was destined for and received at this MAC layer",
+ MakeTraceSourceAccessor (&UanMacRcGw::m_rxLogger))
+ .AddTraceSource ("Cycle",
+ "Trace cycle statistics",
+ MakeTraceSourceAccessor (&UanMacRcGw::m_cycleLogger))
+
+ ;
+
+ return tid;
+}
+
+Address
+UanMacRcGw::GetAddress (void)
+{
+ return m_address;
+}
+
+void
+UanMacRcGw::SetAddress (UanAddress addr)
+{
+ m_address = addr;
+}
+
+bool
+UanMacRcGw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
+{
+ NS_LOG_WARN ("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
+ return false;
+}
+
+void
+UanMacRcGw::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
+{
+ m_forwardUpCb = cb;
+}
+
+void
+UanMacRcGw::AttachPhy (Ptr<UanPhy> phy)
+{
+ m_phy = phy;
+ phy->SetReceiveOkCallback (MakeCallback (&UanMacRcGw::ReceivePacket, this));
+ phy->SetReceiveErrorCallback (MakeCallback (&UanMacRcGw::ReceiveError, this));
+}
+
+void
+UanMacRcGw::ReceiveError (Ptr<Packet> pkt, double sinr)
+{
+}
+
+Address
+UanMacRcGw::GetBroadcast (void) const
+{
+ return UanAddress::GetBroadcast ();
+}
+
+void
+UanMacRcGw::ReceivePacket (Ptr<Packet> pkt, double sinr, UanTxMode mode)
+{
+ UanHeaderCommon ch;
+ pkt->PeekHeader (ch);
+
+ if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
+ {
+ m_rxLogger (pkt, mode);
+ }
+ else
+ {
+ return;
+ }
+
+ pkt->RemoveHeader (ch);
+
+ switch (ch.GetType ())
+ {
+ case UanMacRc::TYPE_DATA:
+ {
+ UanHeaderRcData dh;
+ pkt->RemoveHeader (dh);
+ m_propDelay[ch.GetSrc ()] = dh.GetPropDelay ();
+ if (m_ackData.find (ch.GetSrc ()) == m_ackData.end ())
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GATEWAY Received unexpected data packet");
+ }
+ else
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Received data packet from " << ch.GetSrc () << " length = " << pkt->GetSize ());
+ m_ackData[ch.GetSrc ()].rxFrames.insert (dh.GetFrameNo ());
+ }
+ m_forwardUpCb (pkt, ch.GetSrc ());
+ }
+ break;
+ case UanMacRc::TYPE_GWPING:
+ case UanMacRc::TYPE_RTS:
+ if (m_state == CTSING)
+ {
+ return;
+ }
+
+ {
+ UanHeaderRcRts rh;
+ pkt->RemoveHeader (rh);
+
+ if (m_requests.find (ch.GetSrc ()) == m_requests.end ())
+ {
+ Request req;
+ req.numFrames = rh.GetNoFrames ();
+ req.rxTime = Simulator::Now ();
+ req.frameNo = rh.GetFrameNo ();
+ req.retryNo = rh.GetRetryNo ();
+ req.length = rh.GetLength ();
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW storing reservation from " << ch.GetSrc () << " with length " << req.length);
+ m_requests.insert (std::make_pair (ch.GetSrc (), req));
+ std::map<UanAddress, Time>::iterator it = m_propDelay.find (ch.GetSrc ());
+ if (it == m_propDelay.end ())
+ {
+ m_sortedRes.insert (std::make_pair (m_maxDelta, ch.GetSrc ()));
+ }
+ else
+ {
+ m_sortedRes.insert (std::make_pair ( (*it).second, ch.GetSrc ()));
+ }
+ }
+ }
+ if (m_state == IDLE)
+ {
+ StartCycle ();
+ }
+ break;
+ case UanMacRc::TYPE_CTS:
+ NS_FATAL_ERROR ("Received CTS at GW. Currently only support single GW network!");
+ break;
+ case UanMacRc::TYPE_ACK:
+ NS_FATAL_ERROR ("Received ACK at GW. Currently only support single GW network!");
+ break;
+ default:
+ NS_FATAL_ERROR ("Received unknown packet at GW!");
+ }
+}
+
+void
+UanMacRcGw::StartCycle (void)
+{
+ uint32_t numRts = m_sortedRes.size ();
+
+ if (numRts)
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting non-empty cycle");
+ }
+ else
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Simulator starting EMPTY cycle");
+ }
+
+ // Calculate dataRate
+ uint32_t totalBytes = 0;
+ uint32_t totalFrames = 0;
+ double pDelay = 0;
+ if (numRts > 0)
+ {
+ std::map<UanAddress, Request>::iterator rit = m_requests.begin ();
+ for (; rit != m_requests.end (); rit++)
+ {
+ totalBytes += (*rit).second.length;
+ totalFrames += (*rit).second.numFrames;
+ }
+ pDelay = 2 * m_sortedRes.begin ()->first.GetSeconds ();
+ }
+
+
+ double minRate = m_phy->GetMode (m_numRates).GetDataRateBps ();
+
+ uint32_t optA = m_maxRes;
+ if (m_maxRes == 0)
+ {
+ optA = FindOptA ();
+ }
+ double thAlpha = ComputeAlpha (totalFrames, totalBytes, m_numNodes, optA, pDelay / 2.0);
+
+ double thCtlRate = m_totalRate * thAlpha;
+
+ double temprate = (thCtlRate - minRate) / ((double) m_rateStep) + 0.5;
+ m_currentRateNum = (uint32_t) temprate;
+ if (m_currentRateNum >= m_numRates)
+ {
+ m_currentRateNum = m_numRates - 1;
+ }
+
+ NS_LOG_DEBUG ("Found theoretical alpha: " << thAlpha << " Found associated rate = " << thCtlRate << " Giving rate number: " << temprate);
+ double thX = thAlpha * m_totalRate / (2.0 * m_numNodes * m_rtsSize * 8.0);
+
+ double dataRate = m_phy->GetMode (m_currentRateNum).GetDataRateBps ();
+
+
+ if (thX < m_minRetryRate)
+ {
+ NS_LOG_WARN ("Gateway found optimum RTS retry rate is below minimum");
+ m_currentRetryRate = 0;
+ }
+ else
+ {
+ m_currentRetryRate = (uint16_t)((thX - m_minRetryRate) / m_retryStep + 0.5) ;
+ }
+
+ double actualX = m_currentRetryRate * m_retryStep + m_minRetryRate;
+
+ uint32_t ctlRate = m_phy->GetMode (m_currentRateNum + m_numRates).GetDataRateBps ();
+
+
+ double winSize = (double)(totalBytes) * 8.0 / dataRate + m_sifs.GetSeconds () * totalFrames + pDelay;
+ if (numRts == 0)
+ {
+ winSize = (optA * exp (1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2 * m_maxDelta.GetSeconds ();
+ }
+ double effWinSize = winSize - m_rtsSize * 8 / ctlRate - 2 * m_maxDelta.GetSeconds ();
+
+
+ // Before fast CTS/ACK(below)
+ double cycleSeconds = winSize + (totalFrames + 1.0) * m_sifs.GetSeconds () + m_ctsSizeG * 8.0 / dataRate + (m_ctsSizeN + m_ackSize) * 8.0 * numRts / dataRate;
+
+ Time ctsTxTimeG = Seconds (m_ctsSizeG * 8.0 / dataRate);
+ Time ctsTxTimeTotal = Seconds (m_ctsSizeN * 8.0 * numRts / dataRate) + ctsTxTimeG;
+ if (numRts == 0)
+ {
+ UanHeaderRcCtsGlobal ctsg;
+ ctsg.SetWindowTime (Seconds (effWinSize));
+ ctsg.SetRateNum (m_currentRateNum);
+ ctsg.SetRetryRate (m_currentRetryRate);
+ ctsg.SetTxTimeStamp (Simulator::Now ());
+
+ UanHeaderCommon ch (m_address, UanAddress::GetBroadcast (), UanMacRc::TYPE_CTS);
+ Ptr<Packet> p = Create<Packet> ();
+ p->AddHeader (ctsg);
+ p->AddHeader (ch);
+ SendPacket (p, m_currentRateNum);
+
+
+ Simulator::Schedule (Seconds (cycleSeconds), &UanMacRcGw::StartCycle, this);
+ m_state = INCYCLE;
+ m_cycleLogger (Simulator::Now (), Seconds (0), numRts, totalBytes, effWinSize, ctlRate, actualX);
+ return;
+ }
+
+ Time nextEarliest = ctsTxTimeTotal + m_sifs;
+
+ m_state = CTSING;
+ Simulator::Schedule (nextEarliest, &UanMacRcGw::CycleStarted, this);
+
+ std::set<std::pair<Time, UanAddress> >::iterator it = m_sortedRes.begin ();
+ Time minPdelay = (*it).first;
+ Ptr<Packet> cts = Create<Packet> ();
+
+ for (; it != m_sortedRes.end (); it++)
+ {
+ Request req = m_requests[(*it).second];
+ Time pdelay = (*it).first;
+
+ AckData newData;
+ newData.expFrames = req.numFrames;
+ newData.frameNo = req.frameNo;
+ UanAddress dest = (*it).second;
+ m_ackData.insert (std::make_pair (dest, newData));
+
+ Time earliestArr = ctsTxTimeTotal + pdelay + pdelay + m_sifs;
+ Time arrivalTime = std::max (earliestArr, nextEarliest);
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Scheduling request for prop. delay " << pdelay.GetSeconds () << " for " << (*it).second << " Earliest possible arrival=" << earliestArr.GetSeconds () << " Next arrival time=" << nextEarliest.GetSeconds ());
+ nextEarliest = arrivalTime + Seconds (req.length * 8.0 / dataRate) + Seconds (m_sifs.GetSeconds () * req.numFrames);
+
+ UanHeaderRcCts ctsh;
+ ctsh.SetAddress (dest);
+ ctsh.SetRtsTimeStamp (req.rxTime);
+ ctsh.SetFrameNo (req.frameNo);
+ ctsh.SetRetryNo (req.retryNo);
+ ctsh.SetDelayToTx (arrivalTime);
+ cts->AddHeader (ctsh);
+
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Scheduling reception for " << (uint32_t) req.numFrames << " frames at " << (Simulator::Now () + arrivalTime).GetSeconds () << " (delaytiltx of " << arrivalTime.GetSeconds () << ") Total length is " << req.length << " with txtime " << req.length * 8 / dataRate << " seconds");
+ }
+
+ UanHeaderRcCtsGlobal ctsg;
+ ctsg.SetRateNum (m_currentRateNum);
+ ctsg.SetRetryRate (m_currentRetryRate);
+ ctsg.SetWindowTime (Seconds (effWinSize));
+ ctsg.SetTxTimeStamp (Simulator::Now ());
+ UanHeaderCommon ch;
+ ch.SetDest (UanAddress::GetBroadcast ());
+ ch.SetSrc (m_address);
+ ch.SetType (UanMacRc::TYPE_CTS);
+ cts->AddHeader (ctsg);
+ cts->AddHeader (ch);
+ SendPacket (cts, m_currentRateNum);
+
+ m_requests.clear ();
+ m_sortedRes.clear ();
+ Simulator::Schedule (nextEarliest, &UanMacRcGw::EndCycle, this);
+
+
+ m_cycleLogger (Simulator::Now (), minPdelay, numRts, totalBytes, cycleSeconds, ctlRate, actualX);
+}
+
+void
+UanMacRcGw::CycleStarted ()
+{
+ m_state = INCYCLE;
+}
+void
+UanMacRcGw::EndCycle ()
+{
+
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW Ending cycle");
+
+ Time nextAck = Seconds (0);
+
+ Time ackTime = Seconds (m_ackSize * 8.0 / m_phy->GetMode (m_currentRateNum).GetDataRateBps ());
+
+ std::map<UanAddress, AckData>::iterator it = m_ackData.begin ();
+ for (; it != m_ackData.end (); it++)
+ {
+ UanAddress dest = (*it).first;
+ AckData &data = (*it).second;
+
+ std::list<uint32_t> toNack;
+ for (uint32_t i = 0; i < data.expFrames; i++)
+ {
+ if (data.rxFrames.find (i) == data.rxFrames.end ())
+ {
+ toNack.push_back (i);
+ }
+ }
+ UanHeaderCommon ch;
+ ch.SetDest (dest);
+ ch.SetSrc (m_address);
+ ch.SetType (UanMacRc::TYPE_ACK);
+ UanHeaderRcAck ah;
+ ah.SetFrameNo (data.frameNo);
+ std::list<uint32_t>::iterator nit = toNack.begin ();
+ for (; nit != toNack.end (); nit++)
+ {
+ ah.AddNackedFrame (*nit);
+ }
+
+ Ptr<Packet> ack = Create<Packet> ();
+ ack->AddHeader (ah);
+ ack->AddHeader (ch);
+ Simulator::Schedule (nextAck, &UanMacRcGw::SendPacket, this, ack, m_currentRateNum);
+ nextAck = nextAck + ackTime + m_sifs;
+ }
+ m_ackData.clear ();
+ Simulator::Schedule (nextAck, &UanMacRcGw::StartCycle, this);
+
+}
+void
+UanMacRcGw::SendPacket (Ptr<Packet> pkt, uint32_t rate)
+{
+ UanHeaderCommon ch;
+ pkt->PeekHeader (ch);
+ std::string type;
+ switch (ch.GetType ())
+ {
+ case UanMacRc::TYPE_DATA:
+ type = "DATA";
+ break;
+ case UanMacRc::TYPE_RTS:
+ type = "RTS";
+ break;
+ case UanMacRc::TYPE_CTS:
+ type = "CTS";
+ break;
+ case UanMacRc::TYPE_ACK:
+ type = "ACK";
+ break;
+ case UanMacRc::TYPE_GWPING:
+ type = "GWPING";
+ break;
+ default:
+ type = "UNKNOWN";
+ break;
+ }
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW sending " << type << " packet with size " << pkt->GetSize () << " to " << ch.GetDest () << " at rate " << rate);
+ m_phy->SendPacket (pkt, rate);
+}
+
+
+double
+UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
+{
+
+ double alpha;
+ double lrae = m_rtsSize * 8.0*a*std::exp (1.0);
+ if (totalFrames == 0)
+ {
+
+ alpha = (2.0 * lrae + 8.0 * m_rtsSize - std::sqrt (m_ctsSizeG * 8.0 * 8.0 * m_rtsSize + 2 * 8.0 * m_ctsSizeG * 8.0 * m_rtsSize * a * std::exp (1.0)) ) /
+ (2 * lrae + 8.0 * m_rtsSize - 8.0 * m_ctsSizeG);
+ }
+ else
+ {
+ double w = totalBytes * 8.0 + totalFrames*m_sifs.GetSeconds () * m_totalRate;
+ double v = m_rtsSize * 8.0 + 2 * lrae;
+ double u = (2 * m_maxDelta.GetSeconds () - 2 * deltaK) * m_totalRate;
+
+ double gamma = (w - u + v) / (2 * (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
+
+ alpha = -gamma + sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
+
+ if (alpha < 0 || alpha > 1)
+ {
+ alpha = -gamma - sqrt (gamma * gamma + v / (u - totalFrames * m_sifs.GetSeconds () * m_totalRate));
+ }
+ }
+ NS_ASSERT_MSG (alpha > 0 && alpha < 1, "Error computing alpha. Alpha out of valid range!");
+ return alpha;
+}
+
+std::vector<double>
+UanMacRcGw::GetExpPdk (void)
+{
+ uint32_t n = m_numNodes;
+ std::vector<double> pds;
+ std::map<UanAddress, Time>::iterator pdit = m_propDelay.begin ();
+
+ for (; pdit != m_propDelay.end (); pdit++)
+ {
+ pds.push_back (pdit->second.GetSeconds ());
+ }
+ while (pds.size () < m_numNodes)
+ {
+ pds.push_back (m_maxDelta.GetSeconds ());
+ }
+
+ std::sort (pds.begin (), pds.end ());
+ // Find expected min. prop. delay for k nodes
+ std::vector<double> exppdk;
+ exppdk.push_back (m_maxDelta.GetSeconds ());
+ for (uint32_t k = 1; k <= n; k++)
+ {
+ uint32_t ind = CompExpMinIndex (n,k) - 1;
+ exppdk.push_back (pds[ind]);
+ }
+ return exppdk;
+}
+
+double
+UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
+{
+ UanHeaderCommon ch;
+ uint32_t lh = ch.GetSerializedSize ();
+
+ uint32_t n = m_numNodes;
+ double expk = n * (1 - std::exp (-((double) a) / (double) n));
+ NS_LOG_DEBUG ("expk = " << expk);
+
+ // Compute expected data per cycle
+ double expdata = 8 * ld * expk;
+
+ // Compute expected time per cycle
+ double alpha0 = ComputeAlpha (0,0,n,a,exppdk[0]);
+ double c0 = 8.0 * m_ctsSizeG / ( m_totalRate * (1 - alpha0)) + 2 * m_maxDelta.GetSeconds () + (a * std::exp (1.0) + 0.5) * 2 * m_rtsSize * 8.0 / (alpha0 * m_totalRate);
+ double exptime = ComputePiK (a,n,0) * c0;
+ double expp = 0;
+ for (uint32_t i = 1; i <= n; i++)
+ {
+ expp += ComputePiK (a,n,i) * exppdk[i - 1];
+ }
+
+ exptime += ComputeExpBOverA (n,a,ld + lh,exppdk) + expk * 2 * m_sifs.GetSeconds () + m_sifs.GetSeconds () + 2 * expp;
+ double s = (1.0 / m_totalRate) * expdata / exptime;
+
+ return s;
+}
+
+double
+UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
+{
+ return ComputeExpS (a, ld, GetExpPdk ());
+}
+
+uint32_t
+UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
+{
+ double sum = 0;
+ for (uint32_t i = 1; i <= n - k + 1; i++)
+ {
+ double p = (double) NchooseK (n - i, k - 1) / NchooseK (n, k);
+ sum += p * i;
+ }
+ return (uint32_t)(sum + 0.5);
+}
+
+double
+UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
+{
+ double nck = (double) NchooseK (n, k);
+ return nck * std::pow ( (std::exp ( (double) a / (double) n) - 1.0), (double) k) * std::exp (-( (double) a));
+}
+
+double
+UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
+{
+
+ double sum = 0;
+ uint32_t lt = 8.0 * (m_ctsSizeN + ldlh + m_ackSize);
+ for (uint32_t k = 1; k <= n; k++)
+ {
+ double num = 8.0 * m_ctsSizeG + k * lt;
+ double denom = (1.0 - ComputeAlpha (k, k * ldlh, n, a, deltaK[k])) * m_totalRate;
+ double pik = ComputePiK (a, n, k);
+ double term = pik * num / denom;
+
+ sum += term;
+ }
+
+ return sum;
+}
+
+uint64_t
+UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
+{
+ if (k > n)
+ {
+ return 0;
+ }
+
+ if (k > n / 2)
+ {
+ k = n - k;
+ }
+
+ double accum = 1;
+ for (uint32_t i = 1; i <= k; i++)
+ {
+ accum = accum * (n - k + i) / i;
+ }
+
+ return (uint64_t)(accum + 0.5);
+
+}
+
+uint32_t
+UanMacRcGw::FindOptA (void)
+{
+ double tput = 0;
+ uint32_t a = 1;
+ while (1)
+ {
+
+ double newtput = ComputeExpS (a, m_frameSize);
+ if (newtput < tput)
+ {
+ a--;
+ break;
+ }
+ else
+ {
+ tput = newtput;
+ a++;
+ }
+ }
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " GW: Found optimum a = " << a);
+ return a;
+}
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-rc-gw.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANMACRCGW_H
+#define UANMACRCGW_H
+
+#include "uan-mac.h"
+#include "uan-address.h"
+
+#include "ns3/nstime.h"
+#include "ns3/traced-callback.h"
+
+
+
+
+#include <set>
+#include <map>
+
+namespace ns3 {
+
+class UanTxMode;
+
+/**
+ * \class UanMacRcGw
+ *
+ * \brief Gateway side of RC-MAC
+ *
+ *
+ *
+ * This MAC protocol assumes a network topology where all traffic
+ * is destined for a set of GW nodes which are connected via
+ * some out of band (RF?) means. UanMacRcGw is the protocol
+ * which runs on the gateway nodes.
+ *
+ * This particular implementation
+ * assumes that there is only a single gateway.
+ *
+ * For more information on class operation email
+ * lentracy@u.washington.edu
+ * (This work is, as of yet, unpublished)
+ */
+
+class UanMacRcGw : public ns3::UanMac
+{
+public:
+ UanMacRcGw ();
+ virtual ~UanMacRcGw ();
+
+ static TypeId GetTypeId (void);
+
+ // Inherited virtual functions
+ virtual Address GetAddress (void);
+ virtual void SetAddress (UanAddress addr);
+ virtual bool Enqueue (Ptr<Packet> pkt, const Address &dest, uint16_t protocolNumber);
+ virtual void SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb);
+ virtual void AttachPhy (Ptr<UanPhy> phy);
+ virtual Address GetBroadcast (void) const;
+
+private:
+ enum State {
+ IDLE, INCYCLE, CTSING
+ };
+ State m_state;
+
+ struct Request
+ {
+ uint8_t numFrames;
+ uint8_t frameNo;
+ uint8_t retryNo;
+ uint16_t length;
+ Time rxTime;
+ };
+
+ struct AckData
+ {
+ uint8_t frameNo;
+ std::set<uint8_t> rxFrames;
+ uint8_t expFrames;
+ };
+ Callback<void, Ptr<Packet>, const UanAddress& > m_forwardUpCb;
+ Ptr<UanPhy> m_phy;
+ UanAddress m_address;
+ Time m_maxDelta;
+ Time m_sifs;
+ uint32_t m_maxRes;
+ uint32_t m_numRates;
+ uint32_t m_rtsSize;
+ uint32_t m_ctsSizeN;
+ uint32_t m_ctsSizeG;
+ uint32_t m_ackSize;
+ double m_retryRate;
+ uint16_t m_currentRetryRate;
+ uint32_t m_currentRateNum;
+ uint32_t m_numNodes;
+ uint32_t m_totalRate;
+ uint32_t m_rateStep;
+ uint32_t m_frameSize;
+
+ uint16_t m_numRetryRates;
+ double m_minRetryRate;
+ double m_retryStep;
+
+ std::map<UanAddress, Time> m_propDelay;
+
+ std::map<UanAddress, AckData> m_ackData;
+
+
+ std::map<UanAddress, Request> m_requests;
+ std::set<std::pair<Time, UanAddress> > m_sortedRes;
+
+ TracedCallback<Ptr<const Packet>, UanTxMode > m_rxLogger;
+
+ // Start time, min p-delay, reservations, frames, bytes, window size, ctl rate, retry rate
+ TracedCallback<Time, Time, uint32_t, uint32_t, double, uint32_t, double> m_cycleLogger;
+
+ void ReceivePacket (Ptr<Packet> pkt, double sinr, UanTxMode mode);
+ void StartCycle (void);
+ void EndCycle (void);
+ void SendPacket (Ptr<Packet> pkt, uint32_t rate);
+ void CycleStarted (void);
+ void ReceiveError (Ptr<Packet> pkt, double sinr);
+
+ // Stuff for computing exp throughput
+ double ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK);
+ std::vector<double> GetExpPdk (void);
+ double ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk);
+ double ComputeExpS (uint32_t a, uint32_t ld);
+ uint32_t CompExpMinIndex (uint32_t n, uint32_t k);
+ double ComputePiK (uint32_t a, uint32_t n, uint32_t k);
+ double ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK);
+ uint64_t NchooseK (uint32_t n, uint32_t k);
+ uint32_t FindOptA (void);
+protected:
+ virtual void DoDispose ();
+
+};
+
+/**
+ * \brief Defined for use in UanMacRcGw
+ * \param a Address to compare
+ * \param b Address to compare
+ */
+bool operator < (UanAddress &a, UanAddress &b);
+
+}
+
+#endif // UANMACRCGW_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-rc.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,757 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-mac-rc.h"
+#include "uan-header-rc.h"
+#include "uan-tx-mode.h"
+#include "uan-phy.h"
+#include "uan-header-common.h"
+#include "uan-phy-dual.h"
+
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/random-variable.h"
+#include "ns3/assert.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+
+#include <list>
+#include <utility>
+
+
+
+NS_LOG_COMPONENT_DEFINE ("UanMacRc");
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanMacRc);
+
+Reservation::Reservation ()
+ : m_length (0),
+ m_frameNo (0),
+ m_retryNo (0),
+ m_transmitted (false)
+{
+
+}
+
+Reservation::Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts)
+ : m_frameNo (frameNo),
+ m_retryNo (0),
+ m_transmitted (false)
+{
+ uint32_t numPkts = (maxPkts) ? maxPkts : list.size ();
+ uint32_t length = 0;
+ UanHeaderRcData dh;
+ UanHeaderCommon ch;
+
+ for (uint32_t i = 0; i < numPkts; i++)
+ {
+ length += list.front ().first->GetSize () +
+ ch.GetSerializedSize () +
+ dh.GetSerializedSize ();
+ m_pktList.push_back (list.front ());
+ list.pop_front ();
+ }
+ m_length = length;
+}
+
+Reservation::~Reservation ()
+{
+ std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
+ for (it = m_pktList.begin (); it != m_pktList.end (); it++)
+ {
+ it->first = Ptr<Packet> ((Packet *) 0);
+ }
+ m_pktList.clear ();
+ m_timestamp.clear ();
+}
+uint32_t
+Reservation::GetNoFrames () const
+{
+ return m_pktList.size ();
+}
+
+uint32_t
+Reservation::GetLength () const
+{
+ return m_length;
+}
+
+const std::list<std::pair <Ptr<Packet>, UanAddress > > &
+Reservation::GetPktList (void) const
+{
+ return m_pktList;
+}
+
+uint8_t
+Reservation::GetFrameNo () const
+{
+ return m_frameNo;
+}
+
+uint8_t
+Reservation::GetRetryNo () const
+{
+ return m_retryNo;
+}
+
+Time
+Reservation::GetTimestamp (uint8_t n) const
+{
+ return m_timestamp[n];
+}
+
+bool
+Reservation::IsTransmitted () const
+{
+ return m_transmitted;
+}
+
+void
+Reservation::SetFrameNo (uint8_t fn)
+{
+ m_frameNo = fn;
+}
+
+void
+Reservation::AddTimestamp (Time t)
+{
+ m_timestamp.push_back (t);
+}
+
+void
+Reservation::IncrementRetry ()
+{
+ m_retryNo++;
+}
+
+void
+Reservation::SetTransmitted (bool t)
+{
+ m_transmitted = true;
+}
+
+uint32_t UanMacRc::m_cntrlSends = 0;
+
+UanMacRc::UanMacRc ()
+ : UanMac (),
+ m_state (UNASSOCIATED),
+ m_rtsBlocked (false),
+ m_currentRate (10),
+ m_frameNo (0)
+{
+ UanHeaderCommon ch;
+ UanHeaderRcCts ctsh;
+ UanHeaderRcCtsGlobal ctsg;
+
+ m_ctsSizeN = ctsh.GetSerializedSize ();
+ m_ctsSizeG = ch.GetSerializedSize () + ctsg.GetSerializedSize ();
+}
+
+UanMacRc::~UanMacRc ()
+{
+}
+
+void
+UanMacRc::DoDispose ()
+{
+ m_phy = 0;
+ std::list<std::pair <Ptr<Packet>, UanAddress > >::iterator it;
+ for (it = m_pktQueue.begin (); it != m_pktQueue.end (); it++)
+ {
+ it->first = 0;
+ }
+ m_pktQueue.clear ();
+ m_resList.clear ();
+ m_startAgain.Cancel ();
+ m_rtsEvent.Cancel ();
+
+ UanMac::DoDispose ();
+}
+
+TypeId
+UanMacRc::GetTypeId (void)
+{
+ TypeId tid = TypeId ("ns3::UanMacRc")
+ .SetParent<UanMac> ()
+ .AddConstructor<UanMacRc> ()
+ .AddAttribute ("RetryRate",
+ "Number of retry attempts per second (of RTS/GWPING)",
+ DoubleValue (1 / 5.0),
+ MakeDoubleAccessor (&UanMacRc::m_retryRate),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxFrames",
+ "Maximum number of frames to include in a single RTS",
+ UintegerValue (1),
+ MakeUintegerAccessor (&UanMacRc::m_maxFrames),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("QueueLimit",
+ "Maximum packets to queue at MAC",
+ UintegerValue (10),
+ MakeUintegerAccessor (&UanMacRc::m_queueLimit),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("SIFS",
+ "Spacing to give between frames (this should match gateway)",
+ TimeValue (Seconds (0.2)),
+ MakeTimeAccessor (&UanMacRc::m_sifs),
+ MakeTimeChecker ())
+ .AddAttribute ("NumberOfRates",
+ "Number of rate divisions supported by each PHY",
+ UintegerValue (0),
+ MakeUintegerAccessor (&UanMacRc::m_numRates),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MinRetryRate",
+ "Smallest allowed RTS retry rate",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&UanMacRc::m_minRetryRate),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RetryStep",
+ "Retry rate increment",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&UanMacRc::m_retryStep),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("NumberOfRetryRates",
+ "Number of retry rates",
+ UintegerValue (100),
+ MakeUintegerAccessor (&UanMacRc::m_numRetryRates),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("MaxPropDelay",
+ "Maximum possible propagation delay to gateway",
+ TimeValue (Seconds (2)),
+ MakeTimeAccessor (&UanMacRc::m_learnedProp),
+ MakeTimeChecker ())
+ .AddTraceSource ("Enqueue",
+ "A (data) packet arrived at MAC for transmission",
+ MakeTraceSourceAccessor (&UanMacRc::m_enqueueLogger))
+ .AddTraceSource ("Dequeue",
+ "A (data) packet was passed down to PHY from MAC",
+ MakeTraceSourceAccessor (&UanMacRc::m_dequeueLogger))
+ .AddTraceSource ("RX",
+ "A packet was destined for and received at this MAC layer",
+ MakeTraceSourceAccessor (&UanMacRc::m_rxLogger))
+ ;
+ return tid;
+}
+
+
+Address
+UanMacRc::GetAddress (void)
+{
+ return m_address;
+}
+
+void
+UanMacRc::SetAddress (UanAddress addr)
+{
+ m_address = addr;
+}
+
+bool
+UanMacRc::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
+{
+ if (protocolNumber > 0)
+ {
+ NS_LOG_WARN ("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
+ }
+
+
+ if (m_pktQueue.size () >= m_queueLimit)
+ {
+ return false;
+ }
+
+ m_pktQueue.push_back (std::make_pair (packet, UanAddress::ConvertFrom (dest)));
+
+ switch (m_state)
+ {
+ case UNASSOCIATED:
+ Associate ();
+ return true;
+ case IDLE:
+ if (!m_rtsEvent.IsRunning ())
+ {
+ SendRts ();
+ }
+ return true;
+ case GWPSENT:
+ case RTSSENT:
+ case DATATX:
+ return true;
+ }
+
+ return true;
+}
+
+void
+UanMacRc::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
+{
+ m_forwardUpCb = cb;
+}
+
+void
+UanMacRc::AttachPhy (Ptr<UanPhy> phy)
+{
+ m_phy = phy;
+ m_phy->SetReceiveOkCallback (MakeCallback (&UanMacRc::ReceiveOkFromPhy, this));
+}
+
+Address
+UanMacRc::GetBroadcast (void) const
+{
+ return UanAddress::GetBroadcast ();
+}
+
+void
+UanMacRc::ReceiveOkFromPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
+{
+
+ UanHeaderCommon ch;
+ pkt->RemoveHeader (ch);
+ if (ch.GetDest () == m_address || ch.GetDest () == UanAddress::GetBroadcast ())
+ {
+ m_rxLogger (pkt, mode);
+ }
+
+ switch (ch.GetType ())
+ {
+ case TYPE_DATA:
+
+ if (ch.GetDest () == m_address)
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
+ UanHeaderRcData dh;
+ pkt->RemoveHeader (dh);
+ m_forwardUpCb (pkt, ch.GetSrc ());
+ }
+ break;
+ case TYPE_RTS:
+ // Currently don't respond to RTS packets at non-gateway nodes
+ // (Code assumes single network neighberhood)
+ break;
+ case TYPE_CTS:
+ {
+ uint32_t ctsBytes = ch.GetSerializedSize () + pkt->GetSize ();
+ m_assocAddr = ch.GetSrc ();
+ UanHeaderRcCtsGlobal ctsg;
+ pkt->RemoveHeader (ctsg);
+ m_currentRate = ctsg.GetRateNum ();
+ m_retryRate = m_minRetryRate + m_retryStep*ctsg.GetRetryRate ();
+
+ UanHeaderRcRts rhtmp;
+
+ Time winDelay = ctsg.GetWindowTime ();
+
+ if (winDelay.GetSeconds () > 0)
+ {
+ m_rtsBlocked = false;
+ Simulator::Schedule (winDelay, &UanMacRc::BlockRtsing, this);
+ }
+ else
+ {
+ NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received window period < 0");
+ }
+
+ UanHeaderRcCts ctsh;
+ ctsh.SetAddress (UanAddress::GetBroadcast ());
+ while (pkt->GetSize () > 0)
+ {
+ pkt->RemoveHeader (ctsh);
+ if (ctsh.GetAddress () == m_address)
+ {
+ if (m_state == GWPSENT)
+ {
+ m_assocAddr = ch.GetSrc ();
+ ScheduleData (ctsh, ctsg, ctsBytes);
+ }
+ else if (m_state == RTSSENT)
+ {
+ ScheduleData (ctsh, ctsg, ctsBytes);
+ }
+ else
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
+ }
+ }
+ }
+ }
+ break;
+ case TYPE_GWPING:
+ // Do not respond to GWPINGS at non-gateway nodes
+ break;
+ case TYPE_ACK:
+ m_rtsBlocked = true;
+ if (ch.GetDest () != m_address)
+ {
+ return;
+ }
+ ProcessAck (pkt);
+ break;
+ default:
+ NS_FATAL_ERROR ("Unknown packet type " << ch.GetType () << " received at node " << GetAddress ());
+ }
+
+}
+
+void
+UanMacRc::ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes)
+{
+ NS_ASSERT (m_state == RTSSENT || m_state == GWPSENT);
+
+
+
+ std::list<Reservation>::iterator it = m_resList.begin ();
+ for (; it != m_resList.end (); it++)
+ {
+ if (it->GetFrameNo () == ctsh.GetFrameNo ())
+ {
+ break;
+ }
+ }
+ if (it == m_resList.end ())
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet with no corresponding reservation!");
+ return;
+ }
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received CTS packet. Scheduling data");
+ it->SetTransmitted ();
+
+ double currentBps = m_phy->GetMode (m_currentRate).GetDataRateBps ();
+
+ m_learnedProp = Simulator::Now () - ctsg.GetTxTimeStamp () - Seconds (ctsBytes * 8.0 / currentBps);
+
+
+ Time arrTime = ctsg.GetTxTimeStamp () + ctsh.GetDelayToTx ();
+ Time txTime = arrTime - m_learnedProp;
+
+ Time startDelay = txTime - Simulator::Now ();
+
+ Time frameDelay = Seconds (0);
+
+ const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
+ std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
+ pit = l.begin ();
+
+
+
+ for (uint32_t i = 0; i < it->GetNoFrames (); i++, pit++)
+ {
+ Ptr<Packet> pkt = (*pit).first->Copy ();
+
+ UanHeaderRcData dh;
+ dh.SetFrameNo (i);
+ dh.SetPropDelay (m_learnedProp);
+ pkt->AddHeader (dh);
+
+ UanHeaderCommon ch;
+ ch.SetType (TYPE_DATA);
+ ch.SetDest (m_assocAddr);
+ ch.SetSrc (m_address);
+
+ pkt->AddHeader (ch);
+ Time eventTime = startDelay + frameDelay;
+ if (eventTime.GetSeconds () < 0)
+ {
+ if (eventTime.GetSeconds () > -0.001)
+ {
+ eventTime = Seconds (0);
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds ());
+ }
+ }
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " scheduling with delay " << eventTime.GetSeconds () << " propDelay " << m_learnedProp.GetSeconds () << " start delay " << startDelay.GetSeconds () << " arrival time " << arrTime.GetSeconds ());
+ Simulator::Schedule (eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
+ frameDelay = frameDelay + m_sifs + Seconds (pkt->GetSize () / currentBps);
+ }
+
+ m_state = IDLE;
+ if (!m_pktQueue.empty ())
+ {
+
+ if (m_rtsEvent.IsRunning ())
+ {
+ m_rtsEvent.Cancel ();
+ }
+ ExponentialVariable ev (1 / m_retryRate);
+ double timeout = ev.GetValue ();
+ m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::SendRts, this);
+ }
+
+}
+
+void
+UanMacRc::SendPacket (Ptr<Packet> pkt, uint32_t rate)
+{
+ UanHeaderCommon ch;
+ pkt->PeekHeader (ch);
+ std::string type;
+ switch (ch.GetType ())
+ {
+ case TYPE_DATA:
+ type = "DATA";
+ break;
+ case TYPE_RTS:
+ type = "RTS";
+ break;
+ case TYPE_CTS:
+ type = "CTS";
+ break;
+ case TYPE_ACK:
+ type = "ACK";
+ break;
+ case TYPE_GWPING:
+ type = "GWPING";
+ break;
+ default:
+ type = "UNKNOWN";
+ break;
+ }
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " transmitting " << pkt->GetSize () << " byte packet of type " << type << " with rate " << rate << "(" << m_phy->GetMode (rate).GetDataRateBps () << ") to " << ch.GetDest ());
+ m_dequeueLogger (pkt, rate);
+ m_phy->SendPacket (pkt, rate);
+}
+
+void
+UanMacRc::ProcessAck (Ptr<Packet> ack)
+{
+ UanHeaderRcAck ah;
+ ack->RemoveHeader (ah);
+
+ std::list<Reservation>::iterator it = m_resList.begin ();
+ for (; it != m_resList.end (); it++)
+ {
+ if (it->GetFrameNo () == ah.GetFrameNo ())
+ {
+ break;
+ }
+ }
+ if (it == m_resList.end ())
+ {
+ NS_LOG_DEBUG ("In " << __func__ << " could not find reservation corresponding to received ACK");
+ return;
+ }
+ if (!it->IsTransmitted ())
+ {
+ return;
+ }
+ if (ah.GetNoNacks () > 0)
+ {
+ const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList ();
+ std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
+ pit = l.begin ();
+
+ const std::set<uint8_t> &nacks = ah.GetNackedFrames ();
+ std::set<uint8_t>::iterator nit = nacks.begin ();
+ uint8_t pnum = 0;
+ for (; nit != nacks.end (); nit++)
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " Received NACK for " << (uint32_t) *nit);
+ while (pnum < *nit)
+ {
+ pit++;
+ pnum++;
+ }
+ UanHeaderRcData dh;
+ UanHeaderCommon ch;
+ m_pktQueue.push_front (*pit);
+ }
+ }
+ else
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Node " << m_address << " received ACK for all frames");
+ }
+ m_resList.erase (it);
+}
+
+UanHeaderRcRts
+UanMacRc::CreateRtsHeader (const Reservation &res)
+{
+ UanHeaderRcRts rh = UanHeaderRcRts ();
+
+ rh.SetLength (res.GetLength ());
+ rh.SetNoFrames (res.GetNoFrames ());
+ rh.SetTimeStamp (res.GetTimestamp (res.GetRetryNo ()));
+ rh.SetFrameNo (res.GetFrameNo ());
+ rh.SetRetryNo (res.GetRetryNo ());
+ return rh;
+}
+
+void
+UanMacRc::Associate (void)
+{
+ m_cntrlSends++;
+
+ Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
+ res.AddTimestamp (Simulator::Now ());
+ m_frameNo++;
+ m_resList.push_back (res);
+ Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
+ bool phy1ok = IsPhy1Ok ();
+ if (phy1ok && !phyDual->IsPhy2Tx () & !m_rtsBlocked)
+ {
+ Ptr<Packet> pkt = Create<Packet> (0);
+ pkt->AddHeader (CreateRtsHeader (res));
+ pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending first GWPING " << *pkt);
+ SendPacket (pkt,m_currentRate + m_numRates);
+ }
+ m_state = GWPSENT;
+ NS_ASSERT (!m_rtsEvent.IsRunning ());
+ ExponentialVariable ev (1.0 / m_retryRate);
+ double timeout = ev.GetValue ();
+ m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
+}
+
+void
+UanMacRc::AssociateTimeout ()
+{
+ m_cntrlSends++;
+ if (m_state != GWPSENT)
+ {
+ return;
+ }
+ Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
+ bool phy1ok = IsPhy1Ok ();
+ if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
+ {
+ Ptr<Packet> pkt = Create<Packet> ();
+
+ Reservation res = m_resList.back ();
+ m_resList.pop_back ();
+ res.AddTimestamp (Simulator::Now ());
+ res.IncrementRetry ();
+
+ pkt->AddHeader (CreateRtsHeader (res));
+ pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_GWPING));
+
+ SendPacket (pkt,m_currentRate + m_numRates);
+ m_resList.push_back (res);
+ }
+ NS_ASSERT (!m_rtsEvent.IsRunning ());
+ ExponentialVariable ev (1.0 / m_retryRate);
+ double timeout = ev.GetValue ();
+ m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::AssociateTimeout, this);
+}
+
+
+void
+UanMacRc::SendRts (void)
+{
+ m_cntrlSends++;
+ if (m_state == RTSSENT)
+ {
+ return;
+ }
+
+ NS_ASSERT (!m_pktQueue.empty ());
+
+ Reservation res (m_pktQueue, m_frameNo, m_maxFrames);
+ res.AddTimestamp (Simulator::Now ());
+ m_frameNo++;
+ m_resList.push_back (res);
+ Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
+ bool phy1ok = IsPhy1Ok ();
+ if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked )
+ {
+ Ptr<Packet> pkt = Create<Packet> (0);
+ pkt->AddHeader (CreateRtsHeader (res));
+ pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
+ SendPacket (pkt,m_currentRate + m_numRates);
+ }
+ m_state = RTSSENT;
+ NS_ASSERT (!m_rtsEvent.IsRunning ());
+ ExponentialVariable ev (1.0 / m_retryRate);
+ double timeout = ev.GetValue ();
+ m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
+
+}
+
+// We assume here that packet types are known at detection.
+bool
+UanMacRc::IsPhy1Ok ()
+{
+ Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
+
+ bool phy1ok = true;
+ if (phyDual->IsPhy1Rx ())
+ {
+ Ptr<Packet> pkt = phyDual->GetPhy1PacketRx ();
+ UanHeaderCommon ch;
+ pkt->PeekHeader (ch);
+ if (ch.GetType () == TYPE_CTS || ch.GetType () == TYPE_ACK)
+ {
+ phy1ok = false;
+ }
+ else if (ch.GetDest () == m_address)
+ {
+ phy1ok = false;
+ }
+ }
+ return phy1ok;
+}
+
+void
+UanMacRc::RtsTimeout (void)
+{
+ m_cntrlSends++;
+
+ if (m_state != RTSSENT)
+ {
+ return;
+ }
+ Ptr<UanPhyDual> phyDual = m_phy->GetObject<UanPhyDual> ();
+
+ bool phy1ok = IsPhy1Ok ();
+ if (phy1ok && !phyDual->IsPhy2Tx () && !m_rtsBlocked)
+ {
+
+ if (m_resList.empty ())
+ {
+ NS_FATAL_ERROR (Simulator::Now ().GetSeconds () << " Node " << m_address << " tried to retry RTS with empty reservation list");
+ }
+ Ptr<Packet> pkt = Create<Packet> (0);
+
+ Reservation res = m_resList.back ();
+ NS_ASSERT (!res.IsTransmitted ());
+ m_resList.pop_back ();
+ res.AddTimestamp (Simulator::Now ());
+ res.IncrementRetry ();
+ m_resList.push_back (res);
+ pkt->AddHeader (CreateRtsHeader (res));
+ pkt->AddHeader (UanHeaderCommon (m_address, UanAddress::GetBroadcast (), (uint8_t) TYPE_RTS));
+ SendPacket (pkt,m_currentRate + m_numRates);
+
+ }
+ m_state = RTSSENT;
+ NS_ASSERT (!m_rtsEvent.IsRunning ());
+ ExponentialVariable ev (1.0 / m_retryRate);
+ double timeout = ev.GetValue ();
+ m_rtsEvent = Simulator::Schedule (Seconds (timeout), &UanMacRc::RtsTimeout, this);
+}
+
+void
+UanMacRc::BlockRtsing (void)
+{
+ m_rtsBlocked = true;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac-rc.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANMACRC_H
+#define UANMACRC_H
+
+#include "uan-mac.h"
+#include "uan-address.h"
+
+#include "ns3/nstime.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/traced-callback.h"
+#include "ns3/event-id.h"
+
+#include <list>
+#include <utility>
+#include <vector>
+
+
+namespace ns3 {
+
+class Address;
+class UanTxMode;
+class UanHeaderRcRts;
+class UanHeaderRcCts;
+class UanHeaderRcCtsGlobal;
+class UanPhy;
+
+
+/**
+ * \class Reservation
+ * \brief Stores reservation info for use in scheduling data channel by reservation channel MAC
+ */
+class Reservation
+{
+public:
+ /**
+ * \brief Create empty object with default values
+ */
+ Reservation ();
+ /**
+ * \brief Create Reservation object with given packet list, frame number and max packets
+ * \param list List of packets for assigned to reservation
+ * \param frameNo Frame number of reservation transmission
+ * \param maxPkts Maximum number of packets to assign to reservation from packet list (0 = no maximum)
+ */
+ Reservation (std::list<std::pair <Ptr<Packet>, UanAddress > > &list, uint8_t frameNo, uint32_t maxPkts = 0);
+ ~Reservation ();
+ /**
+ * \returns number of frames in reservation
+ */
+ uint32_t GetNoFrames () const;
+ /**
+ * \returns total byte length of reservation (sum of all packets with headers)
+ */
+ uint32_t GetLength () const;
+ /**
+ * \returns reference to list of packets in this reservation
+ */
+ const std::list<std::pair <Ptr<Packet>, UanAddress > > &GetPktList (void) const;
+ /**
+ * \returns Frame number of reservation
+ */
+ uint8_t GetFrameNo () const;
+ /**
+ * \returns Retry number of reservation
+ */
+ uint8_t GetRetryNo () const;
+ /**
+ * \returns Timestamp nth RTS send for this reservation
+ * \param n Timestamp for retry number n to return
+ */
+ Time GetTimestamp (uint8_t n) const;
+ /**
+ * \returns True if reservation packets have been transmitted
+ */
+ bool IsTransmitted () const;
+ /**
+ * \param fn Frame number to set reservation to
+ */
+ void SetFrameNo (uint8_t fn);
+ /**
+ * \param t Time of latest RTS send
+ */
+ void AddTimestamp (Time t);
+ /**
+ * \brief Increments retry count by 1
+ */
+ void IncrementRetry ();
+ /**
+ * \param t True if resevation has been transmitted
+ * \brief Sets reservation transmitted state
+ */
+ void SetTransmitted (bool t = true);
+private:
+ std::list<std::pair <Ptr<Packet>, UanAddress > > m_pktList;
+ uint32_t m_length;
+ uint8_t m_frameNo;
+ std::vector<Time> m_timestamp;
+ uint8_t m_retryNo;
+ bool m_transmitted;
+
+};
+
+
+/**
+ * \class UanMacRc
+ * \brief Non-gateway node MAC for reservation channel MAC protocol
+ *
+ * This MAC protocol assumes a network topology where all traffic
+ * is destined for a set of GW nodes which are connected via
+ * some out of band (RF?) means. This particular implementation
+ * assumes that there is only a single gateway.
+ *
+ * For more information on class operation email
+ * lentracy@u.washington.edu
+ * (This work is, as of yet, unpublished)
+ */
+class UanMacRc : public ns3::UanMac
+{
+public:
+ enum {
+ TYPE_DATA, TYPE_GWPING, TYPE_RTS, TYPE_CTS, TYPE_ACK
+ };
+ UanMacRc ();
+ virtual ~UanMacRc ();
+
+ static TypeId GetTypeId (void);
+
+ // Inherited virtual functions
+ virtual Address GetAddress (void);
+ virtual void SetAddress (UanAddress addr);
+ virtual bool Enqueue (Ptr<Packet> pkt, const Address &dest, uint16_t protocolNumber);
+ virtual void SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb);
+ virtual void AttachPhy (Ptr<UanPhy> phy);
+ virtual Address GetBroadcast (void) const;
+
+private:
+ enum State {
+ UNASSOCIATED, GWPSENT, IDLE, RTSSENT, DATATX
+ };
+
+ State m_state;
+ bool m_rtsBlocked;
+
+ EventId m_startAgain;
+ UanAddress m_address;
+ double m_retryRate;
+ UanAddress m_assocAddr;
+ Ptr<UanPhy> m_phy;
+ uint32_t m_numRates;
+ uint32_t m_currentRate;
+ uint32_t m_maxFrames;
+ uint32_t m_queueLimit;
+ uint8_t m_frameNo;
+ Time m_sifs;
+ Time m_learnedProp;
+
+ uint16_t m_numRetryRates;
+ double m_minRetryRate;
+ double m_retryStep;
+
+ uint32_t m_ctsSizeN;
+ uint32_t m_ctsSizeG;
+
+ std::list<std::pair <Ptr<Packet>, UanAddress > > m_pktQueue;
+ std::list<Reservation> m_resList;
+
+ Callback<void, Ptr<Packet>, const UanAddress& > m_forwardUpCb;
+
+ TracedCallback<Ptr<const Packet>, UanTxMode > m_rxLogger;
+ TracedCallback<Ptr<const Packet>, uint16_t > m_enqueueLogger;
+ TracedCallback<Ptr<const Packet>, uint16_t > m_dequeueLogger;
+
+ EventId m_rtsEvent;
+ void ReceiveOkFromPhy (Ptr<Packet>, double sinr, UanTxMode mode);
+
+ void Associate (void);
+ void AssociateTimeout (void);
+ void SendRts (void);
+ void RtsTimeout (void);
+ UanHeaderRcRts CreateRtsHeader (const Reservation &res);
+ void ScheduleData (const UanHeaderRcCts &ctsh, const UanHeaderRcCtsGlobal &ctsg, uint32_t ctsBytes);
+ void ProcessAck (Ptr<Packet> ack);
+ void SendPacket (Ptr<Packet> pkt, uint32_t rate);
+ bool IsPhy1Ok (void);
+ void BlockRtsing (void);
+
+ static uint32_t m_cntrlSends;
+
+protected:
+ void DoDispose ();
+};
+
+}
+
+#endif // UANMACRC_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-mac.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANMAC_H
+#define UANMAC_H
+
+#include "ns3/address.h"
+#include "ns3/object.h"
+#include "ns3/packet.h"
+
+#include "ns3/address.h"
+#include "ns3/nstime.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class UanPhy;
+class UanChannel;
+class UanNetDevice;
+class UanTransducer;
+class UanAddress;
+
+
+
+/**
+ * \class UanMac
+ *
+ * \brief Virtual base class for all UAN MAC protocols
+ */
+class UanMac : public Object
+{
+public:
+ /**
+ * \returns MAC Address
+ */
+ virtual Address GetAddress (void) = 0;
+
+ /**
+ * \param addr UanAddress for this MAC
+ */
+ virtual void SetAddress (UanAddress addr) = 0;
+
+ /**
+ * Enqueue packet to be transmitted
+ * \param pkt Packet to be transmitted
+ * \param dest Destination address
+ * \param protocolNumber Protocol #. Usage varies by MAC
+ */
+ virtual bool Enqueue (Ptr<Packet> pkt, const Address &dest, uint16_t protocolNumber) = 0;
+ /**
+ * \param cb Callback to be called when a packet is forwarded up to higher layer
+ */
+ virtual void SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb) = 0;
+
+ /**
+ * Attach PHY layer to this MAC.
+ * Some MACs may be designed to work with multiple PHY
+ * layers. Others may only work with one.
+ *
+ * \param phy Phy layer to attach to this MAC
+ *
+ */
+ virtual void AttachPhy (Ptr<UanPhy> phy) = 0;
+
+ /**
+ * \returns Broadcast address
+ */
+ virtual Address GetBroadcast (void) const = 0;
+
+};
+
+}
+
+#endif // UANMAC_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-net-device.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,365 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "ns3/trace-source-accessor.h"
+#include "ns3/traced-callback.h"
+#include "ns3/pointer.h"
+#include "ns3/node.h"
+#include "ns3/assert.h"
+#include "uan-net-device.h"
+#include "uan-phy.h"
+#include "uan-mac.h"
+#include "uan-channel.h"
+#include "uan-transducer.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("UanNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanNetDevice);
+
+UanNetDevice::UanNetDevice ()
+ : NetDevice (),
+ m_mtu (64000)
+{
+}
+
+UanNetDevice::~UanNetDevice ()
+{
+}
+
+void
+UanNetDevice::DoDispose ()
+{
+ m_node = 0;
+ m_channel = 0;
+ m_mac = 0;
+ m_phy = 0;
+ m_trans = 0;
+ NetDevice::DoDispose ();
+}
+
+TypeId
+UanNetDevice::GetTypeId ()
+{
+
+
+ static TypeId tid = TypeId ("ns3::UanNetDevice")
+ .SetParent<NetDevice> ()
+ .AddAttribute ("Channel", "The channel attached to this device",
+ PointerValue (),
+ MakePointerAccessor (&UanNetDevice::DoGetChannel, &UanNetDevice::SetChannel),
+ MakePointerChecker<UanChannel> ())
+ .AddAttribute ("Phy", "The PHY layer attached to this device.",
+ PointerValue (),
+ MakePointerAccessor (&UanNetDevice::GetPhy, &UanNetDevice::SetPhy),
+ MakePointerChecker<UanPhy> ())
+ .AddAttribute ("Mac", "The MAC layer attached to this device.",
+ PointerValue (),
+ MakePointerAccessor (&UanNetDevice::GetMac, &UanNetDevice::SetMac),
+ MakePointerChecker<UanMac> ())
+ .AddAttribute ("Transducer", "The Transducer attached to this device.",
+ PointerValue (),
+ MakePointerAccessor (&UanNetDevice::GetTransducer,
+ &UanNetDevice::SetTransducer),
+ MakePointerChecker<UanTransducer> ())
+ .AddTraceSource ("Rx", "Received payload from the MAC layer.",
+ MakeTraceSourceAccessor (&UanNetDevice::m_rxLogger))
+ .AddTraceSource ("Tx", "Send payload to the MAC layer.",
+ MakeTraceSourceAccessor (&UanNetDevice::m_txLogger))
+ ;
+ return tid;
+}
+
+void
+UanNetDevice::SetMac (Ptr<UanMac> mac)
+{
+ if (mac != 0)
+ {
+ m_mac = mac;
+ NS_LOG_DEBUG ("Set MAC");
+
+ if (m_phy != 0)
+ {
+ m_phy->SetMac (mac);
+ m_mac->AttachPhy (m_phy);
+ NS_LOG_DEBUG ("Attached MAC to PHY");
+ }
+ m_mac->SetForwardUpCb (MakeCallback (&UanNetDevice::ForwardUp, this));
+ }
+
+}
+
+void
+UanNetDevice::SetPhy (Ptr<UanPhy> phy)
+{
+ if (phy != 0)
+ {
+ m_phy = phy;
+ m_phy->SetDevice (Ptr<UanNetDevice> (this));
+ NS_LOG_DEBUG ("Set PHY");
+ if (m_mac != 0)
+ {
+ m_mac->AttachPhy (phy);
+ m_phy->SetMac (m_mac);
+ NS_LOG_DEBUG ("Attached PHY to MAC");
+ }
+ if (m_trans != 0)
+ {
+ m_phy->SetTransducer (m_trans);
+ NS_LOG_DEBUG ("Added PHY to trans");
+ }
+
+ }
+}
+
+void
+UanNetDevice::SetChannel (Ptr<UanChannel> channel)
+{
+ if (channel != 0)
+ {
+ m_channel = channel;
+ NS_LOG_DEBUG ("Set CHANNEL");
+ if (m_trans != 0)
+ {
+
+ m_channel->AddDevice (this, m_trans);
+ NS_LOG_DEBUG ("Added self to channel device list");
+ m_trans->SetChannel (m_channel);
+ NS_LOG_DEBUG ("Set Transducer channel");
+ }
+ if (m_phy != 0 )
+ {
+ m_phy->SetChannel (channel);
+ }
+ }
+}
+
+Ptr<UanChannel>
+UanNetDevice::DoGetChannel (void) const
+{
+ return m_channel;
+
+}
+Ptr<UanMac>
+UanNetDevice::GetMac () const
+{
+ return m_mac;
+}
+
+Ptr<UanPhy>
+UanNetDevice::GetPhy () const
+{
+ return m_phy;
+}
+
+void
+UanNetDevice::SetIfIndex (uint32_t index)
+{
+ m_ifIndex = index;
+}
+
+uint32_t
+UanNetDevice::GetIfIndex () const
+{
+ return m_ifIndex;
+}
+
+Ptr<Channel>
+UanNetDevice::GetChannel () const
+{
+ return m_channel;
+}
+
+Address
+UanNetDevice::GetAddress () const
+{
+ return m_mac->GetAddress ();
+}
+
+bool
+UanNetDevice::SetMtu (uint16_t mtu)
+{
+ // TODO: Check this in MAC
+ NS_LOG_WARN ("UanNetDevice: MTU is not implemented");
+ m_mtu = mtu;
+ return true;
+}
+
+uint16_t
+UanNetDevice::GetMtu () const
+{
+ return m_mtu;
+}
+
+bool
+UanNetDevice::IsLinkUp () const
+{
+ return (m_linkup && (m_phy != 0));
+}
+
+bool
+UanNetDevice::IsBroadcast () const
+{
+ return true;
+}
+
+Address
+UanNetDevice::GetBroadcast () const
+{
+ return m_mac->GetBroadcast ();
+}
+
+bool
+UanNetDevice::IsMulticast () const
+{
+ return false;
+}
+
+Address
+UanNetDevice::GetMulticast (Ipv4Address multicastGroup) const
+{
+ NS_FATAL_ERROR ("UanNetDevice does not support multicast");
+ return m_mac->GetBroadcast ();
+}
+
+Address
+UanNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ NS_FATAL_ERROR ("UanNetDevice does not support multicast");
+ return m_mac->GetBroadcast ();
+}
+
+bool
+UanNetDevice::IsBridge (void) const
+{
+ return false;
+}
+bool
+UanNetDevice::IsPointToPoint () const
+{
+ return false;
+}
+
+bool
+UanNetDevice::Send (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
+{
+ return m_mac->Enqueue (packet, dest, protocolNumber);
+}
+
+bool
+UanNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+{
+ // Not yet implemented
+ NS_ASSERT_MSG (0, "Not yet implemented");
+ return false;
+}
+Ptr<Node>
+UanNetDevice::GetNode () const
+{
+ return m_node;
+}
+
+void
+UanNetDevice::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+bool
+UanNetDevice::NeedsArp () const
+{
+ return false;
+}
+
+void
+UanNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+ m_forwardUp = cb;
+}
+
+void
+UanNetDevice::ForwardUp (Ptr<Packet> pkt, const UanAddress &src)
+{
+ NS_LOG_DEBUG ("Forwarding packet up to application");
+ m_rxLogger (pkt, src);
+ m_forwardUp (this, pkt, 0, src);
+
+}
+
+Ptr<UanTransducer>
+UanNetDevice::GetTransducer (void) const
+{
+ return m_trans;
+}
+void
+UanNetDevice::SetTransducer (Ptr<UanTransducer> trans)
+{
+
+ if (trans != 0)
+ {
+ m_trans = trans;
+ NS_LOG_DEBUG ("Set Transducer");
+ if (m_phy != 0)
+ {
+ m_phy->SetTransducer (m_trans);
+ NS_LOG_DEBUG ("Attached Phy to transducer");
+ }
+
+ if (m_channel != 0)
+ {
+ m_channel->AddDevice (this, m_trans);
+ m_trans->SetChannel (m_channel);
+ NS_LOG_DEBUG ("Added self to channel device list");
+ }
+ }
+
+}
+
+void
+UanNetDevice::AddLinkChangeCallback (Callback<void> callback)
+{
+ m_linkChanges.ConnectWithoutContext (callback);
+}
+
+
+void
+UanNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
+{
+ // Not implemented yet
+ NS_ASSERT_MSG (0, "Not yet implemented");
+}
+
+bool
+UanNetDevice::SupportsSendFrom (void) const
+{
+ return false;
+}
+
+void
+UanNetDevice::SetAddress (Address address)
+{
+ NS_ASSERT_MSG (0, "Tried to set MAC address with no MAC");
+ m_mac->SetAddress (UanAddress::ConvertFrom (address));
+}
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-net-device.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANNETDEVICE_H
+#define UANNETDEVICE_H
+
+#include "ns3/net-device.h"
+#include "ns3/pointer.h"
+#include "ns3/traced-callback.h"
+#include "uan-address.h"
+#include <list>
+
+namespace ns3 {
+
+class UanChannel;
+class UanPhy;
+class UanMac;
+class UanTransducer;
+
+/**
+ * \class UanNetDevice
+ *
+ * \brief Net device for UAN models
+ */
+class UanNetDevice : public NetDevice
+{
+public:
+ /**
+ * \brief UanPhyList is defined as a standard template lib list of UanPhy objects
+ */
+ typedef std::list<Ptr<UanPhy> > UanPhyList;
+ /**
+ * \brief UanTransducerList is a standard template lib list of UanTransducer objects
+ */
+ typedef std::list<Ptr<UanTransducer> > UanTransducerList;
+
+ static TypeId GetTypeId (void);
+
+ UanNetDevice ();
+ virtual ~UanNetDevice ();
+
+ /**
+ * \param mac Set MAC layer for this device
+ */
+ void SetMac (Ptr<UanMac> mac);
+
+ /**
+ * \param phy Set PHY layer for this device
+ */
+ void SetPhy (Ptr<UanPhy> phy);
+
+ /**
+ * \param channel The channel this device is attached to
+ */
+ void SetChannel (Ptr<UanChannel> channel);
+
+ /**
+ * \returns MAC this device is using
+ */
+ Ptr<UanMac> GetMac (void) const;
+
+ /**
+ * \returns PHY this device is using
+ */
+ Ptr<UanPhy> GetPhy (void) const;
+
+ /**
+ * \returns Transducer in net device
+ */
+ Ptr<UanTransducer> GetTransducer (void) const;
+ /**
+ * \param trans Transducer to use in this net device
+ */
+ void SetTransducer (Ptr<UanTransducer> trans);
+
+ // Purely virtual functions from base class
+ virtual void SetIfIndex (const uint32_t index);
+ virtual uint32_t GetIfIndex (void) const;
+ virtual Ptr<Channel> GetChannel (void) const;
+ virtual Address GetAddress (void) const;
+ virtual bool SetMtu (const uint16_t mtu);
+ virtual uint16_t GetMtu (void) const;
+ virtual bool IsLinkUp (void) const;
+ virtual bool IsBroadcast (void) const;
+ virtual Address GetBroadcast (void) const;
+ virtual bool IsMulticast (void) const;
+ virtual Address GetMulticast (Ipv4Address multicastGroup) const;
+ virtual Address GetMulticast (Ipv6Address addr) const;
+ virtual bool IsBridge (void) const ;
+ virtual bool IsPointToPoint (void) const;
+ virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+ virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
+ virtual Ptr<Node> GetNode (void) const;
+ virtual void SetNode (Ptr<Node> node);
+ virtual bool NeedsArp (void) const;
+ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
+ virtual bool SupportsSendFrom (void) const;
+ virtual void AddLinkChangeCallback (Callback<void> callback);
+ virtual void SetAddress (Address address);
+private:
+ virtual void ForwardUp (Ptr<Packet> pkt, const UanAddress &src);
+ Ptr<UanChannel> DoGetChannel (void) const;
+
+ Ptr<UanTransducer> m_trans;
+ Ptr<Node> m_node;
+ Ptr<UanChannel> m_channel;
+ Ptr<UanMac> m_mac;
+ Ptr<UanPhy> m_phy;
+
+ std::string m_name;
+ uint32_t m_ifIndex;
+ uint16_t m_mtu;
+ bool m_linkup;
+ TracedCallback<> m_linkChanges;
+ ReceiveCallback m_forwardUp;
+
+ TracedCallback<Ptr<const Packet>, UanAddress> m_rxLogger;
+ TracedCallback<Ptr<const Packet>, UanAddress> m_txLogger;
+protected:
+ virtual void DoDispose ();
+};
+
+} // namespace ns3
+
+#endif // UANNETDEVICE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-noise-model-default.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-noise-model-default.h"
+#include "ns3/double.h"
+
+#include <cmath>
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanNoiseModelDefault);
+
+UanNoiseModelDefault::UanNoiseModelDefault ()
+{
+
+}
+
+UanNoiseModelDefault::~UanNoiseModelDefault ()
+{
+}
+
+TypeId
+UanNoiseModelDefault::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanNoiseModelDefault")
+ .SetParent<Object> ()
+ .AddConstructor<UanNoiseModelDefault> ()
+ .AddAttribute ("Wind", "Wind speed in m/s",
+ DoubleValue (1),
+ MakeDoubleAccessor (&UanNoiseModelDefault::m_wind),
+ MakeDoubleChecker<double> (0))
+ .AddAttribute ("Shipping", "Shipping contribution to noise between 0 and 1",
+ DoubleValue (0),
+ MakeDoubleAccessor (&UanNoiseModelDefault::m_shipping),
+ MakeDoubleChecker<double> (0,1))
+ ;
+ return tid;
+}
+
+// Common acoustic noise formulas. These can be found
+// in "Priniciples of Underwater Sound" by Robert J. Urick
+double
+UanNoiseModelDefault::GetNoiseDbHz (double fKhz) const
+{
+ double turb, win, ship, thermal, noise;
+ turb = 17.0 - 30.0 * log10 (fKhz);
+ turb = pow (10.0, turb * 0.1);
+
+ ship = 40.0 + 20.0 * (m_shipping - 0.5) + 26.0 * log10 (fKhz) - 60.0 * log10 (fKhz + 0.03);
+ ship = pow (10.0, (ship * 0.1));
+
+ win = 50.0 + 7.5 * pow (m_wind, 0.5) + 20.0 * log10 (fKhz) - 40.0 * log10 (fKhz + 0.4);
+ win = pow (10.0, m_wind * 0.1);
+
+ thermal = -15 + 20 * log10 (fKhz);
+ thermal = pow (10, thermal * 0.1);
+
+ noise = 10 * log10 (turb + ship + win + thermal);
+
+ return noise;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-noise-model-default.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANNOISEMODELDEFAULT_H
+#define UANNOISEMODELDEFAULT_H
+
+#include "ns3/uan-noise-model.h"
+#include "ns3/attribute.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+/**
+ * \class UanNoiseModelDefault
+ *
+ * Standard ambient acoustic noise model. See attributes for parameters
+ *
+ * This class returns ambient noise by following the algorithm given in
+ * Harris, A. F. and Zorzi, M. 2007. Modeling the underwater acoustic channel in ns2.
+ * In Proceedings of the 2nd international Conference on Performance Evaluation
+ * Methodologies and Tools (Nantes, France, October 22 - 27, 2007). ValueTools,
+ * vol. 321. ICST (Institute for Computer Sciences Social-Informatics and
+ * Telecommunications Engineering), ICST, Brussels, Belgium, 1-8.
+ *
+ * Which uses the noise model also given in the book
+ * "Principles of Underwater Sound" by Urick
+ */
+class UanNoiseModelDefault : public UanNoiseModel
+{
+public:
+ UanNoiseModelDefault ();
+ virtual ~UanNoiseModelDefault ();
+
+ static TypeId GetTypeId (void);
+ /**
+ * \returns Noise power in dB re 1uPa/Hz
+ * \param fKhz Frequency in kHz
+ */
+ virtual double GetNoiseDbHz (double fKhz) const;
+
+private:
+ double m_wind;
+ double m_shipping;
+
+};
+
+}
+
+#endif // UANNOISEMODELDEFAULT_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-noise-model.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANNOISEMODEL_H
+#define UANNOISEMODEL_H
+
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class UanNoiseModel : public ns3::Object
+{
+public:
+ /**
+ * \param fKhz Frequency in kHz
+ * \returns Noise power in dB re 1uPa/Hz
+ */
+ virtual double GetNoiseDbHz (double fKhz) const = 0;
+
+};
+
+} // namespace ns3
+
+#endif // UANNOISEMODEL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-phy-dual.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,636 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-phy.h"
+#include "uan-phy-dual.h"
+#include "uan-phy-gen.h"
+#include "uan-tx-mode.h"
+#include "uan-net-device.h"
+#include "uan-channel.h"
+#include "ns3/double.h"
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/simulator.h"
+#include "uan-header-common.h"
+#include "uan-mac-rc.h"
+
+#include <cmath>
+
+
+NS_LOG_COMPONENT_DEFINE ("UanPhyDual");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanPhyDual);
+NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDual);
+
+UanPhyCalcSinrDual::UanPhyCalcSinrDual ()
+{
+
+}
+UanPhyCalcSinrDual::~UanPhyCalcSinrDual ()
+{
+
+}
+
+TypeId
+UanPhyCalcSinrDual::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPhyCalcSinrDual")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyCalcSinrDual> ()
+ ;
+ return tid;
+}
+
+double
+UanPhyCalcSinrDual::CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList) const
+{
+
+ if (mode.GetModType () != UanTxMode::OTHER)
+ {
+ NS_LOG_WARN ("Calculating SINR for unsupported modulation type");
+ }
+
+ double intKp = -DbToKp (rxPowerDb); // This packet is in the arrivalList
+ UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
+ for (; it != arrivalList.end (); it++)
+ {
+ // Only count interference if there is overlap in incoming frequency
+ if (std::abs ( (double) it->GetTxMode ().GetCenterFreqHz () - (double) mode.GetCenterFreqHz ())
+ < (double)(it->GetTxMode ().GetBandwidthHz () / 2 + mode.GetBandwidthHz () / 2) - 0.5)
+ {
+ UanHeaderCommon ch, ch2;
+ if (pkt)
+ {
+ pkt->PeekHeader (ch);
+ }
+ it->GetPacket ()->PeekHeader (ch2);
+
+ if (pkt)
+ {
+ if (ch.GetType () == UanMacRc::TYPE_DATA)
+ {
+ NS_LOG_DEBUG ("Adding interferer from " << ch2.GetSrc () << " against " << ch.GetSrc () << ": PktRxMode: "
+ << mode.GetName () << " Int mode: " << it->GetTxMode ().GetName () << " Separation: "
+ << std::abs ( (double) it->GetTxMode ().GetCenterFreqHz () - (double) mode.GetCenterFreqHz ())
+ << " Combined bandwidths: " << (double)(it->GetTxMode ().GetBandwidthHz () / 2 + mode.GetBandwidthHz () / 2) - 0.5);
+ }
+ }
+ intKp += DbToKp (it->GetRxPowerDb ());
+ }
+ }
+
+ double totalIntDb = KpToDb (intKp + DbToKp (ambNoiseDb));
+
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Calculating SINR: RxPower = " << rxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
+ return rxPowerDb - totalIntDb;
+}
+
+UanPhyDual::UanPhyDual ()
+ : UanPhy ()
+{
+
+ m_phy1 = CreateObject<UanPhyGen> ();
+ m_phy2 = CreateObject<UanPhyGen> ();
+
+ m_phy1->SetReceiveOkCallback (m_recOkCb);
+ m_phy2->SetReceiveOkCallback (m_recOkCb);
+
+ m_phy1->SetReceiveErrorCallback (m_recErrCb);
+ m_phy2->SetReceiveErrorCallback (m_recErrCb);
+
+}
+
+UanPhyDual::~UanPhyDual ()
+{
+}
+
+void
+UanPhyDual::DoDispose ()
+{
+ m_phy1 = 0;
+ m_phy2 = 0;
+ UanPhy::DoDispose ();
+}
+
+TypeId
+UanPhyDual::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPhyDual")
+ .SetParent<UanPhy> ()
+ .AddConstructor<UanPhyDual> ()
+ .AddAttribute ("CcaThresholdPhy1",
+ "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy1",
+ DoubleValue (10),
+ MakeDoubleAccessor (&UanPhyDual::GetCcaThresholdPhy1, &UanPhyDual::SetCcaThresholdPhy1),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("CcaThresholdPhy2",
+ "Aggregate energy of incoming signals to move to CCA Busy state dB of Phy2",
+ DoubleValue (10),
+ MakeDoubleAccessor (&UanPhyDual::GetCcaThresholdPhy2, &UanPhyDual::SetCcaThresholdPhy2),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerPhy1",
+ "Transmission output power in dB of Phy1",
+ DoubleValue (190),
+ MakeDoubleAccessor (&UanPhyDual::GetTxPowerDbPhy1, &UanPhyDual::SetTxPowerDbPhy1),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerPhy2",
+ "Transmission output power in dB of Phy2",
+ DoubleValue (190),
+ MakeDoubleAccessor (&UanPhyDual::GetTxPowerDbPhy2, &UanPhyDual::SetTxPowerDbPhy2),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxGainPhy1",
+ "Gain added to incoming signal at receiver of Phy1",
+ DoubleValue (0),
+ MakeDoubleAccessor (&UanPhyDual::GetRxGainDbPhy1, &UanPhyDual::SetRxGainDbPhy1),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxGainPhy2",
+ "Gain added to incoming signal at receiver of Phy2",
+ DoubleValue (0),
+ MakeDoubleAccessor (&UanPhyDual::GetRxGainDbPhy2, &UanPhyDual::SetRxGainDbPhy2),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("SupportedModesPhy1",
+ "List of modes supported by Phy1",
+ UanModesListValue (UanPhyGen::GetDefaultModes ()),
+ MakeUanModesListAccessor (&UanPhyDual::GetModesPhy1, &UanPhyDual::SetModesPhy1),
+ MakeUanModesListChecker () )
+ .AddAttribute ("SupportedModesPhy2",
+ "List of modes supported by Phy2",
+ UanModesListValue (UanPhyGen::GetDefaultModes ()),
+ MakeUanModesListAccessor (&UanPhyDual::GetModesPhy2, &UanPhyDual::SetModesPhy2),
+ MakeUanModesListChecker () )
+ .AddAttribute ("PerModelPhy1",
+ "Functor to calculate PER based on SINR and TxMode for Phy1",
+ PointerValue (CreateObject<UanPhyPerGenDefault> ()),
+ MakePointerAccessor (&UanPhyDual::GetPerModelPhy1, &UanPhyDual::SetPerModelPhy1),
+ MakePointerChecker<UanPhyPer> ())
+ .AddAttribute ("PerModelPhy2",
+ "Functor to calculate PER based on SINR and TxMode for Phy2",
+ PointerValue (CreateObject<UanPhyPerGenDefault> ()),
+ MakePointerAccessor (&UanPhyDual::GetPerModelPhy2, &UanPhyDual::SetPerModelPhy2),
+ MakePointerChecker<UanPhyPer> ())
+ .AddAttribute ("SinrModelPhy1",
+ "Functor to calculate SINR based on pkt arrivals and modes for Phy1",
+ PointerValue (CreateObject<UanPhyCalcSinrDual> ()),
+ MakePointerAccessor (&UanPhyDual::GetSinrModelPhy1, &UanPhyDual::SetSinrModelPhy1),
+ MakePointerChecker<UanPhyCalcSinr> ())
+ .AddAttribute ("SinrModelPhy2",
+ "Functor to calculate SINR based on pkt arrivals and modes for Phy2",
+ PointerValue (CreateObject<UanPhyCalcSinrDual> ()),
+ MakePointerAccessor (&UanPhyDual::GetSinrModelPhy2, &UanPhyDual::SetSinrModelPhy2),
+ MakePointerChecker<UanPhyCalcSinr> ())
+ .AddTraceSource ("RxOk",
+ "A packet was received successfully",
+ MakeTraceSourceAccessor (&UanPhyDual::m_rxOkLogger))
+ .AddTraceSource ("RxError",
+ "A packet was received unsuccessfully",
+ MakeTraceSourceAccessor (&UanPhyDual::m_rxErrLogger))
+ .AddTraceSource ("Tx",
+ "Packet transmission beginning",
+ MakeTraceSourceAccessor (&UanPhyDual::m_txLogger))
+
+ ;
+
+ return tid;
+}
+
+void
+UanPhyDual::SendPacket (Ptr<Packet> pkt, uint32_t modeNum)
+{
+ if (modeNum <= m_phy1->GetNModes () - 1)
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending packet on Phy1 with mode number " << modeNum);
+ m_txLogger (pkt, m_phy1->GetTxPowerDb (), m_phy1->GetMode (modeNum));
+ m_phy1->SendPacket (pkt, modeNum);
+
+ }
+ else
+ {
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending packet on Phy2 with mode number " << modeNum - m_phy1->GetNModes ());
+ m_txLogger (pkt, m_phy2->GetTxPowerDb (), m_phy2->GetMode (modeNum - m_phy1->GetNModes ()));
+ m_phy2->SendPacket (pkt, modeNum - m_phy1->GetNModes ());
+ }
+}
+void
+UanPhyDual::RegisterListener (UanPhyListener *listener)
+{
+ m_phy1->RegisterListener (listener);
+ m_phy2->RegisterListener (listener);
+}
+
+void
+UanPhyDual::StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp)
+{
+ // Not called. StartRxPacket in m_phy1 and m_phy2 are called directly from Transducer.
+}
+
+void
+UanPhyDual::SetReceiveOkCallback (RxOkCallback cb)
+{
+ m_phy1->SetReceiveOkCallback (cb);
+ m_phy2->SetReceiveOkCallback (cb);
+}
+
+void
+UanPhyDual::SetReceiveErrorCallback (RxErrCallback cb)
+{
+ m_phy1->SetReceiveErrorCallback (cb);
+ m_phy2->SetReceiveErrorCallback (cb);
+}
+
+void
+UanPhyDual::SetRxGainDb (double gain)
+{
+ m_phy1->SetRxGainDb (gain);
+ m_phy2->SetRxGainDb (gain);
+}
+void
+UanPhyDual::SetRxGainDbPhy1 (double gain)
+{
+ m_phy1->SetRxGainDb (gain);
+}
+
+void
+UanPhyDual::SetRxGainDbPhy2 (double gain)
+{
+ m_phy2->SetRxGainDb (gain);
+}
+
+void
+UanPhyDual::SetTxPowerDb (double txpwr)
+{
+ m_phy1->SetTxPowerDb (txpwr);
+ m_phy2->SetTxPowerDb (txpwr);
+}
+
+void
+UanPhyDual::SetTxPowerDbPhy1 (double txpwr)
+{
+ m_phy1->SetTxPowerDb (txpwr);
+}
+void
+UanPhyDual::SetTxPowerDbPhy2 (double txpwr)
+{
+ m_phy2->SetTxPowerDb (txpwr);
+}
+
+void
+UanPhyDual::SetRxThresholdDb (double thresh)
+{
+ NS_LOG_WARN ("SetRxThresholdDb is deprecated and has no effect. Look at PER Functor attribute");
+ m_phy1->SetRxThresholdDb (thresh);
+ m_phy2->SetRxThresholdDb (thresh);
+}
+void
+UanPhyDual::SetCcaThresholdDb (double thresh)
+{
+ m_phy1->SetCcaThresholdDb (thresh);
+ m_phy2->SetCcaThresholdDb (thresh);
+}
+
+void
+UanPhyDual::SetCcaThresholdPhy1 (double thresh)
+{
+ m_phy1->SetCcaThresholdDb (thresh);
+}
+void
+UanPhyDual::SetCcaThresholdPhy2 (double thresh)
+{
+ m_phy2->SetCcaThresholdDb (thresh);
+}
+
+double
+UanPhyDual::GetRxGainDb (void)
+{
+ NS_LOG_WARN ("Warning: UanPhyDual::GetRxGainDb returns RxGain of Phy 1");
+ return m_phy1->GetRxGainDb ();
+}
+double
+UanPhyDual::GetRxGainDbPhy1 (void) const
+{
+ return m_phy1->GetRxGainDb ();
+}
+double
+UanPhyDual::GetRxGainDbPhy2 (void) const
+{
+ return m_phy2->GetRxGainDb ();
+}
+
+double
+UanPhyDual::GetTxPowerDb (void)
+{
+ NS_LOG_WARN ("Warning: Dual Phy only returns TxPowerDb of Phy 1");
+ return m_phy1->GetTxPowerDb ();
+}
+
+double
+UanPhyDual::GetTxPowerDbPhy1 (void) const
+{
+ return m_phy1->GetTxPowerDb ();
+}
+
+double
+UanPhyDual::GetTxPowerDbPhy2 (void) const
+{
+ return m_phy2->GetTxPowerDb ();
+}
+
+double
+UanPhyDual::GetRxThresholdDb (void)
+{
+ return m_phy1->GetRxThresholdDb ();
+}
+
+double
+UanPhyDual::GetCcaThresholdDb (void)
+{
+ NS_LOG_WARN ("Dual Phy only returns CCAThreshold of Phy 1");
+ return m_phy1->GetCcaThresholdDb ();
+}
+double
+UanPhyDual::GetCcaThresholdPhy1 (void) const
+{
+ return m_phy1->GetCcaThresholdDb ();
+}
+double
+UanPhyDual::GetCcaThresholdPhy2 (void) const
+{
+ return m_phy2->GetCcaThresholdDb ();
+}
+
+bool
+UanPhyDual::IsPhy1Idle (void)
+{
+ return m_phy1->IsStateIdle ();
+}
+bool
+UanPhyDual::IsPhy2Idle (void)
+{
+ return m_phy2->IsStateIdle ();
+}
+
+bool
+UanPhyDual::IsPhy1Rx (void)
+{
+ return m_phy1->IsStateRx ();
+}
+
+bool
+UanPhyDual::IsPhy2Rx (void)
+{
+ return m_phy2->IsStateRx ();
+}
+
+bool
+UanPhyDual::IsPhy1Tx (void)
+{
+ return m_phy1->IsStateTx ();
+}
+
+Ptr<Packet>
+UanPhyDual::GetPhy1PacketRx (void) const
+{
+ return m_phy1->GetPacketRx ();
+}
+
+Ptr<Packet>
+UanPhyDual::GetPhy2PacketRx (void) const
+{
+ return m_phy2->GetPacketRx ();
+}
+
+bool
+UanPhyDual::IsPhy2Tx (void)
+{
+ return m_phy2->IsStateTx ();
+}
+
+bool
+UanPhyDual::IsStateIdle (void)
+{
+ return m_phy1->IsStateIdle () && m_phy2->IsStateIdle ();
+}
+bool
+UanPhyDual::IsStateBusy (void)
+{
+ return !IsStateIdle ();
+}
+bool
+UanPhyDual::IsStateRx (void)
+{
+ return m_phy1->IsStateRx () || m_phy2->IsStateRx ();
+}
+bool
+UanPhyDual::IsStateTx (void)
+{
+ return m_phy1->IsStateTx () || m_phy2->IsStateTx ();
+}
+bool
+UanPhyDual::IsStateCcaBusy (void)
+{
+ return m_phy1->IsStateCcaBusy () || m_phy2->IsStateCcaBusy ();
+}
+Ptr<UanChannel>
+UanPhyDual::GetChannel (void) const
+{
+ return m_phy1->GetChannel ();
+}
+Ptr<UanNetDevice>
+UanPhyDual::GetDevice (void)
+{
+ return m_phy1->GetDevice ();
+}
+void
+UanPhyDual::SetChannel (Ptr<UanChannel> channel)
+{
+ m_phy1->SetChannel (channel);
+ m_phy2->SetChannel (channel);
+}
+void
+UanPhyDual::SetDevice (Ptr<UanNetDevice> device)
+{
+ m_phy1->SetDevice (device);
+ m_phy2->SetDevice (device);
+}
+void
+UanPhyDual::SetMac (Ptr<UanMac> mac)
+{
+ m_phy1->SetMac (mac);
+ m_phy2->SetMac (mac);
+}
+void
+UanPhyDual::NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode)
+{
+
+}
+void
+UanPhyDual::NotifyIntChange (void)
+{
+ m_phy1->NotifyIntChange ();
+ m_phy2->NotifyIntChange ();
+
+}
+void
+UanPhyDual::SetTransducer (Ptr<UanTransducer> trans)
+{
+ m_phy1->SetTransducer (trans);
+ m_phy2->SetTransducer (trans);
+}
+Ptr<UanTransducer>
+UanPhyDual::GetTransducer (void)
+{
+ NS_LOG_WARN ("DualPhy Returning transducer of Phy1");
+ return m_phy1->GetTransducer ();
+}
+uint32_t
+UanPhyDual::GetNModes (void)
+{
+ return m_phy1->GetNModes () + m_phy2->GetNModes ();
+}
+UanTxMode
+UanPhyDual::GetMode (uint32_t n)
+{
+ if (n < m_phy1->GetNModes ())
+ {
+ return m_phy1->GetMode (n);
+ }
+ else
+ {
+ return m_phy2->GetMode (n - m_phy1->GetNModes ());
+ }
+}
+
+UanModesList
+UanPhyDual::GetModesPhy1 (void) const
+{
+
+ UanModesListValue modeValue;
+ m_phy1->GetAttribute ("SupportedModes", modeValue);
+ return modeValue.Get ();
+}
+
+UanModesList
+UanPhyDual::GetModesPhy2 (void) const
+{
+ UanModesListValue modeValue;
+ m_phy2->GetAttribute ("SupportedModes", modeValue);
+ return modeValue.Get ();
+}
+
+void
+UanPhyDual::SetModesPhy1 (UanModesList modes)
+{
+ m_phy1->SetAttribute ("SupportedModes", UanModesListValue (modes));
+}
+
+void
+UanPhyDual::SetModesPhy2 (UanModesList modes)
+{
+ m_phy2->SetAttribute ("SupportedModes", UanModesListValue (modes));
+}
+
+Ptr<UanPhyPer>
+UanPhyDual::GetPerModelPhy1 (void) const
+{
+ PointerValue perValue;
+ m_phy1->GetAttribute ("PerModel", perValue);
+ return perValue;
+}
+
+Ptr<UanPhyPer>
+UanPhyDual::GetPerModelPhy2 (void) const
+{
+ PointerValue perValue;
+ m_phy2->GetAttribute ("PerModel", perValue);
+ return perValue;
+}
+
+void
+UanPhyDual::SetPerModelPhy1 (Ptr<UanPhyPer> per)
+{
+ m_phy1->SetAttribute ("PerModel", PointerValue (per));
+}
+
+void
+UanPhyDual::SetPerModelPhy2 (Ptr<UanPhyPer> per)
+{
+ m_phy2->SetAttribute ("PerModel", PointerValue (per));
+}
+
+Ptr<UanPhyCalcSinr>
+UanPhyDual::GetSinrModelPhy1 (void) const
+{
+ PointerValue sinrValue;
+ m_phy1->GetAttribute ("SinrModel", sinrValue);
+ return sinrValue;
+}
+
+Ptr<UanPhyCalcSinr>
+UanPhyDual::GetSinrModelPhy2 (void) const
+{
+ PointerValue sinrValue;
+ m_phy2->GetAttribute ("SinrModel", sinrValue);
+ return sinrValue;
+}
+
+void
+UanPhyDual::SetSinrModelPhy1 (Ptr<UanPhyCalcSinr> sinr)
+{
+ m_phy1->SetAttribute ("SinrModel", PointerValue (sinr));
+}
+
+void
+UanPhyDual::SetSinrModelPhy2 (Ptr<UanPhyCalcSinr> sinr)
+{
+ m_phy2->SetAttribute ("SinrModel", PointerValue (sinr));
+}
+
+void
+UanPhyDual::RxOkFromSubPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode)
+{
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Received packet");
+ m_recOkCb (pkt, sinr, mode);
+ m_rxOkLogger (pkt, sinr, mode);
+}
+
+void
+UanPhyDual::RxErrFromSubPhy (Ptr<Packet> pkt, double sinr)
+{
+ m_recErrCb (pkt, sinr);
+ m_rxErrLogger (pkt, sinr, m_phy1->GetMode (0));
+}
+
+Ptr<Packet>
+UanPhyDual::GetPacketRx (void) const
+{
+ NS_FATAL_ERROR ("GetPacketRx not valid for UanPhyDual. Must specify GetPhy1PacketRx or GetPhy2PacketRx");
+ return Create<Packet> ();
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-phy-dual.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANPHYDUAL_H
+#define UANPHYDUAL_H
+
+#include "ns3/uan-phy.h"
+
+
+
+namespace ns3 {
+
+class UanTxMode;
+class UanModesList;
+
+
+/**
+ * \class UanPhyCalcSinrDual
+ * \brief Default SINR model for UanPhyDual
+ *
+ * Considers interfering packet power as additional ambient noise only
+ * if there is overlap in frequency band as found from supplied UanTxMode.
+ * If there is no overlap, then the packets are considered not to interfere.
+ */
+class UanPhyCalcSinrDual : public UanPhyCalcSinr
+{
+public:
+ UanPhyCalcSinrDual ();
+ virtual ~UanPhyCalcSinrDual ();
+ static TypeId GetTypeId (void);
+ virtual double CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList
+ ) const;
+};
+
+/**
+ * \class UanPhyDual
+ *
+ * A class that wraps two generic UAN Phy layers (UanPhyGen) into a single PHY.
+ * This is used to simulate two receivers (and transmitters) that use
+ * the same front end hardware. When attached to a UanTransducerHd,
+ * this results in a net device able to transmit on one or two channels
+ * simultaneously or receive on one or two channels simultaneously but
+ * that cannot transmit and receive simultaneously.
+ *
+ * Many of the standard PHY functions here become ambiguous. In most cases
+ * information for "Phy1" are returned.
+ */
+class UanPhyDual : public UanPhy
+{
+public:
+ UanPhyDual ();
+ virtual ~UanPhyDual ();
+
+ static TypeId GetTypeId ();
+
+ virtual void SendPacket (Ptr<Packet> pkt, uint32_t modeNum);
+
+ /**
+ * \brief Register a class to receive phy state change notifications
+ * \param listener Class derived from UanPhyListener to receive notifications
+ *
+ * Note that, from UanPhyDual, you may receive duplicate
+ * messages as underneath there are two generic phys here.
+ * Each will notify of state changes independently.
+ */
+ virtual void RegisterListener (UanPhyListener *listener);
+ virtual void StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp);
+ virtual void SetReceiveOkCallback (RxOkCallback cb);
+ virtual void SetReceiveErrorCallback (RxErrCallback cb);
+ virtual void SetRxGainDb (double gain);
+ virtual void SetTxPowerDb (double txpwr);
+ virtual void SetRxThresholdDb (double thresh);
+ virtual void SetCcaThresholdDb (double thresh);
+ virtual double GetRxGainDb (void);
+ virtual double GetTxPowerDb (void);
+ virtual double GetRxThresholdDb (void);
+ virtual double GetCcaThresholdDb (void);
+ virtual bool IsStateIdle (void);
+ virtual bool IsStateBusy (void);
+ virtual bool IsStateRx (void);
+ virtual bool IsStateTx (void);
+ virtual bool IsStateCcaBusy (void);
+ virtual Ptr<UanChannel> GetChannel (void) const;
+ virtual Ptr<UanNetDevice> GetDevice (void);
+ virtual void SetChannel (Ptr<UanChannel> channel);
+ virtual void SetDevice (Ptr<UanNetDevice> device);
+ virtual void SetMac (Ptr<UanMac> mac);
+ virtual void NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode);
+ virtual void NotifyIntChange (void);
+ virtual void SetTransducer (Ptr<UanTransducer> trans);
+ virtual Ptr<UanTransducer> GetTransducer (void);
+ virtual uint32_t GetNModes (void);
+ virtual UanTxMode GetMode (uint32_t n);
+
+ /**
+ * /returns True if Phy1 is Idle
+ */
+ bool IsPhy1Idle (void);
+ /**
+ * /returns True if Phy2 is Idle
+ */
+ bool IsPhy2Idle (void);
+ /**
+ * /returns True if Phy1 is currently in RX mode
+ */
+ bool IsPhy1Rx (void);
+ /**
+ * /returns True if Phy2 is currently in RX mode
+ */
+ bool IsPhy2Rx (void);
+ /**
+ * /returns True if Phy1 is in TX mode
+ */
+ bool IsPhy1Tx (void);
+ /**
+ * /returns True if Phy2 is in TX mode
+ */
+ bool IsPhy2Tx (void);
+
+ // Attribute getters and setters
+ /**
+ * \returns Clear channel assessment threshold of Phy1
+ */
+ double GetCcaThresholdPhy1 (void) const;
+ /**
+ * \returns Clear channel assessment threshold of Phy2
+ */
+ double GetCcaThresholdPhy2 (void) const;
+ /**
+ * \param double Signal power threshold in dB to set Phy1 to
+ */
+ void SetCcaThresholdPhy1 (double);
+ /**
+ * \param double Signal power threshold in dB to set Phy2 to
+ */
+ void SetCcaThresholdPhy2 (double);
+
+ /**
+ * \returns Current TX power setting of Phy 1 in dB
+ */
+ double GetTxPowerDbPhy1 (void) const;
+ /**
+ * \returns Current TX power setting of Phy 2 in dB
+ */
+ double GetTxPowerDbPhy2 (void) const;
+ /**
+ * \returns TX power setting of Phy1 in dB
+ */
+ void SetTxPowerDbPhy1 (double);
+ /**
+ * \returns TX power setting of Phy2 in dB
+ */
+ void SetTxPowerDbPhy2 (double);
+
+ /**
+ * \returns RX gain of Phy1 in dB
+ */
+ double GetRxGainDbPhy1 (void) const;
+ /**
+ * \returns RX gain of Phy2 in dB
+ */
+ double GetRxGainDbPhy2 (void) const;
+ /**
+ * \param double value in dB to apply to RX gain of Phy1
+ */
+ void SetRxGainDbPhy1 (double);
+ /**
+ * \param double value in dB to apply to RX gain of Phy2
+ */
+ void SetRxGainDbPhy2 (double);
+
+ /**
+ * \returns List of available modes on Phy1
+ */
+ UanModesList GetModesPhy1 (void) const;
+ /**
+ * \returns List of available modes on Phy2
+ */
+ UanModesList GetModesPhy2 (void) const;
+ /**
+ * \param modes List of modes to use on Phy1 (index corresponds to mode #)
+ */
+ void SetModesPhy1 (UanModesList modes);
+ /**
+ * \param modes List of modes to use on Phy2 (index corresponds to mode #)
+ */
+ void SetModesPhy2 (UanModesList modes);
+
+ /**
+ * \returns Ptr to PER model for Phy1
+ */
+ Ptr<UanPhyPer> GetPerModelPhy1 (void) const;
+ /**
+ * \returns Ptr to PER model for Phy2
+ */
+ Ptr<UanPhyPer> GetPerModelPhy2 (void) const;
+ /**
+ * \param per Ptr to PER model to use on Phy1
+ */
+ void SetPerModelPhy1 (Ptr<UanPhyPer> per);
+ /**
+ * \param per Ptr to PER model to use on Phy2
+ */
+ void SetPerModelPhy2 (Ptr<UanPhyPer> per);
+
+ /**
+ * \returns Ptr to SINR model for Phy1
+ */
+ Ptr<UanPhyCalcSinr> GetSinrModelPhy1 (void) const;
+ /**
+ * \returns Ptr to SINR model for Phy2
+ */
+ Ptr<UanPhyCalcSinr> GetSinrModelPhy2 (void) const;
+ /**
+ * \param calcSinr Ptr to SINR model to use on Phy1
+ */
+ void SetSinrModelPhy1 (Ptr<UanPhyCalcSinr> calcSinr);
+ /**
+ * \param calcSinr Ptr to SINR model to use on Phy2
+ */
+ void SetSinrModelPhy2 (Ptr<UanPhyCalcSinr> calcSinr);
+
+ /**
+ * \returns Packet currently being received on Phy1 (Null Ptr if none)
+ */
+ Ptr<Packet> GetPhy1PacketRx (void) const;
+ /**
+ * \returns Packet currently being received on Phy2 (Null Ptr if none)
+ */
+ Ptr<Packet> GetPhy2PacketRx (void) const;
+ /**
+ * \returns Packet currenty being received on Phy1 (Null Ptr if none)
+ */
+ Ptr<Packet> GetPacketRx (void) const;
+
+private:
+ Ptr<UanPhy> m_phy1;
+ Ptr<UanPhy> m_phy2;
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_rxOkLogger;
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_rxErrLogger;
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_txLogger;
+ RxOkCallback m_recOkCb;
+ RxErrCallback m_recErrCb;
+
+
+ void RxOkFromSubPhy (Ptr<Packet> pkt, double sinr, UanTxMode mode);
+ void RxErrFromSubPhy (Ptr<Packet> pkt, double sinr);
+protected:
+ virtual void DoDispose ();
+};
+
+}
+
+#endif // UANPHYDUAL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-phy-gen.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,864 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-phy-gen.h"
+#include "uan-transducer.h"
+#include "uan-channel.h"
+#include "uan-net-device.h"
+#include "ns3/simulator.h"
+#include "ns3/traced-callback.h"
+#include "ns3/ptr.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/double.h"
+#include "ns3/log.h"
+#include "ns3/uan-tx-mode.h"
+#include "ns3/node.h"
+#include "ns3/uinteger.h"
+#include "ns3/random-variable.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("UanPhyGen");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanPhyGen);
+NS_OBJECT_ENSURE_REGISTERED (UanPhyPerGenDefault);
+NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrDefault);
+NS_OBJECT_ENSURE_REGISTERED (UanPhyCalcSinrFhFsk);
+NS_OBJECT_ENSURE_REGISTERED (UanPhyPerUmodem);
+
+
+/*************** UanPhyCalcSinrDefault definition *****************/
+UanPhyCalcSinrDefault::UanPhyCalcSinrDefault ()
+{
+
+}
+UanPhyCalcSinrDefault::~UanPhyCalcSinrDefault ()
+{
+
+}
+
+TypeId
+UanPhyCalcSinrDefault::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPhyCalcSinrDefault")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyCalcSinrDefault> ()
+ ;
+ return tid;
+}
+
+double
+UanPhyCalcSinrDefault::CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList) const
+{
+ if (mode.GetModType () == UanTxMode::OTHER)
+ {
+ NS_LOG_WARN ("Calculating SINR for unsupported modulation type");
+ }
+
+ double intKp = -DbToKp (rxPowerDb); // This packet is in the arrivalList
+ UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
+ for (; it != arrivalList.end (); it++)
+ {
+ intKp += DbToKp (it->GetRxPowerDb ());
+ }
+
+ double totalIntDb = KpToDb (intKp + DbToKp (ambNoiseDb));
+
+ NS_LOG_DEBUG ("Calculating SINR: RxPower = " << rxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << rxPowerDb - totalIntDb << " dB.");
+ return rxPowerDb - totalIntDb;
+}
+
+/*************** UanPhyCalcSinrFhFsk definition *****************/
+UanPhyCalcSinrFhFsk::UanPhyCalcSinrFhFsk ()
+{
+
+}
+UanPhyCalcSinrFhFsk::~UanPhyCalcSinrFhFsk ()
+{
+
+}
+
+TypeId
+UanPhyCalcSinrFhFsk::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPhyCalcSinrFhFsk")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyCalcSinrFhFsk> ()
+ .AddAttribute ("NumberOfHops",
+ "Number of frequencies in hopping pattern",
+ UintegerValue (13),
+ MakeUintegerAccessor (&UanPhyCalcSinrFhFsk::m_hops),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+double
+UanPhyCalcSinrFhFsk::CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList) const
+{
+ if (mode.GetModType () != UanTxMode::FSK)
+ {
+ NS_LOG_WARN ("Calculating SINR for unsupported mode type");
+ }
+
+
+
+ double ts = 1.0 / mode.GetPhyRateSps ();
+ double clearingTime = (m_hops - 1.0) * ts;
+ double csp = pdp.SumTapsFromMaxNc (Seconds (0), Seconds (ts));
+
+ UanPdp::Iterator tmpIt = pdp.GetBegin ();
+
+ // Get maximum arrival offset
+ double maxAmp = -1;
+ double maxTapDelay = 0.0;
+ UanPdp::Iterator pit = pdp.GetBegin ();
+ for (; pit != pdp.GetEnd (); pit++)
+ {
+ if (abs (pit->GetAmp ()) > maxAmp)
+ {
+ maxAmp = abs (pit->GetAmp ());
+ maxTapDelay = pit->GetDelay ().GetSeconds ();
+ }
+ }
+
+
+ double effRxPowerDb = rxPowerDb + KpToDb (csp);
+
+ double isiUpa = rxPowerDb * pdp.SumTapsFromMaxNc (Seconds (ts + clearingTime), Seconds (ts));
+ UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
+ double intKp = -DbToKp (effRxPowerDb);
+ for (; it != arrivalList.end (); it++)
+ {
+ UanPdp intPdp = it->GetPdp ();
+ double tDelta = std::abs (arrTime.GetSeconds () + maxTapDelay - it->GetArrivalTime ().GetSeconds ());
+ // We want tDelta in terms of a single symbol (i.e. if tDelta = 7.3 symbol+clearing
+ // times, the offset in terms of the arriving symbol power is
+ // 0.3 symbol+clearing times.
+
+ int32_t syms = (uint32_t)( (double) tDelta / (ts + clearingTime));
+ tDelta = tDelta - syms * (ts + clearingTime);
+
+ // Align to pktRx
+ if (arrTime + Seconds (maxTapDelay) > it->GetArrivalTime ())
+ {
+ tDelta = ts + clearingTime - tDelta;
+ }
+
+ double intPower = 0.0;
+ if (tDelta < ts)
+ {
+ intPower += intPdp.SumTapsNc (Seconds (0), Seconds (ts - tDelta));
+ intPower += intPdp.SumTapsNc (Seconds (ts - tDelta + clearingTime),
+ Seconds (2 * ts - tDelta + clearingTime));
+ }
+ else
+ {
+ Time start = Seconds (ts + clearingTime - tDelta);
+ Time end = start + Seconds (ts);
+ intPower += intPdp.SumTapsNc (start, end);
+
+ start = start + Seconds (ts + clearingTime);
+ end = start + Seconds (ts);
+ intPower += intPdp.SumTapsNc (start, end);
+ }
+ intKp += DbToKp (it->GetRxPowerDb ()) * intPower;
+ }
+
+ double totalIntDb = KpToDb (isiUpa + intKp + DbToKp (ambNoiseDb));
+
+ NS_LOG_DEBUG ("Calculating SINR: RxPower = " << rxPowerDb << " dB. Effective Rx power " << effRxPowerDb << " dB. Number of interferers = " << arrivalList.size () << " Interference + noise power = " << totalIntDb << " dB. SINR = " << effRxPowerDb - totalIntDb << " dB.");
+ return effRxPowerDb - totalIntDb;
+}
+
+/*************** UanPhyPerGenDefault definition *****************/
+UanPhyPerGenDefault::UanPhyPerGenDefault ()
+{
+
+}
+
+UanPhyPerGenDefault::~UanPhyPerGenDefault ()
+{
+
+}
+TypeId
+UanPhyPerGenDefault::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPhyPerGenDefault")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyPerGenDefault> ()
+ .AddAttribute ("Threshold", "SINR cutoff for good packet reception",
+ DoubleValue (8),
+ MakeDoubleAccessor (&UanPhyPerGenDefault::m_thresh),
+ MakeDoubleChecker<double> ());
+ return tid;
+}
+
+
+// Default PER calculation simply compares SINR to a threshold which is configurable
+// via an attribute.
+double
+UanPhyPerGenDefault::CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode)
+{
+ if (sinrDb >= m_thresh)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*************** UanPhyPerUmodem definition *****************/
+UanPhyPerUmodem::UanPhyPerUmodem ()
+{
+
+}
+UanPhyPerUmodem::~UanPhyPerUmodem ()
+{
+
+}
+
+TypeId UanPhyPerUmodem::GetTypeId (void)
+{
+ static TypeId tid =
+ TypeId ("ns3::UanPhyPerUmodem")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyPerUmodem> ()
+ ;
+ return tid;
+}
+
+double
+UanPhyPerUmodem::NChooseK (uint32_t n, uint32_t k)
+{
+ double result;
+
+ result = 1.0;
+
+ for (uint32_t i = std::max (k,n - k) + 1; i <= n; ++i)
+ {
+ result *= i;
+ }
+
+ for (uint32_t i = 2; i <= std::min (k,n - k); ++i)
+ {
+ result /= i;
+ }
+
+ return result;
+}
+
+double
+UanPhyPerUmodem::CalcPer (Ptr<Packet> pkt, double sinr, UanTxMode mode)
+{
+ uint32_t d[] =
+ { 12, 14, 16, 18, 20, 22, 24, 26, 28 };
+ double Bd[] =
+ {
+ 33, 281, 2179, 15035LLU, 105166LLU, 692330LLU, 4580007LLU, 29692894LLU,
+ 190453145LLU
+ };
+
+ // double Rc = 1.0 / 2.0;
+ double ebno = std::pow (10.0, sinr / 10.0);
+ double perror = 1.0 / (2.0 + ebno);
+ double P[9];
+
+ if (sinr >= 10)
+ {
+ return 0;
+ }
+ if (sinr <= 6)
+ {
+ return 1;
+ }
+
+ for (uint32_t r = 0; r < 9; r++)
+ {
+ double sumd = 0;
+ for (uint32_t k = 0; k < d[r]; k++)
+ {
+ sumd = sumd + NChooseK (d[r] - 1 + k, k) * std::pow (1 - perror, (double) k);
+ }
+ P[r] = std::pow (perror, (double) d[r]) * sumd;
+
+ }
+
+ double Pb = 0;
+ for (uint32_t r = 0; r < 8; r++)
+ {
+ Pb = Pb + Bd[r] * P[r];
+ }
+
+ // cout << "Pb = " << Pb << endl;
+ uint32_t bits = pkt->GetSize () * 8;
+
+ double Ppacket = 1;
+ double temp = NChooseK (bits, 0);
+ temp *= std::pow ( (1 - Pb), (double) bits);
+ Ppacket -= temp;
+ temp = NChooseK (288, 1) * Pb * std::pow ( (1 - Pb), bits - 1.0);
+ Ppacket -= temp;
+
+ if (Ppacket > 1)
+ {
+ return 1;
+ }
+ else
+ {
+ return Ppacket;
+ }
+}
+
+/*************** UanPhyGen definition *****************/
+UanPhyGen::UanPhyGen ()
+ : UanPhy (),
+ m_state (IDLE),
+ m_channel (0),
+ m_transducer (0),
+ m_device (0),
+ m_mac (0),
+ m_rxGainDb (0),
+ m_txPwrDb (0),
+ m_rxThreshDb (0),
+ m_ccaThreshDb (0),
+ m_pktRx (0)
+{
+
+}
+
+UanPhyGen::~UanPhyGen ()
+{
+
+}
+
+void
+UanPhyGen::DoDispose ()
+{
+ m_listeners.clear ();
+ m_channel = 0;
+ m_transducer = 0;
+ m_device = 0;
+ m_mac = 0;
+ m_per = 0;
+ m_sinr = 0;
+ m_pktRx = 0;
+ UanPhy::DoDispose ();
+}
+
+UanModesList
+UanPhyGen::GetDefaultModes (void)
+{
+ UanModesList l;
+ l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::FSK,80,80,22000,4000,13,"FSK"));
+ l.AppendMode (UanTxModeFactory::CreateMode (UanTxMode::PSK,200, 200, 22000, 4000, 4, "QPSK"));
+ return l;
+}
+TypeId
+UanPhyGen::GetTypeId (void)
+{
+
+ static TypeId tid = TypeId ("ns3::UanPhyGen")
+ .SetParent<Object> ()
+ .AddConstructor<UanPhyGen> ()
+ .AddAttribute ("CcaThreshold",
+ "Aggregate energy of incoming signals to move to CCA Busy state dB",
+ DoubleValue (10),
+ MakeDoubleAccessor (&UanPhyGen::m_ccaThreshDb),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxThreshold",
+ "Required SNR for signal acquisition in dB",
+ DoubleValue (10),
+ MakeDoubleAccessor (&UanPhyGen::m_rxThreshDb),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPower",
+ "Transmission output power in dB",
+ DoubleValue (190),
+ MakeDoubleAccessor (&UanPhyGen::m_txPwrDb),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxGain",
+ "Gain added to incoming signal at receiver",
+ DoubleValue (0),
+ MakeDoubleAccessor (&UanPhyGen::m_rxGainDb),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("SupportedModes",
+ "List of modes supported by this PHY",
+ UanModesListValue (UanPhyGen::GetDefaultModes ()),
+ MakeUanModesListAccessor (&UanPhyGen::m_modes),
+ MakeUanModesListChecker () )
+ .AddAttribute ("PerModel",
+ "Functor to calculate PER based on SINR and TxMode",
+ PointerValue (CreateObject<UanPhyPerGenDefault> ()),
+ MakePointerAccessor (&UanPhyGen::m_per),
+ MakePointerChecker<UanPhyPer> ())
+ .AddAttribute ("SinrModel",
+ "Functor to calculate SINR based on pkt arrivals and modes",
+ PointerValue (CreateObject<UanPhyCalcSinrDefault> ()),
+ MakePointerAccessor (&UanPhyGen::m_sinr),
+ MakePointerChecker<UanPhyCalcSinr> ())
+ .AddTraceSource ("RxOk",
+ "A packet was received successfully",
+ MakeTraceSourceAccessor (&UanPhyGen::m_rxOkLogger))
+ .AddTraceSource ("RxError",
+ "A packet was received unsuccessfully",
+ MakeTraceSourceAccessor (&UanPhyGen::m_rxErrLogger))
+ .AddTraceSource ("Tx",
+ "Packet transmission beginning",
+ MakeTraceSourceAccessor (&UanPhyGen::m_txLogger))
+ ;
+ return tid;
+
+}
+
+void
+UanPhyGen::SendPacket (Ptr<Packet> pkt, uint32_t modeNum)
+{
+ NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Transmitting packet");
+ if (m_state == TX)
+ {
+ NS_LOG_DEBUG ("PHY requested to TX while already Transmitting. Dropping packet.");
+ return;
+ }
+
+ UanTxMode txMode = GetMode (modeNum);
+
+ if (m_pktRx != 0)
+ {
+ m_minRxSinrDb = -1e30;
+ m_pktRx = 0;
+ }
+
+ m_transducer->Transmit (Ptr<UanPhy> (this), pkt, m_txPwrDb, txMode);
+ m_state = TX;
+ double txdelay = pkt->GetSize () * 8.0 / txMode.GetDataRateBps ();
+ Simulator::Schedule (Seconds (txdelay), &UanPhyGen::TxEndEvent, this);
+ NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << " notifying listeners");
+ NotifyListenersTxStart (Seconds (txdelay));
+ m_txLogger (pkt, m_txPwrDb, txMode);
+}
+
+void
+UanPhyGen::TxEndEvent ()
+{
+ NS_ASSERT (m_state = TX);
+ if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
+ {
+ m_state = CCABUSY;
+ NotifyListenersCcaStart ();
+ }
+ else
+ {
+ m_state = IDLE;
+ }
+}
+
+void
+UanPhyGen::RegisterListener (UanPhyListener *listener)
+{
+ m_listeners.push_back (listener);
+}
+
+
+void
+UanPhyGen::StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp)
+{
+ switch (m_state)
+ {
+ case TX:
+ NS_ASSERT (false);
+ break;
+ case RX:
+ {
+ NS_ASSERT (m_pktRx);
+ double newSinrDb = CalculateSinrDb (m_pktRx, m_pktRxArrTime, m_rxRecvPwrDb, m_pktRxMode, m_pktRxPdp);
+ m_minRxSinrDb = (newSinrDb < m_minRxSinrDb) ? newSinrDb : m_minRxSinrDb;
+ NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in RX mode. SINR of pktRx = " << m_minRxSinrDb);
+ }
+ break;
+
+ case CCABUSY:
+ case IDLE:
+ {
+ NS_ASSERT (!m_pktRx);
+ bool hasmode = false;
+ for (uint32_t i = 0; i < GetNModes (); i++)
+ {
+ if (txMode.GetUid () == GetMode (i).GetUid ())
+ {
+ hasmode = true;
+ break;
+ }
+ }
+ if (!hasmode)
+ {
+ break;
+ }
+
+
+ double newsinr = CalculateSinrDb (pkt, Simulator::Now (), rxPowerDb, txMode, pdp);
+ NS_LOG_DEBUG ("PHY " << m_mac->GetAddress () << ": Starting RX in IDLE mode. SINR = " << newsinr);
+ if (newsinr > m_rxThreshDb)
+ {
+ m_state = RX;
+ m_rxRecvPwrDb = rxPowerDb;
+ m_minRxSinrDb = newsinr;
+ m_pktRx = pkt;
+ m_pktRxArrTime = Simulator::Now ();
+ m_pktRxMode = txMode;
+ m_pktRxPdp = pdp;
+ double txdelay = pkt->GetSize () * 8.0 / txMode.GetDataRateBps ();
+ Simulator::Schedule (Seconds (txdelay), &UanPhyGen::RxEndEvent, this, pkt, rxPowerDb, txMode);
+ NotifyListenersRxStart ();
+ }
+
+ }
+ break;
+ }
+
+ if (m_state == IDLE && GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
+ {
+ m_state = CCABUSY;
+ NotifyListenersCcaStart ();
+ }
+
+}
+
+void
+UanPhyGen::RxEndEvent (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode)
+{
+ if (pkt != m_pktRx)
+ {
+ return;
+ }
+
+ if (GetInterferenceDb ( (Ptr<Packet>) 0) > m_ccaThreshDb)
+ {
+ m_state = CCABUSY;
+ NotifyListenersCcaStart ();
+ }
+ else
+ {
+ m_state = IDLE;
+ }
+
+ UniformVariable pg;
+
+ if (pg.GetValue (0, 1) > m_per->CalcPer (m_pktRx, m_minRxSinrDb, txMode))
+ {
+ m_rxOkLogger (pkt, m_minRxSinrDb, txMode);
+ NotifyListenersRxGood ();
+ if (!m_recOkCb.IsNull ())
+ {
+ m_recOkCb (pkt, m_minRxSinrDb, txMode);
+ }
+
+ }
+ else
+ {
+ m_rxErrLogger (pkt, m_minRxSinrDb, txMode);
+ NotifyListenersRxBad ();
+ if (!m_recErrCb.IsNull ())
+ {
+ m_recErrCb (pkt, m_minRxSinrDb);
+ }
+ }
+
+ m_pktRx = 0;
+}
+
+void
+UanPhyGen::SetReceiveOkCallback (RxOkCallback cb)
+{
+ m_recOkCb = cb;
+}
+
+void
+UanPhyGen::SetReceiveErrorCallback (RxErrCallback cb)
+{
+ m_recErrCb = cb;
+}
+
+
+bool
+UanPhyGen::IsStateIdle (void)
+{
+ return m_state == IDLE;
+}
+bool
+UanPhyGen::IsStateBusy (void)
+{
+ return m_state != IDLE;
+}
+bool
+UanPhyGen::IsStateRx (void)
+{
+ return m_state == RX;
+}
+bool
+UanPhyGen::IsStateTx (void)
+{
+ return m_state == TX;
+}
+
+bool
+UanPhyGen::IsStateCcaBusy (void)
+{
+ return m_state == CCABUSY;
+}
+
+
+void
+UanPhyGen::SetRxGainDb (double gain)
+{
+ m_rxGainDb = gain;
+
+}
+void
+UanPhyGen::SetTxPowerDb (double txpwr)
+{
+ m_txPwrDb = txpwr;
+}
+void
+UanPhyGen::SetRxThresholdDb (double thresh)
+{
+ m_rxThreshDb = thresh;
+}
+void
+UanPhyGen::SetCcaThresholdDb (double thresh)
+{
+ m_ccaThreshDb = thresh;
+}
+double
+UanPhyGen::GetRxGainDb (void)
+{
+ return m_rxGainDb;
+}
+double
+UanPhyGen::GetTxPowerDb (void)
+{
+ return m_txPwrDb;
+
+}
+double
+UanPhyGen::GetRxThresholdDb (void)
+{
+ return m_rxThreshDb;
+}
+double
+UanPhyGen::GetCcaThresholdDb (void)
+{
+ return m_ccaThreshDb;
+}
+
+Ptr<UanChannel>
+UanPhyGen::GetChannel (void) const
+{
+ return m_channel;
+}
+
+Ptr<UanNetDevice>
+UanPhyGen::GetDevice (void)
+{
+ return m_device;
+}
+
+Ptr<UanTransducer>
+UanPhyGen::GetTransducer (void)
+{
+ return m_transducer;
+}
+void
+UanPhyGen::SetChannel (Ptr<UanChannel> channel)
+{
+ m_channel = channel;
+}
+
+void
+UanPhyGen::SetDevice (Ptr<UanNetDevice> device)
+{
+ m_device = device;
+}
+
+void
+UanPhyGen::SetMac (Ptr<UanMac> mac)
+{
+ m_mac = mac;
+}
+
+void
+UanPhyGen::SetTransducer (Ptr<UanTransducer> trans)
+{
+ m_transducer = trans;
+ m_transducer->AddPhy (this);
+}
+
+
+void
+UanPhyGen::NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode)
+{
+ if (m_pktRx)
+ {
+ m_minRxSinrDb = -1e30;
+ }
+}
+
+void
+UanPhyGen::NotifyIntChange (void)
+{
+ if (m_state == CCABUSY && GetInterferenceDb (Ptr<Packet> ()) < m_ccaThreshDb)
+ {
+ m_state = IDLE;
+ NotifyListenersCcaEnd ();
+ }
+}
+
+double
+UanPhyGen::CalculateSinrDb (Ptr<Packet> pkt, Time arrTime, double rxPowerDb, UanTxMode mode, UanPdp pdp)
+{
+ double noiseDb = m_channel->GetNoiseDbHz ( (double) mode.GetCenterFreqHz () / 1000.0) + 10 * log10 (mode.GetBandwidthHz ());
+ return m_sinr->CalcSinrDb (pkt, arrTime, rxPowerDb, noiseDb, mode, pdp, m_transducer->GetArrivalList ());
+}
+
+double
+UanPhyGen::GetInterferenceDb (Ptr<Packet> pkt)
+{
+
+ const UanTransducer::ArrivalList &arrivalList = m_transducer->GetArrivalList ();
+
+ UanTransducer::ArrivalList::const_iterator it = arrivalList.begin ();
+
+ double interfPower = 0;
+
+ for (; it != arrivalList.end (); it++)
+ {
+ if (pkt != it->GetPacket ())
+ {
+ interfPower += DbToKp (it->GetRxPowerDb ());
+ }
+ }
+
+ return KpToDb (interfPower);
+
+}
+
+double
+UanPhyGen::DbToKp (double db)
+{
+ return pow (10, db / 10.0);
+}
+double
+UanPhyGen::KpToDb (double kp)
+{
+ return 10 * log10 (kp);
+}
+
+void
+UanPhyGen::NotifyListenersRxStart (void)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyRxStart ();
+ }
+
+}
+void
+UanPhyGen::NotifyListenersRxGood (void)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyRxEndOk ();
+ }
+}
+void
+UanPhyGen::NotifyListenersRxBad (void)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyRxEndError ();
+ }
+}
+void
+UanPhyGen::NotifyListenersCcaStart (void)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyCcaStart ();
+ }
+}
+void
+UanPhyGen::NotifyListenersCcaEnd (void)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyCcaEnd ();
+ }
+}
+
+void
+UanPhyGen::NotifyListenersTxStart (Time duration)
+{
+ ListenerList::const_iterator it = m_listeners.begin ();
+ for (; it != m_listeners.end (); it++)
+ {
+ (*it)->NotifyTxStart (duration);
+ }
+}
+
+uint32_t
+UanPhyGen::GetNModes (void)
+{
+ return m_modes.GetNModes ();
+}
+
+UanTxMode
+UanPhyGen::GetMode (uint32_t n)
+{
+ NS_ASSERT (n < m_modes.GetNModes ());
+
+ return m_modes[n];
+}
+
+Ptr<Packet>
+UanPhyGen::GetPacketRx (void) const
+{
+ return m_pktRx;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-phy-gen.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANPHYGEN_H
+#define UANPHYGEN_H
+
+
+#include "uan-phy.h"
+#include "ns3/traced-callback.h"
+#include "ns3/nstime.h"
+#include <list>
+
+namespace ns3 {
+
+/**
+ * \class UanPhyPerGenDefault
+ * \brief Default Packet Error Rate calculator for UanPhyGen
+ * Considers no error if SINR is > user defined threshold
+ * (configured by an attribute).
+ */
+class UanPhyPerGenDefault : public UanPhyPer
+{
+public:
+ UanPhyPerGenDefault ();
+ virtual ~UanPhyPerGenDefault ();
+
+ static TypeId GetTypeId (void);
+ virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode);
+private:
+ double m_thresh;
+
+};
+
+/**
+ * \class UanPhyPerUmodem
+ * \brief Packet error rate calculation assuming WHOI Micromodem like PHY
+ * Calculates PER assuming rate 1/2 convolutional code with constraint length 9
+ * with soft decision viterbi decoding and a CRC capable of correcting 1 bit error
+ */
+class UanPhyPerUmodem : public UanPhyPer
+{
+public:
+ UanPhyPerUmodem ();
+ virtual ~UanPhyPerUmodem ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ *
+ * This implementation uses calculations
+ * for binary FSK modulation coded by a rate 1/2 convolutional code
+ * with constraint length = 9 and a viterbi decoder and finally a CRC capable
+ * of correcting one bit error. These equations can be found in
+ * the book, Digital Communications, by Proakis (Any version I think)
+ *
+ * \param pkt Packet which is under consideration
+ * \param sinrDb SINR at receiver
+ * \param mode TX mode used to transmit packet
+ * \returns Probability of packet error
+ */
+ virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode);
+private:
+ double NChooseK (uint32_t n, uint32_t k);
+
+};
+/**
+ * \class UanPhyCalcSinrDefault
+ * \brief Default SINR calculator for UanPhyGen
+ * The default ignores mode data and assumes that all rxpower transmitted is
+ * captured by the receiver, and that all signal power associated with
+ * interfering packets affects SINR identically to additional ambient noise.
+ */
+class UanPhyCalcSinrDefault : public UanPhyCalcSinr
+{
+
+public:
+ UanPhyCalcSinrDefault ();
+ virtual ~UanPhyCalcSinrDefault ();
+ static TypeId GetTypeId (void);
+ /**
+ * This implementation simply adds all arriving signal power
+ * and assumes it acts identically to additional noise.
+ *
+ * \param pkt Packet which is under consideration
+ * \param arrTime Arrival time of packet pkt
+ * \param rxPowerDb Received signal power at receiver
+ * \param mode TX mode used to transmit packet
+ * \param pdp Power delay profile of arriving packet pkt
+ * \param arrivalList List of other, simultaneously arriving packets
+ * \returns Probability of packet error
+ */
+ virtual double CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList
+ ) const;
+};
+
+/**
+ * \class UanPhyCalcSinrFhFsk
+ * \brief WHOI Micromodem like FH-FSK model
+ *
+ * Model of interference calculation for FH-FSK wherein all nodes
+ * use an identical hopping pattern. In this case, there is an (M-1)*SymbolTime
+ * clearing time between symbols transmitted on the same frequency.
+ * This clearing time combats ISI from channel delay spread and also has
+ * a byproduct of possibly reducing interference from other transmitted packets.
+ */
+class UanPhyCalcSinrFhFsk : public UanPhyCalcSinr
+{
+
+public:
+ UanPhyCalcSinrFhFsk ();
+ virtual ~UanPhyCalcSinrFhFsk ();
+ static TypeId GetTypeId (void);
+ virtual double CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList
+ ) const;
+private:
+ uint32_t m_hops;
+};
+
+/**
+ * \class UanPhyGen
+ * \brief Generic PHY model
+ *
+ * This is a generic PHY class. SINR and PER information
+ * are controlled via attributes. By adapting the SINR
+ * and PER models to a specific situation, this PHY should
+ * be able to model a wide variety of networks.
+ */
+class UanPhyGen : public UanPhy
+{
+public:
+ UanPhyGen ();
+ virtual ~UanPhyGen ();
+ /**
+ * \returns Default TX modes of UanPhyGen
+ */
+ static UanModesList GetDefaultModes (void);
+
+ static TypeId GetTypeId (void);
+ virtual void SendPacket (Ptr<Packet> pkt, uint32_t modeNum);
+ virtual void RegisterListener (UanPhyListener *listener);
+ virtual void StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp);
+ virtual void SetReceiveOkCallback (RxOkCallback cb);
+ virtual void SetReceiveErrorCallback (RxErrCallback cb);
+ virtual bool IsStateIdle (void);
+ virtual bool IsStateBusy (void);
+ virtual bool IsStateRx (void);
+ virtual bool IsStateTx (void);
+ virtual bool IsStateCcaBusy (void);
+ virtual void SetRxGainDb (double gain);
+ virtual void SetTxPowerDb (double txpwr);
+ virtual void SetRxThresholdDb (double thresh);
+ virtual void SetCcaThresholdDb (double thresh);
+ virtual double GetRxGainDb (void);
+ virtual double GetTxPowerDb (void);
+ virtual double GetRxThresholdDb (void);
+ virtual double GetCcaThresholdDb (void);
+ virtual Ptr<UanChannel> GetChannel (void) const;
+ virtual Ptr<UanNetDevice> GetDevice (void);
+ virtual Ptr<UanTransducer> GetTransducer (void);
+ virtual void SetChannel (Ptr<UanChannel> channel);
+ virtual void SetDevice (Ptr<UanNetDevice> device);
+ virtual void SetMac (Ptr<UanMac> mac);
+ virtual void SetTransducer (Ptr<UanTransducer> trans);
+ virtual void NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode);
+ virtual void NotifyIntChange (void);
+ virtual uint32_t GetNModes (void);
+ virtual UanTxMode GetMode (uint32_t n);
+ virtual Ptr<Packet> GetPacketRx (void) const;
+
+private:
+ typedef std::list<UanPhyListener *> ListenerList;
+
+ UanModesList m_modes;
+
+ State m_state;
+ ListenerList m_listeners;
+ RxOkCallback m_recOkCb;
+ RxErrCallback m_recErrCb;
+ Ptr<UanChannel> m_channel;
+ Ptr<UanTransducer> m_transducer;
+ Ptr<UanNetDevice> m_device;
+ Ptr<UanMac> m_mac;
+ Ptr<UanPhyPer> m_per;
+ Ptr<UanPhyCalcSinr> m_sinr;
+
+ double m_rxGainDb;
+ double m_txPwrDb;
+ double m_rxThreshDb;
+ double m_ccaThreshDb;
+
+
+ Ptr<Packet> m_pktRx;
+ double m_minRxSinrDb;
+ double m_rxRecvPwrDb;
+ Time m_pktRxArrTime;
+ UanPdp m_pktRxPdp;
+ UanTxMode m_pktRxMode;
+
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_rxOkLogger;
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_rxErrLogger;
+ TracedCallback<Ptr<const Packet>, double, UanTxMode > m_txLogger;
+
+
+ double CalculateSinrDb (Ptr<Packet> pkt, Time arrTime, double rxPowerDb, UanTxMode mode, UanPdp pdp);
+ double GetInterferenceDb (Ptr<Packet> pkt);
+ double DbToKp (double db);
+ double KpToDb (double kp);
+ void RxEndEvent (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode);
+ void TxEndEvent ();
+
+ void NotifyListenersRxStart (void);
+ void NotifyListenersRxGood (void);
+ void NotifyListenersRxBad (void);
+ void NotifyListenersCcaStart (void);
+ void NotifyListenersCcaEnd (void);
+ void NotifyListenersTxStart (Time duration);
+protected:
+ virtual void DoDispose ();
+
+};
+
+} // namespace ns3
+
+#endif // UANPHYGEN_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-phy.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,340 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+
+#ifndef UANPHY_H
+#define UANPHY_H
+
+#include "ns3/object.h"
+#include "ns3/uan-mac.h"
+#include "ns3/uan-tx-mode.h"
+#include "ns3/uan-prop-model.h"
+#include "ns3/uan-transducer.h"
+
+namespace ns3 {
+
+
+/**
+ * \class UanPhyCalcSinr
+ *
+ * Class used for calculating SINR of packet in UanPhy.
+ * Can be set to any derived class using attributes of UanPhy
+ * to implement different models.
+ */
+class UanPhyCalcSinr : public ns3::Object
+{
+
+public:
+ /**
+ * \param pkt Packet to calculate SINR for
+ * \param arrTime Arrival time of pkt
+ * \param rxPowerDb The received signal strength of the packet in dB re 1 uPa
+ * \param ambNoiseDb Ambient channel noise in dB re 1 uPa
+ * \param mode TX Mode of pkt
+ * \param pdp Power delay profile of pkt
+ * \param arrivalList List of interfering arrivals given from Transducer.
+ */
+ virtual double CalcSinrDb (Ptr<Packet> pkt,
+ Time arrTime,
+ double rxPowerDb,
+ double ambNoiseDb,
+ UanTxMode mode,
+ UanPdp pdp,
+ const UanTransducer::ArrivalList &arrivalList
+ ) const = 0;
+ /**
+ * \param db dB value
+ * \returns kilopascals
+ * \brief Converts dB re 1 uPa to kilopascals
+ */
+ inline double DbToKp (double db) const
+ {
+ return pow (10, db / 10.0);
+ }
+ /**
+ * \param kp value in kilopascals
+ * \returns dB re 1 uPa
+ * \brief Converts kilopascals to dB re 1 uPa
+ */
+ inline double KpToDb (double kp) const
+ {
+ return 10 * log10 (kp);
+ }
+};
+
+/**
+ * \class UanPhyPer
+ * Used in UanPhy for determining probability of packet error based on received SINR and
+ * modulation (mode). Can be set in UanPhy via attributes
+ */
+class UanPhyPer : public ns3::Object
+{
+public:
+ /**
+ * Calculates the prob. of packet error based on
+ * SINR at the receiver and a tx mode.
+ * \param pkt Packet which is under consideration
+ * \param sinrDb SINR at receiver
+ * \param mode TX mode used to transmit packet
+ * \returns Probability of packet error
+ */
+ virtual double CalcPer (Ptr<Packet> pkt, double sinrDb, UanTxMode mode) = 0;
+};
+
+
+/**
+ * \class UanPhyListener
+ *
+ * \brief Interface for PHY event listener
+ * A class which implements this interface may register with Phy object
+ * to receive notification of TX/RX/CCA events
+ */
+class UanPhyListener
+{
+public:
+ /**
+ * \brief Function called when Phy object begins receiving packet
+ */
+ virtual void NotifyRxStart (void) = 0;
+ /**
+ * \brief Function called when Phy object finishes receiving packet without error
+ */
+ virtual void NotifyRxEndOk (void) = 0;
+ /**
+ * \brief Function called when Phy object finishes receiving packet in error
+ */
+ virtual void NotifyRxEndError (void) = 0;
+ /**
+ * \brief Function called when Phy object begins sensing channel is busy
+ */
+ virtual void NotifyCcaStart (void) = 0;
+ /**
+ * \brief Function called when Phy object stops sensing channel is busy
+ */
+ virtual void NotifyCcaEnd (void) = 0;
+ /**
+ * \param duration Duration of transmission
+ * \brief Function called when transmission starts from Phy object
+ */
+ virtual void NotifyTxStart (Time duration) = 0;
+};
+
+/**
+ * \class UanPhy
+ *
+ * \brief Base class for UAN Phy models
+ */
+class UanPhy : public ns3::Object
+{
+public:
+ /// Enum defining possible Phy states
+ enum State {
+ IDLE, CCABUSY, RX, TX
+ };
+
+ /**
+ * arg1: packet received successfully
+ * arg2: snr of packet
+ * arg3: mode of packet
+ */
+ typedef Callback<void, Ptr<Packet>, double, UanTxMode> RxOkCallback;
+
+ /**
+ * arg1: packet received successfully
+ * arg2: snr of packet
+ */
+ typedef Callback<void, Ptr<Packet>, double > RxErrCallback;
+
+ /**
+ * \param pkt Packet to transmit
+ * \param modeNum Index of mode in SupportedModes list to use for transmission
+ */
+ virtual void SendPacket (Ptr<Packet> pkt, uint32_t modeNum) = 0;
+
+ /**
+ * \param listener New listener to register
+ *
+ * Register an object to be notified of common Phy events
+ */
+ virtual void RegisterListener (UanPhyListener *listener) = 0;
+
+ /**
+ * \brief Packet arriving from channel: i.e. leading bit of packet has arrived.
+ * \param pkt Packet which is arriving
+ * \param rxPowerDb Signal power of incoming packet in dB
+ * \param txMode Transmission mode defining modulation of incoming packet
+ * \param pdp Power delay profile of incoming packet
+ */
+ virtual void StartRxPacket (Ptr<Packet> pkt, double rxPowerDb, UanTxMode txMode, UanPdp pdp) = 0;
+
+ /**
+ * \param cb Callback to be enabled when packet is received without error
+ */
+ virtual void SetReceiveOkCallback (RxOkCallback cb) = 0;
+
+ /**
+ * \param cb Callback to be enabled when a packet is received with errors
+ */
+ virtual void SetReceiveErrorCallback (RxErrCallback cb) = 0;
+
+ /**
+ * \param gain Gain added at receiver
+ */
+
+ virtual void SetRxGainDb (double gain) = 0;
+
+ /**
+ * \param txpwr Final output transmission power in dB
+ */
+ virtual void SetTxPowerDb (double txpwr) = 0;
+
+ /**
+ * \param thresh Threshold SINR for propper reception in dB
+ */
+ virtual void SetRxThresholdDb (double thresh) = 0;
+
+ /**
+ * \param thresh Signal power at receiver required for CCA busy state
+ *
+ */
+ virtual void SetCcaThresholdDb (double thresh) = 0;
+
+ /**
+ * \returns Gain added to signal at receiver in dB
+ */
+ virtual double GetRxGainDb (void) = 0;
+
+ /**
+ * \returns Current TX power output
+ */
+ virtual double GetTxPowerDb (void) = 0;
+
+ /**
+ * \returns Required signal strength, in dB, to begin receiving packet
+ */
+ virtual double GetRxThresholdDb (void) = 0;
+
+ /**
+ * \returns Threshold signal strength in dB to enter CCA busy mode
+ */
+ virtual double GetCcaThresholdDb (void) = 0;
+
+ /**
+ *
+ * \returns True if Phy is IDLE
+ */
+ virtual bool IsStateIdle (void) = 0;
+ /**
+ *
+ * \returns True if Phy is not IDLE
+ */
+ virtual bool IsStateBusy (void) = 0;
+ /**
+ *
+ * \returns True if Phy is currently in receive mode
+ */
+ virtual bool IsStateRx (void) = 0;
+ /**
+ *
+ * \returns True if Phy is busy transmitting
+ */
+ virtual bool IsStateTx (void) = 0;
+ /**
+ *
+ * \returns True if Phy is not TX or RX but the channel is sensed busy
+ */
+ virtual bool IsStateCcaBusy (void) = 0;
+
+ /**
+ * \returns Channel this phy is attached to
+ */
+ virtual Ptr<UanChannel> GetChannel (void) const = 0;
+
+ /**
+ * \returns the Net Device that this Phy is a part of
+ */
+ virtual Ptr<UanNetDevice> GetDevice (void) = 0;
+
+ /**
+ * \param channel The channel this Phy is attached to
+ */
+ virtual void SetChannel (Ptr<UanChannel> channel) = 0;
+
+ /**
+ * \param device The Net Device this Phy is a part of
+ */
+ virtual void SetDevice (Ptr<UanNetDevice> device) = 0;
+
+ /**
+ * \param mac The MAC forwarding messages to this Phy
+ */
+ virtual void SetMac (Ptr<UanMac> mac) = 0;
+
+ /**
+ * \param packet Packet that is beginning transmission
+ * \param txPowerDb Transmit power of packet
+ * \param txMode Transmission mode of packet
+ *
+ * Notification that there is a transmission beginning
+ * on the transducer that this Phy is attached to.
+ */
+
+ virtual void NotifyTransStartTx (Ptr<Packet> packet, double txPowerDb, UanTxMode txMode) = 0;
+
+ /**
+ *
+ * Function called when there has been a change in the
+ * ammount of interference this node is experiencing
+ * from other transmissions
+ */
+ virtual void NotifyIntChange (void) = 0;
+
+ /**
+ *
+ * \param trans Transducer this Phy outputs to / receives from
+ */
+ virtual void SetTransducer (Ptr<UanTransducer> trans) = 0;
+
+ /**
+ * \returns Transducer this Phy outputs to / receives from
+ */
+ virtual Ptr<UanTransducer> GetTransducer (void) = 0;
+
+ /**
+ * \returns Number of TX modes supported by this PHY
+ */
+ virtual uint32_t GetNModes (void) = 0;
+
+ /**
+ * \param n Mode number of mode to return (place in Modeslist)
+ * \returns Mode n
+ */
+ virtual UanTxMode GetMode (uint32_t n) = 0;
+
+ /**
+ * \warning Returns non-valid pointer if IsStateRx == false
+ * \returns Packet currently being received in PHY
+ */
+ virtual Ptr<Packet> GetPacketRx (void) const = 0;
+};
+
+}
+
+#endif // UANPHY_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model-ideal.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-prop-model-ideal.h"
+#include "uan-tx-mode.h"
+#include "ns3/mobility-model.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanPropModelIdeal);
+
+UanPropModelIdeal::UanPropModelIdeal ()
+{
+}
+
+UanPropModelIdeal::~UanPropModelIdeal ()
+{
+}
+
+TypeId
+UanPropModelIdeal::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPropModelIdeal")
+ .SetParent<Object> ()
+ .AddConstructor<UanPropModelIdeal> ()
+ ;
+ return tid;
+}
+
+
+double
+UanPropModelIdeal::GetPathLossDb (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+
+ return 0;
+}
+UanPdp
+UanPropModelIdeal::GetPdp (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+ return UanPdp::CreateImpulsePdp ();
+}
+
+Time
+UanPropModelIdeal::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+ return Seconds (a->GetDistanceFrom (b) / 1500.0);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model-ideal.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANPROPMODELIDEAL_H_
+#define UANPROPMODELIDEAL_H_
+
+#include "uan-prop-model.h"
+#include "ns3/mobility-model.h"
+#include "ns3/nstime.h"
+namespace ns3 {
+
+/**
+ * \class UanPropModelIdeal
+ *
+ * \brief Ideal propagation model (no pathloss, impulse PDP)
+ */
+class UanPropModelIdeal : public ns3::UanPropModel
+{
+public:
+ UanPropModelIdeal ();
+ virtual ~UanPropModelIdeal ();
+
+ static TypeId GetTypeId (void);
+
+ // Inherited methods
+ virtual double GetPathLossDb (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+ virtual UanPdp GetPdp (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+ virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+};
+
+}
+
+#endif /*UANPROPMODELIDEAL_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model-thorp.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+#include "uan-prop-model-thorp.h"
+#include "uan-tx-mode.h"
+#include "ns3/double.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("UanPropModelThorp");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanPropModelThorp);
+
+UanPropModelThorp::UanPropModelThorp ()
+{
+}
+
+UanPropModelThorp::~UanPropModelThorp ()
+{
+}
+
+TypeId
+UanPropModelThorp::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::UanPropModelThorp")
+ .SetParent<Object> ()
+ .AddConstructor<UanPropModelThorp> ()
+ .AddAttribute ("SpreadCoef",
+ "Spreading coefficient used in calculation of Thorp's approximation",
+ DoubleValue (1.5),
+ MakeDoubleAccessor (&UanPropModelThorp::m_SpreadCoef),
+ MakeDoubleChecker<double> ())
+ ;
+ return tid;
+}
+
+double
+UanPropModelThorp::GetPathLossDb (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+ double distKyd = a->GetDistanceFrom (b) / 1.093613298; // Convert from dB/km to dB/kyd
+
+ return m_SpreadCoef * 10.0 * log10 (distKyd)
+ + distKyd * GetAttenDbKyd (mode.GetCenterFreqHz () / 1000.0);
+}
+
+UanPdp
+UanPropModelThorp::GetPdp (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+ return UanPdp::CreateImpulsePdp ();
+}
+
+Time
+UanPropModelThorp::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode)
+{
+ return Seconds (a->GetDistanceFrom (b) / 1500.0);
+}
+
+double
+UanPropModelThorp::GetAttenDbKyd (double freqKhz)
+{
+
+ double fsq = freqKhz * freqKhz;
+ double atten;
+
+ if (freqKhz < 0.4)
+ {
+ atten = 0.11 * fsq / (1 + fsq) + 44 * fsq / (4100 + freqKhz)
+ + 2.75 * 0.0001 * fsq + 0.003;
+ }
+ else
+ {
+ atten = 0.002 + 0.11 * (freqKhz / (1 + freqKhz)) + 0.011 * freqKhz;
+ }
+
+ return atten;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model-thorp.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANPROPMODELTHORP_H_
+#define UANPROPMODELTHORP_H_
+
+#include "uan-prop-model.h"
+
+namespace ns3 {
+
+class UanTxMode;
+
+/**
+ * \class UanPropModelThorp
+ * \brief Uses Thorp's approximation to compute pathloss. Assumes implulse PDP.
+ */
+class UanPropModelThorp : public ns3::UanPropModel
+{
+public:
+ UanPropModelThorp ();
+ virtual ~UanPropModelThorp ();
+
+ static TypeId GetTypeId (void);
+
+ virtual double GetPathLossDb (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+ virtual UanPdp GetPdp (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+ virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode);
+
+private:
+ double GetAttenDbKyd (double freqKhz);
+
+ double m_SpreadCoef;
+};
+
+}
+
+#endif /* UANPROPMODELTHORP_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-prop-model.h"
+#include "ns3/nstime.h"
+#include <complex>
+#include <vector>
+
+
+namespace ns3 {
+
+std::ostream &
+operator<< (std::ostream &os, UanPdp &pdp)
+{
+ os << pdp.GetNTaps () << '|';
+ os << pdp.GetResolution ().GetSeconds () << '|';
+
+ UanPdp::Iterator it = pdp.m_taps.begin ();
+ for (; it != pdp.m_taps.end (); it++)
+ {
+ os << (*it).GetAmp () << '|';
+ }
+ return os;
+
+}
+std::istream &
+operator>> (std::istream &is, UanPdp &pdp)
+{
+ uint32_t ntaps;
+ double resolution;
+ char c1;
+
+ is >> ntaps >> c1;
+ if (c1 != '|')
+ {
+ NS_FATAL_ERROR ("UanPdp data corrupted at # of taps");
+ return is;
+ }
+ is >> resolution >> c1;
+ if (c1 != '|')
+ {
+ NS_FATAL_ERROR ("UanPdp data corrupted at resolution");
+ return is;
+ }
+ pdp.m_resolution = Seconds (resolution);
+
+
+ std::complex<double> amp;
+ pdp.m_taps = std::vector<Tap> (ntaps);
+ for (uint32_t i = 0; i < ntaps; i++)
+ {
+ is >> amp >> c1;
+ if (c1 != '|')
+ {
+ NS_FATAL_ERROR ("UanPdp data corrupted at tap " << i);
+ return is;
+ }
+ pdp.m_taps[i] = Tap (Seconds (resolution * i), amp);
+ }
+ return is;
+
+}
+
+Tap::Tap ()
+ : m_amplitude (0.0),
+ m_delay (Seconds (0))
+{
+
+}
+
+Tap::Tap (Time delay, std::complex<double> amp)
+ : m_amplitude (amp),
+ m_delay (delay)
+{
+
+}
+
+std::complex<double>
+Tap::GetAmp (void) const
+{
+ return m_amplitude;
+}
+
+Time
+Tap::GetDelay (void) const
+{
+ return m_delay;
+}
+
+
+UanPdp::UanPdp ()
+{
+
+}
+
+UanPdp::UanPdp (std::vector<Tap> taps, Time resolution)
+ : m_taps (taps),
+ m_resolution (resolution)
+{
+}
+
+UanPdp::UanPdp (std::vector<std::complex<double> > amps, Time resolution)
+ : m_resolution (resolution)
+{
+ m_taps.resize (amps.size ());
+ Time arrTime = Seconds (0);
+ for (uint32_t index = 0; index < amps.size (); index++)
+ {
+ m_taps[index] = Tap (arrTime, amps[index]);
+ arrTime = arrTime + m_resolution;
+ }
+}
+
+UanPdp::UanPdp (std::vector<double> amps, Time resolution)
+ : m_resolution (resolution)
+{
+ m_taps.resize (amps.size ());
+ Time arrTime = Seconds (0);
+ for (uint32_t index = 0; index < amps.size (); index++)
+ {
+ m_taps[index] = Tap (arrTime, amps[index]);
+ arrTime = arrTime + m_resolution;
+ }
+}
+
+UanPdp::~UanPdp ()
+{
+ m_taps.clear ();
+}
+
+void
+UanPdp::SetTap (std::complex<double> amp, uint32_t index)
+{
+ if (m_taps.size () <= index)
+ {
+ m_taps.resize (index + 1);
+ }
+
+ Time delay = Seconds (index * m_resolution.GetSeconds ());
+ m_taps[index] = Tap (delay, amp);
+}
+const Tap &
+UanPdp::GetTap (uint32_t i) const
+{
+ NS_ASSERT_MSG (i < GetNTaps (), "Call to UanPdp::GetTap with requested tap out of range");
+ return m_taps[i];
+}
+void
+UanPdp::SetNTaps (uint32_t nTaps)
+{
+ m_taps.resize (nTaps);
+}
+void
+UanPdp::SetResolution (Time resolution)
+{
+ m_resolution = resolution;
+}
+UanPdp::Iterator
+UanPdp::GetBegin (void) const
+{
+ return m_taps.begin ();
+}
+
+UanPdp::Iterator
+UanPdp::GetEnd (void) const
+{
+ return m_taps.end ();
+}
+
+uint32_t
+UanPdp::GetNTaps (void) const
+{
+ return m_taps.size ();
+}
+
+Time
+UanPdp::GetResolution (void) const
+{
+ return m_resolution;
+}
+
+std::complex<double>
+UanPdp::SumTapsFromMaxC (Time delay, Time duration) const
+{
+ if (m_resolution <= Seconds (0))
+ {
+ NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
+ "UanPdp with resolution 0 and multiple taps");
+
+ return m_taps[0].GetAmp ();
+ }
+
+ uint32_t numTaps = (uint32_t)(duration.GetSeconds () / (double) m_resolution.GetSeconds () + 0.5);
+ double maxAmp = -1;
+ uint32_t maxTapIndex;
+
+ for (uint32_t i = 0; i < GetNTaps (); i++)
+ {
+ if (abs (m_taps[i].GetAmp ()) > maxAmp)
+ {
+ maxAmp = abs (m_taps[i].GetAmp ());
+ maxTapIndex = i;
+ }
+ }
+ uint32_t start = maxTapIndex + delay.GetSeconds () / m_resolution.GetSeconds ();
+ uint32_t end = std::min (start + numTaps, GetNTaps ());
+ std::complex<double> sum = 0;
+ for (uint32_t i = start; i < end; i++)
+ {
+ sum += m_taps[i].GetAmp ();
+ }
+ return sum;
+}
+double
+UanPdp::SumTapsFromMaxNc (Time delay, Time duration) const
+{
+ if (m_resolution <= Seconds (0))
+ {
+ NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
+ "UanPdp with resolution 0 and multiple taps");
+
+ return abs (m_taps[0].GetAmp ());
+ }
+
+ uint32_t numTaps = (uint32_t)(duration.GetSeconds () / (double) m_resolution.GetSeconds () + 0.5);
+ double maxAmp = -1;
+ uint32_t maxTapIndex;
+
+ for (uint32_t i = 0; i < GetNTaps (); i++)
+ {
+ if (abs (m_taps[i].GetAmp ()) > maxAmp)
+ {
+ maxAmp = abs (m_taps[i].GetAmp ());
+ maxTapIndex = i;
+ }
+ }
+
+
+ uint32_t start = maxTapIndex + delay.GetSeconds () / m_resolution.GetSeconds ();
+ uint32_t end = std::min (start + numTaps, GetNTaps ());
+ double sum = 0;
+ for (uint32_t i = start; i < end; i++)
+
+ {
+ sum += abs (m_taps[i].GetAmp ());
+ }
+ return sum;
+}
+double
+UanPdp::SumTapsNc (Time begin, Time end) const
+{
+ if (m_resolution <= Seconds (0))
+ {
+ NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
+ "UanPdp with resolution 0 and multiple taps");
+
+ if (begin <= Seconds (0.0) && end >= Seconds (0.0))
+ {
+ return abs (m_taps[0].GetAmp ());
+ }
+ else
+ {
+ return 0.0;
+ }
+ }
+
+ uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
+ uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
+
+ endIndex = std::min (endIndex, GetNTaps ());
+ double sum = 0;
+ for (uint32_t i = stIndex; i < endIndex; i++)
+ {
+ sum += abs (m_taps[i].GetAmp ());
+ }
+ return sum;
+
+}
+
+
+
+std::complex<double>
+UanPdp::SumTapsC (Time begin, Time end) const
+{
+ if (m_resolution <= Seconds (0))
+ {
+ NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
+ "UanPdp with resolution 0 and multiple taps");
+
+ if (begin <= Seconds (0.0) && end >= Seconds (0.0))
+ {
+ return m_taps[0].GetAmp ();
+ }
+ else
+ {
+ return std::complex<double> (0.0);
+ }
+ }
+
+ uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
+ uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
+
+ endIndex = std::min (endIndex, GetNTaps ());
+
+ std::complex<double> sum = 0;
+ for (uint32_t i = stIndex; i < endIndex; i++)
+ {
+ sum += m_taps[i].GetAmp ();
+ }
+ return sum;
+}
+
+UanPdp
+UanPdp::CreateImpulsePdp (void)
+{
+ UanPdp pdp;
+ pdp.SetResolution (Seconds (0));
+ pdp.SetTap (1.0,0);
+ return pdp;
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-prop-model.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANPROPMODEL_H_
+#define UANPROPMODEL_H_
+
+#include "ns3/object.h"
+#include "ns3/mobility-model.h"
+#include "ns3/nstime.h"
+
+
+#include <vector>
+#include <complex>
+#include <utility>
+
+namespace ns3 {
+
+class UanTxMode;
+
+/**
+ * \class Tap
+ * \brief Holds PDP Tap information (amplitude and delay)
+ */
+class Tap
+{
+public:
+ /**
+ * Default constructor. Creates Tap with delay=0, amp=0
+ */
+ Tap ();
+ /**
+ * \param delay Time delay (usually from first arrival) of signal
+ * \param amp Complex amplitude of arrival
+ */
+ Tap (Time delay, std::complex<double> amp);
+ /**
+ * \returns Complex amplitude of arrival
+ */
+ std::complex<double> GetAmp (void) const;
+ /**
+ * \returns Time delay (usually from first arrival) of signal
+ */
+ Time GetDelay (void) const;
+
+private:
+ std::complex<double> m_amplitude;
+ Time m_delay;
+};
+
+/**
+ * \class UanPdp
+ *
+ * Container class to describe power delay profile returned
+ * from UAN propagation models using tapped delay line model.
+ * This should model a channel impulse response as a set of
+ * equally spaced signal arrivals.
+ *
+ * Generally, the profile should be normalized, such that
+ * the sum of all taps should equal 1. The received signal
+ * power on any interval (t1, t2) can then be found from
+ * summing the taps on the interval and multiplying by
+ * the total received power at the receiver.
+ *
+ *
+ */
+class UanPdp
+{
+public:
+ /**
+ * \brief Iterator is a standard template library constant interator
+ */
+ typedef std::vector<Tap>::const_iterator Iterator;
+ /**
+ * \brief Create empty PDP object
+ */
+ UanPdp ();
+ /**
+ * \brief Create PDP object with provided number of taps and resolution
+ * \param numTaps Number of taps in this PDP
+ * \resolution Time resolution of this PDP
+ */
+ UanPdp (uint32_t numTaps, Time resolution);
+ /**
+ * \brief Create PDP object from a vector of Tap objects
+ * \param taps Taps to include in this PDP
+ * \param resolution Resolution of PDP object
+ */
+ UanPdp (std::vector<Tap> taps, Time resolution);
+ /**
+ * \brief Create PDP object from vector of arrival amplitudes
+ * \param arrivals Vector of complex amplitude arrivals
+ * \param resolution Time duration between arrivals in vector
+ */
+ UanPdp (std::vector<std::complex<double > > arrivals, Time resolution);
+ /**
+ * \brief Create PDP object from real valued arrival amplitudes
+ * \param arrivals vector of real valued arrivals
+ * \param resolution Time duration between arrivals in vector
+ */
+ UanPdp (std::vector<double> arrivals, Time resolution);
+ ~UanPdp ();
+
+ /**
+ * \param arrival complex arrival value
+ * \param index index of arrival
+ */
+ void SetTap (std::complex<double> arrival, uint32_t index);
+ /**
+ * \param nTaps number of taps in this PDP
+ */
+ void SetNTaps (uint32_t nTaps);
+ /**
+ * \param resolution Resolution of PDP (time between arrivals)
+ */
+ void SetResolution (Time resolution);
+ /**
+ * \returns Iterator positioned at first arrival
+ */
+ Iterator GetBegin (void) const;
+ /**
+ * \returns Iterator positioned after last arrival
+ */
+ Iterator GetEnd (void) const;
+ /**
+ * \returns Number of taps in PDP
+ */
+ uint32_t GetNTaps (void) const;
+ /**
+ * \returns Tap object at index i
+ * \param i Index number of tap to return (0 based)
+ */
+ const Tap &GetTap (uint32_t i) const;
+ /**
+ * \returns Resolution of PDP (time duration between arrivals)
+ */
+ Time GetResolution (void) const;
+ /**
+ * \param begin Time value to begin summing arrivals
+ * \param end Time value to end summing arrivals
+ * \returns Returns Non-coherent sum of arrivals between two time values
+ *
+ * Assuming that Tap at index 0 arrives at time 0,
+ * this function sums non-coherently (sums amplitude of arrivals
+ * ignoring phase difference) all arrivals between a start
+ * and end time.
+ */
+ double SumTapsNc (Time begin, Time end) const;
+ /**
+ * \param begin Time value to begin summing arrivals
+ * \param end Time value to end summing arrivals
+ * \returns Returns coherent sum of arrivals between two time values
+ *
+ * Assuming that Tap at index 0 arrives at time 0,
+ * this function sums coherently (sums amplitude of arrivals
+ * considering phase difference) all arrivals between a start
+ * and end time.
+ */
+ std::complex<double> SumTapsC (Time begin, Time end) const;
+ /**
+ * \param delay Time duratation after max to begin summing arrivals
+ * \param duration Time duration to sum arrivals for
+ * \returns non-coherent sum of arrivals after max in given window
+ *
+ * this function sums non-coherently (sums amplitude of arrivals
+ * ignoring phase difference) all arrivals in a given duration
+ * starting the given time after the maximum amplitude arrival received
+ */
+ double SumTapsFromMaxNc (Time delay, Time duration) const;
+ /**
+ * \param delay Time duratation after max to begin summing arrivals
+ * \param duration Time duration to sum arrivals for
+ * \returns coherent sum of arrivals after max in given window
+ *
+ * this function sums coherently (sums amplitude of arrivals
+ * considering phase difference) all arrivals in a given duration
+ * starting the given time after the maximum amplitude arrival received
+ */
+ std::complex<double> SumTapsFromMaxC (Time delay, Time duration) const;
+
+ /**
+ * \returns A PDP with a singlue unit impulse arrival at time 0
+ */
+ static UanPdp CreateImpulsePdp (void);
+private:
+ friend std::ostream &operator<< (std::ostream &os, UanPdp &pdp);
+ friend std::istream &operator>> (std::istream &is, UanPdp &pdp);
+ std::vector<Tap> m_taps;
+ Time m_resolution;
+
+};
+/**
+ * \brief Writes PDP to stream as list of arrivals
+ */
+std::ostream &operator<< (std::ostream &os, UanPdp &pdp);
+/**
+ * \brief Reads in list of arrivals from stream is
+ */
+std::istream &operator>> (std::ostream &is, UanPdp &pdp);
+
+/**
+ * \class UanPropModel
+ *
+ * Base class for implemented underwater propagation models
+ */
+class UanPropModel : public Object
+{
+public:
+ /**
+ * Computes pathloss between nodes a and b.
+ * \returns Pathloss in dB re 1 uPa
+ * \param a Ptr to mobility model of node a
+ * \param b Ptr to mobility model of node b
+ * \param mode TX mode of transmission between a and b
+ */
+ virtual double GetPathLossDb (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode txMode) = 0;
+
+ /**
+ * \returns PDP for link between nodes a and b
+ * \param a Ptr to mobility model of node a
+ * \param b Ptr to mobility model of node b
+ * \param mode TX mode of transmission from a to b
+ */
+ virtual UanPdp GetPdp (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode) = 0;
+ /**
+ * Finds propagation delay between nodes a and b
+ * \param a Ptr to mobility model of node a
+ * \param b Ptr to mobility model of node b
+ * \param mode TX mode of transmission
+ * \returns Propagation delay
+ */
+ virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b, UanTxMode mode) = 0;
+
+};
+
+}
+
+#endif /*UANPROPMODEL_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-test.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-net-device.h"
+#include "uan-channel.h"
+#include "uan-mac-aloha.h"
+#include "uan-phy-gen.h"
+#include "uan-transducer-hd.h"
+#include "uan-prop-model-ideal.h"
+#include "ns3/constant-position-mobility-model.h"
+#include "ns3/simulator.h"
+#include "ns3/test.h"
+#include "ns3/node.h"
+#include "ns3/object-factory.h"
+#include "ns3/pointer.h"
+#include "ns3/callback.h"
+
+using namespace ns3;
+
+class UanTest : public TestCase
+{
+public:
+ UanTest ();
+
+ virtual bool DoRun (void);
+private:
+ Ptr<UanNetDevice> CreateNode (Vector pos, Ptr<UanChannel> chan);
+ bool DoPhyTests ();
+ uint32_t DoOnePhyTest (Time t1, Time t2, uint32_t r1, uint32_t r2, Ptr<UanPropModel> prop, uint32_t mode1 = 0, uint32_t mode2 = 0);
+ bool RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
+ void SendOnePacket (Ptr<UanNetDevice> dev, uint32_t mode);
+ ObjectFactory m_phyFac;
+ uint32_t m_bytesRx;
+
+};
+
+
+UanTest::UanTest () : TestCase ("UAN")
+{
+
+}
+
+bool
+UanTest::RxPacket (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender)
+{
+ m_bytesRx += pkt->GetSize ();
+ return true;
+}
+void
+UanTest::SendOnePacket (Ptr<UanNetDevice> dev, uint32_t mode)
+{
+ Ptr<Packet> pkt = Create<Packet> (17);
+ dev->Send (pkt, dev->GetBroadcast (), mode);
+
+}
+Ptr<UanNetDevice>
+UanTest::CreateNode (Vector pos, Ptr<UanChannel> chan)
+{
+
+
+ Ptr<UanPhy> phy = m_phyFac.Create<UanPhy> ();
+ Ptr<Node> node = CreateObject<Node> ();
+ Ptr<UanNetDevice> dev = CreateObject<UanNetDevice> ();
+ Ptr<UanMacAloha> mac = CreateObject<UanMacAloha> ();
+ Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel> ();
+
+ Ptr<UanTransducerHd> trans = CreateObject<UanTransducerHd> ();
+
+ mobility->SetPosition (pos);
+ node->AggregateObject (mobility);
+ mac->SetAddress (UanAddress::Allocate ());
+
+ dev->SetPhy (phy);
+ dev->SetMac (mac);
+ dev->SetChannel (chan);
+ dev->SetTransducer (trans);
+ node->AddDevice (dev);
+
+ return dev;
+}
+
+
+uint32_t
+UanTest::DoOnePhyTest (Time txTime1,
+ Time txTime2,
+ uint32_t r1,
+ uint32_t r2,
+ Ptr<UanPropModel> prop,
+ uint32_t mode1,
+ uint32_t mode2)
+{
+
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ channel->SetAttribute ("PropagationModel", PointerValue (prop));
+
+ Ptr<UanNetDevice> dev0 = CreateNode (Vector (r1,50,50), channel);
+ Ptr<UanNetDevice> dev1 = CreateNode (Vector (0,50,50), channel);
+ Ptr<UanNetDevice> dev2 = CreateNode (Vector (r1 + r2, 50, 50), channel);
+
+ dev0->SetReceiveCallback (MakeCallback (&UanTest::RxPacket, this));
+
+ Simulator::Schedule (txTime1, &UanTest::SendOnePacket, this, dev1, mode1);
+ Simulator::Schedule (txTime2, &UanTest::SendOnePacket, this, dev2, mode2);
+
+ m_bytesRx = 0;
+ Simulator::Stop (Seconds (20.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return m_bytesRx;
+}
+
+
+bool
+UanTest::DoPhyTests ()
+{
+ // Phy Gen / Default PER / Default SINR
+ AttributeList phyList;
+ UanModesList mList;
+ UanTxMode mode = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 10000, 4000, 2, "TestMode");
+ mList.AppendMode (UanTxMode (mode));
+ Ptr<UanPhyPerGenDefault> perDef = CreateObject<UanPhyPerGenDefault> ();
+ Ptr<UanPhyCalcSinrDefault> sinrDef = CreateObject<UanPhyCalcSinrDefault> ();
+ TypeId phyId = TypeId::LookupByName ("ns3::UanPhyGen");
+ m_phyFac.SetTypeId (phyId);
+ phyList.SetWithTid (phyId, "PerModel", PointerValue (perDef));
+ phyList.SetWithTid (phyId, "SinrModel", PointerValue (sinrDef));
+ phyList.SetWithTid (phyId, "SupportedModes", UanModesListValue (mList));
+
+ m_phyFac.Set (phyList);
+
+ Ptr<UanPropModelIdeal> prop = CreateObject<UanPropModelIdeal> ();
+
+ // No collision (Get 2 packets)
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (3.001), 50, 50, prop),
+ 34, "Should have received 34 bytes from 2 disjoint packets");
+
+ // Collision (Lose both packets)
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (2.99), 50, 50, prop),
+ 0, "Expected collision resulting in loss of both packets");
+
+
+ // Phy Gen / FH-FSK SINR check
+
+ Ptr<UanPhyCalcSinrFhFsk> sinrFhfsk = CreateObject <UanPhyCalcSinrFhFsk> ();
+ phyList.Reset ();
+ phyList.SetWithTid (phyId, "PerModel", PointerValue (perDef));
+ phyList.SetWithTid (phyId, "SinrModel", PointerValue (sinrFhfsk));
+ phyList.SetWithTid (phyId, "SupportedModes", UanModesListValue (mList));
+ m_phyFac.Set (phyList);
+
+#ifdef UAN_PROP_BH_INSTALLED
+ Ptr<UanPropModelBh> prop = CreateObject<UanPropModelBh> ();
+#endif // UAN_PROP_BH_INSTALLED
+
+ // No collision (Get 2 packets)
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (3.001), 50, 50, prop),
+ 34, "Should have received 34 bytes from 2 disjoint packets");
+
+ // Should correctly receive first arriving packet
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (1.0126), 50, 50, prop),
+ 17, "Should have recieved 17 bytes from first arriving packet");
+
+ // Packets should collide and both be lost
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (1.0 + 7.01 * (13.0 / 80.0)), 50, 50, prop),
+ 0, "Packets should collide, but received data");
+
+ // Phy Dual
+ UanTxMode mode00 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 10000, 4000, 2, "TestMode00");
+ UanTxMode mode10 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 11000, 4000, 2, "TestMode10");
+ UanTxMode mode20 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 15000, 4000, 2, "TestMode20");
+ UanTxMode mode01 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 10000, 4000, 2, "TestMode01");
+ UanTxMode mode11 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 11000, 4000, 2, "TestMode11");
+ UanTxMode mode21 = UanTxModeFactory::CreateMode (UanTxMode::FSK, 80, 80, 15000, 4000, 2, "TestMode21");
+
+ UanModesList m0;
+ m0.AppendMode (mode00);
+ m0.AppendMode (mode10);
+ m0.AppendMode (mode20);
+ UanModesList m1;
+ m1.AppendMode (mode01);
+ m1.AppendMode (mode11);
+ m1.AppendMode (mode21);
+
+ phyId = TypeId::LookupByName ("ns3::UanPhyDual");
+ m_phyFac.SetTypeId (phyId);
+ phyList.Reset ();
+ phyList.SetWithTid (phyId, "SupportedModesPhy1", UanModesListValue (m0));
+ phyList.SetWithTid (phyId, "SupportedModesPhy2", UanModesListValue (m1));
+ m_phyFac.Set (phyList);
+
+ // No collision (Get 2 packets)
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (3.01), 50, 50, prop),
+ 34, "Expected no collision");
+
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (2.99), 50, 50, prop, 0, 0),
+ 0, "Expected collision with both packets lost");
+
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (2.99), 50, 50, prop, 0, 2),
+ 17, "Expected collision with only one packets lost");
+
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (2.99), 50, 50, prop, 0, 5),
+ 34, "Expected no collision");
+
+ NS_TEST_ASSERT_MSG_EQ (DoOnePhyTest (Seconds (1.0), Seconds (2.99), 50, 50, prop, 2, 3),
+ 34, "Expected no collision");
+
+ return false;
+}
+
+bool
+UanTest::DoRun (void)
+{
+
+ Ptr<UanPhyPerUmodem> per = CreateObject<UanPhyPerUmodem> ();
+ Ptr<Packet> pkt = Create<Packet> (1000);
+ double error = per->CalcPer (pkt, 9, UanPhyGen::GetDefaultModes ()[0]);
+ NS_TEST_ASSERT_MSG_EQ_TOL (error, 0.539, 0.001, "Got PER outside of tolerance");
+
+#ifdef UAN_PROP_BH_INSTALLED
+ // Correct DB lookup for BH prop.
+ Ptr<UanPropModelBh> propBh = CreateObject<UanPropModelBh> ();
+ BellhopResp resp = propBh->GetResp (10000, 50, 50, 1000);
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (resp.GetPathLossDb (), -44.1753, 0.001, "Got BH Pathloss outside of tolerance");
+
+ NS_TEST_ASSERT_MSG_EQ_TOL (resp.GetPdp ().GetTap (4).GetAmp (), 0.14159, 0.001, "Got BH arrival outside of tolerance");
+
+#endif // UAN_PROP_BH_INSTALLED
+
+ return DoPhyTests ();
+
+}
+
+
+class UanTestSuite : public TestSuite
+{
+public:
+ UanTestSuite ();
+};
+
+UanTestSuite::UanTestSuite ()
+ : TestSuite ("devices-uan", UNIT)
+{
+ AddTestCase (new UanTest);
+}
+
+UanTestSuite g_uanTestSuite;
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-transducer-hd.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#include "uan-transducer-hd.h"
+#include "ns3/simulator.h"
+#include "ns3/uan-prop-model.h"
+#include "uan-phy.h"
+#include "uan-channel.h"
+#include "ns3/log.h"
+#include "ns3/pointer.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("UanTransducerHd");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UanTransducerHd);
+UanTransducerHd::UanTransducerHd ()
+ : UanTransducer (),
+ m_state (RX),
+ m_endTxTime (Seconds (0))
+{
+}
+
+UanTransducerHd::~UanTransducerHd ()
+{
+}
+
+void
+UanTransducerHd::DoDispose ()
+{
+ m_channel = 0;
+ UanPhyList::iterator it = m_phyList.begin ();
+ for (; it != m_phyList.end (); it++)
+ {
+ *it = 0;
+ }
+ ArrivalList::iterator ait = m_arrivalList.begin ();
+ for (; ait != m_arrivalList.end (); ait++)
+ {
+ ait->GetPacket () = 0;
+ }
+ m_phyList.clear ();
+ m_arrivalList.clear ();
+ m_endTxEvent.Cancel ();
+
+ UanTransducer::DoDispose ();
+}
+TypeId
+UanTransducerHd::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::UanTransducerHd")
+ .SetParent<Object> ()
+ .AddConstructor<UanTransducerHd> ()
+ ;
+ return tid;
+}
+
+UanTransducer::State
+UanTransducerHd::GetState () const
+{
+ return m_state;
+}
+
+
+bool
+UanTransducerHd::IsRx (void) const
+{
+ return m_state == RX;
+}
+
+bool
+UanTransducerHd::IsTx (void) const
+{
+ return m_state == TX;
+
+}
+
+const UanTransducer::ArrivalList &
+UanTransducerHd::GetArrivalList (void) const
+{
+ return m_arrivalList;
+}
+
+void
+UanTransducerHd::Receive (Ptr<Packet> packet,
+ double rxPowerDb,
+ UanTxMode txMode,
+ UanPdp pdp)
+{
+ UanPacketArrival arrival (packet,
+ rxPowerDb,
+ txMode,
+ pdp,
+ Simulator::Now ());
+
+ m_arrivalList.push_back (arrival);
+ Time txDelay = Seconds (packet->GetSize () * 8.0 / txMode.GetDataRateBps ());
+ Simulator::Schedule (txDelay, &UanTransducerHd::RemoveArrival, this, arrival);
+ NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Transducer in receive");
+ if (m_state == RX)
+ {
+ NS_LOG_DEBUG ("Transducer state = RX");
+ UanPhyList::const_iterator it = m_phyList.begin ();
+ for (; it != m_phyList.end (); it++)
+ {
+ NS_LOG_DEBUG ("Calling StartRx");
+ (*it)->StartRxPacket (packet, rxPowerDb, txMode, pdp);
+ }
+ }
+}
+
+void
+UanTransducerHd::Transmit (Ptr<UanPhy> src,
+ Ptr<Packet> packet,
+ double txPowerDb,
+ UanTxMode txMode)
+{
+
+ Time endTxTime;
+ if (m_state == TX)
+ {
+ Simulator::Remove (m_endTxEvent);
+ }
+ else
+ {
+ m_state = TX;
+ }
+
+
+ Time delay = Seconds (packet->GetSize () * 8.0 / txMode.GetDataRateBps ());
+ NS_LOG_DEBUG ("Transducer transmitting: TX delay = "
+ << delay << " seconds for packet size "
+ << packet->GetSize () << " bytes and rate = "
+ << txMode.GetDataRateBps () << " bps");
+ UanPhyList::const_iterator it = m_phyList.begin ();
+ for (; it != m_phyList.end (); it++)
+ {
+ if (src != (*it))
+ {
+ (*it)->NotifyTransStartTx (packet, txPowerDb, txMode);
+ }
+ }
+ m_channel->TxPacket (Ptr<UanTransducer> (this), packet, txPowerDb, txMode);
+
+
+ delay = std::max (delay, m_endTxTime - Simulator::Now ());
+
+ m_endTxEvent = Simulator::Schedule (delay, &UanTransducerHd::EndTx, this);
+ m_endTxTime = Simulator::Now () + delay;
+}
+
+void
+UanTransducerHd::EndTx (void)
+{
+ NS_ASSERT (m_state == TX);
+ m_state = RX;
+ m_endTxTime = Seconds (0);
+}
+void
+UanTransducerHd::SetChannel (Ptr<UanChannel> chan)
+{
+ NS_LOG_DEBUG ("Transducer setting channel");
+ m_channel = chan;
+
+}
+Ptr<UanChannel>
+UanTransducerHd::GetChannel (void) const
+{
+ return m_channel;
+}
+void
+UanTransducerHd::AddPhy (Ptr<UanPhy> phy)
+{
+ m_phyList.push_back (phy);
+}
+
+const UanTransducer::UanPhyList &
+UanTransducerHd::GetPhyList (void) const
+{
+ return m_phyList;
+}
+
+void
+UanTransducerHd::RemoveArrival (UanPacketArrival arrival)
+{
+
+ // Remove entry from arrival list
+ ArrivalList::iterator it = m_arrivalList.begin ();
+ for (; it != m_arrivalList.end (); it++)
+ {
+ if (it->GetPacket () == arrival.GetPacket ())
+ {
+ m_arrivalList.erase (it);
+ break;
+ }
+ }
+ UanPhyList::const_iterator ait = m_phyList.begin ();
+ for (; ait != m_phyList.end (); ait++)
+ {
+ (*ait)->NotifyIntChange ();
+ }
+
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-transducer-hd.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANTRANSDUCERHD_H_
+#define UANTRANSDUCERHD_H_
+
+#include "uan-transducer.h"
+#include "ns3/simulator.h"
+namespace ns3 {
+
+/**
+ * \class UanTransducerHd
+ * \brief Half duplex implementation of transducer object
+ *
+ * This class will only allow attached Phy's to receive packets if not in TX mode
+ */
+class UanTransducerHd : public ns3::UanTransducer
+{
+public:
+ UanTransducerHd ();
+ virtual ~UanTransducerHd ();
+
+ static TypeId GetTypeId (void);
+
+ // inherited methods
+ virtual State GetState (void) const;
+ virtual bool IsRx (void) const;
+ virtual bool IsTx (void) const;
+ virtual const ArrivalList &GetArrivalList (void) const;
+ virtual void Receive (Ptr<Packet> packet, double rxPowerDb, UanTxMode txMode, UanPdp pdp);
+ virtual void Transmit (Ptr<UanPhy> src, Ptr<Packet> packet, double txPowerDb, UanTxMode txMode);
+ virtual void SetChannel (Ptr<UanChannel> chan);
+ virtual Ptr<UanChannel> GetChannel (void) const;
+ virtual void AddPhy (Ptr<UanPhy>);
+ virtual const UanPhyList &GetPhyList (void) const;
+
+private:
+ State m_state;
+ ArrivalList m_arrivalList;
+ UanPhyList m_phyList;
+ Ptr<UanChannel> m_channel;
+ EventId m_endTxEvent;
+ Time m_endTxTime;
+
+ void RemoveArrival (UanPacketArrival arrival);
+ void EndTx (void);
+protected:
+ virtual void DoDispose ();
+};
+
+}
+
+#endif /*UANTRANSDUCERSIMPLE_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-transducer.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+#ifndef UANTRANSDUCER_H_
+#define UANTRANSDUCER_H_
+
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "uan-tx-mode.h"
+#include "ns3/uan-prop-model.h"
+// #include "uan-channel.h"
+// #include "uan-phy.h"
+
+#include <list>
+namespace ns3 {
+
+class UanPhy;
+class UanChannel;
+
+
+/**
+ * \class UanPacketArrival
+ *
+ * \brief Class consisting of packet arrival information (Time, RxPower, mode, PDP)
+ */
+class UanPacketArrival
+{
+public:
+ /**
+ * \param packet Packet arriving
+ * \param rxPowerDb RX signal power in dB of arriving packet
+ * \param txMode TX mode of arriving packet
+ * \param pdp Power delay profile of arriving packet
+ * \param arrTime Arrival time of packet
+ */
+ UanPacketArrival (Ptr<Packet> packet, double rxPowerDb, UanTxMode txMode, UanPdp pdp, Time arrTime)
+ : m_packet (packet),
+ m_rxPowerDb (rxPowerDb),
+ m_txMode (txMode),
+ m_pdp (pdp),
+ m_arrTime (arrTime)
+ {
+ }
+
+ ~UanPacketArrival()
+ {
+ m_packet = 0;
+ }
+
+ /**
+ * \returns Pointer to packet that arrived
+ */
+ inline Ptr<Packet> GetPacket (void) const
+ {
+ return m_packet;
+ }
+ /**
+ * \returns Received signal strength in dB re 1uPa
+ */
+ inline double GetRxPowerDb (void) const
+ {
+ return m_rxPowerDb;
+ }
+ /**
+ * \returns UanTxMode used to transmit packet
+ */
+ inline const UanTxMode &GetTxMode (void) const
+ {
+ return m_txMode;
+ }
+ /**
+ * \returns Arrival time of packet
+ */
+ inline Time GetArrivalTime (void) const
+ {
+ return m_arrTime;
+ }
+ /**
+ * \returns PDP of arriving signal
+ */
+ inline UanPdp GetPdp (void) const
+ {
+ return m_pdp;
+ }
+private:
+ Ptr<Packet> m_packet;
+ double m_rxPowerDb;
+ UanTxMode m_txMode;
+ UanPdp m_pdp;
+ Time m_arrTime;
+};
+
+/**
+ * \class UanTransducer
+ * \brief Virtual base for Transducer objects
+ *
+ * The Transducer was added to support classes such as UanPhyDual.
+ * In a generic Phy setting, this class functions to hold information about all
+ * possibly interfering packets.
+ */
+class UanTransducer : public Object
+{
+public:
+ /**
+ * \brief Transducer state (receiving or transmitting)
+ */
+ enum State {
+ TX, RX
+ };
+
+ /**
+ * \brief Arrival list is a standard template library list of UanPacketArrivals objects
+ */
+ typedef std::list<UanPacketArrival> ArrivalList;
+ /**
+ * \brief UanPhyList is a standard template library list of UanPhy objects
+ */
+ typedef std::list<Ptr<UanPhy> > UanPhyList;
+
+ /**
+ * \returns State (TX or RX) of this transducer
+ */
+ virtual State GetState (void) const = 0;
+
+ /**
+ * \returns True if this transducer is available for receiving an incoming packet.
+ */
+ virtual bool IsRx (void) const = 0;
+ /**
+ * \returns True if there is a packet being transmitted from this transducer.
+ */
+ virtual bool IsTx (void) const = 0;
+ /**
+ * \returns List of all packets currently crossing this node in the water.
+ */
+ virtual const ArrivalList &GetArrivalList (void) const = 0;
+ /**
+ * \brief Receive Notify this object that a new packet has arrived at this nodes location
+ * \param packet Packet arriving
+ * \param rxPowerDb Signal power in dB of arriving packet
+ * \param txMode Mode arriving packet is using
+ * \param pdp PDP of arriving signal
+ */
+ virtual void Receive (Ptr<Packet> packet, double rxPowerDb, UanTxMode txMode, UanPdp pdp) = 0;
+ /**
+ * \brief Transmit a packet from this transducer
+ * \param src Source PHY
+ * \param packet Packet to transmit
+ * \param txPowerDb Outgoing Tx power of packet
+ * \param txMode Mode to transmit packet with.
+ */
+ virtual void Transmit (Ptr<UanPhy> src, Ptr<Packet> packet, double txPowerDb, UanTxMode txMode) = 0;
+ /**
+ * \param chan Channel this transducer is attached to
+ */
+ virtual void SetChannel (Ptr<UanChannel> chan) = 0;
+ /**
+ * \returns Channel this transducer is attached to
+ */
+ virtual Ptr<UanChannel> GetChannel (void) const = 0;
+ /**
+ * \param phy Add phy above this transducer (may connect > 1 Phy to a transducer)
+ */
+ virtual void AddPhy (Ptr<UanPhy> phy) = 0;
+ /**
+ * \returns List of all Phy's this transducer sends packets to.
+ */
+ virtual const UanPhyList &GetPhyList (void) const = 0;
+};
+
+} // namespace ns3
+
+#endif /*UANTRANSDUCER_H_*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-tx-mode.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+#include "uan-tx-mode.h"
+#include "ns3/log.h"
+#include <map>
+#include <utility>
+
+NS_LOG_COMPONENT_DEFINE ("UanTxMode");
+
+namespace ns3 {
+
+UanTxMode::UanTxMode ()
+{
+}
+
+UanTxMode::~UanTxMode ()
+{
+}
+
+
+UanTxMode::ModulationType
+UanTxMode::GetModType (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_type;
+}
+
+uint32_t
+UanTxMode::GetDataRateBps (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_dataRateBps;
+}
+
+uint32_t
+UanTxMode::GetPhyRateSps (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_phyRateSps;
+}
+
+uint32_t
+UanTxMode::GetCenterFreqHz (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_cfHz;
+}
+
+uint32_t
+UanTxMode::GetBandwidthHz (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_bwHz;
+}
+
+uint32_t
+UanTxMode::GetConstellationSize (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_constSize;
+}
+
+std::string
+UanTxMode::GetName (void) const
+{
+ return UanTxModeFactory::GetFactory ().GetModeItem (m_uid).m_name;
+}
+
+uint32_t
+UanTxMode::GetUid (void) const
+{
+ return m_uid;
+}
+
+std::ostream &
+operator<< (std::ostream & os, const UanTxMode &mode)
+{
+ os << mode.m_uid;
+ return os;
+}
+
+std::istream &
+operator>> (std::istream & is, UanTxMode &mode)
+{
+ std::string name;
+ uint32_t duh;
+
+ is >> duh;
+
+ mode.m_uid = duh;
+ return is;
+}
+
+
+
+UanTxModeFactory::UanTxModeFactory ()
+ : m_nextUid (0)
+{
+
+}
+UanTxModeFactory::~UanTxModeFactory ()
+{
+ m_modes.clear ();
+}
+bool
+UanTxModeFactory::NameUsed (std::string name)
+{
+ std::map<uint32_t, UanTxModeItem>::iterator it = m_modes.begin ();
+
+ for (; it != m_modes.end (); it++)
+ {
+ if ((*it).second.m_name == name)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+UanTxMode
+UanTxModeFactory::CreateMode (UanTxMode::ModulationType type,
+ uint32_t dataRateBps,
+ uint32_t phyRateSps,
+ uint32_t cfHz,
+ uint32_t bwHz,
+ uint32_t constSize,
+ std::string name)
+{
+ UanTxModeFactory &factory = UanTxModeFactory::GetFactory ();
+
+
+ UanTxModeItem *item;
+
+ if (factory.NameUsed (name))
+ {
+ NS_LOG_WARN ("Redefining UanTxMode with name \"" << name << "\"");
+ item = &factory.GetModeItem (name);
+ }
+ else
+ {
+ item = &factory.m_modes[factory.m_nextUid];
+ item->m_uid = factory.m_nextUid++;
+ }
+
+ item->m_type = type;
+ item->m_dataRateBps = dataRateBps;
+ item->m_phyRateSps = phyRateSps;
+ item->m_cfHz = cfHz;
+ item->m_bwHz = bwHz;
+ item->m_constSize = constSize;
+ item->m_name = name;
+ return factory.MakeModeFromItem (*item);
+}
+
+UanTxModeFactory::UanTxModeItem &
+UanTxModeFactory::GetModeItem (uint32_t uid)
+{
+ if (uid >= m_nextUid)
+ {
+ NS_FATAL_ERROR ("Attempting to retrieve UanTxMode with uid, "
+ << uid << ", >= m_nextUid");
+ }
+
+ return m_modes[uid];
+}
+
+UanTxModeFactory::UanTxModeItem &
+UanTxModeFactory::GetModeItem (std::string name)
+{
+ std::map<uint32_t, UanTxModeItem>::iterator it = m_modes.begin ();
+ for (; it != m_modes.end (); it++)
+ {
+ if ((*it).second.m_name == name)
+ {
+ return (*it).second;
+ }
+ }
+ NS_FATAL_ERROR ("Unknown mode, \"" << name << "\", requested from mode factory");
+ return (*it).second; // dummy to get rid of warning
+}
+
+UanTxMode
+UanTxModeFactory::GetMode (std::string name)
+{
+ UanTxModeFactory &factory = UanTxModeFactory::GetFactory ();
+ return factory.MakeModeFromItem (factory.GetModeItem (name));
+}
+
+UanTxMode
+UanTxModeFactory::GetMode (uint32_t uid)
+{
+ UanTxModeFactory &factory = UanTxModeFactory::GetFactory ();
+ return factory.MakeModeFromItem (factory.GetModeItem (uid));
+}
+
+UanTxMode
+UanTxModeFactory::MakeModeFromItem (const UanTxModeItem &item)
+{
+ UanTxMode mode;
+ mode.m_uid = item.m_uid;
+ return mode;
+}
+
+UanTxModeFactory &
+UanTxModeFactory::GetFactory (void)
+{
+ static UanTxModeFactory factory;
+ return factory;
+}
+
+UanModesList::UanModesList (void)
+{
+}
+
+UanModesList::~UanModesList (void)
+{
+ m_modes.clear ();
+}
+
+void
+UanModesList::AppendMode (UanTxMode newMode)
+{
+ m_modes.push_back (newMode);
+}
+
+void
+UanModesList::DeleteMode (uint32_t modeNum)
+{
+ NS_ASSERT (modeNum < m_modes.size ());
+
+
+ std::vector<UanTxMode>::iterator it = m_modes.begin ();
+ for (uint32_t i = 0; i < modeNum; i++)
+ {
+ it++;
+ }
+ it = m_modes.erase (it);
+}
+
+UanTxMode
+UanModesList::operator[] (uint32_t i) const
+{
+ NS_ASSERT (i < m_modes.size ());
+ return m_modes[i];
+}
+
+uint32_t
+UanModesList::GetNModes (void) const
+{
+ return m_modes.size ();
+}
+
+std::ostream &
+operator << (std::ostream &os, const UanModesList &ml)
+{
+
+ os << ml.GetNModes () << "|";
+
+ for (uint32_t i = 0; i < ml.m_modes.size (); i++)
+ {
+ os << ml[i] << "|";
+ }
+ return os;
+}
+std::istream &
+operator >> (std::istream &is, UanModesList &ml)
+{
+ char c;
+
+ int numModes;
+
+ is >> numModes >> c;
+ if (c != '|')
+ {
+ is.setstate (std::ios_base::failbit);
+ }
+ ml.m_modes.clear ();
+ ml.m_modes.resize (numModes);
+
+ for (int i = 0; i < numModes; i++)
+ {
+ is >> ml.m_modes[i] >> c;
+ if (c != '|')
+ {
+ is.setstate (std::ios_base::failbit);
+ }
+ }
+
+ return is;
+}
+
+ATTRIBUTE_HELPER_CPP (UanModesList);
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan-tx-mode.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+#ifndef UANTXMODE_H
+#define UANTXMODE_H
+
+#include "ns3/object.h"
+#include <map>
+
+namespace ns3 {
+
+class UanTxModeFactory;
+class UanTxMode;
+
+/**
+ * \class UanTxMode
+ * \brief Abstraction of packet modulation information
+ */
+class UanTxMode
+{
+public:
+ UanTxMode ();
+ ~UanTxMode ();
+
+ /**
+ * Modulation type
+ */
+ typedef enum {
+ PSK, QAM, FSK, OTHER
+ } ModulationType;
+ /**
+ * \returns The modulation type of the mode
+ */
+ ModulationType GetModType (void) const;
+ /**
+ * \returns Data rate of the TX mode in bits per second
+ */
+ uint32_t GetDataRateBps (void) const;
+ /**
+ * \returns PHY rate in symbols per second
+ */
+ uint32_t GetPhyRateSps (void) const;
+ /**
+ * \returns Center frequency of transmitted signal in Hz
+ */
+ uint32_t GetCenterFreqHz (void) const;
+ /**
+ * \returns Bandwidth of transmitted signal in Hz
+ */
+ uint32_t GetBandwidthHz (void) const;
+ /**
+ * \returns Number of constellation points in modulation
+ */
+ uint32_t GetConstellationSize (void) const;
+ /**
+ * \returns Name
+ */
+ std::string GetName (void) const;
+ /**
+ * \returns Unique ID
+ */
+ uint32_t GetUid (void) const;
+
+private:
+ friend class UanTxModeFactory;
+ friend std::ostream &operator<< (std::ostream & os, const UanTxMode &mode);
+ friend std::istream &operator>> (std::istream & is, UanTxMode &mode);
+
+
+ uint32_t m_uid;
+
+};
+/**
+ * \brief Writes tx mode entry to stream os
+ */
+std::ostream & operator << (std::ostream & os, const UanTxMode &mode);
+/**
+ * \brief Reads tx mode entry from stream is
+ */
+std::istream & operator >> (std::istream & is, const UanTxMode &mode);
+
+class UanTxModeFactory
+{
+public:
+ UanTxModeFactory ();
+ ~UanTxModeFactory ();
+
+ /**
+ *
+ * \param dataRateBps Data rate in BPS
+ * \param phyRateSps Symbol rate in symbols per second
+ * \param cfHz Center frequency in Hz
+ * \param bwHz Bandwidth in Hz
+ * \param constSize Modulation constellation size (2 for BPSK, 4 for QPSK)
+ * \param name Unique string name for this transmission mode
+ */
+ static UanTxMode CreateMode (UanTxMode::ModulationType type,
+ uint32_t dataRateBps,
+ uint32_t phyRateSps,
+ uint32_t cfHz,
+ uint32_t bwHz,
+ uint32_t constSize,
+ std::string name);
+
+ /**
+ * \param name String name of mode
+ * \returns Mode with given name
+ */
+ static UanTxMode GetMode (std::string name);
+ /**
+ * \param uid Unique ID of mode
+ * \returns The mode with given uid
+ */
+ static UanTxMode GetMode (uint32_t uid);
+private:
+ friend class UanTxMode;
+ uint32_t m_nextUid;
+
+ struct UanTxModeItem
+ {
+ UanTxMode::ModulationType m_type;
+ uint32_t m_cfHz;
+ uint32_t m_bwHz;
+ uint32_t m_dataRateBps;
+ uint32_t m_phyRateSps;
+ uint32_t m_constSize;
+ uint32_t m_uid;
+ std::string m_name;
+ };
+
+ std::map<uint32_t, UanTxModeItem> m_modes;
+ bool NameUsed (std::string name);
+ static UanTxModeFactory &GetFactory (void);
+ UanTxModeItem &GetModeItem (uint32_t uid);
+ UanTxModeItem &GetModeItem (std::string name);
+ UanTxMode MakeModeFromItem (const UanTxModeItem &item);
+
+};
+
+/**
+ * \class UanModesList
+ * \brief Container for UanTxModes
+ */
+class UanModesList
+{
+public:
+ UanModesList ();
+ virtual ~UanModesList ();
+
+ /**
+ * \param mode Add mode to list
+ */
+ void AppendMode (UanTxMode mode);
+ /**
+ * \brief delete mode at given index
+ * \param num Index of mode to delete
+ */
+ void DeleteMode (uint32_t num);
+ /**
+ * \param index Mode index
+ * \returns mode at given index
+ */
+ UanTxMode operator[] (uint32_t index) const;
+ /**
+ * \returns Number of modes in list
+ */
+ uint32_t GetNModes (void) const;
+
+
+private:
+ std::vector<UanTxMode> m_modes;
+ friend std::ostream &operator << (std::ostream &os, const UanModesList &ml);
+ friend std::istream &operator >> (std::istream &is, UanModesList &ml);
+};
+
+/**
+ * \brief Write UanModesList to stream os
+ */
+std::ostream &operator << (std::ostream &os, const UanModesList &ml);
+/**
+ * \brief Read UanModesList from stream is
+ */
+std::istream &operator >> (std::istream &is, UanModesList &ml);
+
+///UanModesList is attribute value
+ATTRIBUTE_HELPER_HEADER (UanModesList);
+
+} // namespace ns3
+
+#endif // UANTXMODE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/uan.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Leonard Tracy <lentracy@gmail.com>
+ */
+
+/**
+ * \ingroup devices
+ * \defgroup UAN UAN Models
+ *
+ * \section UanOverview UAN Module Overview
+ *
+ * The main goal of the UAN Model is to enable researchers to
+ * model a variety of underwater network scenarios. The UAN model
+ * is broken into three main parts: The channel, PHY, and MAC models.
+ *
+ *
+ * \section UanPropOverview UAN Propagation Models
+ *
+ * Modelling of the underwater acoustic channel has been an active
+ * area of research for quite some time. Given the complications involved,
+ * surface and bottom interactions, varying speed of sound, etc..., the detailed
+ * models in use for ocean acoustics research are much too complex
+ * (in terms of runtime) for use in network level simulations. We have
+ * attempted to provide the often used models as well as make an attempt to bridge, in part, the gap between
+ * complicated ocean acoustic models and network level simulation. The three propagation
+ * models included are the ideal channel model, the Thorp propagation model and
+ * the Bellhop propagation model (Available as an addition).
+ *
+ * All of the Propagation Models follow the same simple interface in ns3::UanPropModel.
+ * The propagation models provide a power delay profile (PDP) and pathloss
+ * information. The PDP is retrieved using the GetPdp method which returns type UanPdp.
+ * ns3::UanPdp utilises a tapped delay line model for the acoustic channel.
+ * The UanPdp class is a container class for Taps, each tap has a delay and amplitude
+ * member corresponding to the time of arrival (relative to the first tap arrival time)
+ * and amplitude. The propagation model also provides pathloss between the source
+ * and receiver in dB re 1uPa. The PDP and pathloss can then be used to find the
+ * received signal power over a duration of time (i.e. received signal power in
+ * a symbol duration and ISI which interferes with neighbouring signals). Both
+ * UanPropModelIdeal and UanPropModelThorp return a single impulse for a PDP.
+ *
+ * a) Ideal Channel Model ns3::UanPropModelIdeal
+ *
+ * The ideal channel model assumes 0 pathloss inside a cylindrical area with bounds
+ * set by attribute. The ideal channel model also assumes an impulse PDP.
+ *
+ * b) Thorp Propagation Model ns3::UanPropModelThorp
+ *
+ * The Thorp Propagation Model calculates pathloss using the well-known Thorp approximation.
+ * This model is similar to the underwater channel model implemented in ns2 as described here:
+ *
+ * Harris, A. F. and Zorzi, M. 2007. Modeling the underwater acoustic channel in ns2. In Proceedings
+ * of the 2nd international Conference on Performance Evaluation Methodologies and Tools
+ * (Nantes, France, October 22 - 27, 2007). ValueTools, vol. 321. ICST (Institute for Computer
+ * Sciences Social-Informatics and Telecommunications Engineering), ICST, Brussels, Belgium, 1-8.
+ *
+ * The frequency used in calculation however, is the center frequency of the modulation as found from
+ * ns3::UanTxMode. The Thorp Propagation Model also assumes an impulse channel response.
+ *
+ * c) Bellhop Propagation Model ns3::UanPropModelBh (Available as an addition)
+ *
+ * The Bellhop propagation model reads propagation information from a database. A configuration
+ * file describing the location, and resolution of the archived information must be supplied via
+ * attributes. We have included a utility, create-dat, which can create these data files using the Bellhop
+ * Acoustic Ray Tracing software (http://oalib.hlsresearch.com/).
+ *
+ * The create-dat utility requires a Bellhop installation to run. Bellhop takes
+ * environment information about the channel, such as sound speed profile, surface height
+ * bottom type, water depth, and uses a gaussian ray tracing algorithm to determine
+ * propagation information. Arrivals from Bellhop are grouped together into equal length
+ * taps (the arrivals in a tap duration are coherently summed). The maximum taps are then
+ * aligned to take the same position in the PDP. The create-dat utility averages together
+ * several runs and then normalizes the average such that the sum of all taps is 1. The same
+ * configuration file used to create the data files using create-dat should be passed via
+ * attribute to the Bellhop Propagation Model.
+ *
+ * The Bellhop propagation model is available as a patch. The link address will be
+ * made available here when it is posted online. Otherwise email lentracy@gmail.com
+ * for more information.
+ *
+ *
+ * \section UanPhyOverview UAN PHY Model Overview
+ *
+ * The PHY has been designed to allow for relatively easy extension
+ * to new networking scenarios. We feel this is important as, to date,
+ * there has been no commonly accepted network level simulation model
+ * for underwater networks. The lack of commonly accepted network simulation
+ * tools has resulted in a wide array of simulators and models used to report
+ * results in literature. The lack of standardization makes comparing results
+ * nearly impossible.
+ *
+ * The main component of the PHY Model is the generic
+ * PHY class, ns3::UanPhyGen. The PHY class's general responsibility
+ * is to handle packet acquisition, error determination, and forwarding of successful
+ * packets up to the MAC layer. The Generic PHY uses two models for determination
+ * of signal to noise ratio (SINR) and packet error rate (PER). The
+ * combination of the PER and SINR models determine successful reception
+ * of packets. The PHY model connects to the channel via a Transducer class.
+ * The Transducer class is responsible for tracking all arriving packets and
+ * departing packets over the duration of the events. How the PHY class and the PER and SINR models
+ * respond to packets is based on the "Mode" of the transmission as described by the ns3::UanTxMode
+ * class.
+ *
+ * When a MAC layer sends down a packet to the PHY for transmission it specifies a "mode number" to
+ * be used for the transmission. The PHY class accepts, as an attribute, a list of supported modes. The
+ * mode number corresponds to an index in the supported modes. The UanTxMode contains simple modulation
+ * information and a unique string id. The generic PHY class will only acquire arriving packets which
+ * use a mode which is in the supported modes list of the PHY. The mode along with received signal power,
+ * and other pertinent attributes (e.g. possibly interfering packets and their modes) are passed to the SINR
+ * and PER models for calculation of SINR and probability of error.
+ *
+ * Several simple example PER and SINR models have been created.
+ * a) The PER models
+ * - Default (simple) PER model (ns3::UanPhyPerGenDefault): The Default PER model tests the packet against a threshold and
+ * assumes error (with prob. 1) if the SINR is below the threshold or success if the SINR is above
+ * the threshold
+ * - Micromodem FH-FSK PER (ns3::UanPhyPerUmodem). The FH-FSK PER model calculates probability of error assuming a
+ * rate 1/2 convolutional code with constraint length 9 and a CRC check capable of correcting
+ * up to 1 bit error. This is similar to what is used in the receiver of the WHOI Micromodem.
+ *
+ * b) SINR models
+ * - Default Model (ns3::UanPhyCalcSinrDefault), The default SINR model assumes that all transmitted energy is captured at the receiver
+ * and that there is no ISI. Any received signal power from interferes acts as additional
+ * ambient noise.
+ * - FH-FSK SINR Model (ns3::UanPhyCalcSinrFhFsk), The WHOI Micromodem operating in FH-FSK mode uses a predetermined hopping
+ * pattern that is shared by all nodes in the network. We model this by only including signal
+ * energy receiving within one symbol time (as given by ns3::UanTxMode) in calculating the
+ * received signal power. A channel clearing time is given to the FH-FSK SINR model via attribute.
+ * Any signal energy arriving in adjacent signals (after a symbol time and the clearing time) is
+ * considered ISI and is treated as additional ambient noise. Interfering signal arrivals inside
+ * a symbol time (any symbol time) is also counted as additional ambient noise
+ * - Frequency filtered SINR (ns3::UanPhyCalcSinrDual). This SINR model calculates SINR in the same manner
+ * as the default model. This model however only considers interference if there is an overlap in frequency
+ * of the arriving packets as determined by UanTxMode.
+ *
+ * In addition to the generic PHY a dual phy layer is also included (ns3::UanPhyDual). This wraps two
+ * generic phy layers together to model a net device which includes two receivers. This was primarily
+ * developed for UanMacRc, described in the next section.
+ *
+ *\section UanMAC UAN MAC Model Overview
+ *
+ * Over the last several years there have been a myriad of underwater MAC proposals
+ * in the literature. We have included three MAC protocols with this distribution:
+ * a) CW-MAC, a MAC protocol which uses a slotted contention window similar in nature to
+ * the IEEE 802.11 DCF. Nodes have a constant contention window measured in slot times (configured
+ * via attribute). If the channel is sensed busy, then nodes backoff by randomly (uniform distribution) choose
+ * a slot to transmit in. The slot time durations are also configured via attribute. This MAC was described in
+ *
+ * Parrish N.; Tracy L.; Roy S. Arabshahi P.; and Fox, W., System Design Considerations for Undersea Networks:
+ * Link and Multiple Access Protocols , IEEE Journal on Selected Areas in Communications (JSAC), Special
+ * Issue on Underwater Wireless Communications and Networks, Dec. 2008.
+ *
+ * b) RC-MAC (ns3::UanMacRc ns3::UanMacRcGw) a reservation channel protocol which dynamically divides
+ * the available bandwidth into a data channel and a control channel. This MAC protocol
+ * assumes there is a gateway node which all network traffic is destined for. The current
+ * implementation assumes a single gateway and a single network neighborhood (a single hop network).
+ * RTS/CTS handshaking is used and time is divided into cycles. Non-gateway nodes transmit RTS packets
+ * on the control channel in parallel to data packet transmissions which were scheduled in the previous cycle
+ * at the start of a new cycle, the gateway responds on the data channel with a CTS packet which includes
+ * packet transmission times of data packets for received RTS packets in the previous cycle as well as bandwidth
+ * allocation information. At the end of a cycle ACK packets are transmitted for received data packets.
+ *
+ * When a publication is available it will be cited here.
+ *
+ * c) Simple ALOHA (ns3::UanMacAloha) Nodes transmit at will.
+ *
+ *
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/waf Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/uan/wscript Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,51 @@
+
+
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ module = bld.create_ns3_module('uan', ['node'])
+ module.source = [
+ 'uan-channel.cc',
+ 'uan-phy-gen.cc',
+ 'uan-transducer-hd.cc',
+ 'uan-address.cc',
+ 'uan-net-device.cc',
+ 'uan-tx-mode.cc',
+ 'uan-prop-model.cc',
+ 'uan-prop-model-ideal.cc',
+ 'uan-mac-aloha.cc',
+ 'uan-header-common.cc',
+ 'uan-noise-model-default.cc',
+ 'uan-mac-cw.cc',
+ 'uan-prop-model-thorp.cc',
+ 'uan-phy-dual.cc',
+ 'uan-header-rc.cc',
+ 'uan-mac-rc.cc',
+ 'uan-mac-rc-gw.cc',
+ 'uan-test.cc'
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'uan'
+ headers.source = [
+ 'uan-channel.h',
+ 'uan-phy.h',
+ 'uan-mac.h',
+ 'uan-net-device.h',
+ 'uan-prop-model.h',
+ 'uan-tx-mode.h',
+ 'uan-transducer.h',
+ 'uan-phy-gen.h',
+ 'uan-transducer-hd.h',
+ 'uan-address.h',
+ 'uan-prop-model-ideal.h',
+ 'uan-mac-aloha.h',
+ 'uan-header-common.h',
+ 'uan-noise-model.h',
+ 'uan-noise-model-default.h',
+ 'uan-mac-cw.h',
+ 'uan-prop-model-thorp.h',
+ 'uan-phy-dual.h',
+ 'uan-header-rc.h',
+ 'uan-mac-rc.h',
+ 'uan-mac-rc-gw.h'
+ ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/uan-helper.cc Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,228 @@
+/*
+ * uan-helper.cc
+ *
+ * Copyright (c) 2008 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Created on: 9-Oct-2008
+ * Author: Leonard Tracy <lentracy@u.washington.edu>
+ *
+ *
+ */
+
+#include "uan-helper.h"
+#include "ns3/uan-net-device.h"
+#include "ns3/uan-mac.h"
+#include "ns3/uan-phy.h"
+#include "ns3/uan-channel.h"
+#include "ns3/uan-prop-model.h"
+#include "ns3/uan-prop-model-ideal.h"
+#include "ns3/uan-transducer.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+#include "ns3/uan-tx-mode.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/uan-noise-model-default.h"
+
+#include <sstream>
+#include <string>
+
+NS_LOG_COMPONENT_DEFINE("UanHelper");
+namespace ns3
+{
+
+static void AsciiPhyTxEvent (std::ostream *os, std::string context,
+ Ptr<const Packet> packet, double txPowerDb, UanTxMode mode)
+{
+ *os << "+ " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+}
+
+static void AsciiPhyRxOkEvent (std::ostream *os, std::string context,
+ Ptr<const Packet> packet, double snr, UanTxMode mode)
+{
+ *os << "r " << Simulator::Now ().GetSeconds () << " " << context << " " << *packet << std::endl;
+}
+
+UanHelper::UanHelper ()
+{
+ m_mac.SetTypeId ("ns3::UanMacAloha");
+ m_phy.SetTypeId ("ns3::UanPhyGen");
+ m_transducer.SetTypeId ("ns3::UanTransducerHd");
+
+}
+
+UanHelper::~UanHelper ()
+{
+
+}
+
+
+void
+UanHelper::SetMac (std::string macType,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_mac = ObjectFactory ();
+ m_mac.SetTypeId (macType);
+ m_mac.Set (n0, v0);
+ m_mac.Set (n1, v1);
+ m_mac.Set (n2, v2);
+ m_mac.Set (n3, v3);
+ m_mac.Set (n4, v4);
+ m_mac.Set (n5, v5);
+ m_mac.Set (n6, v6);
+ m_mac.Set (n7, v7);
+}
+
+void
+UanHelper::SetPhy (std::string phyType,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_phy = ObjectFactory ();
+ m_phy.SetTypeId (phyType);
+ m_phy.Set (n0, v0);
+ m_phy.Set (n1, v1);
+ m_phy.Set (n2, v2);
+ m_phy.Set (n3, v3);
+ m_phy.Set (n4, v4);
+ m_phy.Set (n5, v5);
+ m_phy.Set (n6, v6);
+ m_phy.Set (n7, v7);
+
+}
+
+void
+UanHelper::SetTransducer (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_transducer = ObjectFactory ();
+ m_transducer.SetTypeId (type);
+ m_transducer.Set (n0, v0);
+ m_transducer.Set (n1, v1);
+ m_transducer.Set (n2, v2);
+ m_transducer.Set (n3, v3);
+ m_transducer.Set (n4, v4);
+ m_transducer.Set (n5, v5);
+ m_transducer.Set (n6, v6);
+ m_transducer.Set (n7, v7);
+
+}
+
+void
+UanHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
+{
+ Packet::EnablePrinting ();
+ std::ostringstream oss;
+
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::UanNetDevice/Phy/RxOk";
+ Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
+
+ oss.str ("");
+
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::UanNetDevice/Phy/Tx";
+ Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
+}
+
+void
+UanHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
+{
+ for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+ {
+ Ptr<NetDevice> dev = *i;
+ EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+ }
+}
+
+void
+UanHelper::EnableAscii (std::ostream &os, NodeContainer n)
+{
+ NetDeviceContainer devs;
+ for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+ {
+ devs.Add (node->GetDevice (j));
+ }
+ }
+ EnableAscii (os, devs);
+}
+
+void
+UanHelper::EnableAsciiAll (std::ostream &os)
+{
+ EnableAscii (os, NodeContainer::GetGlobal ());
+}
+
+NetDeviceContainer
+UanHelper::Install (NodeContainer c) const
+{
+
+ Ptr<UanChannel> channel = CreateObject<UanChannel> ();
+ Ptr<UanNoiseModelDefault> noise =CreateObject<UanNoiseModelDefault> ();
+ channel->SetPropagationModel (CreateObject<UanPropModelIdeal> ());
+ channel->SetNoiseModel (noise);
+
+ return Install (c, channel);
+}
+
+NetDeviceContainer
+UanHelper::Install (NodeContainer c, Ptr<UanChannel> channel) const
+{
+ NetDeviceContainer devices;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<UanNetDevice> device = CreateObject<UanNetDevice> ();
+
+ Ptr<UanMac> mac = m_mac.Create<UanMac> ();
+ Ptr<UanPhy> phy = m_phy.Create<UanPhy> ();
+ Ptr<UanTransducer> trans = m_transducer.Create<UanTransducer> ();
+
+ mac->SetAddress (UanAddress::Allocate ());
+ device->SetMac (mac);
+ device->SetPhy (phy);
+ device->SetTransducer(trans);
+ device->SetChannel (channel);
+
+ node->AddDevice (device);
+ devices.Add (device);
+ NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
+ }
+ return devices;
+}
+
+} //end namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/uan-helper.h Thu Jun 24 14:35:29 2010 -0400
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Leonard Tracy <lentracy@u.washington.edu>
+ *
+ *
+ */
+
+#ifndef UANHELPER_H_
+#define UANHELPER_H_
+
+#include <string>
+#include "ns3/attribute.h"
+#include "ns3/object-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+
+namespace ns3
+{
+
+class UanChannel;
+
+class UanHelper
+{
+public:
+ UanHelper();
+ virtual ~UanHelper();
+
+ /**
+ * \param type the type of ns3::UanMac to create.
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ *
+ * All the attributes specified in this method should exist
+ * in the requested mac.
+ */
+ void SetMac (std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+
+ /**
+ * \param phyType the type of ns3::UanPhy to create.
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ *
+ * All the attributes specified in this method should exist
+ * in the requested phy.
+ */
+ void SetPhy (std::string phyType,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+
+ /**
+ * \param type the type of ns3::Transducer to create
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ *
+ * All the attributes specified in this method should exist
+ * in the requested transducer.
+ */
+ void SetTransducer (std::string type,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+ std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+ std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+ std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+ std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+ /**
+ * \param os output stream
+ * \param nodeid the id of the node to generate ascii output for.
+ * \param deviceid the id of the device to generate ascii output for.
+ *
+ * Enable ascii output on the specified deviceid within the
+ * specified nodeid if it is of type ns3::WifiNetDevice and dump
+ * that to the specified stdc++ output stream.
+ */
+ static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
+ /**
+ * \param os output stream
+ * \param d device container
+ *
+ * Enable ascii output on each device which is of the
+ * ns3::WifiNetDevice type and which is located in the input
+ * device container and dump that to the specified
+ * stdc++ output stream.
+ */
+ static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+ /**
+ * \param os output stream
+ * \param n node container
+ *
+ * Enable ascii output on each device which is of the
+ * ns3::WifiNetDevice type and which is located in one
+ * of the input node and dump that to the specified
+ * stdc++ output stream.
+ */
+ static void EnableAscii (std::ostream &os, NodeContainer n);
+ /**
+ * \param os output stream
+ *
+ * Enable ascii output on each device which is of the
+ * ns3::WifiNetDevice type and dump that to the specified
+ * stdc++ output stream.
+ */
+ static void EnableAsciiAll (std::ostream &os);
+
+ /**
+ * \param c a set of nodes
+ *
+ * This method creates a simple ns3::WifiChannel (with a default
+ * ns3::PropagationLossModel and ns3::PropagationDelayModel) and
+ * creates, for each of the input nodes, a new ns3::WifiNetDevice
+ * attached to this shared channel. Each ns3::WifiNetDevice is also
+ * configured with an ns3::WifiRemoteStationManager, ns3::WifiMac, and,
+ * ns3::WifiPhy, all of which are created based on the user-specified
+ * attributes specified in WifiHelper::SetRemoteStationManager,
+ * WifiHelper::SetMac, and, WifiHelper::SetPhy.
+ */
+
+ NetDeviceContainer Install (NodeContainer c) const;
+ /**
+ * \param channel a channel to use
+ * \param c a set of nodes
+ *
+ * For each of the input nodes, a new ns3::WifiNetDevice is attached
+ * to the shared input channel. Each ns3::WifiNetDevice is also
+ * configured with an ns3::WifiRemoteStationManager, ns3::WifiMac, and,
+ * ns3::WifiPhy, all of which are created based on the user-specified
+ * attributes specified in WifiHelper::SetRemoteStationManager,
+ * WifiHelper::SetMac, and, WifiHelper::SetPhy.
+ *
+ * The user is expected to attach to the input channel a proper
+ * ns3::PropagationLossModel, and ns3::PropagationDelayModel.
+ */
+ NetDeviceContainer Install (NodeContainer c, Ptr<UanChannel> channel) const;
+
+private:
+ ObjectFactory m_mac;
+ ObjectFactory m_phy;
+ ObjectFactory m_transducer;
+
+};
+
+
+} //end namespace ns3
+
+#endif /* UANHELPER_H_ */
--- a/src/helper/wscript Thu Jun 24 10:04:30 2010 -0700
+++ b/src/helper/wscript Thu Jun 24 14:35:29 2010 -0400
@@ -25,6 +25,7 @@
'spectrum-helper.cc',
'adhoc-aloha-noack-ideal-phy-helper.cc',
'v4ping-helper.cc',
+ 'uan-helper.cc',
'nqos-wifi-mac-helper.cc',
'qos-wifi-mac-helper.cc',
'ipv4-nix-vector-helper.cc',
@@ -82,6 +83,7 @@
'spectrum-helper.h',
'adhoc-aloha-noack-ideal-phy-helper.h',
'v4ping-helper.h',
+ 'uan-helper.h',
'nqos-wifi-mac-helper.h',
'qos-wifi-mac-helper.h',
'ipv4-nix-vector-helper.h',
--- a/src/wscript Thu Jun 24 10:04:30 2010 -0700
+++ b/src/wscript Thu Jun 24 14:35:29 2010 -0400
@@ -43,6 +43,8 @@
'helper',
'contrib/stats',
'applications/v4ping',
+ 'devices/uan',
+ 'devices/mesh',
'devices/spectrum',
'devices/mesh',
'devices/mesh/dot11s',