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/mesh-wifi-interface-mac.h"
28 #include "ns3/simulator.h"
29 #include "ns3/wifi-mac-header.h"
30 #include "ns3/mesh-information-element-vector.h"
31 #include "ns3/log.h"
32 namespace ns3 {
33 namespace dot11s {
36 {
37  m_ifIndex = interface;
38  m_protocol = protocol;
39 }
40 
42 {
43 }
44 
45 void
47 {
48  m_parent = parent;
49  m_parent->TraceConnectWithoutContext ("TxErrHeader", MakeCallback (&PeerManagementProtocolMac::TxError, this));
50  m_parent->TraceConnectWithoutContext ("TxOkHeader", MakeCallback (&PeerManagementProtocolMac::TxOk, this));
51 }
52 void
54 {
55  m_protocol->TransmissionFailure (m_ifIndex, hdr.GetAddr1 ());
56 }
57 void
59 {
60  m_protocol->TransmissionSuccess (m_ifIndex, hdr.GetAddr1 ());
61 }
62 bool
64 {
65  // First of all we copy a packet, because we need to remove some
66  //headers
67  Ptr<Packet> packet = const_packet->Copy ();
68  if (header.IsBeacon ())
69  {
70  MgtBeaconHeader beacon_hdr;
71  packet->RemoveHeader (beacon_hdr);
73  packet->RemoveHeader (elements);
74  Ptr<IeBeaconTiming> beaconTiming = DynamicCast<IeBeaconTiming> (elements.FindFirst (IE11S_BEACON_TIMING));
75  Ptr<IeMeshId> meshId = DynamicCast<IeMeshId> (elements.FindFirst (IE11S_MESH_ID));
76 
77  if ((meshId != 0) && (m_protocol->GetMeshId ()->IsEqual (*meshId)))
78  {
79  m_protocol->ReceiveBeacon (m_ifIndex, header.GetAddr2 (), MicroSeconds (
80  beacon_hdr.GetBeaconIntervalUs ()), beaconTiming);
81  }
82  // Beacon shall not be dropped. May be needed to another plugins
83  return true;
84  }
85  uint16_t aid = 0; // applicable only in Confirm message
86  IeConfiguration config;
87  if (header.IsAction ())
88  {
89  WifiActionHeader actionHdr;
90  packet->RemoveHeader (actionHdr);
91  WifiActionHeader::ActionValue actionValue = actionHdr.GetAction ();
92  // If can not handle - just return;
94  {
95  return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
96  }
97  m_stats.rxMgt++;
98  m_stats.rxMgtBytes += packet->GetSize ();
99  Mac48Address peerAddress = header.GetAddr2 ();
100  Mac48Address peerMpAddress = header.GetAddr3 ();
102  {
104  PeerLinkOpenStart peerFrame;
105  packet->RemoveHeader (peerFrame);
106  fields = peerFrame.GetFields ();
107  if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
108  {
109  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
110  // Broken peer link frame - drop it
111  m_stats.brokenMgt++;
112  return false;
113  }
114  if (!(m_parent->CheckSupportedRates (fields.rates)))
115  {
116  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
117  // Broken peer link frame - drop it
118  m_stats.brokenMgt++;
119  return false;
120  }
121  config = fields.config;
122  }
124  {
126  PeerLinkConfirmStart peerFrame;
127  packet->RemoveHeader (peerFrame);
128  fields = peerFrame.GetFields ();
129  if (!(m_parent->CheckSupportedRates (fields.rates)))
130  {
131  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
132  // Broken peer link frame - drop it
133  m_stats.brokenMgt++;
134  return false;
135  }
136  aid = fields.aid;
137  config = fields.config;
138  }
140  {
142  PeerLinkCloseStart peerFrame;
143  packet->RemoveHeader (peerFrame);
144  fields = peerFrame.GetFields ();
145  if (!fields.meshId.IsEqual ( *(m_protocol->GetMeshId ())))
146  {
147  m_protocol->ConfigurationMismatch (m_ifIndex, peerAddress);
148  // Broken peer link frame - drop it
149  m_stats.brokenMgt++;
150  return false;
151  }
152  }
153  else
154  {
155  NS_FATAL_ERROR ("Unknown Self-protected Action type: " << actionValue.selfProtectedAction);
156  }
157  Ptr<IePeerManagement> peerElement;
158  //Peer Management element is the last element in this frame - so, we can use MeshInformationElementVector
160  packet->RemoveHeader (elements);
161  peerElement = DynamicCast<IePeerManagement>(elements.FindFirst (IE11S_PEERING_MANAGEMENT));
162 
163  NS_ASSERT (peerElement != 0);
164  //Check that frame subtype corresponds to peer link subtype
165  if (peerElement->SubtypeIsOpen ())
166  {
167  m_stats.rxOpen++;
169  }
170  if (peerElement->SubtypeIsConfirm ())
171  {
172  m_stats.rxConfirm++;
174  }
175  if (peerElement->SubtypeIsClose ())
176  {
177  m_stats.rxClose++;
179  }
180  //Deliver Peer link management frame to protocol:
181  m_protocol->ReceivePeerLinkFrame (m_ifIndex, peerAddress, peerMpAddress, aid, *peerElement, config);
182  // if we can handle a frame - drop it
183  return false;
184  }
185  return m_protocol->IsActiveLink (m_ifIndex, header.GetAddr2 ());
186 }
187 bool
189  Mac48Address from, Mac48Address to)
190 {
191  if (header.IsAction ())
192  {
193  WifiActionHeader actionHdr;
194  packet->PeekHeader (actionHdr);
195  if (actionHdr.GetCategory () == WifiActionHeader::SELF_PROTECTED)
196  {
197  return true;
198  }
199  }
200  if (header.GetAddr1 ().IsGroup ())
201  {
202  return true;
203  }
204  else
205  {
206  if (m_protocol->IsActiveLink (m_ifIndex, header.GetAddr1 ()))
207  {
208  return true;
209  }
210  else
211  {
212  m_stats.dropped++;
213  return false;
214  }
215  }
216 }
217 void
219 {
220  if (m_protocol->GetBeaconCollisionAvoidance ())
221  {
222  Ptr<IeBeaconTiming> beaconTiming = m_protocol->GetBeaconTimingElement (m_ifIndex);
223  beacon.AddInformationElement (beaconTiming);
224  }
225  beacon.AddInformationElement (m_protocol->GetMeshId ());
226  m_protocol->NotifyBeaconSent (m_ifIndex, beacon.GetBeaconInterval ());
227 }
228 
229 void
231  uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
232 {
233  //Create a packet:
234  meshConfig.SetNeighborCount (m_protocol->GetNumberOfLinks ());
235  Ptr<Packet> packet = Create<Packet> ();
237  elements.AddInformationElement (Ptr<IePeerManagement> (&peerElement));
238  packet->AddHeader (elements);
239  //Create an 802.11 frame header:
240  //Send management frame to MAC:
241  if (peerElement.SubtypeIsOpen ())
242  {
244  fields.rates = m_parent->GetSupportedRates ();
245  fields.capability = 0;
246  fields.meshId = *(m_protocol->GetMeshId ());
247  fields.config = meshConfig;
248  PeerLinkOpenStart plinkOpen;
249  WifiActionHeader actionHdr;
250  m_stats.txOpen++;
253  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
254  plinkOpen.SetPlinkOpenStart (fields);
255  packet->AddHeader (plinkOpen);
256  packet->AddHeader (actionHdr);
257  }
258  if (peerElement.SubtypeIsConfirm ())
259  {
261  fields.rates = m_parent->GetSupportedRates ();
262  fields.capability = 0;
263  fields.config = meshConfig;
264  PeerLinkConfirmStart plinkConfirm;
265  WifiActionHeader actionHdr;
266  m_stats.txConfirm++;
269  fields.aid = aid;
270  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
271  plinkConfirm.SetPlinkConfirmStart (fields);
272  packet->AddHeader (plinkConfirm);
273  packet->AddHeader (actionHdr);
274  }
275  if (peerElement.SubtypeIsClose ())
276  {
278  fields.meshId = *(m_protocol->GetMeshId ());
279  PeerLinkCloseStart plinkClose;
280  WifiActionHeader actionHdr;
281  m_stats.txClose++;
284  actionHdr.SetAction (WifiActionHeader::SELF_PROTECTED, action);
285  plinkClose.SetPlinkCloseStart (fields);
286  packet->AddHeader (plinkClose);
287  packet->AddHeader (actionHdr);
288  }
289  m_stats.txMgt++;
290  m_stats.txMgtBytes += packet->GetSize ();
291  // Wifi Mac header:
292  WifiMacHeader hdr;
293  hdr.SetAction ();
294  hdr.SetAddr1 (peerAddress);
295  hdr.SetAddr2 (m_parent->GetAddress ());
296  //Addr is not used here, we use it as our MP address
297  hdr.SetAddr3 (m_protocol->GetAddress ());
298  hdr.SetDsNotFrom ();
299  hdr.SetDsNotTo ();
300  m_parent->SendManagementFrame (packet, hdr);
301 }
302 
305 {
306  if (m_parent != 0)
307  {
308  return m_parent->GetAddress ();
309  }
310  else
311  {
312  return Mac48Address ();
313  }
314 }
315 void
317 {
318  if (shift != Seconds (0))
319  {
321  }
322  m_parent->ShiftTbtt (shift);
323 }
325  txOpen (0), txConfirm (0), txClose (0), rxOpen (0), rxConfirm (0), rxClose (0), dropped (0), brokenMgt (0),
326  txMgt (0), txMgtBytes (0), rxMgt (0), rxMgtBytes (0), beaconShift (0)
327 {
328 }
329 void
331 {
332  os << "<Statistics "
333  "txOpen=\"" << txOpen << "\"" << std::endl <<
334  "txConfirm=\"" << txConfirm << "\"" << std::endl <<
335  "txClose=\"" << txClose << "\"" << std::endl <<
336  "rxOpen=\"" << rxOpen << "\"" << std::endl <<
337  "rxConfirm=\"" << rxConfirm << "\"" << std::endl <<
338  "rxClose=\"" << rxClose << "\"" << std::endl <<
339  "dropped=\"" << dropped << "\"" << std::endl <<
340  "brokenMgt=\"" << brokenMgt << "\"" << std::endl <<
341  "txMgt=\"" << txMgt << "\"" << std::endl <<
342  "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl <<
343  "rxMgt=\"" << rxMgt << "\"" << std::endl <<
344  "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl <<
345  "beaconShift=\"" << beaconShift << "\"/>" << std::endl;
346 }
347 void
348 PeerManagementProtocolMac::Report (std::ostream & os) const
349 {
350  os << "<PeerManagementProtocolMac "
351  "address=\"" << m_parent->GetAddress () << "\">" << std::endl;
352  m_stats.Print (os);
353  os << "</PeerManagementProtocolMac>" << std::endl;
354 }
355 void
357 {
358  m_stats = Statistics ();
359 }
360 uint32_t
362 {
363  return m_parent->GetLinkMetric (peerAddress);
364 }
365 int64_t
367 {
368  return m_protocol->AssignStreams (stream);
369 }
370 
371 } // namespace dot11s
372 } // namespace ns3
373 
bool IsBeacon(void) const
Return true if the header is a Beacon header.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void AddInformationElement(Ptr< WifiInformationElement > ie)
Add information element.
void SetAction()
Set Type/Subtype values for an action header.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
void SetBeaconShift(Time shift)
BCA functionality.
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:548
uint64_t GetBeaconIntervalUs(void) const
Return the beacon interval in microseconds unit.
Definition: mgt-headers.cc:177
bool IsAction() const
Return true if the header is an Action header.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
#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
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
void SetAction(enum CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:762
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:796
bool AddInformationElement(Ptr< WifiInformationElement > element)
add an IE, if maxSize has exceeded, returns false
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
PeerManagementProtocolMac(uint32_t interface, Ptr< PeerManagementProtocol > protocol)
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
Ptr< WifiInformationElement > FindFirst(WifiInformationElementId id) const
vector of pointers to information elements is the body of IeVector
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
Update frame before it will be forwarded down.
uint32_t GetLinkMetric(Mac48Address peerAddress)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:278
Every class exported by the ns3 library is enclosed in the ns3 namespace.
#define IE11S_MESH_ID
bool IsGroup(void) const
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SendPeerLinkManagementFrame(Mac48Address peerAddress, Mac48Address peerMpAddress, uint16_t aid, IePeerManagement peerElement, IeConfiguration meshConfig)
an EUI-48 address
Definition: mac48-address.h:43
Mac48Address GetAddress() const
debug only, used to print established links
Introspection did not find any typical Config paths.
Beacon is beacon header + list of arbitrary information elements.
Time GetBeaconInterval() const
Returns a beacon interval of wifi beacon.
enum SelfProtectedActionValue selfProtectedAction
Definition: mgt-headers.h:619
#define IE11S_BEACON_TIMING
void UpdateBeacon(MeshWifiBeacon &beacon) const
Update beacon before it will be formed and sent.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
typedef for union of different ActionValues
Definition: mgt-headers.h:615
Describes Mesh Configuration Element see 7.3.2.86 of 802.11s draft 3.0.
void SetNeighborCount(uint8_t neighbors)
bool IsEqual(IeMeshId const &o) const
Definition: ie-dot11s-id.cc:58
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Process received frame.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
ActionValue GetAction()
Return the action value.
Definition: mgt-headers.cc:817
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Each plugin must be installed on interface to work.
void TxError(WifiMacHeader const &hdr)
Closes link when a proper number of successive transmissions have failed.
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:525
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
#define IE11S_PEERING_MANAGEMENT