From d53de9bedddc6b417fd0317d02ff3e2c353fbf31 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 18 Mar 2009 17:40:38 +0300 Subject: [PATCH] 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',