wifi: Add frame capture support
This commit is contained in:
@@ -55,9 +55,17 @@
|
||||
#include "ns3/propagation-delay-model.h"
|
||||
#include "ns3/nist-error-rate-model.h"
|
||||
#include "ns3/constant-position-mobility-model.h"
|
||||
#include "ns3/simple-frame-capture-model.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("test-interference-helper");
|
||||
|
||||
bool checkResults = false;
|
||||
bool expectRxASuccessfull = false;
|
||||
bool expectRxBSuccessfull = false;
|
||||
|
||||
/// InterferenceExperiment
|
||||
class InterferenceExperiment
|
||||
{
|
||||
@@ -71,12 +79,14 @@ public:
|
||||
double xB; ///< x B
|
||||
std::string txModeA; ///< transmit mode A
|
||||
std::string txModeB; ///< transmit mode B
|
||||
uint32_t txPowerLevelA; ///< transmit power level A
|
||||
uint32_t txPowerLevelB; ///< transmit power level B
|
||||
double txPowerLevelA; ///< transmit power level A
|
||||
double txPowerLevelB; ///< transmit power level B
|
||||
uint32_t packetSizeA; ///< packet size A
|
||||
uint32_t packetSizeB; ///< packet size B
|
||||
WifiPhyStandard standard; ///< standard
|
||||
WifiPreamble preamble; ///< preamble
|
||||
bool captureEnabled; ///< whether physical layer capture is enabled
|
||||
double captureMargin; ///< margin used for physical layer capture
|
||||
};
|
||||
|
||||
InterferenceExperiment ();
|
||||
@@ -87,6 +97,8 @@ public:
|
||||
void Run (struct InterferenceExperiment::Input input);
|
||||
|
||||
private:
|
||||
/// Function triggered when a packet is dropped
|
||||
void PacketDropped(Ptr<const Packet> packet);
|
||||
/// Send A function
|
||||
void SendA (void) const;
|
||||
/// Send B function
|
||||
@@ -94,6 +106,8 @@ private:
|
||||
Ptr<YansWifiPhy> m_txA; ///< transmit A function
|
||||
Ptr<YansWifiPhy> m_txB; ///< transmit B function
|
||||
struct Input m_input; ///< input
|
||||
bool m_droppedA; ///< flag to indicate whether packet A has been dropped
|
||||
bool m_droppedB; ///< flag to indicate whether packet B has been dropped
|
||||
};
|
||||
|
||||
void
|
||||
@@ -118,21 +132,44 @@ InterferenceExperiment::SendB (void) const
|
||||
m_txB->SendPacket (p, txVector);
|
||||
}
|
||||
|
||||
void
|
||||
InterferenceExperiment::PacketDropped(Ptr<const Packet> packet)
|
||||
{
|
||||
if (packet->GetUid () == 0)
|
||||
{
|
||||
m_droppedA = true;
|
||||
}
|
||||
else if (packet->GetUid () == 1)
|
||||
{
|
||||
m_droppedB = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_ERROR ("Unknown packet!");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
InterferenceExperiment::InterferenceExperiment ()
|
||||
: m_droppedA (false),
|
||||
m_droppedB (false)
|
||||
{
|
||||
}
|
||||
|
||||
InterferenceExperiment::Input::Input ()
|
||||
: interval (MicroSeconds (0)),
|
||||
xA (-5),
|
||||
xB (5),
|
||||
txModeA ("OfdmRate54Mbps"),
|
||||
txModeB ("OfdmRate54Mbps"),
|
||||
txPowerLevelA (0),
|
||||
txPowerLevelB (0),
|
||||
txPowerLevelA (16.0206),
|
||||
txPowerLevelB (16.0206),
|
||||
packetSizeA (1500),
|
||||
packetSizeB (1500),
|
||||
standard (WIFI_PHY_STANDARD_80211a),
|
||||
preamble (WIFI_PREAMBLE_LONG)
|
||||
preamble (WIFI_PREAMBLE_LONG),
|
||||
captureEnabled (false),
|
||||
captureMargin (0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -157,7 +194,11 @@ InterferenceExperiment::Run (struct InterferenceExperiment::Input input)
|
||||
posRx->SetPosition (Vector (0.0, 0.0, 0.0));
|
||||
|
||||
m_txA = CreateObject<YansWifiPhy> ();
|
||||
m_txA->SetTxPowerStart (input.txPowerLevelA);
|
||||
m_txA->SetTxPowerEnd (input.txPowerLevelA);
|
||||
m_txB = CreateObject<YansWifiPhy> ();
|
||||
m_txB->SetTxPowerStart (input.txPowerLevelB);
|
||||
m_txB->SetTxPowerEnd (input.txPowerLevelB);
|
||||
Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy> ();
|
||||
|
||||
Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
|
||||
@@ -170,18 +211,31 @@ InterferenceExperiment::Run (struct InterferenceExperiment::Input input)
|
||||
m_txA->SetMobility (posTxA);
|
||||
m_txB->SetMobility (posTxB);
|
||||
rx->SetMobility (posRx);
|
||||
if (input.captureEnabled)
|
||||
{
|
||||
Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
|
||||
frameCaptureModel->SetMargin (input.captureMargin);
|
||||
rx->SetFrameCaptureModel (frameCaptureModel);
|
||||
}
|
||||
|
||||
m_txA->ConfigureStandard (input.standard);
|
||||
m_txB->ConfigureStandard (input.standard);
|
||||
rx->ConfigureStandard (input.standard);
|
||||
|
||||
rx->TraceConnectWithoutContext("PhyRxDrop", MakeCallback(&InterferenceExperiment::PacketDropped, this));
|
||||
|
||||
Simulator::Schedule (Seconds (0), &InterferenceExperiment::SendA, this);
|
||||
Simulator::Schedule (Seconds (0) + input.interval, &InterferenceExperiment::SendB, this);
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
if(checkResults && (m_droppedA == expectRxASuccessfull || m_droppedB == expectRxBSuccessfull))
|
||||
{
|
||||
NS_LOG_ERROR ("Results are not expected!");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
@@ -202,10 +256,17 @@ int main (int argc, char *argv[])
|
||||
cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
|
||||
cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
|
||||
cmd.AddValue ("preamble", "Type of preamble", str_preamble);
|
||||
cmd.AddValue ("enableCapture", "Enable/disable physical layer capture", input.captureEnabled);
|
||||
cmd.AddValue ("captureMargin", "Margin used for physical layer capture", input.captureMargin);
|
||||
cmd.AddValue ("checkResults", "Used to check results at the end of the test", checkResults);
|
||||
cmd.AddValue ("expectRxASuccessfull", "Indicate whether packet A is expected to be successfully received", expectRxASuccessfull);
|
||||
cmd.AddValue ("expectRxBSuccessfull", "Indicate whether packet B is expected to be successfully received", expectRxBSuccessfull);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
LogComponentEnable ("WifiPhy", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("InterferenceHelper", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("SimpleFrameCaptureModel", LOG_LEVEL_ALL);
|
||||
|
||||
input.interval = MicroSeconds (delay);
|
||||
|
||||
|
||||
36
src/wifi/model/frame-capture-model.cc
Normal file
36
src/wifi/model/frame-capture-model.cc
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include "frame-capture-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (FrameCaptureModel);
|
||||
|
||||
TypeId FrameCaptureModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::FrameCaptureModel")
|
||||
.SetParent<Object> ()
|
||||
.SetGroupName ("Wifi")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
60
src/wifi/model/frame-capture-model.h
Normal file
60
src/wifi/model/frame-capture-model.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef FRAME_CAPTURE_MODEL_H
|
||||
#define FRAME_CAPTURE_MODEL_H
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "interference-helper.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
* \brief the interface for Wifi's frame capture models
|
||||
*
|
||||
*/
|
||||
class FrameCaptureModel : public Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* A pure virtual method that must be implemented in the subclass.
|
||||
* This method returns whether the reception should be switched to a
|
||||
* new incoming frame.
|
||||
*
|
||||
* \param currentEvent the event of the current frame
|
||||
* \param newEvent the event of the new incoming frame
|
||||
*
|
||||
* \return true if the reception should be switched to a new incoming frame,
|
||||
* false otherwise
|
||||
*/
|
||||
virtual bool CaptureNewFrame (Ptr<InterferenceHelper::Event> currentEvent, Ptr<InterferenceHelper::Event> newEvent) const = 0;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* FRAME_CAPTURE_MODEL_H */
|
||||
|
||||
@@ -33,8 +33,9 @@ NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
|
||||
* Phy event class
|
||||
****************************************************************/
|
||||
|
||||
InterferenceHelper::Event::Event (WifiTxVector txVector, Time duration, double rxPower)
|
||||
: m_txVector (txVector),
|
||||
InterferenceHelper::Event::Event (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPower)
|
||||
: m_packet (packet),
|
||||
m_txVector (txVector),
|
||||
m_startTime (Simulator::Now ()),
|
||||
m_endTime (m_startTime + duration),
|
||||
m_rxPowerW (rxPower)
|
||||
@@ -45,6 +46,12 @@ InterferenceHelper::Event::~Event ()
|
||||
{
|
||||
}
|
||||
|
||||
Ptr<const Packet>
|
||||
InterferenceHelper::Event::GetPacket (void) const
|
||||
{
|
||||
return m_packet;
|
||||
}
|
||||
|
||||
Time
|
||||
InterferenceHelper::Event::GetDuration (void) const
|
||||
{
|
||||
@@ -87,9 +94,10 @@ InterferenceHelper::Event::GetPayloadMode (void) const
|
||||
* short period of time.
|
||||
****************************************************************/
|
||||
|
||||
InterferenceHelper::NiChange::NiChange (Time time, double delta)
|
||||
InterferenceHelper::NiChange::NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event)
|
||||
: m_time (time),
|
||||
m_delta (delta)
|
||||
m_delta (delta),
|
||||
m_event (event)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -105,6 +113,12 @@ InterferenceHelper::NiChange::GetDelta (void) const
|
||||
return m_delta;
|
||||
}
|
||||
|
||||
Ptr<InterferenceHelper::Event>
|
||||
InterferenceHelper::NiChange::GetEvent (void) const
|
||||
{
|
||||
return m_event;
|
||||
}
|
||||
|
||||
bool
|
||||
InterferenceHelper::NiChange::operator < (const InterferenceHelper::NiChange& o) const
|
||||
{
|
||||
@@ -131,11 +145,10 @@ InterferenceHelper::~InterferenceHelper ()
|
||||
}
|
||||
|
||||
Ptr<InterferenceHelper::Event>
|
||||
InterferenceHelper::Add (WifiTxVector txVector, Time duration, double rxPowerW)
|
||||
InterferenceHelper::Add (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPowerW)
|
||||
{
|
||||
Ptr<InterferenceHelper::Event> event;
|
||||
|
||||
event = Create<InterferenceHelper::Event> (txVector, duration, rxPowerW);
|
||||
event = Create<InterferenceHelper::Event> (packet, txVector, duration, rxPowerW);
|
||||
AppendEvent (event);
|
||||
return event;
|
||||
}
|
||||
@@ -146,7 +159,8 @@ InterferenceHelper::AddForeignSignal (Time duration, double rxPowerW)
|
||||
// Parameters other than duration and rxPowerW are unused for this type
|
||||
// of signal, so we provide dummy versions
|
||||
WifiTxVector fakeTxVector;
|
||||
Add (fakeTxVector, duration, rxPowerW);
|
||||
Ptr<const Packet> packet (0);
|
||||
Add (packet, fakeTxVector, duration, rxPowerW);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -214,13 +228,13 @@ InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event)
|
||||
m_firstPower += i->GetDelta ();
|
||||
}
|
||||
m_niChanges.erase (m_niChanges.begin (), nowIterator);
|
||||
m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW ()));
|
||||
m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW (), event));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW ()));
|
||||
AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW (), event));
|
||||
}
|
||||
AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW ()));
|
||||
AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW (), event));
|
||||
|
||||
}
|
||||
|
||||
@@ -244,17 +258,41 @@ double
|
||||
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const
|
||||
{
|
||||
double noiseInterference = m_firstPower;
|
||||
NS_ASSERT (m_rxing);
|
||||
for (NiChanges::const_iterator i = m_niChanges.begin () + 1; i != m_niChanges.end (); i++)
|
||||
NiChanges::const_iterator eventIterator = m_niChanges.begin ();
|
||||
while (eventIterator != m_niChanges.end ())
|
||||
{
|
||||
if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ())
|
||||
// Iterate the NI change list from the beginning to the end
|
||||
// until find the position of the event in the NI change list
|
||||
// The reason of using the event that causes the NI change to identify
|
||||
// different NI changes is because in some special cases
|
||||
// different NI changes happen at the same time with the same delta
|
||||
// value. Therefore, it may be impossible to identify a NI change that belongs
|
||||
// to which event based on just the NI time and NI delta value
|
||||
if (eventIterator->GetEvent () != event)
|
||||
{
|
||||
// The NI changes which happen before the event should be considered
|
||||
// as the interference. This considers the case that the receiving event
|
||||
// arrives while another receiving event is going on. The SINR of
|
||||
// the newly arrived event is calculated for checking the possibility of frame capture
|
||||
noiseInterference += eventIterator->GetDelta ();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
++eventIterator;
|
||||
}
|
||||
|
||||
for (NiChanges::const_iterator i = eventIterator + 1; i != m_niChanges.end (); ++i)
|
||||
{
|
||||
if (event->GetEndTime () == i->GetTime () && event == i->GetEvent ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
ni->push_back (*i);
|
||||
}
|
||||
ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference));
|
||||
ni->push_back (NiChange (event->GetEndTime (), 0));
|
||||
ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference, event));
|
||||
ni->push_back (NiChange (event->GetEndTime (), 0, event));
|
||||
return noiseInterference;
|
||||
}
|
||||
|
||||
@@ -840,7 +878,7 @@ InterferenceHelper::EraseEvents (void)
|
||||
InterferenceHelper::NiChanges::iterator
|
||||
InterferenceHelper::GetPosition (Time moment)
|
||||
{
|
||||
return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0));
|
||||
return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define INTERFERENCE_HELPER_H
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
#include "error-rate-model.h"
|
||||
|
||||
@@ -43,13 +44,19 @@ public:
|
||||
/**
|
||||
* Create an Event with the given parameters.
|
||||
*
|
||||
* \param packet the packet
|
||||
* \param txVector TXVECTOR of the packet
|
||||
* \param duration duration of the signal
|
||||
* \param rxPower the receive power (w)
|
||||
*/
|
||||
Event (WifiTxVector txVector, Time duration, double rxPower);
|
||||
Event (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPower);
|
||||
~Event ();
|
||||
|
||||
/** Return the packet.
|
||||
*
|
||||
* \return the packet
|
||||
*/
|
||||
Ptr<const Packet> GetPacket (void) const;
|
||||
/**
|
||||
* Return the duration of the signal.
|
||||
*
|
||||
@@ -89,6 +96,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
Ptr<const Packet> m_packet; ///< packet
|
||||
WifiTxVector m_txVector; ///< TXVECTOR
|
||||
Time m_startTime; ///< start time
|
||||
Time m_endTime; ///< end time
|
||||
@@ -152,13 +160,14 @@ private:
|
||||
/**
|
||||
* Add the packet-related signal to interference helper.
|
||||
*
|
||||
* \param packet the packet
|
||||
* \param txVector TXVECTOR of the packet
|
||||
* \param duration the duration of the signal
|
||||
* \param rxPower receive power (W)
|
||||
*
|
||||
* \return InterferenceHelper::Event
|
||||
*/
|
||||
Ptr<InterferenceHelper::Event> Add (WifiTxVector txVector, Time duration, double rxPower);
|
||||
Ptr<InterferenceHelper::Event> Add (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPower);
|
||||
|
||||
/**
|
||||
* Add a non-Wifi signal to interference helper.
|
||||
@@ -211,8 +220,9 @@ public:
|
||||
*
|
||||
* \param time time of the event
|
||||
* \param delta the power
|
||||
* \param event causes this NI change
|
||||
*/
|
||||
NiChange (Time time, double delta);
|
||||
NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event);
|
||||
/**
|
||||
* Return the event time.
|
||||
*
|
||||
@@ -225,6 +235,12 @@ public:
|
||||
* \return the power
|
||||
*/
|
||||
double GetDelta (void) const;
|
||||
/**
|
||||
* Return the event causes the corresponding NI change
|
||||
*
|
||||
* \return the event
|
||||
*/
|
||||
Ptr<InterferenceHelper::Event> GetEvent (void) const;
|
||||
/**
|
||||
* Compare the event time of two NiChange objects (a < o).
|
||||
*
|
||||
@@ -237,6 +253,7 @@ public:
|
||||
private:
|
||||
Time m_time; ///< time
|
||||
double m_delta; ///< delta
|
||||
Ptr<InterferenceHelper::Event> m_event;
|
||||
};
|
||||
/**
|
||||
* typedef for a vector of NiChanges
|
||||
@@ -309,6 +326,7 @@ private:
|
||||
NiChanges m_niChanges;
|
||||
double m_firstPower; ///< first power
|
||||
bool m_rxing; ///< flag whether it is in receiving state
|
||||
|
||||
/// Returns an iterator to the first nichange, which is later than moment
|
||||
NiChanges::iterator GetPosition (Time moment);
|
||||
/**
|
||||
|
||||
88
src/wifi/model/simple-frame-capture-model.cc
Normal file
88
src/wifi/model/simple-frame-capture-model.cc
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include "simple-frame-capture-model.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/double.h"
|
||||
#include "wifi-utils.h"
|
||||
#include "wifi-phy.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SimpleFrameCaptureModel");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (SimpleFrameCaptureModel);
|
||||
|
||||
TypeId
|
||||
SimpleFrameCaptureModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::SimpleFrameCaptureModel")
|
||||
.SetParent<FrameCaptureModel> ()
|
||||
.SetGroupName ("Wifi")
|
||||
.AddConstructor<SimpleFrameCaptureModel> ()
|
||||
.AddAttribute ("Margin",
|
||||
"Reception is switched if the newly arrived frame has a power higher than "
|
||||
"this value above the frame currently being received (expressed in dB).",
|
||||
DoubleValue (10),
|
||||
MakeDoubleAccessor (&SimpleFrameCaptureModel::GetMargin,
|
||||
&SimpleFrameCaptureModel::SetMargin),
|
||||
MakeDoubleChecker<double> ())
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
SimpleFrameCaptureModel::SimpleFrameCaptureModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
SimpleFrameCaptureModel::~SimpleFrameCaptureModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
void
|
||||
SimpleFrameCaptureModel::SetMargin (double margin)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << margin);
|
||||
m_margin = margin;
|
||||
}
|
||||
|
||||
double
|
||||
SimpleFrameCaptureModel::GetMargin (void) const
|
||||
{
|
||||
return m_margin;
|
||||
}
|
||||
|
||||
bool
|
||||
SimpleFrameCaptureModel::CaptureNewFrame (Ptr<InterferenceHelper::Event> currentEvent, Ptr<InterferenceHelper::Event> newEvent) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (newEvent->GetTxVector ().GetPreambleType () != WIFI_PREAMBLE_NONE
|
||||
&& (WToDbm (currentEvent->GetRxPowerW ()) + m_margin) < WToDbm (newEvent->GetRxPowerW ())
|
||||
&& ((currentEvent->GetStartTime () + WifiPhy::CalculatePlcpPreambleAndHeaderDuration (currentEvent->GetTxVector ())) > Simulator::Now ()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
82
src/wifi/model/simple-frame-capture-model.h
Normal file
82
src/wifi/model/simple-frame-capture-model.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef SIMPLE_FRAME_CAPTURE_MODEL_H
|
||||
#define SIMPLE_FRAME_CAPTURE_MODEL_H
|
||||
|
||||
#include "frame-capture-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
/**
|
||||
* \ingroup wifi
|
||||
*
|
||||
* A simple threshold-based model for frame capture effect.
|
||||
* If the new incoming frame arrives while the receiver is
|
||||
* receiving the preamble of another frame and the SIR of
|
||||
* the new incoming frame is above a fixed margin, then
|
||||
* the current frame is dropped and the receiver locks
|
||||
* onto the new incoming frame.
|
||||
*/
|
||||
class SimpleFrameCaptureModel : public FrameCaptureModel
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
SimpleFrameCaptureModel ();
|
||||
~SimpleFrameCaptureModel ();
|
||||
|
||||
/**
|
||||
* Sets the frame capture margin (dB).
|
||||
*
|
||||
* \param margin the frame capture margin in dB
|
||||
*/
|
||||
void SetMargin (double margin);
|
||||
/**
|
||||
* Return the frame capture margin (dB).
|
||||
*
|
||||
* \return the frame capture margin in dB
|
||||
*/
|
||||
double GetMargin (void) const;
|
||||
|
||||
/**
|
||||
* This method returns whether the reception should be switched to a
|
||||
* new incoming frame.
|
||||
*
|
||||
* \param currentEvent the event of the current frame
|
||||
* \param newEvent the event of the new incoming frame
|
||||
*
|
||||
* \return true if the reception should be switched to a new incoming frame,
|
||||
* false otherwise
|
||||
*/
|
||||
bool CaptureNewFrame (Ptr<InterferenceHelper::Event> currentEvent, Ptr<InterferenceHelper::Event> newEvent) const;
|
||||
|
||||
|
||||
private:
|
||||
double m_margin;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* SIMPLE_FRAME_CAPTURE_MODEL_H */
|
||||
|
||||
@@ -221,6 +221,7 @@ WifiPhyStateHelper::GetState (void) const
|
||||
void
|
||||
WifiPhyStateHelper::NotifyTxStart (Time duration, double txPowerDbm)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyTxStart (duration, txPowerDbm);
|
||||
@@ -230,6 +231,7 @@ WifiPhyStateHelper::NotifyTxStart (Time duration, double txPowerDbm)
|
||||
void
|
||||
WifiPhyStateHelper::NotifyRxStart (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyRxStart (duration);
|
||||
@@ -239,6 +241,7 @@ WifiPhyStateHelper::NotifyRxStart (Time duration)
|
||||
void
|
||||
WifiPhyStateHelper::NotifyRxEndOk (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyRxEndOk ();
|
||||
@@ -248,6 +251,7 @@ WifiPhyStateHelper::NotifyRxEndOk (void)
|
||||
void
|
||||
WifiPhyStateHelper::NotifyRxEndError (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyRxEndError ();
|
||||
@@ -257,6 +261,7 @@ WifiPhyStateHelper::NotifyRxEndError (void)
|
||||
void
|
||||
WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyMaybeCcaBusyStart (duration);
|
||||
@@ -266,6 +271,7 @@ WifiPhyStateHelper::NotifyMaybeCcaBusyStart (Time duration)
|
||||
void
|
||||
WifiPhyStateHelper::NotifySwitchingStart (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifySwitchingStart (duration);
|
||||
@@ -275,6 +281,7 @@ WifiPhyStateHelper::NotifySwitchingStart (Time duration)
|
||||
void
|
||||
WifiPhyStateHelper::NotifySleep (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifySleep ();
|
||||
@@ -284,6 +291,7 @@ WifiPhyStateHelper::NotifySleep (void)
|
||||
void
|
||||
WifiPhyStateHelper::NotifyWakeup (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++)
|
||||
{
|
||||
(*i)->NotifyWakeup ();
|
||||
@@ -293,6 +301,7 @@ WifiPhyStateHelper::NotifyWakeup (void)
|
||||
void
|
||||
WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Time now = Simulator::Now ();
|
||||
Time idleStart = Max (m_endCcaBusy, m_endRx);
|
||||
idleStart = Max (idleStart, m_endTx);
|
||||
@@ -314,6 +323,7 @@ void
|
||||
WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, double txPowerDbm,
|
||||
WifiTxVector txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << txDuration << packet << txPowerDbm << txVector);
|
||||
m_txTrace (packet, txVector.GetMode (), txVector.GetPreambleType (), txVector.GetTxPowerLevel ());
|
||||
Time now = Simulator::Now ();
|
||||
switch (GetState ())
|
||||
@@ -352,6 +362,7 @@ WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> packet, doubl
|
||||
void
|
||||
WifiPhyStateHelper::SwitchToRx (Time rxDuration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << rxDuration);
|
||||
NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
|
||||
NS_ASSERT (!m_rxing);
|
||||
Time now = Simulator::Now ();
|
||||
@@ -385,6 +396,7 @@ WifiPhyStateHelper::SwitchToRx (Time rxDuration)
|
||||
void
|
||||
WifiPhyStateHelper::SwitchToChannelSwitching (Time switchingDuration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << switchingDuration);
|
||||
Time now = Simulator::Now ();
|
||||
switch (GetState ())
|
||||
{
|
||||
@@ -430,6 +442,7 @@ WifiPhyStateHelper::SwitchToChannelSwitching (Time switchingDuration)
|
||||
void
|
||||
WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet, double snr, WifiTxVector txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << snr << txVector);
|
||||
m_rxOkTrace (packet, snr, txVector.GetMode (), txVector.GetPreambleType ());
|
||||
NotifyRxEndOk ();
|
||||
DoSwitchFromRx ();
|
||||
@@ -443,6 +456,7 @@ WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet, double snr, WifiTxVec
|
||||
void
|
||||
WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << snr);
|
||||
m_rxErrorTrace (packet, snr);
|
||||
NotifyRxEndError ();
|
||||
DoSwitchFromRx ();
|
||||
@@ -455,6 +469,7 @@ WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr)
|
||||
void
|
||||
WifiPhyStateHelper::DoSwitchFromRx (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (IsStateRx ());
|
||||
NS_ASSERT (m_rxing);
|
||||
|
||||
@@ -469,6 +484,7 @@ WifiPhyStateHelper::DoSwitchFromRx (void)
|
||||
void
|
||||
WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration);
|
||||
NotifyMaybeCcaBusyStart (duration);
|
||||
Time now = Simulator::Now ();
|
||||
switch (GetState ())
|
||||
@@ -497,6 +513,7 @@ WifiPhyStateHelper::SwitchMaybeToCcaBusy (Time duration)
|
||||
void
|
||||
WifiPhyStateHelper::SwitchToSleep (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Time now = Simulator::Now ();
|
||||
switch (GetState ())
|
||||
{
|
||||
@@ -527,6 +544,7 @@ WifiPhyStateHelper::SwitchToSleep (void)
|
||||
void
|
||||
WifiPhyStateHelper::SwitchFromSleep (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration);
|
||||
NS_ASSERT (IsStateSleep ());
|
||||
Time now = Simulator::Now ();
|
||||
m_stateLogger (m_startSleep, now - m_startSleep, WifiPhy::SLEEP);
|
||||
@@ -541,4 +559,15 @@ WifiPhyStateHelper::SwitchFromSleep (Time duration)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhyStateHelper::SwitchFromRxAbort (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (IsStateRx ());
|
||||
NS_ASSERT (m_rxing);
|
||||
m_endRx = Simulator::Now ();
|
||||
DoSwitchFromRx ();
|
||||
NS_ASSERT (!IsStateRx ());
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -185,6 +185,10 @@ public:
|
||||
* \param duration the duration of CCA busy state
|
||||
*/
|
||||
void SwitchFromSleep (Time duration);
|
||||
/**
|
||||
* Abort current reception
|
||||
*/
|
||||
void SwitchFromRxAbort (void);
|
||||
|
||||
/**
|
||||
* TracedCallback signature for state changes.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "wifi-phy-tag.h"
|
||||
#include "ampdu-tag.h"
|
||||
#include "wifi-utils.h"
|
||||
#include "frame-capture-model.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -314,6 +315,12 @@ WifiPhy::GetTypeId (void)
|
||||
MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported,
|
||||
&WifiPhy::SetShortPlcpPreambleSupported),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("FrameCaptureModel",
|
||||
"Ptr to an object that implements the frame capture model",
|
||||
PointerValue (0), //StringValue ("ns3::SimpleFrameCaptureModel"),
|
||||
MakePointerAccessor (&WifiPhy::GetFrameCaptureModel,
|
||||
&WifiPhy::SetFrameCaptureModel),
|
||||
MakePointerChecker <FrameCaptureModel>())
|
||||
.AddTraceSource ("PhyTxBegin",
|
||||
"Trace source indicating a packet "
|
||||
"has begun transmitting over the channel medium",
|
||||
@@ -378,7 +385,8 @@ WifiPhy::WifiPhy ()
|
||||
m_channelNumber (0),
|
||||
m_initialChannelNumber (0),
|
||||
m_totalAmpduSize (0),
|
||||
m_totalAmpduNumSymbols (0)
|
||||
m_totalAmpduNumSymbols (0),
|
||||
m_currentEvent (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_UNUSED (m_numberOfTransmitters);
|
||||
@@ -702,6 +710,18 @@ WifiPhy::GetErrorRateModel (void) const
|
||||
return m_interference.GetErrorRateModel ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::SetFrameCaptureModel (Ptr<FrameCaptureModel> model)
|
||||
{
|
||||
m_frameCaptureModel = model;
|
||||
}
|
||||
|
||||
Ptr<FrameCaptureModel>
|
||||
WifiPhy::GetFrameCaptureModel (void) const
|
||||
{
|
||||
return m_frameCaptureModel;
|
||||
}
|
||||
|
||||
double
|
||||
WifiPhy::GetPowerDbm (uint8_t power) const
|
||||
{
|
||||
@@ -2356,7 +2376,6 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
//This function should be later split to check separately whether plcp preamble and plcp header can be successfully received.
|
||||
//Note: plcp preamble reception is not yet modeled.
|
||||
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration);
|
||||
AmpduTag ampduTag;
|
||||
Time endRx = Simulator::Now () + rxDuration;
|
||||
|
||||
WifiPhyTag tag;
|
||||
@@ -2380,15 +2399,13 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams");
|
||||
}
|
||||
|
||||
WifiPreamble preamble = txVector.GetPreambleType ();
|
||||
MpduType mpdutype = tag.GetMpduType ();
|
||||
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
|
||||
|
||||
Ptr<InterferenceHelper::Event> event;
|
||||
event = m_interference.Add (txVector,
|
||||
event = m_interference.Add (packet,
|
||||
txVector,
|
||||
rxDuration,
|
||||
rxPowerW);
|
||||
|
||||
MpduType mpdutype = tag.GetMpduType ();
|
||||
switch (m_state->GetState ())
|
||||
{
|
||||
case WifiPhy::SWITCHING:
|
||||
@@ -2407,18 +2424,31 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
{
|
||||
//that packet will be noise _after_ the completion of the
|
||||
//channel switching.
|
||||
goto maybeCcaBusy;
|
||||
MaybeCcaBusyDuration ();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WifiPhy::RX:
|
||||
NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
|
||||
rxPowerW << "W)");
|
||||
NotifyRxDrop (packet);
|
||||
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
|
||||
NS_ASSERT (m_currentEvent != 0);
|
||||
if (m_frameCaptureModel != 0 &&
|
||||
m_frameCaptureModel->CaptureNewFrame(m_currentEvent, event))
|
||||
{
|
||||
//that packet will be noise _after_ the reception of the
|
||||
//currently-received packet.
|
||||
goto maybeCcaBusy;
|
||||
AbortCurrentReception ();
|
||||
NS_LOG_DEBUG ("Switch to new packet");
|
||||
StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
|
||||
rxPowerW << "W)");
|
||||
NotifyRxDrop (packet);
|
||||
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
|
||||
{
|
||||
//that packet will be noise _after_ the reception of the
|
||||
//currently-received packet.
|
||||
MaybeCcaBusyDuration ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WifiPhy::TX:
|
||||
@@ -2429,77 +2459,13 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
{
|
||||
//that packet will be noise _after_ the transmission of the
|
||||
//currently-transmitted packet.
|
||||
goto maybeCcaBusy;
|
||||
MaybeCcaBusyDuration ();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WifiPhy::CCA_BUSY:
|
||||
case WifiPhy::IDLE:
|
||||
if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
|
||||
{
|
||||
if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
|
||||
{
|
||||
m_plcpSuccess = false;
|
||||
m_mpdusNum = 0;
|
||||
NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
|
||||
NotifyRxDrop (packet);
|
||||
goto maybeCcaBusy;
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
|
||||
{
|
||||
//received the first MPDU in an MPDU
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
m_rxMpduReferenceNumber++;
|
||||
}
|
||||
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
|
||||
{
|
||||
//received the other MPDUs that are part of the A-MPDU
|
||||
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
|
||||
{
|
||||
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mpdusNum--;
|
||||
}
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
|
||||
{
|
||||
NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
|
||||
m_mpdusNum = 0;
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
|
||||
//sync to signal
|
||||
m_state->SwitchToRx (rxDuration);
|
||||
NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
|
||||
NotifyRxBegin (packet);
|
||||
m_interference.NotifyRxStart ();
|
||||
|
||||
if (preamble != WIFI_PREAMBLE_NONE)
|
||||
{
|
||||
NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
|
||||
m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
|
||||
packet, txVector, mpdutype, event);
|
||||
}
|
||||
|
||||
NS_ASSERT (m_endRxEvent.IsExpired ());
|
||||
m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
|
||||
packet, preamble, mpdutype, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
|
||||
rxPowerW << "<" << GetEdThresholdW () << ")");
|
||||
NotifyRxDrop (packet);
|
||||
m_plcpSuccess = false;
|
||||
goto maybeCcaBusy;
|
||||
}
|
||||
StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event);
|
||||
break;
|
||||
case WifiPhy::SLEEP:
|
||||
NS_LOG_DEBUG ("drop packet because in sleep mode");
|
||||
@@ -2507,10 +2473,11 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
||||
m_plcpSuccess = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
maybeCcaBusy:
|
||||
void
|
||||
WifiPhy::MaybeCcaBusyDuration ()
|
||||
{
|
||||
//We are here because we have received the first bit of a packet and we are
|
||||
//not going to be able to synchronize on it
|
||||
//In this model, CCA becomes busy when the aggregation of all signals as
|
||||
@@ -2571,6 +2538,7 @@ WifiPhy::EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutyp
|
||||
InterferenceHelper::SnrPer snrPer;
|
||||
snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
|
||||
m_interference.NotifyRxEnd ();
|
||||
m_currentEvent = 0;
|
||||
|
||||
if (m_plcpSuccess == true)
|
||||
{
|
||||
@@ -3661,6 +3629,100 @@ WifiPhy::SwitchMaybeToCcaBusy (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::AbortCurrentReception ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_endPlcpRxEvent.IsRunning ())
|
||||
{
|
||||
m_endPlcpRxEvent.Cancel ();
|
||||
}
|
||||
if (m_endRxEvent.IsRunning ())
|
||||
{
|
||||
m_endRxEvent.Cancel ();
|
||||
}
|
||||
NotifyRxDrop (m_currentEvent->GetPacket ());
|
||||
m_interference.NotifyRxEnd ();
|
||||
m_state->SwitchFromRxAbort ();
|
||||
m_currentEvent = 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartRx (Ptr<Packet> packet, WifiTxVector txVector, MpduType mpdutype, double rxPowerW, Time rxDuration, Ptr<InterferenceHelper::Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << txVector << (uint16_t)mpdutype << rxPowerW << rxDuration);
|
||||
if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
|
||||
{
|
||||
AmpduTag ampduTag;
|
||||
WifiPreamble preamble = txVector.GetPreambleType ();
|
||||
if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false))
|
||||
{
|
||||
m_plcpSuccess = false;
|
||||
m_mpdusNum = 0;
|
||||
NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received");
|
||||
NotifyRxDrop (packet);
|
||||
MaybeCcaBusyDuration ();
|
||||
return;
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
|
||||
{
|
||||
//received the first MPDU in an MPDU
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
m_rxMpduReferenceNumber++;
|
||||
}
|
||||
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
|
||||
{
|
||||
//received the other MPDUs that are part of the A-MPDU
|
||||
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
|
||||
{
|
||||
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mpdusNum--;
|
||||
}
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost");
|
||||
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
|
||||
}
|
||||
else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
|
||||
{
|
||||
NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
|
||||
m_mpdusNum = 0;
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
|
||||
m_currentEvent = event;
|
||||
m_state->SwitchToRx (rxDuration);
|
||||
NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
|
||||
NotifyRxBegin (packet);
|
||||
m_interference.NotifyRxStart ();
|
||||
|
||||
if (preamble != WIFI_PREAMBLE_NONE)
|
||||
{
|
||||
NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
|
||||
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector);
|
||||
m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this,
|
||||
packet, txVector, mpdutype, event);
|
||||
}
|
||||
|
||||
NS_ASSERT (m_endRxEvent.IsExpired ());
|
||||
m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this,
|
||||
packet, preamble, mpdutype, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
|
||||
rxPowerW << "<" << GetEdThresholdW () << ")");
|
||||
NotifyRxDrop (packet);
|
||||
m_plcpSuccess = false;
|
||||
MaybeCcaBusyDuration ();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t
|
||||
WifiPhy::AssignStreams (int64_t stream)
|
||||
{
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
#include <map>
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
#include "ns3/channel.h"
|
||||
#include "wifi-phy-standard.h"
|
||||
#include "interference-helper.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/string.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -44,6 +44,11 @@ namespace ns3 {
|
||||
*/
|
||||
class WifiPhyStateHelper;
|
||||
|
||||
/**
|
||||
* FrameCaptureModel class
|
||||
*/
|
||||
class FrameCaptureModel;
|
||||
|
||||
/**
|
||||
* This enumeration defines the type of an MPDU.
|
||||
*/
|
||||
@@ -371,7 +376,7 @@ public:
|
||||
*
|
||||
* \return the total amount of time this PHY will stay busy for the transmission of the PLCP preamble and PLCP header.
|
||||
*/
|
||||
Time CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector);
|
||||
static Time CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector);
|
||||
|
||||
/**
|
||||
* \param txVector the transmission parameters used for this packet
|
||||
@@ -1445,6 +1450,7 @@ public:
|
||||
* \return the reception gain in dB
|
||||
*/
|
||||
double GetRxGain (void) const;
|
||||
|
||||
/**
|
||||
* Sets the device this PHY is associated with.
|
||||
*
|
||||
@@ -1602,6 +1608,19 @@ public:
|
||||
*/
|
||||
Ptr<ErrorRateModel> GetErrorRateModel (void) const;
|
||||
|
||||
/**
|
||||
* Sets the frame capture model.
|
||||
*
|
||||
* \param rate the frame capture model
|
||||
*/
|
||||
void SetFrameCaptureModel (Ptr<FrameCaptureModel> rate);
|
||||
/**
|
||||
* Return the frame capture model this PHY is using.
|
||||
*
|
||||
* \return the frame capture model this PHY is using
|
||||
*/
|
||||
Ptr<FrameCaptureModel> GetFrameCaptureModel (void) const;
|
||||
|
||||
/**
|
||||
* \return the channel width
|
||||
*/
|
||||
@@ -1771,6 +1790,34 @@ private:
|
||||
* \return the FrequencyWidthPair found
|
||||
*/
|
||||
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard (uint8_t channelNumber, WifiPhyStandard standard) const;
|
||||
|
||||
/**
|
||||
* Due to newly arrived signal, the current reception cannot be continued and has to be aborted
|
||||
*
|
||||
*/
|
||||
void AbortCurrentReception (void);
|
||||
|
||||
/**
|
||||
* Eventually switch to CCA busy
|
||||
*/
|
||||
void MaybeCcaBusyDuration (void);
|
||||
|
||||
/**
|
||||
* Starting receiving the packet after having detected the medium is idle or after a reception switch.
|
||||
*
|
||||
* \param packet the arriving packet
|
||||
* \param txVector the TXVECTOR of the arriving packet
|
||||
* \param mpdutype the type of the MPDU as defined in WifiPhy::MpduType.
|
||||
* \param rxPowerW the receive power in W
|
||||
* \param rxDuration the duration needed for the reception of the packet
|
||||
* \param event the corresponding event of the first time the packet arrives
|
||||
*/
|
||||
void StartRx (Ptr<Packet> packet,
|
||||
WifiTxVector txVector,
|
||||
MpduType mpdutype,
|
||||
double rxPowerW,
|
||||
Time rxDuration,
|
||||
Ptr<InterferenceHelper::Event> event);
|
||||
|
||||
/**
|
||||
* The trace source fired when a packet begins the transmission process on
|
||||
@@ -1931,6 +1978,9 @@ private:
|
||||
|
||||
Ptr<NetDevice> m_device; //!< Pointer to the device
|
||||
Ptr<MobilityModel> m_mobility; //!< Pointer to the mobility model
|
||||
|
||||
Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
|
||||
Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -343,6 +343,8 @@ cpp_examples = [
|
||||
("wifi-manager-example --wifiManager=Ideal --standard=802.11ax-2.4GHz --serverChannelWidth=40 --clientChannelWidth=40 --serverShortGuardInterval=800 --clientShortGuardInterval=800 --serverNss=4 --clientNss=4 --stepTime=0.1", "False", "False"),
|
||||
("wifi-manager-example --wifiManager=Ideal --standard=802.11ax-2.4GHz --serverChannelWidth=40 --clientChannelWidth=40 --serverShortGuardInterval=1600 --clientShortGuardInterval=1600 --serverNss=4 --clientNss=4 --stepTime=0.1", "False", "False"),
|
||||
("wifi-manager-example --wifiManager=Ideal --standard=802.11ax-2.4GHz --serverChannelWidth=40 --clientChannelWidth=40 --serverShortGuardInterval=3200 --clientShortGuardInterval=3200 --serverNss=4 --clientNss=4 --stepTime=0.1", "False", "False"),
|
||||
("test-interference-helper --enableCapture=0 --txPowerA=5 --txPowerB=15 --delay=10 --txModeA=OfdmRate6Mbps --txModeB=OfdmRate6Mbps --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=0", "True", "True"),
|
||||
("test-interference-helper --enableCapture=1 --txPowerA=5 --txPowerB=15 --delay=10 --txModeA=OfdmRate6Mbps --txModeB=OfdmRate6Mbps --checkResults=1 --expectRxASuccessfull=0 --expectRxBSuccessfull=1", "True", "True"),
|
||||
]
|
||||
|
||||
# A list of Python examples to run in order to ensure that they remain
|
||||
|
||||
@@ -83,6 +83,8 @@ def build(bld):
|
||||
'model/dsss-parameter-set.cc',
|
||||
'model/edca-parameter-set.cc',
|
||||
'model/he-capabilities.cc',
|
||||
'model/frame-capture-model.cc',
|
||||
'model/simple-frame-capture-model.cc',
|
||||
'helper/wifi-radio-energy-model-helper.cc',
|
||||
'helper/vht-wifi-mac-helper.cc',
|
||||
'helper/ht-wifi-mac-helper.cc',
|
||||
@@ -190,6 +192,8 @@ def build(bld):
|
||||
'model/dsss-parameter-set.h',
|
||||
'model/edca-parameter-set.h',
|
||||
'model/he-capabilities.h',
|
||||
'model/frame-capture-model.h',
|
||||
'model/simple-frame-capture-model.h',
|
||||
'helper/wifi-radio-energy-model-helper.h',
|
||||
'helper/vht-wifi-mac-helper.h',
|
||||
'helper/ht-wifi-mac-helper.h',
|
||||
|
||||
Reference in New Issue
Block a user