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 * 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
34namespace ns3
35{
36
37NS_LOG_COMPONENT_DEFINE("PeerManagementProtocolMac");
38
39namespace dot11s
40{
43{
44 m_ifIndex = interface;
45 m_protocol = protocol;
46}
47
49{
50}
51
52void
54{
55 m_parent = parent;
56 m_parent->TraceConnectWithoutContext("DroppedMpdu",
58 m_parent->TraceConnectWithoutContext("AckedMpdu",
60}
61
62void
64{
65 m_protocol->TransmissionFailure(m_ifIndex, mpdu->GetHeader().GetAddr1());
66}
67
68void
70{
71 m_protocol->TransmissionSuccess(m_ifIndex, mpdu->GetHeader().GetAddr1());
72}
73
74bool
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(),
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
140 return false;
141 }
142 if (!(m_parent->CheckSupportedRates(
143 AllSupportedRates{fields.rates, fields.extendedRates})))
144 {
145 NS_LOG_DEBUG("PEER_LINK_OPEN: configuration mismatch");
146 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
147 // Broken peer link frame - drop it
149 return false;
150 }
151 config = fields.config;
152 }
154 {
155 NS_LOG_DEBUG("Received PEER_LINK_CONFIRM");
157 PeerLinkConfirmStart peerFrame;
158 packet->RemoveHeader(peerFrame);
159 fields = peerFrame.GetFields();
160 if (!(m_parent->CheckSupportedRates(
161 AllSupportedRates{fields.rates, fields.extendedRates})))
162 {
163 NS_LOG_DEBUG("PEER_LINK_CONFIRM: configuration mismatch");
164 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
165 // Broken peer link frame - drop it
167 return false;
168 }
169 aid = fields.aid;
170 config = fields.config;
171 }
173 {
174 NS_LOG_DEBUG("Received PEER_LINK_CLOSE");
176 PeerLinkCloseStart peerFrame;
177 packet->RemoveHeader(peerFrame);
178 fields = peerFrame.GetFields();
179 if (!fields.meshId.IsEqual(*(m_protocol->GetMeshId())))
180 {
181 NS_LOG_DEBUG("PEER_LINK_CLOSE: configuration mismatch");
182 m_protocol->ConfigurationMismatch(m_ifIndex, peerAddress);
183 // Broken peer link frame - drop it
185 return false;
186 }
187 }
188 else
189 {
191 "Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
192 }
193 Ptr<IePeerManagement> peerElement;
195 // To determine header size here, we can rely on the knowledge that
196 // this is the last header to remove.
197 packet->RemoveHeader(elements, packet->GetSize());
198 peerElement = DynamicCast<IePeerManagement>(elements.FindFirst(IE_MESH_PEERING_MANAGEMENT));
199
200 NS_ASSERT(peerElement);
201 // Check that frame subtype corresponds to peer link subtype
202 if (peerElement->SubtypeIsOpen())
203 {
204 m_stats.rxOpen++;
206 }
207 if (peerElement->SubtypeIsConfirm())
208 {
211 }
212 if (peerElement->SubtypeIsClose())
213 {
216 }
217 // Deliver Peer link management frame to protocol:
218 m_protocol->ReceivePeerLinkFrame(m_ifIndex,
219 peerAddress,
220 peerMpAddress,
221 aid,
222 *peerElement,
223 config);
224 // if we can handle a frame - drop it
225 return false;
226 }
227 return m_protocol->IsActiveLink(m_ifIndex, header.GetAddr2());
228}
229
230bool
232 WifiMacHeader& header,
233 Mac48Address from,
234 Mac48Address to)
235{
236 NS_LOG_FUNCTION(this << packet << header << from << to);
237 if (header.IsAction())
238 {
239 WifiActionHeader actionHdr;
240 packet->PeekHeader(actionHdr);
242 {
243 return true;
244 }
245 }
246 if (header.GetAddr1().IsGroup())
247 {
248 return true;
249 }
250 else
251 {
252 if (m_protocol->IsActiveLink(m_ifIndex, header.GetAddr1()))
253 {
254 return true;
255 }
256 else
257 {
259 return false;
260 }
261 }
262}
263
264void
266{
267 if (m_protocol->GetBeaconCollisionAvoidance())
268 {
269 Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement(m_ifIndex);
270 beacon.AddInformationElement(beaconTiming);
271 }
272 beacon.AddInformationElement(m_protocol->GetMeshId());
273 m_protocol->NotifyBeaconSent(m_ifIndex, beacon.GetBeaconInterval());
274}
275
276void
278 Mac48Address peerMpAddress,
279 uint16_t aid,
280 IePeerManagement peerElement,
281 IeConfiguration meshConfig)
282{
283 NS_LOG_FUNCTION(this << peerAddress << peerMpAddress);
284 // Create a packet:
285 meshConfig.SetNeighborCount(m_protocol->GetNumberOfLinks());
286 Ptr<Packet> packet = Create<Packet>();
288 elements.AddInformationElement(Ptr<IePeerManagement>(&peerElement));
289 packet->AddHeader(elements);
290 // Create an 802.11 frame header:
291 // Send management frame to MAC:
292 if (peerElement.SubtypeIsOpen())
293 {
295 auto allSupportedRates = m_parent->GetSupportedRates();
296 fields.rates = allSupportedRates.rates;
297 fields.extendedRates = allSupportedRates.extendedRates;
298 fields.capability = 0;
299 fields.meshId = *(m_protocol->GetMeshId());
300 fields.config = meshConfig;
301 PeerLinkOpenStart plinkOpen;
302 WifiActionHeader actionHdr;
303 m_stats.txOpen++;
305 action.selfProtectedAction = WifiActionHeader::PEER_LINK_OPEN;
307 plinkOpen.SetPlinkOpenStart(fields);
308 packet->AddHeader(plinkOpen);
309 packet->AddHeader(actionHdr);
310 }
311 if (peerElement.SubtypeIsConfirm())
312 {
314 auto allSupportedRates = m_parent->GetSupportedRates();
315 fields.rates = allSupportedRates.rates;
316 fields.extendedRates = allSupportedRates.extendedRates;
317 fields.capability = 0;
318 fields.config = meshConfig;
319 PeerLinkConfirmStart plinkConfirm;
320 WifiActionHeader actionHdr;
323 action.selfProtectedAction = WifiActionHeader::PEER_LINK_CONFIRM;
324 fields.aid = aid;
326 plinkConfirm.SetPlinkConfirmStart(fields);
327 packet->AddHeader(plinkConfirm);
328 packet->AddHeader(actionHdr);
329 }
330 if (peerElement.SubtypeIsClose())
331 {
333 fields.meshId = *(m_protocol->GetMeshId());
334 PeerLinkCloseStart plinkClose;
335 WifiActionHeader actionHdr;
338 action.selfProtectedAction = WifiActionHeader::PEER_LINK_CLOSE;
340 plinkClose.SetPlinkCloseStart(fields);
341 packet->AddHeader(plinkClose);
342 packet->AddHeader(actionHdr);
343 }
344 m_stats.txMgt++;
345 m_stats.txMgtBytes += packet->GetSize();
346 // Wifi Mac header:
347 WifiMacHeader hdr;
349 hdr.SetAddr1(peerAddress);
350 hdr.SetAddr2(m_parent->GetAddress());
351 // Addr is not used here, we use it as our MP address
352 hdr.SetAddr3(m_protocol->GetAddress());
353 hdr.SetDsNotFrom();
354 hdr.SetDsNotTo();
355 m_parent->SendManagementFrame(packet, hdr);
356}
357
360{
361 if (m_parent)
362 {
363 return m_parent->GetAddress();
364 }
365 else
366 {
367 return Mac48Address();
368 }
369}
370
371void
373{
374 if (shift != Seconds(0))
375 {
377 }
378 m_parent->ShiftTbtt(shift);
379}
380
382 : txOpen(0),
383 txConfirm(0),
384 txClose(0),
385 rxOpen(0),
386 rxConfirm(0),
387 rxClose(0),
388 dropped(0),
389 brokenMgt(0),
390 txMgt(0),
391 txMgtBytes(0),
392 rxMgt(0),
393 rxMgtBytes(0),
394 beaconShift(0)
395{
396}
397
398void
400{
401 os << "<Statistics "
402 "txOpen=\""
403 << txOpen << "\"" << std::endl
404 << "txConfirm=\"" << txConfirm << "\"" << std::endl
405 << "txClose=\"" << txClose << "\"" << std::endl
406 << "rxOpen=\"" << rxOpen << "\"" << std::endl
407 << "rxConfirm=\"" << rxConfirm << "\"" << std::endl
408 << "rxClose=\"" << rxClose << "\"" << std::endl
409 << "dropped=\"" << dropped << "\"" << std::endl
410 << "brokenMgt=\"" << brokenMgt << "\"" << std::endl
411 << "txMgt=\"" << txMgt << "\"" << std::endl
412 << "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl
413 << "rxMgt=\"" << rxMgt << "\"" << std::endl
414 << "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl
415 << "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
416}
417
418void
420{
421 os << "<PeerManagementProtocolMac "
422 "address=\""
423 << m_parent->GetAddress() << "\">" << std::endl;
424 m_stats.Print(os);
425 os << "</PeerManagementProtocolMac>" << std::endl;
426}
427
428void
430{
432}
433
436{
437 return m_parent->GetLinkMetric(peerAddress);
438}
439
440int64_t
442{
443 return m_protocol->AssignStreams(stream);
444}
445
446} // namespace dot11s
447} // 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:516
uint64_t GetBeaconIntervalUs() const
Return the beacon interval in microseconds unit.
Definition: mgt-headers.cc:76
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:539
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:601
CategoryValue GetCategory() const
Return the category value.
Definition: mgt-headers.cc:658
ActionValue GetAction() const
Return the action value.
Definition: mgt-headers.cc:693
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:702
@ WIFI_MAC_MGT_ACTION
Struct containing all supported rates.
typedef for union of different ActionValues
Definition: mgt-headers.h:723
SelfProtectedActionValue selfProtectedAction
self protected
Definition: mgt-headers.h:728
#define IE_BEACON_TIMING
#define IE_MESH_PEERING_MANAGEMENT
#define IE_MESH_ID