--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h Wed Mar 18 17:40:38 2009 +0300
@@ -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 <boyko@iitp.ru>
+ */
+
+#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> 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> 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_ */
--- a/src/devices/mesh/mesh-wifi-interface-mac.cc Wed Mar 18 16:08:49 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac.cc Wed Mar 18 17:40:38 2009 +0300
@@ -300,6 +300,16 @@
}
//-----------------------------------------------------------------------------
+// Plugins
+//-----------------------------------------------------------------------------
+void
+MeshWifiInterfaceMac::InstallPlugin( Ptr<MeshWifiInterfaceMacPlugin> plugin)
+{
+ plugin->SetParent(this);
+ m_plugins.push_back(plugin);
+}
+
+//-----------------------------------------------------------------------------
// Forward frame up/down
//-----------------------------------------------------------------------------
void
@@ -310,51 +320,33 @@
}
void
-MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address from, Mac48Address to)
{
- // 1. Create and add mesh header using routing information
- WifiMacHeader hdr;
- Ptr<Packet> packet_to_send = packet->Copy();
-
- /*
- TODO:
- for all plugins {
- plugin.UpdateOutcomingPacket....(packet, from, to);
- }
- */
-
- /*
- WifiMeshHeader meshHdr;
+ // copy packet to allow modifications
+ Ptr<Packet> packet = const_packet->Copy();
- // 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 = "<<from<<
- ", da = "<<to<<
- ", ra = "<<tag.GetAddress()<<
- ", I am "<<GetAddress()<<
- ", ttl = "<<(int)meshHdr.GetMeshTtl()
- );
-#endif
- if (to!= Mac48Address::GetBroadcast())
- NS_ASSERT(tag.GetAddress()!=Mac48Address::GetBroadcast());
-
+ WifiMacHeader hdr;
hdr.SetTypeData ();
- hdr.SetAddr1 (tag.GetAddress());
hdr.SetAddr2 (GetAddress ());
hdr.SetAddr3 (to);
hdr.SetAddr4 (from);
hdr.SetDsFrom ();
hdr.SetDsTo ();
- packet_to_send->AddHeader(meshHdr);
- */
+ // Address 1 is unknwon here. Routing plugin is responsible to correctly set it.
+ hdr.SetAddr1 (Mac48Address ());
- // 2. Queue frame
+ // Filter packet through all installed plugins
+ for(PluginList::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
+ {
+ bool drop = !((*i)->UpdateOutcomingFrame(packet, hdr, from, to));
+ if (drop) return; // plugin drops frame
+ }
+
+ // Assert that address1 is set. Assert will fail e.g. if there is no installed routing plugin.
+ NS_ASSERT(hdr.GetAddr1() != Mac48Address() );
+
+ // Queue frame
WifiRemoteStation *destination = m_stationManager->Lookup (to);
if (destination->IsBrandNew ())
@@ -367,7 +359,7 @@
}
destination->RecordDisassociated ();
}
- m_BE->Queue (packet_to_send, hdr);
+ m_BE->Queue (packet, hdr);
}
SupportedRates
@@ -476,7 +468,6 @@
m_beaconSendEvent = Simulator::Schedule (GetTBTT(), &MeshWifiInterfaceMac::SendBeacon, this);
}
-
void
MeshWifiInterfaceMac::ScheduleNextBeacon()
{
@@ -496,205 +487,60 @@
// Form & send beacon
MeshWifiBeacon beacon(GetSsid (), GetSupportedRates (), m_beaconInterval.GetMicroSeconds ());
- /*
- TODO ask all plugins to add smth. to beacon
- for all plugins {
- plugin.UpdateBeacon(beacon);
- }
- */
+ // Ask all plugins to add their specific information elements to beacon
+ for(PluginList::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
+ (*i)->UpdateBeacon(beacon);
m_beaconDca->Queue(beacon.CreatePacket(), beacon.CreateHeader(GetAddress()));
ScheduleNextBeacon();
}
-
void
MeshWifiInterfaceMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
{
- /* TODO
+ // Process beacon
if (hdr->IsBeacon ())
{
- MgtMeshBeaconHeader beacon;
+ MgtBeaconHeader beacon_hdr;
Mac48Address from = hdr->GetAddr2();
- packet->RemoveHeader (beacon);
+
+ packet->PeekHeader (beacon_hdr);
+
NS_LOG_DEBUG("Beacon received from "<<hdr->GetAddr2()<<
" to "<<GetAddress()<<
" at "<<Simulator::Now ().GetMicroSeconds ()<<
" microseconds");
-#if 0
- NeighboursTimingUnitsList neighbours;
- neighbours = beacon.GetWifiBeaconTimingElement().GetNeighboursTimingElementsList();
- for (NeighboursTimingUnitsList::const_iterator j = neighbours.begin(); j!= neighbours.end(); j++)
- fprintf(
- stderr,
- "neigbours:\nAID=%u, last_beacon=%u ,beacon_interval=%u\n",
- (*j)->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:
+
+ // update supported rates
+ if (beacon_hdr.GetSsid().IsEqual(GetSsid()))
{
- 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;
+ 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);
+ }
+ }
}
}
- if (hdr->IsData())
+
+ // Filter frame through all installed plugins
+ for (PluginList::iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
{
- 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="<<hdr->GetAddr3()<<
- ", sa="<<hdr->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());
+ bool drop = !((*i)->Receive(packet, *hdr));
+ if (drop) return; // plugin drops frame
}
- */
+
+ // Forward data up
+ if (hdr->IsData())
+ ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3());
}
} // namespace ns3
--- a/src/devices/mesh/mesh-wifi-interface-mac.h Wed Mar 18 16:08:49 2009 +0300
+++ b/src/devices/mesh/mesh-wifi-interface-mac.h Wed Mar 18 17:40:38 2009 +0300
@@ -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 @@
///\name Plugins
//\{
- // TODO
+ /// Install plugin. TODO return unique ID to allow unregister plugins
+ void InstallPlugin(Ptr<MeshWifiInterfaceMacPlugin> plugin);
//\}
private:
@@ -212,6 +214,10 @@
/// "Timer" for the next beacon
EventId m_beaconSendEvent;
+
+ typedef std::vector< Ptr<MeshWifiInterfaceMacPlugin> > PluginList;
+ /// List of all installed plugins
+ PluginList m_plugins;
};
} // namespace ns3
--- a/src/devices/mesh/wscript Wed Mar 18 16:08:49 2009 +0300
+++ b/src/devices/mesh/wscript Wed Mar 18 17:40:38 2009 +0300
@@ -31,6 +31,7 @@
'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',