A Discrete-Event Network Simulator
API
wifi-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "wifi-net-device.h"
21
22#include "wifi-mac.h"
23#include "wifi-phy.h"
24
25#include "ns3/channel.h"
26#include "ns3/eht-configuration.h"
27#include "ns3/he-configuration.h"
28#include "ns3/ht-configuration.h"
29#include "ns3/llc-snap-header.h"
30#include "ns3/log.h"
31#include "ns3/node.h"
32#include "ns3/object-vector.h"
33#include "ns3/pointer.h"
34#include "ns3/uinteger.h"
35#include "ns3/vht-configuration.h"
36
37namespace ns3
38{
39
40NS_LOG_COMPONENT_DEFINE("WifiNetDevice");
41
42NS_OBJECT_ENSURE_REGISTERED(WifiNetDevice);
43
44TypeId
46{
47 static TypeId tid =
48 TypeId("ns3::WifiNetDevice")
50 .AddConstructor<WifiNetDevice>()
51 .SetGroupName("Wifi")
52 .AddAttribute("Mtu",
53 "The MAC-level Maximum Transmission Unit",
56 MakeUintegerChecker<uint16_t>(1, MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH))
57 .AddAttribute("Channel",
58 "The channel attached to this device",
61 MakePointerChecker<Channel>(),
63 "Use the Channel attribute of WifiPhy")
64 .AddAttribute("Phy",
65 "The PHY layer attached to this device.",
70 MakePointerChecker<WifiPhy>())
71 .AddAttribute(
72 "Phys",
73 "The PHY layers attached to this device (11be multi-link devices only).",
76 MakeObjectVectorChecker<WifiPhy>())
77 .AddAttribute("Mac",
78 "The MAC layer attached to this device.",
81 MakePointerChecker<WifiMac>())
82 .AddAttribute(
83 "RemoteStationManager",
84 "The station manager attached to this device.",
89 MakePointerChecker<WifiRemoteStationManager>())
90 .AddAttribute("RemoteStationManagers",
91 "The remote station managers attached to this device (11be multi-link "
92 "devices only).",
96 MakeObjectVectorChecker<WifiPhy>())
97 .AddAttribute("HtConfiguration",
98 "The HtConfiguration object.",
101 MakePointerChecker<HtConfiguration>())
102 .AddAttribute("VhtConfiguration",
103 "The VhtConfiguration object.",
104 PointerValue(),
106 MakePointerChecker<VhtConfiguration>())
107 .AddAttribute("HeConfiguration",
108 "The HeConfiguration object.",
109 PointerValue(),
111 MakePointerChecker<HeConfiguration>())
112 .AddAttribute("EhtConfiguration",
113 "The EhtConfiguration object.",
114 PointerValue(),
116 MakePointerChecker<EhtConfiguration>());
117 return tid;
118}
119
121 : m_standard(WIFI_STANDARD_UNSPECIFIED),
122 m_configComplete(false)
123{
125}
126
128{
130}
131
132void
134{
136 m_node = nullptr;
137 if (m_mac)
138 {
139 m_mac->Dispose();
140 m_mac = nullptr;
141 }
142 for (auto& phy : m_phys)
143 {
144 if (phy)
145 {
146 phy->Dispose();
147 phy = nullptr;
148 }
149 }
150 m_phys.clear();
151 for (auto& stationManager : m_stationManagers)
152 {
153 if (stationManager)
154 {
155 stationManager->Dispose();
156 stationManager = nullptr;
157 }
158 }
159 m_stationManagers.clear();
161 {
162 m_htConfiguration->Dispose();
163 m_htConfiguration = nullptr;
164 }
166 {
168 m_vhtConfiguration = nullptr;
169 }
171 {
172 m_heConfiguration->Dispose();
173 m_heConfiguration = nullptr;
174 }
176 {
177 m_ehtConfiguration->Dispose();
178 m_ehtConfiguration = nullptr;
179 }
181}
182
183void
185{
187
188 for (const auto& phy : m_phys)
189 {
190 if (phy)
191 {
192 phy->Initialize();
193 }
194 }
195 if (m_mac)
196 {
197 m_mac->Initialize();
198 }
199 for (const auto& stationManager : m_stationManagers)
200 {
201 if (stationManager)
202 {
203 stationManager->Initialize();
204 }
205 }
207}
208
209void
211{
212 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
213 {
214 return;
215 }
216 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
217 m_mac->SetWifiPhys(m_phys);
218 m_mac->SetWifiRemoteStationManagers(m_stationManagers);
219 m_mac->SetForwardUpCallback(MakeCallback(&WifiNetDevice::ForwardUp, this));
220 m_mac->SetLinkUpCallback(MakeCallback(&WifiNetDevice::LinkUp, this));
221 m_mac->SetLinkDownCallback(MakeCallback(&WifiNetDevice::LinkDown, this));
222 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
223 {
224 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
225 m_stationManagers.at(linkId)->SetupMac(m_mac);
226 }
227 m_configComplete = true;
228}
229
230void
232{
233 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
234 m_standard = standard;
235}
236
239{
240 return m_standard;
241}
242
243void
245{
246 m_mac = mac;
248}
249
250void
252{
253 m_phys.clear();
254 m_phys.push_back(phy);
255 m_linkUp = true;
257}
258
259void
260WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
261{
262 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
263 "Multiple PHYs only allowed for 11be multi-link devices");
264 m_phys = phys;
265 m_linkUp = true;
267}
268
269void
271{
272 m_stationManagers.clear();
273 m_stationManagers.push_back(manager);
275}
276
277void
279{
280 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
281 "Multiple remote station managers only allowed for 11be multi-link devices");
282 m_stationManagers = managers;
284}
285
288{
289 return m_mac;
290}
291
294{
296}
297
299WifiNetDevice::GetPhy(uint8_t i) const
300{
301 NS_ASSERT(i < GetPhys().size());
302 return GetPhys().at(i);
303}
304
305const std::vector<Ptr<WifiPhy>>&
307{
308 return m_phys;
309}
310
311uint8_t
313{
314 return GetPhys().size();
315}
316
319{
320 return GetRemoteStationManager(0);
321}
322
325{
326 NS_ASSERT(linkId < GetRemoteStationManagers().size());
327 return GetRemoteStationManagers().at(linkId);
328}
329
330const std::vector<Ptr<WifiRemoteStationManager>>&
332{
333 return m_stationManagers;
334}
335
336uint8_t
338{
339 return GetRemoteStationManagers().size();
340}
341
342void
344{
345 m_ifIndex = index;
346}
347
350{
351 return m_ifIndex;
352}
353
356{
357 for (uint8_t i = 1; i < GetNPhys(); i++)
358 {
359 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
360 {
361 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
362 }
363 }
364
365 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
366}
367
368void
370{
372}
373
376{
377 return m_mac->GetAddress();
378}
379
380bool
381WifiNetDevice::SetMtu(const uint16_t mtu)
382{
384 {
385 return false;
386 }
387 m_mtu = mtu;
388 return true;
389}
390
391uint16_t
393{
394 return m_mtu;
395}
396
397bool
399{
400 return !m_phys.empty() && m_linkUp;
401}
402
403void
405{
407}
408
409bool
411{
412 return true;
413}
414
417{
419}
420
421bool
423{
424 return true;
425}
426
429{
430 return Mac48Address::GetMulticast(multicastGroup);
431}
432
435{
436 return Mac48Address::GetMulticast(addr);
437}
438
439bool
441{
442 return false;
443}
444
445bool
447{
448 return false;
449}
450
451bool
452WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
453{
454 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
456
458
459 LlcSnapHeader llc;
460 llc.SetType(protocolNumber);
461 packet->AddHeader(llc);
462
463 m_mac->NotifyTx(packet);
464 m_mac->Enqueue(packet, realTo);
465 return true;
466}
467
470{
471 return m_node;
472}
473
474void
476{
477 m_node = node;
479}
480
481bool
483{
484 return true;
485}
486
487void
489{
490 m_forwardUp = cb;
491}
492
493void
495{
496 NS_LOG_FUNCTION(this << packet << from << to);
497 LlcSnapHeader llc;
499 if (to.IsBroadcast())
500 {
502 }
503 else if (to.IsGroup())
504 {
506 }
507 else if (to == m_mac->GetAddress())
508 {
510 }
511 else
512 {
514 }
515
516 Ptr<Packet> copy = packet->Copy();
518 {
519 m_mac->NotifyRx(packet);
520 copy->RemoveHeader(llc);
521 m_forwardUp(this, copy, llc.GetType(), from);
522 }
523 else
524 {
525 copy->RemoveHeader(llc);
526 }
527
528 if (!m_promiscRx.IsNull())
529 {
530 m_mac->NotifyPromiscRx(copy);
531 m_promiscRx(this, copy, llc.GetType(), from, to, type);
532 }
533}
534
535void
537{
538 m_linkUp = true;
540}
541
542void
544{
545 m_linkUp = false;
547}
548
549bool
551 const Address& source,
552 const Address& dest,
553 uint16_t protocolNumber)
554{
555 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
558
560 Mac48Address realFrom = Mac48Address::ConvertFrom(source);
561
562 LlcSnapHeader llc;
563 llc.SetType(protocolNumber);
564 packet->AddHeader(llc);
565
566 m_mac->NotifyTx(packet);
567 m_mac->Enqueue(packet, realTo, realFrom);
568
569 return true;
570}
571
572void
574{
575 m_promiscRx = cb;
576 m_mac->SetPromisc();
577}
578
579bool
581{
582 return m_mac->SupportsSendFrom();
583}
584
585void
587{
588 m_htConfiguration = htConfiguration;
589}
590
593{
594 return (m_standard >= WIFI_STANDARD_80211n ? m_htConfiguration : nullptr);
595}
596
597void
599{
600 m_vhtConfiguration = vhtConfiguration;
601}
602
605{
607}
608
609void
611{
612 m_heConfiguration = heConfiguration;
613}
614
617{
618 return (m_standard >= WIFI_STANDARD_80211ax ? m_heConfiguration : nullptr);
619}
620
621void
623{
624 m_ehtConfiguration = ehtConfiguration;
625}
626
629{
631}
632
633} // namespace ns3
a polymophic address class
Definition: address.h:92
bool IsNull() const
Check for null implementation.
Definition: callback.h:556
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Describes an IPv6 address.
Definition: ipv6-address.h:50
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
bool IsBroadcast() const
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:303
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:305
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
void Dispose()
Dispose of this Object.
Definition: object.cc:219
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Hold objects of type Ptr<T>.
Definition: pointer.h:37
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:76
Hold an unsigned integer type.
Definition: uinteger.h:45
Hold together all Wifi-related objects.
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Receive a packet from the lower layer and pass the packet up the stack.
static TypeId GetTypeId()
Get the type ID.
bool NeedsArp() const override
bool SupportsSendFrom() const override
void SetMac(const Ptr< WifiMac > mac)
Ptr< HtConfiguration > m_htConfiguration
the HtConfiguration
bool IsBroadcast() const override
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void LinkDown()
Set that the link is down (i.e.
Ptr< EhtConfiguration > m_ehtConfiguration
the EhtConfiguration
virtual const std::vector< Ptr< WifiPhy > > & GetPhys() const
void SetPhys(const std::vector< Ptr< WifiPhy > > &phys)
void SetHeConfiguration(Ptr< HeConfiguration > heConfiguration)
void SetHtConfiguration(Ptr< HtConfiguration > htConfiguration)
Address GetBroadcast() const override
std::vector< Ptr< WifiPhy > > m_phys
the phy objects
bool SetMtu(const uint16_t mtu) override
virtual const std::vector< Ptr< WifiRemoteStationManager > > & GetRemoteStationManagers() const
bool IsBridge() const override
Return true if the net device is acting as a bridge.
Ptr< WifiMac > GetMac() const
uint32_t m_ifIndex
IF index.
Ptr< VhtConfiguration > m_vhtConfiguration
the VhtConfiguration
Ptr< VhtConfiguration > GetVhtConfiguration() const
bool m_configComplete
configuration complete
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
void SetIfIndex(const uint32_t index) override
NetDevice::ReceiveCallback m_forwardUp
forward up callback
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Ptr< HeConfiguration > m_heConfiguration
the HeConfiguration
Ptr< EhtConfiguration > GetEhtConfiguration() const
bool IsMulticast() const override
void DoDispose() override
Destructor implementation.
uint8_t GetNRemoteStationManagers() const
void SetVhtConfiguration(Ptr< VhtConfiguration > vhtConfiguration)
void DoInitialize() override
Initialize() implementation.
NetDevice::PromiscReceiveCallback m_promiscRx
promiscuous receive callback
TracedCallback m_linkChanges
link change callback
Ptr< HtConfiguration > GetHtConfiguration() const
void SetRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Ptr< Channel > GetChannel() const override
WifiStandard GetStandard() const
Get the Wifi standard.
void SetNode(const Ptr< Node > node) override
void SetRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &managers)
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
uint8_t GetNPhys() const
bool IsLinkUp() const override
std::vector< Ptr< WifiRemoteStationManager > > m_stationManagers
the station managers
Ptr< HeConfiguration > GetHeConfiguration() const
void SetAddress(Address address) override
Set the address of this interface.
Ptr< WifiRemoteStationManager > GetRemoteStationManager() const
void SetStandard(WifiStandard standard)
Set the Wifi standard.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Ptr< Node > m_node
the node
void SetEhtConfiguration(Ptr< EhtConfiguration > ehtConfiguration)
WifiStandard m_standard
Wifi standard.
Ptr< WifiPhy > GetPhy() const
uint32_t GetIfIndex() const override
void SetPhy(const Ptr< WifiPhy > phy)
Ptr< WifiMac > m_mac
the MAC
void CompleteConfig()
Complete the configuration of this Wi-Fi device by connecting all lower components (e....
Address GetAddress() const override
void AddLinkChangeCallback(Callback< void > callback) override
uint16_t GetMtu() const override
void LinkUp()
Set that the link is up.
Ptr< Node > GetNode() const override
virtual Ptr< Channel > GetChannel() const =0
Return the Channel this WifiPhy is connected to.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:230
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:691
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Definition: wifi-utils.h:140
static const uint16_t MAX_MSDU_SIZE
This value conforms to the 802.11 specification.
static const uint16_t LLC_SNAP_HEADER_LENGTH
The length in octects of the LLC/SNAP header.
mac
Definition: third.py:85
phy
Definition: third.py:82