A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("OcbWifiMac");
36 
37 namespace ns3 {
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 
57  // use WaveMacLow instead of MacLow
58  m_low = CreateObject<WaveMacLow> ();
61  m_dca->SetLow (m_low);
62  for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
63  {
64  i->second->SetLow (m_low);
65  }
66 
67  // Let the lower layers know that we are acting as an OCB node
69  // BSSID is still needed in the low part of MAC
71 }
72 
74 {
75  NS_LOG_FUNCTION (this);
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION (this << vsc << peer << oi);
82  WifiMacHeader hdr;
83  hdr.SetAction ();
84  hdr.SetAddr1 (peer);
85  hdr.SetAddr2 (GetAddress ());
87  hdr.SetDsNotFrom ();
88  hdr.SetDsNotTo ();
91  vsc->AddHeader (vsa);
92 
93  if (m_qosSupported)
94  {
95  uint8_t tid = QosUtilsGetTidForPacket (vsc);
96  tid = tid > 7 ? 0 : tid;
97  m_edca[QosUtilsMapTidToAc (tid)]->Queue (vsc, hdr);
98  }
99  else
100  {
101  m_dca->Queue (vsc, hdr);
102  }
103 }
104 
105 void
107 {
108  NS_LOG_FUNCTION (this << oi << &cb);
110 }
111 
112 void
114 {
115  NS_LOG_FUNCTION (this << oi);
117 }
118 
119 void
121 {
122  NS_LOG_WARN ("in OCB mode we should not call SetSsid");
123 }
124 
125 Ssid
127 {
128  NS_FATAL_ERROR ("in OCB mode we should not call GetSsid");
129  // we really do not want to return ssid, however we have to provide
130  return RegularWifiMac::GetSsid ();
131 }
132 
133 
134 void
136 {
137  NS_FATAL_ERROR ("in OCB mode we should not call SetBsid");
138 }
139 
142 {
143  NS_FATAL_ERROR ("in OCB mode we should not call GetBssid");
144  return WILDCARD_BSSID;
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION (this << &linkUp);
152 
153  // The approach taken here is that, from the point of view of a STA
154  // in OCB mode, the link is always up, so we immediately invoke the
155  // callback if one is set
156  linkUp ();
157 }
158 
159 void
161 {
162  NS_LOG_FUNCTION (this << &linkDown);
164  NS_LOG_WARN ("in OCB mode the like will never down, so linkDown will never be called");
165 }
166 
167 void
169 {
170  NS_LOG_FUNCTION (this << packet << to);
171  if (m_stationManager->IsBrandNew (to))
172  {
173  // In ocb mode, we assume that every destination supports all
174  // the rates we support.
175  for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
176  {
177  m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
178  }
179  m_stationManager->RecordDisassociated (to);
180  }
181 
182  WifiMacHeader hdr;
183 
184  // If we are not a QoS STA then we definitely want to use AC_BE to
185  // transmit the packet. A TID of zero will map to AC_BE (through \c
186  // QosUtilsMapTidToAc()), so we use that as our default here.
187  uint8_t tid = 0;
188 
189  if (m_qosSupported)
190  {
193  hdr.SetQosNoEosp ();
194  hdr.SetQosNoAmsdu ();
195  // About transmission of multiple frames,
196  // in Ad-hoc mode TXOP is not supported for now, so TxopLimit=0;
197  // however in OCB mode, 802.11p do not allow transmit multiple frames
198  // so TxopLimit must equal 0
199  hdr.SetQosTxopLimit (0);
200 
201  // Fill in the QoS control field in the MAC header
202  tid = QosUtilsGetTidForPacket (packet);
203  // Any value greater than 7 is invalid and likely indicates that
204  // the packet had no QoS tag, so we revert to zero, which'll
205  // mean that AC_BE is used.
206  if (tid >= 7)
207  {
208  tid = 0;
209  }
210  hdr.SetQosTid (tid);
211  }
212  else
213  {
214  hdr.SetTypeData ();
215  }
216 
217  hdr.SetAddr1 (to);
218  hdr.SetAddr2 (GetAddress ());
219  hdr.SetAddr3 (WILDCARD_BSSID);
220  hdr.SetDsNotFrom ();
221  hdr.SetDsNotTo ();
222 
223  if (m_qosSupported)
224  {
225  // Sanity check that the TID is valid
226  NS_ASSERT (tid < 8);
227  m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
228  }
229  else
230  {
231  m_dca->Queue (packet, hdr);
232  }
233 }
234 
235 /*
236  * see 802.11p-2010 chapter 11.19
237  * here we only care about data packet and vsa management frame
238  */
239 void
241 {
242  NS_LOG_FUNCTION (this << packet << hdr);
243  NS_ASSERT (!hdr->IsCtl ());
244  NS_ASSERT (hdr->GetAddr3 () == WILDCARD_BSSID);
245 
246  Mac48Address from = hdr->GetAddr2 ();
247  Mac48Address to = hdr->GetAddr1 ();
248 
249  if (hdr->IsData ())
250  {
251  if (hdr->IsQosData () && hdr->IsQosAmsdu ())
252  {
253  NS_LOG_DEBUG ("Received A-MSDU from" << from);
254  DeaggregateAmsduAndForward (packet, hdr);
255  }
256  else
257  {
258  ForwardUp (packet, from, to);
259  }
260  return;
261  }
262 
263  // why put check here, not before "if (hdr->IsData ())" ?
264  // because WifiNetDevice::ForwardUp needs to m_promiscRx data packet
265  // and will filter data packet for itself
266  // so we need to filter management frame
267  if (to != GetAddress () && !to.IsGroup ())
268  {
269  NS_LOG_LOGIC ("the management frame is not for us");
270  NotifyRxDrop (packet);
271  return;
272  }
273 
274  if (hdr->IsMgt () && hdr->IsAction ())
275  {
276  // yes, we only care about VendorSpecificAction frame in OCB mode
277  // other management frames will be handled by RegularWifiMac::Receive
279  packet->PeekHeader (vsaHdr);
280  if (vsaHdr.GetCategory () == CATEGORY_OF_VSA)
281  {
283  packet->RemoveHeader (vsa);
286 
287  if (cb.IsNull ())
288  {
289  NS_LOG_DEBUG ("cannot find VscCallback for OrganizationIdentifier=" << oi);
290  return;
291  }
292  bool succeed = cb (this, oi,packet, from);
293 
294  if (!succeed)
295  {
296  NS_LOG_DEBUG ("vsc callback could not handle the packet successfully");
297  }
298 
299  return;
300  }
301  }
302  // Invoke the receive handler of our parent class to deal with any
303  // other frames. Specifically, this will handle Block Ack-related
304  // Management Action frames.
305  RegularWifiMac::Receive (packet, hdr);
306 }
307 
308 void
309 OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum AcIndex ac)
310 {
311  Ptr<Dcf> dcf;
312  switch (ac)
313  {
314  case AC_VO:
316  dcf->SetMinCw ((cwmin + 1) / 4 - 1);
317  dcf->SetMaxCw ((cwmin + 1) / 2 - 1);
318  dcf->SetAifsn (aifsn);
319  break;
320  case AC_VI:
322  dcf->SetMinCw ((cwmin + 1) / 2 - 1);
323  dcf->SetMaxCw (cwmin);
324  dcf->SetAifsn (aifsn);
325  break;
326  case AC_BE:
328  dcf->SetMinCw (cwmin);
329  dcf->SetMaxCw (cwmax);
330  dcf->SetAifsn (aifsn);
331  break;
332  case AC_BK:
334  dcf->SetMinCw (cwmin);
335  dcf->SetMaxCw (cwmax);
336  dcf->SetAifsn (aifsn);
337  break;
338  case AC_BE_NQOS:
340  dcf->SetMinCw (cwmin);
341  dcf->SetMaxCw (cwmax);
342  dcf->SetAifsn (aifsn);
343  break;
344  case AC_UNDEF:
345  NS_FATAL_ERROR ("I don't know what to do with this");
346  break;
347  }
348 }
349 
350 void
352 {
354  || (standard == WIFI_PHY_STANDARD_80211a));
355 
356  uint32_t cwmin = 15;
357  uint32_t cwmax = 1023;
358 
359  // The special value of AC_BE_NQOS which exists in the Access
360  // Category enumeration allows us to configure plain old DCF.
361  ConfigureEdca (cwmin, cwmax, 2, AC_BE_NQOS);
362 
363  // Now we configure the EDCA functions
364  // see IEEE802.11p-2010 section 7.3.2.29
365  // Wave CCH and SCHs set default 802.11p EDCA
366  ConfigureEdca (cwmin, cwmax, 2, AC_VO);
367  ConfigureEdca (cwmin, cwmax, 3, AC_VI);
368  ConfigureEdca (cwmin, cwmax, 6, AC_BE);
369  ConfigureEdca (cwmin, cwmax, 9, AC_BK);
370 
371 }
372 } // 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.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
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:920
void RegisterVscCallback(OrganizationIdentifier oi, VscCallback cb)
virtual void FinishConfigureStandard(enum WifiPhyStandard standard)
virtual uint32_t GetNModes(void) const =0
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
virtual ~OcbWifiMac(void)
Definition: ocb-wifi-mac.cc:73
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:1014
void SetupLowListener(Ptr< MacLow > low)
Set up listener for MacLow events.
Definition: dcf-manager.cc:306
#define NS_ASSERT(condition)
Definition: assert.h:64
void SendVsc(Ptr< Packet > vsc, Mac48Address peer, OrganizationIdentifier oi)
Definition: ocb-wifi-mac.cc:79
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
VendorSpecificContentManager m_vscManager
Definition: ocb-wifi-mac.h:137
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 NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:270
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)
Ptr< WifiPhy > m_phy
Wifi PHY.
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...
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:27
static Mac48Address GetBroadcast(void)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
uint8_t GetCategory() const
the category field shall be CATEGORY_OF_VSA
bool IsMgt(void) const
Return true if the Type is Management.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
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)
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:41
virtual WifiMode GetMode(uint32_t mode) const =0
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
virtual void SetLinkDownCallback(Callback< void > linkDown)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
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)
Definition: log.h:280
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
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.
NS_LOG_COMPONENT_DEFINE("OcbWifiMac")
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.
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
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)
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.