--- a/src/devices/mesh/dot11s/dot11s-mac-header.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/dot11s-mac-header.cc Tue Jul 14 09:44:09 2009 +0400
@@ -258,17 +258,8 @@
case MESH_PATH_SELECTION:
switch (m_actionValue)
{
- case PATH_REQUEST:
- retval.pathSelection = PATH_REQUEST;
- return retval;
- case PATH_REPLY:
- retval.pathSelection = PATH_REPLY;
- return retval;
- case PATH_ERROR:
- retval.pathSelection = PATH_ERROR;
- return retval;
- case ROOT_ANNOUNCEMENT:
- retval.pathSelection = ROOT_ANNOUNCEMENT;
+ case PATH_SELECTION:
+ retval.pathSelection = PATH_SELECTION;
return retval;
default:
NS_FATAL_ERROR ("Unknown mesh path selection action code");
--- a/src/devices/mesh/dot11s/dot11s-mac-header.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/dot11s-mac-header.h Tue Jul 14 09:44:09 2009 +0400
@@ -111,10 +111,7 @@
/* Compatible with open80211s implementation */
enum PathSelectionActionValue
{
- PATH_REQUEST = 0,
- PATH_REPLY = 1,
- PATH_ERROR = 2,
- ROOT_ANNOUNCEMENT = 3,
+ PATH_SELECTION = 0,
};
enum InterworkActionValue
{
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc Tue Jul 14 09:44:09 2009 +0400
@@ -29,6 +29,7 @@
#include "hwmp-tag.h"
#include "ie-dot11s-preq.h"
#include "ie-dot11s-prep.h"
+#include "ie-dot11s-rann.h"
namespace ns3 {
namespace dot11s {
@@ -97,44 +98,44 @@
WifiMeshActionHeader::ActionValue actionValue = actionHdr.GetAction ();
if(actionHdr.GetCategory () != WifiMeshActionHeader::MESH_PATH_SELECTION)
return true;
- switch (actionValue.pathSelection)
+ IeRann rann;
+ IePreq preq;
+ IePrep prep;
+ IePerr perr;
+ while (packet->RemoveHeader (rann))
+ {
+ NS_LOG_WARN("RANN is not supported!");
+ }
+ while (packet->RemoveHeader (preq))
{
- case WifiMeshActionHeader::PATH_REQUEST:
- {
- IePreq preq;
- m_stats.rxPreq ++;
- packet->RemoveHeader (preq);
- if(preq.GetOriginatorAddress () == m_protocol->GetAddress ())
- return false;
- if (preq.GetTtl () == 0)
- return false;
- preq.DecrementTtl ();
- m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
- return false;
- }
- case WifiMeshActionHeader::PATH_REPLY:
- {
- IePrep prep;
- m_stats.rxPrep ++;
- packet->RemoveHeader (prep);
- if(prep.GetTtl () == 0)
- return false;
- prep.DecrementTtl ();
- m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
- return false;
- }
- case WifiMeshActionHeader::PATH_ERROR:
- {
- IePerr perr;
- m_stats.rxPerr ++;
- packet->RemoveHeader (perr);
- m_protocol->ReceivePerr (perr, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
- return false;
- }
- case WifiMeshActionHeader::ROOT_ANNOUNCEMENT:
- return false;
+ m_stats.rxPreq ++;
+ if (preq.GetOriginatorAddress () == m_protocol->GetAddress ())
+ continue;
+ if (preq.GetTtl () == 0)
+ continue;
+ preq.DecrementTtl ();
+ m_protocol->ReceivePreq (preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
}
- return true;
+ while (packet->RemoveHeader (prep))
+ {
+ m_stats.rxPrep ++;
+ if (prep.GetTtl () == 0)
+ continue;
+ prep.DecrementTtl ();
+ m_protocol->ReceivePrep (prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (), m_parent->GetLinkMetric(header.GetAddr2 ()));
+ }
+ std::vector<IePerr::FailedDestination> failedDestinations;
+ while (packet->RemoveHeader (perr))
+ {
+ m_stats.rxPerr ++;
+ std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector ();
+ for(std::vector<IePerr::FailedDestination>::const_iterator i = destinations.begin (); i != destinations.end (); i ++)
+ failedDestinations.push_back (*i);
+ }
+ if (failedDestinations.size () > 0)
+ m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
+ NS_ASSERT(packet->GetSize () == 0);
+ return false;
}
bool
@@ -161,58 +162,38 @@
m_stats.txData ++;
m_stats.txDataBytes += packet->GetSize ();
MeshHeader meshHdr;
- meshHdr.SetMeshSeqno(tag.GetSeqno());
- meshHdr.SetMeshTtl(tag.GetTtl());
- packet->AddHeader(meshHdr);
- header.SetAddr1(tag.GetAddress());
+ meshHdr.SetMeshSeqno (tag.GetSeqno());
+ meshHdr.SetMeshTtl (tag.GetTtl());
+ packet->AddHeader (meshHdr);
+ header.SetAddr1 (tag.GetAddress());
return true;
}
+WifiMeshActionHeader
+HwmpProtocolMac::GetWifiMeshActionHeader ()
+{
+ WifiMeshActionHeader actionHdr;
+ WifiMeshActionHeader::ActionValue action;
+ action.pathSelection = WifiMeshActionHeader::PATH_SELECTION;
+ actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
+ return actionHdr;
+}
void
HwmpProtocolMac::SendPreq(IePreq preq)
{
- m_preqQueue.push_back (preq);
- SendOnePreq ();
+ NS_LOG_FUNCTION_NOARGS ();
+ std::vector<IePreq> preq_vector;
+ preq_vector.push_back(preq);
+ SendPreq(preq_vector);
}
void
-HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno)
+HwmpProtocolMac::SendPreq(std::vector<IePreq> preq)
{
- for(std::vector<IePreq>::iterator i = m_preqQueue.begin (); i != m_preqQueue.end (); i ++)
- if(i->MayAddAddress(m_protocol->GetAddress ()))
- {
- i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
- return;
- }
- IePreq preq;
- //fill PREQ:
- preq.SetHopcount (0);
- preq.SetTTL (m_protocol->GetMaxTtl ());
- preq.SetPreqID (m_protocol->GetNextPreqId ());
- preq.SetOriginatorAddress (m_protocol->GetAddress ());
- preq.SetOriginatorSeqNumber (originator_seqno);
- preq.SetLifetime (m_protocol->GetActivePathLifetime ());
- preq.AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
- m_preqQueue.push_back (preq);
- //set iterator position to my preq:
- SendOnePreq ();
-}
-void
-HwmpProtocolMac::SendOnePreq ()
-{
- if(m_preqTimer.IsRunning ())
- return;
- if (m_preqQueue.size () == 0)
- return;
- //reschedule sending PREQ
- NS_ASSERT (!m_preqTimer.IsRunning());
- m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendOnePreq, this);
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader(m_preqQueue[0]);
- //Action header:
- WifiMeshActionHeader actionHdr;
- WifiMeshActionHeader::ActionValue action;
- action.pathSelection = WifiMeshActionHeader::PATH_REQUEST;
- actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (actionHdr);
+ Ptr<Packet> packet = Create<Packet> ();
+ for(std::vector<IePreq>::const_iterator i = preq.begin (); i != preq.end (); i ++)
+ {
+ packet->AddHeader (*i);
+ }
+ packet->AddHeader (GetWifiMeshActionHeader ());
//create 802.11 header:
WifiMacHeader hdr;
hdr.SetAction ();
@@ -230,60 +211,51 @@
m_stats.txMgtBytes += packet->GetSize ();
m_parent->SendManagementFrame(packet, hdr);
}
- //erase queue
- m_preqQueue.erase (m_preqQueue.begin());
}
void
-HwmpProtocolMac::SendOnePerr()
+HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno)
{
- if(m_perrTimer.IsRunning ())
- return;
- if(m_myPerr.receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
+ NS_LOG_FUNCTION_NOARGS ();
+ for(std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end(); i ++)
{
- m_myPerr.receivers.clear ();
- m_myPerr.receivers.push_back (Mac48Address::GetBroadcast ());
+ if(i->IsFull ())
+ continue;
+ NS_ASSERT (i->GetDestCount () > 0);
+ i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
}
- m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendOnePerr, this);
-//Create packet
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader(m_myPerr.perr);
- //Action header:
- WifiMeshActionHeader actionHdr;
- WifiMeshActionHeader::ActionValue action;
- action.pathSelection = WifiMeshActionHeader::PATH_ERROR;
- actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (actionHdr);
- //create 802.11 header:
- WifiMacHeader hdr;
- hdr.SetAction ();
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- hdr.SetAddr2 (m_parent->GetAddress ());
- hdr.SetAddr3 (m_protocol->GetAddress ());
- //Send Management frame
- for(std::vector<Mac48Address>::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
- {
- hdr.SetAddr1 (*i);
- m_stats.txPerr ++;
- m_stats.txMgt ++;
- m_stats.txMgtBytes += packet->GetSize ();
- m_parent->SendManagementFrame(packet, hdr);
- }
- m_myPerr.perr.ResetPerr ();
- m_myPerr.receivers.clear ();
+ IePreq preq;
+ preq.SetHopcount (0);
+ preq.SetTTL (m_protocol->GetMaxTtl ());
+ preq.SetPreqID (m_protocol->GetNextPreqId ());
+ preq.SetOriginatorAddress (m_protocol->GetAddress ());
+ preq.SetOriginatorSeqNumber (originator_seqno);
+ preq.SetLifetime (m_protocol->GetActivePathLifetime ());
+ preq.AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
+ m_myPreq.push_back(preq);
+ SendMyPreq ();
+}
+void
+HwmpProtocolMac::SendMyPreq ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if(m_preqTimer.IsRunning ())
+ return;
+ if(m_myPreq.size () == 0)
+ return;
+ //reschedule sending PREQ
+ NS_ASSERT (!m_preqTimer.IsRunning());
+ m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendMyPreq, this);
+ SendPreq (m_myPreq);
+ m_myPreq.clear ();
}
void
HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver)
{
+ NS_LOG_FUNCTION_NOARGS ();
//Create packet
Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader(prep);
- //Action header:
- WifiMeshActionHeader actionHdr;
- WifiMeshActionHeader::ActionValue action;
- action.pathSelection = WifiMeshActionHeader::PATH_REPLY;
- actionHdr.SetAction (WifiMeshActionHeader::MESH_PATH_SELECTION, action);
- packet->AddHeader (actionHdr);
+ packet->AddHeader (prep);
+ packet->AddHeader (GetWifiMeshActionHeader ());
//create 802.11 header:
WifiMacHeader hdr;
hdr.SetAction ();
@@ -299,19 +271,91 @@
m_parent->SendManagementFrame(packet, hdr);
}
void
-HwmpProtocolMac::SendPerr(IePerr perr, std::vector<Mac48Address> receivers)
+HwmpProtocolMac::ForwardPerr(std::vector<IePerr::FailedDestination> failedDestinations, std::vector<Mac48Address> receivers)
{
- m_myPerr.perr.Merge(perr);
- for(unsigned int i = 0; i < receivers.size (); i ++)
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Packet> packet = Create<Packet> ();
+ IePerr perr;
+ for(std::vector<IePerr::FailedDestination>::const_iterator i = failedDestinations.begin (); i != failedDestinations.end (); i ++)
+ {
+ if(!perr.IsFull ())
+ perr.AddAddressUnit (*i);
+ else
+ {
+ packet->AddHeader (perr);
+ perr.ResetPerr ();
+ }
+ }
+ if(perr.GetNumOfDest () > 0)
+ packet->AddHeader (perr);
+ packet->AddHeader (GetWifiMeshActionHeader ());
+ //create 802.11 header:
+ WifiMacHeader hdr;
+ hdr.SetAction ();
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ hdr.SetAddr2 (m_parent->GetAddress ());
+ hdr.SetAddr3 (m_protocol->GetAddress ());
+ if(receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
+ {
+ receivers.clear ();
+ receivers.push_back (Mac48Address::GetBroadcast ());
+ }
+ //Send Management frame
+ for(std::vector<Mac48Address>::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
{
- bool should_add = true;
- for (unsigned int j = 0; j < m_myPerr.receivers.size (); j ++)
- if(receivers[j] == m_myPerr.receivers[i])
- should_add = false;
- if(should_add)
- m_myPerr.receivers.push_back(receivers[i]);
+ hdr.SetAddr1 (*i);
+ m_stats.txPerr ++;
+ m_stats.txMgt ++;
+ m_stats.txMgtBytes += packet->GetSize ();
+ m_parent->SendManagementFrame(packet, hdr);
+ }
+}
+void
+HwmpProtocolMac::InitiatePerr (std::vector<IePerr::FailedDestination> failedDestinations, std::vector<Mac48Address> receivers)
+{
+ //All duplicates in PERR are checked here, and there is no reason to
+ //check it at any athoer place
+ {
+ std::vector<Mac48Address>::const_iterator end = receivers.end();
+ for(std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != end; i ++)
+ {
+ bool should_add = true;
+ for (std::vector<Mac48Address>::const_iterator j = m_myPerr.receivers.begin (); j != m_myPerr.receivers.end (); j ++)
+ if ((*i) == (*j))
+ should_add = false;
+ if (should_add)
+ m_myPerr.receivers.push_back(*i);
+ }
}
- SendOnePerr ();
+ {
+ std::vector<IePerr::FailedDestination>::const_iterator end = failedDestinations.end ();
+ for(std::vector<IePerr::FailedDestination>::const_iterator i = failedDestinations.begin (); i != end; i ++)
+ {
+ bool should_add = true;
+ for
+ (
+ std::vector<IePerr::FailedDestination>::const_iterator j = m_myPerr.destinations.begin ();
+ j != m_myPerr.destinations.end ();
+ j ++)
+ if ( ((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum) )
+ should_add = false;
+ if (should_add)
+ m_myPerr.destinations.push_back(*i);
+ }
+ }
+ SendMyPerr ();
+}
+void
+HwmpProtocolMac::SendMyPerr()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if(m_perrTimer.IsRunning ())
+ return;
+ m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this);
+ ForwardPerr (m_myPerr.destinations, m_myPerr.receivers);
+ m_myPerr.destinations.clear ();
+ m_myPerr.receivers.clear ();
}
uint32_t
HwmpProtocolMac::GetLinkMetric(Mac48Address peerAddress) const
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h Tue Jul 14 09:44:09 2009 +0400
@@ -23,6 +23,7 @@
#define HWMP_STATE_H
#include "ns3/mesh-wifi-interface-mac-plugin.h"
+#include "ie-dot11s-preq.h"
#include "ie-dot11s-perr.h"
namespace ns3 {
@@ -32,6 +33,7 @@
namespace dot11s {
class HwmpProtocol;
+class WifiMeshActionHeader;
class IePreq;
class IePrep;
class IePerr;
@@ -57,12 +59,17 @@
private:
friend class HwmpProtocol;
-
+ ///\returns a path selection action header
+ static WifiMeshActionHeader GetWifiMeshActionHeader ();
///\name Intercation with HWMP:
//\{
- void SendPreq(IePreq preq);
- void SendPrep(IePrep prep, Mac48Address receiver);
- void SendPerr(IePerr perr, std::vector<Mac48Address> receivers);
+ void SendPreq (IePreq preq);
+ void SendPreq (std::vector<IePreq> preq);
+ void SendPrep (IePrep prep, Mac48Address receiver);
+ //Forward a peth error
+ void ForwardPerr(std::vector<IePerr::FailedDestination> destinations, std::vector<Mac48Address> receivers);
+ // initiate my own path error
+ void InitiatePerr (std::vector<IePerr::FailedDestination> destinations, std::vector<Mac48Address> receivers);
/** \brief Request a destination. If can not send preq immediately -
* add a destination to exisying PREQ generated by me and stored in
* PREQ queue
@@ -73,8 +80,8 @@
//\}
/// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
- void SendOnePreq ();
- void SendOnePerr ();
+ void SendMyPreq ();
+ void SendMyPerr ();
/// \return metric to HWMP protocol, needed only by metrics to add
//peer as routing entry
uint32_t GetLinkMetric (Mac48Address peerAddress) const;
@@ -87,16 +94,16 @@
uint32_t m_ifIndex;
Ptr<HwmpProtocol> m_protocol;
- ///\name PREQ queue and PREQ timer:
+ ///\name my PREQ and PREQ timer:
//\{
- EventId m_preqTimer;
- std::vector<IePreq> m_preqQueue;
+ EventId m_preqTimer;
+ std::vector<IePreq> m_myPreq;
//\}
///\name PERR timer and stored path error
//\{
EventId m_perrTimer;
struct MyPerr {
- IePerr perr;
+ std::vector<IePerr::FailedDestination> destinations;
std::vector<Mac48Address> receivers;
};
MyPerr m_myPerr;
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc Tue Jul 14 09:44:09 2009 +0400
@@ -34,7 +34,6 @@
#include "airtime-metric.h"
#include "ie-dot11s-preq.h"
#include "ie-dot11s-prep.h"
-#include "ie-dot11s-perr.h"
NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
@@ -304,7 +303,7 @@
if(result.retransmitter != Mac48Address::GetBroadcast ())
{
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
- MakePathError (destinations);
+ InitiatePathError (MakePathError (destinations));
}
m_stats.totalDropped ++;
return false;
@@ -317,6 +316,7 @@
uint32_t dst_seqno = 0;
if(result.retransmitter != Mac48Address::GetBroadcast ())
dst_seqno = result.seqnum;
+ m_stats.initiatedPreq ++;
for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
i->second->RequestDestination(destination, originator_seqno, dst_seqno);
}
@@ -558,28 +558,25 @@
prep_sender->second->SendPrep (prep, result.retransmitter);
}
void
-HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp)
+HwmpProtocol::ReceivePerr (std::vector<IePerr::FailedDestination> destinations, Mac48Address from, uint32_t interface, Mac48Address fromMp)
{
//Acceptance cretirea:
NS_LOG_DEBUG("I am "<<GetAddress ()<<", received PERR from "<<from);
- std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector ();
+ std::vector<IePerr::FailedDestination> retval;
HwmpRtable::LookupResult result;
for(unsigned int i = 0; i < destinations.size (); i ++)
{
result = m_rtable->LookupReactive (destinations[i].destination);
- if (
+ if (!(
(result.retransmitter != from) ||
(result.ifIndex != interface) ||
(result.seqnum > destinations[i].seqnum)
- )
- {
- perr.DeleteAddressUnit(destinations[i].destination);
- continue;
- }
+ ))
+ retval.push_back(destinations[i]);
}
- if(perr.GetNumOfDest () == 0)
+ if(retval.size() == 0)
return;
- MakePathError (destinations);
+ ForwardPathError (MakePathError (retval));
}
void
HwmpProtocol::SendPrep (
@@ -604,8 +601,7 @@
HwmpProtocolMacMap::const_iterator prep_sender = m_interfaces.find (interface);
NS_ASSERT(prep_sender != m_interfaces.end ());
prep_sender->second->SendPrep (prep, retransmitter);
- //m_prepCallback (prep, retransmitter);
-
+ m_stats.initiatedPrep ++;
}
bool
HwmpProtocol::Install (Ptr<MeshPointDevice> mp)
@@ -641,7 +637,7 @@
if(status)
return;
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
- MakePathError (destinations);
+ InitiatePathError (MakePathError (destinations));
}
void
HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
@@ -664,28 +660,47 @@
}
return false;
}
-void
+HwmpProtocol::PathError
HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations)
{
+ PathError retval;
//HwmpRtable increments a sequence number as written in 11B.9.7.2
- std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations);
- if(receivers.size () == 0)
- return;
- IePerr perr;
+ retval.receivers = GetPerrReceivers (destinations);
+ if(retval.receivers.size () == 0)
+ return retval;
+ m_stats.initiatedPerr ++;
for(unsigned int i = 0; i < destinations.size (); i ++)
{
- perr.AddAddressUnit(destinations[i]);
+ retval.destinations.push_back(destinations[i]);
m_rtable->DeleteReactivePath(destinations[i].destination);
}
+ return retval;
+}
+void
+HwmpProtocol::InitiatePathError(PathError perr)
+{
for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
{
std::vector<Mac48Address> receivers_for_interface;
- for(unsigned int j = 0; j < receivers.size(); j ++)
- if(i->first == receivers[j].first)
- receivers_for_interface.push_back(receivers[j].second);
- i->second->SendPerr (perr, receivers_for_interface);
+ for(unsigned int j = 0; j < perr.receivers.size(); j ++)
+ if(i->first == perr.receivers[j].first)
+ receivers_for_interface.push_back(perr.receivers[j].second);
+ i->second->InitiatePerr (perr.destinations, receivers_for_interface);
}
}
+void
+HwmpProtocol::ForwardPathError(PathError perr)
+{
+ for(HwmpProtocolMacMap::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
+ {
+ std::vector<Mac48Address> receivers_for_interface;
+ for(unsigned int j = 0; j < perr.receivers.size(); j ++)
+ if(i->first == perr.receivers[j].first)
+ receivers_for_interface.push_back(perr.receivers[j].second);
+ i->second->ForwardPerr (perr.destinations, receivers_for_interface);
+ }
+}
+
std::vector<std::pair<uint32_t, Mac48Address> >
HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest)
{
@@ -964,7 +979,10 @@
"txBytes=\"" << txBytes << "\" "
"droppedTtl=\"" << droppedTtl << "\" "
"totalQueued=\"" << totalQueued << "\" "
- "totalDropped=\"" << totalDropped << "\"/>\n";
+ "totalDropped=\"" << totalDropped << "\" "
+ "initiatedPreq=\"" << initiatedPreq << "\" "
+ "initiatedPrep=\"" << initiatedPrep << "\" "
+ "initiatedPerr=\"" << initiatedPerr << "\"\n";
}
void
HwmpProtocol::Report (std::ostream & os) const
--- a/src/devices/mesh/dot11s/hwmp-protocol.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.h Tue Jul 14 09:44:09 2009 +0400
@@ -90,7 +90,7 @@
//\{
void ReceivePreq(IePreq preq, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric);
void ReceivePrep(IePrep prep, Mac48Address from, uint32_t interface, Mac48Address fromMp, uint32_t metric);
- void ReceivePerr(IePerr perr, Mac48Address from, uint32_t interface, Mac48Address fromMp);
+ void ReceivePerr(std::vector<IePerr::FailedDestination>, Mac48Address from, uint32_t interface, Mac48Address fromMp);
void SendPrep (
Mac48Address src,
Mac48Address dst,
@@ -100,9 +100,25 @@
uint32_t destinationSN,
uint32_t lifetime,
uint32_t interface);
-
- ///\brief forms a path error information element when list of destination fails on a given interface
- void MakePathError (std::vector<IePerr::FailedDestination> destinations);
+ /**
+ * \brief Structure of path error: IePerr and list of receivers:
+ * interfaces and MAC address
+ */
+ struct PathError
+ {
+ std::vector<IePerr::FailedDestination> destinations;
+ /// interface-address
+ std::vector<std::pair<uint32_t, Mac48Address> > receivers;
+ };
+ /**
+ * \brief forms a path error information element when list of destination fails on a given interface
+ * \attention removes all entries from routing table!
+ */
+ PathError MakePathError (std::vector<IePerr::FailedDestination> destinations);
+ ///\brief Forwards a received path error
+ void ForwardPathError (PathError perr);
+ ///\brief Pasess a selg-generated PERR to interface-plugin
+ void InitiatePathError (PathError perr);
/// \return list of addresses where a PERR should be sent to
std::vector<std::pair<uint32_t, Mac48Address> > GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest);
@@ -151,9 +167,12 @@
uint16_t droppedTtl;
uint16_t totalQueued;
uint16_t totalDropped;
+ uint16_t initiatedPreq;
+ uint16_t initiatedPrep;
+ uint16_t initiatedPerr;
void Print (std::ostream & os) const;
- Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalQueued (0), totalDropped (0) {}
+ Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalQueued (0), totalDropped (0), initiatedPreq (0), initiatedPrep (0), initiatedPerr (0) {}
};
Statistics m_stats;
///\}
--- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc Tue Jul 14 09:44:09 2009 +0400
@@ -32,9 +32,8 @@
void
IePerr::PrintInformation (std::ostream &os) const
{
- os << "Number of failed destinations: = " << m_numOfDest;
- NS_ASSERT (m_numOfDest == m_addressUnits.size ());
- for (unsigned int j = 0; j < m_numOfDest; j++)
+ os << "Number of failed destinations: = " << m_addressUnits.size ();
+ for (unsigned int j = 0; j < m_addressUnits.size (); j++)
{
os << "Failed destination address: = "<< m_addressUnits[j].destination <<
", sequence number = " << m_addressUnits[j].seqnum;
@@ -42,22 +41,20 @@
os << "\n";
}
-IePerr::IePerr ():
- m_numOfDest (0)
+IePerr::IePerr ()
{
}
uint8_t
IePerr::GetNumOfDest ()
{
- return m_numOfDest;
+ return m_addressUnits.size ();
}
void
IePerr::SerializeInformation (Buffer::Iterator i) const
{
i.WriteU8 (0);
- i.WriteU8 (m_numOfDest);
- NS_ASSERT (m_numOfDest == m_addressUnits.size ());
- for (unsigned int j = 0; j < m_numOfDest; j++)
+ i.WriteU8 (m_addressUnits.size ());
+ for (unsigned int j = 0; j < m_addressUnits.size (); j++)
{
WriteTo (i, m_addressUnits[j].destination);
i.WriteHtolsbU32 (m_addressUnits[j].seqnum);
@@ -68,10 +65,10 @@
{
Buffer::Iterator i = start;
i.Next (1); //Mode flags is not used now
- m_numOfDest = i.ReadU8 ();
- NS_ASSERT ((2+10*m_numOfDest) == length);
+ uint8_t numOfDest = i.ReadU8 ();
+ NS_ASSERT ((2+10*numOfDest) == length);
length = 0; //to avoid compiler warning in optimized builds
- for (unsigned int j = 0; j < m_numOfDest; j++)
+ for (unsigned int j = 0; j < numOfDest; j++)
{
FailedDestination unit;
ReadFrom (i,unit.destination);
@@ -87,8 +84,7 @@
uint8_t retval =
1 //ModeFlags
+1 //NumOfDests
- +6*m_numOfDest
- +4*m_numOfDest;
+ +(6+4) * m_addressUnits.size ();
return retval;
}
@@ -98,10 +94,15 @@
for (unsigned int i = 0; i < m_addressUnits.size (); i ++)
if (m_addressUnits[i].destination == unit.destination)
return;
+ if((m_addressUnits.size () + 1) * 10 + 2 > 255)
+ return;
m_addressUnits.push_back (unit);
- m_numOfDest++;
}
-
+bool
+IePerr::IsFull () const
+{
+ return (GetSerializedSize () + 10 > 255);
+}
std::vector<IePerr::FailedDestination>
IePerr::GetAddressUnitVector () const
{
@@ -113,34 +114,18 @@
for (std::vector<FailedDestination>::iterator i = m_addressUnits.begin (); i != m_addressUnits.end(); i ++)
if (i->destination == address)
{
- m_numOfDest --;
m_addressUnits.erase (i);
break;
}
}
void
-IePerr::Merge(const IePerr perr)
-{
- std::vector<FailedDestination> to_merge = perr.GetAddressUnitVector ();
- for (std::vector<FailedDestination>::iterator i = to_merge.begin (); i != to_merge.end(); i ++)
- {
- bool should_add = true;
- for (std::vector<FailedDestination>::iterator j = m_addressUnits.begin (); j != m_addressUnits.end(); j ++)
- if ((i->destination == j->destination) && (i->seqnum <= j->seqnum))
- should_add = false;
- if(should_add)
- AddAddressUnit (*i);
- }
-}
-void
IePerr::ResetPerr ()
{
- m_numOfDest = 0;
m_addressUnits.clear ();
}
bool operator== (const IePerr & a, const IePerr & b)
{
- if(a.m_numOfDest != b.m_numOfDest)
+ if(a.m_addressUnits.size () != b.m_addressUnits.size ())
return false;
for(unsigned int i = 0; i < a.m_addressUnits.size(); i ++)
{
@@ -179,10 +164,6 @@
dest.seqnum = 3;
a.AddAddressUnit(dest);
- IePerr b = a;
- b.Merge(a);
- NS_TEST_ASSERT_EQUAL (a, b);
-
result = result && TestRoundtripSerialization (a);
return result;
}
--- a/src/devices/mesh/dot11s/ie-dot11s-perr.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-perr.h Tue Jul 14 09:44:09 2009 +0400
@@ -44,9 +44,9 @@
uint8_t GetNumOfDest ();
void AddAddressUnit (struct FailedDestination unit);
+ bool IsFull () const;
std::vector<FailedDestination> GetAddressUnitVector () const;
void DeleteAddressUnit (Mac48Address address);
- void Merge(const IePerr perr);
void ResetPerr ();
private:
WifiElementId ElementId () const{
@@ -57,7 +57,6 @@
void PrintInformation (std::ostream& os) const;
uint8_t GetInformationSize () const;
private:
- uint8_t m_numOfDest;
std::vector<FailedDestination> m_addressUnits;
friend bool operator== (const IePerr & a, const IePerr & b);
};
--- a/src/devices/mesh/dot11s/ie-dot11s-prep.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-prep.cc Tue Jul 14 09:44:09 2009 +0400
@@ -188,8 +188,7 @@
+4 //Lifetime
+4 //metric
+6 //Originator address
- +4 //Originator seqno
- +1; //destination count
+ +4; //Originator seqno
return retval;
};
void
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.cc Tue Jul 14 09:44:09 2009 +0400
@@ -336,6 +336,7 @@
for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator i = m_destinations.begin (); i != m_destinations.end(); i++ )
if ((*i)->GetDestinationAddress () == dest_address)
return;
+ //TODO: check overflow
Ptr<DestinationAddressUnit>new_element = Create<DestinationAddressUnit> ();
new_element->SetFlags (doFlag, rfFlag, false);
new_element->SetDestinationAddress (dest_address);
@@ -355,7 +356,7 @@
}
}
void
-IePreq::ClearDestinationAddressElement ()
+IePreq::ClearDestinationAddressElements ()
{
int i;
for (std::vector<Ptr<DestinationAddressUnit> >::iterator j = m_destinations.begin (); j != m_destinations.end(); j++)
@@ -363,6 +364,7 @@
for (i = 0; i < m_destCount; i ++)
m_destinations.pop_back ();
m_destinations.clear ();
+ m_destCount = 0;
}
bool operator== (const DestinationAddressUnit & a, const DestinationAddressUnit & b)
{
@@ -408,8 +410,15 @@
return false;
if(m_destinations[0]->GetDestinationAddress () == Mac48Address::GetBroadcast ())
return false;
+ if((GetInformationSize () + 11) > 255)
+ return false;
return true;
}
+bool
+IePreq::IsFull () const
+{
+ return ((GetInformationSize () + 11) > 255);
+}
#ifdef RUN_SELF_TESTS
/// Built-in self test for IePreq
--- a/src/devices/mesh/dot11s/ie-dot11s-preq.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/dot11s/ie-dot11s-preq.h Tue Jul 14 09:44:09 2009 +0400
@@ -64,20 +64,30 @@
public:
IePreq ();
~IePreq ();
+ /**
+ * Add a destination address unit: flags, destination and sequence
+ * number
+ */
void AddDestinationAddressElement (
bool doFlag,
bool rfFlag,
Mac48Address dest_address,
uint32_t dest_seq_number
);
+ /// Delete a destination address unit by destination
void DelDestinationAddressElement (Mac48Address dest_address);
- void ClearDestinationAddressElement ();
+ /// Clear PREQ: remove all destinations
+ void ClearDestinationAddressElements ();
+ /// Get all destinations, which are stored in PREQ:
std::vector<Ptr<DestinationAddressUnit> > GetDestinationList ();
+ /// SetProper flags which indicate that PREQ is unicast
void SetUnicastPreq ();
/*
* \brief In proactive case: need we send PREP
*/
void SetNeedNotPrep ();
+ ///\name Setters for fields:
+ ///\{
void SetHopcount (uint8_t hopcount);
void SetTTL (uint8_t ttl);
void SetPreqID (uint32_t id);
@@ -86,7 +96,9 @@
void SetLifetime (uint32_t lifetime);
void SetMetric (uint32_t metric);
void SetDestCount (uint8_t dest_count);
-
+ ///\}
+ ///\name Getters for fields:
+ ///\{
bool IsUnicastPreq () const;
bool IsNeedNotPrep () const;
uint8_t GetHopCount () const;
@@ -97,6 +109,8 @@
uint32_t GetLifetime () const;
uint32_t GetMetric () const;
uint8_t GetDestCount () const;
+ ///\}
+ /// Handle TTL and Metric:
void DecrementTtl ();
void IncrementMetric (uint32_t metric);
/*
@@ -104,7 +118,7 @@
* this preq is not proactive
*/
bool MayAddAddress(Mac48Address originator);
-
+ bool IsFull () const;
private:
WifiElementId ElementId () const{
return IE11S_PREQ;
--- a/src/devices/mesh/flame/flame-installer.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/flame/flame-installer.cc Tue Jul 14 09:44:09 2009 +0400
@@ -52,11 +52,18 @@
{
mp->Report (os);
// TODO report flame counters
+ Ptr <FlameProtocol> flame = mp->GetObject<FlameProtocol> ();
+ NS_ASSERT(flame != 0);
+ flame->Report (os);
}
void
FlameStack::ResetStats (const Ptr<MeshPointDevice> mp)
{
mp->ResetStats ();
// TODO reset flame counters
+ Ptr <FlameProtocol> flame = mp->GetObject<FlameProtocol> ();
+ NS_ASSERT(flame != 0);
+
+ flame->ResetStats ();
}
} //namespace ns3
--- a/src/devices/mesh/flame/flame-protocol-mac.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/flame/flame-protocol-mac.cc Tue Jul 14 09:44:09 2009 +0400
@@ -51,6 +51,11 @@
}
tag.receiver = header.GetAddr1 ();
tag.transmitter = header.GetAddr2 ();
+ if(tag.receiver == Mac48Address::GetBroadcast ())
+ m_stats.rxBroadcast ++;
+ else
+ m_stats.rxUnicast ++;
+ m_stats.rxBytes += packet->GetSize ();
packet->AddPacketTag (tag);
return true;
}
@@ -65,6 +70,11 @@
NS_FATAL_ERROR ("FLAME tag must exist here");
}
header.SetAddr1 (tag.receiver);
+ if(tag.receiver == Mac48Address::GetBroadcast ())
+ m_stats.txBroadcast ++;
+ else
+ m_stats.txUnicast ++;
+ m_stats.txBytes += packet->GetSize ();
return true;
}
uint16_t
@@ -73,12 +83,29 @@
return m_parent->GetFrequencyChannel ();
}
void
+FlameProtocolMac::Statistics::Print (std::ostream &os) const
+{
+ os << "<Statistics "
+ "txUnicast=\"" << txUnicast << "\" "
+ "txBroadcast=\"" << txBroadcast << "\" "
+ "txBytes=\"" << txBytes << "\" "
+ "rxUnicast=\"" << rxUnicast << "\" "
+ "rxBroadcast=\"" << rxBroadcast << "\" "
+ "rxBytes=\"" << rxBytes << "\"/>\n";
+}
+void
FlameProtocolMac::Report (std::ostream & os) const
{
+ os << "<FlameProtocolMac\n"
+ "address =\""<< m_parent->GetAddress () <<"\">\n";
+ m_stats.Print(os);
+ os << "</FlameProtocolMac>\n";
+
}
void
FlameProtocolMac::ResetStats ()
{
+ m_stats = Statistics ();
}
} //namespace flame
--- a/src/devices/mesh/flame/flame-protocol-mac.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/flame/flame-protocol-mac.h Tue Jul 14 09:44:09 2009 +0400
@@ -57,6 +57,23 @@
uint32_t m_ifIndex;
Ptr<MeshWifiInterfaceMac> m_parent;
///\}
+ ///\name Statistics:
+ ///\{
+ struct Statistics
+ {
+ uint16_t txUnicast;
+ uint16_t txBroadcast;
+ uint32_t txBytes;
+ uint16_t rxUnicast;
+ uint16_t rxBroadcast;
+ uint32_t rxBytes;
+
+ void Print (std::ostream & os) const;
+ Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), rxUnicast (0), rxBroadcast (0), rxBytes (0) {}
+ };
+ Statistics m_stats;
+ ///\}
+
};
} //namespace flame
} //namespace ns3
--- a/src/devices/mesh/flame/flame-protocol.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/flame/flame-protocol.cc Tue Jul 14 09:44:09 2009 +0400
@@ -157,8 +157,13 @@
flameHdr.SetProtocol (protocolType);
flameHdr.SetOrigDst (destination);
flameHdr.SetOrigSrc (source);
+ m_stats.txBytes += packet->GetSize ();
packet->AddHeader (flameHdr);
tag.receiver = result.retransmitter;
+ if(result.retransmitter == Mac48Address::GetBroadcast ())
+ m_stats.txBroadcast ++;
+ else
+ m_stats.txUnicast ++;
NS_LOG_DEBUG("Source: send packet with RA = " << tag.receiver);
packet->AddPacketTag (tag);
routeReply (true, packet, source, destination, FLAME_PROTOCOL, result.ifIndex);
@@ -179,6 +184,7 @@
"received packet with SA = GetAddress (), RA = " << tag.receiver <<
", TA = " << tag.transmitter <<
", I am "<<GetAddress ());
+ m_stats.totalDropped ++;
return false;
}
if(destination == Mac48Address::GetBroadcast ())
@@ -187,9 +193,11 @@
NS_ASSERT (HandleDataFrame(flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, sourceIface));
FlameTag tag (Mac48Address::GetBroadcast ());
flameHdr.AddCost (1);
+ m_stats.txBytes += packet->GetSize ();
packet->AddHeader (flameHdr);
packet->AddPacketTag (tag);
routeReply (true, packet, source, destination, FLAME_PROTOCOL, FlameRtable::INTERFACE_ANY);
+ m_stats.txBroadcast ++;
return true;
}
else
@@ -204,10 +212,16 @@
NS_LOG_DEBUG("unicast packet dropped, because no route! I am "<<GetAddress () <<
", RA = " << tag.receiver <<
", TA = " << tag.transmitter);
+ m_stats.totalDropped ++;
return false;
}
}
tag.receiver = result.retransmitter;
+ if(result.retransmitter == Mac48Address::GetBroadcast ())
+ m_stats.txBroadcast ++;
+ else
+ m_stats.txUnicast ++;
+ m_stats.txBytes += packet->GetSize ();
flameHdr.AddCost (1);
packet->AddHeader (flameHdr);
packet->AddPacketTag (tag);
@@ -285,10 +299,43 @@
if(result.seqnum >= seqno)
return true;
if (flameHdr.GetCost () > m_maxCost)
+ {
+ m_stats.droppedTtl ++;
return true;
+ }
m_rtable->AddPath (source, receiver, fromInterface, flameHdr.GetCost (), flameHdr.GetSeqno ());
return false;
}
+//Statistics:
+void FlameProtocol::Statistics::Print (std::ostream & os) const
+{
+ os << "<Statistics "
+ "txUnicast=\"" << txUnicast << "\" "
+ "txBroadcast=\"" << txBroadcast << "\" "
+ "txBytes=\"" << txBytes << "\" "
+ "droppedTtl=\"" << droppedTtl << "\" "
+ "totalDropped=\"" << totalDropped << "\"/>\n";
+}
+
+void
+FlameProtocol::Report (std::ostream & os) const
+{
+ os << "<Flame "
+ "address=\"" << m_address << "\"\n"
+ "broadcastInterval=\"" << m_broadcastInterval.GetSeconds () << "\"\n"
+ "maxCost=\"" << (uint16_t)m_maxCost << "\">\n";
+ m_stats.Print (os);
+ for(FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++)
+ plugin->second->Report(os);
+ os << "</Flame>\n";
+}
+void
+FlameProtocol::ResetStats ()
+{
+ m_stats = Statistics ();
+ for(FlamePluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++)
+ plugin->second->ResetStats ();
+}
} //namespace flame
} //namespace ns3
--- a/src/devices/mesh/flame/flame-protocol.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/flame/flame-protocol.h Tue Jul 14 09:44:09 2009 +0400
@@ -33,9 +33,16 @@
* \ingroup mesh
* \defgroup flame FLAME
*
- * \brief Forwarding LAyer for Meshing protocol
+ * \brief Forwarding LAyer for MEshing protocol
*
- * TODO add relevant references
+ * Simple L2.5 mesh routing protocol developed by
+ * Herman Elfrink <herman.elfrink@ti-wmc.nl> and presented in
+ * "Easy Wireless: broadband ad-hoc networking for emergency services"
+ * by Maurits de Graaf et. al. at The Sixth Annual Mediterranean Ad Hoc
+ * Networking WorkShop, Corfu, Greece, June 12-15, 2007
+ *
+ * see also Linux kernel mailing list discussion at
+ * http://lkml.org/lkml/2006/5/23/82
*/
namespace ns3 {
namespace flame {
@@ -126,6 +133,21 @@
uint16_t m_myLastSeqno;
/// Routing table:
Ptr<FlameRtable> m_rtable;
+ ///\name Statistics:
+ ///\{
+ struct Statistics
+ {
+ uint16_t txUnicast;
+ uint16_t txBroadcast;
+ uint32_t txBytes;
+ uint16_t droppedTtl;
+ uint16_t totalDropped;
+ void Print (std::ostream & os) const;
+ Statistics () : txUnicast (0), txBroadcast (0), txBytes (0), droppedTtl (0), totalDropped (0) {}
+ };
+ Statistics m_stats;
+ ///\}
+
};
} //namespace flame
} //namespace ns3
--- a/src/devices/mesh/mesh-wifi-interface-mac.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/mesh-wifi-interface-mac.cc Tue Jul 14 09:44:09 2009 +0400
@@ -31,6 +31,7 @@
#include "ns3/simulator.h"
#include "ns3/yans-wifi-phy.h"
#include "ns3/pointer.h"
+#include "ns3/qos-tag.h"
NS_LOG_COMPONENT_DEFINE ("MeshWifiInterfaceMac");
@@ -62,18 +63,7 @@
&MeshWifiInterfaceMac::GetBeaconGeneration
),
MakeBooleanChecker ()
- )
-
- .AddAttribute ("BE", "The DcaTxop object",
- PointerValue (),
- MakePointerAccessor (&MeshWifiInterfaceMac::GetBE,
- &MeshWifiInterfaceMac::SetBE),
- MakePointerChecker<DcaTxop> ())
- .AddAttribute ("VO", "The DcaTxop object",
- PointerValue (),
- MakePointerAccessor (&MeshWifiInterfaceMac::GetVO,
- &MeshWifiInterfaceMac::SetVO),
- MakePointerChecker<DcaTxop> ());
+ );
return tid;
}
@@ -199,10 +189,8 @@
{
NS_LOG_FUNCTION (this << stationManager);
m_stationManager = stationManager;
- NS_ASSERT(m_BE != 0);
- m_BE->SetWifiRemoteStationManager (stationManager);
- NS_ASSERT(m_VO != 0);
- m_VO->SetWifiRemoteStationManager (stationManager);
+ for (Queues::const_iterator i = m_queues.begin (); i != m_queues.end (); i ++)
+ i->second->SetWifiRemoteStationManager (stationManager);
m_beaconDca->SetWifiRemoteStationManager (stationManager);
m_low->SetWifiRemoteStationManager (stationManager);
}
@@ -293,8 +281,7 @@
m_low = 0;
m_dcfManager = 0;
m_phy = 0;
- m_BE = 0;
- m_VO = 0;
+ m_queues.clear ();
m_beaconSendEvent.Cancel ();
m_beaconDca = 0;
@@ -387,6 +374,11 @@
hdr.SetAddr4 (from);
hdr.SetDsFrom ();
hdr.SetDsTo ();
+ // Fill QoS fields:
+ hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ hdr.SetQosNoEosp ();
+ hdr.SetQosNoAmsdu ();
+ hdr.SetQosTxopLimit (0);
// Address 1 is unknwon here. Routing plugin is responsible to correctly set it.
hdr.SetAddr1 (Mac48Address ());
@@ -414,9 +406,16 @@
}
destination->RecordDisassociated ();
}
+ //Classify: application sets a tag, which is removed here
+ // Get Qos tag:
+ AccessClass ac = AC_BE;
+ QosTag tag;
+ if(packet->RemovePacketTag (tag))
+ ac = QosUtilsMapTidToAc (tag.Get ());
m_stats.sentFrames ++;
m_stats.sentBytes += packet->GetSize ();
- m_BE->Queue (packet, hdr);
+ NS_ASSERT(m_queues.find(ac) != m_queues.end ());
+ m_queues[ac]->Queue (packet, hdr);
}
void
@@ -431,7 +430,12 @@
}
m_stats.sentFrames ++;
m_stats.sentBytes += packet->GetSize ();
- m_VO->Queue (packet, header);
+ Queues::iterator i = m_queues.find (AC_VO);
+ if (i == m_queues.end ())
+ {
+ NS_FATAL_ERROR("Voice queue is not set up!");
+ }
+ m_queues[AC_VO]->Queue (packet, header);
}
SupportedRates
@@ -606,6 +610,9 @@
if (drop) return; // plugin drops frame
}
+ // Check if QoS tag exists and add it:
+ if (hdr->IsQosData ())
+ packet->AddPacketTag (QosTag (hdr->GetQosTid ()));
// Forward data up
if (hdr->IsData ())
ForwardUp (packet, hdr->GetAddr4(), hdr->GetAddr3());
@@ -671,28 +678,28 @@
m_stats = Statistics::Statistics ();
}
void
-MeshWifiInterfaceMac::SetBE (Ptr<DcaTxop> dcaTxop)
+MeshWifiInterfaceMac::SetQueue (Ptr<DcaTxop> queue, AccessClass ac)
{
- m_BE = dcaTxop;
- m_BE->SetLow (m_low);
- m_BE->SetManager (m_dcfManager);
-}
-void
-MeshWifiInterfaceMac::SetVO (Ptr<DcaTxop> dcaTxop)
-{
- m_VO = dcaTxop;
- m_VO->SetLow (m_low);
- m_VO->SetManager (m_dcfManager);
+ Queues::iterator i = m_queues.find(ac);
+ if(i != m_queues.end ())
+ {
+ NS_LOG_WARN("Queue is already set!");
+ return;
+ }
+ m_queues.insert (std::make_pair(ac, queue));
+ m_queues[ac]->SetLow (m_low);
+ m_queues[ac]->SetManager (m_dcfManager);
}
Ptr<DcaTxop>
-MeshWifiInterfaceMac::GetBE () const
+MeshWifiInterfaceMac::GetQueue (AccessClass ac)
{
- return m_BE;
-}
-Ptr<DcaTxop>
-MeshWifiInterfaceMac::GetVO () const
-{
- return m_VO;
+ Queues::iterator i = m_queues.find(ac);
+ if(i != m_queues.end ())
+ {
+ NS_LOG_WARN("Queue is not found! Check access class!");
+ return 0;
+ }
+ return i->second;
}
} // namespace ns3
--- a/src/devices/mesh/mesh-wifi-interface-mac.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/mesh/mesh-wifi-interface-mac.h Tue Jul 14 09:44:09 2009 +0400
@@ -33,7 +33,7 @@
#include "ns3/wifi-mac.h"
#include "ns3/mesh-wifi-interface-mac-plugin.h"
#include "ns3/event-id.h"
-
+#include "qos-utils.h"
namespace ns3 {
class WifiMacHeader;
@@ -160,11 +160,9 @@
void ResetStats ();
/// Enable/disable beacons
void SetBeaconGeneration (bool enable);
+ void SetQueue (Ptr<DcaTxop> queue, AccessClass ac);
private:
- Ptr<DcaTxop> GetBE(void) const;
- void SetBE (Ptr<DcaTxop> dcaTxop);
- Ptr<DcaTxop> GetVO(void) const;
- void SetVO (Ptr<DcaTxop> dcaTxop);
+ Ptr<DcaTxop> GetQueue (AccessClass ac);
/// Frame receive handler
void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
/// Forward frame to mesh point
@@ -183,10 +181,8 @@
private:
///\name Wifi MAC internals
//\{
- Ptr<DcaTxop> m_BE;
- Ptr<DcaTxop> m_BK;
- Ptr<DcaTxop> m_VI;
- Ptr<DcaTxop> m_VO;
+ typedef std::map<AccessClass, Ptr<DcaTxop> > Queues;
+ Queues m_queues;
Ptr<DcaTxop> m_beaconDca;
Ptr<WifiRemoteStationManager> m_stationManager;
Ptr<WifiPhy> m_phy;
--- a/src/devices/wifi/qos-tag.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/wifi/qos-tag.cc Tue Jul 14 09:44:09 2009 +0400
@@ -43,7 +43,11 @@
return GetTypeId ();
}
-QosTag::QosTag()
+QosTag::QosTag ():
+ m_tid (0)
+{}
+QosTag::QosTag (uint8_t tid):
+ m_tid (tid)
{}
uint32_t
--- a/src/devices/wifi/qos-tag.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/wifi/qos-tag.h Tue Jul 14 09:44:09 2009 +0400
@@ -33,6 +33,7 @@
virtual TypeId GetInstanceTypeId (void) const;
QosTag ();
+ QosTag (uint8_t tid);
virtual void Serialize (TagBuffer i) const;
virtual void Deserialize (TagBuffer i);
virtual uint32_t GetSerializedSize () const;
--- a/src/devices/wifi/qos-utils.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/devices/wifi/qos-utils.cc Tue Jul 14 09:44:09 2009 +0400
@@ -28,30 +28,23 @@
switch (tid) {
case 0 :
return AC_BE;
- break;
case 1 :
return AC_BK;
- break;
case 2 :
return AC_BK;
- break;
case 3 :
return AC_BE;
- break;
case 4 :
return AC_VI;
- break;
case 5 :
return AC_VI;
- break;
case 6 :
return AC_VO;
- break;
case 7 :
return AC_VO;
- break;
+ default:
+ return AC_BE;
}
- return AC_UNDEF;
}
uint8_t
--- a/src/helper/mesh-interface-helper.cc Tue Jul 14 09:43:58 2009 +0400
+++ b/src/helper/mesh-interface-helper.cc Tue Jul 14 09:44:09 2009 +0400
@@ -28,8 +28,15 @@
MeshInterfaceHelper::MeshInterfaceHelper ()
{
- m_Be.SetTypeId ("ns3::DcaTxop");
- m_Vo.SetTypeId ("ns3::DcaTxop");
+ m_queues.insert (std::make_pair (AC_VO, ObjectFactory ()));
+ m_queues.insert (std::make_pair (AC_VI, ObjectFactory ()));
+ m_queues.insert (std::make_pair (AC_BE, ObjectFactory ()));
+ m_queues.insert (std::make_pair (AC_BK, ObjectFactory ()));
+
+ m_queues[AC_VO].SetTypeId ("ns3::DcaTxop");
+ m_queues[AC_VI].SetTypeId ("ns3::DcaTxop");
+ m_queues[AC_BE].SetTypeId ("ns3::DcaTxop");
+ m_queues[AC_BK].SetTypeId ("ns3::DcaTxop");
}
MeshInterfaceHelper::~MeshInterfaceHelper ()
@@ -40,14 +47,6 @@
{
MeshInterfaceHelper helper;
helper.SetType ();
- helper.SetBeParameters (
- "MinCw", UintegerValue (15),
- "MaxCw", UintegerValue (255),
- "Aifsn", UintegerValue (2));
- helper.SetVoParameters (
- "MinCw", UintegerValue (3),
- "MaxCw", UintegerValue (7),
- "Aifsn", UintegerValue (2));
helper.SetRemoteStationManager ("ns3::ArfWifiManager");
return helper;
}
@@ -73,26 +72,24 @@
m_mac.Set (n7, v7);
}
void
-MeshInterfaceHelper::SetBeParameters (std::string n0, const AttributeValue &v0,
- std::string n1, const AttributeValue &v1,
- std::string n2, const AttributeValue &v2,
- std::string n3, const AttributeValue &v3)
+MeshInterfaceHelper::SetQueueParameters ( AccessClass ac,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3)
{
- m_Be.Set (n0, v0);
- m_Be.Set (n1, v1);
- m_Be.Set (n2, v2);
- m_Be.Set (n3, v3);
-}
-void
-MeshInterfaceHelper::SetVoParameters (std::string n0, const AttributeValue &v0,
- std::string n1, const AttributeValue &v1,
- std::string n2, const AttributeValue &v2,
- std::string n3, const AttributeValue &v3)
-{
- m_Vo.Set (n0, v0);
- m_Vo.Set (n1, v1);
- m_Vo.Set (n2, v2);
- m_Vo.Set (n3, v3);
+ std::map<AccessClass, ObjectFactory>::iterator queue = m_queues.find (ac);
+ if (queue != m_queues.end ())
+ {
+ queue->second.Set (n0, v0);
+ queue->second.Set (n1, v1);
+ queue->second.Set (n2, v2);
+ queue->second.Set (n3, v3);
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Queue is not set!");
+ }
}
void
MeshInterfaceHelper::SetRemoteStationManager (std::string type,
@@ -137,11 +134,12 @@
Ptr<WifiMac>
MeshInterfaceHelper::Create (void) const
{
- Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
- Ptr<DcaTxop> be = m_Be.Create<DcaTxop> ();
- Ptr<DcaTxop> vo = m_Vo.Create<DcaTxop> ();
- mac->SetAttribute ("BE", PointerValue (be));
- mac->SetAttribute ("VO", PointerValue (vo));
+ Ptr<MeshWifiInterfaceMac> mac = m_mac.Create<MeshWifiInterfaceMac> ();
+ for (std::map<AccessClass, ObjectFactory>::const_iterator i = m_queues.begin (); i != m_queues.end (); i ++)
+ {
+ //Ptr<DcaTxop> dca = i->second->Create ();
+ mac->SetQueue(i->second.Create<DcaTxop> (), i->first);
+ }
return mac;
}
void
--- a/src/helper/mesh-interface-helper.h Tue Jul 14 09:43:58 2009 +0400
+++ b/src/helper/mesh-interface-helper.h Tue Jul 14 09:44:09 2009 +0400
@@ -23,6 +23,7 @@
#include "ns3/wifi-helper.h"
#include "ns3/wifi-net-device.h"
#include "ns3/mesh-wifi-interface-mac.h"
+#include "ns3/qos-utils.h"
namespace ns3 {
class MeshInterfaceHelper : public WifiMacHelper
@@ -51,23 +52,16 @@
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
/**
+ * \param ac is access class of the queue to be adjusted
* \param type the type of ns3::WifiMac to create.
* \param n%d the name of the attribute to set
* \param v%d the value of the attribute to set
*/
- void SetBeParameters ( std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
- std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
- std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
- std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
- /**
- * \param type the type of ns3::WifiMac to create.
- * \param n%d the name of the attribute to set
- * \param v%d the value of the attribute to set
- */
- void SetVoParameters ( std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
- std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
- std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
- std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
+ void SetQueueParameters (AccessClass ac,
+ std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+ std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+ std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+ std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue ());
/**
* \param type the type of ns3::WifiRemoteStationManager to create.
* \param n%d the name of the attribute to set
@@ -104,8 +98,7 @@
Ptr<WifiMac> Create (void) const;
ObjectFactory m_mac;
- ObjectFactory m_Be;
- ObjectFactory m_Vo;
+ std::map<AccessClass, ObjectFactory> m_queues;
ObjectFactory m_stationManager;
};