Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1243)

Unified Diff: ns-3.13/src/ar-model/examples/error-model-test.cc

Issue 6201059: New IEEE 802.11 indoor wireless channel models for ns-3
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ns-3.13/src/ar-model/configs/coefsAR.cfg ('k') | ns-3.13/src/ar-model/model/ar-model.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ns-3.13/src/ar-model/examples/error-model-test.cc
diff --git a/ns-3.13/src/ar-model/examples/error-model-test.cc b/ns-3.13/src/ar-model/examples/error-model-test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..071fcca2a7973efedf4a4ce1af6929c8e919ed32
--- /dev/null
+++ b/ns-3.13/src/ar-model/examples/error-model-test.cc
@@ -0,0 +1,1051 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Universidad de Cantabria
+ *
+ * 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: David Gómez Fernández <dgomez@tlmat.unican.es>
+ * Ramón Agüero Calvo <ramon@tlmat.unican.es>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/applications-module.h"
+
+#include "ns3/wifi-helper.h"
+#include "ns3/yans-wifi-helper.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/wifi-module.h"
+#include "ns3/propagation-loss-model.h"
+
+#include "ns3/aodv-routing-protocol.h"
+
+#include "ns3/ar-model.h"
+#include "ns3/hidden-markov-error-model.h"
+
+#include "ns3/socket.h"
+#include <ns3/node-list.h>
+
+#include "ns3/wifi-mac-header.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/tcp-header.h"
+#include "ns3/udp-header.h"
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <stdio.h>
+
+#include "scratch-logging.h"
+//#include "experiment.h"
+
+
+NS_LOG_COMPONENT_DEFINE("TcpErrorModelTest");
+
+using namespace std;
+using namespace ns3;
+
+std::string ConvertMacToString(Mac48Address mac);
+std::string getcwd();
+
+enum ChannelMode_t {
+ HIDDEN_MARKOV_ERROR_MODEL,
+ BURSTY_ERROR_AUTO_REGRESSIVE_MODEL,
+ NIST_ERROR_RATE_MODEL
+};
+
+enum TransportProtocol_t {
+ TCP_PROTOCOL,
+ UDP_PROTOCOL
+};
+
+
+class Experiment {
+public:
+ Experiment ();
+ ~Experiment ();
+
+ u_int32_t GetPacketCounter() const;
+ void SetPacketCounter(u_int32_t packetCounter);
+ u_int32_t GetPktsCorrect() const;
+ void SetPktsCorrect(u_int32_t pktsCorrect);
+ u_int32_t GetPktsReceived() const;
+ void SetPktsReceived(u_int32_t pktsReceived);
+ u_int32_t GetPktsTransmitted () const;
+
+ void SetTransportProtocol (TransportProtocol_t protocol);
+ TransportProtocol_t GetTransportProtocol () const;
+
+ Ptr<Socket> SetupPacketReceive(Ptr<Node> node);
+ void GenerateTraffic(Ptr<Socket> socket, uint32_t pktSize,
+ uint32_t pktCount, Time pktInterval);
+ //Tracing
+ void PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble);
+ void PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr);
+
+ //BEAR Callback integration
+ void HmmRxTrace (Ptr<Packet> packet, Time timestamp, bool error, u_int16_t state);
+ void BearRxTrace (Ptr<Packet> packet, Time timestamp, bool error, double propagation, double slowFading, double fastFading);
+
+ //Upper Layer parser
+ packetInfo_t ParsePacket (Ptr<const Packet> packet);
+
+ void OpenTraceFile (string fileName, ChannelMode_t channelModel);
+ void CloseTraceFile ();
+
+ void TraceToFile (string line);
+
+
+private:
+ fstream m_file;
+
+ void ReceivePacket(Ptr<Socket> socket);
+ void SetPosition(Ptr<Node> node, Vector position);
+ Vector GetPosition(Ptr<Node> node);
+ u_int32_t m_pktsReceived;
+ u_int32_t m_pktsCorrect;
+ u_int32_t m_packetCounter;
+
+ u_int32_t m_packetsTransmitted;
+
+ TransportProtocol_t m_protocol;
+};
+
+
+Experiment::Experiment(): m_pktsReceived (0),
+ m_pktsCorrect (0),
+ m_packetCounter (0),
+ m_packetsTransmitted (0)
+{}
+
+Experiment::~Experiment()
+{}
+
+
+void Experiment::SetPosition(Ptr<Node> node, Vector position) {
+ Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
+ mobility->SetPosition(position);
+}
+Vector Experiment::GetPosition(Ptr<Node> node) {
+ Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
+ return mobility->GetPosition();
+}
+void Experiment::ReceivePacket(Ptr<Socket> socket) {
+ Ptr<Packet> packet;
+ while (packet = socket->Recv()) {
+ // m_pktsReceived++;
+ }
+}
+
+Ptr<Socket> Experiment::SetupPacketReceive(Ptr<Node> node) {
+
+ TypeId tid = TypeId::LookupByName("ns3::TcpSocketFactory");
+
+ if (m_protocol == UDP_PROTOCOL)
+ tid = TypeId::LookupByName("ns3::UdpSocketFactory");
+ Ptr<Socket> sink = Socket::CreateSocket(node, tid);
+ InetSocketAddress local = InetSocketAddress(Ipv4Address::GetAny(), 80);
+ sink->Bind(local);
+ sink->SetRecvCallback(MakeCallback(&Experiment::ReceivePacket, this));
+ return sink;
+}
+void Experiment::GenerateTraffic(Ptr<Socket> socket, uint32_t pktSize,
+ uint32_t pktCount, Time pktInterval) {
+ m_packetCounter --;
+ if (m_packetCounter > 0) {
+ socket->Send(Create<Packet>(pktSize));
+ Simulator::Schedule(pktInterval, &Experiment::GenerateTraffic, this,
+ socket, pktSize, pktCount - 1, pktInterval);
+ } else {
+ socket->Close();
+ }
+ m_packetsTransmitted ++;
+}
+
+u_int32_t Experiment::GetPacketCounter () const
+{
+ return m_packetCounter;
+}
+
+void Experiment::SetPacketCounter (u_int32_t packetCounter)
+{
+ this->m_packetCounter = packetCounter;
+}
+
+u_int32_t Experiment::GetPktsCorrect () const
+{
+ return m_pktsCorrect;
+}
+
+void Experiment::SetPktsCorrect (u_int32_t pktsCorrect)
+{
+ this->m_pktsCorrect = pktsCorrect;
+}
+
+u_int32_t Experiment::GetPktsReceived () const
+{
+ return m_pktsReceived;
+}
+
+void Experiment::SetPktsReceived(u_int32_t pktsReceived)
+{
+ this->m_pktsReceived = pktsReceived;
+}
+
+u_int32_t Experiment::GetPktsTransmitted() const
+{
+ return m_packetsTransmitted;
+}
+
+void Experiment::SetTransportProtocol(TransportProtocol_t protocol)
+{
+ m_protocol = protocol;
+}
+
+TransportProtocol_t Experiment::GetTransportProtocol () const
+{
+ return m_protocol;
+}
+
+//// Trace data frames and their corresponding ACKs
+
+void Experiment::PhyRxOkTrace(std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
+{
+
+ ///////////////////////////////////////////////////////
+ NS_LOG_FUNCTION_NOARGS();
+ WifiMacHeader hdr;
+ packetInfo_t packetInfo;
+ char line [255];
+ bool dataOrAck;
+
+ //Ip addresses variables needed for Ipv4Address to String conversion
+ u_int8_t source [4];
+ u_int8_t destination [4];
+ char sourceChar [32];
+ char destChar [32];
+
+ packet->PeekHeader (hdr); //Don't forget to uncomment
+ packetInfo = ParsePacket(packet);
+
+ switch (packetInfo.type)
+ {
+ case TCP_DATA:
+ if (m_protocol == TCP_PROTOCOL)
+ {
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+
+ //Get the MAC and IP Addresses
+ packetInfo.ipv4Hdr.GetSource().Serialize(source); //Get a string from Ipv4Address
+ packetInfo.ipv4Hdr.GetDestination().Serialize(destination);
+ sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1], source[2], source[3]);
+ sprintf(destChar, "%d.%d.%d.%d", destination[0], destination[1], destination[2], destination[3]);
+
+ sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d %16d %16f", \
+ Simulator::Now().GetSeconds(), true, sourceChar, \
+ destChar, packetInfo.wifiHdr.IsRetry(), \
+ packetInfo.payloadLength, \
+ packetInfo.wifiHdr.GetSequenceNumber(), \
+ packetInfo.tcpHdr.GetSequenceNumber().GetValue(), \
+ packetInfo.tcpHdr.GetAckNumber().GetValue(), \
+ snr);
+ TraceToFile(line);
+ }
+ break;
+ case UDP_DATA:
+ if (m_protocol == UDP_PROTOCOL)
+ {
+ //Distinguish between data or ACK
+ if (hdr.IsData())
+ dataOrAck = false;
+ else if (hdr.IsAck())
+ dataOrAck = true;
+
+ sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %10f", \
+ Simulator::Now().GetSeconds(), \
+ true, \
+ ConvertMacToString(hdr.GetAddr2()).c_str(), \
+ ConvertMacToString(hdr.GetAddr1()).c_str(), \
+ dataOrAck ? "ACK" : "DATA", \
+ packet->GetSize(), \
+ hdr.GetSequenceNumber(), \
+ snr);
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+
+ TraceToFile(line);
+ }
+ break;
+ default:
+ NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type);
+ break;
+ }
+
+
+ ////////////////////////////////////
+
+}
+
+void Experiment::PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr)
+{
+ ///////////////////////////////////////////////////////
+ NS_LOG_FUNCTION_NOARGS();
+ WifiMacHeader hdr;
+ packetInfo_t packetInfo;
+ char line [255];
+ bool dataOrAck;
+
+ //Ip addresses variables needed for Ipv4Address to String conversion
+ u_int8_t source [4];
+ u_int8_t destination [4];
+ char sourceChar [32];
+ char destChar [32];
+
+ packet->PeekHeader (hdr); //Don't forget to uncomment
+ packetInfo = ParsePacket(packet);
+
+ switch (packetInfo.type)
+ {
+ case TCP_DATA:
+ if (m_protocol == TCP_PROTOCOL)
+ {
+ m_pktsReceived ++;
+
+ //Get the MAC and IP Addresses
+ packetInfo.ipv4Hdr.GetSource().Serialize(source); //Get a string from Ipv4Address
+ packetInfo.ipv4Hdr.GetDestination().Serialize(destination);
+ sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1], source[2], source[3]);
+ sprintf(destChar, "%d.%d.%d.%d", destination[0], destination[1], destination[2], destination[3]);
+
+ sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d %16d %16f", \
+ Simulator::Now().GetSeconds(), false, sourceChar, \
+ destChar, packetInfo.wifiHdr.IsRetry(), \
+ packetInfo.payloadLength, \
+ packetInfo.wifiHdr.GetSequenceNumber(), \
+ packetInfo.tcpHdr.GetSequenceNumber().GetValue(), \
+ packetInfo.tcpHdr.GetAckNumber().GetValue(), \
+ snr);
+ TraceToFile(line);
+ }
+
+ break;
+ case UDP_DATA:
+ if (m_protocol == UDP_PROTOCOL)
+ {
+ //Distinguish between data or ACK
+ if (hdr.IsData())
+ dataOrAck = false;
+ else if (hdr.IsAck())
+ dataOrAck = true;
+
+ sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %10f", \
+ Simulator::Now().GetSeconds(), \
+ false, \
+ ConvertMacToString(hdr.GetAddr2()).c_str(), \
+ ConvertMacToString(hdr.GetAddr1()).c_str(), \
+ dataOrAck ? "ACK" : "DATA", \
+ packet->GetSize(), \
+ hdr.GetSequenceNumber(), \
+ snr);
+ m_pktsReceived ++;
+ TraceToFile(line);
+
+ }
+ break;
+ default:
+ NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type);
+ break;
+ }
+
+
+ ////////////////////////////////////
+
+}
+
+packetInfo_t Experiment::ParsePacket (Ptr<const Packet> packet)
+{
+ NS_LOG_FUNCTION(packet);
+
+ packetInfo_t packetInfo;
+ Ptr<Packet> pktCopy = packet->Copy();
+
+ pktCopy->RemoveHeader(packetInfo.wifiHdr);
+
+ if (packetInfo.wifiHdr.IsData())
+ {
+ pktCopy->RemoveHeader(packetInfo.llcHdr);
+ switch (packetInfo.llcHdr.GetType())
+ {
+ case 0x0806: //ARP
+ packetInfo.type = ARP_PACKET;
+ break;
+ case 0x0800: //IP packet
+ pktCopy->RemoveHeader(packetInfo.ipv4Hdr);
+ switch (packetInfo.ipv4Hdr.GetProtocol())
+ {
+ case 6: //TCP
+ pktCopy->RemoveHeader(packetInfo.tcpHdr);
+ packetInfo.type = TCP_DATA;
+
+ break;
+ case 17: //UDP
+ pktCopy->RemoveHeader(packetInfo.udpHdr);
+ packetInfo.type = UDP_DATA;
+ break;
+ default:
+ NS_LOG_ERROR ("Protocol not implemented yet (IP) --> " << packetInfo.llcHdr.GetType());
+ break;
+ }
+ break;
+ default:
+ NS_LOG_ERROR ("Protocol not implemented yet (LLC) --> " << packetInfo.llcHdr.GetType());
+ break;
+ }
+ }
+ else if (packetInfo.wifiHdr.IsAck())
+ {
+ packetInfo.type = IEEE_80211_ACK;
+ }
+ else // 802.11 Control/Management frame
+ {
+ packetInfo.type = IEEE_80211_NODATA;
+ }
+
+ packetInfo.payloadLength = pktCopy->GetSize() - 4; //Last four bytes are used for tagging
+
+ return packetInfo;
+}
+
+void Experiment::BearRxTrace(Ptr<Packet> packet, Time timestamp, bool error, double propagation, double slowFading, double fastFading)
+{
+ NS_LOG_FUNCTION_NOARGS();
+ WifiMacHeader hdr;
+ packetInfo_t packetInfo;
+ char line [255];
+ bool dataOrAck; //Value used for UDP tracing
+
+ //Ip addresses variables needed for Ipv4Address to String conversion
+ u_int8_t source [4];
+ u_int8_t destination [4];
+ char sourceChar [32];
+ char destChar [32];
+
+ packet->PeekHeader (hdr); //Don't forget to uncomment
+ packetInfo = ParsePacket(packet);
+
+ switch (packetInfo.type)
+ {
+
+ case TCP_DATA:
+ if (m_protocol == TCP_PROTOCOL)
+ {
+ if (error == 0)
+ {
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+ }
+ else
+ {
+ m_pktsReceived ++;
+ }
+
+ //Get the MAC and IP Addresses
+ packetInfo.ipv4Hdr.GetSource().Serialize(source); //Get a string from Ipv4Address
+ packetInfo.ipv4Hdr.GetDestination().Serialize(destination);
+ sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1], source[2], source[3]);
+ sprintf(destChar, "%d.%d.%d.%d", destination[0], destination[1], destination[2], destination[3]);
+
+ sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d %16d %16f", \
+ Simulator::Now().GetSeconds(), !error, sourceChar, \
+ destChar, packetInfo.wifiHdr.IsRetry(), \
+ packetInfo.payloadLength, \
+ packetInfo.wifiHdr.GetSequenceNumber(), \
+ packetInfo.tcpHdr.GetSequenceNumber().GetValue(), \
+ packetInfo.tcpHdr.GetAckNumber().GetValue(), \
+ propagation + slowFading + fastFading);
+
+ TraceToFile(line);
+ }
+ break;
+ case UDP_DATA:
+ if (m_protocol == UDP_PROTOCOL)
+ {
+ if (error == 0)
+ {
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+ }
+ else
+ {
+ m_pktsReceived ++;
+ }
+ //Distinguish between data or ACK
+ if (hdr.IsData())
+ dataOrAck = false;
+ else if (hdr.IsAck()) //
+ dataOrAck = true;
+
+ sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %12f %12f %12f", \
+ timestamp.GetSeconds(), \
+ !error, \
+ ConvertMacToString(hdr.GetAddr2()).c_str(), \
+ ConvertMacToString(hdr.GetAddr1()).c_str(), \
+ dataOrAck ? "ACK" : "DATA", \
+ packet->GetSize(), \
+ hdr.GetSequenceNumber(), \
+ propagation, \
+ slowFading, \
+ fastFading \
+ );
+ TraceToFile(line);
+ }
+ break;
+ default:
+ NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type);
+ break;
+ }
+
+
+
+}
+
+void Experiment::HmmRxTrace(Ptr<Packet> packet, Time timestamp, bool error, u_int16_t state)
+{
+ NS_LOG_FUNCTION_NOARGS();
+ WifiMacHeader hdr;
+ packetInfo_t packetInfo;
+ char line [255];
+ bool dataOrAck; //Value used for UDP tracing
+
+ //Ip addresses variables needed for Ipv4Address to String conversion
+ u_int8_t source [4];
+ u_int8_t destination [4];
+ char sourceChar [32];
+ char destChar [32];
+
+ packet->PeekHeader (hdr); //Don't forget to uncomment
+ packetInfo = ParsePacket(packet);
+
+ switch (packetInfo.type)
+ {
+ case TCP_DATA:
+ if (m_protocol == TCP_PROTOCOL)
+ {
+ if (error == 0)
+ {
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+ }
+ else
+ {
+ m_pktsReceived ++;
+ }
+
+ //Get the MAC and IP Addresses
+ packetInfo.ipv4Hdr.GetSource().Serialize(source); //Get a string from Ipv4Address
+ packetInfo.ipv4Hdr.GetDestination().Serialize(destination);
+ sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1], source[2], source[3]);
+ sprintf(destChar, "%d.%d.%d.%d", destination[0], destination[1], destination[2], destination[3]);
+
+ sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d %16d %16d", \
+ Simulator::Now().GetSeconds(), !error, sourceChar, \
+ destChar, packetInfo.wifiHdr.IsRetry(), \
+ packetInfo.payloadLength, \
+ packetInfo.wifiHdr.GetSequenceNumber(), \
+ packetInfo.tcpHdr.GetSequenceNumber().GetValue(), \
+ packetInfo.tcpHdr.GetAckNumber().GetValue(), \
+ state);
+ TraceToFile(line);
+ }
+ break;
+ case UDP_DATA:
+ if (m_protocol == UDP_PROTOCOL)
+ {
+ if (error == 0)
+ {
+ m_pktsCorrect ++;
+ m_pktsReceived ++;
+ }
+ else
+ {
+ m_pktsReceived ++;
+ }
+ //Distinguish between data or ACK
+ if (hdr.IsData())
+ dataOrAck = false;
+ else if (hdr.IsAck())
+ dataOrAck = true;
+ sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %8d", \
+ timestamp.GetSeconds(), \
+ !error, \
+ ConvertMacToString(hdr.GetAddr2()).c_str(), \
+ ConvertMacToString(hdr.GetAddr1()).c_str(), \
+ dataOrAck ? "ACK" : "DATA", \
+ packet->GetSize(), \
+ hdr.GetSequenceNumber(), \
+ state);
+ TraceToFile(line);
+ }
+ break;
+ default:
+ NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type);
+ break;
+ }
+
+
+}
+
+
+void Experiment::OpenTraceFile (string fileName, ChannelMode_t channelModel = BURSTY_ERROR_AUTO_REGRESSIVE_MODEL)
+{
+ string path = getcwd() + "/traces/" + fileName;
+ char title [255];
+ string lastField; //Channel Model Dependent field (trace field)
+ NS_LOG_DEBUG(path);
+ m_file.open(path.c_str(), fstream::out);
+
+ //Split into TCP and UDP simulations
+ switch (m_protocol)
+ {
+ case TCP_PROTOCOL:
+ if (channelModel == HIDDEN_MARKOV_ERROR_MODEL)
+ lastField = "State";
+ else
+ lastField = "SNR (dB)";
+
+ sprintf (title, "%16s %16s %20s %20s %16s %16s %16s %16s %16s %16s", \
+ "Time", "CRC", "Source", "Destination", "802.11 RETX", \
+ "Length","SeqNum", "TCP SeqNum", "TCP AckNum", \
+ lastField.c_str());
+ break;
+
+ case UDP_PROTOCOL:
+ switch (channelModel)
+ {
+ case BURSTY_ERROR_AUTO_REGRESSIVE_MODEL:
+ sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %12s %12s %12s", \
+ "Time", "CRC", "SRC", "DST", "DATA/ACK", "Length", "SeqNum", \
+ "Propagation","Slow Fading", "Fast Fading");
+ break;
+ case HIDDEN_MARKOV_ERROR_MODEL:
+ sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %8s", \
+ "Time", "CRC", "SRC", "DST", "DATA/ACK", "Length", "SeqNum", \
+ "State");
+ break;
+ case NIST_ERROR_RATE_MODEL:
+ sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %10s", \
+ "Time", "CRC", "SRC", "DST", "DATA/ACK", "Length", "SeqNum", "SNR (dB)");
+ break;
+ }
+
+ break;
+ default:
+ NS_LOG_ERROR("Cannot open a trace file because transport protocol is not correct");
+ }
+
+ m_file << title << endl;
+}
+
+void Experiment::CloseTraceFile()
+{
+ NS_LOG_FUNCTION_NOARGS();
+ if (m_file.is_open())
+ m_file.close();
+ else
+ NS_LOG_ERROR("Open file not found");
+}
+
+void Experiment::TraceToFile(string line)
+{
+ NS_LOG_DEBUG(line);
+ m_file << line << endl;
+}
+
+
+
+std::string getcwd() {
+ char buf[FILENAME_MAX];
+ char* succ = getcwd(buf, FILENAME_MAX);
+ if (succ)
+ return std::string(succ);
+ return ""; // raise a flag, throw an exception, ...
+}
+
+std::string ConvertMacToString(Mac48Address mac)
+{
+ NS_LOG_FUNCTION(mac);
+ u_int8_t temp[6];
+ char result[24];
+ mac.CopyTo(temp);
+
+ sprintf(result,"%02X:%02X:%02X:%02X:%02X:%02X", temp[0], temp[1], temp[2], temp[3], temp[4], temp[5] );
+
+ return std::string(result);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// MAIN ///////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+
+int main (int argc, char *argv[])
+{
+ //Logging
+ EnableLogging();
+
+
+ //Variable initialization
+ // Hidden Markov Model Coefficient file
+ string transitionFileHmm = "HMM_4states/HMM_03_TR_1.txt" ;
+ string emissionFileHmm = "HMM_4states/HMM_03_EMIS_1.txt" ;
+
+ string hmmChannel = "Good";
+
+ //BEAR model Coefficients file
+ string arModelCoefficientsFile = "coefsAR.cfg";
+
+ //Parameter to switch among the different channel models
+ string channelModel = "Bear";
+
+ //Transport protocol
+ string transportProtocol = "TCP";
+ TransportProtocol_t protocol;
+
+ //Random variable generation (Random seed)
+ SeedManager::SetSeed(1);
+
+ //Trace file name
+ u_int16_t scenario = 1; //Scenario number --> Used for trace file naming (see documentation to get the model particular parameters)
+ string outputChannelTypeFileName;
+ string outputFileName = "TCP";
+ ChannelMode_t enumChannelModel;
+
+ //Simulation parameters
+ float distance = 20; //Distance between nodes
+
+
+ u_int32_t numPackets = 10000;
+ u_int32_t packetLength = 1460;
+ uint64_t interPacketTime = 1000000;
+ u_int32_t run = 1;
+ u_int32_t runCounter;
+ u_int32_t runOffset = 0;
+
+ //Command parsing
+ CommandLine cmd;
+
+ //Error model parameters
+ cmd.AddValue ("ChannelModel", "Channel model to insert into the nodes", channelModel );
+ //BEAR model
+ cmd.AddValue ("ArModelCoefficientFile", "File name which contains the AR model coefficients", arModelCoefficientsFile);
+
+ //Hidden Markov Error Model parameters
+ cmd.AddValue ("HmmChannel", "Type of HMM channel: Good, Average or bad", hmmChannel);
+ cmd.AddValue ("TransitionFileHmm", "HMM transition file name (from configs file)", transitionFileHmm);
+ cmd.AddValue ("EmissionFileHmm", "HMM emission file name (from configs file)", emissionFileHmm);
+
+ //Simulation-related parameters
+ cmd.AddValue ("Run", "Number of simulations to run", run);
+ cmd.AddValue ("RunOffset", "Offset introduced at the SeedManager and the file naming counter", runOffset);
+ cmd.AddValue ("Scenario", "Type of analysis (channel model coefficients and conditions)", scenario);
+ cmd.AddValue ("NumPackets", "Total number of packets sent in the simulation", numPackets);
+ cmd.AddValue ("PacketLength", "Number of bytes in each packet", packetLength);
+ cmd.AddValue ("InterPacketTime", "Time (in microseconds) between two consecutive packets (application level)", interPacketTime);
+ cmd.AddValue ("OutputChannelTypeFileName", "File name to store the output trace", outputChannelTypeFileName);
+ cmd.AddValue ("Distance", "Distance (in meters) between nodes", distance);
+ cmd.AddValue ("TransportProtocol", "TCP or UDP" , transportProtocol);
+
+ cmd.Parse (argc, argv);
+
+ //Default attributes initialization
+ //Wifi attributes
+ Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",StringValue ("DsssRate2Mbps"));
+ // Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200")); //Disable RTS/CTS transmission
+ Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200")); //Disable fragmentation
+ Config::SetDefault ("ns3::ConstantRateWifiManager::DataMode", StringValue ("DsssRate11Mbps"));
+ Config::SetDefault ("ns3::ConstantRateWifiManager::ControlMode", StringValue ("DsssRate11Mbps")); //WiFi Buffer Size
+ Config::SetDefault ("ns3::WifiMacQueue::MaxPacketNumber", UintegerValue (900000000));
+ Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (4));
+ Config::SetDefault ("ns3::WifiNetDevice::Mtu", UintegerValue (1512));
+
+ //HiddenErrorMarkov model attributes
+ Config::SetDefault ("ns3::HiddenMarkovErrorModel::TransitionMatrixFileName", StringValue (transitionFileHmm));
+ Config::SetDefault ("ns3::HiddenMarkovErrorModel::EmissionMatrixFileName", StringValue (emissionFileHmm));
+
+ GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
+
+ if (transportProtocol == "TCP")
+ protocol = TCP_PROTOCOL;
+ else if (transportProtocol == "UDP")
+ protocol = UDP_PROTOCOL;
+ else
+ NS_LOG_ERROR("Transport Protocol undefined");
+
+ if (channelModel == "SWEEP")
+ distance = 72;
+
+ if ((scenario < 1) || (scenario > 6))
+ {
+ NS_LOG_ERROR("HMM configuration et not supported");
+ return -1;
+ }
+
+ /////////-----------------------MAIN LOOP-----------------------/////////
+
+ for (runCounter = 1; runCounter <= run; runCounter ++)
+ {
+ Experiment exp_;
+ exp_.SetTransportProtocol(protocol);
+ //Create the nodes
+ NodeContainer wifiNodes;
+ wifiNodes.Create(2);
+
+ //Prepare the Wifi NetDevices
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default(); //Don't remove (Necessary at YansWifiPhy::EndReceive)
+ YansWifiChannelHelper wifiChannel;
+
+ //Change the seed for each simulation run
+ SeedManager::SetRun(runCounter + runOffset);
+
+ //Channel model initialization
+ // BEAR model = ArModel (Propagation Loss Model) + BurstyErrorModel (Error Model)
+
+ if (channelModel == "Bear")
+ {
+ outputChannelTypeFileName = "Bear";
+ enumChannelModel = BURSTY_ERROR_AUTO_REGRESSIVE_MODEL;
+
+ //Set the propagation delay model
+ wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
+ //Set the propagation loss model
+ wifiChannel.AddPropagationLoss("ns3::ArModel");
+ Ptr<ArModel> arBaseModel = CreateObject<ArModel> ();
+ wifiChannel.AddPropagationLoss(arBaseModel);
+ //Set the error model
+ Ptr<BurstyErrorModel> errorModel = CreateObject<BurstyErrorModel> (); //Manual BEAR model instance
+ wifiPhy.SetErrorModel(errorModel);
+ arBaseModel->SetErrorModel(errorModel); // Bursty error model is closely linked to the AR propagation loss model
+
+ //Callback
+ errorModel->SetRxCallback (MakeCallback (&Experiment::BearRxTrace, &exp_));
+ }
+
+ // HiddenMarkovErrorModel --> Does not take into account the SNR, hence the propagation loss model is not relevant
+ else if (channelModel == "HMM")
+ {
+ //Prepare the coefficients files according to the channel type
+ if (hmmChannel == "Good")
+ {
+ sprintf((char *) transitionFileHmm.c_str(), "HMM_4states/HMM_12_TR_%1d.txt", scenario);
+ sprintf((char *) emissionFileHmm.c_str(), "HMM_4states/HMM_12_EMIS_%1d.txt", scenario);
+
+ }
+ else if (hmmChannel == "Average")
+ {
+ sprintf((char *) transitionFileHmm.c_str(), "HMM_4states/HMM_09_TR_%1d.txt", scenario);
+ sprintf((char *) emissionFileHmm.c_str(), "HMM_4states/HMM_09_EMIS_%1d.txt", scenario);
+ }
+ else if (hmmChannel == "Bad")
+ {
+ sprintf((char *) transitionFileHmm.c_str(), "HMM_4states/HMM_05_TR_%1d.txt", scenario);
+ sprintf((char *) emissionFileHmm.c_str(), "HMM_4states/HMM_05_EMIS_%1d.txt", scenario);
+ }
+ else
+ {
+ NS_LOG_UNCOND ("HMM Channel Model not valid... Exiting");
+ return -1;
+ }
+
+ outputChannelTypeFileName = "HMM_" + hmmChannel;
+ enumChannelModel = HIDDEN_MARKOV_ERROR_MODEL;
+
+ //Set the propagation delay model
+ wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ //Set the propagation loss model
+ wifiChannel.AddPropagationLoss ("ns3::SimplePropagationLossModel", "MaxDistance", DoubleValue(200.0));
+
+ //Set the error model
+ Ptr<HiddenMarkovErrorModel> errorModel = CreateObject<HiddenMarkovErrorModel> ();
+ errorModel->SetTransitionMatrixFileName(transitionFileHmm);
+ errorModel->SetEmissionMatrixFileName(emissionFileHmm);
+ errorModel->GetCoefficients();
+
+ wifiPhy.SetErrorModel(errorModel);
+
+ //Callback
+ errorModel->SetRxCallback(MakeCallback(&Experiment::HmmRxTrace, &exp_));
+ }
+
+ //NS-3 Legacy error decision model --> LogDistancePropagationLossModel + NistErrorRateModel
+ else if (channelModel == "NIST")
+ {
+ outputChannelTypeFileName = "NIST";
+ enumChannelModel = NIST_ERROR_RATE_MODEL;
+// distance = 89.6; //Distance value which FER yields approximately 0.5
+ distance = 80; //FER ~ 0.16
+
+ //Set the propagation delay model
+ wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
+ //Set the propagation loss model
+ wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel");
+ wifiChannel.AddPropagationLoss("ns3::RandomPropagationLossModel", "Variable", RandomVariableValue (NormalVariable (0.0, 2.8)));
+
+ wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel");
+ }
+
+ //Make a sweep in order to fully characterize the throughput vs FER curve shape in a memoryless channel
+ else if (channelModel == "SWEEP")
+ {
+ if ((int) runCounter % 5 == 0)
+ distance += 0.5 ;
+
+ outputChannelTypeFileName = "SWEEP";
+ enumChannelModel = NIST_ERROR_RATE_MODEL;
+ // distance = 89.6; //Distance value which FER yields approximately 0.5
+// distance = 80; //FER ~ 0.16
+
+ //Set the propagation delay model
+ wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
+ //Set the propagation loss model
+ wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel");
+// wifiChannel.AddPropagationLoss("ns3::RandomPropagationLossModel", "Variable", RandomVariableValue (NormalVariable (0.0, 2.8)));
+ wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel");
+
+ }
+
+ wifiPhy.SetChannel (wifiChannel.Create());
+ WifiHelper wifi = WifiHelper::Default();
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager");
+ NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default();
+
+ NetDeviceContainer wifiDevices = wifi.Install(wifiPhy, wifiMac, wifiNodes);
+
+ //Node mobility configuration
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
+ positionAlloc->Add(Vector(0.0, 0.0, 0.0));
+ positionAlloc->Add(Vector(distance, 0.0, 0.0));
+ mobility.SetPositionAllocator(positionAlloc);
+ mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
+ mobility.Install (wifiNodes);
+
+ //Set the upper layers (default configuration)
+ InternetStackHelper internet;
+
+ // Sysctl option configuration
+ if (transportProtocol == "TCP")
+ {
+ internet.SetTcp ("ns3::NscTcpL4Protocol","Library",StringValue ("liblinux2.6.26.so"));
+ Config::Set ("/NodeList/3/$ns3::Ns3NscStack<linux2.6.26>/net.inet.tcp.mssdflt", StringValue ("1460"));
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1460));
+ // Config::Set ("/NodeList/3/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_sack", StringValue ("0"));
+ // Config::Set ("/NodeList/3/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_timestamps", StringValue ("0"));
+ // Config::Set ("/NodeList/3/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_window_scaling", StringValue ("0"));
+
+ //TCP parameter set
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1460));
+ Config::SetDefault ("ns3::TcpSocket::RcvBufSize", UintegerValue (90000000));
+ Config::SetDefault ("ns3::TcpSocket::SndBufSize", UintegerValue (90000000));
+
+ outputFileName= "TCP";
+
+ // Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno"));
+ // Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpReno"));
+ }
+ else if (transportProtocol == "UDP")
+ {
+ outputFileName = "UDP";
+ Config::SetDefault ("ns3::UdpSocket::RcvBufSize", UintegerValue (90000000));
+ }
+
+ internet.Install (wifiNodes);
+
+ //New TCP simulation model (Application changes)
+ //Define IP level
+ Ipv4AddressHelper ipv4;
+ NS_LOG_INFO("Assign IP Addresses.");
+ ipv4.SetBase("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer ipInterfaceContainer = ipv4.Assign(wifiDevices);
+
+
+ uint16_t port = 50000; // Server Port
+
+ OnOffHelper onoff ("ns3::TcpSocketFactory", Address (InetSocketAddress (Ipv4Address ("10.1.1.1"), port))); //OnOffHelper instance
+
+ //If UDP-based simulation, establish UDP at the OnOffHelper object
+ if (transportProtocol == "UDP")
+ onoff.SetAttribute("Protocol", StringValue ("ns3::UdpSocketFactory"));
+
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+ onoff.SetAttribute ("DataRate", StringValue ("11Mbps"));
+ onoff.SetAttribute ("PacketSize", UintegerValue (packetLength));
+ onoff.SetAttribute ("MaxBytes", UintegerValue (packetLength * numPackets));
+ // onoff.SetAttribute ("Tx", MakeTraceSourceAccessor (&OnOffApplication::m_txTrace));
+
+ ApplicationContainer app = onoff.Install (wifiNodes.Get(1)); //install the onoff aplication in the AP node
+ // Start the application
+ app.Start (Seconds (1.0));
+ app.Stop (Seconds (10000.0));
+
+ // Create a packet sink to receive these packets in the Station node
+ PacketSinkHelper sink ("ns3::TcpSocketFactory", Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+ //If UDP-based simulation, establish UDP at the OnOffHelper object
+ if (transportProtocol == "UDP")
+ sink.SetAttribute("Protocol", StringValue("ns3::UdpSocketFactory"));
+
+
+
+ app = sink.Install (wifiNodes.Get(0));
+ app.Start (Seconds (0.0));
+ app.Stop (Seconds (11000.0));
+
+ //End new simulation scheme
+ ////////////////////
+
+ //Tracing connectors
+ if (enumChannelModel == NIST_ERROR_RATE_MODEL) //Frame reception tracing for
+ {
+ Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxOk", MakeCallback (&Experiment::PhyRxOkTrace, &exp_));
+ Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback (&Experiment::PhyRxErrorTrace, &exp_));
+ }
+
+ //Connect to the error models
+ wifiPhy.EnablePcap (outputChannelTypeFileName, wifiNodes, true);
+ wifiPhy.EnableAscii("Prueba", wifiNodes);
+
+
+ //TCP trace file
+ char temp[128];
+ sprintf(temp,"%s_%s_%02d_%03d.tr", outputFileName.c_str(), outputChannelTypeFileName.c_str(), scenario, runCounter + runOffset);
+ exp_.OpenTraceFile(temp, enumChannelModel);
+
+ Simulator::Stop(Seconds(11010));
+
+ Simulator::Run();
+ Simulator::Destroy();
+
+ //Print statistics
+ NS_LOG_UNCOND("Run " << runCounter + runOffset << " FER = " << exp_.GetPktsReceived() - exp_.GetPktsCorrect() << "/" \
+ << exp_.GetPktsReceived() << " = " << \
+ ((double) exp_.GetPktsReceived() - (double) exp_.GetPktsCorrect())/(double)exp_.GetPktsReceived());
+ exp_.CloseTraceFile();
+ }
+}
+
« no previous file with comments | « ns-3.13/src/ar-model/configs/coefsAR.cfg ('k') | ns-3.13/src/ar-model/model/ar-model.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b