src/devices/mesh/dot11s/peer-manager-protocol.cc
changeset 4882 3eab2f6b1adc
parent 4881 cec7f8e2bbdf
child 4883 27921b45078e
--- a/src/devices/mesh/dot11s/peer-manager-protocol.cc	Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,443 +0,0 @@
-/* -*-  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 "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"
-#include "ns3/mesh-wifi-interface-mac.h"
-#include "ns3/mesh-wifi-interface-mac-plugin.h"
-#include "peer-link.h"
-#include "peer-manager-plugin.h"
-
-
-NS_LOG_COMPONENT_DEFINE ("PeerManagerProtocol");
-namespace ns3 {
-namespace dot11s {
-/***************************************************
- * PeerManager
- ***************************************************/
-NS_OBJECT_ENSURE_REGISTERED (PeerManagerProtocol);
-
-TypeId
-PeerManagerProtocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::PeerManagerProtocol")
-    .SetParent<Object> ()
-    .AddConstructor<PeerManagerProtocol> ()
-    // peerLinkCleanupTimeout. We go through the map of peer links and 
-    // remove all links which state is IDLE.
-    .AddAttribute ("PeerLinkCleanupPeriod",
-        "Idle peer link collection interval",
-        TimeValue (MilliSeconds (80)),
-        MakeTimeAccessor (&PeerManagerProtocol::m_peerLinkCleanupPeriod),
-        MakeTimeChecker ()
-        )
-    // maximum number of peer links. Now we calculate the total
-    // number of peer links on all interfaces
-    .AddAttribute ("MaxNumberOfPeerLinks",
-        "Maximum number of peer links",
-        UintegerValue (32),
-        MakeUintegerAccessor (&PeerManagerProtocol::m_maxNumberOfPeerLinks),
-        MakeUintegerChecker<uint8_t> ()
-        );
-  return tid;
-}
-PeerManagerProtocol::PeerManagerProtocol ():
-  m_lastAssocId (0),
-  m_lastLocalLinkId (1),
-  m_numberOfActivePeers (0)
-{
-  m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &PeerManagerProtocol::PeerCleanup, this);
-}
-PeerManagerProtocol::~PeerManagerProtocol ()
-{
-  //cancel cleanup event and go through the map of peer links,
-  //deleting each
-  m_cleanupEvent.Cancel ();
-  for (PeerLinksMap::iterator j = m_peerLinks.begin (); j != m_peerLinks.end (); j++)
-    {
-      for (PeerLinksOnInterface::iterator i = j->second.begin (); i != j->second.end(); i++)
-        {
-          (*i)->ClearTimingElement ();
-          (*i) = 0;
-        }
-      j->second.clear ();
-    }
-  m_peerLinks.clear ();
-  //cleaning beacon structures:
-  for(BeaconInfoMap::iterator i =  m_neighbourBeacons.begin(); i != m_neighbourBeacons.end(); i ++)
-  {
-    i->second.clear();
-  }
-  m_neighbourBeacons.clear();
-}
-
-bool
-PeerManagerProtocol::AttachInterfaces(std::vector<Ptr<WifiNetDevice> > interfaces)
-{
-  for(std::vector<Ptr<WifiNetDevice> >::iterator i = interfaces.begin(); i != interfaces.end(); i ++)
-  {
-    MeshWifiInterfaceMac * mac = dynamic_cast<MeshWifiInterfaceMac *> (PeekPointer ((*i)->GetMac ()));
-    if (mac == NULL)
-      return false;
-    Ptr<PeerManagerMacPlugin> peerPlugin = Create<PeerManagerMacPlugin> ((*i)->GetIfIndex(), this);
-    mac->InstallPlugin(peerPlugin);
-    m_plugins[(*i)->GetIfIndex()] = peerPlugin;
-    PeerLinksOnInterface newmap;
-    m_peerLinks[(*i)->GetIfIndex()] = newmap;
-  }
-  return true;
-}
-
-Ptr<IeBeaconTiming>
-PeerManagerProtocol::GetBeaconTimingElement(uint32_t interface)
-{
-  Ptr<IeBeaconTiming> retval = Create<IeBeaconTiming> ();
-  BeaconInfoMap::iterator i = m_neighbourBeacons.find(interface);
-  if(i == m_neighbourBeacons.end())
-    return retval;
-  bool cleaned = false;
-  while(!cleaned)
-  {
-    for(BeaconsOnInterface::iterator j = i->second.begin(); j != i->second.end(); j++)
-    {
-      //check beacon loss and make a timing element
-      //if last beacon was 3 beacons ago - we do not put it to the
-      //timing element
-      if(
-          (j->second.referenceTbtt.GetMicroSeconds() +
-           (j->second.beaconInterval.GetMicroSeconds()* 3))
-          <
-          Simulator::Now().GetMicroSeconds()
-          )
-      {
-        i->second.erase(j);
-        break;
-      }
-    }
-    cleaned = true;
-  }
-  for(BeaconsOnInterface::iterator j = i->second.begin(); j != i->second.end(); j++)
-    retval->AddNeighboursTimingElementUnit(j->second.aid, j->second.referenceTbtt, j->second.beaconInterval);
-  return retval;
-}
-
-void
-PeerManagerProtocol::FillBeaconInfo(uint32_t interface, Mac48Address peerAddress, Time receivingTime, Time beaconInterval)
-{
-  BeaconInfoMap::iterator i = m_neighbourBeacons.find(interface);
-  if(i == m_neighbourBeacons.end())
-  {
-     BeaconsOnInterface newMap;
-     m_neighbourBeacons[interface] = newMap;
-  }
-  i = m_neighbourBeacons.find(interface);
-  BeaconsOnInterface::iterator j = i->second.find(peerAddress);
-  if(j == i->second.end())
-  {
-    BeaconInfo newInfo;
-    newInfo.referenceTbtt = receivingTime;
-    newInfo.beaconInterval = beaconInterval;
-    newInfo.aid = m_lastAssocId++;
-    if(m_lastAssocId == 0xff)
-      m_lastAssocId = 0;
-    i->second[peerAddress] = newInfo;
-  }
-  else
-  {
-    j->second.referenceTbtt = receivingTime;
-    j->second.beaconInterval = beaconInterval;
-  }
-}
-
-void
-PeerManagerProtocol::UpdatePeerBeaconTiming(
-    uint32_t interface,
-    bool meshBeacon,
-    IeBeaconTiming timingElement,
-    Mac48Address peerAddress,
-    Time receivingTime,
-    Time beaconInterval)
-{
-  FillBeaconInfo(interface, peerAddress, receivingTime, beaconInterval);
-   if(!meshBeacon)
-     return;
-   //BCA:
-   PeerManagerPluginMap::iterator plugin = m_plugins.find (interface);
-   NS_ASSERT(plugin != m_plugins.end ());
-   plugin->second->SetBeaconShift(GetNextBeaconShift(interface));
-   //PM STATE Machine
-   Ptr<PeerLink> peerLink = FindPeerLink(interface, peerAddress);
-   if(peerLink !=0)  
-   {
-     peerLink->SetBeaconTimingElement (timingElement);
-     peerLink->SetBeaconInformation (receivingTime, beaconInterval);
-   }
-   else
-   {
-     peerLink = InitiateLink (interface, peerAddress, receivingTime, beaconInterval);
-     peerLink->SetBeaconTimingElement (timingElement);
-     if (ShouldSendOpen (interface, peerAddress))
-       peerLink->MLMEActivePeerLinkOpen ();
-   }
-}
-
-void
-PeerManagerProtocol::ReceivePeerLinkFrame (
-    uint32_t interface,
-    Mac48Address peerAddress,
-    uint16_t aid,
-    IePeerManagement peerManagementElement,
-    IeConfiguration meshConfig
-      )
-{
-  Ptr<PeerLink> peerLink = FindPeerLink(interface, peerAddress);
-  if (peerManagementElement.SubtypeIsOpen ())
-  {
-    dot11sReasonCode reasonCode;
-    bool reject = ! (ShouldAcceptOpen (interface, peerAddress,reasonCode));
-    if (peerLink == 0)
-      peerLink = InitiateLink (interface, peerAddress, Simulator::Now (), Seconds(1.0));
-    if(!reject)
-    {
-      peerLink->MLMEPassivePeerLinkOpen ();
-      peerLink->OpenAccept (peerManagementElement.GetLocalLinkId(), meshConfig);
-    }
-    else
-      peerLink->OpenReject (peerManagementElement.GetLocalLinkId(), meshConfig, reasonCode);
-  }
-  if (peerLink == 0)
-    return;
-  if (peerManagementElement.SubtypeIsConfirm ())
-    peerLink->ConfirmAccept (peerManagementElement.GetLocalLinkId(), peerManagementElement.GetPeerLinkId(), aid, meshConfig);
-  if (peerManagementElement.SubtypeIsClose ())
-    peerLink->Close (
-        peerManagementElement.GetLocalLinkId(),
-        peerManagementElement.GetPeerLinkId(),
-        peerManagementElement.GetReasonCode()
-        );
-}
-
-void
-PeerManagerProtocol::ConfigurationMismatch (uint32_t interface, Mac48Address peerAddress)
-{
-  Ptr<PeerLink> peerLink = FindPeerLink(interface, peerAddress);
-  if(peerLink != 0)
-      peerLink->MLMECancelPeerLink (REASON11S_MESH_CONFIGURATION_POLICY_VIOLATION);
-}
-
-Ptr<PeerLink>
-PeerManagerProtocol::InitiateLink (
-  uint32_t interface,
-  Mac48Address peerAddress,
-  Time lastBeacon,
-  Time beaconInterval)
-{
-  Ptr<PeerLink> new_link = CreateObject<PeerLink> ();
-  if (m_lastLocalLinkId == 0xff)
-    m_lastLocalLinkId = 0;
-  //find a beacon entry
-  BeaconInfoMap::iterator beaconsOnInterface = m_neighbourBeacons.find (interface);
-  if(beaconsOnInterface == m_neighbourBeacons.end())
-    FillBeaconInfo(interface, peerAddress, lastBeacon, beaconInterval);
-  BeaconsOnInterface::iterator beacon = beaconsOnInterface->second.find (peerAddress);
-  if(beacon == beaconsOnInterface->second.end ())
-    FillBeaconInfo(interface, peerAddress, lastBeacon, beaconInterval);
-  //find a peer link  - it must not exist
-  NS_ASSERT(FindPeerLink(interface, peerAddress) == 0);
-  // Plugin must exist
-  PeerManagerPluginMap::iterator plugin = m_plugins.find (interface);
-  NS_ASSERT(plugin != m_plugins.end ());
-  PeerLinksMap::iterator iface = m_peerLinks.find (interface);
-  NS_ASSERT (iface != m_peerLinks.end());
-  new_link->SetLocalAid (beacon->second.aid);
-  new_link->SetInterface (interface);
-  new_link->SetLocalLinkId (m_lastLocalLinkId++);
-  new_link->SetPeerAddress (peerAddress);
-  new_link->SetBeaconInformation (lastBeacon, beaconInterval);
-  new_link->SetMacPlugin (plugin->second);
-  new_link->MLMESetSignalStatusCallback (MakeCallback(&PeerManagerProtocol::PeerLinkStatus, this));
-  iface->second.push_back (new_link);  
-  return new_link;
-}
-Ptr<PeerLink>
-PeerManagerProtocol::FindPeerLink(uint32_t interface, Mac48Address peerAddress)
-{
-  PeerLinksMap::iterator iface = m_peerLinks.find (interface);
-  NS_ASSERT (iface != m_peerLinks.end());
-  for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end(); i++)  
-    if ((*i)->GetPeerAddress () == peerAddress)
-      return (*i);
-  return 0;
-}
-void
-PeerManagerProtocol::PeerCleanup ()
-{
-  //Cleanup a peer link descriptors:
-  for (
-    PeerLinksMap::iterator j = m_peerLinks.begin ();
-    j != m_peerLinks.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 ();
-    }
-  // cleanup neighbour beacons:
-  m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &PeerManagerProtocol::PeerCleanup, this);
-}
-bool
-PeerManagerProtocol::IsActiveLink (uint32_t interface, Mac48Address peerAddress)
-{
-  Ptr<PeerLink> peerLink = FindPeerLink(interface, peerAddress);
-    if(peerLink != 0)
-      return (peerLink->LinkIsEstab ());
-  return false;
-}
-bool
-PeerManagerProtocol::ShouldSendOpen (uint32_t interface, Mac48Address peerAddress)
-{
-  if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
-    return false;
-  return true;
-}
-bool
-PeerManagerProtocol::ShouldAcceptOpen (uint32_t interface, Mac48Address peerAddress, dot11sReasonCode & reasonCode)
-{
-  if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
-    {
-      reasonCode = REASON11S_MESH_MAX_PEERS;
-      return false;
-    }
-  return true;
-}
-Time
-PeerManagerProtocol::GetNextBeaconShift (uint32_t interface)
-{
-  //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 = Simulator::Now().GetMicroSeconds();
-  uint32_t futureBeaconInTimeUnits = 0;
-  //Going through all my timing elements and detecting future beacon collisions
-  PeerLinksMap::iterator iface = m_peerLinks.find (interface);
-  NS_ASSERT (iface != m_peerLinks.end());
-  PeerManagerPluginMap::iterator plugin = m_plugins.find (interface);
-  NS_ASSERT(plugin != m_plugins.end());
-  std::pair<Time, Time> myBeacon = plugin->second->GetBeaconInfo ();
-  for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
-    {
-      IeBeaconTiming::NeighboursTimingUnitsList neighbours;
-      neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList();
-      //first let's form the list of all kown Tbtts
-      for (IeBeaconTiming::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 = myBeacon.first.GetMicroSeconds ()/1024;
-          //My beacon interval in Time Units
-          uint32_t myBeaconIntervalInTimeUnits;
-          myBeaconIntervalInTimeUnits = myBeacon.second.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
-      //Do not shift to the past
-      if(MicroSeconds(beaconShift * 1024) + Simulator::Now() < myBeacon.first)
-        return MicroSeconds (beaconShift * 1024);
-      else
-        return MicroSeconds (0);
-    }
-  //No collision detected, hence no shift is needed
-  else
-    return MicroSeconds (0);
-}
-void
-PeerManagerProtocol::PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, bool status)
-{
-   PeerManagerPluginMap::iterator plugin = m_plugins.find (interface);
-   NS_ASSERT(plugin != m_plugins.end());
-   NS_LOG_UNCOND("LINK between me:"<<plugin->second->GetAddress() <<" and peer:"<<peerAddress<<", at interface "<<interface);
-   if(status)
-   {
-     NS_LOG_UNCOND("Established");
-     m_numberOfActivePeers ++;
-   }
-   else
-   {
-     NS_LOG_UNCOND("Closed");
-     m_numberOfActivePeers --;
-   }
-}
-  
-} // namespace dot11s
-} //namespace ns3
-