22 #include "ns3/peer-management-protocol.h"
23 #include "peer-management-protocol-mac.h"
24 #include "ie-dot11s-configuration.h"
25 #include "ie-dot11s-id.h"
26 #include "ns3/mesh-point-device.h"
27 #include "ns3/simulator.h"
28 #include "ns3/assert.h"
30 #include "ns3/random-variable-stream.h"
31 #include "ns3/mesh-wifi-interface-mac.h"
32 #include "ns3/mesh-wifi-interface-mac-plugin.h"
33 #include "ns3/wifi-net-device.h"
34 #include "ns3/trace-source-accessor.h"
42 NS_OBJECT_ENSURE_REGISTERED (PeerManagementProtocol);
45 PeerManagementProtocol::GetTypeId (
void)
47 static TypeId tid = TypeId (
"ns3::dot11s::PeerManagementProtocol")
49 .AddConstructor<PeerManagementProtocol> ()
52 .AddAttribute (
"MaxNumberOfPeerLinks",
53 "Maximum number of peer links",
55 MakeUintegerAccessor (
56 &PeerManagementProtocol::m_maxNumberOfPeerLinks),
57 MakeUintegerChecker<uint8_t> ()
59 .AddAttribute (
"MaxBeaconShiftValue",
60 "Maximum number of TUs for beacon shifting",
62 MakeUintegerAccessor (
64 MakeUintegerChecker<uint16_t> ()
66 .AddAttribute (
"EnableBeaconCollisionAvoidance",
67 "Enable/Disable Beacon collision avoidance.",
73 .AddTraceSource (
"LinkOpen",
74 "New peer link opened",
77 .AddTraceSource (
"LinkClose",
78 "New peer link closed",
85 PeerManagementProtocol::PeerManagementProtocol () :
86 m_lastAssocId (0), m_lastLocalLinkId (1), m_enableBca (true), m_maxBeaconShift (15)
88 m_beaconShift = CreateObject<UniformRandomVariable> ();
90 PeerManagementProtocol::~PeerManagementProtocol ()
99 for (PeerLinksMap::iterator j = m_peerLinks.begin (); j != m_peerLinks.end (); j++)
101 for (PeerLinksOnInterface::iterator i = j->second.begin (); i != j->second.end (); i++)
107 m_peerLinks.clear ();
114 std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
115 for (std::vector<
Ptr<NetDevice> >::iterator i = interfaces.begin (); i != interfaces.end (); i++)
128 mac->InstallPlugin (plugin);
129 m_plugins[(*i)->GetIfIndex ()] = plugin;
131 m_peerLinks[(*i)->GetIfIndex ()] = newmap;
135 mp->AggregateObject (
this);
142 if (!GetBeaconCollisionAvoidance ())
147 PeerLinksMap::iterator iface = m_peerLinks.find (interface);
149 for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
153 if ((*i)->GetBeaconInterval () ==
Seconds (0))
158 retval->AddNeighboursTimingElementUnit ((*i)->GetLocalAid (), (*i)->GetLastBeacon (),
159 (*i)->GetBeaconInterval ());
168 for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++)
170 if (i->second->GetAddress () == peerAddress)
175 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
178 if (ShouldSendOpen (interface, peerAddress))
181 peerLink->MLMEActivePeerLinkOpen ();
188 peerLink->SetBeaconInformation (
Simulator::Now (), beaconInterval);
189 if (GetBeaconCollisionAvoidance ())
191 peerLink->SetBeaconTimingElement (*PeekPointer (timingElement));
200 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
201 if (peerManagementElement.SubtypeIsOpen ())
204 bool reject = !(ShouldAcceptOpen (interface, peerAddress, reasonCode));
207 peerLink = InitiateLink (interface, peerAddress, peerMeshPointAddress);
211 peerLink->OpenAccept (peerManagementElement.GetLocalLinkId (), meshConfig, peerMeshPointAddress);
215 peerLink->OpenReject (peerManagementElement.GetLocalLinkId (), meshConfig, peerMeshPointAddress,
223 if (peerManagementElement.SubtypeIsConfirm ())
225 peerLink->ConfirmAccept (peerManagementElement.GetLocalLinkId (),
226 peerManagementElement.GetPeerLinkId (), aid, meshConfig, peerMeshPointAddress);
228 if (peerManagementElement.SubtypeIsClose ())
230 peerLink->Close (peerManagementElement.GetLocalLinkId (), peerManagementElement.GetPeerLinkId (),
231 peerManagementElement.GetReasonCode ());
237 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
240 peerLink->MLMECancelPeerLink (REASON11S_MESH_CAPABILITY_POLICY_VIOLATION);
246 NS_LOG_DEBUG (
"transmission failed between "<<
GetAddress () <<
" and " << peerAddress <<
" failed, link will be closed");
247 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
250 peerLink->TransmissionFailure ();
257 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
260 peerLink->TransmissionSuccess ();
264 PeerManagementProtocol::InitiateLink (uint32_t interface,
Mac48Address peerAddress,
269 if (FindPeerLink (interface, peerAddress) != 0)
274 PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
276 PeerLinksMap::iterator iface = m_peerLinks.find (interface);
278 new_link->SetLocalAid (m_lastAssocId++);
279 new_link->SetInterface (interface);
280 new_link->SetLocalLinkId (m_lastLocalLinkId++);
281 new_link->SetPeerAddress (peerAddress);
282 new_link->SetPeerMeshPointAddress (peerMeshPointAddress);
283 new_link->SetMacPlugin (plugin->second);
285 iface->second.push_back (new_link);
292 PeerLinksMap::iterator iface = m_peerLinks.find (interface);
294 for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
296 if ((*i)->GetPeerAddress () == peerAddress)
298 if ((*i)->LinkIsIdle ())
301 (iface->second).erase (i);
316 m_peerStatusCallback = cb;
319 std::vector<Mac48Address>
322 std::vector<Mac48Address> retval;
323 PeerLinksMap::const_iterator iface = m_peerLinks.find (interface);
325 for (PeerLinksOnInterface::const_iterator i = iface->second.begin (); i != iface->second.end (); i++)
327 if ((*i)->LinkIsEstab ())
329 retval.push_back ((*i)->GetPeerAddress ());
335 std::vector< Ptr<PeerLink> >
338 std::vector< Ptr<PeerLink> > links;
340 for (PeerLinksMap::const_iterator iface = m_peerLinks.begin (); iface != m_peerLinks.end (); ++iface)
342 for (PeerLinksOnInterface::const_iterator i = iface->second.begin ();
343 i != iface->second.end (); i++)
344 if ((*i)->LinkIsEstab ())
345 links.push_back (*i);
352 Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
355 return (peerLink->LinkIsEstab ());
360 PeerManagementProtocol::ShouldSendOpen (uint32_t interface,
Mac48Address peerAddress)
362 return (m_stats.linksTotal <= m_maxNumberOfPeerLinks);
366 PeerManagementProtocol::ShouldAcceptOpen (uint32_t interface,
Mac48Address peerAddress,
369 if (m_stats.linksTotal > m_maxNumberOfPeerLinks)
371 reasonCode = REASON11S_MESH_MAX_PEERS;
380 if (!GetBeaconCollisionAvoidance ())
384 PeerLinksMap::iterator iface = m_peerLinks.find (interface);
386 NS_ASSERT (m_plugins.find (interface) != m_plugins.end ());
388 std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface);
389 std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface);
390 if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ()))
395 uint16_t lastBeaconInTimeElement = (uint16_t) ((lastBeacon->second.GetMicroSeconds () >> 8) & 0xffff);
397 NS_ASSERT_MSG (TuToTime (m_maxBeaconShift) <= m_beaconInterval[interface],
"Wrong beacon shift parameters");
399 if (iface->second.size () == 0)
402 ShiftOwnBeacon (interface);
407 for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
409 bool myBeaconExists =
false;
411 for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbors.begin (); j != neighbors.end (); j++)
413 if ((*i)->GetPeerAid () == (*j)->GetAid ())
416 myBeaconExists =
true;
420 ((int16_t) ((*j)->GetLastBeacon () - lastBeaconInTimeElement) >= 0) &&
421 (((*j)->GetLastBeacon () - lastBeaconInTimeElement) % (4 * TimeToTu (beaconInterval->second)) == 0)
424 ShiftOwnBeacon (interface);
431 ShiftOwnBeacon (interface);
438 PeerManagementProtocol::ShiftOwnBeacon (uint32_t interface)
443 shift = (int) m_beaconShift->GetValue ();
447 PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
449 plugin->second->SetBeaconShift (TuToTime (shift));
453 PeerManagementProtocol::TuToTime (
int x)
458 PeerManagementProtocol::TimeToTu (Time x)
460 return (
int)(x.GetMicroSeconds () / 1024);
466 NS_LOG_LOGIC (
"link_open " << myIface <<
" " << peerIface);
467 m_stats.linksOpened++;
468 m_stats.linksTotal++;
469 if (!m_peerStatusCallback.IsNull ())
471 m_peerStatusCallback (peerMp, peerIface, interface,
true);
473 m_linkOpenTraceSrc (myIface, peerIface);
479 NS_LOG_LOGIC (
"link_close " << myIface <<
" " << peerIface);
480 m_stats.linksClosed++;
481 m_stats.linksTotal--;
482 if (!m_peerStatusCallback.IsNull ())
484 m_peerStatusCallback (peerMp, peerIface, interface,
false);
486 m_linkCloseTraceSrc (myIface, peerIface);
493 PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
495 NS_LOG_DEBUG (
"Link between me:" << m_address <<
" my interface:" << plugin->second->GetAddress ()
496 <<
" and peer mesh point:" << peerMeshPointAddress <<
" and its interface:" << peerAddress
497 <<
", at my interface ID:" <<
interface << ". State movement:" << ostate << " -> " << nstate);
498 if ((nstate == PeerLink::ESTAB) && (ostate != PeerLink::ESTAB))
500 NotifyLinkOpen (peerMeshPointAddress, peerAddress, plugin->second->GetAddress (), interface);
502 if ((ostate == PeerLink::ESTAB) && (nstate != PeerLink::ESTAB))
504 NotifyLinkClose (peerMeshPointAddress, peerAddress, plugin->second->GetAddress (), interface);
506 if (nstate == PeerLink::IDLE)
513 PeerManagementProtocol::GetNumberOfLinks ()
515 return m_stats.linksTotal;
518 PeerManagementProtocol::GetMeshId ()
const
524 PeerManagementProtocol::SetMeshId (std::string s)
526 m_meshId = Create<IeMeshId> (s);
538 m_beaconInterval[interface] = beaconInterval;
540 PeerManagementProtocol::Statistics::Statistics (uint16_t t) :
541 linksTotal (t), linksOpened (0), linksClosed (0)
545 PeerManagementProtocol::Statistics::Print (std::ostream & os)
const
548 "linksTotal=\"" << linksTotal <<
"\" "
549 "linksOpened=\"" << linksOpened <<
"\" "
550 "linksClosed=\"" << linksClosed <<
"\"/>" << std::endl;
555 os <<
"<PeerManagementProtocol>" << std::endl;
557 for (PeerManagementProtocolMacMap::const_iterator plugins = m_plugins.begin (); plugins != m_plugins.end (); plugins++)
560 plugins->second->Report (os);
562 PeerLinksMap::const_iterator iface = m_peerLinks.find (plugins->second->m_ifIndex);
564 for (PeerLinksOnInterface::const_iterator i = iface->second.begin (); i != iface->second.end (); i++)
569 os <<
"</PeerManagementProtocol>" << std::endl;
572 PeerManagementProtocol::ResetStats ()
574 m_stats = Statistics (m_stats.linksTotal);
575 for (PeerManagementProtocolMacMap::const_iterator plugins = m_plugins.begin (); plugins != m_plugins.end (); plugins++)
577 plugins->second->ResetStats ();
605 PeerManagementProtocol::GetBeaconCollisionAvoidance ()
const
void NotifyLinkClose(Mac48Address peerMp, Mac48Address peerIface, Mac48Address myIface, uint32_t interface)
Aux. method to register closed links.
virtual void DoInitialize()
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
void NotifyLinkOpen(Mac48Address peerMp, Mac48Address peerIface, Mac48Address myIface, uint32_t interface)
Aux. method to register open links.
Ptr< UniformRandomVariable > m_beaconShift
Add randomness to beacon shift.
void Report(std::ostream &) const
: Report statistics
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Ptr< PeerLink > FindPeerLink(uint32_t interface, Mac48Address peerAddress)
Find active peer link by my interface and peer interface MAC.
std::vector< Ptr< IeBeaconTimingUnit > > NeighboursTimingUnitsList
#define NS_FATAL_ERROR(msg)
fatal error handling
LinkEventCallback m_linkCloseTraceSrc
LinkClose trace source.
PeerState
Peer Link state:
bool IsActiveLink(uint32_t interface, Mac48Address peerAddress)
Checks if there is established link.
std::vector< Ptr< PeerLink > > PeerLinksOnInterface
std::vector< Mac48Address > GetPeers(uint32_t interface) const
Get list of active peers of my given interface.
See 7.3.2.85 of draft 2.07.
Hold together all Wifi-related objects.This class holds together ns3::WifiChannel, ns3::WifiPhy, ns3::WifiMac, and, ns3::WifiRemoteStationManager.
static Mac48Address GetBroadcast(void)
void NotifyBeaconSent(uint32_t interface, Time beaconInterval)
Notify about beacon send event, needed to schedule BCA.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Mac48Address GetAddress()
Get mesh point address. TODO this used by plugins only. Now MAC plugins can ask MP addrress directly ...
void SetPeerLinkStatusCallback(Callback< void, Mac48Address, Mac48Address, uint32_t, bool > cb)
Set peer link status change callback.
#define NS_LOG_LOGIC(msg)
std::vector< Ptr< PeerLink > > GetPeerLinks() const
Get list of all active peer links.
static Mac48Address ConvertFrom(const Address &address)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Mac48Address GetAddress() const
debug only, used to print established links
LinkEventCallback m_linkOpenTraceSrc
LinkOpen trace source.
void ReceivePeerLinkFrame(uint32_t interface, Mac48Address peerAddress, Mac48Address peerMeshPointAddress, uint16_t aid, IePeerManagement peerManagementElement, IeConfiguration meshConfig)
Methods that handle Peer link management frames interaction:
Ptr< IeBeaconTiming > GetBeaconTimingElement(uint32_t interface)
When we are sending a beacon - we fill beacon timing element.
void PeerLinkStatus(uint32_t interface, Mac48Address peerAddress, Mac48Address peerMeshPointAddres, PeerLink::PeerState ostate, PeerLink::PeerState nstate)
Indicates changes in peer links.
#define NS_ASSERT_MSG(condition, message)
void ConfigurationMismatch(uint32_t interface, Mac48Address peerAddress)
Cancels peer link due to broken configuration (Mesh ID or Supported rates)
void TransmissionFailure(uint32_t interface, const Mac48Address peerAddress)
Cancels peer link due to successive transmission failures.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
void CheckBeaconCollisions(uint32_t interface)
BCA.
PmpReasonCode
Codes used by 802.11s Peer Management Protocol.
#define NS_LOG_DEBUG(msg)
bool m_enableBca
Flag which enables BCA.
void ReceiveBeacon(uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr< IeBeaconTiming > beaconTiming)
To initiate peer link we must notify about received beacon.
Describes Mesh Configuration Element see 7.3.2.86 of 802.11s draft 3.0.
void SetBeaconCollisionAvoidance(bool enable)
Enable or disable beacon collision avoidance.
int64_t AssignStreams(int64_t stream)
Hold an floating point type.
uint16_t m_maxBeaconShift
Beacon can be shifted at [-m_maxBeaconShift; +m_maxBeaconShift] TUs.
void SetAttribute(std::string name, const AttributeValue &value)
Basic MAC of mesh point Wi-Fi interface. Its function is extendable through plugins mechanism...
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
bool Install(Ptr< MeshPointDevice >)
Install PMP on given mesh point.
void TransmissionSuccess(uint32_t interface, const Mac48Address peerAddress)
resets transmission failure statistics