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/mgt-action-headers.h"
32#include "ns3/simulator.h"
33#include "ns3/wifi-mpdu.h"
34
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("PeerManagementProtocolMac");
39
40namespace dot11s
41{
44{
45 m_ifIndex = interface;
46 m_protocol = protocol;
47}
48
50{
51}
52
53void
55{
56 m_parent = parent;
57 m_parent->TraceConnectWithoutContext("DroppedMpdu",
59 m_parent->TraceConnectWithoutContext("AckedMpdu",
61}
62
63void
65{
66 m_protocol->TransmissionFailure(m_ifIndex, mpdu->GetHeader().GetAddr1());
67}
68
69void
71{
72 m_protocol->TransmissionSuccess(m_ifIndex, mpdu->GetHeader().GetAddr1());
73}
74
75bool
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(),
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
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
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
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
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 {
212 }
213 if (peerElement->SubtypeIsClose())
214 {
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
231bool
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 {
260 return false;
261 }
262 }
263}
264
265void
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
277void
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;
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;
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
372void
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
399void
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
419void
421{
422 os << "<PeerManagementProtocolMac "
423 "address=\""
424 << m_parent->GetAddress() << "\">" << std::endl;
425 m_stats.Print(os);
426 os << "</PeerManagementProtocolMac>" << std::endl;
427}
428
429void
431{
433}
434
437{
438 return m_parent->GetLinkMetric(peerAddress);
439}
440
441int64_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
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