branch merge

This commit is contained in:
Craig Dowell committed 2010-02-08 23:16:24 -08:00
commit d0d718e2f2
29 files changed
+944 -263

No files matched your search

@@ -145,6 +145,138 @@ FriisPropagationLossModelTestCase::DoRun (void)
return GetErrorStatus ();
}
// Added for Two-Ray Ground Model - tomhewer@mac.com
class TwoRayGroundPropagationLossModelTestCase : public TestCase
{
public:
TwoRayGroundPropagationLossModelTestCase ();
virtual ~TwoRayGroundPropagationLossModelTestCase ();
private:
virtual bool DoRun (void);
typedef struct
{
Vector m_position;
double m_pt; // dBm
double m_pr; // W
double m_tolerance;
} TestVector;
TestVectors<TestVector> m_testVectors;
};
TwoRayGroundPropagationLossModelTestCase::TwoRayGroundPropagationLossModelTestCase ()
: TestCase ("Check to see that the ns-3 TwoRayGround propagation loss model provides correct received power"),
m_testVectors ()
{
}
TwoRayGroundPropagationLossModelTestCase::~TwoRayGroundPropagationLossModelTestCase ()
{
}
bool
TwoRayGroundPropagationLossModelTestCase::DoRun (void)
{
// wavelength at 2.4 GHz is 0.125m
Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::Lambda", DoubleValue (0.125));
Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::SystemLoss", DoubleValue (1.0));
// set antenna height to 1.5m above z coordinate
Config::SetDefault ("ns3::TwoRayGroundPropagationLossModel::HeightAboveZ", DoubleValue (1.5));
// Select a reference transmit power of 17.0206 dBm
// Pt = 10^(17.0206/10)/10^3 = .05035702 W
double txPowerW = 0.05035702;
double txPowerdBm = 10 * log10 (txPowerW) + 30;
//
// As with the Friis tests above, we want to test the propagation loss
// model calculations at a few chosen distances and compare the results
// to those we can manually calculate. Let us test the ns-3 calculated
// value for agreement to be within 5e-16, as above.
//
TestVector testVector;
// Below the Crossover distance use Friis so this test should be the same as that above
// Crossover = (4 * PI * TxAntennaHeight * RxAntennaHeight) / Lamdba
// Crossover = (4 * PI * 1.5 * 1.5) / 0.125 = 226.1946m
testVector.m_position = Vector (100, 0, 0);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 4.98265e-10;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
// These values are above the crossover distance and therefore use the Two Ray calculation
testVector.m_position = Vector (500, 0, 0);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 4.07891862e-12;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
testVector.m_position = Vector (1000, 0, 0);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 2.5493241375e-13;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
testVector.m_position = Vector (2000, 0, 0);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 1.593327585938e-14;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
// Repeat the tests for non-zero z coordinates
// Pr = (0.05035702 * (1.5*1.5) * (2.5*2.5)) / (500*500*500*500) = 1.13303295e-11
// dCross = (4 * pi * 1.5 * 2.5) / 0.125 = 376.99m
testVector.m_position = Vector (500, 0, 1);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 1.13303295e-11;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
// Pr = (0.05035702 * (1.5*1.5) * (5.5*5.5)) / (1000*1000*1000*1000) = 3.42742467375e-12
// dCross = (4 * pi * 1.5 * 5.5) / 0.125 = 829.38m
testVector.m_position = Vector (1000, 0, 4);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 3.42742467375e-12;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
// Pr = (0.05035702 * (1.5*1.5) * (11.5*11.5)) / (2000*2000*2000*2000) = 9.36522547734e-13
// dCross = (4 * pi * 1.5 * 11.5) / 0.125 = 1734.15m
testVector.m_position = Vector (2000, 0, 10);
testVector.m_pt = txPowerdBm;
testVector.m_pr = 9.36522547734e-13;
testVector.m_tolerance = 5e-16;
m_testVectors.Add (testVector);
// Now, check that the received power values are expected
Ptr<MobilityModel> a = CreateObject<ConstantPositionMobilityModel> ();
a->SetPosition (Vector (0,0,0));
Ptr<MobilityModel> b = CreateObject<ConstantPositionMobilityModel> ();
Ptr<TwoRayGroundPropagationLossModel> lossModel = CreateObject<TwoRayGroundPropagationLossModel> ();
for (uint32_t i = 0; i < m_testVectors.GetN (); ++i)
{
testVector = m_testVectors.Get (i);
b->SetPosition (testVector.m_position);
double resultdBm = lossModel->CalcRxPower (testVector.m_pt, a, b);
double resultW = pow (10.0, resultdBm / 10.0) / 1000;
NS_TEST_EXPECT_MSG_EQ_TOL (resultW, testVector.m_pr, testVector.m_tolerance, "Got unexpected rcv power");
}
return GetErrorStatus ();
}
class LogDistancePropagationLossModelTestCase : public TestCase
{
public:
@@ -244,6 +376,7 @@ PropagationLossModelsTestSuite::PropagationLossModelsTestSuite ()
: TestSuite ("propagation-loss-model", UNIT)
{
AddTestCase (new FriisPropagationLossModelTestCase);
AddTestCase (new TwoRayGroundPropagationLossModelTestCase);
AddTestCase (new LogDistancePropagationLossModelTestCase);
}
+171
View File
@@ -17,6 +17,7 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
* Contributions: Tom Hewer <tomhewer@mac.com> for Two Ray Ground Model
*/
#include "propagation-loss-model.h"
@@ -232,6 +233,176 @@ FriisPropagationLossModel::DoCalcRxPower (double txPowerDbm,
return txPowerDbm + pr;
}
// ------------------------------------------------------------------------- //
// -- Two-Ray Ground Model ported from NS-2 -- tomhewer@mac.com -- Nov09 //
NS_OBJECT_ENSURE_REGISTERED (TwoRayGroundPropagationLossModel);
const double TwoRayGroundPropagationLossModel::PI = 3.14159265358979323846;
TypeId
TwoRayGroundPropagationLossModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TwoRayGroundPropagationLossModel")
.SetParent<PropagationLossModel> ()
.AddConstructor<TwoRayGroundPropagationLossModel> ()
.AddAttribute ("Lambda",
"The wavelength (default is 5.15 GHz at 300 000 km/s).",
DoubleValue (300000000.0 / 5.150e9),
MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_lambda),
MakeDoubleChecker<double> ())
.AddAttribute ("SystemLoss", "The system loss",
DoubleValue (1.0),
MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_systemLoss),
MakeDoubleChecker<double> ())
.AddAttribute ("MinDistance",
"The distance under which the propagation model refuses to give results (m)",
DoubleValue (0.5),
MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::SetMinDistance,
&TwoRayGroundPropagationLossModel::GetMinDistance),
MakeDoubleChecker<double> ())
.AddAttribute ("HeightAboveZ",
"The height of the antenna (m) above the node's Z coordinate",
DoubleValue (0),
MakeDoubleAccessor (&TwoRayGroundPropagationLossModel::m_heightAboveZ),
MakeDoubleChecker<double> ())
;
return tid;
}
TwoRayGroundPropagationLossModel::TwoRayGroundPropagationLossModel ()
{
}
void
TwoRayGroundPropagationLossModel::SetSystemLoss (double systemLoss)
{
m_systemLoss = systemLoss;
}
double
TwoRayGroundPropagationLossModel::GetSystemLoss (void) const
{
return m_systemLoss;
}
void
TwoRayGroundPropagationLossModel::SetMinDistance (double minDistance)
{
m_minDistance = minDistance;
}
double
TwoRayGroundPropagationLossModel::GetMinDistance (void) const
{
return m_minDistance;
}
void
TwoRayGroundPropagationLossModel::SetHeightAboveZ (double heightAboveZ)
{
m_heightAboveZ = heightAboveZ;
}
void
TwoRayGroundPropagationLossModel::SetLambda (double frequency, double speed)
{
m_lambda = speed / frequency;
}
void
TwoRayGroundPropagationLossModel::SetLambda (double lambda)
{
m_lambda = lambda;
}
double
TwoRayGroundPropagationLossModel::GetLambda (void) const
{
return m_lambda;
}
double
TwoRayGroundPropagationLossModel::DbmToW (double dbm) const
{
double mw = pow (10.0,dbm / 10.0);
return mw / 1000.0;
}
double
TwoRayGroundPropagationLossModel::DbmFromW (double w) const
{
double dbm = log10 (w * 1000.0) * 10.0;
return dbm;
}
double
TwoRayGroundPropagationLossModel::DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
/*
* Two-Ray Ground equation:
*
* where Pt, Gt and Gr are in dBm units
* L, Ht and Hr are in meter units.
*
* Pr Gt * Gr * (Ht^2 * Hr^2)
* -- = (-------------------------)
* Pt d^4 * L
*
* Gt: tx gain (unit-less)
* Gr: rx gain (unit-less)
* Pt: tx power (dBm)
* d: distance (m)
* L: system loss
* Ht: Tx antenna height (m)
* Hr: Rx antenna height (m)
* lambda: wavelength (m)
*
* As with the Friis model we ignore tx and rx gain and output values
* are in dB or dBm
*
* (Ht * Ht) * (Hr * Hr)
* rx = tx + 10 log10 (-----------------------)
* (d * d * d * d) * L
*/
double distance = a->GetDistanceFrom (b);
if (distance <= m_minDistance)
{
return txPowerDbm;
}
// Set the height of the Tx and Rx antennae
double txAntHeight = a->GetPosition ().z + m_heightAboveZ;
double rxAntHeight = b->GetPosition ().z + m_heightAboveZ;
// Calculate a crossover distance, under which we use Friis
/*
*
* dCross = (4 * pi * Ht * Hr) / lambda
*
*/
double dCross = (4 * PI * txAntHeight * rxAntHeight) / GetLambda ();
double tmp = 0;
if (distance <= dCross)
{
// We use Friis
double numerator = m_lambda * m_lambda;
tmp = PI * distance;
double denominator = 16 * tmp * tmp * m_systemLoss;
double pr = 10 * log10 (numerator / denominator);
NS_LOG_DEBUG ("Receiver within crossover (" << dCross << "m) for Two_ray path; using Friis");
NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << pr << "dB");
return txPowerDbm + pr;
}
else // Use Two-Ray Pathloss
{
tmp = txAntHeight * rxAntHeight;
double rayNumerator = tmp * tmp;
tmp = distance * distance;
double rayDenominator = tmp * tmp * m_systemLoss;
double rayPr = 10 * log10 (rayNumerator / rayDenominator);
NS_LOG_DEBUG ("distance=" << distance << "m, attenuation coefficient=" << rayPr << "dB");
return txPowerDbm + rayPr;
}
}
// ------------------------------------------------------------------------- //
NS_OBJECT_ENSURE_REGISTERED (LogDistancePropagationLossModel);
+90
View File
@@ -18,6 +18,7 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Contributions: Timo Bingmann <timo.bingmann@student.kit.edu>
* Contributions: Gary Pei <guangyu.pei@boeing.com> for fixed RSS
* Contributions: Tom Hewer <tomhewer@mac.com> for two ray ground model
*/
#ifndef PROPAGATION_LOSS_MODEL_H
@@ -182,6 +183,95 @@ private:
double m_minDistance;
};
/*
*
* \brief a Two-Ray Ground propagation loss model ported from NS2
*
* Two-ray ground reflection model.
*
* \f$ Pr = \frac{Pt * Gt * Gr * (ht^2 * hr^2)}{d^4 * L} \f$
*
* The original equation in Rappaport's book assumes L = 1.
* To be consistent with the free space equation, L is added here.
*
* Ht and Hr are set at the respective nodes z coordinate plus a model parameter
* set via SetHeightAboveZ.
*
* The two-ray model does not give a good result for short distances, due to the
* oscillation caused by constructive and destructive combination of the two
* rays. Instead the Friis free-space model is used for small distances.
*
* The crossover distance, below which Friis is used, is calculated as follows:
*
* \f$ dCross = \frac{(4 * pi * Ht * Hr)}{lambda} \f$
*/
class TwoRayGroundPropagationLossModel : public PropagationLossModel
{
public:
static TypeId GetTypeId (void);
TwoRayGroundPropagationLossModel ();
/**
* \param frequency (Hz)
* \param speed (m/s)
*
* Set the main wavelength used in the TwoRayGround model
* calculation.
*/
void SetLambda (double frequency, double speed);
/**
* \param lambda (m) the wavelength
*
* Set the main wavelength used in the TwoRayGround model
* calculation.
*/
void SetLambda (double lambda);
/**
* \param systemLoss (dimension-less)
*
* Set the system loss used by the TwoRayGround propagation model.
*/
void SetSystemLoss (double systemLoss);
/**
* \param minDistance the minimum distance
*
* Below this distance, the txpower is returned
* unmodified as the rxpower.
*/
void SetMinDistance (double minDistance);
/**
* \returns the minimum distance.
*/
double GetMinDistance (void) const;
/**
* \returns the current wavelength (m)
*/
double GetLambda (void) const;
/**
* \returns the current system loss (dimention-less)
*/
double GetSystemLoss (void) const;
/**
* \Set the model antenna height above the node's Z coordinate
*/
void SetHeightAboveZ (double heightAboveZ);
private:
TwoRayGroundPropagationLossModel (const TwoRayGroundPropagationLossModel &o);
TwoRayGroundPropagationLossModel & operator = (const TwoRayGroundPropagationLossModel &o);
virtual double DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const;
double DbmToW (double dbm) const;
double DbmFromW (double w) const;
static const double PI;
double m_lambda;
double m_systemLoss;
double m_minDistance;
double m_heightAboveZ;
};
/**
* \brief a log distance propagation model.
*
+3 -49
View File
@@ -444,16 +444,16 @@ EmuNetDevice::CreateSocket (void)
//
// Execute the socket creation process image.
//
status = ::execl (FindCreator ("emu-sock-creator").c_str (),
status = ::execlp ("emu-sock-creator",
"emu-sock-creator", // argv[0] (filename)
oss.str ().c_str (), // argv[1] (-p<path?
(char *)NULL);
//
// If the execl successfully completes, it never returns. If it returns it failed or the OS is
// If the execlp successfully completes, it never returns. If it returns it failed or the OS is
// broken. In either case, we bail.
//
NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Back from execl(), errno = " << ::strerror (errno));
NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Back from execlp(), errno = " << ::strerror (errno));
}
else
{
@@ -581,52 +581,6 @@ EmuNetDevice::CreateSocket (void)
}
}
std::string
EmuNetDevice::FindCreator (std::string creatorName)
{
NS_LOG_FUNCTION (creatorName);
std::list<std::string> locations;
// The path to the bits if we're sitting there with them
locations.push_back ("./");
locations.push_back ("./");
// The path to the bits if we're sitting in the root of the repo
locations.push_back ("./build/optimized/src/devices/emu/");
locations.push_back ("./build/debug/src/devices/emu/");
// if at the level of src (or build)
locations.push_back ("../build/optimized/src/devices/emu/");
locations.push_back ("../build/debug/src/devices/emu/");
// src/devices (or build/debug)
locations.push_back ("../../build/optimized/src/devices/emu/");
locations.push_back ("../../build/debug/src/devices/emu/");
// src/devices/emu (or build/debug/examples)
locations.push_back ("../../../build/optimized/src/devices/emu/");
locations.push_back ("../../../build/debug/src/devices/emu/");
// src/devices/emu (or build/debug/examples/emulation)
locations.push_back ("../../../../build/optimized/src/devices/emu/");
locations.push_back ("../../../../build/debug/src/devices/emu/");
for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
{
struct stat st;
if (::stat ((*i + creatorName).c_str (), &st) == 0)
{
NS_LOG_INFO ("Found Creator " << *i + creatorName);
return *i + creatorName;
}
}
NS_FATAL_ERROR ("EmuNetDevice::FindCreator(): Couldn't find creator");
return ""; // quiet compiler
}
void
EmuNetDevice::StopDevice (void)
{
+7
View File
@@ -1,5 +1,7 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import os.path
def configure(conf):
if conf.env['ENABLE_THREADING']:
conf.env['ENABLE_EMU'] = conf.check(header_name='netpacket/packet.h',
@@ -12,6 +14,11 @@ def configure(conf):
False,
"needs threading support which is not available")
if conf.env['ENABLE_EMU']:
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
emucreatordir = os.path.abspath(os.path.join(blddir, "src/devices/emu"))
conf.env.append_value('NS3_EXECUTABLE_PATH', emucreatordir)
def build(bld):
module = bld.create_ns3_module('emu', ['node'])
module.source = [
@@ -511,11 +511,19 @@ PointToPointNetDevice::Send(
// Even if the transmitter is immediately available, we still enqueue and
// dequeue the packet to hit the tracing hooks.
//
m_queue->Enqueue (packet);
packet = m_queue->Dequeue ();
m_snifferTrace (packet);
m_promiscSnifferTrace (packet);
return TransmitStart (packet);
if (m_queue->Enqueue (packet) == true)
{
packet = m_queue->Dequeue ();
m_snifferTrace (packet);
m_promiscSnifferTrace (packet);
return TransmitStart (packet);
}
else
{
// Enqueue may fail (overflow)
m_macTxDropTrace (packet);
return false;
}
}
else
{
+4 -42
View File
@@ -477,8 +477,8 @@ TapBridge::CreateTap (void)
//
// Execute the socket creation process image.
//
status = ::execl (FindCreator ("tap-creator").c_str (),
FindCreator ("tap-creator").c_str (), // argv[0] (filename)
status = ::execlp ("tap-creator",
"tap-creator", // argv[0] (filename)
ossDeviceName.str ().c_str (), // argv[1] (-d<device name>)
ossGateway.str ().c_str (), // argv[2] (-g<gateway>)
ossIp.str ().c_str (), // argv[3] (-i<IP address>)
@@ -489,10 +489,10 @@ TapBridge::CreateTap (void)
(char *)NULL);
//
// If the execl successfully completes, it never returns. If it returns it failed or the OS is
// If the execlp successfully completes, it never returns. If it returns it failed or the OS is
// broken. In either case, we bail.
//
NS_FATAL_ERROR ("TapBridge::CreateTap(): Back from execl(), errno = " << ::strerror (errno));
NS_FATAL_ERROR ("TapBridge::CreateTap(): Back from execlp(), errno = " << ::strerror (errno));
}
else
{
@@ -614,44 +614,6 @@ TapBridge::CreateTap (void)
}
}
std::string
TapBridge::FindCreator (std::string creatorName)
{
NS_LOG_FUNCTION (creatorName);
std::list<std::string> locations;
// The path to the bits if we're sitting in the root of the repo
locations.push_back ("./build/optimized/src/devices/tap-bridge/");
locations.push_back ("./build/debug/src/devices/tap-bridge/");
// if in src
locations.push_back ("../build/optimized/src/devices/tap-bridge/");
locations.push_back ("../build/debug/src/devices/tap-bridge/");
// if in src/devices
locations.push_back ("../../build/optimized/src/devices/tap-bridge/");
locations.push_back ("../../build/debug/src/devices/tap-bridge/");
// if in src/devices/tap-bridge
locations.push_back ("../../../build/optimized/src/devices/tap-bridge/");
locations.push_back ("../../../build/debug/src/devices/tap-bridge/");
for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
{
struct stat st;
if (::stat ((*i + creatorName).c_str (), &st) == 0)
{
NS_LOG_INFO ("Found Creator " << *i + creatorName);
return *i + creatorName;
}
}
NS_FATAL_ERROR ("TapBridge::FindCreator(): Couldn't find creator");
return ""; // quiet compiler
}
void
TapBridge::ReadThread (void)
{
-10
View File
@@ -231,16 +231,6 @@ private:
*/
void CreateTap (void);
/**
* \internal
*
* Figure out where the tap creation program lives on the system.
*
* \param creatorName The name of the program used to create the Tap.
* \returns A path name to use when you want to create a Tap.
*/
std::string FindCreator (std::string creatorName);
/**
* \internal
*
+7
View File
@@ -1,5 +1,7 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import os.path
def configure(conf):
if conf.env['ENABLE_THREADING']:
conf.env['ENABLE_TAP'] = conf.check(header_name='linux/if_tun.h',
@@ -12,6 +14,11 @@ def configure(conf):
False,
"needs threading support which is not available")
if conf.env['ENABLE_TAP']:
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
tapcreatordir = os.path.abspath(os.path.join(blddir, "src/devices/tap-bridge"))
conf.env.append_value('NS3_EXECUTABLE_PATH', tapcreatordir)
def build(bld):
module = bld.create_ns3_module('tap-bridge', ['node'])
module.source = [
+20 -21
View File
@@ -36,9 +36,8 @@
NS_LOG_COMPONENT_DEFINE ("DcaTxop");
#define MY_DEBUG(x) \
NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_low->GetAddress () << "] ";
namespace ns3 {
@@ -361,7 +360,7 @@ DcaTxop::NotifyAccessGranted (void)
{
if (m_queue->IsEmpty ())
{
MY_DEBUG ("queue empty");
NS_LOG_DEBUG ("queue empty");
return;
}
m_currentPacket = m_queue->Dequeue (&m_currentHdr);
@@ -372,7 +371,7 @@ DcaTxop::NotifyAccessGranted (void)
m_currentHdr.SetNoMoreFragments ();
m_currentHdr.SetNoRetry ();
m_fragmentNumber = 0;
MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
NS_LOG_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
", to="<<m_currentHdr.GetAddr1 ()<<
", seq="<<m_currentHdr.GetSequenceControl ());
}
@@ -391,7 +390,7 @@ DcaTxop::NotifyAccessGranted (void)
m_dcf->ResetCw ();
m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
StartAccessIfNeeded ();
MY_DEBUG ("tx broadcast");
NS_LOG_DEBUG ("tx broadcast");
}
else
{
@@ -411,12 +410,12 @@ DcaTxop::NotifyAccessGranted (void)
}
if (IsLastFragment ())
{
MY_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
NS_LOG_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
params.DisableNextData ();
}
else
{
MY_DEBUG ("fragmenting size="<<fragment->GetSize ());
NS_LOG_DEBUG ("fragmenting size="<<fragment->GetSize ());
params.EnableNextData (GetNextFragmentSize ());
}
Low ()->StartTransmission (fragment, &hdr, params,
@@ -427,12 +426,12 @@ DcaTxop::NotifyAccessGranted (void)
if (NeedRts (m_currentPacket))
{
params.EnableRts ();
MY_DEBUG ("tx unicast rts");
NS_LOG_DEBUG ("tx unicast rts");
}
else
{
params.DisableRts ();
MY_DEBUG ("tx unicast");
NS_LOG_DEBUG ("tx unicast");
}
params.DisableNextData ();
Low ()->StartTransmission (m_currentPacket, &m_currentHdr,
@@ -451,7 +450,7 @@ void
DcaTxop::NotifyCollision (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("collision");
NS_LOG_DEBUG ("collision");
m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
RestartAccessIfNeeded ();
}
@@ -467,16 +466,16 @@ void
DcaTxop::GotCts (double snr, WifiMode txMode)
{
NS_LOG_FUNCTION (this << snr << txMode);
MY_DEBUG ("got cts");
NS_LOG_DEBUG ("got cts");
}
void
DcaTxop::MissedCts (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("missed cts");
NS_LOG_DEBUG ("missed cts");
if (!NeedRtsRetransmission ())
{
MY_DEBUG ("Cts Fail");
NS_LOG_DEBUG ("Cts Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalRtsFailed ();
if (!m_txFailedCallback.IsNull ())
@@ -501,7 +500,7 @@ DcaTxop::GotAck (double snr, WifiMode txMode)
if (!NeedFragmentation () ||
IsLastFragment ())
{
MY_DEBUG ("got ack. tx done.");
NS_LOG_DEBUG ("got ack. tx done.");
if (!m_txOkCallback.IsNull ())
{
m_txOkCallback (m_currentHdr);
@@ -517,17 +516,17 @@ DcaTxop::GotAck (double snr, WifiMode txMode)
}
else
{
MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
}
}
void
DcaTxop::MissedAck (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("missed ack");
NS_LOG_DEBUG ("missed ack");
if (!NeedDataRetransmission ())
{
MY_DEBUG ("Ack Fail");
NS_LOG_DEBUG ("Ack Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalDataFailed ();
if (!m_txFailedCallback.IsNull ())
@@ -540,7 +539,7 @@ DcaTxop::MissedAck (void)
}
else
{
MY_DEBUG ("Retransmit");
NS_LOG_DEBUG ("Retransmit");
m_currentHdr.SetRetry ();
m_dcf->UpdateFailedCw ();
}
@@ -551,7 +550,7 @@ void
DcaTxop::StartNext (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("start next packet fragment");
NS_LOG_DEBUG ("start next packet fragment");
/* this callback is used only for fragments. */
NextFragment ();
WifiMacHeader hdr;
@@ -575,7 +574,7 @@ void
DcaTxop::Cancel (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("transmission cancelled");
NS_LOG_DEBUG ("transmission cancelled");
/**
* This happens in only one case: in an AP, you have two DcaTxop:
* - one is used exclusively for beacons and has a high priority.
+29 -29
View File
@@ -37,8 +37,8 @@
NS_LOG_COMPONENT_DEFINE ("EdcaTxopN");
#define MY_DEBUG(x) \
NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_low->GetAddress () << "] ";
namespace ns3 {
@@ -317,7 +317,7 @@ EdcaTxopN::NotifyAccessGranted (void)
{
if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
{
MY_DEBUG ("queue is empty");
NS_LOG_DEBUG ("queue is empty");
return;
}
struct Bar bar;
@@ -332,7 +332,7 @@ EdcaTxopN::NotifyAccessGranted (void)
{
if (m_queue->PeekFirstAvailable (&m_currentHdr, m_currentPacketTimestamp, m_qosBlockedDestinations) == 0)
{
MY_DEBUG ("no available packets in the queue");
NS_LOG_DEBUG ("no available packets in the queue");
return;
}
if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () &&
@@ -351,7 +351,7 @@ EdcaTxopN::NotifyAccessGranted (void)
m_currentHdr.SetNoMoreFragments ();
m_currentHdr.SetNoRetry ();
m_fragmentNumber = 0;
MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
NS_LOG_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
", to="<<m_currentHdr.GetAddr1 ()<<
", seq="<<m_currentHdr.GetSequenceControl ());
if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ())
@@ -376,7 +376,7 @@ EdcaTxopN::NotifyAccessGranted (void)
m_dcf->ResetCw ();
m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
StartAccessIfNeeded ();
MY_DEBUG ("tx broadcast");
NS_LOG_DEBUG ("tx broadcast");
}
else
{
@@ -400,12 +400,12 @@ EdcaTxopN::NotifyAccessGranted (void)
Ptr<Packet> fragment = GetFragmentPacket (&hdr);
if (IsLastFragment ())
{
MY_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
params.DisableNextData ();
}
else
{
MY_DEBUG ("fragmenting size=" << fragment->GetSize ());
NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
params.EnableNextData (GetNextFragmentSize ());
}
m_low->StartTransmission (fragment, &hdr, params,
@@ -453,18 +453,18 @@ EdcaTxopN::NotifyAccessGranted (void)
m_currentHdr.SetAddr3 (m_low->GetBssid ());
m_currentPacket = currentAggregatedPacket;
currentAggregatedPacket = 0;
MY_DEBUG ("tx unicast A-MSDU");
NS_LOG_DEBUG ("tx unicast A-MSDU");
}
}
if (NeedRts ())
{
params.EnableRts ();
MY_DEBUG ("tx unicast rts");
NS_LOG_DEBUG ("tx unicast rts");
}
else
{
params.DisableRts ();
MY_DEBUG ("tx unicast");
NS_LOG_DEBUG ("tx unicast");
}
params.DisableNextData ();
m_low->StartTransmission (m_currentPacket, &m_currentHdr,
@@ -492,17 +492,17 @@ void
EdcaTxopN::GotCts (double snr, WifiMode txMode)
{
NS_LOG_FUNCTION (this << snr << txMode);
MY_DEBUG ("got cts");
NS_LOG_DEBUG ("got cts");
}
void
EdcaTxopN::MissedCts (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("missed cts");
NS_LOG_DEBUG ("missed cts");
if (!NeedRtsRetransmission ())
{
MY_DEBUG ("Cts Fail");
NS_LOG_DEBUG ("Cts Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalRtsFailed ();
if (!m_txFailedCallback.IsNull ())
@@ -548,7 +548,7 @@ EdcaTxopN::GotAck (double snr, WifiMode txMode)
IsLastFragment () ||
m_currentHdr.IsQosAmsdu ())
{
MY_DEBUG ("got ack. tx done.");
NS_LOG_DEBUG ("got ack. tx done.");
if (!m_txOkCallback.IsNull ())
{
m_txOkCallback (m_currentHdr);
@@ -582,7 +582,7 @@ EdcaTxopN::GotAck (double snr, WifiMode txMode)
}
else
{
MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
}
}
@@ -590,10 +590,10 @@ void
EdcaTxopN::MissedAck (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("missed ack");
NS_LOG_DEBUG ("missed ack");
if (!NeedDataRetransmission ())
{
MY_DEBUG ("Ack Fail");
NS_LOG_DEBUG ("Ack Fail");
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalDataFailed ();
if (!m_txFailedCallback.IsNull ())
@@ -606,7 +606,7 @@ EdcaTxopN::MissedAck (void)
}
else
{
MY_DEBUG ("Retransmit");
NS_LOG_DEBUG ("Retransmit");
m_currentHdr.SetRetry ();
m_dcf->UpdateFailedCw ();
}
@@ -618,9 +618,9 @@ void
EdcaTxopN::MissedBlockAck (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("missed block ack");
NS_LOG_DEBUG ("missed block ack");
//should i report this to station addressed by ADDR1?
MY_DEBUG ("Retransmit block ack request");
NS_LOG_DEBUG ("Retransmit block ack request");
m_currentHdr.SetRetry ();
m_dcf->UpdateFailedCw ();
@@ -689,7 +689,7 @@ void
EdcaTxopN::StartNext (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("start next packet fragment");
NS_LOG_DEBUG ("start next packet fragment");
/* this callback is used only for fragments. */
NextFragment ();
WifiMacHeader hdr;
@@ -713,7 +713,7 @@ void
EdcaTxopN::Cancel (void)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("transmission cancelled");
NS_LOG_DEBUG ("transmission cancelled");
}
bool
@@ -835,18 +835,18 @@ void
EdcaTxopN::GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("received ADDBA response from "<<recipient);
NS_LOG_DEBUG ("received ADDBA response from "<<recipient);
uint8_t tid = respHdr->GetTid ();
if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
{
if (respHdr->GetStatusCode ().IsSuccess ())
{
MY_DEBUG ("block ack agreement established with "<<recipient);
NS_LOG_DEBUG ("block ack agreement established with "<<recipient);
m_baManager->UpdateAgreement (respHdr, recipient);
}
else
{
MY_DEBUG ("discard ADDBA response"<<recipient);
NS_LOG_DEBUG ("discard ADDBA response"<<recipient);
m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
}
}
@@ -857,14 +857,14 @@ void
EdcaTxopN::GotDelBaFrame (const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("received DELBA frame from="<<recipient);
NS_LOG_DEBUG ("received DELBA frame from="<<recipient);
m_baManager->TearDownBlockAck (recipient, delBaHdr->GetTid ());
}
void
EdcaTxopN::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient)
{
MY_DEBUG ("got block ack from="<<recipient);
NS_LOG_DEBUG ("got block ack from="<<recipient);
m_baManager->NotifyGotBlockAck (blockAck, recipient);
m_currentPacket = 0;
m_dcf->ResetCw ();
@@ -996,7 +996,7 @@ EdcaTxopN::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
uint16_t timeout, bool immediateBAck)
{
NS_LOG_FUNCTION (this);
MY_DEBUG ("sent ADDBA request to "<<dest);
NS_LOG_DEBUG ("sent ADDBA request to "<<dest);
WifiMacHeader hdr;
hdr.SetAction ();
hdr.SetAddr1 (dest);
+5 -5
View File
@@ -89,7 +89,7 @@ Ipv4EndPoint::GetBoundNetDevice (void)
}
void
Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback)
Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> callback)
{
m_rxCallback = callback;
}
@@ -106,17 +106,17 @@ Ipv4EndPoint::SetDestroyCallback (Callback<void> callback)
}
void
Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport)
{
if (!m_rxCallback.IsNull ())
{
Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, sport);
Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, daddr, sport);
}
}
void
Ipv4EndPoint::DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
Ipv4EndPoint::DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport)
{
m_rxCallback (p, saddr, sport);
m_rxCallback (p, saddr, daddr, sport);
}
void
+4 -4
View File
@@ -59,13 +59,13 @@ public:
Ptr<NetDevice> GetBoundNetDevice (void);
// Called from socket implementations to get notified about important events.
void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> callback);
void SetIcmpCallback (Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> callback);
void SetDestroyCallback (Callback<void> callback);
// Called from an L4Protocol implementation to notify an endpoint of a
// packet reception.
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport);
// Called from an L4Protocol implementation to notify an endpoint of
// an icmp message reception.
void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
@@ -73,7 +73,7 @@ public:
uint32_t icmpInfo);
private:
void DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
void DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport);
void DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
uint8_t icmpType, uint8_t icmpCode,
uint32_t icmpInfo);
@@ -82,7 +82,7 @@ private:
Ipv4Address m_peerAddr;
uint16_t m_peerPort;
Ptr<NetDevice> m_boundnetdevice;
Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
Callback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint16_t> m_rxCallback;
Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
Callback<void> m_destroyCallback;
};
+6
View File
@@ -463,6 +463,12 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t pr
}
packet->RemoveHeader (ipHeader);
// Trim any residual frame padding from underlying devices
if (ipHeader.GetPayloadSize () < packet->GetSize ())
{
packet->RemoveAtEnd (packet->GetSize () - ipHeader.GetPayloadSize ());
}
if (!ipHeader.IsChecksumOk ())
{
NS_LOG_LOGIC ("Dropping received packet -- checksum not ok");
+6
View File
@@ -695,6 +695,12 @@ void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16
Ipv6Header hdr;
packet->RemoveHeader (hdr);
// Trim any residual frame padding from underlying devices
if (hdr.GetPayloadLength () < packet->GetSize ())
{
packet->RemoveAtEnd (packet->GetSize () - hdr.GetPayloadLength ());
}
/* forward up to IPv6 raw sockets */
for (SocketList::iterator it = m_sockets.begin () ; it != m_sockets.end () ; ++it)
{
+1 -1
View File
@@ -382,7 +382,7 @@ void NscTcpL4Protocol::wakeup()
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
endPoint != endPoints.end (); endPoint++) {
// NSC HACK: (ab)use TcpSocket::ForwardUp for signalling
(*endPoint)->ForwardUp (NULL, Ipv4Address(), 0);
(*endPoint)->ForwardUp (NULL, Ipv4Address(), Ipv4Address(), 0);
}
}
+1 -1
View File
@@ -465,7 +465,7 @@ NscTcpSocketImpl::GetRxAvailable (void) const
}
void
NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
NscTcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
{
NSCWakeup();
}
+1 -1
View File
@@ -88,7 +88,7 @@ private:
friend class Tcp;
// invoked by Tcp class
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
void Destroy (void);
//methods for state
bool SendPendingData(void);
+1 -1
View File
@@ -546,7 +546,7 @@ TcpL4Protocol::Receive (Ptr<Packet> packet,
}
NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
(*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
(*endPoints.begin ())->ForwardUp (packet, source, destination, tcpHeader.GetSourcePort ());
return Ipv4L4Protocol::RX_OK;
}
+48 -74
View File
@@ -70,8 +70,6 @@ TcpSocketImpl::GetTypeId ()
m_endPoint (0),
m_node (0),
m_tcp (0),
m_localAddress (Ipv4Address::GetZero ()),
m_localPort (0),
m_errno (ERROR_NOTERROR),
m_shutdownSend (false),
m_shutdownRecv (false),
@@ -109,10 +107,6 @@ TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock)
m_endPoint (0),
m_node (sock.m_node),
m_tcp (sock.m_tcp),
m_remoteAddress (sock.m_remoteAddress),
m_remotePort (sock.m_remotePort),
m_localAddress (sock.m_localAddress),
m_localPort (sock.m_localPort),
m_errno (sock.m_errno),
m_shutdownSend (sock.m_shutdownSend),
m_shutdownRecv (sock.m_shutdownRecv),
@@ -266,8 +260,6 @@ TcpSocketImpl::FinishBind (void)
}
m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
m_localAddress = m_endPoint->GetLocalAddress ();
m_localPort = m_endPoint->GetLocalPort ();
return 0;
}
@@ -377,13 +369,12 @@ TcpSocketImpl::Connect (const Address & address)
NS_ASSERT (m_endPoint != 0);
}
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
m_remoteAddress = transport.GetIpv4 ();
m_remotePort = transport.GetPort ();
m_endPoint->SetPeer(transport.GetIpv4 (), transport.GetPort ());
if (ipv4->GetRoutingProtocol () != 0)
{
Ipv4Header header;
header.SetDestination (m_remoteAddress);
header.SetDestination (m_endPoint->GetPeerAddress());
Socket::SocketErrno errno_;
Ptr<Ipv4Route> route;
Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
@@ -396,7 +387,7 @@ TcpSocketImpl::Connect (const Address & address)
}
else
{
NS_LOG_LOGIC ("TcpSocketImpl::Connect(): Route to " << m_remoteAddress << " does not exist");
NS_LOG_LOGIC ("TcpSocketImpl::Connect(): Route to " << m_endPoint->GetPeerAddress() << " does not exist");
NS_LOG_ERROR (errno_);
m_errno = errno_;
return -1;
@@ -602,7 +593,7 @@ TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
}
}
SocketAddressTag tag;
tag.SetAddress (InetSocketAddress (m_remoteAddress, m_remotePort));
tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress(), m_endPoint->GetPeerPort()));
outPacket->AddPacketTag (tag);
return outPacket;
}
@@ -638,7 +629,8 @@ int
TcpSocketImpl::GetSockName (Address &address) const
{
NS_LOG_FUNCTION_NOARGS ();
address = InetSocketAddress(m_localAddress, m_localPort);
address = InetSocketAddress(m_endPoint->GetLocalAddress (),
m_endPoint->GetLocalPort ());
return 0;
}
@@ -661,7 +653,7 @@ TcpSocketImpl::BindToNetDevice (Ptr<NetDevice> netdevice)
}
void
TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
{
NS_LOG_DEBUG("Socket " << this << " got forward up" <<
" dport " << m_endPoint->GetLocalPort() <<
@@ -669,7 +661,11 @@ TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
" sport " << m_endPoint->GetPeerPort() <<
" saddr " << m_endPoint->GetPeerAddress());
NS_LOG_FUNCTION (this << packet << ipv4 << port);
NS_LOG_FUNCTION (this << packet << saddr << daddr << port);
Address fromAddress = InetSocketAddress (saddr, port);
Address toAddress = InetSocketAddress (daddr, m_endPoint->GetLocalPort());
if (m_shutdownRecv)
{
return;
@@ -695,11 +691,10 @@ TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
Actions_t action = ProcessEvent (event); //updates the state
Address address = InetSocketAddress (ipv4, port);
NS_LOG_DEBUG("Socket " << this <<
" processing pkt action, " << action <<
" current state " << m_state);
ProcessPacketAction (action, packet, tcpHeader, address);
ProcessPacketAction (action, packet, tcpHeader, fromAddress, toAddress);
}
Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
@@ -727,7 +722,6 @@ Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
{
Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
m_connected = true;
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
}
if (saveState < CLOSING && (m_state == CLOSING || m_state == TIMED_WAIT) )
@@ -787,10 +781,10 @@ void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
header.SetSequenceNumber (m_nextTxSequence);
header.SetAckNumber (m_nextRxSequence);
header.SetSourcePort (m_endPoint->GetLocalPort ());
header.SetDestinationPort (m_remotePort);
header.SetDestinationPort (m_endPoint->GetPeerPort ());
header.SetWindowSize (AdvertisedWindowSize());
m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
m_remoteAddress, m_boundnetdevice);
m_endPoint->GetPeerAddress (), m_boundnetdevice);
Time rto = m_rtt->RetransmitTimeout ();
bool hasSyn = flags & TcpHeader::SYN;
bool hasFin = flags & TcpHeader::FIN;
@@ -901,7 +895,8 @@ bool TcpSocketImpl::ProcessAction (Actions_t a)
bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
const TcpHeader& tcpHeader,
const Address& fromAddress)
const Address& fromAddress,
const Address& toAddress)
{
NS_LOG_FUNCTION (this << a << p << fromAddress);
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
@@ -935,40 +930,18 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
NS_LOG_LOGIC ("Cloned a TcpSocketImpl " << newSock);
//this listening socket should do nothing more
Simulator::ScheduleNow (&TcpSocketImpl::CompleteFork, newSock,
p, tcpHeader,fromAddress);
p, tcpHeader, fromAddress, toAddress);
return true;
}
// This is the cloned endpoint
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
else
{
// This is the cloned endpoint
// TCP SYN consumes one byte
m_nextRxSequence = tcpHeader.GetSequenceNumber ()
+ SequenceNumber (1);
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
}
// Look up the source address
if (ipv4->GetRoutingProtocol () != 0)
{
Ipv4Header header;
Socket::SocketErrno errno_;
Ptr<Ipv4Route> route;
Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a source address
header.SetDestination (m_remoteAddress);
route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
if (route != 0)
{
NS_LOG_LOGIC ("Route exists");
m_endPoint->SetLocalAddress (route->GetSource ());
}
else
{
NS_LOG_ERROR (errno_);
m_errno = errno_;
return -1;
}
}
else
{
NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
}
// TCP SYN consumes one byte
m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
break;
case ACK_TX_1:
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
@@ -1001,7 +974,8 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
NEW_SEQ_RX,
p,
tcpHeader,
fromAddress);
fromAddress,
toAddress);
}
if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
{
@@ -1025,7 +999,7 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
break;
case NEW_SEQ_RX:
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_SEQ_RX");
NewRx (p, tcpHeader, fromAddress); // Process new data received
NewRx (p, tcpHeader, fromAddress, toAddress); // Process new data received
break;
case PEER_CLOSE:
{
@@ -1039,14 +1013,14 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose"
<< " rxseq " << tcpHeader.GetSequenceNumber ()
<< " nextRxSeq " << m_nextRxSequence);
NewRx (p, tcpHeader, fromAddress);
NewRx (p, tcpHeader, fromAddress, toAddress);
return true;
}
// Now we need to see if any data came with the FIN
// if so, call NewRx
if (p->GetSize () != 0)
{
NewRx (p, tcpHeader, fromAddress);
NewRx (p, tcpHeader, fromAddress, toAddress);
}
++m_nextRxSequence; //bump this to account for the FIN
States_t saveState = m_state; // Used to see if app responds
@@ -1078,7 +1052,7 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SERV_NOTIFY");
NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
m_connected = true; // ! This is bogus; fix when we clone the tcp
m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
m_endPoint->SetPeer (m_endPoint->GetPeerAddress(), m_endPoint->GetPeerPort());
//treat the connection orientation final ack as a newack
CommonNewAck (tcpHeader.GetAckNumber (), true);
NotifyNewConnectionCreated (this, fromAddress);
@@ -1089,21 +1063,19 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
return true;
}
void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress, const Address& toAddress)
{
// Get port and address from peer (connecting host)
m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
m_endPoint = m_tcp->Allocate (m_localAddress,
m_localPort,
m_remoteAddress,
m_remotePort);
m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom(toAddress).GetIpv4 (),
InetSocketAddress::ConvertFrom(toAddress).GetPort (),
InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
//the cloned socket with be in listen state, so manually change state
m_state = SYN_RCVD;
//equivalent to FinishBind
m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress, toAddress);
}
void TcpSocketImpl::ConnectionSucceeded()
@@ -1165,7 +1137,7 @@ bool TcpSocketImpl::SendPendingData (bool withAck)
header.SetSequenceNumber (m_nextTxSequence);
header.SetAckNumber (m_nextRxSequence);
header.SetSourcePort (m_endPoint->GetLocalPort());
header.SetDestinationPort (m_remotePort);
header.SetDestinationPort (m_endPoint->GetPeerPort());
header.SetWindowSize (AdvertisedWindowSize());
if (m_shutdownSend)
{
@@ -1185,7 +1157,8 @@ bool TcpSocketImpl::SendPendingData (bool withAck)
NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
m_tcp->SendPacket (p, header,
m_endPoint->GetLocalAddress (),
m_remoteAddress, m_boundnetdevice);
m_endPoint->GetPeerAddress (),
m_boundnetdevice);
m_rtt->SentSeq(m_nextTxSequence, sz); // notify the RTT
// Notify the application of the data being sent
Simulator::ScheduleNow(&TcpSocketImpl::NotifyDataSent, this, sz);
@@ -1243,7 +1216,8 @@ uint16_t TcpSocketImpl::AdvertisedWindowSize()
void TcpSocketImpl::NewRx (Ptr<Packet> p,
const TcpHeader& tcpHeader,
const Address& fromAddress)
const Address& fromAddress,
const Address& toAddress)
{
NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
@@ -1310,7 +1284,7 @@ void TcpSocketImpl::NewRx (Ptr<Packet> p,
{ // See if we can close now
if (m_bufferedData.empty())
{
ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress);
ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress, toAddress);
}
}
}
@@ -1627,11 +1601,11 @@ void TcpSocketImpl::PersistTimeout ()
tcpHeader.SetSequenceNumber (m_nextTxSequence);
tcpHeader.SetAckNumber (m_nextRxSequence);
tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
tcpHeader.SetDestinationPort (m_remotePort);
tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
tcpHeader.SetWindowSize (AdvertisedWindowSize());
m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
m_remoteAddress, m_boundnetdevice);
m_endPoint->GetPeerAddress (), m_boundnetdevice);
NS_LOG_LOGIC ("Schedule persist timeout at time "
<<Simulator::Now ().GetSeconds () << " to expire at time "
<< (Simulator::Now () + m_persistTime).GetSeconds());
@@ -1692,12 +1666,12 @@ void TcpSocketImpl::Retransmit ()
tcpHeader.SetSequenceNumber (m_nextTxSequence);
tcpHeader.SetAckNumber (m_nextRxSequence);
tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
tcpHeader.SetDestinationPort (m_remotePort);
tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
tcpHeader.SetFlags (flags);
tcpHeader.SetWindowSize (AdvertisedWindowSize());
m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
m_remoteAddress, m_boundnetdevice);
m_endPoint->GetPeerAddress (), m_boundnetdevice);
}
void
+6 -9
View File
@@ -101,7 +101,7 @@ private:
friend class Tcp;
// invoked by Tcp class
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
void Destroy (void);
int DoSendTo (Ptr<Packet> p, const Address &daddr);
int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
@@ -114,10 +114,11 @@ private:
Ipv4Address saddr, Ipv4Address daddr);
bool ProcessPacketAction (Actions_t a, Ptr<Packet> p,
const TcpHeader& tcpHeader,
const Address& fromAddress);
const Address& fromAddress,
const Address& toAddress);
Actions_t ProcessEvent (Events_t e);
bool SendPendingData(bool withAck = false);
void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAddress);
void ConnectionSucceeded();
//methods for window management
@@ -131,7 +132,7 @@ private:
uint16_t AdvertisedWindowSize();
// Manage data tx/rx
void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
void NewRx (Ptr<Packet>, const TcpHeader&, const Address& fromAddress, const Address& toAddress);
void RxBufFinishInsert (SequenceNumber);
Ptr<TcpSocketImpl> Copy ();
virtual void NewAck (SequenceNumber seq);
@@ -178,11 +179,7 @@ private:
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
Ptr<TcpL4Protocol> m_tcp;
Ipv4Address m_remoteAddress;
uint16_t m_remotePort;
//these two are so that the socket/endpoint cloning works
Ipv4Address m_localAddress;
uint16_t m_localPort;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
+1 -1
View File
@@ -230,7 +230,7 @@ UdpL4Protocol::Receive(Ptr<Packet> packet,
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
endPoint != endPoints.end (); endPoint++)
{
(*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
(*endPoint)->ForwardUp (packet->Copy (), source, destination, udpHeader.GetSourcePort ());
}
return Ipv4L4Protocol::RX_OK;
}
+3 -3
View File
@@ -583,9 +583,9 @@ UdpSocketImpl::BindToNetDevice (Ptr<NetDevice> netdevice)
}
void
UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port)
{
NS_LOG_FUNCTION (this << packet << ipv4 << port);
NS_LOG_FUNCTION (this << packet << saddr << daddr << port);
if (m_shutdownRecv)
{
@@ -593,7 +593,7 @@ UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
}
if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
{
Address address = InetSocketAddress (ipv4, port);
Address address = InetSocketAddress (saddr, port);
SocketAddressTag tag;
tag.SetAddress (address);
packet->AddPacketTag (tag);
+1 -1
View File
@@ -98,7 +98,7 @@ private:
friend class UdpSocketFactory;
// invoked by Udp class
int FinishBind (void);
void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port);
void Destroy (void);
int DoSend (Ptr<Packet> p);
int DoSendTo (Ptr<Packet> p, const Address &daddr);
+10 -2
View File
@@ -72,8 +72,16 @@ Ipv4Mask::Ipv4Mask (char const *mask)
{
if (*mask == ASCII_SLASH)
{
m_mask = static_cast<uint32_t> (atoi (++mask));
NS_ASSERT (m_mask <= 32);
uint32_t plen = static_cast<uint32_t> (atoi (++mask));
NS_ASSERT (plen <= 32);
if (plen > 0)
{
m_mask = 0xffffffff << (32 - plen);
}
else
{
m_mask = 0;
}
}
else
{
+360
View File
@@ -0,0 +1,360 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2010 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/log.h"
#include "ns3/abort.h"
#include "ns3/test.h"
#include "ns3/pcap-file.h"
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/uinteger.h"
#include "ns3/data-rate.h"
#include "ns3/inet-socket-address.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/csma-helper.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/tcp-socket-factory.h"
#include "ns3/node-container.h"
#include "ns3/simulator.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("Ns3SocketTest");
// ===========================================================================
// Tests of TCP implementations from the application/socket perspective
// ===========================================================================
//
//
// Simple class to write data to sockets
class SocketWriter : public Application
{
public:
SocketWriter ();
virtual ~SocketWriter ();
void Setup (Ptr<Node> node, Address peer);
void Connect ();
void Write (uint32_t numBytes);
void Close ();
private:
virtual void StartApplication (void);
virtual void StopApplication (void);
Address m_peer;
Ptr<Node> m_node;
Ptr<Socket> m_socket;
bool m_isSetup;
bool m_isConnected;
};
SocketWriter::SocketWriter () : m_node (0), m_socket (0), m_isSetup (false), m_isConnected (false)
{
}
SocketWriter::~SocketWriter ()
{
m_socket = 0;
m_node = 0;
}
void
SocketWriter::StartApplication ()
{
m_socket = Socket::CreateSocket (m_node, TcpSocketFactory::GetTypeId ());
m_socket->Bind ();
}
void
SocketWriter::StopApplication ()
{
}
void
SocketWriter::Setup (Ptr<Node> node, Address peer)
{
m_peer = peer;
m_node = node;
m_isSetup = true;
}
void
SocketWriter::Connect ()
{
if (!m_isSetup)
{
NS_FATAL_ERROR ("Forgot to call Setup() first");
}
m_socket->Connect (m_peer);
m_isConnected = true;
}
void
SocketWriter::Write (uint32_t numBytes)
{
if (!m_isConnected)
{
Connect ();
}
Ptr<Packet> packet = Create<Packet> (numBytes);
m_socket->Send (packet);
}
void
SocketWriter::Close ()
{
m_socket->Close ();
}
class Ns3TcpSocketTestCase1 : public TestCase
{
public:
Ns3TcpSocketTestCase1 ();
virtual ~Ns3TcpSocketTestCase1 () {}
private:
virtual bool DoRun (void);
bool m_writeResults;
void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
TestVectors<uint32_t> m_inputs;
TestVectors<uint32_t> m_responses;
};
Ns3TcpSocketTestCase1::Ns3TcpSocketTestCase1 ()
: TestCase ("Check that ns-3 TCP successfully transfers an application data write of various sizes (point-to-point)"),
m_writeResults (false)
{
}
void
Ns3TcpSocketTestCase1::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
{
m_responses.Add (p->GetSize ());
}
bool
Ns3TcpSocketTestCase1::DoRun (void)
{
uint16_t sinkPort = 50000;
double sinkStopTime = 40; // sec; will trigger Socket::Close
double writerStopTime = 30; // sec; will trigger Socket::Close
double simStopTime = 60; // sec
Time sinkStopTimeObj = Seconds (sinkStopTime);
Time writerStopTimeObj = Seconds (writerStopTime);
Time simStopTimeObj= Seconds (simStopTime);
Ptr<Node> n0 = CreateObject<Node> ();
Ptr<Node> n1 = CreateObject<Node> ();
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
devices = pointToPoint.Install (n0, n1);
InternetStackHelper internet;
internet.InstallAll ();
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.252");
Ipv4InterfaceContainer ifContainer = address.Assign (devices);
Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
socketWriter->Setup (n0, sinkAddress);
n0->AddApplication (socketWriter);
socketWriter->SetStartTime (Seconds (0.));
socketWriter->SetStopTime (writerStopTimeObj);
PacketSinkHelper sink ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
ApplicationContainer apps = sink.Install (n1);
// Start the sink application at time zero, and stop it at sinkStopTime
apps.Start (Seconds (0.0));
apps.Stop (sinkStopTimeObj);
Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
MakeCallback (&Ns3TcpSocketTestCase1::SinkRx, this));
Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
// Send 1, 10, 100, 1000 bytes
Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 1);
m_inputs.Add (1);
Simulator::Schedule(Seconds (12), &SocketWriter::Write, socketWriter, 10);
m_inputs.Add (10);
Simulator::Schedule(Seconds (14), &SocketWriter::Write, socketWriter, 100);
m_inputs.Add (100);
Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1000);
m_inputs.Add (536);
m_inputs.Add (464); // ns-3 TCP default segment size of 536
Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
if (m_writeResults)
{
pointToPoint.EnablePcapAll ("tcp-socket-test-case-1");
}
Simulator::Stop (simStopTimeObj);
Simulator::Run ();
Simulator::Destroy ();
// Compare inputs and outputs
NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
for (uint32_t i = 0; i < m_responses.GetN (); i++)
{
uint32_t in = m_inputs.Get (i);
uint32_t out = m_responses.Get (i);
NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes");
}
return GetErrorStatus ();
}
class Ns3TcpSocketTestCase2 : public TestCase
{
public:
Ns3TcpSocketTestCase2 ();
virtual ~Ns3TcpSocketTestCase2 () {}
private:
virtual bool DoRun (void);
bool m_writeResults;
void SinkRx (std::string path, Ptr<const Packet> p, const Address &address);
TestVectors<uint32_t> m_inputs;
TestVectors<uint32_t> m_responses;
};
Ns3TcpSocketTestCase2::Ns3TcpSocketTestCase2 ()
: TestCase ("Check to see that ns-3 TCP successfully transfers an application data write of various sizes (CSMA)"),
m_writeResults (false)
{
}
void
Ns3TcpSocketTestCase2::SinkRx (std::string path, Ptr<const Packet> p, const Address &address)
{
m_responses.Add (p->GetSize ());
}
bool
Ns3TcpSocketTestCase2::DoRun (void)
{
uint16_t sinkPort = 50000;
double sinkStopTime = 40; // sec; will trigger Socket::Close
double writerStopTime = 30; // sec; will trigger Socket::Close
double simStopTime = 60; // sec
Time sinkStopTimeObj = Seconds (sinkStopTime);
Time writerStopTimeObj = Seconds (writerStopTime);
Time simStopTimeObj= Seconds (simStopTime);
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000));
NodeContainer nodes;
nodes.Create (2);
Ptr<Node> n0 = nodes.Get (0);
Ptr<Node> n1 = nodes.Get (1);
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
devices = csma.Install (nodes);
InternetStackHelper internet;
internet.InstallAll ();
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.252");
Ipv4InterfaceContainer ifContainer = address.Assign (devices);
Ptr<SocketWriter> socketWriter = CreateObject<SocketWriter> ();
Address sinkAddress (InetSocketAddress (ifContainer.GetAddress (1), sinkPort));
socketWriter->Setup (n0, sinkAddress);
n0->AddApplication (socketWriter);
socketWriter->SetStartTime (Seconds (0.));
socketWriter->SetStopTime (writerStopTimeObj);
PacketSinkHelper sink ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
ApplicationContainer apps = sink.Install (n1);
// Start the sink application at time zero, and stop it at sinkStopTime
apps.Start (Seconds (0.0));
apps.Stop (sinkStopTimeObj);
Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx",
MakeCallback (&Ns3TcpSocketTestCase2::SinkRx, this));
Simulator::Schedule(Seconds (2), &SocketWriter::Connect, socketWriter);
// Send 1, 10, 100, 1000 bytes
// PointToPoint default MTU is 576 bytes, which leaves 536 bytes for TCP
Simulator::Schedule(Seconds (10), &SocketWriter::Write, socketWriter, 1);
m_inputs.Add (1);
Simulator::Schedule(Seconds (12), &SocketWriter::Write, socketWriter, 10);
m_inputs.Add (10);
Simulator::Schedule(Seconds (14), &SocketWriter::Write, socketWriter, 100);
m_inputs.Add (100);
Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1000);
m_inputs.Add (1000);
// Next packet will fragment
Simulator::Schedule(Seconds (16), &SocketWriter::Write, socketWriter, 1001);
m_inputs.Add (1000);
m_inputs.Add (1);
Simulator::Schedule(writerStopTimeObj, &SocketWriter::Close, socketWriter);
if (m_writeResults)
{
csma.EnablePcapAll ("tcp-socket-test-case-2", false);
}
Simulator::Stop (simStopTimeObj);
Simulator::Run ();
Simulator::Destroy ();
// Compare inputs and outputs
NS_TEST_ASSERT_MSG_EQ (m_inputs.GetN (), m_responses.GetN (), "Incorrect number of expected receive events");
for (uint32_t i = 0; i < m_responses.GetN (); i++)
{
uint32_t in = m_inputs.Get (i);
uint32_t out = m_responses.Get (i);
NS_TEST_ASSERT_MSG_EQ (in, out, "Mismatch: expected " << in << " bytes, got " << out << " bytes");
}
return GetErrorStatus ();
}
class Ns3TcpSocketTestSuite : public TestSuite
{
public:
Ns3TcpSocketTestSuite ();
};
Ns3TcpSocketTestSuite::Ns3TcpSocketTestSuite ()
: TestSuite ("ns3-tcp-socket", SYSTEM)
{
AddTestCase (new Ns3TcpSocketTestCase1);
AddTestCase (new Ns3TcpSocketTestCase2);
}
Ns3TcpSocketTestSuite ns3TcpSocketTestSuite;
+2 -1
View File
@@ -13,5 +13,6 @@ def build(bld):
if bld.env['NSC_ENABLED']:
ns3tcp.source = [
'ns3tcp-interop-test-suite.cc',
'ns3tcp-cwnd-test-suite.cc'
'ns3tcp-cwnd-test-suite.cc',
'ns3tcp-socket-test-suite.cc'
]
+6 -3
View File
@@ -697,12 +697,14 @@ class run_python_unit_tests_task(Task.TaskBase):
self.bld.env, proc_env, force_no_valgrind=True)
def check_shell(bld):
if 'NS3_MODULE_PATH' not in os.environ:
if ('NS3_MODULE_PATH' not in os.environ) or ('NS3_EXECUTABLE_PATH' not in os.environ):
return
env = bld.env
correct_modpath = os.pathsep.join(env['NS3_MODULE_PATH'])
found_modpath = os.environ['NS3_MODULE_PATH']
if found_modpath != correct_modpath:
correct_execpath = os.pathsep.join(env['NS3_EXECUTABLE_PATH'])
found_execpath = os.environ['NS3_EXECUTABLE_PATH']
if (found_modpath != correct_modpath) or (correct_execpath != found_execpath):
msg = ("Detected shell (./waf shell) with incorrect configuration\n"
"=========================================================\n"
"Possible reasons for this problem:\n"
@@ -728,7 +730,8 @@ def shell(ctx):
shell = os.environ.get("SHELL", "/bin/sh")
env = wutils.bld.env
wutils.run_argv([shell], env, {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH'])})
os_env = {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH']), 'NS3_EXECUTABLE_PATH': os.pathsep.join(env['NS3_EXECUTABLE_PATH'])}
wutils.run_argv([shell], env, os_env)
def _doxygen(bld):
env = wutils.bld.env
+5
View File
@@ -112,6 +112,11 @@ def get_proc_env(os_env=None):
else:
proc_env['PYTHONPATH'] = pymoddir
if 'PATH' in proc_env:
proc_env['PATH'] = os.pathsep.join(list(env['NS3_EXECUTABLE_PATH']) + [proc_env['PATH']])
else:
proc_env['PATH'] = os.pathsep.join(list(env['NS3_EXECUTABLE_PATH']))
return proc_env
def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):