forked from Gabrielcarvfer/NS3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuan-rc-example.cc
304 lines (253 loc) · 9.67 KB
/
uan-rc-example.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Leonard Tracy <[email protected]>
*/
/**
* \file uan-rc-example.cc
* \ingroup UAN
* This example uses UanMacRc and UanMacRcGw which combined form a system
* using what is referred to as RC-MAC. Details of RC-MAC will be published
* soon. In brief terms, RC-MAC is a dual channel protocol wherein the
* available bandwidth is dynamically divided into two channels,
* a reservation channel and a data channel. The network is assumed
* to consist of a single gateway node which services several
* non-gateway nodes.
*
* Time is divided into cycles. The non-gateway nodes transmit RTS packets
* on the reservation channel in parallel to scheduled data transmissions
* (scheduled in the previous cycle), and the gateway stores these requests
* for the duration of the cycle. At the start of the next cycle
* the gateway node transmits a CTS which contains packet transmission times
* for reserved packets as well as bandwidth allocation information
*
* This script deploys a single gateway node (current UanMacRc only supports
* a single gateway) in the center of a region and then distributes
* non-gateway nodes around the gateway with a uniformly distributed range
* between each node and the gateway.
*
* The script supports two simulation types. By default the gateway
* dynamically determines the optimal parameter settings and
* simulations are run with varying number of nodes (SimMin to SimMax as
* set by the command line). If DoNode=0 is given as a command line option
* then the mac parameter "a" (approximate expected number of successful
* RTS arrivals per cycle) is varied as the simulation parameter.
*
* For questions about this MAC protocol email "[email protected]"
*/
#include "uan-rc-example.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/log.h"
#include "ns3/config.h"
#include "ns3/callback.h"
#include "ns3/stats-module.h"
#include <fstream>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("UanRcExample");
Experiment::Experiment ()
: m_simMin (1),
m_simMax (1),
m_simStep (1),
m_numRates (1023),
m_totalRate (4096),
m_maxRange (3000),
m_numNodes (15),
m_pktSize (1000),
m_doNode (true),
m_sifs (Seconds (0.05)),
m_simTime (Seconds (5000)),
m_gnuplotfile ("uan-rc-example.gpl"),
m_bytesTotal (0)
{
}
void
Experiment::ReceivePacket (Ptr<Socket> socket)
{
Ptr<Packet> packet;
while ((packet = socket->Recv ()))
{
m_bytesTotal += packet->GetSize ();
}
}
UanTxMode
Experiment::CreateMode (uint32_t kass,
uint32_t fc,
bool upperblock,
std::string name)
{
std::ostringstream buf;
buf << name << " " << kass;
uint32_t rate = m_totalRate/(m_numRates+1)* (kass);
uint32_t bw = kass * m_totalRate / (m_numRates+1);
uint32_t fcmode;
if(upperblock)
fcmode = (m_totalRate - bw)/2 + fc;
else
fcmode = (uint32_t)((-((double) m_totalRate ) + (double) bw)/2.0 + (double) fc);
uint32_t phyrate = m_totalRate;
UanTxMode mode;
mode = UanTxModeFactory::CreateMode (UanTxMode::OTHER,
rate,
phyrate,
fcmode,
bw,
2,
buf.str ());
return mode;
}
//Creates m_numRates different modes each dividing m_totalRate Hz (assumes 1 bit per hz)
//centered at frequency fc
void
Experiment::CreateDualModes (uint32_t fc)
{
for (uint32_t i=1; i < m_numRates+1; i++)
{
m_controlModes.AppendMode (CreateMode (i, fc, false, "control "));
}
for (uint32_t i=m_numRates; i > 0; i--)
{
m_dataModes.AppendMode (CreateMode (i, fc, true, "data "));
}
}
uint32_t
Experiment::Run (uint32_t param)
{
UanHelper uan;
m_bytesTotal=0;
uint32_t nNodes;
uint32_t a;
if(m_doNode)
{
a=0;
nNodes = param;
}
else
{
nNodes = m_numNodes;
a = param;
}
Time pDelay = Seconds ((double) m_maxRange / 1500.0);
uan.SetPhy ("ns3::UanPhyDual",
"SupportedModesPhy1", UanModesListValue (m_dataModes),
"SupportedModesPhy2", UanModesListValue (m_controlModes));
uan.SetMac ("ns3::UanMacRcGw",
"NumberOfRates", UintegerValue (m_numRates),
"NumberOfNodes", UintegerValue (nNodes),
"MaxReservations", UintegerValue (a),
"SIFS", TimeValue (m_sifs),
"MaxPropDelay", TimeValue (pDelay),
"FrameSize", UintegerValue (m_pktSize));
Ptr<UanChannel> chan = CreateObject<UanChannel>();
NodeContainer sink;
sink.Create (1);
NetDeviceContainer sinkDev = uan.Install (sink, chan);
uan.SetMac ("ns3::UanMacRc",
"NumberOfRates", UintegerValue (m_numRates),
"MaxPropDelay", TimeValue (pDelay));
NodeContainer nodes;
nodes.Create (nNodes);
NetDeviceContainer devices = uan.Install (nodes, chan);
MobilityHelper mobility;
uint32_t depth = 70;
Ptr<ListPositionAllocator> pos = CreateObject<ListPositionAllocator> ();
Ptr<UniformRandomVariable> urv = CreateObject<UniformRandomVariable> ();
Ptr<UniformRandomVariable> utheta = CreateObject<UniformRandomVariable> ();
pos->Add (Vector (m_maxRange, m_maxRange, depth));
for (uint32_t i=0; i<nNodes; i++)
{
double theta = utheta->GetValue (0, 2.0*M_PI);
double r = urv->GetValue (0,m_maxRange);
double x = m_maxRange + r*std::cos (theta);
double y = m_maxRange + r*std::sin (theta);
pos->Add (Vector (x, y, depth));
}
mobility.SetPositionAllocator (pos);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (sink);
mobility.Install (nodes);
PacketSocketHelper pktskth;
pktskth.Install (nodes);
pktskth.Install (sink);
PacketSocketAddress socket;
socket.SetSingleDevice (sinkDev.Get (0)->GetIfIndex ());
socket.SetPhysicalAddress (sinkDev.Get (0)->GetAddress ());
socket.SetProtocol (0);
OnOffHelper app ("ns3::PacketSocketFactory", Address (socket));
app.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
app.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
app.SetAttribute ("DataRate", DataRateValue (m_totalRate));
app.SetAttribute ("PacketSize", UintegerValue (m_pktSize));
ApplicationContainer apps = app.Install (nodes);
apps.Start (Seconds (0.5));
apps.Stop (m_simTime + Seconds (0.5));
Ptr<Node> sinkNode = sink.Get (0);
TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory");
Ptr<Socket> sinkSocket = Socket::CreateSocket (sinkNode, psfid);
sinkSocket->Bind (socket);
sinkSocket->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
Simulator::Stop (m_simTime + Seconds (0.6));
Simulator::Run ();
Simulator::Destroy ();
return m_bytesTotal;
}
int
main (int argc, char *argv[])
{
Experiment exp;
bool quiet = false;
CommandLine cmd (__FILE__);
cmd.AddValue ("TotalRate", "Total channel capacity", exp.m_totalRate);
cmd.AddValue ("NumberRates", "Number of divided rates ( (NumberRates+1)%TotalRate should be 0)", exp.m_numRates);
cmd.AddValue ("MaxRange", "Maximum range between gateway and acoustic node", exp.m_maxRange);
cmd.AddValue ("SimMin", "Minimum parameter to test (nodes if DoNode=1, \"a\" param otherwise)", exp.m_simMin);
cmd.AddValue ("SimMax", "Maximum parameter to test (nodes if DoNode=1, \"a\" param otherwise)", exp.m_simMax);
cmd.AddValue ("SimStep", "Amount to increment param per trial", exp.m_simStep);
cmd.AddValue ("DataFile", "Filename for GnuPlot", exp.m_gnuplotfile);
cmd.AddValue ("NumberNodes", "Number of nodes (invalid for doNode=1)", exp.m_numNodes);
cmd.AddValue ("SIFS", "SIFS time duration", exp.m_sifs);
cmd.AddValue ("PktSize", "Packet size in bytes", exp.m_pktSize);
cmd.AddValue ("SimTime", "Simulation time per trial", exp.m_simTime);
cmd.AddValue ("DoNode", "1 for do max nodes simulation (invalidates AMin and AMax values)", exp.m_doNode);
cmd.AddValue ("Quiet", "Run in quiet mode (disable logging)", quiet);
cmd.Parse (argc, argv);
if (!quiet)
{
LogComponentEnable ("UanRcExample", LOG_LEVEL_ALL);
}
exp.CreateDualModes (12000);
;
Gnuplot2dDataset ds;
for (uint32_t param=exp.m_simMin; param<=exp.m_simMax; param += exp.m_simStep)
{
uint32_t bytesRx = exp.Run (param);
NS_LOG_DEBUG ("param=" << param << ": Received " << bytesRx << " bytes at sink");
double util = bytesRx*8.0/(exp.m_simTime.GetSeconds ()*exp.m_totalRate);
ds.Add (param, util);
SeedManager::SetRun (SeedManager::GetRun () + 1);
}
Gnuplot gp;
gp.AddDataset (ds);
std::ofstream of (exp.m_gnuplotfile.c_str ());
if (!of.is_open ())
{
NS_FATAL_ERROR ("Can not open GNU Plot outfile: " << exp.m_gnuplotfile);
}
gp.GenerateOutput (of);
}