A Discrete-Event Network Simulator
API
peer-management-protocol-mac.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009 IITP RAS
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Kirill Andreev <andreev@iitp.ru>
19 */
20
23#include "dot11s-mac-header.h"
26#include "peer-link-frame.h"
27#include "ns3/wifi-mac-queue-item.h"
28#include "ns3/mesh-wifi-interface-mac.h"
29#include "ns3/simulator.h"
30#include "ns3/mesh-information-element-vector.h"
31#include "ns3/log.h"
32
33namespace ns3 {
34
35NS_LOG_COMPONENT_DEFINE ("PeerManagementProtocolMac");
36
37namespace dot11s {
40{
41 m_ifIndex = interface;
42 m_protocol = protocol;
43}
44
46{
47}
48
49void
51{
52 m_parent = parent;
53 m_parent->TraceConnectWithoutContext ("DroppedMpdu", MakeCallback (&PeerManagementProtocolMac::TxError, this));
54 m_parent->TraceConnectWithoutContext ("AckedMpdu", MakeCallback (&PeerManagementProtocolMac::TxOk, this));
55}
56void
58{
59 m_protocol->TransmissionFailure (m_ifIndex, mpdu->GetHeader ().GetAddr1 ());
60}
61void
63{
64 m_protocol->TransmissionSuccess (m_ifIndex, mpdu->GetHeader ().GetAddr1 ());
65}
66bool
68{
69 NS_LOG_FUNCTION (this << const_packet << header);
70 // First of all we copy a packet, because we need to remove some
71 //headers
72 Ptr<Packet> packet = const_packet->Copy ();
73 if (header.IsBeacon ())
74 {
75 NS_LOG_DEBUG ("Is Beacon from " << header.GetAddr2 ());
76 MgtBeaconHeader beacon_hdr;
77 packet->RemoveHeader (beacon_hdr);
79 // To determine header size here, we can rely on the knowledge that
80 // this is the last header to remove.
81 packet->RemoveHeader (elements, packet->GetSize ());
82 Ptr<IeBeaconTiming> beaconTiming = DynamicCast<IeBeaconTiming> (elements.FindFirst (IE_BEACON_TIMING));
83 Ptr<IeMeshId> meshId = DynamicCast<IeMeshId> (elements.FindFirst (IE_MESH_ID));
84
85 if ((meshId != 0) && (m_protocol->GetMeshId ()->IsEqual (*meshId)))
86 {
87 m_protocol->ReceiveBeacon (m_ifIndex, header.GetAddr2 (), MicroSeconds (
88 beacon_hdr.GetBeaconIntervalUs ()), beaconTiming);
89 }
90 else
91 {
92 NS_LOG_DEBUG ("MeshId mismatch " << m_protocol->GetMeshId ()->PeekString () << " " << (*meshId) << "; ignoring");
93 }
94 // Beacon shall not be dropped. May be needed to another plugins
95 return true;
96 }
97 uint16_t aid = 0; // applicable only in Confirm message
98 IeConfiguration config;
99 if (header.IsAction ())
100 {
101 NS_LOG_DEBUG ("Is action");
102 WifiActionHeader actionHdr;
103 packet->RemoveHeader (actionHdr);
104 WifiActionHeader::ActionValue actionValue = actionHdr.GetAction ();
105 // If can not handle - just return;
107 {
108 NS_LOG_DEBUG ("Cannot handle non SELF PROTECTED");
109 return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
110 }
111 m_stats.rxMgt++;
112 m_stats.rxMgtBytes += packet->GetSize ();
113 Mac48Address peerAddress = header.GetAddr2 ();
114 Mac48Address peerMpAddress = header.GetAddr3 ();
116 {
117 NS_LOG_DEBUG ("Received PEER_LINK_OPEN");
119 PeerLinkOpenStart peerFrame;
120 packet->RemoveHeader (peerFrame);
121 fields = peerFrame.GetFields ();
122 if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
123 {
124 NS_LOG_DEBUG ("PEER_LINK_OPEN: MeshId mismatch");
125 m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
126 // Broken peer link frame - drop it
128 return false;
129 }
130 if (!(m_parent->CheckSupportedRates (fields.rates)))
131 {
132 NS_LOG_DEBUG ("PEER_LINK_OPEN: configuration mismatch");
133 m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
134 // Broken peer link frame - drop it
136 return false;
137 }
138 config = fields.config;
139 }
141 {
142 NS_LOG_DEBUG ("Received PEER_LINK_CONFIRM");
144 PeerLinkConfirmStart peerFrame;
145 packet->RemoveHeader (peerFrame);
146 fields = peerFrame.GetFields ();
147 if (!(m_parent->CheckSupportedRates (fields.rates)))
148 {
149 NS_LOG_DEBUG ("PEER_LINK_CONFIRM: configuration mismatch");
150 m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
151 // Broken peer link frame - drop it
153 return false;
154 }
155 aid = fields.aid;
156 config = fields.config;
157 }
159 {
160 NS_LOG_DEBUG ("Received PEER_LINK_CLOSE");
162 PeerLinkCloseStart peerFrame;
163 packet->RemoveHeader (peerFrame);
164 fields = peerFrame.GetFields ();
165 if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
166 {
167 NS_LOG_DEBUG ("PEER_LINK_CLOSE: configuration mismatch");
168 m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
169 // Broken peer link frame - drop it
171 return false;
172 }
173 }
174 else
175 {
176 NS_FATAL_ERROR ("Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
177 }
178 Ptr<IePeerManagement> peerElement;
180 // To determine header size here, we can rely on the knowledge that
181 // this is the last header to remove.
182 packet->RemoveHeader (elements, packet->GetSize ());
183 peerElement = DynamicCast<IePeerManagement>(elements.FindFirst (IE_MESH_PEERING_MANAGEMENT));
184
185 NS_ASSERT (peerElement != 0);
186 //Check that frame subtype corresponds to peer link subtype
187 if (peerElement->SubtypeIsOpen ())
188 {
189 m_stats.rxOpen++;
191 }
192 if (peerElement->SubtypeIsConfirm ())
193 {
196 }
197 if (peerElement->SubtypeIsClose ())
198 {
201 }
202 //Deliver Peer link management frame to protocol:
203 m_protocol->ReceivePeerLinkFrame (m_ifIndex, peerAddress, peerMpAddress, aid, *peerElement, config);
204 // if we can handle a frame - drop it
205 return false;
206 }
207 return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
208}
209bool
211 Mac48Address from, Mac48Address to)
212{
213 NS_LOG_FUNCTION (this << packet << header << from << to);
214 if (header.IsAction ())
215 {
216 WifiActionHeader actionHdr;
217 packet->PeekHeader (actionHdr);
219 {
220 return true;
221 }
222 }
223 if (header.GetAddr1 ().IsGroup ())
224 {
225 return true;
226 }
227 else
228 {
229 if (m_protocol->IsActiveLink (m_ifIndex, header.GetAddr1 ()))
230 {
231 return true;
232 }
233 else
234 {
236 return false;
237 }
238 }
239}
240void
242{
243 if (m_protocol->GetBeaconCollisionAvoidance ())
244 {
245 Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement (m_ifIndex);
246 beacon.AddInformationElement (beaconTiming);
247 }
248 beacon.AddInformationElement (m_protocol->GetMeshId ());
249 m_protocol->NotifyBeaconSent (m_ifIndex, beacon.GetBeaconInterval ());
250}
251
252void
254 uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
255{
256 NS_LOG_FUNCTION (this << peerAddress << peerMpAddress);
257 //Create a packet:
258 meshConfig.SetNeighborCount (m_protocol->GetNumberOfLinks ());
259 Ptr<Packet> packet = Create<Packet> ();
261 elements.AddInformationElement (Ptr<IePeerManagement> (&peerElement));
262 packet->AddHeader (elements);
263 //Create an 802.11 frame header:
264 //Send management frame to MAC:
265 if (peerElement.SubtypeIsOpen ())
266 {
268 fields.rates = m_parent->GetSupportedRates ();
269 fields.capability = 0;
270 fields.meshId = *(m_protocol->GetMeshId ());
271 fields.config = meshConfig;
272 PeerLinkOpenStart plinkOpen;
273 WifiActionHeader actionHdr;
274 m_stats.txOpen++;
277 actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
278 plinkOpen.SetPlinkOpenStart (fields);
279 packet->AddHeader (plinkOpen);
280 packet->AddHeader (actionHdr);
281 }
282 if (peerElement.SubtypeIsConfirm ())
283 {
285 fields.rates = m_parent->GetSupportedRates ();
286 fields.capability = 0;
287 fields.config = meshConfig;
288 PeerLinkConfirmStart plinkConfirm;
289 WifiActionHeader actionHdr;
293 fields.aid = aid;
294 actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
295 plinkConfirm.SetPlinkConfirmStart (fields);
296 packet->AddHeader (plinkConfirm);
297 packet->AddHeader (actionHdr);
298 }
299 if (peerElement.SubtypeIsClose ())
300 {
302 fields.meshId = *(m_protocol->GetMeshId ());
303 PeerLinkCloseStart plinkClose;
304 WifiActionHeader actionHdr;
308 actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
309 plinkClose.SetPlinkCloseStart (fields);
310 packet->AddHeader (plinkClose);
311 packet->AddHeader (actionHdr);
312 }
313 m_stats.txMgt++;
314 m_stats.txMgtBytes += packet->GetSize ();
315 // Wifi Mac header:
316 WifiMacHeader hdr;
318 hdr.SetAddr1 (peerAddress);
319 hdr.SetAddr2 (m_parent->GetAddress ());
320 //Addr is not used here, we use it as our MP address
321 hdr.SetAddr3 (m_protocol->GetAddress ());
322 hdr.SetDsNotFrom ();
323 hdr.SetDsNotTo ();
324 m_parent->SendManagementFrame (packet, hdr);
325}
326
329{
330 if (m_parent != 0)
331 {
332 return m_parent->GetAddress ();
333 }
334 else
335 {
336 return Mac48Address ();
337 }
338}
339void
341{
342 if (shift != Seconds (0))
343 {
345 }
346 m_parent->ShiftTbtt (shift);
347}
349 txOpen (0), txConfirm (0), txClose (0), rxOpen (0), rxConfirm (0), rxClose (0), dropped (0), brokenMgt (0),
350 txMgt (0), txMgtBytes (0), rxMgt (0), rxMgtBytes (0), beaconShift (0)
351{
352}
353void
355{
356 os << "<Statistics "
357 "txOpen=\"" << txOpen << "\"" << std::endl <<
358 "txConfirm=\"" << txConfirm << "\"" << std::endl <<
359 "txClose=\"" << txClose << "\"" << std::endl <<
360 "rxOpen=\"" << rxOpen << "\"" << std::endl <<
361 "rxConfirm=\"" << rxConfirm << "\"" << std::endl <<
362 "rxClose=\"" << rxClose << "\"" << std::endl <<
363 "dropped=\"" << dropped << "\"" << std::endl <<
364 "brokenMgt=\"" << brokenMgt << "\"" << std::endl <<
365 "txMgt=\"" << txMgt << "\"" << std::endl <<
366 "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl <<
367 "rxMgt=\"" << rxMgt << "\"" << std::endl <<
368 "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl <<
369 "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
370}
371void
372PeerManagementProtocolMac::Report (std::ostream & os) const
373{
374 os << "<PeerManagementProtocolMac "
375 "address=\"" << m_parent->GetAddress () << "\">" << std::endl;
376 m_stats.Print (os);
377 os << "</PeerManagementProtocolMac>" << std::endl;
378}
379void
381{
382 m_stats = Statistics ();
383}
386{
387 return m_parent->GetLinkMetric (peerAddress);
388}
389int64_t
391{
392 return m_protocol->AssignStreams (stream);
393}
394
395} // namespace dot11s
396} // namespace ns3
397
an EUI-48 address
Definition: mac48-address.h:44
bool IsGroup(void) 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:862
uint64_t GetBeaconIntervalUs(void) const
Return the beacon interval in microseconds unit.
Definition: mgt-headers.cc:208
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:885
CategoryValue GetCategory()
Return the category value.
ActionValue GetAction()
Return the action value.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
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.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
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.
bool IsAction(void) const
Return true if the header is an Action header.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 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.
bool IsBeacon(void) const
Return true if the header is a Beacon header.
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(IeMeshId const &o) const
Equality test.
Definition: ie-dot11s-id.cc:58
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.
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
This method appears to test a few conditions.
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Set pointer to parent.
void TxError(WifiMacDropReason reason, Ptr< const WifiMacQueueItem > mpdu)
Closes link when a proper number of successive transmissions have failed.
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Receive and process a packet.
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 TxOk(Ptr< const WifiMacQueueItem > mpdu)
Transmit OK function.
int64_t AssignStreams(int64_t stream)
Assign the streams.
void UpdateBeacon(MeshWifiBeacon &beacon) const
Add beacon timing and mesh ID information elements, and notify beacon sent.
void SendPeerLinkManagementFrame(Mac48Address peerAddress, Mac48Address peerMpAddress, uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
Send peer link management frame function.
uint32_t GetLinkMetric(Mac48Address peerAddress)
Get the link metric.
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:67
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#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:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:66
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ WIFI_MAC_MGT_ACTION
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
typedef for union of different ActionValues
Definition: mgt-headers.h:956
SelfProtectedActionValue selfProtectedAction
self protected action
Definition: mgt-headers.h:959
#define IE_BEACON_TIMING
#define IE_MESH_PEERING_MANAGEMENT
#define IE_MESH_ID