OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2011 Universidad de Cantabria |
| 4 * |
| 5 * This program is free software; you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 2 as |
| 7 * published by the Free Software Foundation; |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software |
| 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 * |
| 18 * Author: David Gómez Fernández <dgomez@tlmat.unican.es> |
| 19 * Ramón Agüero Calvo <ramon@tlmat.unican.es> |
| 20 */ |
| 21 |
| 22 #include "ns3/core-module.h" |
| 23 #include "ns3/mobility-module.h" |
| 24 #include "ns3/applications-module.h" |
| 25 |
| 26 #include "ns3/wifi-helper.h" |
| 27 #include "ns3/yans-wifi-helper.h" |
| 28 #include "ns3/inet-socket-address.h" |
| 29 #include "ns3/internet-stack-helper.h" |
| 30 #include "ns3/ipv4-address-helper.h" |
| 31 #include "ns3/wifi-module.h" |
| 32 #include "ns3/propagation-loss-model.h" |
| 33 |
| 34 #include "ns3/aodv-routing-protocol.h" |
| 35 |
| 36 #include "ns3/ar-model.h" |
| 37 #include "ns3/hidden-markov-error-model.h" |
| 38 |
| 39 #include "ns3/socket.h" |
| 40 #include <ns3/node-list.h> |
| 41 |
| 42 #include "ns3/wifi-mac-header.h" |
| 43 #include "ns3/llc-snap-header.h" |
| 44 #include "ns3/ipv4-header.h" |
| 45 #include "ns3/tcp-header.h" |
| 46 #include "ns3/udp-header.h" |
| 47 |
| 48 #include <iostream> |
| 49 #include <fstream> |
| 50 #include <vector> |
| 51 #include <string> |
| 52 #include <stdio.h> |
| 53 |
| 54 #include "scratch-logging.h" |
| 55 //#include "experiment.h" |
| 56 |
| 57 NS_LOG_COMPONENT_DEFINE("TcpErrorModelTest"); |
| 58 |
| 59 using namespace std; |
| 60 using namespace ns3; |
| 61 |
| 62 std::string ConvertMacToString(Mac48Address mac); |
| 63 std::string getcwd(); |
| 64 |
| 65 enum ChannelMode_t { |
| 66 HIDDEN_MARKOV_ERROR_MODEL, |
| 67 BURSTY_ERROR_AUTO_REGRESSIVE_MODEL, |
| 68 NIST_ERROR_RATE_MODEL |
| 69 }; |
| 70 |
| 71 enum TransportProtocol_t { |
| 72 TCP_PROTOCOL, |
| 73 UDP_PROTOCOL |
| 74 }; |
| 75 |
| 76 class Experiment { |
| 77 public: |
| 78 Experiment (); |
| 79 ~Experiment (); |
| 80 |
| 81 u_int32_t GetPacketCounter() const; |
| 82 void SetPacketCounter(u_int32_t packetCounter); |
| 83 u_int32_t GetPktsCorrect() const; |
| 84 void SetPktsCorrect(u_int32_t pktsCorrect); |
| 85 u_int32_t GetPktsReceived() const; |
| 86 void SetPktsReceived(u_int32_t pktsReceived); |
| 87 u_int32_t GetPktsTransmitted () const; |
| 88 |
| 89 void SetTransportProtocol (TransportProtocol_t protocol); |
| 90 TransportProtocol_t GetTransportProtocol () const; |
| 91 |
| 92 Ptr<Socket> SetupPacketReceive(Ptr<Node> node); |
| 93 void GenerateTraffic(Ptr<Socket> socket, uint32_t pktSize, |
| 94 uint32_t pktCount, Time pktInterval); |
| 95 //Tracing |
| 96 void PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double
snr, WifiMode mode, enum WifiPreamble preamble); |
| 97 void PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, dou
ble snr); |
| 98 |
| 99 //BEAR Callback integration |
| 100 void HmmRxTrace (Ptr<Packet> packet, Time timestamp, bool error, u_int16
_t state); |
| 101 void BearRxTrace (Ptr<Packet> packet, Time timestamp, bool error, double
propagation, double slowFading, double fastFading); |
| 102 |
| 103 //Upper Layer parser |
| 104 packetInfo_t ParsePacket (Ptr<const Packet> packet); |
| 105 |
| 106 void OpenTraceFile (string fileName, ChannelMode_t channelModel); |
| 107 void CloseTraceFile (); |
| 108 |
| 109 void TraceToFile (string line); |
| 110 |
| 111 |
| 112 private: |
| 113 fstream m_file; |
| 114 |
| 115 void ReceivePacket(Ptr<Socket> socket); |
| 116 void SetPosition(Ptr<Node> node, Vector position); |
| 117 Vector GetPosition(Ptr<Node> node); |
| 118 u_int32_t m_pktsReceived; |
| 119 u_int32_t m_pktsCorrect; |
| 120 u_int32_t m_packetCounter; |
| 121 |
| 122 u_int32_t m_packetsTransmitted; |
| 123 |
| 124 TransportProtocol_t m_protocol; |
| 125 }; |
| 126 |
| 127 |
| 128 Experiment::Experiment(): m_pktsReceived (0), |
| 129 m_pktsCorrect (0), |
| 130 m_packetCounter (0), |
| 131 m_packetsTransmitted (0) |
| 132 {} |
| 133 |
| 134 Experiment::~Experiment() |
| 135 {} |
| 136 |
| 137 |
| 138 void Experiment::SetPosition(Ptr<Node> node, Vector position) { |
| 139 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>(); |
| 140 mobility->SetPosition(position); |
| 141 } |
| 142 Vector Experiment::GetPosition(Ptr<Node> node) { |
| 143 Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>(); |
| 144 return mobility->GetPosition(); |
| 145 } |
| 146 void Experiment::ReceivePacket(Ptr<Socket> socket) { |
| 147 Ptr<Packet> packet; |
| 148 while (packet = socket->Recv()) { |
| 149 // m_pktsReceived++; |
| 150 } |
| 151 } |
| 152 |
| 153 Ptr<Socket> Experiment::SetupPacketReceive(Ptr<Node> node) { |
| 154 |
| 155 TypeId tid = TypeId::LookupByName("ns3::TcpSocketFactory"); |
| 156 |
| 157 if (m_protocol == UDP_PROTOCOL) |
| 158 tid = TypeId::LookupByName("ns3::UdpSocketFactory"); |
| 159 Ptr<Socket> sink = Socket::CreateSocket(node, tid); |
| 160 InetSocketAddress local = InetSocketAddress(Ipv4Address::GetAny(), 80); |
| 161 sink->Bind(local); |
| 162 sink->SetRecvCallback(MakeCallback(&Experiment::ReceivePacket, this)); |
| 163 return sink; |
| 164 } |
| 165 void Experiment::GenerateTraffic(Ptr<Socket> socket, uint32_t pktSize, |
| 166 uint32_t pktCount, Time pktInterval) { |
| 167 m_packetCounter --; |
| 168 if (m_packetCounter > 0) { |
| 169 socket->Send(Create<Packet>(pktSize)); |
| 170 Simulator::Schedule(pktInterval, &Experiment::GenerateTraffic, t
his, |
| 171 socket, pktSize, pktCount - 1, pktInterval); |
| 172 } else { |
| 173 socket->Close(); |
| 174 } |
| 175 m_packetsTransmitted ++; |
| 176 } |
| 177 |
| 178 u_int32_t Experiment::GetPacketCounter () const |
| 179 { |
| 180 return m_packetCounter; |
| 181 } |
| 182 |
| 183 void Experiment::SetPacketCounter (u_int32_t packetCounter) |
| 184 { |
| 185 this->m_packetCounter = packetCounter; |
| 186 } |
| 187 |
| 188 u_int32_t Experiment::GetPktsCorrect () const |
| 189 { |
| 190 return m_pktsCorrect; |
| 191 } |
| 192 |
| 193 void Experiment::SetPktsCorrect (u_int32_t pktsCorrect) |
| 194 { |
| 195 this->m_pktsCorrect = pktsCorrect; |
| 196 } |
| 197 |
| 198 u_int32_t Experiment::GetPktsReceived () const |
| 199 { |
| 200 return m_pktsReceived; |
| 201 } |
| 202 |
| 203 void Experiment::SetPktsReceived(u_int32_t pktsReceived) |
| 204 { |
| 205 this->m_pktsReceived = pktsReceived; |
| 206 } |
| 207 |
| 208 u_int32_t Experiment::GetPktsTransmitted() const |
| 209 { |
| 210 return m_packetsTransmitted; |
| 211 } |
| 212 |
| 213 void Experiment::SetTransportProtocol(TransportProtocol_t protocol) |
| 214 { |
| 215 m_protocol = protocol; |
| 216 } |
| 217 |
| 218 TransportProtocol_t Experiment::GetTransportProtocol () const |
| 219 { |
| 220 return m_protocol; |
| 221 } |
| 222 |
| 223 //// Trace data frames and their corresponding ACKs |
| 224 |
| 225 void Experiment::PhyRxOkTrace(std::string context, Ptr<const Packet> packet, dou
ble snr, WifiMode mode, enum WifiPreamble preamble) |
| 226 { |
| 227 |
| 228 /////////////////////////////////////////////////////// |
| 229 NS_LOG_FUNCTION_NOARGS(); |
| 230 WifiMacHeader hdr; |
| 231 packetInfo_t packetInfo; |
| 232 char line [255]; |
| 233 bool dataOrAck; |
| 234 |
| 235 //Ip addresses variables needed for Ipv4Address to String conversion |
| 236 u_int8_t source [4]; |
| 237 u_int8_t destination [4]; |
| 238 char sourceChar [32]; |
| 239 char destChar [32]; |
| 240 |
| 241 packet->PeekHeader (hdr); //Don't forget to uncomment |
| 242 packetInfo = ParsePacket(packet); |
| 243 |
| 244 switch (packetInfo.type) |
| 245 { |
| 246 case TCP_DATA: |
| 247 if (m_protocol == TCP_PROTOCOL) |
| 248 { |
| 249 m_pktsCorrect ++; |
| 250 m_pktsReceived ++; |
| 251 |
| 252 //Get the MAC and IP Addresses |
| 253 packetInfo.ipv4Hdr.GetSource().Serialize(source);
//Get a string from Ipv4Address |
| 254 packetInfo.ipv4Hdr.GetDestination().Serialize(destinatio
n); |
| 255 sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1],
source[2], source[3]); |
| 256 sprintf(destChar, "%d.%d.%d.%d", destination[0], destina
tion[1], destination[2], destination[3]); |
| 257 |
| 258 sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d
%16d %16f", \ |
| 259 Simulator::Now().GetSeconds(), true, sou
rceChar, \ |
| 260 destChar, packetInfo.wifiHdr.IsRetry(),
\ |
| 261 packetInfo.payloadLength,
\ |
| 262 packetInfo.wifiHdr.GetSequenceNumber(),
\ |
| 263 packetInfo.tcpHdr.GetSequenceNumber().Ge
tValue(), \ |
| 264 packetInfo.tcpHdr.GetAckNumber().GetValu
e(), \ |
| 265 snr); |
| 266 TraceToFile(line); |
| 267 } |
| 268 break; |
| 269 case UDP_DATA: |
| 270 if (m_protocol == UDP_PROTOCOL) |
| 271 { |
| 272 //Distinguish between data or ACK |
| 273 if (hdr.IsData()) |
| 274 dataOrAck = false; |
| 275 else if (hdr.IsAck()) |
| 276 dataOrAck = true; |
| 277 |
| 278 sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %10f",
\ |
| 279 Simulator::Now().GetSeconds(),
\ |
| 280 true,
\ |
| 281 ConvertMacToString(hdr.GetAddr2()).c_str
(), \ |
| 282 ConvertMacToString(hdr.GetAddr1()).c_str
(), \ |
| 283 dataOrAck ? "ACK" : "DATA",
\ |
| 284 packet->GetSize(),
\ |
| 285 hdr.GetSequenceNumber(),
\ |
| 286 snr); |
| 287 m_pktsCorrect ++; |
| 288 m_pktsReceived ++; |
| 289 |
| 290 TraceToFile(line); |
| 291 } |
| 292 break; |
| 293 default: |
| 294 NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type); |
| 295 break; |
| 296 } |
| 297 |
| 298 |
| 299 //////////////////////////////////// |
| 300 |
| 301 } |
| 302 |
| 303 void Experiment::PhyRxErrorTrace (std::string context, Ptr<const Packet> packet,
double snr) |
| 304 { |
| 305 /////////////////////////////////////////////////////// |
| 306 NS_LOG_FUNCTION_NOARGS(); |
| 307 WifiMacHeader hdr; |
| 308 packetInfo_t packetInfo; |
| 309 char line [255]; |
| 310 bool dataOrAck; |
| 311 |
| 312 //Ip addresses variables needed for Ipv4Address to String conversion |
| 313 u_int8_t source [4]; |
| 314 u_int8_t destination [4]; |
| 315 char sourceChar [32]; |
| 316 char destChar [32]; |
| 317 |
| 318 packet->PeekHeader (hdr); //Don't forget to uncomment |
| 319 packetInfo = ParsePacket(packet); |
| 320 |
| 321 switch (packetInfo.type) |
| 322 { |
| 323 case TCP_DATA: |
| 324 if (m_protocol == TCP_PROTOCOL) |
| 325 { |
| 326 m_pktsReceived ++; |
| 327 |
| 328 //Get the MAC and IP Addresses |
| 329 packetInfo.ipv4Hdr.GetSource().Serialize(source);
//Get a string from Ipv4Address |
| 330 packetInfo.ipv4Hdr.GetDestination().Serialize(destinatio
n); |
| 331 sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1],
source[2], source[3]); |
| 332 sprintf(destChar, "%d.%d.%d.%d", destination[0], destina
tion[1], destination[2], destination[3]); |
| 333 |
| 334 sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d
%16d %16f", \ |
| 335 Simulator::Now().GetSeconds(), false, so
urceChar, \ |
| 336 destChar, packetInfo.wifiHdr.IsRetry(),
\ |
| 337 packetInfo.payloadLength,
\ |
| 338 packetInfo.wifiHdr.GetSequenceNumber(),
\ |
| 339 packetInfo.tcpHdr.GetSequenceNumber().Ge
tValue(), \ |
| 340 packetInfo.tcpHdr.GetAckNumber().GetValu
e(), \ |
| 341 snr); |
| 342 TraceToFile(line); |
| 343 } |
| 344 |
| 345 break; |
| 346 case UDP_DATA: |
| 347 if (m_protocol == UDP_PROTOCOL) |
| 348 { |
| 349 //Distinguish between data or ACK |
| 350 if (hdr.IsData()) |
| 351 dataOrAck = false; |
| 352 else if (hdr.IsAck()) |
| 353 dataOrAck = true; |
| 354 |
| 355 sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %10f",
\ |
| 356 Simulator::Now().GetSeconds(),
\ |
| 357 false,
\ |
| 358 ConvertMacToString(hdr.GetAddr2()).c_str(),
\ |
| 359 ConvertMacToString(hdr.GetAddr1()).c_str(),
\ |
| 360 dataOrAck ? "ACK" : "DATA",
\ |
| 361 packet->GetSize(),
\ |
| 362 hdr.GetSequenceNumber(),
\ |
| 363 snr); |
| 364 m_pktsReceived ++; |
| 365 TraceToFile(line); |
| 366 |
| 367 } |
| 368 break; |
| 369 default: |
| 370 NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type); |
| 371 break; |
| 372 } |
| 373 |
| 374 |
| 375 //////////////////////////////////// |
| 376 |
| 377 } |
| 378 |
| 379 packetInfo_t Experiment::ParsePacket (Ptr<const Packet> packet) |
| 380 { |
| 381 NS_LOG_FUNCTION(packet); |
| 382 |
| 383 packetInfo_t packetInfo; |
| 384 Ptr<Packet> pktCopy = packet->Copy(); |
| 385 |
| 386 pktCopy->RemoveHeader(packetInfo.wifiHdr); |
| 387 |
| 388 if (packetInfo.wifiHdr.IsData()) |
| 389 { |
| 390 pktCopy->RemoveHeader(packetInfo.llcHdr); |
| 391 switch (packetInfo.llcHdr.GetType()) |
| 392 { |
| 393 case 0x0806: //ARP |
| 394 packetInfo.type = ARP_PACKET; |
| 395 break; |
| 396 case 0x0800: //IP packet |
| 397 pktCopy->RemoveHeader(packetInfo.ipv4Hdr); |
| 398 switch (packetInfo.ipv4Hdr.GetProtocol()) |
| 399 { |
| 400 case 6: //TCP |
| 401 pktCopy->RemoveHeader(packetInfo.tcpHdr); |
| 402 packetInfo.type = TCP_DATA; |
| 403 |
| 404 break; |
| 405 case 17: //UDP |
| 406 pktCopy->RemoveHeader(packetInfo.udpHdr); |
| 407 packetInfo.type = UDP_DATA; |
| 408 break; |
| 409 default: |
| 410 NS_LOG_ERROR ("Protocol not implemented yet (IP)
--> " << packetInfo.llcHdr.GetType()); |
| 411 break; |
| 412 } |
| 413 break; |
| 414 default: |
| 415 NS_LOG_ERROR ("Protocol not implemented yet (LLC) --> "
<< packetInfo.llcHdr.GetType()); |
| 416 break; |
| 417 } |
| 418 } |
| 419 else if (packetInfo.wifiHdr.IsAck()) |
| 420 { |
| 421 packetInfo.type = IEEE_80211_ACK; |
| 422 } |
| 423 else // 802.11 Control/Management frame |
| 424 { |
| 425 packetInfo.type = IEEE_80211_NODATA; |
| 426 } |
| 427 |
| 428 packetInfo.payloadLength = pktCopy->GetSize() - 4;
//Last four bytes are used for tagging |
| 429 |
| 430 return packetInfo; |
| 431 } |
| 432 |
| 433 void Experiment::BearRxTrace(Ptr<Packet> packet, Time timestamp, bool error, dou
ble propagation, double slowFading, double fastFading) |
| 434 { |
| 435 NS_LOG_FUNCTION_NOARGS(); |
| 436 WifiMacHeader hdr; |
| 437 packetInfo_t packetInfo; |
| 438 char line [255]; |
| 439 bool dataOrAck; //Value used for UDP tracing |
| 440 |
| 441 //Ip addresses variables needed for Ipv4Address to String conversion |
| 442 u_int8_t source [4]; |
| 443 u_int8_t destination [4]; |
| 444 char sourceChar [32]; |
| 445 char destChar [32]; |
| 446 |
| 447 packet->PeekHeader (hdr); //Don't forget to uncomment |
| 448 packetInfo = ParsePacket(packet); |
| 449 |
| 450 switch (packetInfo.type) |
| 451 { |
| 452 |
| 453 case TCP_DATA: |
| 454 if (m_protocol == TCP_PROTOCOL) |
| 455 { |
| 456 if (error == 0) |
| 457 { |
| 458 m_pktsCorrect ++; |
| 459 m_pktsReceived ++; |
| 460 } |
| 461 else |
| 462 { |
| 463 m_pktsReceived ++; |
| 464 } |
| 465 |
| 466 //Get the MAC and IP Addresses |
| 467 packetInfo.ipv4Hdr.GetSource().Serialize(source);
//Get a string from Ipv4Address |
| 468 packetInfo.ipv4Hdr.GetDestination().Serialize(destinatio
n); |
| 469 sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1],
source[2], source[3]); |
| 470 sprintf(destChar, "%d.%d.%d.%d", destination[0], destina
tion[1], destination[2], destination[3]); |
| 471 |
| 472 sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d
%16d %16f", \ |
| 473 Simulator::Now().GetSeconds(), !error, s
ourceChar, \ |
| 474 destChar, packetInfo.wifiHdr.IsRetry(),
\ |
| 475 packetInfo.payloadLength,
\ |
| 476 packetInfo.wifiHdr.GetSequenceNumber(),
\ |
| 477 packetInfo.tcpHdr.GetSequenceNumber().Ge
tValue(), \ |
| 478 packetInfo.tcpHdr.GetAckNumber().GetValu
e(), \ |
| 479 propagation + slowFading + fastFading); |
| 480 |
| 481 TraceToFile(line); |
| 482 } |
| 483 break; |
| 484 case UDP_DATA: |
| 485 if (m_protocol == UDP_PROTOCOL) |
| 486 { |
| 487 if (error == 0) |
| 488 { |
| 489 m_pktsCorrect ++; |
| 490 m_pktsReceived ++; |
| 491 } |
| 492 else |
| 493 { |
| 494 m_pktsReceived ++; |
| 495 } |
| 496 //Distinguish between data or ACK |
| 497 if (hdr.IsData()) |
| 498 dataOrAck = false; |
| 499 else if (hdr.IsAck()) // |
| 500 dataOrAck = true; |
| 501 |
| 502 sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %12f %12
f %12f", \ |
| 503 timestamp.GetSeconds(),
\ |
| 504 !error,
\ |
| 505 ConvertMacToString(hdr.GetAddr2()).c_str
(), \ |
| 506 ConvertMacToString(hdr.GetAddr1()).c_str
(), \ |
| 507 dataOrAck ? "ACK" : "DATA",
\ |
| 508 packet->GetSize(),
\ |
| 509 hdr.GetSequenceNumber(),
\ |
| 510 propagation,
\ |
| 511 slowFading,
\ |
| 512 fastFading
\ |
| 513 ); |
| 514 TraceToFile(line); |
| 515 } |
| 516 break; |
| 517 default: |
| 518 NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type); |
| 519 break; |
| 520 } |
| 521 |
| 522 |
| 523 |
| 524 } |
| 525 |
| 526 void Experiment::HmmRxTrace(Ptr<Packet> packet, Time timestamp, bool error, u_in
t16_t state) |
| 527 { |
| 528 NS_LOG_FUNCTION_NOARGS(); |
| 529 WifiMacHeader hdr; |
| 530 packetInfo_t packetInfo; |
| 531 char line [255]; |
| 532 bool dataOrAck; //Value used for UDP tracing |
| 533 |
| 534 //Ip addresses variables needed for Ipv4Address to String conversion |
| 535 u_int8_t source [4]; |
| 536 u_int8_t destination [4]; |
| 537 char sourceChar [32]; |
| 538 char destChar [32]; |
| 539 |
| 540 packet->PeekHeader (hdr); //Don't forget to uncomment |
| 541 packetInfo = ParsePacket(packet); |
| 542 |
| 543 switch (packetInfo.type) |
| 544 { |
| 545 case TCP_DATA: |
| 546 if (m_protocol == TCP_PROTOCOL) |
| 547 { |
| 548 if (error == 0) |
| 549 { |
| 550 m_pktsCorrect ++; |
| 551 m_pktsReceived ++; |
| 552 } |
| 553 else |
| 554 { |
| 555 m_pktsReceived ++; |
| 556 } |
| 557 |
| 558 //Get the MAC and IP Addresses |
| 559 packetInfo.ipv4Hdr.GetSource().Serialize(source);
//Get a string from Ipv4Address |
| 560 packetInfo.ipv4Hdr.GetDestination().Serialize(destinatio
n); |
| 561 sprintf(sourceChar, "%d.%d.%d.%d", source[0], source[1],
source[2], source[3]); |
| 562 sprintf(destChar, "%d.%d.%d.%d", destination[0], destina
tion[1], destination[2], destination[3]); |
| 563 |
| 564 sprintf (line, "%16f %16d %20s %20s %16d %16d %16d %16d
%16d %16d", \ |
| 565 Simulator::Now().GetSeconds(), !error, s
ourceChar, \ |
| 566 destChar, packetInfo.wifiHdr.IsRetry(),
\ |
| 567 packetInfo.payloadLength,
\ |
| 568 packetInfo.wifiHdr.GetSequenceNumber(),
\ |
| 569 packetInfo.tcpHdr.GetSequenceNumber().Ge
tValue(), \ |
| 570 packetInfo.tcpHdr.GetAckNumber().GetValu
e(), \ |
| 571 state); |
| 572 TraceToFile(line); |
| 573 } |
| 574 break; |
| 575 case UDP_DATA: |
| 576 if (m_protocol == UDP_PROTOCOL) |
| 577 { |
| 578 if (error == 0) |
| 579 { |
| 580 m_pktsCorrect ++; |
| 581 m_pktsReceived ++; |
| 582 } |
| 583 else |
| 584 { |
| 585 m_pktsReceived ++; |
| 586 } |
| 587 //Distinguish between data or ACK |
| 588 if (hdr.IsData()) |
| 589 dataOrAck = false; |
| 590 else if (hdr.IsAck()) |
| 591 dataOrAck = true; |
| 592 sprintf(line, "%10f %10d %20s %20s %10s %8d %8d %8d",
\ |
| 593 timestamp.GetSeconds(),
\ |
| 594 !error,
\ |
| 595 ConvertMacToString(hdr.GetAddr2()).c_str
(), \ |
| 596 ConvertMacToString(hdr.GetAddr1()).c_str
(), \ |
| 597 dataOrAck ? "ACK" : "DATA",
\ |
| 598 packet->GetSize(),
\ |
| 599 hdr.GetSequenceNumber(),
\ |
| 600 state); |
| 601 TraceToFile(line); |
| 602 } |
| 603 break; |
| 604 default: |
| 605 NS_LOG_ERROR("Unknown packet type --> " << packetInfo.type); |
| 606 break; |
| 607 } |
| 608 |
| 609 |
| 610 } |
| 611 |
| 612 |
| 613 void Experiment::OpenTraceFile (string fileName, ChannelMode_t channelModel = B
URSTY_ERROR_AUTO_REGRESSIVE_MODEL) |
| 614 { |
| 615 string path = getcwd() + "/traces/" + fileName; |
| 616 char title [255]; |
| 617 string lastField; //Channel Model
Dependent field (trace field) |
| 618 NS_LOG_DEBUG(path); |
| 619 m_file.open(path.c_str(), fstream::out); |
| 620 |
| 621 //Split into TCP and UDP simulations |
| 622 switch (m_protocol) |
| 623 { |
| 624 case TCP_PROTOCOL: |
| 625 if (channelModel == HIDDEN_MARKOV_ERROR_MODEL) |
| 626 lastField = "State"; |
| 627 else |
| 628 lastField = "SNR (dB)"; |
| 629 |
| 630 sprintf (title, "%16s %16s %20s %20s %16s %16s %16s %16s %16s %1
6s", \ |
| 631 "Time", "CRC", "Source", "Destination", "802.11
RETX", \ |
| 632 "Length","SeqNum", "TCP SeqNum", "TCP AckNum",
\ |
| 633 lastField.c_str()); |
| 634 break; |
| 635 |
| 636 case UDP_PROTOCOL: |
| 637 switch (channelModel) |
| 638 { |
| 639 case BURSTY_ERROR_AUTO_REGRESSIVE_MODEL: |
| 640 sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %12s %1
2s %12s", \ |
| 641 "Time", "CRC", "SRC", "DST", "DATA/ACK",
"Length", "SeqNum", \ |
| 642 "Propagation","Slow Fading", "Fast Fadin
g"); |
| 643 break; |
| 644 case HIDDEN_MARKOV_ERROR_MODEL: |
| 645 sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %8s",
\ |
| 646 "Time", "CRC", "SRC", "DST", "DATA/ACK",
"Length", "SeqNum", \ |
| 647 "State"); |
| 648 break; |
| 649 case NIST_ERROR_RATE_MODEL: |
| 650 sprintf(title, "%10s %10s %20s %20s %10s %8s %8s %10s",
\ |
| 651 "Time", "CRC", "SRC", "DST", "DATA/ACK",
"Length", "SeqNum", "SNR (dB)"); |
| 652 break; |
| 653 } |
| 654 |
| 655 break; |
| 656 default: |
| 657 NS_LOG_ERROR("Cannot open a trace file because transport protoco
l is not correct"); |
| 658 } |
| 659 |
| 660 m_file << title << endl; |
| 661 } |
| 662 |
| 663 void Experiment::CloseTraceFile() |
| 664 { |
| 665 NS_LOG_FUNCTION_NOARGS(); |
| 666 if (m_file.is_open()) |
| 667 m_file.close(); |
| 668 else |
| 669 NS_LOG_ERROR("Open file not found"); |
| 670 } |
| 671 |
| 672 void Experiment::TraceToFile(string line) |
| 673 { |
| 674 NS_LOG_DEBUG(line); |
| 675 m_file << line << endl; |
| 676 } |
| 677 |
| 678 |
| 679 |
| 680 std::string getcwd() { |
| 681 char buf[FILENAME_MAX]; |
| 682 char* succ = getcwd(buf, FILENAME_MAX); |
| 683 if (succ) |
| 684 return std::string(succ); |
| 685 return ""; // raise a flag, throw an exception, ... |
| 686 } |
| 687 |
| 688 std::string ConvertMacToString(Mac48Address mac) |
| 689 { |
| 690 NS_LOG_FUNCTION(mac); |
| 691 u_int8_t temp[6]; |
| 692 char result[24]; |
| 693 mac.CopyTo(temp); |
| 694 |
| 695 sprintf(result,"%02X:%02X:%02X:%02X:%02X:%02X", temp[0], temp[1], temp[2
], temp[3], temp[4], temp[5] ); |
| 696 |
| 697 return std::string(result); |
| 698 } |
| 699 |
| 700 ////////////////////////////////////////////////////////////////////////////////
//// |
| 701 /////////////////////////////// MAIN ///////////////////////////////////
//// |
| 702 ////////////////////////////////////////////////////////////////////////////////
//// |
| 703 |
| 704 int main (int argc, char *argv[]) |
| 705 { |
| 706 //Logging |
| 707 EnableLogging(); |
| 708 |
| 709 |
| 710 //Variable initialization |
| 711 // Hidden Markov Model Coefficient file |
| 712 string transitionFileHmm = "HMM_4states/HMM_03_TR_1.txt" ; |
| 713 string emissionFileHmm = "HMM_4states/HMM_03_EMIS_1.txt" ; |
| 714 |
| 715 string hmmChannel = "Good"; |
| 716 |
| 717 //BEAR model Coefficients file |
| 718 string arModelCoefficientsFile = "coefsAR.cfg"; |
| 719 |
| 720 //Parameter to switch among the different channel models |
| 721 string channelModel = "Bear"; |
| 722 |
| 723 //Transport protocol |
| 724 string transportProtocol = "TCP"; |
| 725 TransportProtocol_t protocol; |
| 726 |
| 727 //Random variable generation (Random seed) |
| 728 SeedManager::SetSeed(1); |
| 729 |
| 730 //Trace file name |
| 731 u_int16_t scenario = 1; //Scenario number --> Us
ed for trace file naming (see documentation to get the model particular paramete
rs) |
| 732 string outputChannelTypeFileName; |
| 733 string outputFileName = "TCP"; |
| 734 ChannelMode_t enumChannelModel; |
| 735 |
| 736 //Simulation parameters |
| 737 float distance = 20; //Distance between nodes |
| 738 |
| 739 |
| 740 u_int32_t numPackets = 10000; |
| 741 u_int32_t packetLength = 1460; |
| 742 uint64_t interPacketTime = 1000000; |
| 743 u_int32_t run = 1; |
| 744 u_int32_t runCounter; |
| 745 u_int32_t runOffset = 0; |
| 746 |
| 747 //Command parsing |
| 748 CommandLine cmd; |
| 749 |
| 750 //Error model parameters |
| 751 cmd.AddValue ("ChannelModel", "Channel model to insert into the nodes",
channelModel ); |
| 752 //BEAR model |
| 753 cmd.AddValue ("ArModelCoefficientFile", "File name which contains the AR
model coefficients", arModelCoefficientsFile); |
| 754 |
| 755 //Hidden Markov Error Model parameters |
| 756 cmd.AddValue ("HmmChannel", "Type of HMM channel: Good, Average or bad",
hmmChannel); |
| 757 cmd.AddValue ("TransitionFileHmm", "HMM transition file name (from confi
gs file)", transitionFileHmm); |
| 758 cmd.AddValue ("EmissionFileHmm", "HMM emission file name (from configs f
ile)", emissionFileHmm); |
| 759 |
| 760 //Simulation-related parameters |
| 761 cmd.AddValue ("Run", "Number of simulations to run", run); |
| 762 cmd.AddValue ("RunOffset", "Offset introduced at the SeedManager and the
file naming counter", runOffset); |
| 763 cmd.AddValue ("Scenario", "Type of analysis (channel model coefficients
and conditions)", scenario); |
| 764 cmd.AddValue ("NumPackets", "Total number of packets sent in the simulat
ion", numPackets); |
| 765 cmd.AddValue ("PacketLength", "Number of bytes in each packet", packetLe
ngth); |
| 766 cmd.AddValue ("InterPacketTime", "Time (in microseconds) between two con
secutive packets (application level)", interPacketTime); |
| 767 cmd.AddValue ("OutputChannelTypeFileName", "File name to store the outpu
t trace", outputChannelTypeFileName); |
| 768 cmd.AddValue ("Distance", "Distance (in meters) between nodes", distance
); |
| 769 cmd.AddValue ("TransportProtocol", "TCP or UDP" , transportProtocol); |
| 770 |
| 771 cmd.Parse (argc, argv); |
| 772 |
| 773 //Default attributes initialization |
| 774 //Wifi attributes |
| 775 Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",Stri
ngValue ("DsssRate2Mbps")); |
| 776 // Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
StringValue ("2200")); //Disable RTS/CTS transmission |
| 777 Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThresho
ld", StringValue ("2200")); //Disable fragmentation |
| 778 Config::SetDefault ("ns3::ConstantRateWifiManager::DataMode", StringValu
e ("DsssRate11Mbps")); |
| 779 Config::SetDefault ("ns3::ConstantRateWifiManager::ControlMode", StringV
alue ("DsssRate11Mbps")); //WiFi Buffer Size |
| 780 Config::SetDefault ("ns3::WifiMacQueue::MaxPacketNumber", UintegerValue
(900000000)); |
| 781 Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerVa
lue (4)); |
| 782 Config::SetDefault ("ns3::WifiNetDevice::Mtu", UintegerValue (1512)); |
| 783 |
| 784 //HiddenErrorMarkov model attributes |
| 785 Config::SetDefault ("ns3::HiddenMarkovErrorModel::TransitionMatrixFileNa
me", StringValue (transitionFileHmm)); |
| 786 Config::SetDefault ("ns3::HiddenMarkovErrorModel::EmissionMatrixFileName
", StringValue (emissionFileHmm)); |
| 787 |
| 788 GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); |
| 789 |
| 790 if (transportProtocol == "TCP") |
| 791 protocol = TCP_PROTOCOL; |
| 792 else if (transportProtocol == "UDP") |
| 793 protocol = UDP_PROTOCOL; |
| 794 else |
| 795 NS_LOG_ERROR("Transport Protocol undefined"); |
| 796 |
| 797 if (channelModel == "SWEEP") |
| 798 distance = 72; |
| 799 |
| 800 if ((scenario < 1) || (scenario > 6)) |
| 801 { |
| 802 NS_LOG_ERROR("HMM configuration et not supported"); |
| 803 return -1; |
| 804 } |
| 805 |
| 806 /////////-----------------------MAIN LOOP-----------------------////////
/ |
| 807 |
| 808 for (runCounter = 1; runCounter <= run; runCounter ++) |
| 809 { |
| 810 Experiment exp_; |
| 811 exp_.SetTransportProtocol(protocol); |
| 812 //Create the nodes |
| 813 NodeContainer wifiNodes; |
| 814 wifiNodes.Create(2); |
| 815 |
| 816 //Prepare the Wifi NetDevices |
| 817 YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default();
//Don't remove (Necessary at YansWifiPhy::EndReceive) |
| 818 YansWifiChannelHelper wifiChannel; |
| 819 |
| 820 //Change the seed for each simulation run |
| 821 SeedManager::SetRun(runCounter + runOffset); |
| 822 |
| 823 //Channel model initialization |
| 824 // BEAR model = ArModel (Propagation Loss Model) + BurstyErrorMo
del (Error Model) |
| 825 |
| 826 if (channelModel == "Bear") |
| 827 { |
| 828 outputChannelTypeFileName = "Bear"; |
| 829 enumChannelModel = BURSTY_ERROR_AUTO_REGRESSIVE_MODEL; |
| 830 |
| 831 //Set the propagation delay model |
| 832 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropa
gationDelayModel"); |
| 833 //Set the propagation loss model |
| 834 wifiChannel.AddPropagationLoss("ns3::ArModel"); |
| 835 Ptr<ArModel> arBaseModel = CreateObject<ArModel> (); |
| 836 wifiChannel.AddPropagationLoss(arBaseModel); |
| 837 //Set the error model |
| 838 Ptr<BurstyErrorModel> errorModel = CreateObject<BurstyEr
rorModel> (); //Manual BEAR model instance |
| 839 wifiPhy.SetErrorModel(errorModel); |
| 840 arBaseModel->SetErrorModel(errorModel);
// Bursty error model is closely linked to the AR propagation loss model |
| 841 |
| 842 //Callback |
| 843 errorModel->SetRxCallback (MakeCallback (&Experiment::Be
arRxTrace, &exp_)); |
| 844 } |
| 845 |
| 846 // HiddenMarkovErrorModel --> Does not take into account the SNR
, hence the propagation loss model is not relevant |
| 847 else if (channelModel == "HMM") |
| 848 { |
| 849 //Prepare the coefficients files according to the channe
l type |
| 850 if (hmmChannel == "Good") |
| 851 { |
| 852 sprintf((char *) transitionFileHmm.c_str(), "HMM
_4states/HMM_12_TR_%1d.txt", scenario); |
| 853 sprintf((char *) emissionFileHmm.c_str(), "HMM_4
states/HMM_12_EMIS_%1d.txt", scenario); |
| 854 |
| 855 } |
| 856 else if (hmmChannel == "Average") |
| 857 { |
| 858 sprintf((char *) transitionFileHmm.c_str(), "HMM
_4states/HMM_09_TR_%1d.txt", scenario); |
| 859 sprintf((char *) emissionFileHmm.c_str(), "HMM_4
states/HMM_09_EMIS_%1d.txt", scenario); |
| 860 } |
| 861 else if (hmmChannel == "Bad") |
| 862 { |
| 863 sprintf((char *) transitionFileHmm.c_str(), "HMM
_4states/HMM_05_TR_%1d.txt", scenario); |
| 864 sprintf((char *) emissionFileHmm.c_str(), "HMM_4
states/HMM_05_EMIS_%1d.txt", scenario); |
| 865 } |
| 866 else |
| 867 { |
| 868 NS_LOG_UNCOND ("HMM Channel Model not valid... E
xiting"); |
| 869 return -1; |
| 870 } |
| 871 |
| 872 outputChannelTypeFileName = "HMM_" + hmmChannel; |
| 873 enumChannelModel = HIDDEN_MARKOV_ERROR_MODEL; |
| 874 |
| 875 //Set the propagation delay model |
| 876 wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedProp
agationDelayModel"); |
| 877 //Set the propagation loss model |
| 878 wifiChannel.AddPropagationLoss ("ns3::SimplePropagationL
ossModel", "MaxDistance", DoubleValue(200.0)); |
| 879 |
| 880 //Set the error model |
| 881 Ptr<HiddenMarkovErrorModel> errorModel = CreateObject<Hi
ddenMarkovErrorModel> (); |
| 882 errorModel->SetTransitionMatrixFileName(transitionFileHm
m); |
| 883 errorModel->SetEmissionMatrixFileName(emissionFileHmm); |
| 884 errorModel->GetCoefficients(); |
| 885 |
| 886 wifiPhy.SetErrorModel(errorModel); |
| 887 |
| 888 //Callback |
| 889 errorModel->SetRxCallback(MakeCallback(&Experiment::HmmR
xTrace, &exp_)); |
| 890 } |
| 891 |
| 892 //NS-3 Legacy error decision model --> LogDistancePropagationLos
sModel + NistErrorRateModel |
| 893 else if (channelModel == "NIST") |
| 894 { |
| 895 outputChannelTypeFileName = "NIST"; |
| 896 enumChannelModel = NIST_ERROR_RATE_MODEL; |
| 897 // distance = 89.6; //Distance value
which FER yields approximately 0.5 |
| 898 distance = 80; //FER ~ 0.16 |
| 899 |
| 900 //Set the propagation delay model |
| 901 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropa
gationDelayModel"); |
| 902 //Set the propagation loss model |
| 903 wifiChannel.AddPropagationLoss("ns3::LogDistancePropagat
ionLossModel"); |
| 904 wifiChannel.AddPropagationLoss("ns3::RandomPropagationLo
ssModel", "Variable", RandomVariableValue (NormalVariable (0.0, 2.8))); |
| 905 |
| 906 wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel"); |
| 907 } |
| 908 |
| 909 //Make a sweep in order to fully characterize the throughput vs
FER curve shape in a memoryless channel |
| 910 else if (channelModel == "SWEEP") |
| 911 { |
| 912 if ((int) runCounter % 5 == 0) |
| 913 distance += 0.5 ; |
| 914 |
| 915 outputChannelTypeFileName = "SWEEP"; |
| 916 enumChannelModel = NIST_ERROR_RATE_MODEL; |
| 917 // distance = 89.6;
//Distance value which FER yields approximately 0.5 |
| 918 // distance = 80; //FER ~ 0.16 |
| 919 |
| 920 //Set the propagation delay model |
| 921 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropa
gationDelayModel"); |
| 922 //Set the propagation loss model |
| 923 wifiChannel.AddPropagationLoss("ns3::LogDistancePropagat
ionLossModel"); |
| 924 // wifiChannel.AddPropagationLoss("ns3::RandomPropagationLo
ssModel", "Variable", RandomVariableValue (NormalVariable (0.0, 2.8))); |
| 925 wifiPhy.SetErrorRateModel("ns3::YansErrorRateModel"); |
| 926 |
| 927 } |
| 928 |
| 929 wifiPhy.SetChannel (wifiChannel.Create()); |
| 930 WifiHelper wifi = WifiHelper::Default(); |
| 931 wifi.SetStandard (WIFI_PHY_STANDARD_80211b); |
| 932 wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager"); |
| 933 NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default(); |
| 934 |
| 935 NetDeviceContainer wifiDevices = wifi.Install(wifiPhy, wifiMac,
wifiNodes); |
| 936 |
| 937 //Node mobility configuration |
| 938 MobilityHelper mobility; |
| 939 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPosi
tionAllocator>(); |
| 940 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); |
| 941 positionAlloc->Add(Vector(distance, 0.0, 0.0)); |
| 942 mobility.SetPositionAllocator(positionAlloc); |
| 943 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); |
| 944 mobility.Install (wifiNodes); |
| 945 |
| 946 //Set the upper layers (default configuration) |
| 947 InternetStackHelper internet; |
| 948 |
| 949 // Sysctl option configuration |
| 950 if (transportProtocol == "TCP") |
| 951 { |
| 952 internet.SetTcp ("ns3::NscTcpL4Protocol","Library",Strin
gValue ("liblinux2.6.26.so")); |
| 953 Config::Set ("/NodeList/3/$ns3::Ns3NscStack<linux2.6.26>
/net.inet.tcp.mssdflt", StringValue ("1460")); |
| 954 Config::SetDefault ("ns3::TcpSocket::SegmentSize", Uinte
gerValue (1460)); |
| 955 // Config::Set ("/NodeList/3/$ns3::Ns3NscSt
ack<linux2.6.26>/net.ipv4.tcp_sack", StringValue ("0")); |
| 956 // Config::Set ("/NodeList/3/$ns3::Ns3NscSt
ack<linux2.6.26>/net.ipv4.tcp_timestamps", StringValue ("0")); |
| 957 // Config::Set ("/NodeList/3/$ns3::Ns3NscSt
ack<linux2.6.26>/net.ipv4.tcp_window_scaling", StringValue ("0")); |
| 958 |
| 959 //TCP parameter set |
| 960 Config::SetDefault ("ns3::TcpSocket::SegmentSize", Uinte
gerValue (1460)); |
| 961 Config::SetDefault ("ns3::TcpSocket::RcvBufSize", Uinteg
erValue (90000000)); |
| 962 Config::SetDefault ("ns3::TcpSocket::SndBufSize", Uinteg
erValue (90000000)); |
| 963 |
| 964 outputFileName= "TCP"; |
| 965 |
| 966 // Config::SetDefault("ns3::TcpL4Protocol::
SocketType", StringValue("ns3::TcpNewReno")); |
| 967 // Config::SetDefault("ns3::TcpL4Protocol::
SocketType", StringValue("ns3::TcpReno")); |
| 968 } |
| 969 else if (transportProtocol == "UDP") |
| 970 { |
| 971 outputFileName = "UDP"; |
| 972 Config::SetDefault ("ns3::UdpSocket::RcvBufSize", Uinteg
erValue (90000000)); |
| 973 } |
| 974 |
| 975 internet.Install (wifiNodes); |
| 976 |
| 977 //New TCP simulation model (Application changes) |
| 978 //Define IP level |
| 979 Ipv4AddressHelper ipv4; |
| 980 NS_LOG_INFO("Assign IP Addresses."); |
| 981 ipv4.SetBase("10.1.1.0", "255.255.255.0"); |
| 982 Ipv4InterfaceContainer ipInterfaceContainer = ipv4.Assign(wifiDe
vices); |
| 983 |
| 984 |
| 985 uint16_t port = 50000;
// Server Port |
| 986 |
| 987 OnOffHelper onoff ("ns3::TcpSocketFactory", Address (InetSocketA
ddress (Ipv4Address ("10.1.1.1"), port))); //OnOffHelper instance |
| 988 |
| 989 //If UDP-based simulation, establish UDP at the OnOffHelper obje
ct |
| 990 if (transportProtocol == "UDP") |
| 991 onoff.SetAttribute("Protocol", StringValue ("ns3::UdpSoc
ketFactory")); |
| 992 |
| 993 onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVaria
ble (1))); |
| 994 onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVari
able (0))); |
| 995 onoff.SetAttribute ("DataRate", StringValue ("11Mbps")); |
| 996 onoff.SetAttribute ("PacketSize", UintegerValue (packetLength)); |
| 997 onoff.SetAttribute ("MaxBytes", UintegerValue (packetLength * nu
mPackets)); |
| 998 // onoff.SetAttribute ("Tx", MakeTraceSourceAccessor (&OnOf
fApplication::m_txTrace)); |
| 999 |
| 1000 ApplicationContainer app = onoff.Install (wifiNodes.Get(1)); //
install the onoff aplication in the AP node |
| 1001 // Start the application |
| 1002 app.Start (Seconds (1.0)); |
| 1003 app.Stop (Seconds (10000.0)); |
| 1004 |
| 1005 // Create a packet sink to receive these packets in the Station
node |
| 1006 PacketSinkHelper sink ("ns3::TcpSocketFactory", Address
(InetSocketAddress (Ipv4Address::GetAny (), port))); |
| 1007 //If UDP-based simulation, establish UDP at the OnOffHelper obje
ct |
| 1008 if (transportProtocol == "UDP") |
| 1009 sink.SetAttribute("Protocol", StringValue("ns3::UdpSock
etFactory")); |
| 1010 |
| 1011 app = sink.Install (wifiNodes.Get(0)); |
| 1012 app.Start (Seconds (0.0)); |
| 1013 app.Stop (Seconds (11000.0)); |
| 1014 |
| 1015 //End new simulation scheme |
| 1016 //////////////////// |
| 1017 |
| 1018 //Tracing connectors |
| 1019 if (enumChannelModel == NIST_ERROR_RATE_MODEL) //Frame
reception tracing for |
| 1020 { |
| 1021 Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxO
k", MakeCallback (&Experiment::PhyRxOkTrace, &exp_)); |
| 1022 Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxE
rror", MakeCallback (&Experiment::PhyRxErrorTrace, &exp_)); |
| 1023 } |
| 1024 |
| 1025 //Connect to the error models |
| 1026 wifiPhy.EnablePcap (outputChannelTypeFileName, wifiNodes
, true); |
| 1027 wifiPhy.EnableAscii("Prueba", wifiNodes); |
| 1028 |
| 1029 |
| 1030 //TCP trace file |
| 1031 char temp[128]; |
| 1032 sprintf(temp,"%s_%s_%02d_%03d.tr", outputFileName.c_str(), outpu
tChannelTypeFileName.c_str(), scenario, runCounter + runOffset); |
| 1033 exp_.OpenTraceFile(temp, enumChannelModel); |
| 1034 |
| 1035 Simulator::Stop(Seconds(11010)); |
| 1036 |
| 1037 Simulator::Run(); |
| 1038 Simulator::Destroy(); |
| 1039 |
| 1040 //Print statistics |
| 1041 NS_LOG_UNCOND("Run " << runCounter + runOffset << " FER = " << e
xp_.GetPktsReceived() - exp_.GetPktsCorrect() << "/" \ |
| 1042 << exp_.GetPktsReceived() << " = " <<
\ |
| 1043 ((double) exp_.GetPktsReceived() - (double) exp_
.GetPktsCorrect())/(double)exp_.GetPktsReceived()); |
| 1044 exp_.CloseTraceFile(); |
| 1045 } |
| 1046 } |
| 1047 |
OLD | NEW |