Moved hwmp to dot11s, removed unneded files, removed unneded headers from
wscript
--- a/src/devices/mesh/dot11s/dot11s-helper.cc Wed Mar 25 16:58:24 2009 +0300
+++ b/src/devices/mesh/dot11s/dot11s-helper.cc Wed Mar 25 17:37:51 2009 +0300
@@ -28,7 +28,6 @@
#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 {
namespace dot11s {
--- a/src/devices/mesh/dot11s/dot11s-helper.h Wed Mar 25 16:58:24 2009 +0300
+++ b/src/devices/mesh/dot11s/dot11s-helper.h Wed Mar 25 17:37:51 2009 +0300
@@ -22,7 +22,7 @@
#ifndef _MESHWIFIHELPER_H
#define _MESHWIFIHELPER_H
#include "ns3/wifi-helper.h"
-#include "ns3/peer-manager-protocol.h"
+#include "ns3/peer-management-protocol.h"
namespace ns3 {
namespace dot11s {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp-rtable.cc Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,282 @@
+/* -*- 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
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "ns3/object.h"
+#include "ns3/assert.h"
+#include "ns3/simulator.h"
+#include "ns3/ptr.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/hwmp-rtable.h"
+
+NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
+
+TypeId
+HwmpRtable::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::HwmpRtable")
+ .SetParent<Object> ()
+ .AddConstructor<HwmpRtable> ();
+ return tid;
+
+}
+
+HwmpRtable::HwmpRtable ()
+{
+}
+
+HwmpRtable::~HwmpRtable ()
+{
+ DoDispose ();
+}
+
+void
+HwmpRtable::DoDispose ()
+{
+ NS_LOG_UNCOND ("RTABLE DISPOSE STARTED");
+ m_routes.clear ();
+ m_roots.clear ();
+}
+
+void
+HwmpRtable::AddReactivePath (
+ Mac48Address destination,
+ Mac48Address retransmitter,
+ uint32_t port,
+ uint32_t metric,
+ Time lifetime,
+ uint32_t seqnum
+)
+{
+ std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+ if (i == m_routes.end ())
+ {
+ ReactiveRoute newroute;
+ m_routes[destination] = newroute;
+ }
+ else
+ {
+ /**
+ * if outport differs from stored, routing info is
+ * actual and metric is worse - we ignore this
+ * information
+ */
+ if (
+ (i->second.port != port) &&
+ (i->second.metric < metric) &&
+ /**
+ * The routing info is actual or it
+ * was received from peer
+ */
+ ((i->second.whenExpire > Simulator::Now ())||(i->second.whenExpire == Seconds(0)))
+ )
+ return;
+ }
+ i = m_routes.find (destination);
+ NS_ASSERT (i != m_routes.end());
+ i->second.retransmitter = retransmitter;
+ i->second.port = port;
+ i->second.metric = metric;
+ if (lifetime != Seconds (0))
+ i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+ else
+ /**
+ * Information about peer does not have lifetime
+ */
+ i->second.whenExpire = Seconds (0);
+ i->second.seqnum = seqnum;
+}
+
+void
+HwmpRtable::AddProactivePath (
+ uint32_t metric,
+ Mac48Address root,
+ Mac48Address retransmitter,
+ uint32_t port,
+ Time lifetime,
+ uint32_t seqnum
+)
+{
+ ProactiveRoute newroute;
+ m_roots[port] = newroute;
+ std::map<uint32_t,ProactiveRoute>::iterator i = m_roots.find (port);
+ NS_ASSERT (i != m_roots.end());
+ i->second.root = root;
+ i->second.retransmitter = retransmitter;
+ i->second.metric = metric;
+ i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
+ i->second.seqnum = seqnum;
+
+}
+
+void
+HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t port, Mac48Address precursor)
+{
+ bool should_add = true;
+ std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+ if ((i != m_routes.end ()) && (i->second.port == port))
+ {
+ for (unsigned int j = 0 ; j < i->second.precursors.size (); j ++)
+ if (i->second.precursors[j] == precursor)
+ {
+ should_add = false;
+ break;
+ }
+ if (should_add)
+ i->second.precursors.push_back (precursor);
+ }
+ std::map<uint32_t,ProactiveRoute>::iterator k = m_roots.find (port);
+ if (k != m_roots.end ())
+ {
+ for (unsigned int j = 0 ; j < k->second.precursors.size (); j ++)
+ if (k->second.precursors[j] == precursor)
+ return;
+ k->second.precursors.push_back (precursor);
+ return;
+ }
+}
+
+void
+HwmpRtable::DeleteProactivePath (uint32_t port)
+{
+ std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
+ if (j != m_roots.end ())
+ m_roots.erase (j);
+
+}
+void
+HwmpRtable::DeleteProactivePath (Mac48Address root, uint32_t port)
+{
+ std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
+ if ((j != m_roots.end ())&&(j->second.root == root))
+ m_roots.erase (j);
+
+}
+
+void
+HwmpRtable::DeleteReactivePath (Mac48Address destination, uint32_t port)
+{
+ std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+ if (i != m_routes.end ())
+ if (i->second.port == port)
+ m_routes.erase (i);
+}
+
+HwmpRtable::LookupResult
+HwmpRtable::LookupReactive (Mac48Address destination)
+{
+ LookupResult result;
+ result.retransmitter = Mac48Address::GetBroadcast ();
+ result.metric = MAX_METRIC;
+ result.ifIndex = PORT_ANY;
+
+ std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+ if (i == m_routes.end ())
+ return result;
+ result.ifIndex = i->second.port;
+ //Seconds (0) means that this is routing
+ if (i->second.whenExpire < Simulator::Now ())
+ if (i->second.retransmitter != destination)
+ return result;
+ result.retransmitter = i->second.retransmitter;
+ result.metric = i->second.metric;
+ result.seqnum = i->second.seqnum;
+ return result;
+}
+
+HwmpRtable::LookupResult
+HwmpRtable::LookupProactive (uint32_t port)
+{
+ LookupResult result;
+ result.retransmitter = Mac48Address::GetBroadcast ();
+ result.metric = MAX_METRIC;
+ result.ifIndex = PORT_ANY;
+ std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
+ if (i == m_roots.end ())
+ return result;
+ result.ifIndex = i->first;
+ if (i->second.whenExpire < Simulator::Now ())
+ return result;
+ result.retransmitter = i->second.retransmitter;
+ result.metric = i->second.metric;
+ result.seqnum = i->second.seqnum;
+ return result;
+}
+
+std::vector<HwmpRtable::FailedDestination>
+HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress, uint32_t port)
+{
+ std::vector<FailedDestination> retval;
+ for (std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.begin (); i != m_routes.end(); i++)
+ if ((i->second.retransmitter == peerAddress)&& (i->second.port == port))
+ {
+ FailedDestination dst;
+ dst.destination = i->first;
+ i->second.seqnum ++;
+ dst.seqnum = i->second.seqnum;
+ retval.push_back (dst);
+ }
+ /**
+ * Lookup a path to root
+ */
+ std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
+ if ((i != m_roots.end ())&&(i->second.retransmitter == peerAddress))
+ {
+ FailedDestination dst;
+ dst.destination = i->second.root;
+ dst.seqnum = i->second.seqnum;
+ retval.push_back (dst);
+ }
+ return retval;
+}
+uint32_t
+HwmpRtable::RequestSeqnum (Mac48Address destination)
+{
+ std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
+ if (i == m_routes.end ())
+ return 0;
+ return i->second.seqnum;
+}
+
+std::vector<Mac48Address>
+HwmpRtable::GetPrecursors (Mac48Address destination, uint32_t port)
+{
+ std::vector<Mac48Address> retval;
+ std::map<uint32_t, ProactiveRoute>::iterator root = m_roots.find (port);
+ if ((root != m_roots.end ()) &&(root->second.root == destination))
+ {
+ for (unsigned int i = 0; i < root->second.precursors.size (); i ++)
+ retval.push_back (root->second.precursors[i]);
+ }
+ std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
+ if ( (route != m_routes.end ()) && (route->second.port == port) )
+ {
+ for (unsigned int i = 0; i < route->second.precursors.size (); i ++)
+ retval.push_back (route->second.precursors[i]);
+ }
+ return retval;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp-rtable.h Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,107 @@
+/* -*- 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
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef HWMP_RTABLE_H
+#define HWMP_RTABLE_H
+
+#include <list>
+#include <map>
+#include "ns3/nstime.h"
+#include "ns3/mac48-address.h"
+#include "ns3/net-device.h"
+#include "ns3/event-id.h"
+#include "ns3/packet.h"
+namespace ns3 {
+
+/**
+ * \ingroup mesh
+ */
+class HwmpRtable : public Object
+{
+public:
+ static TypeId GetTypeId ();
+ HwmpRtable ();
+ ~HwmpRtable ();
+ void DoDispose ();
+ void AddReactivePath (
+ Mac48Address destination,
+ Mac48Address retransmitter,
+ uint32_t port,
+ uint32_t metric,
+ Time lifetime,
+ uint32_t seqnum
+ );
+ void AddProactivePath (
+ uint32_t metric,
+ Mac48Address root,
+ Mac48Address retransmitter,
+ uint32_t port,
+ Time lifetime,
+ uint32_t seqnum
+ );
+ void AddPrecursor (Mac48Address destination, uint32_t port, Mac48Address precursor);
+ void DeleteProactivePath (uint32_t port);
+ void DeleteProactivePath (Mac48Address root, uint32_t port);
+ void DeleteReactivePath (Mac48Address destination, uint32_t port);
+ struct LookupResult
+ {
+ Mac48Address retransmitter;
+ uint32_t ifIndex;
+ uint32_t metric;
+ uint32_t seqnum;
+ };
+ LookupResult LookupReactive (Mac48Address destination);
+ LookupResult LookupProactive (uint32_t port);
+ //path error routines:
+ struct FailedDestination
+ {
+ Mac48Address destination;
+ uint32_t seqnum;
+ };
+ std::vector<FailedDestination> GetUnreachableDestinations (Mac48Address peerAddress, uint32_t port);
+ uint32_t RequestSeqnum (Mac48Address dst);
+ std::vector<Mac48Address> GetPrecursors (Mac48Address destination, uint32_t port);
+ const static uint32_t PORT_ANY = 0xffffffff;
+ const static uint32_t MAX_METRIC = 0xffffffff;
+private:
+ struct ReactiveRoute
+ {
+ Mac48Address retransmitter;
+ uint32_t port;
+ uint32_t metric;
+ Time whenExpire;
+ uint32_t seqnum;
+ std::vector<Mac48Address> precursors;
+ };
+ struct ProactiveRoute
+ {
+ Mac48Address root;
+ Mac48Address retransmitter;
+ uint32_t metric;
+ Time whenExpire;
+ uint32_t seqnum;
+ std::vector<Mac48Address> precursors;
+ };
+ std::map<Mac48Address, ReactiveRoute> m_routes;
+ std::map<uint32_t, ProactiveRoute> m_roots;
+};
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp-state.cc Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,539 @@
+/* -*- 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
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#include "ns3/hwmp-state.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("HwmpState");
+TypeId
+HwmpState::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::HwmpState")
+ .SetParent<Object> ()
+ .AddConstructor<HwmpState> ()
+ ;
+ return tid;
+}
+
+HwmpState::HwmpState ():
+ m_myPreq (m_preqQueue.end()),
+ m_preqId (1),
+ m_myDsn (1),
+ m_disabled (false),
+ m_maxTtl (10)
+{
+}
+void
+HwmpState::SetRequestRouteCallback (
+ Callback<HwmpRtable::LookupResult, const Mac48Address&> cb)
+{
+ m_requestRouteCallback = cb;
+}
+
+void
+HwmpState::SetRequestRootPathCallback (
+ Callback<HwmpRtable::LookupResult, uint32_t> cb)
+{
+ m_requestRootPathCallback = cb;
+}
+
+//Setting MAC
+void
+HwmpState::SetMac (Ptr<MeshWifiMac> mac)
+{
+ mac->SetPeerStatusCallback (MakeCallback(&HwmpState::PeerStatus, this));
+ mac->SetPreqReceivedCallback (MakeCallback(&HwmpState::ReceivePreq, this));
+ mac->SetPrepReceivedCallback (MakeCallback(&HwmpState::ReceivePrep, this));
+ mac->SetPerrReceivedCallback (MakeCallback(&HwmpState::ReceivePerr, this));
+ m_address = mac->GetAddress ();
+ m_preqCallback = MakeCallback (&MeshWifiMac::SendPreq, mac);
+ m_prepCallback = MakeCallback (&MeshWifiMac::SendPrep, mac);
+ m_perrCallback = MakeCallback (&MeshWifiMac::SendPerr, mac);
+}
+HwmpState::~HwmpState ()
+{
+ m_preqQueue.clear ();
+}
+//Interaction with HWMP:
+void
+HwmpState::SetRoutingInfoCallback (
+ Callback<void, INFO> cb
+)
+{
+ m_routingInfoCallback = cb;
+}
+
+void
+HwmpState::SetRetransmittersOfPerrCallback (
+ Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> cb)
+{
+ m_retransmittersOfPerrCallback = cb;
+}
+
+void
+HwmpState::RequestDestination (Mac48Address dst)
+{
+ if (m_preqQueue.end () == m_myPreq)
+ {
+ IeDot11sPreq preq;
+ //fill PREQ:
+ preq.SetHopcount (0);
+ preq.SetTTL (m_maxTtl);
+ preq.SetPreqID (m_preqId++);
+ if (m_preqId == MAX_PREQ_ID)
+ m_preqId = 0;
+ preq.SetLifetime (TIME_TO_TU(dot11sParameters::dot11MeshHWMPactivePathTimeout));
+ preq.SetOriginatorSeqNumber (m_myDsn++);
+ if (m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ preq.SetOriginatorAddress (m_address);
+ preq.AddDestinationAddressElement (false, false, dst, 0); //DO = 0, RF = 0
+ if (m_preqTimer.IsRunning ())
+ {
+ NS_LOG_DEBUG ("No my preq");
+ m_preqQueue.push_back (preq);
+ //set iterator position to my preq:
+ m_myPreq = m_preqQueue.end () -1;
+ }
+ else
+ {
+ NS_LOG_DEBUG ("Send PREQ now, "<<preq.GetPreqID()<<" destinations, now is "<<Simulator::Now());
+ m_preqCallback (preq);
+ NS_ASSERT (!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+ }
+ else
+ {
+ NS_ASSERT (m_myPreq->GetOriginatorAddress() == m_address);
+ NS_LOG_DEBUG ("add a destination "<<dst);
+ m_myPreq->AddDestinationAddressElement (false, false, dst, 0); //DO = 0, RF = 0
+ }
+}
+void
+HwmpState::SendPathError (std::vector<HwmpRtable::FailedDestination> destinations)
+{
+ std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback (destinations, m_ifIndex);
+ NS_LOG_DEBUG ("SendPathError started");
+ if (receivers.size () == 0)
+ return;
+ NS_LOG_DEBUG (m_address<<" Should Send PERR to");
+ for (unsigned int i = 0; i < receivers.size (); i ++)
+ {
+ AddPerrReceiver (receivers[i]);
+ NS_LOG_DEBUG (receivers[i]);
+ }
+ NS_LOG_DEBUG ("To tel about failure with");
+ for (unsigned int i = 0; i < destinations.size (); i ++)
+ {
+ m_myPerr.AddAddressUnit (destinations[i]);
+ NS_LOG_DEBUG (destinations[i].destination);
+ }
+ if (!m_perrTimer.IsRunning ())
+ {
+ m_perrCallback (m_myPerr,m_myPerrReceivers);
+ m_myPerr.ResetPerr ();
+ m_perrTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpState::SendOnePerr,this);
+ }
+}
+//needed to fill routing information structure
+void
+HwmpState::SetAssociatedIfaceId (uint32_t interface)
+{
+ m_ifIndex = interface;
+}
+
+uint32_t
+HwmpState::GetAssociatedIfaceId ()
+{
+ return m_ifIndex;
+}
+
+//Interaction with MAC:
+void
+HwmpState::ReceivePreq (IeDot11sPreq& preq, const Mac48Address& from, const uint32_t& metric)
+{
+ if (m_disabled)
+ return;
+ if (preq.GetOriginatorAddress () == m_address)
+ return;
+ preq.DecrementTtl ();
+ preq.IncrementMetric (metric);
+ if (preq.GetTtl () == 0)
+ return;
+ //acceptance cretirea:
+ std::map<Mac48Address, uint32_t>::iterator i = m_dsnDatabase.find (preq.GetOriginatorAddress());
+ if (i == m_dsnDatabase.end ())
+ {
+ m_dsnDatabase[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber();
+ m_preqMetricDatabase[preq.GetOriginatorAddress ()] = preq.GetMetric();
+ }
+ else
+ {
+ if (i->second > preq.GetOriginatorSeqNumber ())
+ return;
+ if (i->second == preq.GetOriginatorSeqNumber ())
+ {
+ //find metric
+ std::map<Mac48Address, uint32_t>::iterator j =
+ m_preqMetricDatabase.find (preq.GetOriginatorAddress());
+ NS_ASSERT (j != m_dsnDatabase.end());
+ if (j->second <= preq.GetMetric ())
+ return;
+ }
+ m_dsnDatabase[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber();
+ m_preqMetricDatabase[preq.GetOriginatorAddress ()] = preq.GetMetric();
+ }
+ NS_LOG_DEBUG (
+ "PREQ from "<< preq.GetOriginatorAddress ()
+ <<", at "<< m_address
+ <<", TTL ="<< (int)preq.GetTtl ()
+ <<", metric = "<< preq.GetMetric ()
+ <<", hopcount = "<< (int)preq.GetHopCount ()
+ <<", preqId = "<< preq.GetPreqID ()
+ <<", transmitter is "<<from);
+ //fill routingTable
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = preq.GetOriginatorAddress ();
+ newInfo.nextHop = from;
+ newInfo.metric = preq.GetMetric ();
+ newInfo.lifetime = TU_TO_TIME (preq.GetLifetime());
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = preq.GetOriginatorSeqNumber ();
+ newInfo.type = INFO_PREQ;
+ //check if can answer:
+ std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
+ for (std::vector<Ptr<DestinationAddressUnit> >::iterator i = destinations.begin (); i != destinations.end(); i++)
+ {
+ if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast())
+ {
+ //only proactive PREQ contains destination
+ //address as broadcast! Proactive preq MUST
+ //have destination count equal to 1 and
+ //per destination flags DO and RF
+ NS_ASSERT (preq.GetDestCount() == 1);
+ NS_ASSERT (((*i)->IsDo()) && ((*i)->IsRf()));
+ NS_LOG_DEBUG ("PROACTIVE PREQ RECEIVED");
+ newInfo.type = INFO_PROACTIVE;
+ m_routingInfoCallback (newInfo);
+ if (!preq.IsNeedNotPrep ())
+ {
+ SendPrep (
+ preq.GetOriginatorAddress (),
+ m_address,
+ from,
+ preq.GetMetric (),
+ preq.GetOriginatorSeqNumber (),
+ m_myDsn ++,
+ preq.GetLifetime ()
+ );
+ if (m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ }
+ break;
+ }
+ if ((*i)->GetDestinationAddress () == m_address)
+ {
+ preq.DelDestinationAddressElement ((*i)->GetDestinationAddress());
+ SendPrep (
+ preq.GetOriginatorAddress (),
+ m_address,
+ from,
+ 0,
+ preq.GetOriginatorSeqNumber (),
+ m_myDsn++,
+ preq.GetLifetime ()
+ );
+ if (m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ continue;
+ }
+ //check if can answer:
+ HwmpRtable::LookupResult result = m_requestRouteCallback ((*i)->GetDestinationAddress());
+ if ((! ((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
+ {
+ //have a valid information and acn answer
+ if ((*i)->IsRf ())
+ (*i)->SetFlags (true, false); //DO = 1, RF = 0 (as it was)
+ else
+ {
+ //send a PREP and delete destination
+ preq.DelDestinationAddressElement ((*i)->GetDestinationAddress());
+ SendPrep (
+ preq.GetOriginatorAddress (),
+ (*i)->GetDestinationAddress (),
+ result.retransmitter,
+ result.metric,
+ preq.GetOriginatorSeqNumber (),
+ result.seqnum,
+ preq.GetLifetime ()
+ );
+ continue;
+ }
+ }
+ }
+ m_routingInfoCallback (newInfo);
+ //chack if must retransmit:
+ if (preq.GetDestCount () == 0)
+ return;
+ if (m_preqTimer.IsRunning ())
+ {
+ m_preqQueue.push_back (preq);
+ }
+ else
+ {
+ m_preqCallback (preq);
+ NS_ASSERT (!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+}
+
+void
+HwmpState::ReceivePrep (IeDot11sPrep& prep, const Mac48Address& from, const uint32_t& metric)
+{
+ if (m_disabled)
+ return;
+ prep.DecrementTtl ();
+ prep.IncrementMetric (metric);
+ //acceptance cretirea:
+ std::map<Mac48Address, uint32_t>::iterator i = m_dsnDatabase.find (prep.GetDestinationAddress());
+ if (i == m_dsnDatabase.end ())
+ {
+ m_dsnDatabase[prep.GetDestinationAddress ()] = prep.GetDestinationSeqNumber();
+ }
+ else
+ if (i->second > prep.GetDestinationSeqNumber ())
+ return;
+ //update routing info
+ HwmpRtable::LookupResult result = m_requestRouteCallback (prep.GetDestinationAddress());
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ //try to look for default route
+ result = m_requestRootPathCallback (m_ifIndex);
+ if ((result.retransmitter == Mac48Address::GetBroadcast ())&&(m_address != prep.GetDestinationAddress()))
+ return;
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = prep.GetOriginatorAddress ();
+ newInfo.source = prep.GetDestinationAddress ();
+ newInfo.nextHop = from;
+ newInfo.metric = prep.GetMetric ();
+ newInfo.lifetime = TU_TO_TIME (prep.GetLifetime());
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = prep.GetOriginatorSeqNumber ();
+ newInfo.prevHop = result.retransmitter;
+ newInfo.type = INFO_PREP;
+ NS_LOG_DEBUG ("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
+ NS_LOG_DEBUG ("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
+ m_routingInfoCallback (newInfo);
+ if (prep.GetDestinationAddress () == m_address)
+ {
+ NS_LOG_DEBUG ("Destination resolved"<<newInfo.destination);
+ return;
+ }
+ m_prepCallback (prep, result.retransmitter);
+}
+
+void
+HwmpState::ReceivePerr (IeDot11sPerr& perr, const Mac48Address& from)
+{
+ if (m_disabled)
+ return;
+ NS_LOG_DEBUG (m_address<<" RECEIVED PERR from "<<from);
+ /**
+ * Check forwarding conditions:
+ */
+ std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector ();
+ for (unsigned int i = 0; i < destinations.size (); i ++)
+ {
+ /**
+ * Lookup for a valid routing information
+ */
+ HwmpRtable::LookupResult result = m_requestRouteCallback (destinations[i].destination);
+ if (
+ (result.retransmitter != from)
+ || (result.seqnum >= destinations[i].seqnum)
+ )
+
+ perr.DeleteAddressUnit (destinations[i].destination);
+ }
+ NS_LOG_DEBUG ("Retransmit "<<(int)perr.GetNumOfDest());
+ if (perr.GetNumOfDest () == 0)
+ return;
+ destinations = perr.GetAddressUnitVector ();
+ SendPathError (destinations);
+}
+
+void
+HwmpState::PeerStatus (const Mac48Address peerAddress, const bool status, const uint32_t metric)
+{
+ INFO newInfo;
+ newInfo.me = m_address;
+ newInfo.destination = peerAddress;
+ newInfo.nextHop = peerAddress;
+ newInfo.metric = metric;
+ newInfo.outPort = m_ifIndex;
+ newInfo.dsn = 0;
+ if (status)
+ newInfo.type = INFO_NEW_PEER;
+ else
+ newInfo.type = INFO_FAILED_PEER;
+ m_routingInfoCallback (newInfo);
+}
+
+bool
+HwmpState::SetRoot ()
+{
+#if 0
+ //TODO:: delete this lines!!!!!!!
+ if (m_address != Mac48Address ("00:00:00:00:00:10"))
+ return false;
+ //TODO
+#endif
+ Simulator::Schedule (dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
+ return true;
+}
+
+void
+HwmpState::SendProactivePreq ()
+{
+ NS_LOG_DEBUG ("Sending proactive PREQ");
+ IeDot11sPreq preq;
+ //By default: must answer
+ preq.SetHopcount (0);
+ preq.SetTTL (m_maxTtl);
+ preq.SetPreqID (m_preqId++);
+ if (m_preqId == MAX_PREQ_ID)
+ m_preqId = 0;
+ preq.SetLifetime (TIME_TO_TU(dot11sParameters::dot11MeshHWMPpathToRootInterval));
+ preq.SetOriginatorSeqNumber (m_myDsn++);
+ if (m_myDsn == MAX_DSN)
+ m_myDsn = 0;
+ preq.SetOriginatorAddress (m_address);
+ preq.AddDestinationAddressElement (
+ true,
+ true,
+ Mac48Address::GetBroadcast ()
+ ,0);
+ if (m_preqTimer.IsRunning ())
+ m_preqQueue.push_back (preq);
+ else
+ {
+ NS_LOG_DEBUG ("Send now "<<preq.GetPreqID());
+ m_preqCallback (preq);
+ NS_ASSERT (!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+ }
+ Simulator::Schedule (dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
+}
+
+void
+HwmpState::AddPerrReceiver (Mac48Address receiver)
+{
+ /**
+ * add new vector of addresses to m_perrReceiversand check
+ * duplicates
+ */
+ for (unsigned int j = 0; j < m_myPerrReceivers.size (); j++)
+ if (m_myPerrReceivers[j] == receiver)
+ return;
+ m_myPerrReceivers.push_back (receiver);
+}
+
+void
+HwmpState::UnSetRoot ()
+{
+}
+
+void
+HwmpState::Disable ()
+{
+ m_disabled = true;
+}
+
+void
+HwmpState::Enable ()
+{
+ m_disabled = false;
+}
+
+Mac48Address
+HwmpState::GetAddress ()
+{
+ return m_address;
+}
+
+void
+HwmpState::SendOnePreq ()
+{
+ if (m_preqQueue.size () == 0)
+ return;
+ if (m_myPreq == m_preqQueue.begin ())
+ m_myPreq == m_preqQueue.end ();
+ IeDot11sPreq preq = m_preqQueue[0];
+ NS_LOG_DEBUG (
+ "Sending PREQ from "<<preq.GetOriginatorAddress () <<
+ " destinations are "<< (int)preq.GetDestCount()<<
+ ", at "<<Simulator::Now ()<<
+ ", store in queue "<<m_preqQueue.size ()<<
+ " preqs"<<", I am "<<m_address);
+ m_preqCallback (preq);
+ //erase first!
+ m_preqQueue.erase (m_preqQueue.begin());
+ //reschedule sending PREQ
+ NS_ASSERT (!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
+}
+
+void
+HwmpState::SendPrep (Mac48Address dst,
+ Mac48Address src,
+ Mac48Address retransmitter,
+ uint32_t initMetric,
+ uint32_t dsn,
+ uint32_t originatorDsn,
+ uint32_t lifetime)
+{
+ IeDot11sPrep prep;
+ prep.SetHopcount (0);
+ prep.SetTTL (m_maxTtl);
+ prep.SetDestinationAddress (dst);
+ prep.SetDestinationSeqNumber (dsn);
+ prep.SetLifetime (lifetime);
+ prep.SetMetric (0);
+ prep.SetOriginatorAddress (src);
+ prep.SetOriginatorSeqNumber (originatorDsn);
+ m_prepCallback (prep, retransmitter);
+}
+
+void
+HwmpState::SendOnePerr ()
+{
+ if (m_myPerr.GetNumOfDest () == 0)
+ return;
+ m_perrCallback (m_myPerr, m_myPerrReceivers);
+ m_myPerr.ResetPerr ();
+}
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp-state.h Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,179 @@
+/* -*- 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
+ *
+ * Author: Kirill Andreev <andreev@iitp.ru>
+ */
+
+
+#ifndef HWMP_STATE_H
+#define HWMP_STATE_H
+#include <map>
+#include "ns3/hwmp-rtable.h"
+#include "ns3/packet.h"
+#include "ns3/mesh-wifi-mac.h"
+#include "ns3/ie-dot11s-preq.h"
+#include "ns3/ie-dot11s-prep.h"
+#include "ns3/ie-dot11s-perr.h"
+#include "ns3/dot11s-parameters.h"
+#include "ns3/wifi-net-device.h"
+namespace ns3 {
+/**
+ * \ingroup mesh
+ *
+ * \brief Handles HWMP state machine at each real interface
+ *
+ * \details Implements the following:
+ * 1. Keep it's own DSN,
+ * 2. Keep PREQ and PREP timers adn send this frames in
+ * accordance with HWMP-limitations
+ * 3. Deliver routing information to Hwmp main class
+ * 4. Notify about broken peers
+ */
+class HwmpState : public Object {
+public:
+ static TypeId GetTypeId ();
+ HwmpState ();
+ ~HwmpState ();
+
+ /**
+ * \brief Interface with HWMP - Hwmp can only
+ * request address and collect routing
+ * information
+ */
+ void SetRequestRouteCallback (
+ Callback<HwmpRtable::LookupResult, const Mac48Address&> cb);
+ void SetRequestRootPathCallback (
+ Callback<HwmpRtable::LookupResult, uint32_t> cb);
+
+ enum InfoType {
+ INFO_PREQ,
+ INFO_PREP,
+ INFO_PERR,
+ INFO_PROACTIVE,
+ INFO_NEW_PEER,
+ INFO_FAILED_PEER
+ };
+ typedef struct RoutingInfo {
+ Mac48Address me;
+ Mac48Address destination;
+ Mac48Address source;
+ Mac48Address nextHop;
+ Mac48Address prevHop;
+ uint32_t outPort;
+ uint32_t metric;
+ std::vector<Mac48Address> failedDestinations;
+ uint32_t dsn;
+ Time lifetime;
+ enum InfoType type;
+ } INFO;
+ void SetRoutingInfoCallback (
+ Callback<void, INFO> cb
+ );
+ void SetRetransmittersOfPerrCallback (
+ Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> cb);
+ void RequestDestination (Mac48Address dest);
+ void SendPathError (std::vector<HwmpRtable::FailedDestination> destinations);
+ void SetAssociatedIfaceId (uint32_t interface);
+ uint32_t GetAssociatedIfaceId ();
+ //Mac interaction:
+ void SetMac (Ptr<MeshWifiMac> mac);
+ void SetSendPreqCallback (
+ Callback<void, const IeDot11sPreq&> cb);
+ void SetSendPrepCallback (
+ Callback<void, const IeDot11sPrep&> cb);
+ void SetSendPerrCallback (
+ Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > cb);
+ void ReceivePreq (IeDot11sPreq&, const Mac48Address& from, const uint32_t& metric);
+ void ReceivePrep (IeDot11sPrep&, const Mac48Address& from, const uint32_t& metric);
+ void ReceivePerr (IeDot11sPerr&, const Mac48Address& from);
+ void PeerStatus (
+ const Mac48Address peerAddress,
+ const bool status,
+ const uint32_t metric
+ );
+ //Proactive mode routines:
+ bool SetRoot ();
+ void UnSetRoot ();
+ //external handling:
+ void Disable ();
+ void Enable ();
+ //DEBUG purpose:
+ Mac48Address GetAddress ();
+private:
+ static const uint32_t MAX_PREQ_ID = 0xffffffff;
+ static const uint32_t MAX_DSN = 0xffffffff;
+ //information about associated port:
+ Mac48Address m_address;
+ //index when HWMP state is attached
+ uint32_t m_ifIndex;
+ //timers for PREQ and PREP:
+ EventId m_preqTimer;
+ void SendOnePreq ();
+ std::vector<IeDot11sPreq> m_preqQueue;
+ //true means that we can add a destination to
+ //existing PREQ element
+ //False means that we must send
+ EventId m_prepTimer;
+ void SendPrep (
+ Mac48Address dst, //dst is PREQ's originator address
+ Mac48Address src, //src is PREQ's destination address
+ Mac48Address retransmitter,
+ uint32_t initMetric,
+ uint32_t dsn,/* taken form PREQ*/
+ uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
+ uint32_t lifetime //taken from PREQ
+ );
+ std::vector<IeDot11sPreq>::iterator m_myPreq;
+ //HWMP interaction callbacks:
+ Callback<void, INFO> m_routingInfoCallback;
+ Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> m_retransmittersOfPerrCallback;
+ Callback<HwmpRtable::LookupResult, const Mac48Address&> m_requestRouteCallback;
+ Callback<HwmpRtable::LookupResult, uint32_t> m_requestRootPathCallback;
+ //Mac interaction callbacks:
+ Callback<void, const IeDot11sPreq&> m_preqCallback;
+ Callback<void, const IeDot11sPrep&, const Mac48Address&> m_prepCallback;
+ Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > m_perrCallback;
+ //HwmpCounters:
+ uint32_t m_preqId;
+ uint32_t m_myDsn;
+ //Seqno and metric database
+ std::map<Mac48Address, uint32_t> m_dsnDatabase;
+ std::map<Mac48Address, uint32_t> m_preqMetricDatabase;
+ //Disable/enable functionality
+ bool m_disabled;
+ //Proactive PREQ mechanism:
+ EventId m_proactivePreqTimer;
+ void SendProactivePreq ();
+ /**
+ * \brief Two PERRs may not be sent closer to
+ * each other than
+ * dot11MeshHWMPperrMinInterval, so, each HWMP
+ * state collects all unreachable destinations
+ * and once in dot11MeshHWMPperrMinInterval
+ * should send PERR, and PERR element should
+ * be cleared
+ */
+ IeDot11sPerr m_myPerr;
+ std::vector<Mac48Address> m_myPerrReceivers;
+ void AddPerrReceiver (Mac48Address receiver);
+ EventId m_perrTimer;
+ void SendOnePerr ();
+ //Configurable parameters:
+ uint8_t m_maxTtl;
+};
+} //namespace ns3
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp.cc Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,696 @@
+/* -*- 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>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+
+#include "ns3/hwmp.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/mesh-point-device.h"
+
+NS_LOG_COMPONENT_DEFINE ("Hwmp");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Hwmp);
+NS_OBJECT_ENSURE_REGISTERED (HwmpTag);
+//Class HwmpTag:
+HwmpTag::HwmpTag ()
+{
+}
+
+HwmpTag::~HwmpTag ()
+{
+}
+
+void
+HwmpTag::SetAddress (Mac48Address retransmitter)
+{
+ m_address = retransmitter;
+}
+
+Mac48Address
+HwmpTag::GetAddress ()
+{
+ return m_address;
+}
+
+void
+HwmpTag::SetTtl (uint8_t ttl)
+{
+ m_ttl = ttl;
+}
+
+uint8_t
+HwmpTag::GetTtl ()
+{
+ return m_ttl;
+}
+
+void
+HwmpTag::SetMetric (uint32_t metric)
+{
+ m_metric = metric;
+}
+
+uint32_t
+HwmpTag::GetMetric ()
+{
+ return m_metric;
+}
+
+void
+HwmpTag::SetSeqno (uint32_t seqno)
+{
+ m_seqno = seqno;
+}
+
+uint32_t
+HwmpTag::GetSeqno ()
+{
+ return m_seqno;
+}
+
+TypeId
+HwmpTag::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::HwmpTag")
+ .SetParent<Tag> ()
+ .AddConstructor<HwmpTag> ()
+ ;
+ return tid;
+}
+
+TypeId
+HwmpTag::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+HwmpTag::GetSerializedSize () const
+{
+ return 6 //address
+ +1 //ttl
+ +4; //metric
+}
+
+void
+HwmpTag::Serialize (TagBuffer i) const
+{
+ uint8_t address[6];
+ int j;
+ m_address.CopyTo (address);
+ i.WriteU8 (m_ttl);
+ i.WriteU32 (m_metric);
+ for (j = 0; j < 6; j ++)
+ i.WriteU8 (address[j]);
+}
+
+void
+HwmpTag::Deserialize (TagBuffer i)
+{
+ uint8_t address[6];
+ int j;
+ m_ttl = i.ReadU8 ();
+ m_metric = i.ReadU32 ();
+ for (j = 0; j < 6; j ++)
+ address[j] = i.ReadU8 ();
+ m_address.CopyFrom (address);
+}
+
+void
+HwmpTag::Print (std::ostream &os) const
+{
+ os << "address=" << m_address;
+ os << "ttl=" << m_ttl;
+ os << "metrc=" << m_metric;
+}
+void
+HwmpTag::DecrementTtl ()
+{
+ m_ttl --;
+}
+//Class HWMP:
+TypeId
+Hwmp::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Hwmp")
+ .SetParent<MeshL2RoutingProtocol> ()
+ .AddConstructor<Hwmp> ();
+ return tid;
+}
+Hwmp::Hwmp ():
+ m_rtable (CreateObject<HwmpRtable> ()),
+ m_maxTtl (32),
+ m_broadcastPerr (false)
+{
+}
+
+Hwmp::~Hwmp ()
+{
+}
+
+void
+Hwmp::DoDispose ()
+{
+ for (std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.begin (); i != m_timeoutDatabase.end(); i ++)
+ i->second.Cancel ();
+ m_timeoutDatabase.clear ();
+ m_seqnoDatabase.clear ();
+ m_rtable = 0;
+
+ /**
+ * clear routing queue:
+ */
+ for (
+ std::map<Mac48Address, std::queue<QueuedPacket> >::iterator i = m_rqueue.begin ();
+ i != m_rqueue.end ();
+ i++
+ )
+ {
+ while (1)
+ {
+ if (i->second.empty ())
+ break;
+ i->second.pop ();
+ }
+ }
+ m_rqueue.clear ();
+ /**
+ * clear HWMP states
+ */
+ for (unsigned int i = 0; i < m_hwmpStates.size (); i ++)
+ m_hwmpStates[i] = 0;
+ m_hwmpStates.clear ();
+}
+
+bool
+Hwmp::RequestRoute (
+ uint32_t sourceIface,
+ const Mac48Address source,
+ const Mac48Address destination,
+ Ptr<Packet> packet,
+ uint16_t protocolType, //ethrnet 'Protocol' field
+ MeshL2RoutingProtocol::RouteReplyCallback routeReply
+)
+{
+ HwmpRtable::LookupResult result;
+ HwmpTag tag;
+ if (sourceIface == GetMeshPoint ()->GetIfIndex())
+ // packet from level 3
+ {
+ if (destination == Mac48Address::GetBroadcast ())
+ {
+ //set seqno!
+ tag.SetSeqno (m_seqno++);
+ if (m_seqno == MAX_SEQNO)
+ m_seqno = 0;
+ }
+ tag.SetTtl (m_maxTtl);
+ }
+ else
+ // packet from own interface
+ {
+ NS_ASSERT (packet->FindFirstMatchingTag(tag));
+ //check seqno!
+ if (destination == Mac48Address::GetBroadcast ())
+ {
+ std::map<Mac48Address, uint32_t>::iterator i = m_seqnoDatabase.find (source);
+ if (i == m_seqnoDatabase.end ())
+ m_seqnoDatabase[source] = tag.GetSeqno ();
+ else
+ {
+ if (i->second >= tag.GetSeqno ())
+ return false;
+ m_seqnoDatabase[source] = tag.GetSeqno ();
+ }
+ }
+ }
+ tag.SetAddress (Mac48Address::GetBroadcast());
+ if (tag.GetTtl () == 0)
+ return false;
+ tag.DecrementTtl ();
+ if (destination == Mac48Address::GetBroadcast ())
+ {
+ //add RA tag RA = broadcast
+ packet->RemoveAllTags ();
+ packet->AddTag (tag);
+ routeReply (
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ HwmpRtable::PORT_ANY
+ );
+ return true;
+ }
+ result = m_rtable->LookupReactive (destination);
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ //no actual route exists, queue packet and start route
+ //discover procedure
+ if (sourceIface != GetMeshPoint ()->GetIfIndex())
+ {
+ //Start path error procedure:
+ NS_LOG_DEBUG ("Must Send PERR");
+ std::vector<HwmpRtable::FailedDestination> destinations;
+ HwmpRtable::FailedDestination dst;
+ dst.seqnum = m_rtable->RequestSeqnum (destination);
+ dst.destination = destination;
+ destinations.push_back (dst);
+ StartPathErrorProcedure (destinations, result.ifIndex);
+ }
+ MeshL2RoutingProtocol::QueuedPacket pkt;
+ packet->RemoveAllTags ();
+ packet->AddTag (tag);
+ pkt.pkt = packet;
+ pkt.dst = destination;
+ pkt.src = source;
+ pkt.protocol = protocolType;
+ pkt.reply = routeReply;
+ pkt.inPort = sourceIface;
+ QueuePacket (pkt);
+ for (unsigned int i = 0; i< m_requestCallback.size (); i++)
+ {
+ if ((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
+ {
+ if (ShouldSendPreq (destination))
+ m_requestCallback[i] (destination);
+ }
+ else
+ {
+ NS_ASSERT (false);
+ //PROACTIVE mode
+ //lookup a default route
+ result = m_rtable->LookupProactive (m_hwmpStates[i]->GetAssociatedIfaceId());
+ if (result.retransmitter == Mac48Address::GetBroadcast ())
+ {
+ m_rtable->DeleteProactivePath (m_hwmpStates[i]->GetAssociatedIfaceId());
+ m_modes[i] = REACTIVE;
+ if (ShouldSendPreq (destination))
+ m_requestCallback[i] (destination);
+ continue;
+ }
+ tag.SetAddress (result.retransmitter);
+ packet->RemoveAllTags ();
+ packet->AddTag (tag);
+ routeReply (
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ result.ifIndex
+ );
+ }
+ }
+ for (unsigned int i = 0; i< m_requestCallback.size (); i++)
+ {
+ m_requestCallback[i] (Mac48Address("00:00:00:00:00:19"));
+ }
+ }
+ else
+ {
+ tag.SetAddress (result.retransmitter);
+ packet->RemoveAllTags ();
+ packet->AddTag (tag);
+ routeReply (
+ true,
+ packet,
+ source,
+ destination,
+ protocolType,
+ result.ifIndex
+ );
+ }
+ return true;
+}
+bool
+Hwmp::AttachPorts (std::vector<Ptr<NetDevice> > ports)
+{
+ for (std::vector<Ptr<NetDevice> >::iterator i = ports.begin (); i != ports.end(); i++)
+ {
+ //Checking netdevice:
+ const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
+ if (wifiNetDev == NULL)
+ return false;
+ MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer (wifiNetDev->GetMac ()));
+ if (meshWifiMac == NULL)
+ return false;
+ //Adding HWMP-state
+ Ptr<HwmpState> hwmpState = CreateObject<HwmpState> ();
+ hwmpState->SetRoutingInfoCallback (MakeCallback(&Hwmp::ObtainRoutingInformation, this));
+ hwmpState->SetMac (meshWifiMac);
+ hwmpState->SetRequestRouteCallback (MakeCallback(&Hwmp::RequestRouteForAddress, this));
+ hwmpState->SetRequestRootPathCallback (MakeCallback(&Hwmp::RequestRootPathForPort, this));
+ hwmpState->SetAssociatedIfaceId (wifiNetDev->GetIfIndex());
+ hwmpState->SetRetransmittersOfPerrCallback (MakeCallback(&Hwmp::GetRetransmittersForFailedDestinations,this));
+ m_hwmpStates.push_back (hwmpState);
+ m_requestCallback.push_back (MakeCallback(&HwmpState::RequestDestination, hwmpState));
+ m_pathErrorCallback.push_back (MakeCallback(&HwmpState::SendPathError, hwmpState));
+ //Default mode is reactive, default state is enabled
+ enum DeviceState state = ENABLED;
+ enum DeviceMode mode = REACTIVE;
+ m_states.push_back (state);
+ m_modes.push_back (mode);
+ }
+ return true;
+}
+
+void
+Hwmp::DisablePort (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if ((*i)->GetAssociatedIfaceId () == port)
+ {
+ m_states[position] = DISABLED;
+ m_hwmpStates[position]->Disable ();
+ return;
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::EnablePort (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if ((*i)->GetAssociatedIfaceId () == port)
+ {
+ m_states[position] = ENABLED;
+ m_hwmpStates[position]->Enable ();
+ return;
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::SetRoot (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if (((*i)->GetAssociatedIfaceId () == port)||(port == HwmpRtable::PORT_ANY))
+ {
+ if (m_hwmpStates[position]->SetRoot ())
+ {
+ m_modes[position] = ROOT;
+ NS_LOG_DEBUG ("I am proactive");
+ }
+ }
+ position ++;
+ }
+}
+void
+Hwmp::SetProactive (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if ((*i)->GetAssociatedIfaceId () == port)
+ {
+ m_modes[position] = PROACTIVE;
+ return;
+ }
+ position ++;
+ }
+}
+bool
+Hwmp::IsRoot (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if ((*i)->GetAssociatedIfaceId () == port)
+ if (m_modes[position] == ROOT)
+ return true;
+ position ++;
+ }
+ return false;
+}
+void
+Hwmp::UnSetRoot (uint32_t port)
+{
+ int position = 0;
+ for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
+ {
+ if (((*i)->GetAssociatedIfaceId () == port)||(port == HwmpRtable::PORT_ANY))
+ {
+ m_modes[position] = REACTIVE;
+ m_hwmpStates[position]->UnSetRoot ();
+ }
+ position ++;
+ }
+}
+
+void
+Hwmp::ObtainRoutingInformation (
+ HwmpState::INFO info
+)
+{
+ switch (info.type)
+ {
+ case HwmpState::INFO_PREP:
+ if (info.me != info.source)
+ {
+ m_rtable->AddPrecursor (info.source, info.outPort, info.nextHop);
+ m_rtable->AddPrecursor (info.destination, info.outPort, info.prevHop);
+ NS_LOG_DEBUG ("path to "<<info.source<<" precursor is "<<info.nextHop);
+ NS_LOG_DEBUG ("path to "<<info.destination<<" precursor is "<<info.prevHop);
+ }
+ case HwmpState::INFO_PREQ:
+ m_rtable->AddReactivePath (
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.metric,
+ info.lifetime,
+ info.dsn);
+ SendAllPossiblePackets (info.destination);
+ break;
+ case HwmpState::INFO_PERR:
+ //delete first subentry
+ case HwmpState::INFO_PROACTIVE:
+ //add information to the root MP.
+ m_rtable->AddProactivePath (
+ info.metric,
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.lifetime,
+ info.dsn);
+ //Set mode as PROACTIVE:
+ SetProactive (info.outPort);
+ break;
+ case HwmpState::INFO_NEW_PEER:
+#if 0
+ m_rtable->AddReactivePath (
+ info.destination,
+ info.nextHop,
+ info.outPort,
+ info.metric,
+ Seconds (0),
+ 0);
+#endif
+ break;
+ case HwmpState::INFO_FAILED_PEER:
+ /**
+ * Conditions for generating PERR
+ */
+ {
+ NS_LOG_DEBUG ("Failed peer"<<info.destination);
+ std::vector<HwmpRtable::FailedDestination> failedDestinations =
+ m_rtable->GetUnreachableDestinations (info.destination, info.outPort);
+ /**
+ * Entry about peer does not contain seqnum
+ */
+ HwmpRtable::FailedDestination peer;
+ peer.destination = info.destination;
+ peer.seqnum = 0;
+ failedDestinations.push_back (peer);
+ StartPathErrorProcedure (failedDestinations, info.outPort);
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+HwmpRtable::LookupResult
+Hwmp::RequestRouteForAddress (const Mac48Address& dst)
+{
+ return m_rtable->LookupReactive (dst);
+}
+
+HwmpRtable::LookupResult
+Hwmp::RequestRootPathForPort (uint32_t port)
+{
+ return m_rtable->LookupProactive (port);
+}
+
+void
+Hwmp::StartPathErrorProcedure (std::vector<HwmpRtable::FailedDestination> destinations, uint32_t port)
+{
+ NS_LOG_DEBUG ("START PERR");
+ for (unsigned int i = 0; i < m_hwmpStates.size (); i++)
+ if (m_hwmpStates[i]->GetAssociatedIfaceId () == port)
+ m_pathErrorCallback[i] (destinations);
+}
+std::vector<Mac48Address>
+Hwmp::GetRetransmittersForFailedDestinations (std::vector<HwmpRtable::FailedDestination> failedDest, uint32_t port)
+{
+ std::vector<Mac48Address> retransmitters;
+ if (m_broadcastPerr)
+ retransmitters.push_back (Mac48Address::GetBroadcast());
+ else
+ for (unsigned int i = 0; i < failedDest.size (); i ++)
+ {
+ std::vector<Mac48Address> precursors =
+ m_rtable->GetPrecursors (failedDest[i].destination, port);
+ for (unsigned int j = 0; j < precursors.size (); j++)
+ {
+ for (unsigned int k = 0; k < retransmitters.size (); k ++)
+ if (retransmitters[k] == precursors[j])
+ break;
+ retransmitters.push_back (precursors[j]);
+ }
+ }
+ for (unsigned int i = 0; i < failedDest.size (); i ++)
+ {
+ m_rtable->DeleteReactivePath (failedDest[i].destination, port);
+ m_rtable->DeleteProactivePath (failedDest[i].destination, port);
+ }
+ return retransmitters;
+}
+void
+Hwmp::SetMaxQueueSize (int maxPacketsPerDestination)
+{
+ m_maxQueueSize = maxPacketsPerDestination;
+}
+
+bool
+Hwmp::QueuePacket (MeshL2RoutingProtocol::QueuedPacket packet)
+{
+ if ((int)m_rqueue[packet.dst].size () > m_maxQueueSize)
+ return false;
+ m_rqueue[packet.dst].push (packet);
+ return true;
+}
+
+MeshL2RoutingProtocol::QueuedPacket
+Hwmp::DequeuePacket (Mac48Address dst)
+{
+ MeshL2RoutingProtocol::QueuedPacket retval;
+ retval.pkt = NULL;
+ //Ptr<Packet> in this structure is NULL when queue is empty
+ std::map<Mac48Address, std::queue<QueuedPacket> >:: iterator i = m_rqueue.find (dst);
+ if (i == m_rqueue.end ())
+ return retval;
+ if ((int)m_rqueue[dst].size () == 0)
+ return retval;
+ if ((int)i->second.size () == 0)
+ {
+ m_rqueue.erase (i);
+ return retval;
+ }
+ retval = m_rqueue[dst].front ();
+ m_rqueue[dst].pop ();
+ return retval;
+}
+
+void
+Hwmp::SendAllPossiblePackets (Mac48Address dst)
+{
+ HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
+ MeshL2RoutingProtocol::QueuedPacket packet;
+ while (1)
+
+ {
+ packet = DequeuePacket (dst);
+ if (packet.pkt == NULL)
+ return;
+ //set RA tag for retransmitter:
+ HwmpTag tag;
+ NS_ASSERT (packet.pkt->FindFirstMatchingTag(tag));
+ tag.SetAddress (result.retransmitter);
+ NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast());
+ packet.pkt->RemoveAllTags ();
+ packet.pkt->AddTag (tag);
+ packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
+ }
+}
+
+bool
+Hwmp::ShouldSendPreq (Mac48Address dst)
+{
+ std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
+ if (i == m_timeoutDatabase.end ())
+ {
+ m_timeoutDatabase[dst] = Simulator::Schedule (
+ MilliSeconds (2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
+ &Hwmp::RetryPathDiscovery, this, dst, 0);
+ return true;
+ }
+ return false;
+}
+void
+Hwmp::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
+{
+ HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
+ if (result.retransmitter != Mac48Address::GetBroadcast ())
+ {
+ std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
+ NS_ASSERT (i != m_timeoutDatabase.end());
+ m_timeoutDatabase.erase (i);
+ return;
+ }
+ numOfRetry++;
+ if (numOfRetry > dot11sParameters::dot11MeshHWMPmaxPREQretries)
+ {
+ MeshL2RoutingProtocol::QueuedPacket packet;
+ //purge queue and delete entry from retryDatabase
+ while (1)
+ {
+ packet = DequeuePacket (dst);
+ if (packet.pkt == NULL)
+ break;
+ packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
+ }
+ std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
+ NS_ASSERT (i != m_timeoutDatabase.end());
+ m_timeoutDatabase.erase (i);
+ return;
+ }
+ for (unsigned int i = 0; i < m_requestCallback.size (); i++)
+ if ((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
+ m_requestCallback[i] (dst);
+ m_timeoutDatabase[dst] = Simulator::Schedule (
+ MilliSeconds (2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
+ &Hwmp::RetryPathDiscovery, this, dst, numOfRetry);
+}
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/hwmp.h Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,276 @@
+/* -*- 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>
+ * Pavel Boyko <boyko@iitp.ru>
+ */
+
+
+#ifndef HWMP_H
+#define HWMP_H
+
+#include <map>
+#include <queue>
+#include "ns3/tag.h"
+#include "ns3/object.h"
+#include "ns3/mac48-address.h"
+#include "ns3/mesh-l2-routing-protocol.h"
+#include "ns3/packet.h"
+#include "ns3/hwmp-state.h"
+namespace ns3 {
+class HwmpState;
+/**
+ * \ingroup mesh
+ *
+ * \brief Hwmp tag implements interaction between HWMP
+ * protocol and MeshWifiMac
+ *
+ * \details Hwmp tag keeps the following:
+ * 1. When packet is passed from Hwmp to 11sMAC:
+ * - retransmitter address,
+ * - TTL value,
+ * 2. When packet is passed to Hwmp from 11sMAC:
+ * - lasthop address,
+ * - TTL value,
+ * - metric value (metric of link is recalculated
+ * at each packet, but routing table stores metric
+ * obtained during path discovery procedure)
+ */
+class HwmpTag : public Tag
+{
+public:
+ HwmpTag ();
+ ~HwmpTag ();
+ void SetAddress (Mac48Address retransmitter);
+ Mac48Address GetAddress ();
+ void SetTtl (uint8_t ttl);
+ uint8_t GetTtl ();
+ void SetMetric (uint32_t metric);
+ uint32_t GetMetric ();
+ void SetSeqno (uint32_t seqno);
+ uint32_t GetSeqno ();
+ void DecrementTtl ();
+
+ static TypeId GetTypeId ();
+ virtual TypeId GetInstanceTypeId () const;
+ virtual uint32_t GetSerializedSize () const;
+ virtual void Serialize (TagBuffer i) const;
+ virtual void Deserialize (TagBuffer i);
+ virtual void Print (std::ostream &os) const;
+private:
+ Mac48Address m_address;
+ uint8_t m_ttl;
+ uint32_t m_metric;
+ uint32_t m_seqno;
+};
+/**
+ * \ingroup mesh
+ */
+class Hwmp : public MeshL2RoutingProtocol
+{
+public:
+ static TypeId GetTypeId ();
+ Hwmp ();
+ ~Hwmp ();
+ void DoDispose ();
+ //intheritedfrom L2RoutingProtocol
+ /**
+ * \brief L2Routing protocol base class metod
+ *
+ * \details Route resolving procedure consits
+ * of the following steps:
+ * 1. Find reactive route and send a packet.
+ * 2. Find all ports which are operate in
+ * 'Proactive' mode and find a proper default
+ * routes. and send packet to all proactive
+ * 'ports'.
+ * 3. If there are ports which are operate in
+ * reactive mode - queue packet and start
+ * route reactive path discovery
+ *
+ * \bug Now packet is sent to the 'best root'
+ * rather than to the best root at each port
+ */
+ bool RequestRoute (
+ uint32_t sourceIface,
+ const Mac48Address source,
+ const Mac48Address destination,
+ Ptr<Packet> packet,
+ uint16_t protocolType,
+ MeshL2RoutingProtocol::RouteReplyCallback routeReply
+ );
+ bool AttachPorts (std::vector<Ptr<NetDevice> >);
+ /**
+ * \brief Disables port by index.
+ * \details Needed for external modules like
+ * clusterization.
+ */
+ void DisablePort (uint32_t port);
+ /**
+ * \brief enables port
+ */
+ void EnablePort (uint32_t port);
+ /**
+ * \brief Setting proative mode.
+ * \details To enable proactive mode you must
+ * set a root node. Choosing the route is made
+ * in accordance with the following:
+ * 1. Find 'reactive' route. If route is
+ * found - send a packet using this
+ * information
+ * 2. If there is no reactive route -
+ * find proactive or 'default' route.
+ * \attention Comparsion between proactive and
+ * reactive routes is incorrect, because we
+ * have metric to root MP in te first case and
+ * metric to the destination in the second
+ * case.
+ * \param port is the port where proactive
+ * mode should be activated
+ */
+ void SetRoot (uint32_t port);
+ /**
+ * \brief Disable root functionality at a
+ * given port
+ */
+ void UnSetRoot (uint32_t port);
+ /**
+ * \brief HwmpState retrns to Hwmp class all
+ * routing information obtained from all HWMP
+ * action frames
+ */
+ void ObtainRoutingInformation (
+ HwmpState::INFO info
+ );
+ /**
+ * \brief Hwmp state noyifyes that neighbour
+ * is dissapeared. Hwmp state knows about peer
+ * failure from MAC
+ */
+ void PeerFailure (Mac48Address peerAddress);
+ void SetMaxTtl (uint8_t ttl);
+ uint8_t GetMaxTtl ();
+private:
+ static const uint32_t MAX_SEQNO = 0xffffffff;
+ //candidate queue is implemented inside the
+ //protocol:
+ void SetMaxQueueSize (int maxPacketsPerDestination);
+ int m_maxQueueSize;
+ bool QueuePacket (MeshL2RoutingProtocol::QueuedPacket packet);
+ MeshL2RoutingProtocol::QueuedPacket DequeuePacket (Mac48Address dst);
+ void SendAllPossiblePackets (Mac48Address dst);
+ std::map<Mac48Address, std::queue<QueuedPacket> > m_rqueue;
+ //devices and HWMP states:
+ enum DeviceState {
+ ENABLED,
+ DISABLED
+ };
+ enum DeviceMode {
+ REACTIVE,
+ PROACTIVE,
+ ROOT
+ };
+ std::vector<enum DeviceState> m_states;
+ std::vector<enum DeviceMode> m_modes;
+ std::vector<Ptr<HwmpState> > m_hwmpStates;
+ //Routing table:
+ Ptr<HwmpRtable> m_rtable;
+ //Proactive routines:
+ /**
+ * \brief Set port state as proactive.
+ * \details mode is supposed to be proactive
+ * when proatcive PREQ with a valid
+ * information was received.
+ */
+ void SetProactive (uint32_t port);
+ /**
+ * \brief Checks if the port is root, if true
+ * - no default routes must be used at this
+ * port
+ */
+ bool IsRoot (uint32_t port);
+ /**
+ * \brief Interaction with HwmpState class -
+ * request for starting routing discover
+ * procedure (reactive route discovery!)
+ * \param Mac48Address is destination to be
+ * resolved
+ */
+ std::vector< Callback<void, Mac48Address> > m_requestCallback;
+ /**
+ * \brief Callback that shall be executed when
+ * need to send Path error
+ * \param std::vector<Mac48Address> is the
+ * list of unreachable destinations
+ * \param std::vector<Mac48Address> is
+ * receivers of PERR
+ */
+ std::vector<Callback<void,std::vector<HwmpRtable::FailedDestination> > > m_pathErrorCallback;
+ void StartPathErrorProcedure (
+ std::vector<HwmpRtable::FailedDestination> destinations,
+ uint32_t port);
+ /**
+ * \brief HwmpState need to know where to
+ * retransmit PERR, only HWMP knows how to
+ * retransmit it (broadcast/unicast) and only
+ * HWMP has accessto routing table
+ */
+ std::vector<Mac48Address> GetRetransmittersForFailedDestinations (
+ std::vector<HwmpRtable::FailedDestination> failedDest,
+ uint32_t port);
+ /**
+ * \brief Needed by HwmpState to find routes in case
+ * of intermediate reply and choosing the
+ * better route
+ *
+ */
+ HwmpRtable::LookupResult RequestRouteForAddress (const Mac48Address& destination);
+ HwmpRtable::LookupResult RequestRootPathForPort (uint32_t port);
+
+ /**
+ * \attention mesh seqno is processed at HWMP
+ */
+ uint32_t m_seqno;
+ std::map<Mac48Address, uint32_t/**/> m_seqnoDatabase;
+ //Timers:
+ /**
+ * /brief checks when last preq was initiated, returns
+ * false when retry has not expired
+ */
+ bool ShouldSendPreq (Mac48Address dst);
+ /**
+ * \brief Generates PREQ retry when route is
+ * still unresolved after first PREQ
+ * If number of retries greater than
+ * dot11sParameters::dot11MeshHWMPmaxPREQretries,
+ * we return all packets to upper layers
+ */
+ void RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry);
+ /**
+ * Keeps PREQ retry timers for every
+ * destination
+ */
+ std::map<Mac48Address, EventId> m_timeoutDatabase;
+ /**
+ * Configurable parameters:
+ */
+ uint8_t m_maxTtl;
+ bool m_broadcastPerr;
+};
+} //namespace ns3
+#endif
--- a/src/devices/mesh/dot11s/peer-link-frame.h Wed Mar 25 16:58:24 2009 +0300
+++ b/src/devices/mesh/dot11s/peer-link-frame.h Wed Mar 25 17:37:51 2009 +0300
@@ -23,7 +23,7 @@
#include "ns3/header.h"
#include "ns3/supported-rates.h"
#include "ns3/ssid.h"
-#include "ns3/ie-dot11s-peer-management.h"
+#include "ie-dot11s-peer-management.h"
namespace ns3 {
class MeshWifiInterfaceMac;
namespace dot11s {
--- a/src/devices/mesh/dot11s/peer-link.h Wed Mar 25 16:58:24 2009 +0300
+++ b/src/devices/mesh/dot11s/peer-link.h Wed Mar 25 17:37:51 2009 +0300
@@ -28,7 +28,7 @@
#include "ie-dot11s-beacon-timing.h"
#include "ie-dot11s-peer-management.h"
#include "ie-dot11s-configuration.h"
-#include "peer-manager-plugin.h"
+#include "peer-management-plugin.h"
namespace ns3 {
namespace dot11s {
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/peer-management-plugin.cc Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,237 @@
+/* -*- 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: Kirill Andreev <andreev@iitp.ru>
+ */
+
+#include "ns3/mesh-wifi-interface-mac.h"
+#include "ie-dot11s-configuration.h"
+#include "ie-dot11s-peer-management.h"
+#include "peer-management-plugin.h"
+#include "peer-link-frame.h"
+#include "ns3/mesh-wifi-mac-header.h"
+#include "ns3/simulator.h"
+#include "ns3/wifi-mac-header.h"
+#include "ns3/mesh-wifi-mac-header.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE("PeerManager");
+namespace ns3 {
+namespace dot11s {
+PeerManagerMacPlugin::PeerManagerMacPlugin (uint32_t interface, Ptr<PeerManagerProtocol> protocol)
+{
+ m_ifIndex = interface;
+ m_protocol = protocol;
+}
+
+PeerManagerMacPlugin::~PeerManagerMacPlugin ()
+{
+}
+
+void
+PeerManagerMacPlugin::SetParent (Ptr<MeshWifiInterfaceMac> parent)
+{
+ m_parent = parent;
+}
+
+bool
+PeerManagerMacPlugin::Receive (Ptr<Packet> const_packet, const WifiMacHeader & header)
+{
+ // First of all we copy a packet, because we need to remove some
+ //headers
+ Ptr<Packet> packet = const_packet->Copy();
+ if(header.IsBeacon())
+ {
+ IeBeaconTiming beaconTiming;
+ Ptr<Packet> myBeacon = packet->Copy();
+ MgtBeaconHeader beacon_hdr;
+ myBeacon->RemoveHeader(beacon_hdr);
+ bool meshBeacon = false;
+ if(beaconTiming.FindFirst(myBeacon))
+ meshBeacon = true;
+ m_protocol->UpdatePeerBeaconTiming(
+ m_ifIndex,
+ meshBeacon,
+ beaconTiming,
+ header.GetAddr2(),
+ Simulator::Now(),
+ MicroSeconds(beacon_hdr.GetBeaconIntervalUs())
+ );
+ // Beacon shall not be dropeed. May be needed to another plugins
+ return true;
+ }
+ if(header.IsMultihopAction())
+ {
+ WifiMeshHeader meshHdr;
+ packet->RemoveHeader (meshHdr);
+ WifiMeshMultihopActionHeader multihopHdr;
+ //parse multihop action header:
+ packet->RemoveHeader (multihopHdr);
+ WifiMeshMultihopActionHeader::ACTION_VALUE actionValue = multihopHdr.GetAction ();
+ // If can not handle - just return;
+ if(multihopHdr.GetCategory () != WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT)
+ return true;
+ Mac48Address peerAddress = header.GetAddr2 ();
+ PeerLinkFrameStart::PlinkFrameStartFields fields;
+ {
+ PeerLinkFrameStart peerFrame;
+ packet->RemoveHeader (peerFrame);
+ fields = peerFrame.GetFields();
+ }
+ if (actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)
+ {
+ if(!(m_parent->CheckSupportedRates(fields.rates)))
+ {
+ m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
+ // Broken peer link frame - drop it
+ return false;
+ }
+ if (!fields.meshId.IsEqual(m_parent->GetSsid()))
+ {
+ m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
+ // Broken peer link frame - drop it
+ return true;
+ }
+ }
+ // MeshConfiguration Element - exists in all peer link management
+ // frames except CLOSE
+ IeConfiguration meshConfig;
+ if(fields.subtype != IePeerManagement::PEER_CLOSE)
+ packet->RemoveHeader(meshConfig);
+ IePeerManagement peerElement;
+ packet->RemoveHeader(peerElement);
+ // Check the correspondance betwee action valuse and peer link
+ // management element subtypes:
+ switch (actionValue.peerLink)
+ {
+ case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM:
+ NS_ASSERT(fields.subtype == IePeerManagement::PEER_CONFIRM);
+ break;
+ case WifiMeshMultihopActionHeader::PEER_LINK_OPEN:
+ NS_ASSERT(fields.subtype == IePeerManagement::PEER_OPEN);
+ break;
+ case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE:
+ NS_ASSERT(fields.subtype == IePeerManagement::PEER_CLOSE);
+ break;
+ default:
+ // Protocol can not define which frame is it - pass further
+ return true;
+ }
+ //Deliver Peer link management frame to protocol:
+ m_protocol->ReceivePeerLinkFrame(m_ifIndex, peerAddress, fields.aid, peerElement, meshConfig);
+ // if we can handle a frame - drop it
+ return false;
+ }
+ return true;
+}
+
+bool
+PeerManagerMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const
+{
+ return true;
+}
+
+void
+PeerManagerMacPlugin::UpdateBeacon (MeshWifiBeacon & beacon) const
+{
+ Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
+ beacon.AddInformationElement(beaconTiming);
+}
+
+void
+PeerManagerMacPlugin::SendPeerLinkManagementFrame(
+ Mac48Address peerAddress,
+ uint16_t aid,
+ IePeerManagement peerElement,
+ IeConfiguration meshConfig
+ )
+{
+ //Create a packet:
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (peerElement);
+ if(!peerElement.SubtypeIsClose())
+ packet->AddHeader (meshConfig);
+ PeerLinkFrameStart::PlinkFrameStartFields fields;
+ fields.subtype = peerElement.GetSubtype();
+ fields.aid = aid;
+ fields.rates = m_parent->GetSupportedRates ();
+ fields.meshId = m_parent->GetSsid ();
+ PeerLinkFrameStart plinkFrame;
+ plinkFrame.SetPlinkFrameStart(fields);
+ packet->AddHeader (plinkFrame);
+ //Create an 802.11 frame header:
+ //Send management frame to MAC:
+ WifiMeshMultihopActionHeader multihopHdr;
+ if (peerElement.SubtypeIsOpen ())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN;
+ multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ if (peerElement.SubtypeIsConfirm ())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM;
+ multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ if (peerElement.SubtypeIsClose ())
+ {
+ WifiMeshMultihopActionHeader::ACTION_VALUE action;
+ action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE;
+ multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
+ }
+ packet->AddHeader (multihopHdr);
+ //mesh header:
+ WifiMeshHeader meshHdr;
+ meshHdr.SetMeshTtl (1);
+ meshHdr.SetMeshSeqno (0);
+ packet->AddHeader (meshHdr);
+ //Wifi Mac header:
+ WifiMacHeader hdr;
+ hdr.SetMultihopAction ();
+ hdr.SetAddr1 (peerAddress);
+ hdr.SetAddr2 (m_parent->GetAddress ());
+ hdr.SetAddr3 (m_parent->GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ m_parent->SendManagementFrame(packet, hdr);
+}
+
+Mac48Address
+PeerManagerMacPlugin::GetAddress () const
+{
+ if(m_parent != 0)
+ return m_parent->GetAddress ();
+ else return Mac48Address::Mac48Address();
+}
+std::pair<Time, Time>
+PeerManagerMacPlugin::GetBeaconInfo() const
+{
+ std::pair<Time,Time> retval;
+ retval.first = m_parent->GetTbtt ();
+ retval.second = m_parent->GetBeaconInterval ();
+ return retval;
+}
+void
+PeerManagerMacPlugin::SetBeaconShift(Time shift)
+{
+ m_parent->ShiftTbtt (shift);
+}
+
+} // namespace dot11s
+} //namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/peer-management-plugin.h Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,104 @@
+/* -*- 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: Kirill Andreev <andreev@iitp.ru>
+ */
+
+#ifndef PEER_MANAGER_MAC_PLUGIN_H_
+#define PEER_MANAGER_MAC_PLUGIN_H_
+
+#include "ns3/mesh-wifi-interface-mac-plugin.h"
+#include "peer-management-protocol.h"
+
+namespace ns3 {
+class MeshWifiInterfaceMac;
+namespace dot11s {
+class IeConfiguration;
+class IePeerManagement;
+class PeerManagerProtocol;
+/**
+ * \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
+ * element and mesh configuration element and passes it to main part
+ * of protocol
+ */
+class PeerManagerMacPlugin : public MeshWifiInterfaceMacPlugin
+{
+public:
+ PeerManagerMacPlugin (uint32_t interface, Ptr<PeerManagerProtocol> protocol);
+ ~PeerManagerMacPlugin ();
+ ///\name Inherited from plugin abstract class
+ ///\{
+ void SetParent (Ptr<MeshWifiInterfaceMac> parent);
+ bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
+ bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const;
+ void UpdateBeacon (MeshWifiBeacon & beacon) const;
+ ///\}
+private:
+ friend class PeerManagerProtocol;
+ friend class PeerLink;
+ ///\name BCA functionallity:
+ ///\{
+ ///\brief Fills TBTT and beacon interval. Needed by BCA
+ ///functionallity
+ ///\param first in retval is TBTT
+ ///\param second in retval is beacon interval
+ std::pair<Time, Time> GetBeaconInfo() const;
+ void SetBeaconShift(Time shift);
+ ///\}
+ void SetPeerManagerProtcol(Ptr<PeerManagerProtocol> protocol);
+ void SendPeerLinkManagementFrame(
+ Mac48Address peerAddress,
+ uint16_t aid,
+ IePeerManagement peerElement,
+ IeConfiguration meshConfig
+ );
+ ///\brief DUBUG only - to print established links
+ Mac48Address GetAddress () const;
+private:
+ ///\name Information about MAC and protocol:
+ ///\{
+ Ptr<MeshWifiInterfaceMac> m_parent;
+ uint32_t m_ifIndex;
+ Ptr<PeerManagerProtocol> m_protocol;
+ ///\}
+ ///\name Create peer link management frames:
+ ///\{
+ Ptr<Packet> CreatePeerLinkOpenFrame();
+ Ptr<Packet> CreatePeerLinkConfirmFrame();
+ Ptr<Packet> CreatePeerLinkCloseFrame();
+ ///This structure keeps all fields in peer link management frame,
+ ///which are not subclasses of WifiInformationElement
+ struct PlinkFrameStart {
+ uint8_t subtype;
+ uint16_t aid;
+ SupportedRates rates;
+ uint16_t qos;
+ };
+ /// \name Parses the start of the frame, where there are no
+ /// WifiInformationElements exist
+ PlinkFrameStart ParsePlinkFrame(Ptr<const Packet> packet);
+ ///\}
+};
+
+} // namespace dot11s
+} //namespace ns3
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/peer-management-protocol.cc Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,443 @@
+/* -*- 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-management-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-management-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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/mesh/dot11s/peer-management-protocol.h Wed Mar 25 17:37:51 2009 +0300
@@ -0,0 +1,202 @@
+/* -*- 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 DOT11S_PEER_MAN_H
+#define DOT11S_PEER_MAN_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/event-id.h"
+#include "ie-dot11s-peer-management.h"
+#include "ie-dot11s-beacon-timing.h"
+#include "ie-dot11s-configuration.h"
+
+#include <list>
+#include <map>
+namespace ns3 {
+namespace dot11s {
+class PeerManagerMacPlugin;
+class PeerLink;
+/**
+ * \ingroup dot11s
+ *
+ * \brief 802.11s Peer Management Protocol model
+ */
+class PeerManagerProtocol : public Object
+{
+public:
+ PeerManagerProtocol ();
+ ~PeerManagerProtocol ();
+ static TypeId GetTypeId ();
+ bool AttachInterfaces(std::vector<Ptr<WifiNetDevice> >);
+ /** \brief Methods that handle beacon sending/receiving procedure.
+ * This methods interact with MAC_layer plug-in
+ * \{
+ */
+ /**
+ * \brief When we are sending a beacon - we fill beacon timing
+ * element
+ * \param IeBeaconTiming is a beacon timing element that
+ * should be present in beacon
+ * \param interface is a interface sending a beacon
+ */
+ Ptr<IeBeaconTiming> GetBeaconTimingElement(uint32_t interface);
+ /**
+ * \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 interface is a interface on which beacon was received
+ * \param timingElement is a timing element of remote beacon
+ */
+ void UpdatePeerBeaconTiming(
+ uint32_t interface,
+ bool meshBeacon,
+ IeBeaconTiming 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 interface ID of a given MAC (interfaceID rather
+ * than MAC address, beacause many interfaces may have the same MAC)
+ * \param Mac48Address is address of peer
+ * \param uint16_t is association ID, which peer has assigned to
+ * us
+ * \param IeConfiguration is mesh configuration element
+ * taken from the peer management frame
+ * \param IePeerManagement is peer link management element
+ */
+ void ReceivePeerLinkFrame(
+ uint32_t interface,
+ Mac48Address peerAddress,
+ uint16_t aid,
+ IePeerManagement peerManagementElement,
+ IeConfiguration meshConfig
+ );
+ /**
+ * Cancell peer link due to broken configuration (SSID or Supported
+ * rates)
+ */
+ void ConfigurationMismatch (uint32_t interface, Mac48Address peerAddress);
+ /**
+ * Checks if there is established link
+ */
+ bool IsActiveLink (uint32_t interface, Mac48Address peerAddress);
+ ///\}
+ ///\brief Needed by external module to do MLME
+ Ptr<PeerLink> FindPeerLink(uint32_t interface, Mac48Address peerAddress);
+private:
+ ///\name Private structures
+ ///\{
+ ///\brief keeps information about beacon of peer station:
+ /// beacon interval, association ID, last time we have received a
+ /// beacon
+ struct BeaconInfo
+ {
+ uint16_t aid; //Assoc ID
+ Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
+ Time beaconInterval; //Beacon interval of my station;
+ };
+ /// We keep a vector of pointers to PeerLink class. This vector
+ /// keeps all peer links at a given interface.
+ typedef std::vector<Ptr<PeerLink> > PeerLinksOnInterface;
+ /// This map keeps all peer links.
+ ///\param uint32_t is interface ID
+ typedef std::map<uint32_t, PeerLinksOnInterface> PeerLinksMap;
+ ///\brief This map keeps relationship between peer address and its
+ /// beacon information
+ typedef std::map<Mac48Address, BeaconInfo> BeaconsOnInterface;
+ ///\brief This map keeps beacon information on all intefaces
+ typedef std::map<uint32_t, BeaconsOnInterface> BeaconInfoMap;
+ ///\brief this vector keeps pointers to MAC-plugins
+ typedef std::map<uint32_t, Ptr<PeerManagerMacPlugin> > PeerManagerPluginMap;
+ ///\}
+private:
+ /**
+ * Return a position in beacon-storage for a given remote station
+ */
+ void FillBeaconInfo(uint32_t interface, Mac48Address peerAddress, Time receivingTime, Time beaconInterval);
+ Ptr<PeerLink> InitiateLink (uint32_t interface, Mac48Address peerAddress, Time lastBeacon, Time beaconInterval);
+ /**
+ * \name External peer-chooser
+ * \{
+ */
+ bool ShouldSendOpen (uint32_t interface, Mac48Address peerAddress);
+ bool ShouldAcceptOpen (uint32_t interface, Mac48Address peerAddress, dot11sReasonCode & reasonCode);
+ /**
+ * \}
+ * \brief Indicates changes in peer links
+ */
+ void PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, bool status);
+ /**
+ * Removes all links which are idle
+ */
+ void PeerCleanup ();
+ ///\brief BCA
+ Time GetNextBeaconShift (uint32_t interface);
+private:
+ PeerManagerPluginMap m_plugins;
+ /**
+ * \name Information related to beacons:
+ * \{
+ */
+ BeaconInfoMap m_neighbourBeacons;
+ ///\}
+ uint16_t m_lastAssocId;
+ uint16_t m_lastLocalLinkId;
+ uint8_t m_numberOfActivePeers; //number of established peer links
+ uint8_t m_maxNumberOfPeerLinks;
+ /**
+ * Peer Links
+ * \{
+ */
+ PeerLinksMap m_peerLinks;
+ /**
+ * \}
+ */
+ /**
+ * Periodically we scan the peer manager list of peers
+ * and check if the too many beacons were lost:
+ * \{
+ */
+ Time m_peerLinkCleanupPeriod;
+ EventId m_cleanupEvent;
+ /**
+ * \}
+ */
+};
+
+} // namespace dot11s
+} //namespace ns3
+#endif
--- a/src/devices/mesh/dot11s/peer-manager-plugin.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/* -*- 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: Kirill Andreev <andreev@iitp.ru>
- */
-
-#include "ns3/mesh-wifi-interface-mac.h"
-#include "ie-dot11s-configuration.h"
-#include "ie-dot11s-peer-management.h"
-#include "peer-manager-plugin.h"
-#include "peer-link-frame.h"
-#include "ns3/mesh-wifi-mac-header.h"
-#include "ns3/simulator.h"
-#include "ns3/wifi-mac-header.h"
-#include "ns3/mesh-wifi-mac-header.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE("PeerManager");
-namespace ns3 {
-namespace dot11s {
-PeerManagerMacPlugin::PeerManagerMacPlugin (uint32_t interface, Ptr<PeerManagerProtocol> protocol)
-{
- m_ifIndex = interface;
- m_protocol = protocol;
-}
-
-PeerManagerMacPlugin::~PeerManagerMacPlugin ()
-{
-}
-
-void
-PeerManagerMacPlugin::SetParent (Ptr<MeshWifiInterfaceMac> parent)
-{
- m_parent = parent;
-}
-
-bool
-PeerManagerMacPlugin::Receive (Ptr<Packet> const_packet, const WifiMacHeader & header)
-{
- // First of all we copy a packet, because we need to remove some
- //headers
- Ptr<Packet> packet = const_packet->Copy();
- if(header.IsBeacon())
- {
- IeBeaconTiming beaconTiming;
- Ptr<Packet> myBeacon = packet->Copy();
- MgtBeaconHeader beacon_hdr;
- myBeacon->RemoveHeader(beacon_hdr);
- bool meshBeacon = false;
- if(beaconTiming.FindFirst(myBeacon))
- meshBeacon = true;
- m_protocol->UpdatePeerBeaconTiming(
- m_ifIndex,
- meshBeacon,
- beaconTiming,
- header.GetAddr2(),
- Simulator::Now(),
- MicroSeconds(beacon_hdr.GetBeaconIntervalUs())
- );
- // Beacon shall not be dropeed. May be needed to another plugins
- return true;
- }
- if(header.IsMultihopAction())
- {
- WifiMeshHeader meshHdr;
- packet->RemoveHeader (meshHdr);
- WifiMeshMultihopActionHeader multihopHdr;
- //parse multihop action header:
- packet->RemoveHeader (multihopHdr);
- WifiMeshMultihopActionHeader::ACTION_VALUE actionValue = multihopHdr.GetAction ();
- // If can not handle - just return;
- if(multihopHdr.GetCategory () != WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT)
- return true;
- Mac48Address peerAddress = header.GetAddr2 ();
- PeerLinkFrameStart::PlinkFrameStartFields fields;
- {
- PeerLinkFrameStart peerFrame;
- packet->RemoveHeader (peerFrame);
- fields = peerFrame.GetFields();
- }
- if (actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)
- {
- if(!(m_parent->CheckSupportedRates(fields.rates)))
- {
- m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
- // Broken peer link frame - drop it
- return false;
- }
- if (!fields.meshId.IsEqual(m_parent->GetSsid()))
- {
- m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
- // Broken peer link frame - drop it
- return true;
- }
- }
- // MeshConfiguration Element - exists in all peer link management
- // frames except CLOSE
- IeConfiguration meshConfig;
- if(fields.subtype != IePeerManagement::PEER_CLOSE)
- packet->RemoveHeader(meshConfig);
- IePeerManagement peerElement;
- packet->RemoveHeader(peerElement);
- // Check the correspondance betwee action valuse and peer link
- // management element subtypes:
- switch (actionValue.peerLink)
- {
- case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM:
- NS_ASSERT(fields.subtype == IePeerManagement::PEER_CONFIRM);
- break;
- case WifiMeshMultihopActionHeader::PEER_LINK_OPEN:
- NS_ASSERT(fields.subtype == IePeerManagement::PEER_OPEN);
- break;
- case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE:
- NS_ASSERT(fields.subtype == IePeerManagement::PEER_CLOSE);
- break;
- default:
- // Protocol can not define which frame is it - pass further
- return true;
- }
- //Deliver Peer link management frame to protocol:
- m_protocol->ReceivePeerLinkFrame(m_ifIndex, peerAddress, fields.aid, peerElement, meshConfig);
- // if we can handle a frame - drop it
- return false;
- }
- return true;
-}
-
-bool
-PeerManagerMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const
-{
- return true;
-}
-
-void
-PeerManagerMacPlugin::UpdateBeacon (MeshWifiBeacon & beacon) const
-{
- Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
- beacon.AddInformationElement(beaconTiming);
-}
-
-void
-PeerManagerMacPlugin::SendPeerLinkManagementFrame(
- Mac48Address peerAddress,
- uint16_t aid,
- IePeerManagement peerElement,
- IeConfiguration meshConfig
- )
-{
- //Create a packet:
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (peerElement);
- if(!peerElement.SubtypeIsClose())
- packet->AddHeader (meshConfig);
- PeerLinkFrameStart::PlinkFrameStartFields fields;
- fields.subtype = peerElement.GetSubtype();
- fields.aid = aid;
- fields.rates = m_parent->GetSupportedRates ();
- fields.meshId = m_parent->GetSsid ();
- PeerLinkFrameStart plinkFrame;
- plinkFrame.SetPlinkFrameStart(fields);
- packet->AddHeader (plinkFrame);
- //Create an 802.11 frame header:
- //Send management frame to MAC:
- WifiMeshMultihopActionHeader multihopHdr;
- if (peerElement.SubtypeIsOpen ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- if (peerElement.SubtypeIsConfirm ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- if (peerElement.SubtypeIsClose ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- packet->AddHeader (multihopHdr);
- //mesh header:
- WifiMeshHeader meshHdr;
- meshHdr.SetMeshTtl (1);
- meshHdr.SetMeshSeqno (0);
- packet->AddHeader (meshHdr);
- //Wifi Mac header:
- WifiMacHeader hdr;
- hdr.SetMultihopAction ();
- hdr.SetAddr1 (peerAddress);
- hdr.SetAddr2 (m_parent->GetAddress ());
- hdr.SetAddr3 (m_parent->GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- m_parent->SendManagementFrame(packet, hdr);
-}
-
-Mac48Address
-PeerManagerMacPlugin::GetAddress () const
-{
- if(m_parent != 0)
- return m_parent->GetAddress ();
- else return Mac48Address::Mac48Address();
-}
-std::pair<Time, Time>
-PeerManagerMacPlugin::GetBeaconInfo() const
-{
- std::pair<Time,Time> retval;
- retval.first = m_parent->GetTbtt ();
- retval.second = m_parent->GetBeaconInterval ();
- return retval;
-}
-void
-PeerManagerMacPlugin::SetBeaconShift(Time shift)
-{
- m_parent->ShiftTbtt (shift);
-}
-
-} // namespace dot11s
-} //namespace ns3
-
--- a/src/devices/mesh/dot11s/peer-manager-plugin.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/* -*- 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: Kirill Andreev <andreev@iitp.ru>
- */
-
-#ifndef PEER_MANAGER_MAC_PLUGIN_H_
-#define PEER_MANAGER_MAC_PLUGIN_H_
-
-#include "ns3/mesh-wifi-interface-mac-plugin.h"
-#include "peer-manager-protocol.h"
-
-namespace ns3 {
-class MeshWifiInterfaceMac;
-namespace dot11s {
-class IeConfiguration;
-class IePeerManagement;
-class PeerManagerProtocol;
-/**
- * \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
- * element and mesh configuration element and passes it to main part
- * of protocol
- */
-class PeerManagerMacPlugin : public MeshWifiInterfaceMacPlugin
-{
-public:
- PeerManagerMacPlugin (uint32_t interface, Ptr<PeerManagerProtocol> protocol);
- ~PeerManagerMacPlugin ();
- ///\name Inherited from plugin abstract class
- ///\{
- void SetParent (Ptr<MeshWifiInterfaceMac> parent);
- bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
- bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const;
- void UpdateBeacon (MeshWifiBeacon & beacon) const;
- ///\}
-private:
- friend class PeerManagerProtocol;
- friend class PeerLink;
- ///\name BCA functionallity:
- ///\{
- ///\brief Fills TBTT and beacon interval. Needed by BCA
- ///functionallity
- ///\param first in retval is TBTT
- ///\param second in retval is beacon interval
- std::pair<Time, Time> GetBeaconInfo() const;
- void SetBeaconShift(Time shift);
- ///\}
- void SetPeerManagerProtcol(Ptr<PeerManagerProtocol> protocol);
- void SendPeerLinkManagementFrame(
- Mac48Address peerAddress,
- uint16_t aid,
- IePeerManagement peerElement,
- IeConfiguration meshConfig
- );
- ///\brief DUBUG only - to print established links
- Mac48Address GetAddress () const;
-private:
- ///\name Information about MAC and protocol:
- ///\{
- Ptr<MeshWifiInterfaceMac> m_parent;
- uint32_t m_ifIndex;
- Ptr<PeerManagerProtocol> m_protocol;
- ///\}
- ///\name Create peer link management frames:
- ///\{
- Ptr<Packet> CreatePeerLinkOpenFrame();
- Ptr<Packet> CreatePeerLinkConfirmFrame();
- Ptr<Packet> CreatePeerLinkCloseFrame();
- ///This structure keeps all fields in peer link management frame,
- ///which are not subclasses of WifiInformationElement
- struct PlinkFrameStart {
- uint8_t subtype;
- uint16_t aid;
- SupportedRates rates;
- uint16_t qos;
- };
- /// \name Parses the start of the frame, where there are no
- /// WifiInformationElements exist
- PlinkFrameStart ParsePlinkFrame(Ptr<const Packet> packet);
- ///\}
-};
-
-} // namespace dot11s
-} //namespace ns3
-#endif
-
--- 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
-
--- a/src/devices/mesh/dot11s/peer-manager-protocol.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +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>
- */
-
-
-#ifndef DOT11S_PEER_MAN_H
-#define DOT11S_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/ie-dot11s-configuration.h"
-#include "ns3/event-id.h"
-
-#include <list>
-#include <map>
-namespace ns3 {
-namespace dot11s {
-class PeerManagerMacPlugin;
-class PeerLink;
-/**
- * \ingroup dot11s
- *
- * \brief 802.11s Peer Management Protocol model
- */
-class PeerManagerProtocol : public Object
-{
-public:
- PeerManagerProtocol ();
- ~PeerManagerProtocol ();
- static TypeId GetTypeId ();
- bool AttachInterfaces(std::vector<Ptr<WifiNetDevice> >);
- /** \brief Methods that handle beacon sending/receiving procedure.
- * This methods interact with MAC_layer plug-in
- * \{
- */
- /**
- * \brief When we are sending a beacon - we fill beacon timing
- * element
- * \param IeBeaconTiming is a beacon timing element that
- * should be present in beacon
- * \param interface is a interface sending a beacon
- */
- Ptr<IeBeaconTiming> GetBeaconTimingElement(uint32_t interface);
- /**
- * \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 interface is a interface on which beacon was received
- * \param timingElement is a timing element of remote beacon
- */
- void UpdatePeerBeaconTiming(
- uint32_t interface,
- bool meshBeacon,
- IeBeaconTiming 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 interface ID of a given MAC (interfaceID rather
- * than MAC address, beacause many interfaces may have the same MAC)
- * \param Mac48Address is address of peer
- * \param uint16_t is association ID, which peer has assigned to
- * us
- * \param IeConfiguration is mesh configuration element
- * taken from the peer management frame
- * \param IePeerManagement is peer link management element
- */
- void ReceivePeerLinkFrame(
- uint32_t interface,
- Mac48Address peerAddress,
- uint16_t aid,
- IePeerManagement peerManagementElement,
- IeConfiguration meshConfig
- );
- /**
- * Cancell peer link due to broken configuration (SSID or Supported
- * rates)
- */
- void ConfigurationMismatch (uint32_t interface, Mac48Address peerAddress);
- /**
- * Checks if there is established link
- */
- bool IsActiveLink (uint32_t interface, Mac48Address peerAddress);
- ///\}
- ///\brief Needed by external module to do MLME
- Ptr<PeerLink> FindPeerLink(uint32_t interface, Mac48Address peerAddress);
-private:
- ///\name Private structures
- ///\{
- ///\brief keeps information about beacon of peer station:
- /// beacon interval, association ID, last time we have received a
- /// beacon
- struct BeaconInfo
- {
- uint16_t aid; //Assoc ID
- Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
- Time beaconInterval; //Beacon interval of my station;
- };
- /// We keep a vector of pointers to PeerLink class. This vector
- /// keeps all peer links at a given interface.
- typedef std::vector<Ptr<PeerLink> > PeerLinksOnInterface;
- /// This map keeps all peer links.
- ///\param uint32_t is interface ID
- typedef std::map<uint32_t, PeerLinksOnInterface> PeerLinksMap;
- ///\brief This map keeps relationship between peer address and its
- /// beacon information
- typedef std::map<Mac48Address, BeaconInfo> BeaconsOnInterface;
- ///\brief This map keeps beacon information on all intefaces
- typedef std::map<uint32_t, BeaconsOnInterface> BeaconInfoMap;
- ///\brief this vector keeps pointers to MAC-plugins
- typedef std::map<uint32_t, Ptr<PeerManagerMacPlugin> > PeerManagerPluginMap;
- ///\}
-private:
- /**
- * Return a position in beacon-storage for a given remote station
- */
- void FillBeaconInfo(uint32_t interface, Mac48Address peerAddress, Time receivingTime, Time beaconInterval);
- Ptr<PeerLink> InitiateLink (uint32_t interface, Mac48Address peerAddress, Time lastBeacon, Time beaconInterval);
- /**
- * \name External peer-chooser
- * \{
- */
- bool ShouldSendOpen (uint32_t interface, Mac48Address peerAddress);
- bool ShouldAcceptOpen (uint32_t interface, Mac48Address peerAddress, dot11sReasonCode & reasonCode);
- /**
- * \}
- * \brief Indicates changes in peer links
- */
- void PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, bool status);
- /**
- * Removes all links which are idle
- */
- void PeerCleanup ();
- ///\brief BCA
- Time GetNextBeaconShift (uint32_t interface);
-private:
- PeerManagerPluginMap m_plugins;
- /**
- * \name Information related to beacons:
- * \{
- */
- BeaconInfoMap m_neighbourBeacons;
- ///\}
- uint16_t m_lastAssocId;
- uint16_t m_lastLocalLinkId;
- uint8_t m_numberOfActivePeers; //number of established peer links
- uint8_t m_maxNumberOfPeerLinks;
- /**
- * Peer Links
- * \{
- */
- PeerLinksMap m_peerLinks;
- /**
- * \}
- */
- /**
- * Periodically we scan the peer manager list of peers
- * and check if the too many beacons were lost:
- * \{
- */
- Time m_peerLinkCleanupPeriod;
- EventId m_cleanupEvent;
- /**
- * \}
- */
-};
-
-} // namespace dot11s
-} //namespace ns3
-#endif
--- a/src/devices/mesh/dot11s/wscript Wed Mar 25 16:58:24 2009 +0300
+++ b/src/devices/mesh/dot11s/wscript Wed Mar 25 17:37:51 2009 +0300
@@ -11,8 +11,8 @@
'ie-dot11s-perr.cc',
'ie-dot11s-rann.cc',
'peer-link-frame.cc',
- 'peer-manager-plugin.cc',
- 'peer-manager-protocol.cc',
+ 'peer-management-plugin.cc',
+ 'peer-management-protocol.cc',
'dot11s-helper.cc',
'peer-link.cc',
]
@@ -22,15 +22,15 @@
'ie-dot11s-beacon-timing.h',
'ie-dot11s-configuration.h',
'ie-dot11s-peer-management.h',
- 'ie-dot11s-preq.h',
- 'ie-dot11s-prep.h',
- 'ie-dot11s-perr.h',
- 'ie-dot11s-rann.h',
- 'peer-link-frame.h',
- 'peer-manager-protocol.h',
- 'peer-manager-plugin.h',
+ #'ie-dot11s-preq.h',
+ #'ie-dot11s-prep.h',
+ #'ie-dot11s-perr.h',
+ #'ie-dot11s-rann.h',
+ #'peer-link-frame.h',
+ 'peer-management-protocol.h',
+ #'peer-management-plugin.h',
'dot11s-helper.h',
- 'peer-link.h',
+ #'peer-link.h',
]
# obj = bld.create_ns3_program('wifi-phy-test',
--- a/src/devices/mesh/hwmp-rtable.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#include "ns3/object.h"
-#include "ns3/assert.h"
-#include "ns3/simulator.h"
-#include "ns3/ptr.h"
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/hwmp-rtable.h"
-
-NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
-
-TypeId
-HwmpRtable::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::HwmpRtable")
- .SetParent<Object> ()
- .AddConstructor<HwmpRtable> ();
- return tid;
-
-}
-
-HwmpRtable::HwmpRtable ()
-{
-}
-
-HwmpRtable::~HwmpRtable ()
-{
- DoDispose ();
-}
-
-void
-HwmpRtable::DoDispose ()
-{
- NS_LOG_UNCOND ("RTABLE DISPOSE STARTED");
- m_routes.clear ();
- m_roots.clear ();
-}
-
-void
-HwmpRtable::AddReactivePath (
- Mac48Address destination,
- Mac48Address retransmitter,
- uint32_t port,
- uint32_t metric,
- Time lifetime,
- uint32_t seqnum
-)
-{
- std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
- if (i == m_routes.end ())
- {
- ReactiveRoute newroute;
- m_routes[destination] = newroute;
- }
- else
- {
- /**
- * if outport differs from stored, routing info is
- * actual and metric is worse - we ignore this
- * information
- */
- if (
- (i->second.port != port) &&
- (i->second.metric < metric) &&
- /**
- * The routing info is actual or it
- * was received from peer
- */
- ((i->second.whenExpire > Simulator::Now ())||(i->second.whenExpire == Seconds(0)))
- )
- return;
- }
- i = m_routes.find (destination);
- NS_ASSERT (i != m_routes.end());
- i->second.retransmitter = retransmitter;
- i->second.port = port;
- i->second.metric = metric;
- if (lifetime != Seconds (0))
- i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
- else
- /**
- * Information about peer does not have lifetime
- */
- i->second.whenExpire = Seconds (0);
- i->second.seqnum = seqnum;
-}
-
-void
-HwmpRtable::AddProactivePath (
- uint32_t metric,
- Mac48Address root,
- Mac48Address retransmitter,
- uint32_t port,
- Time lifetime,
- uint32_t seqnum
-)
-{
- ProactiveRoute newroute;
- m_roots[port] = newroute;
- std::map<uint32_t,ProactiveRoute>::iterator i = m_roots.find (port);
- NS_ASSERT (i != m_roots.end());
- i->second.root = root;
- i->second.retransmitter = retransmitter;
- i->second.metric = metric;
- i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
- i->second.seqnum = seqnum;
-
-}
-
-void
-HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t port, Mac48Address precursor)
-{
- bool should_add = true;
- std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
- if ((i != m_routes.end ()) && (i->second.port == port))
- {
- for (unsigned int j = 0 ; j < i->second.precursors.size (); j ++)
- if (i->second.precursors[j] == precursor)
- {
- should_add = false;
- break;
- }
- if (should_add)
- i->second.precursors.push_back (precursor);
- }
- std::map<uint32_t,ProactiveRoute>::iterator k = m_roots.find (port);
- if (k != m_roots.end ())
- {
- for (unsigned int j = 0 ; j < k->second.precursors.size (); j ++)
- if (k->second.precursors[j] == precursor)
- return;
- k->second.precursors.push_back (precursor);
- return;
- }
-}
-
-void
-HwmpRtable::DeleteProactivePath (uint32_t port)
-{
- std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
- if (j != m_roots.end ())
- m_roots.erase (j);
-
-}
-void
-HwmpRtable::DeleteProactivePath (Mac48Address root, uint32_t port)
-{
- std::map<uint32_t,ProactiveRoute>::iterator j = m_roots.find (port);
- if ((j != m_roots.end ())&&(j->second.root == root))
- m_roots.erase (j);
-
-}
-
-void
-HwmpRtable::DeleteReactivePath (Mac48Address destination, uint32_t port)
-{
- std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
- if (i != m_routes.end ())
- if (i->second.port == port)
- m_routes.erase (i);
-}
-
-HwmpRtable::LookupResult
-HwmpRtable::LookupReactive (Mac48Address destination)
-{
- LookupResult result;
- result.retransmitter = Mac48Address::GetBroadcast ();
- result.metric = MAX_METRIC;
- result.ifIndex = PORT_ANY;
-
- std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
- if (i == m_routes.end ())
- return result;
- result.ifIndex = i->second.port;
- //Seconds (0) means that this is routing
- if (i->second.whenExpire < Simulator::Now ())
- if (i->second.retransmitter != destination)
- return result;
- result.retransmitter = i->second.retransmitter;
- result.metric = i->second.metric;
- result.seqnum = i->second.seqnum;
- return result;
-}
-
-HwmpRtable::LookupResult
-HwmpRtable::LookupProactive (uint32_t port)
-{
- LookupResult result;
- result.retransmitter = Mac48Address::GetBroadcast ();
- result.metric = MAX_METRIC;
- result.ifIndex = PORT_ANY;
- std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
- if (i == m_roots.end ())
- return result;
- result.ifIndex = i->first;
- if (i->second.whenExpire < Simulator::Now ())
- return result;
- result.retransmitter = i->second.retransmitter;
- result.metric = i->second.metric;
- result.seqnum = i->second.seqnum;
- return result;
-}
-
-std::vector<HwmpRtable::FailedDestination>
-HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress, uint32_t port)
-{
- std::vector<FailedDestination> retval;
- for (std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.begin (); i != m_routes.end(); i++)
- if ((i->second.retransmitter == peerAddress)&& (i->second.port == port))
- {
- FailedDestination dst;
- dst.destination = i->first;
- i->second.seqnum ++;
- dst.seqnum = i->second.seqnum;
- retval.push_back (dst);
- }
- /**
- * Lookup a path to root
- */
- std::map<uint32_t, ProactiveRoute>::iterator i = m_roots.find (port);
- if ((i != m_roots.end ())&&(i->second.retransmitter == peerAddress))
- {
- FailedDestination dst;
- dst.destination = i->second.root;
- dst.seqnum = i->second.seqnum;
- retval.push_back (dst);
- }
- return retval;
-}
-uint32_t
-HwmpRtable::RequestSeqnum (Mac48Address destination)
-{
- std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
- if (i == m_routes.end ())
- return 0;
- return i->second.seqnum;
-}
-
-std::vector<Mac48Address>
-HwmpRtable::GetPrecursors (Mac48Address destination, uint32_t port)
-{
- std::vector<Mac48Address> retval;
- std::map<uint32_t, ProactiveRoute>::iterator root = m_roots.find (port);
- if ((root != m_roots.end ()) &&(root->second.root == destination))
- {
- for (unsigned int i = 0; i < root->second.precursors.size (); i ++)
- retval.push_back (root->second.precursors[i]);
- }
- std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
- if ( (route != m_routes.end ()) && (route->second.port == port) )
- {
- for (unsigned int i = 0; i < route->second.precursors.size (); i ++)
- retval.push_back (route->second.precursors[i]);
- }
- return retval;
-}
-
-}//namespace ns3
--- a/src/devices/mesh/hwmp-rtable.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#ifndef HWMP_RTABLE_H
-#define HWMP_RTABLE_H
-
-#include <list>
-#include <map>
-#include "ns3/nstime.h"
-#include "ns3/mac48-address.h"
-#include "ns3/net-device.h"
-#include "ns3/event-id.h"
-#include "ns3/packet.h"
-namespace ns3 {
-
-/**
- * \ingroup mesh
- */
-class HwmpRtable : public Object
-{
-public:
- static TypeId GetTypeId ();
- HwmpRtable ();
- ~HwmpRtable ();
- void DoDispose ();
- void AddReactivePath (
- Mac48Address destination,
- Mac48Address retransmitter,
- uint32_t port,
- uint32_t metric,
- Time lifetime,
- uint32_t seqnum
- );
- void AddProactivePath (
- uint32_t metric,
- Mac48Address root,
- Mac48Address retransmitter,
- uint32_t port,
- Time lifetime,
- uint32_t seqnum
- );
- void AddPrecursor (Mac48Address destination, uint32_t port, Mac48Address precursor);
- void DeleteProactivePath (uint32_t port);
- void DeleteProactivePath (Mac48Address root, uint32_t port);
- void DeleteReactivePath (Mac48Address destination, uint32_t port);
- struct LookupResult
- {
- Mac48Address retransmitter;
- uint32_t ifIndex;
- uint32_t metric;
- uint32_t seqnum;
- };
- LookupResult LookupReactive (Mac48Address destination);
- LookupResult LookupProactive (uint32_t port);
- //path error routines:
- struct FailedDestination
- {
- Mac48Address destination;
- uint32_t seqnum;
- };
- std::vector<FailedDestination> GetUnreachableDestinations (Mac48Address peerAddress, uint32_t port);
- uint32_t RequestSeqnum (Mac48Address dst);
- std::vector<Mac48Address> GetPrecursors (Mac48Address destination, uint32_t port);
- const static uint32_t PORT_ANY = 0xffffffff;
- const static uint32_t MAX_METRIC = 0xffffffff;
-private:
- struct ReactiveRoute
- {
- Mac48Address retransmitter;
- uint32_t port;
- uint32_t metric;
- Time whenExpire;
- uint32_t seqnum;
- std::vector<Mac48Address> precursors;
- };
- struct ProactiveRoute
- {
- Mac48Address root;
- Mac48Address retransmitter;
- uint32_t metric;
- Time whenExpire;
- uint32_t seqnum;
- std::vector<Mac48Address> precursors;
- };
- std::map<Mac48Address, ReactiveRoute> m_routes;
- std::map<uint32_t, ProactiveRoute> m_roots;
-};
-} //namespace ns3
-#endif
--- a/src/devices/mesh/hwmp-state.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,539 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#include "ns3/hwmp-state.h"
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/log.h"
-
-namespace ns3 {
-
-NS_LOG_COMPONENT_DEFINE ("HwmpState");
-TypeId
-HwmpState::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::HwmpState")
- .SetParent<Object> ()
- .AddConstructor<HwmpState> ()
- ;
- return tid;
-}
-
-HwmpState::HwmpState ():
- m_myPreq (m_preqQueue.end()),
- m_preqId (1),
- m_myDsn (1),
- m_disabled (false),
- m_maxTtl (10)
-{
-}
-void
-HwmpState::SetRequestRouteCallback (
- Callback<HwmpRtable::LookupResult, const Mac48Address&> cb)
-{
- m_requestRouteCallback = cb;
-}
-
-void
-HwmpState::SetRequestRootPathCallback (
- Callback<HwmpRtable::LookupResult, uint32_t> cb)
-{
- m_requestRootPathCallback = cb;
-}
-
-//Setting MAC
-void
-HwmpState::SetMac (Ptr<MeshWifiMac> mac)
-{
- mac->SetPeerStatusCallback (MakeCallback(&HwmpState::PeerStatus, this));
- mac->SetPreqReceivedCallback (MakeCallback(&HwmpState::ReceivePreq, this));
- mac->SetPrepReceivedCallback (MakeCallback(&HwmpState::ReceivePrep, this));
- mac->SetPerrReceivedCallback (MakeCallback(&HwmpState::ReceivePerr, this));
- m_address = mac->GetAddress ();
- m_preqCallback = MakeCallback (&MeshWifiMac::SendPreq, mac);
- m_prepCallback = MakeCallback (&MeshWifiMac::SendPrep, mac);
- m_perrCallback = MakeCallback (&MeshWifiMac::SendPerr, mac);
-}
-HwmpState::~HwmpState ()
-{
- m_preqQueue.clear ();
-}
-//Interaction with HWMP:
-void
-HwmpState::SetRoutingInfoCallback (
- Callback<void, INFO> cb
-)
-{
- m_routingInfoCallback = cb;
-}
-
-void
-HwmpState::SetRetransmittersOfPerrCallback (
- Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> cb)
-{
- m_retransmittersOfPerrCallback = cb;
-}
-
-void
-HwmpState::RequestDestination (Mac48Address dst)
-{
- if (m_preqQueue.end () == m_myPreq)
- {
- IeDot11sPreq preq;
- //fill PREQ:
- preq.SetHopcount (0);
- preq.SetTTL (m_maxTtl);
- preq.SetPreqID (m_preqId++);
- if (m_preqId == MAX_PREQ_ID)
- m_preqId = 0;
- preq.SetLifetime (TIME_TO_TU(dot11sParameters::dot11MeshHWMPactivePathTimeout));
- preq.SetOriginatorSeqNumber (m_myDsn++);
- if (m_myDsn == MAX_DSN)
- m_myDsn = 0;
- preq.SetOriginatorAddress (m_address);
- preq.AddDestinationAddressElement (false, false, dst, 0); //DO = 0, RF = 0
- if (m_preqTimer.IsRunning ())
- {
- NS_LOG_DEBUG ("No my preq");
- m_preqQueue.push_back (preq);
- //set iterator position to my preq:
- m_myPreq = m_preqQueue.end () -1;
- }
- else
- {
- NS_LOG_DEBUG ("Send PREQ now, "<<preq.GetPreqID()<<" destinations, now is "<<Simulator::Now());
- m_preqCallback (preq);
- NS_ASSERT (!m_preqTimer.IsRunning());
- m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
- }
- }
- else
- {
- NS_ASSERT (m_myPreq->GetOriginatorAddress() == m_address);
- NS_LOG_DEBUG ("add a destination "<<dst);
- m_myPreq->AddDestinationAddressElement (false, false, dst, 0); //DO = 0, RF = 0
- }
-}
-void
-HwmpState::SendPathError (std::vector<HwmpRtable::FailedDestination> destinations)
-{
- std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback (destinations, m_ifIndex);
- NS_LOG_DEBUG ("SendPathError started");
- if (receivers.size () == 0)
- return;
- NS_LOG_DEBUG (m_address<<" Should Send PERR to");
- for (unsigned int i = 0; i < receivers.size (); i ++)
- {
- AddPerrReceiver (receivers[i]);
- NS_LOG_DEBUG (receivers[i]);
- }
- NS_LOG_DEBUG ("To tel about failure with");
- for (unsigned int i = 0; i < destinations.size (); i ++)
- {
- m_myPerr.AddAddressUnit (destinations[i]);
- NS_LOG_DEBUG (destinations[i].destination);
- }
- if (!m_perrTimer.IsRunning ())
- {
- m_perrCallback (m_myPerr,m_myPerrReceivers);
- m_myPerr.ResetPerr ();
- m_perrTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpState::SendOnePerr,this);
- }
-}
-//needed to fill routing information structure
-void
-HwmpState::SetAssociatedIfaceId (uint32_t interface)
-{
- m_ifIndex = interface;
-}
-
-uint32_t
-HwmpState::GetAssociatedIfaceId ()
-{
- return m_ifIndex;
-}
-
-//Interaction with MAC:
-void
-HwmpState::ReceivePreq (IeDot11sPreq& preq, const Mac48Address& from, const uint32_t& metric)
-{
- if (m_disabled)
- return;
- if (preq.GetOriginatorAddress () == m_address)
- return;
- preq.DecrementTtl ();
- preq.IncrementMetric (metric);
- if (preq.GetTtl () == 0)
- return;
- //acceptance cretirea:
- std::map<Mac48Address, uint32_t>::iterator i = m_dsnDatabase.find (preq.GetOriginatorAddress());
- if (i == m_dsnDatabase.end ())
- {
- m_dsnDatabase[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber();
- m_preqMetricDatabase[preq.GetOriginatorAddress ()] = preq.GetMetric();
- }
- else
- {
- if (i->second > preq.GetOriginatorSeqNumber ())
- return;
- if (i->second == preq.GetOriginatorSeqNumber ())
- {
- //find metric
- std::map<Mac48Address, uint32_t>::iterator j =
- m_preqMetricDatabase.find (preq.GetOriginatorAddress());
- NS_ASSERT (j != m_dsnDatabase.end());
- if (j->second <= preq.GetMetric ())
- return;
- }
- m_dsnDatabase[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber();
- m_preqMetricDatabase[preq.GetOriginatorAddress ()] = preq.GetMetric();
- }
- NS_LOG_DEBUG (
- "PREQ from "<< preq.GetOriginatorAddress ()
- <<", at "<< m_address
- <<", TTL ="<< (int)preq.GetTtl ()
- <<", metric = "<< preq.GetMetric ()
- <<", hopcount = "<< (int)preq.GetHopCount ()
- <<", preqId = "<< preq.GetPreqID ()
- <<", transmitter is "<<from);
- //fill routingTable
- INFO newInfo;
- newInfo.me = m_address;
- newInfo.destination = preq.GetOriginatorAddress ();
- newInfo.nextHop = from;
- newInfo.metric = preq.GetMetric ();
- newInfo.lifetime = TU_TO_TIME (preq.GetLifetime());
- newInfo.outPort = m_ifIndex;
- newInfo.dsn = preq.GetOriginatorSeqNumber ();
- newInfo.type = INFO_PREQ;
- //check if can answer:
- std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
- for (std::vector<Ptr<DestinationAddressUnit> >::iterator i = destinations.begin (); i != destinations.end(); i++)
- {
- if ((*i)->GetDestinationAddress () == Mac48Address::GetBroadcast())
- {
- //only proactive PREQ contains destination
- //address as broadcast! Proactive preq MUST
- //have destination count equal to 1 and
- //per destination flags DO and RF
- NS_ASSERT (preq.GetDestCount() == 1);
- NS_ASSERT (((*i)->IsDo()) && ((*i)->IsRf()));
- NS_LOG_DEBUG ("PROACTIVE PREQ RECEIVED");
- newInfo.type = INFO_PROACTIVE;
- m_routingInfoCallback (newInfo);
- if (!preq.IsNeedNotPrep ())
- {
- SendPrep (
- preq.GetOriginatorAddress (),
- m_address,
- from,
- preq.GetMetric (),
- preq.GetOriginatorSeqNumber (),
- m_myDsn ++,
- preq.GetLifetime ()
- );
- if (m_myDsn == MAX_DSN)
- m_myDsn = 0;
- }
- break;
- }
- if ((*i)->GetDestinationAddress () == m_address)
- {
- preq.DelDestinationAddressElement ((*i)->GetDestinationAddress());
- SendPrep (
- preq.GetOriginatorAddress (),
- m_address,
- from,
- 0,
- preq.GetOriginatorSeqNumber (),
- m_myDsn++,
- preq.GetLifetime ()
- );
- if (m_myDsn == MAX_DSN)
- m_myDsn = 0;
- continue;
- }
- //check if can answer:
- HwmpRtable::LookupResult result = m_requestRouteCallback ((*i)->GetDestinationAddress());
- if ((! ((*i)->IsDo())) && (result.retransmitter != Mac48Address::GetBroadcast()))
- {
- //have a valid information and acn answer
- if ((*i)->IsRf ())
- (*i)->SetFlags (true, false); //DO = 1, RF = 0 (as it was)
- else
- {
- //send a PREP and delete destination
- preq.DelDestinationAddressElement ((*i)->GetDestinationAddress());
- SendPrep (
- preq.GetOriginatorAddress (),
- (*i)->GetDestinationAddress (),
- result.retransmitter,
- result.metric,
- preq.GetOriginatorSeqNumber (),
- result.seqnum,
- preq.GetLifetime ()
- );
- continue;
- }
- }
- }
- m_routingInfoCallback (newInfo);
- //chack if must retransmit:
- if (preq.GetDestCount () == 0)
- return;
- if (m_preqTimer.IsRunning ())
- {
- m_preqQueue.push_back (preq);
- }
- else
- {
- m_preqCallback (preq);
- NS_ASSERT (!m_preqTimer.IsRunning());
- m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
- }
-}
-
-void
-HwmpState::ReceivePrep (IeDot11sPrep& prep, const Mac48Address& from, const uint32_t& metric)
-{
- if (m_disabled)
- return;
- prep.DecrementTtl ();
- prep.IncrementMetric (metric);
- //acceptance cretirea:
- std::map<Mac48Address, uint32_t>::iterator i = m_dsnDatabase.find (prep.GetDestinationAddress());
- if (i == m_dsnDatabase.end ())
- {
- m_dsnDatabase[prep.GetDestinationAddress ()] = prep.GetDestinationSeqNumber();
- }
- else
- if (i->second > prep.GetDestinationSeqNumber ())
- return;
- //update routing info
- HwmpRtable::LookupResult result = m_requestRouteCallback (prep.GetDestinationAddress());
- if (result.retransmitter == Mac48Address::GetBroadcast ())
- //try to look for default route
- result = m_requestRootPathCallback (m_ifIndex);
- if ((result.retransmitter == Mac48Address::GetBroadcast ())&&(m_address != prep.GetDestinationAddress()))
- return;
- INFO newInfo;
- newInfo.me = m_address;
- newInfo.destination = prep.GetOriginatorAddress ();
- newInfo.source = prep.GetDestinationAddress ();
- newInfo.nextHop = from;
- newInfo.metric = prep.GetMetric ();
- newInfo.lifetime = TU_TO_TIME (prep.GetLifetime());
- newInfo.outPort = m_ifIndex;
- newInfo.dsn = prep.GetOriginatorSeqNumber ();
- newInfo.prevHop = result.retransmitter;
- newInfo.type = INFO_PREP;
- NS_LOG_DEBUG ("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
- NS_LOG_DEBUG ("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
- m_routingInfoCallback (newInfo);
- if (prep.GetDestinationAddress () == m_address)
- {
- NS_LOG_DEBUG ("Destination resolved"<<newInfo.destination);
- return;
- }
- m_prepCallback (prep, result.retransmitter);
-}
-
-void
-HwmpState::ReceivePerr (IeDot11sPerr& perr, const Mac48Address& from)
-{
- if (m_disabled)
- return;
- NS_LOG_DEBUG (m_address<<" RECEIVED PERR from "<<from);
- /**
- * Check forwarding conditions:
- */
- std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector ();
- for (unsigned int i = 0; i < destinations.size (); i ++)
- {
- /**
- * Lookup for a valid routing information
- */
- HwmpRtable::LookupResult result = m_requestRouteCallback (destinations[i].destination);
- if (
- (result.retransmitter != from)
- || (result.seqnum >= destinations[i].seqnum)
- )
-
- perr.DeleteAddressUnit (destinations[i].destination);
- }
- NS_LOG_DEBUG ("Retransmit "<<(int)perr.GetNumOfDest());
- if (perr.GetNumOfDest () == 0)
- return;
- destinations = perr.GetAddressUnitVector ();
- SendPathError (destinations);
-}
-
-void
-HwmpState::PeerStatus (const Mac48Address peerAddress, const bool status, const uint32_t metric)
-{
- INFO newInfo;
- newInfo.me = m_address;
- newInfo.destination = peerAddress;
- newInfo.nextHop = peerAddress;
- newInfo.metric = metric;
- newInfo.outPort = m_ifIndex;
- newInfo.dsn = 0;
- if (status)
- newInfo.type = INFO_NEW_PEER;
- else
- newInfo.type = INFO_FAILED_PEER;
- m_routingInfoCallback (newInfo);
-}
-
-bool
-HwmpState::SetRoot ()
-{
-#if 0
- //TODO:: delete this lines!!!!!!!
- if (m_address != Mac48Address ("00:00:00:00:00:10"))
- return false;
- //TODO
-#endif
- Simulator::Schedule (dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
- return true;
-}
-
-void
-HwmpState::SendProactivePreq ()
-{
- NS_LOG_DEBUG ("Sending proactive PREQ");
- IeDot11sPreq preq;
- //By default: must answer
- preq.SetHopcount (0);
- preq.SetTTL (m_maxTtl);
- preq.SetPreqID (m_preqId++);
- if (m_preqId == MAX_PREQ_ID)
- m_preqId = 0;
- preq.SetLifetime (TIME_TO_TU(dot11sParameters::dot11MeshHWMPpathToRootInterval));
- preq.SetOriginatorSeqNumber (m_myDsn++);
- if (m_myDsn == MAX_DSN)
- m_myDsn = 0;
- preq.SetOriginatorAddress (m_address);
- preq.AddDestinationAddressElement (
- true,
- true,
- Mac48Address::GetBroadcast ()
- ,0);
- if (m_preqTimer.IsRunning ())
- m_preqQueue.push_back (preq);
- else
- {
- NS_LOG_DEBUG ("Send now "<<preq.GetPreqID());
- m_preqCallback (preq);
- NS_ASSERT (!m_preqTimer.IsRunning());
- m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
- }
- Simulator::Schedule (dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
-}
-
-void
-HwmpState::AddPerrReceiver (Mac48Address receiver)
-{
- /**
- * add new vector of addresses to m_perrReceiversand check
- * duplicates
- */
- for (unsigned int j = 0; j < m_myPerrReceivers.size (); j++)
- if (m_myPerrReceivers[j] == receiver)
- return;
- m_myPerrReceivers.push_back (receiver);
-}
-
-void
-HwmpState::UnSetRoot ()
-{
-}
-
-void
-HwmpState::Disable ()
-{
- m_disabled = true;
-}
-
-void
-HwmpState::Enable ()
-{
- m_disabled = false;
-}
-
-Mac48Address
-HwmpState::GetAddress ()
-{
- return m_address;
-}
-
-void
-HwmpState::SendOnePreq ()
-{
- if (m_preqQueue.size () == 0)
- return;
- if (m_myPreq == m_preqQueue.begin ())
- m_myPreq == m_preqQueue.end ();
- IeDot11sPreq preq = m_preqQueue[0];
- NS_LOG_DEBUG (
- "Sending PREQ from "<<preq.GetOriginatorAddress () <<
- " destinations are "<< (int)preq.GetDestCount()<<
- ", at "<<Simulator::Now ()<<
- ", store in queue "<<m_preqQueue.size ()<<
- " preqs"<<", I am "<<m_address);
- m_preqCallback (preq);
- //erase first!
- m_preqQueue.erase (m_preqQueue.begin());
- //reschedule sending PREQ
- NS_ASSERT (!m_preqTimer.IsRunning());
- m_preqTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
-}
-
-void
-HwmpState::SendPrep (Mac48Address dst,
- Mac48Address src,
- Mac48Address retransmitter,
- uint32_t initMetric,
- uint32_t dsn,
- uint32_t originatorDsn,
- uint32_t lifetime)
-{
- IeDot11sPrep prep;
- prep.SetHopcount (0);
- prep.SetTTL (m_maxTtl);
- prep.SetDestinationAddress (dst);
- prep.SetDestinationSeqNumber (dsn);
- prep.SetLifetime (lifetime);
- prep.SetMetric (0);
- prep.SetOriginatorAddress (src);
- prep.SetOriginatorSeqNumber (originatorDsn);
- m_prepCallback (prep, retransmitter);
-}
-
-void
-HwmpState::SendOnePerr ()
-{
- if (m_myPerr.GetNumOfDest () == 0)
- return;
- m_perrCallback (m_myPerr, m_myPerrReceivers);
- m_myPerr.ResetPerr ();
-}
-}//namespace ns3
--- a/src/devices/mesh/hwmp-state.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#ifndef HWMP_STATE_H
-#define HWMP_STATE_H
-#include <map>
-#include "ns3/hwmp-rtable.h"
-#include "ns3/packet.h"
-#include "ns3/mesh-wifi-mac.h"
-#include "ns3/ie-dot11s-preq.h"
-#include "ns3/ie-dot11s-prep.h"
-#include "ns3/ie-dot11s-perr.h"
-#include "ns3/dot11s-parameters.h"
-#include "ns3/wifi-net-device.h"
-namespace ns3 {
-/**
- * \ingroup mesh
- *
- * \brief Handles HWMP state machine at each real interface
- *
- * \details Implements the following:
- * 1. Keep it's own DSN,
- * 2. Keep PREQ and PREP timers adn send this frames in
- * accordance with HWMP-limitations
- * 3. Deliver routing information to Hwmp main class
- * 4. Notify about broken peers
- */
-class HwmpState : public Object {
-public:
- static TypeId GetTypeId ();
- HwmpState ();
- ~HwmpState ();
-
- /**
- * \brief Interface with HWMP - Hwmp can only
- * request address and collect routing
- * information
- */
- void SetRequestRouteCallback (
- Callback<HwmpRtable::LookupResult, const Mac48Address&> cb);
- void SetRequestRootPathCallback (
- Callback<HwmpRtable::LookupResult, uint32_t> cb);
-
- enum InfoType {
- INFO_PREQ,
- INFO_PREP,
- INFO_PERR,
- INFO_PROACTIVE,
- INFO_NEW_PEER,
- INFO_FAILED_PEER
- };
- typedef struct RoutingInfo {
- Mac48Address me;
- Mac48Address destination;
- Mac48Address source;
- Mac48Address nextHop;
- Mac48Address prevHop;
- uint32_t outPort;
- uint32_t metric;
- std::vector<Mac48Address> failedDestinations;
- uint32_t dsn;
- Time lifetime;
- enum InfoType type;
- } INFO;
- void SetRoutingInfoCallback (
- Callback<void, INFO> cb
- );
- void SetRetransmittersOfPerrCallback (
- Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> cb);
- void RequestDestination (Mac48Address dest);
- void SendPathError (std::vector<HwmpRtable::FailedDestination> destinations);
- void SetAssociatedIfaceId (uint32_t interface);
- uint32_t GetAssociatedIfaceId ();
- //Mac interaction:
- void SetMac (Ptr<MeshWifiMac> mac);
- void SetSendPreqCallback (
- Callback<void, const IeDot11sPreq&> cb);
- void SetSendPrepCallback (
- Callback<void, const IeDot11sPrep&> cb);
- void SetSendPerrCallback (
- Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > cb);
- void ReceivePreq (IeDot11sPreq&, const Mac48Address& from, const uint32_t& metric);
- void ReceivePrep (IeDot11sPrep&, const Mac48Address& from, const uint32_t& metric);
- void ReceivePerr (IeDot11sPerr&, const Mac48Address& from);
- void PeerStatus (
- const Mac48Address peerAddress,
- const bool status,
- const uint32_t metric
- );
- //Proactive mode routines:
- bool SetRoot ();
- void UnSetRoot ();
- //external handling:
- void Disable ();
- void Enable ();
- //DEBUG purpose:
- Mac48Address GetAddress ();
-private:
- static const uint32_t MAX_PREQ_ID = 0xffffffff;
- static const uint32_t MAX_DSN = 0xffffffff;
- //information about associated port:
- Mac48Address m_address;
- //index when HWMP state is attached
- uint32_t m_ifIndex;
- //timers for PREQ and PREP:
- EventId m_preqTimer;
- void SendOnePreq ();
- std::vector<IeDot11sPreq> m_preqQueue;
- //true means that we can add a destination to
- //existing PREQ element
- //False means that we must send
- EventId m_prepTimer;
- void SendPrep (
- Mac48Address dst, //dst is PREQ's originator address
- Mac48Address src, //src is PREQ's destination address
- Mac48Address retransmitter,
- uint32_t initMetric,
- uint32_t dsn,/* taken form PREQ*/
- uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
- uint32_t lifetime //taken from PREQ
- );
- std::vector<IeDot11sPreq>::iterator m_myPreq;
- //HWMP interaction callbacks:
- Callback<void, INFO> m_routingInfoCallback;
- Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> m_retransmittersOfPerrCallback;
- Callback<HwmpRtable::LookupResult, const Mac48Address&> m_requestRouteCallback;
- Callback<HwmpRtable::LookupResult, uint32_t> m_requestRootPathCallback;
- //Mac interaction callbacks:
- Callback<void, const IeDot11sPreq&> m_preqCallback;
- Callback<void, const IeDot11sPrep&, const Mac48Address&> m_prepCallback;
- Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > m_perrCallback;
- //HwmpCounters:
- uint32_t m_preqId;
- uint32_t m_myDsn;
- //Seqno and metric database
- std::map<Mac48Address, uint32_t> m_dsnDatabase;
- std::map<Mac48Address, uint32_t> m_preqMetricDatabase;
- //Disable/enable functionality
- bool m_disabled;
- //Proactive PREQ mechanism:
- EventId m_proactivePreqTimer;
- void SendProactivePreq ();
- /**
- * \brief Two PERRs may not be sent closer to
- * each other than
- * dot11MeshHWMPperrMinInterval, so, each HWMP
- * state collects all unreachable destinations
- * and once in dot11MeshHWMPperrMinInterval
- * should send PERR, and PERR element should
- * be cleared
- */
- IeDot11sPerr m_myPerr;
- std::vector<Mac48Address> m_myPerrReceivers;
- void AddPerrReceiver (Mac48Address receiver);
- EventId m_perrTimer;
- void SendOnePerr ();
- //Configurable parameters:
- uint8_t m_maxTtl;
-};
-} //namespace ns3
-#endif
--- a/src/devices/mesh/hwmp.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,696 +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>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-
-#include "ns3/hwmp.h"
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/mesh-point-device.h"
-
-NS_LOG_COMPONENT_DEFINE ("Hwmp");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Hwmp);
-NS_OBJECT_ENSURE_REGISTERED (HwmpTag);
-//Class HwmpTag:
-HwmpTag::HwmpTag ()
-{
-}
-
-HwmpTag::~HwmpTag ()
-{
-}
-
-void
-HwmpTag::SetAddress (Mac48Address retransmitter)
-{
- m_address = retransmitter;
-}
-
-Mac48Address
-HwmpTag::GetAddress ()
-{
- return m_address;
-}
-
-void
-HwmpTag::SetTtl (uint8_t ttl)
-{
- m_ttl = ttl;
-}
-
-uint8_t
-HwmpTag::GetTtl ()
-{
- return m_ttl;
-}
-
-void
-HwmpTag::SetMetric (uint32_t metric)
-{
- m_metric = metric;
-}
-
-uint32_t
-HwmpTag::GetMetric ()
-{
- return m_metric;
-}
-
-void
-HwmpTag::SetSeqno (uint32_t seqno)
-{
- m_seqno = seqno;
-}
-
-uint32_t
-HwmpTag::GetSeqno ()
-{
- return m_seqno;
-}
-
-TypeId
-HwmpTag::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::HwmpTag")
- .SetParent<Tag> ()
- .AddConstructor<HwmpTag> ()
- ;
- return tid;
-}
-
-TypeId
-HwmpTag::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-uint32_t
-HwmpTag::GetSerializedSize () const
-{
- return 6 //address
- +1 //ttl
- +4; //metric
-}
-
-void
-HwmpTag::Serialize (TagBuffer i) const
-{
- uint8_t address[6];
- int j;
- m_address.CopyTo (address);
- i.WriteU8 (m_ttl);
- i.WriteU32 (m_metric);
- for (j = 0; j < 6; j ++)
- i.WriteU8 (address[j]);
-}
-
-void
-HwmpTag::Deserialize (TagBuffer i)
-{
- uint8_t address[6];
- int j;
- m_ttl = i.ReadU8 ();
- m_metric = i.ReadU32 ();
- for (j = 0; j < 6; j ++)
- address[j] = i.ReadU8 ();
- m_address.CopyFrom (address);
-}
-
-void
-HwmpTag::Print (std::ostream &os) const
-{
- os << "address=" << m_address;
- os << "ttl=" << m_ttl;
- os << "metrc=" << m_metric;
-}
-void
-HwmpTag::DecrementTtl ()
-{
- m_ttl --;
-}
-//Class HWMP:
-TypeId
-Hwmp::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::Hwmp")
- .SetParent<MeshL2RoutingProtocol> ()
- .AddConstructor<Hwmp> ();
- return tid;
-}
-Hwmp::Hwmp ():
- m_rtable (CreateObject<HwmpRtable> ()),
- m_maxTtl (32),
- m_broadcastPerr (false)
-{
-}
-
-Hwmp::~Hwmp ()
-{
-}
-
-void
-Hwmp::DoDispose ()
-{
- for (std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.begin (); i != m_timeoutDatabase.end(); i ++)
- i->second.Cancel ();
- m_timeoutDatabase.clear ();
- m_seqnoDatabase.clear ();
- m_rtable = 0;
-
- /**
- * clear routing queue:
- */
- for (
- std::map<Mac48Address, std::queue<QueuedPacket> >::iterator i = m_rqueue.begin ();
- i != m_rqueue.end ();
- i++
- )
- {
- while (1)
- {
- if (i->second.empty ())
- break;
- i->second.pop ();
- }
- }
- m_rqueue.clear ();
- /**
- * clear HWMP states
- */
- for (unsigned int i = 0; i < m_hwmpStates.size (); i ++)
- m_hwmpStates[i] = 0;
- m_hwmpStates.clear ();
-}
-
-bool
-Hwmp::RequestRoute (
- uint32_t sourceIface,
- const Mac48Address source,
- const Mac48Address destination,
- Ptr<Packet> packet,
- uint16_t protocolType, //ethrnet 'Protocol' field
- MeshL2RoutingProtocol::RouteReplyCallback routeReply
-)
-{
- HwmpRtable::LookupResult result;
- HwmpTag tag;
- if (sourceIface == GetMeshPoint ()->GetIfIndex())
- // packet from level 3
- {
- if (destination == Mac48Address::GetBroadcast ())
- {
- //set seqno!
- tag.SetSeqno (m_seqno++);
- if (m_seqno == MAX_SEQNO)
- m_seqno = 0;
- }
- tag.SetTtl (m_maxTtl);
- }
- else
- // packet from own interface
- {
- NS_ASSERT (packet->FindFirstMatchingTag(tag));
- //check seqno!
- if (destination == Mac48Address::GetBroadcast ())
- {
- std::map<Mac48Address, uint32_t>::iterator i = m_seqnoDatabase.find (source);
- if (i == m_seqnoDatabase.end ())
- m_seqnoDatabase[source] = tag.GetSeqno ();
- else
- {
- if (i->second >= tag.GetSeqno ())
- return false;
- m_seqnoDatabase[source] = tag.GetSeqno ();
- }
- }
- }
- tag.SetAddress (Mac48Address::GetBroadcast());
- if (tag.GetTtl () == 0)
- return false;
- tag.DecrementTtl ();
- if (destination == Mac48Address::GetBroadcast ())
- {
- //add RA tag RA = broadcast
- packet->RemoveAllTags ();
- packet->AddTag (tag);
- routeReply (
- true,
- packet,
- source,
- destination,
- protocolType,
- HwmpRtable::PORT_ANY
- );
- return true;
- }
- result = m_rtable->LookupReactive (destination);
- if (result.retransmitter == Mac48Address::GetBroadcast ())
- {
- //no actual route exists, queue packet and start route
- //discover procedure
- if (sourceIface != GetMeshPoint ()->GetIfIndex())
- {
- //Start path error procedure:
- NS_LOG_DEBUG ("Must Send PERR");
- std::vector<HwmpRtable::FailedDestination> destinations;
- HwmpRtable::FailedDestination dst;
- dst.seqnum = m_rtable->RequestSeqnum (destination);
- dst.destination = destination;
- destinations.push_back (dst);
- StartPathErrorProcedure (destinations, result.ifIndex);
- }
- MeshL2RoutingProtocol::QueuedPacket pkt;
- packet->RemoveAllTags ();
- packet->AddTag (tag);
- pkt.pkt = packet;
- pkt.dst = destination;
- pkt.src = source;
- pkt.protocol = protocolType;
- pkt.reply = routeReply;
- pkt.inPort = sourceIface;
- QueuePacket (pkt);
- for (unsigned int i = 0; i< m_requestCallback.size (); i++)
- {
- if ((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
- {
- if (ShouldSendPreq (destination))
- m_requestCallback[i] (destination);
- }
- else
- {
- NS_ASSERT (false);
- //PROACTIVE mode
- //lookup a default route
- result = m_rtable->LookupProactive (m_hwmpStates[i]->GetAssociatedIfaceId());
- if (result.retransmitter == Mac48Address::GetBroadcast ())
- {
- m_rtable->DeleteProactivePath (m_hwmpStates[i]->GetAssociatedIfaceId());
- m_modes[i] = REACTIVE;
- if (ShouldSendPreq (destination))
- m_requestCallback[i] (destination);
- continue;
- }
- tag.SetAddress (result.retransmitter);
- packet->RemoveAllTags ();
- packet->AddTag (tag);
- routeReply (
- true,
- packet,
- source,
- destination,
- protocolType,
- result.ifIndex
- );
- }
- }
- for (unsigned int i = 0; i< m_requestCallback.size (); i++)
- {
- m_requestCallback[i] (Mac48Address("00:00:00:00:00:19"));
- }
- }
- else
- {
- tag.SetAddress (result.retransmitter);
- packet->RemoveAllTags ();
- packet->AddTag (tag);
- routeReply (
- true,
- packet,
- source,
- destination,
- protocolType,
- result.ifIndex
- );
- }
- return true;
-}
-bool
-Hwmp::AttachPorts (std::vector<Ptr<NetDevice> > ports)
-{
- for (std::vector<Ptr<NetDevice> >::iterator i = ports.begin (); i != ports.end(); i++)
- {
- //Checking netdevice:
- const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
- if (wifiNetDev == NULL)
- return false;
- MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer (wifiNetDev->GetMac ()));
- if (meshWifiMac == NULL)
- return false;
- //Adding HWMP-state
- Ptr<HwmpState> hwmpState = CreateObject<HwmpState> ();
- hwmpState->SetRoutingInfoCallback (MakeCallback(&Hwmp::ObtainRoutingInformation, this));
- hwmpState->SetMac (meshWifiMac);
- hwmpState->SetRequestRouteCallback (MakeCallback(&Hwmp::RequestRouteForAddress, this));
- hwmpState->SetRequestRootPathCallback (MakeCallback(&Hwmp::RequestRootPathForPort, this));
- hwmpState->SetAssociatedIfaceId (wifiNetDev->GetIfIndex());
- hwmpState->SetRetransmittersOfPerrCallback (MakeCallback(&Hwmp::GetRetransmittersForFailedDestinations,this));
- m_hwmpStates.push_back (hwmpState);
- m_requestCallback.push_back (MakeCallback(&HwmpState::RequestDestination, hwmpState));
- m_pathErrorCallback.push_back (MakeCallback(&HwmpState::SendPathError, hwmpState));
- //Default mode is reactive, default state is enabled
- enum DeviceState state = ENABLED;
- enum DeviceMode mode = REACTIVE;
- m_states.push_back (state);
- m_modes.push_back (mode);
- }
- return true;
-}
-
-void
-Hwmp::DisablePort (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if ((*i)->GetAssociatedIfaceId () == port)
- {
- m_states[position] = DISABLED;
- m_hwmpStates[position]->Disable ();
- return;
- }
- position ++;
- }
-}
-
-void
-Hwmp::EnablePort (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if ((*i)->GetAssociatedIfaceId () == port)
- {
- m_states[position] = ENABLED;
- m_hwmpStates[position]->Enable ();
- return;
- }
- position ++;
- }
-}
-
-void
-Hwmp::SetRoot (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if (((*i)->GetAssociatedIfaceId () == port)||(port == HwmpRtable::PORT_ANY))
- {
- if (m_hwmpStates[position]->SetRoot ())
- {
- m_modes[position] = ROOT;
- NS_LOG_DEBUG ("I am proactive");
- }
- }
- position ++;
- }
-}
-void
-Hwmp::SetProactive (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if ((*i)->GetAssociatedIfaceId () == port)
- {
- m_modes[position] = PROACTIVE;
- return;
- }
- position ++;
- }
-}
-bool
-Hwmp::IsRoot (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if ((*i)->GetAssociatedIfaceId () == port)
- if (m_modes[position] == ROOT)
- return true;
- position ++;
- }
- return false;
-}
-void
-Hwmp::UnSetRoot (uint32_t port)
-{
- int position = 0;
- for (std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin (); i != m_hwmpStates.end(); i++)
- {
- if (((*i)->GetAssociatedIfaceId () == port)||(port == HwmpRtable::PORT_ANY))
- {
- m_modes[position] = REACTIVE;
- m_hwmpStates[position]->UnSetRoot ();
- }
- position ++;
- }
-}
-
-void
-Hwmp::ObtainRoutingInformation (
- HwmpState::INFO info
-)
-{
- switch (info.type)
- {
- case HwmpState::INFO_PREP:
- if (info.me != info.source)
- {
- m_rtable->AddPrecursor (info.source, info.outPort, info.nextHop);
- m_rtable->AddPrecursor (info.destination, info.outPort, info.prevHop);
- NS_LOG_DEBUG ("path to "<<info.source<<" precursor is "<<info.nextHop);
- NS_LOG_DEBUG ("path to "<<info.destination<<" precursor is "<<info.prevHop);
- }
- case HwmpState::INFO_PREQ:
- m_rtable->AddReactivePath (
- info.destination,
- info.nextHop,
- info.outPort,
- info.metric,
- info.lifetime,
- info.dsn);
- SendAllPossiblePackets (info.destination);
- break;
- case HwmpState::INFO_PERR:
- //delete first subentry
- case HwmpState::INFO_PROACTIVE:
- //add information to the root MP.
- m_rtable->AddProactivePath (
- info.metric,
- info.destination,
- info.nextHop,
- info.outPort,
- info.lifetime,
- info.dsn);
- //Set mode as PROACTIVE:
- SetProactive (info.outPort);
- break;
- case HwmpState::INFO_NEW_PEER:
-#if 0
- m_rtable->AddReactivePath (
- info.destination,
- info.nextHop,
- info.outPort,
- info.metric,
- Seconds (0),
- 0);
-#endif
- break;
- case HwmpState::INFO_FAILED_PEER:
- /**
- * Conditions for generating PERR
- */
- {
- NS_LOG_DEBUG ("Failed peer"<<info.destination);
- std::vector<HwmpRtable::FailedDestination> failedDestinations =
- m_rtable->GetUnreachableDestinations (info.destination, info.outPort);
- /**
- * Entry about peer does not contain seqnum
- */
- HwmpRtable::FailedDestination peer;
- peer.destination = info.destination;
- peer.seqnum = 0;
- failedDestinations.push_back (peer);
- StartPathErrorProcedure (failedDestinations, info.outPort);
- }
- break;
- default:
- return;
- }
-}
-
-HwmpRtable::LookupResult
-Hwmp::RequestRouteForAddress (const Mac48Address& dst)
-{
- return m_rtable->LookupReactive (dst);
-}
-
-HwmpRtable::LookupResult
-Hwmp::RequestRootPathForPort (uint32_t port)
-{
- return m_rtable->LookupProactive (port);
-}
-
-void
-Hwmp::StartPathErrorProcedure (std::vector<HwmpRtable::FailedDestination> destinations, uint32_t port)
-{
- NS_LOG_DEBUG ("START PERR");
- for (unsigned int i = 0; i < m_hwmpStates.size (); i++)
- if (m_hwmpStates[i]->GetAssociatedIfaceId () == port)
- m_pathErrorCallback[i] (destinations);
-}
-std::vector<Mac48Address>
-Hwmp::GetRetransmittersForFailedDestinations (std::vector<HwmpRtable::FailedDestination> failedDest, uint32_t port)
-{
- std::vector<Mac48Address> retransmitters;
- if (m_broadcastPerr)
- retransmitters.push_back (Mac48Address::GetBroadcast());
- else
- for (unsigned int i = 0; i < failedDest.size (); i ++)
- {
- std::vector<Mac48Address> precursors =
- m_rtable->GetPrecursors (failedDest[i].destination, port);
- for (unsigned int j = 0; j < precursors.size (); j++)
- {
- for (unsigned int k = 0; k < retransmitters.size (); k ++)
- if (retransmitters[k] == precursors[j])
- break;
- retransmitters.push_back (precursors[j]);
- }
- }
- for (unsigned int i = 0; i < failedDest.size (); i ++)
- {
- m_rtable->DeleteReactivePath (failedDest[i].destination, port);
- m_rtable->DeleteProactivePath (failedDest[i].destination, port);
- }
- return retransmitters;
-}
-void
-Hwmp::SetMaxQueueSize (int maxPacketsPerDestination)
-{
- m_maxQueueSize = maxPacketsPerDestination;
-}
-
-bool
-Hwmp::QueuePacket (MeshL2RoutingProtocol::QueuedPacket packet)
-{
- if ((int)m_rqueue[packet.dst].size () > m_maxQueueSize)
- return false;
- m_rqueue[packet.dst].push (packet);
- return true;
-}
-
-MeshL2RoutingProtocol::QueuedPacket
-Hwmp::DequeuePacket (Mac48Address dst)
-{
- MeshL2RoutingProtocol::QueuedPacket retval;
- retval.pkt = NULL;
- //Ptr<Packet> in this structure is NULL when queue is empty
- std::map<Mac48Address, std::queue<QueuedPacket> >:: iterator i = m_rqueue.find (dst);
- if (i == m_rqueue.end ())
- return retval;
- if ((int)m_rqueue[dst].size () == 0)
- return retval;
- if ((int)i->second.size () == 0)
- {
- m_rqueue.erase (i);
- return retval;
- }
- retval = m_rqueue[dst].front ();
- m_rqueue[dst].pop ();
- return retval;
-}
-
-void
-Hwmp::SendAllPossiblePackets (Mac48Address dst)
-{
- HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
- MeshL2RoutingProtocol::QueuedPacket packet;
- while (1)
-
- {
- packet = DequeuePacket (dst);
- if (packet.pkt == NULL)
- return;
- //set RA tag for retransmitter:
- HwmpTag tag;
- NS_ASSERT (packet.pkt->FindFirstMatchingTag(tag));
- tag.SetAddress (result.retransmitter);
- NS_ASSERT (result.retransmitter != Mac48Address::GetBroadcast());
- packet.pkt->RemoveAllTags ();
- packet.pkt->AddTag (tag);
- packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
- }
-}
-
-bool
-Hwmp::ShouldSendPreq (Mac48Address dst)
-{
- std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
- if (i == m_timeoutDatabase.end ())
- {
- m_timeoutDatabase[dst] = Simulator::Schedule (
- MilliSeconds (2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
- &Hwmp::RetryPathDiscovery, this, dst, 0);
- return true;
- }
- return false;
-}
-void
-Hwmp::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
-{
- HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
- if (result.retransmitter != Mac48Address::GetBroadcast ())
- {
- std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
- NS_ASSERT (i != m_timeoutDatabase.end());
- m_timeoutDatabase.erase (i);
- return;
- }
- numOfRetry++;
- if (numOfRetry > dot11sParameters::dot11MeshHWMPmaxPREQretries)
- {
- MeshL2RoutingProtocol::QueuedPacket packet;
- //purge queue and delete entry from retryDatabase
- while (1)
- {
- packet = DequeuePacket (dst);
- if (packet.pkt == NULL)
- break;
- packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
- }
- std::map<Mac48Address, EventId>::iterator i = m_timeoutDatabase.find (dst);
- NS_ASSERT (i != m_timeoutDatabase.end());
- m_timeoutDatabase.erase (i);
- return;
- }
- for (unsigned int i = 0; i < m_requestCallback.size (); i++)
- if ((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
- m_requestCallback[i] (dst);
- m_timeoutDatabase[dst] = Simulator::Schedule (
- MilliSeconds (2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
- &Hwmp::RetryPathDiscovery, this, dst, numOfRetry);
-}
-} //namespace ns3
--- a/src/devices/mesh/hwmp.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +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>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-
-#ifndef HWMP_H
-#define HWMP_H
-
-#include <map>
-#include <queue>
-#include "ns3/tag.h"
-#include "ns3/object.h"
-#include "ns3/mac48-address.h"
-#include "ns3/mesh-l2-routing-protocol.h"
-#include "ns3/packet.h"
-#include "ns3/hwmp-state.h"
-namespace ns3 {
-class HwmpState;
-/**
- * \ingroup mesh
- *
- * \brief Hwmp tag implements interaction between HWMP
- * protocol and MeshWifiMac
- *
- * \details Hwmp tag keeps the following:
- * 1. When packet is passed from Hwmp to 11sMAC:
- * - retransmitter address,
- * - TTL value,
- * 2. When packet is passed to Hwmp from 11sMAC:
- * - lasthop address,
- * - TTL value,
- * - metric value (metric of link is recalculated
- * at each packet, but routing table stores metric
- * obtained during path discovery procedure)
- */
-class HwmpTag : public Tag
-{
-public:
- HwmpTag ();
- ~HwmpTag ();
- void SetAddress (Mac48Address retransmitter);
- Mac48Address GetAddress ();
- void SetTtl (uint8_t ttl);
- uint8_t GetTtl ();
- void SetMetric (uint32_t metric);
- uint32_t GetMetric ();
- void SetSeqno (uint32_t seqno);
- uint32_t GetSeqno ();
- void DecrementTtl ();
-
- static TypeId GetTypeId ();
- virtual TypeId GetInstanceTypeId () const;
- virtual uint32_t GetSerializedSize () const;
- virtual void Serialize (TagBuffer i) const;
- virtual void Deserialize (TagBuffer i);
- virtual void Print (std::ostream &os) const;
-private:
- Mac48Address m_address;
- uint8_t m_ttl;
- uint32_t m_metric;
- uint32_t m_seqno;
-};
-/**
- * \ingroup mesh
- */
-class Hwmp : public MeshL2RoutingProtocol
-{
-public:
- static TypeId GetTypeId ();
- Hwmp ();
- ~Hwmp ();
- void DoDispose ();
- //intheritedfrom L2RoutingProtocol
- /**
- * \brief L2Routing protocol base class metod
- *
- * \details Route resolving procedure consits
- * of the following steps:
- * 1. Find reactive route and send a packet.
- * 2. Find all ports which are operate in
- * 'Proactive' mode and find a proper default
- * routes. and send packet to all proactive
- * 'ports'.
- * 3. If there are ports which are operate in
- * reactive mode - queue packet and start
- * route reactive path discovery
- *
- * \bug Now packet is sent to the 'best root'
- * rather than to the best root at each port
- */
- bool RequestRoute (
- uint32_t sourceIface,
- const Mac48Address source,
- const Mac48Address destination,
- Ptr<Packet> packet,
- uint16_t protocolType,
- MeshL2RoutingProtocol::RouteReplyCallback routeReply
- );
- bool AttachPorts (std::vector<Ptr<NetDevice> >);
- /**
- * \brief Disables port by index.
- * \details Needed for external modules like
- * clusterization.
- */
- void DisablePort (uint32_t port);
- /**
- * \brief enables port
- */
- void EnablePort (uint32_t port);
- /**
- * \brief Setting proative mode.
- * \details To enable proactive mode you must
- * set a root node. Choosing the route is made
- * in accordance with the following:
- * 1. Find 'reactive' route. If route is
- * found - send a packet using this
- * information
- * 2. If there is no reactive route -
- * find proactive or 'default' route.
- * \attention Comparsion between proactive and
- * reactive routes is incorrect, because we
- * have metric to root MP in te first case and
- * metric to the destination in the second
- * case.
- * \param port is the port where proactive
- * mode should be activated
- */
- void SetRoot (uint32_t port);
- /**
- * \brief Disable root functionality at a
- * given port
- */
- void UnSetRoot (uint32_t port);
- /**
- * \brief HwmpState retrns to Hwmp class all
- * routing information obtained from all HWMP
- * action frames
- */
- void ObtainRoutingInformation (
- HwmpState::INFO info
- );
- /**
- * \brief Hwmp state noyifyes that neighbour
- * is dissapeared. Hwmp state knows about peer
- * failure from MAC
- */
- void PeerFailure (Mac48Address peerAddress);
- void SetMaxTtl (uint8_t ttl);
- uint8_t GetMaxTtl ();
-private:
- static const uint32_t MAX_SEQNO = 0xffffffff;
- //candidate queue is implemented inside the
- //protocol:
- void SetMaxQueueSize (int maxPacketsPerDestination);
- int m_maxQueueSize;
- bool QueuePacket (MeshL2RoutingProtocol::QueuedPacket packet);
- MeshL2RoutingProtocol::QueuedPacket DequeuePacket (Mac48Address dst);
- void SendAllPossiblePackets (Mac48Address dst);
- std::map<Mac48Address, std::queue<QueuedPacket> > m_rqueue;
- //devices and HWMP states:
- enum DeviceState {
- ENABLED,
- DISABLED
- };
- enum DeviceMode {
- REACTIVE,
- PROACTIVE,
- ROOT
- };
- std::vector<enum DeviceState> m_states;
- std::vector<enum DeviceMode> m_modes;
- std::vector<Ptr<HwmpState> > m_hwmpStates;
- //Routing table:
- Ptr<HwmpRtable> m_rtable;
- //Proactive routines:
- /**
- * \brief Set port state as proactive.
- * \details mode is supposed to be proactive
- * when proatcive PREQ with a valid
- * information was received.
- */
- void SetProactive (uint32_t port);
- /**
- * \brief Checks if the port is root, if true
- * - no default routes must be used at this
- * port
- */
- bool IsRoot (uint32_t port);
- /**
- * \brief Interaction with HwmpState class -
- * request for starting routing discover
- * procedure (reactive route discovery!)
- * \param Mac48Address is destination to be
- * resolved
- */
- std::vector< Callback<void, Mac48Address> > m_requestCallback;
- /**
- * \brief Callback that shall be executed when
- * need to send Path error
- * \param std::vector<Mac48Address> is the
- * list of unreachable destinations
- * \param std::vector<Mac48Address> is
- * receivers of PERR
- */
- std::vector<Callback<void,std::vector<HwmpRtable::FailedDestination> > > m_pathErrorCallback;
- void StartPathErrorProcedure (
- std::vector<HwmpRtable::FailedDestination> destinations,
- uint32_t port);
- /**
- * \brief HwmpState need to know where to
- * retransmit PERR, only HWMP knows how to
- * retransmit it (broadcast/unicast) and only
- * HWMP has accessto routing table
- */
- std::vector<Mac48Address> GetRetransmittersForFailedDestinations (
- std::vector<HwmpRtable::FailedDestination> failedDest,
- uint32_t port);
- /**
- * \brief Needed by HwmpState to find routes in case
- * of intermediate reply and choosing the
- * better route
- *
- */
- HwmpRtable::LookupResult RequestRouteForAddress (const Mac48Address& destination);
- HwmpRtable::LookupResult RequestRootPathForPort (uint32_t port);
-
- /**
- * \attention mesh seqno is processed at HWMP
- */
- uint32_t m_seqno;
- std::map<Mac48Address, uint32_t/**/> m_seqnoDatabase;
- //Timers:
- /**
- * /brief checks when last preq was initiated, returns
- * false when retry has not expired
- */
- bool ShouldSendPreq (Mac48Address dst);
- /**
- * \brief Generates PREQ retry when route is
- * still unresolved after first PREQ
- * If number of retries greater than
- * dot11sParameters::dot11MeshHWMPmaxPREQretries,
- * we return all packets to upper layers
- */
- void RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry);
- /**
- * Keeps PREQ retry timers for every
- * destination
- */
- std::map<Mac48Address, EventId> m_timeoutDatabase;
- /**
- * Configurable parameters:
- */
- uint8_t m_maxTtl;
- bool m_broadcastPerr;
-};
-} //namespace ns3
-#endif
--- a/src/devices/mesh/mesh-mgt-headers.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +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 "ns3/mesh-mgt-headers.h"
-#include "ns3/address-utils.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-/***********************************************************
- * Mesh Beacon
- ***********************************************************/
-void
-MgtMeshBeaconHeader::SetIeDot11sConfiguration (IeDot11sConfiguration mesh_config)
-{
- m_meshConfig = mesh_config;
-}
-
-void
-MgtMeshBeaconHeader::SetIeDot11sBeaconTiming (IeDot11sBeaconTiming wifi_timing)
-{
- m_meshTiming = wifi_timing;
-}
-
-IeDot11sConfiguration
-MgtMeshBeaconHeader::GetIeDot11sConfiguration ()
-{
- return m_meshConfig;
-}
-
-IeDot11sBeaconTiming
-MgtMeshBeaconHeader::GetIeDot11sBeaconTiming ()
-{
- return m_meshTiming;
-}
-
-uint32_t
-MgtMeshBeaconHeader::GetSerializedSize () const
-{
- uint32_t size = (
- MgtBeaconHeader::GetSerializedSize ()
- + m_meshConfig.GetSerializedSize ()
- + m_meshTiming.GetSerializedSize ()
- + 9 //MSCIE
- );
- return size;
-}
-void
-MgtMeshBeaconHeader::Serialize (Buffer::Iterator start) const
-{
- //First we pack Beacon:
- Buffer::Iterator i = start;
- MgtBeaconHeader::Serialize (i);
- i.Next (MgtBeaconHeader::GetSerializedSize ());
- m_meshConfig.Serialize (i);
- i.Next (m_meshConfig.GetSerializedSize());
- m_meshTiming.Serialize (i);
- i.Next (m_meshTiming.GetSerializedSize());
- i.Next (9); //MSCIE
-}
-
-uint32_t
-MgtMeshBeaconHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- MgtBeaconHeader::Deserialize (start);
- i.Next (MgtBeaconHeader::GetSerializedSize ());
- m_meshConfig.Deserialize (i);
- i.Next (m_meshConfig.GetSerializedSize());
- i.Next (m_meshTiming.Deserialize(i));
- i.Next (9); //MSCIE
- return i.GetDistanceFrom (start);
-}
-
-
-/***********************************************************
-* PeerLinkOpen frame:
-************************************************************/
-NS_OBJECT_ENSURE_REGISTERED (MeshMgtPeerLinkManFrame);
-
-MeshMgtPeerLinkManFrame::MeshMgtPeerLinkManFrame ()
-{
-}
-
-void
-MeshMgtPeerLinkManFrame::SetAid (uint16_t aid)
-{
- Aid = aid;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetSupportedRates (SupportedRates rates)
-{
- Rates = rates;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetQosField (uint16_t qos)
-{
- QoS = qos;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetMeshId (Ssid Id)
-{
- MeshId = Id;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetIeDot11sConfiguration (IeDot11sConfiguration MeshConf)
-{
- MeshConfig = MeshConf;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetIeDot11sPeerManagement (IeDot11sPeerManagement meshPeerElement)
-{
- PeerLinkMan = meshPeerElement;
-}
-
-uint16_t
-MeshMgtPeerLinkManFrame::GetAid ()
-{
- return Aid;
-}
-
-SupportedRates
-MeshMgtPeerLinkManFrame::GetSupportedRates ()
-{
- return Rates;
-}
-
-uint16_t
-MeshMgtPeerLinkManFrame::GetQosField ()
-{
- return QoS;
-}
-
-Ssid
-MeshMgtPeerLinkManFrame::GetMeshId ()
-{
- return MeshId;
-}
-
-IeDot11sConfiguration
-MeshMgtPeerLinkManFrame::GetIeDot11sConfiguration ()
-{
- return MeshConfig;
-}
-
-IeDot11sPeerManagement
-MeshMgtPeerLinkManFrame::GetIeDot11sPeerManagement ()
-{
- return PeerLinkMan;
-}
-
-TypeId
-MeshMgtPeerLinkManFrame::GetTypeId ()
-{
- static TypeId tid =
- TypeId ("ns3::MeshMgtPeerLinkManFrame")
- .SetParent<Header> ()
- .AddConstructor<MeshMgtPeerLinkManFrame> ()
- ;
- return tid;
-}
-
-TypeId
-MeshMgtPeerLinkManFrame::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-void
-MeshMgtPeerLinkManFrame::Print (std::ostream &os) const
-{
- //TODO:fill this method
-}
-
-uint32_t
-MeshMgtPeerLinkManFrame::GetSerializedSize () const
-{
- uint32_t size = 1; //Subtype
- if (MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
- size += 2; //AID of remote peer
- if (MESH_MGT_HEADER_PEER_CLOSE != Subtype)
- {
- size += Rates.GetSerializedSize ();
- size += 2;
- size += MeshId.GetSerializedSize ();
- size += MeshConfig.GetSerializedSize ();
- }
- size += PeerLinkMan.GetSerializedSize ();
- return size;
-}
-
-void
-MeshMgtPeerLinkManFrame::Serialize (Buffer::Iterator start) const
-{
- Buffer::Iterator i = start;
- i.WriteU8 (Subtype); //Like a Category in Standart
- if (MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
-
- i.WriteHtonU16 (Aid);
- if (MESH_MGT_HEADER_PEER_CLOSE != Subtype)
- {
- i = Rates.Serialize (i);
- //now QoS capabilities
- i.WriteHtonU16 (QoS);
- i = MeshId.Serialize (i);
- MeshConfig.Serialize (i);
- i.Next (MeshConfig.GetSerializedSize());
- }
- PeerLinkMan.Serialize (i);
- i.Next (PeerLinkMan.GetSerializedSize());
-}
-
-uint32_t
-MeshMgtPeerLinkManFrame::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- Subtype = i.ReadU8 ();
- if (MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
- Aid = i.ReadNtohU16 ();
- if (MESH_MGT_HEADER_PEER_CLOSE != Subtype)
- {
- i = Rates.Deserialize (i);
- QoS = i.ReadNtohU16 ();
- i = MeshId.Deserialize (i);
- MeshConfig.Deserialize (i);
- i.Next (MeshConfig.GetSerializedSize());
- }
- PeerLinkMan.Deserialize (i);
- i.Next (PeerLinkMan.GetSerializedSize());
- return i.GetDistanceFrom (start);
-}
-void
-MeshMgtPeerLinkManFrame::SetOpen ()
-{
- Subtype = MESH_MGT_HEADER_PEER_OPEN;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetConfirm ()
-{
- Subtype = MESH_MGT_HEADER_PEER_CONFIRM;
-}
-
-void
-MeshMgtPeerLinkManFrame::SetClose ()
-{
- Subtype = MESH_MGT_HEADER_PEER_CLOSE;
-}
-
-bool
-MeshMgtPeerLinkManFrame::IsOpen ()
-{
- return (Subtype == MESH_MGT_HEADER_PEER_OPEN);
-}
-
-bool
-MeshMgtPeerLinkManFrame::IsConfirm ()
-{
- return (Subtype == MESH_MGT_HEADER_PEER_CONFIRM);
-}
-
-bool
-MeshMgtPeerLinkManFrame::IsClose ()
-{
- return (Subtype == MESH_MGT_HEADER_PEER_CLOSE);
-}
-
-} //namespace NS3
-
-
--- a/src/devices/mesh/mesh-mgt-headers.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +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>
- */
-
-
-#ifndef MESH_MGT_HEADERS_H
-#define MESH_MGT_HEADERS_H
-
-#include "ns3/header.h"
-#include "ns3/supported-rates.h"
-#include "ns3/ie-dot11s-peer-management.h"
-#include "ns3/ie-dot11s-configuration.h"
-#include "ns3/ie-dot11s-beacon-timing.h"
-#include "ns3/mgt-headers.h"
-#include "ns3/ssid.h"
-
-namespace ns3 {
-/**
- * \ingroup mesh
- */
-class MgtMeshBeaconHeader : public MgtBeaconHeader
-{
-public:
- void SetIeDot11sConfiguration (IeDot11sConfiguration mesh_config);
- void SetIeDot11sBeaconTiming (IeDot11sBeaconTiming wifi_timing);
- IeDot11sConfiguration GetIeDot11sConfiguration ();
- IeDot11sBeaconTiming GetIeDot11sBeaconTiming ();
- virtual uint32_t GetSerializedSize () const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
-
-private:
- IeDot11sConfiguration m_meshConfig;
- IeDot11sBeaconTiming m_meshTiming;
-};
-
-/**
- * \ingroup mesh
- */
-class MeshMgtPeerLinkManFrame : public Header
-{
-public:
- MeshMgtPeerLinkManFrame ();
- void SetAid (uint16_t aid);
- void SetSupportedRates (SupportedRates rates);
- void SetQosField (uint16_t qos);
- void SetMeshId (Ssid Id);
- void SetIeDot11sConfiguration (IeDot11sConfiguration MeshConf);
- void SetIeDot11sPeerManagement (IeDot11sPeerManagement meshPeerElement);
-
- uint16_t GetAid ();
- SupportedRates GetSupportedRates ();
- uint16_t GetQosField ();
- Ssid GetMeshId ();
- IeDot11sConfiguration GetIeDot11sConfiguration ();
- IeDot11sPeerManagement GetIeDot11sPeerManagement ();
-
- static TypeId GetTypeId ();
- virtual TypeId GetInstanceTypeId () const;
- virtual void Print (std::ostream &os) const;
- virtual uint32_t GetSerializedSize () const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
- //Subtype defining methods:
- void SetOpen ();
- void SetConfirm ();
- void SetClose ();
-
- bool IsOpen ();
- bool IsConfirm ();
- bool IsClose ();
-
-private:
- uint8_t Subtype;
- static const uint8_t MESH_MGT_HEADER_PEER_OPEN = 1;
- static const uint8_t MESH_MGT_HEADER_PEER_CONFIRM = 2;
- static const uint8_t MESH_MGT_HEADER_PEER_CLOSE = 3;
- // Standart is also requires a ReasonCode to be within
- // PeerLinkClose frame format, but it is present within
- // IeDot11sPeerManagement, so we did not duplicate
- // it.
- uint16_t Aid; //only in Confirm
- SupportedRates Rates; //only in Open and Confirm
- uint16_t QoS; //only in Open and Confirm
- Ssid MeshId; //only in Open and Confirm
- IeDot11sConfiguration MeshConfig; //only in Open and Confirm
- IeDot11sPeerManagement PeerLinkMan; //in all types of frames
-};
-
-}//namespace NS3
-#endif
-
--- a/src/devices/mesh/mesh-wifi-mac-header.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-/* -*- 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: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#include "ns3/assert.h"
-#include "ns3/address-utils.h"
-#include "ns3/mesh-wifi-mac-header.h"
-
-namespace ns3 {
-
-/***********************************************************
- * Here Mesh Mac Header functionality is defined.
- ***********************************************************/
-TypeId
-WifiMeshHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::WifiMeshHeader")
- .SetParent<Header> ()
- .AddConstructor<WifiMeshHeader> ()
- ;
- return tid;
-}
-
-WifiMeshHeader::WifiMeshHeader ()
- :m_meshFlags (0)
-{
-}
-
-WifiMeshHeader::~WifiMeshHeader ()
-{
-}
-
-TypeId
-WifiMeshHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-void
-WifiMeshHeader::SetAddr5 (Mac48Address address)
-{
- m_addr5 = address;
-}
-
-void
-WifiMeshHeader::SetAddr6 (Mac48Address address)
-{
- m_addr6 = address;
-}
-
-void
-WifiMeshHeader::SetAddr7 (Mac48Address address)
-{
- m_addr7 = address;
-}
-
-Mac48Address
-WifiMeshHeader::GetAddr5 ()
-{
- return m_addr5;
-}
-
-Mac48Address
-WifiMeshHeader::GetAddr6 ()
-{
- return m_addr6;
-}
-
-Mac48Address
-WifiMeshHeader::GetAddr7 ()
-{
- return m_addr7;
-}
-
-void
-WifiMeshHeader::SetMeshSeqno (uint32_t seqno)
-{
- m_meshSeqno = seqno;
-}
-
-uint32_t
-WifiMeshHeader::GetMeshSeqno ()
-{
- return m_meshSeqno;
-}
-
-void
-WifiMeshHeader::SetMeshTtl (uint8_t TTL)
-{
- m_meshTtl = TTL;
-}
-
-uint8_t
-WifiMeshHeader::GetMeshTtl ()
-{
- return m_meshTtl;
-}
-
-void
-WifiMeshHeader::SetAddressExt (uint8_t num_of_addresses)
-{
- if (num_of_addresses > 3)
- return;
- m_meshFlags = 0xc0 | (num_of_addresses << 6);
-}
-
-uint8_t
-WifiMeshHeader::GetAddressExt ()
-{
- return ((0xc0 & m_meshFlags) >> 6);
-}
-
-
-uint32_t
-WifiMeshHeader::GetSerializedSize () const
-{
- return 6 + ((0xc0 & m_meshFlags) >> 6)*6;
-}
-
-void
-WifiMeshHeader::Serialize (Buffer::Iterator start) const
-{
- Buffer::Iterator i = start;
- i.WriteU8 (m_meshFlags);
- i.WriteU8 (m_meshTtl);
- i.WriteU32 (m_meshSeqno);
- uint8_t addresses_to_add = (m_meshFlags & 0xc0) >> 6;
- //Writing Address extensions:
- if (addresses_to_add > 0)
- WriteTo (i, m_addr5);
- if (addresses_to_add > 1)
- WriteTo (i, m_addr6);
- if (addresses_to_add > 2)
- WriteTo (i, m_addr7);
-}
-
-uint32_t
-WifiMeshHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- uint8_t addresses_to_read = 0;
- m_meshFlags = i.ReadU8 ();
- m_meshTtl = i.ReadU8 ();
- m_meshSeqno = i.ReadU32 ();
- addresses_to_read = (m_meshFlags & 0xc0) >> 6;
- if (addresses_to_read > 0)
- ReadFrom (i, m_addr5);
- if (addresses_to_read > 1)
- ReadFrom (i, m_addr6);
- if (addresses_to_read > 2)
- ReadFrom (i, m_addr7);
- return i.GetDistanceFrom (start);
-}
-void
-WifiMeshHeader::Print (std::ostream &os) const
-{
- os << "flags" << m_meshFlags
- << "ttl" << m_meshTtl
- << "seqno" << m_meshSeqno;
-}
-/**********************************************************
- * MultihopActionFrame
- **********************************************************/
-WifiMeshMultihopActionHeader::WifiMeshMultihopActionHeader ()
-{
-}
-
-WifiMeshMultihopActionHeader::~WifiMeshMultihopActionHeader ()
-{
-}
-
-void
-WifiMeshMultihopActionHeader::SetAction (
- enum WifiMeshMultihopActionHeader::CategoryValue type,
- WifiMeshMultihopActionHeader::ACTION_VALUE action)
-{
- switch (type)
- {
- case MESH_PEER_LINK_MGT:
- m_category = 4;
- switch (action.peerLink)
- {
- case PEER_LINK_OPEN:
- m_actionValue = 0;
- break;
- case PEER_LINK_CONFIRM:
- m_actionValue = 1;
- break;
- case PEER_LINK_CLOSE:
- m_actionValue = 2;
- break;
- };
- break;
- case MESH_LINK_METRIC:
- m_category = 5;
- break;
- case MESH_PATH_SELECTION:
- m_category = 6;
- switch (action.pathSelection)
- {
- case PATH_REQUEST:
- m_actionValue = 0;
- break;
- case PATH_REPLY:
- m_actionValue = 1;
- break;
- case PATH_ERROR:
- m_actionValue = 2;
- break;
- case ROOT_ANNOUNCEMENT:
- m_actionValue = 3;
- break;
- };
- break;
- case MESH_INTERWORK_ACTION:
- m_category = 7;
- break;
- case MESH_RESOURCE_COORDINATION:
- m_category = 8;
- break;
- };
-}
-
-enum WifiMeshMultihopActionHeader::CategoryValue
-WifiMeshMultihopActionHeader::GetCategory ()
-{
- switch (m_category)
- {
- case 4:
- return MESH_PEER_LINK_MGT;
- case 5:
- return MESH_LINK_METRIC;
- case 6:
- return MESH_PATH_SELECTION;
- case 7:
- return MESH_INTERWORK_ACTION;
- case 8:
- return MESH_RESOURCE_COORDINATION;
- default:
- NS_ASSERT (false);
- return MESH_PEER_LINK_MGT;
- }
-}
-
-WifiMeshMultihopActionHeader::ACTION_VALUE
-WifiMeshMultihopActionHeader::GetAction ()
-{
- ACTION_VALUE retval;
- switch (m_category)
- {
- case 4:
- //MESH_PEER_LINK_MGT;
- switch (m_actionValue)
- {
- case 0:
- retval.peerLink = PEER_LINK_OPEN;
- return retval;
- case 1:
- retval.peerLink = PEER_LINK_CONFIRM;
- return retval;
- case 2:
- retval.peerLink = PEER_LINK_CLOSE;
- return retval;
- default:
- NS_ASSERT (false);
- return retval;
-
- }
- case 5:
- //MESH_LINK_METRIC;
- case 6:
- //MESH_PATH_SELECTION;
- switch (m_actionValue)
- {
- case 0:
- retval.pathSelection = PATH_REQUEST;
- return retval;
- case 1:
- retval.pathSelection = PATH_REPLY;
- return retval;
- case 2:
- retval.pathSelection = PATH_ERROR;
- return retval;
- case 3:
- retval.pathSelection = ROOT_ANNOUNCEMENT;
- return retval;
- default:
- NS_ASSERT (false);
- return retval;
- }
-
- case 7:
- //MESH_INTERWORK_ACTION;
- case 8:
- //MESH_RESOURCE_COORDINATION;
- default:
- NS_ASSERT (false);
- return retval;
- }
-}
-
-TypeId
-WifiMeshMultihopActionHeader::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::WifiMeshMultihopActionHeader")
- .SetParent<Header> ()
- .AddConstructor<WifiMeshMultihopActionHeader> ()
- ;
- return tid;
-}
-
-TypeId
-WifiMeshMultihopActionHeader::GetInstanceTypeId () const
-{
- return GetTypeId ();
-}
-
-void
-WifiMeshMultihopActionHeader::Print (std::ostream &os) const
-{
-}
-
-uint32_t
-WifiMeshMultihopActionHeader::GetSerializedSize () const
-{
- return 2;
-}
-
-void
-WifiMeshMultihopActionHeader::Serialize (Buffer::Iterator start) const
-{
- start.WriteU8 (m_category);
- start.WriteU8 (m_actionValue);
-}
-
-uint32_t
-WifiMeshMultihopActionHeader::Deserialize (Buffer::Iterator start)
-{
- Buffer::Iterator i = start;
- m_category = i.ReadU8 ();
- m_actionValue = i.ReadU8 ();
- return i.GetDistanceFrom (start);
-}
-
-} // namespace ns3
--- a/src/devices/mesh/mesh-wifi-mac-header.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/* -*- 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: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#ifndef MESH_WIFI_MAC_HEADER_H
-#define MESH_WIFI_MAC_HEADER_H
-
-#include "ns3/header.h"
-#include "ns3/mac48-address.h"
-
-namespace ns3 {
-/**
- * \ingroup mesh
- */
-class WifiMeshHeader : public Header //7.1.3.5b
-{
-public:
- WifiMeshHeader ();
- ~WifiMeshHeader ();
- static TypeId GetTypeId ();
- virtual TypeId GetInstanceTypeId () const;
- virtual void Print (std::ostream &os) const;
-
- void SetAddr5 (Mac48Address address);
- void SetAddr6 (Mac48Address address);
- void SetAddr7 (Mac48Address address);
- Mac48Address GetAddr5 ();
- Mac48Address GetAddr6 ();
- Mac48Address GetAddr7 ();
-
- void SetMeshSeqno (uint32_t seqno);
- uint32_t GetMeshSeqno ();
-
- void SetMeshTtl (uint8_t TTL);
- uint8_t GetMeshTtl ();
-
- void SetAddressExt (uint8_t num_of_addresses);
- uint8_t GetAddressExt ();
-
- virtual uint32_t GetSerializedSize () const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
-private:
- uint8_t m_meshFlags;
- uint8_t m_meshTtl;
- uint32_t m_meshSeqno;
- Mac48Address m_addr5;
- Mac48Address m_addr6;
- Mac48Address m_addr7;
-};
-
-/**
- * \ingroup mesh
- */
-class WifiMeshMultihopActionHeader : public Header //7.2.3.14
-{
- //Multichop action frame consists of Mesh header, Action, and
- //the last information. Mesh header is present within all data
- //frames and multihop action frames, so Mesh header is a
- //separate structure. Each MultihopAction frames (frames like
- //PREQ, PREP and other) start form Category field and Action
- //value field, so the Multihop Action Frame should containt
- //three fields: Category, Action Value;
-public:
- WifiMeshMultihopActionHeader ();
- ~WifiMeshMultihopActionHeader ();
- enum CategoryValue //table 7-24 staring from 4
- {
- MESH_PEER_LINK_MGT =4,
- MESH_LINK_METRIC,
- MESH_PATH_SELECTION,
- MESH_INTERWORK_ACTION,
- MESH_RESOURCE_COORDINATION,
- };
- enum PeerLinkMgtActionValue
- {
- PEER_LINK_OPEN = 0,
- PEER_LINK_CONFIRM,
- PEER_LINK_CLOSE,
- };
- enum LinkMetricActionValue
- {
- LINK_METRIC_REQUEST = 0,
- LINK_METRIC_REPORT,
- };
- enum PathSelectionActionValue
- {
- PATH_REQUEST = 0,
- PATH_REPLY,
- PATH_ERROR,
- ROOT_ANNOUNCEMENT,
- };
- enum InterworkActionValue
- {
- PORTAL_ANNOUNCEMENT = 0,
- };
- enum ResourceCoordinationActionValue
- {
- CONGESTION_CONTROL_NOTIFICATION = 0,
- MDA_SETUP_REQUEST,
- MDA_SETUP_REPLY,
- MDAOP_ADVERTISMENT_REQUEST,
- MDAOP_ADVERTISMENTS,
- MDAOP_SET_TEARDOWN,
- BEACON_TIMING_REQUEST,
- BEACON_TIMING_RESPONSE,
- TBTT_ADJASTMENT_REQUEST,
- MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
- };
- typedef union
- {
- enum PeerLinkMgtActionValue peerLink;
- enum LinkMetricActionValue linkMetrtic;
- enum PathSelectionActionValue pathSelection;
- enum InterworkActionValue interwork;
- enum ResourceCoordinationActionValue resourceCoordination;
- } ACTION_VALUE;
- void SetAction (enum CategoryValue type,ACTION_VALUE action);
- enum CategoryValue GetCategory ();
- ACTION_VALUE GetAction ();
- static TypeId GetTypeId ();
- virtual TypeId GetInstanceTypeId () const;
- virtual void Print (std::ostream &os) const;
- virtual uint32_t GetSerializedSize () const;
- virtual void Serialize (Buffer::Iterator start) const;
- virtual uint32_t Deserialize (Buffer::Iterator start);
-private:
- uint8_t m_category;
- uint8_t m_actionValue;
-};
-} // namespace ns3
-#endif /* MESH_WIFI_MAC_HEADER_H */
--- a/src/devices/mesh/mesh-wifi-mac.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,962 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- */
-
-
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/node.h"
-#include "ns3/random-variable.h"
-#include "ns3/mesh-wifi-mac.h"
-#include "ns3/dca-txop.h"
-#include "ns3/wifi-mac-header.h"
-#include "ns3/mesh-wifi-mac-header.h"
-#include "ns3/mgt-headers.h"
-#include "ns3/wifi-phy.h"
-#include "ns3/dcf-manager.h"
-#include "ns3/mac-rx-middle.h"
-#include "ns3/mac-low.h"
-#include "ns3/tx-statistics.h"
-#include "ns3/hwmp.h"
-#include "ns3/ie-dot11s-beacon-timing.h"
-#include "ns3/mgt-headers.h"
-#include "ns3/wifi-remote-station-manager.h"
-#include "ns3/mesh-wifi-peer-manager.h"
-
-NS_LOG_COMPONENT_DEFINE ("MeshWifiMac");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (MeshWifiMac);
-
-TypeId
-MeshWifiMac::GetTypeId ()
-{
- static TypeId tid = TypeId ("ns3::MeshWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<MeshWifiMac> ()
- .AddAttribute ("BeaconInterval", "Beacon Interval",
- TimeValue (Seconds (1.0)),
- MakeTimeAccessor (&MeshWifiMac::m_beaconInterval),
- MakeTimeChecker ()
- )
- .AddAttribute ("RandomStart", "Window when beacon generating starts (uniform random) in seconds",
- TimeValue (Seconds (0.1)),
- MakeTimeAccessor (&MeshWifiMac::m_randomStart),
- MakeTimeChecker ()
- )
- .AddAttribute ("SoftwareDelay", "Window of uniformely distributed random software handling delay",
- TimeValue (MicroSeconds (500)),
- MakeTimeAccessor (&MeshWifiMac::m_softwareDelay),
- MakeTimeChecker ()
- )
- .AddAttribute ("BeaconGeneration", "Enable/Disable Beaconing.",
- BooleanValue (true),
- MakeBooleanAccessor (
- &MeshWifiMac::SetBeaconGeneration,
- &MeshWifiMac::GetBeaconGeneration
- ),
- MakeBooleanChecker ()
- );
- return tid;
-}
-
-MeshWifiMac::MeshWifiMac ()
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiMac::Receive, this));
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_beaconDca = CreateObject<DcaTxop> ();
- 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<DcaTxop> ();
- m_VO->SetLow (m_low);
- m_VO->SetMinCw (3);
- m_VO->SetMaxCw (7);
- m_VO->SetManager (m_dcfManager);
- m_VO->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
- m_VO->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
-
- m_BE = CreateObject<DcaTxop> ();
- m_BE->SetLow (m_low);
- m_BE->SetManager (m_dcfManager);
- m_BE->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
- m_BE->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
-}
-
-MeshWifiMac::~MeshWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-/*
- * Public Methods:
- */
-void
-MeshWifiMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_slot = slotTime;
-}
-
-void
-MeshWifiMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_sifs = sifs;
-}
-void
-MeshWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-
-void
-MeshWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-
-void
-MeshWifiMac::SetPifs (Time pifs)
-{
- NS_LOG_FUNCTION (this << pifs);
- m_pifs = pifs;
-}
-void
-MeshWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
- m_eifsNoDifs = eifsNoDifs;
-}
-
-Time
-MeshWifiMac::GetSlot () const
-{
- return m_slot;
-}
-
-Time
-MeshWifiMac::GetSifs () const
-{
- return m_sifs;
-}
-
-Time
-MeshWifiMac::GetEifsNoDifs () const
-{
- return m_eifsNoDifs;
-}
-
-Time
-MeshWifiMac::GetAckTimeout () const
-{
- return m_low->GetAckTimeout ();
-}
-
-Time
-MeshWifiMac::GetCtsTimeout () const
-{
- return m_low->GetCtsTimeout ();
-}
-
-Time
-MeshWifiMac::GetPifs () const
-{
- return m_low->GetPifs ();
-}
-
-void
-MeshWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- NS_LOG_FUNCTION (this << phy);
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-
-void
-MeshWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> 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
-MeshWifiMac::SetPeerLinkManager (Ptr<WifiPeerManager> manager)
-{
- m_peerManager = manager;
-}
-
-void
-MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_LOG_FUNCTION (this << packet << to << from);
- ForwardDown (packet, from, to);
-}
-
-void
-MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << to);
- ForwardDown (packet, m_low->GetAddress (), to);
-}
-
-bool
-MeshWifiMac::SupportsSendFrom () const
-{
- return true;
-}
-
-void
-MeshWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- NS_LOG_FUNCTION (this);
- m_upCallback = upCallback;
-}
-
-void
-MeshWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- NS_LOG_FUNCTION (this);
- if (!linkUp.IsNull ())
- {
- linkUp ();
- }
-}
-
-void
-MeshWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- NS_LOG_FUNCTION (this);
-}
-
-Mac48Address
-MeshWifiMac::GetAddress () const
-{
- return m_address;
-}
-Mac48Address
-MeshWifiMac::GetBssid () const
-{
- return m_address;
-}
-
-Ssid
-MeshWifiMac::GetSsid () const
-{
- return m_MeshId;
-}
-
-void
-MeshWifiMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (address);
- m_low->SetAddress (address);
- m_address = address;
-}
-
-void
-MeshWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (ssid);
- m_MeshId = ssid;
-}
-
-void
-MeshWifiMac::SetBeaconInterval (Time interval)
-{
- NS_LOG_FUNCTION (this << interval);
- m_beaconInterval = interval;
-}
-
-void
-MeshWifiMac::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_peerManager = 0;
- m_beaconSendEvent.Cancel ();
- m_beaconFormEvent.Cancel ();
- m_beaconDca = 0;
- WifiMac::DoDispose ();
-}
-
-void
-MeshWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst)
-{
- NS_LOG_FUNCTION (this << packet << src);
- m_upCallback (packet, src, dst);
-}
-
-void
-MeshWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
-{
- //TODO:Classify and queue
- WifiMacHeader hdr;
- Ptr<Packet> packet_to_send = packet->Copy ();
- WifiMeshHeader meshHdr;
- //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());
- hdr.SetTypeData ();
- hdr.SetAddr1 (tag.GetAddress ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (to);
- hdr.SetAddr4 (from);
- hdr.SetDsFrom ();
- hdr.SetDsTo ();
- //TODO: classify should be fixed!
- packet_to_send->AddHeader (meshHdr);
- WifiRemoteStation *destination = m_stationManager->Lookup (to);
-
- if (destination->IsBrandNew ())
- {
- // in adhoc mode, we assume that every destination
- // supports all the rates we support.
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
- {
- destination->AddSupportedMode (m_phy->GetMode (i));
- }
- destination->RecordDisassociated ();
- }
- m_BE->Queue (packet_to_send, hdr);
-}
-
-SupportedRates
-MeshWifiMac::GetSupportedRates () const
-{
- // send the set of supported rates and make sure that we indicate
- // the Basic Rate set in this set of supported rates.
- SupportedRates rates;
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
- {
- WifiMode mode = m_phy->GetMode (i);
- rates.AddSupportedRate (mode.GetDataRate ());
- }
- // set the basic rates
- for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
- {
- WifiMode mode = m_stationManager->GetBasicMode (j);
- rates.SetBasicRate (mode.GetDataRate ());
- }
- return rates;
-}
-
-void
-MeshWifiMac::SendOneBeacon ()
-{
- NS_LOG_FUNCTION (this);
- NS_LOG_DEBUG (GetAddress()<<" is sending beacon");
- //Software delay should never be bigger than beacon interval!
- NS_ASSERT (!m_beaconSendEvent.IsRunning());
- Time last_software_delay = m_beaconFormingRandomDelay;
- MgtMeshBeaconHeader beacon;
- beacon.SetSsid (GetSsid ());
- beacon.SetSupportedRates (GetSupportedRates ());
- beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- beacon.SetIeDot11sBeaconTiming (m_peerManager->GetIeDot11sBeaconTimingForMyBeacon(GetAddress()));
- m_beaconSendEvent = Simulator::Schedule (
- m_beaconFormingRandomDelay,
- &MeshWifiMac::QueueOneBeacon,
- this,
- beacon);
- UniformVariable coefficient (0.0, m_beaconFormingRandomDelay.GetSeconds());
- m_beaconFormingRandomDelay = Seconds (coefficient.GetValue());
-
- //MBCA functionality, TODO: add the switch off/on MBCA mechanism capability
- //Let's find when we send the next beacon
- Time myNextTBTT = Simulator::Now ()+m_beaconInterval+last_software_delay;
- //The mext function compares my TBTT with neighbor's TBTTs using timing elemnt
- //and returns time shift for the next beacon if future collision is detected
- Time nextBeaconShift = m_peerManager->GetNextBeaconShift (GetAddress(), myNextTBTT);
-
- m_beaconFormEvent = Simulator::Schedule (m_beaconInterval-m_beaconFormingRandomDelay+last_software_delay+nextBeaconShift, &MeshWifiMac::SendOneBeacon, this);
-}
-
-void
-MeshWifiMac::QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr)
-{
- WifiMacHeader hdr;
- hdr.SetBeacon ();
- hdr.SetAddr1 (Mac48Address::GetBroadcast ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
-
- packet->AddHeader (beacon_hdr);
- m_beaconDca->Queue (packet, hdr);
- m_peerManager->SetSentBeaconTimers (
- GetAddress (),
- Simulator::Now (),
- MicroSeconds (beacon_hdr.GetBeaconIntervalUs())
- );
-
-}
-void
-MeshWifiMac::SetBeaconGeneration (bool enable)
-{
- NS_LOG_FUNCTION (this << enable);
- if (enable)
- {
- UniformVariable coefficient (0.0, m_randomStart.GetSeconds());
- Time randomStart = Seconds (coefficient.GetValue());
- // Beacons must be sent with a random delay,
- // otherwise, they will all be broken
- m_beaconFormEvent = Simulator::Schedule (randomStart, &MeshWifiMac::SendOneBeacon, this);
- }
- else
- m_beaconFormEvent.Cancel ();
-}
-
-bool
-MeshWifiMac::GetBeaconGeneration () const
-{
- return m_beaconFormEvent.IsRunning ();
-}
-
-void
-MeshWifiMac::TxOk (WifiMacHeader const &hdr)
-{
-}
-
-void
-MeshWifiMac::TxFailed (WifiMacHeader const &hdr)
-{
-}
-
-void
-MeshWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
-{
- if (hdr->IsBeacon ())
- {
- MgtMeshBeaconHeader beacon;
- Mac48Address from = hdr->GetAddr2 ();
- packet->RemoveHeader (beacon);
- NS_LOG_DEBUG ("Beacon received from "<<hdr->GetAddr2()<<
- " to "<<GetAddress ()<<
- " at "<<Simulator::Now ().GetMicroSeconds ()<<
- " microseconds");
-#if 0
- NeighboursTimingUnitsList neighbours;
- neighbours = beacon.GetIeDot11sBeaconTiming ().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.GetIeDot11sBeaconTiming ()
- );
- 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 IeDot11sConfiguration (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.GetIeDot11sPeerManagement (),
- m_meshConfig
- );
- return;
- case WifiMeshMultihopActionHeader::PEER_LINK_OPEN:
- m_peerManager->SetOpenReceived (
- GetAddress (),
- peerAddress,
- peer_frame.GetIeDot11sPeerManagement (),
- m_meshConfig
- );
- return;
- case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE:
- m_peerManager->SetCloseReceived (
- GetAddress (),
- peerAddress,
- peer_frame.GetIeDot11sPeerManagement ()
- );
- return;
- default:
- return;
- }
- break;
- }
- case WifiMeshMultihopActionHeader::MESH_PATH_SELECTION:
- {
- if (!m_peerManager->IsActiveLink (GetAddress(), hdr->GetAddr2()))
- return;
- switch (actionValue.pathSelection)
- {
- case WifiMeshMultihopActionHeader::PATH_REQUEST:
- {
- IeDot11sPreq preq;
- packet->RemoveHeader (preq);
- //TODO:recalculate
- //metric
- m_preqReceived (preq, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
- return;
- }
- case WifiMeshMultihopActionHeader::PATH_REPLY:
- {
- IeDot11sPrep prep;
- packet->RemoveHeader (prep);
- m_prepReceived (prep, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
- }
- return;
- case WifiMeshMultihopActionHeader::PATH_ERROR:
- {
- IeDot11sPerr 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="<<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());
- }
-}
-
-Time
-MeshWifiMac::CalcSwDelay ()
-{
- UniformVariable coefficient (0.0, m_softwareDelay.GetSeconds());
- Time delay = Seconds (coefficient.GetValue());
- if (delay.GetSeconds () + Simulator::Now().GetSeconds() < m_lastMgtFrame.GetSeconds())
- delay = Seconds (m_lastMgtFrame.GetSeconds() - Simulator::Now().GetSeconds());
- m_lastMgtFrame = Seconds (Simulator::Now().GetSeconds()+delay.GetSeconds());
- NS_ASSERT (delay.GetSeconds() >= 0);
- return delay;
-}
-
-void
-MeshWifiMac::SendPeerLinkOpen (IeDot11sPeerManagement peer_element, Mac48Address peerAddress)
-{
- MeshMgtPeerLinkManFrame open;
- open.SetOpen ();
- open.SetIeDot11sConfiguration (m_meshConfig);
- open.SetIeDot11sPeerManagement (peer_element);
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, open, peerAddress);
-}
-
-void
-MeshWifiMac::SendPeerLinkConfirm (IeDot11sPeerManagement peer_element, Mac48Address peerAddress, uint16_t aid)
-{
- MeshMgtPeerLinkManFrame confirm;
- confirm.SetConfirm ();
- confirm.SetIeDot11sConfiguration (m_meshConfig);
- confirm.SetIeDot11sPeerManagement (peer_element);
- confirm.SetAid (aid);
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, confirm, peerAddress);
-
-}
-
-void
-MeshWifiMac::SendPeerLinkClose (IeDot11sPeerManagement peer_element, Mac48Address peerAddress)
-{
- MeshMgtPeerLinkManFrame close;
- close.SetClose ();
- close.SetIeDot11sConfiguration (m_meshConfig);
- close.SetIeDot11sPeerManagement (peer_element);
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, close, peerAddress);
-
-}
-
-void
-MeshWifiMac::PeerLinkStatus (Mac48Address peerAddress, bool status)
-{
- //pass information to HwmpState
- m_peerStatusCallback (peerAddress, status, CalculateMetric(peerAddress));
-}
-void
-MeshWifiMac::QueuePeerLinkFrame (MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress)
-{
- Ptr<Packet> packet = Create<Packet> ();
- //Setting peer frame:
- peer_frame.SetSupportedRates (GetSupportedRates ());
- peer_frame.SetQosField (0);
- peer_frame.SetMeshId (GetSsid());
- packet->AddHeader (peer_frame);
- //multihop header:
- WifiMeshMultihopActionHeader multihopHdr;
- if (peer_frame.IsOpen ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- if (peer_frame.IsConfirm ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- if (peer_frame.IsClose ())
- {
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
- }
- packet->AddHeader (multihopHdr);
- //mesh header:
- WifiMeshHeader meshHdr;
- meshHdr.SetMeshTtl (1);
- meshHdr.SetMeshSeqno (0);
- packet->AddHeader (meshHdr);
- //Wifi Mac header:
- WifiMacHeader hdr;
- hdr.SetMultihopAction ();
- hdr.SetAddr1 (peerAddress);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- //queue:
- m_VO->Queue (packet,hdr);
-}
-
-void
-MeshWifiMac::SetSoftwareDelay (Time delay)
-{
- m_softwareDelay = delay;
-}
-
-Time
-MeshWifiMac::GetSoftwareDelay ()
-{
- return m_softwareDelay;
-}
-
-void
-MeshWifiMac::SendPreq (const IeDot11sPreq& preq)
-{
- //Add a PREQ
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (preq);
- //Add a Action values:
- WifiMeshMultihopActionHeader multihopHdr;
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.pathSelection = WifiMeshMultihopActionHeader::PATH_REQUEST;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (multihopHdr);
- //Add a mesh Header
- WifiMeshHeader meshHdr;
- //TODO: normal seqno!
- meshHdr.SetMeshTtl (1);
- meshHdr.SetMeshSeqno (0);
- packet->AddHeader (meshHdr);
- //Add a wifi header:
- WifiMacHeader hdr;
- hdr.SetMultihopAction ();
- hdr.SetAddr1 (Mac48Address::GetBroadcast ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (Mac48Address ("00:00:00:00:00:00"));
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
- //m_VO->Queue (packet,hdr);
-
-}
-
-void
-MeshWifiMac::SendPrep (const IeDot11sPrep& prep, const Mac48Address& to)
-{
- if (!m_peerManager->IsActiveLink (GetAddress(), to))
- return;
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (prep);
- //Add a Action values:
- WifiMeshMultihopActionHeader multihopHdr;
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.pathSelection = WifiMeshMultihopActionHeader::PATH_REPLY;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (multihopHdr);
- //Add a mesh Header
- WifiMeshHeader meshHdr;
- //TODO: normal seqno!
- meshHdr.SetMeshTtl (1);
- meshHdr.SetMeshSeqno (0);
- packet->AddHeader (meshHdr);
- //Add a wifi header:
- WifiMacHeader hdr;
- hdr.SetMultihopAction ();
- hdr.SetDsNotTo ();
- hdr.SetDsNotFrom ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress());
- hdr.SetAddr3 (Mac48Address("00:00:00:00:00:00"));
- //m_VO->Queue (packet,hdr);
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
-}
-
-void
-MeshWifiMac::SendPerr (const IeDot11sPerr& perr, std::vector<Mac48Address> receivers)
-{
- NS_ASSERT (receivers.size() != 0);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (perr);
- //Add a Action values:
- WifiMeshMultihopActionHeader multihopHdr;
- WifiMeshMultihopActionHeader::ACTION_VALUE action;
- action.pathSelection = WifiMeshMultihopActionHeader::PATH_ERROR;
- multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (multihopHdr);
- //Add a mesh Header
- WifiMeshHeader meshHdr;
- //TODO: normal seqno!
- meshHdr.SetMeshTtl (1);
- meshHdr.SetMeshSeqno (0);
- packet->AddHeader (meshHdr);
- //Add a wifi header:
- WifiMacHeader hdr;
- hdr.SetMultihopAction ();
- hdr.SetDsNotTo ();
- hdr.SetDsNotFrom ();
- hdr.SetAddr2 (GetAddress());
- hdr.SetAddr3 (Mac48Address("00:00:00:00:00:00"));
- //m_VO->Queue (packet,hdr);
- for (unsigned int i = 0; i < receivers.size (); i ++)
- {
- NS_LOG_DEBUG (GetAddress()<<" is sending PERR to "<<receivers[i]);
- hdr.SetAddr1 (receivers[i]);
- Simulator::Schedule (CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
- }
-}
-void
-MeshWifiMac::QueuePathSelectionFrame (Ptr<Packet> packet, const WifiMacHeader hdr)
-{
- m_VO->Queue (packet, hdr);
-}
-void
-MeshWifiMac::SetPreqReceivedCallback (
- Callback<void, IeDot11sPreq&, const Mac48Address&, const uint32_t&> cb)
-{
- m_preqReceived = cb;
-}
-
-void
-MeshWifiMac::SetPrepReceivedCallback (
- Callback<void, IeDot11sPrep&, const Mac48Address&, const uint32_t&> cb)
-{
- m_prepReceived = cb;
-}
-
-void
-MeshWifiMac::SetPerrReceivedCallback (
- Callback<void, IeDot11sPerr&, const Mac48Address&> cb)
-{
- m_perrReceived = cb;
-}
-
-void
-MeshWifiMac::SetPeerStatusCallback (
- Callback<void, Mac48Address, bool, uint32_t> cb)
-{
- m_peerStatusCallback = cb;
-}
-
-uint32_t
-MeshWifiMac::CalculateMetric (Mac48Address peerAddress)
-{
- //suppose Bt == 1000 bytes;
- uint32_t testLength = 1000;
- WifiRemoteStation *peerSta = m_stationManager->Lookup (peerAddress);
- WifiTxStatistics::RATE_LENGTH_STAT stats = peerSta->GetTxStat ().statistics;
- Time overhead = m_sifs + MicroSeconds (32) + MicroSeconds(8);
- uint32_t metric = (uint32_t) ((double)overhead.GetNanoSeconds()/102.4);
- uint32_t maxRate = 0;
- uint32_t packet_sent = 0;
- for (WifiTxStatistics::RATE_LENGTH_STAT::iterator lengthPos = stats.begin (); lengthPos != stats.end(); lengthPos++)
- {
- if (lengthPos->first > testLength)
- continue;
- for (
- WifiTxStatistics::RATE_STAT::iterator ratePos = lengthPos->second.begin ();
- ratePos != lengthPos->second.end ();
- ratePos ++
- )
- {
-#if 0
- NS_LOG_DEBUG ("Rate is "<<ratePos->first
- <<": SUCCESS = "<<ratePos->second.packetsAcked
- <<", RRETRY = " <<ratePos->second.packetsRetried
- <<", FAILURE = "<<ratePos->second.packetsFailed);
-#endif
- double coefficient =
- (double) (
- ratePos->second.packetsRetried
- + ratePos->second.packetsAcked
- )/ ((double)ratePos->second.packetsAcked);
- uint16_t avgLength = 0;
- if (ratePos->second.packetsAcked == 0)
- avgLength = lengthPos->first;
- else
- avgLength = ratePos->second.bytesAcked/ratePos->second.packetsAcked;
- uint32_t payload = (uint32_t) ((double)avgLength / ((double)ratePos->first)*1e9);
- if (packet_sent < ratePos->second.packetsAcked)
- {
- metric = (uint32_t) (coefficient*((double)overhead.GetNanoSeconds() + (double)payload)/10240);
- packet_sent = ratePos->second.packetsAcked;
- maxRate = ratePos->first;
- }
- }
- }
-
- //NS_LOG_DEBUG ("RATE is "<<maxRate<<" metric is "<<metric);
- //peerSta->ResetTxStat ();
- NS_ASSERT (metric != 0);
- return metric;
-}
-
-} // namespace ns3
--- a/src/devices/mesh/mesh-wifi-mac.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,369 +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
- *
- * Author: Kirill Andreev <andreev@iitp.ru>
- * Pavel Boyko <boyko@iitp.ru>
- */
-
-#ifndef MAC_HIGH_MESH_H
-#define MAC_HIGH_MESH_H
-
-#include <map>
-#include "ns3/mac48-address.h"
-#include "ns3/mesh-mgt-headers.h"
-#include "ns3/wifi-mac.h"
-#include "ns3/ie-dot11s-preq.h"
-#include "ns3/ie-dot11s-prep.h"
-#include "ns3/ie-dot11s-perr.h"
-
-namespace ns3 {
-
-class WifiMacHeader;
-class DcaTxop;
-class WifiPhy;
-class DcfManager;
-class MacRxMiddle;
-class MacLow;
-class WifiPeerManager;
-/**
- * \ingroup mesh
- *
- * \brief Implements basic MAC layer of mesh point interface. Basic 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 MeshWifiMac : public WifiMac
-{
-public:
- static TypeId GetTypeId ();
-
- MeshWifiMac ();
- ~MeshWifiMac ();
- // inherited from WifiMac.
- void SetSlot (Time slotTime);
- void SetSifs (Time sifs);
- void SetPifs (Time pifs);
- void SetCtsTimeout (Time ctsTimeout);
- void SetAckTimeout (Time ackTimeout);
- void SetEifsNoDifs (Time eifsNoDifs);
- Time GetSlot () const;
- Time GetSifs () const;
- Time GetPifs () const;
- Time GetCtsTimeout () const;
- Time GetAckTimeout () const;
- Time GetEifsNoDifs () const;
- void SetWifiPhy (Ptr<WifiPhy> phy);
- void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
- void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- bool SupportsSendFrom () const;
- void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- void SetLinkUpCallback (Callback<void> linkUp);
- void SetLinkDownCallback (Callback<void> linkDown);
- Mac48Address GetAddress () const;
- Mac48Address GetBssid () const;
- Ssid GetSsid () const;
- void SetAddress (Mac48Address address);
- void SetSsid (Ssid ssid);
- /**
- * \param interval is an interval between two
- * successive beacons
- */
- void SetBeaconInterval (Time interval);
- /**
- * \returns interval between two beacons
- */
- Time GetBeaconInterval () const;
- /**
- * \param delay is the maximum software delay.
- *
- * \details 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.
- *
- */
- void SetSoftwareDelay (Time delay);
- /**
- * \returns software delay parameter
- */
- Time GetSoftwareDelay ();
- /**
- * \param manager is pointer to the
- * WifiPeerManager class, which implements
- * peer-link management state machine.
- *
- * \details The purpose of peer manager is
- * obtaining all needed information from
- * beacons and send peer link management
- * frames.
- *
- * This funcion sets all needed callbacks to
- * a given peer manager
- */
- void SetPeerLinkManager (Ptr<WifiPeerManager> manager);
- void SetPreqReceivedCallback (
- Callback<void, IeDot11sPreq&, const Mac48Address&, const uint32_t&> cb);
- /**
- * \brief this callback is set by Hwmp routing
- * protocol and executed when MAC has received
- * PREP.
- * \param cb is a callback to be executed when
- * receiving PREP.
- */
- void SetPrepReceivedCallback (
- Callback<void, IeDot11sPrep&, const Mac48Address&, const uint32_t&> cb);
- /**
- * \brief this callback is set by Hwmp routing
- * protocol and executed when MAC has received
- * PERR.
- * \param cb is a callback to be executed when
- * receiving PERR.
- */
- void SetPerrReceivedCallback (
- Callback<void, IeDot11sPerr&, const Mac48Address&> cb);
-
- /**
- * \brief this callback is set by Hwmp routing
- * protocol and executed when MAC has detected
- * the peer link failure
- * \param cb is a callback to be executed when
- * peer failure has ben detected
- */
- void SetPeerStatusCallback (
- Callback<void, Mac48Address, bool, uint32_t> cb);
- /**
- * \brief Sends a PREQ frame.
- * \param preq is preq information element
- * formed by protocol. This function just adds
- * a proper WifiMacHeader
- * \attention This method is public, because
- * HWMP makes a callback using this method
- */
- void SendPreq (const IeDot11sPreq& preq);
- /**
- * \brief Sends a PREP frame.
- * \param prep is prep information element
- * formed by protocol. This function just adds
- * a proper WifiMacHeader
- * \param to is an address of retransmitter of
- * the prep
- * \attention This method is public, because
- * HWMP makes a callback using this method
- */
-
- void SendPrep (const IeDot11sPrep& prep, const Mac48Address& to);
- /**
- * \brief Sends a PERR frame.
- * \param perr is perr information element
- * formed by protocol. This function just adds
- * a proper WifiMacHeader.
- * \param receivers is list of addresses where
- * to send PERR (unicast PERR case)
- * \attention This method is public, because
- * HWMP makes a callback using this method
- */
- void SendPerr (const IeDot11sPerr& perr, std::vector<Mac48Address> receivers);
- /**
- * \brief Sends PeerLinkOpen frame to a given
- * address. Mac only forms a proper
- * WifiMacHeader.
- * \param peer_element is peer link frame to
- * be sent
- * \param peerAddress is the address of
- * destination of given frame
- */
- void SendPeerLinkOpen (
- IeDot11sPeerManagement peer_element,
- Mac48Address peerAddress
- );
- /**
- * \brief Sends PeerLinkConfirm frame to a given
- * address. Mac only forms a proper
- * WifiMacHeader.
- * \param peer_element is peer link frame to
- * be sent
- * \param peerAddress is the address of
- * destination of given frame
- * \param aid is the assocciation ID stored in
- * peer manager
- */
- void SendPeerLinkConfirm (
- IeDot11sPeerManagement peer_element,
- Mac48Address peerAddress,
- uint16_t aid
- );
- /**
- * \brief Sends PeerLinkClose frame to a given
- * address. Mac only forms a proper
- * WifiMacHeader.
- * \param peer_element is peer link frame to
- * be sent
- * \param peerAddress is the address of
- * destination of given frame
- */
- void SendPeerLinkClose (
- IeDot11sPeerManagement peer_element,
- Mac48Address peerAddress
- );
- /**
- * \brief this method is executed by peer
- * manager when peer link opened or closed
- * \param status true when link was opened,
- * false if link was closed
- * \param peerAddress is the address of
- * destination of given frame
- */
- void PeerLinkStatus (Mac48Address peerAddress, bool status);
-
- /**
- * \brief Peer Manager notifyes MAC about new
- * peer link or peer link failure.
- * \details This method should pass this event
- * to HWMP, and it should generate new routing
- * information or should generate Path Error
- * \param peerAddress it the address of
- * neighbour
- * \param status If true - new peer link, perr
- * link failure otherwise
- */
- void PeerEvent (
- Mac48Address peerAddress,
- bool status
- );
-private:
- void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
- void ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst);
- void ForwardDown (
- Ptr<const Packet> packet,
- Mac48Address from,
- Mac48Address to
- );
- void TxOk (WifiMacHeader const &hdr);
- void TxFailed (WifiMacHeader const &hdr);
- /**
- * \brief At the software delay before TBTT
- * SendOneBeacon is ececuted. It forms a
- * beacon frame body. Then calculates software
- * delay and schedules QueueOneBeacon
- */
- void SendOneBeacon ();
- /**
- * \brief Puts a formed beacon to the output
- * queue. SendOneBeacon forms a beacon and
- * after software delay QueueOneBeacon is
- * executed
- * \param beacon_hdr is beacon to be queued
- */
- void QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr);
- /**
- * \brief Executed after software delay by
- * SendPeerLinkOpen/Confirm/Close frames and
- * puts this frame to the output queue.
- * \param peer_frame peer link management
- * frame
- * \param peerAddress the address of
- * destination.
- */
- void QueuePeerLinkFrame (MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress);
- /**
- * \brief Executed after software delay by
- * SendPreq/Prep/Perr frames and
- * puts this frame to the output queue.
- * \param packet is packet body,
- * \param hdr is WifiMacHeader
- */
- void QueuePathSelectionFrame (Ptr<Packet> packet, const WifiMacHeader hdr);
- void SetBeaconGeneration (bool enable);
- bool GetBeaconGeneration () const;
- SupportedRates GetSupportedRates () const;
- void DoDispose ();
-
- Ptr<DcaTxop> m_BE;
- Ptr<DcaTxop> m_BK;
- Ptr<DcaTxop> m_VI;
- Ptr<DcaTxop> m_VO;
- Ptr<DcaTxop> m_beaconDca;
- Ptr<WifiRemoteStationManager> m_stationManager;
- Ptr<WifiPhy> m_phy;
- Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_upCallback;
- Time m_beaconInterval;
- Time m_randomStart;
-
- DcfManager *m_dcfManager;
- MacRxMiddle *m_rxMiddle;
- Ptr<MacLow> m_low;
- Mac48Address m_address;
- Ssid m_MeshId;
- EventId m_beaconFormEvent;
- EventId m_beaconSendEvent;
- Time m_slot;
- Time m_sifs;
- Time m_pifs;
- Time m_ackTimeout;
- Time m_ctsTimeout;
-
- Time m_eifsNoDifs;
- IeDot11sConfiguration m_meshConfig; //Stores my configuration;
- //Peer Descriptor pointer:
- Ptr<WifiPeerManager> m_peerManager;
- Time m_softwareDelay;
- /**
- * \attention Software delay is used for management
- * frames, so, if this delay is calculated
- * independenly, the packet order may be
- * broken, so the last mgt frame sending time
- * should be keeped within MAC
- */
- Time m_lastMgtFrame;
- /**
- * \returns the value of software delay
- * uniformely distributed between 0 and
- * m_softwareDealy (initiated by
- * SetSoftwareDelay method).
- */
- Time CalcSwDelay ();
- /**
- * \brief keeps delay for sending first
- * beacon. this delay is uniformely
- * distributed between 0 and given value
- */
- Time m_beaconFormingRandomDelay;
- Callback<void, IeDot11sPreq&, const Mac48Address&, const uint32_t&> m_preqReceived;
- Callback<void, IeDot11sPrep&, const Mac48Address&, const uint32_t&> m_prepReceived;
- Callback<void, IeDot11sPerr&, const Mac48Address&> m_perrReceived;
- Callback<void, Mac48Address, bool, uint32_t> m_peerStatusCallback;
- /**
- * \brief metric calculation parameters
- */
- uint32_t CalculateMetric (Mac48Address peerAddress);
- std::map<Mac48Address, uint32_t> m_metricDatabase;
-};
-
-} // namespace ns3
-
-
-#endif /* MAC_HIGH_MESH_H */
--- a/src/devices/mesh/mesh-wifi-peer-manager.cc Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,990 +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 "ns3/mesh-wifi-peer-manager.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 ("WifiPeerManager");
-namespace ns3 {
-/***************************************************
- * PeerLinkDescriptorDUP
- ***************************************************/
-WifiPeerLinkDescriptorDUP::WifiPeerLinkDescriptorDUP ():
- m_localLinkId (0),
- m_peerLinkId (0),
- m_state (IDLE),
- m_retryCounter (0),
- m_maxBeaconLoss (3)
-{}
-
-void
-WifiPeerLinkDescriptorDUP::SetPeerAddress (Mac48Address macaddr)
-{
- m_peerAddress = macaddr;
-}
-
-void
-WifiPeerLinkDescriptorDUP::SetLocalAddress (Mac48Address macaddr)
-{
- m_localAddress = macaddr;
-}
-
-void
-WifiPeerLinkDescriptorDUP::SetLocalLinkId (uint16_t id)
-{
- m_localLinkId = id;
-}
-void
-WifiPeerLinkDescriptorDUP::SetLocalAid (uint16_t aid)
-{
- m_assocId = aid;
-}
-void
-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, &WifiPeerLinkDescriptorDUP::BeaconLoss, this);
-}
-
-void
-WifiPeerLinkDescriptorDUP::SetMaxBeaconLoss (uint8_t maxBeaconLoss)
-{
- m_maxBeaconLoss = maxBeaconLoss;
-}
-
-void
-WifiPeerLinkDescriptorDUP::SetLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, bool> cb)
-{
- m_linkStatusCallback = cb;
-}
-void
-WifiPeerLinkDescriptorDUP::BeaconLoss ()
-{
- StateMachine (CNCL);
-}
-
-void
-WifiPeerLinkDescriptorDUP::SetBeaconTimingElement (IeDot11sBeaconTiming beaconTiming)
-{
- m_beaconTiming = beaconTiming;
-}
-
-Mac48Address
-WifiPeerLinkDescriptorDUP::GetPeerAddress () const
-{
- return m_peerAddress;
-}
-
-Mac48Address
-WifiPeerLinkDescriptorDUP::GetLocalAddress () const
-{
- return m_localAddress;
-}
-
-
-uint16_t
-WifiPeerLinkDescriptorDUP::GetLocalAid () const
-{
- return m_assocId;
-}
-
-Time
-WifiPeerLinkDescriptorDUP::GetLastBeacon () const
-{
- return m_lastBeacon;
-}
-
-Time
-WifiPeerLinkDescriptorDUP::GetBeaconInterval () const
-{
- return m_beaconInterval;
-}
-IeDot11sBeaconTiming
-WifiPeerLinkDescriptorDUP::GetBeaconTimingElement () const
-{
- return m_beaconTiming;
-}
-
-void
-WifiPeerLinkDescriptorDUP::ClearTimingElement ()
-{
- m_beaconTiming.ClearTimingElement ();
-}
-
-
-void WifiPeerLinkDescriptorDUP::MLMECancelPeerLink (dot11sReasonCode reason)
-{
- StateMachine (CNCL,reason);
-}
-
-void WifiPeerLinkDescriptorDUP::MLMEPassivePeerLinkOpen ()
-{
- StateMachine (PASOPN);
-}
-
-void WifiPeerLinkDescriptorDUP::MLMEActivePeerLinkOpen ()
-{
- StateMachine (ACTOPN);
-}
-void WifiPeerLinkDescriptorDUP::MLMEPeeringRequestReject ()
-{
- StateMachine (REQ_RJCT, REASON11S_PEER_LINK_CANCELLED);
-}
-#if 0
-void WifiPeerLinkDescriptorDUP::MLMEBindSecurityAssociation ()
-{
- StateMachine (BNDSA);
-}
-#endif
-void
-WifiPeerLinkDescriptorDUP::SetMac (Ptr<MeshWifiMac> mac)
-{
- m_mac = mac;
-}
-void WifiPeerLinkDescriptorDUP::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 WifiPeerLinkDescriptorDUP::PeerLinkOpenAccept (uint16_t localLinkId, IeDot11sConfiguration conf)
-{
- if (m_peerLinkId == 0)
- m_peerLinkId = localLinkId;
- m_configuration = conf;
- StateMachine (OPN_ACPT);
-}
-
-void WifiPeerLinkDescriptorDUP::PeerLinkOpenReject (uint16_t localLinkId, IeDot11sConfiguration conf,dot11sReasonCode reason)
-{
- if ( m_peerLinkId == 0)
- m_peerLinkId = localLinkId;
- m_configuration = conf;
- StateMachine (OPN_RJCT, reason);
-}
-
-void
-WifiPeerLinkDescriptorDUP::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 WifiPeerLinkDescriptorDUP:: 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
-WifiPeerLinkDescriptorDUP::LinkIsEstab () const
-{
- if (m_state == ESTAB)
- return true;
- return false;
-}
-
-bool
-WifiPeerLinkDescriptorDUP::LinkIsIdle () const
-{
- if (m_state == IDLE)
- return true;
- return false;
-}
-
-void
-WifiPeerLinkDescriptorDUP::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 WifiPeerLinkDescriptorDUP::ClearRetryTimer ()
-{
- m_retryTimer.Cancel ();
-}
-
-void WifiPeerLinkDescriptorDUP::ClearConfirmTimer ()
-{
- m_confirmTimer.Cancel ();
-}
-
-void WifiPeerLinkDescriptorDUP::ClearHoldingTimer ()
-{
- m_holdingTimer.Cancel ();
-}
-
-void WifiPeerLinkDescriptorDUP::SendPeerLinkClose (dot11sReasonCode reasoncode)
-{
- IeDot11sPeerManagement peerElement;
- peerElement.SetPeerClose (m_localLinkId, m_peerLinkId, reasoncode);
- m_mac->SendPeerLinkClose (peerElement,m_peerAddress);
-}
-
-void WifiPeerLinkDescriptorDUP::SendPeerLinkOpen ()
-{
- IeDot11sPeerManagement peerElement;
- peerElement.SetPeerOpen (m_localLinkId);
- NS_ASSERT (m_mac != NULL);
- m_mac->SendPeerLinkOpen (peerElement, m_peerAddress);
-}
-
-void WifiPeerLinkDescriptorDUP::SendPeerLinkConfirm ()
-{
- IeDot11sPeerManagement peerElement;
- peerElement.SetPeerConfirm (m_localLinkId, m_peerLinkId);
- m_mac->SendPeerLinkConfirm (peerElement, m_peerAddress, m_assocId);
-}
-
-void WifiPeerLinkDescriptorDUP::SetHoldingTimer ()
-{
- m_holdingTimer = Simulator::Schedule (dot11sParameters::dot11MeshHoldingTimeout, &WifiPeerLinkDescriptorDUP::HoldingTimeout, this);
-}
-
-void WifiPeerLinkDescriptorDUP::HoldingTimeout ()
-{
- StateMachine (TOH);
-}
-
-void WifiPeerLinkDescriptorDUP::SetRetryTimer ()
-{
- m_retryTimer = Simulator::Schedule (dot11sParameters::dot11MeshRetryTimeout, &WifiPeerLinkDescriptorDUP::RetryTimeout, this);
-}
-
-void WifiPeerLinkDescriptorDUP::RetryTimeout ()
-{
- if ( m_retryCounter < dot11sParameters::dot11MeshMaxRetries)
- StateMachine (TOR1);
- else
- StateMachine (TOR2);
-}
-
-void WifiPeerLinkDescriptorDUP::SetConfirmTimer ()
-{
- m_confirmTimer = Simulator::Schedule (dot11sParameters::dot11MeshConfirmTimeout, &WifiPeerLinkDescriptorDUP::ConfirmTimeout, this);
-}
-
-void WifiPeerLinkDescriptorDUP::ConfirmTimeout ()
-{
- StateMachine (TOC);
-}
-
-
-/***************************************************
- * PeerManager
- ***************************************************/
-NS_OBJECT_ENSURE_REGISTERED (WifiPeerManager);
-
-TypeId
-WifiPeerManager::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::WifiPeerManager")
- .SetParent<Object> ()
- .AddConstructor<WifiPeerManager> ()
- //peerLinkCleanupTimeout. This constant is not specified in Draft 2.0
- .AddAttribute ("PeerLinkCleanupPeriod",
- "PeerLinkCleanupPeriod",
- TimeValue (MilliSeconds (80)),
- MakeTimeAccessor (&WifiPeerManager::m_peerLinkCleanupPeriod),
- MakeTimeChecker ()
- )
- //MaxBeaconLost. This constant is not specified in Draft 2.0
- .AddAttribute ("MaxBeaconLost", "Max Beacon Lost",
- UintegerValue (3),
- MakeUintegerAccessor (&WifiPeerManager::m_maxBeaconLoss),
- MakeUintegerChecker<uint8_t> ()
- )
- //maximum number of peer links.
- .AddAttribute ("MaxNumberOfPeerLinks",
- "Maximum number of peer links ",
- UintegerValue (32),
- MakeUintegerAccessor (&WifiPeerManager::m_maxNumberOfPeerLinks),
- MakeUintegerChecker<uint8_t> ()
- );
- return tid;
-
-}
-WifiPeerManager::WifiPeerManager ()
-{
- m_assocId = 0;
- m_numberOfActivePeers = 0;
- // firs peerLinkId is 1, because 0 means "unknown"
- m_localLinkId = 1;
- m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &WifiPeerManager::PeerCleanup, this);
-}
-WifiPeerManager::~WifiPeerManager ()
-{
- 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<WifiPeerLinkDescriptorDUP> >::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 ();
-}
-void
-WifiPeerManager::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
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- {
- if ((*i)->GetPeerAddress () == peerAddress)
- {
- (*i)->SetBeaconTimingElement (beaconTiming);
- (*i)->SetBeaconInformation (lastBeacon, beaconInterval);
- return;
- }
- }
- Ptr<WifiPeerLinkDescriptorDUP> new_descriptor =
- AddDescriptor (portAddress, peerAddress, Simulator::Now(), beaconInterval);
- new_descriptor->SetBeaconTimingElement (beaconTiming);
-}
-
-bool
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> > descriptors;
- m_peerDescriptors[meshWifiMac->GetAddress ()] = descriptors;
- //Add beacon timers:
- struct BeaconInfo myBeacon;
- m_myBeaconInfo[meshWifiMac->GetAddress ()] = myBeacon;
- }
- return true;
-}
-void
-WifiPeerManager::AskIfOpenNeeded (Mac48Address portAddress, Mac48Address peerAddress)
-{
- PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
- NS_ASSERT (port != m_peerDescriptors.end());
- for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- if ((*i)->GetPeerAddress () == peerAddress)
- {
- if (ShouldSendOpen (portAddress, peerAddress))
- (*i)->MLMEActivePeerLinkOpen ();
- break;
- }
-}
-
-void
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::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<WifiPeerLinkDescriptorDUP>new_descriptor = AddDescriptor (
- portAddress,
- peerAddress,
- Simulator::Now (),
- myBeacon->second.beaconInterval
- );
- new_descriptor->PeerLinkOpenAccept (peerMan.GetLocalLinkId(), conf);
-}
-void
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- if ((*i)->GetPeerAddress () == peerAddress)
- (*i)->PeerLinkConfirmAccept (peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerAid, meshConfig);
-}
-
-void
-WifiPeerManager::SetCloseReceived (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- IeDot11sPeerManagement peerMan
-)
-{
- PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
- NS_ASSERT (port != m_peerDescriptors.end());
- 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());
- return;
- }
-}
-
-void
-WifiPeerManager::ConfigurationMismatch (
- Mac48Address portAddress,
- Mac48Address peerAddress
-)
-{
- PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
- NS_ASSERT (port != m_peerDescriptors.end());
- 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);
- return;
- }
-
-}
-
-IeDot11sBeaconTiming
-WifiPeerManager::GetIeDot11sBeaconTimingForMyBeacon (Mac48Address portAddress)
-{
- PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
- NS_ASSERT (port != m_peerDescriptors.end());
- IeDot11sBeaconTiming return_val;
- 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 (
- (*i)->GetLocalAid (),
- (*i)->GetLastBeacon (),
- (*i)->GetBeaconInterval ()
- );
- }
- return return_val;
-
-}
-IeDot11sBeaconTiming
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- if ((*i)->GetPeerAddress () == addr)
- return_val = (*i)->GetBeaconTimingElement ();
- return return_val;
-}
-Ptr<WifiPeerLinkDescriptorDUP>
-WifiPeerManager::AddDescriptor (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- Time lastBeacon,
- Time beaconInterval)
-{
- Ptr<WifiPeerLinkDescriptorDUP> new_descriptor = Create<WifiPeerLinkDescriptorDUP> ();
- 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(&WifiPeerManager::PeerLinkStatus, this));
- NS_ASSERT (port != m_peerDescriptors.end());
- m_peerDescriptors[portAddress].push_back (new_descriptor);
- return new_descriptor;
-}
-
-void
-WifiPeerManager::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, &WifiPeerManager::PeerCleanup, this);
-}
-
-std::vector<Mac48Address>
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- return_value.push_back ((*i)->GetPeerAddress());
- return return_value;
-}
-
-bool
-WifiPeerManager::IsActiveLink (Mac48Address portAddress, Mac48Address peerAddress)
-{
- PeerDescriptorsMap::iterator port = m_peerDescriptors.find (portAddress);
- NS_ASSERT (port != m_peerDescriptors.end());
- for (std::vector<Ptr<WifiPeerLinkDescriptorDUP> >::iterator i = port->second.begin (); i != port->second.end(); i++)
- if ((*i)->GetPeerAddress () == peerAddress)
- return ((*i)->LinkIsEstab ());
- return false;
-}
-
-bool
-WifiPeerManager::ShouldSendOpen (Mac48Address portAddress, Mac48Address peerAddress)
-{
- if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
- return false;
- return true;
-}
-
-bool
-WifiPeerManager::ShouldAcceptOpen (Mac48Address portAddress, Mac48Address peerAddress,dot11sReasonCode & reasonCode)
-{
- if (m_numberOfActivePeers > m_maxNumberOfPeerLinks)
- {
- reasonCode = REASON11S_MESH_MAX_PEERS;
- return false;
- }
- return true;
-}
-
-Time
-WifiPeerManager::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<WifiPeerLinkDescriptorDUP> >::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
-WifiPeerManager::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);
-}
-} //namespace NS3
--- a/src/devices/mesh/mesh-wifi-peer-manager.h Wed Mar 25 16:58:24 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +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>
- */
-
-
-#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/mesh-wifi-mac.h"
-
-#include <list>
-
-namespace ns3 {
-class MeshWifiMac;
-/**
- * \ingroup mesh
- */
-class WifiPeerLinkDescriptorDUP : public RefCountBase
-{
-public:
- WifiPeerLinkDescriptorDUP ();
- /**
- * 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 SetPeerLinkDescriptorDUPElement (IeDot11sPeerManagement peerLinkElement);
- Mac48Address GetPeerAddress () const;
- /**
- * Debug purpose
- */
- Mac48Address GetLocalAddress () const;
- uint16_t GetLocalAid () const;
- Time GetLastBeacon () const;
- Time GetBeaconInterval () const;
- IeDot11sBeaconTiming GetBeaconTimingElement () const;
- IeDot11sPeerManagement GetPeerLinkDescriptorDUPElement () const;
- void ClearTimingElement ();
- /* MLME */
- void MLMECancelPeerLink (dot11sReasonCode reason);
- void MLMEPassivePeerLinkOpen ();
- void MLMEActivePeerLinkOpen ();
- void MLMEPeeringRequestReject ();
-#if 0
- void MLMEBindSecurityAssociation ();
-#endif
- void SetMac (Ptr<MeshWifiMac> mac);
- 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 ();
- Ptr<MeshWifiMac> m_mac;
- Callback<void, Mac48Address, Mac48Address, bool> m_linkStatusCallback;
-};
-/**
- * \ingroup mesh
- */
-class WifiPeerManager : public Object
-{
-public:
- WifiPeerManager ();
- WifiPeerManager (Ptr<MeshWifiMac> mac_pointer);
- ~WifiPeerManager ();
- static TypeId GetTypeId ();
- //Returns a beacon timing element stored for remote station:
- IeDot11sBeaconTiming GetIeDot11sBeaconTimingForAddress (Mac48Address portAddress, Mac48Address addr);
- //Returns a list of all addresses, which beacons can be decoded:
- std::vector<Mac48Address> GetNeighbourAddressList (Mac48Address portAddress, Mac48Address peerAddress);
- bool AttachPorts (std::vector<Ptr<WifiNetDevice> >);
- //void SetMac (Ptr<MeshWifiMac> mac);
- Time GetNextBeaconShift (Mac48Address portAddress, Time myNextTBTT);
-
- void SetSentBeaconTimers (
- Mac48Address portAddress,
- Time ReferenceTBTT,
- Time BeaconInterval
- );
- void AskIfOpenNeeded (
- Mac48Address portAddress,
- Mac48Address peerAddress
- );
- void SetReceivedBeaconTimers (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- Time lastBeacon,
- Time beaconInterval,
- IeDot11sBeaconTiming beaconTiming
- );
- void SetOpenReceived (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- IeDot11sPeerManagement peerMan,
- IeDot11sConfiguration conf
- );
- void SetConfirmReceived (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- uint16_t peerAid,
- IeDot11sPeerManagement peerMan,
- IeDot11sConfiguration meshConfig
- );
- void SetCloseReceived (
- Mac48Address portAddress,
- Mac48Address peerAddress,
- IeDot11sPeerManagement peerMan
- );
- //Using this function MAC
- void ConfigurationMismatch (
- Mac48Address portAddress,
- Mac48Address peerAddress
- );
- //Returns a beacon timing element to added into my beacon:
- IeDot11sBeaconTiming
- GetIeDot11sBeaconTimingForMyBeacon (
- Mac48Address portAddress
- );
- bool IsActiveLink (
- Mac48Address portAddress,
- Mac48Address peerAddress
- );
-private:
- 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<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;
-
- //Ptr<MeshWifiMac> m_mac;
- //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<WifiPeerLinkDescriptorDUP> 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);
-};
-
-} //namespace ns3
-#endif