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/simulator.h"
32 #include "ns3/wifi-mpdu.h"
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("PeerManagementProtocolMac");
38 
39 namespace dot11s
40 {
43 {
44  m_ifIndex = interface;
45  m_protocol = protocol;
46 }
47 
49 {
50 }
51 
52 void
54 {
55  m_parent = parent;
56  m_parent->TraceConnectWithoutContext("DroppedMpdu",
58  m_parent->TraceConnectWithoutContext("AckedMpdu",
60 }
61 
62 void
64 {
65  m_protocol->TransmissionFailure(m_ifIndex, mpdu->GetHeader().GetAddr1());
66 }
67 
68 void
70 {
71  m_protocol->TransmissionSuccess(m_ifIndex, mpdu->GetHeader().GetAddr1());
72 }
73 
74 bool
76 {
77  NS_LOG_FUNCTION(this << const_packet << header);
78  // First of all we copy a packet, because we need to remove some
79  // headers
80  Ptr<Packet> packet = const_packet->Copy();
81  if (header.IsBeacon())
82  {
83  NS_LOG_DEBUG("Is Beacon from " << header.GetAddr2());
84  MgtBeaconHeader beacon_hdr;
85  packet->RemoveHeader(beacon_hdr);
87  // To determine header size here, we can rely on the knowledge that
88  // this is the last header to remove.
89  packet->RemoveHeader(elements, packet->GetSize());
90  Ptr<IeBeaconTiming> beaconTiming =
91  DynamicCast<IeBeaconTiming>(elements.FindFirst(IE_BEACON_TIMING));
92  Ptr<IeMeshId> meshId = DynamicCast<IeMeshId>(elements.FindFirst(IE_MESH_ID));
93 
94  if (meshId && (m_protocol->GetMeshId()->IsEqual(*meshId)))
95  {
96  m_protocol->ReceiveBeacon(m_ifIndex,
97  header.GetAddr2(),
98  MicroSeconds(beacon_hdr.GetBeaconIntervalUs()),
99  beaconTiming);
100  }
101  else
102  {
103  NS_LOG_DEBUG("MeshId mismatch " << m_protocol->GetMeshId()->PeekString() << " "
104  << (*meshId) << "; ignoring");
105  }
106  // Beacon shall not be dropped. May be needed to another plugins
107  return true;
108  }
109  uint16_t aid = 0; // applicable only in Confirm message
110  IeConfiguration config;
111  if (header.IsAction())
112  {
113  NS_LOG_DEBUG("Is action");
114  WifiActionHeader actionHdr;
115  packet->RemoveHeader(actionHdr);
116  WifiActionHeader::ActionValue actionValue = actionHdr.GetAction();
117  // If can not handle - just return;
119  {
120  NS_LOG_DEBUG("Cannot handle non SELF PROTECTED");
121  return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
122  }
123  m_stats.rxMgt++;
124  m_stats.rxMgtBytes += packet->GetSize();
125  Mac48Address peerAddress = header.GetAddr2();
126  Mac48Address peerMpAddress = header.GetAddr3();
128  {
129  NS_LOG_DEBUG("Received PEER_LINK_OPEN");
131  PeerLinkOpenStart peerFrame;
132  packet->RemoveHeader(peerFrame);
133  fields = peerFrame.GetFields();
134  if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
135  {
136  NS_LOG_DEBUG("PEER_LINK_OPEN: MeshId mismatch");
137  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
138  // Broken peer link frame - drop it
139  m_stats.brokenMgt++;
140  return false;
141  }
142  if (!(m_parent->CheckSupportedRates(fields.rates)))
143  {
144  NS_LOG_DEBUG("PEER_LINK_OPEN: configuration mismatch");
145  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
146  // Broken peer link frame - drop it
147  m_stats.brokenMgt++;
148  return false;
149  }
150  config = fields.config;
151  }
153  {
154  NS_LOG_DEBUG("Received PEER_LINK_CONFIRM");
156  PeerLinkConfirmStart peerFrame;
157  packet->RemoveHeader(peerFrame);
158  fields = peerFrame.GetFields();
159  if (!(m_parent->CheckSupportedRates(fields.rates)))
160  {
161  NS_LOG_DEBUG("PEER_LINK_CONFIRM: configuration mismatch");
162  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
163  // Broken peer link frame - drop it
164  m_stats.brokenMgt++;
165  return false;
166  }
167  aid = fields.aid;
168  config = fields.config;
169  }
171  {
172  NS_LOG_DEBUG("Received PEER_LINK_CLOSE");
174  PeerLinkCloseStart peerFrame;
175  packet->RemoveHeader(peerFrame);
176  fields = peerFrame.GetFields();
177  if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
178  {
179  NS_LOG_DEBUG("PEER_LINK_CLOSE: configuration mismatch");
180  m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
181  // Broken peer link frame - drop it
182  m_stats.brokenMgt++;
183  return false;
184  }
185  }
186  else
187  {
189  "Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
190  }
191  Ptr<IePeerManagement> peerElement;
193  // To determine header size here, we can rely on the knowledge that
194  // this is the last header to remove.
195  packet->RemoveHeader(elements, packet->GetSize());
196  peerElement = DynamicCast<IePeerManagement>(elements.FindFirst(IE_MESH_PEERING_MANAGEMENT));
197 
198  NS_ASSERT(peerElement);
199  // Check that frame subtype corresponds to peer link subtype
200  if (peerElement->SubtypeIsOpen())
201  {
202  m_stats.rxOpen++;
204  }
205  if (peerElement->SubtypeIsConfirm())
206  {
207  m_stats.rxConfirm++;
209  }
210  if (peerElement->SubtypeIsClose())
211  {
212  m_stats.rxClose++;
214  }
215  // Deliver Peer link management frame to protocol:
216  m_protocol->ReceivePeerLinkFrame(m_ifIndex,
217  peerAddress,
218  peerMpAddress,
219  aid,
220  *peerElement,
221  config);
222  // if we can handle a frame - drop it
223  return false;
224  }
225  return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
226 }
227 
228 bool
230  WifiMacHeader& header,
231  Mac48Address from,
232  Mac48Address to)
233 {
234  NS_LOG_FUNCTION(this << packet << header << from << to);
235  if (header.IsAction())
236  {
237  WifiActionHeader actionHdr;
238  packet->PeekHeader(actionHdr);
240  {
241  return true;
242  }
243  }
244  if (header.GetAddr1().IsGroup())
245  {
246  return true;
247  }
248  else
249  {
250  if (m_protocol->IsActiveLink(m_ifIndex, header.GetAddr1()))
251  {
252  return true;
253  }
254  else
255  {
256  m_stats.dropped++;
257  return false;
258  }
259  }
260 }
261 
262 void
264 {
265  if (m_protocol->GetBeaconCollisionAvoidance())
266  {
267  Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
268  beacon.AddInformationElement(beaconTiming);
269  }
270  beacon.AddInformationElement(m_protocol->GetMeshId());
271  m_protocol->NotifyBeaconSent(m_ifIndex, beacon.GetBeaconInterval());
272 }
273 
274 void
276  Mac48Address peerMpAddress,
277  uint16_t aid,
278  IePeerManagement peerElement,
279  IeConfiguration meshConfig)
280 {
281  NS_LOG_FUNCTION(this << peerAddress << peerMpAddress);
282  // Create a packet:
283  meshConfig.SetNeighborCount(m_protocol->GetNumberOfLinks());
284  Ptr<Packet> packet = Create<Packet>();
286  elements.AddInformationElement(Ptr<IePeerManagement>(&peerElement));
287  packet->AddHeader(elements);
288  // Create an 802.11 frame header:
289  // Send management frame to MAC:
290  if (peerElement.SubtypeIsOpen())
291  {
293  fields.rates = m_parent->GetSupportedRates();
294  fields.capability = 0;
295  fields.meshId = *(m_protocol->GetMeshId());
296  fields.config = meshConfig;
297  PeerLinkOpenStart plinkOpen;
298  WifiActionHeader actionHdr;
299  m_stats.txOpen++;
301  action.selfProtectedAction = WifiActionHeader::PEER_LINK_OPEN;
303  plinkOpen.SetPlinkOpenStart(fields);
304  packet->AddHeader(plinkOpen);
305  packet->AddHeader(actionHdr);
306  }
307  if (peerElement.SubtypeIsConfirm())
308  {
310  fields.rates = m_parent->GetSupportedRates();
311  fields.capability = 0;
312  fields.config = meshConfig;
313  PeerLinkConfirmStart plinkConfirm;
314  WifiActionHeader actionHdr;
315  m_stats.txConfirm++;
317  action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
318  fields.aid = aid;
320  plinkConfirm.SetPlinkConfirmStart(fields);
321  packet->AddHeader(plinkConfirm);
322  packet->AddHeader(actionHdr);
323  }
324  if (peerElement.SubtypeIsClose())
325  {
327  fields.meshId = *(m_protocol->GetMeshId());
328  PeerLinkCloseStart plinkClose;
329  WifiActionHeader actionHdr;
330  m_stats.txClose++;
332  action.selfProtectedAction = WifiActionHeader::PEER_LINK_CLOSE;
334  plinkClose.SetPlinkCloseStart(fields);
335  packet->AddHeader(plinkClose);
336  packet->AddHeader(actionHdr);
337  }
338  m_stats.txMgt++;
339  m_stats.txMgtBytes += packet->GetSize();
340  // Wifi Mac header:
341  WifiMacHeader hdr;
343  hdr.SetAddr1(peerAddress);
344  hdr.SetAddr2(m_parent->GetAddress());
345  // Addr is not used here, we use it as our MP address
346  hdr.SetAddr3(m_protocol->GetAddress());
347  hdr.SetDsNotFrom();
348  hdr.SetDsNotTo();
349  m_parent->SendManagementFrame(packet, hdr);
350 }
351 
354 {
355  if (m_parent)
356  {
357  return m_parent->GetAddress();
358  }
359  else
360  {
361  return Mac48Address();
362  }
363 }
364 
365 void
367 {
368  if (shift != Seconds(0))
369  {
371  }
372  m_parent->ShiftTbtt(shift);
373 }
374 
376  : txOpen(0),
377  txConfirm(0),
378  txClose(0),
379  rxOpen(0),
380  rxConfirm(0),
381  rxClose(0),
382  dropped(0),
383  brokenMgt(0),
384  txMgt(0),
385  txMgtBytes(0),
386  rxMgt(0),
387  rxMgtBytes(0),
388  beaconShift(0)
389 {
390 }
391 
392 void
394 {
395  os << "<Statistics "
396  "txOpen=\""
397  << txOpen << "\"" << std::endl
398  << "txConfirm=\"" << txConfirm << "\"" << std::endl
399  << "txClose=\"" << txClose << "\"" << std::endl
400  << "rxOpen=\"" << rxOpen << "\"" << std::endl
401  << "rxConfirm=\"" << rxConfirm << "\"" << std::endl
402  << "rxClose=\"" << rxClose << "\"" << std::endl
403  << "dropped=\"" << dropped << "\"" << std::endl
404  << "brokenMgt=\"" << brokenMgt << "\"" << std::endl
405  << "txMgt=\"" << txMgt << "\"" << std::endl
406  << "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl
407  << "rxMgt=\"" << rxMgt << "\"" << std::endl
408  << "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl
409  << "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
410 }
411 
412 void
413 PeerManagementProtocolMac::Report(std::ostream& os) const
414 {
415  os << "<PeerManagementProtocolMac "
416  "address=\""
417  << m_parent->GetAddress() << "\">" << std::endl;
418  m_stats.Print(os);
419  os << "</PeerManagementProtocolMac>" << std::endl;
420 }
421 
422 void
424 {
425  m_stats = Statistics();
426 }
427 
428 uint32_t
430 {
431  return m_parent->GetLinkMetric(peerAddress);
432 }
433 
434 int64_t
436 {
437  return m_protocol->AssignStreams(stream);
438 }
439 
440 } // namespace dot11s
441 } // namespace ns3
an EUI-48 address
Definition: mac48-address.h:46
bool IsGroup() const
Introspection did not find any typical Config paths.
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:1257
uint64_t GetBeaconIntervalUs() const
Return the beacon interval in microseconds unit.
Definition: mgt-headers.cc:319
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:863
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:78
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 |.
Definition: mgt-headers.h:1279
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.
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
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.
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:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:75
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:707
@ WIFI_MAC_MGT_ACTION
typedef for union of different ActionValues
Definition: mgt-headers.h:1444
SelfProtectedActionValue selfProtectedAction
self protected
Definition: mgt-headers.h:1449
#define IE_BEACON_TIMING
#define IE_MESH_PEERING_MANAGEMENT
#define IE_MESH_ID