merge with ns3dev
This commit is contained in:
@@ -30,13 +30,13 @@
|
||||
#include "hwmp-tag.h"
|
||||
#include "ie-dot11s-preq.h"
|
||||
#include "ie-dot11s-prep.h"
|
||||
#include "ie-dot11s-perr.h"
|
||||
|
||||
namespace ns3 {
|
||||
namespace dot11s {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("HwmpMacPlugin");
|
||||
HwmpMacPlugin::HwmpMacPlugin (uint32_t ifIndex, Ptr<HwmpProtocol> protocol)
|
||||
HwmpMacPlugin::HwmpMacPlugin (uint32_t ifIndex, Ptr<HwmpProtocol> protocol):
|
||||
m_myPreq (m_preqQueue.end())
|
||||
{
|
||||
m_ifIndex = ifIndex;
|
||||
m_protocol = protocol;
|
||||
@@ -142,52 +142,11 @@ HwmpMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header,
|
||||
header.SetAddr1(tag.GetAddress());
|
||||
return true;
|
||||
}
|
||||
#if 0
|
||||
HwmpMacPlugin::HwmpMacPlugin ():
|
||||
m_myPreq (m_preqQueue.end()),
|
||||
{
|
||||
}
|
||||
|
||||
HwmpMacPlugin::~HwmpMacPlugin ()
|
||||
{
|
||||
m_preqQueue.clear ();
|
||||
}
|
||||
//Interaction with HWMP:
|
||||
#endif
|
||||
void
|
||||
HwmpMacPlugin::SendPreq(IePreq preq)
|
||||
{
|
||||
//Create packet
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(preq);
|
||||
//Multihop action header:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_REQUEST;
|
||||
multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader (multihopHdr);
|
||||
//Mesh header
|
||||
WifiMeshHeader meshHdr;
|
||||
meshHdr.SetMeshTtl (m_protocol->GetMaxTtl ());
|
||||
//TODO: should seqno be here?
|
||||
meshHdr.SetMeshSeqno (0);
|
||||
meshHdr.SetAddressExt(1);
|
||||
meshHdr.SetAddr4(preq.GetOriginatorAddress ());
|
||||
packet->AddHeader (meshHdr);
|
||||
//create 802.11 header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction ();
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
hdr.SetAddr2 (m_parent->GetAddress ());
|
||||
hdr.SetAddr3 (Mac48Address::GetBroadcast ());
|
||||
//Send Management frame
|
||||
std::vector <Mac48Address> receivers = m_protocol->GetPreqReceivers (m_ifIndex);
|
||||
for(std::vector<Mac48Address>::iterator i = receivers.begin (); i != receivers.end (); i ++)
|
||||
{
|
||||
hdr.SetAddr1 (*i);
|
||||
m_parent->SendManagementFrame(packet, hdr);
|
||||
}
|
||||
m_preqQueue.push_back (preq);
|
||||
SendOnePreq ();
|
||||
}
|
||||
void
|
||||
HwmpMacPlugin::RequestDestination (Mac48Address dst)
|
||||
@@ -206,149 +165,14 @@ HwmpMacPlugin::RequestDestination (Mac48Address dst)
|
||||
m_preqQueue.push_back (preq);
|
||||
//set iterator position to my preq:
|
||||
m_myPreq = m_preqQueue.end () -1;
|
||||
NS_LOG_UNCOND("no preq");
|
||||
SendOnePreq ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (m_myPreq->GetOriginatorAddress() == m_parent->GetAddress());
|
||||
NS_LOG_UNCOND ("add a destination "<<dst);
|
||||
m_myPreq->AddDestinationAddressElement (false, false, dst, 0); //DO = 0, RF = 0
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
HwmpMacPlugin::SendPathError (std::vector<HwmpRtable::FailedDestination> destinations)
|
||||
{
|
||||
std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback (destinations, m_ifIndex);
|
||||
NS_LOG_DEBUG ("SendPathError started");
|
||||
if (receivers.size () == 0)
|
||||
return;
|
||||
NS_LOG_DEBUG (m_address<<" Should Send PERR to");
|
||||
for (unsigned int i = 0; i < receivers.size (); i ++)
|
||||
{
|
||||
AddPerrReceiver (receivers[i]);
|
||||
NS_LOG_DEBUG (receivers[i]);
|
||||
}
|
||||
NS_LOG_DEBUG ("To tel about failure with");
|
||||
for (unsigned int i = 0; i < destinations.size (); i ++)
|
||||
{
|
||||
m_myPerr.AddAddressUnit (destinations[i]);
|
||||
NS_LOG_DEBUG (destinations[i].destination);
|
||||
}
|
||||
if (!m_perrTimer.IsRunning ())
|
||||
{
|
||||
m_perrCallback (m_myPerr,m_myPerrReceivers);
|
||||
m_myPerr.ResetPerr ();
|
||||
m_perrTimer = Simulator::Schedule (dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpMacPlugin::SendOnePerr,this);
|
||||
}
|
||||
}
|
||||
//needed to fill routing information structure
|
||||
|
||||
void
|
||||
HwmpMacPlugin::ReceivePrep (IeDot11sPrep& prep, const Mac48Address& from, const uint32_t& metric)
|
||||
{
|
||||
if (m_disabled)
|
||||
return;
|
||||
prep.DecrementTtl ();
|
||||
prep.IncrementMetric (metric);
|
||||
//acceptance cretirea:
|
||||
std::map<Mac48Address, uint32_t>::iterator i = m_dsnDatabase.find (prep.GetDestinationAddress());
|
||||
if (i == m_dsnDatabase.end ())
|
||||
{
|
||||
m_dsnDatabase[prep.GetDestinationAddress ()] = prep.GetDestinationSeqNumber();
|
||||
}
|
||||
else
|
||||
if (i->second > prep.GetDestinationSeqNumber ())
|
||||
return;
|
||||
//update routing info
|
||||
HwmpRtable::LookupResult result = m_requestRouteCallback (prep.GetDestinationAddress());
|
||||
if (result.retransmitter == Mac48Address::GetBroadcast ())
|
||||
//try to look for default route
|
||||
result = m_requestRootPathCallback (m_ifIndex);
|
||||
if ((result.retransmitter == Mac48Address::GetBroadcast ())&&(m_address != prep.GetDestinationAddress()))
|
||||
return;
|
||||
INFO newInfo;
|
||||
newInfo.me = m_address;
|
||||
newInfo.destination = prep.GetOriginatorAddress ();
|
||||
newInfo.source = prep.GetDestinationAddress ();
|
||||
newInfo.nextHop = from;
|
||||
newInfo.metric = prep.GetMetric ();
|
||||
newInfo.lifetime = TU_TO_TIME (prep.GetLifetime());
|
||||
newInfo.outPort = m_ifIndex;
|
||||
newInfo.dsn = prep.GetOriginatorSeqNumber ();
|
||||
newInfo.prevHop = result.retransmitter;
|
||||
newInfo.type = INFO_PREP;
|
||||
NS_LOG_DEBUG ("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
|
||||
NS_LOG_DEBUG ("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
|
||||
m_routingInfoCallback (newInfo);
|
||||
if (prep.GetDestinationAddress () == m_address)
|
||||
{
|
||||
NS_LOG_DEBUG ("Destination resolved"<<newInfo.destination);
|
||||
return;
|
||||
}
|
||||
m_prepCallback (prep, result.retransmitter);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpMacPlugin::ReceivePerr (IeDot11sPerr& perr, const Mac48Address& from)
|
||||
{
|
||||
if (m_disabled)
|
||||
return;
|
||||
NS_LOG_DEBUG (m_address<<" RECEIVED PERR from "<<from);
|
||||
/**
|
||||
* Check forwarding conditions:
|
||||
*/
|
||||
std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector ();
|
||||
for (unsigned int i = 0; i < destinations.size (); i ++)
|
||||
{
|
||||
/**
|
||||
* Lookup for a valid routing information
|
||||
*/
|
||||
HwmpRtable::LookupResult result = m_requestRouteCallback (destinations[i].destination);
|
||||
if (
|
||||
(result.retransmitter != from)
|
||||
|| (result.seqnum >= destinations[i].seqnum)
|
||||
)
|
||||
|
||||
perr.DeleteAddressUnit (destinations[i].destination);
|
||||
}
|
||||
NS_LOG_DEBUG ("Retransmit "<<(int)perr.GetNumOfDest());
|
||||
if (perr.GetNumOfDest () == 0)
|
||||
return;
|
||||
destinations = perr.GetAddressUnitVector ();
|
||||
SendPathError (destinations);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpMacPlugin::PeerStatus (const Mac48Address peerAddress, const bool status, const uint32_t metric)
|
||||
{
|
||||
INFO newInfo;
|
||||
newInfo.me = m_address;
|
||||
newInfo.destination = peerAddress;
|
||||
newInfo.nextHop = peerAddress;
|
||||
newInfo.metric = metric;
|
||||
newInfo.outPort = m_ifIndex;
|
||||
newInfo.dsn = 0;
|
||||
if (status)
|
||||
newInfo.type = INFO_NEW_PEER;
|
||||
else
|
||||
newInfo.type = INFO_FAILED_PEER;
|
||||
m_routingInfoCallback (newInfo);
|
||||
}
|
||||
void
|
||||
HwmpMacPlugin::AddPerrReceiver (Mac48Address receiver)
|
||||
{
|
||||
/**
|
||||
* add new vector of addresses to m_perrReceiversand check
|
||||
* duplicates
|
||||
*/
|
||||
for (unsigned int j = 0; j < m_myPerrReceivers.size (); j++)
|
||||
if (m_myPerrReceivers[j] == receiver)
|
||||
return;
|
||||
m_myPerrReceivers.push_back (receiver);
|
||||
}
|
||||
#endif
|
||||
void
|
||||
HwmpMacPlugin::SendOnePreq ()
|
||||
{
|
||||
@@ -358,13 +182,85 @@ HwmpMacPlugin::SendOnePreq ()
|
||||
return;
|
||||
if (m_myPreq == m_preqQueue.begin ())
|
||||
m_myPreq == m_preqQueue.end ();
|
||||
NS_LOG_UNCOND ("I am "<<m_parent->GetAddress ()<<"sending PREQ:"<<m_preqQueue[0]);
|
||||
SendPreq(m_preqQueue[0]);
|
||||
//erase first!
|
||||
m_preqQueue.erase (m_preqQueue.begin());
|
||||
//reschedule sending PREQ
|
||||
NS_ASSERT (!m_preqTimer.IsRunning());
|
||||
m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpMacPlugin::SendOnePreq, this);
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(m_preqQueue[0]);
|
||||
//Multihop action header:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_REQUEST;
|
||||
multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader (multihopHdr);
|
||||
//Mesh header
|
||||
WifiMeshHeader meshHdr;
|
||||
meshHdr.SetMeshTtl (m_protocol->GetMaxTtl ());
|
||||
//TODO: should seqno be here?
|
||||
meshHdr.SetMeshSeqno (0);
|
||||
meshHdr.SetAddressExt(1);
|
||||
meshHdr.SetAddr4(m_preqQueue[0].GetOriginatorAddress ());
|
||||
packet->AddHeader (meshHdr);
|
||||
//create 802.11 header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction ();
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
hdr.SetAddr2 (m_parent->GetAddress ());
|
||||
hdr.SetAddr3 (Mac48Address::GetBroadcast ());
|
||||
//Send Management frame
|
||||
std::vector <Mac48Address> receivers = m_protocol->GetPreqReceivers (m_ifIndex);
|
||||
for(std::vector<Mac48Address>::iterator i = receivers.begin (); i != receivers.end (); i ++)
|
||||
{
|
||||
hdr.SetAddr1 (*i);
|
||||
m_parent->SendManagementFrame(packet, hdr);
|
||||
}
|
||||
//erase queue
|
||||
m_preqQueue.erase (m_preqQueue.begin());
|
||||
}
|
||||
void
|
||||
HwmpMacPlugin::SendOnePerr()
|
||||
{
|
||||
if(m_perrTimer.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 (), &HwmpMacPlugin::SendOnePerr, this);
|
||||
//Create packet
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(m_myPerr.perr);
|
||||
//Multihop action header:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_ERROR;
|
||||
multihopHdr.SetAction (WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader (multihopHdr);
|
||||
//Mesh header
|
||||
WifiMeshHeader meshHdr;
|
||||
meshHdr.SetMeshTtl (m_protocol->GetMaxTtl ());
|
||||
//TODO: should seqno be here?
|
||||
meshHdr.SetMeshSeqno (0);
|
||||
meshHdr.SetAddressExt(1);
|
||||
meshHdr.SetAddr4(m_protocol->GetAddress ());
|
||||
packet->AddHeader (meshHdr);
|
||||
//create 802.11 header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction ();
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
hdr.SetAddr2 (m_parent->GetAddress ());
|
||||
hdr.SetAddr3 (Mac48Address::GetBroadcast ());
|
||||
//Send Management frame
|
||||
for(std::vector<Mac48Address>::iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
|
||||
{
|
||||
hdr.SetAddr1 (*i);
|
||||
m_parent->SendManagementFrame(packet, hdr);
|
||||
}
|
||||
m_myPerr.perr.ResetPerr ();
|
||||
m_myPerr.receivers.clear ();
|
||||
}
|
||||
void
|
||||
HwmpMacPlugin::SendPrep (IePrep prep, Mac48Address receiver)
|
||||
@@ -393,41 +289,24 @@ HwmpMacPlugin::SendPrep (IePrep prep, Mac48Address receiver)
|
||||
hdr.SetDsNotTo ();
|
||||
hdr.SetAddr1 (receiver);
|
||||
hdr.SetAddr2 (m_parent->GetAddress ());
|
||||
hdr.SetAddr3 (Mac48Address::GetBroadcast ());
|
||||
hdr.SetAddr3 (prep.GetDestinationAddress ());
|
||||
//Send Management frame
|
||||
NS_LOG_UNCOND("Sending PREP");
|
||||
m_parent->SendManagementFrame(packet, hdr);
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
HwmpMacPlugin::SendPrep (Mac48Address dst,
|
||||
Mac48Address src,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t initMetric,
|
||||
uint32_t dsn,
|
||||
uint32_t originatorDsn,
|
||||
uint32_t lifetime)
|
||||
HwmpMacPlugin::SendPerr(IePerr perr, std::vector<Mac48Address> receivers)
|
||||
{
|
||||
IeDot11sPrep prep;
|
||||
prep.SetHopcount (0);
|
||||
prep.SetTTL (m_maxTtl);
|
||||
prep.SetDestinationAddress (dst);
|
||||
prep.SetDestinationSeqNumber (dsn);
|
||||
prep.SetLifetime (lifetime);
|
||||
prep.SetMetric (0);
|
||||
prep.SetOriginatorAddress (src);
|
||||
prep.SetOriginatorSeqNumber (originatorDsn);
|
||||
//m_prepCallback (prep, retransmitter);
|
||||
m_myPerr.perr.Merge(perr);
|
||||
for(unsigned int i = 0; i < receivers.size (); 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]);
|
||||
}
|
||||
SendOnePerr ();
|
||||
}
|
||||
|
||||
void
|
||||
HwmpMacPlugin::SendOnePerr ()
|
||||
{
|
||||
if (m_myPerr.GetNumOfDest () == 0)
|
||||
return;
|
||||
m_perrCallback (m_myPerr, m_myPerrReceivers);
|
||||
m_myPerr.ResetPerr ();
|
||||
}
|
||||
#endif
|
||||
} //namespace dot11s
|
||||
}//namespace ns3
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define HWMP_STATE_H
|
||||
|
||||
#include "ns3/mesh-wifi-interface-mac-plugin.h"
|
||||
#include "ie-dot11s-perr.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -67,7 +68,7 @@ private:
|
||||
|
||||
/// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
|
||||
void SendOnePreq ();
|
||||
|
||||
void SendOnePerr ();
|
||||
private:
|
||||
Ptr<MeshWifiInterfaceMac> m_parent;
|
||||
uint32_t m_ifIndex;
|
||||
@@ -79,116 +80,15 @@ private:
|
||||
std::vector<IePreq> m_preqQueue;
|
||||
std::vector<IePreq>::iterator m_myPreq;
|
||||
//\}
|
||||
};
|
||||
|
||||
#if 0
|
||||
class HwmpMacPlugin : public MeshWifiInterfaceMacPlugin {
|
||||
public:
|
||||
static TypeId GetTypeId ();
|
||||
HwmpMacPlugin ();
|
||||
~HwmpMacPlugin ();
|
||||
|
||||
/**
|
||||
* \brief Interface with HWMP - Hwmp can only
|
||||
* request address and collect routing
|
||||
* information
|
||||
*/
|
||||
void SetRequestRouteCallback (
|
||||
Callback<HwmpRtable::LookupResult, const Mac48Address&> cb);
|
||||
void SetRequestRootPathCallback (
|
||||
Callback<HwmpRtable::LookupResult, uint32_t> cb);
|
||||
|
||||
enum InfoType {
|
||||
INFO_PREQ,
|
||||
INFO_PREP,
|
||||
INFO_PERR,
|
||||
INFO_PROACTIVE,
|
||||
INFO_NEW_PEER,
|
||||
INFO_FAILED_PEER
|
||||
///\name PERR timer and stored path error
|
||||
//{
|
||||
EventId m_perrTimer;
|
||||
struct MyPerr {
|
||||
IePerr perr;
|
||||
std::vector<Mac48Address> receivers;
|
||||
};
|
||||
typedef struct RoutingInfo {
|
||||
Mac48Address me;
|
||||
Mac48Address destination;
|
||||
Mac48Address source;
|
||||
Mac48Address nextHop;
|
||||
Mac48Address prevHop;
|
||||
uint32_t outPort;
|
||||
uint32_t metric;
|
||||
std::vector<Mac48Address> failedDestinations;
|
||||
uint32_t dsn;
|
||||
Time lifetime;
|
||||
enum InfoType type;
|
||||
} INFO;
|
||||
void SetRoutingInfoCallback (
|
||||
Callback<void, INFO> cb
|
||||
);
|
||||
void SetRetransmittersOfPerrCallback (
|
||||
Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> cb);
|
||||
void SendPathError (std::vector<HwmpRtable::FailedDestination> destinations);
|
||||
void SetAssociatedIfaceId (uint32_t interface);
|
||||
uint32_t GetAssociatedIfaceId ();
|
||||
//Mac interaction:
|
||||
void SetMac (Ptr<MeshWifiMac> mac);
|
||||
void SetSendPreqCallback (
|
||||
Callback<void, const IeDot11sPreq&> cb);
|
||||
void SetSendPrepCallback (
|
||||
Callback<void, const IeDot11sPrep&> cb);
|
||||
void SetSendPerrCallback (
|
||||
Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > cb);
|
||||
void ReceivePreq (IeDot11sPreq&, const Mac48Address& from, const uint32_t& metric);
|
||||
void ReceivePrep (IeDot11sPrep&, const Mac48Address& from, const uint32_t& metric);
|
||||
void ReceivePerr (IeDot11sPerr&, const Mac48Address& from);
|
||||
private:
|
||||
//true means that we can add a destination to
|
||||
//existing PREQ element
|
||||
//False means that we must send
|
||||
void SendPrep (
|
||||
Mac48Address dst, //dst is PREQ's originator address
|
||||
Mac48Address src, //src is PREQ's destination address
|
||||
Mac48Address retransmitter,
|
||||
uint32_t initMetric,
|
||||
uint32_t dsn,/* taken form PREQ*/
|
||||
uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
|
||||
uint32_t lifetime //taken from PREQ
|
||||
);
|
||||
//HWMP interaction callbacks:
|
||||
Callback<void, INFO> m_routingInfoCallback;
|
||||
Callback<std::vector<Mac48Address>, std::vector<HwmpRtable::FailedDestination>, uint32_t> m_retransmittersOfPerrCallback;
|
||||
Callback<HwmpRtable::LookupResult, const Mac48Address&> m_requestRouteCallback;
|
||||
Callback<HwmpRtable::LookupResult, uint32_t> m_requestRootPathCallback;
|
||||
//Mac interaction callbacks:
|
||||
Callback<void, const IeDot11sPreq&> m_preqCallback;
|
||||
Callback<void, const IeDot11sPrep&, const Mac48Address&> m_prepCallback;
|
||||
Callback<void, const IeDot11sPerr&, std::vector<Mac48Address> > m_perrCallback;
|
||||
//HwmpCounters:
|
||||
uint32_t m_preqId;
|
||||
uint32_t m_myDsn;
|
||||
//Seqno and metric database
|
||||
std::map<Mac48Address, uint32_t> m_dsnDatabase;
|
||||
std::map<Mac48Address, uint32_t> m_preqMetricDatabase;
|
||||
//Disable/enable functionality
|
||||
bool m_disabled;
|
||||
//Proactive PREQ mechanism:
|
||||
EventId m_proactivePreqTimer;
|
||||
void SendProactivePreq ();
|
||||
/**
|
||||
* \brief Two PERRs may not be sent closer to
|
||||
* each other than
|
||||
* dot11MeshHWMPperrMinInterval, so, each HWMP
|
||||
* state collects all unreachable destinations
|
||||
* and once in dot11MeshHWMPperrMinInterval
|
||||
* should send PERR, and PERR element should
|
||||
* be cleared
|
||||
*/
|
||||
IeDot11sPerr m_myPerr;
|
||||
std::vector<Mac48Address> m_myPerrReceivers;
|
||||
void AddPerrReceiver (Mac48Address receiver);
|
||||
EventId m_perrTimer;
|
||||
void SendOnePerr ();
|
||||
//Configurable parameters:
|
||||
uint8_t m_maxTtl;
|
||||
MyPerr m_myPerr;
|
||||
};
|
||||
#endif
|
||||
} //namespace dot11s
|
||||
} //namespace ns3
|
||||
#endif
|
||||
|
||||
@@ -172,7 +172,6 @@ HwmpProtocol::RequestRoute (
|
||||
tag.SetTtl (m_maxTtl+1);
|
||||
if (m_dataSeqno == 0xffffffff)
|
||||
m_dataSeqno = 0;
|
||||
NS_LOG_UNCOND("add a tag"<<packet->GetUid());
|
||||
packet->AddPacketTag(tag);
|
||||
}
|
||||
}
|
||||
@@ -225,7 +224,8 @@ HwmpProtocol::ForwardUnicast(uint32_t sourceIface, const Mac48Address source, c
|
||||
result = m_rtable->LookupProactiveExpired ();
|
||||
if((result.retransmitter == Mac48Address::GetBroadcast ()) && (!m_isRoot))
|
||||
return false;
|
||||
MakePathError (result.retransmitter);
|
||||
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
|
||||
MakePathError (destinations);
|
||||
if(!m_isRoot)
|
||||
return false;
|
||||
}
|
||||
@@ -319,7 +319,6 @@ HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface)
|
||||
}
|
||||
if ((*i)->GetDestinationAddress () == m_address)
|
||||
{
|
||||
NS_LOG_UNCOND("PREQ has reached destination:"<<m_address);
|
||||
preq.DelDestinationAddressElement ((*i)->GetDestinationAddress());
|
||||
SendPrep (
|
||||
m_address,
|
||||
@@ -372,7 +371,7 @@ HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface)
|
||||
if (preq.GetDestCount () == 0)
|
||||
return;
|
||||
//Forward PREQ to all interfaces:
|
||||
NS_LOG_UNCOND("I am "<<m_address<<"retransmitting PREQ:"<<preq);
|
||||
NS_LOG_DEBUG("I am "<<m_address<<"retransmitting PREQ:"<<preq);
|
||||
for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
|
||||
i->second->SendPreq (preq);
|
||||
}
|
||||
@@ -381,7 +380,7 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface)
|
||||
{
|
||||
prep.IncrementMetric (1);
|
||||
//acceptance cretirea:
|
||||
NS_LOG_UNCOND("I am "<<m_address<<", received prep");
|
||||
NS_LOG_DEBUG("I am "<<m_address<<", received prep");
|
||||
std::map<Mac48Address, uint32_t>::iterator i = m_lastHwmpSeqno.find (prep.GetOriginatorAddress());
|
||||
if (i == m_lastHwmpSeqno.end ())
|
||||
{
|
||||
@@ -407,10 +406,7 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface)
|
||||
//try to look for default route
|
||||
result = m_rtable->LookupProactive ();
|
||||
if (result.retransmitter == Mac48Address::GetBroadcast ())
|
||||
{
|
||||
NS_LOG_UNCOND("I am "<<m_address<<", can not forward prep");
|
||||
return;
|
||||
}
|
||||
m_rtable->AddPrecursor (prep.GetOriginatorAddress (), interface, result.retransmitter);
|
||||
//Forward PREP
|
||||
HwmpPluginMap::iterator prep_sender = m_interfaces.find (result.ifIndex);
|
||||
@@ -421,6 +417,29 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface)
|
||||
void
|
||||
HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface)
|
||||
{
|
||||
//Acceptance cretirea:
|
||||
NS_LOG_DEBUG("I am "<<m_address<<", received PERR from "<<from);
|
||||
std::vector<IePerr::FailedDestination> destinations = perr.GetAddressUnitVector ();
|
||||
HwmpRtable::LookupResult result;
|
||||
for(unsigned int i = 0; i < destinations.size (); i ++)
|
||||
{
|
||||
result = m_rtable->LookupReactive (destinations[i].destination);
|
||||
NS_LOG_DEBUG("Destination = "<<destinations[i].destination<<", RA = "<<result.retransmitter);
|
||||
if (
|
||||
(result.retransmitter != from) ||
|
||||
(result.ifIndex != interface) ||
|
||||
(result.seqnum > destinations[i].seqnum)
|
||||
)
|
||||
{
|
||||
perr.DeleteAddressUnit(destinations[i].destination);
|
||||
continue;
|
||||
}
|
||||
m_rtable->DeleteReactivePath(destinations[i].destination);
|
||||
}
|
||||
if(perr.GetNumOfDest () == 0)
|
||||
return;
|
||||
NS_LOG_UNCOND("Forward PERR");
|
||||
MakePathError (destinations);
|
||||
}
|
||||
void
|
||||
HwmpProtocol::SendPrep (
|
||||
@@ -433,7 +452,6 @@ HwmpProtocol::SendPrep (
|
||||
uint32_t lifetime,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_LOG_UNCOND("sending prep to "<<dst<<" through "<<retransmitter);
|
||||
IePrep prep;
|
||||
prep.SetHopcount (0);
|
||||
prep.SetTtl (m_maxTtl);
|
||||
@@ -471,10 +489,6 @@ HwmpProtocol::Install (Ptr<MeshPointDevice> mp)
|
||||
mp->SetRoutingProtocol (this);
|
||||
// Mesh point aggregates all installed protocols
|
||||
mp->AggregateObject (this);
|
||||
//Address tmp_addr = mp->GetAddress ();
|
||||
//Mac48Address * address = dynamic_cast<Mac48Address *> (&tmp_addr);
|
||||
//if (address == NULL)
|
||||
// return false;
|
||||
m_address = Mac48Address::ConvertFrom (mp->GetAddress ());//* address;
|
||||
return true;
|
||||
}
|
||||
@@ -482,11 +496,12 @@ void
|
||||
HwmpProtocol::PeerLinkStatus(Mac48Address peerAddress, uint32_t interface, bool status)
|
||||
{
|
||||
if(status)
|
||||
{
|
||||
// m_rtable->AddReactivePath(peerAddress, peerAddress, interface, 1, Seconds (0), 0);
|
||||
}
|
||||
m_rtable->AddReactivePath(peerAddress, peerAddress, interface, 1, Seconds (0), 0);
|
||||
else
|
||||
MakePathError (peerAddress);
|
||||
{
|
||||
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
|
||||
MakePathError (destinations);
|
||||
}
|
||||
}
|
||||
void
|
||||
HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
|
||||
@@ -507,104 +522,27 @@ HwmpProtocol::DropDataFrame(uint32_t seqno, Mac48Address source)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
HwmpProtocol::ObtainRoutingInformation (
|
||||
HwmpProtocolState::INFO info
|
||||
)
|
||||
HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations)
|
||||
{
|
||||
switch (info.type)
|
||||
{
|
||||
case HwmpProtocolState::INFO_PREP:
|
||||
if (info.me != info.source)
|
||||
{
|
||||
m_rtable->AddPrecursor (info.source, info.outPort, info.nextHop);
|
||||
m_rtable->AddPrecursor (info.destination, info.outPort, info.prevHop);
|
||||
NS_LOG_DEBUG ("path to "<<info.source<<" precursor is "<<info.nextHop);
|
||||
NS_LOG_DEBUG ("path to "<<info.destination<<" precursor is "<<info.prevHop);
|
||||
}
|
||||
case HwmpProtocolState::INFO_PREQ:
|
||||
m_rtable->AddReactivePath (
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.metric,
|
||||
info.lifetime,
|
||||
info.dsn);
|
||||
SendAllPossiblePackets (info.destination);
|
||||
break;
|
||||
case HwmpProtocolState::INFO_PERR:
|
||||
//delete first subentry
|
||||
case HwmpProtocolState::INFO_PROACTIVE:
|
||||
//add information to the root MP.
|
||||
m_rtable->AddProactivePath (
|
||||
info.metric,
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.lifetime,
|
||||
info.dsn);
|
||||
//Set mode as PROACTIVE:
|
||||
SetProactive (info.outPort);
|
||||
break;
|
||||
case HwmpProtocolState::INFO_NEW_PEER:
|
||||
#if 0
|
||||
m_rtable->AddReactivePath (
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.metric,
|
||||
Seconds (0),
|
||||
0);
|
||||
#endif
|
||||
break;
|
||||
case HwmpProtocolState::INFO_FAILED_PEER:
|
||||
/**
|
||||
* Conditions for generating PERR
|
||||
*/
|
||||
{
|
||||
NS_LOG_DEBUG ("Failed peer"<<info.destination);
|
||||
std::vector<HwmpRtable::FailedDestination> failedDestinations =
|
||||
m_rtable->GetUnreachableDestinations (info.destination, info.outPort);
|
||||
/**
|
||||
* Entry about peer does not contain seqnum
|
||||
*/
|
||||
HwmpRtable::FailedDestination peer;
|
||||
peer.destination = info.destination;
|
||||
peer.seqnum = 0;
|
||||
failedDestinations.push_back (peer);
|
||||
MakePathError (failedDestinations, info.outPort);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void
|
||||
HwmpProtocol::MakePathError (Mac48Address retransmitter)
|
||||
{
|
||||
NS_LOG_UNCOND ("START PERR, I am "<<m_address);
|
||||
//TODO:
|
||||
//make a perr IE and send
|
||||
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (retransmitter);
|
||||
//HwmpRtable increments a sequence number as written in 11B.9.7.2
|
||||
NS_LOG_UNCOND("Number of unreachable destinations:"<<destinations.size ());
|
||||
for(std::vector<IePerr::FailedDestination>::iterator i = destinations.begin (); i != destinations.end (); i ++)
|
||||
{
|
||||
HwmpRtable::LookupResult result = m_rtable->LookupReactiveExpired (i->destination);
|
||||
NS_LOG_UNCOND("Address::"<<i->destination<<", next hop is "<<result.retransmitter);
|
||||
}
|
||||
std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations);
|
||||
NS_LOG_UNCOND("Number of perr receivers:"<<receivers.size ());
|
||||
if(receivers.size () == 0)
|
||||
return;
|
||||
for(std::vector<std::pair<uint32_t, Mac48Address> >::iterator i = receivers.begin (); i != receivers.end (); i ++)
|
||||
NS_LOG_UNCOND("Address:"<<i->second<<", interface:"<<i->first);
|
||||
//form a path error and send it to proper ports
|
||||
IePerr perr;
|
||||
NS_ASSERT(false);
|
||||
for(unsigned int i = 0; i < destinations.size (); i ++)
|
||||
{
|
||||
perr.AddAddressUnit(destinations[i]);
|
||||
m_rtable->DeleteReactivePath(destinations[i].destination);
|
||||
}
|
||||
for(HwmpPluginMap::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);
|
||||
}
|
||||
}
|
||||
std::vector<std::pair<uint32_t, Mac48Address> >
|
||||
HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest)
|
||||
@@ -619,16 +557,10 @@ HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDes
|
||||
retval.push_back(precursors[j]);
|
||||
}
|
||||
//Check if we have dublicates in retval and precursors:
|
||||
unsigned int size = retval.size();
|
||||
for (unsigned int i = 0; i < size; i ++)
|
||||
for (unsigned int j = i; j < size; j ++)
|
||||
for (unsigned int i = 0; i < retval.size(); i ++)
|
||||
for (unsigned int j = i; j < retval.size(); j ++)
|
||||
if(retval[i].second == retval[j].second)
|
||||
{
|
||||
//erase and check size
|
||||
NS_LOG_UNCOND("deleting dublicate");
|
||||
retval.erase(retval.begin() + j);
|
||||
size --;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
std::vector<Mac48Address>
|
||||
@@ -672,8 +604,10 @@ HwmpProtocol::DequeueFirstPacket ()
|
||||
QueuedPacket retval;
|
||||
retval.pkt = NULL;
|
||||
if(m_rqueue.size () != 0)
|
||||
{
|
||||
retval = m_rqueue[0];
|
||||
m_rqueue.erase (m_rqueue.begin ());
|
||||
m_rqueue.erase (m_rqueue.begin ());
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
void
|
||||
@@ -724,7 +658,6 @@ HwmpProtocol::ShouldSendPreq (Mac48Address dst)
|
||||
std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.find (dst);
|
||||
if (i == m_preqTimeouts.end ())
|
||||
{
|
||||
NS_LOG_UNCOND("Timeout is:" <<2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds()));
|
||||
m_preqTimeouts[dst] = Simulator::Schedule (
|
||||
MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
|
||||
&HwmpProtocol::RetryPathDiscovery, this, dst, 0);
|
||||
@@ -763,10 +696,7 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
|
||||
return;
|
||||
}
|
||||
for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
|
||||
{
|
||||
i->second->RequestDestination(dst);
|
||||
i->second->RequestDestination(Mac48Address("00:00:00:00:00:10"));
|
||||
}
|
||||
m_preqTimeouts[dst] = Simulator::Schedule (
|
||||
MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
|
||||
&HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
|
||||
@@ -786,7 +716,6 @@ HwmpProtocol::UnsetRoot ()
|
||||
void
|
||||
HwmpProtocol::SendProactivePreq ()
|
||||
{
|
||||
NS_LOG_DEBUG ("Sending proactive PREQ");
|
||||
IePreq preq;
|
||||
//By default: must answer
|
||||
preq.SetHopcount (0);
|
||||
@@ -797,6 +726,7 @@ HwmpProtocol::SendProactivePreq ()
|
||||
//\attention: do not forget to set originator address, sequence
|
||||
//number and preq ID in HWMP-MAC plugin
|
||||
preq.AddDestinationAddressElement (true, true, Mac48Address::GetBroadcast (), 0);
|
||||
preq.SetOriginatorAddress(m_address);
|
||||
for(HwmpPluginMap::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i ++)
|
||||
i->second->SendPreq(preq);
|
||||
m_proactivePreqTimer = Simulator::Schedule (m_dot11MeshHWMPactiveRootTimeout, &HwmpProtocol::SendProactivePreq, this);
|
||||
@@ -847,6 +777,11 @@ HwmpProtocol::GetActivePathLifetime ()
|
||||
{
|
||||
return m_dot11MeshHWMPactivePathTimeout.GetMicroSeconds () / 1024;
|
||||
}
|
||||
uint8_t
|
||||
HwmpProtocol::GetUnicastPerrThreshold()
|
||||
{
|
||||
return m_unicastPerrThreshold;
|
||||
}
|
||||
Mac48Address
|
||||
HwmpProtocol::GetAddress ()
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ private:
|
||||
uint32_t interface);
|
||||
|
||||
///\brief forms a path error information element when list of destination fails on a given interface
|
||||
void MakePathError (Mac48Address peerAddress);
|
||||
void MakePathError (std::vector<IePerr::FailedDestination> destinations);
|
||||
/// \return list of addresses where a PERR should be sent to
|
||||
std::vector<std::pair<uint32_t, Mac48Address> > GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest);
|
||||
|
||||
@@ -204,6 +204,7 @@ private:
|
||||
uint32_t GetNextPreqId ();
|
||||
uint32_t GetNextHwmpSeqno ();
|
||||
uint32_t GetActivePathLifetime ();
|
||||
uint8_t GetUnicastPerrThreshold ();
|
||||
//\}
|
||||
Callback <std::vector<Mac48Address>, uint32_t> m_neighboursCallback;
|
||||
};
|
||||
|
||||
@@ -107,7 +107,7 @@ IePerr::AddAddressUnit (FailedDestination unit)
|
||||
}
|
||||
|
||||
std::vector<IePerr::FailedDestination>
|
||||
IePerr::GetAddressUnitVector ()
|
||||
IePerr::GetAddressUnitVector () const
|
||||
{
|
||||
return m_addressUnits;
|
||||
}
|
||||
@@ -115,14 +115,27 @@ void
|
||||
IePerr::DeleteAddressUnit (Mac48Address address)
|
||||
{
|
||||
for (std::vector<FailedDestination>::iterator i = m_addressUnits.begin (); i != m_addressUnits.end(); i ++)
|
||||
if ((*i).destination == address)
|
||||
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 ()
|
||||
{
|
||||
|
||||
@@ -45,10 +45,11 @@ public:
|
||||
};
|
||||
uint8_t GetNumOfDest ();
|
||||
|
||||
void AddAddressUnit (struct FailedDestination unit);
|
||||
std::vector<FailedDestination> GetAddressUnitVector ();
|
||||
void DeleteAddressUnit (Mac48Address address);
|
||||
void ResetPerr ();
|
||||
void AddAddressUnit (struct FailedDestination unit);
|
||||
std::vector<FailedDestination> GetAddressUnitVector () const;
|
||||
void DeleteAddressUnit (Mac48Address address);
|
||||
void Merge(const IePerr perr);
|
||||
void ResetPerr ();
|
||||
private:
|
||||
WifiElementId ElementId () const{
|
||||
return IE11S_PERR;
|
||||
|
||||
@@ -454,17 +454,15 @@ PeerManagementProtocol::PeerLinkStatus (uint32_t interface, Mac48Address peerAdd
|
||||
{
|
||||
PeerManagerPluginMap::iterator plugin = m_plugins.find (interface);
|
||||
NS_ASSERT(plugin != m_plugins.end());
|
||||
NS_LOG_UNCOND("LINK between me:"<<plugin->second->GetAddress() <<" and peer:"<<peerAddress<<", at interface "<<interface);
|
||||
NS_LOG_DEBUG(
|
||||
"LINK between me:"<<plugin->second->GetAddress() <<
|
||||
" and peer:"<<peerAddress<<
|
||||
", at interface "<<interface<<
|
||||
"Status(1 - opened, 0 - closed)"<<status);
|
||||
if(status)
|
||||
{
|
||||
NS_LOG_UNCOND("Established");
|
||||
m_numberOfActivePeers ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_UNCOND("Closed");
|
||||
m_numberOfActivePeers --;
|
||||
}
|
||||
if(!m_peerStatusCallback.IsNull ())
|
||||
m_peerStatusCallback (peerAddress, interface, status);
|
||||
}
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/tx-statistics.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("WifiTxStatistics");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
TypeId
|
||||
WifiTxStatistics::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiTxStatistics")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<WifiTxStatistics> ();
|
||||
return tid;
|
||||
}
|
||||
WifiTxStatistics::WifiTxStatistics ():
|
||||
m_numOfGroups (10),
|
||||
m_maxLength (2500)
|
||||
{
|
||||
}
|
||||
WifiTxStatistics::~WifiTxStatistics ()
|
||||
{
|
||||
}
|
||||
void
|
||||
WifiTxStatistics::SetLengthDivisionParams (uint16_t maxLength, uint8_t numOfGroups)
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
WifiTxStatistics::NotifyDataSent (uint16_t length, uint32_t dataRate)
|
||||
{
|
||||
m_currentSize = length;
|
||||
m_currentRate = dataRate;
|
||||
}
|
||||
|
||||
WifiTxStatistics::RATE_STAT::iterator
|
||||
WifiTxStatistics::FillCurrentStatPosition (uint16_t length, uint32_t dataRate)
|
||||
{
|
||||
uint16_t group = (length/ (m_maxLength/m_numOfGroups)+1)* (m_maxLength/m_numOfGroups);
|
||||
#if 0
|
||||
for (RATE_LENGTH_STAT::iterator i = m_stats.begin (); i != m_stats.end(); i ++)
|
||||
if (i->first == )
|
||||
#endif
|
||||
RATE_LENGTH_STAT::iterator lengthPos = m_stats.find (group);
|
||||
if (lengthPos == m_stats.end ())
|
||||
{
|
||||
RATE_STAT newStat;
|
||||
m_stats[group] = newStat;
|
||||
}
|
||||
lengthPos = m_stats.find (group);
|
||||
NS_ASSERT (lengthPos != m_stats.end());
|
||||
RATE_STAT::iterator ratePos = lengthPos->second.find (dataRate);
|
||||
if (ratePos == lengthPos->second.end ())
|
||||
{
|
||||
SIMPLE_STAT newStat;
|
||||
newStat.packetsFailed =0;
|
||||
newStat.packetsRetried = 0;
|
||||
newStat.packetsAcked = 0;
|
||||
newStat.rtsFailed = 0;
|
||||
newStat.rtsRetried = 0;
|
||||
newStat.rtsAcked = 0;
|
||||
newStat.bytesFailed = 0;
|
||||
newStat.bytesRetried = 0;
|
||||
newStat.bytesAcked = 0;
|
||||
lengthPos->second[dataRate] = newStat;
|
||||
}
|
||||
ratePos = lengthPos->second.find (dataRate);
|
||||
NS_ASSERT (ratePos != lengthPos->second.end());
|
||||
return ratePos;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyDataFailed ()
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition (m_currentSize, m_currentRate);
|
||||
ratePos->second.packetsFailed++;
|
||||
ratePos->second.bytesFailed += m_currentSize;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyGotAck (uint32_t retryCounter)
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition (m_currentSize, m_currentRate);
|
||||
ratePos->second.packetsAcked++;
|
||||
ratePos->second.packetsRetried += retryCounter;
|
||||
ratePos->second.bytesAcked+= m_currentSize;
|
||||
ratePos->second.bytesRetried += (m_currentSize*retryCounter);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsSend (uint32_t rtsRate, uint32_t dataLength)
|
||||
{
|
||||
m_currentSize = dataLength;
|
||||
m_currentRate = rtsRate;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsFailed ()
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition (m_currentSize, m_currentRate);
|
||||
ratePos->second.rtsFailed++;
|
||||
ratePos->second.bytesFailed += m_currentSize;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsSuccess (uint32_t retryCounter)
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition (m_currentSize, m_currentRate);
|
||||
ratePos->second.rtsAcked++;
|
||||
ratePos->second.rtsRetried += retryCounter;
|
||||
ratePos->second.bytesAcked += m_currentSize;
|
||||
ratePos->second.bytesRetried += (m_currentSize*retryCounter);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::ResetStatistics ()
|
||||
{
|
||||
for (RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin (); lengthPos != m_stats.end(); lengthPos++)
|
||||
lengthPos->second.clear ();
|
||||
}
|
||||
#if 0
|
||||
WifiTxStatistics::SIMPLE_STAT
|
||||
WifiTxStatistics::GetTxStatCommon ()
|
||||
{
|
||||
}
|
||||
|
||||
WifiTxStatistics::RATE_STAT
|
||||
WifiTxStatistics::GetTxStatRate ()
|
||||
{
|
||||
}
|
||||
|
||||
WifiTxStatistics::LENGTH_STAT
|
||||
WifiTxStatistics::GetTxStatLength ()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
WifiTxStatistics::TX_STATISTICS
|
||||
WifiTxStatistics::GetTxStatRateLength ()
|
||||
{
|
||||
TX_STATISTICS retval;
|
||||
retval.statistics = m_stats;
|
||||
retval.lengthInterval = m_maxLength / m_numOfGroups;
|
||||
retval.maxLength = m_maxLength;
|
||||
return retval;
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
WifiTxStatistics::Print ()
|
||||
{
|
||||
for (RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin (); lengthPos != m_stats.end(); lengthPos++)
|
||||
{
|
||||
NS_LOG_UNCOND ("\tGROUP = " <<lengthPos->first);
|
||||
for (RATE_STAT::iterator ratePos = lengthPos->second.begin (); ratePos != lengthPos->second.end(); ratePos ++)
|
||||
{
|
||||
NS_LOG_UNCOND ("Rate is "<<ratePos->first
|
||||
<<": SUCCESS = "<<ratePos->second.packetsAcked
|
||||
<<", RRETRY = " <<ratePos->second.packetsRetried
|
||||
<<", FAILURE = "<<ratePos->second.packetsFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} //namespace ns3
|
||||
@@ -1,105 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TX_STAT_H
|
||||
#define TX_STAT_H
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-value.h"
|
||||
#include "ns3/wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
class WifiTxStatistics : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
WifiTxStatistics ();
|
||||
~WifiTxStatistics ();
|
||||
|
||||
struct TxStat
|
||||
{
|
||||
/**
|
||||
* Packet counters:
|
||||
*/
|
||||
uint32_t packetsFailed;
|
||||
uint32_t packetsRetried;
|
||||
uint32_t packetsAcked;
|
||||
/**
|
||||
* RTS counters:
|
||||
*/
|
||||
uint32_t rtsFailed;
|
||||
uint32_t rtsRetried;
|
||||
uint32_t rtsAcked;
|
||||
/**
|
||||
* Byte counters:
|
||||
*/
|
||||
uint64_t bytesFailed;
|
||||
uint64_t bytesRetried;
|
||||
uint64_t bytesAcked;
|
||||
};
|
||||
typedef struct TxStat SIMPLE_STAT;
|
||||
typedef std::map<uint32_t, SIMPLE_STAT> RATE_STAT;
|
||||
#if 0
|
||||
typedef std::map<uint16_t, SIMPLE_STAT> LENGTH_STAT;
|
||||
#endif
|
||||
typedef std::map<uint16_t, RATE_STAT> RATE_LENGTH_STAT;
|
||||
|
||||
void SetLengthDivisionParams (uint16_t maxLength, uint8_t numOfGroups);
|
||||
|
||||
void NotifyDataSent (uint16_t length, uint32_t dataRate);
|
||||
void NotifyDataFailed ();
|
||||
void NotifyGotAck (uint32_t retryCounter);
|
||||
|
||||
void NotifyRtsSend (uint32_t rtsRate, uint32_t dataLength);
|
||||
void NotifyRtsRetried ();
|
||||
void NotifyRtsFailed ();
|
||||
void NotifyRtsSuccess (uint32_t retryCounter);
|
||||
|
||||
void ResetStatistics ();
|
||||
#if 0
|
||||
SIMPLE_STAT GetTxStatCommon ();
|
||||
RATE_STAT GetTxStatRate ();
|
||||
LENGTH_STAT GetTxStatLength ();
|
||||
#endif
|
||||
typedef struct {
|
||||
RATE_LENGTH_STAT statistics;
|
||||
uint16_t lengthInterval;
|
||||
uint16_t maxLength;
|
||||
} TX_STATISTICS;
|
||||
TX_STATISTICS GetTxStatRateLength ();
|
||||
private:
|
||||
RATE_STAT::iterator FillCurrentStatPosition (uint16_t length, uint32_t dataRate);
|
||||
//DEBUG PURPOSE
|
||||
//void Print ();
|
||||
RATE_LENGTH_STAT m_stats;
|
||||
bool m_isTx;
|
||||
uint8_t m_numOfGroups;
|
||||
uint16_t m_maxLength;
|
||||
uint16_t m_currentSize;
|
||||
uint32_t m_currentRate;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
@@ -11,7 +11,7 @@ def build(bld):
|
||||
'mesh-wifi-interface-mac.cc',
|
||||
# Not refactored
|
||||
'mesh-wifi-mac-header.cc',
|
||||
'tx-statistics.cc',
|
||||
#'tx-statistics.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'mesh'
|
||||
@@ -24,7 +24,7 @@ def build(bld):
|
||||
'mesh-wifi-interface-mac.h',
|
||||
'mesh-wifi-interface-mac-plugin.h',
|
||||
# Dirty
|
||||
'tx-statistics.h',
|
||||
#'tx-statistics.h',
|
||||
'mesh-wifi-mac-header.h',
|
||||
]
|
||||
|
||||
|
||||
@@ -422,9 +422,7 @@ WifiRemoteStation::WifiRemoteStation ()
|
||||
: m_state (BRAND_NEW),
|
||||
m_ssrc (0),
|
||||
m_slrc (0)
|
||||
{
|
||||
m_txStat = CreateObject<WifiTxStatistics> ();
|
||||
}
|
||||
{}
|
||||
WifiRemoteStation::~WifiRemoteStation ()
|
||||
{}
|
||||
|
||||
@@ -545,7 +543,7 @@ WifiRemoteStation::GetCtsMode (WifiMode rtsMode)
|
||||
WifiMode
|
||||
WifiRemoteStation::GetAckMode (WifiMode dataMode)
|
||||
{
|
||||
return dataMode;
|
||||
return GetControlAnswerMode (dataMode);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -574,14 +572,12 @@ WifiRemoteStation::GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSiz
|
||||
{
|
||||
if (GetManager ()->IsLowLatency ())
|
||||
{
|
||||
m_txStat->NotifyDataSent(fullPacketSize, DoGetDataMode (fullPacketSize).GetDataRate());
|
||||
return DoGetDataMode (fullPacketSize);
|
||||
}
|
||||
TxModeTag tag;
|
||||
bool found;
|
||||
found = ConstCast<Packet> (packet)->RemovePacketTag (tag);
|
||||
NS_ASSERT (found);
|
||||
m_txStat->NotifyDataSent(fullPacketSize, tag.GetDataMode ().GetDataRate());
|
||||
return tag.GetDataMode ();
|
||||
}
|
||||
WifiMode
|
||||
@@ -589,14 +585,12 @@ WifiRemoteStation::GetRtsMode (Ptr<const Packet> packet)
|
||||
{
|
||||
if (GetManager ()->IsLowLatency ())
|
||||
{
|
||||
m_txStat->NotifyDataSent(packet->GetSize() +36, DoGetRtsMode().GetDataRate());
|
||||
return DoGetRtsMode ();
|
||||
}
|
||||
TxModeTag tag;
|
||||
bool found;
|
||||
found = ConstCast<Packet> (packet)->RemovePacketTag (tag);
|
||||
NS_ASSERT (found);
|
||||
m_txStat->NotifyDataSent(packet->GetSize() +36, tag.GetRtsMode ().GetDataRate());
|
||||
return tag.GetRtsMode ();
|
||||
}
|
||||
|
||||
@@ -699,7 +693,6 @@ WifiRemoteStation::ReportDataFailed (void)
|
||||
void
|
||||
WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
|
||||
{
|
||||
m_txStat->NotifyRtsSuccess(m_ssrc);
|
||||
m_ssrc = 0;
|
||||
DoReportRtsOk (ctsSnr, ctsMode, rtsSnr);
|
||||
}
|
||||
@@ -707,7 +700,6 @@ WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
|
||||
void
|
||||
WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
|
||||
{
|
||||
m_txStat->NotifyGotAck(m_slrc);
|
||||
m_slrc = 0;
|
||||
DoReportDataOk (ackSnr, ackMode, dataSnr);
|
||||
}
|
||||
@@ -716,7 +708,6 @@ void
|
||||
WifiRemoteStation::ReportFinalRtsFailed (void)
|
||||
{
|
||||
m_ssrc = 0;
|
||||
m_txStat->NotifyRtsFailed();
|
||||
DoReportFinalRtsFailed ();
|
||||
}
|
||||
|
||||
@@ -724,7 +715,6 @@ void
|
||||
WifiRemoteStation::ReportFinalDataFailed (void)
|
||||
{
|
||||
m_slrc = 0;
|
||||
m_txStat->NotifyDataFailed();
|
||||
DoReportFinalDataFailed ();
|
||||
}
|
||||
|
||||
@@ -733,16 +723,5 @@ WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
|
||||
{
|
||||
DoReportRxOk (rxSnr, txMode);
|
||||
}
|
||||
WifiTxStatistics::TX_STATISTICS
|
||||
WifiRemoteStation::GetTxStat()
|
||||
{
|
||||
return m_txStat->GetTxStatRateLength();
|
||||
}
|
||||
void
|
||||
WifiRemoteStation::ResetTxStat()
|
||||
{
|
||||
m_txStat->ResetStatistics();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-value.h"
|
||||
#include "ns3/tx-statistics.h"
|
||||
#include "wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -258,8 +257,6 @@ public:
|
||||
* handshake.
|
||||
*/
|
||||
WifiMode GetAckMode (WifiMode dataMode);
|
||||
WifiTxStatistics::TX_STATISTICS GetTxStat();
|
||||
void ResetTxStat();
|
||||
|
||||
private:
|
||||
typedef std::vector<WifiMode> SupportedModes;
|
||||
@@ -289,7 +286,6 @@ private:
|
||||
SupportedModes m_modes;
|
||||
TracedValue<uint32_t> m_ssrc;
|
||||
TracedValue<uint32_t> m_slrc;
|
||||
Ptr<WifiTxStatistics> m_txStat;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
Reference in New Issue
Block a user