A Discrete-Event Network Simulator
API
ocb-wifi-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 INRIA
4  * Copyright (c) 2013 Dalian University of Technology
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Junling Bu <linlinjavaer@gmail.com>
21  */
22 #include "ns3/pointer.h"
23 #include "ns3/log.h"
24 #include "ns3/string.h"
25 #include "ns3/qos-tag.h"
26 #include "ns3/mac-low.h"
27 #include "ns3/dcf-manager.h"
28 #include "ns3/mac-rx-middle.h"
29 #include "ns3/mgt-headers.h"
30 #include "wave-mac-low.h"
31 #include "ocb-wifi-mac.h"
32 #include "vendor-specific-action.h"
33 #include "higher-tx-tag.h"
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("OcbWifiMac");
38 
39 NS_OBJECT_ENSURE_REGISTERED (OcbWifiMac);
40 
42 
43 TypeId
45 {
46  static TypeId tid = TypeId ("ns3::OcbWifiMac")
48  .AddConstructor<OcbWifiMac> ()
49  ;
50  return tid;
51 }
52 
54 {
55  NS_LOG_FUNCTION (this);
56  // Let the lower layers know that we are acting as an OCB node
58  // BSSID is still needed in the low part of MAC
59  RegularWifiMac::SetBssid (WILDCARD_BSSID);
60 }
61 
63 {
64  NS_LOG_FUNCTION (this);
65 }
66 
67 void
69 {
70  NS_LOG_FUNCTION (this << vsc << peer << oi);
71  WifiMacHeader hdr;
72  hdr.SetAction ();
73  hdr.SetAddr1 (peer);
74  hdr.SetAddr2 (GetAddress ());
75  hdr.SetAddr3 (WILDCARD_BSSID);
76  hdr.SetDsNotFrom ();
77  hdr.SetDsNotTo ();
80  vsc->AddHeader (vsa);
81 
82  if (m_qosSupported)
83  {
84  uint8_t tid = QosUtilsGetTidForPacket (vsc);
85  tid = tid > 7 ? 0 : tid;
86  m_edca[QosUtilsMapTidToAc (tid)]->Queue (vsc, hdr);
87  }
88  else
89  {
90  m_dca->Queue (vsc, hdr);
91  }
92 }
93 
94 void
96 {
97  NS_LOG_FUNCTION (this << oi << &cb);
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION (this << oi);
106 }
107 
108 void
110 {
111  NS_LOG_WARN ("in OCB mode we should not call SetSsid");
112 }
113 
114 Ssid
116 {
117  NS_LOG_WARN ("in OCB mode we should not call GetSsid");
118  // we really do not want to return ssid, however we have to provide
119  return RegularWifiMac::GetSsid ();
120 }
121 
122 
123 void
125 {
126  NS_LOG_WARN ("in OCB mode we should not call SetBsid");
127 }
128 
131 {
132  NS_LOG_WARN ("in OCB mode we should not call GetBssid");
133  return WILDCARD_BSSID;
134 }
135 
136 void
138 {
139  NS_LOG_FUNCTION (this << &linkUp);
141 
142  // The approach taken here is that, from the point of view of a STA
143  // in OCB mode, the link is always up, so we immediately invoke the
144  // callback if one is set
145  linkUp ();
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this << &linkDown);
153  NS_LOG_WARN ("in OCB mode the like will never down, so linkDown will never be called");
154 }
155 
156 void
158 {
159  NS_LOG_FUNCTION (this << packet << to);
160  if (m_stationManager->IsBrandNew (to))
161  {
162  // In ocb mode, we assume that every destination supports all
163  // the rates we support.
164  m_stationManager->AddAllSupportedModes (to);
165  m_stationManager->RecordDisassociated (to);
166  }
167 
168  WifiMacHeader hdr;
169 
170  // If we are not a QoS STA then we definitely want to use AC_BE to
171  // transmit the packet. A TID of zero will map to AC_BE (through \c
172  // QosUtilsMapTidToAc()), so we use that as our default here.
173  uint8_t tid = 0;
174 
175  if (m_qosSupported)
176  {
179  hdr.SetQosNoEosp ();
180  hdr.SetQosNoAmsdu ();
181  // About transmission of multiple frames,
182  // in Ad-hoc mode TXOP is not supported for now, so TxopLimit=0;
183  // however in OCB mode, 802.11p do not allow transmit multiple frames
184  // so TxopLimit must equal 0
185  hdr.SetQosTxopLimit (0);
186 
187  // Fill in the QoS control field in the MAC header
188  tid = QosUtilsGetTidForPacket (packet);
189  // Any value greater than 7 is invalid and likely indicates that
190  // the packet had no QoS tag, so we revert to zero, which'll
191  // mean that AC_BE is used.
192  if (tid >= 7)
193  {
194  tid = 0;
195  }
196  hdr.SetQosTid (tid);
197  }
198  else
199  {
200  hdr.SetTypeData ();
201  }
202 
203  hdr.SetAddr1 (to);
204  hdr.SetAddr2 (GetAddress ());
205  hdr.SetAddr3 (WILDCARD_BSSID);
206  hdr.SetDsNotFrom ();
207  hdr.SetDsNotTo ();
208 
209  if (m_qosSupported)
210  {
211  // Sanity check that the TID is valid
212  NS_ASSERT (tid < 8);
213  m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
214  }
215  else
216  {
217  m_dca->Queue (packet, hdr);
218  }
219 }
220 
221 /*
222  * see 802.11p-2010 chapter 11.19
223  * here we only care about data packet and vsa management frame
224  */
225 void
227 {
228  NS_LOG_FUNCTION (this << packet << hdr);
229  NS_ASSERT (!hdr->IsCtl ());
230  NS_ASSERT (hdr->GetAddr3 () == WILDCARD_BSSID);
231 
232  Mac48Address from = hdr->GetAddr2 ();
233  Mac48Address to = hdr->GetAddr1 ();
234 
235  if (hdr->IsData ())
236  {
237  if (hdr->IsQosData () && hdr->IsQosAmsdu ())
238  {
239  NS_LOG_DEBUG ("Received A-MSDU from" << from);
240  DeaggregateAmsduAndForward (packet, hdr);
241  }
242  else
243  {
244  ForwardUp (packet, from, to);
245  }
246  return;
247  }
248 
249  // why put check here, not before "if (hdr->IsData ())" ?
250  // because WifiNetDevice::ForwardUp needs to m_promiscRx data packet
251  // and will filter data packet for itself
252  // so we need to filter management frame
253  if (to != GetAddress () && !to.IsGroup ())
254  {
255  NS_LOG_LOGIC ("the management frame is not for us");
256  NotifyRxDrop (packet);
257  return;
258  }
259 
260  if (hdr->IsMgt () && hdr->IsAction ())
261  {
262  // yes, we only care about VendorSpecificAction frame in OCB mode
263  // other management frames will be handled by RegularWifiMac::Receive
265  packet->PeekHeader (vsaHdr);
266  if (vsaHdr.GetCategory () == CATEGORY_OF_VSA)
267  {
269  packet->RemoveHeader (vsa);
272 
273  if (cb.IsNull ())
274  {
275  NS_LOG_DEBUG ("cannot find VscCallback for OrganizationIdentifier=" << oi);
276  return;
277  }
278  bool succeed = cb (this, oi,packet, from);
279 
280  if (!succeed)
281  {
282  NS_LOG_DEBUG ("vsc callback could not handle the packet successfully");
283  }
284 
285  return;
286  }
287  }
288  // Invoke the receive handler of our parent class to deal with any
289  // other frames. Specifically, this will handle Block Ack-related
290  // Management Action frames.
291  RegularWifiMac::Receive (packet, hdr);
292 }
293 
294 void
295 OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum AcIndex ac)
296 {
297  NS_LOG_FUNCTION (this << cwmin << cwmax << aifsn << ac);
298  Ptr<Dcf> dcf;
299  switch (ac)
300  {
301  case AC_VO:
303  dcf->SetMinCw ((cwmin + 1) / 4 - 1);
304  dcf->SetMaxCw ((cwmin + 1) / 2 - 1);
305  dcf->SetAifsn (aifsn);
306  break;
307  case AC_VI:
309  dcf->SetMinCw ((cwmin + 1) / 2 - 1);
310  dcf->SetMaxCw (cwmin);
311  dcf->SetAifsn (aifsn);
312  break;
313  case AC_BE:
315  dcf->SetMinCw (cwmin);
316  dcf->SetMaxCw (cwmax);
317  dcf->SetAifsn (aifsn);
318  break;
319  case AC_BK:
321  dcf->SetMinCw (cwmin);
322  dcf->SetMaxCw (cwmax);
323  dcf->SetAifsn (aifsn);
324  break;
325  case AC_BE_NQOS:
327  dcf->SetMinCw (cwmin);
328  dcf->SetMaxCw (cwmax);
329  dcf->SetAifsn (aifsn);
330  break;
331  case AC_UNDEF:
332  NS_FATAL_ERROR ("I don't know what to do with this");
333  break;
334  }
335 }
336 
337 void
339 {
340  NS_LOG_FUNCTION (this << standard);
342  || (standard == WIFI_PHY_STANDARD_80211a));
343 
344  uint32_t cwmin = 15;
345  uint32_t cwmax = 1023;
346 
347  // The special value of AC_BE_NQOS which exists in the Access
348  // Category enumeration allows us to configure plain old DCF.
349  ConfigureEdca (cwmin, cwmax, 2, AC_BE_NQOS);
350 
351  // Now we configure the EDCA functions
352  // see IEEE802.11p-2010 section 7.3.2.29
353  // Wave CCH and SCHs set default 802.11p EDCA
354  ConfigureEdca (cwmin, cwmax, 2, AC_VO);
355  ConfigureEdca (cwmin, cwmax, 3, AC_VI);
356  ConfigureEdca (cwmin, cwmax, 6, AC_BE);
357  ConfigureEdca (cwmin, cwmax, 9, AC_BK);
358 }
359 
360 
361 void
363 {
364  NS_LOG_FUNCTION (this);
366  m_low->NotifySleepNow ();
367 }
368 
369 void
371 {
372  NS_LOG_FUNCTION (this);
373  // wake-up operation is not required in m_low object
375 }
376 
377 void
379 {
380  NS_LOG_FUNCTION (this << duration);
382 }
383 
384 void
386 {
387  NS_LOG_FUNCTION (this << ac);
388  Ptr<EdcaTxopN> queue = m_edca.find (ac)->second;
389  NS_ASSERT (queue != 0);
390  // reset and flush queue
391  queue->NotifyChannelSwitching ();
392 }
393 
394 void
396 {
397  NS_LOG_FUNCTION (this);
398  // The switching event is used to notify MAC entity reset its operation.
400  m_low->NotifySwitchingStartNow (Time (0));
401 }
402 
403 void
405 {
406  NS_LOG_FUNCTION (this << device);
407  // To extend current OcbWifiMac for WAVE 1609.4, we shall use WaveMacLow instead of MacLow
408  m_low = CreateObject<WaveMacLow> ();
409  (DynamicCast<WaveMacLow> (m_low))->SetWaveNetDevice (device);
410  m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
412  m_dca->SetLow (m_low);
413  for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
414  {
415  i->second->SetLow (m_low);
416  i->second->CompleteConfig ();
417  }
418 }
419 } // 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.
void NotifyWakeupNow(void)
Notify the DCF that the device has been resumed from sleep mode.
Definition: dcf-manager.cc:801
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void ConfigureEdca(uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum AcIndex ac)
void SetQosAckPolicy(enum QosAckPolicy policy)
Set the QoS ACK policy in the QoS control field.
Callback template class.
Definition: callback.h:978
void RegisterVscCallback(OrganizationIdentifier oi, VscCallback cb)
virtual void FinishConfigureStandard(enum WifiPhyStandard standard)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
virtual ~OcbWifiMac(void)
Definition: ocb-wifi-mac.cc:62
bool IsAction() const
Return true if the header is an Action header.
EdcaQueues m_edca
This is a map from Access Category index to the corresponding channel access function.
Mac48Address GetAddr3(void) const
Return the address in the Address 3 field.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1072
void SetupLowListener(Ptr< MacLow > low)
Set up listener for MacLow events.
Definition: dcf-manager.cc:338
void CancleTx(enum AcIndex ac)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void SendVsc(Ptr< Packet > vsc, Mac48Address peer, OrganizationIdentifier oi)
Definition: ocb-wifi-mac.cc:68
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
VendorSpecificContentManager m_vscManager
Definition: ocb-wifi-mac.h:178
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
void EnableForWave(Ptr< WaveNetDevice > device)
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:274
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
See IEEE 802.11-2007 chapter 7.3.1.11 and 7.4.5 also IEEE 802.11p-2010 chapter 7.4.5 Although WifiActionHeader has been defined in wifi mgt-header.h/.cc, it is not a good way to inherit from it or add vendor specific action support.
static const Mac48Address WILDCARD_BSSID
Definition: ocb-wifi-mac.cc:41
virtual void DeaggregateAmsduAndForward(Ptr< Packet > aggregatedPacket, const WifiMacHeader *hdr)
This method can be called to de-aggregate an A-MSDU and forward the constituent packets up the stack...
virtual void SetLinkDownCallback(Callback< void > linkDown)
bool IsCtl(void) const
Return true if the Type is Control.
virtual Ssid GetSsid(void) const
Video.
Definition: qos-utils.h:42
Voice.
Definition: qos-utils.h:44
Best Effort.
Definition: qos-utils.h:38
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
MacRxMiddle * m_rxMiddle
RX middle (de-fragmentation etc.)
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
If a qos tag is attached to the packet, returns a value < 8.
Definition: qos-utils.cc:60
void DeregisterVscCallback(OrganizationIdentifier &oi)
virtual void SetLinkUpCallback(Callback< void > linkUp)
SetLinkUpCallback and SetLinkDownCallback will be overloaded In OCB mode, stations can send packets d...
virtual void SetBssid(Mac48Address bssid)
Ptr< EdcaTxopN > GetVOQueue(void) const
Accessor for the AC_VO channel access function.
Background.
Definition: qos-utils.h:40
void ForwardUp(Ptr< Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
base class for all MAC-level wifi objects.
virtual Ssid GetSsid(void) const
bool m_qosSupported
This Boolean is set true iff this WifiMac is to model 802.11e/WMM style Quality of Service...
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Ptr< DcaTxop > m_dca
This holds a pointer to the DCF instance for this WifiMac - used for transmission of frames to non-Qo...
Ptr< EdcaTxopN > GetBEQueue(void) const
Accessor for the AC_BE channel access function.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
static TypeId GetTypeId(void)
Definition: ocb-wifi-mac.cc:44
void SetOrganizationIdentifier(OrganizationIdentifier oi)
the organization identifier is a public organizationally unique identifier assigned by the IEEE...
Ptr< DcaTxop > GetDcaTxop(void) const
Accessor for the DCF object.
void Suspend(void)
To support MAC extension for multiple channel operation, Suspend the activity in current MAC entity...
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:27
uint8_t GetCategory(void) const
the category field shall be CATEGORY_OF_VSA
void MakeVirtualBusy(Time duration)
static Mac48Address GetBroadcast(void)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
Definition: edca-txop-n.cc:663
bool IsMgt(void) const
Return true if the Type is Management.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Ptr< MacLow > m_low
MacLow (RTS, CTS, DATA, ACK etc.)
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
void RemoveReceiveVscCallback(OrganizationIdentifier oi)
Ptr< EdcaTxopN > GetVIQueue(void) const
Accessor for the AC_VI channel access function.
virtual void SetLinkUpCallback(Callback< void > linkUp)
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsGroup(void) const
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
DcfManager * m_dcfManager
DCF manager (access to channel)
an EUI-48 address
Definition: mac48-address.h:43
virtual void SetLinkDownCallback(Callback< void > linkDown)
void NotifyMaybeCcaBusyStartNow(Time duration)
Definition: dcf-manager.cc:711
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:37
virtual void SetSsid(Ssid ssid)
VscCallback FindVscCallback(OrganizationIdentifier &oi)
static const uint8_t CATEGORY_OF_VSA
see IEEE 802.11-2007 chapter 7.3.1.11 Table 7-24—Category values
void SetQosTxopLimit(uint8_t txop)
Set TXOP limit in the QoS control field.
Ptr< EdcaTxopN > GetBKQueue(void) const
Accessor for the AC_BK channel access function.
bool IsData(void) const
Return true if the Type is DATA.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS DATA...
virtual Mac48Address GetBssid(void) const
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
virtual Mac48Address GetAddress(void) const
void SetTypeData(void)
Set Type/Subtype values for a data packet with no subtype equal to 0.
Total number of ACs.
Definition: qos-utils.h:47
void SetQosNoAmsdu(void)
Set that A-MSDU is not present.
void NotifySleepNow(void)
Notify the DCF that the device has been put in sleep mode.
Definition: dcf-manager.cc:782
virtual void SetBssid(Mac48Address bssid)
void SetType(enum WifiMacType type)
Set Type/Subtype values with the correct values depending on the given type.
OrganizationIdentifier GetOrganizationIdentifier(void) const
virtual void Enqueue(Ptr< const Packet > packet, Mac48Address to)
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
Ptr< WifiRemoteStationManager > m_stationManager
Remote station manager (rate control, RTS/CTS/fragmentation thresholds etc.)
void SetQosNoEosp()
Un-set the end of service period (EOSP) bit in the QoS control field.
void Reset(void)
To support MAC extension for multiple channel operation, Reset current MAC entity and flush its inter...
void NotifySwitchingStartNow(Time duration)
Definition: dcf-manager.cc:722
a unique identifier for an interface.
Definition: type-id.h:51
void Resume(void)
To support MAC extension for multiple channel operation, Resume the activity of suspended MAC entity...
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:35
void AddReceiveVscCallback(OrganizationIdentifier oi, VscCallback cb)
Definition: ocb-wifi-mac.cc:95
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.