Added new peer manager class, an old one we keep without change
authorKirill Andreev <andreev@iitp.ru>
Thu, 19 Mar 2009 17:28:37 +0300
changeset 4857 ddfb13420455
parent 4856 b7241df728a3
child 4858 78437693dcc7
Added new peer manager class, an old one we keep without change
src/devices/mesh/mesh-wifi-helper.cc
src/devices/mesh/mesh-wifi-interface-mac-plugin.h
src/devices/mesh/mesh-wifi-interface-mac.cc
src/devices/mesh/mesh-wifi-interface-mac.h
src/devices/mesh/mesh-wifi-peer-manager.cc
src/devices/mesh/mesh-wifi-peer-manager.h
src/devices/mesh/peer-manager-plugin.cc
src/devices/mesh/peer-manager-plugin.h
src/devices/mesh/peer-manager-protocol.cc
src/devices/mesh/peer-manager-protocol.h
src/devices/mesh/wscript
--- a/src/devices/mesh/mesh-wifi-helper.cc	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-helper.cc	Thu Mar 19 17:28:37 2009 +0300
@@ -27,6 +27,7 @@
 #include "ns3/wifi-channel.h"
 #include "ns3/wifi-remote-station-manager.h"
 #include "ns3/mesh-wifi-interface-mac.h"
+#include "ns3/peer-manager-plugin.h"
 
 namespace ns3 {
 
@@ -118,6 +119,8 @@
     std::vector<Ptr<WifiNetDevice> > nodeDevices;
     Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
     Ptr<MeshWifiInterfaceMac> mac = m_meshMac.Create<MeshWifiInterfaceMac> ();
+    Ptr<Dot11sPeerManagerMacPlugin> peer_plugin = Create<Dot11sPeerManagerMacPlugin>();
+    mac->InstallPlugin(peer_plugin);
     Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
     Ptr<WifiPhy> phy = phyHelper.Create (node, device);
     mac->SetAddress (Mac48Address::Allocate ());
--- a/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Thu Mar 19 17:28:37 2009 +0300
@@ -41,11 +41,8 @@
 class MeshWifiInterfaceMacPlugin : public RefCountBase
 {
 public:
-#if 0
-  MeshWifiInterfaceMacPlugin ();
   /// This is for subclasses
-  virtual ~MeshWifiInterfaceMacPlugin ();
-#endif
+  virtual ~MeshWifiInterfaceMacPlugin (){};
   /// Each plugin must be installed on interface to work 
   virtual void SetParent (Ptr<MeshWifiInterfaceMac> parent) = 0; 
   /** 
--- a/src/devices/mesh/mesh-wifi-interface-mac.cc	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac.cc	Thu Mar 19 17:28:37 2009 +0300
@@ -461,9 +461,9 @@
   return m_tbtt;
 }
 
-void MeshWifiInterfaceMac::ShiftTBTT (Time shift)
+void MeshWifiInterfaceMac::ShiftTbtt (Time shift)
 {
-  // User of ShiftTBTT () must take care don't shift it to the past
+  // User of ShiftTbtt () must take care don't shift it to the past
   NS_ASSERT (GetTbtt() + shift > Simulator::Now());
   
   m_tbtt += shift;
--- a/src/devices/mesh/mesh-wifi-interface-mac.h	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac.h	Thu Mar 19 17:28:37 2009 +0300
@@ -112,9 +112,9 @@
    * 
    * 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. 
+   * \attention User of ShiftTbtt () must take care to not shift it to the past. 
    */
-  void ShiftTBTT (Time shift);
+  void ShiftTbtt (Time shift);
   /**
    * \brief Set maximum software delay. Maximum software delay must be smaller than beacon interval.
    *
--- a/src/devices/mesh/mesh-wifi-peer-manager.cc	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-peer-manager.cc	Thu Mar 19 17:28:37 2009 +0300
@@ -29,9 +29,9 @@
 NS_LOG_COMPONENT_DEFINE ("WifiPeerManager");
 namespace ns3 {
 /***************************************************
- * PeerLinkDescriptor
+ * PeerLinkDescriptorDUP
  ***************************************************/
-WifiPeerLinkDescriptor::WifiPeerLinkDescriptor ():
+WifiPeerLinkDescriptorDUP::WifiPeerLinkDescriptorDUP ():
     m_localLinkId (0),
     m_peerLinkId (0),
     m_state (IDLE),
@@ -40,134 +40,134 @@
 {}
 
 void
-WifiPeerLinkDescriptor::SetPeerAddress (Mac48Address macaddr)
+WifiPeerLinkDescriptorDUP::SetPeerAddress (Mac48Address macaddr)
 {
   m_peerAddress = macaddr;
 }
 
 void
-WifiPeerLinkDescriptor::SetLocalAddress (Mac48Address macaddr)
+WifiPeerLinkDescriptorDUP::SetLocalAddress (Mac48Address macaddr)
 {
   m_localAddress = macaddr;
 }
 
 void
-WifiPeerLinkDescriptor::SetLocalLinkId (uint16_t id)
+WifiPeerLinkDescriptorDUP::SetLocalLinkId (uint16_t id)
 {
   m_localLinkId = id;
 }
 void
-WifiPeerLinkDescriptor::SetLocalAid (uint16_t aid)
+WifiPeerLinkDescriptorDUP::SetLocalAid (uint16_t aid)
 {
   m_assocId = aid;
 }
 void
-WifiPeerLinkDescriptor::SetBeaconInformation (Time lastBeacon, Time beaconInterval)
+WifiPeerLinkDescriptorDUP::SetBeaconInformation (Time lastBeacon, Time beaconInterval)
 {
   m_lastBeacon = lastBeacon;
   m_beaconInterval = beaconInterval;
   m_beaconLossTimer.Cancel ();
   Time delay = Seconds (beaconInterval.GetSeconds()*m_maxBeaconLoss);
   NS_ASSERT (delay.GetMicroSeconds() != 0);
-  m_beaconLossTimer = Simulator::Schedule (delay, &WifiPeerLinkDescriptor::BeaconLoss, this);
+  m_beaconLossTimer = Simulator::Schedule (delay, &WifiPeerLinkDescriptorDUP::BeaconLoss, this);
 }
 
 void
-WifiPeerLinkDescriptor::SetMaxBeaconLoss (uint8_t maxBeaconLoss)
+WifiPeerLinkDescriptorDUP::SetMaxBeaconLoss (uint8_t maxBeaconLoss)
 {
   m_maxBeaconLoss = maxBeaconLoss;
 }
 
 void
-WifiPeerLinkDescriptor::SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb)
+WifiPeerLinkDescriptorDUP::SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb)
 {
   m_linkStatusCallback = cb;
 }
 void
-WifiPeerLinkDescriptor::BeaconLoss ()
+WifiPeerLinkDescriptorDUP::BeaconLoss ()
 {
   StateMachine (CNCL);
 }
 
 void
-WifiPeerLinkDescriptor::SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming)
+WifiPeerLinkDescriptorDUP::SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming)
 {
   m_beaconTiming = beaconTiming;
 }
 
 Mac48Address
-WifiPeerLinkDescriptor::GetPeerAddress () const
+WifiPeerLinkDescriptorDUP::GetPeerAddress () const
 {
   return m_peerAddress;
 }
 
 Mac48Address
-WifiPeerLinkDescriptor::GetLocalAddress () const
+WifiPeerLinkDescriptorDUP::GetLocalAddress () const
 {
   return m_localAddress;
 }
 
 
 uint16_t
-WifiPeerLinkDescriptor::GetLocalAid () const
+WifiPeerLinkDescriptorDUP::GetLocalAid () const
 {
   return m_assocId;
 }
 
 Time
-WifiPeerLinkDescriptor::GetLastBeacon () const
+WifiPeerLinkDescriptorDUP::GetLastBeacon () const
 {
   return m_lastBeacon;
 }
 
 Time
-WifiPeerLinkDescriptor::GetBeaconInterval () const
+WifiPeerLinkDescriptorDUP::GetBeaconInterval () const
 {
   return m_beaconInterval;
 }
 IeDot11sBeaconTiming
-WifiPeerLinkDescriptor::GetBeaconTimingElement () const
+WifiPeerLinkDescriptorDUP::GetBeaconTimingElement () const
 {
   return m_beaconTiming;
 }
 
 void
-WifiPeerLinkDescriptor::ClearTimingElement ()
+WifiPeerLinkDescriptorDUP::ClearTimingElement ()
 {
   m_beaconTiming.ClearTimingElement ();
 }
 
 
-void  WifiPeerLinkDescriptor::MLMECancelPeerLink (dot11sReasonCode reason)
+void  WifiPeerLinkDescriptorDUP::MLMECancelPeerLink (dot11sReasonCode reason)
 {
   StateMachine (CNCL,reason);
 }
 
-void  WifiPeerLinkDescriptor::MLMEPassivePeerLinkOpen ()
+void  WifiPeerLinkDescriptorDUP::MLMEPassivePeerLinkOpen ()
 {
   StateMachine (PASOPN);
 }
 
-void  WifiPeerLinkDescriptor::MLMEActivePeerLinkOpen ()
+void  WifiPeerLinkDescriptorDUP::MLMEActivePeerLinkOpen ()
 {
   StateMachine (ACTOPN);
 }
