From 3aebd147bdae0d0375c5cb090d31a3b1c56c7287 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 18 Mar 2009 14:37:29 +0300 Subject: [PATCH 1/4] Use reference counting for WifiInformationElement --- src/devices/mesh/mesh-wifi-beacon.cc | 14 +++++++------- src/devices/mesh/mesh-wifi-beacon.h | 4 ++-- src/devices/mesh/wifi-information-element.h | 4 +++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/devices/mesh/mesh-wifi-beacon.cc b/src/devices/mesh/mesh-wifi-beacon.cc index b6a97701f..6df52d5d8 100644 --- a/src/devices/mesh/mesh-wifi-beacon.cc +++ b/src/devices/mesh/mesh-wifi-beacon.cc @@ -30,18 +30,18 @@ MeshWifiBeacon::MeshWifiBeacon(Ssid ssid, SupportedRates rates, uint64_t us) m_header.SetBeaconIntervalUs (us); } -void MeshWifiBeacon::AddInformationElement(const WifiInformationElement * ie) +void MeshWifiBeacon::AddInformationElement(Ptr ie) { m_elements.push_back(ie); } namespace { -/// aux sorter -struct IEComparator +/// aux sorter for Ptr +struct PIEComparator { - bool operator()(const WifiInformationElement * a, const WifiInformationElement * b) const + bool operator() (Ptr a, Ptr b) const { - return (*a < *b); + return ((*PeekPointer(a)) < (*PeekPointer(b))); } }; } @@ -50,9 +50,9 @@ Ptr MeshWifiBeacon::CreatePacket() { Ptr packet = Create (); - std::sort(m_elements.begin(), m_elements.end(), IEComparator()); + std::sort(m_elements.begin(), m_elements.end(), PIEComparator()); - std::vector::const_reverse_iterator i; + std::vector< Ptr >::const_reverse_iterator i; for(i = m_elements.rbegin(); i != m_elements.rend(); ++i) { packet->AddHeader(**i); diff --git a/src/devices/mesh/mesh-wifi-beacon.h b/src/devices/mesh/mesh-wifi-beacon.h index 07dfeedc1..28d14b975 100644 --- a/src/devices/mesh/mesh-wifi-beacon.h +++ b/src/devices/mesh/mesh-wifi-beacon.h @@ -51,7 +51,7 @@ public: /// Read standard Wifi beacon header MgtBeaconHeader Header () const { return m_header; } /// Add information element - void AddInformationElement (const WifiInformationElement * ie); + void AddInformationElement (Ptr ie); /// Create frame = { header + all information elements sorted by ElementId() } Ptr CreatePacket (); @@ -59,7 +59,7 @@ private: /// Beacon header MgtBeaconHeader m_header; /// List of information elements added - std::vector m_elements; + std::vector< Ptr > m_elements; }; } diff --git a/src/devices/mesh/wifi-information-element.h b/src/devices/mesh/wifi-information-element.h index 2973f0aed..7e7ac4b15 100644 --- a/src/devices/mesh/wifi-information-element.h +++ b/src/devices/mesh/wifi-information-element.h @@ -22,6 +22,7 @@ #define WIFIINFORMATIONELEMENT_H_ #include "ns3/header.h" +#include "ns3/ref-count-base.h" namespace ns3 { @@ -70,7 +71,8 @@ enum WifiElementId { * Element ID as defined in this standard. The Length field specifies the number of octets in the Information * field. */ -class WifiInformationElement : public Header +class WifiInformationElement : public Header, + public RefCountBase // need this to use Ptr { public: /// Support object system From 726ca47d37efa2a31ddd4603afea4eae86337855 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 18 Mar 2009 16:08:49 +0300 Subject: [PATCH 2/4] MeshWifiInterfaceMac just added and beacon generation refactored --- src/devices/mesh/mesh-wifi-beacon.cc | 16 +- src/devices/mesh/mesh-wifi-beacon.h | 11 +- src/devices/mesh/mesh-wifi-interface-mac.cc | 703 ++++++++++++++++++++ src/devices/mesh/mesh-wifi-interface-mac.h | 221 ++++++ src/devices/mesh/wscript | 6 +- 5 files changed, 950 insertions(+), 7 deletions(-) create mode 100644 src/devices/mesh/mesh-wifi-interface-mac.cc create mode 100644 src/devices/mesh/mesh-wifi-interface-mac.h diff --git a/src/devices/mesh/mesh-wifi-beacon.cc b/src/devices/mesh/mesh-wifi-beacon.cc index 6df52d5d8..e0c8eadc4 100644 --- a/src/devices/mesh/mesh-wifi-beacon.cc +++ b/src/devices/mesh/mesh-wifi-beacon.cc @@ -58,10 +58,24 @@ Ptr MeshWifiBeacon::CreatePacket() packet->AddHeader(**i); } - packet->AddHeader(Header()); + packet->AddHeader(BeaconHeader()); return packet; } + +WifiMacHeader MeshWifiBeacon::CreateHeader (Mac48Address address) +{ + WifiMacHeader hdr; + + hdr.SetBeacon (); + hdr.SetAddr1 (Mac48Address::GetBroadcast ()); + hdr.SetAddr2 (address); + hdr.SetAddr3 (address); + hdr.SetDsNotFrom (); + hdr.SetDsNotTo (); + + return hdr; +} } // namespace diff --git a/src/devices/mesh/mesh-wifi-beacon.h b/src/devices/mesh/mesh-wifi-beacon.h index 28d14b975..bd147424d 100644 --- a/src/devices/mesh/mesh-wifi-beacon.h +++ b/src/devices/mesh/mesh-wifi-beacon.h @@ -25,7 +25,7 @@ #include "ns3/packet.h" #include "ns3/wifi-information-element.h" #include "ns3/mgt-headers.h" // from wifi module -#include "ns3/ssid.h" +#include "ns3/wifi-mac-header.h" #include @@ -49,11 +49,14 @@ public: */ MeshWifiBeacon(Ssid ssid, SupportedRates rates, uint64_t us); /// Read standard Wifi beacon header - MgtBeaconHeader Header () const { return m_header; } + MgtBeaconHeader BeaconHeader () const { return m_header; } /// Add information element void AddInformationElement (Ptr ie); - /// Create frame = { header + all information elements sorted by ElementId() } - Ptr CreatePacket (); + + /// Create wifi header for beacon frame. \param address is sender address + WifiMacHeader CreateHeader (Mac48Address address); + /// Create frame = { beacon header + all information elements sorted by ElementId() } + Ptr CreatePacket (); private: /// Beacon header diff --git a/src/devices/mesh/mesh-wifi-interface-mac.cc b/src/devices/mesh/mesh-wifi-interface-mac.cc new file mode 100644 index 000000000..aefc29326 --- /dev/null +++ b/src/devices/mesh/mesh-wifi-interface-mac.cc @@ -0,0 +1,703 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Kirill Andreev + * Pavel Boyko + */ + +#include "ns3/mesh-wifi-interface-mac.h" +#include "ns3/mesh-wifi-beacon.h" +#include "ns3/log.h" +#include "ns3/wifi-phy.h" +#include "ns3/dcf-manager.h" +#include "ns3/mac-rx-middle.h" +#include "ns3/mac-low.h" +#include "ns3/dca-txop.h" +#include "ns3/mesh-wifi-mac-header.h" +#include "ns3/random-variable.h" +#include "ns3/simulator.h" + +NS_LOG_COMPONENT_DEFINE ("MeshWifiInterfaceMac"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (MeshWifiInterfaceMac); + +TypeId +MeshWifiInterfaceMac::GetTypeId () +{ + static TypeId tid = TypeId ("ns3::MeshWifiInterfaceMac") + .SetParent () + .AddConstructor () + .AddAttribute ("BeaconInterval", "Beacon Interval", + TimeValue (Seconds (1.0)), + MakeTimeAccessor (&MeshWifiInterfaceMac::m_beaconInterval), + MakeTimeChecker () + ) + .AddAttribute ("RandomStart", "Window when beacon generating starts (uniform random) in seconds", + TimeValue (Seconds (0.1)), + MakeTimeAccessor (&MeshWifiInterfaceMac::m_randomStart), + MakeTimeChecker () + ) + .AddAttribute ("SoftwareDelay", "Window of uniformely distributed random software handling delay", + TimeValue (MicroSeconds (500)), + MakeTimeAccessor (&MeshWifiInterfaceMac::m_softwareDelay), + MakeTimeChecker () + ) + .AddAttribute ("BeaconGeneration", "Enable/Disable Beaconing.", + BooleanValue (true), + MakeBooleanAccessor ( + &MeshWifiInterfaceMac::SetBeaconGeneration, + &MeshWifiInterfaceMac::GetBeaconGeneration + ), + MakeBooleanChecker () + ); + return tid; +} + +MeshWifiInterfaceMac::MeshWifiInterfaceMac () +{ + NS_LOG_FUNCTION (this); + + m_rxMiddle = new MacRxMiddle (); + m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiInterfaceMac::Receive, this)); + + m_low = CreateObject (); + m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle)); + + m_dcfManager = new DcfManager (); + m_dcfManager->SetupLowListener (m_low); + + m_beaconDca = CreateObject (); + m_beaconDca->SetLow (m_low); + m_beaconDca->SetMinCw (0); + m_beaconDca->SetMaxCw (0); + m_beaconDca->SetAifsn(1); + m_beaconDca->SetManager (m_dcfManager); + + m_VO = CreateObject (); + m_VO->SetLow (m_low); + m_VO->SetMinCw (3); + m_VO->SetMaxCw (7); + m_VO->SetManager (m_dcfManager); + + m_BE = CreateObject (); + m_BE->SetLow (m_low); + m_BE->SetManager (m_dcfManager); +} + +MeshWifiInterfaceMac::~MeshWifiInterfaceMac () +{ + NS_LOG_FUNCTION (this); +} + +//----------------------------------------------------------------------------- +// WifiMac inherited +//----------------------------------------------------------------------------- +void +MeshWifiInterfaceMac::SetSlot (Time slotTime) +{ + NS_LOG_FUNCTION (this << slotTime); + m_dcfManager->SetSlot (slotTime); + m_slot = slotTime; +} + +void +MeshWifiInterfaceMac::SetSifs (Time sifs) +{ + NS_LOG_FUNCTION (this << sifs); + m_dcfManager->SetSifs (sifs); + m_sifs = sifs; +} +void +MeshWifiInterfaceMac::SetAckTimeout (Time ackTimeout) +{ + m_low->SetAckTimeout (ackTimeout); +} + +void +MeshWifiInterfaceMac::SetCtsTimeout (Time ctsTimeout) +{ + m_low->SetCtsTimeout (ctsTimeout); +} + +void +MeshWifiInterfaceMac::SetPifs (Time pifs) +{ + NS_LOG_FUNCTION (this << pifs); + m_pifs = pifs; +} +void +MeshWifiInterfaceMac::SetEifsNoDifs (Time eifsNoDifs) +{ + NS_LOG_FUNCTION (this << eifsNoDifs); + m_dcfManager->SetEifsNoDifs (eifsNoDifs); + m_eifsNoDifs = eifsNoDifs; +} + +Time +MeshWifiInterfaceMac::GetSlot () const + { + return m_slot; + } + +Time +MeshWifiInterfaceMac::GetSifs () const + { + return m_sifs; + } + +Time +MeshWifiInterfaceMac::GetEifsNoDifs () const + { + return m_eifsNoDifs; + } + +Time +MeshWifiInterfaceMac::GetAckTimeout () const + { + return m_low->GetAckTimeout (); + } + +Time +MeshWifiInterfaceMac::GetCtsTimeout () const + { + return m_low->GetCtsTimeout (); + } + +Time +MeshWifiInterfaceMac::GetPifs () const + { + return m_low->GetPifs (); + } + +void +MeshWifiInterfaceMac::SetWifiPhy (Ptr phy) +{ + NS_LOG_FUNCTION (this << phy); + m_phy = phy; + m_dcfManager->SetupPhyListener (phy); + m_low->SetPhy (phy); +} + +void +MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr stationManager) +{ + NS_LOG_FUNCTION (this << stationManager); + m_stationManager = stationManager; + m_BE->SetWifiRemoteStationManager (stationManager); + m_VO->SetWifiRemoteStationManager (stationManager); + m_beaconDca->SetWifiRemoteStationManager (stationManager); + m_low->SetWifiRemoteStationManager (stationManager); +} + +void +MeshWifiInterfaceMac::Enqueue (Ptr packet, Mac48Address to, Mac48Address from) +{ + NS_LOG_FUNCTION (this << packet << to << from); + ForwardDown (packet, from, to); +} + +void +MeshWifiInterfaceMac::Enqueue (Ptr packet, Mac48Address to) +{ + NS_LOG_FUNCTION (this << packet << to); + ForwardDown (packet, m_low->GetAddress (), to); +} + +bool +MeshWifiInterfaceMac::SupportsSendFrom () const + { + return true; + } + +void +MeshWifiInterfaceMac::SetForwardUpCallback (Callback, Mac48Address, Mac48Address> upCallback) +{ + NS_LOG_FUNCTION (this); + m_upCallback = upCallback; +} + +void +MeshWifiInterfaceMac::SetLinkUpCallback (Callback linkUp) +{ + NS_LOG_FUNCTION (this); + if (!linkUp.IsNull ()) + { + linkUp (); + } +} + +void +MeshWifiInterfaceMac::SetLinkDownCallback (Callback linkDown) +{ + NS_LOG_FUNCTION (this); +} + +Mac48Address +MeshWifiInterfaceMac::GetAddress () const + { + return m_address; + } +Mac48Address +MeshWifiInterfaceMac::GetBssid () const + { + return m_address; + } + +Ssid +MeshWifiInterfaceMac::GetSsid () const + { + return m_MeshId; + } + +void +MeshWifiInterfaceMac::SetAddress (Mac48Address address) +{ + NS_LOG_FUNCTION (address); + m_low->SetAddress(address); + m_address = address; +} + +void +MeshWifiInterfaceMac::SetSsid (Ssid ssid) +{ + NS_LOG_FUNCTION (ssid); + m_MeshId = ssid; +} + +void +MeshWifiInterfaceMac::DoDispose () +{ + NS_LOG_FUNCTION (this); + delete m_rxMiddle; + delete m_dcfManager; + //Delete smart pointers: + m_rxMiddle = 0; + m_low = 0; + m_dcfManager = 0; + m_phy = 0; + m_BE = 0; + m_VO = 0; + m_beaconSendEvent.Cancel (); + m_beaconDca = 0; + + WifiMac::DoDispose (); +} + +//----------------------------------------------------------------------------- +// Forward frame up/down +//----------------------------------------------------------------------------- +void +MeshWifiInterfaceMac::ForwardUp (Ptr packet, Mac48Address src, Mac48Address dst) +{ + NS_LOG_FUNCTION (this << packet << src); + m_upCallback (packet, src, dst); +} + +void +MeshWifiInterfaceMac::ForwardDown (Ptr packet, Mac48Address from, Mac48Address to) +{ + // 1. Create and add mesh header using routing information + WifiMacHeader hdr; + Ptr packet_to_send = packet->Copy(); + + /* + TODO: + for all plugins { + plugin.UpdateOutcomingPacket....(packet, from, to); + } + */ + + /* + WifiMeshHeader meshHdr; + + // TODO: Address 1 we receive from HWMP tag + HwmpTag tag; + NS_ASSERT(packet->FindFirstMatchingTag(tag)); + meshHdr.SetMeshTtl(tag.GetTtl()); + meshHdr.SetMeshSeqno(tag.GetSeqno()); +#if 0 + NS_LOG_DEBUG( + "TX Packet sa = "<Queue(beacon.CreatePacket(), beacon.CreateHeader(GetAddress())); + + ScheduleNextBeacon(); +} + + +void +MeshWifiInterfaceMac::Receive (Ptr packet, WifiMacHeader const *hdr) +{ + /* TODO + if (hdr->IsBeacon ()) + { + MgtMeshBeaconHeader beacon; + Mac48Address from = hdr->GetAddr2(); + packet->RemoveHeader (beacon); + NS_LOG_DEBUG("Beacon received from "<GetAddr2()<< + " to "<GetAID(), + (*j)->GetLastBeacon(), + (*j)->GetBeaconInterval() + ); +#endif + m_peerManager->SetReceivedBeaconTimers( + GetAddress(), + from, + Simulator::Now (), + MicroSeconds(beacon.GetBeaconIntervalUs()), + beacon.GetWifiBeaconTimingElement() + ); + if (!beacon.GetSsid().IsEqual(GetSsid())) + return; + SupportedRates rates = beacon.GetSupportedRates (); + WifiRemoteStation *peerSta = m_stationManager->Lookup (hdr->GetAddr2 ()); + for (uint32_t i = 0; i < m_phy->GetNModes (); i++) + { + WifiMode mode = m_phy->GetMode (i); + if (rates.IsSupportedRate (mode.GetDataRate ())) + { + peerSta->AddSupportedMode (mode); + if (rates.IsBasicRate (mode.GetDataRate ())) + { + m_stationManager->AddBasicMode (mode); + } + } + } + // TODO:Chack MeshConfigurationElement(now is nothing + // to be checked) + m_peerManager->AskIfOpenNeeded(GetAddress(), from); + return; + } + if (hdr->IsMultihopAction()) + { + WifiMeshHeader meshHdr; + //no mesh header parameters are needed here: + //TODO: check TTL + packet->RemoveHeader(meshHdr); + WifiMeshMultihopActionHeader multihopHdr; + //parse multihop action header: + packet->RemoveHeader(multihopHdr); + WifiMeshMultihopActionHeader::ACTION_VALUE + actionValue = multihopHdr.GetAction(); + switch (multihopHdr.GetCategory()) + { + case WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT: + { + Mac48Address peerAddress; + MeshMgtPeerLinkManFrame peer_frame; + if (hdr->GetAddr1 () != GetAddress ()) + return; + peerAddress = hdr->GetAddr2(); + packet->RemoveHeader (peer_frame); + if (actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) + { + //check Supported Rates + SupportedRates rates = peer_frame.GetSupportedRates(); + for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++) + { + WifiMode mode = m_stationManager->GetBasicMode (i); + if (!rates.IsSupportedRate (mode.GetDataRate ())) + { + m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress); + return; + } + } + //Check SSID + if (!peer_frame.GetMeshId().IsEqual(GetSsid())) + { + m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress); + return; + } + } + switch (actionValue.peerLink) + { + case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM: + m_peerManager->SetConfirmReceived( + GetAddress(), + peerAddress, + peer_frame.GetAid(), + peer_frame.GetPeerLinkManagementElement(), + m_meshConfig + ); + return; + case WifiMeshMultihopActionHeader::PEER_LINK_OPEN: + m_peerManager->SetOpenReceived( + GetAddress(), + peerAddress, + peer_frame.GetPeerLinkManagementElement(), + m_meshConfig + ); + return; + case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE: + m_peerManager->SetCloseReceived( + GetAddress(), + peerAddress, + peer_frame.GetPeerLinkManagementElement() + ); + return; + default: + return; + } + break; + } + case WifiMeshMultihopActionHeader::MESH_PATH_SELECTION: + { + if (!m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2())) + return; + switch (actionValue.pathSelection) + { + case WifiMeshMultihopActionHeader::PATH_REQUEST: + { + WifiPreqInformationElement preq; + packet->RemoveHeader(preq); + //TODO:recalculate + //metric + m_preqReceived(preq, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2())); + return; + } + case WifiMeshMultihopActionHeader::PATH_REPLY: + { + WifiPrepInformationElement prep; + packet->RemoveHeader(prep); + m_prepReceived(prep, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2())); + } + return; + case WifiMeshMultihopActionHeader::PATH_ERROR: + { + WifiPerrInformationElement perr; + packet->RemoveHeader(perr); + m_perrReceived(perr, hdr->GetAddr2()); + } + return; + case WifiMeshMultihopActionHeader::ROOT_ANNOUNCEMENT: + return; + } + } + default: + break; + } + } + if (hdr->IsData()) + { + NS_ASSERT((hdr->IsFromDs()) && (hdr->IsToDs())); + NS_ASSERT(hdr->GetAddr4()!=Mac48Address::GetBroadcast()); + //check seqno + WifiMeshHeader meshHdr; + packet->RemoveHeader(meshHdr); + NS_LOG_DEBUG( + "DATA TA="<< hdr->GetAddr2()<< + ", da="<GetAddr3()<< + ", sa="<GetAddr4()<< + ", TTL="<<(int)meshHdr.GetMeshTtl()); + HwmpTag tag; + //mesh header is present within DATA and multihop action frames, so it must be done within MAC + tag.SetSeqno(meshHdr.GetMeshSeqno()); + tag.SetAddress(hdr->GetAddr2()); + tag.SetTtl(meshHdr.GetMeshTtl()); + //metric should be later + packet->RemoveAllTags(); + packet->AddTag(tag); + if (m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2())) + ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3()); + } + */ +} + +} // namespace ns3 + + + diff --git a/src/devices/mesh/mesh-wifi-interface-mac.h b/src/devices/mesh/mesh-wifi-interface-mac.h new file mode 100644 index 000000000..a572a6139 --- /dev/null +++ b/src/devices/mesh/mesh-wifi-interface-mac.h @@ -0,0 +1,221 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Kirill Andreev + * Pavel Boyko + */ + +#ifndef MESHWIFIINTERFACEMAC_H_ +#define MESHWIFIINTERFACEMAC_H_ + +#include +#include +#include "ns3/mac48-address.h" +#include "ns3/mac48-address-comparator.h" +#include "ns3/mgt-headers.h" +#include "ns3/mesh-mgt-headers.h" +#include "ns3/callback.h" +#include "ns3/packet.h" +#include "ns3/nstime.h" +#include "ns3/mesh-wifi-beacon-timing-element.h" +#include "ns3/wifi-remote-station-manager.h" +#include "ns3/mesh-wifi-peer-manager.h" +#include "ns3/wifi-mac.h" + +namespace ns3 { + +class WifiMacHeader; +class DcaTxop; +class WifiPhy; +class DcfManager; +class MacRxMiddle; +class MacLow; +/** + * \ingroup mesh + * + * \brief Basic MAC of mesh point Wi-Fi interface. Its function is extendable through plugins mechanism. + * + * Now only three output queues are used: + * - beacons (PIFS and no backoff), + * - background traffic, + * - management and priority traffic. + * + */ +class MeshWifiInterfaceMac : public WifiMac +{ +public: + /// Never forget to support typeid + static TypeId GetTypeId (); + /// C-tor + MeshWifiInterfaceMac(); + /// D-tor + virtual ~MeshWifiInterfaceMac(); + + ///\name Inherited from WifiMac + //\{ + virtual void SetSlot (Time slotTime); + virtual void SetSifs (Time sifs); + virtual void SetPifs (Time pifs); + virtual void SetCtsTimeout (Time ctsTimeout); + virtual void SetAckTimeout (Time ackTimeout); + virtual void SetEifsNoDifs (Time eifsNoDifs); + virtual Time GetSlot () const; + virtual Time GetSifs () const; + virtual Time GetPifs () const; + virtual Time GetCtsTimeout () const; + virtual Time GetAckTimeout () const; + virtual Time GetEifsNoDifs () const; + virtual void SetWifiPhy (Ptr phy); + virtual void SetWifiRemoteStationManager (Ptr stationManager); + virtual void Enqueue (Ptr packet, Mac48Address to, Mac48Address from); + virtual void Enqueue (Ptr packet, Mac48Address to); + virtual bool SupportsSendFrom () const; + virtual void SetForwardUpCallback (Callback, Mac48Address, Mac48Address> upCallback); + virtual void SetLinkUpCallback (Callback linkUp); + virtual void SetLinkDownCallback (Callback linkDown); + virtual Mac48Address GetAddress () const; + virtual Mac48Address GetBssid () const; + virtual Ssid GetSsid () const; + virtual void SetAddress (Mac48Address address); + virtual void SetSsid (Ssid ssid); + //\} + + ///\name Beacons + //\{ + + /// Set interval between two successive beacons + void SetBeaconInterval (Time interval); + /// \return interval between two beacons + Time GetBeaconInterval () const; + /** + * \brief Next beacon frame time + * + * This is supposed to be used by any entity managing beacon collision avoidance (e.g. Peer management protocol in 802.11s) + */ + Time GetTBTT() const; + /** + * \brief Shift TBTT. + * + * This is supposed to be used by any entity managing beacon collision avoidance (e.g. Peer management protocol in 802.11s) + * + * \attention User of ShiftTBTT() must take care to not shift it to the past. + */ + void ShiftTBTT(Time shift); + /** + * \brief Set maximum software delay. Maximum software delay must be smaller than beacon interval. + * + * Software delay models random small internal delay to avoid simultaneous operation of + * different mesh points (e.g. on power on). + * + * Software delay is calculated as uniformely distributed random value between zero and + * given parameter. All management frames are sent after software delay is passed, + * for example, beacon is formed at software delay before putting it to the queue. + * + * \attention The software delay is supposed to be independent from traffic intensity. + * + * \param delay is the maximum software delay. + */ + void SetSoftwareDelay(Time delay); + /// \return Maximum software delay + Time GetSoftwareDelay(); + + //\} + + ///\name Plugins + //\{ + // TODO + //\} + +private: + /// Frame receive handler + void Receive (Ptr packet, WifiMacHeader const *hdr); + /// Forward frame to mesh point + virtual void ForwardUp (Ptr packet, Mac48Address src, Mac48Address dst); + /// Send frame. Frame is supposed to be tagged by routing information. TODO: clarify this point + void ForwardDown(Ptr packet, Mac48Address from, Mac48Address to); + /// Calc software delay value uniformely distributed between 0 and m_softwareDealy, see SetSoftwareDelay(). + Time CalcSwDelay(); + /// Send beacon + void SendBeacon (); + /// Schedule next beacon + void ScheduleNextBeacon (); + /// Enable/disable beacons + void SetBeaconGeneration (bool enable); + /// Get current beaconing status + bool GetBeaconGeneration () const; + /// Get list of supported bitrates + SupportedRates GetSupportedRates () const; + /// Real d-tor + virtual void DoDispose (); + +private: + ///\name Wifi MAC internals + //\{ + Ptr m_BE; + Ptr m_BK; + Ptr m_VI; + Ptr m_VO; + Ptr m_beaconDca; + Ptr m_stationManager; + Ptr m_phy; + Callback, Mac48Address, Mac48Address> m_upCallback; + //\} + + ///\name Wifi timing intervals + //\{ + Time m_slot; + Time m_sifs; + Time m_pifs; + Time m_ackTimeout; + Time m_ctsTimeout; + Time m_eifsNoDifs; + //\} + + ///\name Mesh timing intervals + //\{ + /// Beaconing interval. + Time m_beaconInterval; + /// Maximum delay before first beacon + Time m_randomStart; + /// Maximum software delay + Time m_softwareDelay; + /// Send time of the last management frame, used to ensure correct frame order + Time m_lastMgtFrame; + /// Time for the next frame + Time m_tbtt; + //\} + + /// DCF implementation + DcfManager* m_dcfManager; + /// Middle MAC sublayer + MacRxMiddle* m_rxMiddle; + /// Low MAX sublayer + Ptr m_low; + /// My address + Mac48Address m_address; + /// SSID + Ssid m_MeshId; + + /// "Timer" for the next beacon + EventId m_beaconSendEvent; +}; + +} // namespace ns3 + + + +#endif /* MESHWIFIINTERFACEMAC_H_ */ diff --git a/src/devices/mesh/wscript b/src/devices/mesh/wscript index 233ca4d1c..ed97a0446 100644 --- a/src/devices/mesh/wscript +++ b/src/devices/mesh/wscript @@ -4,10 +4,11 @@ def build(bld): obj = bld.create_ns3_module('mesh', ['wifi', '802.11s']) obj.source = [ # Refactored + 'wifi-information-element.cc', 'mesh-point-device.cc', 'mesh-l2-routing-protocol.cc', 'mesh-wifi-beacon.cc', - 'wifi-information-element.cc', + 'mesh-wifi-interface-mac.cc', # Not refactored 'mesh-wifi-helper.cc', 'mesh-wifi-mac-header.cc', @@ -25,10 +26,11 @@ def build(bld): headers.module = 'mesh' headers.source = [ # Refactored + 'wifi-information-element.h', 'mesh-point-device.h', 'mesh-l2-routing-protocol.h', 'mesh-wifi-beacon.h', - 'wifi-information-element.h', + 'mesh-wifi-interface-mac.h', # Dirty 'dot11s-codes.h', 'hwmp-state.h', From d53de9bedddc6b417fd0317d02ff3e2c353fbf31 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 18 Mar 2009 17:40:38 +0300 Subject: [PATCH 3/4] Basic MAC plugins functionality implemented --- .../mesh/mesh-wifi-interface-mac-plugin.h | 74 +++++ src/devices/mesh/mesh-wifi-interface-mac.cc | 272 ++++-------------- src/devices/mesh/mesh-wifi-interface-mac.h | 8 +- src/devices/mesh/wscript | 1 + 4 files changed, 141 insertions(+), 214 deletions(-) create mode 100644 src/devices/mesh/mesh-wifi-interface-mac-plugin.h diff --git a/src/devices/mesh/mesh-wifi-interface-mac-plugin.h b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h new file mode 100644 index 000000000..c7ecb10ae --- /dev/null +++ b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h @@ -0,0 +1,74 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Pavel Boyko + */ + +#ifndef MESHWIFIINTERFACEMACPLUGIN_H_ +#define MESHWIFIINTERFACEMACPLUGIN_H_ + +#include "ns3/wifi-mac-header.h" +#include "ns3/packet.h" +#include "ns3/mac48-address.h" +#include "ns3/mesh-wifi-beacon.h" +#include "ns3/ref-count-base.h" + +namespace ns3 { + +class MeshWifiInterfaceMac; + +/** + * \ingroup mesh + * + * \brief Common interface for mesh point interface MAC plugins + * + * TODO: plugins description + */ +class MeshWifiInterfaceMacPlugin : public RefCountBase +{ +public: + /// C-tor creates unplugged plugin + MeshWifiInterfaceMacPlugin() { /*do nothing*/} + /// This is for subclasses + virtual ~MeshWifiInterfaceMacPlugin() { /*do nothing*/ } + + /// Each plugin must be installed on interface to work + virtual void SetParent(MeshWifiInterfaceMac * parent) = 0; + /** + * \brief Process received frame + * + * \return false if (and only if) frame should be dropped + * TODO define when MAC call this + */ + virtual bool Receive(Ptr packet, const WifiMacHeader & header) = 0; + /** + * \brief Update frame before it will be forwarded down + * + * \return false if (and only if) frame should be dropped + * TODO define when MAC call this, preconditions & postconditions + */ + virtual bool UpdateOutcomingFrame(Ptr packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const = 0; + /** + * \brief Update beacon before it will be formed and sent + * + * TODO define when MAC call this + */ + virtual void UpdateBeacon(MeshWifiBeacon & beacon) const; +}; + +} // namespace ns3 +#endif /* MESHWIFIINTERFACEMACPLUGIN_H_ */ diff --git a/src/devices/mesh/mesh-wifi-interface-mac.cc b/src/devices/mesh/mesh-wifi-interface-mac.cc index aefc29326..14cf9900d 100644 --- a/src/devices/mesh/mesh-wifi-interface-mac.cc +++ b/src/devices/mesh/mesh-wifi-interface-mac.cc @@ -299,6 +299,16 @@ MeshWifiInterfaceMac::DoDispose () WifiMac::DoDispose (); } +//----------------------------------------------------------------------------- +// Plugins +//----------------------------------------------------------------------------- +void +MeshWifiInterfaceMac::InstallPlugin( Ptr plugin) +{ + plugin->SetParent(this); + m_plugins.push_back(plugin); +} + //----------------------------------------------------------------------------- // Forward frame up/down //----------------------------------------------------------------------------- @@ -310,51 +320,33 @@ MeshWifiInterfaceMac::ForwardUp (Ptr packet, Mac48Address src, Mac48Addr } void -MeshWifiInterfaceMac::ForwardDown (Ptr packet, Mac48Address from, Mac48Address to) +MeshWifiInterfaceMac::ForwardDown (Ptr const_packet, Mac48Address from, Mac48Address to) { - // 1. Create and add mesh header using routing information + // copy packet to allow modifications + Ptr packet = const_packet->Copy(); + WifiMacHeader hdr; - Ptr packet_to_send = packet->Copy(); - - /* - TODO: - for all plugins { - plugin.UpdateOutcomingPacket....(packet, from, to); - } - */ - - /* - WifiMeshHeader meshHdr; - - // TODO: Address 1 we receive from HWMP tag - HwmpTag tag; - NS_ASSERT(packet->FindFirstMatchingTag(tag)); - meshHdr.SetMeshTtl(tag.GetTtl()); - meshHdr.SetMeshSeqno(tag.GetSeqno()); -#if 0 - NS_LOG_DEBUG( - "TX Packet sa = "<GetAddr2()<< " to "<GetAID(), - (*j)->GetLastBeacon(), - (*j)->GetBeaconInterval() - ); -#endif - m_peerManager->SetReceivedBeaconTimers( - GetAddress(), - from, - Simulator::Now (), - MicroSeconds(beacon.GetBeaconIntervalUs()), - beacon.GetWifiBeaconTimingElement() - ); - if (!beacon.GetSsid().IsEqual(GetSsid())) - return; - SupportedRates rates = beacon.GetSupportedRates (); - WifiRemoteStation *peerSta = m_stationManager->Lookup (hdr->GetAddr2 ()); - for (uint32_t i = 0; i < m_phy->GetNModes (); i++) + + // update supported rates + if (beacon_hdr.GetSsid().IsEqual(GetSsid())) { - WifiMode mode = m_phy->GetMode (i); - if (rates.IsSupportedRate (mode.GetDataRate ())) - { - peerSta->AddSupportedMode (mode); - if (rates.IsBasicRate (mode.GetDataRate ())) - { + SupportedRates rates = beacon_hdr.GetSupportedRates (); + WifiRemoteStation * peerSta = m_stationManager->Lookup (hdr->GetAddr2 ()); + + for (uint32_t i = 0; i < m_phy->GetNModes (); i++) + { + WifiMode mode = m_phy->GetMode (i); + if (rates.IsSupportedRate (mode.GetDataRate ())) + { + peerSta->AddSupportedMode (mode); + if (rates.IsBasicRate (mode.GetDataRate ())) m_stationManager->AddBasicMode (mode); - } - } + } + } } - // TODO:Chack MeshConfigurationElement(now is nothing - // to be checked) - m_peerManager->AskIfOpenNeeded(GetAddress(), from); - return; } - if (hdr->IsMultihopAction()) + + // Filter frame through all installed plugins + for (PluginList::iterator i = m_plugins.begin(); i != m_plugins.end(); ++i) { - WifiMeshHeader meshHdr; - //no mesh header parameters are needed here: - //TODO: check TTL - packet->RemoveHeader(meshHdr); - WifiMeshMultihopActionHeader multihopHdr; - //parse multihop action header: - packet->RemoveHeader(multihopHdr); - WifiMeshMultihopActionHeader::ACTION_VALUE - actionValue = multihopHdr.GetAction(); - switch (multihopHdr.GetCategory()) - { - case WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT: - { - Mac48Address peerAddress; - MeshMgtPeerLinkManFrame peer_frame; - if (hdr->GetAddr1 () != GetAddress ()) - return; - peerAddress = hdr->GetAddr2(); - packet->RemoveHeader (peer_frame); - if (actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE) - { - //check Supported Rates - SupportedRates rates = peer_frame.GetSupportedRates(); - for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++) - { - WifiMode mode = m_stationManager->GetBasicMode (i); - if (!rates.IsSupportedRate (mode.GetDataRate ())) - { - m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress); - return; - } - } - //Check SSID - if (!peer_frame.GetMeshId().IsEqual(GetSsid())) - { - m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress); - return; - } - } - switch (actionValue.peerLink) - { - case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM: - m_peerManager->SetConfirmReceived( - GetAddress(), - peerAddress, - peer_frame.GetAid(), - peer_frame.GetPeerLinkManagementElement(), - m_meshConfig - ); - return; - case WifiMeshMultihopActionHeader::PEER_LINK_OPEN: - m_peerManager->SetOpenReceived( - GetAddress(), - peerAddress, - peer_frame.GetPeerLinkManagementElement(), - m_meshConfig - ); - return; - case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE: - m_peerManager->SetCloseReceived( - GetAddress(), - peerAddress, - peer_frame.GetPeerLinkManagementElement() - ); - return; - default: - return; - } - break; - } - case WifiMeshMultihopActionHeader::MESH_PATH_SELECTION: - { - if (!m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2())) - return; - switch (actionValue.pathSelection) - { - case WifiMeshMultihopActionHeader::PATH_REQUEST: - { - WifiPreqInformationElement preq; - packet->RemoveHeader(preq); - //TODO:recalculate - //metric - m_preqReceived(preq, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2())); - return; - } - case WifiMeshMultihopActionHeader::PATH_REPLY: - { - WifiPrepInformationElement prep; - packet->RemoveHeader(prep); - m_prepReceived(prep, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2())); - } - return; - case WifiMeshMultihopActionHeader::PATH_ERROR: - { - WifiPerrInformationElement perr; - packet->RemoveHeader(perr); - m_perrReceived(perr, hdr->GetAddr2()); - } - return; - case WifiMeshMultihopActionHeader::ROOT_ANNOUNCEMENT: - return; - } - } - default: - break; - } + bool drop = !((*i)->Receive(packet, *hdr)); + if (drop) return; // plugin drops frame } + + // Forward data up if (hdr->IsData()) - { - NS_ASSERT((hdr->IsFromDs()) && (hdr->IsToDs())); - NS_ASSERT(hdr->GetAddr4()!=Mac48Address::GetBroadcast()); - //check seqno - WifiMeshHeader meshHdr; - packet->RemoveHeader(meshHdr); - NS_LOG_DEBUG( - "DATA TA="<< hdr->GetAddr2()<< - ", da="<GetAddr3()<< - ", sa="<GetAddr4()<< - ", TTL="<<(int)meshHdr.GetMeshTtl()); - HwmpTag tag; - //mesh header is present within DATA and multihop action frames, so it must be done within MAC - tag.SetSeqno(meshHdr.GetMeshSeqno()); - tag.SetAddress(hdr->GetAddr2()); - tag.SetTtl(meshHdr.GetMeshTtl()); - //metric should be later - packet->RemoveAllTags(); - packet->AddTag(tag); - if (m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2())) - ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3()); - } - */ + ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3()); } } // namespace ns3 diff --git a/src/devices/mesh/mesh-wifi-interface-mac.h b/src/devices/mesh/mesh-wifi-interface-mac.h index a572a6139..8a99ce22d 100644 --- a/src/devices/mesh/mesh-wifi-interface-mac.h +++ b/src/devices/mesh/mesh-wifi-interface-mac.h @@ -35,6 +35,7 @@ #include "ns3/wifi-remote-station-manager.h" #include "ns3/mesh-wifi-peer-manager.h" #include "ns3/wifi-mac.h" +#include "ns3/mesh-wifi-interface-mac-plugin.h" namespace ns3 { @@ -137,7 +138,8 @@ public: ///\name Plugins //\{ - // TODO + /// Install plugin. TODO return unique ID to allow unregister plugins + void InstallPlugin(Ptr plugin); //\} private: @@ -212,6 +214,10 @@ private: /// "Timer" for the next beacon EventId m_beaconSendEvent; + + typedef std::vector< Ptr > PluginList; + /// List of all installed plugins + PluginList m_plugins; }; } // namespace ns3 diff --git a/src/devices/mesh/wscript b/src/devices/mesh/wscript index ed97a0446..33184a085 100644 --- a/src/devices/mesh/wscript +++ b/src/devices/mesh/wscript @@ -31,6 +31,7 @@ def build(bld): 'mesh-l2-routing-protocol.h', 'mesh-wifi-beacon.h', 'mesh-wifi-interface-mac.h', + 'mesh-wifi-interface-mac-plugin.h', # Dirty 'dot11s-codes.h', 'hwmp-state.h', From 39072b6d5dbef9aa35b537b39b9ac23bba01cc66 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 18 Mar 2009 17:56:53 +0300 Subject: [PATCH 4/4] mesh/dot11s doxygen module added --- src/devices/mesh/802.11s/dot11s.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/devices/mesh/802.11s/dot11s.h diff --git a/src/devices/mesh/802.11s/dot11s.h b/src/devices/mesh/802.11s/dot11s.h new file mode 100644 index 000000000..004395650 --- /dev/null +++ b/src/devices/mesh/802.11s/dot11s.h @@ -0,0 +1,29 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 IITP RAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Pavel Boyko + * + * This is doxygen module description, don't include + */ +/** + * \ingroup mesh + * \defgroup dot11s IEEE 802.11s draft + * + * \brief IEEE 802.11s (mesh) draft standard implementation + * + * TODO: add documentation on 802.11s implementation here + */ \ No newline at end of file