1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/llc-snap-header.h"
22 #include "ns3/channel.h"
23 #include "ns3/pointer.h"
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 #include "ns3/uinteger.h"
27 #include "wifi-net-device.h"
28 #include "wifi-phy.h"
29 #include "wifi-mac.h"
30 #include "ns3/ht-configuration.h"
31 #include "ns3/vht-configuration.h"
32 #include "ns3/he-configuration.h"
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("WifiNetDevice");
37 
38 NS_OBJECT_ENSURE_REGISTERED (WifiNetDevice);
39 
40 TypeId
GetTypeId(void)41 WifiNetDevice::GetTypeId (void)
42 {
43   static TypeId tid = TypeId ("ns3::WifiNetDevice")
44     .SetParent<NetDevice> ()
45     .AddConstructor<WifiNetDevice> ()
46     .SetGroupName ("Wifi")
47     .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
48                    UintegerValue (MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH),
49                    MakeUintegerAccessor (&WifiNetDevice::SetMtu,
50                                          &WifiNetDevice::GetMtu),
51                    MakeUintegerChecker<uint16_t> (1,MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH))
52     .AddAttribute ("Channel", "The channel attached to this device",
53                    PointerValue (),
54                    MakePointerAccessor (&WifiNetDevice::GetChannel),
55                    MakePointerChecker<Channel> ())
56     .AddAttribute ("Phy", "The PHY layer attached to this device.",
57                    PointerValue (),
58                    MakePointerAccessor (&WifiNetDevice::GetPhy,
59                                         &WifiNetDevice::SetPhy),
60                    MakePointerChecker<WifiPhy> ())
61     .AddAttribute ("Mac", "The MAC layer attached to this device.",
62                    PointerValue (),
63                    MakePointerAccessor (&WifiNetDevice::GetMac,
64                                         &WifiNetDevice::SetMac),
65                    MakePointerChecker<WifiMac> ())
66     .AddAttribute ("RemoteStationManager", "The station manager attached to this device.",
67                    PointerValue (),
68                    MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager,
69                                         &WifiNetDevice::GetRemoteStationManager),
70                    MakePointerChecker<WifiRemoteStationManager> ())
71     .AddAttribute ("HtConfiguration",
72                    "The HtConfiguration object.",
73                    PointerValue (),
74                    MakePointerAccessor (&WifiNetDevice::GetHtConfiguration),
75                    MakePointerChecker<HtConfiguration> ())
76     .AddAttribute ("VhtConfiguration",
77                    "The VhtConfiguration object.",
78                    PointerValue (),
79                    MakePointerAccessor (&WifiNetDevice::GetVhtConfiguration),
80                    MakePointerChecker<VhtConfiguration> ())
81     .AddAttribute ("HeConfiguration",
82                    "The HeConfiguration object.",
83                    PointerValue (),
84                    MakePointerAccessor (&WifiNetDevice::GetHeConfiguration),
85                    MakePointerChecker<HeConfiguration> ())
86   ;
87   return tid;
88 }
89 
WifiNetDevice()90 WifiNetDevice::WifiNetDevice ()
91   : m_configComplete (false)
92 {
93   NS_LOG_FUNCTION_NOARGS ();
94 }
95 
~WifiNetDevice()96 WifiNetDevice::~WifiNetDevice ()
97 {
98   NS_LOG_FUNCTION_NOARGS ();
99 }
100 
101 void
DoDispose(void)102 WifiNetDevice::DoDispose (void)
103 {
104   NS_LOG_FUNCTION_NOARGS ();
105   m_node = 0;
106   if (m_mac)
107     {
108       m_mac->Dispose ();
109       m_mac = 0;
110     }
111   if (m_phy)
112     {
113       m_phy->Dispose ();
114       m_phy = 0;
115     }
116   if (m_stationManager)
117     {
118       m_stationManager->Dispose ();
119       m_stationManager = 0;
120     }
121   if (m_htConfiguration)
122     {
123       m_htConfiguration->Dispose ();
124       m_htConfiguration = 0;
125     }
126   if (m_vhtConfiguration)
127     {
128       m_vhtConfiguration->Dispose ();
129       m_vhtConfiguration = 0;
130     }
131   if (m_heConfiguration)
132     {
133       m_heConfiguration->Dispose ();
134       m_heConfiguration = 0;
135     }
136   NetDevice::DoDispose ();
137 }
138 
139 void
DoInitialize(void)140 WifiNetDevice::DoInitialize (void)
141 {
142   NS_LOG_FUNCTION_NOARGS ();
143   if (m_phy)
144     {
145       m_phy->Initialize ();
146     }
147   if (m_mac)
148     {
149       m_mac->Initialize ();
150     }
151   if (m_stationManager)
152     {
153       m_stationManager->Initialize ();
154     }
155   NetDevice::DoInitialize ();
156 }
157 
158 void
CompleteConfig(void)159 WifiNetDevice::CompleteConfig (void)
160 {
161   if (m_mac == 0
162       || m_phy == 0
163       || m_stationManager == 0
164       || m_node == 0
165       || m_configComplete)
166     {
167       return;
168     }
169   m_mac->SetWifiRemoteStationManager (m_stationManager);
170   m_mac->SetWifiPhy (m_phy);
171   m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
172   m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
173   m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
174   m_stationManager->SetupPhy (m_phy);
175   m_stationManager->SetupMac (m_mac);
176   m_configComplete = true;
177 }
178 
179 void
SetMac(const Ptr<WifiMac> mac)180 WifiNetDevice::SetMac (const Ptr<WifiMac> mac)
181 {
182   m_mac = mac;
183   CompleteConfig ();
184 }
185 
186 void
SetPhy(const Ptr<WifiPhy> phy)187 WifiNetDevice::SetPhy (const Ptr<WifiPhy> phy)
188 {
189   m_phy = phy;
190   CompleteConfig ();
191 }
192 
193 void
SetRemoteStationManager(const Ptr<WifiRemoteStationManager> manager)194 WifiNetDevice::SetRemoteStationManager (const Ptr<WifiRemoteStationManager> manager)
195 {
196   m_stationManager = manager;
197   CompleteConfig ();
198 }
199 
200 Ptr<WifiMac>
GetMac(void) const201 WifiNetDevice::GetMac (void) const
202 {
203   return m_mac;
204 }
205 
206 Ptr<WifiPhy>
GetPhy(void) const207 WifiNetDevice::GetPhy (void) const
208 {
209   return m_phy;
210 }
211 
212 Ptr<WifiRemoteStationManager>
GetRemoteStationManager(void) const213 WifiNetDevice::GetRemoteStationManager (void) const
214 {
215   return m_stationManager;
216 }
217 
218 void
SetIfIndex(const uint32_t index)219 WifiNetDevice::SetIfIndex (const uint32_t index)
220 {
221   m_ifIndex = index;
222 }
223 
224 uint32_t
GetIfIndex(void) const225 WifiNetDevice::GetIfIndex (void) const
226 {
227   return m_ifIndex;
228 }
229 
230 Ptr<Channel>
GetChannel(void) const231 WifiNetDevice::GetChannel (void) const
232 {
233   return m_phy->GetChannel ();
234 }
235 
236 void
SetAddress(Address address)237 WifiNetDevice::SetAddress (Address address)
238 {
239   m_mac->SetAddress (Mac48Address::ConvertFrom (address));
240 }
241 
242 Address
GetAddress(void) const243 WifiNetDevice::GetAddress (void) const
244 {
245   return m_mac->GetAddress ();
246 }
247 
248 bool
SetMtu(const uint16_t mtu)249 WifiNetDevice::SetMtu (const uint16_t mtu)
250 {
251   if (mtu > MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH)
252     {
253       return false;
254     }
255   m_mtu = mtu;
256   return true;
257 }
258 
259 uint16_t
GetMtu(void) const260 WifiNetDevice::GetMtu (void) const
261 {
262   return m_mtu;
263 }
264 
265 bool
IsLinkUp(void) const266 WifiNetDevice::IsLinkUp (void) const
267 {
268   return m_phy != 0 && m_linkUp;
269 }
270 
271 void
AddLinkChangeCallback(Callback<void> callback)272 WifiNetDevice::AddLinkChangeCallback (Callback<void> callback)
273 {
274   m_linkChanges.ConnectWithoutContext (callback);
275 }
276 
277 bool
IsBroadcast(void) const278 WifiNetDevice::IsBroadcast (void) const
279 {
280   return true;
281 }
282 
283 Address
GetBroadcast(void) const284 WifiNetDevice::GetBroadcast (void) const
285 {
286   return Mac48Address::GetBroadcast ();
287 }
288 
289 bool
IsMulticast(void) const290 WifiNetDevice::IsMulticast (void) const
291 {
292   return true;
293 }
294 
295 Address
GetMulticast(Ipv4Address multicastGroup) const296 WifiNetDevice::GetMulticast (Ipv4Address multicastGroup) const
297 {
298   return Mac48Address::GetMulticast (multicastGroup);
299 }
300 
GetMulticast(Ipv6Address addr) const301 Address WifiNetDevice::GetMulticast (Ipv6Address addr) const
302 {
303   return Mac48Address::GetMulticast (addr);
304 }
305 
306 bool
IsPointToPoint(void) const307 WifiNetDevice::IsPointToPoint (void) const
308 {
309   return false;
310 }
311 
312 bool
IsBridge(void) const313 WifiNetDevice::IsBridge (void) const
314 {
315   return false;
316 }
317 
318 bool
Send(Ptr<Packet> packet,const Address & dest,uint16_t protocolNumber)319 WifiNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
320 {
321   NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
322   NS_ASSERT (Mac48Address::IsMatchingType (dest));
323 
324   Mac48Address realTo = Mac48Address::ConvertFrom (dest);
325 
326   LlcSnapHeader llc;
327   llc.SetType (protocolNumber);
328   packet->AddHeader (llc);
329 
330   m_mac->NotifyTx (packet);
331   m_mac->Enqueue (packet, realTo);
332   return true;
333 }
334 
335 Ptr<Node>
GetNode(void) const336 WifiNetDevice::GetNode (void) const
337 {
338   return m_node;
339 }
340 
341 void
SetNode(const Ptr<Node> node)342 WifiNetDevice::SetNode (const Ptr<Node> node)
343 {
344   m_node = node;
345   CompleteConfig ();
346 }
347 
348 bool
NeedsArp(void) const349 WifiNetDevice::NeedsArp (void) const
350 {
351   return true;
352 }
353 
354 void
SetReceiveCallback(NetDevice::ReceiveCallback cb)355 WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
356 {
357   m_forwardUp = cb;
358 }
359 
360 void
ForwardUp(Ptr<const Packet> packet,Mac48Address from,Mac48Address to)361 WifiNetDevice::ForwardUp (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
362 {
363   NS_LOG_FUNCTION (this << packet << from << to);
364   LlcSnapHeader llc;
365   NetDevice::PacketType type;
366   if (to.IsBroadcast ())
367     {
368       type = NetDevice::PACKET_BROADCAST;
369     }
370   else if (to.IsGroup ())
371     {
372       type = NetDevice::PACKET_MULTICAST;
373     }
374   else if (to == m_mac->GetAddress ())
375     {
376       type = NetDevice::PACKET_HOST;
377     }
378   else
379     {
380       type = NetDevice::PACKET_OTHERHOST;
381     }
382 
383   Ptr<Packet> copy = packet->Copy ();
384   if (type != NetDevice::PACKET_OTHERHOST)
385     {
386       m_mac->NotifyRx (packet);
387       copy->RemoveHeader (llc);
388       m_forwardUp (this, copy, llc.GetType (), from);
389     }
390   else
391     {
392       copy->RemoveHeader (llc);
393     }
394 
395   if (!m_promiscRx.IsNull ())
396     {
397       m_mac->NotifyPromiscRx (copy);
398       m_promiscRx (this, copy, llc.GetType (), from, to, type);
399     }
400 }
401 
402 void
LinkUp(void)403 WifiNetDevice::LinkUp (void)
404 {
405   m_linkUp = true;
406   m_linkChanges ();
407 }
408 
409 void
LinkDown(void)410 WifiNetDevice::LinkDown (void)
411 {
412   m_linkUp = false;
413   m_linkChanges ();
414 }
415 
416 bool
SendFrom(Ptr<Packet> packet,const Address & source,const Address & dest,uint16_t protocolNumber)417 WifiNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
418 {
419   NS_LOG_FUNCTION (this << packet << source << dest << protocolNumber);
420   NS_ASSERT (Mac48Address::IsMatchingType (dest));
421   NS_ASSERT (Mac48Address::IsMatchingType (source));
422 
423   Mac48Address realTo = Mac48Address::ConvertFrom (dest);
424   Mac48Address realFrom = Mac48Address::ConvertFrom (source);
425 
426   LlcSnapHeader llc;
427   llc.SetType (protocolNumber);
428   packet->AddHeader (llc);
429 
430   m_mac->NotifyTx (packet);
431   m_mac->Enqueue (packet, realTo, realFrom);
432 
433   return true;
434 }
435 
436 void
SetPromiscReceiveCallback(PromiscReceiveCallback cb)437 WifiNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
438 {
439   m_promiscRx = cb;
440   m_mac->SetPromisc ();
441 }
442 
443 bool
SupportsSendFrom(void) const444 WifiNetDevice::SupportsSendFrom (void) const
445 {
446   return m_mac->SupportsSendFrom ();
447 }
448 
449 void
SetHtConfiguration(Ptr<HtConfiguration> htConfiguration)450 WifiNetDevice::SetHtConfiguration (Ptr<HtConfiguration> htConfiguration)
451 {
452   m_htConfiguration = htConfiguration;
453 }
454 
455 Ptr<HtConfiguration>
GetHtConfiguration(void) const456 WifiNetDevice::GetHtConfiguration (void) const
457 {
458   return m_htConfiguration;
459 }
460 
461 void
SetVhtConfiguration(Ptr<VhtConfiguration> vhtConfiguration)462 WifiNetDevice::SetVhtConfiguration (Ptr<VhtConfiguration> vhtConfiguration)
463 {
464   m_vhtConfiguration = vhtConfiguration;
465 }
466 
467 Ptr<VhtConfiguration>
GetVhtConfiguration(void) const468 WifiNetDevice::GetVhtConfiguration (void) const
469 {
470   return m_vhtConfiguration;
471 }
472 
473 void
SetHeConfiguration(Ptr<HeConfiguration> heConfiguration)474 WifiNetDevice::SetHeConfiguration (Ptr<HeConfiguration> heConfiguration)
475 {
476   m_heConfiguration = heConfiguration;
477 }
478 
479 Ptr<HeConfiguration>
GetHeConfiguration(void) const480 WifiNetDevice::GetHeConfiguration (void) const
481 {
482   return m_heConfiguration;
483 }
484 
485 } //namespace ns3
486