A Discrete-Event Network Simulator
API
peer-management-protocol-mac.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Kirill Andreev <andreev@iitp.ru>
19  */
20 
23 #include "dot11s-mac-header.h"
26 #include "peer-link-frame.h"
27 #include "ns3/mesh-wifi-interface-mac.h"
28 #include "ns3/simulator.h"
29 #include "ns3/wifi-mac-header.h"
30 #include "ns3/mesh-information-element-vector.h"
31 #include "ns3/log.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("PeerManagementProtocolMac");
36 
37 namespace dot11s {
40 {
41  m_ifIndex = interface;
42  m_protocol = protocol;
43 }
44 
46 {
47 }
48 
49 void
51 {
52  m_parent = parent;
53  m_parent->TraceConnectWithoutContext ("TxErrHeader", MakeCallback (&PeerManagementProtocolMac::TxError, this));
54  m_parent->TraceConnectWithoutContext ("TxOkHeader", MakeCallback (&PeerManagementProtocolMac::TxOk, this));
55 }
56 void
58 {
59  m_protocol->TransmissionFailure (m_ifIndex, hdr.GetAddr1 ());
60 }
61 void
63 {
64  m_protocol->TransmissionSuccess (m_ifIndex, hdr.GetAddr1 ());
65 }
66 bool
68 {
69  NS_LOG_FUNCTION (this << const_packet << header);
70  // First of all we copy a packet, because we need to remove some
71  //headers
72  Ptr<Packet> packet = const_packet->Copy ();
73  if (header.IsBeacon ())
74  {
75  NS_LOG_DEBUG ("Is Beacon from " << header.GetAddr2 ());
76  MgtBeaconHeader beacon_hdr;
77  packet->RemoveHeader (beacon_hdr);
79  packet->RemoveHeader (elements);
80  Ptr<IeBeaconTiming> beaconTiming = DynamicCast<IeBeaconTiming> (elements.FindFirst (IE_BEACON_TIMING));
81  Ptr<IeMeshId> meshId = DynamicCast<IeMeshId> (elements.FindFirst (IE_MESH_ID));
82 
83  if ((meshId != 0) && (m_protocol->GetMeshId ()->IsEqual (*meshId)))
84  {
85  m_protocol->ReceiveBeacon (m_ifIndex, header.GetAddr2 (), MicroSeconds (
86  beacon_hdr.GetBeaconIntervalUs ()), beaconTiming);
87  }
88  else
89  {
90  NS_LOG_DEBUG ("MeshId mismatch " << m_protocol->GetMeshId ()->PeekString () << " " << (*meshId) << "; ignoring");
91  }
92  // Beacon shall not be dropped. May be needed to another plugins
93  return true;
94  }
95  uint16_t aid = 0; // applicable only in Confirm message
96  IeConfiguration config;
97  if (header.IsAction ())
98  {
99  NS_LOG_DEBUG ("Is action");
100  WifiActionHeader actionHdr;
101  packet->RemoveHeader (actionHdr);
102  WifiActionHeader::ActionValue actionValue = actionHdr.GetAction ();
103  // If can not handle - just return;
104  if (actionHdr.GetCategory () != WifiActionHeader::SELF_PROTECTED)
105  {
106  NS_LOG_DEBUG ("Cannot handle non SELF PROTECTED");
107  return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
108  }
109  m_stats.rxMgt++;
110  m_stats.rxMgtBytes += packet->GetSize ();
111  Mac48Address peerAddress = header.GetAddr2 ();
112  Mac48Address peerMpAddress = header.GetAddr3 ();
114  {
115  NS_LOG_DEBUG ("Received PEER_LINK_OPEN");
117  PeerLinkOpenStart peerFrame;
118  packet->RemoveHeader (peerFrame);
119  fields = peerFrame.GetFields ();
120  if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
121  {
122  NS_LOG_DEBUG ("PEER_LINK_OPEN: MeshId mismatch");
123  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
124  // Broken peer link frame - drop it
125  m_stats.brokenMgt++;
126  return false;
127  }
128  if (!(m_parent->CheckSupportedRates (fields.rates)))
129  {
130  NS_LOG_DEBUG ("PEER_LINK_OPEN: configuration mismatch");
131  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
132  // Broken peer link frame - drop it
133  m_stats.brokenMgt++;
134  return false;
135  }
136  config = fields.config;
137  }
139  {
140  NS_LOG_DEBUG ("Received PEER_LINK_CONFIRM");
142  PeerLinkConfirmStart peerFrame;
143  packet->RemoveHeader (peerFrame);
144  fields = peerFrame.GetFields ();
145  if (!(m_parent->CheckSupportedRates (fields.rates)))
146  {
147  NS_LOG_DEBUG ("PEER_LINK_CONFIRM: configuration mismatch");
148  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
149  // Broken peer link frame - drop it
150  m_stats.brokenMgt++;
151  return false;
152  }
153  aid = fields.aid;
154  config = fields.config;
155  }
157  {
158  NS_LOG_DEBUG ("Received PEER_LINK_CLOSE");
160  PeerLinkCloseStart peerFrame;
161  packet->RemoveHeader (peerFrame);
162  fields = peerFrame.GetFields ();
163  if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
164  {
165  NS_LOG_DEBUG ("PEER_LINK_CLOSE: configuration mismatch");
166  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
167  // Broken peer link frame - drop it
168  m_stats.brokenMgt++;
169  return false;
170  }
171  }
172  else
173  {
174  NS_FATAL_ERROR ("Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
175  }
176  Ptr<IePeerManagement> peerElement;
177  //Peer Management element is the last element in this frame - so, we can use MeshInformationElementVector
179  packet->RemoveHeader (elements);
180  peerElement = DynamicCast<IePeerManagement>(elements.FindFirst (IE_MESH_PEERING_MANAGEMENT));
181 
182  NS_ASSERT (peerElement != 0);
183  //Check that frame subtype corresponds to peer link subtype
184  if (peerElement->SubtypeIsOpen ())
185  {
186  m_stats.rxOpen++;
188  }
189  if (peerElement->SubtypeIsConfirm ())
190  {
191  m_stats.rxConfirm++;
193  }
194  if (peerElement->SubtypeIsClose ())
195  {
196  m_stats.rxClose++;
198  }
199  //Deliver Peer link management frame to protocol:
200  m_protocol->ReceivePeerLinkFrame (m_ifIndex, peerAddress, peerMpAddress, aid, *peerElement, config);
201  // if we can handle a frame - drop it
202  return false;
203  }
204  return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
205 }
206 bool
208  Mac48Address from, Mac48Address to)
209 {
210  NS_LOG_FUNCTION (this << packet << header << from << to);
211  if (header.IsAction ())
212  {
213  WifiActionHeader actionHdr;
214  packet->PeekHeader (actionHdr);
215  if (actionHdr.GetCategory () == WifiActionHeader::SELF_PROTECTED)
216  {
217  return true;
218  }
219  }
220  if (header.GetAddr1 ().IsGroup ())
221  {
222  return true;
223  }
224  else
225  {
226  if (m_protocol->IsActiveLink (m_ifIndex, header.GetAddr1 ()))
227  {
228  return true;
229  }
230  else
231  {
232  m_stats.dropped++;
233  return false;
234  }
235  }
236 }
237 void
239 {
240  if (m_protocol->GetBeaconCollisionAvoidance ())
241  {
242  Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement (m_ifIndex);
243  beacon.AddInformationElement (beaconTiming);
244  }
245  beacon.AddInformationElement (m_protocol->GetMeshId ());
246  m_protocol->NotifyBeaconSent (m_ifIndex, beacon.GetBeaconInterval ());
247 }
248 
249 void
251  uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
252 {
253  NS_LOG_FUNCTION (this << peerAddress << peerMpAddress);
254  //Create a packet:
255  meshConfig.SetNeighborCount (m_protocol->GetNumberOfLinks ());
256  Ptr<Packet> packet = Create<Packet> ();
258  elements.AddInformationElement (Ptr<IePeerManagement> (&peerElement));
259  packet->AddHeader (elements);
260  //Create an 802.11 frame header:
261  //Send management frame to MAC:
262  if (peerElement.SubtypeIsOpen ())
263  {
265  fields.rates = m_parent->GetSupportedRates ();
266  fields.capability = 0;
267  fields.meshId = *(m_protocol->GetMeshId ());
268  fields.config = meshConfig;
269  PeerLinkOpenStart plinkOpen;
270  WifiActionHeader actionHdr;
271  m_stats.txOpen++;
274  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
275  plinkOpen.SetPlinkOpenStart (fields);
276  packet->AddHeader (plinkOpen);
277  packet->AddHeader (actionHdr);
278  }
279  if (peerElement.SubtypeIsConfirm ())
280  {
282  fields.rates = m_parent->GetSupportedRates ();
283  fields.capability = 0;
284  fields.config = meshConfig;
285  PeerLinkConfirmStart plinkConfirm;
286  WifiActionHeader actionHdr;
287  m_stats.txConfirm++;
290  fields.aid = aid;
291  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
292  plinkConfirm.SetPlinkConfirmStart (fields);
293  packet->AddHeader (plinkConfirm);
294  packet->AddHeader (actionHdr);
295  }
296  if (peerElement.SubtypeIsClose ())
297  {
299  fields.meshId = *(m_protocol->GetMeshId ());
300  PeerLinkCloseStart plinkClose;
301  WifiActionHeader actionHdr;
302  m_stats.txClose++;
305  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
306  plinkClose.SetPlinkCloseStart (fields);
307  packet->AddHeader (plinkClose);
308  packet->AddHeader (actionHdr);
309  }
310  m_stats.txMgt++;
311  m_stats.txMgtBytes += packet->GetSize ();
312  // Wifi Mac header:
313  WifiMacHeader hdr;
314  hdr.SetAction ();
315  hdr.SetAddr1 (peerAddress);
316  hdr.SetAddr2 (m_parent->GetAddress ());
317  //Addr is not used here, we use it as our MP address
318  hdr.SetAddr3 (m_protocol->GetAddress ());
319  hdr.SetDsNotFrom ();
320  hdr.SetDsNotTo ();
321  m_parent->SendManagementFrame (packet, hdr);
322 }
323 
326 {
327  if (m_parent != 0)
328  {
329  return m_parent->GetAddress ();
330  }
331  else
332  {
333  return Mac48Address ();
334  }
335 }
336 void
338 {
339  if (shift != Seconds (0))
340  {
342  }
343  m_parent->ShiftTbtt (shift);
344 }
346  txOpen (0), txConfirm (0), txClose (0), rxOpen (0), rxConfirm (0), rxClose (0), dropped (0), brokenMgt (0),
347  txMgt (0), txMgtBytes (0), rxMgt (0), rxMgtBytes (0), beaconShift (0)
348 {
349 }
350 void
352 {
353  os << "<Statistics "
354  "txOpen=\"" << txOpen << "\"" << std::endl <<
355  "txConfirm=\"" << txConfirm << "\"" << std::endl <<
356  "txClose=\"" << txClose << "\"" << std::endl <<
357  "rxOpen=\"" << rxOpen << "\"" << std::endl <<
358  "rxConfirm=\"" << rxConfirm << "\"" << std::endl <<
359  "rxClose=\"" << rxClose << "\"" << std::endl <<
360  "dropped=\"" << dropped << "\"" << std::endl <<
361  "brokenMgt=\"" << brokenMgt << "\"" << std::endl <<
362  "txMgt=\"" << txMgt << "\"" << std::endl <<
363  "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl <<
364  "rxMgt=\"" << rxMgt << "\"" << std::endl <<
365  "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl <<
366  "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
367 }
368 void
369 PeerManagementProtocolMac::Report (std::ostream & os) const
370 {
371  os << "<PeerManagementProtocolMac "
372  "address=\"" << m_parent->GetAddress () << "\">" << std::endl;
373  m_stats.Print (os);
374  os << "</PeerManagementProtocolMac>" << std::endl;
375 }
376 void
378 {
379  m_stats = Statistics ();
380 }
381 uint32_t
383 {
384  return m_parent->GetLinkMetric (peerAddress);
385 }
386 int64_t
388 {
389  return m_protocol->AssignStreams (stream);
390 }
391 
392 } // namespace dot11s
393 } // namespace ns3
394 
bool IsBeacon(void) const
Return true if the header is a Beacon header.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:267
void AddInformationElement(Ptr< WifiInformationElement > ie)
Add information element.
void SetAction()
Set Type/Subtype values for an action header.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetBeaconShift(Time shift)
Set beacon shift function.
#define IE_MESH_ID
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:625
bool IsAction() const
Return true if the header is an Action header.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
int64_t AssignStreams(int64_t stream)
Assign the streams.
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:888
bool AddInformationElement(Ptr< WifiInformationElement > element)
add an IE, if maxSize has exceeded, returns false
bool SubtypeIsOpen() const
Subtype is open function.
according to IEEE 802.11 - 2012
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
PeerManagementProtocolMac(uint32_t interface, Ptr< PeerManagementProtocol > protocol)
Constructor.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
Ptr< WifiInformationElement > FindFirst(WifiInformationElementId id) const
vector of pointers to information elements is the body of IeVector
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
This method appears to test a few conditions.
uint32_t GetLinkMetric(Mac48Address peerAddress)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsGroup(void) const
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SendPeerLinkManagementFrame(Mac48Address peerAddress, Mac48Address peerMpAddress, uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
Send peer link management frame function.
an EUI-48 address
Definition: mac48-address.h:43
Mac48Address GetAddress() const
debug only, used to print established links
Introspection did not find any typical Config paths.
Beacon is beacon header + list of arbitrary information elements.
Ptr< MeshWifiInterfaceMac > m_parent
parent
Time GetBeaconInterval() const
Returns the beacon interval of Wifi beacon.
SelfProtectedActionValue selfProtectedAction
self protected action
Definition: mgt-headers.h:700
void TxOk(WifiMacHeader const &hdr)
Transmit OK function.
void UpdateBeacon(MeshWifiBeacon &beacon) const
Add beacon timing and mesh ID information elements, and notify beacon sent.
bool SubtypeIsClose() const
Subtype is close function.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
typedef for union of different ActionValues
Definition: mgt-headers.h:696
Describes Mesh Configuration Element see 7.3.2.86 of 802.11s draft 3.0.
void SetNeighborCount(uint8_t neighbors)
Set neighbor count.
bool IsEqual(IeMeshId const &o) const
Equality test.
Definition: ie-dot11s-id.cc:58
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Receive and process a packet.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1009
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
#define IE_BEACON_TIMING
ActionValue GetAction()
Return the action value.
Definition: mgt-headers.cc:909
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Set pointer to parent.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:854
void TxError(WifiMacHeader const &hdr)
Closes link when a proper number of successive transmissions have failed.
Ptr< PeerManagementProtocol > m_protocol
protocol
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:602
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void Print(std::ostream &os) const
Print function.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
bool SubtypeIsConfirm() const
Subtype is confirm function.
#define IE_MESH_PEERING_MANAGEMENT