A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
adhoc-wifi-mac.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006, 2009 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
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  * Author: Mirko Banchi <mk.banchi@gmail.com>
21  */
22 #include "adhoc-wifi-mac.h"
23 
24 #include "ns3/pointer.h"
25 #include "ns3/log.h"
26 #include "ns3/string.h"
27 #include "ns3/boolean.h"
28 #include "ns3/trace-source-accessor.h"
29 
30 #include "qos-tag.h"
31 #include "mac-low.h"
32 #include "dcf-manager.h"
33 #include "mac-rx-middle.h"
34 #include "mac-tx-middle.h"
35 #include "msdu-aggregator.h"
36 #include "amsdu-subframe-header.h"
37 #include "mgt-headers.h"
38 
39 NS_LOG_COMPONENT_DEFINE ("AdhocWifiMac");
40 
41 namespace ns3 {
42 
43 NS_OBJECT_ENSURE_REGISTERED (AdhocWifiMac);
44 
45 TypeId
46 AdhocWifiMac::GetTypeId (void)
47 {
48  static TypeId tid = TypeId ("ns3::AdhocWifiMac")
49  .SetParent<RegularWifiMac> ()
50  .AddConstructor<AdhocWifiMac> ()
51  ;
52  return tid;
53 }
54 
55 AdhocWifiMac::AdhocWifiMac ()
56 {
57  NS_LOG_FUNCTION (this);
58 
59  // Let the lower layers know that we are acting in an IBSS
60  SetTypeOfStation (ADHOC_STA);
61 }
62 
63 AdhocWifiMac::~AdhocWifiMac ()
64 {
65  NS_LOG_FUNCTION (this);
66 }
67 
68 void
70 {
71  NS_LOG_FUNCTION (this << address);
72  // In an IBSS, the BSSID is supposed to be generated per Section
73  // 11.1.3 of IEEE 802.11. We don't currently do this - instead we
74  // make an IBSS STA a bit like an AP, with the BSSID for frames
75  // transmitted by each STA set to that STA's address.
76  //
77  // This is why we're overriding this method.
79  RegularWifiMac::SetBssid (address);
80 }
81 
82 void
84 {
85  NS_LOG_FUNCTION (this << packet << to);
86  if (m_stationManager->IsBrandNew (to))
87  {
88  // In ad hoc mode, we assume that every destination supports all
89  // the rates we support.
90  for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
91  {
92  m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
93  }
94  m_stationManager->RecordDisassociated (to);
95  }
96 
97  WifiMacHeader hdr;
98 
99  // If we are not a QoS STA then we definitely want to use AC_BE to
100  // transmit the packet. A TID of zero will map to AC_BE (through \c
101  // QosUtilsMapTidToAc()), so we use that as our default here.
102  uint8_t tid = 0;
103 
104  // For now, a STA that supports QoS does not support non-QoS
105  // associations, and vice versa. In future the STA model should fall
106  // back to non-QoS if talking to a peer that is also non-QoS. At
107  // that point there will need to be per-station QoS state maintained
108  // by the association state machine, and consulted here.
109  if (m_qosSupported)
110  {
111  hdr.SetType (WIFI_MAC_QOSDATA);
112  hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
113  hdr.SetQosNoEosp ();
114  hdr.SetQosNoAmsdu ();
115  // Transmission of multiple frames in the same TXOP is not
116  // supported for now
117  hdr.SetQosTxopLimit (0);
118 
119  // Fill in the QoS control field in the MAC header
120  tid = QosUtilsGetTidForPacket (packet);
121  // Any value greater than 7 is invalid and likely indicates that
122  // the packet had no QoS tag, so we revert to zero, which'll
123  // mean that AC_BE is used.
124  if (tid >= 7)
125  {
126  tid = 0;
127  }
128  hdr.SetQosTid (tid);
129  }
130  else
131  {
132  hdr.SetTypeData ();
133  }
134 
135  hdr.SetAddr1 (to);
136  hdr.SetAddr2 (m_low->GetAddress ());
137  hdr.SetAddr3 (GetBssid ());
138  hdr.SetDsNotFrom ();
139  hdr.SetDsNotTo ();
140 
141  if (m_qosSupported)
142  {
143  // Sanity check that the TID is valid
144  NS_ASSERT (tid < 8);
145  m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
146  }
147  else
148  {
149  m_dca->Queue (packet, hdr);
150  }
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << &linkUp);
158 
159  // The approach taken here is that, from the point of view of a STA
160  // in IBSS mode, the link is always up, so we immediately invoke the
161  // callback if one is set
162  linkUp ();
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this << packet << hdr);
169  NS_ASSERT (!hdr->IsCtl ());
170  Mac48Address from = hdr->GetAddr2 ();
171  Mac48Address to = hdr->GetAddr1 ();
172  if (hdr->IsData ())
173  {
174  if (hdr->IsQosData () && hdr->IsQosAmsdu ())
175  {
176  NS_LOG_DEBUG ("Received A-MSDU from" << from);
177  DeaggregateAmsduAndForward (packet, hdr);
178  }
179  else
180  {
181  ForwardUp (packet, from, to);
182  }
183  return;
184  }
185 
186  // Invoke the receive handler of our parent class to deal with any
187  // other frames. Specifically, this will handle Block Ack-related
188  // Management Action frames.
189  RegularWifiMac::Receive (packet, hdr);
190 }
191 
192 } // namespace ns3
virtual void SetLinkUpCallback(Callback< void > linkUp)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual uint32_t GetNModes(void) const =0
virtual void Enqueue(Ptr< const Packet > packet, Mac48Address to)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void DeaggregateAmsduAndForward(Ptr< Packet > aggregatedPacket, const WifiMacHeader *hdr)
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
virtual void Receive(Ptr< Packet > packet, const WifiMacHeader *hdr)
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
Definition: qos-utils.cc:60
virtual void SetBssid(Mac48Address bssid)
virtual void SetAddress(Mac48Address address)
void SetTypeOfStation(TypeOfStation type)
Ptr< DcaTxop > m_dca
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Definition: qos-utils.cc:27
virtual void SetAddress(Mac48Address address)
virtual void SetLinkUpCallback(Callback< void > linkUp)
an EUI-48 address
Definition: mac48-address.h:41
virtual WifiMode GetMode(uint32_t mode) const =0
virtual Mac48Address GetBssid(void) const
#define NS_LOG_DEBUG(msg)
Definition: log.h:255