merge
This commit is contained in:
@@ -258,17 +258,8 @@ WifiMeshActionHeader::GetAction ()
|
||||
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");
|
||||
|
||||
@@ -111,10 +111,7 @@ public:
|
||||
/* Compatible with open80211s implementation */
|
||||
enum PathSelectionActionValue
|
||||
{
|
||||
PATH_REQUEST = 0,
|
||||
PATH_REPLY = 1,
|
||||
PATH_ERROR = 2,
|
||||
ROOT_ANNOUNCEMENT = 3,
|
||||
PATH_SELECTION = 0,
|
||||
};
|
||||
enum InterworkActionValue
|
||||
{
|
||||
|
||||
@@ -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 @@ HwmpProtocolMac::ReceiveAction (Ptr<Packet> packet, const WifiMacHeader & header
|
||||
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))
|
||||
{
|
||||
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;
|
||||
NS_LOG_WARN("RANN is not supported!");
|
||||
}
|
||||
return true;
|
||||
while (packet->RemoveHeader (preq))
|
||||
{
|
||||
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 ()));
|
||||
}
|
||||
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 @@ HwmpProtocolMac::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & heade
|
||||
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 @@ HwmpProtocolMac::SendOnePreq ()
|
||||
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 ())
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
for(std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end(); i ++)
|
||||
{
|
||||
if(i->IsFull ())
|
||||
continue;
|
||||
NS_ASSERT (i->GetDestCount () > 0);
|
||||
i->AddDestinationAddressElement (m_protocol->GetDoFlag(), m_protocol->GetRfFlag(), dst, dst_seqno);
|
||||
}
|
||||
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_myPerr.receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
|
||||
{
|
||||
m_myPerr.receivers.clear ();
|
||||
m_myPerr.receivers.push_back (Mac48Address::GetBroadcast ());
|
||||
}
|
||||
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 ();
|
||||
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 @@ HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver)
|
||||
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 ++)
|
||||
{
|
||||
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]);
|
||||
if(!perr.IsFull ())
|
||||
perr.AddAddressUnit (*i);
|
||||
else
|
||||
{
|
||||
packet->AddHeader (perr);
|
||||
perr.ResetPerr ();
|
||||
}
|
||||
}
|
||||
SendOnePerr ();
|
||||
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 ++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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 @@ class MeshWifiInterfaceMac;
|
||||
namespace dot11s {
|
||||
|
||||
class HwmpProtocol;
|
||||
class WifiMeshActionHeader;
|
||||
class IePreq;
|
||||
class IePrep;
|
||||
class IePerr;
|
||||
@@ -57,12 +59,17 @@ public:
|
||||
|
||||
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 @@ private:
|
||||
//\}
|
||||
|
||||
/// 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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -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 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c
|
||||
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 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c
|
||||
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 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, M
|
||||
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 @@ HwmpProtocol::SendPrep (
|
||||
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 @@ HwmpProtocol::PeerLinkStatus(Mac48Address meshPointAddress, Mac48Address peerAdd
|
||||
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 @@ HwmpProtocol::DropDataFrame(uint32_t seqno, Mac48Address source)
|
||||
}
|
||||
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 @@ void HwmpProtocol::Statistics::Print (std::ostream & os) const
|
||||
"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
|
||||
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
//\{
|
||||
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 @@ private:
|
||||
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 @@ private:
|
||||
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;
|
||||
///\}
|
||||
|
||||
@@ -32,9 +32,8 @@ IePerr::~IePerr ()
|
||||
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 @@ IePerr::PrintInformation (std::ostream &os) const
|
||||
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 @@ IePerr::DeserializeInformation (Buffer::Iterator start, uint8_t length)
|
||||
{
|
||||
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 @@ IePerr::GetInformationSize () const
|
||||
uint8_t retval =
|
||||
1 //ModeFlags
|
||||
+1 //NumOfDests
|
||||
+6*m_numOfDest
|
||||
+4*m_numOfDest;
|
||||
+(6+4) * m_addressUnits.size ();
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -98,10 +94,15 @@ IePerr::AddAddressUnit (FailedDestination unit)
|
||||
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 @@ IePerr::DeleteAddressUnit (Mac48Address address)
|
||||
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 @@ bool IePerrBist::RunTests ()
|
||||
dest.seqnum = 3;
|
||||
a.AddAddressUnit(dest);
|
||||
|
||||
IePerr b = a;
|
||||
b.Merge(a);
|
||||
NS_TEST_ASSERT_EQUAL (a, b);
|
||||
|
||||
result = result && TestRoundtripSerialization (a);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ public:
|
||||
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 @@ private:
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -188,8 +188,7 @@ IePrep::GetInformationSize () const
|
||||
+4 //Lifetime
|
||||
+4 //metric
|
||||
+6 //Originator address
|
||||
+4 //Originator seqno
|
||||
+1; //destination count
|
||||
+4; //Originator seqno
|
||||
return retval;
|
||||
};
|
||||
void
|
||||
|
||||
@@ -336,6 +336,7 @@ IePreq::AddDestinationAddressElement (
|
||||
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 @@ IePreq::DelDestinationAddressElement (Mac48Address dest_address)
|
||||
}
|
||||
}
|
||||
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 @@ IePreq::ClearDestinationAddressElement ()
|
||||
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 @@ IePreq::MayAddAddress (Mac48Address originator)
|
||||
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
|
||||
|
||||
@@ -64,20 +64,30 @@ class IePreq : public WifiInformationElement
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
* this preq is not proactive
|
||||
*/
|
||||
bool MayAddAddress(Mac48Address originator);
|
||||
|
||||
bool IsFull () const;
|
||||
private:
|
||||
WifiElementId ElementId () const{
|
||||
return IE11S_PREQ;
|
||||
|
||||
@@ -52,11 +52,18 @@ FlameStack::Report (const Ptr<MeshPointDevice> mp, std::ostream& os)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -51,6 +51,11 @@ FlameProtocolMac::Receive (Ptr<Packet> packet, const WifiMacHeader & header)
|
||||
}
|
||||
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 @@ FlameProtocolMac::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & head
|
||||
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 @@ FlameProtocolMac::GetChannelId () const
|
||||
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
|
||||
|
||||
@@ -57,6 +57,23 @@ private:
|
||||
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
|
||||
|
||||
@@ -157,8 +157,13 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c
|
||||
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 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c
|
||||
"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 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c
|
||||
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 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, c
|
||||
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 @@ FlameProtocol::HandleDataFrame (uint16_t seqno, Mac48Address source, const Flame
|
||||
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
|
||||
|
||||
@@ -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 @@ private:
|
||||
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
|
||||
|
||||
@@ -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::GetTypeId ()
|
||||
&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 @@ MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager>
|
||||
{
|
||||
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 @@ MeshWifiInterfaceMac::DoDispose ()
|
||||
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 @@ MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address
|
||||
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 @@ MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address
|
||||
}
|
||||
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 @@ MeshWifiInterfaceMac::SendManagementFrame (Ptr<Packet> packet, const WifiMacHead
|
||||
}
|
||||
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 @@ MeshWifiInterfaceMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
|
||||
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 @@ MeshWifiInterfaceMac::ResetStats ()
|
||||
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
|
||||
|
||||
|
||||
@@ -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 @@ public:
|
||||
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:
|
||||
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;
|
||||
|
||||
@@ -43,7 +43,11 @@ QosTag::GetInstanceTypeId (void) const
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
QosTag::QosTag()
|
||||
QosTag::QosTag ():
|
||||
m_tid (0)
|
||||
{}
|
||||
QosTag::QosTag (uint8_t tid):
|
||||
m_tid (tid)
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
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;
|
||||
|
||||
@@ -28,30 +28,23 @@ QosUtilsMapTidToAc (uint8_t tid)
|
||||
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
|
||||
|
||||
@@ -28,8 +28,15 @@ namespace ns3 {
|
||||
|
||||
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::Default (void)
|
||||
{
|
||||
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 @@ MeshInterfaceHelper::SetType (std::string n0, const AttributeValue &v0,
|
||||
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 @@ MeshInterfaceHelper::CreateInterface (const WifiPhyHelper &phyHelper, Ptr<Node>
|
||||
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
|
||||
|
||||
@@ -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 @@ public:
|
||||
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 @@ private:
|
||||
Ptr<WifiMac> Create (void) const;
|
||||
|
||||
ObjectFactory m_mac;
|
||||
ObjectFactory m_Be;
|
||||
ObjectFactory m_Vo;
|
||||
std::map<AccessClass, ObjectFactory> m_queues;
|
||||
ObjectFactory m_stationManager;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user