--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.cc Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.cc Wed Jul 08 18:45:39 2009 +0400
@@ -228,46 +228,6 @@
m_myPreq.ClearDestinationAddressElements ();
}
void
-HwmpProtocolMac::SendOnePerr()
-{
- NS_LOG_FUNCTION_NOARGS ();
- 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 (), &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 ();
-}
-void
HwmpProtocolMac::SendPrep (IePrep prep, Mac48Address receiver)
{
NS_LOG_FUNCTION_NOARGS ();
@@ -295,9 +255,42 @@
m_parent->SendManagementFrame(packet, hdr);
}
void
-HwmpProtocolMac::SendPerr(IePerr perr, std::vector<Mac48Address> receivers)
+HwmpProtocolMac::ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers)
{
NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader(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 ());
+ 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 (IePerr perr, std::vector<Mac48Address> receivers)
+{
m_myPerr.perr.Merge(perr);
for(unsigned int i = 0; i < receivers.size (); i ++)
{
@@ -308,7 +301,18 @@
if(should_add)
m_myPerr.receivers.push_back(receivers[i]);
}
- SendOnePerr ();
+ 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.perr, m_myPerr.receivers);
+ m_myPerr.perr.ResetPerr ();
+ m_myPerr.receivers.clear ();
}
uint32_t
HwmpProtocolMac::GetLinkMetric(Mac48Address peerAddress) const
--- a/src/devices/mesh/dot11s/hwmp-protocol-mac.h Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol-mac.h Wed Jul 08 18:45:39 2009 +0400
@@ -63,7 +63,10 @@
//\{
void SendPreq(IePreq preq);
void SendPrep(IePrep prep, Mac48Address receiver);
- void SendPerr(IePerr perr, std::vector<Mac48Address> receivers);
+ //Forward a peth error
+ void ForwardPerr(IePerr perr, std::vector<Mac48Address> receivers);
+ // initiate my own path error
+ void InitiatePerr(IePerr perr, 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
@@ -75,7 +78,7 @@
/// Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue)
void SendMyPreq ();
- void SendOnePerr ();
+ void SendMyPerr ();
/// \return metric to HWMP protocol, needed only by metrics to add
//peer as routing entry
uint32_t GetLinkMetric (Mac48Address peerAddress) const;
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc Wed Jul 08 18:45:39 2009 +0400
@@ -304,7 +304,7 @@
if(result.retransmitter != Mac48Address::GetBroadcast ())
{
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (result.retransmitter);
- MakePathError (destinations);
+ InitiatePathError (MakePathError (destinations));
}
m_stats.totalDropped ++;
return false;
@@ -580,7 +580,7 @@
}
if(perr.GetNumOfDest () == 0)
return;
- MakePathError (destinations);
+ ForwardPathError (MakePathError (destinations));
}
void
HwmpProtocol::SendPrep (
@@ -641,7 +641,7 @@
if(status)
return;
std::vector<IePerr::FailedDestination> destinations = m_rtable->GetUnreachableDestinations (peerAddress);
- MakePathError (destinations);
+ InitiatePathError (MakePathError (destinations));
}
void
HwmpProtocol::SetNeighboursCallback(Callback<std::vector<Mac48Address>, uint32_t> cb)
@@ -664,29 +664,47 @@
}
return false;
}
-void
+HwmpProtocol::PathError
HwmpProtocol::MakePathError (std::vector<IePerr::FailedDestination> destinations)
{
+ PathError retval;
//HwmpRtable increments a sequence number as written in 11B.9.7.2
- std::vector<std::pair<uint32_t, Mac48Address> > receivers = GetPerrReceivers (destinations);
- if(receivers.size () == 0)
- return;
- IePerr perr;
+ retval.receivers = GetPerrReceivers (destinations);
+ if(retval.receivers.size () == 0)
+ return retval;
m_stats.initiatedPerr ++;
for(unsigned int i = 0; i < destinations.size (); i ++)
{
- perr.AddAddressUnit(destinations[i]);
+ retval.perr.AddAddressUnit(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.perr, 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.perr, receivers_for_interface);
+ }
+}
+
std::vector<std::pair<uint32_t, Mac48Address> >
HwmpProtocol::GetPerrReceivers (std::vector<IePerr::FailedDestination> failedDest)
{
--- a/src/devices/mesh/dot11s/hwmp-protocol.h Wed Jul 08 17:06:37 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.h Wed Jul 08 18:45:39 2009 +0400
@@ -100,9 +100,25 @@
uint32_t destinationSN,
uint32_t lifetime,
uint32_t interface);
-
- ///\brief forms a path error information element when list of destination fails on a given interface
- void MakePathError (std::vector<IePerr::FailedDestination> destinations);
+ /**
+ * \brief Structure of path error: IePerr and list of receivers:
+ * interfaces and MAC address
+ */
+ struct PathError
+ {
+ IePerr perr;
+ /// 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);