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("Phy",
48 "The PHY layer attached to this device.",
54 .AddAttribute(
55 "Phys",
56 "The PHY layers attached to this device (11be multi-link devices only).",
60 .AddAttribute("Mac",
61 "The MAC layer attached to this device.",
65 .AddAttribute(
66 "RemoteStationManager",
67 "The station manager attached to this device.",
73 .AddAttribute("RemoteStationManagers",
74 "The remote station managers attached to this device (11be multi-link "
75 "devices only).",
80 .AddAttribute("HtConfiguration",
81 "The HtConfiguration object.",
85 .AddAttribute("VhtConfiguration",
86 "The VhtConfiguration object.",
90 .AddAttribute("HeConfiguration",
91 "The HeConfiguration object.",
95 .AddAttribute("EhtConfiguration",
96 "The EhtConfiguration object.",
100 return tid;
101}
102
104 : m_standard(WIFI_STANDARD_UNSPECIFIED),
105 m_configComplete(false)
106{
108}
109
114
115void
117{
119 m_node = nullptr;
120 if (m_mac)
121 {
122 m_mac->Dispose();
123 m_mac = nullptr;
124 }
125 for (auto& phy : m_phys)
126 {
127 if (phy)
128 {
129 phy->Dispose();
130 phy = nullptr;
131 }
132 }
133 m_phys.clear();
134 for (auto& stationManager : m_stationManagers)
135 {
136 if (stationManager)
137 {
138 stationManager->Dispose();
139 stationManager = nullptr;
140 }
141 }
142 m_stationManagers.clear();
144 {
145 m_htConfiguration->Dispose();
146 m_htConfiguration = nullptr;
147 }
149 {
150 m_vhtConfiguration->Dispose();
151 m_vhtConfiguration = nullptr;
152 }
154 {
155 m_heConfiguration->Dispose();
156 m_heConfiguration = nullptr;
157 }
159 {
160 m_ehtConfiguration->Dispose();
161 m_ehtConfiguration = nullptr;
162 }
164}
165
166void
168{
170
171 for (const auto& phy : m_phys)
172 {
173 if (phy)
174 {
175 phy->Initialize();
176 }
177 }
178 if (m_mac)
179 {
180 m_mac->Initialize();
181 }
182 for (const auto& stationManager : m_stationManagers)
183 {
184 if (stationManager)
185 {
186 stationManager->Initialize();
187 }
188 }
190}
191
192void
194{
195 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
196 {
197 return;
198 }
199 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
200 m_mac->SetWifiPhys(m_phys);
201 m_mac->SetWifiRemoteStationManagers(m_stationManagers);
202 m_mac->SetForwardUpCallback(MakeCallback(&WifiNetDevice::ForwardUp, this));
203 m_mac->SetLinkUpCallback(MakeCallback(&WifiNetDevice::LinkUp, this));
204 m_mac->SetLinkDownCallback(MakeCallback(&WifiNetDevice::LinkDown, this));
205 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
206 {
207 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
208 m_stationManagers.at(linkId)->SetupMac(m_mac);
209 }
210 m_configComplete = true;
211}
212
213void
215{
216 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
217 m_standard = standard;
218}
219
222{
223 return m_standard;
224}
225
226void
228{
229 m_mac = mac;
231}
232
233void
235{
236 m_phys.clear();
237 m_phys.push_back(phy);
238 phy->SetPhyId(0);
239 m_linkUp = true;
241}
242
243void
244WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
245{
246 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
247 "Multiple PHYs only allowed for 11be multi-link devices");
248 m_phys = phys;
249 for (std::size_t id = 0; id < phys.size(); ++id)
250 {
251 m_phys.at(id)->SetPhyId(id);
252 }
253 m_linkUp = true;
255}
256
257void
264
265void
267{
268 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
269 "Multiple remote station managers only allowed for 11be multi-link devices");
270 m_stationManagers = managers;
272}
273
276{
277 return m_mac;
278}
279
282{
284}
285
287WifiNetDevice::GetPhy(uint8_t i) const
288{
289 NS_ASSERT(i < GetPhys().size());
290 return GetPhys().at(i);
291}
292
293const std::vector<Ptr<WifiPhy>>&
295{
296 return m_phys;
297}
298
299uint8_t
301{
302 return GetPhys().size();
303}
304
310
313{
314 NS_ASSERT(linkId < GetRemoteStationManagers().size());
315 return GetRemoteStationManagers().at(linkId);
316}
317
318const std::vector<Ptr<WifiRemoteStationManager>>&
323
324uint8_t
329
330void
332{
333 m_ifIndex = index;
334}
335
338{
339 return m_ifIndex;
340}
341
344{
345 for (uint8_t i = 1; i < GetNPhys(); i++)
346 {
347 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
348 {
349 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
350 }
351 }
352
353 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
354}
355
356void
358{
359 m_mac->SetAddress(Mac48Address::ConvertFrom(address));
360}
361
364{
365 Ptr<StaWifiMac> staMac;
366 std::set<uint8_t> linkIds;
367
368 /**
369 * Normally, the MAC address that the network device has to advertise to upper layers is
370 * the MLD address, if this device is an MLD, or the unique MAC address, otherwise.
371 * Advertising the MAC address returned by WifiMac::GetAddress() is therefore the right
372 * thing to do in both cases. However, there is an exception: if this device is a non-AP MLD
373 * associated with a single link AP (hence, no ML setup was done), we need to advertise the
374 * MAC address of the link used to communicate with the AP. In fact, if we advertised the
375 * MLD address, the AP could not forward a frame to us because it would not recognize our
376 * MLD address as the MAC address of an associated station.
377 */
378
379 // Handle the exception first
380 if (m_mac->GetTypeOfStation() == STA &&
381 (staMac = StaticCast<StaWifiMac>(m_mac))->IsAssociated() && m_mac->GetNLinks() > 1 &&
382 (linkIds = staMac->GetSetupLinkIds()).size() == 1 &&
383 !m_mac->GetWifiRemoteStationManager(*linkIds.begin())
384 ->GetMldAddress(m_mac->GetBssid(*linkIds.begin())))
385 {
386 return m_mac->GetFrameExchangeManager(*linkIds.begin())->GetAddress();
387 }
388
389 return m_mac->GetAddress();
390}
391
392bool
393WifiNetDevice::SetMtu(const uint16_t mtu)
394{
396 {
397 return false;
398 }
399 m_mtu = mtu;
400 return true;
401}
402
403uint16_t
405{
406 return m_mtu;
407}
408
409bool
411{
412 return !m_phys.empty() && m_linkUp;
413}
414
415void
420
421bool
423{
424 return true;
425}
426
432
433bool
435{
436 return true;
437}
438
441{
442 return Mac48Address::GetMulticast(multicastGroup);
443}
444
450
451bool
453{
454 return false;
455}
456
457bool
459{
460 return false;
461}
462
463bool
464WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
465{
466 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
467 return DoSend(packet, std::nullopt, dest, protocolNumber);
468}
469
472{
473 return m_node;
474}
475
476void
478{
479 m_node = node;
481}
482
483bool
485{
486 return true;
487}
488
489void
494
495void
497{
498 NS_LOG_FUNCTION(this << packet << from << to);
499 LlcSnapHeader llc;
501 if (to.IsBroadcast())
502 {
504 }
505 else if (to.IsGroup())
506 {
508 }
509 else if (to == GetAddress())
510 {
512 }
513 else
514 {
516 }
517
518 Ptr<Packet> copy = packet->Copy();
519 if (type != NetDevice::PACKET_OTHERHOST)
520 {
521 m_mac->NotifyRx(packet);
522 copy->RemoveHeader(llc);
523 m_forwardUp(this, copy, llc.GetType(), from);
524 }
525 else
526 {
527 copy->RemoveHeader(llc);
528 }
529
530 if (!m_promiscRx.IsNull())
531 {
532 m_mac->NotifyPromiscRx(copy);
533 m_promiscRx(this, copy, llc.GetType(), from, to, type);
534 }
535}
536
537void
539{
540 m_linkUp = true;
542}
543
544void
546{
547 m_linkUp = false;
549}
550
551bool
553 const Address& source,
554 const Address& dest,
555 uint16_t protocolNumber)
556{
557 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
558 return DoSend(packet, source, dest, protocolNumber);
559}
560
561bool
563 std::optional<Address> source,
564 const Address& dest,
565 uint16_t protocolNumber)
566{
567 NS_LOG_FUNCTION(this << packet << dest << protocolNumber << source.value_or(Address()));
568
569 if (source)
570 {
572 *source << " is not compatible with a Mac48Address");
573 }
575 dest << " is not compatible with a Mac48Address");
576
577 auto realTo = Mac48Address::ConvertFrom(dest);
578
579 LlcSnapHeader llc;
580 llc.SetType(protocolNumber);
581 packet->AddHeader(llc);
582
583 m_mac->NotifyTx(packet);
584 if (source)
585 {
586 auto realFrom = Mac48Address::ConvertFrom(*source);
587 m_mac->Enqueue(packet, realTo, realFrom);
588 }
589 else
590 {
591 m_mac->Enqueue(packet, realTo);
592 }
593
594 return true;
595}
596
597void
603
604bool
606{
607 return m_mac->SupportsSendFrom();
608}
609
610void
612{
613 m_htConfiguration = htConfiguration;
614}
615
621
622void
624{
625 m_vhtConfiguration = vhtConfiguration;
626}
627
633
634void
636{
637 m_heConfiguration = heConfiguration;
638}
639
645
646void
648{
649 m_ehtConfiguration = ehtConfiguration;
650}
651
657
658} // 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:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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 AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
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
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#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:59
@ 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.
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
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:272
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.