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());
74 MgtBeaconHeader beacon_hdr;
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());
80 Ptr<IeBeaconTiming> beaconTiming =
83
84 if (meshId && (m_protocol->GetMeshId()->IsEqual(*meshId)))
85 {
86 m_protocol->ReceiveBeacon(m_ifIndex,
87 header.GetAddr2(),
89 beaconTiming);
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");
104 WifiActionHeader actionHdr;
105 packet->RemoveHeader(actionHdr);
106 WifiActionHeader::ActionValue actionValue = actionHdr.GetAction();
107 // If can not handle - just return;
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();
115 Mac48Address peerAddress = header.GetAddr2();
116 Mac48Address peerMpAddress = header.GetAddr3();
118 {
119 NS_LOG_DEBUG("Received PEER_LINK_OPEN");
121 PeerLinkOpenStart peerFrame;
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 }
144 {
145 NS_LOG_DEBUG("Received PEER_LINK_CONFIRM");
147 PeerLinkConfirmStart peerFrame;
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 }
163 {
164 NS_LOG_DEBUG("Received PEER_LINK_CLOSE");
166 PeerLinkCloseStart peerFrame;
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 }
183 Ptr<IePeerManagement> peerElement;
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
190 NS_ASSERT(peerElement);
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,
209 peerAddress,
210 peerMpAddress,
211 aid,
212 *peerElement,
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 {
229 WifiActionHeader actionHdr;
230 packet->PeekHeader(actionHdr);
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
268 Mac48Address peerMpAddress,
269 uint16_t aid,
270 IePeerManagement peerElement,
271 IeConfiguration meshConfig)
272{
273 NS_LOG_FUNCTION(this << peerAddress << peerMpAddress);
274 // Create a packet:
275 meshConfig.SetNeighborCount(m_protocol->GetNumberOfLinks());
276 Ptr<Packet> packet = Create<Packet>();
278 elements.AddInformationElement(Ptr<IePeerManagement>(&peerElement));
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();
286 fields.rates = allSupportedRates.rates;
287 fields.extendedRates = allSupportedRates.extendedRates;
288 fields.capability = 0;
289 fields.meshId = *(m_protocol->GetMeshId());
290 fields.config = meshConfig;
291 PeerLinkOpenStart plinkOpen;
292 WifiActionHeader actionHdr;
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();
305 fields.rates = allSupportedRates.rates;
306 fields.extendedRates = allSupportedRates.extendedRates;
307 fields.capability = 0;
308 fields.config = meshConfig;
309 PeerLinkConfirmStart plinkConfirm;
310 WifiActionHeader actionHdr;
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());
324 PeerLinkCloseStart plinkClose;
325 WifiActionHeader actionHdr;
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:
337 WifiMacHeader hdr;
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
426{
427 return m_parent->GetLinkMetric(peerAddress);
428}
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.
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.
uint64_t GetBeaconIntervalUs() const
Return the beacon interval in microseconds unit.
Smart pointer class similar to boost::intrusive_ptr.
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 |.
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.
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: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:70
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
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ 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