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/boolean.h"
16#include "ns3/channel.h"
17#include "ns3/eht-configuration.h"
18#include "ns3/he-configuration.h"
19#include "ns3/ht-configuration.h"
20#include "ns3/llc-snap-header.h"
21#include "ns3/log.h"
22#include "ns3/node.h"
23#include "ns3/object-vector.h"
24#include "ns3/pointer.h"
25#include "ns3/uinteger.h"
26#include "ns3/vht-configuration.h"
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("WifiNetDevice");
32
34
37{
38 static TypeId tid =
39 TypeId("ns3::WifiNetDevice")
41 .AddConstructor<WifiNetDevice>()
42 .SetGroupName("Wifi")
43 .AddAttribute("Mtu",
44 "The MAC-level Maximum Transmission Unit",
48 .AddAttribute("Phy",
49 "The PHY layer attached to this device.",
51 MakePointerAccessor(static_cast<Ptr<WifiPhy> (WifiNetDevice::*)() const>(
55 .AddAttribute(
56 "Phys",
57 "The PHY layers attached to this device (11be multi-link devices only).",
61 .AddAttribute("Mac",
62 "The MAC layer attached to this device.",
66 .AddAttribute("RemoteStationManager",
67 "The station manager attached to this device.",
71 static_cast<Ptr<WifiRemoteStationManager> (WifiNetDevice::*)() const>(
74 .AddAttribute("RemoteStationManagers",
75 "The remote station managers attached to this device (11be multi-link "
76 "devices only).",
81 .AddAttribute("HtConfiguration",
82 "The HtConfiguration object.",
86 .AddAttribute("VhtConfiguration",
87 "The VhtConfiguration object.",
91 .AddAttribute("HeConfiguration",
92 "The HeConfiguration object.",
96 .AddAttribute("EhtConfiguration",
97 "The EhtConfiguration object.",
101 return tid;
102}
103
110
115
116void
118{
120 m_node = nullptr;
121 if (m_mac)
122 {
123 m_mac->Dispose();
124 m_mac = nullptr;
125 }
126 for (auto& phy : m_phys)
127 {
128 if (phy)
129 {
130 phy->Dispose();
131 phy = nullptr;
132 }
133 }
134 m_phys.clear();
135 for (auto& stationManager : m_stationManagers)
136 {
137 if (stationManager)
138 {
139 stationManager->Dispose();
140 stationManager = nullptr;
141 }
142 }
143 m_stationManagers.clear();
145 {
146 m_htConfiguration->Dispose();
147 m_htConfiguration = nullptr;
148 }
150 {
151 m_vhtConfiguration->Dispose();
152 m_vhtConfiguration = nullptr;
153 }
155 {
156 m_heConfiguration->Dispose();
157 m_heConfiguration = nullptr;
158 }
160 {
161 m_ehtConfiguration->Dispose();
162 m_ehtConfiguration = nullptr;
163 }
165}
166
167void
169{
171
172 for (const auto& phy : m_phys)
173 {
174 if (phy)
175 {
176 phy->Initialize();
177 }
178 }
179 if (m_mac)
180 {
181 m_mac->Initialize();
182 }
183 for (const auto& stationManager : m_stationManagers)
184 {
185 if (stationManager)
186 {
187 stationManager->Initialize();
188 }
189 }
191}
192
193void
195{
196 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
197 {
198 return;
199 }
200 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
201 m_mac->SetWifiPhys(m_phys);
202 m_mac->SetWifiRemoteStationManagers(m_stationManagers);
203 m_mac->SetForwardUpCallback(MakeCallback(&WifiNetDevice::ForwardUp, this));
204 m_mac->SetLinkUpCallback(MakeCallback(&WifiNetDevice::LinkUp, this));
205 m_mac->SetLinkDownCallback(MakeCallback(&WifiNetDevice::LinkDown, this));
206 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
207 {
208 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
209 m_stationManagers.at(linkId)->SetupMac(m_mac);
210 }
211 m_configComplete = true;
212}
213
214void
216{
217 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
218 m_standard = standard;
219}
220
223{
224 return m_standard;
225}
226
227void
229{
230 m_mac = mac;
232}
233
234void
236{
237 m_phys.clear();
238 m_phys.push_back(phy);
239 phy->SetPhyId(0);
240 m_linkUp = true;
242}
243
244void
245WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
246{
247 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
248 "Multiple PHYs only allowed for 11be multi-link devices");
249 m_phys = phys;
250 for (std::size_t id = 0; id < phys.size(); ++id)
251 {
252 m_phys.at(id)->SetPhyId(id);
253 }
254 m_linkUp = true;
256}
257
258void
265
266void
268{
269 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
270 "Multiple remote station managers only allowed for 11be multi-link devices");
271 m_stationManagers = managers;
273}
274
277{
278 return m_mac;
279}
280
283{
285}
286
288WifiNetDevice::GetPhy(uint8_t i) const
289{
290 NS_ASSERT(i < GetPhys().size());
291 return GetPhys().at(i);
292}
293
294const std::vector<Ptr<WifiPhy>>&
296{
297 return m_phys;
298}
299
300uint8_t
302{
303 return GetPhys().size();
304}
305
311
314{
315 NS_ASSERT(linkId < GetRemoteStationManagers().size());
316 return GetRemoteStationManagers().at(linkId);
317}
318
319const std::vector<Ptr<WifiRemoteStationManager>>&
324
325uint8_t
330
331void
333{
334 m_ifIndex = index;
335}
336
339{
340 return m_ifIndex;
341}
342
345{
346 for (uint8_t i = 1; i < GetNPhys(); i++)
347 {
348 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
349 {
350 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
351 }
352 }
353
354 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
355}
356
357void
359{
360 m_mac->SetAddress(Mac48Address::ConvertFrom(address));
361}
362
365{
366 Ptr<StaWifiMac> staMac;
367 std::set<uint8_t> linkIds;
368
369 /**
370 * Normally, the MAC address that the network device has to advertise to upper layers is
371 * the MLD address, if this device is an MLD, or the unique MAC address, otherwise.
372 * Advertising the MAC address returned by WifiMac::GetAddress() is therefore the right
373 * thing to do in both cases. However, there is an exception: if this device is a non-AP MLD
374 * associated with a single link AP (hence, no ML setup was done), we need to advertise the
375 * MAC address of the link used to communicate with the AP. In fact, if we advertised the
376 * MLD address, the AP could not forward a frame to us because it would not recognize our
377 * MLD address as the MAC address of an associated station.
378 */
379
380 // Handle the exception first
381 if (m_mac->GetTypeOfStation() == STA &&
382 (staMac = StaticCast<StaWifiMac>(m_mac))->IsAssociated() && m_mac->GetNLinks() > 1 &&
383 (linkIds = staMac->GetSetupLinkIds()).size() == 1 &&
384 !m_mac->GetWifiRemoteStationManager(*linkIds.begin())
385 ->GetMldAddress(m_mac->GetBssid(*linkIds.begin())))
386 {
387 return m_mac->GetFrameExchangeManager(*linkIds.begin())->GetAddress();
388 }
389
390 return m_mac->GetAddress();
391}
392
393bool
394WifiNetDevice::SetMtu(const uint16_t mtu)
395{
397 {
398 return false;
399 }
400 m_mtu = mtu;
401 return true;
402}
403
404uint16_t
406{
407 return m_mtu;
408}
409
410bool
412{
413 return !m_phys.empty() && m_linkUp;
414}
415
416void
418{
419 m_linkChanges.ConnectWithoutContext(callback);
420}
421
422bool
424{
425 return true;
426}
427
433
434bool
436{
437 return true;
438}
439
442{
443 return Mac48Address::GetMulticast(multicastGroup);
444}
445
451
452bool
454{
455 return false;
456}
457
458bool
460{
461 return false;
462}
463
464bool
465WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
466{
467 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
468 return DoSend(packet, std::nullopt, dest, protocolNumber);
469}
470
473{
474 return m_node;
475}
476
477void
479{
480 m_node = node;
482}
483
484bool
486{
487 return true;
488}
489
490void
495
496void
498{
499 NS_LOG_FUNCTION(this << packet << from << to);
500 LlcSnapHeader llc;
502 if (to.IsBroadcast())
503 {
505 }
506 else if (to.IsGroup())
507 {
509 }
510 else if (to == GetAddress())
511 {
513 }
514 else
515 {
517 }
518
519 Ptr<Packet> copy = packet->Copy();
520 if (type != NetDevice::PACKET_OTHERHOST)
521 {
522 m_mac->NotifyRx(packet);
523 copy->RemoveHeader(llc);
524 m_forwardUp(this, copy, llc.GetType(), from);
525 }
526 else
527 {
528 copy->RemoveHeader(llc);
529 }
530
531 if (!m_promiscRx.IsNull())
532 {
533 m_mac->NotifyPromiscRx(copy);
534 m_promiscRx(this, copy, llc.GetType(), from, to, type);
535 }
536}
537
538void
540{
541 m_linkUp = true;
543}
544
545void
547{
548 m_linkUp = false;
550}
551
552bool
554 const Address& source,
555 const Address& dest,
556 uint16_t protocolNumber)
557{
558 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
559 return DoSend(packet, source, dest, protocolNumber);
560}
561
562bool
564 std::optional<Address> source,
565 const Address& dest,
566 uint16_t protocolNumber)
567{
568 NS_LOG_FUNCTION(this << packet << dest << protocolNumber << source.value_or(Address()));
569
570 if (source)
571 {
573 *source << " is not compatible with a Mac48Address");
574 }
576 dest << " is not compatible with a Mac48Address");
577
578 auto realTo = Mac48Address::ConvertFrom(dest);
579
580 LlcSnapHeader llc;
581 llc.SetType(protocolNumber);
582 packet->AddHeader(llc);
583
584 m_mac->NotifyTx(packet);
585 if (source)
586 {
587 auto realFrom = Mac48Address::ConvertFrom(*source);
588 m_mac->Enqueue(packet, realTo, realFrom);
589 }
590 else
591 {
592 m_mac->Enqueue(packet, realTo);
593 }
594
595 return true;
596}
597
598void
604
605bool
607{
608 return m_mac->SupportsSendFrom();
609}
610
611void
613{
614 m_htConfiguration = htConfiguration;
615}
616
622
623void
625{
626 m_vhtConfiguration = vhtConfiguration;
627}
628
634
635void
637{
638 m_heConfiguration = heConfiguration;
639}
640
646
647void
649{
650 m_ehtConfiguration = ehtConfiguration;
651}
652
658
659bool
661{
663 {
664 return false;
665 }
666
667 BooleanValue emlsrActivated;
668 if (!m_ehtConfiguration->GetAttributeFailSafe("EmlsrActivated", emlsrActivated))
669 {
670 return false;
671 }
672 return emlsrActivated.Get();
673}
674
675} // namespace ns3
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
bool Get() const
Definition boolean.cc:44
Callback template class.
Definition callback.h:422
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
Callback< bool, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address &, const Address &, PacketType > PromiscReceiveCallback
Definition net-device.h:341
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
Callback< bool, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address & > ReceiveCallback
Definition net-device.h:311
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
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
bool IsEmlsrActivated() const
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
#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:249
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:270
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:295
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:592
static constexpr 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.