branch merge
This commit is contained in:
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -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'
|
||||
]
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in new issue
Block a user