A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "wifi-net-device.h"
10
12#include "sta-wifi-mac.h"
13#include "wifi-phy.h"
14
15#include "ns3/channel.h"
16#include "ns3/eht-configuration.h"
17#include "ns3/he-configuration.h"
18#include "ns3/ht-configuration.h"
19#include "ns3/llc-snap-header.h"
20#include "ns3/log.h"
21#include "ns3/node.h"
22#include "ns3/object-vector.h"
23#include "ns3/pointer.h"
24#include "ns3/uinteger.h"
25#include "ns3/vht-configuration.h"
26
27namespace ns3
28{
29
30NS_LOG_COMPONENT_DEFINE("WifiNetDevice");
31
32NS_OBJECT_ENSURE_REGISTERED(WifiNetDevice);
33
34TypeId
36{
37 static TypeId tid =
38 TypeId("ns3::WifiNetDevice")
40 .AddConstructor<WifiNetDevice>()
41 .SetGroupName("Wifi")
42 .AddAttribute("Mtu",
43 "The MAC-level Maximum Transmission Unit",
47 .AddAttribute("Channel",
48 "The channel attached to this device",
53 "class WifiNetDevice; use the Channel "
54 "attribute of WifiPhy")
55 .AddAttribute("Phy",
56 "The PHY layer attached to this device.",
62 .AddAttribute(
63 "Phys",
64 "The PHY layers attached to this device (11be multi-link devices only).",
68 .AddAttribute("Mac",
69 "The MAC layer attached to this device.",
73 .AddAttribute(
74 "RemoteStationManager",
75 "The station manager attached to this device.",
81 .AddAttribute("RemoteStationManagers",
82 "The remote station managers attached to this device (11be multi-link "
83 "devices only).",
88 .AddAttribute("HtConfiguration",
89 "The HtConfiguration object.",
93 .AddAttribute("VhtConfiguration",
94 "The VhtConfiguration object.",
98 .AddAttribute("HeConfiguration",
99 "The HeConfiguration object.",
100 PointerValue(),
103 .AddAttribute("EhtConfiguration",
104 "The EhtConfiguration object.",
105 PointerValue(),
108 return tid;
109}
110
112 : m_standard(WIFI_STANDARD_UNSPECIFIED),
113 m_configComplete(false)
114{
116}
117
122
123void
125{
127 m_node = nullptr;
128 if (m_mac)
129 {
130 m_mac->Dispose();
131 m_mac = nullptr;
132 }
133 for (auto& phy : m_phys)
134 {
135 if (phy)
136 {
137 phy->Dispose();
138 phy = nullptr;
139 }
140 }
141 m_phys.clear();
142 for (auto& stationManager : m_stationManagers)
143 {
144 if (stationManager)
145 {
146 stationManager->Dispose();
147 stationManager = nullptr;
148 }
149 }
150 m_stationManagers.clear();
152 {
153 m_htConfiguration->Dispose();
154 m_htConfiguration = nullptr;
155 }
157 {
158 m_vhtConfiguration->Dispose();
159 m_vhtConfiguration = nullptr;
160 }
162 {
163 m_heConfiguration->Dispose();
164 m_heConfiguration = nullptr;
165 }
167 {
168 m_ehtConfiguration->Dispose();
169 m_ehtConfiguration = nullptr;
170 }
172}
173
174void
176{
178
179 for (const auto& phy : m_phys)
180 {
181 if (phy)
182 {
183 phy->Initialize();
184 }
185 }
186 if (m_mac)
187 {
188 m_mac->Initialize();
189 }
190 for (const auto& stationManager : m_stationManagers)
191 {
192 if (stationManager)
193 {
194 stationManager->Initialize();
195 }
196 }
198}
199
200void
202{
203 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
204 {
205 return;
206 }
207 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
208 m_mac->SetWifiPhys(m_phys);
209 m_mac->SetWifiRemoteStationManagers(m_stationManagers);
210 m_mac->SetForwardUpCallback(MakeCallback(&WifiNetDevice::ForwardUp, this));
211 m_mac->SetLinkUpCallback(MakeCallback(&WifiNetDevice::LinkUp, this));
212 m_mac->SetLinkDownCallback(MakeCallback(&WifiNetDevice::LinkDown, this));
213 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
214 {
215 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
216 m_stationManagers.at(linkId)->SetupMac(m_mac);
217 }
218 m_configComplete = true;
219}
220
221void
223{
224 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
225 m_standard = standard;
226}
227
230{
231 return m_standard;
232}
233
234void
236{
237 m_mac = mac;
239}
240
241void
243{
244 m_phys.clear();
245 m_phys.push_back(phy);
246 phy->SetPhyId(0);
247 m_linkUp = true;
249}
250
251void
252WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
253{
254 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
255 "Multiple PHYs only allowed for 11be multi-link devices");
256 m_phys = phys;
257 for (std::size_t id = 0; id < phys.size(); ++id)
258 {
259 m_phys.at(id)->SetPhyId(id);
260 }
261 m_linkUp = true;
263}
264
265void
272
273void
275{
276 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
277 "Multiple remote station managers only allowed for 11be multi-link devices");
278 m_stationManagers = managers;
280}
281
284{
285 return m_mac;
286}
287
290{
292}
293
295WifiNetDevice::GetPhy(uint8_t i) const
296{
297 NS_ASSERT(i < GetPhys().size());
298 return GetPhys().at(i);
299}
300
301const std::vector<Ptr<WifiPhy>>&
303{
304 return m_phys;
305}
306
307uint8_t
309{
310 return GetPhys().size();
311}
312
318
321{
322 NS_ASSERT(linkId < GetRemoteStationManagers().size());
323 return GetRemoteStationManagers().at(linkId);
324}
325
326const std::vector<Ptr<WifiRemoteStationManager>>&
331
332uint8_t
337
338void
340{
341 m_ifIndex = index;
342}
343
346{
347 return m_ifIndex;
348}
349
352{
353 for (uint8_t i = 1; i < GetNPhys(); i++)
354 {
355 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
356 {
357 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
358 }
359 }
360
361 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
362}
363
364void
366{
367 m_mac->SetAddress(Mac48Address::ConvertFrom(address));
368}
369
372{
373 Ptr<StaWifiMac> staMac;
374 std::set<uint8_t> linkIds;
375
376 /**
377 * Normally, the MAC address that the network device has to advertise to upper layers is
378 * the MLD address, if this device is an MLD, or the unique MAC address, otherwise.
379 * Advertising the MAC address returned by WifiMac::GetAddress() is therefore the right
380 * thing to do in both cases. However, there is an exception: if this device is a non-AP MLD
381 * associated with a single link AP (hence, no ML setup was done), we need to advertise the
382 * MAC address of the link used to communicate with the AP. In fact, if we advertised the
383 * MLD address, the AP could not forward a frame to us because it would not recognize our
384 * MLD address as the MAC address of an associated station.
385 */
386
387 // Handle the exception first
388 if (m_mac->GetTypeOfStation() == STA &&
389 (staMac = StaticCast<StaWifiMac>(m_mac))->IsAssociated() && m_mac->GetNLinks() > 1 &&
390 (linkIds = staMac->GetSetupLinkIds()).size() == 1 &&
391 !m_mac->GetWifiRemoteStationManager(*linkIds.begin())
392 ->GetMldAddress(m_mac->GetBssid(*linkIds.begin())))
393 {
394 return m_mac->GetFrameExchangeManager(*linkIds.begin())->GetAddress();
395 }
396
397 return m_mac->GetAddress();
398}
399
400bool
401WifiNetDevice::SetMtu(const uint16_t mtu)
402{
404 {
405 return false;
406 }
407 m_mtu = mtu;
408 return true;
409}
410
411uint16_t
413{
414 return m_mtu;
415}
416
417bool
419{
420 return !m_phys.empty() && m_linkUp;
421}
422
423void
428
429bool
431{
432 return true;
433}
434
440
441bool
443{
444 return true;
445}
446
449{
450 return Mac48Address::GetMulticast(multicastGroup);
451}
452
458
459bool
461{
462 return false;
463}
464
465bool
467{
468 return false;
469}
470
471bool
472WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
473{
474 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
475 return DoSend(packet, std::nullopt, dest, protocolNumber);
476}
477
480{
481 return m_node;
482}
483
484void
486{
487 m_node = node;
489}
490
491bool
493{
494 return true;
495}
496
497void
502
503void
505{
506 NS_LOG_FUNCTION(this << packet << from << to);
507 LlcSnapHeader llc;
509 if (to.IsBroadcast())
510 {
512 }
513 else if (to.IsGroup())
514 {
516 }
517 else if (to == GetAddress())
518 {
520 }
521 else
522 {
524 }
525
526 Ptr<Packet> copy = packet->Copy();
527 if (type != NetDevice::PACKET_OTHERHOST)
528 {
529 m_mac->NotifyRx(packet);
530 copy->RemoveHeader(llc);
531 m_forwardUp(this, copy, llc.GetType(), from);
532 }
533 else
534 {
535 copy->RemoveHeader(llc);
536 }
537
538 if (!m_promiscRx.IsNull())
539 {
540 m_mac->NotifyPromiscRx(copy);
541 m_promiscRx(this, copy, llc.GetType(), from, to, type);
542 }
543}
544
545void
547{
548 m_linkUp = true;
550}
551
552void
554{
555 m_linkUp = false;
557}
558
559bool
561 const Address& source,
562 const Address& dest,
563 uint16_t protocolNumber)
564{
565 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
566 return DoSend(packet, source, dest, protocolNumber);
567}
568
569bool
571 std::optional<Address> source,
572 const Address& dest,
573 uint16_t protocolNumber)
574{
575 NS_LOG_FUNCTION(this << packet << dest << protocolNumber << source.value_or(Address()));
576
577 if (source)
578 {
580 *source << " is not compatible with a Mac48Address");
581 }
583 dest << " is not compatible with a Mac48Address");
584
585 auto realTo = Mac48Address::ConvertFrom(dest);
586
587 LlcSnapHeader llc;
588 llc.SetType(protocolNumber);
589 packet->AddHeader(llc);
590
591 m_mac->NotifyTx(packet);
592 if (source)
593 {
594 auto realFrom = Mac48Address::ConvertFrom(*source);
595 m_mac->Enqueue(packet, realTo, realFrom);
596 }
597 else
598 {
599 m_mac->Enqueue(packet, realTo);
600 }
601
602 return true;
603}
604
605void
611
612bool
614{
615 return m_mac->SupportsSendFrom();
616}
617
618void
620{
621 m_htConfiguration = htConfiguration;
622}
623
629
630void
632{
633 m_vhtConfiguration = vhtConfiguration;
634}
635
641
642void
644{
645 m_heConfiguration = heConfiguration;
646}
647
653
654void
656{
657 m_ehtConfiguration = ehtConfiguration;
658}
659
665
666} // namespace ns3
a polymophic address class
Definition address.h:90
Callback template class.
Definition callback.h:422
bool IsNull() const
Check for null implementation.
Definition callback.h:555
Ipv4 addresses are stored in host order in this class.
Describes an IPv6 address.
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
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:87
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition net-device.h:296
@ PACKET_BROADCAST
Packet addressed to all.
Definition net-device.h:292
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition net-device.h:294
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
void Dispose()
Dispose of this Object.
Definition object.cc:247
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition type-id.h:64
Hold an unsigned integer type.
Definition uinteger.h:34
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....
bool DoSend(Ptr< Packet > packet, std::optional< Address > source, const Address &dest, uint16_t protocolNumber)
Send a packet.
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:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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:35
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ STA
Definition wifi-mac.h:58
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:684
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
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:183
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
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 octets of the LLC/SNAP header.