A Discrete-Event Network Simulator
API
peer-management-protocol-mac.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 IITP RAS
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Kirill Andreev <andreev@iitp.ru>
18  */
19 
21 
22 #include "dot11s-mac-header.h"
25 #include "peer-link-frame.h"
27 
28 #include "ns3/log.h"
29 #include "ns3/mesh-information-element-vector.h"
30 #include "ns3/mesh-wifi-interface-mac.h"
31 #include "ns3/mgt-action-headers.h"
32 #include "ns3/simulator.h"
33 #include "ns3/wifi-mpdu.h"
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("PeerManagementProtocolMac");
39 
40 namespace dot11s
41 {
44 {
45  m_ifIndex = interface;
46  m_protocol = protocol;
47 }
48 
50 {
51 }
52 
53 void
55 {
56  m_parent = parent;
57  m_parent->TraceConnectWithoutContext("DroppedMpdu",
59  m_parent->TraceConnectWithoutContext("AckedMpdu",
61 }
62 
63 void
65 {
66  m_protocol->TransmissionFailure(m_ifIndex, mpdu->GetHeader().GetAddr1());
67 }
68 
69 void
71 {
72  m_protocol->TransmissionSuccess(m_ifIndex, mpdu->GetHeader().GetAddr1());
73 }
74 
75 bool
77 {
78  NS_LOG_FUNCTION(this << const_packet << header);
79  // First of all we copy a packet, because we need to remove some
80  // headers
81  Ptr<Packet> packet = const_packet->Copy();
82  if (header.IsBeacon())
83  {
84  NS_LOG_DEBUG("Is Beacon from " << header.GetAddr2());
85  MgtBeaconHeader beacon_hdr;
86  packet->RemoveHeader(beacon_hdr);
88  // To determine header size here, we can rely on the knowledge that
89  // this is the last header to remove.
90  packet->RemoveHeader(elements, packet->GetSize());
91  Ptr<IeBeaconTiming> beaconTiming =
92  DynamicCast<IeBeaconTiming>(elements.FindFirst(IE_BEACON_TIMING));
93  Ptr<IeMeshId> meshId = DynamicCast<IeMeshId>(elements.FindFirst(IE_MESH_ID));
94 
95  if (meshId && (m_protocol->GetMeshId()->IsEqual(*meshId)))
96  {
97  m_protocol->ReceiveBeacon(m_ifIndex,
98  header.GetAddr2(),
99  MicroSeconds(beacon_hdr.GetBeaconIntervalUs()),
100  beaconTiming);
101  }
102  else
103  {
104  NS_LOG_DEBUG("MeshId mismatch " << m_protocol->GetMeshId()->PeekString() << " "
105  << (*meshId) << "; ignoring");
106  }
107  // Beacon shall not be dropped. May be needed to another plugins
108  return true;
109  }
110  uint16_t aid = 0; // applicable only in Confirm message
111  IeConfiguration config;
112  if (header.IsAction())
113  {
114  NS_LOG_DEBUG("Is action");
115  WifiActionHeader actionHdr;
116  packet->RemoveHeader(actionHdr);
117  WifiActionHeader::ActionValue actionValue = actionHdr.GetAction();
118  // If can not handle - just return;
120  {
121  NS_LOG_DEBUG("Cannot handle non SELF PROTECTED");
122  return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
123  }
124  m_stats.rxMgt++;
125  m_stats.rxMgtBytes += packet->GetSize();
126  Mac48Address peerAddress = header.GetAddr2();
127  Mac48Address peerMpAddress = header.GetAddr3();
129  {
130  NS_LOG_DEBUG("Received PEER_LINK_OPEN");
132  PeerLinkOpenStart peerFrame;
133  packet->RemoveHeader(peerFrame);
134  fields = peerFrame.GetFields();
135  if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
136  {
137  NS_LOG_DEBUG("PEER_LINK_OPEN: MeshId mismatch");
138  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
139  // Broken peer link frame - drop it
140  m_stats.brokenMgt++;
141  return false;
142  }
143  if (!(m_parent->CheckSupportedRates(
144  AllSupportedRates{fields.rates, fields.extendedRates})))
145  {
146  NS_LOG_DEBUG("PEER_LINK_OPEN: configuration mismatch");
147  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
148  // Broken peer link frame - drop it
149  m_stats.brokenMgt++;
150  return false;
151  }
152  config = fields.config;
153  }
155  {
156  NS_LOG_DEBUG("Received PEER_LINK_CONFIRM");
158  PeerLinkConfirmStart peerFrame;
159  packet->RemoveHeader(peerFrame);
160  fields = peerFrame.GetFields();
161  if (!(m_parent->CheckSupportedRates(
162  AllSupportedRates{fields.rates, fields.extendedRates})))
163  {
164  NS_LOG_DEBUG("PEER_LINK_CONFIRM: configuration mismatch");
165  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
166  // Broken peer link frame - drop it
167  m_stats.brokenMgt++;
168  return false;
169  }
170  aid = fields.aid;
171  config = fields.config;
172  }
174  {
175  NS_LOG_DEBUG("Received PEER_LINK_CLOSE");
177  PeerLinkCloseStart peerFrame;
178  packet->RemoveHeader(peerFrame);
179  fields = peerFrame.GetFields();
180  if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
181  {
182  NS_LOG_DEBUG("PEER_LINK_CLOSE: configuration mismatch");
183  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
184  // Broken peer link frame - drop it
185  m_stats.brokenMgt++;
186  return false;
187  }
188  }
189  else
190  {
192  "Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
193  }
194  Ptr<IePeerManagement> peerElement;
196  // To determine header size here, we can rely on the knowledge that
197  // this is the last header to remove.
198  packet->RemoveHeader(elements, packet->GetSize());
199  peerElement = DynamicCast<IePeerManagement>(elements.FindFirst(IE_MESH_PEERING_MANAGEMENT));
200 
201  NS_ASSERT(peerElement);
202  // Check that frame subtype corresponds to peer link subtype
203  if (peerElement->SubtypeIsOpen())
204  {
205  m_stats.rxOpen++;
207  }
208  if (peerElement->SubtypeIsConfirm())
209  {
210  m_stats.rxConfirm++;
212  }
213  if (peerElement->SubtypeIsClose())
214  {
215  m_stats.rxClose++;
217  }
218  // Deliver Peer link management frame to protocol:
219  m_protocol->ReceivePeerLinkFrame(m_ifIndex,
220  peerAddress,
221  peerMpAddress,
222  aid,
223  *peerElement,
224  config);
225  // if we can handle a frame - drop it
226  return false;
227  }
228  return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
229 }
230 
231 bool
233  WifiMacHeader& header,
234  Mac48Address from,
235  Mac48Address to)
236 {
237  NS_LOG_FUNCTION(this << packet << header << from << to);
238  if (header.IsAction())
239  {
240  WifiActionHeader actionHdr;
241  packet->PeekHeader(actionHdr);
243  {
244  return true;
245  }
246  }
247  if (header.GetAddr1().IsGroup())
248  {
249  return true;
250  }
251  else
252  {
253  if (m_protocol->IsActiveLink(m_ifIndex, header.GetAddr1()))
254  {
255  return true;
256  }
257  else
258  {
259  m_stats.dropped++;
260  return false;
261  }
262  }
263 }
264 
265 void
267 {
268  if (m_protocol->GetBeaconCollisionAvoidance())
269  {
270  Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
271  beacon.AddInformationElement(beaconTiming);
272  }
273  beacon.AddInformationElement(m_protocol->GetMeshId());
274  m_protocol->NotifyBeaconSent(m_ifIndex, beacon.GetBeaconInterval());
275 }
276 
277 void
279  Mac48Address peerMpAddress,
280  uint16_t aid,
281  IePeerManagement peerElement,
282  IeConfiguration meshConfig)
283 {
284  NS_LOG_FUNCTION(this << peerAddress << peerMpAddress);
285  // Create a packet:
286  meshConfig.SetNeighborCount(m_protocol->GetNumberOfLinks());
287  Ptr<Packet> packet = Create<Packet>();
289  elements.AddInformationElement(Ptr<IePeerManagement>(&peerElement));
290  packet->AddHeader(elements);
291  // Create an 802.11 frame header:
292  // Send management frame to MAC:
293  if (peerElement.SubtypeIsOpen())
294  {
296  auto allSupportedRates = m_parent->GetSupportedRates();
297  fields.rates = allSupportedRates.rates;
298  fields.extendedRates = allSupportedRates.extendedRates;
299  fields.capability = 0;
300  fields.meshId = *(m_protocol->GetMeshId());
301  fields.config = meshConfig;
302  PeerLinkOpenStart plinkOpen;
303  WifiActionHeader actionHdr;
304  m_stats.txOpen++;
306  action.selfProtectedAction = WifiActionHeader::PEER_LINK_OPEN;
308  plinkOpen.SetPlinkOpenStart(fields);
309  packet->AddHeader(plinkOpen);
310  packet->AddHeader(actionHdr);
311  }
312  if (peerElement.SubtypeIsConfirm())
313  {
315  auto allSupportedRates = m_parent->GetSupportedRates();
316  fields.rates = allSupportedRates.rates;
317  fields.extendedRates = allSupportedRates.extendedRates;
318  fields.capability = 0;
319  fields.config = meshConfig;
320  PeerLinkConfirmStart plinkConfirm;
321  WifiActionHeader actionHdr;
322  m_stats.txConfirm++;
324  action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
325  fields.aid = aid;
327  plinkConfirm.SetPlinkConfirmStart(fields);
328  packet->AddHeader(plinkConfirm);
329  packet->AddHeader(actionHdr);
330  }
331  if (peerElement.SubtypeIsClose())
332  {
334  fields.meshId = *(m_protocol->GetMeshId());
335  PeerLinkCloseStart plinkClose;
336  WifiActionHeader actionHdr;
337  m_stats.txClose++;
339  action.selfProtectedAction = WifiActionHeader::PEER_LINK_CLOSE;
341  plinkClose.SetPlinkCloseStart(fields);
342  packet->AddHeader(plinkClose);
343  packet->AddHeader(actionHdr);
344  }
345  m_stats.txMgt++;
346  m_stats.txMgtBytes += packet->GetSize();
347  // Wifi Mac header:
348  WifiMacHeader hdr;
350  hdr.SetAddr1(peerAddress);
351  hdr.SetAddr2(m_parent->GetAddress());
352  // Addr is not used here, we use it as our MP address
353  hdr.SetAddr3(m_protocol->GetAddress());
354  hdr.SetDsNotFrom();
355  hdr.SetDsNotTo();
356  m_parent->SendManagementFrame(packet, hdr);
357 }
358 
361 {
362  if (m_parent)
363  {
364  return m_parent->GetAddress();
365  }
366  else
367  {
368  return Mac48Address();
369  }
370 }
371 
372 void
374 {
375  if (shift != Seconds(0))
376  {
378  }
379  m_parent->ShiftTbtt(shift);
380 }
381 
383  : txOpen(0),
384  txConfirm(0),
385  txClose(0),
386  rxOpen(0),
387  rxConfirm(0),
388  rxClose(0),
389  dropped(0),
390  brokenMgt(0),
391  txMgt(0),
392  txMgtBytes(0),
393  rxMgt(0),
394  rxMgtBytes(0),
395  beaconShift(0)
396 {
397 }
398 
399 void
401 {
402  os << "<Statistics "
403  "txOpen=\""
404  << txOpen << "\"" << std::endl
405  << "txConfirm=\"" << txConfirm << "\"" << std::endl
406  << "txClose=\"" << txClose << "\"" << std::endl
407  << "rxOpen=\"" << rxOpen << "\"" << std::endl
408  << "rxConfirm=\"" << rxConfirm << "\"" << std::endl
409  << "rxClose=\"" << rxClose << "\"" << std::endl
410  << "dropped=\"" << dropped << "\"" << std::endl
411  << "brokenMgt=\"" << brokenMgt << "\"" << std::endl
412  << "txMgt=\"" << txMgt << "\"" << std::endl
413  << "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl
414  << "rxMgt=\"" << rxMgt << "\"" << std::endl
415  << "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl
416  << "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
417 }
418 
419 void
420 PeerManagementProtocolMac::Report(std::ostream& os) const
421 {
422  os << "<PeerManagementProtocolMac "
423  "address=\""
424  << m_parent->GetAddress() << "\">" << std::endl;
425  m_stats.Print(os);
426  os << "</PeerManagementProtocolMac>" << std::endl;
427 }
428 
429 void
431 {
432  m_stats = Statistics();
433 }
434 
435 uint32_t
437 {
438  return m_parent->GetLinkMetric(peerAddress);
439 }
440 
441 int64_t
443 {
444  return m_protocol->AssignStreams(stream);
445 }
446 
447 } // namespace dot11s
448 } // namespace ns3
an EUI-48 address
Definition: mac48-address.h:46
bool IsGroup() const
bool AddInformationElement(Ptr< WifiInformationElement > element)
add an IE, if maxSize has exceeded, returns false
Ptr< WifiInformationElement > FindFirst(WifiInformationElementId id) const
vector of pointers to information elements is the body of IeVector
Beacon is beacon header + list of arbitrary information elements.
Time GetBeaconInterval() const
Returns the beacon interval of Wifi beacon.
void AddInformationElement(Ptr< WifiInformationElement > ie)
Add information element.
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:512
uint64_t GetBeaconIntervalUs() const
Return the beacon interval in microseconds unit.
Definition: mgt-headers.cc:75
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
CategoryValue GetCategory() const
Return the category value.
ActionValue GetAction() const
Return the action value.
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr3() const
Return the address in the Address 3 field.
bool IsBeacon() const
Return true if the header is a Beacon header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
bool IsAction() const
Return true if the header is an Action header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
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(const IeMeshId &o) const
Equality test.
Definition: ie-dot11s-id.cc:63
according to IEEE 802.11 - 2012
bool SubtypeIsOpen() const
Subtype is open function.
bool SubtypeIsClose() const
Subtype is close function.
bool SubtypeIsConfirm() const
Subtype is confirm function.
void SetParent(Ptr< MeshWifiInterfaceMac > parent) override
Set pointer to parent.
PeerManagementProtocolMac(uint32_t interface, Ptr< PeerManagementProtocol > protocol)
Constructor.
void Report(std::ostream &) const
Report statistics.
Mac48Address GetAddress() const
debug only, used to print established links
void UpdateBeacon(MeshWifiBeacon &beacon) const override
Add beacon timing and mesh ID information elements, and notify beacon sent.
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to) override
This method appears to test a few conditions.
void TxError(WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Closes link when a proper number of successive transmissions have failed.
int64_t AssignStreams(int64_t stream) override
Assign the streams.
void SendPeerLinkManagementFrame(Mac48Address peerAddress, Mac48Address peerMpAddress, uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
Send peer link management frame function.
void TxOk(Ptr< const WifiMpdu > mpdu)
Transmit OK function.
uint32_t GetLinkMetric(Mac48Address peerAddress)
Get the link metric.
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header) override
Receive and process a packet.
Ptr< PeerManagementProtocol > m_protocol
protocol
void SetBeaconShift(Time shift)
Set beacon shift function.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:77
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
@ WIFI_MAC_MGT_ACTION
Struct containing all supported rates.
typedef for union of different ActionValues
SelfProtectedActionValue selfProtectedAction
self protected
#define IE_BEACON_TIMING
#define IE_MESH_PEERING_MANAGEMENT
#define IE_MESH_ID