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.",
50 MakePointerAccessor(static_cast<Ptr<WifiPhy> (WifiNetDevice::*)() const>(
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("RemoteStationManager",
66 "The station manager attached to this device.",
70 static_cast<Ptr<WifiRemoteStationManager> (WifiNetDevice::*)() const>(
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.