-void WifiPeerLinkDescriptor::MLMEPeeringRequestReject ()
+void WifiPeerLinkDescriptorDUP::MLMEPeeringRequestReject ()
 {
   StateMachine (REQ_RJCT, REASON11S_PEER_LINK_CANCELLED);
 }
 #if 0
-void  WifiPeerLinkDescriptor::MLMEBindSecurityAssociation ()
+void  WifiPeerLinkDescriptorDUP::MLMEBindSecurityAssociation ()
 {
   StateMachine (BNDSA);
 }
 #endif
 void
-WifiPeerLinkDescriptor::SetMac (Ptr<MeshWifiMac> mac)
+WifiPeerLinkDescriptorDUP::SetMac (Ptr<MeshWifiMac> mac)
 {
   m_mac = mac;
 }
-void WifiPeerLinkDescriptor::PeerLinkClose (uint16_t localLinkId,uint16_t peerLinkId, dot11sReasonCode reason)
+void WifiPeerLinkDescriptorDUP::PeerLinkClose (uint16_t localLinkId,uint16_t peerLinkId, dot11sReasonCode reason)
 {
   if (peerLinkId != 0 && m_localLinkId != peerLinkId)
     return;
@@ -178,7 +178,7 @@
   StateMachine (CLS_ACPT, reason);
 }
 
-void WifiPeerLinkDescriptor::PeerLinkOpenAccept (uint16_t localLinkId, IeDot11sConfiguration  conf)
+void WifiPeerLinkDescriptorDUP::PeerLinkOpenAccept (uint16_t localLinkId, IeDot11sConfiguration  conf)
 {
   if (m_peerLinkId == 0)
     m_peerLinkId = localLinkId;
@@ -186,7 +186,7 @@
   StateMachine (OPN_ACPT);
 }
 
-void WifiPeerLinkDescriptor::PeerLinkOpenReject (uint16_t localLinkId, IeDot11sConfiguration  conf,dot11sReasonCode reason)
+void WifiPeerLinkDescriptorDUP::PeerLinkOpenReject (uint16_t localLinkId, IeDot11sConfiguration  conf,dot11sReasonCode reason)
 {
   if ( m_peerLinkId == 0)
     m_peerLinkId = localLinkId;
@@ -195,7 +195,7 @@
 }
 
 void
-WifiPeerLinkDescriptor::PeerLinkConfirmAccept (uint16_t localLinkId,uint16_t peerLinkId, uint16_t peerAid, IeDot11sConfiguration  conf)
+WifiPeerLinkDescriptorDUP::PeerLinkConfirmAccept (uint16_t localLinkId,uint16_t peerLinkId, uint16_t peerAid, IeDot11sConfiguration  conf)
 {
   if ( m_localLinkId != peerLinkId)
     return;
@@ -208,7 +208,7 @@
   StateMachine (CNF_ACPT);
 }
 
-void   WifiPeerLinkDescriptor:: PeerLinkConfirmReject (uint16_t localLinkId, uint16_t peerLinkId,
+void   WifiPeerLinkDescriptorDUP:: PeerLinkConfirmReject (uint16_t localLinkId, uint16_t peerLinkId,
     IeDot11sConfiguration  conf,dot11sReasonCode reason)
 {
   if (m_localLinkId != peerLinkId)
@@ -222,7 +222,7 @@
 }
 
 bool
-WifiPeerLinkDescriptor::LinkIsEstab () const
+WifiPeerLinkDescriptorDUP::LinkIsEstab () const
 {
   if (m_state == ESTAB)
     return true;
@@ -230,7 +230,7 @@
 }
 
 bool
-WifiPeerLinkDescriptor::LinkIsIdle () const
+WifiPeerLinkDescriptorDUP::LinkIsIdle () const
 {
   if (m_state == IDLE)
     return true;
@@ -238,7 +238,7 @@
 }
 
 void
-WifiPeerLinkDescriptor::StateMachine (PeerEvent event,dot11sReasonCode reasoncode)
+WifiPeerLinkDescriptorDUP::StateMachine (PeerEvent event,dot11sReasonCode reasoncode)
 {
   switch (m_state)
     {
@@ -481,29 +481,29 @@
     }
 }
 
-void WifiPeerLinkDescriptor::ClearRetryTimer ()
+void WifiPeerLinkDescriptorDUP::ClearRetryTimer ()
 {
   m_retryTimer.Cancel ();
 }
 
-void WifiPeerLinkDescriptor::ClearConfirmTimer ()
+void WifiPeerLinkDescriptorDUP::ClearConfirmTimer ()
 {
   m_confirmTimer.Cancel ();
 }
 
-void WifiPeerLinkDescriptor::ClearHoldingTimer ()
+void WifiPeerLinkDescriptorDUP::ClearHoldingTimer ()
 {
   m_holdingTimer.Cancel ();
 }
 
-void WifiPeerLinkDescriptor::SendPeerLinkClose (dot11sReasonCode reasoncode)
+void WifiPeerLinkDescriptorDUP::SendPeerLinkClose (dot11sReasonCode reasoncode)
 {
   IeDot11sPeerManagement peerElement;
   peerElement.SetPeerClose (m_localLinkId, m_peerLinkId, reasoncode);
   m_mac->SendPeerLinkClose (peerElement,m_peerAddress);
 }
 
-void WifiPeerLinkDescriptor::SendPeerLinkOpen ()
+void WifiPeerLinkDescriptorDUP::SendPeerLinkOpen ()
 {
   IeDot11sPeerManagement peerElement;
   peerElement.SetPeerOpen (m_localLinkId);
@@ -511,29 +511,29 @@
   m_mac->SendPeerLinkOpen (peerElement, m_peerAddress);
 }
 
-void WifiPeerLinkDescriptor::SendPeerLinkConfirm ()
+void WifiPeerLinkDescriptorDUP::SendPeerLinkConfirm ()
 {
   IeDot11sPeerManagement peerElement;
   peerElement.SetPeerConfirm (m_localLinkId, m_peerLinkId);
   m_mac->SendPeerLinkConfirm (peerElement, m_peerAddress, m_assocId);
 }
 
-void WifiPeerLinkDescriptor::SetHoldingTimer ()
+void WifiPeerLinkDescriptorDUP::SetHoldingTimer ()
 {
-  m_holdingTimer = Simulator::Schedule (dot11sParameters::dot11MeshHoldingTimeout, &WifiPeerLinkDescriptor::HoldingTimeout, this);
+  m_holdingTimer = Simulator::Schedule (dot11sParameters::dot11MeshHoldingTimeout, &WifiPeerLinkDescriptorDUP::HoldingTimeout, this);
 }
 
-void WifiPeerLinkDescriptor::HoldingTimeout ()
+void WifiPeerLinkDescriptorDUP::HoldingTimeout ()
 {
   StateMachine (TOH);
 }
 
-void WifiPeerLinkDescriptor::SetRetryTimer ()
+void WifiPeerLinkDescriptorDUP::SetRetryTimer ()
 {
-  m_retryTimer = Simulator::Schedule (dot11sParameters::dot11MeshRetryTimeout, &WifiPeerLinkDescriptor::RetryTimeout, this);
+  m_retryTimer = Simulator::Schedule (dot11sParameters::dot11MeshRetryTimeout, &WifiPeerLinkDescriptorDUP::RetryTimeout, this);
 }
 
-void WifiPeerLinkDescriptor::RetryTimeout ()
+void WifiPeerLinkDescriptorDUP::RetryTimeout ()
 {
   if ( m_retryCounter < dot11sParameters::dot11MeshMaxRetries)
     StateMachine (TOR1);
@@ -541,12 +541,12 @@
     StateMachine (TOR2);
 }
 
-void WifiPeerLinkDescriptor::SetConfirmTimer ()
+void WifiPeerLinkDescriptorDUP::SetConfirmTimer ()
 {
-  m_confirmTimer = Simulator::Schedule (dot11sParameters::dot11MeshConfirmTimeout, &WifiPeerLinkDescriptor::ConfirmTimeout, this);
+  m_confirmTimer = Simulator::Schedule (dot11sParameters::dot11MeshConfirmTimeout, &WifiPeerLinkDescriptorDUP::ConfirmTimeout, this);
 }
 
-void WifiPeerLinkDescriptor::ConfirmTimeout ()
+void WifiPeerLinkDescriptorDUP::ConfirmTimeout ()
 {
   StateMachine (TOC);
 }
@@ -604,7 +604,7 @@
     j++)
     {
       int to_delete = 0;
-      for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = j->second.begin (); i != j->second.end(); i++)
+      for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = j->second.begin (); i != j->second.end(); i++)
         {
           to_delete ++;
           (*i)->ClearTimingElement ();
@@ -641,7 +641,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     {
       if ((*i)->GetPeerAddress () == peerAddress)
         {
@@ -650,7 +650,7 @@
           return;
         }
     }
-  Ptr<WifiPeerLinkDescriptor> new_descriptor =
+  Ptr<WifiPeerLinkDescriptorDUP> new_descriptor =
     AddDescriptor (portAddress, peerAddress, Simulator::Now(), beaconInterval);
   new_descriptor->SetBeaconTimingElement (beaconTiming);
 }
