A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
peer-management-protocol-mac.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 IITP RAS
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Kirill Andreev <andreev@iitp.ru>
7 */
8
10
11#include "dot11s-mac-header.h"
14#include "peer-link-frame.h"
16
17#include "ns3/log.h"
18#include "ns3/mesh-information-element-vector.h"
19#include "ns3/mesh-wifi-interface-mac.h"
20#include "ns3/mgt-action-headers.h"
21#include "ns3/simulator.h"
22#include "ns3/wifi-mpdu.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("PeerManagementProtocolMac");
28
29namespace dot11s
30{
37
41
42void
44{
45 m_parent = parent;
46 m_parent->TraceConnectWithoutContext("DroppedMpdu",
48 m_parent->TraceConnectWithoutContext("AckedMpdu",
50}
51
52void
54{
55 m_protocol->TransmissionFailure(m_ifIndex, mpdu->GetHeader().GetAddr1());
56}
57
58void
60{
61 m_protocol->TransmissionSuccess(m_ifIndex, mpdu->GetHeader().GetAddr1());
62}
63
64bool
66{
67 NS_LOG_FUNCTION(this << const_packet << header);
68 // First of all we copy a packet, because we need to remove some
69 // headers
70 Ptr<Packet> packet = const_packet->Copy();
71 if (header.IsBeacon())
72 {
73 NS_LOG_DEBUG("Is Beacon from " << header.GetAddr2());
75 packet->RemoveHeader(beacon_hdr);
77 // To determine header size here, we can rely on the knowledge that
78 // this is the last header to remove.
79 packet->RemoveHeader(elements, packet->GetSize());
83
84 if (meshId && (m_protocol->GetMeshId()->IsEqual(*meshId)))
85 {
86 m_protocol->ReceiveBeacon(m_ifIndex,
87 header.GetAddr2(),
88 MicroSeconds(beacon_hdr.GetBeaconIntervalUs()),
90 }
91 else
92 {
93 NS_LOG_DEBUG("MeshId mismatch " << m_protocol->GetMeshId()->PeekString() << " "
94 << (*meshId) << "; ignoring");
95 }
96 // Beacon shall not be dropped. May be needed to another plugins
97 return true;
98 }
99 uint16_t aid = 0; // applicable only in Confirm message
100 IeConfiguration config;
101 if (header.IsAction())
102 {
103 NS_LOG_DEBUG("Is action");
105 packet->RemoveHeader(actionHdr);
107 // If can not handle - just return;
108 if (actionHdr.GetCategory() != WifiActionHeader::SELF_PROTECTED)
109 {
110 NS_LOG_DEBUG("Cannot handle non SELF PROTECTED");
111 return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
112 }
113 m_stats.rxMgt++;
114 m_stats.rxMgtBytes += packet->GetSize();
117 if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_OPEN)
118 {
119 NS_LOG_DEBUG("Received PEER_LINK_OPEN");
122 packet->RemoveHeader(peerFrame);
123 fields = peerFrame.GetFields();
124 if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
125 {
126 NS_LOG_DEBUG("PEER_LINK_OPEN: MeshId mismatch");
127 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
128 // Broken peer link frame - drop it
130 return false;
131 }
132 if (!(m_parent->CheckSupportedRates(
133 AllSupportedRates{fields.rates, fields.extendedRates})))
134 {
135 NS_LOG_DEBUG("PEER_LINK_OPEN: configuration mismatch");
136 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
137 // Broken peer link frame - drop it
139 return false;
140 }
141 config = fields.config;
142 }
143 else if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_CONFIRM)
144 {
145 NS_LOG_DEBUG("Received PEER_LINK_CONFIRM");
148 packet->RemoveHeader(peerFrame);
149 fields = peerFrame.GetFields();
150 if (!(m_parent->CheckSupportedRates(
151 AllSupportedRates{fields.rates, fields.extendedRates})))
152 {
153 NS_LOG_DEBUG("PEER_LINK_CONFIRM: configuration mismatch");
154 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
155 // Broken peer link frame - drop it
157 return false;
158 }
159 aid = fields.aid;
160 config = fields.config;
161 }
162 else if (actionValue.selfProtectedAction == WifiActionHeader::PEER_LINK_CLOSE)
163 {
164 NS_LOG_DEBUG("Received PEER_LINK_CLOSE");
167 packet->RemoveHeader(peerFrame);
168 fields = peerFrame.GetFields();
169 if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
170 {
171 NS_LOG_DEBUG("PEER_LINK_CLOSE: configuration mismatch");
172 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
173 // Broken peer link frame - drop it
175 return false;
176 }
177 }
178 else
179 {
181 "Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
182 }
185 // To determine header size here, we can rely on the knowledge that
186 // this is the last header to remove.
187 packet->RemoveHeader(elements, packet->GetSize());
189
191 // Check that frame subtype corresponds to peer link subtype
192 if (peerElement->SubtypeIsOpen())
193 {
194 m_stats.rxOpen++;
196 }
197 if (peerElement->SubtypeIsConfirm())
198 {
201 }
202 if (peerElement->SubtypeIsClose())
203 {
206 }
207 // Deliver Peer link management frame to protocol:
208 m_protocol->ReceivePeerLinkFrame(m_ifIndex,
211 aid,
213 config);
214 // if we can handle a frame - drop it
215 return false;
216 }
217 return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
218}
219
220bool
222 WifiMacHeader& header,
223 Mac48Address from,
224 Mac48Address to)
225{
226 NS_LOG_FUNCTION(this << packet << header << from << to);
227 if (header.IsAction())
228 {
230 packet->PeekHeader(actionHdr);
231 if (actionHdr.GetCategory() == WifiActionHeader::SELF_PROTECTED)
232 {
233 return true;
234 }
235 }
236 if (header.GetAddr1().IsGroup())
237 {
238 return true;
239 }
240 else
241 {
242 if (m_protocol->IsActiveLink(m_ifIndex, header.GetAddr1()))
243 {
244 return true;
245 }
246 else
247 {
249 return false;
250 }
251 }
252}
253
254void
256{
257 if (m_protocol->GetBeaconCollisionAvoidance())
258 {
259 Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
260 beacon.AddInformationElement(beaconTiming);
261 }
262 beacon.AddInformationElement(m_protocol->GetMeshId());
263 m_protocol->NotifyBeaconSent(m_ifIndex, beacon.GetBeaconInterval());
264}
265
266void
269 uint16_t aid,
272{
274 // Create a packet:
275 meshConfig.SetNeighborCount(m_protocol->GetNumberOfLinks());
276 Ptr<Packet> packet = Create<Packet>();
279 packet->AddHeader(elements);
280 // Create an 802.11 frame header:
281 // Send management frame to MAC:
282 if (peerElement.SubtypeIsOpen())
283 {
285 auto allSupportedRates = m_parent->GetSupportedRates();
287 fields.extendedRates = allSupportedRates.extendedRates;
288 fields.capability = 0;
289 fields.meshId = *(m_protocol->GetMeshId());
290 fields.config = meshConfig;
293 m_stats.txOpen++;
295 action.selfProtectedAction = WifiActionHeader::PEER_LINK_OPEN;
297 plinkOpen.SetPlinkOpenStart(fields);
298 packet->AddHeader(plinkOpen);
299 packet->AddHeader(actionHdr);
300 }
301 if (peerElement.SubtypeIsConfirm())
302 {
304 auto allSupportedRates = m_parent->GetSupportedRates();
306 fields.extendedRates = allSupportedRates.extendedRates;
307 fields.capability = 0;
308 fields.config = meshConfig;
313 action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
314 fields.aid = aid;
316 plinkConfirm.SetPlinkConfirmStart(fields);
317 packet->AddHeader(plinkConfirm);
318 packet->AddHeader(actionHdr);
319 }
320 if (peerElement.SubtypeIsClose())
321 {
323 fields.meshId = *(m_protocol->GetMeshId());
328 action.selfProtectedAction = WifiActionHeader::PEER_LINK_CLOSE;
330 plinkClose.SetPlinkCloseStart(fields);
331 packet->AddHeader(plinkClose);
332 packet->AddHeader(actionHdr);
333 }
334 m_stats.txMgt++;
335 m_stats.txMgtBytes += packet->GetSize();
336 // Wifi Mac header:
339 hdr.SetAddr1(peerAddress);
340 hdr.SetAddr2(m_parent->GetAddress());
341 // Addr is not used here, we use it as our MP address
342 hdr.SetAddr3(m_protocol->GetAddress());
343 hdr.SetDsNotFrom();
344 hdr.SetDsNotTo();
345 m_parent->SendManagementFrame(packet, hdr);
346}
347
350{
351 if (m_parent)
352 {
353 return m_parent->GetAddress();
354 }
355 else
356 {
357 return Mac48Address();
358 }
359}
360
361void
363{
364 if (!shift.IsZero())
365 {
367 }
368 m_parent->ShiftTbtt(shift);
369}
370
372 : txOpen(0),
373 txConfirm(0),
374 txClose(0),
375 rxOpen(0),
376 rxConfirm(0),
377 rxClose(0),
378 dropped(0),
379 brokenMgt(0),
380 txMgt(0),
381 txMgtBytes(0),
382 rxMgt(0),
383 rxMgtBytes(0),
384 beaconShift(0)
385{
386}
387
388void
390{
391 os << "<Statistics "
392 "txOpen=\""
393 << txOpen << "\"" << std::endl
394 << "txConfirm=\"" << txConfirm << "\"" << std::endl
395 << "txClose=\"" << txClose << "\"" << std::endl
396 << "rxOpen=\"" << rxOpen << "\"" << std::endl
397 << "rxConfirm=\"" << rxConfirm << "\"" << std::endl
398 << "rxClose=\"" << rxClose << "\"" << std::endl
399 << "dropped=\"" << dropped << "\"" << std::endl
400 << "brokenMgt=\"" << brokenMgt << "\"" << std::endl
401 << "txMgt=\"" << txMgt << "\"" << std::endl
402 << "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl
403 << "rxMgt=\"" << rxMgt << "\"" << std::endl
404 << "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl
405 << "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
406}
407
408void
410{
411 os << "<PeerManagementProtocolMac "
412 "address=\""
413 << m_parent->GetAddress() << "\">" << std::endl;
414 m_stats.Print(os);
415 os << "</PeerManagementProtocolMac>" << std::endl;
416}
417
418void
423
429
430int64_t
432{
433 return m_protocol->AssignStreams(stream);
434}
435
436} // namespace dot11s
437} // namespace ns3
an EUI-48 address
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.
Implement the header for management frames of type beacon.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
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.
bool IsAction() const
Return true if the header is an Action header.
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.
Describes Mesh Configuration Element see 7.3.2.86 of 802.11s draft 3.0.
according to IEEE 802.11 - 2012
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:55
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
WifiMacDropReason
The reason why an MPDU was dropped.
Definition wifi-mac.h:71
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:684
@ WIFI_MAC_MGT_ACTION
Struct containing all supported rates.
typedef for union of different ActionValues
#define IE_BEACON_TIMING
#define IE_MESH_PEERING_MANAGEMENT
#define IE_MESH_ID