This commit is contained in:
Pavel Boyko
2009-07-14 09:44:09 +04:00
23 changed files with 533 additions and 343 deletions

View File

@@ -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");

View File

@@ -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
{

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
///\}

View File

@@ -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;
}

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};