1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2005,2006 INRIA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20
21 #include "ns3/llc-snap-header.h"
22 #include "ns3/channel.h"
23 #include "ns3/pointer.h"
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 #include "ns3/uinteger.h"
27 #include "wifi-net-device.h"
28 #include "wifi-phy.h"
29 #include "wifi-mac.h"
30 #include "ns3/ht-configuration.h"
31 #include "ns3/vht-configuration.h"
32 #include "ns3/he-configuration.h"
33
34 namespace ns3 {
35
36 NS_LOG_COMPONENT_DEFINE ("WifiNetDevice");
37
38 NS_OBJECT_ENSURE_REGISTERED (WifiNetDevice);
39
40 TypeId
GetTypeId(void)41 WifiNetDevice::GetTypeId (void)
42 {
43 static TypeId tid = TypeId ("ns3::WifiNetDevice")
44 .SetParent<NetDevice> ()
45 .AddConstructor<WifiNetDevice> ()
46 .SetGroupName ("Wifi")
47 .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
48 UintegerValue (MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH),
49 MakeUintegerAccessor (&WifiNetDevice::SetMtu,
50 &WifiNetDevice::GetMtu),
51 MakeUintegerChecker<uint16_t> (1,MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH))
52 .AddAttribute ("Channel", "The channel attached to this device",
53 PointerValue (),
54 MakePointerAccessor (&WifiNetDevice::GetChannel),
55 MakePointerChecker<Channel> ())
56 .AddAttribute ("Phy", "The PHY layer attached to this device.",
57 PointerValue (),
58 MakePointerAccessor (&WifiNetDevice::GetPhy,
59 &WifiNetDevice::SetPhy),
60 MakePointerChecker<WifiPhy> ())
61 .AddAttribute ("Mac", "The MAC layer attached to this device.",
62 PointerValue (),
63 MakePointerAccessor (&WifiNetDevice::GetMac,
64 &WifiNetDevice::SetMac),
65 MakePointerChecker<WifiMac> ())
66 .AddAttribute ("RemoteStationManager", "The station manager attached to this device.",
67 PointerValue (),
68 MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager,
69 &WifiNetDevice::GetRemoteStationManager),
70 MakePointerChecker<WifiRemoteStationManager> ())
71 .AddAttribute ("HtConfiguration",
72 "The HtConfiguration object.",
73 PointerValue (),
74 MakePointerAccessor (&WifiNetDevice::GetHtConfiguration),
75 MakePointerChecker<HtConfiguration> ())
76 .AddAttribute ("VhtConfiguration",
77 "The VhtConfiguration object.",
78 PointerValue (),
79 MakePointerAccessor (&WifiNetDevice::GetVhtConfiguration),
80 MakePointerChecker<VhtConfiguration> ())
81 .AddAttribute ("HeConfiguration",
82 "The HeConfiguration object.",
83 PointerValue (),
84 MakePointerAccessor (&WifiNetDevice::GetHeConfiguration),
85 MakePointerChecker<HeConfiguration> ())
86 ;
87 return tid;
88 }
89
WifiNetDevice()90 WifiNetDevice::WifiNetDevice ()
91 : m_configComplete (false)
92 {
93 NS_LOG_FUNCTION_NOARGS ();
94 }
95
~WifiNetDevice()96 WifiNetDevice::~WifiNetDevice ()
97 {
98 NS_LOG_FUNCTION_NOARGS ();
99 }
100
101 void
DoDispose(void)102 WifiNetDevice::DoDispose (void)
103 {
104 NS_LOG_FUNCTION_NOARGS ();
105 m_node = 0;
106 if (m_mac)
107 {
108 m_mac->Dispose ();
109 m_mac = 0;
110 }
111 if (m_phy)
112 {
113 m_phy->Dispose ();
114 m_phy = 0;
115 }
116 if (m_stationManager)
117 {
118 m_stationManager->Dispose ();
119 m_stationManager = 0;
120 }
121 if (m_htConfiguration)
122 {
123 m_htConfiguration->Dispose ();
124 m_htConfiguration = 0;
125 }
126 if (m_vhtConfiguration)
127 {
128 m_vhtConfiguration->Dispose ();
129 m_vhtConfiguration = 0;
130 }
131 if (m_heConfiguration)
132 {
133 m_heConfiguration->Dispose ();
134 m_heConfiguration = 0;
135 }
136 NetDevice::DoDispose ();
137 }
138
139 void
DoInitialize(void)140 WifiNetDevice::DoInitialize (void)
141 {
142 NS_LOG_FUNCTION_NOARGS ();
143 if (m_phy)
144 {
145 m_phy->Initialize ();
146 }
147 if (m_mac)
148 {
149 m_mac->Initialize ();
150 }
151 if (m_stationManager)
152 {
153 m_stationManager->Initialize ();
154 }
155 NetDevice::DoInitialize ();
156 }
157
158 void
CompleteConfig(void)159 WifiNetDevice::CompleteConfig (void)
160 {
161 if (m_mac == 0
162 || m_phy == 0
163 || m_stationManager == 0
164 || m_node == 0
165 || m_configComplete)
166 {
167 return;
168 }
169 m_mac->SetWifiRemoteStationManager (m_stationManager);
170 m_mac->SetWifiPhy (m_phy);
171 m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
172 m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
173 m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
174 m_stationManager->SetupPhy (m_phy);
175 m_stationManager->SetupMac (m_mac);
176 m_configComplete = true;
177 }
178
179 void
SetMac(const Ptr<WifiMac> mac)180 WifiNetDevice::SetMac (const Ptr<WifiMac> mac)
181 {
182 m_mac = mac;
183 CompleteConfig ();
184 }
185
186 void
SetPhy(const Ptr<WifiPhy> phy)187 WifiNetDevice::SetPhy (const Ptr<WifiPhy> phy)
188 {
189 m_phy = phy;
190 CompleteConfig ();
191 }
192
193 void
SetRemoteStationManager(const Ptr<WifiRemoteStationManager> manager)194 WifiNetDevice::SetRemoteStationManager (const Ptr<WifiRemoteStationManager> manager)
195 {
196 m_stationManager = manager;
197 CompleteConfig ();
198 }
199
200 Ptr<WifiMac>
GetMac(void) const201 WifiNetDevice::GetMac (void) const
202 {
203 return m_mac;
204 }
205
206 Ptr<WifiPhy>
GetPhy(void) const207 WifiNetDevice::GetPhy (void) const
208 {
209 return m_phy;
210 }
211
212 Ptr<WifiRemoteStationManager>
GetRemoteStationManager(void) const213 WifiNetDevice::GetRemoteStationManager (void) const
214 {
215 return m_stationManager;
216 }
217
218 void
SetIfIndex(const uint32_t index)219 WifiNetDevice::SetIfIndex (const uint32_t index)
220 {
221 m_ifIndex = index;
222 }
223
224 uint32_t
GetIfIndex(void) const225 WifiNetDevice::GetIfIndex (void) const
226 {
227 return m_ifIndex;
228 }
229
230 Ptr<Channel>
GetChannel(void) const231 WifiNetDevice::GetChannel (void) const
232 {
233 return m_phy->GetChannel ();
234 }
235
236 void
SetAddress(Address address)237 WifiNetDevice::SetAddress (Address address)
238 {
239 m_mac->SetAddress (Mac48Address::ConvertFrom (address));
240 }
241
242 Address
GetAddress(void) const243 WifiNetDevice::GetAddress (void) const
244 {
245 return m_mac->GetAddress ();
246 }
247
248 bool
SetMtu(const uint16_t mtu)249 WifiNetDevice::SetMtu (const uint16_t mtu)
250 {
251 if (mtu > MAX_MSDU_SIZE - LLC_SNAP_HEADER_LENGTH)
252 {
253 return false;
254 }
255 m_mtu = mtu;
256 return true;
257 }
258
259 uint16_t
GetMtu(void) const260 WifiNetDevice::GetMtu (void) const
261 {
262 return m_mtu;
263 }
264
265 bool
IsLinkUp(void) const266 WifiNetDevice::IsLinkUp (void) const
267 {
268 return m_phy != 0 && m_linkUp;
269 }
270
271 void
AddLinkChangeCallback(Callback<void> callback)272 WifiNetDevice::AddLinkChangeCallback (Callback<void> callback)
273 {
274 m_linkChanges.ConnectWithoutContext (callback);
275 }
276
277 bool
IsBroadcast(void) const278 WifiNetDevice::IsBroadcast (void) const
279 {
280 return true;
281 }
282
283 Address
GetBroadcast(void) const284 WifiNetDevice::GetBroadcast (void) const
285 {
286 return Mac48Address::GetBroadcast ();
287 }
288
289 bool
IsMulticast(void) const290 WifiNetDevice::IsMulticast (void) const
291 {
292 return true;
293 }
294
295 Address
GetMulticast(Ipv4Address multicastGroup) const296 WifiNetDevice::GetMulticast (Ipv4Address multicastGroup) const
297 {
298 return Mac48Address::GetMulticast (multicastGroup);
299 }
300
GetMulticast(Ipv6Address addr) const301 Address WifiNetDevice::GetMulticast (Ipv6Address addr) const
302 {
303 return Mac48Address::GetMulticast (addr);
304 }
305
306 bool
IsPointToPoint(void) const307 WifiNetDevice::IsPointToPoint (void) const
308 {
309 return false;
310 }
311
312 bool
IsBridge(void) const313 WifiNetDevice::IsBridge (void) const
314 {
315 return false;
316 }
317
318 bool
Send(Ptr<Packet> packet,const Address & dest,uint16_t protocolNumber)319 WifiNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
320 {
321 NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
322 NS_ASSERT (Mac48Address::IsMatchingType (dest));
323
324 Mac48Address realTo = Mac48Address::ConvertFrom (dest);
325
326 LlcSnapHeader llc;
327 llc.SetType (protocolNumber);
328 packet->AddHeader (llc);
329
330 m_mac->NotifyTx (packet);
331 m_mac->Enqueue (packet, realTo);
332 return true;
333 }
334
335 Ptr<Node>
GetNode(void) const336 WifiNetDevice::GetNode (void) const
337 {
338 return m_node;
339 }
340
341 void
SetNode(const Ptr<Node> node)342 WifiNetDevice::SetNode (const Ptr<Node> node)
343 {
344 m_node = node;
345 CompleteConfig ();
346 }
347
348 bool
NeedsArp(void) const349 WifiNetDevice::NeedsArp (void) const
350 {
351 return true;
352 }
353
354 void
SetReceiveCallback(NetDevice::ReceiveCallback cb)355 WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
356 {
357 m_forwardUp = cb;
358 }
359
360 void
ForwardUp(Ptr<const Packet> packet,Mac48Address from,Mac48Address to)361 WifiNetDevice::ForwardUp (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
362 {
363 NS_LOG_FUNCTION (this << packet << from << to);
364 LlcSnapHeader llc;
365 NetDevice::PacketType type;
366 if (to.IsBroadcast ())
367 {
368 type = NetDevice::PACKET_BROADCAST;
369 }
370 else if (to.IsGroup ())
371 {
372 type = NetDevice::PACKET_MULTICAST;
373 }
374 else if (to == m_mac->GetAddress ())
375 {
376 type = NetDevice::PACKET_HOST;
377 }
378 else
379 {
380 type = NetDevice::PACKET_OTHERHOST;
381 }
382
383 Ptr<Packet> copy = packet->Copy ();
384 if (type != NetDevice::PACKET_OTHERHOST)
385 {
386 m_mac->NotifyRx (packet);
387 copy->RemoveHeader (llc);
388 m_forwardUp (this, copy, llc.GetType (), from);
389 }
390 else
391 {
392 copy->RemoveHeader (llc);
393 }
394
395 if (!m_promiscRx.IsNull ())
396 {
397 m_mac->NotifyPromiscRx (copy);
398 m_promiscRx (this, copy, llc.GetType (), from, to, type);
399 }
400 }
401
402 void
LinkUp(void)403 WifiNetDevice::LinkUp (void)
404 {
405 m_linkUp = true;
406 m_linkChanges ();
407 }
408
409 void
LinkDown(void)410 WifiNetDevice::LinkDown (void)
411 {
412 m_linkUp = false;
413 m_linkChanges ();
414 }
415
416 bool
SendFrom(Ptr<Packet> packet,const Address & source,const Address & dest,uint16_t protocolNumber)417 WifiNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
418 {
419 NS_LOG_FUNCTION (this << packet << source << dest << protocolNumber);
420 NS_ASSERT (Mac48Address::IsMatchingType (dest));
421 NS_ASSERT (Mac48Address::IsMatchingType (source));
422
423 Mac48Address realTo = Mac48Address::ConvertFrom (dest);
424 Mac48Address realFrom = Mac48Address::ConvertFrom (source);
425
426 LlcSnapHeader llc;
427 llc.SetType (protocolNumber);
428 packet->AddHeader (llc);
429
430 m_mac->NotifyTx (packet);
431 m_mac->Enqueue (packet, realTo, realFrom);
432
433 return true;
434 }
435
436 void
SetPromiscReceiveCallback(PromiscReceiveCallback cb)437 WifiNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
438 {
439 m_promiscRx = cb;
440 m_mac->SetPromisc ();
441 }
442
443 bool
SupportsSendFrom(void) const444 WifiNetDevice::SupportsSendFrom (void) const
445 {
446 return m_mac->SupportsSendFrom ();
447 }
448
449 void
SetHtConfiguration(Ptr<HtConfiguration> htConfiguration)450 WifiNetDevice::SetHtConfiguration (Ptr<HtConfiguration> htConfiguration)
451 {
452 m_htConfiguration = htConfiguration;
453 }
454
455 Ptr<HtConfiguration>
GetHtConfiguration(void) const456 WifiNetDevice::GetHtConfiguration (void) const
457 {
458 return m_htConfiguration;
459 }
460
461 void
SetVhtConfiguration(Ptr<VhtConfiguration> vhtConfiguration)462 WifiNetDevice::SetVhtConfiguration (Ptr<VhtConfiguration> vhtConfiguration)
463 {
464 m_vhtConfiguration = vhtConfiguration;
465 }
466
467 Ptr<VhtConfiguration>
GetVhtConfiguration(void) const468 WifiNetDevice::GetVhtConfiguration (void) const
469 {
470 return m_vhtConfiguration;
471 }
472
473 void
SetHeConfiguration(Ptr<HeConfiguration> heConfiguration)474 WifiNetDevice::SetHeConfiguration (Ptr<HeConfiguration> heConfiguration)
475 {
476 m_heConfiguration = heConfiguration;
477 }
478
479 Ptr<HeConfiguration>
GetHeConfiguration(void) const480 WifiNetDevice::GetHeConfiguration (void) const
481 {
482 return m_heConfiguration;
483 }
484
485 } //namespace ns3
486