Mesh: fixed HWMP sequence and metric filtering, added route discovery time

trace source, fixed beacon collision avoidanceadded ability to enable/disable
BCA
This commit is contained in:
Kirill Andreev
2009-10-23 15:34:14 +04:00
parent bdb28bbea6
commit 84e1fc122d
13 changed files with 241 additions and 274 deletions

View File

@@ -31,7 +31,7 @@ AirtimeLinkMetricCalculator::GetTypeId ()
.SetParent<Object> ()
.AddConstructor<AirtimeLinkMetricCalculator> ()
.AddAttribute ( "OverheadNanosec",
"Overhead expressed in nanoseconds:DIFS+ 2* SIFS + 2* PREAMBLE + 2* ACK",
"Overhead expressed in nanoseconds:DIFS+ SIFS + 2 * PREAMBLE + ACK",
UintegerValue (108000),
MakeUintegerAccessor (&AirtimeLinkMetricCalculator::m_overheadNanosec),
MakeUintegerChecker<uint32_t> (1)
@@ -80,9 +80,9 @@ AirtimeLinkMetricCalculator::CalculateMetric (Mac48Address peerAddress, Ptr<Mesh
WifiRemoteStation * station = mac->GetStationManager ()->Lookup (peerAddress);
NS_ASSERT (station != 0);
Ptr<Packet> test_frame = Create<Packet> (m_testLength + m_headerLength + m_meshHeaderLength);
Ptr<Packet> test_frame = Create<Packet> (m_testLength + m_meshHeaderLength);
uint32_t rate =
station->GetDataMode (test_frame, m_testLength + m_headerLength + m_meshHeaderLength).GetDataRate ();
station->GetDataMode (test_frame, m_testLength + m_meshHeaderLength).GetDataRate ();
uint32_t payload_nanosec = (uint32_t) (
(double) ((m_testLength + m_meshHeaderLength) * 8 /*octets -> bits*/) * sec2ns / ((double) rate));
uint32_t header_nanosec = (uint32_t) ((double) (m_headerLength * 8 /*octets -> bits*/* sec2ns)

View File

@@ -45,13 +45,13 @@ public:
static TypeId GetTypeId ();
uint32_t CalculateMetric (Mac48Address peerAddress, Ptr<MeshWifiInterfaceMac> mac);
private:
//\brief Overhead expressed in nanoseconds:DIFS+ 2* SIFS + 2*PREAMBLE + 2* ACK
/// Overhead expressed in nanoseconds:DIFS + SIFS + 2 * PREAMBLE + ACK
uint32_t m_overheadNanosec;
///\brief Bt value
/// Bt value
uint32_t m_testLength;
///\brief header length (used in overhead)
/// header length (used in overhead)
uint16_t m_headerLength;
///\brief meshHeader length (6 octets usually)
/// meshHeader length (minimum 6 octets)
uint16_t m_meshHeaderLength;
};
} //namespace dot11s

View File

@@ -33,6 +33,7 @@
#include "airtime-metric.h"
#include "ie-dot11s-preq.h"
#include "ie-dot11s-prep.h"
#include "ns3/trace-source-accessor.h"
#include "ie-dot11s-perr.h"
NS_LOG_COMPONENT_DEFINE ("HwmpProtocol");
@@ -157,7 +158,13 @@ HwmpProtocol::GetTypeId ()
MakeBooleanAccessor (
&HwmpProtocol::m_rfFlag),
MakeBooleanChecker ()
);
)
.AddTraceSource ( "RouteDiscoveryTime",
"The time of route discovery procedure",
MakeTraceSourceAccessor (
&HwmpProtocol::m_routeDiscoveryTimeCallback)
)
;
return tid;
}
@@ -201,14 +208,14 @@ void
HwmpProtocol::DoDispose ()
{
NS_LOG_FUNCTION_NOARGS ();
for (std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i ++)
for (std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.begin (); i != m_preqTimeouts.end (); i ++)
{
i->second.Cancel ();
i->second.preqTimeout.Cancel ();
}
m_proactivePreqTimer.Cancel();
m_preqTimeouts.clear ();
m_lastDataSeqno.clear ();
m_lastHwmpSeqno.clear ();
m_hwmpSeqnoMetricDatabase.clear ();
m_interfaces.clear ();
m_rqueue.clear ();
m_rtable = 0;
@@ -392,31 +399,24 @@ HwmpProtocol::ReceivePreq (IePreq preq, Mac48Address from, uint32_t interface, M
{
preq.IncrementMetric (metric);
//acceptance cretirea:
std::map<Mac48Address, uint32_t>::const_iterator i = m_lastHwmpSeqno.find (preq.GetOriginatorAddress());
if (i == m_lastHwmpSeqno.end ())
std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
preq.GetOriginatorAddress ());
if (i != m_hwmpSeqnoMetricDatabase.end ())
{
m_lastHwmpSeqno[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber ();
m_lastHwmpMetric[preq.GetOriginatorAddress ()] = preq.GetMetric ();
}
else
{
if ((int32_t)(i->second - preq.GetOriginatorSeqNumber ()) > 0)
if ((int32_t)(i->second.first - preq.GetOriginatorSeqNumber ()) > 0)
{
return;
}
if (i->second == preq.GetOriginatorSeqNumber ())
if (i->second.first == preq.GetOriginatorSeqNumber ())
{
//find metric
std::map<Mac48Address, uint32_t>::const_iterator j = m_lastHwmpMetric.find (preq.GetOriginatorAddress());
NS_ASSERT (j != m_lastHwmpSeqno.end ());
if (j->second <= preq.GetMetric ())
if (i->second.second <= preq.GetMetric ())
{
return;
}
}
m_lastHwmpSeqno[preq.GetOriginatorAddress ()] = preq.GetOriginatorSeqNumber ();
m_lastHwmpMetric[preq.GetOriginatorAddress ()] = preq.GetMetric ();
}
m_hwmpSeqnoMetricDatabase[preq.GetOriginatorAddress ()] = std::make_pair (preq.GetOriginatorSeqNumber (), preq.GetMetric ());
NS_LOG_DEBUG("I am " << GetAddress () << "Accepted preq from address" << from << ", preq:" << preq);
std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
//Add reactive path to originator:
@@ -559,25 +559,16 @@ HwmpProtocol::ReceivePrep (IePrep prep, Mac48Address from, uint32_t interface, M
{
prep.IncrementMetric (metric);
//acceptance cretirea:
std::map<Mac48Address, uint32_t>::const_iterator i = m_lastHwmpSeqno.find (prep.GetOriginatorAddress ());
if (i == m_lastHwmpSeqno.end ())
std::map<Mac48Address, std::pair<uint32_t, uint32_t> >::const_iterator i = m_hwmpSeqnoMetricDatabase.find (
prep.GetOriginatorAddress ());
if ((i != m_hwmpSeqnoMetricDatabase.end ()) && ((int32_t)(i->second.first - prep.GetOriginatorSeqNumber ()) > 0))
{
m_lastHwmpSeqno[prep.GetOriginatorAddress ()] = prep.GetOriginatorSeqNumber ();
return;
}
else
{
if ((int32_t)(i->second - prep.GetOriginatorSeqNumber ()) > 0)
{
return;
}
else
{
m_lastHwmpSeqno[prep.GetOriginatorAddress ()] = prep.GetOriginatorSeqNumber ();
}
}
m_hwmpSeqnoMetricDatabase[prep.GetOriginatorAddress ()] = std::make_pair (prep.GetOriginatorSeqNumber (), prep.GetMetric ());
//update routing info
//Now add a path to destination and add precursor to source
NS_LOG_DEBUG("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
NS_LOG_DEBUG ("I am " << GetAddress () << ", received prep from " << prep.GetOriginatorAddress () << ", receiver was:" << from);
HwmpRtable::LookupResult result = m_rtable->LookupReactive (prep.GetDestinationAddress ());
//Add a reactive path only if it is better than existing:
if (
@@ -904,6 +895,12 @@ HwmpProtocol::DequeueFirstPacket ()
void
HwmpProtocol::ReactivePathResolved (Mac48Address dst)
{
std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
if (i != m_preqTimeouts.end ())
{
m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
}
HwmpRtable::LookupResult result = m_rtable->LookupReactive (dst);
NS_ASSERT(result.retransmitter != Mac48Address::GetBroadcast ());
//Send all packets stored for this destination
@@ -950,12 +947,13 @@ HwmpProtocol::ProactivePathResolved ()
bool
HwmpProtocol::ShouldSendPreq (Mac48Address dst)
{
std::map<Mac48Address, EventId>::const_iterator i = m_preqTimeouts.find (dst);
std::map<Mac48Address, PreqEvent>::const_iterator i = m_preqTimeouts.find (dst);
if (i == m_preqTimeouts.end ())
{
m_preqTimeouts[dst] = Simulator::Schedule (
m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
m_dot11MeshHWMPnetDiameterTraversalTime * Scalar (2),
&HwmpProtocol::RetryPathDiscovery, this, dst, 1);
m_preqTimeouts[dst].whenScheduled = Simulator::Now ();
return true;
}
return false;
@@ -970,8 +968,8 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
}
if (result.retransmitter != Mac48Address::GetBroadcast ())
{
std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.find (dst);
NS_ASSERT (i != m_preqTimeouts.end ());
std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
NS_ASSERT (i != m_preqTimeouts.end ());
m_preqTimeouts.erase (i);
return;
}
@@ -986,8 +984,9 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
packet.reply (false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
packet = DequeueFirstPacketByDst (dst);
}
std::map<Mac48Address, EventId>::iterator i = m_preqTimeouts.find (dst);
std::map<Mac48Address, PreqEvent>::iterator i = m_preqTimeouts.find (dst);
NS_ASSERT (i != m_preqTimeouts.end ());
m_routeDiscoveryTimeCallback (Simulator::Now () - i->second.whenScheduled);
m_preqTimeouts.erase (i);
return;
}
@@ -997,7 +996,7 @@ HwmpProtocol::RetryPathDiscovery (Mac48Address dst, uint8_t numOfRetry)
{
i->second->RequestDestination (dst, originator_seqno, dst_seqno);
}
m_preqTimeouts[dst] = Simulator::Schedule (
m_preqTimeouts[dst].preqTimeout = Simulator::Schedule (
Scalar (2 * (numOfRetry + 1)) * m_dot11MeshHWMPnetDiameterTraversalTime,
&HwmpProtocol::RetryPathDiscovery, this, dst, numOfRetry);
}
@@ -1112,7 +1111,7 @@ void HwmpProtocol::Statistics::Print (std::ostream & os) const
"totalDropped=\"" << totalDropped << "\" "
"initiatedPreq=\"" << initiatedPreq << "\" "
"initiatedPrep=\"" << initiatedPrep << "\" "
"initiatedPerr=\"" << initiatedPerr << "\"" << std::endl;
"initiatedPerr=\"" << initiatedPerr << "\"/>" << std::endl;
}
void
HwmpProtocol::Report (std::ostream & os) const

View File

@@ -24,6 +24,7 @@
#include "ns3/mesh-l2-routing-protocol.h"
#include "ns3/nstime.h"
#include "ns3/event-id.h"
#include "ns3/traced-value.h"
#include <vector>
#include <map>
@@ -156,6 +157,8 @@ private:
*/
bool DropDataFrame (uint32_t seqno, Mac48Address source);
//\}
/// Route discovery time:
TracedCallback<Time> m_routeDiscoveryTimeCallback;
///\name Methods related to Queue/Dequeue procedures
///\{
bool QueuePacket (QueuedPacket packet);
@@ -225,18 +228,20 @@ private:
///\{
/// Data sequence number database
std::map<Mac48Address, uint32_t> m_lastDataSeqno;
/// DSN databse
std::map<Mac48Address, uint32_t> m_lastHwmpSeqno;
/// Metric database
std::map<Mac48Address, uint32_t> m_lastHwmpMetric;
/// keeps HWMP seqno (first in pair) and HWMP metric (second in pair) for each address
std::map<Mac48Address, std::pair<uint32_t, uint32_t> > m_hwmpSeqnoMetricDatabase;
///\}
/// Routing table
Ptr<HwmpRtable> m_rtable;
///\name Timers:
///\{
std::map<Mac48Address, EventId> m_preqTimeouts;
//\{
struct PreqEvent {
EventId preqTimeout;
Time whenScheduled;
};
std::map<Mac48Address, PreqEvent> m_preqTimeouts;
EventId m_proactivePreqTimer;
/// Random start in Proactive PREQ propagation
Time m_randomStart;

View File

@@ -94,6 +94,10 @@ PeerLink::PeerLink () :
m_peerMeshPointAddress (Mac48Address::GetBroadcast ()),
m_localLinkId (0),
m_peerLinkId (0),
m_assocId (0),
m_peerAssocId (0),
m_lastBeacon (Seconds (0)),
m_beaconInterval (Seconds (0)),
m_packetFail (0),
m_state (IDLE),
m_retryCounter (0),
@@ -188,6 +192,12 @@ PeerLink::GetLocalAid () const
{
return m_assocId;
}
uint16_t
PeerLink::GetPeerAid () const
{
return m_peerAssocId;
}
Time
PeerLink::GetLastBeacon () const
{

View File

@@ -74,11 +74,9 @@ public:
void SetPeerMeshPointAddress (Mac48Address macaddr);
void SetInterface (uint32_t interface);
void SetLocalLinkId (uint16_t id);
//void SetPeerLinkId (uint16_t id);
void SetLocalAid (uint16_t aid);
//void SetPeerAid (uint16_t aid);
uint16_t GetPeerAid () const;
void SetBeaconTimingElement (IeBeaconTiming beaconTiming);
//void SetPeerLinkDescriptorElement (IePeerManagement peerLinkElement);
Mac48Address GetPeerAddress () const;
uint16_t GetLocalAid () const;
Time GetLastBeacon () const;

View File

@@ -69,22 +69,16 @@ PeerManagementProtocolMac::Receive (Ptr<Packet> const_packet, const WifiMacHeade
{
MgtBeaconHeader beacon_hdr;
packet->RemoveHeader (beacon_hdr);
//meshId.FindFirst (myBeacon);
bool meshBeacon = false;
WifiInformationElementVector elements;
packet->RemoveHeader(elements);
Ptr<IeBeaconTiming> beaconTiming = DynamicCast<IeBeaconTiming> (elements.FindFirst (IE11S_BEACON_TIMING));
Ptr<IeMeshId> meshId = DynamicCast<IeMeshId> (elements.FindFirst (IE11S_MESH_ID));
if ((beaconTiming != 0) && (meshId != 0))
if ((meshId != 0) && (m_protocol->GetMeshId ()->IsEqual (*meshId)))
{
if (m_protocol->GetMeshId ()->IsEqual (*meshId))
{
meshBeacon = true;
}
m_protocol->ReceiveBeacon (m_ifIndex, header.GetAddr2 (), MicroSeconds (
beacon_hdr.GetBeaconIntervalUs ()), beaconTiming);
}
m_protocol->UpdatePeerBeaconTiming (m_ifIndex, meshBeacon, *beaconTiming, header.GetAddr2 (),
Simulator::Now (), MicroSeconds (beacon_hdr.GetBeaconIntervalUs ()));
// Beacon shall not be dropeed. May be needed to another plugins
return true;
}
@@ -190,9 +184,13 @@ PeerManagementProtocolMac::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHead
void
PeerManagementProtocolMac::UpdateBeacon (MeshWifiBeacon & beacon) const
{
Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement (m_ifIndex);
beacon.AddInformationElement (beaconTiming);
if (m_protocol->GetBeaconCollisionAvoidance ())
{
Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement (m_ifIndex);
beacon.AddInformationElement (beaconTiming);
}
beacon.AddInformationElement (m_protocol->GetMeshId ());
m_protocol->NotifyBeaconSent (m_ifIndex, beacon.GetBeaconInterval ());
}
void
@@ -269,14 +267,6 @@ PeerManagementProtocolMac::GetAddress () const
return Mac48Address::Mac48Address ();
}
}
std::pair<Time, Time>
PeerManagementProtocolMac::GetBeaconInfo () const
{
std::pair<Time, Time> retval;
retval.first = m_parent->GetTbtt ();
retval.second = m_parent->GetBeaconInterval ();
return retval;
}
void
PeerManagementProtocolMac::SetBeaconShift (Time shift)
{

View File

@@ -86,15 +86,8 @@ private:
///// Closes link when a proper number of successive transmissions have failed
void TxError (WifiMacHeader const &hdr);
void TxOk (WifiMacHeader const &hdr);
///\name BCA functionallity:
///\{
///\brief Fills TBTT and beacon interval. Needed by BCA
///functionallity
///\param first in retval is TBTT
///\param second in retval is beacon interval
std::pair<Time, Time> GetBeaconInfo () const;
///BCA functionallity:
void SetBeaconShift (Time shift);
///\}
void SetPeerManagerProtcol (Ptr<PeerManagementProtocol> protocol);
void SendPeerLinkManagementFrame (
Mac48Address peerAddress,

View File

@@ -55,18 +55,25 @@ PeerManagementProtocol::GetTypeId (void)
&PeerManagementProtocol::m_maxNumberOfPeerLinks),
MakeUintegerChecker<uint8_t> ()
)
.AddAttribute ( "MaxBeaconLossForBeaconTiming",
"If maximum number of beacons were lost, station will not included in beacon timing element",
UintegerValue (3),
.AddAttribute ( "MaxBeaconShiftValue",
"Maximum number of TUs for beacon shifting",
UintegerValue (15),
MakeUintegerAccessor (
&PeerManagementProtocol::m_maxBeaconLostForBeaconTiming),
MakeUintegerChecker<uint8_t> ()
&PeerManagementProtocol::m_maxBeaconShift),
MakeUintegerChecker<uint16_t> ()
)
.AddAttribute ( "EnableBeaconCollisionAvoidance",
"Enable/Disable Beacon collision avoidance.",
BooleanValue (true),
MakeBooleanAccessor (
&PeerManagementProtocol::SetBeaconCollisionAvoidance, &PeerManagementProtocol::GetBeaconCollisionAvoidance),
MakeBooleanChecker ()
)
;
return tid;
}
PeerManagementProtocol::PeerManagementProtocol () :
m_lastAssocId (0), m_lastLocalLinkId (1), m_maxBeaconLostForBeaconTiming (3)
m_lastAssocId (0), m_lastLocalLinkId (1), m_enableBca (true), m_maxBeaconShift (15)
{
}
PeerManagementProtocol::~PeerManagementProtocol ()
@@ -87,13 +94,6 @@ PeerManagementProtocol::DoDispose ()
j->second.clear ();
}
m_peerLinks.clear ();
//cleaning beacon structures:
for (BeaconInfoMap::iterator i = m_neighbourBeacons.begin (); i != m_neighbourBeacons.end (); i++)
{
i->second.clear ();
}
m_neighbourBeacons.clear ();
m_plugins.clear ();
}
@@ -128,89 +128,33 @@ PeerManagementProtocol::Install (Ptr<MeshPointDevice> mp)
Ptr<IeBeaconTiming>
PeerManagementProtocol::GetBeaconTimingElement (uint32_t interface)
{
if (!GetBeaconCollisionAvoidance ())
{
return 0;
}
Ptr<IeBeaconTiming> retval = Create<IeBeaconTiming> ();
BeaconInfoMap::iterator i = m_neighbourBeacons.find (interface);
if (i == m_neighbourBeacons.end ())
PeerLinksMap::iterator iface = m_peerLinks.find (interface);
NS_ASSERT (iface != m_peerLinks.end ());
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
{
return retval;
}
bool cleaned = false;
while (!cleaned)
{
BeaconsOnInterface::iterator start = i->second.begin ();
for (BeaconsOnInterface::iterator j = start; j != i->second.end (); j++)
//If we do not know peer Assoc Id, we shall not add any info
//to a beacon timing element
if ((*i)->GetBeaconInterval () == Seconds (0))
{
//check beacon loss and make a timing element
//if last beacon was m_maxBeaconLostForBeaconTiming beacons ago - we do not put it to the
//timing element
if ((j->second.referenceTbtt + j->second.beaconInterval * Scalar (m_maxBeaconLostForBeaconTiming))
< Simulator::Now ())
{
start = j;
i->second.erase (j);
break;
}
//No beacon was received, do not include to the beacon timing element
continue;
}
cleaned = true;
}
for (BeaconsOnInterface::const_iterator j = i->second.begin (); j != i->second.end (); j++)
{
retval->AddNeighboursTimingElementUnit (j->second.aid, j->second.referenceTbtt,
j->second.beaconInterval);
retval->AddNeighboursTimingElementUnit ((*i)->GetLocalAid (), (*i)->GetLastBeacon (),
(*i)->GetBeaconInterval ());
}
return retval;
}
void
PeerManagementProtocol::FillBeaconInfo (uint32_t interface, Mac48Address peerAddress, Time receivingTime,
Time beaconInterval)
PeerManagementProtocol::ReceiveBeacon (uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr<IeBeaconTiming> timingElement)
{
BeaconInfoMap::iterator i = m_neighbourBeacons.find (interface);
if (i == m_neighbourBeacons.end ())
{
BeaconsOnInterface newMap;
m_neighbourBeacons[interface] = newMap;
}
i = m_neighbourBeacons.find (interface);
BeaconsOnInterface::iterator j = i->second.find (peerAddress);
if (j == i->second.end ())
{
BeaconInfo newInfo;
newInfo.referenceTbtt = receivingTime;
newInfo.beaconInterval = beaconInterval;
newInfo.aid = m_lastAssocId++;
if (m_lastAssocId == 0xff)
{
m_lastAssocId = 0;
}
i->second[peerAddress] = newInfo;
}
else
{
j->second.referenceTbtt = receivingTime;
j->second.beaconInterval = beaconInterval;
}
}
void
PeerManagementProtocol::UpdatePeerBeaconTiming (uint32_t interface, bool meshBeacon,
IeBeaconTiming timingElement, Mac48Address peerAddress, Time receivingTime, Time beaconInterval)
{
FillBeaconInfo (interface, peerAddress, receivingTime, beaconInterval);
if (!meshBeacon)
{
return;
}
//BCA:
PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
NS_ASSERT (plugin != m_plugins.end ());
Time shift = GetNextBeaconShift (interface);
if (TimeToTu (shift) != 0)
{
plugin->second->SetBeaconShift (shift);
}
//PM STATE Machine
//Check that a given beacon is not from our interface
Simulator::Schedule (beaconInterval - TuToTime (m_maxBeaconShift + 1), &PeerManagementProtocol::DoShiftBeacon, this, interface);
for (PeerManagementProtocolMacMap::const_iterator i = m_plugins.begin (); i != m_plugins.end (); i++)
{
if (i->second->GetAddress () == peerAddress)
@@ -219,21 +163,19 @@ PeerManagementProtocol::UpdatePeerBeaconTiming (uint32_t interface, bool meshBea
}
}
Ptr<PeerLink> peerLink = FindPeerLink (interface, peerAddress);
if (peerLink != 0)
{
peerLink->SetBeaconTimingElement (timingElement);
peerLink->SetBeaconInformation (receivingTime, beaconInterval);
}
else
if (peerLink == 0)
{
if (ShouldSendOpen (interface, peerAddress))
{
peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast (), receivingTime,
beaconInterval);
peerLink->SetBeaconTimingElement (timingElement);
peerLink = InitiateLink (interface, peerAddress, Mac48Address::GetBroadcast ());
peerLink->MLMEActivePeerLinkOpen ();
}
}
peerLink->SetBeaconInformation (Simulator::Now (), beaconInterval);
if (GetBeaconCollisionAvoidance ())
{
peerLink->SetBeaconTimingElement (*PeekPointer (timingElement));
}
}
void
@@ -248,8 +190,7 @@ PeerManagementProtocol::ReceivePeerLinkFrame (uint32_t interface, Mac48Address p
bool reject = !(ShouldAcceptOpen (interface, peerAddress, reasonCode));
if (peerLink == 0)
{
peerLink = InitiateLink (interface, peerAddress, peerMeshPointAddress, Simulator::Now (), Seconds (
1.0));
peerLink = InitiateLink (interface, peerAddress, peerMeshPointAddress);
}
if (!reject)
{
@@ -307,26 +248,9 @@ PeerManagementProtocol::TransmissionSuccess (uint32_t interface, Mac48Address pe
}
Ptr<PeerLink>
PeerManagementProtocol::InitiateLink (uint32_t interface, Mac48Address peerAddress,
Mac48Address peerMeshPointAddress, Time lastBeacon, Time beaconInterval)
Mac48Address peerMeshPointAddress)
{
Ptr<PeerLink> new_link = CreateObject<PeerLink> ();
if (m_lastLocalLinkId == 0xff)
{
m_lastLocalLinkId = 0;
}
//find a beacon entry
BeaconInfoMap::iterator beaconsOnInterface = m_neighbourBeacons.find (interface);
if (beaconsOnInterface == m_neighbourBeacons.end ())
{
FillBeaconInfo (interface, peerAddress, lastBeacon, beaconInterval);
}
beaconsOnInterface = m_neighbourBeacons.find (interface);
BeaconsOnInterface::iterator beacon = beaconsOnInterface->second.find (peerAddress);
if (beacon == beaconsOnInterface->second.end ())
{
FillBeaconInfo (interface, peerAddress, lastBeacon, beaconInterval);
}
beacon = beaconsOnInterface->second.find (peerAddress);
//find a peer link - it must not exist
if (FindPeerLink (interface, peerAddress) != 0)
{
@@ -337,17 +261,17 @@ PeerManagementProtocol::InitiateLink (uint32_t interface, Mac48Address peerAddre
NS_ASSERT (plugin != m_plugins.end ());
PeerLinksMap::iterator iface = m_peerLinks.find (interface);
NS_ASSERT (iface != m_peerLinks.end ());
new_link->SetLocalAid (beacon->second.aid);
new_link->SetLocalAid (m_lastAssocId++);
new_link->SetInterface (interface);
new_link->SetLocalLinkId (m_lastLocalLinkId++);
new_link->SetPeerAddress (peerAddress);
new_link->SetPeerMeshPointAddress (peerMeshPointAddress);
new_link->SetBeaconInformation (lastBeacon, beaconInterval);
new_link->SetMacPlugin (plugin->second);
new_link->MLMESetSignalStatusCallback (MakeCallback (&PeerManagementProtocol::PeerLinkStatus, this));
iface->second.push_back (new_link);
return new_link;
}
Ptr<PeerLink>
PeerManagementProtocol::FindPeerLink (uint32_t interface, Mac48Address peerAddress)
{
@@ -377,13 +301,14 @@ PeerManagementProtocol::SetPeerLinkStatusCallback (
{
m_peerStatusCallback = cb;
}
std::vector<Mac48Address>
PeerManagementProtocol::GetActiveLinks (uint32_t interface)
PeerManagementProtocol::GetPeers (uint32_t interface) const
{
std::vector<Mac48Address> retval;
PeerLinksMap::iterator iface = m_peerLinks.find (interface);
PeerLinksMap::const_iterator iface = m_peerLinks.find (interface);
NS_ASSERT (iface != m_peerLinks.end ());
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
for (PeerLinksOnInterface::const_iterator i = iface->second.begin (); i != iface->second.end (); i++)
{
if ((*i)->LinkIsEstab ())
{
@@ -392,6 +317,21 @@ PeerManagementProtocol::GetActiveLinks (uint32_t interface)
}
return retval;
}
std::vector< Ptr<PeerLink> >
PeerManagementProtocol::GetPeerLinks () const
{
std::vector< Ptr<PeerLink> > links;
for (PeerLinksMap::const_iterator iface = m_peerLinks.begin (); iface != m_peerLinks.end (); ++iface)
{
for (PeerLinksOnInterface::const_iterator i = iface->second.begin ();
i != iface->second.end (); i++)
if ((*i)->LinkIsEstab ())
links.push_back (*i);
}
return links;
}
bool
PeerManagementProtocol::IsActiveLink (uint32_t interface, Mac48Address peerAddress)
{
@@ -407,6 +347,7 @@ PeerManagementProtocol::ShouldSendOpen (uint32_t interface, Mac48Address peerAdd
{
return (m_stats.linksTotal <= m_maxNumberOfPeerLinks);
}
bool
PeerManagementProtocol::ShouldAcceptOpen (uint32_t interface, Mac48Address peerAddress,
PmpReasonCode & reasonCode)
@@ -418,56 +359,70 @@ PeerManagementProtocol::ShouldAcceptOpen (uint32_t interface, Mac48Address peerA
}
return true;
}
Time
PeerManagementProtocol::GetNextBeaconShift (uint32_t interface)
void
PeerManagementProtocol::DoShiftBeacon (uint32_t interface)
{
//REMINDER:: in timing element 1) last beacon reception time is measured in units of 256 microseconds
// 2) beacon interval is mesured in units of 1024 microseconds
// 3) hereafter TU = 1024 microseconds
//So, the shift is a random integer variable uniformly distributed in [-15;-1] U [1;15]
static int maxShift = 15;
static int minShift = 1;
UniformVariable randomSign (-1, 1);
UniformVariable randomShift (minShift, maxShift);
if (!GetBeaconCollisionAvoidance ())
{
return;
}
// If beacon interval is equal to the neighbor's one and one o more beacons received
// by my neighbor coincide with my beacon - apply random uniformly distributed shift from
// [-m_maxBeaconShift, m_maxBeaconShift] except 0.
UniformVariable beaconShift (-m_maxBeaconShift, m_maxBeaconShift);
PeerLinksMap::iterator iface = m_peerLinks.find (interface);
NS_ASSERT (iface != m_peerLinks.end ());
PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
PeerManagementProtocolMacMap::const_iterator plugin = m_plugins.find (interface);
NS_ASSERT (plugin != m_plugins.end ());
std::pair<Time, Time> myBeacon = plugin->second->GetBeaconInfo ();
if (Simulator::Now () + TuToTime (maxShift) > myBeacon.first + myBeacon.second)
std::map<uint32_t, Time>::const_iterator lastBeacon = m_lastBeacon.find (interface);
std::map<uint32_t, Time>::const_iterator beaconInterval = m_beaconInterval.find (interface);
if ((lastBeacon == m_lastBeacon.end ()) || (beaconInterval == m_beaconInterval.end ()))
{
return MicroSeconds (0);
return;
}
if (TuToTime (m_maxBeaconShift) > m_beaconInterval[interface])
{
NS_FATAL_ERROR ("Wrong beacon shift parameters");
return;
}
for (PeerLinksOnInterface::iterator i = iface->second.begin (); i != iface->second.end (); i++)
{
IeBeaconTiming::NeighboursTimingUnitsList neighbours;
if ((*i)->LinkIsIdle ())
{
continue;
}
neighbours = (*i)->GetBeaconTimingElement ().GetNeighboursTimingElementsList ();
//Going through all my timing elements and detecting future beacon collisions
for (IeBeaconTiming::NeighboursTimingUnitsList::const_iterator j = neighbours.begin (); j
!= neighbours.end (); j++)
{
//We apply MBAC only if beacon Intervals are equal
if ((*j)->GetBeaconInterval () == TimeToTu (myBeacon.second))
if ((*i)->GetPeerAid () == (*j)->GetAid ())
{
//Apply MBCA if future beacons may coinside
if ((TimeToTu (myBeacon.first) - ((*j)->GetLastBeacon () / 4)) % ((*j)->GetBeaconInterval ())
== 0)
{
int beaconShift = randomShift.GetInteger (minShift, maxShift) * ((randomSign.GetValue ()
>= 0) ? 1 : -1);
NS_LOG_DEBUG ("Apply MBCA: Shift value = " << beaconShift << " beacon TUs");
//Do not shift to the past!
return (TuToTime (beaconShift) + Simulator::Now () < myBeacon.first) ? TuToTime (
beaconShift) : TuToTime (0);
}
// I am present at neighbour's list of neighbors
continue;
}
//Beacon interval is stored in TU's
if (((*j)->GetBeaconInterval ()) != TimeToTu(beaconInterval->second))
{
continue;
}
//Timing element keeps beacon receiving times in 256us units, TU=1024us
if ((int) ((int)(*j)->GetLastBeacon () / 4 - (int)TimeToTu (lastBeacon->second)) % TimeToTu (
beaconInterval->second)
!= 0)
{
continue;
}
int shift = 0;
do
{
shift = (int) beaconShift.GetValue ();
}
while (shift == 0);
PeerManagementProtocolMacMap::iterator plugin = m_plugins.find (interface);
NS_ASSERT (plugin != m_plugins.end ());
plugin->second->SetBeaconShift (TuToTime (shift));
return;
}
}
return MicroSeconds (0);
}
Time
PeerManagementProtocol::TuToTime (uint32_t x)
@@ -533,6 +488,12 @@ PeerManagementProtocol::GetAddress ()
{
return m_address;
}
void
PeerManagementProtocol::NotifyBeaconSent (uint32_t interface, Time beaconInterval)
{
m_lastBeacon[interface] = Simulator::Now ();
m_beaconInterval[interface] = beaconInterval;
}
PeerManagementProtocol::Statistics::Statistics (uint16_t t) :
linksTotal (t), linksOpened (0), linksClosed (0)
{
@@ -574,6 +535,16 @@ PeerManagementProtocol::ResetStats ()
}
}
void
PeerManagementProtocol::SetBeaconCollisionAvoidance (bool enable)
{
m_enableBca = enable;
}
bool
PeerManagementProtocol::GetBeaconCollisionAvoidance () const
{
return m_enableBca;
}
} // namespace dot11s
} //namespace ns3

View File

@@ -74,25 +74,12 @@ public:
*/
Ptr<IeBeaconTiming> GetBeaconTimingElement (uint32_t interface);
/**
* \brief When we receive a beacon from peer-station, we remember
* its beacon timing element (needed for peer choosing mechanism),
* and remember beacon timers - last beacon and beacon interval to
* detect beacon loss and cancel links
* \param interface is a interface on which beacon was received
* \param meshBeacon indicates whether the beacon is mesh beacon or not.
* \param timingElement is a timing element of remote beacon
* \param peerAddress is an address where a beacon was received from
* \param receivingTime is a time when beacon was received
* \param beaconInterval is a beacon interval of received beacon
* \brief To initiate peer link we must notify about received beacon
* \param interface the interface where a beacon was received from
* \param peerAddress address of station, which sent a beacon
* \param beaconInterval beacon interval (needed by beacon loss counter)
*/
void UpdatePeerBeaconTiming (
uint32_t interface,
bool meshBeacon,
IeBeaconTiming timingElement,
Mac48Address peerAddress,
Time receivingTime,
Time beaconInterval
);
void ReceiveBeacon (uint32_t interface, Mac48Address peerAddress, Time beaconInterval, Ptr<IeBeaconTiming> beaconTiming);
//\}
/**
* \brief Methods that handle Peer link management frames
@@ -137,16 +124,26 @@ public:
*/
bool IsActiveLink (uint32_t interface, Mac48Address peerAddress);
//\}
///\brief Needed by external module to do MLME
Ptr<PeerLink> FindPeerLink (uint32_t interface, Mac48Address peerAddress);
///\name Interface to other protocols (MLME)
//\{
/// Set peer link status change callback
void SetPeerLinkStatusCallback (Callback<void, Mac48Address, Mac48Address, uint32_t, bool> cb);
std::vector<Mac48Address> GetActiveLinks (uint32_t interface);
///\brief needed by plugins to set global source address
/// Find active peer link by my interface and peer interface MAC
Ptr<PeerLink> FindPeerLink (uint32_t interface, Mac48Address peerAddress);
/// Get list of all active peer links
std::vector < Ptr<PeerLink> > GetPeerLinks () const;
/// Get list of active peers of my given interface
std::vector<Mac48Address> GetPeers (uint32_t interface) const;
/// Get mesh point address. TODO this used by plugins only. Now MAC plugins can ask MP addrress directly from main MAC
Mac48Address GetAddress ();
///\brief Needed to fill mesh configuration
uint8_t GetNumberOfLinks ();
void SetMeshId (std::string s);
Ptr<IeMeshId> GetMeshId () const;
/// Enable or disable beacon collision avoidance
void SetBeaconCollisionAvoidance (bool enable);
bool GetBeaconCollisionAvoidance () const;
/// Notify about beacon send event, needed to schedule BCA
void NotifyBeaconSent (uint32_t interface, Time beaconInterval);
///\brief: Report statistics
void Report (std::ostream &) const;
void ResetStats ();
@@ -177,16 +174,10 @@ private:
PeerManagementProtocol& operator= (const PeerManagementProtocol &);
PeerManagementProtocol (const PeerManagementProtocol &);
/**
* \brief Fills information of received beacon. Needed to form own beacon timing element
*/
void FillBeaconInfo (uint32_t interface, Mac48Address peerAddress, Time receivingTime, Time beaconInterval);
Ptr<PeerLink> InitiateLink (
uint32_t interface,
Mac48Address peerAddress,
Mac48Address peerMeshPointAddress,
Time lastBeacon,
Time beaconInterval
Mac48Address peerMeshPointAddress
);
/**
* \name External peer-chooser
@@ -200,7 +191,7 @@ private:
*/
void PeerLinkStatus (uint32_t interface, Mac48Address peerAddress, Mac48Address peerMeshPointAddres, PeerLink::PeerState ostate, PeerLink::PeerState nstate);
///\brief BCA
Time GetNextBeaconShift (uint32_t interface);
void DoShiftBeacon (uint32_t interface);
/**
* \name Time<-->TU converters:
* \{
@@ -212,16 +203,19 @@ private:
PeerManagementProtocolMacMap m_plugins;
Mac48Address m_address;
Ptr<IeMeshId> m_meshId;
/**
* \name Information related to beacons:
* \{
*/
BeaconInfoMap m_neighbourBeacons;
///\}
uint16_t m_lastAssocId;
uint16_t m_lastLocalLinkId;
uint8_t m_maxNumberOfPeerLinks;
uint8_t m_maxBeaconLostForBeaconTiming;
/// Flag which enables BCA
bool m_enableBca;
/// Beacon can be shifted at [-m_maxBeaconShift; +m_maxBeaconShift] TUs
uint16_t m_maxBeaconShift;
///Last beacon at each interface
std::map<uint32_t, Time> m_lastBeacon;
///Beacon interval at each interface
std::map<uint32_t, Time> m_beaconInterval;
/**
* \name Peer Links
* \{

View File

@@ -35,6 +35,11 @@ MeshWifiBeacon::AddInformationElement (Ptr<WifiInformationElement> ie)
m_elements.AddInformationElement (ie);
}
Time
MeshWifiBeacon::GetBeaconInterval () const
{
return MicroSeconds (m_header.GetBeaconIntervalUs ());
}
Ptr<Packet>
MeshWifiBeacon::CreatePacket ()

View File

@@ -58,6 +58,8 @@ public:
* \param mpAddress is mesh point address
*/
WifiMacHeader CreateHeader (Mac48Address address, Mac48Address mpAddress);
///Returns a beacon interval of wifi beacon
Time GetBeaconInterval () const;
/// Create frame = { beacon header + all information elements sorted by ElementId () }
Ptr<Packet> CreatePacket ();

View File

@@ -75,7 +75,7 @@ Dot11sStack::InstallStack (Ptr<MeshPointDevice> mp)
//Install interaction between HWMP and Peer management protocol:
//PeekPointer()'s to avoid circular Ptr references
pmp->SetPeerLinkStatusCallback (MakeCallback (&HwmpProtocol::PeerLinkStatus, PeekPointer (hwmp)));
hwmp->SetNeighboursCallback (MakeCallback (&PeerManagementProtocol::GetActiveLinks, PeekPointer (pmp)));
hwmp->SetNeighboursCallback (MakeCallback (&PeerManagementProtocol::GetPeers, PeekPointer (pmp)));
return true;
}
void