1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 MIRKO BANCHI
4  * Copyright (c) 2015 University of Washington
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors: Mirko Banchi <mk.banchi@gmail.com>
20  *          Sebastien Deronne <sebastien.deronne@gmail.com>
21  *          Tom Henderson <tomhend@u.washington.edu>
22  *
23  * Adapted from wifi-ht-network.cc example
24  */
25 
26 #include <iomanip>
27 #include "ns3/command-line.h"
28 #include "ns3/config.h"
29 #include "ns3/string.h"
30 #include "ns3/yans-wifi-helper.h"
31 #include "ns3/spectrum-wifi-helper.h"
32 #include "ns3/ssid.h"
33 #include "ns3/mobility-helper.h"
34 #include "ns3/internet-stack-helper.h"
35 #include "ns3/ipv4-address-helper.h"
36 #include "ns3/udp-client-server-helper.h"
37 #include "ns3/packet-sink-helper.h"
38 #include "ns3/on-off-helper.h"
39 #include "ns3/packet-sink.h"
40 #include "ns3/yans-wifi-channel.h"
41 #include "ns3/multi-model-spectrum-channel.h"
42 #include "ns3/propagation-loss-model.h"
43 #include "ns3/waveform-generator.h"
44 #include "ns3/waveform-generator-helper.h"
45 #include "ns3/non-communicating-net-device.h"
46 #include "ns3/wifi-net-device.h"
47 
48 // This is a simple example of an IEEE 802.11n Wi-Fi network with a
49 // non-Wi-Fi interferer.  It is an adaptation of the wifi-spectrum-per-example
50 //
51 // Unless the --waveformPower argument is passed, it will operate similarly to
52 // wifi-spectrum-per-example.  Adding --waveformPower=value for values
53 // greater than 0.0001 will result in frame losses beyond those that
54 // result from the normal SNR based on distance path loss.
55 //
56 // If YansWifiPhy is selected as the wifiType, --waveformPower will have
57 // no effect.
58 //
59 // Network topology:
60 //
61 //  Wi-Fi 192.168.1.0
62 //
63 //   STA                  AP
64 //    * <-- distance -->  *
65 //    |                   |
66 //    n1                  n2
67 //
68 // Users may vary the following command-line arguments in addition to the
69 // attributes, global values, and default values typically available:
70 //
71 //    --simulationTime:  Simulation time in seconds [10]
72 //    --udp:             UDP if set to 1, TCP otherwise [true]
73 //    --distance:        meters separation between nodes [50]
74 //    --index:           restrict index to single value between 0 and 31 [256]
75 //    --wifiType:        select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
76 //    --errorModelType:  select ns3::NistErrorRateModel or ns3::YansErrorRateModel [ns3::NistErrorRateModel]
77 //    --enablePcap:      enable pcap output [false]
78 //    --waveformPower:   Waveform power (linear W) [0]
79 //
80 // By default, the program will step through 32 index values, corresponding
81 // to the following MCS, channel width, and guard interval combinations:
82 //   index 0-7:    MCS 0-7, long guard interval, 20 MHz channel
83 //   index 8-15:   MCS 0-7, short guard interval, 20 MHz channel
84 //   index 16-23:  MCS 0-7, long guard interval, 40 MHz channel
85 //   index 24-31:  MCS 0-7, short guard interval, 40 MHz channel
86 // and send UDP for 10 seconds using each MCS, using the SpectrumWifiPhy and the
87 // NistErrorRateModel, at a distance of 50 meters.  The program outputs
88 // results such as:
89 //
90 // wifiType: ns3::SpectrumWifiPhy distance: 50m; time: 10; TxPower: 16 dBm (40 mW)
91 // index   MCS  Rate (Mb/s) Tput (Mb/s) Received Signal (dBm)Noi+Inf(dBm) SNR (dB)
92 //     0     0      6.50        5.77    7414      -64.69      -93.97       29.27
93 //     1     1     13.00       11.58   14892      -64.69      -93.97       29.27
94 //     2     2     19.50       17.39   22358      -64.69      -93.97       29.27
95 //     3     3     26.00       23.23   29875      -64.69      -93.97       29.27
96 //   ...
97 //
98 
99 using namespace ns3;
100 
101 // Global variables for use in callbacks.
102 double g_signalDbmAvg;
103 double g_noiseDbmAvg;
104 uint32_t g_samples;
105 
MonitorSniffRx(Ptr<const Packet> packet,uint16_t channelFreqMhz,WifiTxVector txVector,MpduInfo aMpdu,SignalNoiseDbm signalNoise,uint16_t staId)106 void MonitorSniffRx (Ptr<const Packet> packet,
107                      uint16_t channelFreqMhz,
108                      WifiTxVector txVector,
109                      MpduInfo aMpdu,
110                      SignalNoiseDbm signalNoise,
111                      uint16_t staId)
112 
113 {
114   g_samples++;
115   g_signalDbmAvg += ((signalNoise.signal - g_signalDbmAvg) / g_samples);
116   g_noiseDbmAvg += ((signalNoise.noise - g_noiseDbmAvg) / g_samples);
117 }
118 
119 NS_LOG_COMPONENT_DEFINE ("WifiSpectrumPerInterference");
120 
121 Ptr<SpectrumModel> SpectrumModelWifi5180MHz, SpectrumModelWifi5190MHz;
122 
123 class static_SpectrumModelWifi5180MHz_initializer
124 {
125 public:
static_SpectrumModelWifi5180MHz_initializer()126   static_SpectrumModelWifi5180MHz_initializer ()
127   {
128     BandInfo bandInfo;
129     bandInfo.fc = 5180e6;
130     bandInfo.fl = 5180e6 - 10e6;
131     bandInfo.fh = 5180e6 + 10e6;
132 
133     Bands bands;
134     bands.push_back (bandInfo);
135 
136     SpectrumModelWifi5180MHz = Create<SpectrumModel> (bands);
137   }
138 
139 } static_SpectrumModelWifi5180MHz_initializer_instance;
140 
141 class static_SpectrumModelWifi5190MHz_initializer
142 {
143 public:
static_SpectrumModelWifi5190MHz_initializer()144   static_SpectrumModelWifi5190MHz_initializer ()
145   {
146     BandInfo bandInfo;
147     bandInfo.fc = 5190e6;
148     bandInfo.fl = 5190e6 - 10e6;
149     bandInfo.fh = 5190e6 + 10e6;
150 
151     Bands bands;
152     bands.push_back (bandInfo);
153 
154     SpectrumModelWifi5190MHz = Create<SpectrumModel> (bands);
155   }
156 
157 } static_SpectrumModelWifi5190MHz_initializer_instance;
158 
main(int argc,char * argv[])159 int main (int argc, char *argv[])
160 {
161   bool udp = true;
162   double distance = 50;
163   double simulationTime = 10; //seconds
164   uint16_t index = 256;
165   std::string wifiType = "ns3::SpectrumWifiPhy";
166   std::string errorModelType = "ns3::NistErrorRateModel";
167   bool enablePcap = false;
168   const uint32_t tcpPacketSize = 1448;
169   double waveformPower = 0;
170 
171   CommandLine cmd (__FILE__);
172   cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
173   cmd.AddValue ("udp", "UDP if set to 1, TCP otherwise", udp);
174   cmd.AddValue ("distance", "meters separation between nodes", distance);
175   cmd.AddValue ("index", "restrict index to single value between 0 and 31", index);
176   cmd.AddValue ("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
177   cmd.AddValue ("errorModelType", "select ns3::NistErrorRateModel or ns3::YansErrorRateModel", errorModelType);
178   cmd.AddValue ("enablePcap", "enable pcap output", enablePcap);
179   cmd.AddValue ("waveformPower", "Waveform power (linear W)", waveformPower);
180   cmd.Parse (argc,argv);
181 
182   uint16_t startIndex = 0;
183   uint16_t stopIndex = 31;
184   if (index < 32)
185     {
186       startIndex = index;
187       stopIndex = index;
188     }
189 
190   std::cout << "wifiType: " << wifiType << " distance: " << distance << "m; time: " << simulationTime << "; TxPower: 16 dBm (40 mW)" << std::endl;
191   std::cout << std::setw (5) << "index" <<
192     std::setw (6) << "MCS" <<
193     std::setw (13) << "Rate (Mb/s)" <<
194     std::setw (12) << "Tput (Mb/s)" <<
195     std::setw (10) << "Received " <<
196     std::setw (12) << "Signal (dBm)" <<
197     std::setw (12) << "Noi+Inf(dBm)" <<
198     std::setw (9) << "SNR (dB)" <<
199     std::endl;
200   for (uint16_t i = startIndex; i <= stopIndex; i++)
201     {
202       uint32_t payloadSize;
203       if (udp)
204         {
205           payloadSize = 972; // 1000 bytes IPv4
206         }
207       else
208         {
209           payloadSize = 1448; // 1500 bytes IPv6
210           Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
211         }
212 
213       NodeContainer wifiStaNode;
214       wifiStaNode.Create (1);
215       NodeContainer wifiApNode;
216       wifiApNode.Create (1);
217       NodeContainer interferingNode;
218       interferingNode.Create (1);
219 
220       YansWifiPhyHelper phy;
221       SpectrumWifiPhyHelper spectrumPhy;
222       Ptr<MultiModelSpectrumChannel> spectrumChannel;
223       uint16_t frequency = (i <= 15 ? 5180 : 5190);
224       if (wifiType == "ns3::YansWifiPhy")
225         {
226           YansWifiChannelHelper channel;
227           channel.AddPropagationLoss ("ns3::FriisPropagationLossModel",
228                                       "Frequency", DoubleValue (frequency * 1e6));
229           channel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
230           phy.SetChannel (channel.Create ());
231           phy.Set ("Frequency", UintegerValue (frequency));
232         }
233       else if (wifiType == "ns3::SpectrumWifiPhy")
234         {
235           spectrumChannel
236             = CreateObject<MultiModelSpectrumChannel> ();
237           Ptr<FriisPropagationLossModel> lossModel
238             = CreateObject<FriisPropagationLossModel> ();
239           lossModel->SetFrequency (frequency * 1e6);
240           spectrumChannel->AddPropagationLossModel (lossModel);
241 
242           Ptr<ConstantSpeedPropagationDelayModel> delayModel
243             = CreateObject<ConstantSpeedPropagationDelayModel> ();
244           spectrumChannel->SetPropagationDelayModel (delayModel);
245 
246           spectrumPhy.SetChannel (spectrumChannel);
247           spectrumPhy.SetErrorRateModel (errorModelType);
248           spectrumPhy.Set ("Frequency", UintegerValue (frequency)); // channel 36 at 20 MHz, 38 at 40 MHz
249         }
250       else
251         {
252           NS_FATAL_ERROR ("Unsupported WiFi type " << wifiType);
253         }
254 
255       WifiHelper wifi;
256       wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
257       WifiMacHelper mac;
258 
259       Ssid ssid = Ssid ("ns380211n");
260 
261       double datarate = 0;
262       StringValue DataRate;
263       if (i == 0)
264         {
265           DataRate = StringValue ("HtMcs0");
266           datarate = 6.5;
267         }
268       else if (i == 1)
269         {
270           DataRate = StringValue ("HtMcs1");
271           datarate = 13;
272         }
273       else if (i == 2)
274         {
275           DataRate = StringValue ("HtMcs2");
276           datarate = 19.5;
277         }
278       else if (i == 3)
279         {
280           DataRate = StringValue ("HtMcs3");
281           datarate = 26;
282         }
283       else if (i == 4)
284         {
285           DataRate = StringValue ("HtMcs4");
286           datarate = 39;
287         }
288       else if (i == 5)
289         {
290           DataRate = StringValue ("HtMcs5");
291           datarate = 52;
292         }
293       else if (i == 6)
294         {
295           DataRate = StringValue ("HtMcs6");
296           datarate = 58.5;
297         }
298       else if (i == 7)
299         {
300           DataRate = StringValue ("HtMcs7");
301           datarate = 65;
302         }
303       else if (i == 8)
304         {
305           DataRate = StringValue ("HtMcs0");
306           datarate = 7.2;
307         }
308       else if (i == 9)
309         {
310           DataRate = StringValue ("HtMcs1");
311           datarate = 14.4;
312         }
313       else if (i == 10)
314         {
315           DataRate = StringValue ("HtMcs2");
316           datarate = 21.7;
317         }
318       else if (i == 11)
319         {
320           DataRate = StringValue ("HtMcs3");
321           datarate = 28.9;
322         }
323       else if (i == 12)
324         {
325           DataRate = StringValue ("HtMcs4");
326           datarate = 43.3;
327         }
328       else if (i == 13)
329         {
330           DataRate = StringValue ("HtMcs5");
331           datarate = 57.8;
332         }
333       else if (i == 14)
334         {
335           DataRate = StringValue ("HtMcs6");
336           datarate = 65;
337         }
338       else if (i == 15)
339         {
340           DataRate = StringValue ("HtMcs7");
341           datarate = 72.2;
342         }
343       else if (i == 16)
344         {
345           DataRate = StringValue ("HtMcs0");
346           datarate = 13.5;
347         }
348       else if (i == 17)
349         {
350           DataRate = StringValue ("HtMcs1");
351           datarate = 27;
352         }
353       else if (i == 18)
354         {
355           DataRate = StringValue ("HtMcs2");
356           datarate = 40.5;
357         }
358       else if (i == 19)
359         {
360           DataRate = StringValue ("HtMcs3");
361           datarate = 54;
362         }
363       else if (i == 20)
364         {
365           DataRate = StringValue ("HtMcs4");
366           datarate = 81;
367         }
368       else if (i == 21)
369         {
370           DataRate = StringValue ("HtMcs5");
371           datarate = 108;
372         }
373       else if (i == 22)
374         {
375           DataRate = StringValue ("HtMcs6");
376           datarate = 121.5;
377         }
378       else if (i == 23)
379         {
380           DataRate = StringValue ("HtMcs7");
381           datarate = 135;
382         }
383       else if (i == 24)
384         {
385           DataRate = StringValue ("HtMcs0");
386           datarate = 15;
387         }
388       else if (i == 25)
389         {
390           DataRate = StringValue ("HtMcs1");
391           datarate = 30;
392         }
393       else if (i == 26)
394         {
395           DataRate = StringValue ("HtMcs2");
396           datarate = 45;
397         }
398       else if (i == 27)
399         {
400           DataRate = StringValue ("HtMcs3");
401           datarate = 60;
402         }
403       else if (i == 28)
404         {
405           DataRate = StringValue ("HtMcs4");
406           datarate = 90;
407         }
408       else if (i == 29)
409         {
410           DataRate = StringValue ("HtMcs5");
411           datarate = 120;
412         }
413       else if (i == 30)
414         {
415           DataRate = StringValue ("HtMcs6");
416           datarate = 135;
417         }
418       else
419         {
420           DataRate = StringValue ("HtMcs7");
421           datarate = 150;
422         }
423 
424       wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
425                                     "ControlMode", DataRate);
426 
427       NetDeviceContainer staDevice;
428       NetDeviceContainer apDevice;
429 
430       if (wifiType == "ns3::YansWifiPhy")
431         {
432           mac.SetType ("ns3::StaWifiMac",
433                        "Ssid", SsidValue (ssid));
434           staDevice = wifi.Install (phy, mac, wifiStaNode);
435           mac.SetType ("ns3::ApWifiMac",
436                        "Ssid", SsidValue (ssid));
437           apDevice = wifi.Install (phy, mac, wifiApNode);
438 
439         }
440       else if (wifiType == "ns3::SpectrumWifiPhy")
441         {
442           mac.SetType ("ns3::StaWifiMac",
443                        "Ssid", SsidValue (ssid));
444           staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
445           mac.SetType ("ns3::ApWifiMac",
446                        "Ssid", SsidValue (ssid));
447           apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
448         }
449 
450       if (i <= 7)
451         {
452           Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (false));
453         }
454       else if (i > 7 && i <= 15)
455         {
456           Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (true));
457         }
458       else if (i > 15 && i <= 23)
459         {
460           Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (false));
461         }
462       else
463         {
464           Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (true));
465         }
466 
467       // mobility.
468       MobilityHelper mobility;
469       Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
470 
471       positionAlloc->Add (Vector (0.0, 0.0, 0.0));
472       positionAlloc->Add (Vector (distance, 0.0, 0.0));
473       positionAlloc->Add (Vector (distance, distance, 0.0));
474       mobility.SetPositionAllocator (positionAlloc);
475 
476       mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
477 
478       mobility.Install (wifiApNode);
479       mobility.Install (wifiStaNode);
480       mobility.Install (interferingNode);
481 
482       /* Internet stack*/
483       InternetStackHelper stack;
484       stack.Install (wifiApNode);
485       stack.Install (wifiStaNode);
486 
487       Ipv4AddressHelper address;
488       address.SetBase ("192.168.1.0", "255.255.255.0");
489       Ipv4InterfaceContainer staNodeInterface;
490       Ipv4InterfaceContainer apNodeInterface;
491 
492       staNodeInterface = address.Assign (staDevice);
493       apNodeInterface = address.Assign (apDevice);
494 
495       /* Setting applications */
496       ApplicationContainer serverApp;
497       if (udp)
498         {
499           //UDP flow
500           uint16_t port = 9;
501           UdpServerHelper server (port);
502           serverApp = server.Install (wifiStaNode.Get (0));
503           serverApp.Start (Seconds (0.0));
504           serverApp.Stop (Seconds (simulationTime + 1));
505 
506           UdpClientHelper client (staNodeInterface.GetAddress (0), port);
507           client.SetAttribute ("MaxPackets", UintegerValue (4294967295u));
508           client.SetAttribute ("Interval", TimeValue (Time ("0.0001"))); //packets/s
509           client.SetAttribute ("PacketSize", UintegerValue (payloadSize));
510           ApplicationContainer clientApp = client.Install (wifiApNode.Get (0));
511           clientApp.Start (Seconds (1.0));
512           clientApp.Stop (Seconds (simulationTime + 1));
513         }
514       else
515         {
516           //TCP flow
517           uint16_t port = 50000;
518           Address localAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
519           PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", localAddress);
520           serverApp = packetSinkHelper.Install (wifiStaNode.Get (0));
521           serverApp.Start (Seconds (0.0));
522           serverApp.Stop (Seconds (simulationTime + 1));
523 
524           OnOffHelper onoff ("ns3::TcpSocketFactory", Ipv4Address::GetAny ());
525           onoff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
526           onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
527           onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
528           onoff.SetAttribute ("DataRate", DataRateValue (1000000000)); //bit/s
529           AddressValue remoteAddress (InetSocketAddress (staNodeInterface.GetAddress (0), port));
530           onoff.SetAttribute ("Remote", remoteAddress);
531           ApplicationContainer clientApp = onoff.Install (wifiApNode.Get (0));
532           clientApp.Start (Seconds (1.0));
533           clientApp.Stop (Seconds (simulationTime + 1));
534         }
535 
536       // Configure waveform generator
537       Ptr<SpectrumValue> wgPsd = Create<SpectrumValue> (i <= 15 ? SpectrumModelWifi5180MHz
538                                                                 : SpectrumModelWifi5190MHz);
539       *wgPsd = waveformPower / 20e6;  // PSD spread across 20 MHz
540       NS_LOG_INFO ("wgPsd : " << *wgPsd << " integrated power: " << Integral (*(GetPointer (wgPsd))));
541 
542       if (wifiType == "ns3::SpectrumWifiPhy")
543         {
544           WaveformGeneratorHelper waveformGeneratorHelper;
545           waveformGeneratorHelper.SetChannel (spectrumChannel);
546           waveformGeneratorHelper.SetTxPowerSpectralDensity (wgPsd);
547 
548           waveformGeneratorHelper.SetPhyAttribute ("Period", TimeValue (Seconds (0.0007)));
549           waveformGeneratorHelper.SetPhyAttribute ("DutyCycle", DoubleValue (1));
550           NetDeviceContainer waveformGeneratorDevices = waveformGeneratorHelper.Install (interferingNode);
551 
552           Simulator::Schedule (Seconds (0.002), &WaveformGenerator::Start,
553                                waveformGeneratorDevices.Get (0)->GetObject<NonCommunicatingNetDevice> ()->GetPhy ()->GetObject<WaveformGenerator> ());
554         }
555 
556       Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/Phy/MonitorSnifferRx", MakeCallback (&MonitorSniffRx));
557 
558       if (enablePcap)
559         {
560           phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
561           std::stringstream ss;
562           ss << "wifi-spectrum-per-example-" << i;
563           phy.EnablePcap (ss.str (), apDevice);
564         }
565       g_signalDbmAvg = 0;
566       g_noiseDbmAvg = 0;
567       g_samples = 0;
568 
569       // Make sure we are tuned to 5180 MHz; if not, the example will
570       // not work properly
571       Ptr<NetDevice> staDevicePtr = staDevice.Get (0);
572       Ptr<WifiPhy> wifiPhyPtr = staDevicePtr->GetObject <WifiNetDevice> ()->GetPhy ();
573       if (i <= 15)
574         {
575           NS_ABORT_MSG_IF (wifiPhyPtr->GetChannelWidth () != 20,
576                            "Error: Channel width must be 20 MHz if MCS index <= 15");
577           NS_ABORT_MSG_IF (wifiPhyPtr->GetFrequency () != 5180,
578                            "Error:  Wi-Fi nodes must be tuned to 5180 MHz to match the waveform generator");
579         }
580       else
581         {
582           NS_ABORT_MSG_IF (wifiPhyPtr->GetChannelWidth () != 40,
583                            "Error: Channel width must be 40 MHz if MCS index > 15");
584           NS_ABORT_MSG_IF (wifiPhyPtr->GetFrequency () != 5190,
585                            "Error:  Wi-Fi nodes must be tuned to 5190 MHz to match the waveform generator");
586         }
587 
588       Simulator::Stop (Seconds (simulationTime + 1));
589       Simulator::Run ();
590 
591       double throughput = 0;
592       uint64_t totalPacketsThrough = 0;
593       if (udp)
594         {
595           //UDP
596           totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
597           throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
598         }
599       else
600         {
601           //TCP
602           uint64_t totalBytesRx = DynamicCast<PacketSink> (serverApp.Get (0))->GetTotalRx ();
603           totalPacketsThrough = totalBytesRx / tcpPacketSize;
604           throughput = totalBytesRx * 8 / (simulationTime * 1000000.0); //Mbit/s
605         }
606       std::cout << std::setw (5) << i <<
607         std::setw (6) << (i % 8) <<
608         std::setprecision (2) << std::fixed <<
609         std::setw (10) << datarate <<
610         std::setw (12) << throughput <<
611         std::setw (8) << totalPacketsThrough;
612       if (totalPacketsThrough > 0)
613         {
614           std::cout << std::setw (12) << g_signalDbmAvg <<
615             std::setw (12) << g_noiseDbmAvg <<
616             std::setw (12) << (g_signalDbmAvg - g_noiseDbmAvg) <<
617             std::endl;
618         }
619       else
620         {
621           std::cout << std::setw (12) << "N/A" <<
622             std::setw (12) << "N/A" <<
623             std::setw (12) << "N/A" <<
624             std::endl;
625         }
626       Simulator::Destroy ();
627     }
628   return 0;
629 }
630