1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/scratch/cwexp.cc Wed Apr 01 00:31:47 2009 -0700
1.3 @@ -0,0 +1,263 @@
1.4 +/*
1.5 + * cwexp.cc
1.6 + *
1.7 + * Created on: 15-Jan-2009
1.8 + * Author: Leonard Tracy
1.9 + */
1.10 +
1.11 +
1.12 +#include "ns3/core-module.h"
1.13 +#include "ns3/common-module.h"
1.14 +#include "ns3/uan-module.h"
1.15 +#include "ns3/node-module.h"
1.16 +#include "ns3/mobility-module.h"
1.17 +#include "ns3/contrib-module.h"
1.18 +#include "ns3/helper-module.h"
1.19 +
1.20 +#include <iostream>
1.21 +#include <fstream>
1.22 +
1.23 +using namespace ns3;
1.24 +
1.25 +NS_LOG_COMPONENT_DEFINE("CwExp");
1.26 +
1.27 +
1.28 +class Experiment
1.29 +{
1.30 +public:
1.31 +
1.32 + Experiment() : m_BytesTotal(0),
1.33 + m_asciitracefile("cwascii.tr") { }
1.34 +
1.35 + ///Runs an experiment with the current settings
1.36 + Gnuplot2dDataset Run(UanHelper &uan);
1.37 + void ReceivePacket(Ptr<Socket> socket);
1.38 + void UpdatePositions(NodeContainer &nodes, NetDeviceContainer &dev, uint32_t cw);
1.39 + void ResetData(std::ostream *os, uint32_t cw);
1.40 + uint32_t m_NumNodes;
1.41 + uint32_t m_DataRate;
1.42 + double m_Load;
1.43 + double m_Boundary;
1.44 + double m_Depth;
1.45 + uint32_t m_PacketSize;
1.46 + uint32_t m_BytesTotal;
1.47 + uint32_t m_CwMin;
1.48 + uint32_t m_CwMax;
1.49 + uint32_t m_Avgs;
1.50 +
1.51 + std::string m_mldatfile;
1.52 + std::string m_gnudatfile;
1.53 + std::string m_asciitracefile;
1.54 +
1.55 + Time m_SlotTime;
1.56 +
1.57 +
1.58 + Gnuplot2dDataset m_Data;
1.59 +
1.60 +};
1.61 +
1.62 +void
1.63 +Experiment::ResetData(std::ostream *os, uint32_t cw)
1.64 +{
1.65 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Resetting data");
1.66 + m_Data.Add(cw, m_BytesTotal);
1.67 + *os << cw << " " << m_BytesTotal << std::endl;
1.68 + m_BytesTotal = 0;
1.69 +}
1.70 +
1.71 +void
1.72 +Experiment::UpdatePositions(NodeContainer &nodes, NetDeviceContainer &devices, uint32_t cw)
1.73 +{
1.74 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Updating positions");
1.75 + NodeContainer::Iterator it = nodes.Begin();
1.76 + for(;it != nodes.End();it++)
1.77 + {
1.78 + Ptr<MobilityModel> mp = (*it)->GetObject<MobilityModel>();
1.79 + UniformVariable uv(0,m_Boundary);
1.80 +
1.81 + Vector a(uv.GetValue(),
1.82 + uv.GetValue(),
1.83 + 70.0);
1.84 + NS_LOG_DEBUG("Setting new position: " << a);
1.85 + }
1.86 +
1.87 + Config::Set("/NodeList/*/DeviceList/*/Mac/CW", UintegerValue(cw));
1.88 +
1.89 +}
1.90 +
1.91 +void
1.92 +Experiment::ReceivePacket(Ptr<Socket> socket)
1.93 +{
1.94 + Ptr<Packet> packet;
1.95 + //NS_LOG_DEBUG("Receiving packet?");
1.96 + while(packet = socket->Recv())
1.97 + {
1.98 + //NS_LOG_DEBUG("Packetsize = " << packet->GetSize());
1.99 + m_BytesTotal += packet->GetSize();
1.100 + //std::cout << "Received packet: " << *packet;
1.101 + }
1.102 +}
1.103 +Gnuplot2dDataset
1.104 +Experiment::Run(UanHelper &uan)
1.105 +{
1.106 + uan.SetMac("ns3::UanMacCw", "CW", UintegerValue(m_CwMin), "SlotTime", TimeValue(m_SlotTime));
1.107 +
1.108 + NodeContainer nc = NodeContainer();
1.109 + NodeContainer sink = NodeContainer();
1.110 + nc.Create(m_NumNodes);
1.111 + sink.Create(1);
1.112 +
1.113 + PacketSocketHelper pktskth;
1.114 + pktskth.Install(nc);
1.115 + pktskth.Install(sink);
1.116 +
1.117 + Ptr<UanPropModelBh> prop = CreateObject<UanPropModelBh>("ConfigFile", StringValue("../uan-apps/exbhconfig.cfg"));
1.118 + Ptr<UanPropModelIdeal> iprop = CreateObject<UanPropModelIdeal>();
1.119 + Ptr<UanChannel> channel = CreateObject<UanChannel>("PropagationModel", PointerValue(iprop));
1.120 +
1.121 + //Create net device and nodes with UanHelper
1.122 + NetDeviceContainer devices = uan.Install(nc, channel);
1.123 + NetDeviceContainer sinkdev = uan.Install(sink, channel);
1.124 +
1.125 + MobilityHelper mobility;
1.126 + Ptr<ListPositionAllocator> pos = CreateObject<ListPositionAllocator>();
1.127 + pos->Add(Vector(m_Boundary/2, m_Boundary/2, m_Depth));
1.128 + UniformVariable urv(0,m_Boundary);
1.129 +
1.130 + for(uint32_t i=0;i<m_NumNodes;i++)
1.131 + {
1.132 + pos->Add(Vector(urv.GetValue(), urv.GetValue(), m_Depth));
1.133 + }
1.134 +
1.135 + mobility.SetPositionAllocator(pos);
1.136 + mobility.SetMobilityModel("ns3::StaticMobilityModel");
1.137 + mobility.Install(sink);
1.138 +
1.139 + NS_LOG_DEBUG("Position of sink: " << sink.Get(0)->GetObject<MobilityModel>()->GetPosition());
1.140 + mobility.Install(nc);
1.141 +
1.142 +
1.143 + NodeContainer::Iterator it = nc.Begin();
1.144 + for(uint32_t i=0;i<nc.GetN();i++)
1.145 + {
1.146 + Ptr<Node> node = nc.Get(i);
1.147 + Ptr<NetDevice> dev = devices.Get(i);
1.148 + NS_LOG_DEBUG("Position of node " << dev->GetAddress() << ": " << node->GetObject<MobilityModel>()->GetPosition());
1.149 + it++;
1.150 + }
1.151 +
1.152 + PacketSocketAddress socket;
1.153 + socket.SetSingleDevice(sinkdev.Get(0)->GetIfIndex());
1.154 + socket.SetPhysicalAddress(sinkdev.Get(0)->GetAddress());
1.155 + socket.SetProtocol(0);
1.156 + NS_LOG_DEBUG("Remote address: " << socket);
1.157 +
1.158 + OnOffHelper app("ns3::PacketSocketFactory", Address(socket));
1.159 + app.SetAttribute("OnTime", RandomVariableValue(ConstantVariable ( (m_CwMax - m_CwMin + 1)*2500*m_Avgs)));
1.160 + app.SetAttribute("OffTime", RandomVariableValue(ConstantVariable(0)));
1.161 + app.SetAttribute("DataRate", DataRateValue(m_DataRate));
1.162 + app.SetAttribute("PacketSize", UintegerValue(m_PacketSize));
1.163 +
1.164 + //Schedule update events;
1.165 + Time simTime = Seconds(2000);
1.166 +
1.167 + ApplicationContainer apps = app.Install(nc);
1.168 + apps.Start(Seconds(0.5));
1.169 + Time now = Seconds(0.5);
1.170 + uint32_t cw = m_CwMin;
1.171 +
1.172 + std::ofstream mld(m_mldatfile.c_str());
1.173 + uint32_t an = 0;
1.174 + while(cw <= m_CwMax)
1.175 + {
1.176 + now += simTime;
1.177 + Simulator::Schedule(now, &Experiment::ResetData, this, &mld, cw);
1.178 + an++;
1.179 + if(an == m_Avgs)
1.180 + {
1.181 + cw++;
1.182 + an=0;
1.183 + }
1.184 + Simulator::Schedule(now, &Experiment::UpdatePositions, this, nc, devices, cw);
1.185 + }
1.186 + apps.Stop(now + simTime);
1.187 +
1.188 + Ptr<Node> sinkNode = sink.Get(0);
1.189 + TypeId psfid = TypeId::LookupByName("ns3::PacketSocketFactory");
1.190 + if(sinkNode->GetObject<SocketFactory>(psfid) == 0)
1.191 + {
1.192 + Ptr<PacketSocketFactory> psf = CreateObject<PacketSocketFactory>();
1.193 + sinkNode->AggregateObject(psf);
1.194 + }
1.195 + Ptr<Socket> sinkSocket = Socket::CreateSocket(sinkNode, psfid);
1.196 + sinkSocket->Bind(socket);
1.197 + sinkSocket->SetRecvCallback(MakeCallback(&Experiment::ReceivePacket, this));
1.198 +
1.199 + m_BytesTotal = 0;
1.200 +
1.201 + //GtkConfigStore config;
1.202 + //config.Configure();
1.203 +
1.204 +// std::ofstream ascii(m_asciitracefile.c_str());
1.205 +// uan.EnableAsciiAll(ascii);
1.206 +
1.207 + Simulator::Run();
1.208 + Simulator::Destroy();
1.209 + return m_Data;
1.210 +}
1.211 +
1.212 +int
1.213 +main(int argc, char **argv)
1.214 +{
1.215 +
1.216 + LogComponentEnable("CwExp", LOG_LEVEL_ALL);
1.217 + LogComponentEnable("UanMacCw", LOG_LEVEL_ALL);
1.218 + //LogComponentEnable("UanMacAloha", LOG_LEVEL_ALL);
1.219 + LogComponentEnable("UanPhyGen", LOG_LEVEL_ALL);
1.220 +
1.221 + //uan.SetMac("ns3::UanMacCw", "CW", UintegerValue(60), "SlotTime", TimeValue(Seconds(0.2)));
1.222 +
1.223 + Experiment exp;
1.224 + exp.m_NumNodes = 15;
1.225 + exp.m_Depth = 70;
1.226 + exp.m_Boundary = 500;
1.227 + exp.m_PacketSize = 32;
1.228 + exp.m_DataRate = 80;
1.229 + exp.m_CwMin = 2;
1.230 + exp.m_CwMax = 200;
1.231 + double slottime = 0.2;
1.232 + exp.m_Avgs = 7;
1.233 + exp.m_mldatfile = std::string("cwexpmlout.dat");
1.234 + std::string gnudatfile("cwexpgnuout.dat");
1.235 +
1.236 + CommandLine cmd;
1.237 + cmd.AddValue("NumNodes", "Number of transmitting nodes", exp.m_NumNodes);
1.238 + cmd.AddValue("Depth", "Depth of transmitting and sink nodes", exp.m_Depth);
1.239 + cmd.AddValue("RegionSize", "Size of boundary in meters", exp.m_Boundary);
1.240 + cmd.AddValue("PacketSize", "Generated packet size in bytes", exp.m_PacketSize);
1.241 + cmd.AddValue("DataRate", "DataRate in bps", exp.m_DataRate);
1.242 + cmd.AddValue("CwMin", "Min CW to simulate", exp.m_CwMin);
1.243 + cmd.AddValue("CwMax", "Max CW to simulate", exp.m_CwMax);
1.244 + cmd.AddValue("SlotTime", "Slot duration in seconds", slottime);
1.245 + cmd.AddValue("Averages", "Number of topologies to test for each cw point", exp.m_Avgs);
1.246 + cmd.AddValue("MlFile", "Name for plain text file output", exp.m_mldatfile);
1.247 + cmd.AddValue("GnuFile", "Name for GNU Plot output", gnudatfile);
1.248 +
1.249 + cmd.Parse(argc, argv);
1.250 +
1.251 + exp.m_SlotTime = Seconds(slottime);
1.252 +
1.253 + UanHelper uan;
1.254 + uan.SetPhy("ns3::UanPhyDual");
1.255 +
1.256 +
1.257 + Gnuplot gp;
1.258 + Gnuplot2dDataset ds;
1.259 + ds = exp.Run(uan);
1.260 +
1.261 + gp.AddDataset(ds);
1.262 + //std::ofstream of(filename.c_str());
1.263 + std::ofstream of(gnudatfile.c_str());
1.264 + gp.GenerateOutput(of);
1.265 +
1.266 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/scratch/rctest.cc Wed Apr 01 00:31:47 2009 -0700
2.3 @@ -0,0 +1,298 @@
2.4 +/*
2.5 + * rctest.cc
2.6 + *
2.7 + * Created on: 4-Mar-2009
2.8 + * Author: ltracy
2.9 + */
2.10 +
2.11 +#include "ns3/core-module.h"
2.12 +#include "ns3/common-module.h"
2.13 +#include "ns3/uan-module.h"
2.14 +#include "ns3/helper-module.h"
2.15 +#include "ns3/mobility-module.h"
2.16 +#include "ns3/node-module.h"
2.17 +#include "ns3/log.h"
2.18 +#include "ns3/config.h"
2.19 +#include "ns3/callback.h"
2.20 +
2.21 +#include <sstream>
2.22 +#include <iostream>
2.23 +#include <cmath>
2.24 +#include <fstream>
2.25 +
2.26 +NS_LOG_COMPONENT_DEFINE("RcTest");
2.27 +
2.28 +using namespace ns3;
2.29 +
2.30 +
2.31 +uint32_t m_bytesRx;
2.32 +namespace ns3
2.33 +{
2.34 +extern uint32_t m_cntrlSends;
2.35 +}
2.36 +
2.37 +
2.38 +static void
2.39 +ReceivePacket(Ptr<Socket> socket)
2.40 +{
2.41 +
2.42 + Ptr<Packet> packet;
2.43 + while(packet = socket->Recv())
2.44 + {
2.45 + m_bytesRx += packet->GetSize();
2.46 + }
2.47 +
2.48 +}
2.49 +
2.50 +static void
2.51 +TraceCycle(std::ostream *os, Time startTime,
2.52 + Time minPdelay, uint32_t numRes, uint32_t bytes,
2.53 + double winSec, uint32_t ctlRate, double retryRate)
2.54 +{
2.55 + *os << startTime.GetSeconds() << " " << minPdelay.GetSeconds() << " " << numRes << " "
2.56 + << bytes << " " << winSec << " " << ctlRate << " " << retryRate << std::endl;
2.57 +}
2.58 +
2.59 +//static void
2.60 +//SendPacket(Ptr<NetDevice> dev)
2.61 +//{
2.62 +// NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Sending packet");
2.63 +// Ptr<Packet> pkt = Create<Packet>(1000);
2.64 +// dev->Send(pkt, UanAddress(UanAddress::GetBroadcast()), 0);
2.65 +//}
2.66 +
2.67 +UanTxMode
2.68 +CreateMode(uint32_t ktot, uint32_t kass, uint32_t b, uint32_t m, uint32_t fc, bool upperblock, std::string name)
2.69 +{
2.70 +
2.71 + std::ostringstream buf;
2.72 + buf << name << " " << kass;
2.73 +
2.74 + uint32_t rate = b/ktot* (kass) * m;
2.75 + uint32_t bw = kass * b / ktot;
2.76 + uint32_t fcmode;
2.77 + if(upperblock)
2.78 + fcmode = (b - bw)/2 + fc;
2.79 + else
2.80 + fcmode = (uint32_t) ((-((double) b ) + (double) bw)/2.0 + (double) fc);
2.81 +
2.82 +
2.83 + uint32_t phyrate = b;
2.84 +
2.85 + UanTxMode mode;
2.86 + mode = UanTxModeFactory::CreateMode(UanTxMode::OTHER,
2.87 + rate,
2.88 + phyrate,
2.89 + fcmode,
2.90 + bw,
2.91 + (uint32_t) std::pow(double(2),double(m)),
2.92 + buf.str());
2.93 + return mode;
2.94 +
2.95 +}
2.96 +
2.97 +//Want rate 0 = fastest data rate/slowest control channel rate.
2.98 +//Assume over simplified OFDMA with K available subcarriers, total bandwidth B and m bits per symbol
2.99 +//Also assume that we can divy up between the two channels by ind. subcarrier, i.e. # of rates = K
2.100 +void
2.101 +CreateDualModes(UanModesList &dataModes, UanModesList &controlModes, uint32_t k, uint32_t b, uint32_t m, uint32_t fc)
2.102 +{
2.103 +
2.104 +
2.105 + for(uint32_t i=1;i < k; i++)
2.106 + {
2.107 + controlModes.AppendMode(CreateMode(k, i, b, m, fc, false, "control "));
2.108 + }
2.109 + for(uint32_t i=k-1; i > 0; i--)
2.110 + {
2.111 + dataModes.AppendMode(CreateMode(k, i, b, m, fc, true, "data "));
2.112 + }
2.113 +}
2.114 +
2.115 +
2.116 +int
2.117 +main(int argc, char *argv[])
2.118 +{
2.119 +
2.120 + LogComponentEnable("UanMacRc", LOG_LEVEL_ALL);
2.121 + LogComponentEnable("UanMacRcGw", LOG_LEVEL_ALL);
2.122 + //LogComponentEnable("UanPhyDual", LOG_LEVEL_ALL);
2.123 + LogComponentEnable("RcTest", LOG_LEVEL_ALL);
2.124 + //LogComponentEnable("UanPhyGen", LOG_LEVEL_ALL);
2.125 + //LogComponentEnable("UanTransducerHd", LOG_LEVEL_ALL);
2.126 +
2.127 + uint32_t totalRate=4096;
2.128 + uint32_t numRates=1024;
2.129 + uint32_t amin = 1;
2.130 + uint32_t amax = 50;
2.131 + uint32_t runNumber=0;
2.132 + uint32_t seed=0;
2.133 + uint32_t maxr=1000;
2.134 + uint32_t N=30;
2.135 + double SIFS = 0.05;
2.136 + double simTime = 5000.0;
2.137 + uint32_t pktSize = 1000;
2.138 + std::string tputfile = "rctest.dat";
2.139 + std::string cycleFile = "cycles.dat";
2.140 +
2.141 + CommandLine cmd;
2.142 + cmd.AddValue("RunNumber", "RunNumber to give to RNG", runNumber);
2.143 + cmd.AddValue("TotalRate", "Total channel capacity", totalRate);
2.144 + cmd.AddValue("NumberRates", "Number of divided rates", numRates);
2.145 + cmd.AddValue("MaxRange", "Maximum range between gateway and acoustic node", maxr);
2.146 + cmd.AddValue("AMin", "Minimum constant to test", amin);
2.147 + cmd.AddValue("AMax", "Maximum constant to test", amax);
2.148 + cmd.AddValue("TputFile", "Filename of throughput log", tputfile);
2.149 + cmd.AddValue("NumberNodes", "Number of nodes", N);
2.150 + cmd.AddValue("SIFS", "SIFS duration (seconds)", SIFS);
2.151 + cmd.AddValue("PktSize", "Packet size in bytes", pktSize);
2.152 + cmd.AddValue("SimTime", "Seconds of simulation time", simTime);
2.153 + cmd.AddValue("CyclesFile", "Filename of file to log cycle stats to", cycleFile);
2.154 +
2.155 + cmd.Parse(argc,argv);
2.156 +
2.157 +
2.158 + UanModesList dataModes;
2.159 + UanModesList controlModes;
2.160 +
2.161 + CreateDualModes(dataModes, controlModes, numRates, totalRate, 1, 12000);
2.162 +
2.163 +// uint32_t printMode = 0;
2.164 +// std::cout << "Data: " << dataModes[printMode].GetDataRateBps() << ", " << dataModes[printMode].GetBandwidthHz() << ", " << dataModes[printMode].GetCenterFreqHz() << std::endl;
2.165 +// std::cout << "Control: " << controlModes[printMode].GetDataRateBps() << ", " << controlModes[printMode].GetBandwidthHz() << ", " << controlModes[printMode].GetCenterFreqHz() << std::endl;
2.166 +
2.167 + UanHelper uan;
2.168 + uan.SetPhy("ns3::UanPhyDual",
2.169 + "SupportedModesPhy1", UanModesListValue(dataModes),
2.170 + "SupportedModesPhy2", UanModesListValue(controlModes));
2.171 +
2.172 + std::ofstream data(tputfile.c_str());
2.173 +
2.174 + if(seed)
2.175 + {
2.176 + NS_ASSERT(SeedManager::CheckSeed(1));
2.177 + SeedManager::SetSeed(seed);
2.178 + SeedManager::SetRun(runNumber);
2.179 + }
2.180 +
2.181 + for(uint32_t km=amin;km<=amax;km++)
2.182 + {
2.183 +
2.184 +
2.185 +
2.186 + NS_LOG_DEBUG("Run number: " << runNumber);
2.187 +
2.188 + uan.SetMac("ns3::UanMacRcGw",
2.189 + "NumberOfRates", UintegerValue(dataModes.GetNModes()),
2.190 + "NumberOfNodes", UintegerValue(N),
2.191 + "MaxReservations", UintegerValue(km),
2.192 + "RetryRate", DoubleValue(1/30.0),
2.193 + "SIFS", TimeValue(Seconds(SIFS)),
2.194 + "MaxPropDelay", TimeValue(Seconds(maxr/1500.0)));
2.195 +
2.196 +
2.197 + Ptr<UanChannel> chan = CreateObject<UanChannel>();
2.198 +
2.199 + NodeContainer sink;
2.200 + sink.Create(1);
2.201 +
2.202 +
2.203 + NetDeviceContainer sinkDev = uan.Install(sink, chan);
2.204 + //Trace cycles
2.205 + std::ostringstream oss;
2.206 + uint32_t nodeid = sink.Get(0)->GetId();
2.207 + uint32_t devid = sinkDev.Get(0)->GetIfIndex();
2.208 + oss << "/NodeList/" << nodeid << "/DeviceList/" << devid << "/$ns3::UanNetDevice/Mac/Cycle";
2.209 + std::ofstream cycle(cycleFile.c_str());
2.210 + Config::ConnectWithoutContext(oss.str(), MakeBoundCallback(&TraceCycle, &cycle) );
2.211 +
2.212 + uan.SetMac("ns3::UanMacRc", "NumberOfRates", UintegerValue(dataModes.GetNModes()),
2.213 + "RetryRate", DoubleValue(1/100.0));
2.214 +
2.215 + NodeContainer nodes;
2.216 + nodes.Create(N);
2.217 +
2.218 + NetDeviceContainer devices = uan.Install(nodes, chan);
2.219 +
2.220 + MobilityHelper mobility;
2.221 +
2.222 +
2.223 + uint32_t depth = 70;
2.224 + UniformVariable urv(0,maxr);
2.225 +
2.226 + Ptr<ListPositionAllocator> pos = CreateObject<ListPositionAllocator>();
2.227 + pos->Add(Vector(maxr, maxr, depth));
2.228 + double rsum=0;;
2.229 + double minr = 2*maxr;
2.230 + for(uint32_t i=0;i<N;i++)
2.231 + {
2.232 + UniformVariable uv(0, 2*M_PI);
2.233 + double theta = uv.GetValue();
2.234 + double newr = urv.GetValue();
2.235 + rsum += newr;
2.236 + minr = std::min(minr, newr);
2.237 + pos->Add(Vector(maxr + cos(theta)*newr, maxr + sin(theta)*newr, depth));
2.238 +
2.239 + }
2.240 + NS_LOG_DEBUG("Mean range from gateway: " << rsum/N << " min. range " << minr);
2.241 + mobility.SetPositionAllocator(pos);
2.242 + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2.243 + mobility.Install(sink);
2.244 + mobility.Install(nodes);
2.245 +
2.246 + Ptr<MobilityModel> mp = sink.Get(0)->GetObject<MobilityModel>();
2.247 + NS_LOG_DEBUG("Sink position " << mp->GetPosition());
2.248 + NodeContainer::Iterator it = nodes.Begin();
2.249 + for(;it != nodes.End();it++)
2.250 + {
2.251 + Ptr<MobilityModel> mp = (*it)->GetObject<MobilityModel>();
2.252 + NS_LOG_DEBUG("Node position: " << mp->GetPosition());
2.253 + }
2.254 +
2.255 + PacketSocketHelper pktskth;
2.256 + pktskth.Install(nodes);
2.257 + pktskth.Install(sink);
2.258 +
2.259 + PacketSocketAddress socket;
2.260 + socket.SetSingleDevice(sinkDev.Get(0)->GetIfIndex());
2.261 + socket.SetPhysicalAddress(sinkDev.Get(0)->GetAddress());
2.262 + socket.SetProtocol(0);
2.263 +
2.264 + OnOffHelper app("ns3::PacketSocketFactory", Address(socket));
2.265 + app.SetAttribute("OnTime", RandomVariableValue(ConstantVariable(2*simTime)));
2.266 + app.SetAttribute("OffTime", RandomVariableValue(ConstantVariable(0)));
2.267 + app.SetAttribute("DataRate", DataRateValue(totalRate));
2.268 + app.SetAttribute("PacketSize", UintegerValue(pktSize));
2.269 +
2.270 + ApplicationContainer apps = app.Install(nodes);
2.271 +
2.272 + apps.Start(Seconds(0.5));
2.273 + apps.Stop((Seconds(simTime+0.5)));
2.274 +
2.275 + Ptr<Node> sinkNode = sink.Get(0);
2.276 + TypeId psfid = TypeId::LookupByName("ns3::PacketSocketFactory");
2.277 + if(sinkNode->GetObject<SocketFactory>(psfid) == 0)
2.278 + {
2.279 + Ptr<PacketSocketFactory> psf = CreateObject<PacketSocketFactory>();
2.280 + sinkNode->AggregateObject(psf);
2.281 + }
2.282 + Ptr<Socket> sinkSocket = Socket::CreateSocket(sinkNode, psfid);
2.283 + sinkSocket->Bind(socket);
2.284 + sinkSocket->SetRecvCallback(MakeCallback(ReceivePacket));
2.285 +
2.286 + Simulator::Stop(Seconds(simTime + 0.6));
2.287 + Simulator::Run();
2.288 + Simulator::Destroy();
2.289 +
2.290 + std::cout << "Received " << m_bytesRx << " bytes at sink" << std::endl;
2.291 + std::cout << "Control channel attempts " << m_cntrlSends << std::endl;
2.292 + double throughput = m_bytesRx*8.0/(5000.0*4096.0);
2.293 + std::cout << "a = " << km << " Throughput = " << throughput << std::endl;
2.294 +
2.295 + data << km << " " << throughput << std::endl;
2.296 + m_bytesRx = 0;
2.297 + m_cntrlSends = 0;
2.298 +
2.299 +
2.300 + }
2.301 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/devices/uan/uan-address.cc Wed Apr 01 00:31:47 2009 -0700
3.3 @@ -0,0 +1,137 @@
3.4 +/*
3.5 + * Copyright (c) 2008 University of Washington
3.6 + *
3.7 + * This program is free software: you can redistribute it and/or modify
3.8 + * it under the terms of the GNU General Public License as published by
3.9 + * the Free Software Foundation, either version 3 of the License, or
3.10 + * (at your option) any later version.
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details.
3.16 + *
3.17 + * You should have received a copy of the GNU General Public License
3.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
3.19 + *
3.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
3.21 + *
3.22 + *
3.23 + */
3.24 +
3.25 +#include "uan-address.h"
3.26 +#include "ns3/address.h"
3.27 +
3.28 +namespace ns3
3.29 +{
3.30 +
3.31 +UanAddress::UanAddress()
3.32 +{
3.33 + m_address = 255;
3.34 +}
3.35 +
3.36 +UanAddress::UanAddress(uint8_t addr) :
3.37 + m_address(addr)
3.38 +{
3.39 +}
3.40 +
3.41 +UanAddress::~UanAddress()
3.42 +{
3.43 +}
3.44 +
3.45 +uint8_t
3.46 +UanAddress::GetType (void)
3.47 +{
3.48 + static uint8_t type = Address::Register ();
3.49 + return type;
3.50 +}
3.51 +
3.52 +
3.53 +Address
3.54 +UanAddress::ConvertTo(void) const
3.55 +{
3.56 + return Address(GetType(), &m_address, 1);
3.57 +}
3.58 +
3.59 +
3.60 +UanAddress
3.61 +UanAddress::ConvertFrom(const Address &address)
3.62 +{
3.63 + NS_ASSERT(IsMatchingType(address));
3.64 + UanAddress uAddr;
3.65 + address.CopyTo(&uAddr.m_address);
3.66 + return uAddr;
3.67 +}
3.68 +
3.69 +uint8_t
3.70 +UanAddress::GetAsInt(void) const
3.71 +{
3.72 + return m_address;
3.73 +}
3.74 +bool
3.75 +UanAddress::IsMatchingType (const Address &address)
3.76 +{
3.77 + return address.CheckCompatible(GetType(), 1);
3.78 +}
3.79 +
3.80 +UanAddress::operator Address () const
3.81 +{
3.82 + return ConvertTo();
3.83 +}
3.84 +
3.85 +void
3.86 +UanAddress::CopyFrom(const uint8_t *pBuffer)
3.87 +{
3.88 + m_address = *pBuffer;
3.89 +}
3.90 +
3.91 +void
3.92 +UanAddress::CopyTo(uint8_t *pBuffer)
3.93 +{
3.94 + *pBuffer = m_address;
3.95 +
3.96 +}
3.97 +
3.98 +UanAddress
3.99 +UanAddress::GetBroadcast()
3.100 +{
3.101 + return UanAddress(255);
3.102 +}
3.103 +UanAddress
3.104 +UanAddress::Allocate()
3.105 +{
3.106 + static uint8_t nextAllocated=0;
3.107 +
3.108 + uint32_t address = nextAllocated++;
3.109 + if(nextAllocated == 255)
3.110 + nextAllocated = 0;
3.111 +
3.112 + return UanAddress(address);
3.113 +}
3.114 +
3.115 +bool operator == (const UanAddress &a, const UanAddress &b)
3.116 +{
3.117 + return a.m_address == b.m_address;
3.118 +}
3.119 +
3.120 +bool operator != (const UanAddress &a, const UanAddress &b)
3.121 +{
3.122 + return !(a==b);
3.123 +}
3.124 +
3.125 +std::ostream& operator<< (std::ostream& os, const UanAddress & address)
3.126 +{
3.127 + os << (int) address.m_address;
3.128 + return os;
3.129 +}
3.130 +std::istream& operator>> (std::istream& is, UanAddress & address)
3.131 +{
3.132 + int x;
3.133 + is >> x;
3.134 + NS_ASSERT(0 <= x);
3.135 + NS_ASSERT(x <= 255);
3.136 + address.m_address = x;
3.137 + return is;
3.138 +}
3.139 +
3.140 +} //namespace ns3
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/devices/uan/uan-address.h Wed Apr 01 00:31:47 2009 -0700
4.3 @@ -0,0 +1,86 @@
4.4 +/*
4.5 + * Copyright (c) 2008 University of Washington
4.6 + *
4.7 + * This program is free software: you can redistribute it and/or modify
4.8 + * it under the terms of the GNU General Public License as published by
4.9 + * the Free Software Foundation, either version 3 of the License, or
4.10 + * (at your option) any later version.
4.11 + *
4.12 + * This program is distributed in the hope that it will be useful,
4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 + * GNU General Public License for more details.
4.16 + *
4.17 + * You should have received a copy of the GNU General Public License
4.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
4.19 + *
4.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
4.21 + *
4.22 + *
4.23 + */
4.24 +
4.25 +#ifndef UANADDRESS_H_
4.26 +#define UANADDRESS_H_
4.27 +
4.28 +#include "ns3/address.h"
4.29 +#include <iostream>
4.30 +
4.31 +namespace ns3
4.32 +{
4.33 +
4.34 +/**
4.35 + * \class UanAddress
4.36 + *
4.37 + * A class used for addressing UAN MAC's. This implementation uses a simple 8 bit
4.38 + * flat addressing scheme. It is unlikely that perceived underwater networks will
4.39 + * soon exceed 200 nodes (or the overlapping of two underwater networks - the ocean is big),
4.40 + * so this should provide adequate addressing for most applications.
4.41 + */
4.42 +class UanAddress
4.43 +{
4.44 +public:
4.45 + UanAddress();
4.46 +
4.47 + UanAddress(uint8_t addr);
4.48 + virtual ~UanAddress();
4.49 +
4.50 +
4.51 + static UanAddress ConvertFrom(const Address &address);
4.52 + static bool IsMatchingType (const Address &address);
4.53 + operator Address () const;
4.54 +
4.55 + void CopyFrom(const uint8_t *pBuffer);
4.56 + void CopyTo(uint8_t *pBuffer);
4.57 +
4.58 + uint8_t GetAsInt(void) const;
4.59 +
4.60 + /**
4.61 + * \returns Broadcast address: 255
4.62 + */
4.63 + static UanAddress GetBroadcast(void);
4.64 + static UanAddress Allocate();
4.65 +
4.66 +
4.67 +private:
4.68 + uint8_t m_address;
4.69 +
4.70 + static uint8_t GetType (void);
4.71 + Address ConvertTo(void) const;
4.72 +
4.73 + friend bool operator == (const UanAddress &a, const UanAddress &b);
4.74 + friend bool operator != (const UanAddress &a, const UanAddress &b);
4.75 + friend std::ostream& operator<< (std::ostream& os, const UanAddress & address);
4.76 + friend std::istream& operator>> (std::istream& is, UanAddress & address);
4.77 +
4.78 +};
4.79 +
4.80 +
4.81 +
4.82 +bool operator == (const UanAddress &a, const UanAddress &b);
4.83 +bool operator != (const UanAddress &a, const UanAddress &b);
4.84 +std::ostream& operator<< (std::ostream& os, const UanAddress & address);
4.85 +std::istream& operator>> (std::istream& is, UanAddress & address);
4.86 +
4.87 +} //namespace ns3
4.88 +
4.89 +#endif /*UANADDRESS_H_*/
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/devices/uan/uan-channel.cc Wed Apr 01 00:31:47 2009 -0700
5.3 @@ -0,0 +1,163 @@
5.4 +/*
5.5 + * Copyright (c) 2008 University of Washington
5.6 + *
5.7 + * This program is free software: you can redistribute it and/or modify
5.8 + * it under the terms of the GNU General Public License as published by
5.9 + * the Free Software Foundation, either version 3 of the License, or
5.10 + * (at your option) any later version.
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details.
5.16 + *
5.17 + * You should have received a copy of the GNU General Public License
5.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
5.19 + *
5.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
5.21 + *
5.22 + *
5.23 + */
5.24 +
5.25 +#include "ns3/object.h"
5.26 +#include "ns3/packet.h"
5.27 +#include "ns3/simulator.h"
5.28 +#include "ns3/mobility-model.h"
5.29 +#include "ns3/net-device.h"
5.30 +#include "ns3/node.h"
5.31 +#include "ns3/log.h"
5.32 +#include "ns3/pointer.h"
5.33 +#include "ns3/log.h"
5.34 +
5.35 +#include "uan-channel.h"
5.36 +#include "uan-phy.h"
5.37 +#include "uan-prop-model.h"
5.38 +#include "uan-tx-mode.h"
5.39 +#include "uan-net-device.h"
5.40 +#include "uan-transducer.h"
5.41 +#include "uan-noise-model-default.h"
5.42 +#include "uan-prop-model-ideal.h"
5.43 +
5.44 +NS_LOG_COMPONENT_DEFINE("UanChannel");
5.45 +namespace ns3
5.46 +{
5.47 +
5.48 +NS_OBJECT_ENSURE_REGISTERED(UanChannel);
5.49 +
5.50 +TypeId
5.51 +UanChannel::GetTypeId ()
5.52 +{
5.53 + static TypeId tid = TypeId ("ns3::UanChannel")
5.54 + .SetParent<Channel> ()
5.55 + .AddConstructor<UanChannel> ()
5.56 + .AddAttribute ("PropagationModel", "A pointer to the propagation model.",
5.57 + PointerValue (CreateObject<UanPropModelIdeal>()),
5.58 + MakePointerAccessor(&UanChannel::m_prop),
5.59 + MakePointerChecker<UanPropagationModel> ())
5.60 + .AddAttribute("NoiseModel", "A pointer to the model of the channel ambient noise.",
5.61 + PointerValue(CreateObject<UanNoiseModelDefault>()),
5.62 + MakePointerAccessor(&UanChannel::m_noise),
5.63 + MakePointerChecker<UanNoiseModel>());
5.64 +
5.65 + return tid;
5.66 +}
5.67 +
5.68 +UanChannel::UanChannel() :
5.69 + m_prop(0)
5.70 +{
5.71 +}
5.72 +
5.73 +UanChannel::~UanChannel()
5.74 +{
5.75 + m_devList.clear();
5.76 +}
5.77 +
5.78 +void
5.79 +UanChannel::SetPropagationModel(Ptr<UanPropagationModel> prop)
5.80 +{
5.81 + NS_LOG_DEBUG("Set Prop Model " << this);
5.82 + m_prop = prop;
5.83 +}
5.84 +
5.85 +uint32_t
5.86 +UanChannel::GetNDevices() const
5.87 +{
5.88 + return m_devList.size();
5.89 +}
5.90 +
5.91 +Ptr<NetDevice>
5.92 +UanChannel::GetDevice(uint32_t i) const
5.93 +{
5.94 + return m_devList[i].first;
5.95 +}
5.96 +
5.97 +void
5.98 +UanChannel::AddDevice(Ptr<UanNetDevice> dev, Ptr<UanTransducer> trans)
5.99 +{
5.100 + NS_LOG_DEBUG("Adding dev/trans pair number " << m_devList.size());
5.101 + m_devList.push_back(std::make_pair(dev, trans));
5.102 +}
5.103 +
5.104 +void
5.105 +UanChannel::TxPacket(Ptr<UanTransducer> src, Ptr<Packet> packet, double txPowerDb, UanTxMode txMode)
5.106 +{
5.107 + Ptr<MobilityModel> senderMobility = 0;
5.108 +
5.109 + NS_LOG_DEBUG("Channel scheduling");
5.110 + for (UanDeviceList::const_iterator i = m_devList.begin (); i != m_devList.end (); i++)
5.111 + {
5.112 +
5.113 + if (src == i->second)
5.114 + {
5.115 + senderMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
5.116 + break;
5.117 + }
5.118 + }
5.119 + NS_ASSERT(senderMobility != 0);
5.120 + int j=0;
5.121 + for(UanDeviceList::const_iterator i = m_devList.begin(); i != m_devList.end(); i++)
5.122 + {
5.123 + if(src != i->second)
5.124 + {
5.125 + NS_LOG_DEBUG("Scheduling " << i->first->GetMac()->GetAddress());
5.126 + Ptr<MobilityModel> rcvrMobility = i->first->GetNode()->GetObject<MobilityModel> ();
5.127 + Time delay = m_prop->GetDelay(senderMobility, rcvrMobility, txMode);
5.128 + UanPdp pdp = m_prop->GetPdp(senderMobility, rcvrMobility, txMode);
5.129 + double rxPowerDb = txPowerDb + m_prop->GetPathLossDb(senderMobility, rcvrMobility, txMode);
5.130 +
5.131 + NS_LOG_DEBUG("txPowerDb="<<txPowerDb<<"dB, rxPowerDb="<<rxPowerDb<<
5.132 + "distance="<<senderMobility->GetDistanceFrom (rcvrMobility)<<"m, delay="<<delay);
5.133 +
5.134 + Ptr<Packet> copy = packet->Copy();
5.135 + Simulator::Schedule(delay, &UanChannel::SendUp, this,
5.136 + j, copy, rxPowerDb, txMode, pdp);
5.137 + }
5.138 + j++;
5.139 + }
5.140 +}
5.141 +
5.142 +void
5.143 +UanChannel::SetNoiseModel(Ptr<UanNoiseModel> noise)
5.144 +{
5.145 + NS_ASSERT(noise);
5.146 + m_noise = noise;
5.147 + NS_LOG_DEBUG("Noise test: " << m_noise->GetNoiseDbHz(22) << std::endl);
5.148 +
5.149 +}
5.150 +void
5.151 +UanChannel::SendUp(uint32_t i, Ptr<Packet> packet, double rxPowerDb,
5.152 + UanTxMode txMode, UanPdp pdp)
5.153 +{
5.154 + NS_LOG_DEBUG("Channel: In sendup");
5.155 + m_devList[i].second->Receive(packet, rxPowerDb, txMode, pdp);
5.156 +}
5.157 +
5.158 +double
5.159 +UanChannel::GetNoiseDbHz(double fKhz)
5.160 +{
5.161 + NS_ASSERT(m_noise);
5.162 + double noise = m_noise->GetNoiseDbHz(fKhz);
5.163 + return noise;
5.164 +}
5.165 +
5.166 +} // namespace ns3
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/devices/uan/uan-channel.h Wed Apr 01 00:31:47 2009 -0700
6.3 @@ -0,0 +1,107 @@
6.4 +/*
6.5 + * Copyright (c) 2008 University of Washington
6.6 + *
6.7 + * This program is free software: you can redistribute it and/or modify
6.8 + * it under the terms of the GNU General Public License as published by
6.9 + * the Free Software Foundation, either version 3 of the License, or
6.10 + * (at your option) any later version.
6.11 + *
6.12 + * This program is distributed in the hope that it will be useful,
6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 + * GNU General Public License for more details.
6.16 + *
6.17 + * You should have received a copy of the GNU General Public License
6.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6.19 + *
6.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
6.21 + *
6.22 + *
6.23 + */
6.24 +
6.25 +#ifndef UANCHANNEL_H_
6.26 +#define UANCHANNEL_H_
6.27 +
6.28 +#include "ns3/net-device.h"
6.29 +#include "ns3/channel.h"
6.30 +#include "ns3/packet.h"
6.31 +#include "ns3/uan-prop-model.h"
6.32 +#include "ns3/uan-noise-model.h"
6.33 +
6.34 +#include <list>
6.35 +#include <vector>
6.36 +
6.37 +namespace ns3
6.38 +{
6.39 +
6.40 +class UanNetDevice;
6.41 +class UanPhy;
6.42 +class UanTransducer;
6.43 +class UanTxMode;
6.44 +
6.45 +
6.46 +class UanChannel : public Channel
6.47 +{
6.48 +public:
6.49 +
6.50 + typedef std::vector<std::pair<Ptr<UanNetDevice>, Ptr<UanTransducer> > >
6.51 + UanDeviceList;
6.52 +
6.53 + UanChannel();
6.54 + UanChannel(std::string name);
6.55 + virtual ~UanChannel();
6.56 +
6.57 + static TypeId GetTypeId();
6.58 +
6.59 + //Methods inherrited from base class
6.60 + virtual uint32_t GetNDevices(void) const;
6.61 + virtual Ptr<NetDevice> GetDevice(uint32_t i) const;
6.62 +
6.63 + /**
6.64 + * \param src Transducer transmitting packet
6.65 + * \param packet Packet to be transmitted
6.66 + * \param txPowerDb Transmission power in dB
6.67 + *
6.68 + * Send a packet out on the channel
6.69 + */
6.70 + void TxPacket(Ptr<UanTransducer> src, Ptr<Packet> packet, double txPowerDb,
6.71 + UanTxMode txmode);
6.72 +
6.73 + /**
6.74 + * \param dev Net Device of node
6.75 + * \param trans Transducer of net device attached to this channel
6.76 + *
6.77 + * Adds device to receiver list for this channel
6.78 + */
6.79 + void AddDevice(Ptr<UanNetDevice> dev, Ptr<UanTransducer> trans);
6.80 +
6.81 + /**
6.82 + * \param prop Propagation model this channel will use for path loss/propagation delay
6.83 + */
6.84 + void SetPropagationModel(Ptr<UanPropagationModel> prop);
6.85 +
6.86 + /**
6.87 + * \param noise Noise model this channel will use to determine ambient channel noise.
6.88 + *
6.89 + */
6.90 + void SetNoiseModel(Ptr<UanNoiseModel> noise);
6.91 +
6.92 + /**
6.93 + * \params fKhz Frequency in kHz
6.94 + * \returns Ambient noise in dB/Hz on channel at a frequency
6.95 + */
6.96 + double GetNoiseDbHz(double fKhz);
6.97 +
6.98 +private:
6.99 +
6.100 + UanDeviceList m_devList;
6.101 + Ptr<UanPropagationModel> m_prop;
6.102 + Ptr<UanNoiseModel> m_noise;
6.103 +
6.104 + void SendUp(uint32_t i, Ptr<Packet> packet, double rxPowerDb, UanTxMode txMode, UanPdp pdp);
6.105 +
6.106 +};
6.107 +
6.108 +}
6.109 +
6.110 +#endif /*UANCHANNEL_H_*/
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/devices/uan/uan-header-common.cc Wed Apr 01 00:31:47 2009 -0700
7.3 @@ -0,0 +1,131 @@
7.4 +/*
7.5 + * Copyright (c) 2008 University of Washington
7.6 + *
7.7 + * This program is free software: you can redistribute it and/or modify
7.8 + * it under the terms of the GNU General Public License as published by
7.9 + * the Free Software Foundation, either version 3 of the License, or
7.10 + * (at your option) any later version.
7.11 + *
7.12 + * This program is distributed in the hope that it will be useful,
7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.15 + * GNU General Public License for more details.
7.16 + *
7.17 + * You should have received a copy of the GNU General Public License
7.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7.19 + *
7.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
7.21 + *
7.22 + *
7.23 + */
7.24 +
7.25 +#include "uan-header-common.h"
7.26 +#include "uan-address.h"
7.27 +
7.28 +namespace ns3
7.29 +{
7.30 +
7.31 +UanHeaderCommon::UanHeaderCommon()
7.32 +{
7.33 +}
7.34 +
7.35 +UanHeaderCommon::UanHeaderCommon(const UanAddress src, const UanAddress dest, uint8_t type) :
7.36 + Header(),
7.37 + m_dest(dest),
7.38 + m_src(src),
7.39 + m_type(type)
7.40 +{
7.41 +
7.42 +}
7.43 +
7.44 +TypeId
7.45 +UanHeaderCommon::GetTypeId(void)
7.46 +{
7.47 + static TypeId tid = TypeId ("ns3::UanHeaderCommon")
7.48 + .SetParent<Header> ()
7.49 + .AddConstructor<UanHeaderCommon> ()
7.50 + ;
7.51 + return tid;
7.52 +}
7.53 +
7.54 +TypeId
7.55 +UanHeaderCommon::GetInstanceTypeId(void) const
7.56 +{
7.57 + return GetTypeId();
7.58 +}
7.59 +UanHeaderCommon::~UanHeaderCommon()
7.60 +{
7.61 +}
7.62 +
7.63 +
7.64 +void
7.65 +UanHeaderCommon::SetDest(UanAddress dest)
7.66 +{
7.67 + m_dest = dest;
7.68 +}
7.69 +void
7.70 +UanHeaderCommon::SetSrc(UanAddress src)
7.71 +{
7.72 + m_src = src;
7.73 +}
7.74 +
7.75 +void
7.76 +UanHeaderCommon::SetType(uint8_t type)
7.77 +{
7.78 + m_type = type;
7.79 +}
7.80 +
7.81 +UanAddress
7.82 +UanHeaderCommon::GetDest(void) const
7.83 +{
7.84 + return m_dest;
7.85 +}
7.86 +UanAddress
7.87 +UanHeaderCommon::GetSrc(void) const
7.88 +{
7.89 + return m_src;
7.90 +}
7.91 +uint8_t
7.92 +UanHeaderCommon::GetType(void) const
7.93 +{
7.94 + return m_type;
7.95 +}
7.96 +
7.97 +//Inherrited methods
7.98 +
7.99 +uint32_t
7.100 +UanHeaderCommon::GetSerializedSize (void) const
7.101 +{
7.102 + return 1 + 1 + 1;
7.103 +}
7.104 +
7.105 +void
7.106 +UanHeaderCommon::Serialize (Buffer::Iterator start) const
7.107 +{
7.108 + start.WriteU8(m_src.GetAsInt());
7.109 + start.WriteU8(m_dest.GetAsInt());
7.110 + start.WriteU8(m_type);
7.111 +}
7.112 +
7.113 +uint32_t
7.114 +UanHeaderCommon::Deserialize (Buffer::Iterator start)
7.115 +{
7.116 + Buffer::Iterator rbuf = start;
7.117 +
7.118 + m_src = UanAddress(rbuf.ReadU8());
7.119 + m_dest = UanAddress(rbuf.ReadU8());
7.120 + m_type = rbuf.ReadU8();
7.121 +
7.122 + return rbuf.GetDistanceFrom(start);
7.123 +}
7.124 +
7.125 +void
7.126 +UanHeaderCommon::Print (std::ostream &os) const
7.127 +{
7.128 + os << "UAN src=" << m_src << " dest=" << m_dest << " type=" << uint32_t(m_type);
7.129 +}
7.130 +
7.131 +
7.132 +
7.133 +
7.134 +} //namespace ns3
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/devices/uan/uan-header-common.h Wed Apr 01 00:31:47 2009 -0700
8.3 @@ -0,0 +1,75 @@
8.4 +/*
8.5 + * Copyright (c) 2008 University of Washington
8.6 + *
8.7 + * This program is free software: you can redistribute it and/or modify
8.8 + * it under the terms of the GNU General Public License as published by
8.9 + * the Free Software Foundation, either version 3 of the License, or
8.10 + * (at your option) any later version.
8.11 + *
8.12 + * This program is distributed in the hope that it will be useful,
8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 + * GNU General Public License for more details.
8.16 + *
8.17 + * You should have received a copy of the GNU General Public License
8.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
8.19 + *
8.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
8.21 + *
8.22 + *
8.23 + */
8.24 +
8.25 +#ifndef UANHEADERCOMMON_H_
8.26 +#define UANHEADERCOMMON_H_
8.27 +
8.28 +#include "ns3/header.h"
8.29 +#include "ns3/nstime.h"
8.30 +#include "ns3/simulator.h"
8.31 +#include "uan-address.h"
8.32 +
8.33 +namespace ns3
8.34 +{
8.35 +
8.36 +/**
8.37 + * \class UanHeaderCommon
8.38 + *
8.39 + * Header includes 1 byte src address, 1 byte dest address,
8.40 + * and a 1 byte type field.
8.41 + */
8.42 +class UanHeaderCommon : public ns3::Header
8.43 +{
8.44 +public:
8.45 + UanHeaderCommon();
8.46 + UanHeaderCommon(const UanAddress src, const UanAddress dest, uint8_t type);
8.47 + virtual ~UanHeaderCommon();
8.48 +
8.49 + static TypeId GetTypeId(void);
8.50 +
8.51 + void SetDest(UanAddress dest);
8.52 + void SetSrc(UanAddress src);
8.53 + void SetType(uint8_t type);
8.54 +
8.55 + UanAddress GetDest(void) const;
8.56 + UanAddress GetSrc(void) const;
8.57 + uint8_t GetType(void) const;
8.58 +
8.59 +
8.60 +
8.61 + //Inherrited methods
8.62 + virtual uint32_t GetSerializedSize (void) const;
8.63 + virtual void Serialize (Buffer::Iterator start) const;
8.64 + virtual uint32_t Deserialize (Buffer::Iterator start);
8.65 + virtual void Print (std::ostream &os) const;
8.66 + virtual TypeId GetInstanceTypeId(void) const;
8.67 +private:
8.68 +
8.69 + UanAddress m_dest;
8.70 + UanAddress m_src;
8.71 + uint8_t m_type;
8.72 +
8.73 +
8.74 +};
8.75 +
8.76 +}
8.77 +
8.78 +#endif /*UANHEADERCOMMON_H_*/
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/devices/uan/uan-header-rc.cc Wed Apr 01 00:31:47 2009 -0700
9.3 @@ -0,0 +1,544 @@
9.4 +/*
9.5 + * uan-header-rc.cc
9.6 + *
9.7 + * Created on: 2-Mar-2009
9.8 + * Author: ltracy
9.9 + */
9.10 +
9.11 +#include "uan-header-rc.h"
9.12 +
9.13 +#include <set>
9.14 +
9.15 +namespace ns3
9.16 +{
9.17 +
9.18 +UanHeaderRcData::UanHeaderRcData() :
9.19 + Header(),
9.20 + m_frameNo(0),
9.21 + m_propDelay(Seconds(0))
9.22 +{
9.23 + // TODO Auto-generated constructor stub
9.24 +
9.25 +}
9.26 +
9.27 +UanHeaderRcData::UanHeaderRcData(uint8_t frameNo, Time propDelay)
9.28 + : Header(),
9.29 + m_frameNo(frameNo),
9.30 + m_propDelay(propDelay)
9.31 +{
9.32 +
9.33 +}
9.34 +
9.35 +UanHeaderRcData::~UanHeaderRcData()
9.36 +{
9.37 + // TODO Auto-generated destructor stub
9.38 +}
9.39 +
9.40 +
9.41 +TypeId
9.42 +UanHeaderRcData::GetTypeId()
9.43 +{
9.44 + static TypeId tid = TypeId("ns3::UanHeaderRcData")
9.45 + .SetParent<Header> ()
9.46 + .AddConstructor<UanHeaderRcData>()
9.47 + ;
9.48 + return tid;
9.49 +}
9.50 +
9.51 +void
9.52 +UanHeaderRcData::SetFrameNo(uint8_t no)
9.53 +{
9.54 + m_frameNo = no;
9.55 +}
9.56 +
9.57 +void
9.58 +UanHeaderRcData::SetPropDelay(Time propDelay)
9.59 +{
9.60 + m_propDelay = propDelay;
9.61 +}
9.62 +
9.63 +uint8_t
9.64 +UanHeaderRcData::GetFrameNo(void)
9.65 +{
9.66 + return m_frameNo;
9.67 +}
9.68 +
9.69 +Time
9.70 +UanHeaderRcData::GetPropDelay(void)
9.71 +{
9.72 + return m_propDelay;
9.73 +}
9.74 +
9.75 +uint32_t
9.76 +UanHeaderRcData::GetSerializedSize (void) const
9.77 +{
9.78 + return 1 + 2;
9.79 +}
9.80 +
9.81 +void
9.82 +UanHeaderRcData::Serialize (Buffer::Iterator start) const
9.83 +{
9.84 + start.WriteU8(m_frameNo);
9.85 + start.WriteU16( (uint16_t) (1000.0*m_propDelay.GetSeconds() + 0.5));
9.86 +}
9.87 +uint32_t
9.88 +UanHeaderRcData::Deserialize (Buffer::Iterator start)
9.89 +{
9.90 + Buffer::Iterator rbuf = start;
9.91 +
9.92 + m_frameNo = start.ReadU8();
9.93 + m_propDelay = Seconds( ((double) start.ReadU16())/1000.0 );
9.94 +
9.95 + return rbuf.GetDistanceFrom(start);
9.96 +}
9.97 +
9.98 +void
9.99 +UanHeaderRcData::Print (std::ostream &os) const
9.100 +{
9.101 + os << "Frame No=" << (uint32_t) m_frameNo << " Prop Delay=" << m_propDelay.GetSeconds();
9.102 +}
9.103 +
9.104 +TypeId
9.105 +UanHeaderRcData::GetInstanceTypeId(void) const
9.106 +{
9.107 + return GetTypeId();
9.108 +}
9.109 +
9.110 +
9.111 +UanHeaderRcRts::UanHeaderRcRts() :
9.112 + Header(),
9.113 + m_frameNo(0),
9.114 + m_noFrames(0),
9.115 + m_length(0),
9.116 + m_timeStamp(Seconds(0)),
9.117 + m_retryNo(0)
9.118 +{
9.119 +
9.120 +}
9.121 +
9.122 +UanHeaderRcRts::UanHeaderRcRts(uint8_t frameNo, uint8_t retryNo, uint8_t noFrames, uint16_t length, Time timeStamp) :
9.123 + Header(),
9.124 + m_frameNo(frameNo),
9.125 + m_noFrames(noFrames),
9.126 + m_length(length),
9.127 + m_timeStamp(timeStamp),
9.128 + m_retryNo(retryNo)
9.129 +{
9.130 +
9.131 +}
9.132 +
9.133 +UanHeaderRcRts::~UanHeaderRcRts()
9.134 +{
9.135 +
9.136 +}
9.137 +
9.138 +TypeId
9.139 +UanHeaderRcRts::GetTypeId()
9.140 +{
9.141 + static TypeId tid = TypeId("ns3::UanHeaderRcRts")
9.142 + .SetParent<Header> ()
9.143 + .AddConstructor<UanHeaderRcRts>()
9.144 + ;
9.145 + return tid;
9.146 +
9.147 +}
9.148 +
9.149 +void
9.150 +UanHeaderRcRts::SetFrameNo(uint8_t no)
9.151 +{
9.152 + m_frameNo = no;
9.153 +}
9.154 +
9.155 +void
9.156 +UanHeaderRcRts::SetNoFrames(uint8_t no)
9.157 +{
9.158 + m_noFrames = no;
9.159 +}
9.160 +
9.161 +void
9.162 +UanHeaderRcRts::SetLength(uint16_t length)
9.163 +{
9.164 + m_length = length;
9.165 +}
9.166 +void
9.167 +UanHeaderRcRts::SetTimeStamp(Time timeStamp)
9.168 +{
9.169 + m_timeStamp = timeStamp;
9.170 +}
9.171 +
9.172 +void
9.173 +UanHeaderRcRts::SetRetryNo(uint8_t no)
9.174 +{
9.175 + m_retryNo = no;
9.176 +}
9.177 +uint8_t
9.178 +UanHeaderRcRts::GetNoFrames()
9.179 +{
9.180 + return m_noFrames;
9.181 +}
9.182 +
9.183 +uint16_t
9.184 +UanHeaderRcRts::GetLength()
9.185 +{
9.186 + return m_length;
9.187 +}
9.188 +
9.189 +Time
9.190 +UanHeaderRcRts::GetTimeStamp(void)
9.191 +{
9.192 + return m_timeStamp;
9.193 +}
9.194 +
9.195 +uint8_t
9.196 +UanHeaderRcRts::GetRetryNo(void)
9.197 +{
9.198 + return m_retryNo;
9.199 +}
9.200 +
9.201 +uint8_t
9.202 +UanHeaderRcRts::GetFrameNo(void)
9.203 +{
9.204 + return m_frameNo;
9.205 +}
9.206 +
9.207 +uint32_t
9.208 +UanHeaderRcRts::GetSerializedSize (void) const
9.209 +{
9.210 + return 1 + 1 + 1 + 4 + 2;
9.211 +}
9.212 +
9.213 +void
9.214 +UanHeaderRcRts::Serialize (Buffer::Iterator start) const
9.215 +{
9.216 + start.WriteU8(m_frameNo);
9.217 + start.WriteU8(m_retryNo);
9.218 + start.WriteU8(m_noFrames);
9.219 + start.WriteU16(m_length);
9.220 + start.WriteU32((uint32_t) (m_timeStamp.GetSeconds()*1000.0 + 0.5));
9.221 + //start.WriteU16(uint16_t (m_timeStamp.GetSeconds()*1000));
9.222 +}
9.223 +
9.224 +uint32_t
9.225 +UanHeaderRcRts::Deserialize (Buffer::Iterator start)
9.226 +{
9.227 + Buffer::Iterator rbuf = start;
9.228 + m_frameNo = rbuf.ReadU8();
9.229 + m_retryNo = rbuf.ReadU8();
9.230 + m_noFrames = rbuf.ReadU8();
9.231 + m_length = rbuf.ReadU16();
9.232 + m_timeStamp = Seconds ( ((double) rbuf.ReadU32())/1000.0 );
9.233 + //m_timeStamp = Seconds ( rbuf.ReadU16()/1000 );
9.234 + return rbuf.GetDistanceFrom(start);
9.235 +}
9.236 +
9.237 +void
9.238 +UanHeaderRcRts::Print (std::ostream &os) const
9.239 +{
9.240 + 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();
9.241 +}
9.242 +
9.243 +TypeId
9.244 +UanHeaderRcRts::GetInstanceTypeId(void) const
9.245 +{
9.246 + return GetTypeId();
9.247 +}
9.248 +
9.249 +
9.250 +UanHeaderRcCts::UanHeaderRcCts() :
9.251 + Header(),
9.252 + m_frameNo(0),
9.253 + m_timeStamp1(Seconds(0)),
9.254 + m_timeStamp2(Seconds(0)),
9.255 + m_retryNo(0),
9.256 + m_delay(Seconds(0))
9.257 +{
9.258 +
9.259 +}
9.260 +
9.261 +UanHeaderRcCts::UanHeaderRcCts(uint8_t frameNo, uint8_t retryNo, Time ts1, Time ts2, Time delay,
9.262 + uint16_t rate, uint16_t rr, Time blockTime, Time windowTime):
9.263 + Header(),
9.264 + m_frameNo(frameNo),
9.265 + m_timeStamp1(ts1),
9.266 + m_timeStamp2(ts2),
9.267 + m_retryNo(retryNo),
9.268 + m_delay(delay),
9.269 + m_blockTime(blockTime),
9.270 + m_winTime(windowTime),
9.271 + m_retryRate(rr),
9.272 + m_rateNum(rate)
9.273 +{
9.274 +
9.275 +}
9.276 +
9.277 +UanHeaderRcCts::~UanHeaderRcCts()
9.278 +{
9.279 +
9.280 +}
9.281 +
9.282 +TypeId
9.283 +UanHeaderRcCts::GetTypeId()
9.284 +{
9.285 + static TypeId tid = TypeId("ns3::UanHeaderRcCts")
9.286 + .SetParent<Header> ()
9.287 + .AddConstructor<UanHeaderRcCts>()
9.288 + ;
9.289 + return tid;
9.290 +
9.291 +}
9.292 +
9.293 +void
9.294 +UanHeaderRcCts::SetFrameNo(uint8_t frameNo)
9.295 +{
9.296 + m_frameNo = frameNo;
9.297 +}
9.298 +
9.299 +void
9.300 +UanHeaderRcCts::SetTimeStamp1(Time timeStamp)
9.301 +{
9.302 + m_timeStamp1 = timeStamp;
9.303 +}
9.304 +
9.305 +void
9.306 +UanHeaderRcCts::SetTimeStamp2(Time timeStamp)
9.307 +{
9.308 + m_timeStamp2 = timeStamp;
9.309 +}
9.310 +
9.311 +void
9.312 +UanHeaderRcCts::SetDelayToTx(Time delay)
9.313 +{
9.314 + m_delay = delay;
9.315 +}
9.316 +
9.317 +void
9.318 +UanHeaderRcCts::SetRetryNo(uint8_t no)
9.319 +{
9.320 + m_retryNo = no;
9.321 +}
9.322 +
9.323 +void
9.324 +UanHeaderRcCts::SetRateNum(uint16_t rate)
9.325 +{
9.326 + m_rateNum = rate;
9.327 +}
9.328 +
9.329 +void
9.330 +UanHeaderRcCts::SetRetryRate(uint16_t rate)
9.331 +{
9.332 + m_retryRate = rate;
9.333 +}
9.334 +
9.335 +void
9.336 +UanHeaderRcCts::SetBlockTime(Time t)
9.337 +{
9.338 + m_blockTime = t;
9.339 +}
9.340 +
9.341 +void
9.342 +UanHeaderRcCts::SetWindowTime(Time t)
9.343 +{
9.344 + m_winTime = t;
9.345 +}
9.346 +
9.347 +uint16_t
9.348 +UanHeaderRcCts::GetRetryRate(void)
9.349 +{
9.350 + return m_retryRate;
9.351 +
9.352 +}
9.353 +uint8_t
9.354 +UanHeaderRcCts::GetFrameNo()
9.355 +{
9.356 + return m_frameNo;
9.357 +}
9.358 +
9.359 +Time
9.360 +UanHeaderRcCts::GetTimeStamp1(void)
9.361 +{
9.362 + return m_timeStamp1;
9.363 +}
9.364 +
9.365 +Time
9.366 +UanHeaderRcCts::GetTimeStamp2(void)
9.367 +{
9.368 + return m_timeStamp2;
9.369 +}
9.370 +Time
9.371 +UanHeaderRcCts::GetDelayToTx(void)
9.372 +{
9.373 + return m_delay;
9.374 +}
9.375 +
9.376 +uint8_t
9.377 +UanHeaderRcCts::GetRetryNo()
9.378 +{
9.379 + return m_retryNo;
9.380 +}
9.381 +
9.382 +uint16_t
9.383 +UanHeaderRcCts::GetRateNum()
9.384 +{
9.385 + return m_rateNum;
9.386 +}
9.387 +uint32_t
9.388 +UanHeaderRcCts::GetSerializedSize (void) const
9.389 +{
9.390 + return 1 + 1 + 4 + 4 + 4 + 2 + 2 + 2 + 2;
9.391 +}
9.392 +
9.393 +Time
9.394 +UanHeaderRcCts::GetBlockTime(void)
9.395 +{
9.396 + return m_blockTime;
9.397 +}
9.398 +Time
9.399 +UanHeaderRcCts::GetWindowTime(void)
9.400 +{
9.401 + return m_winTime;
9.402 +}
9.403 +
9.404 +void
9.405 +UanHeaderRcCts::Serialize (Buffer::Iterator start) const
9.406 +{
9.407 + start.WriteU8(m_frameNo);
9.408 + start.WriteU8(m_retryNo);
9.409 + start.WriteU32((uint32_t) (m_timeStamp1.GetSeconds()*1000.0 + 0.5));
9.410 + start.WriteU32((uint32_t) (m_timeStamp2.GetSeconds()*1000.0 + 0.5) );
9.411 + start.WriteU32((uint32_t) (m_delay.GetSeconds()*1000.0 + 0.5));
9.412 + start.WriteU16(m_rateNum);
9.413 + start.WriteU16(m_retryRate);
9.414 + start.WriteU16((uint16_t) (m_blockTime.GetSeconds()*1000.0 + 0.5));
9.415 + start.WriteU16((uint16_t) (m_winTime.GetSeconds()*1000.0 + 0.5));
9.416 +}
9.417 +
9.418 +uint32_t
9.419 +UanHeaderRcCts::Deserialize (Buffer::Iterator start)
9.420 +{
9.421 + Buffer::Iterator rbuf = start;
9.422 + m_frameNo = rbuf.ReadU8();
9.423 + m_retryNo = rbuf.ReadU8();
9.424 + m_timeStamp1 = Seconds ( ( (double) rbuf.ReadU32()) / 1000.0 );
9.425 + m_timeStamp2 = Seconds ( ( (double) rbuf.ReadU32()) / 1000.0 );
9.426 + m_delay = Seconds ( ( (double) rbuf.ReadU32()) / 1000.0 );
9.427 + m_rateNum = rbuf.ReadU16();
9.428 + m_retryRate = rbuf.ReadU16();
9.429 + m_blockTime = Seconds ( ( (double) rbuf.ReadU16()) / 1000.0 );
9.430 + m_winTime = Seconds ( ( (double) rbuf.ReadU16()) / 1000.0 );
9.431 + return rbuf.GetDistanceFrom(start);
9.432 +}
9.433 +
9.434 +void
9.435 +UanHeaderRcCts::Print (std::ostream &os) const
9.436 +{
9.437 + os << "CTS (Frame #=" << (uint32_t) m_frameNo << " Retry #=" << (uint32_t) m_retryNo << " Time Stamp 1=" << m_timeStamp1.GetSeconds() << "Time Stamp 2=" << m_timeStamp2.GetSeconds() << " Delay until TX=" << m_delay.GetSeconds() << " Retry Rate=" << m_retryRate << " Block time=" << m_blockTime.GetSeconds() << " Window time=" << m_winTime.GetSeconds() << ")";
9.438 +}
9.439 +
9.440 +TypeId
9.441 +UanHeaderRcCts::GetInstanceTypeId(void) const
9.442 +{
9.443 + return GetTypeId();
9.444 +}
9.445 +
9.446 +UanHeaderRcAck::UanHeaderRcAck()
9.447 + : m_frameNo(0)
9.448 +{
9.449 +}
9.450 +
9.451 +UanHeaderRcAck::~UanHeaderRcAck()
9.452 +{
9.453 +}
9.454 +
9.455 +TypeId
9.456 +UanHeaderRcAck::GetTypeId()
9.457 +{
9.458 + static TypeId tid = TypeId("ns3::UanHeaderRcAck")
9.459 + .SetParent<Header> ()
9.460 + .AddConstructor<UanHeaderRcAck>()
9.461 + ;
9.462 + return tid;
9.463 +}
9.464 +
9.465 +void
9.466 +UanHeaderRcAck::SetFrameNo(uint8_t noFrames)
9.467 +{
9.468 + m_frameNo = noFrames;
9.469 +}
9.470 +
9.471 +void
9.472 +UanHeaderRcAck::AddNackedFrame(uint8_t frame)
9.473 +{
9.474 + m_nackedFrames.insert(frame);
9.475 +}
9.476 +
9.477 +const std::set<uint8_t> &
9.478 +UanHeaderRcAck::GetNackedFrames(void) const
9.479 +{
9.480 + return m_nackedFrames;
9.481 +}
9.482 +
9.483 +uint8_t
9.484 +UanHeaderRcAck::GetFrameNo(void) const
9.485 +{
9.486 + return m_frameNo;
9.487 +}
9.488 +
9.489 +uint8_t
9.490 +UanHeaderRcAck::GetNoNacks(void) const
9.491 +{
9.492 + return m_nackedFrames.size();
9.493 +}
9.494 +
9.495 +uint32_t
9.496 +UanHeaderRcAck::GetSerializedSize (void) const
9.497 +{
9.498 + return 1 + 1 + GetNoNacks();
9.499 +}
9.500 +
9.501 +void
9.502 +UanHeaderRcAck::Serialize (Buffer::Iterator start) const
9.503 +{
9.504 + start.WriteU8(m_frameNo);
9.505 + start.WriteU8(GetNoNacks());
9.506 + std::set<uint8_t>::iterator it = m_nackedFrames.begin();
9.507 + for(;it != m_nackedFrames.end();it++)
9.508 + {
9.509 + start.WriteU8(*it);
9.510 + }
9.511 +}
9.512 +
9.513 +uint32_t
9.514 +UanHeaderRcAck::Deserialize (Buffer::Iterator start)
9.515 +{
9.516 + Buffer::Iterator rbuf = start;
9.517 + m_frameNo = rbuf.ReadU8();
9.518 + uint8_t noAcks = rbuf.ReadU8();
9.519 + m_nackedFrames.clear();
9.520 + for(uint32_t i=0;i<noAcks;i++)
9.521 + {
9.522 + m_nackedFrames.insert(rbuf.ReadU8());
9.523 + }
9.524 + return rbuf.GetDistanceFrom(start);
9.525 +}
9.526 +
9.527 +void
9.528 +UanHeaderRcAck::Print (std::ostream &os) const
9.529 +{
9.530 + os << "# Frames=" << (uint32_t) m_frameNo << " # nacked=" << (uint32_t) GetNoNacks() << " Nacked: ";
9.531 + if(GetNoNacks() > 0)
9.532 + {
9.533 + std::set<uint8_t>::iterator it = m_nackedFrames.begin();
9.534 + os << (uint32_t) *it;
9.535 + it++;
9.536 + for(; it != m_nackedFrames.end();it++)
9.537 + os << ", " << (uint32_t) *it;
9.538 + }
9.539 +}
9.540 +
9.541 +TypeId
9.542 +UanHeaderRcAck::GetInstanceTypeId(void) const
9.543 +{
9.544 + return GetTypeId();
9.545 +}
9.546 +
9.547 +} //namespace ns3
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/devices/uan/uan-header-rc.h Wed Apr 01 00:31:47 2009 -0700
10.3 @@ -0,0 +1,344 @@
10.4 +/*
10.5 + * Copyright (c) 2008 University of Washington
10.6 + *
10.7 + * This program is free software: you can redistribute it and/or modify
10.8 + * it under the terms of the GNU General Public License as published by
10.9 + * the Free Software Foundation, either version 3 of the License, or
10.10 + * (at your option) any later version.
10.11 + *
10.12 + * This program is distributed in the hope that it will be useful,
10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 + * GNU General Public License for more details.
10.16 + *
10.17 + * You should have received a copy of the GNU General Public License
10.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
10.19 + *
10.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
10.21 + *
10.22 + *
10.23 + */
10.24 +
10.25 +/**
10.26 + * \file uan-hearder-rc.h
10.27 + *
10.28 + * Headers (RTS, CTS, ACK, Data) used in UanMacRc and UanMacRcGw
10.29 + *
10.30 + */
10.31 +#ifndef UANHEADERRC_H_
10.32 +#define UANHEADERRC_H_
10.33 +
10.34 +#include "ns3/header.h"
10.35 +#include "ns3/nstime.h"
10.36 +
10.37 +#include <set>
10.38 +
10.39 +namespace ns3
10.40 +{
10.41 +
10.42 +/**
10.43 + * \class UanHeaderRcData
10.44 + *
10.45 + * \brief Extra data header information
10.46 + *
10.47 + * Adds prop. delay measure, and frame number info to
10.48 + * transmitted data packet
10.49 + */
10.50 +class UanHeaderRcData : public ns3::Header
10.51 +{
10.52 +public:
10.53 + UanHeaderRcData();
10.54 + /**
10.55 + * \param frameNo Data frame # of reservation being transmitted
10.56 + * \param propDelay Measured propagation delay found in handshaking
10.57 + * \note Prop. delay is transmitted with 16 bits and ms accuracy
10.58 + */
10.59 + UanHeaderRcData(uint8_t frameNum, Time propDelay);
10.60 + virtual ~UanHeaderRcData();
10.61 +
10.62 + static TypeId GetTypeId(void);
10.63 +
10.64 + /**
10.65 + * \param frameNum Data frame # of reservation being transmitted
10.66 + */
10.67 + void SetFrameNo(uint8_t frameNum);
10.68 + /**
10.69 + * \param propDelay Measured propagation delay found in handshaking
10.70 + * \note Prop. delay is transmitted with 16 bits and ms accuracy
10.71 + */
10.72 + void SetPropDelay(Time propDelay);
10.73 + /**
10.74 + * \returns Data frame # of reservation being transmitted
10.75 + */
10.76 + uint8_t GetFrameNo(void);
10.77 + /**
10.78 + * \returns Measured propagation delay found in handshaking
10.79 + * \note Prop. delay is transmitted with 16 bits and ms accuracy
10.80 + */
10.81 + Time GetPropDelay(void);
10.82 +
10.83 + //Inherrited methods
10.84 + virtual uint32_t GetSerializedSize (void) const;
10.85 + virtual void Serialize (Buffer::Iterator start) const;
10.86 + virtual uint32_t Deserialize (Buffer::Iterator start);
10.87 + virtual void Print (std::ostream &os) const;
10.88 + virtual TypeId GetInstanceTypeId(void) const;
10.89 +
10.90 +private:
10.91 + uint8_t m_frameNo;
10.92 + Time m_propDelay;
10.93 +};
10.94 +
10.95 +/**
10.96 + * \class UanHeaderRcRts
10.97 + *
10.98 + * \brief RTS header
10.99 + *
10.100 + * Contains frame #, retry #, # frames, length, and timestamp
10.101 + */
10.102 +class UanHeaderRcRts : public ns3::Header
10.103 +{
10.104 +public:
10.105 + UanHeaderRcRts();
10.106 + /**
10.107 + * \param frameNo Reservation frame #
10.108 + * \param retryNo Retry # of RTS packet
10.109 + * \param noFrames # of data frames in reservation
10.110 + * \param length # of bytes (including headers) in data
10.111 + * \param ts RTS TX timestamp
10.112 + * \note Timestamp is serialized into 32 bits with ms accuracy
10.113 + */
10.114 + UanHeaderRcRts(uint8_t frameNo, uint8_t retryNo, uint8_t noFrames, uint16_t length, Time ts);
10.115 + virtual ~UanHeaderRcRts();
10.116 +
10.117 + static TypeId GetTypeId(void);
10.118 +
10.119 + /**
10.120 + * \param fno TX frame #
10.121 + */
10.122 + void SetFrameNo(uint8_t fno);
10.123 + /**
10.124 + * \params no Number of data frames included in this reservation request
10.125 + */
10.126 + void SetNoFrames(uint8_t no);
10.127 + /**
10.128 + * \param timeStamp RTS transmission time
10.129 + */
10.130 + void SetTimeStamp(Time timeStamp);
10.131 + /**
10.132 + * \param length Total number of data bytes in reservation (including headers)
10.133 + * \note Timestamp is serialized with 32 bits in ms precision
10.134 + */
10.135 + void SetLength(uint16_t length);
10.136 + /**
10.137 + * \param no Retry number of this RTS (Used to match timestamp to correctly received RTS)
10.138 + */
10.139 + void SetRetryNo(uint8_t no);
10.140 +
10.141 + /**
10.142 + * \returns Frame #
10.143 + */
10.144 + uint8_t GetFrameNo(void);
10.145 + /**
10.146 + * \returns # of data frames in reservation
10.147 + */
10.148 + uint8_t GetNoFrames(void);
10.149 + /**
10.150 + * \returns TX time of the RTS packet
10.151 + * \note Timestamp is serialized with 32 bits in ms precision
10.152 + */
10.153 + Time GetTimeStamp(void);
10.154 + /**
10.155 + * \returns Total # of bytes in data packets for reservation (including headers)
10.156 + */
10.157 + uint16_t GetLength(void);
10.158 + /**
10.159 + * \returns Retry number of this RTS packet
10.160 + */
10.161 + uint8_t GetRetryNo(void);
10.162 +
10.163 + //Inherrited methods
10.164 + virtual uint32_t GetSerializedSize (void) const;
10.165 + virtual void Serialize (Buffer::Iterator start) const;
10.166 + virtual uint32_t Deserialize (Buffer::Iterator start);
10.167 + virtual void Print (std::ostream &os) const;
10.168 + virtual TypeId GetInstanceTypeId(void) const;
10.169 +
10.170 +private:
10.171 + uint8_t m_frameNo;
10.172 + uint8_t m_noFrames;
10.173 + uint16_t m_length;
10.174 + Time m_timeStamp;
10.175 + uint8_t m_retryNo;
10.176 +};
10.177 +
10.178 +/**
10.179 + * \class UanHeaderRcCts
10.180 + *
10.181 + * \brief CTS header
10.182 + *
10.183 + * Includes RTS RX time, CTS TX time, delay until TX, RTS blocking period,
10.184 + * RTS tx period, rate #, and retry rate #
10.185 + */
10.186 +
10.187 +class UanHeaderRcCts : public ns3::Header
10.188 +{
10.189 +public:
10.190 + UanHeaderRcCts();
10.191 + /**
10.192 + * \param frameNo Resrvation frame # being cleared
10.193 + * \param retryNo Retry # of received RTS packet
10.194 + * \param ts1 RX time of RTS packet at gateway
10.195 + * \param ts2 TX time of this CTS packet
10.196 + * \param delay Delay until transmission
10.197 + * \param rate Rate # for current cycle
10.198 + * \param rr Retry rate # for current cycle
10.199 + * \param blockTime Time duration to wait before beginning RTS transmissions
10.200 + * \param windowTime Time duration, following blockTime to allow RTS transmissions
10.201 + * \note Times are serialized, with ms precission, into 32 bit fields.
10.202 + */
10.203 + UanHeaderRcCts(uint8_t frameNo, uint8_t retryNo, Time ts1, Time ts2, Time delay,
10.204 + uint16_t rate, uint16_t rr, Time blockTime, Time windowTime);
10.205 + virtual ~UanHeaderRcCts();
10.206 +
10.207 + static TypeId GetTypeId(void);
10.208 +
10.209 + /**
10.210 + * \param frameNo Frame # of RTS being cleared
10.211 + */
10.212 + void SetFrameNo(uint8_t frameNo);
10.213 + /**
10.214 + * \param timeStamp Time of RTS reception
10.215 + */
10.216 + void SetTimeStamp1(Time timeStamp);
10.217 + /**
10.218 + * \param timeStamp Time of CTS transmission
10.219 + */
10.220 + void SetTimeStamp2(Time timeStamp);
10.221 + /**
10.222 + * \param delay Time duration, from CTS TX, before first data frame arrival
10.223 + */
10.224 + void SetDelayToTx(Time delay);
10.225 + /**
10.226 + * \param no Retry number of RTS frame being cleared
10.227 + */
10.228 + void SetRetryNo(uint8_t no);
10.229 + /**
10.230 + * \param rate Rate number corresponding to data rate of current cycle
10.231 + */
10.232 + void SetRateNum(uint16_t rate);
10.233 + /**
10.234 + * \param rate Retry rate number for current cycle
10.235 + */
10.236 + void SetRetryRate(uint16_t rate);
10.237 + /**
10.238 + * \param t Time to block RTS transmissions
10.239 + */
10.240 + void SetBlockTime(Time t);
10.241 + /**
10.242 + * \param t Time duration following blocking time to allow RTS transmissions
10.243 + */
10.244 + void SetWindowTime(Time t);
10.245 +
10.246 + /**
10.247 + * \returns Frame # of RTS being cleared
10.248 + */
10.249 + uint8_t GetFrameNo(void);
10.250 + /**
10.251 + * \returns RX time of RTS being cleared
10.252 + */
10.253 + Time GetTimeStamp1(void);
10.254 + /**
10.255 + * \returns TX time of CTS packet
10.256 + */
10.257 + Time GetTimeStamp2(void);
10.258 + /**
10.259 + * \returns Delay from TX time of CTS packet until arrival of first data frame
10.260 + */
10.261 + Time GetDelayToTx(void);
10.262 + /**
10.263 + * \returns Retry # of RTS packet being cleared
10.264 + */
10.265 + uint8_t GetRetryNo(void);
10.266 + /**
10.267 + * \returns Rate # corresponding to data rate of current cycle
10.268 + */
10.269 + uint16_t GetRateNum(void);
10.270 + /**
10.271 + * \returns retry rate # of retry rate for current cycle
10.272 + */
10.273 + uint16_t GetRetryRate(void);
10.274 + /**
10.275 + * \returns Time duration to block RTS transmissions
10.276 + */
10.277 + Time GetBlockTime(void);
10.278 + /**
10.279 + * \returns Time duration after blocking time allowed for RTS transmissions
10.280 + */
10.281 + Time GetWindowTime(void);
10.282 +
10.283 + //Inherrited methods
10.284 + virtual uint32_t GetSerializedSize (void) const;
10.285 + virtual void Serialize (Buffer::Iterator start) const;
10.286 + virtual uint32_t Deserialize (Buffer::Iterator start);
10.287 + virtual void Print (std::ostream &os) const;
10.288 + virtual TypeId GetInstanceTypeId(void) const;
10.289 +
10.290 +private:
10.291 + uint8_t m_frameNo;
10.292 + Time m_timeStamp1;
10.293 + Time m_timeStamp2;
10.294 + uint8_t m_retryNo;
10.295 + Time m_delay;
10.296 + Time m_blockTime;
10.297 + Time m_winTime;
10.298 + uint16_t m_retryRate;
10.299 + uint16_t m_rateNum;
10.300 +};
10.301 +
10.302 +class UanHeaderRcAck : public Header
10.303 +{
10.304 +public:
10.305 + UanHeaderRcAck();
10.306 + virtual ~UanHeaderRcAck();
10.307 +
10.308 + static TypeId GetTypeId(void);
10.309 +
10.310 + /**
10.311 + * \params frameNo Frame # of reservation being acknowledged
10.312 + */
10.313 + void SetFrameNo(uint8_t frameNo);
10.314 + /**
10.315 + * \params frame Data frame # being nacked
10.316 + */
10.317 + void AddNackedFrame(uint8_t frame);
10.318 +
10.319 + /**
10.320 + * \returns Set of nacked frames
10.321 + */
10.322 + const std::set<uint8_t> &GetNackedFrames(void) const;
10.323 + /**
10.324 + * \returns Reservation frame # being acknowledged.
10.325 + */
10.326 + uint8_t GetFrameNo(void) const;
10.327 + /**
10.328 + * \returns Number of data frames being NACKED
10.329 + */
10.330 + uint8_t GetNoNacks(void) const;
10.331 +
10.332 + //Inherrited methods
10.333 + virtual uint32_t GetSerializedSize (void) const;
10.334 + virtual void Serialize (Buffer::Iterator start) const;
10.335 + virtual uint32_t Deserialize (Buffer::Iterator start);
10.336 + virtual void Print (std::ostream &os) const;
10.337 + virtual TypeId GetInstanceTypeId(void) const;
10.338 +
10.339 +private:
10.340 + uint8_t m_frameNo;
10.341 + std::set<uint8_t> m_nackedFrames;
10.342 +
10.343 +};
10.344 +
10.345 +}
10.346 +
10.347 +#endif /* UANHEADERRC_H_ */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/src/devices/uan/uan-mac-aloha.cc Wed Apr 01 00:31:47 2009 -0700
11.3 @@ -0,0 +1,123 @@
11.4 +#include "uan-mac-aloha.h"
11.5 +#include "uan-tx-mode.h"
11.6 +#include "uan-address.h"
11.7 +#include "ns3/log.h"
11.8 +#include "uan-phy.h"
11.9 +#include "uan-header-common.h"
11.10 +
11.11 +#include <iostream>
11.12 +NS_LOG_COMPONENT_DEFINE("UanMacAloha");
11.13 +
11.14 +
11.15 +namespace ns3
11.16 +{
11.17 +
11.18 +NS_OBJECT_ENSURE_REGISTERED (UanMacAloha);
11.19 +
11.20 +UanMacAloha::UanMacAloha()
11.21 +{
11.22 +
11.23 + //m_address = UanAddress::Allocate();
11.24 + NS_LOG_DEBUG("Assigned address " << m_address);
11.25 +}
11.26 +
11.27 +UanMacAloha::~UanMacAloha()
11.28 +{
11.29 +}
11.30 +
11.31 +TypeId
11.32 +UanMacAloha::GetTypeId (void)
11.33 +{
11.34 + static TypeId tid = TypeId ("ns3::UanMacAloha")
11.35 + .SetParent<Object> ()
11.36 + .AddConstructor<UanMacAloha>()
11.37 + ;
11.38 + return tid;
11.39 +
11.40 +// .AddAttribute ("Address",
11.41 +// "This node's MAC Address",
11.42 +
11.43 +
11.44 +
11.45 +}
11.46 +Address
11.47 +UanMacAloha::GetAddress(void)
11.48 +{
11.49 + return m_address;
11.50 +}
11.51 +
11.52 +void
11.53 +UanMacAloha::SetAddress(UanAddress addr)
11.54 +{
11.55 + m_address=addr;
11.56 +}
11.57 +bool
11.58 +UanMacAloha::Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
11.59 +{
11.60 + NS_LOG_DEBUG("" << Simulator::Now().GetSeconds() << " MAC " << UanAddress::ConvertFrom(GetAddress()) << " Queueing packet for " << UanAddress::ConvertFrom(dest));
11.61 +
11.62 + if(!m_phy->IsStateTx())
11.63 + {
11.64 + UanAddress src = UanAddress::ConvertFrom(GetAddress());
11.65 + UanAddress udest = UanAddress::ConvertFrom(dest);
11.66 +
11.67 + //UanHeaderCommon header(src, dest, (uint8_t) 0, (uint16_t) packet->GetSize(), Simulator::Now());
11.68 + UanHeaderCommon header;
11.69 + header.SetSrc(src);
11.70 + header.SetDest(udest);
11.71 + header.SetType(0);
11.72 +
11.73 + packet->AddHeader(header);
11.74 + //std::cout << "Packet enqueue at address " << GetAddress() << ": " << *packet << std::endl;
11.75 + m_phy->SendPacket(packet, 0);
11.76 + return true;
11.77 + }
11.78 + else
11.79 + return false;
11.80 +}
11.81 +
11.82 +void
11.83 +UanMacAloha::SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress& > cb)
11.84 +{
11.85 + this->m_forUpCb = cb;
11.86 +}
11.87 +void
11.88 +UanMacAloha::AttachPhy(Ptr<UanPhy> phy)
11.89 +{
11.90 + m_phy = phy;
11.91 + phy->SetReceiveOkCallback(MakeCallback(&UanMacAloha::RxPacketGood, this));
11.92 + phy->SetReceiveErrorCallback(MakeCallback(&UanMacAloha::RxPacketError, this));
11.93 +
11.94 +}
11.95 +void
11.96 +UanMacAloha::RxPacketGood(Ptr<Packet> pkt, double sinr, UanTxMode txMode)
11.97 +{
11.98 + //TODO: Find the source!
11.99 + //TODO: Adding a MAC header would do it!
11.100 +
11.101 + UanHeaderCommon header;
11.102 + pkt->RemoveHeader(header);
11.103 + NS_LOG_DEBUG("Receiving packet from " << header.GetSrc() << " For " << header.GetDest());
11.104 +
11.105 + if(header.GetDest() == GetAddress())
11.106 + {
11.107 + NS_LOG_DEBUG("That means this is for me :)");
11.108 + m_forUpCb(pkt, header.GetDest());
11.109 + }
11.110 +
11.111 +}
11.112 +
11.113 +void
11.114 +UanMacAloha::RxPacketError(Ptr<Packet> pkt, double sinr)
11.115 +{
11.116 + NS_LOG_DEBUG("" << Simulator::Now() << " MAC " << UanAddress::ConvertFrom(GetAddress()) << " Received packet in error with sinr " << sinr);
11.117 +}
11.118 +
11.119 +Address
11.120 +UanMacAloha::GetBroadcast(void) const
11.121 +{
11.122 + UanAddress broadcast(255);
11.123 + return broadcast;
11.124 +}
11.125 +
11.126 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/src/devices/uan/uan-mac-aloha.h Wed Apr 01 00:31:47 2009 -0700
12.3 @@ -0,0 +1,74 @@
12.4 +/*
12.5 + * Copyright (c) 2008 University of Washington
12.6 + *
12.7 + * This program is free software: you can redistribute it and/or modify
12.8 + * it under the terms of the GNU General Public License as published by
12.9 + * the Free Software Foundation, either version 3 of the License, or
12.10 + * (at your option) any later version.
12.11 + *
12.12 + * This program is distributed in the hope that it will be useful,
12.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.15 + * GNU General Public License for more details.
12.16 + *
12.17 + * You should have received a copy of the GNU General Public License
12.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
12.19 + *
12.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
12.21 + *
12.22 + *
12.23 + */
12.24 +
12.25 +#ifndef UANMACALOHA_H_
12.26 +#define UANMACALOHA_H_
12.27 +
12.28 +#include "uan-mac.h"
12.29 +#include "uan-address.h"
12.30 +
12.31 +namespace ns3
12.32 +{
12.33 +
12.34 +
12.35 +class UanPhy;
12.36 +class UanTxMode;
12.37 +
12.38 +class UanMacAloha : public ns3::UanMac
12.39 +{
12.40 +public:
12.41 + UanMacAloha();
12.42 + virtual ~UanMacAloha();
12.43 + static TypeId GetTypeId(void);
12.44 +
12.45 +
12.46 + //Inheritted functions
12.47 + Address GetAddress(void);
12.48 + virtual void SetAddress(UanAddress addr);
12.49 + virtual bool Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);
12.50 + virtual void SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress& > cb);
12.51 + virtual void AttachPhy(Ptr<UanPhy> phy);
12.52 + virtual Address GetBroadcast(void) const;
12.53 +
12.54 +private:
12.55 + UanAddress m_address;
12.56 + Ptr<UanPhy> m_phy;
12.57 + Callback<void, Ptr<Packet>, const UanAddress& > m_forUpCb;
12.58 +
12.59 + /**
12.60 + * \brief Receive packet from lower layer (passed to PHY as callback)
12.61 + * \param pkt Packet being received
12.62 + * \param sinr SINR of received packet
12.63 + * \param txMode Mode of received packet
12.64 + */
12.65 + void RxPacketGood(Ptr<Packet> pkt, double sinr, UanTxMode txMode);
12.66 +
12.67 + /**
12.68 + * \brief Packet received at lower layer in error
12.69 + * \param pkt Packet received in error
12.70 + * \param sinr SINR of received packet
12.71 + */
12.72 + void RxPacketError(Ptr<Packet> pkt, double sinr);
12.73 +};
12.74 +
12.75 +}
12.76 +
12.77 +#endif /*UANMACALOHA_H_*/
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/devices/uan/uan-mac-cw.cc Wed Apr 01 00:31:47 2009 -0700
13.3 @@ -0,0 +1,339 @@
13.4 +/*
13.5 + * uan-mac-cw.cpp
13.6 + *
13.7 + * Created on: 15-Oct-2008
13.8 + * Author: ltracy
13.9 + */
13.10 +
13.11 +#include "uan-mac-cw.h"
13.12 +#include "ns3/attribute.h"
13.13 +#include "ns3/uinteger.h"
13.14 +#include "ns3/double.h"
13.15 +#include "ns3/nstime.h"
13.16 +#include "ns3/random-variable.h"
13.17 +#include "ns3/uan-header-common.h"
13.18 +#include "ns3/trace-source-accessor.h"
13.19 +#include "ns3/log.h"
13.20 +
13.21 +NS_LOG_COMPONENT_DEFINE("UanMacCw");
13.22 +
13.23 +namespace ns3
13.24 +{
13.25 +
13.26 +NS_OBJECT_ENSURE_REGISTERED(UanMacCw);
13.27 +
13.28 +UanMacCw::UanMacCw() :
13.29 + m_phy(0),
13.30 + m_pktTx(0),
13.31 + m_state(IDLE)
13.32 +
13.33 +{
13.34 + // TODO Auto-generated constructor stub
13.35 +
13.36 +}
13.37 +
13.38 +UanMacCw::~UanMacCw()
13.39 +{
13.40 + // TODO Auto-generated destructor stub
13.41 +}
13.42 +
13.43 +
13.44 +TypeId
13.45 +UanMacCw::GetTypeId(void)
13.46 +{
13.47 + static TypeId tid = TypeId("ns3::UanMacCw")
13.48 + .SetParent<Object>()
13.49 + .AddConstructor<UanMacCw>()
13.50 + .AddAttribute("CW", "The MAC parameter CW",
13.51 + UintegerValue(10),
13.52 + MakeUintegerAccessor(&UanMacCw::m_cw),
13.53 + MakeUintegerChecker<uint32_t>())
13.54 + .AddAttribute("SlotTime", "Time slot duration for MAC backoff",
13.55 + TimeValue(MilliSeconds(20)),
13.56 + MakeTimeAccessor(&UanMacCw::m_slotTime),
13.57 + MakeTimeChecker())
13.58 + .AddTraceSource("Enqueue",
13.59 + "A packet arrived at the MAC for transmission",
13.60 + MakeTraceSourceAccessor(&UanMacCw::m_enqueueLogger))
13.61 + .AddTraceSource("Dequeue",
13.62 + "A was passed down to the PHY from the MAC",
13.63 + MakeTraceSourceAccessor(&UanMacCw::m_dequeueLogger))
13.64 + .AddTraceSource("RX",
13.65 + "A packet was destined for this MAC and was received",
13.66 + MakeTraceSourceAccessor(&UanMacCw::m_rxLogger))
13.67 +
13.68 + ;
13.69 + return tid;
13.70 +}
13.71 +
13.72 +Address
13.73 +UanMacCw::GetAddress()
13.74 +{
13.75 + return this->m_address;
13.76 +}
13.77 +
13.78 +void
13.79 +UanMacCw::SetAddress(UanAddress addr)
13.80 +{
13.81 + m_address = addr;
13.82 +}
13.83 +
13.84 +bool
13.85 +UanMacCw::Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
13.86 +{
13.87 +
13.88 + switch(m_state)
13.89 + {
13.90 + case CCABUSY:
13.91 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " MAC " << GetAddress() << " Starting enqueue CCABUSY");
13.92 + if(m_txEndEvent.IsRunning() == TX)
13.93 + NS_LOG_DEBUG("State is TX");
13.94 + else
13.95 + NS_LOG_DEBUG("State is not TX");
13.96 +
13.97 + NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().size() >= 1 || m_phy->IsStateTx());
13.98 + return false;
13.99 + case RUNNING:
13.100 + NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue RUNNING");
13.101 + NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().size() == 0 && !m_phy->IsStateTx());
13.102 + return false;
13.103 + case TX:
13.104 + case IDLE:
13.105 + {
13.106 + NS_ASSERT(!m_pktTx);
13.107 +
13.108 + UanHeaderCommon header;
13.109 + header.SetDest(UanAddress::ConvertFrom(dest));
13.110 + header.SetSrc(m_address);
13.111 + header.SetType(0);
13.112 + packet->AddHeader(header);
13.113 +
13.114 + m_enqueueLogger(packet, protocolNumber);
13.115 +
13.116 + if(m_phy->IsStateBusy())
13.117 + {
13.118 + m_pktTx = packet;
13.119 + m_pktTxProt = protocolNumber;
13.120 + m_state = CCABUSY;
13.121 + UniformVariable rv(0,m_cw);
13.122 + uint32_t cw = (uint32_t) rv.GetValue();
13.123 + m_savedDelayS = Seconds(double(cw)*m_slotTime.GetSeconds());
13.124 + m_sendTime = Simulator::Now() + m_savedDelayS;
13.125 + 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());
13.126 + NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().size() >= 1 || m_phy->IsStateTx());
13.127 + }
13.128 + else
13.129 + {
13.130 + NS_ASSERT(m_state != TX);
13.131 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << ": Addr " << GetAddress() << ": Enqueuing new packet while idle (sending)");
13.132 + NS_ASSERT(m_phy->GetTransducer()->GetArrivalList().size() == 0 && !m_phy->IsStateTx());
13.133 + m_state = TX;
13.134 + m_phy->SendPacket(packet,protocolNumber);
13.135 +
13.136 + }
13.137 + break;
13.138 + }
13.139 + default:
13.140 + NS_LOG_DEBUG("MAC " << GetAddress() << " Starting enqueue SOMETHING ELSE");
13.141 + return false;
13.142 + }
13.143 +
13.144 + return true;
13.145 +
13.146 +
13.147 +}
13.148 +
13.149 +void
13.150 +UanMacCw::SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb)
13.151 +{
13.152 + m_forwardUpCb = cb;
13.153 +}
13.154 +
13.155 +void
13.156 +UanMacCw::AttachPhy(Ptr<UanPhy> phy)
13.157 +{
13.158 + m_phy = phy;
13.159 + m_phy->SetReceiveOkCallback(MakeCallback(&UanMacCw::PhyRxPacketGood, this));
13.160 + m_phy->SetReceiveErrorCallback(MakeCallback(&UanMacCw::PhyRxPacketError, this));
13.161 + m_phy->RegisterListener(this);
13.162 +}
13.163 +
13.164 +Address
13.165 +UanMacCw::GetBroadcast(void) const
13.166 +{
13.167 + return UanAddress::GetBroadcast();
13.168 +}
13.169 +
13.170 +
13.171 +void
13.172 +UanMacCw::NotifyRxStart(void)
13.173 +{
13.174 + if(m_state == RUNNING)
13.175 + {
13.176 +
13.177 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel busy");
13.178 + SaveTimer();
13.179 + m_state = CCABUSY;
13.180 + }
13.181 +
13.182 +}
13.183 +void
13.184 +UanMacCw::NotifyRxEndOk(void)
13.185 +{
13.186 + if(m_state == CCABUSY && !m_phy->IsStateCcaBusy())
13.187 + {
13.188 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel idle");
13.189 + m_state = RUNNING;
13.190 + StartTimer();
13.191 +
13.192 + }
13.193 +
13.194 +}
13.195 +void
13.196 +UanMacCw::NotifyRxEndError(void)
13.197 +{
13.198 + if(m_state == CCABUSY && !m_phy->IsStateCcaBusy())
13.199 + {
13.200 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel idle");
13.201 + m_state = RUNNING;
13.202 + StartTimer();
13.203 +
13.204 + }
13.205 +
13.206 +}
13.207 +void
13.208 +UanMacCw::NotifyCcaStart(void)
13.209 +{
13.210 + if(m_state == RUNNING)
13.211 + {
13.212 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel busy");
13.213 + m_state = CCABUSY;
13.214 + SaveTimer();
13.215 +
13.216 + }
13.217 +
13.218 +}
13.219 +void
13.220 +UanMacCw::NotifyCcaEnd(void)
13.221 +{
13.222 + if(m_state == CCABUSY)
13.223 + {
13.224 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel idle");
13.225 + m_state = RUNNING;
13.226 + StartTimer();
13.227 +
13.228 + }
13.229 +
13.230 +}
13.231 +void
13.232 +UanMacCw::NotifyTxStart(Time duration)
13.233 +{
13.234 +
13.235 + if(m_txEndEvent.IsRunning())
13.236 + Simulator::Cancel(m_txEndEvent);
13.237 +
13.238 + m_txEndEvent = Simulator::Schedule(duration, &UanMacCw::EndTx, this);
13.239 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " scheduling TxEndEvent with delay " << duration.GetSeconds());
13.240 + if(m_state == RUNNING)
13.241 + {
13.242 + NS_ASSERT(0);
13.243 + m_state = CCABUSY;
13.244 + SaveTimer();
13.245 +
13.246 + }
13.247 +
13.248 +}
13.249 +
13.250 +void
13.251 +UanMacCw::EndTx(void)
13.252 +{
13.253 + NS_ASSERT(m_state == TX || m_state == CCABUSY);
13.254 + if(m_state == TX)
13.255 + m_state = IDLE;
13.256 + else if(m_state == CCABUSY)
13.257 + {
13.258 + if(m_phy->IsStateIdle())
13.259 + {
13.260 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << ": Switching to channel idle (After TX!)");
13.261 + m_state = RUNNING;
13.262 + StartTimer();
13.263 + }
13.264 + }
13.265 + else
13.266 + NS_FATAL_ERROR("In strange state at UanMacCw EndTx");
13.267 +}
13.268 +void
13.269 +UanMacCw::SetCw(uint32_t cw)
13.270 +{
13.271 + m_cw = cw;
13.272 +}
13.273 +void
13.274 +UanMacCw::SetSlotTime(Time duration)
13.275 +{
13.276 + m_slotTime = duration;
13.277 +}
13.278 +uint32_t
13.279 +UanMacCw::GetCw(void)
13.280 +{
13.281 + return m_cw;
13.282 +}
13.283 +Time
13.284 +UanMacCw::GetSlotTime(void)
13.285 +{
13.286 + return m_slotTime;
13.287 +}
13.288 +void
13.289 +UanMacCw::PhyRxPacketGood(Ptr<Packet> packet, double sinr, UanTxMode mode)
13.290 +{
13.291 + UanHeaderCommon header;
13.292 + packet->RemoveHeader(header);
13.293 +
13.294 + if(header.GetDest() == m_address)
13.295 + {
13.296 + m_forwardUpCb(packet, m_address);
13.297 + }
13.298 +}
13.299 +void
13.300 +UanMacCw::PhyRxPacketError(Ptr<Packet> packet, double sinr)
13.301 +{
13.302 +
13.303 +}
13.304 +void
13.305 +UanMacCw::SaveTimer(void)
13.306 +{
13.307 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << " Saving timer (Delay = " << (m_savedDelayS = m_sendTime - Simulator::Now()).GetSeconds() << ")");
13.308 + NS_ASSERT(m_pktTx);
13.309 + NS_ASSERT(m_sendTime >= Simulator::Now());
13.310 + m_savedDelayS = m_sendTime - Simulator::Now();
13.311 + Simulator::Cancel(m_sendEvent);
13.312 +
13.313 +
13.314 +}
13.315 +void
13.316 +UanMacCw::StartTimer(void)
13.317 +{
13.318 +
13.319 + m_sendTime = Simulator::Now() + m_savedDelayS;
13.320 + if(m_sendTime == Simulator::Now()) {
13.321 + SendPacket();
13.322 + } else {
13.323 + m_sendEvent = Simulator::Schedule(m_savedDelayS, &UanMacCw::SendPacket, this);
13.324 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << " Starting timer (New send time = " << this->m_sendTime.GetSeconds() << ")");
13.325 + }
13.326 +}
13.327 +
13.328 +void
13.329 +UanMacCw::SendPacket(void)
13.330 +{
13.331 + NS_LOG_DEBUG("Time " << Simulator::Now().GetSeconds() << " Addr " << GetAddress() << " Transmitting ");
13.332 + NS_ASSERT(m_state == RUNNING);
13.333 + m_state = TX;
13.334 + m_phy->SendPacket(m_pktTx,m_pktTxProt);
13.335 + m_pktTx = 0;
13.336 + m_sendTime = Seconds(0);
13.337 + m_savedDelayS = Seconds(0);
13.338 +}
13.339 +
13.340 +
13.341 +
13.342 +} //namespace ns3
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/devices/uan/uan-mac-cw.h Wed Apr 01 00:31:47 2009 -0700
14.3 @@ -0,0 +1,107 @@
14.4 +/*
14.5 + * Copyright (c) 2008 University of Washington
14.6 + *
14.7 + * This program is free software: you can redistribute it and/or modify
14.8 + * it under the terms of the GNU General Public License as published by
14.9 + * the Free Software Foundation, either version 3 of the License, or
14.10 + * (at your option) any later version.
14.11 + *
14.12 + * This program is distributed in the hope that it will be useful,
14.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.15 + * GNU General Public License for more details.
14.16 + *
14.17 + * You should have received a copy of the GNU General Public License
14.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
14.19 + *
14.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
14.21 + *
14.22 + *
14.23 + */
14.24 +#ifndef UANMACCW_H_
14.25 +#define UANMACCW_H_
14.26 +
14.27 +#include "ns3/uan-mac.h"
14.28 +#include "ns3/nstime.h"
14.29 +#include "ns3/simulator.h"
14.30 +#include "ns3/uan-phy.h"
14.31 +#include "ns3/uan-tx-mode.h"
14.32 +#include "ns3/uan-address.h"
14.33 +
14.34 +
14.35 +namespace ns3
14.36 +{
14.37 +
14.38 +class UanMacCw: public ns3::UanMac, public ns3::UanPhyListener
14.39 +{
14.40 +public:
14.41 + UanMacCw();
14.42 + virtual ~UanMacCw();
14.43 + static TypeId GetTypeId(void);
14.44 +
14.45 + /**
14.46 + * \param cw Contention window size
14.47 + */
14.48 + virtual void SetCw(uint32_t cw);
14.49 + /**
14.50 + * \param duration Slot time duration
14.51 + */
14.52 + virtual void SetSlotTime(Time duration);
14.53 + /**
14.54 + * \returns Contention window size
14.55 + */
14.56 + virtual uint32_t GetCw(void);
14.57 + /**
14.58 + * \returns slot time duration
14.59 + */
14.60 + virtual Time GetSlotTime(void);
14.61 +
14.62 + //Inherited methods
14.63 + virtual Address GetAddress();
14.64 + virtual void SetAddress(UanAddress addr);
14.65 + virtual bool Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);
14.66 + virtual void SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb);
14.67 + virtual void AttachPhy(Ptr<UanPhy> phy);
14.68 + virtual Address GetBroadcast(void) const;
14.69 +
14.70 + //PHY listeners
14.71 + virtual void NotifyRxStart(void);
14.72 + virtual void NotifyRxEndOk(void);
14.73 + virtual void NotifyRxEndError(void);
14.74 + virtual void NotifyCcaStart(void);
14.75 + virtual void NotifyCcaEnd(void);
14.76 + virtual void NotifyTxStart(Time duration);
14.77 +private:
14.78 + typedef enum {IDLE, CCABUSY, RUNNING, TX} State;
14.79 +
14.80 + Callback <void, Ptr<Packet>, const UanAddress& > m_forwardUpCb;
14.81 + UanAddress m_address;
14.82 + Ptr<UanPhy> m_phy;
14.83 + TracedCallback<Ptr<const Packet>, UanTxMode > m_rxLogger;
14.84 + TracedCallback<Ptr<const Packet>, uint16_t > m_enqueueLogger;
14.85 + TracedCallback<Ptr<const Packet>, uint16_t > m_dequeueLogger;
14.86 +
14.87 + //Mac parameters
14.88 + uint32_t m_cw;
14.89 + Time m_slotTime;
14.90 +
14.91 + //State variables
14.92 + Time m_sendTime;
14.93 + Time m_savedDelayS;
14.94 + Ptr<Packet> m_pktTx;
14.95 + uint16_t m_pktTxProt;
14.96 + EventId m_sendEvent;
14.97 + EventId m_txEndEvent;
14.98 + State m_state;
14.99 +
14.100 + void PhyRxPacketGood(Ptr<Packet> packet, double sinr, UanTxMode mode);
14.101 + void PhyRxPacketError(Ptr<Packet> packet, double sinr);
14.102 + void SaveTimer(void);
14.103 + void StartTimer(void);
14.104 + void SendPacket(void);
14.105 + void EndTx(void);
14.106 +};
14.107 +
14.108 +}
14.109 +
14.110 +#endif /* UANMACCW_H_ */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/src/devices/uan/uan-mac-rc-gw.cc Wed Apr 01 00:31:47 2009 -0700
15.3 @@ -0,0 +1,602 @@
15.4 +/*
15.5 + * uan-mac-rc-gw.cc
15.6 + *
15.7 + * Created on: 5-Mar-2009
15.8 + * Author: ltracy
15.9 + */
15.10 +
15.11 +#include "uan-mac-rc-gw.h"
15.12 +#include "uan-mac-rc.h"
15.13 +#include "uan-header-common.h"
15.14 +#include "uan-header-rc.h"
15.15 +#include "uan-phy.h"
15.16 +#include "uan-tx-mode.h"
15.17 +
15.18 +#include "ns3/assert.h"
15.19 +#include "ns3/log.h"
15.20 +#include "ns3/trace-source-accessor.h"
15.21 +#include "ns3/nstime.h"
15.22 +#include "ns3/double.h"
15.23 +#include "ns3/uinteger.h"
15.24 +
15.25 +#include <utility>
15.26 +#include <set>
15.27 +#include <map>
15.28 +
15.29 +NS_LOG_COMPONENT_DEFINE("UanMacRcGw");
15.30 +
15.31 +namespace ns3
15.32 +{
15.33 +
15.34 +NS_OBJECT_ENSURE_REGISTERED(UanMacRcGw);
15.35 +
15.36 +bool
15.37 +operator < (UanAddress &a, UanAddress &b)
15.38 +{
15.39 + return a.GetAsInt() < b.GetAsInt();
15.40 +}
15.41 +
15.42 +
15.43 +UanMacRcGw::UanMacRcGw() :
15.44 + m_state(IDLE),
15.45 + m_currentRate(0)
15.46 +{
15.47 + UanHeaderCommon ch;
15.48 + UanHeaderRcRts rts;
15.49 + UanHeaderRcCts cts;
15.50 + UanHeaderRcAck ack;
15.51 +
15.52 + m_rtsSize = ch.GetSerializedSize() + rts.GetSerializedSize();
15.53 + m_ctsSize = ch.GetSerializedSize() + cts.GetSerializedSize();
15.54 + m_ackSize = ch.GetSerializedSize() + ack.GetSerializedSize();
15.55 +
15.56 + NS_LOG_DEBUG("Gateway initialized");
15.57 +}
15.58 +
15.59 +UanMacRcGw::~UanMacRcGw()
15.60 +{
15.61 + // TODO Auto-generated destructor stub
15.62 +}
15.63 +
15.64 +TypeId
15.65 +UanMacRcGw::GetTypeId(void)
15.66 +{
15.67 + TypeId tid = TypeId("ns3::UanMacRcGw")
15.68 + .SetParent<UanMac>()
15.69 + .AddConstructor<UanMacRcGw>()
15.70 + .AddAttribute("MaxReservations",
15.71 + "Maximum number of reservations to accept per cycle",
15.72 + UintegerValue(10),
15.73 + MakeUintegerAccessor(&UanMacRcGw::m_maxRes),
15.74 + MakeUintegerChecker<uint32_t>())
15.75 + .AddAttribute("NumberOfRates",
15.76 + "Number of rates per Phy layer",
15.77 + UintegerValue(1023),
15.78 + MakeUintegerAccessor(&UanMacRcGw::m_numRates),
15.79 + MakeUintegerChecker<uint32_t>())
15.80 + .AddAttribute("RetryRate",
15.81 + "Number of retry rates per second at non-gateway nodes",
15.82 + DoubleValue(1/10.0),
15.83 + MakeDoubleAccessor(&UanMacRcGw::m_retryRate),
15.84 + MakeDoubleChecker<double>())
15.85 + .AddAttribute("MaxPropDelay",
15.86 + "Maximum propagation delay between gateway and non-gateway nodes",
15.87 + TimeValue(Seconds(2)),
15.88 + MakeTimeAccessor(&UanMacRcGw::m_maxDelta),
15.89 + MakeTimeChecker())
15.90 + .AddAttribute("SIFS",
15.91 + "Spacing between frames to account for timing error and processing delay",
15.92 + TimeValue(Seconds(0.2)),
15.93 + MakeTimeAccessor(&UanMacRcGw::m_sifs),
15.94 + MakeTimeChecker())
15.95 + .AddAttribute("NumberOfNodes",
15.96 + "Number of non-gateway nodes in this gateway's neighborhood",
15.97 + UintegerValue(10),
15.98 + MakeUintegerAccessor(&UanMacRcGw::m_numNodes),
15.99 + MakeUintegerChecker<uint32_t>())
15.100 + .AddAttribute("MinRetryRate",
15.101 + "Smallest allowed RTS retry rate",
15.102 + DoubleValue(0.01),
15.103 + MakeDoubleAccessor(&UanMacRcGw::m_minRetryRate),
15.104 + MakeDoubleChecker<double>())
15.105 + .AddAttribute("RetryStep",
15.106 + "Retry rate increment",
15.107 + DoubleValue(0.01),
15.108 + MakeDoubleAccessor(&UanMacRcGw::m_retryStep),
15.109 + MakeDoubleChecker<double>())
15.110 + .AddAttribute("NumberOfRetryRates",
15.111 + "Number of retry rates",
15.112 + UintegerValue(100),
15.113 + MakeUintegerAccessor(&UanMacRcGw::m_numRetryRates),
15.114 + MakeUintegerChecker<uint16_t>())
15.115 + .AddAttribute("TotalRate",
15.116 + "Total available channel rate in bps (for a single channel, without splitting reservation channel)",
15.117 + UintegerValue(4096),
15.118 + MakeUintegerAccessor(&UanMacRcGw::m_totalRate),
15.119 + MakeUintegerChecker<uint32_t>())
15.120 + .AddAttribute("RateStep",
15.121 + "Increments available for rate assignment in bps",
15.122 + UintegerValue(4),
15.123 + MakeUintegerAccessor(&UanMacRcGw::m_rateStep),
15.124 + MakeUintegerChecker<uint32_t>())
15.125 +
15.126 +// .AddTraceSource("Enqueue",
15.127 +// "A (data) packet arrived at MAC for transmission",
15.128 +// MakeTraceSourceAccessor(&UanMacRcGw::m_enqueueLogger))
15.129 +// .AddTraceSource("Dequeue",
15.130 +// "A (data) packet was passed down to PHY from MAC",
15.131 +// MakeTraceSourceAccessor(&UanMacRcGw::m_dequeueLogger))
15.132 + .AddTraceSource("RX",
15.133 + "A packet was destined for and received at this MAC layer",
15.134 + MakeTraceSourceAccessor(&UanMacRcGw::m_rxLogger))
15.135 + .AddTraceSource("Cycle",
15.136 + "Trace cycle statistics",
15.137 + MakeTraceSourceAccessor(&UanMacRcGw::m_cycleLogger))
15.138 +
15.139 + ;
15.140 +
15.141 + return tid;
15.142 +}
15.143 +
15.144 +Address
15.145 +UanMacRcGw::GetAddress(void)
15.146 +{
15.147 + return m_address;
15.148 +}
15.149 +
15.150 +void
15.151 +UanMacRcGw::SetAddress(UanAddress addr)
15.152 +{
15.153 + m_address = addr;
15.154 +}
15.155 +
15.156 +bool
15.157 +UanMacRcGw::Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
15.158 +{
15.159 + NS_LOG_WARN("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
15.160 + return false;
15.161 +}
15.162 +
15.163 +void
15.164 +UanMacRcGw::SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb)
15.165 +{
15.166 + //NS_LOG_WARN("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
15.167 + m_forwardUpCb = cb;
15.168 +}
15.169 +
15.170 +void
15.171 +UanMacRcGw::AttachPhy(Ptr<UanPhy> phy)
15.172 +{
15.173 + m_phy = phy;
15.174 + phy->SetReceiveOkCallback(MakeCallback(&UanMacRcGw::ReceivePacket, this));
15.175 + phy->SetReceiveErrorCallback(MakeCallback(&UanMacRcGw::ReceiveError, this));
15.176 +}
15.177 +
15.178 +void
15.179 +UanMacRcGw::ReceiveError(Ptr<Packet> pkt, double sinr)
15.180 +{
15.181 +// std::string type;
15.182 +// UanHeaderCommon ch;
15.183 +// pkt->PeekHeader(ch);
15.184 +// switch(ch.GetType())
15.185 +// {
15.186 +// case UanMacRc::TYPE_DATA:
15.187 +// type = "DATA";
15.188 +// break;
15.189 +// case UanMacRc::TYPE_RTS:
15.190 +// type= "RTS";
15.191 +// break;
15.192 +// case UanMacRc::TYPE_CTS:
15.193 +// type="CTS";
15.194 +// break;
15.195 +// case UanMacRc::TYPE_ACK:
15.196 +// type="ACK";
15.197 +// break;
15.198 +// case UanMacRc::TYPE_GWPING:
15.199 +// type="GWPING";
15.200 +// break;
15.201 +// default:
15.202 +// type="UNKNOWN";
15.203 +// break;
15.204 +// }
15.205 +// NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Received in error: Packet of type " << type << " from " << ch.GetSrc() << " with SINR " << sinr << " and mode ?");
15.206 +}
15.207 +Address
15.208 +UanMacRcGw::GetBroadcast(void) const
15.209 +{
15.210 + return UanAddress::GetBroadcast();
15.211 +}
15.212 +
15.213 +void
15.214 +UanMacRcGw::ReceivePacket(Ptr<Packet> pkt, double sinr, UanTxMode mode)
15.215 +{
15.216 + UanHeaderCommon ch;
15.217 + pkt->PeekHeader(ch);
15.218 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Received packet from " << ch.GetSrc());
15.219 +
15.220 + if(ch.GetDest() == m_address || ch.GetDest() == UanAddress::GetBroadcast())
15.221 + {
15.222 + m_rxLogger(pkt, mode);
15.223 + }
15.224 + else
15.225 + return;
15.226 +
15.227 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Received packet from " << ch.GetSrc());
15.228 + pkt->RemoveHeader(ch);
15.229 +
15.230 + switch(ch.GetType())
15.231 + {
15.232 + case UanMacRc::TYPE_DATA:
15.233 + {
15.234 + UanHeaderRcData dh;
15.235 + pkt->RemoveHeader(dh);
15.236 + //NS_LOG_DEBUG(Simulator::Now() << "GW Adding prop delay for " << ch.GetSrc() << " of: " << dh.GetPropDelay());
15.237 + m_propDelay[ch.GetSrc()] = dh.GetPropDelay();
15.238 + if(m_ackData.find(ch.GetSrc()) == m_ackData.end())
15.239 + {
15.240 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GATEWAY Received unexpected data packet");
15.241 + }
15.242 + else
15.243 + {
15.244 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Received data packet from " << ch.GetSrc() << " length = " << pkt->GetSize());
15.245 + m_ackData[ch.GetSrc()].rxFrames.insert(dh.GetFrameNo());
15.246 + }
15.247 + m_forwardUpCb(pkt, ch.GetSrc());
15.248 + }
15.249 + break;
15.250 + case UanMacRc::TYPE_GWPING:
15.251 + case UanMacRc::TYPE_RTS:
15.252 + if(m_state == CTSING)
15.253 + return;
15.254 +
15.255 + {
15.256 + UanHeaderRcRts rh;
15.257 + pkt->RemoveHeader(rh);
15.258 +
15.259 + if(m_requests.find(ch.GetSrc()) == m_requests.end())
15.260 + {
15.261 + Request req;
15.262 + req.numFrames = rh.GetNoFrames();
15.263 + req.rxTime = Simulator::Now();
15.264 + req.frameNo = rh.GetFrameNo();
15.265 + req.retryNo = rh.GetRetryNo();
15.266 + req.length = rh.GetLength();
15.267 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW storing reservation from " << ch.GetSrc() << " with length " << req.length);
15.268 + m_requests.insert(std::make_pair(ch.GetSrc(), req));
15.269 + std::map<UanAddress, Time>::iterator it = m_propDelay.find(ch.GetSrc());
15.270 + if(it == m_propDelay.end())
15.271 + m_sortedRes.insert(std::make_pair(m_maxDelta, ch.GetSrc()));
15.272 + else
15.273 + m_sortedRes.insert(std::make_pair((*it).second, ch.GetSrc()));
15.274 + }
15.275 + else
15.276 + {
15.277 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW received duplicate RTS from " << ch.GetSrc());
15.278 + }
15.279 +
15.280 + }
15.281 + if(m_state == IDLE)
15.282 + StartCycle();
15.283 + break;
15.284 + case UanMacRc::TYPE_CTS:
15.285 + NS_FATAL_ERROR("Received CTS at GW. Currently only support single GW network!");
15.286 + break;
15.287 + case UanMacRc::TYPE_ACK:
15.288 + NS_FATAL_ERROR("Received ACK at GW. Currently only support single GW network!");
15.289 + break;
15.290 + default:
15.291 + NS_FATAL_ERROR("Received unknown packet at GW!");
15.292 + }
15.293 +}
15.294 +
15.295 +void
15.296 +UanMacRcGw::StartCycle(void)
15.297 +{
15.298 +
15.299 +
15.300 + uint32_t numRts = m_sortedRes.size();
15.301 +
15.302 + if(numRts)
15.303 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Simulator starting non-empty cycle");
15.304 + else
15.305 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Simulator starting EMPTY cycle");
15.306 +
15.307 +
15.308 +
15.309 + //Calculate dataRate
15.310 + uint32_t totalBytes=0;
15.311 + uint32_t totalFrames=0;
15.312 +
15.313 + if(numRts > 0)
15.314 + {
15.315 + std::map<UanAddress, Request>::iterator rit = m_requests.begin();
15.316 + for(;rit != m_requests.end(); rit++)
15.317 + {
15.318 + totalBytes += (*rit).second.length;
15.319 + totalFrames += (*rit).second.numFrames;
15.320 + }
15.321 + }
15.322 +
15.323 + //Linear search through variables algorithm (Maybe bug in this)
15.324 +// int32_t neededArrivals=0;
15.325 +// if(m_numNodes > m_maxRes)
15.326 +// neededArrivals = (log(m_numNodes - m_maxRes) - log(m_numNodes)) / log( 1.0 - 1.0 / (double) m_numNodes);
15.327 +//
15.328 +// if(m_numNodes <= m_maxRes || neededArrivals > 2.0*m_numNodes)
15.329 +// neededArrivals = 2*m_numNodes;
15.330 +
15.331 + //NS_LOG_DEBUG("Calculated needed arrivals = " << neededArrivals << " for " << m_numNodes << " nodes and " << m_maxRes << " max reservations");
15.332 +
15.333 + //Just using constant a
15.334 + //int32_t neededArrivals = m_maxRes;
15.335 +
15.336 +// double optRateError = 0;
15.337 +// uint32_t optRateNum = 0;
15.338 +// uint32_t optRateValue = m_phy->GetMode(m_numRates).GetDataRateBps();
15.339 +// uint16_t optRetryRate = 0;
15.340 +// double optWinSize;
15.341 +
15.342 +// for(uint16_t rr = 0; rr < m_numRetryRates; rr++)
15.343 +// {
15.344 +// uint32_t semiOptRateNum = m_numRates;
15.345 +// double semiOptRateError = 1e300;
15.346 +// double semiOptRateValue = m_phy->GetMode(m_numRates).GetDataRateBps();
15.347 +// double semiOptWinSize = 0;
15.348 +// for(uint32_t i=0;i<=m_numRates-1;i++)
15.349 +// {
15.350 +// double rate = m_phy->GetMode(i).GetDataRateBps();
15.351 +// double ctlrate = m_phy->GetMode(i+m_numRates).GetDataRateBps();
15.352 +// double winSize;
15.353 +// if(numRts > 0)
15.354 +// {
15.355 +// winSize = (double) (totalBytes)*8.0/rate + 2*m_maxDelta.GetSeconds() / (numRts + 1.0) / 2.0 + m_sifs.GetSeconds()*totalFrames - m_rtsSize*8/ctlrate;
15.356 +//
15.357 +// }
15.358 +// else
15.359 +// winSize = m_maxDelta.GetSeconds() / 2.0 - m_rtsSize*8/ctlrate;
15.360 +// if(winSize < 0)
15.361 +// winSize = 0.0;
15.362 +//
15.363 +// double expReqs = winSize*m_numNodes*(m_minRetryRate+rr*m_retryStep)*std::exp(-2.0 *m_numNodes * (m_minRetryRate+rr*m_retryStep)*m_rtsSize * 8 / ctlrate);
15.364 +//
15.365 +// double rateError = std::abs((double) neededArrivals - expReqs);
15.366 +// //NS_LOG_DEBUG("With i = " << i << " expReqs = " << expReqs << " rateError = " << rateError << " rr = " << rr);
15.367 +// if( (rateError > semiOptRateError && i != 0) || (i == m_numRates))
15.368 +// break;
15.369 +// else
15.370 +// {
15.371 +// semiOptRateError = rateError;
15.372 +// semiOptRateNum = i;
15.373 +// semiOptRateValue = ctlrate;
15.374 +// semiOptWinSize = winSize;
15.375 +// }
15.376 +// }
15.377 +// if(semiOptRateNum <= optRateNum || rr==0 || optRateError - semiOptRateError >= 1.0)
15.378 +// {
15.379 +// //NS_LOG_DEBUG("For retry rate = " << (m_minRetryRate+rr*m_retryStep) << " found opt rate num " << semiOptRateNum << " for ctrl rate " << semiOptRateValue);
15.380 +// optRateNum = semiOptRateNum;
15.381 +// optRateValue = semiOptRateValue;
15.382 +// optRetryRate = rr;
15.383 +// optRateError = semiOptRateError;
15.384 +// optWinSize = semiOptWinSize;
15.385 +// }
15.386 +// }
15.387 +
15.388 +
15.389 + //New algorithm
15.390 +
15.391 + double minRate = m_phy->GetMode(m_numRates).GetDataRateBps();
15.392 +
15.393 + //Temp values
15.394 + double beta = numRts*m_sifs.GetSeconds() + 2.0*m_maxDelta.GetSeconds()/(numRts+1.0);
15.395 + double aep = 0.5 + m_maxRes * exp(1.0);
15.396 + double c = totalBytes*8.0;
15.397 +
15.398 + double optalpha = aep / ( (1/(2.0*m_rtsSize*8.0))*(c + beta * m_totalRate) + aep );
15.399 +
15.400 + double optctlrate = m_totalRate*optalpha;
15.401 +
15.402 + double temprate = (optctlrate - minRate) / ((double) m_rateStep) + 0.5;
15.403 + m_currentRate = (uint32_t) temprate;
15.404 + NS_LOG_DEBUG("Found alpha: " << optalpha << " Found associated rate = " << optctlrate << " Giving rate number: " << temprate);
15.405 + double optret = optalpha*m_totalRate / (2.0*m_numNodes*m_rtsSize*8.0);
15.406 +
15.407 + double dataRate = m_phy->GetMode(m_currentRate).GetDataRateBps();
15.408 +
15.409 +
15.410 + if(optret < m_minRetryRate)
15.411 + {
15.412 + NS_LOG_WARN("Gateway found optimum RTS retry rate is below minimum");
15.413 + m_currentRetryRate = 0;
15.414 + }
15.415 + else
15.416 + {
15.417 + m_currentRetryRate = (uint16_t) ((optret - m_minRetryRate) / m_retryStep + 0.5) ;
15.418 + }
15.419 +
15.420 + double actualrr = m_currentRetryRate * m_retryStep + m_minRetryRate;
15.421 +
15.422 + uint32_t optRateValue = m_phy->GetMode(m_currentRate+m_numRates).GetDataRateBps();
15.423 +
15.424 + double optWinSize = (double) (totalBytes)*8.0/dataRate + 2*m_maxDelta.GetSeconds() / (numRts + 1.0) + m_sifs.GetSeconds()*totalFrames - m_rtsSize*8/optRateValue;
15.425 + double optWinSizeT = (double) (totalBytes)*8.0/(m_totalRate*(1.0 - optalpha)) + 2.0*m_maxDelta.GetSeconds() / (numRts + 1.0) + m_sifs.GetSeconds()*totalFrames - m_rtsSize*8/(optctlrate);
15.426 +
15.427 +
15.428 +
15.429 + double cycleSeconds = totalBytes*8 / dataRate + totalFrames * 3*m_sifs.GetSeconds() + (m_ctsSize + 5)*8*totalFrames/dataRate + m_maxDelta.GetSeconds();
15.430 + double expReqs = optWinSize*m_numNodes*(actualrr)*std::exp(-2.0 *m_numNodes * (actualrr)*m_rtsSize * 8 / optRateValue);
15.431 + double optexpreqs = optWinSizeT * m_numNodes*(optret) * std::exp(-2.0 * m_numNodes * (optret)*m_rtsSize * 8 / (optctlrate));
15.432 + double optRateError = std::abs(expReqs - m_maxRes);
15.433 +
15.434 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW ALGORITHM NEW INFO: expreqs " << expReqs << " With theoretical value: " << optexpreqs << " optalpha " << optalpha << " optret " << optret << " actualrr " << actualrr);
15.435 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW ALGORITHM: For " << numRts << " reservations (totBytes = " << totalBytes << ", " << optWinSize << "), chose rate #=" << m_currentRate << " for ctlrate=" << optRateValue << " with retry rate value " << m_retryStep*m_currentRetryRate+m_minRetryRate << " and rate error " << optRateError << " total cycle time = " << cycleSeconds);
15.436 +
15.437 + Time ctsTxTime = Seconds(m_ctsSize*8/dataRate);
15.438 + if(numRts == 0)
15.439 + {
15.440 + UanHeaderRcCts ctsh;
15.441 + ctsh.SetBlockTime(m_sifs);
15.442 + ctsh.SetWindowTime(Seconds(optWinSize));
15.443 + ctsh.SetRateNum(m_currentRate);
15.444 + ctsh.SetRetryRate(m_currentRetryRate);
15.445 +
15.446 + UanHeaderCommon ch(m_address, UanAddress::GetBroadcast(), UanMacRc::TYPE_CTS);
15.447 + Ptr<Packet> p = Create<Packet>();
15.448 + p->AddHeader(ctsh);
15.449 + p->AddHeader(ch);
15.450 + SendPacket(p, m_currentRate);
15.451 + Simulator::Schedule(ctsTxTime+Seconds(optWinSize) + m_sifs + Seconds(m_rtsSize*8/m_phy->GetMode(m_currentRate + m_numRates).GetDataRateBps()), &UanMacRcGw::StartCycle, this);
15.452 + m_state = INCYCLE;
15.453 + return;
15.454 + }
15.455 +
15.456 +
15.457 +
15.458 +
15.459 + Time nextEarliest = Seconds(numRts*m_ctsSize*8/dataRate) + Seconds(numRts*m_sifs.GetSeconds()) + m_sifs;
15.460 +
15.461 + m_state = CTSING;
15.462 + Simulator::Schedule(nextEarliest, &UanMacRcGw::CycleStarted, this);
15.463 + Time endCts = nextEarliest;
15.464 + Time nextCts = nextEarliest - m_sifs - ctsTxTime;
15.465 + std::set<std::pair<Time, UanAddress> >::iterator it = m_sortedRes.begin();
15.466 + Time minPdelay = (*it).first;
15.467 + for(; it != m_sortedRes.end(); it++)
15.468 + {
15.469 + Request req = m_requests[(*it).second];
15.470 + Time pdelay = (*it).first;
15.471 +
15.472 + NS_LOG_DEBUG(Simulator::Now() << " GW: Scheduling request for prop. delay " << pdelay.GetSeconds() << " for " << (*it).second);
15.473 +
15.474 + AckData newData;
15.475 + newData.expFrames = req.numFrames;
15.476 + newData.frameNo = req.frameNo;
15.477 +
15.478 + UanAddress dest = (*it).second;
15.479 +
15.480 + m_ackData.insert(std::make_pair(dest, newData));
15.481 +
15.482 + Ptr<Packet> cts = Create<Packet>();
15.483 + UanHeaderRcCts ctsh;
15.484 +
15.485 + ctsh.SetTimeStamp1(req.rxTime);
15.486 + ctsh.SetTimeStamp2(nextCts + Simulator::Now());
15.487 +
15.488 + ctsh.SetRateNum(m_currentRate);
15.489 + ctsh.SetFrameNo(req.frameNo);
15.490 + ctsh.SetRetryNo(req.retryNo);
15.491 + ctsh.SetRetryRate(m_currentRetryRate);
15.492 + ctsh.SetBlockTime(endCts - nextCts - ctsTxTime);
15.493 + ctsh.SetWindowTime(Seconds(optWinSize));
15.494 +
15.495 +
15.496 + Time earliestArr = nextCts + pdelay + pdelay + ctsTxTime + m_sifs;
15.497 + Time arrivalTime = std::max(earliestArr, nextEarliest);
15.498 +
15.499 +
15.500 + ctsh.SetDelayToTx(arrivalTime - nextCts);
15.501 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Scheduling reception for " << (uint32_t) req.numFrames << " frames " << (Simulator::Now() + arrivalTime).GetSeconds() << " (delaytiltx of " << (arrivalTime-nextCts).GetSeconds() << ") Total length is " << req.length << " with txtime " << req.length*8/dataRate << " seconds");
15.502 + //NS_LOG_DEBUG(" GW Stamped CTS with tx time " << (nextCts + Simulator::Now()).GetSeconds());
15.503 +
15.504 + UanHeaderCommon ch;
15.505 + ch.SetDest(dest);
15.506 + ch.SetSrc(m_address);
15.507 +
15.508 + ch.SetType(UanMacRc::TYPE_CTS);
15.509 +
15.510 + cts->AddHeader(ctsh);
15.511 + cts->AddHeader(ch);
15.512 +
15.513 + Simulator::Schedule(nextCts, &UanMacRcGw::SendPacket, this, cts, m_currentRate);
15.514 + nextCts = nextCts - m_sifs - ctsTxTime;
15.515 + nextEarliest = arrivalTime + Seconds(req.length*8/dataRate) + Seconds(m_sifs.GetSeconds()*req.numFrames);
15.516 + }
15.517 + m_requests.clear();
15.518 + m_sortedRes.clear();
15.519 + Simulator::Schedule(nextEarliest, &UanMacRcGw::EndCycle, this);
15.520 +
15.521 +
15.522 + m_cycleLogger(Simulator::Now(), minPdelay, numRts, totalBytes, optWinSize, optRateValue, actualrr);
15.523 +}
15.524 +
15.525 +void
15.526 +UanMacRcGw::CycleStarted()
15.527 +{
15.528 + m_state = INCYCLE;
15.529 +}
15.530 +void
15.531 +UanMacRcGw::EndCycle()
15.532 +{
15.533 +
15.534 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Ending cycle");
15.535 +
15.536 + Time nextAck = Seconds(0);
15.537 +
15.538 + Time ackTime = Seconds(m_ackSize * 8.0/ m_phy->GetMode(m_currentRate).GetDataRateBps());
15.539 +
15.540 + std::map<UanAddress, AckData>::iterator it = m_ackData.begin();
15.541 + for(; it != m_ackData.end(); it++)
15.542 + {
15.543 + UanAddress dest = (*it).first;
15.544 + AckData &data = (*it).second;
15.545 +
15.546 + std::list<uint32_t> toNack;
15.547 + for(uint32_t i=0;i<data.expFrames;i++)
15.548 + {
15.549 + if(data.rxFrames.find(i) == data.rxFrames.end())
15.550 + toNack.push_back(i);
15.551 + }
15.552 + UanHeaderCommon ch;
15.553 + ch.SetDest(dest);
15.554 + ch.SetSrc(m_address);
15.555 + ch.SetType(UanMacRc::TYPE_ACK);
15.556 + UanHeaderRcAck ah;
15.557 + ah.SetFrameNo(data.frameNo);
15.558 + std::list<uint32_t>::iterator nit = toNack.begin();
15.559 + for(; nit != toNack.end(); nit++)
15.560 + {
15.561 + ah.AddNackedFrame(*nit);
15.562 + }
15.563 +
15.564 + Ptr<Packet> ack = Create<Packet>();
15.565 + ack->AddHeader(ah);
15.566 + ack->AddHeader(ch);
15.567 + Simulator::Schedule(nextAck, &UanMacRcGw::SendPacket, this, ack, m_currentRate);
15.568 + nextAck = nextAck + ackTime + m_sifs;
15.569 + }
15.570 + m_ackData.clear();
15.571 + Simulator::Schedule(nextAck, &UanMacRcGw::StartCycle, this);
15.572 +
15.573 +}
15.574 +void
15.575 +UanMacRcGw::SendPacket(Ptr<Packet> pkt, uint32_t rate)
15.576 +{
15.577 + UanHeaderCommon ch;
15.578 + pkt->PeekHeader(ch);
15.579 + std::string type;
15.580 + switch(ch.GetType())
15.581 + {
15.582 + case UanMacRc::TYPE_DATA:
15.583 + type = "DATA";
15.584 + break;
15.585 + case UanMacRc::TYPE_RTS:
15.586 + type= "RTS";
15.587 + break;
15.588 + case UanMacRc::TYPE_CTS:
15.589 + type="CTS";
15.590 + break;
15.591 + case UanMacRc::TYPE_ACK:
15.592 + type="ACK";
15.593 + break;
15.594 + case UanMacRc::TYPE_GWPING:
15.595 + type="GWPING";
15.596 + break;
15.597 + default:
15.598 + type="UNKNOWN";
15.599 + break;
15.600 + }
15.601 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW sending " << type << " packet with size " << pkt->GetSize() << " to " << ch.GetDest() << " at rate " << rate);
15.602 + m_phy->SendPacket(pkt, rate);
15.603 +}
15.604 +
15.605 +}// namespace ns3
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/src/devices/uan/uan-mac-rc-gw.h Wed Apr 01 00:31:47 2009 -0700
16.3 @@ -0,0 +1,133 @@
16.4 +/*
16.5 + * Copyright (c) 2008 University of Washington
16.6 + *
16.7 + * This program is free software: you can redistribute it and/or modify
16.8 + * it under the terms of the GNU General Public License as published by
16.9 + * the Free Software Foundation, either version 3 of the License, or
16.10 + * (at your option) any later version.
16.11 + *
16.12 + * This program is distributed in the hope that it will be useful,
16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.15 + * GNU General Public License for more details.
16.16 + *
16.17 + * You should have received a copy of the GNU General Public License
16.18 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
16.19 + *
16.20 + * Author: Leonard Tracy <lentracy@u.washington.edu>
16.21 + *
16.22 + *
16.23 + */
16.24 +
16.25 +#ifndef UANMACRCGW_H_
16.26 +#define UANMACRCGW_H_
16.27 +
16.28 +#include "uan-mac.h"
16.29 +#include "uan-address.h"
16.30 +
16.31 +#include "ns3/nstime.h"
16.32 +#include "ns3/traced-callback.h"
16.33 +
16.34 +
16.35 +
16.36 +
16.37 +#include <set>
16.38 +#include <map>
16.39 +
16.40 +namespace ns3
16.41 +{
16.42 +
16.43 +class UanTxMode;
16.44 +
16.45 +/**
16.46 + * \class UanMacRcGw
16.47 + *
16.48 + * MAC protocol for gateway nodes in a network using reservation channel MAC
16.49 + */
16.50 +class UanMacRcGw: public ns3::UanMac
16.51 +{
16.52 +public:
16.53 + UanMacRcGw();
16.54 + virtual ~UanMacRcGw();
16.55 +
16.56 + static TypeId GetTypeId(void);
16.57 +
16.58 + //Inherited virtual functions
16.59 + virtual Address GetAddress(void);
16.60 + virtual void SetAddress(UanAddress addr);
16.61 + virtual bool Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);
16.62 + virtual void SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb);
16.63 + virtual void AttachPhy(Ptr<UanPhy> phy);
16.64 + virtual Address GetBroadcast(void) const;
16.65 +
16.66 +private:
16.67 + enum State {IDLE, INCYCLE, CTSING};
16.68 + State m_state;
16.69 +
16.70 + struct Request
16.71 + {
16.72 + uint8_t numFrames;
16.73 + uint8_t frameNo;
16.74 + uint8_t retryNo;
16.75 + uint16_t length;
16.76 + Time rxTime;
16.77 + };
16.78 +
16.79 + struct AckData
16.80 + {
16.81 + uint8_t frameNo;
16.82 + std::set<uint8_t> rxFrames;
16.83 + uint8_t expFrames;
16.84 + };
16.85 + Callback<void, Ptr<Packet>, const UanAddress& > m_forwardUpCb;
16.86 + Ptr<UanPhy> m_phy;
16.87 + UanAddress m_address;
16.88 + Time m_maxDelta;
16.89 + Time m_sifs;
16.90 + uint32_t m_maxRes;
16.91 + uint32_t m_numRates;
16.92 + uint32_t m_rtsSize;
16.93 + uint32_t m_ctsSize;
16.94 + uint32_t m_ackSize;
16.95 + double m_retryRate;
16.96 + uint16_t m_currentRetryRate;
16.97 + uint32_t m_currentRate;
16.98 + uint32_t m_numNodes;
16.99 + uint32_t m_totalRate;
16.100 + uint32_t m_rateStep;
16.101 +
16.102 + uint16_t m_numRetryRates;
16.103 + double m_minRetryRate;
16.104 + double m_retryStep;
16.105 +
16.106 + std::map<UanAddress, Time> m_propDelay;
16.107 +
16.108 + std::map<UanAddress, AckData> m_ackData;
16.109 +
16.110 +
16.111 + std::map<UanAddress, Request> m_requests;
16.112 + std::set<std::pair<Time, UanAddress> > m_sortedRes;
16.113 +
16.114 + TracedCallback<Ptr<const Packet>, UanTxMode > m_rxLogger;
16.115 +
16.116 + //Start time, min p-delay, reservations, frames, bytes, window size, ctl rate, retry rate
16.117 + TracedCallback<Time, Time, uint32_t, uint32_t, double, uint32_t, double> m_cycleLogger;
16.118 +// TracedCallback<Ptr<const Packet>, uint16_t > m_enqueueLogger;
16.119 +// TracedCallback<Ptr<const Packet>, uint16_t > m_dequeueLogger;
16.120 +
16.121 + void ReceivePacket(Ptr<Packet> pkt, double sinr, UanTxMode mode);
16.122 + void StartCycle(void);
16.123 + void EndCycle(void);
16.124 + void SendPacket(Ptr<Packet> pkt, uint32_t rate);
16.125 + void CycleStarted(void);
16.126 + void ReceiveError(Ptr<Packet> pkt, double sinr);
16.127 +};
16.128 +
16.129 +/**
16.130 + * Defined for use in UanMacRcGw
16.131 + */
16.132 +bool operator < (UanAddress &a, UanAddress &b);
16.133 +
16.134 +}
16.135 +
16.136 +#endif /* UANMACRCGW_H_ */
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/devices/uan/uan-mac-rc.cc Wed Apr 01 00:31:47 2009 -0700
17.3 @@ -0,0 +1,599 @@
17.4 +/*
17.5 + * uan-mac-rc.cc
17.6 + *
17.7 + * Created on: 1-Mar-2009
17.8 + * Author: ltracy
17.9 + */
17.10 +
17.11 +#include "uan-mac-rc.h"
17.12 +#include "uan-header-rc.h"
17.13 +#include "uan-tx-mode.h"
17.14 +#include "uan-phy.h"
17.15 +#include "uan-header-common.h"
17.16 +#include "uan-phy-dual.h"
17.17 +
17.18 +#include "ns3/log.h"
17.19 +#include "ns3/nstime.h"
17.20 +#include "ns3/simulator.h"
17.21 +#include "ns3/random-variable.h"
17.22 +#include "ns3/assert.h"
17.23 +#include "ns3/double.h"
17.24 +#include "ns3/uinteger.h"
17.25 +
17.26 +#include <list>
17.27 +#include <utility>
17.28 +
17.29 +
17.30 +NS_LOG_COMPONENT_DEFINE("UanMacRc");
17.31 +namespace ns3
17.32 +{
17.33 +
17.34 + uint32_t m_cntrlSends=0;
17.35 +
17.36 +NS_OBJECT_ENSURE_REGISTERED(UanMacRc);
17.37 +
17.38 +UanMacRc::UanMacRc() :
17.39 + m_state(UNASSOCIATED),
17.40 + m_rtsBlocked(false),
17.41 + m_currentRate(10),
17.42 + m_frameNo(0)
17.43 +{
17.44 + UanHeaderCommon ch;
17.45 + UanHeaderRcCts ctsh;
17.46 +
17.47 + m_ctsSize = ch.GetSerializedSize() + ctsh.GetSerializedSize();
17.48 +
17.49 +
17.50 +}
17.51 +
17.52 +UanMacRc::~UanMacRc()
17.53 +{
17.54 + // TODO Auto-generated destructor stub
17.55 +}
17.56 +
17.57 +TypeId
17.58 +UanMacRc::GetTypeId(void)
17.59 +{
17.60 + TypeId tid = TypeId("ns3::UanMacRc")
17.61 + .SetParent<UanMac>()
17.62 + .AddConstructor<UanMacRc>()
17.63 + .AddAttribute("RetryRate",
17.64 + "Number of retry attempts per second (of RTS/GWPING)",
17.65 + DoubleValue(1/5.0),
17.66 + MakeDoubleAccessor(&UanMacRc::m_retryRate),
17.67 + MakeDoubleChecker<double>())
17.68 + .AddAttribute("MaxFrames",
17.69 + "Maximum number of frames to include in a single RTS",
17.70 + UintegerValue(1),
17.71 + MakeUintegerAccessor(&UanMacRc::m_maxFrames),
17.72 + MakeUintegerChecker<uint32_t>())
17.73 + .AddAttribute("QueueLimit",
17.74 + "Maximum packets to queue at MAC",
17.75 + UintegerValue(10),
17.76 + MakeUintegerAccessor(&UanMacRc::m_queueLimit),
17.77 + MakeUintegerChecker<uint32_t>())
17.78 + .AddAttribute("SIFS",
17.79 + "Spacing to give between frames (this should match gateway)",
17.80 + TimeValue(Seconds(0.2)),
17.81 + MakeTimeAccessor(&UanMacRc::m_sifs),
17.82 + MakeTimeChecker())
17.83 + .AddAttribute("NumberOfRates",
17.84 + "Number of rate divisions supported by each PHY",
17.85 + UintegerValue(0),
17.86 + MakeUintegerAccessor(&UanMacRc::m_numRates),
17.87 + MakeUintegerChecker<uint32_t>())
17.88 + .AddAttribute("MinRetryRate",
17.89 + "Smallest allowed RTS retry rate",
17.90 + DoubleValue(0.01),
17.91 + MakeDoubleAccessor(&UanMacRc::m_minRetryRate),
17.92 + MakeDoubleChecker<double>())
17.93 + .AddAttribute("RetryStep",
17.94 + "Retry rate increment",
17.95 + DoubleValue(0.01),
17.96 + MakeDoubleAccessor(&UanMacRc::m_retryStep),
17.97 + MakeDoubleChecker<double>())
17.98 + .AddAttribute("NumberOfRetryRates",
17.99 + "Number of retry rates",
17.100 + UintegerValue(100),
17.101 + MakeUintegerAccessor(&UanMacRc::m_numRetryRates),
17.102 + MakeUintegerChecker<uint16_t>())
17.103 + .AddTraceSource("Enqueue",
17.104 + "A (data) packet arrived at MAC for transmission",
17.105 + MakeTraceSourceAccessor(&UanMacRc::m_enqueueLogger))
17.106 + .AddTraceSource("Dequeue",
17.107 + "A (data) packet was passed down to PHY from MAC",
17.108 + MakeTraceSourceAccessor(&UanMacRc::m_dequeueLogger))
17.109 + .AddTraceSource("RX",
17.110 + "A packet was destined for and received at this MAC layer",
17.111 + MakeTraceSourceAccessor(&UanMacRc::m_rxLogger))
17.112 +
17.113 + ;
17.114 + return tid;
17.115 +}
17.116 +
17.117 +
17.118 +Address
17.119 +UanMacRc::GetAddress(void)
17.120 +{
17.121 + return m_address;
17.122 +}
17.123 +void
17.124 +UanMacRc::SetAddress(UanAddress addr)
17.125 +{
17.126 + m_address = addr;
17.127 +}
17.128 +bool
17.129 +UanMacRc::Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
17.130 +{
17.131 + if(protocolNumber > 0)
17.132 + NS_LOG_WARN("Warning: UanMacRc does not support multiple protocols. protocolNumber argument to Enqueue is being ignored");
17.133 +
17.134 +
17.135 + if(m_pktQueue.size() >= m_queueLimit)
17.136 + return false;
17.137 +
17.138 + m_pktQueue.push_back(std::make_pair(packet, UanAddress::ConvertFrom(dest)));
17.139 +
17.140 + switch(m_state)
17.141 + {
17.142 + case UNASSOCIATED:
17.143 + Associate();
17.144 + return true;
17.145 + case IDLE:
17.146 + if(!m_rtsEvent.IsRunning())
17.147 + SendRts();
17.148 + return true;
17.149 + case GWPSENT:
17.150 + case RTSSENT:
17.151 + case DATATX:
17.152 + return true;
17.153 + }
17.154 +
17.155 + return true;
17.156 +}
17.157 +void
17.158 +UanMacRc::SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb)
17.159 +{
17.160 + m_forwardUpCb = cb;
17.161 +}
17.162 +void
17.163 +UanMacRc::AttachPhy(Ptr<UanPhy> phy)
17.164 +{
17.165 + m_phy = phy;
17.166 + m_phy->SetReceiveOkCallback(MakeCallback(&UanMacRc::ReceiveOkFromPhy, this));
17.167 +}
17.168 +
17.169 +Address
17.170 +UanMacRc::GetBroadcast(void) const
17.171 +{
17.172 + return UanAddress::GetBroadcast();
17.173 +}
17.174 +
17.175 +void
17.176 +UanMacRc::ReceiveOkFromPhy(Ptr<Packet> pkt, double sinr, UanTxMode mode)
17.177 +{
17.178 +
17.179 +
17.180 + //Filter and log packets with headers intact
17.181 + UanHeaderCommon ch;
17.182 + pkt->RemoveHeader(ch);
17.183 + if(ch.GetDest() == m_address || ch.GetDest() == UanAddress::GetBroadcast())
17.184 + m_rxLogger(pkt, mode);
17.185 +
17.186 + switch(ch.GetType())
17.187 + {
17.188 + case TYPE_DATA:
17.189 +
17.190 + if(ch.GetDest() == m_address)
17.191 + {
17.192 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " UanMacRc Receiving DATA packet from PHY");
17.193 + UanHeaderRcData dh;
17.194 + pkt->RemoveHeader(dh);
17.195 + m_forwardUpCb(pkt, ch.GetSrc());
17.196 + }
17.197 + break;
17.198 + case TYPE_RTS:
17.199 + //Currently don't respond to RTS packets at non-gateway nodes
17.200 + break;
17.201 + case TYPE_CTS:
17.202 +
17.203 + {
17.204 + m_assocAddr = ch.GetSrc();
17.205 + m_rtsBlocked = true;
17.206 + UanHeaderRcCts ctsh;
17.207 + pkt->PeekHeader(ctsh);
17.208 + m_currentRate = ctsh.GetRateNum();
17.209 + m_retryRate = m_minRetryRate + m_retryStep*ctsh.GetRetryRate();
17.210 + if(!m_startAgain.IsRunning())
17.211 + {
17.212 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " Scheduling start again with delay " << ctsh.GetBlockTime().GetSeconds());
17.213 + m_startAgain = Simulator::Schedule(ctsh.GetBlockTime(), &UanMacRc::StartRtsing, this);
17.214 + Simulator::Schedule(ctsh.GetBlockTime() + ctsh.GetWindowTime(), &UanMacRc::BlockRtsing, this);
17.215 + }
17.216 +
17.217 + }
17.218 + if(ch.GetDest() != m_address)
17.219 + return;
17.220 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " UanMacRc Receiving CTS packet from PHY");
17.221 +
17.222 + if(m_state == GWPSENT)
17.223 + {
17.224 + m_assocAddr = ch.GetSrc();
17.225 + ScheduleData(pkt);
17.226 + }
17.227 + else if(m_state == RTSSENT)
17.228 + ScheduleData(pkt);
17.229 + else
17.230 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " received CTS while state != RTSSENT or GWPING");
17.231 + break;
17.232 + case TYPE_GWPING:
17.233 + //Do not respond to GWPINGS at non-gateway nodes
17.234 + break;
17.235 + case TYPE_ACK:
17.236 + m_rtsBlocked = true;
17.237 + if(ch.GetDest() != m_address)
17.238 + return;
17.239 + //NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " UanMacRc Receiving ACK packet from PHY");
17.240 + ProcessAck(pkt);
17.241 + break;
17.242 + default:
17.243 + NS_FATAL_ERROR("Unknown packet type " << ch.GetType() << " received at node " << GetAddress());
17.244 + }
17.245 +
17.246 +}
17.247 +
17.248 +void
17.249 +UanMacRc::ScheduleData(Ptr<Packet> cts)
17.250 +{
17.251 + NS_ASSERT(m_state == RTSSENT || m_state == GWPSENT);
17.252 +
17.253 + UanHeaderRcCts ctsh;
17.254 + cts->RemoveHeader(ctsh);
17.255 +
17.256 + std::list<Reservation>::iterator it = m_resList.begin();
17.257 + for(;it != m_resList.end();it++)
17.258 + {
17.259 + if(it->GetFrameNo() == ctsh.GetFrameNo())
17.260 + break;
17.261 + }
17.262 + if(it == m_resList.end())
17.263 + {
17.264 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " received CTS packet with no corresponding reservation!");
17.265 + //NS_FATAL_ERROR("In " << __func__ << " could not find reservation corresponding to received CTS");
17.266 + return;
17.267 + }
17.268 + NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " Node " << m_address << " received CTS packet. Scheduling data");
17.269 + it->SetTransmitted();
17.270 +
17.271 + double currentBps = m_phy->GetMode(m_currentRate).GetDataRateBps();
17.272 +
17.273 + //Since we're synchronized, just compute prop. delay with timestamp
17.274 + //We could synchronize by using the 4 timestamps if an offset existed
17.275 + Time propDelay = Simulator::Now() - ctsh.GetTimeStamp2() - Seconds(m_ctsSize*8 / currentBps);
17.276 + //NS_LOG_DEBUG("Calculated prop delay " << propDelay.GetSeconds());
17.277 +
17.278 + Time arrTime = ctsh.GetTimeStamp2() + ctsh.GetDelayToTx();
17.279 + Time txTime = arrTime - propDelay;
17.280 +
17.281 + //Time startDelay = ctsh.GetTimeStamp2() + ctsh.GetDelayToTx() - Simulator::Now() + ctsh.GetTimeStamp2()
17.282 + Time startDelay = txTime - Simulator::Now();
17.283 +
17.284 + Time frameDelay = Seconds(0);
17.285 +
17.286 + const std::list<std::pair <Ptr<Packet>, UanAddress > > l = it->GetPktList();
17.287 + std::list<std::pair <Ptr<Packet>, UanAddress > >::const_iterator pit;
17.288 + pit = l.begin();
17.289 +
17.290 +
17.291 +
17.292 + for(uint32_t i=0;i<it->GetNoFrames();i++, pit++)
17.293 + {
17.294 + Ptr<Packet> pkt = (*pit).first->Copy();
17.295 + //UanAddress dest = (*pit).second;
17.296 + UanHeaderRcData dh;
17.297 + dh.SetFrameNo(i);
17.298 + dh.SetPropDelay(propDelay);
17.299 + pkt->AddHeader(dh);
17.300 + UanHeaderCommon ch;
17.301 + ch.SetType(TYPE_DATA);
17.302 + //NS_ASSERT(m_assocAddr == dest);
17.303 + ch.SetDest(m_assocAddr);
17.304 + ch.SetSrc(m_address);
17.305 + pkt->AddHeader(ch);
17.306 + Time eventTime = startDelay + frameDelay;
17.307 + if(eventTime.GetSeconds() < 0)
17.308 + {
17.309 + if(eventTime.GetSeconds() > -0.002)
17.310 + eventTime = Seconds(0);
17.311 + else
17.312 + NS_FATAL_ERROR("Scheduling error resulted in very negative data transmission time! eventTime = " << eventTime.GetSeconds());
17.313 + }
17.314 + Simulator::Schedule(eventTime, &UanMacRc::SendPacket, this, pkt, m_currentRate);
17.315 + frameDelay = frameDelay + m_sifs + Seconds(pkt->GetSize()/currentBps);
17.316 + }
17.317 +
17.318 + m_state = IDLE;
17.319 + if(!m_pktQueue.empty())
17.320 + {
17.321 +
17.322 + if(m_rtsEvent.IsRunning())
17.323 + m_rtsEvent.Cancel();
17.324 + ExponentialVariable ev(1/m_retryRate);
17.325 + double timeout = ev.GetValue();
17.326 + m_rtsEvent = Simulator::Schedule(Seconds(timeout), &UanMacRc::SendRts, this);
17.327 + }
17.328 +
17.329 +}
17.330 +
17.331 +void
17.332 +UanMacRc::SendPacket(Ptr<Packet> pkt, uint32_t rate)
17.333 +{
17.334 + UanHeaderCommon ch;
17.335 + pkt->PeekHeader(ch);
17.336 + std::string type;
17.337 + switch(ch.GetType())
17.338 + {
17.339 + case TYPE_DATA:
17.340 + type = "DATA";
17.341 + break;
17.342 + case TYPE_RTS:
17.343 + type= "RTS";
17.344 + break;
17.345 + case TYPE_CTS:
17.346 + type="CTS";
17.347 + break;
17.348 + case TYPE_ACK:
17.349 + type="ACK";
17.350 + break;
17.351 + case TYPE_GWPING:
17.352 + type="GWPING";
17.353 + break;
17.354 + default:
17.355 + type="UNKNOWN";
17.356 + break;
17.357 + }
17.358 + 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());
17.359 + m_dequeueLogger(pkt, rate);
17.360 + m_phy->SendPacket(pkt, rate);
17.361 +}
17.362 +
17.363 +void
17.364 +UanMacRc::ProcessAck(Ptr<Packet> ack)
17.365 +{