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 * 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
23#include "sta-wifi-mac.h"
24#include "wifi-phy.h"
25
26#include "ns3/channel.h"
27#include "ns3/eht-configuration.h"
28#include "ns3/he-configuration.h"
29#include "ns3/ht-configuration.h"
30#include "ns3/llc-snap-header.h"
31#include "ns3/log.h"
32#include "ns3/node.h"
33#include "ns3/object-vector.h"
34#include "ns3/pointer.h"
35#include "ns3/uinteger.h"
36#include "ns3/vht-configuration.h"
37
38namespace ns3
39{
40
41NS_LOG_COMPONENT_DEFINE("WifiNetDevice");
42
43NS_OBJECT_ENSURE_REGISTERED(WifiNetDevice);
44
45TypeId
47{
48 static TypeId tid =
49 TypeId("ns3::WifiNetDevice")
51 .AddConstructor<WifiNetDevice>()
52 .SetGroupName("Wifi")
53 .AddAttribute("Mtu",
54 "The MAC-level Maximum Transmission Unit",
57 MakeUintegerChecker<uint16_t>(1, MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH))
58 .AddAttribute("Channel",
59 "The channel attached to this device",
62 MakePointerChecker<Channel>(),
64 "class WifiNetDevice; use the Channel "
65 "attribute of WifiPhy")
66 .AddAttribute("Phy",
67 "The PHY layer attached to this device.",
72 MakePointerChecker<WifiPhy>())
73 .AddAttribute(
74 "Phys",
75 "The PHY layers attached to this device (11be multi-link devices only).",
78 MakeObjectVectorChecker<WifiPhy>())
79 .AddAttribute("Mac",
80 "The MAC layer attached to this device.",
83 MakePointerChecker<WifiMac>())
84 .AddAttribute(
85 "RemoteStationManager",
86 "The station manager attached to this device.",
91 MakePointerChecker<WifiRemoteStationManager>())
92 .AddAttribute("RemoteStationManagers",
93 "The remote station managers attached to this device (11be multi-link "
94 "devices only).",
98 MakeObjectVectorChecker<WifiRemoteStationManager>())
99 .AddAttribute("HtConfiguration",
100 "The HtConfiguration object.",
101 PointerValue(),
103 MakePointerChecker<HtConfiguration>())
104 .AddAttribute("VhtConfiguration",
105 "The VhtConfiguration object.",
106 PointerValue(),
108 MakePointerChecker<VhtConfiguration>())
109 .AddAttribute("HeConfiguration",
110 "The HeConfiguration object.",
111 PointerValue(),
113 MakePointerChecker<HeConfiguration>())
114 .AddAttribute("EhtConfiguration",
115 "The EhtConfiguration object.",
116 PointerValue(),
118 MakePointerChecker<EhtConfiguration>());
119 return tid;
120}
121
123 : m_standard(WIFI_STANDARD_UNSPECIFIED),
124 m_configComplete(false)
125{
127}
128
130{
132}
133
134void
136{
138 m_node = nullptr;
139 if (m_mac)
140 {
141 m_mac->Dispose();
142 m_mac = nullptr;
143 }
144 for (auto& phy : m_phys)
145 {
146 if (phy)
147 {
148 phy->Dispose();
149 phy = nullptr;
150 }
151 }
152 m_phys.clear();
153 for (auto& stationManager : m_stationManagers)
154 {
155 if (stationManager)
156 {
157 stationManager->Dispose();
158 stationManager = nullptr;
159 }
160 }
161 m_stationManagers.clear();
163 {
164 m_htConfiguration->Dispose();
165 m_htConfiguration = nullptr;
166 }
168 {
170 m_vhtConfiguration = nullptr;
171 }
173 {
174 m_heConfiguration->Dispose();
175 m_heConfiguration = nullptr;
176 }
178 {
179 m_ehtConfiguration->Dispose();
180 m_ehtConfiguration = nullptr;
181 }
183}
184
185void
187{
189
190 for (const auto& phy : m_phys)
191 {
192 if (phy)
193 {
194 phy->Initialize();
195 }
196 }
197 if (m_mac)
198 {
199 m_mac->Initialize();
200 }
201 for (const auto& stationManager : m_stationManagers)
202 {
203 if (stationManager)
204 {
205 stationManager->Initialize();
206 }
207 }
209}
210
211void
213{
214 if (!m_mac || m_phys.empty() || m_stationManagers.empty() || !m_node || m_configComplete)
215 {
216 return;
217 }
218 NS_ABORT_IF(m_phys.size() != m_stationManagers.size());
224 for (std::size_t linkId = 0; linkId < m_stationManagers.size(); linkId++)
225 {
226 m_stationManagers.at(linkId)->SetupPhy(m_phys.at(linkId));
227 m_stationManagers.at(linkId)->SetupMac(m_mac);
228 }
229 m_configComplete = true;
230}
231
232void
234{
235 NS_ABORT_MSG_IF(m_standard != WIFI_STANDARD_UNSPECIFIED, "Wifi standard already set");
236 m_standard = standard;
237}
238
241{
242 return m_standard;
243}
244
245void
247{
248 m_mac = mac;
250}
251
252void
254{
255 m_phys.clear();
256 m_phys.push_back(phy);
257 m_linkUp = true;
259}
260
261void
262WifiNetDevice::SetPhys(const std::vector<Ptr<WifiPhy>>& phys)
263{
264 NS_ABORT_MSG_IF(phys.size() > 1 && !m_ehtConfiguration,
265 "Multiple PHYs only allowed for 11be multi-link devices");
266 m_phys = phys;
267 m_linkUp = true;
269}
270
271void
273{
274 m_stationManagers.clear();
275 m_stationManagers.push_back(manager);
277}
278
279void
281{
282 NS_ABORT_MSG_IF(managers.size() > 1 && !m_ehtConfiguration,
283 "Multiple remote station managers only allowed for 11be multi-link devices");
284 m_stationManagers = managers;
286}
287
290{
291 return m_mac;
292}
293
296{
298}
299
301WifiNetDevice::GetPhy(uint8_t i) const
302{
303 NS_ASSERT(i < GetPhys().size());
304 return GetPhys().at(i);
305}
306
307const std::vector<Ptr<WifiPhy>>&
309{
310 return m_phys;
311}
312
313uint8_t
315{
316 return GetPhys().size();
317}
318
321{
322 return GetRemoteStationManager(0);
323}
324
327{
328 NS_ASSERT(linkId < GetRemoteStationManagers().size());
329 return GetRemoteStationManagers().at(linkId);
330}
331
332const std::vector<Ptr<WifiRemoteStationManager>>&
334{
335 return m_stationManagers;
336}
337
338uint8_t
340{
341 return GetRemoteStationManagers().size();
342}
343
344void
346{
347 m_ifIndex = index;
348}
349
352{
353 return m_ifIndex;
354}
355
358{
359 for (uint8_t i = 1; i < GetNPhys(); i++)
360 {
361 if (GetPhy(i)->GetChannel() != GetPhy(i - 1)->GetChannel())
362 {
363 NS_ABORT_MSG("Do not call WifiNetDevice::GetChannel() when using multiple channels");
364 }
365 }
366
367 return m_phys[SINGLE_LINK_OP_ID]->GetChannel();
368}
369
370void
372{
374}
375
378{
379 Ptr<StaWifiMac> staMac;
380 std::set<uint8_t> linkIds;
381
393 // Handle the exception first
394 if (m_mac->GetTypeOfStation() == STA &&
395 (staMac = StaticCast<StaWifiMac>(m_mac))->IsAssociated() && m_mac->GetNLinks() > 1 &&
396 (linkIds = staMac->GetSetupLinkIds()).size() == 1 &&
397 !GetRemoteStationManager(*linkIds.begin())
398 ->GetMldAddress(m_mac->GetBssid(*linkIds.begin())))
399 {
400 return m_mac->GetFrameExchangeManager(*linkIds.begin())->GetAddress();
401 }
402
403 return m_mac->GetAddress();
404}
405
406bool
407WifiNetDevice::SetMtu(const uint16_t mtu)
408{
410 {
411 return false;
412 }
413 m_mtu = mtu;
414 return true;
415}
416
417uint16_t
419{
420 return m_mtu;
421}
422
423bool
425{
426 return !m_phys.empty() && m_linkUp;
427}
428
429void
431{
433}
434
435bool
437{
438 return true;
439}
440
443{
445}
446
447bool
449{
450 return true;
451}
452
455{
456 return Mac48Address::GetMulticast(multicastGroup);
457}
458
461{
462 return Mac48Address::GetMulticast(addr);
463}
464
465bool
467{
468 return false;
469}
470
471bool
473{
474 return false;
475}
476
477bool
478WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
479{
480 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
482
484
485 LlcSnapHeader llc;
486 llc.SetType(protocolNumber);
487 packet->AddHeader(llc);
488
489 m_mac->NotifyTx(packet);
490 m_mac->Enqueue(packet, realTo);
491 return true;
492}
493
496{
497 return m_node;
498}
499
500void
502{
503 m_node = node;
505}
506
507bool
509{
510 return true;
511}
512
513void
515{
516 m_forwardUp = cb;
517}
518
519void
521{
522 NS_LOG_FUNCTION(this << packet << from << to);
523 LlcSnapHeader llc;
525 if (to.IsBroadcast())
526 {
528 }
529 else if (to.IsGroup())
530 {
532 }
533 else if (to == GetAddress())
534 {
536 }
537 else
538 {
540 }
541
542 Ptr<Packet> copy = packet->Copy();
543 if (type != NetDevice::PACKET_OTHERHOST)
544 {
545 m_mac->NotifyRx(packet);
546 copy->RemoveHeader(llc);
547 m_forwardUp(this, copy, llc.GetType(), from);
548 }
549 else
550 {
551 copy->RemoveHeader(llc);
552 }
553
554 if (!m_promiscRx.IsNull())
555 {
556 m_mac->NotifyPromiscRx(copy);
557 m_promiscRx(this, copy, llc.GetType(), from, to, type);
558 }
559}
560
561void
563{
564 m_linkUp = true;
566}
567
568void
570{
571 m_linkUp = false;
573}
574
575bool
577 const Address& source,
578 const Address& dest,
579 uint16_t protocolNumber)
580{
581 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
584
586 Mac48Address realFrom = Mac48Address::ConvertFrom(source);
587
588 LlcSnapHeader llc;
589 llc.SetType(protocolNumber);
590 packet->AddHeader(llc);
591
592 m_mac->NotifyTx(packet);
593 m_mac->Enqueue(packet, realTo, realFrom);
594
595 return true;
596}
597
598void
600{
601 m_promiscRx = cb;
602 m_mac->SetPromisc();
603}
604
605bool
607{
608 return m_mac->SupportsSendFrom();
609}
610
611void
613{
614 m_htConfiguration = htConfiguration;
615}
616
619{
620 return (m_standard >= WIFI_STANDARD_80211n ? m_htConfiguration : nullptr);
621}
622
623void
625{
626 m_vhtConfiguration = vhtConfiguration;
627}
628
631{
633}
634
635void
637{
638 m_heConfiguration = heConfiguration;
639}
640
643{
644 return (m_standard >= WIFI_STANDARD_80211ax ? m_heConfiguration : nullptr);
645}
646
647void
649{
650 m_ehtConfiguration = ehtConfiguration;
651}
652
655{
657}
658
659} // namespace ns3
a polymophic address class
Definition: address.h:100
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
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
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:186
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
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:75
Hold an unsigned integer type.
Definition: uinteger.h:45
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
Mac48Address GetBssid(uint8_t linkId) const
Definition: wifi-mac.cc:476
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:425
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:443
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:930
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition: wifi-mac.cc:883
void NotifyPromiscRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:613
void NotifyTx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:595
virtual void Enqueue(Ptr< Packet > packet, Mac48Address to, Mac48Address from)
Definition: wifi-mac.cc:1205
void NotifyRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:607
void SetForwardUpCallback(ForwardUpCallback upCallback)
Definition: wifi-mac.cc:1092
virtual bool SupportsSendFrom() const
Definition: wifi-mac.cc:1086
void SetLinkDownCallback(Callback< void > linkDown)
Definition: wifi-mac.cc:1106
void SetPromisc()
Sets the interface in promiscuous mode.
Definition: wifi-mac.cc:482
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition: wifi-mac.cc:1099
Mac48Address GetAddress() const
Definition: wifi-mac.cc:450
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Definition: wifi-mac.cc:949
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.
std::optional< Mac48Address > GetMldAddress(const Mac48Address &address) const
Get the address of the MLD the given station is affiliated with, if any.
#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:227
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:46
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
@ STA
Definition: wifi-mac.h:63
@ 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:702
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 octets of the LLC/SNAP header.