A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
hwmp-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) 2008,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 
21 #include "ns3/mesh-wifi-interface-mac.h"
22 #include "ns3/packet.h"
23 #include "ns3/simulator.h"
24 #include "ns3/nstime.h"
25 #include "ns3/log.h"
26 #include "ns3/mgt-headers.h"
27 #include "dot11s-mac-header.h"
28 #include "hwmp-protocol-mac.h"
29 #include "hwmp-tag.h"
30 #include "ie-dot11s-preq.h"
31 #include "ie-dot11s-prep.h"
32 #include "ie-dot11s-rann.h"
33 #include "ie-dot11s-perr.h"
34 
35 namespace ns3 {
36 namespace dot11s {
37 
38 NS_LOG_COMPONENT_DEFINE ("HwmpProtocolMac");
40  m_ifIndex (ifIndex), m_protocol (protocol)
41 {
42 }
44 {
45 }
46 void
48 {
49  m_parent = parent;
50 }
51 
52 bool
54 {
55  NS_ASSERT (header.IsData ());
56 
57  MeshHeader meshHdr;
58  HwmpTag tag;
59  if (packet->PeekPacketTag (tag))
60  {
61  NS_FATAL_ERROR ("HWMP tag is not supposed to be received by network");
62  }
63 
64  packet->RemoveHeader (meshHdr);
65  m_stats.rxData++;
66  m_stats.rxDataBytes += packet->GetSize ();
67 
69  Mac48Address destination;
70  Mac48Address source;
71  switch (meshHdr.GetAddressExt ())
72  {
73  case 0:
74  source = header.GetAddr4 ();
75  destination = header.GetAddr3 ();
76  break;
77  default:
79  "6-address scheme is not yet supported and 4-address extension is not supposed to be used for data frames.");
80  }
81  tag.SetSeqno (meshHdr.GetMeshSeqno ());
82  tag.SetTtl (meshHdr.GetMeshTtl ());
83  packet->AddPacketTag (tag);
84 
85  if ((destination == Mac48Address::GetBroadcast ()) && (m_protocol->DropDataFrame (meshHdr.GetMeshSeqno (),
86  source)))
87  {
88  return false;
89  }
90  return true;
91 }
92 
93 bool
95 {
96  m_stats.rxMgt++;
97  m_stats.rxMgtBytes += packet->GetSize ();
98  WifiActionHeader actionHdr;
99  packet->RemoveHeader (actionHdr);
101  {
102  return true;
103  }
105  packet->RemoveHeader (elements);
106  std::vector<HwmpProtocol::FailedDestination> failedDestinations;
107  for (MeshInformationElementVector::Iterator i = elements.Begin (); i != elements.End (); i++)
108  {
109  if ((*i)->ElementId () == IE11S_RANN)
110  {
111  NS_LOG_WARN ("RANN is not supported!");
112  }
113  if ((*i)->ElementId () == IE11S_PREQ)
114  {
115  Ptr<IePreq> preq = DynamicCast<IePreq> (*i);
116  NS_ASSERT (preq != 0);
117  m_stats.rxPreq++;
118  if (preq->GetOriginatorAddress () == m_protocol->GetAddress ())
119  {
120  continue;
121  }
122  if (preq->GetTtl () == 0)
123  {
124  continue;
125  }
126  preq->DecrementTtl ();
127  m_protocol->ReceivePreq (*preq, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
128  m_parent->GetLinkMetric (header.GetAddr2 ()));
129  }
130  if ((*i)->ElementId () == IE11S_PREP)
131  {
132  Ptr<IePrep> prep = DynamicCast<IePrep> (*i);
133  NS_ASSERT (prep != 0);
134  m_stats.rxPrep++;
135  if (prep->GetTtl () == 0)
136  {
137  continue;
138  }
139  prep->DecrementTtl ();
140  m_protocol->ReceivePrep (*prep, header.GetAddr2 (), m_ifIndex, header.GetAddr3 (),
141  m_parent->GetLinkMetric (header.GetAddr2 ()));
142  }
143  if ((*i)->ElementId () == IE11S_PERR)
144  {
145  Ptr<IePerr> perr = DynamicCast<IePerr> (*i);
146  NS_ASSERT (perr != 0);
147  m_stats.rxPerr++;
148  std::vector<HwmpProtocol::FailedDestination> destinations = perr->GetAddressUnitVector ();
149  for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = destinations.begin (); i
150  != destinations.end (); i++)
151  {
152  failedDestinations.push_back (*i);
153  }
154  }
155  }
156  if (failedDestinations.size () > 0)
157  {
158  m_protocol->ReceivePerr (failedDestinations, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
159  }
160  NS_ASSERT (packet->GetSize () == 0);
161  return false;
162 }
163 
164 bool
166 {
167  if (header.IsData ())
168  {
169  return ReceiveData (packet, header);
170  }
171  else
172  {
173  if (header.IsAction ())
174  {
175  return ReceiveAction (packet, header);
176  }
177  else
178  {
179  return true; // don't care
180  }
181  }
182 }
183 bool
185  Mac48Address to)
186 {
187  if (!header.IsData ())
188  {
189  return true;
190  }
191  HwmpTag tag;
192  bool tagExists = packet->RemovePacketTag (tag);
193  if (!tagExists)
194  {
195  NS_FATAL_ERROR ("HWMP tag must exist at this point");
196  }
197  m_stats.txData++;
198  m_stats.txDataBytes += packet->GetSize ();
199  MeshHeader meshHdr;
200  meshHdr.SetMeshSeqno (tag.GetSeqno ());
201  meshHdr.SetMeshTtl (tag.GetTtl ());
202  packet->AddHeader (meshHdr);
203  header.SetAddr1 (tag.GetAddress ());
204  return true;
205 }
208 {
209  WifiActionHeader actionHdr;
213  return actionHdr;
214 }
215 void
217 {
219  std::vector<IePreq> preq_vector;
220  preq_vector.push_back (preq);
221  SendPreq (preq_vector);
222 }
223 void
224 HwmpProtocolMac::SendPreq (std::vector<IePreq> preq)
225 {
226  Ptr<Packet> packet = Create<Packet> ();
228  for (std::vector<IePreq>::iterator i = preq.begin (); i != preq.end (); i++)
229  {
230  elements.AddInformationElement (Ptr<IePreq> (&(*i)));
231  }
232  packet->AddHeader (elements);
233  packet->AddHeader (GetWifiActionHeader ());
234  //create 802.11 header:
235  WifiMacHeader hdr;
236  hdr.SetAction ();
237  hdr.SetDsNotFrom ();
238  hdr.SetDsNotTo ();
239  hdr.SetAddr2 (m_parent->GetAddress ());
240  hdr.SetAddr3 (m_protocol->GetAddress ());
241  //Send Management frame
242  std::vector<Mac48Address> receivers = m_protocol->GetPreqReceivers (m_ifIndex);
243  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
244  {
245  hdr.SetAddr1 (*i);
246  m_stats.txPreq++;
247  m_stats.txMgt++;
248  m_stats.txMgtBytes += packet->GetSize ();
249  m_parent->SendManagementFrame (packet, hdr);
250  }
251 }
252 void
253 HwmpProtocolMac::RequestDestination (Mac48Address dst, uint32_t originator_seqno, uint32_t dst_seqno)
254 {
256  for (std::vector<IePreq>::iterator i = m_myPreq.begin (); i != m_myPreq.end (); i++)
257  {
258  if (i->IsFull ())
259  {
260  continue;
261  }
262  NS_ASSERT (i->GetDestCount () > 0);
263  i->AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
264  }
265  IePreq preq;
266  preq.SetHopcount (0);
267  preq.SetTTL (m_protocol->GetMaxTtl ());
268  preq.SetPreqID (m_protocol->GetNextPreqId ());
269  preq.SetOriginatorAddress (m_protocol->GetAddress ());
270  preq.SetOriginatorSeqNumber (originator_seqno);
271  preq.SetLifetime (m_protocol->GetActivePathLifetime ());
272  preq.AddDestinationAddressElement (m_protocol->GetDoFlag (), m_protocol->GetRfFlag (), dst, dst_seqno);
273  m_myPreq.push_back (preq);
274  SendMyPreq ();
275 }
276 void
278 {
280  if (m_preqTimer.IsRunning ())
281  {
282  return;
283  }
284  if (m_myPreq.size () == 0)
285  {
286  return;
287  }
288  //reschedule sending PREQ
290  m_preqTimer = Simulator::Schedule (m_protocol->GetPreqMinInterval (), &HwmpProtocolMac::SendMyPreq, this);
291  SendPreq (m_myPreq);
292  m_myPreq.clear ();
293 }
294 void
296 {
298  //Create packet
299  Ptr<Packet> packet = Create<Packet> ();
301  elements.AddInformationElement (Ptr<IePrep> (&prep));
302  packet->AddHeader (elements);
303  packet->AddHeader (GetWifiActionHeader ());
304  //create 802.11 header:
305  WifiMacHeader hdr;
306  hdr.SetAction ();
307  hdr.SetDsNotFrom ();
308  hdr.SetDsNotTo ();
309  hdr.SetAddr1 (receiver);
310  hdr.SetAddr2 (m_parent->GetAddress ());
311  hdr.SetAddr3 (m_protocol->GetAddress ());
312  //Send Management frame
313  m_stats.txPrep++;
314  m_stats.txMgt++;
315  m_stats.txMgtBytes += packet->GetSize ();
316  m_parent->SendManagementFrame (packet, hdr);
317 }
318 void
319 HwmpProtocolMac::ForwardPerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
320  Mac48Address> receivers)
321 {
323  Ptr<Packet> packet = Create<Packet> ();
324  Ptr<IePerr> perr = Create <IePerr> ();
326  for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i
327  != failedDestinations.end (); i++)
328  {
329  if (!perr->IsFull ())
330  {
331  perr->AddAddressUnit (*i);
332  }
333  else
334  {
335  elements.AddInformationElement (perr);
336  perr->ResetPerr ();
337  }
338  }
339  if (perr->GetNumOfDest () > 0)
340  {
341  elements.AddInformationElement (perr);
342  }
343  packet->AddHeader (elements);
344  packet->AddHeader (GetWifiActionHeader ());
345  //create 802.11 header:
346  WifiMacHeader hdr;
347  hdr.SetAction ();
348  hdr.SetDsNotFrom ();
349  hdr.SetDsNotTo ();
350  hdr.SetAddr2 (m_parent->GetAddress ());
351  hdr.SetAddr3 (m_protocol->GetAddress ());
352  if (receivers.size () >= m_protocol->GetUnicastPerrThreshold ())
353  {
354  receivers.clear ();
355  receivers.push_back (Mac48Address::GetBroadcast ());
356  }
357  //Send Management frame
358  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i++)
359  {
360  //
361  // 64-bit Intel valgrind complains about hdr.SetAddr1 (*i). It likes this
362  // just fine.
363  //
364  Mac48Address address = *i;
365  hdr.SetAddr1 (address);
366  m_stats.txPerr++;
367  m_stats.txMgt++;
368  m_stats.txMgtBytes += packet->GetSize ();
369  m_parent->SendManagementFrame (packet, hdr);
370  }
371 }
372 void
373 HwmpProtocolMac::InitiatePerr (std::vector<HwmpProtocol::FailedDestination> failedDestinations, std::vector<
374  Mac48Address> receivers)
375 {
376  //All duplicates in PERR are checked here, and there is no reason to
377  //check it at any athoer place
378  {
379  std::vector<Mac48Address>::const_iterator end = receivers.end ();
380  for (std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != end; i++)
381  {
382  bool should_add = true;
383  for (std::vector<Mac48Address>::const_iterator j = m_myPerr.receivers.begin (); j
384  != m_myPerr.receivers.end (); j++)
385  {
386  if ((*i) == (*j))
387  {
388  should_add = false;
389  }
390  }
391  if (should_add)
392  {
393  m_myPerr.receivers.push_back (*i);
394  }
395  }
396  }
397  {
398  std::vector<HwmpProtocol::FailedDestination>::const_iterator end = failedDestinations.end ();
399  for (std::vector<HwmpProtocol::FailedDestination>::const_iterator i = failedDestinations.begin (); i != end; i++)
400  {
401  bool should_add = true;
402  for (std::vector<HwmpProtocol::FailedDestination>::const_iterator j = m_myPerr.destinations.begin (); j
403  != m_myPerr.destinations.end (); j++)
404  {
405  if (((*i).destination == (*j).destination) && ((*j).seqnum > (*i).seqnum))
406  {
407  should_add = false;
408  }
409  }
410  if (should_add)
411  {
412  m_myPerr.destinations.push_back (*i);
413  }
414  }
415  }
416  SendMyPerr ();
417 }
418 void
420 {
422  if (m_perrTimer.IsRunning ())
423  {
424  return;
425  }
426  m_perrTimer = Simulator::Schedule (m_protocol->GetPerrMinInterval (), &HwmpProtocolMac::SendMyPerr, this);
428  m_myPerr.destinations.clear ();
429  m_myPerr.receivers.clear ();
430 }
431 uint32_t
433 {
434  return m_parent->GetLinkMetric (peerAddress);
435 }
436 uint16_t
438 {
439  return m_parent->GetFrequencyChannel ();
440 }
442  txPreq (0), rxPreq (0), txPrep (0), rxPrep (0), txPerr (0), rxPerr (0), txMgt (0), txMgtBytes (0),
443  rxMgt (0), rxMgtBytes (0), txData (0), txDataBytes (0), rxData (0), rxDataBytes (0)
444 {
445 }
446 void
447 HwmpProtocolMac::Statistics::Print (std::ostream & os) const
448 {
449  os << "<Statistics "
450  "txPreq= \"" << txPreq << "\"" << std::endl <<
451  "txPrep=\"" << txPrep << "\"" << std::endl <<
452  "txPerr=\"" << txPerr << "\"" << std::endl <<
453  "rxPreq=\"" << rxPreq << "\"" << std::endl <<
454  "rxPrep=\"" << rxPrep << "\"" << std::endl <<
455  "rxPerr=\"" << rxPerr << "\"" << std::endl <<
456  "txMgt=\"" << txMgt << "\"" << std::endl <<
457  "txMgtBytes=\"" << txMgtBytes << "\"" << std::endl <<
458  "rxMgt=\"" << rxMgt << "\"" << std::endl <<
459  "rxMgtBytes=\"" << rxMgtBytes << "\"" << std::endl <<
460  "txData=\"" << txData << "\"" << std::endl <<
461  "txDataBytes=\"" << txDataBytes << "\"" << std::endl <<
462  "rxData=\"" << rxData << "\"" << std::endl <<
463  "rxDataBytes=\"" << rxDataBytes << "\"/>" << std::endl;
464 }
465 void
466 HwmpProtocolMac::Report (std::ostream & os) const
467 {
468  os << "<HwmpProtocolMac" << std::endl <<
469  "address =\"" << m_parent->GetAddress () << "\">" << std::endl;
470  m_stats.Print (os);
471  os << "</HwmpProtocolMac>" << std::endl;
472 }
473 void
475 {
476  m_stats = Statistics ();
477 }
478 
479 int64_t
481 {
482  return m_protocol->AssignStreams (stream);
483 }
484 
485 
486 } // namespace dot11s
487 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetAction()
Set Type/Subtype values for an action header.
bool ReceiveAction(Ptr< Packet > packet, const WifiMacHeader &header)
Receive action management frame.
void SetPreqID(uint32_t id)
uint32_t GetLinkMetric(Mac48Address peerAddress) const
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
void SetParent(Ptr< MeshWifiInterfaceMac > parent)
Update beacon is empty, because HWMP does not know anything about beacons.
void SendMyPreq()
Sends one PREQ when PreqMinInterval after last PREQ expires (if any PREQ exists in rhe queue) ...
Hwmp tag implements interaction between HWMP protocol and MeshWifiMac.
Definition: hwmp-tag.h:48
void SetTTL(uint8_t ttl)
void SendPrep(IePrep prep, Mac48Address receiver)
Request a destination.
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:336
bool IsAction() const
Return true if the header is an Action header.
void RequestDestination(Mac48Address dest, uint32_t originator_seqno, uint32_t dst_seqno)
Request a destination.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
Mac48Address GetAddr4(void) const
Return the address in the Address 4 field.
#define NS_ASSERT(condition)
Definition: assert.h:64
See 7.3.2.97 of 802.11s draft 2.07.
uint32_t GetSize(void) const
Definition: packet.h:650
std::vector< IePreq > m_myPreq
void SetAction(enum CategoryValue type, ActionValue action)
Set action for this Action header.
Definition: mgt-headers.cc:482
bool IsRunning(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:59
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
void SetMeshSeqno(uint32_t seqno)
CategoryValue GetCategory()
Return the category value.
Definition: mgt-headers.cc:513
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
enum PathSelectionActionValue pathSelection
Definition: mgt-headers.h:414
uint32_t GetSeqno()
Definition: hwmp-tag.cc:82
void SetTtl(uint8_t ttl)
Definition: hwmp-tag.cc:52
bool AddInformationElement(Ptr< WifiInformationElement > element)
add an IE, if maxSize has exceeded, returns false
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void SetLifetime(uint32_t lifetime)
void SendPreq(IePreq preq)
Request a destination.
Mac48Address GetAddress()
Definition: hwmp-tag.cc:46
void SetMeshTtl(uint8_t TTL)
Iterator End()
Returns End of the vector.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:863
static WifiActionHeader GetWifiActionHeader()
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
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.
See 7.3.2.96 of 802.11s draft 2.07.
std::vector< Ptr< WifiInformationElement > >::iterator Iterator
As soon as this is a vector, we define an Iterator.
#define IE11S_PERR
#define IE11S_PREQ
Ptr< MeshWifiInterfaceMac > m_parent
#define IE11S_PREP
static Mac48Address GetBroadcast(void)
std::vector< Mac48Address > receivers
void SetOriginatorAddress(Mac48Address originator_address)
HwmpProtocolMac(uint32_t, Ptr< HwmpProtocol >)
Iterator Begin()
Returns Begin of the vector.
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
an EUI-48 address
Definition: mac48-address.h:41
std::vector< HwmpProtocol::FailedDestination > destinations
#define IE11S_RANN
bool UpdateOutcomingFrame(Ptr< Packet > packet, WifiMacHeader &header, Mac48Address from, Mac48Address to)
Update beacon is empty, because HWMP does not know anything about beacons.
Ptr< HwmpProtocol > m_protocol
uint8_t GetTtl()
Definition: hwmp-tag.cc:58
int64_t AssignStreams(int64_t stream)
Update beacon is empty, because HWMP does not know anything about beacons.
bool ReceiveData(Ptr< Packet > packet, const WifiMacHeader &header)
Receive data frame.
NS_LOG_COMPONENT_DEFINE("HwmpProtocolMac")
bool IsData(void) const
Return true if the Type is DATA.
#define NS_LOG_WARN(msg)
Definition: log.h:280
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
void ForwardPerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Request a destination.
typedef for union of different ActionValues
Definition: mgt-headers.h:410
bool Receive(Ptr< Packet > packet, const WifiMacHeader &header)
Update beacon is empty, because HWMP does not know anything about beacons.
Mesh Control field, see IEEE 802.11s draft 3.0 section 7.1.3.5b.
void Report(std::ostream &) const
Report statistics.
void InitiatePerr(std::vector< HwmpProtocol::FailedDestination > destinations, std::vector< Mac48Address > receivers)
Request a destination.
tuple address
Definition: first.py:37
void SetSeqno(uint32_t seqno)
Definition: hwmp-tag.cc:76
void SetHopcount(uint8_t hopcount)
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
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.