Merge to ns3-dev
This commit is contained in:
29
src/devices/mesh/802.11s/dot11s.h
Normal file
29
src/devices/mesh/802.11s/dot11s.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* 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: Pavel Boyko <boyko@iitp.ru>
|
||||
*
|
||||
* This is doxygen module description, don't include
|
||||
*/
|
||||
/**
|
||||
* \ingroup mesh
|
||||
* \defgroup dot11s IEEE 802.11s draft
|
||||
*
|
||||
* \brief IEEE 802.11s (mesh) draft standard implementation
|
||||
*
|
||||
* TODO: add documentation on 802.11s implementation here
|
||||
*/
|
||||
@@ -30,18 +30,18 @@ MeshWifiBeacon::MeshWifiBeacon(Ssid ssid, SupportedRates rates, uint64_t us)
|
||||
m_header.SetBeaconIntervalUs (us);
|
||||
}
|
||||
|
||||
void MeshWifiBeacon::AddInformationElement(const WifiInformationElement * ie)
|
||||
void MeshWifiBeacon::AddInformationElement(Ptr<WifiInformationElement> ie)
|
||||
{
|
||||
m_elements.push_back(ie);
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// aux sorter
|
||||
struct IEComparator
|
||||
/// aux sorter for Ptr<WifiInformationElement>
|
||||
struct PIEComparator
|
||||
{
|
||||
bool operator()(const WifiInformationElement * a, const WifiInformationElement * b) const
|
||||
bool operator() (Ptr<WifiInformationElement> a, Ptr<WifiInformationElement> b) const
|
||||
{
|
||||
return (*a < *b);
|
||||
return ((*PeekPointer(a)) < (*PeekPointer(b)));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -50,18 +50,32 @@ Ptr<Packet> MeshWifiBeacon::CreatePacket()
|
||||
{
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
|
||||
std::sort(m_elements.begin(), m_elements.end(), IEComparator());
|
||||
std::sort(m_elements.begin(), m_elements.end(), PIEComparator());
|
||||
|
||||
std::vector<const WifiInformationElement *>::const_reverse_iterator i;
|
||||
std::vector< Ptr<WifiInformationElement> >::const_reverse_iterator i;
|
||||
for(i = m_elements.rbegin(); i != m_elements.rend(); ++i)
|
||||
{
|
||||
packet->AddHeader(**i);
|
||||
}
|
||||
|
||||
packet->AddHeader(Header());
|
||||
packet->AddHeader(BeaconHeader());
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
WifiMacHeader MeshWifiBeacon::CreateHeader (Mac48Address address)
|
||||
{
|
||||
WifiMacHeader hdr;
|
||||
|
||||
hdr.SetBeacon ();
|
||||
hdr.SetAddr1 (Mac48Address::GetBroadcast ());
|
||||
hdr.SetAddr2 (address);
|
||||
hdr.SetAddr3 (address);
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/wifi-information-element.h"
|
||||
#include "ns3/mgt-headers.h" // from wifi module
|
||||
#include "ns3/ssid.h"
|
||||
#include "ns3/wifi-mac-header.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -49,17 +49,20 @@ public:
|
||||
*/
|
||||
MeshWifiBeacon(Ssid ssid, SupportedRates rates, uint64_t us);
|
||||
/// Read standard Wifi beacon header
|
||||
MgtBeaconHeader Header () const { return m_header; }
|
||||
MgtBeaconHeader BeaconHeader () const { return m_header; }
|
||||
/// Add information element
|
||||
void AddInformationElement (const WifiInformationElement * ie);
|
||||
/// Create frame = { header + all information elements sorted by ElementId() }
|
||||
Ptr<Packet> CreatePacket ();
|
||||
void AddInformationElement (Ptr<WifiInformationElement> ie);
|
||||
|
||||
/// Create wifi header for beacon frame. \param address is sender address
|
||||
WifiMacHeader CreateHeader (Mac48Address address);
|
||||
/// Create frame = { beacon header + all information elements sorted by ElementId() }
|
||||
Ptr<Packet> CreatePacket ();
|
||||
|
||||
private:
|
||||
/// Beacon header
|
||||
MgtBeaconHeader m_header;
|
||||
/// List of information elements added
|
||||
std::vector<const WifiInformationElement *> m_elements;
|
||||
std::vector< Ptr<WifiInformationElement> > m_elements;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
74
src/devices/mesh/mesh-wifi-interface-mac-plugin.h
Normal file
74
src/devices/mesh/mesh-wifi-interface-mac-plugin.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* 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: Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef MESHWIFIINTERFACEMACPLUGIN_H_
|
||||
#define MESHWIFIINTERFACEMACPLUGIN_H_
|
||||
|
||||
#include "ns3/wifi-mac-header.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/mesh-wifi-beacon.h"
|
||||
#include "ns3/ref-count-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class MeshWifiInterfaceMac;
|
||||
|
||||
/**
|
||||
* \ingroup mesh
|
||||
*
|
||||
* \brief Common interface for mesh point interface MAC plugins
|
||||
*
|
||||
* TODO: plugins description
|
||||
*/
|
||||
class MeshWifiInterfaceMacPlugin : public RefCountBase
|
||||
{
|
||||
public:
|
||||
/// C-tor creates unplugged plugin
|
||||
MeshWifiInterfaceMacPlugin() { /*do nothing*/}
|
||||
/// This is for subclasses
|
||||
virtual ~MeshWifiInterfaceMacPlugin() { /*do nothing*/ }
|
||||
|
||||
/// Each plugin must be installed on interface to work
|
||||
virtual void SetParent(MeshWifiInterfaceMac * parent) = 0;
|
||||
/**
|
||||
* \brief Process received frame
|
||||
*
|
||||
* \return false if (and only if) frame should be dropped
|
||||
* TODO define when MAC call this
|
||||
*/
|
||||
virtual bool Receive(Ptr<Packet> packet, const WifiMacHeader & header) = 0;
|
||||
/**
|
||||
* \brief Update frame before it will be forwarded down
|
||||
*
|
||||
* \return false if (and only if) frame should be dropped
|
||||
* TODO define when MAC call this, preconditions & postconditions
|
||||
*/
|
||||
virtual bool UpdateOutcomingFrame(Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const = 0;
|
||||
/**
|
||||
* \brief Update beacon before it will be formed and sent
|
||||
*
|
||||
* TODO define when MAC call this
|
||||
*/
|
||||
virtual void UpdateBeacon(MeshWifiBeacon & beacon) const;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
#endif /* MESHWIFIINTERFACEMACPLUGIN_H_ */
|
||||
549
src/devices/mesh/mesh-wifi-interface-mac.cc
Normal file
549
src/devices/mesh/mesh-wifi-interface-mac.cc
Normal file
@@ -0,0 +1,549 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#include "ns3/mesh-wifi-interface-mac.h"
|
||||
#include "ns3/mesh-wifi-beacon.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/wifi-phy.h"
|
||||
#include "ns3/dcf-manager.h"
|
||||
#include "ns3/mac-rx-middle.h"
|
||||
#include "ns3/mac-low.h"
|
||||
#include "ns3/dca-txop.h"
|
||||
#include "ns3/mesh-wifi-mac-header.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("MeshWifiInterfaceMac");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MeshWifiInterfaceMac);
|
||||
|
||||
TypeId
|
||||
MeshWifiInterfaceMac::GetTypeId ()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::MeshWifiInterfaceMac")
|
||||
.SetParent<WifiMac> ()
|
||||
.AddConstructor<MeshWifiInterfaceMac> ()
|
||||
.AddAttribute ("BeaconInterval", "Beacon Interval",
|
||||
TimeValue (Seconds (1.0)),
|
||||
MakeTimeAccessor (&MeshWifiInterfaceMac::m_beaconInterval),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("RandomStart", "Window when beacon generating starts (uniform random) in seconds",
|
||||
TimeValue (Seconds (0.1)),
|
||||
MakeTimeAccessor (&MeshWifiInterfaceMac::m_randomStart),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("SoftwareDelay", "Window of uniformely distributed random software handling delay",
|
||||
TimeValue (MicroSeconds (500)),
|
||||
MakeTimeAccessor (&MeshWifiInterfaceMac::m_softwareDelay),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("BeaconGeneration", "Enable/Disable Beaconing.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (
|
||||
&MeshWifiInterfaceMac::SetBeaconGeneration,
|
||||
&MeshWifiInterfaceMac::GetBeaconGeneration
|
||||
),
|
||||
MakeBooleanChecker ()
|
||||
);
|
||||
return tid;
|
||||
}
|
||||
|
||||
MeshWifiInterfaceMac::MeshWifiInterfaceMac ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_rxMiddle = new MacRxMiddle ();
|
||||
m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiInterfaceMac::Receive, this));
|
||||
|
||||
m_low = CreateObject<MacLow> ();
|
||||
m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
|
||||
|
||||
m_dcfManager = new DcfManager ();
|
||||
m_dcfManager->SetupLowListener (m_low);
|
||||
|
||||
m_beaconDca = CreateObject<DcaTxop> ();
|
||||
m_beaconDca->SetLow (m_low);
|
||||
m_beaconDca->SetMinCw (0);
|
||||
m_beaconDca->SetMaxCw (0);
|
||||
m_beaconDca->SetAifsn(1);
|
||||
m_beaconDca->SetManager (m_dcfManager);
|
||||
|
||||
m_VO = CreateObject<DcaTxop> ();
|
||||
m_VO->SetLow (m_low);
|
||||
m_VO->SetMinCw (3);
|
||||
m_VO->SetMaxCw (7);
|
||||
m_VO->SetManager (m_dcfManager);
|
||||
|
||||
m_BE = CreateObject<DcaTxop> ();
|
||||
m_BE->SetLow (m_low);
|
||||
m_BE->SetManager (m_dcfManager);
|
||||
}
|
||||
|
||||
MeshWifiInterfaceMac::~MeshWifiInterfaceMac ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// WifiMac inherited
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
MeshWifiInterfaceMac::SetSlot (Time slotTime)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << slotTime);
|
||||
m_dcfManager->SetSlot (slotTime);
|
||||
m_slot = slotTime;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetSifs (Time sifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << sifs);
|
||||
m_dcfManager->SetSifs (sifs);
|
||||
m_sifs = sifs;
|
||||
}
|
||||
void
|
||||
MeshWifiInterfaceMac::SetAckTimeout (Time ackTimeout)
|
||||
{
|
||||
m_low->SetAckTimeout (ackTimeout);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetCtsTimeout (Time ctsTimeout)
|
||||
{
|
||||
m_low->SetCtsTimeout (ctsTimeout);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetPifs (Time pifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << pifs);
|
||||
m_pifs = pifs;
|
||||
}
|
||||
void
|
||||
MeshWifiInterfaceMac::SetEifsNoDifs (Time eifsNoDifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << eifsNoDifs);
|
||||
m_dcfManager->SetEifsNoDifs (eifsNoDifs);
|
||||
m_eifsNoDifs = eifsNoDifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetSlot () const
|
||||
{
|
||||
return m_slot;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetSifs () const
|
||||
{
|
||||
return m_sifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetEifsNoDifs () const
|
||||
{
|
||||
return m_eifsNoDifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetAckTimeout () const
|
||||
{
|
||||
return m_low->GetAckTimeout ();
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetCtsTimeout () const
|
||||
{
|
||||
return m_low->GetCtsTimeout ();
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetPifs () const
|
||||
{
|
||||
return m_low->GetPifs ();
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetWifiPhy (Ptr<WifiPhy> phy)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy);
|
||||
m_phy = phy;
|
||||
m_dcfManager->SetupPhyListener (phy);
|
||||
m_low->SetPhy (phy);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stationManager);
|
||||
m_stationManager = stationManager;
|
||||
m_BE->SetWifiRemoteStationManager (stationManager);
|
||||
m_VO->SetWifiRemoteStationManager (stationManager);
|
||||
m_beaconDca->SetWifiRemoteStationManager (stationManager);
|
||||
m_low->SetWifiRemoteStationManager (stationManager);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << to << from);
|
||||
ForwardDown (packet, from, to);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << to);
|
||||
ForwardDown (packet, m_low->GetAddress (), to);
|
||||
}
|
||||
|
||||
bool
|
||||
MeshWifiInterfaceMac::SupportsSendFrom () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_upCallback = upCallback;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetLinkUpCallback (Callback<void> linkUp)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (!linkUp.IsNull ())
|
||||
{
|
||||
linkUp ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetLinkDownCallback (Callback<void> linkDown)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
MeshWifiInterfaceMac::GetAddress () const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
Mac48Address
|
||||
MeshWifiInterfaceMac::GetBssid () const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
Ssid
|
||||
MeshWifiInterfaceMac::GetSsid () const
|
||||
{
|
||||
return m_MeshId;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetAddress (Mac48Address address)
|
||||
{
|
||||
NS_LOG_FUNCTION (address);
|
||||
m_low->SetAddress(address);
|
||||
m_address = address;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetSsid (Ssid ssid)
|
||||
{
|
||||
NS_LOG_FUNCTION (ssid);
|
||||
m_MeshId = ssid;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::DoDispose ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
delete m_rxMiddle;
|
||||
delete m_dcfManager;
|
||||
//Delete smart pointers:
|
||||
m_rxMiddle = 0;
|
||||
m_low = 0;
|
||||
m_dcfManager = 0;
|
||||
m_phy = 0;
|
||||
m_BE = 0;
|
||||
m_VO = 0;
|
||||
m_beaconSendEvent.Cancel ();
|
||||
m_beaconDca = 0;
|
||||
|
||||
WifiMac::DoDispose ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plugins
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
MeshWifiInterfaceMac::InstallPlugin( Ptr<MeshWifiInterfaceMacPlugin> plugin)
|
||||
{
|
||||
plugin->SetParent(this);
|
||||
m_plugins.push_back(plugin);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward frame up/down
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
MeshWifiInterfaceMac::ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << src);
|
||||
m_upCallback (packet, src, dst);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address from, Mac48Address to)
|
||||
{
|
||||
// copy packet to allow modifications
|
||||
Ptr<Packet> packet = const_packet->Copy();
|
||||
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetTypeData ();
|
||||
hdr.SetAddr2 (GetAddress ());
|
||||
hdr.SetAddr3 (to);
|
||||
hdr.SetAddr4 (from);
|
||||
hdr.SetDsFrom ();
|
||||
hdr.SetDsTo ();
|
||||
|
||||
// Address 1 is unknwon here. Routing plugin is responsible to correctly set it.
|
||||
hdr.SetAddr1 (Mac48Address ());
|
||||
|
||||
// Filter packet through all installed plugins
|
||||
for(PluginList::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
|
||||
{
|
||||
bool drop = !((*i)->UpdateOutcomingFrame(packet, hdr, from, to));
|
||||
if (drop) return; // plugin drops frame
|
||||
}
|
||||
|
||||
// Assert that address1 is set. Assert will fail e.g. if there is no installed routing plugin.
|
||||
NS_ASSERT(hdr.GetAddr1() != Mac48Address() );
|
||||
|
||||
// Queue frame
|
||||
WifiRemoteStation *destination = m_stationManager->Lookup (to);
|
||||
|
||||
if (destination->IsBrandNew ())
|
||||
{
|
||||
// in adhoc mode, we assume that every destination
|
||||
// supports all the rates we support.
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
destination->AddSupportedMode (m_phy->GetMode (i));
|
||||
}
|
||||
destination->RecordDisassociated ();
|
||||
}
|
||||
m_BE->Queue (packet, hdr);
|
||||
}
|
||||
|
||||
SupportedRates
|
||||
MeshWifiInterfaceMac::GetSupportedRates () const
|
||||
{
|
||||
// set the set of supported rates and make sure that we indicate
|
||||
// the Basic Rate set in this set of supported rates.
|
||||
SupportedRates rates;
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
WifiMode mode = m_phy->GetMode (i);
|
||||
rates.AddSupportedRate (mode.GetDataRate ());
|
||||
}
|
||||
// set the basic rates
|
||||
for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
|
||||
{
|
||||
WifiMode mode = m_stationManager->GetBasicMode (j);
|
||||
rates.SetBasicRate (mode.GetDataRate ());
|
||||
}
|
||||
return rates;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Beacons
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
MeshWifiInterfaceMac::SetSoftwareDelay(Time delay)
|
||||
{
|
||||
NS_ASSERT(delay < m_beaconInterval);
|
||||
m_softwareDelay = delay;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetSoftwareDelay()
|
||||
{
|
||||
return m_softwareDelay;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::CalcSwDelay()
|
||||
{
|
||||
UniformVariable coefficient(0.0, m_softwareDelay.GetSeconds());
|
||||
|
||||
// Be sure that frames don't change order due to different software delays
|
||||
Time delay = Seconds(coefficient.GetValue());
|
||||
if (delay.GetSeconds() + Simulator::Now().GetSeconds() < m_lastMgtFrame.GetSeconds())
|
||||
delay = Seconds(m_lastMgtFrame.GetSeconds() - Simulator::Now().GetSeconds());
|
||||
m_lastMgtFrame = Seconds(Simulator::Now().GetSeconds() + delay.GetSeconds());
|
||||
|
||||
NS_ASSERT(delay.GetSeconds() >= 0);
|
||||
return delay;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetBeaconInterval (Time interval)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << interval);
|
||||
m_beaconInterval = interval;
|
||||
|
||||
NS_ASSERT(m_beaconInterval > m_softwareDelay);
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetBeaconInterval() const
|
||||
{
|
||||
return m_beaconInterval;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SetBeaconGeneration (bool enable)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << enable);
|
||||
if (enable)
|
||||
{
|
||||
// Now start sending beacons after some random delay (to avoid collisions)
|
||||
UniformVariable coefficient(0.0, m_randomStart.GetSeconds());
|
||||
Time randomStart = Seconds(coefficient.GetValue());
|
||||
|
||||
m_beaconSendEvent = Simulator::Schedule (randomStart, &MeshWifiInterfaceMac::SendBeacon, this);
|
||||
}
|
||||
else
|
||||
// stop sending beacons
|
||||
m_beaconSendEvent.Cancel ();
|
||||
}
|
||||
|
||||
bool
|
||||
MeshWifiInterfaceMac::GetBeaconGeneration () const
|
||||
{
|
||||
return m_beaconSendEvent.IsRunning ();
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiInterfaceMac::GetTBTT() const
|
||||
{
|
||||
return m_tbtt;
|
||||
}
|
||||
|
||||
void MeshWifiInterfaceMac::ShiftTBTT(Time shift)
|
||||
{
|
||||
// User of ShiftTBTT() must take care don't shift it to the past
|
||||
NS_ASSERT(GetTBTT() + shift > Simulator::Now());
|
||||
|
||||
m_tbtt += shift;
|
||||
// Shift scheduled event
|
||||
Simulator::Cancel (m_beaconSendEvent);
|
||||
m_beaconSendEvent = Simulator::Schedule (GetTBTT(), &MeshWifiInterfaceMac::SendBeacon, this);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::ScheduleNextBeacon()
|
||||
{
|
||||
m_tbtt += GetBeaconInterval();
|
||||
m_beaconSendEvent = Simulator::Schedule (GetTBTT(), &MeshWifiInterfaceMac::SendBeacon, this);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::SendBeacon ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_DEBUG(GetAddress() <<" is sending beacon");
|
||||
|
||||
NS_ASSERT(! m_beaconSendEvent.IsRunning());
|
||||
NS_ASSERT(Simulator::Now() == GetTBTT()); // assert that beacon is just on time
|
||||
|
||||
// Form & send beacon
|
||||
MeshWifiBeacon beacon(GetSsid (), GetSupportedRates (), m_beaconInterval.GetMicroSeconds ());
|
||||
|
||||
// Ask all plugins to add their specific information elements to beacon
|
||||
for(PluginList::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
|
||||
(*i)->UpdateBeacon(beacon);
|
||||
|
||||
m_beaconDca->Queue(beacon.CreatePacket(), beacon.CreateHeader(GetAddress()));
|
||||
|
||||
ScheduleNextBeacon();
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
|
||||
{
|
||||
// Process beacon
|
||||
if (hdr->IsBeacon ())
|
||||
{
|
||||
MgtBeaconHeader beacon_hdr;
|
||||
Mac48Address from = hdr->GetAddr2();
|
||||
|
||||
packet->PeekHeader (beacon_hdr);
|
||||
|
||||
NS_LOG_DEBUG("Beacon received from "<<hdr->GetAddr2()<<
|
||||
" to "<<GetAddress()<<
|
||||
" at "<<Simulator::Now ().GetMicroSeconds ()<<
|
||||
" microseconds");
|
||||
|
||||
// update supported rates
|
||||
if (beacon_hdr.GetSsid().IsEqual(GetSsid()))
|
||||
{
|
||||
SupportedRates rates = beacon_hdr.GetSupportedRates ();
|
||||
WifiRemoteStation * peerSta = m_stationManager->Lookup (hdr->GetAddr2 ());
|
||||
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
WifiMode mode = m_phy->GetMode (i);
|
||||
if (rates.IsSupportedRate (mode.GetDataRate ()))
|
||||
{
|
||||
peerSta->AddSupportedMode (mode);
|
||||
if (rates.IsBasicRate (mode.GetDataRate ()))
|
||||
m_stationManager->AddBasicMode (mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter frame through all installed plugins
|
||||
for (PluginList::iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
|
||||
{
|
||||
bool drop = !((*i)->Receive(packet, *hdr));
|
||||
if (drop) return; // plugin drops frame
|
||||
}
|
||||
|
||||
// Forward data up
|
||||
if (hdr->IsData())
|
||||
ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3());
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
|
||||
227
src/devices/mesh/mesh-wifi-interface-mac.h
Normal file
227
src/devices/mesh/mesh-wifi-interface-mac.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2009 IITP RAS
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Pavel Boyko <boyko@iitp.ru>
|
||||
*/
|
||||
|
||||
#ifndef MESHWIFIINTERFACEMAC_H_
|
||||
#define MESHWIFIINTERFACEMAC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/mac48-address-comparator.h"
|
||||
#include "ns3/mgt-headers.h"
|
||||
#include "ns3/mesh-mgt-headers.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/mesh-wifi-beacon-timing-element.h"
|
||||
#include "ns3/wifi-remote-station-manager.h"
|
||||
#include "ns3/mesh-wifi-peer-manager.h"
|
||||
#include "ns3/wifi-mac.h"
|
||||
#include "ns3/mesh-wifi-interface-mac-plugin.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WifiMacHeader;
|
||||
class DcaTxop;
|
||||
class WifiPhy;
|
||||
class DcfManager;
|
||||
class MacRxMiddle;
|
||||
class MacLow;
|
||||
/**
|
||||
* \ingroup mesh
|
||||
*
|
||||
* \brief Basic MAC of mesh point Wi-Fi interface. Its function is extendable through plugins mechanism.
|
||||
*
|
||||
* Now only three output queues are used:
|
||||
* - beacons (PIFS and no backoff),
|
||||
* - background traffic,
|
||||
* - management and priority traffic.
|
||||
*
|
||||
*/
|
||||
class MeshWifiInterfaceMac : public WifiMac
|
||||
{
|
||||
public:
|
||||
/// Never forget to support typeid
|
||||
static TypeId GetTypeId ();
|
||||
/// C-tor
|
||||
MeshWifiInterfaceMac();
|
||||
/// D-tor
|
||||
virtual ~MeshWifiInterfaceMac();
|
||||
|
||||
///\name Inherited from WifiMac
|
||||
//\{
|
||||
virtual void SetSlot (Time slotTime);
|
||||
virtual void SetSifs (Time sifs);
|
||||
virtual void SetPifs (Time pifs);
|
||||
virtual void SetCtsTimeout (Time ctsTimeout);
|
||||
virtual void SetAckTimeout (Time ackTimeout);
|
||||
virtual void SetEifsNoDifs (Time eifsNoDifs);
|
||||
virtual Time GetSlot () const;
|
||||
virtual Time GetSifs () const;
|
||||
virtual Time GetPifs () const;
|
||||
virtual Time GetCtsTimeout () const;
|
||||
virtual Time GetAckTimeout () const;
|
||||
virtual Time GetEifsNoDifs () const;
|
||||
virtual void SetWifiPhy (Ptr<WifiPhy> phy);
|
||||
virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
|
||||
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
|
||||
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
|
||||
virtual bool SupportsSendFrom () const;
|
||||
virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
|
||||
virtual void SetLinkUpCallback (Callback<void> linkUp);
|
||||
virtual void SetLinkDownCallback (Callback<void> linkDown);
|
||||
virtual Mac48Address GetAddress () const;
|
||||
virtual Mac48Address GetBssid () const;
|
||||
virtual Ssid GetSsid () const;
|
||||
virtual void SetAddress (Mac48Address address);
|
||||
virtual void SetSsid (Ssid ssid);
|
||||
//\}
|
||||
|
||||
///\name Beacons
|
||||
//\{
|
||||
|
||||
/// Set interval between two successive beacons
|
||||
void SetBeaconInterval (Time interval);
|
||||
/// \return interval between two beacons
|
||||
Time GetBeaconInterval () const;
|
||||
/**
|
||||
* \brief Next beacon frame time
|
||||
*
|
||||
* This is supposed to be used by any entity managing beacon collision avoidance (e.g. Peer management protocol in 802.11s)
|
||||
*/
|
||||
Time GetTBTT() const;
|
||||
/**
|
||||
* \brief Shift TBTT.
|
||||
*
|
||||
* This is supposed to be used by any entity managing beacon collision avoidance (e.g. Peer management protocol in 802.11s)
|
||||
*
|
||||
* \attention User of ShiftTBTT() must take care to not shift it to the past.
|
||||
*/
|
||||
void ShiftTBTT(Time shift);
|
||||
/**
|
||||
* \brief Set maximum software delay. Maximum software delay must be smaller than beacon interval.
|
||||
*
|
||||
* Software delay models random small internal delay to avoid simultaneous operation of
|
||||
* different mesh points (e.g. on power on).
|
||||
*
|
||||
* Software delay is calculated as uniformely distributed random value between zero and
|
||||
* given parameter. All management frames are sent after software delay is passed,
|
||||
* for example, beacon is formed at software delay before putting it to the queue.
|
||||
*
|
||||
* \attention The software delay is supposed to be independent from traffic intensity.
|
||||
*
|
||||
* \param delay is the maximum software delay.
|
||||
*/
|
||||
void SetSoftwareDelay(Time delay);
|
||||
/// \return Maximum software delay
|
||||
Time GetSoftwareDelay();
|
||||
|
||||
//\}
|
||||
|
||||
///\name Plugins
|
||||
//\{
|
||||
/// Install plugin. TODO return unique ID to allow unregister plugins
|
||||
void InstallPlugin(Ptr<MeshWifiInterfaceMacPlugin> plugin);
|
||||
//\}
|
||||
|
||||
private:
|
||||
/// Frame receive handler
|
||||
void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
|
||||
/// Forward frame to mesh point
|
||||
virtual void ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst);
|
||||
/// Send frame. Frame is supposed to be tagged by routing information. TODO: clarify this point
|
||||
void ForwardDown(Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
|
||||
/// Calc software delay value uniformely distributed between 0 and m_softwareDealy, see SetSoftwareDelay().
|
||||
Time CalcSwDelay();
|
||||
/// Send beacon
|
||||
void SendBeacon ();
|
||||
/// Schedule next beacon
|
||||
void ScheduleNextBeacon ();
|
||||
/// Enable/disable beacons
|
||||
void SetBeaconGeneration (bool enable);
|
||||
/// Get current beaconing status
|
||||
bool GetBeaconGeneration () const;
|
||||
/// Get list of supported bitrates
|
||||
SupportedRates GetSupportedRates () const;
|
||||
/// Real d-tor
|
||||
virtual void DoDispose ();
|
||||
|
||||
private:
|
||||
///\name Wifi MAC internals
|
||||
//\{
|
||||
Ptr<DcaTxop> m_BE;
|
||||
Ptr<DcaTxop> m_BK;
|
||||
Ptr<DcaTxop> m_VI;
|
||||
Ptr<DcaTxop> m_VO;
|
||||
Ptr<DcaTxop> m_beaconDca;
|
||||
Ptr<WifiRemoteStationManager> m_stationManager;
|
||||
Ptr<WifiPhy> m_phy;
|
||||
Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_upCallback;
|
||||
//\}
|
||||
|
||||
///\name Wifi timing intervals
|
||||
//\{
|
||||
Time m_slot;
|
||||
Time m_sifs;
|
||||
Time m_pifs;
|
||||
Time m_ackTimeout;
|
||||
Time m_ctsTimeout;
|
||||
Time m_eifsNoDifs;
|
||||
//\}
|
||||
|
||||
///\name Mesh timing intervals
|
||||
//\{
|
||||
/// Beaconing interval.
|
||||
Time m_beaconInterval;
|
||||
/// Maximum delay before first beacon
|
||||
Time m_randomStart;
|
||||
/// Maximum software delay
|
||||
Time m_softwareDelay;
|
||||
/// Send time of the last management frame, used to ensure correct frame order
|
||||
Time m_lastMgtFrame;
|
||||
/// Time for the next frame
|
||||
Time m_tbtt;
|
||||
//\}
|
||||
|
||||
/// DCF implementation
|
||||
DcfManager* m_dcfManager;
|
||||
/// Middle MAC sublayer
|
||||
MacRxMiddle* m_rxMiddle;
|
||||
/// Low MAX sublayer
|
||||
Ptr<MacLow> m_low;
|
||||
/// My address
|
||||
Mac48Address m_address;
|
||||
/// SSID
|
||||
Ssid m_MeshId;
|
||||
|
||||
/// "Timer" for the next beacon
|
||||
EventId m_beaconSendEvent;
|
||||
|
||||
typedef std::vector< Ptr<MeshWifiInterfaceMacPlugin> > PluginList;
|
||||
/// List of all installed plugins
|
||||
PluginList m_plugins;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
|
||||
#endif /* MESHWIFIINTERFACEMAC_H_ */
|
||||
@@ -22,6 +22,7 @@
|
||||
#define WIFIINFORMATIONELEMENT_H_
|
||||
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/ref-count-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -70,7 +71,8 @@ enum WifiElementId {
|
||||
* Element ID as defined in this standard. The Length field specifies the number of octets in the Information
|
||||
* field.
|
||||
*/
|
||||
class WifiInformationElement : public Header
|
||||
class WifiInformationElement : public Header,
|
||||
public RefCountBase // need this to use Ptr<WifiInformationElement>
|
||||
{
|
||||
public:
|
||||
/// Support object system
|
||||
|
||||
@@ -4,10 +4,11 @@ def build(bld):
|
||||
obj = bld.create_ns3_module('mesh', ['wifi', '802.11s'])
|
||||
obj.source = [
|
||||
# Refactored
|
||||
'wifi-information-element.cc',
|
||||
'mesh-point-device.cc',
|
||||
'mesh-l2-routing-protocol.cc',
|
||||
'mesh-wifi-beacon.cc',
|
||||
'wifi-information-element.cc',
|
||||
'mesh-wifi-interface-mac.cc',
|
||||
# Not refactored
|
||||
'mesh-wifi-helper.cc',
|
||||
'mesh-wifi-mac-header.cc',
|
||||
@@ -24,10 +25,12 @@ def build(bld):
|
||||
headers.module = 'mesh'
|
||||
headers.source = [
|
||||
# Refactored
|
||||
'wifi-information-element.h',
|
||||
'mesh-point-device.h',
|
||||
'mesh-l2-routing-protocol.h',
|
||||
'mesh-wifi-beacon.h',
|
||||
'wifi-information-element.h',
|
||||
'mesh-wifi-interface-mac.h',
|
||||
'mesh-wifi-interface-mac-plugin.h',
|
||||
# Dirty
|
||||
'dot11s-codes.h',
|
||||
'hwmp-state.h',
|
||||
|
||||
Reference in New Issue
Block a user