@@ -668,7 +668,7 @@
       //Add a mac pointer:
       m_macPointers[meshWifiMac->GetAddress ()] = meshWifiMac;
       //Add descriptor array:
-      std::vector<Ptr<WifiPeerLinkDescriptor> > descriptors;
+      std::vector<Ptr<WifiPeerLinkDescriptorDUP> > descriptors;
       m_peerDescriptors[meshWifiMac->GetAddress ()] = descriptors;
       //Add beacon timers:
       struct BeaconInfo myBeacon;
@@ -681,7 +681,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       {
         if (ShouldSendOpen (portAddress, peerAddress))
@@ -703,7 +703,7 @@
     return;
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       {
         (*i)->PeerLinkOpenAccept (peerMan.GetLocalLinkId(), conf);
@@ -711,7 +711,7 @@
       }
   BeaconInfoMap::iterator myBeacon =  m_myBeaconInfo.find (portAddress);
   NS_ASSERT (myBeacon != m_myBeaconInfo.end());
-  Ptr<WifiPeerLinkDescriptor>new_descriptor = AddDescriptor (
+  Ptr<WifiPeerLinkDescriptorDUP>new_descriptor = AddDescriptor (
         portAddress,
         peerAddress,
         Simulator::Now (),
@@ -730,7 +730,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       (*i)->PeerLinkConfirmAccept (peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerAid, meshConfig);
 }
@@ -744,7 +744,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       {
         (*i)->PeerLinkClose (peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerMan.GetReasonCode());
@@ -760,7 +760,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       {
         (*i)->MLMECancelPeerLink (REASON11S_MESH_CONFIGURATION_POLICY_VIOLATION);
@@ -775,7 +775,7 @@
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
   IeDot11sBeaconTiming return_val;
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     {
       //Just go through all neighbor entries and add it to timing element:
       return_val.AddNeighboursTimingElementUnit (
@@ -795,19 +795,19 @@
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
   IeDot11sBeaconTiming return_val;
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == addr)
       return_val =  (*i)->GetBeaconTimingElement ();
   return return_val;
 }
-Ptr<WifiPeerLinkDescriptor>
+Ptr<WifiPeerLinkDescriptorDUP>
 WifiPeerManager::AddDescriptor (
   Mac48Address portAddress,
   Mac48Address peerAddress,
   Time lastBeacon,
   Time beaconInterval)
 {
-  Ptr<WifiPeerLinkDescriptor> new_descriptor = Create<WifiPeerLinkDescriptor> ();
+  Ptr<WifiPeerLinkDescriptorDUP> new_descriptor = Create<WifiPeerLinkDescriptorDUP> ();
   if (m_assocId == 0xff)
     m_assocId = 0;
   if (m_localLinkId == 0xff)
@@ -863,7 +863,7 @@
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
   std::vector<Mac48Address> return_value;
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     return_value.push_back ((*i)->GetPeerAddress());
   return return_value;
 }
@@ -873,7 +873,7 @@
 {
   PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
   NS_ASSERT (port != m_peerDescriptors.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     if ((*i)->GetPeerAddress () == peerAddress)
       return ((*i)->LinkIsEstab ());
   return false;
@@ -916,7 +916,7 @@
   NS_ASSERT (port != m_peerDescriptors.end());
   BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find (portAddress);
   NS_ASSERT (myBeacon != m_myBeaconInfo.end());
-  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+  for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
     {
       IeDot11sBeaconTiming::NeighboursTimingUnitsList neighbours;
       neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList();
--- a/src/devices/mesh/mesh-wifi-peer-manager.h	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-peer-manager.h	Thu Mar 19 17:28:37 2009 +0300
@@ -36,10 +36,10 @@
 /**
  * \ingroup mesh
  */
-class WifiPeerLinkDescriptor : public RefCountBase
+class WifiPeerLinkDescriptorDUP : public RefCountBase
 {
 public:
-  WifiPeerLinkDescriptor ();
+  WifiPeerLinkDescriptorDUP ();
   /**
    * Beacon loss processing:
    */
@@ -64,7 +64,7 @@
   void  SetLocalAid     (uint16_t aid);
   void  SetPeerAid      (uint16_t aid);
   void  SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming);
-  void  SetPeerLinkDescriptorElement (IeDot11sPeerManagement peerLinkElement);
+  void  SetPeerLinkDescriptorDUPElement (IeDot11sPeerManagement peerLinkElement);
   Mac48Address GetPeerAddress () const;
   /**
    * Debug purpose
@@ -74,7 +74,7 @@
   Time  GetLastBeacon () const;
   Time  GetBeaconInterval () const;
   IeDot11sBeaconTiming    GetBeaconTimingElement () const;
-  IeDot11sPeerManagement  GetPeerLinkDescriptorElement () const;
+  IeDot11sPeerManagement  GetPeerLinkDescriptorDUPElement () const;
   void  ClearTimingElement ();
   /* MLME */
   void  MLMECancelPeerLink (dot11sReasonCode reason);
@@ -253,7 +253,7 @@
     Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
     Time beaconInterval; //Beacon interval of my station;
   };
-  typedef std::map<Mac48Address, std::vector<Ptr<WifiPeerLinkDescriptor> >, std::less<Mac48Address> >  PeerDescriptorsMap;
+  typedef std::map<Mac48Address, std::vector<Ptr<WifiPeerLinkDescriptorDUP> >, std::less<Mac48Address> >  PeerDescriptorsMap;
   typedef std::map<Mac48Address, Ptr<MeshWifiMac>,std::less<Mac48Address> > MeshMacMap;
   typedef std::map<Mac48Address, BeaconInfo, std::less<Mac48Address> > BeaconInfoMap;
 
@@ -282,7 +282,7 @@
   //and check if the too many  beacons were lost:
   Time  m_peerLinkCleanupPeriod;
   EventId  m_cleanupEvent;
-  Ptr<WifiPeerLinkDescriptor> AddDescriptor (
+  Ptr<WifiPeerLinkDescriptorDUP> AddDescriptor (
     Mac48Address portAddress,
     Mac48Address peerAddress,
     Time lastBeacon,
--- a/src/devices/mesh/peer-manager-plugin.cc	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/peer-manager-plugin.cc	Thu Mar 19 17:28:37 2009 +0300
@@ -24,7 +24,7 @@
 #include "ns3/mesh-wifi-interface-mac.h"
 
 #include "ns3/log.h"
-
+NS_LOG_COMPONENT_DEFINE("PeerManager");
 namespace ns3 {
 Dot11sPeerManagerMacPlugin::Dot11sPeerManagerMacPlugin ()
 {
@@ -37,11 +37,30 @@
 void
 Dot11sPeerManagerMacPlugin::SetParent (Ptr<MeshWifiInterfaceMac> parent)
 {
+  NS_LOG_UNCOND("ADD PARENT");
+  m_parent = parent;
 }
 
 bool
 Dot11sPeerManagerMacPlugin::Receive (Ptr<Packet> packet, const WifiMacHeader & header)
 {
+  NS_LOG_UNCOND("received a frame");
+  if(header.IsBeacon())
+  {
+    NS_LOG_UNCOND("Beacon recevied by PM from"<<header.GetAddr2 ());
+    Mac48Address peerAddress = header.GetAddr2 ();
+    Ptr<Packet> myBeacon = packet->Copy ();
+#if 0
+      packet->RemoveHeader (beacon);
+      m_peerManager->SetReceivedBeaconTimers (
+        GetAddress (),
+        from,
+        Simulator::Now (),
+        MicroSeconds (beacon.GetBeaconIntervalUs()),
+        beacon.GetIeDot11sBeaconTiming ()
+      );
+#endif
+  }
   return false;
 }
 
@@ -54,17 +73,6 @@
 void
 Dot11sPeerManagerMacPlugin::UpdateBeacon (MeshWifiBeacon & beacon) const
 {
-}
-
-void
-Dot11sPeerManagerMacPlugin::SetDeliverPeerLinkFrameCallbback (
-    Callback<void, uint32_t, Mac48Address, uint16_t, IeDot11sConfiguration, IeDot11sPeerManagement>
-    )
-{
-}
-
-void
-Dot11sPeerManagerMacPlugin::SetDeliverBeaconCallback (Callback<void>)
-{
+  NS_LOG_UNCOND("I am sending a beacon");
 }
 }//namespace ns3
--- a/src/devices/mesh/peer-manager-plugin.h	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/peer-manager-plugin.h	Thu Mar 19 17:28:37 2009 +0300
@@ -27,7 +27,9 @@
 class MeshWifiInterfaceMac;
 class IeDot11sConfiguration;
 class IeDot11sPeerManagement;
+class Dot11sPeerManagerProtocol;
   /**
+   * \ingroup dot11s
    * \brief This is plugin to Mesh WiFi MAC, which implements
    * interface to dot11s peer management protocol: it takes proper
    * frames from MAC-layer, extracts peer link management information
@@ -50,6 +52,7 @@
     /**
      * \}
      */
+    void SetPeerManagerProtcol(Ptr<Dot11sPeerManagerProtocol> protocol);
     /**
      * Deliver Peer link management information to the protocol-part
      * \param void is returning value - we pass a frame and forget
@@ -67,16 +70,24 @@
         Callback<void, uint32_t, Mac48Address, uint16_t, IeDot11sConfiguration, IeDot11sPeerManagement>
         );
     /**
-     * \brief Notify that beacon was received - needed to initiate state
-     * machine.
-     * \details Now we just notify about beacon and pass no information
-     * to upper layer (TODO: define where a BCA should be)
+     * \brief Forms and sends peer link management frame.
      */
-    void SetDeliverBeaconCallback (Callback<void>);
+    void SendPeerLinkManagementFrame(Mac48Address peerAddress, uint16_t aid, IeDot11sPeerManagement peerElement, IeDot11sConfiguration meshConfig);
+    IeDot11sConfiguration AskPeerLinkManagementElement();
   private:
     Callback<void, uint32_t, Mac48Address, uint16_t, IeDot11sConfiguration, IeDot11sPeerManagement> m_deliverPeerManFrame;
     Callback<void> m_beaconCallback;
     Ptr<MeshWifiInterfaceMac> m_parent;
+    /**
+     * Create peer link management frames:
+     * \{
+     */
+    Ptr<Packet> CreatePeerLinkOpenFrame();
+    Ptr<Packet> CreatePeerLinkConfirmFrame();
+    Ptr<Packet> CreatePeerLinkCloseFrame();
+    /**
+     * \}
+     */
 };
 } //namespace ns3
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/peer-manager-protocol.cc	Thu Mar 19 17:28:37 2009 +0300
@@ -0,0 +1,985 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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>
+ *          Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#include "ns3/peer-manager-protocol.h"
+#include "ns3/dot11s-parameters.h"
+#include "ns3/simulator.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/random-variable.h"
+NS_LOG_COMPONENT_DEFINE ("Dot11sPeerManagerProtocol");
+namespace ns3 {
+/***************************************************
+ * PeerLinkDescriptor
+ ***************************************************/
+WifiPeerLinkDescriptor::WifiPeerLinkDescriptor ():
+    m_localLinkId (0),
+    m_peerLinkId (0),
+    m_state (IDLE),
+    m_retryCounter (0),
+    m_maxBeaconLoss (3)
+{}
+
+void
+WifiPeerLinkDescriptor::SetPeerAddress (Mac48Address macaddr)
+{
+  m_peerAddress = macaddr;
+}
+
+void
+WifiPeerLinkDescriptor::SetLocalAddress (Mac48Address macaddr)
+{
+  m_localAddress = macaddr;
+}
+
+void
+WifiPeerLinkDescriptor::SetLocalLinkId (uint16_t id)
+{
+  m_localLinkId = id;
+}
+void
+WifiPeerLinkDescriptor::SetLocalAid (uint16_t aid)
+{
+  m_assocId = aid;
+}
+void
+WifiPeerLinkDescriptor::SetBeaconInformation (Time lastBeacon, Time beaconInterval)
+{
+  m_lastBeacon = lastBeacon;
+  m_beaconInterval = beaconInterval;
+  m_beaconLossTimer.Cancel ();
+  Time delay = Seconds (beaconInterval.GetSeconds()*m_maxBeaconLoss);
+  NS_ASSERT (delay.GetMicroSeconds() != 0);
+  m_beaconLossTimer = Simulator::Schedule (delay, &WifiPeerLinkDescriptor::BeaconLoss, this);
+}
+
+void
+WifiPeerLinkDescriptor::SetMaxBeaconLoss (uint8_t maxBeaconLoss)
+{
+  m_maxBeaconLoss = maxBeaconLoss;
+}
+
+void
+WifiPeerLinkDescriptor::SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb)
+{
+  m_linkStatusCallback = cb;
+}
+void
+WifiPeerLinkDescriptor::BeaconLoss ()
+{
+  StateMachine (CNCL);
+}
+
+void
+WifiPeerLinkDescriptor::SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming)
+{
+  m_beaconTiming = beaconTiming;
+}
+
+Mac48Address
+WifiPeerLinkDescriptor::GetPeerAddress () const
+{
+  return m_peerAddress;
+}
+
+Mac48Address
+WifiPeerLinkDescriptor::GetLocalAddress () const
+{
+  return m_localAddress;
+}
+
+
+uint16_t
+WifiPeerLinkDescriptor::GetLocalAid () const
+{
+  return m_assocId;
+}
+
+Time
+WifiPeerLinkDescriptor::GetLastBeacon () const
+{
+  return m_lastBeacon;
+}
+
+Time
+WifiPeerLinkDescriptor::GetBeaconInterval () const
+{
+  return m_beaconInterval;
+}
+IeDot11sBeaconTiming
+WifiPeerLinkDescriptor::GetBeaconTimingElement () const
+{
+  return m_beaconTiming;
+}
+
+void
+WifiPeerLinkDescriptor::ClearTimingElement ()
+{
+  m_beaconTiming.ClearTimingElement ();
+}
+
+
+void  WifiPeerLinkDescriptor::MLMECancelPeerLink (dot11sReasonCode reason)
+{
+  StateMachine (CNCL,reason);
+}
+
+void  WifiPeerLinkDescriptor::MLMEPassivePeerLinkOpen ()
+{
+  StateMachine (PASOPN);
+}
+
+void  WifiPeerLinkDescriptor::MLMEActivePeerLinkOpen ()
+{
+  StateMachine (ACTOPN);
+}
+void WifiPeerLinkDescriptor::MLMEPeeringRequestReject ()
+{
+  StateMachine (REQ_RJCT, REASON11S_PEER_LINK_CANCELLED);
+}
+
+void WifiPeerLinkDescriptor::PeerLinkClose (uint16_t localLinkId,uint16_t peerLinkId, dot11sReasonCode reason)
+{
+  if (peerLinkId != 0 && m_localLinkId != peerLinkId)
+    return;
+  if (m_peerLinkId == 0)
+    m_peerLinkId = localLinkId;
+  else if (m_peerLinkId != localLinkId)
+    return;
+  StateMachine (CLS_ACPT, reason);
+}
+
+void WifiPeerLinkDescriptor::PeerLinkOpenAccept (uint16_t localLinkId, IeDot11sConfiguration  conf)
+{
+  if (m_peerLinkId == 0)
+    m_peerLinkId = localLinkId;
+  m_configuration = conf;
+  StateMachine (OPN_ACPT);
+}
+
+void WifiPeerLinkDescriptor::PeerLinkOpenReject (uint16_t localLinkId, IeDot11sConfiguration  conf,dot11sReasonCode reason)
+{
+  if ( m_peerLinkId == 0)
+    m_peerLinkId = localLinkId;
+  m_configuration = conf;
+  StateMachine (OPN_RJCT, reason);
+}
+
+void
+WifiPeerLinkDescriptor::PeerLinkConfirmAccept (uint16_t localLinkId,uint16_t peerLinkId, uint16_t peerAid, IeDot11sConfiguration  conf)
+{
+  if ( m_localLinkId != peerLinkId)
+    return;
+  if ( m_peerLinkId == 0)
+    m_peerLinkId = localLinkId;
+  else if ( m_peerLinkId != localLinkId )
+    return;
+  m_configuration = conf;
+  m_peerAssocId = peerAid;
+  StateMachine (CNF_ACPT);
+}
+
+void   WifiPeerLinkDescriptor:: PeerLinkConfirmReject (uint16_t localLinkId, uint16_t peerLinkId,
+    IeDot11sConfiguration  conf,dot11sReasonCode reason)
+{
+  if (m_localLinkId != peerLinkId)
+    return;
+  if (m_peerLinkId == 0)
+    m_peerLinkId = localLinkId;
+  else if (m_peerLinkId != localLinkId)
+    return;
+  m_configuration = conf;
+  StateMachine (CNF_RJCT, reason);
+}
+
+bool
+WifiPeerLinkDescriptor::LinkIsEstab () const
+{
+  if (m_state == ESTAB)
+    return true;
+  return false;
+}
+
+bool
+WifiPeerLinkDescriptor::LinkIsIdle () const
+{
+  if (m_state == IDLE)
+    return true;
+  return false;
+}
+
+void
+WifiPeerLinkDescriptor::StateMachine (PeerEvent event,dot11sReasonCode reasoncode)
+{
+  switch (m_state)
+    {
+    case IDLE:
+      switch (event)
+        {
+        case PASOPN:
+          m_state = LISTEN;
+          break;
+        case ACTOPN:
+          m_state = OPN_SNT;
+          SendPeerLinkOpen ();
+          SetRetryTimer ();
+          break;
+        default:
+        {}
+        }
+      break;
+    case LISTEN:
+      switch (event)
+        {
+        case CNCL:
+        case CLS_ACPT:
+          m_state = IDLE;
+          // TODO Callback MLME-SignalPeerLinkStatus
+          break;
+        case REQ_RJCT:
+          SendPeerLinkClose (reasoncode);
+          break;
+        case ACTOPN:
+          m_state = OPN_SNT;
+          SendPeerLinkOpen ();
+          SetRetryTimer ();
+          break;
+        case OPN_ACPT:
+          m_state = OPN_RCVD;
+          SendPeerLinkConfirm ();
+          SendPeerLinkOpen ();
+          SetRetryTimer ();
+          break;
+        default:
+        {}
+        }
+      break;
+    case OPN_SNT:
+      switch (event)
+        {
+        case TOR1:
+          SendPeerLinkOpen ();
+          m_retryCounter++;
+          SetRetryTimer ();
+          break;
+        case CNF_ACPT:
+          m_state = CNF_RCVD;
+          ClearRetryTimer ();
+          SetConfirmTimer ();
+          break;
+        case OPN_ACPT:
+          m_state = OPN_RCVD;
+          SendPeerLinkConfirm ();
+          break;
+        case CLS_ACPT:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
+          SetHoldingTimer ();
+          break;
+        case OPN_RJCT:
+        case CNF_RJCT:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (reasoncode);
+          SetHoldingTimer ();
+          break;
+        case TOR2:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_MESH_MAX_RETRIES);
+          SetHoldingTimer ();
+          break;
+        case CNCL:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
+          SetHoldingTimer ();
+          break;
+        default:
+        {}
+        }
+      break;
+    case CNF_RCVD:
+      switch (event)
+        {
+        case CNF_ACPT:
+          break;
+        case OPN_ACPT:
+          m_state = ESTAB;
+          NS_LOG_DEBUG ("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
+          ClearConfirmTimer ();
+          SendPeerLinkConfirm ();
+          m_linkStatusCallback (m_localAddress, m_peerAddress, true);
+          // TODO Callback MLME-SignalPeerLinkStatus
+          break;
+        case CLS_ACPT:
+          m_state = HOLDING;
+          ClearConfirmTimer ();
+          SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
+          SetHoldingTimer ();
+          break;
+        case CNF_RJCT:
+        case OPN_RJCT:
+          m_state = HOLDING;
+          ClearConfirmTimer ();
+          SendPeerLinkClose (reasoncode);
+          SetHoldingTimer ();
+          break;
+        case CNCL:
+          m_state = HOLDING;
+          ClearConfirmTimer ();
+          SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
+          SetHoldingTimer ();
+          break;
+        case TOC:
+          m_state = HOLDING;
+          SendPeerLinkClose (REASON11S_MESH_CONFIRM_TIMEOUT);
+          SetHoldingTimer ();
+          break;
+        default:
+        {}
+        }
+      break;
+    case OPN_RCVD:
+      switch (event)
+        {
+        case TOR1:
+          SendPeerLinkOpen ();
+          m_retryCounter++;
+          SetRetryTimer ();
+          break;
+        case CNF_ACPT:
+          NS_LOG_DEBUG ("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
+          m_state = ESTAB;
+          ClearRetryTimer ();
+          m_linkStatusCallback (m_localAddress, m_peerAddress, true);
+          // TODO Callback MLME-SignalPeerLinkStatus
+          break;
+        case CLS_ACPT:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
+          SetHoldingTimer ();
+          break;
+        case OPN_RJCT:
+        case CNF_RJCT:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (reasoncode);
+          SetHoldingTimer ();
+          break;
+        case TOR2:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_MESH_MAX_RETRIES);
+          SetHoldingTimer ();
+          break;
+        case CNCL:
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
+          SetHoldingTimer ();
+          break;
+        default:
+        {}
+        }
+      break;
+    case ESTAB:
+      switch (event)
+        {
+#if 0
+        case BNDSA:
+          m_state = ESTAB;
+          // TODO Callback MLME-SignalPeerLinkStatus
+          // TODO
+          break;
+#endif
+        case OPN_ACPT:
+          SendPeerLinkConfirm ();
+          break;
+        case CLS_ACPT:
+          NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Close received");
+          m_state = HOLDING;
+          SendPeerLinkClose (REASON11S_MESH_CLOSE_RCVD);
+          SetHoldingTimer ();
+          m_linkStatusCallback (m_localAddress, m_peerAddress, false);
+          break;
+        case OPN_RJCT:
+        case CNF_RJCT:
+          NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Rejected open or confirm");
+          m_state = HOLDING;
+          ClearRetryTimer ();
+          SendPeerLinkClose (reasoncode);
+          SetHoldingTimer ();
+          m_linkStatusCallback (m_localAddress, m_peerAddress, false);
+          break;
+        case CNCL:
+          NS_LOG_DEBUG ("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Link cancelled");
+          m_state = HOLDING;
+          SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
+          SetHoldingTimer ();
+          m_linkStatusCallback (m_localAddress, m_peerAddress, false);
+          break;
+        default:
+        {}
+        }
+      break;
+    case HOLDING:
+      switch (event)
+        {
+        case CLS_ACPT:
+          ClearHoldingTimer ();
+        case TOH:
+          m_state = IDLE;
+          // TODO Callback MLME-SignalPeerLinkStatus
+          break;
+        case OPN_ACPT:
+        case CNF_ACPT:
+          m_state = HOLDING;
+          // reason not spec in D2.0
+          SendPeerLinkClose (REASON11S_PEER_LINK_CANCELLED);
+          break;
+        case OPN_RJCT:
+        case CNF_RJCT:
+          m_state = HOLDING;
+          SendPeerLinkClose (reasoncode);
+          break;
+        default:
+        {}
+        }
+      break;
+    }
+}
+
+void WifiPeerLinkDescriptor::ClearRetryTimer ()
+{
+  m_retryTimer.Cancel ();
+}
+
+void WifiPeerLinkDescriptor::ClearConfirmTimer ()
+{
+  m_confirmTimer.Cancel ();
+}
+
+void WifiPeerLinkDescriptor::ClearHoldingTimer ()
+{
+  m_holdingTimer.Cancel ();
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkClose (dot11sReasonCode reasoncode)
+{
+  IeDot11sPeerManagement peerElement;
+  peerElement.SetPeerClose (m_localLinkId, m_peerLinkId, reasoncode);
+  //m_mac->SendPeerLinkClose (peerElement,m_peerAddress);
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkOpen ()
+{
+  IeDot11sPeerManagement peerElement;
+  peerElement.SetPeerOpen (m_localLinkId);
+  //NS_ASSERT (m_mac != NULL);
+  //m_mac->SendPeerLinkOpen (peerElement, m_peerAddress);
+}
+
+void WifiPeerLinkDescriptor::SendPeerLinkConfirm ()
+{
+  IeDot11sPeerManagement peerElement;
+  peerElement.SetPeerConfirm (m_localLinkId, m_peerLinkId);
+  //m_mac->SendPeerLinkConfirm (peerElement, m_peerAddress, m_assocId);
+}
+
+void WifiPeerLinkDescriptor::SetHoldingTimer ()
+{
+  m_holdingTimer = Simulator::Schedule (dot11sParameters::dot11MeshHoldingTimeout, &WifiPeerLinkDescriptor::HoldingTimeout, this);
+}
+
+void WifiPeerLinkDescriptor::HoldingTimeout ()
+{
+  StateMachine (TOH);
+}
+
+void WifiPeerLinkDescriptor::SetRetryTimer ()
+{
+  m_retryTimer = Simulator::Schedule (dot11sParameters::dot11MeshRetryTimeout, &WifiPeerLinkDescriptor::RetryTimeout, this);
+}
+
+void WifiPeerLinkDescriptor::RetryTimeout ()
+{
+  if ( m_retryCounter < dot11sParameters::dot11MeshMaxRetries)
+    StateMachine (TOR1);
+  else
+    StateMachine (TOR2);
+}
+
+void WifiPeerLinkDescriptor::SetConfirmTimer ()
+{
+  m_confirmTimer = Simulator::Schedule (dot11sParameters::dot11MeshConfirmTimeout, &WifiPeerLinkDescriptor::ConfirmTimeout, this);
+}
+
+void WifiPeerLinkDescriptor::ConfirmTimeout ()
+{
+  StateMachine (TOC);
+}
+
+/***************************************************
+ * PeerManager
+ ***************************************************/
+//NS_OBJECT_ENSURE_REGISTERED (Dot11sPeerManagerProtocol);
+
+TypeId
+Dot11sPeerManagerProtocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Dot11sPeerManagerProtocol")
+                      .SetParent<Object> ()
+                      .AddConstructor<Dot11sPeerManagerProtocol> ();
+#if 0
+                      //peerLinkCleanupTimeout. This constant is not specified in Draft 2.0
+                      .AddAttribute ("PeerLinkCleanupPeriod",
+                                     "PeerLinkCleanupPeriod",
+                                     TimeValue (MilliSeconds (80)),
+                                     MakeTimeAccessor (&Dot11sPeerManagerProtocol::m_peerLinkCleanupPeriod),
+                                     MakeTimeChecker ()
+                                    )
+                      //MaxBeaconLost. This constant is not specified in Draft 2.0
+                      .AddAttribute ("MaxBeaconLost", "Max Beacon Lost",
+                                     UintegerValue (3),
+                                     MakeUintegerAccessor (&Dot11sPeerManagerProtocol::m_maxBeaconLoss),
+                                     MakeUintegerChecker<uint8_t> ()
+                                    )
+                      //maximum number of peer links.
+                      .AddAttribute ("MaxNumberOfPeerLinks",
+                                     "Maximum number of peer links ",
+                                     UintegerValue (32),
+                                     MakeUintegerAccessor (&Dot11sPeerManagerProtocol::m_maxNumberOfPeerLinks),
+                                     MakeUintegerChecker<uint8_t> ()
+                                    );
+#endif
+  return tid;
+
+}
+Dot11sPeerManagerProtocol::Dot11sPeerManagerProtocol ()
+{
+//  m_assocId = 0;
+//  m_numberOfActivePeers = 0;
+//  // firs peerLinkId is 1, because 0 means "unknown"
+//  m_localLinkId = 1;
+//  m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &Dot11sPeerManagerProtocol::PeerCleanup, this);
+}
+Dot11sPeerManagerProtocol::~Dot11sPeerManagerProtocol ()
+{
+#if 0
+  m_cleanupEvent.Cancel ();
+  //TODO: delete a list of descriptors
+  for (
+    PeerDescriptorsMap::iterator j = m_peerDescriptors.begin ();
+    j != m_peerDescriptors.end ();
+    j++)
+    {
+      int to_delete = 0;
+      for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = j->second.begin (); i != j->second.end(); i++)
+        {
+          to_delete ++;
+          (*i)->ClearTimingElement ();
+          (*i) = 0;
+        }
+      for (int i = 0; i < to_delete; i ++)
+        j->second.pop_back ();
+      j->second.clear ();
+    }
+  m_peerDescriptors.clear ();
+#endif
+}
+#if 0
+void
+Dot11sPeerManagerProtocol::SetSentBeaconTimers (
+  Mac48Address portAddress,
+  Time ReferenceTbtt,
+  Time BeaconInterval
+)
+{
+  BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find (portAddress);
+  NS_ASSERT (myBeacon != m_myBeaconInfo.end());
+  myBeacon->second.referenceTbtt = ReferenceTbtt;
+  myBeacon->second.beaconInterval = BeaconInterval;
+
+}
+
+void
+Dot11sPeerManagerProtocol::SetReceivedBeaconTimers (
+  Mac48Address portAddress,
+  Mac48Address peerAddress,
+  Time lastBeacon,
+  Time beaconInterval,
+  IeDot11sBeaconTiming beaconTiming
+)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    {
+      if ((*i)->GetPeerAddress () == peerAddress)
+        {
+          (*i)->SetBeaconTimingElement (beaconTiming);
+          (*i)->SetBeaconInformation (lastBeacon, beaconInterval);
+          return;
+        }
+    }
+  Ptr<WifiPeerLinkDescriptor> new_descriptor =
+    AddDescriptor (portAddress, peerAddress, Simulator::Now(), beaconInterval);
+  new_descriptor->SetBeaconTimingElement (beaconTiming);
+}
+
+bool
+Dot11sPeerManagerProtocol::AttachPorts (std::vector<Ptr<WifiNetDevice> > ports)
+{
+  NS_ASSERT (ports.size() != 0);
+  for (std::vector<Ptr<WifiNetDevice> >::iterator i = ports.begin (); i != ports.end(); i++)
+    {
+      MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer ((*i)->GetMac ()));
+      if (meshWifiMac == NULL)
+        return false;
+      meshWifiMac->SetPeerLinkManager (this);
+      //Add a mac pointer:
+      m_macPointers[meshWifiMac->GetAddress ()] = meshWifiMac;
+      //Add descriptor array:
+      std::vector<Ptr<WifiPeerLinkDescriptor> > descriptors;
+      m_peerDescriptors[meshWifiMac->GetAddress ()] = descriptors;
+      //Add beacon timers:
+      struct BeaconInfo myBeacon;
+      m_myBeaconInfo[meshWifiMac->GetAddress ()] = myBeacon;
+    }
+  return true;
+}
+void
+Dot11sPeerManagerProtocol::AskIfOpenNeeded (Mac48Address portAddress, Mac48Address peerAddress)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      {
+        if (ShouldSendOpen (portAddress, peerAddress))
+          (*i)->MLMEActivePeerLinkOpen ();
+        break;
+      }
+}
+
+void
+Dot11sPeerManagerProtocol::SetOpenReceived (
+  Mac48Address portAddress,
+  Mac48Address peerAddress,
+  IeDot11sPeerManagement peerMan,
+  IeDot11sConfiguration conf
+)
+{
+  dot11sReasonCode reasonCode;
+  if (!ShouldAcceptOpen (portAddress, peerAddress,reasonCode))
+    return;
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      {
+        (*i)->PeerLinkOpenAccept (peerMan.GetLocalLinkId(), conf);
+        return;
+      }
+  BeaconInfoMap::iterator myBeacon =  m_myBeaconInfo.find (portAddress);
+  NS_ASSERT (myBeacon != m_myBeaconInfo.end());
+  Ptr<WifiPeerLinkDescriptor>new_descriptor = AddDescriptor (
+        portAddress,
+        peerAddress,
+        Simulator::Now (),
+        myBeacon->second.beaconInterval
+      );
+  new_descriptor->PeerLinkOpenAccept (peerMan.GetLocalLinkId(), conf);
+}
+void
+Dot11sPeerManagerProtocol::SetConfirmReceived (
+  Mac48Address portAddress,
+  Mac48Address peerAddress,
+  uint16_t peerAid,
+  IeDot11sPeerManagement peerMan,
+  IeDot11sConfiguration meshConfig
+)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      (*i)->PeerLinkConfirmAccept (peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerAid, meshConfig);
+}
+
+void
+Dot11sPeerManagerProtocol::SetCloseReceived (
+  Mac48Address portAddress,
+  Mac48Address peerAddress,
+  IeDot11sPeerManagement peerMan
+)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      {
+        (*i)->PeerLinkClose (peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerMan.GetReasonCode());
+        return;
+      }
+}
+
+void
+Dot11sPeerManagerProtocol::ConfigurationMismatch (
+  Mac48Address portAddress,
+  Mac48Address peerAddress
+)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      {
+        (*i)->MLMECancelPeerLink (REASON11S_MESH_CONFIGURATION_POLICY_VIOLATION);
+        return;
+      }
+
+}
+
+IeDot11sBeaconTiming
+Dot11sPeerManagerProtocol::GetIeDot11sBeaconTimingForMyBeacon (Mac48Address portAddress)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  IeDot11sBeaconTiming return_val;
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    {
+      //Just go through all neighbor entries and add it to timing element:
+      return_val.AddNeighboursTimingElementUnit (
+        (*i)->GetLocalAid (),
+        (*i)->GetLastBeacon (),
+        (*i)->GetBeaconInterval ()
+      );
+    }
+  return return_val;
+
+}
+IeDot11sBeaconTiming
+Dot11sPeerManagerProtocol::GetIeDot11sBeaconTimingForAddress (
+  Mac48Address portAddress,
+  Mac48Address addr)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  IeDot11sBeaconTiming return_val;
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == addr)
+      return_val =  (*i)->GetBeaconTimingElement ();
+  return return_val;
+}
+Ptr<WifiPeerLinkDescriptor>
+Dot11sPeerManagerProtocol::AddDescriptor (
+  Mac48Address portAddress,
+  Mac48Address peerAddress,
+  Time lastBeacon,
+  Time beaconInterval)
+{
+  Ptr<WifiPeerLinkDescriptor> new_descriptor = Create<WifiPeerLinkDescriptor> ();
+  if (m_assocId == 0xff)
+    m_assocId = 0;
+  if (m_localLinkId == 0xff)
+    m_localLinkId = 0;
+  new_descriptor->SetLocalAid (m_assocId++);
+  new_descriptor->SetLocalLinkId (m_localLinkId++);
+  new_descriptor->SetPeerAddress (peerAddress);
+  new_descriptor->SetBeaconInformation (lastBeacon, beaconInterval);
+  //DEBUG ONLY:
+  new_descriptor->SetLocalAddress (portAddress);
+  //check if port address is wrong
+  MeshMacMap::iterator pos = m_macPointers.find (portAddress);
+  NS_ASSERT (pos != m_macPointers.end());
+  //check if descriptors array exist
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  new_descriptor->SetMac (pos->second);
+  new_descriptor->SetMaxBeaconLoss (m_maxBeaconLoss);
+  new_descriptor->SetLinkStatusCallback (MakeCallback(&Dot11sPeerManagerProtocol::PeerLinkStatus, this));
+  NS_ASSERT (port != m_peerDescriptors.end());
+  m_peerDescriptors[portAddress].push_back (new_descriptor);
+  return new_descriptor;
+}
+
+void
+Dot11sPeerManagerProtocol::PeerCleanup ()
+{
+  for (
+    PeerDescriptorsMap::iterator j = m_peerDescriptors.begin ();
+    j != m_peerDescriptors.end ();
+    j++)
+    {
+      std::vector<unsigned int> to_erase;
+      for (unsigned int i = 0; i< j->second.size (); i++)
+        if (j->second[i]->LinkIsIdle ())
+          {
+            j->second[i]->ClearTimingElement ();
+            j->second[i] = 0;
+            to_erase.push_back (i);
+          }
+      if (to_erase.size () == 0)
+        return;
+      for (unsigned int i = to_erase.size ()-1 ; i >= 0; i--)
+        j->second.erase (j->second.begin() + to_erase[i]);
+      to_erase.clear ();
+    }
+  m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &Dot11sPeerManagerProtocol::PeerCleanup, this);
+}
+
+std::vector<Mac48Address>
+Dot11sPeerManagerProtocol::GetNeighbourAddressList (Mac48Address portAddress, Mac48Address peerAddress)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  std::vector<Mac48Address> return_value;
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    return_value.push_back ((*i)->GetPeerAddress());
+  return return_value;
+}
+
+bool
+Dot11sPeerManagerProtocol::IsActiveLink (Mac48Address portAddress, Mac48Address peerAddress)
+{
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    if ((*i)->GetPeerAddress () == peerAddress)
+      return ((*i)->LinkIsEstab ());
+  return false;
+}
+
+bool
+Dot11sPeerManagerProtocol::ShouldSendOpen (Mac48Address portAddress, Mac48Address peerAddress)
+{
+  if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
+    return false;
+  return true;
+}
+
+bool
+Dot11sPeerManagerProtocol::ShouldAcceptOpen (Mac48Address portAddress, Mac48Address peerAddress,dot11sReasonCode & reasonCode)
+{
+  if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
+    {
+      reasonCode = REASON11S_MESH_MAX_PEERS;
+      return false;
+    }
+  return true;
+}
+
+Time
+Dot11sPeerManagerProtocol::GetNextBeaconShift (
+  Mac48Address portAddress,
+  Time myNextTBTT
+)
+{
+  //REMINDER:: in timing element  1) last beacon reception time is measured in units of 256 microseconds
+  //                              2) beacon interval is mesured in units of 1024 microseconds
+  //                              3) hereafter TU = 1024 microseconds
+  //Im my MAC everything is stored in MicroSeconds
+
+  uint32_t myNextTBTTInTimeUnits = 0;
+  uint32_t futureBeaconInTimeUnits = 0;
+  //Going through all my timing elements and detecting future beacon collisions
+  PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
+  NS_ASSERT (port != m_peerDescriptors.end());
+  BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find (portAddress);
+  NS_ASSERT (myBeacon != m_myBeaconInfo.end());
+  for (std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin (); i != port->second.end(); i++)
+    {
+      IeDot11sBeaconTiming::NeighboursTimingUnitsList neighbours;
+      neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList();
+      //first let's form the list of all kown TBTTs
+      for (IeDot11sBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j != neighbours.end(); j++)
+        {
+          uint16_t beaconIntervalTimeUnits;
+          beaconIntervalTimeUnits = (*j)->GetBeaconInterval ();
+
+          //The last beacon time in timing elememt in Time Units
+          uint32_t lastBeaconInTimeUnits;
+          lastBeaconInTimeUnits = (*j)->GetLastBeacon ()/4;
+
+          //The time of my next beacon sending in Time Units
+          myNextTBTTInTimeUnits = myNextTBTT.GetMicroSeconds ()/1024;
+
+          //My beacon interval in Time Units
+          uint32_t myBeaconIntervalInTimeUnits;
+          myBeaconIntervalInTimeUnits = myBeacon->second.beaconInterval.GetMicroSeconds ()/1024;
+
+          //The time the beacon of other station will be sent
+          //we need the time just after my next TBTT (or equal to my TBTT)
+          futureBeaconInTimeUnits = lastBeaconInTimeUnits + beaconIntervalTimeUnits;
+
+          //We apply MBAC only if beacon Intervals are equal
+          if (beaconIntervalTimeUnits == myBeaconIntervalInTimeUnits)
+            {
+              //We know when the neighbor STA transmitted it's beacon
+              //Now we need to know when it's going to send it's beacon in the future
+              //So let's use the valuse of it's beacon interval
+              while (myNextTBTTInTimeUnits >= futureBeaconInTimeUnits)
+                futureBeaconInTimeUnits = futureBeaconInTimeUnits + beaconIntervalTimeUnits;
+              //If we found that my TBTT coincide with another STA's TBTT
+              //break all cylce and return time shift for my next TBTT
+              if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
+                break;
+            }
+
+        }
+      if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
+        break;
+    }
+
+  //TBTTs coincide, so let's calculate the shift
+  if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
+    {
+      NS_LOG_DEBUG ("MBCA: Future beacon collision is detected, applying avoidance mechanism");
+      UniformVariable randomSign (-1, 1);
+      int coefficientSign = -1;
+      if (randomSign.GetValue () >= 0)
+        coefficientSign = 1;
+      UniformVariable randomShift (1, 15);
+      //So, the shift is a random integer variable uniformly distributed in [-15;-1] U [1;15]
+      int beaconShift = randomShift.GetInteger (1,15) * coefficientSign;
+      NS_LOG_DEBUG ("Shift value = " << beaconShift << " beacon TUs");
+      //We need the result not in Time Units, but in microseconds
+      return MicroSeconds (beaconShift * 1024);
+    }
+  //No collision detecterf, hence no shift is needed
+  else
+    return MicroSeconds (0);
+}
+
+void
+Dot11sPeerManagerProtocol::PeerLinkStatus (Mac48Address portAddress, Mac48Address peerAddress, bool status)
+{
+  MeshMacMap::iterator pos = m_macPointers.find (portAddress);
+  NS_ASSERT (pos != m_macPointers.end());
+  pos->second->PeerLinkStatus (peerAddress, status);
+}
+#endif
+} //namespace NS3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/peer-manager-protocol.h	Thu Mar 19 17:28:37 2009 +0300
@@ -0,0 +1,319 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,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>
+ *          Aleksey Kovalenko <kovalenko@iitp.ru>
+ */
+
+
+#ifndef WIFI_PEER_MAN_H
+#define WIFI_PEER_MAN_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/ie-dot11s-peer-management.h"
+#include "ns3/ie-dot11s-beacon-timing.h"
+#include "ns3/peer-manager-plugin.h"
+#include "ns3/ie-dot11s-configuration.h"
+#include "ns3/event-id.h"
+
+#include <list>
+namespace ns3 {
+class EventId;
+/**
+ * \ingroup mesh
+ */
+class WifiPeerLinkDescriptor : public RefCountBase
+{
+public:
+  WifiPeerLinkDescriptor ();
+  /**
+   * Beacon loss processing:
+   */
+  void  SetBeaconInformation (Time lastBeacon, Time BeaconInterval);
+  void  SetMaxBeaconLoss (uint8_t maxBeaconLoss);
+  /**
+   * \brief Methods used to detecet peer link changes
+   * \param bool if true - opened new link, if
+   * false - link closed
+   */
+  void  SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb);
+  /**
+   * Peer link geeters/setters
+   */
+  void  SetPeerAddress (Mac48Address macaddr);
+  /**
+   * Debug purpose
+   */
+  void  SetLocalAddress (Mac48Address macaddr);
+  void  SetLocalLinkId  (uint16_t id);
+  void  SetPeerLinkId   (uint16_t id);
+  void  SetLocalAid     (uint16_t aid);
+  void  SetPeerAid      (uint16_t aid);
+  void  SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming);
+  void  SetPeerLinkDescriptorElement (IeDot11sPeerManagement peerLinkElement);
+  Mac48Address GetPeerAddress () const;
+  /**
+   * Debug purpose
+   */
+  Mac48Address GetLocalAddress () const;
+  uint16_t GetLocalAid () const;
+  Time  GetLastBeacon () const;
+  Time  GetBeaconInterval () const;
+  IeDot11sBeaconTiming    GetBeaconTimingElement () const;
+  IeDot11sPeerManagement  GetPeerLinkDescriptorElement () const;
+  void  ClearTimingElement ();
+  /* MLME */
+  void  MLMECancelPeerLink (dot11sReasonCode reason);
+  void  MLMEPassivePeerLinkOpen ();
+  void  MLMEActivePeerLinkOpen ();
+  void  MLMEPeeringRequestReject ();
+#if 0
+  void  MLMEBindSecurityAssociation ();
+#endif
+  void  PeerLinkClose (uint16_t localLinkID,uint16_t peerLinkID, dot11sReasonCode reason);
+  void  PeerLinkOpenAccept (uint16_t localLinkId, IeDot11sConfiguration  conf);
+  void  PeerLinkOpenReject (uint16_t localLinkId, IeDot11sConfiguration  conf, dot11sReasonCode reason);
+  void  PeerLinkConfirmAccept (
+    uint16_t localLinkId,
+    uint16_t peerLinkId,
+    uint16_t peerAid,
+    IeDot11sConfiguration  conf
+  );
+  void  PeerLinkConfirmReject (
+    uint16_t localLinkId,
+    uint16_t peerLinkId,
+    IeDot11sConfiguration  conf,
+    dot11sReasonCode reason
+  );
+  bool  LinkIsEstab () const;
+  bool  LinkIsIdle  () const;
+private:
+  enum  PeerState {
+    IDLE,
+    LISTEN,
+    OPN_SNT,
+    CNF_RCVD,
+    OPN_RCVD,
+    ESTAB,
+    HOLDING,
+  };
+  enum  PeerEvent
+  {
+    CNCL,  /** MLME-CancelPeerLink */
+    PASOPN,  /** MLME-PassivePeerLinkOpen */
+    ACTOPN,  /** MLME-ActivePeerLinkOpen */
+    //BNDSA,     /** MLME-BindSecurityAssociation */
+    CLS_ACPT, /** PeerLinkClose_Accept */
+    //CLS_IGNR, /** PeerLinkClose_Ignore */
+    OPN_ACPT, /** PeerLinkOpen_Accept */
+    //OPN_IGNR, /** PeerLinkOpen_Ignore */
+    OPN_RJCT, /** PeerLinkOpen_Reject */
+    REQ_RJCT, /** PeerLinkOpenReject by internal reason */
+    CNF_ACPT, /** PeerLinkConfirm_Accept */
+    //CNF_IGNR, /** PeerLinkConfirm_Ignore */
+    CNF_RJCT, /** PeerLinkConfirm_Reject */
+    TOR1,
+    TOR2,
+    TOC,
+    TOH,
+  };
+private:
+  void StateMachine (PeerEvent event,dot11sReasonCode = REASON11S_RESERVED);
+  /** Events handlers */
+  void ClearRetryTimer   ();
+  void ClearConfirmTimer ();
+  void ClearHoldingTimer ();
+  void SetHoldingTimer   ();
+  void SetRetryTimer     ();
+  void SetConfirmTimer   ();
+
+  void SendPeerLinkClose (dot11sReasonCode reasoncode);
+  void SendPeerLinkOpen ();
+  void SendPeerLinkConfirm ();
+  /** Private Event */
+  void HoldingTimeout ();
+  void RetryTimeout   ();
+  void ConfirmTimeout ();
+private:
+  Mac48Address m_peerAddress;
+  Mac48Address m_localAddress;
+  uint16_t m_localLinkId;
+  uint16_t m_peerLinkId;
+  // Used for beacon timing:
+  // All values are stored in microseconds!
+  Time  m_lastBeacon;
+  Time  m_beaconInterval;
+  uint16_t m_assocId; //Assigned Assoc ID
+  uint16_t m_peerAssocId; //Assoc Id assigned to me by peer
+  //State of our peer Link:
+  PeerState m_state;
+
+  IeDot11sConfiguration  m_configuration;
+  // State is a bitfield as defined as follows:
+  // This are states for a given
+  IeDot11sBeaconTiming  m_beaconTiming;
+
+  EventId  m_retryTimer;
+  EventId  m_holdingTimer;
+  EventId  m_confirmTimer;
+  uint16_t m_retryCounter;
+  /**
+   * Beacon loss timers:
+   */
+  EventId  m_beaconLossTimer;
+  uint8_t  m_maxBeaconLoss;
+  void  BeaconLoss ();
+  Callback<void, Mac48Address, Mac48Address, bool>  m_linkStatusCallback;
+};
+/**
+ * \ingroup mesh
+ */
+class Dot11sPeerManagerProtocol : public Object
+{
+public:
+  Dot11sPeerManagerProtocol ();
+  ~Dot11sPeerManagerProtocol ();
+  static TypeId GetTypeId ();
+  /** \brief Methods that handle beacon sending/receiving procedure.
+   * This methods interact with MAC_layer plug-in
+   * \{
+   */
+  /**
+   * \brief When we are sending a beacon - we add a timing element to 
+   * it and remember the time, when we sent a beacon (for BCA)
+   * \param IeDot11sBeaconTiming is a beacon timing element that
+   * should be present in beacon
+   * \param port is a port sending a beacon
+   * \param currentTbtt is a time of beacon sending
+   * \param beaconInterval is a beacon interval on this port
+   */
+  IeDot11sBeaconTiming SendBeacon(uint32_t port, Time currentTbtt, Time beaconInterval);
+  /**
+   * \brief When we receive a beacon from peer-station, we remember
+   * its beacon timing element (needed for peer choosing mechanism),
+   * and remember beacon timers - last beacon and beacon interval to
+   * detect beacon loss and cancel links
+   * \param port is a port on which beacon was received
+   * \param timingElement is a timing element of remote beacon
+   */
+  void ReceiveBeacon(uint32_t port, IeDot11sBeaconTiming timingElement, Mac48Address peerAddress, Time receivingTime, Time beaconInterval);
+  /**
+   * \}
+   */
+  /**
+   * \brief Methods that handle Peer link management frames
+   * interaction:
+   * \{
+   */
+  /**
+   * Deliver Peer link management information to the protocol-part
+   * \param void is returning value - we pass a frame and forget
+   * about it
+   * \param uint32_t - is a port ID of a given MAC (portID rather
+   * than MAC address, beacause many ports may have the same MAC)
+   * \param Mac48Address is address of peer
+   * \param uint16_t is association ID, which peer has assigned to
+   * us
+   * \param IeDot11sConfiguration is mesh configuration element
+   * taken from the peer management frame
+   * \param IeDot11sPeerManagement is peer link management element
+   */
+  void ReceivePeerLinkFrame(
+      uint32_t port,
+      Mac48Address peerAddress,
+      uint16_t aid,
+      IeDot11sConfiguration meshConfig,
+      IeDot11sPeerManagement peerManagementElement
+      );
+  /**
+   * \}
+   */
+private:
+  /**
+   * All private structures:
+   * * peer link descriptors;
+   * * information about received beacons
+   * * pointers to proper plugins
+   * \{
+   */
+  struct BeaconInfo
+  {
+    Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
+    Time beaconInterval; //Beacon interval of my station;
+  };
+  typedef std::map<uint32_t, std::vector<Ptr<WifiPeerLinkDescriptor> >, std::less<Mac48Address> >  PeerDescriptorsMap;
+  typedef std::map<uint32_t, BeaconInfo, std::less<Mac48Address> > BeaconInfoMap;
+  typedef std::map<uint32_t, Ptr<Dot11sPeerManagerMacPlugin>,std::less<Mac48Address> > MeshMacMap;
+  /**
+   * \}
+   */
+#if 0
+  //Maximum peers that may be opened:
+  uint8_t  m_maxNumberOfPeerLinks;
+  /**
+   * Peer manager identify interface by address
+   * of MAC. So, for every interface we store
+   * list of peer descriptors.
+   */
+  PeerDescriptorsMap m_peerDescriptors;
+  /**
+   * List of MAC pointers - to iteract with each
+   * mac
+   */
+  MeshMacMap m_macPointers;
+  uint8_t  m_numberOfActivePeers; //number of established peer links
+  uint16_t m_assocId;  //last stored assoc ID
+  uint16_t m_localLinkId;  //last stored local link ID
+  //This Variables used in beacon miss auto-cleanup:
+  //How many beacons may we lose before the link is
+  //considered to be broken:
+  uint8_t  m_maxBeaconLoss;
+  //Periodically we scan the peer manager list of peers
+  //and check if the too many  beacons were lost:
+  Time  m_peerLinkCleanupPeriod;
+  EventId  m_cleanupEvent;
+  Ptr<WifiPeerLinkDescriptor> AddDescriptor (
+    Mac48Address portAddress,
+    Mac48Address peerAddress,
+    Time lastBeacon,
+    Time beaconInterval
+  );
+  void  PeerCleanup ();
+  //Mechanism of choosing PEERs:
+  bool  ShouldSendOpen (Mac48Address portAddress, Mac48Address peerAddress);
+  bool  ShouldAcceptOpen (
+    Mac48Address portAddress,
+    Mac48Address peerAddress,
+    dot11sReasonCode & reasonCode
+  );
+  //Needed for Beacon Collision Avoidance module:
+  BeaconInfoMap m_myBeaconInfo;
+  /**
+   * Peer link Open/Close callbacks: We need to
+   * inform MAC about this events.
+   * \brief Interaction with peer link
+   * descriptor - notify that peer link was
+   * opened or closed
+   * \param status true - peer link opened, peer
+   * link closed otherwise
+   */
+  void PeerLinkStatus (Mac48Address portAddress, Mac48Address peerAddress, bool status);
+#endif
+};
+} //namespace ns3
+#endif
--- a/src/devices/mesh/wscript	Thu Mar 19 14:31:47 2009 +0300
+++ b/src/devices/mesh/wscript	Thu Mar 19 17:28:37 2009 +0300
@@ -13,7 +13,7 @@
         # Not refactored
         'mesh-wifi-helper.cc',
         'mesh-wifi-mac-header.cc',
-        'mesh-wifi-peer-manager.cc',
+        'peer-manager-protocol.cc',
         'tx-statistics.cc',
         'hwmp-rtable.cc',
         'dot11s-parameters.cc',
@@ -21,6 +21,7 @@
         'mesh-wifi-mac.cc',
         'hwmp-state.cc',
         'mesh-mgt-headers.cc',
+        'mesh-wifi-peer-manager.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'mesh'
@@ -41,9 +42,10 @@
         'hwmp.h',
         'tx-statistics.h',
         'hwmp-rtable.h',
-        'mesh-wifi-peer-manager.h',
+        'peer-manager-protocol.h',
         'mesh-wifi-mac-header.h',
         'mesh-wifi-mac.h',
+        'mesh-wifi-peer-manager.h',
         'mesh-wifi-helper.h',
         ]