Reactive HWMP is ported!

This commit is contained in:
Kirill Andreev
2009-04-01 16:21:24 +04:00
parent f9888706b3
commit 39bf762761
6 changed files with 144 additions and 192 deletions

View File

@@ -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;
@@ -144,7 +144,6 @@ HwmpMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header,
}
#if 0
HwmpMacPlugin::HwmpMacPlugin ():
m_myPreq (m_preqQueue.end()),
{
}
@@ -243,53 +242,6 @@ HwmpMacPlugin::SendPathError (std::vector<HwmpRtable::FailedDestination> destina
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)
{
@@ -319,35 +271,6 @@ HwmpMacPlugin::ReceivePerr (IeDot11sPerr& perr, const Mac48Address& from)
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 ()
@@ -367,6 +290,50 @@ HwmpMacPlugin::SendOnePreq ()
m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpMacPlugin::SendOnePreq, this);
}
void
HwmpMacPlugin::SendPerr()
{
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::SendPerr, 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)
{
//Create packet
@@ -393,41 +360,25 @@ 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::SendOnePerr(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]);
}
SendPerr ();
}
void
HwmpMacPlugin::SendOnePerr ()
{
if (m_myPerr.GetNumOfDest () == 0)
return;
m_perrCallback (m_myPerr, m_myPerrReceivers);
m_myPerr.ResetPerr ();
}
#endif
} //namespace dot11s
}//namespace ns3

View File

@@ -23,6 +23,7 @@
#define HWMP_STATE_H
#include "ns3/mesh-wifi-interface-mac-plugin.h"
#include "ie-dot11s-perr.h"
namespace ns3 {
@@ -61,13 +62,13 @@ private:
//\{
void SendPreq(IePreq preq);
void SendPrep(IePrep prep, Mac48Address receiver);
void SendPerr(IePerr perr, std::vector<Mac48Address> receivers);
void SendOnePerr(IePerr perr, std::vector<Mac48Address> receivers);
void RequestDestination (Mac48Address dest);
//\}
/// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
void SendOnePreq ();
void SendPerr ();
private:
Ptr<MeshWifiInterfaceMac> m_parent;
uint32_t m_ifIndex;
@@ -79,66 +80,20 @@ private:
std::vector<IePreq> m_preqQueue;
std::vector<IePreq>::iterator m_myPreq;
//\}
///\name PERR timer and stored path error
//{
EventId m_perrTimer;
struct MyPerr {
IePerr perr;
std::vector<Mac48Address> receivers;
};
MyPerr m_myPerr;
};
#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
};
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:
private:
//true means that we can add a destination to
//existing PREQ element
//False means that we must send
@@ -171,22 +126,9 @@ private:
//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);
IeDot11sPerr m_myPerr;
EventId m_perrTimer;
void SendOnePerr ();
//Configurable parameters:
uint8_t m_maxTtl;
};
#endif
} //namespace dot11s

View File

@@ -225,7 +225,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;
}
@@ -421,6 +422,28 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface)
void
HwmpProtocol::ReceivePerr (IePerr perr, Mac48Address from, uint32_t interface)
{
//Acceptance cretirea:
NS_LOG_UNCOND("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_UNCOND("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;
MakePathError (destinations);
}
void
HwmpProtocol::SendPrep (
@@ -486,7 +509,10 @@ HwmpProtocol::PeerLinkStatus(Mac48Address peerAddress, uint32_t interface, bool
// 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)
@@ -583,12 +609,11 @@ HwmpProtocol::ObtainRoutingInformation (
}
#endif
void
HwmpProtocol::MakePathError (Mac48Address retransmitter)
HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations)
{
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 ++)
@@ -604,7 +629,20 @@ HwmpProtocol::MakePathError (Mac48Address retransmitter)
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->SendOnePerr (perr, receivers_for_interface);
}
}
std::vector<std::pair<uint32_t, Mac48Address> >
HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest)
@@ -766,6 +804,7 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
{
i->second->RequestDestination(dst);
i->second->RequestDestination(Mac48Address("00:00:00:00:00:10"));
i->second->RequestDestination(Mac48Address("00:00:00:00:00:24"));
}
m_preqTimeouts[dst] = Simulator::Schedule (
MilliSeconds (2*(m_dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
@@ -847,6 +886,11 @@ HwmpProtocol::GetActivePathLifetime ()
{
return m_dot11MeshHWMPactivePathTimeout.GetMicroSeconds () / 1024;
}
uint8_t
HwmpProtocol::GetUnicastPerrThreshold()
{
return m_unicastPerrThreshold;
}
Mac48Address
HwmpProtocol::GetAddress ()
{

View File

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

View File

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

View File

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