A Discrete-Event Network Simulator
API
wifi-phy.cc
Go to the documentation of this file.
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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * S├ębastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <algorithm>
23 #include "ns3/simulator.h"
24 #include "ns3/log.h"
25 #include "ns3/pointer.h"
26 #include "ns3/mobility-model.h"
27 #include "ns3/random-variable-stream.h"
28 #include "ns3/error-model.h"
29 #include "wifi-phy.h"
30 #include "ampdu-tag.h"
31 #include "wifi-utils.h"
32 #include "sta-wifi-mac.h"
33 #include "frame-capture-model.h"
36 #include "error-rate-model.h"
37 #include "wifi-net-device.h"
38 #include "ns3/ht-configuration.h"
39 #include "ns3/he-configuration.h"
40 #include "mpdu-aggregator.h"
41 #include "wifi-psdu.h"
42 #include "wifi-ppdu.h"
43 #include "ap-wifi-mac.h"
44 #include "ns3/dsss-phy.h"
45 #include "ns3/erp-ofdm-phy.h"
46 #include "ns3/he-phy.h" //includes OFDM, HT, and VHT
47 
48 namespace ns3 {
49 
50 NS_LOG_COMPONENT_DEFINE ("WifiPhy");
51 
52 /****************************************************************
53  * The actual WifiPhy class
54  ****************************************************************/
55 
57 
58 const std::set<FrequencyChannelInfo> WifiPhy::m_frequencyChannels =
59 {
60  //2.4 GHz channels
61  // 802.11b uses width of 22, while OFDM modes use width of 20
62  { std::make_tuple (1, 2412, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
63  { std::make_tuple (1, 2412, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
64  { std::make_tuple (2, 2417, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
65  { std::make_tuple (2, 2417, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
66  { std::make_tuple (3, 2422, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
67  { std::make_tuple (3, 2422, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
68  { std::make_tuple (4, 2427, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
69  { std::make_tuple (4, 2427, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
70  { std::make_tuple (5, 2432, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
71  { std::make_tuple (5, 2432, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
72  { std::make_tuple (6, 2437, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
73  { std::make_tuple (6, 2437, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
74  { std::make_tuple (7, 2442, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
75  { std::make_tuple (7, 2442, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
76  { std::make_tuple (8, 2447, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
77  { std::make_tuple (8, 2447, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
78  { std::make_tuple (9, 2452, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
79  { std::make_tuple (9, 2452, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
80  { std::make_tuple (10, 2457, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
81  { std::make_tuple (10, 2457, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
82  { std::make_tuple (11, 2462, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
83  { std::make_tuple (11, 2462, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
84  { std::make_tuple (12, 2467, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
85  { std::make_tuple (12, 2467, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
86  { std::make_tuple (13, 2472, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
87  { std::make_tuple (13, 2472, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
88  // Only defined for 802.11b
89  { std::make_tuple (14, 2484, 22, WIFI_PHY_DSSS_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
90  // 40 MHz channels
91  { std::make_tuple (3, 2422, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
92  { std::make_tuple (4, 2427, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
93  { std::make_tuple (5, 2432, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
94  { std::make_tuple (6, 2437, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
95  { std::make_tuple (7, 2442, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
96  { std::make_tuple (8, 2447, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
97  { std::make_tuple (9, 2452, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
98  { std::make_tuple (10, 2457, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
99  { std::make_tuple (11, 2462, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_2_4GHZ) },
100 
101  // Now the 5 GHz channels used for 802.11a/n/ac/ax
102  // 20 MHz channels
103  { std::make_tuple (36, 5180, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
104  { std::make_tuple (40, 5200, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
105  { std::make_tuple (44, 5220, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
106  { std::make_tuple (48, 5240, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
107  { std::make_tuple (52, 5260, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
108  { std::make_tuple (56, 5280, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
109  { std::make_tuple (60, 5300, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
110  { std::make_tuple (64, 5320, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
111  { std::make_tuple (100, 5500, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
112  { std::make_tuple (104, 5520, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
113  { std::make_tuple (108, 5540, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
114  { std::make_tuple (112, 5560, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
115  { std::make_tuple (116, 5580, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
116  { std::make_tuple (120, 5600, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
117  { std::make_tuple (124, 5620, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
118  { std::make_tuple (128, 5640, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
119  { std::make_tuple (132, 5660, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
120  { std::make_tuple (136, 5680, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
121  { std::make_tuple (140, 5700, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
122  { std::make_tuple (144, 5720, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
123  { std::make_tuple (149, 5745, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
124  { std::make_tuple (153, 5765, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
125  { std::make_tuple (157, 5785, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
126  { std::make_tuple (161, 5805, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
127  { std::make_tuple (165, 5825, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
128  { std::make_tuple (169, 5845, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
129  { std::make_tuple (173, 5865, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
130  { std::make_tuple (177, 5885, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
131  { std::make_tuple (181, 5905, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
132  // 40 MHz channels
133  { std::make_tuple (38, 5190, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
134  { std::make_tuple (46, 5230, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
135  { std::make_tuple (54, 5270, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
136  { std::make_tuple (62, 5310, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
137  { std::make_tuple (102, 5510, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
138  { std::make_tuple (110, 5550, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
139  { std::make_tuple (118, 5590, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
140  { std::make_tuple (126, 5630, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
141  { std::make_tuple (134, 5670, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
142  { std::make_tuple (142, 5710, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
143  { std::make_tuple (151, 5755, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
144  { std::make_tuple (159, 5795, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
145  { std::make_tuple (167, 5835, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
146  { std::make_tuple (175, 5875, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
147  // 80 MHz channels
148  { std::make_tuple (42, 5210, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
149  { std::make_tuple (58, 5290, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
150  { std::make_tuple (106, 5530, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
151  { std::make_tuple (122, 5610, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
152  { std::make_tuple (138, 5690, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
153  { std::make_tuple (155, 5775, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
154  { std::make_tuple (171, 5855, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
155  // 160 MHz channels
156  { std::make_tuple (50, 5250, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
157  { std::make_tuple (114, 5570, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
158  { std::make_tuple (163, 5815, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_5GHZ) },
159 
160  // 802.11p 10 MHz channels at the 5.855-5.925 band
161  { std::make_tuple (172, 5860, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
162  { std::make_tuple (174, 5870, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
163  { std::make_tuple (176, 5880, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
164  { std::make_tuple (178, 5890, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
165  { std::make_tuple (180, 5900, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
166  { std::make_tuple (182, 5910, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
167  { std::make_tuple (184, 5920, 10, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
168 
169  // 802.11p 5 MHz channels at the 5.855-5.925 band (for simplification, we consider the same center frequencies as the 10 MHz channels)
170  { std::make_tuple (171, 5860, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
171  { std::make_tuple (173, 5870, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
172  { std::make_tuple (175, 5880, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
173  { std::make_tuple (177, 5890, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
174  { std::make_tuple (179, 5900, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
175  { std::make_tuple (181, 5910, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
176  { std::make_tuple (183, 5920, 5, WIFI_PHY_80211p_CHANNEL, WIFI_PHY_BAND_5GHZ) },
177 
178  // Now the 6 GHz channels (802.11ax only)
179  // 20 MHz channels
180  { std::make_tuple (1, 5945, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
181  { std::make_tuple (5, 5965, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
182  { std::make_tuple (9, 5985, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
183  { std::make_tuple (13, 6005, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
184  { std::make_tuple (17, 6025, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
185  { std::make_tuple (21, 6045, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
186  { std::make_tuple (25, 6065, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
187  { std::make_tuple (29, 6085, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
188  { std::make_tuple (33, 6105, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
189  { std::make_tuple (37, 6125, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
190  { std::make_tuple (41, 6145, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
191  { std::make_tuple (45, 6165, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
192  { std::make_tuple (49, 6185, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
193  { std::make_tuple (53, 6205, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
194  { std::make_tuple (57, 6225, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
195  { std::make_tuple (61, 6245, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
196  { std::make_tuple (65, 6265, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
197  { std::make_tuple (69, 6285, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
198  { std::make_tuple (73, 6305, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
199  { std::make_tuple (77, 6325, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
200  { std::make_tuple (81, 6345, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
201  { std::make_tuple (85, 6365, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
202  { std::make_tuple (89, 6385, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
203  { std::make_tuple (93, 6405, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
204  { std::make_tuple (97, 6425, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
205  { std::make_tuple (101, 6445, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
206  { std::make_tuple (105, 6465, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
207  { std::make_tuple (109, 6485, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
208  { std::make_tuple (113, 6505, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
209  { std::make_tuple (117, 6525, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
210  { std::make_tuple (121, 6545, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
211  { std::make_tuple (125, 6565, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
212  { std::make_tuple (129, 6585, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
213  { std::make_tuple (133, 6605, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
214  { std::make_tuple (137, 6625, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
215  { std::make_tuple (141, 6645, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
216  { std::make_tuple (145, 6665, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
217  { std::make_tuple (149, 6685, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
218  { std::make_tuple (153, 6705, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
219  { std::make_tuple (157, 6725, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
220  { std::make_tuple (161, 6745, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
221  { std::make_tuple (165, 6765, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
222  { std::make_tuple (169, 6785, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
223  { std::make_tuple (173, 6805, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
224  { std::make_tuple (177, 6825, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
225  { std::make_tuple (181, 6845, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
226  { std::make_tuple (185, 6865, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
227  { std::make_tuple (189, 6885, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
228  { std::make_tuple (193, 6905, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
229  { std::make_tuple (197, 6925, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
230  { std::make_tuple (201, 6945, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
231  { std::make_tuple (205, 6965, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
232  { std::make_tuple (209, 6985, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
233  { std::make_tuple (213, 7005, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
234  { std::make_tuple (217, 7025, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
235  { std::make_tuple (221, 7045, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
236  { std::make_tuple (225, 7065, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
237  { std::make_tuple (229, 7085, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
238  { std::make_tuple (233, 7105, 20, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
239  // 40 MHz channels
240  { std::make_tuple (3, 5955, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
241  { std::make_tuple (11, 5995, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
242  { std::make_tuple (19, 6035, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
243  { std::make_tuple (27, 6075, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
244  { std::make_tuple (35, 6115, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
245  { std::make_tuple (43, 6155, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
246  { std::make_tuple (51, 6195, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
247  { std::make_tuple (59, 6235, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
248  { std::make_tuple (67, 6275, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
249  { std::make_tuple (75, 6315, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
250  { std::make_tuple (83, 6355, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
251  { std::make_tuple (91, 6395, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
252  { std::make_tuple (99, 6435, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
253  { std::make_tuple (107, 6475, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
254  { std::make_tuple (115, 6515, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
255  { std::make_tuple (123, 6555, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
256  { std::make_tuple (131, 6595, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
257  { std::make_tuple (139, 6635, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
258  { std::make_tuple (147, 6675, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
259  { std::make_tuple (155, 6715, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
260  { std::make_tuple (163, 6755, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
261  { std::make_tuple (171, 6795, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
262  { std::make_tuple (179, 6835, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
263  { std::make_tuple (187, 6875, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
264  { std::make_tuple (195, 6915, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
265  { std::make_tuple (203, 6955, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
266  { std::make_tuple (211, 6995, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
267  { std::make_tuple (219, 7035, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
268  { std::make_tuple (227, 7075, 40, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
269  // 80 MHz channels
270  { std::make_tuple (7, 5975, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
271  { std::make_tuple (23, 6055, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
272  { std::make_tuple (39, 6135, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
273  { std::make_tuple (55, 6215, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
274  { std::make_tuple (71, 6295, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
275  { std::make_tuple (87, 6375, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
276  { std::make_tuple (103, 6455, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
277  { std::make_tuple (119, 6535, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
278  { std::make_tuple (135, 6615, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
279  { std::make_tuple (151, 6695, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
280  { std::make_tuple (167, 6775, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
281  { std::make_tuple (183, 6855, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
282  { std::make_tuple (199, 6935, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
283  { std::make_tuple (215, 7015, 80, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
284  // 160 MHz channels
285  { std::make_tuple (15, 6015, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
286  { std::make_tuple (47, 6175, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
287  { std::make_tuple (79, 6335, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
288  { std::make_tuple (111, 6495, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
289  { std::make_tuple (143, 6655, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
290  { std::make_tuple (175, 6815, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) },
291  { std::make_tuple (207, 6975, 160, WIFI_PHY_OFDM_CHANNEL, WIFI_PHY_BAND_6GHZ) }
292 };
293 
294 std::map<WifiModulationClass, Ptr<PhyEntity> > WifiPhy::m_staticPhyEntities; //will be filled by g_constructor_XXX
295 
296 TypeId
298 {
299  static TypeId tid = TypeId ("ns3::WifiPhy")
300  .SetParent<Object> ()
301  .SetGroupName ("Wifi")
302  .AddAttribute ("Frequency",
303  "The center frequency (MHz) of the operating channel. "
304  "If the operating channel for this object has not been set yet, the "
305  "value of this attribute is saved and will be used, along with the channel "
306  "number and width configured via other attributes, to set the operating "
307  "channel when the standard and band are configured. The default value of "
308  "this attribute is 0, which means unspecified center frequency. Note that "
309  "if center frequency and channel number are both 0 when the standard and "
310  "band are configured, a default channel (of the configured width, if any, "
311  "or the default width for the current standard and band, otherwise) is set. "
312  "If the operating channel for this object has been already set, the "
313  "specified center frequency must uniquely identify a channel in the "
314  "band being used.",
315  UintegerValue (0),
318  MakeUintegerChecker<uint16_t> ())
319  .AddAttribute ("ChannelNumber",
320  "The channel number of the operating channel. "
321  "If the operating channel for this object has not been set yet, the "
322  "value of this attribute is saved and will be used, along with the center "
323  "frequency and width configured via other attributes, to set the operating "
324  "channel when the standard and band are configured. The default value of "
325  "this attribute is 0, which means unspecified channel number. Note that "
326  "if center frequency and channel number are both 0 when the standard and "
327  "band are configured, a default channel (of the configured width, if any, "
328  "or the default width for the current standard and band, otherwise) is set. "
329  "If the operating channel for this object has been already set, the "
330  "specified channel number must uniquely identify a channel in the "
331  "band being used.",
332  UintegerValue (0),
335  MakeUintegerChecker<uint8_t> (0, 233))
336  .AddAttribute ("ChannelWidth",
337  "The width in MHz of the operating channel (5, 10, 20, 22, 40, 80 or 160). "
338  "If the operating channel for this object has not been set yet, the "
339  "value of this attribute is saved and will be used, along with the center "
340  "frequency and channel number configured via other attributes, to set the "
341  "operating channel when the standard and band are configured. The default value "
342  "of this attribute is 0, which means unspecified channel width. Note that "
343  "if center frequency and channel number are both 0 when the standard and "
344  "band are configured, a default channel (of the configured width, if any, "
345  "or the default width for the current standard and band, otherwise) is set. "
346  "Do not set this attribute when the standard and band of this object have "
347  "been already configured, because it cannot uniquely identify a channel in "
348  "the band being used.",
349  UintegerValue (0),
352  MakeUintegerChecker<uint16_t> (5, 160))
353  .AddAttribute ("Primary20MHzIndex",
354  "The index of the primary 20 MHz channel within the operating channel "
355  "(0 indicates the 20 MHz subchannel with the lowest center frequency). "
356  "This attribute is only valid if the width of the operating channel is "
357  "a multiple of 20 MHz.",
358  UintegerValue (0),
360  MakeUintegerChecker<uint8_t> (0, 7))
361  .AddAttribute ("RxSensitivity",
362  "The energy of a received signal should be higher than "
363  "this threshold (dBm) for the PHY to detect the signal.",
364  DoubleValue (-101.0),
367  MakeDoubleChecker<double> ())
368  .AddAttribute ("CcaEdThreshold",
369  "The energy of a non Wi-Fi received signal should be higher than "
370  "this threshold (dBm) to allow the PHY layer to declare CCA BUSY state. "
371  "This check is performed on the 20 MHz primary channel only.",
372  DoubleValue (-62.0),
375  MakeDoubleChecker<double> ())
376  .AddAttribute ("TxGain",
377  "Transmission gain (dB).",
378  DoubleValue (0.0),
381  MakeDoubleChecker<double> ())
382  .AddAttribute ("RxGain",
383  "Reception gain (dB).",
384  DoubleValue (0.0),
387  MakeDoubleChecker<double> ())
388  .AddAttribute ("TxPowerLevels",
389  "Number of transmission power levels available between "
390  "TxPowerStart and TxPowerEnd included.",
391  UintegerValue (1),
393  MakeUintegerChecker<uint8_t> ())
394  .AddAttribute ("TxPowerEnd",
395  "Maximum available transmission level (dBm).",
396  DoubleValue (16.0206),
399  MakeDoubleChecker<double> ())
400  .AddAttribute ("TxPowerStart",
401  "Minimum available transmission level (dBm).",
402  DoubleValue (16.0206),
405  MakeDoubleChecker<double> ())
406  .AddAttribute ("RxNoiseFigure",
407  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
408  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
409  "\"the difference in decibels (dB) between"
410  " the noise output of the actual receiver to the noise output of an "
411  " ideal receiver with the same overall gain and bandwidth when the receivers "
412  " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
413  DoubleValue (7),
415  MakeDoubleChecker<double> ())
416  .AddAttribute ("State",
417  "The state of the PHY layer.",
418  PointerValue (),
420  MakePointerChecker<WifiPhyStateHelper> ())
421  .AddAttribute ("ChannelSwitchDelay",
422  "Delay between two short frames transmitted on different frequencies.",
423  TimeValue (MicroSeconds (250)),
425  MakeTimeChecker ())
426  .AddAttribute ("Antennas",
427  "The number of antennas on the device.",
428  UintegerValue (1),
431  MakeUintegerChecker<uint8_t> (1, 8))
432  .AddAttribute ("MaxSupportedTxSpatialStreams",
433  "The maximum number of supported TX spatial streams."
434  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
435  UintegerValue (1),
438  MakeUintegerChecker<uint8_t> (1, 8))
439  .AddAttribute ("MaxSupportedRxSpatialStreams",
440  "The maximum number of supported RX spatial streams."
441  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
442  UintegerValue (1),
445  MakeUintegerChecker<uint8_t> (1, 8))
446  .AddAttribute ("ShortPlcpPreambleSupported",
447  "Whether or not short PHY preamble is supported."
448  "This parameter is only valuable for 802.11b STAs and APs."
449  "Note: 802.11g APs and STAs always support short PHY preamble.",
450  BooleanValue (false),
454  .AddAttribute ("FrameCaptureModel",
455  "Ptr to an object that implements the frame capture model",
456  PointerValue (),
458  MakePointerChecker <FrameCaptureModel> ())
459  .AddAttribute ("PreambleDetectionModel",
460  "Ptr to an object that implements the preamble detection model",
461  PointerValue (),
463  MakePointerChecker <PreambleDetectionModel> ())
464  .AddAttribute ("PostReceptionErrorModel",
465  "An optional packet error model can be added to the receive "
466  "packet process after any propagation-based (SNR-based) error "
467  "models have been applied. Typically this is used to force "
468  "specific packet drops, for testing purposes.",
469  PointerValue (),
471  MakePointerChecker<ErrorModel> ())
472  .AddAttribute ("Sifs",
473  "The duration of the Short Interframe Space. "
474  "NOTE that the default value is overwritten by the value defined "
475  "by the standard; if you want to set this attribute, you have to "
476  "do it after that the PHY object is initialized.",
477  TimeValue (MicroSeconds (0)),
479  MakeTimeChecker ())
480  .AddAttribute ("Slot",
481  "The duration of a slot. "
482  "NOTE that the default value is overwritten by the value defined "
483  "by the standard; if you want to set this attribute, you have to "
484  "do it after that the PHY object is initialized.",
485  TimeValue (MicroSeconds (0)),
487  MakeTimeChecker ())
488  .AddAttribute ("Pifs",
489  "The duration of the PCF Interframe Space. "
490  "NOTE that the default value is overwritten by the value defined "
491  "by the standard; if you want to set this attribute, you have to "
492  "do it after that the PHY object is initialized.",
493  TimeValue (MicroSeconds (0)),
495  MakeTimeChecker ())
496  .AddAttribute ("PowerDensityLimit",
497  "The mean equivalent isotropically radiated power density"
498  "limit (in dBm/MHz) set by regulators.",
499  DoubleValue (100.0), //set to a high value so as to have no effect
501  MakeDoubleChecker<double> ())
502  .AddTraceSource ("PhyTxBegin",
503  "Trace source indicating a packet "
504  "has begun transmitting over the channel medium",
506  "ns3::Packet::TracedCallback")
507  .AddTraceSource ("PhyTxPsduBegin",
508  "Trace source indicating a PSDU "
509  "has begun transmitting over the channel medium",
511  "ns3::WifiPhy::PsduTxBeginCallback")
512  .AddTraceSource ("PhyTxEnd",
513  "Trace source indicating a packet "
514  "has been completely transmitted over the channel.",
516  "ns3::Packet::TracedCallback")
517  .AddTraceSource ("PhyTxDrop",
518  "Trace source indicating a packet "
519  "has been dropped by the device during transmission",
521  "ns3::Packet::TracedCallback")
522  .AddTraceSource ("PhyRxBegin",
523  "Trace source indicating a packet "
524  "has begun being received from the channel medium "
525  "by the device",
527  "ns3::Packet::TracedCallback")
528  .AddTraceSource ("PhyRxPayloadBegin",
529  "Trace source indicating the reception of the "
530  "payload of a PPDU has begun",
532  "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
533  .AddTraceSource ("PhyRxEnd",
534  "Trace source indicating a packet "
535  "has been completely received from the channel medium "
536  "by the device",
538  "ns3::Packet::TracedCallback")
539  .AddTraceSource ("PhyRxDrop",
540  "Trace source indicating a packet "
541  "has been dropped by the device during reception",
543  "ns3::Packet::TracedCallback")
544  .AddTraceSource ("MonitorSnifferRx",
545  "Trace source simulating a wifi device in monitor mode "
546  "sniffing all received frames",
548  "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
549  .AddTraceSource ("MonitorSnifferTx",
550  "Trace source simulating the capability of a wifi device "
551  "in monitor mode to sniff all frames being transmitted",
553  "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
554  ;
555  return tid;
556 }
557 
559  : m_txMpduReferenceNumber (0xffffffff),
560  m_rxMpduReferenceNumber (0xffffffff),
561  m_endPhyRxEvent (),
562  m_endTxEvent (),
563  m_currentEvent (0),
564  m_previouslyRxPpduUid (UINT64_MAX),
565  m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
566  m_band (WIFI_PHY_BAND_UNSPECIFIED),
567  m_initialFrequency (0),
568  m_initialChannelNumber (0),
569  m_initialChannelWidth (0),
570  m_initialPrimary20Index (0),
571  m_sifs (Seconds (0)),
572  m_slot (Seconds (0)),
573  m_pifs (Seconds (0)),
574  m_ackTxTime (Seconds (0)),
575  m_blockAckTxTime (Seconds (0)),
576  m_powerRestricted (false),
577  m_channelAccessRequested (false),
578  m_txSpatialStreams (0),
579  m_rxSpatialStreams (0),
580  m_wifiRadioEnergyModel (0),
581  m_timeLastPreambleDetected (Seconds (0))
582 {
583  NS_LOG_FUNCTION (this);
584  m_random = CreateObject<UniformRandomVariable> ();
585  m_state = CreateObject<WifiPhyStateHelper> ();
586 }
587 
589 {
590  NS_LOG_FUNCTION (this);
591 }
592 
593 void
595 {
596  NS_LOG_FUNCTION (this);
597  m_endTxEvent.Cancel ();
599  for (auto & phyEntity : m_phyEntities)
600  {
601  phyEntity.second->CancelAllEvents ();
602  }
603  m_device = 0;
604  m_mobility = 0;
610  m_random = 0;
611  m_state = 0;
612  m_currentEvent = 0;
613  for (auto & preambleEvent : m_currentPreambleEvents)
614  {
615  preambleEvent.second = 0;
616  }
617  m_currentPreambleEvents.clear ();
618 
619  for (auto & phyEntity : m_phyEntities)
620  {
621  phyEntity.second = 0;
622  }
623  m_phyEntities.clear ();
624 }
625 
627 WifiPhy::GetState (void) const
628 {
629  return m_state;
630 }
631 
632 void
634 {
635  m_state->SetReceiveOkCallback (callback);
636 }
637 
638 void
640 {
641  m_state->SetReceiveErrorCallback (callback);
642 }
643 
644 void
646 {
647  m_state->RegisterListener (listener);
648 }
649 
650 void
652 {
653  m_state->UnregisterListener (listener);
654 }
655 
656 void
658 {
660 }
661 
662 void
663 WifiPhy::SetRxSensitivity (double threshold)
664 {
665  NS_LOG_FUNCTION (this << threshold);
666  m_rxSensitivityW = DbmToW (threshold);
667 }
668 
669 double
671 {
672  return WToDbm (m_rxSensitivityW);
673 }
674 
675 void
676 WifiPhy::SetCcaEdThreshold (double threshold)
677 {
678  NS_LOG_FUNCTION (this << threshold);
679  m_ccaEdThresholdW = DbmToW (threshold);
680 }
681 
682 double
684 {
685  return WToDbm (m_ccaEdThresholdW);
686 }
687 
688 void
689 WifiPhy::SetRxNoiseFigure (double noiseFigureDb)
690 {
691  NS_LOG_FUNCTION (this << noiseFigureDb);
692  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
694 }
695 
696 void
698 {
699  NS_LOG_FUNCTION (this << start);
701 }
702 
703 double
705 {
706  return m_txPowerBaseDbm;
707 }
708 
709 void
711 {
712  NS_LOG_FUNCTION (this << end);
713  m_txPowerEndDbm = end;
714 }
715 
716 double
718 {
719  return m_txPowerEndDbm;
720 }
721 
722 void
724 {
725  NS_LOG_FUNCTION (this << +n);
726  m_nTxPower = n;
727 }
728 
729 uint8_t
731 {
732  return m_nTxPower;
733 }
734 
735 void
736 WifiPhy::SetTxGain (double gain)
737 {
738  NS_LOG_FUNCTION (this << gain);
739  m_txGainDb = gain;
740 }
741 
742 double
743 WifiPhy::GetTxGain (void) const
744 {
745  return m_txGainDb;
746 }
747 
748 void
749 WifiPhy::SetRxGain (double gain)
750 {
751  NS_LOG_FUNCTION (this << gain);
752  m_rxGainDb = gain;
753 }
754 
755 double
756 WifiPhy::GetRxGain (void) const
757 {
758  return m_rxGainDb;
759 }
760 
761 void
763 {
764  NS_LOG_FUNCTION (this << enable);
765  m_shortPreamble = enable;
766 }
767 
768 bool
770 {
771  return m_shortPreamble;
772 }
773 
774 void
776 {
777  m_device = device;
778 }
779 
781 WifiPhy::GetDevice (void) const
782 {
783  return m_device;
784 }
785 
786 void
788 {
790 }
791 
794 {
795  if (m_mobility != 0)
796  {
797  return m_mobility;
798  }
799  else
800  {
801  return m_device->GetNode ()->GetObject<MobilityModel> ();
802  }
803 }
804 
805 void
807 {
810 }
811 
812 void
814 {
815  NS_LOG_FUNCTION (this << em);
817 }
818 
819 void
821 {
822  m_frameCaptureModel = model;
823 }
824 
825 void
827 {
828  m_preambleDetectionModel = model;
829 }
830 
831 void
833 {
834  m_wifiRadioEnergyModel = wifiRadioEnergyModel;
835 }
836 
837 double
838 WifiPhy::GetPowerDbm (uint8_t power) const
839 {
841  NS_ASSERT (m_nTxPower > 0);
842  double dbm;
843  if (m_nTxPower > 1)
844  {
845  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
846  }
847  else
848  {
849  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
850  dbm = m_txPowerBaseDbm;
851  }
852  return dbm;
853 }
854 
855 Time
857 {
858  return m_channelSwitchDelay;
859 }
860 
861 double
862 WifiPhy::CalculateSnr (const WifiTxVector& txVector, double ber) const
863 {
864  return m_interference.GetErrorRateModel ()->CalculateSnr (txVector, ber);
865 }
866 
869 {
870  const auto it = m_staticPhyEntities.find (modulation);
871  NS_ABORT_MSG_IF (it == m_staticPhyEntities.end (), "Unimplemented Wi-Fi modulation class");
872  return it->second;
873 }
874 
877 {
878  const auto it = m_phyEntities.find (modulation);
879  NS_ABORT_MSG_IF (it == m_phyEntities.end (), "Unsupported Wi-Fi modulation class");
880  return it->second;
881 }
882 
883 void
885 {
886  NS_LOG_FUNCTION (modulation);
887  NS_ASSERT_MSG (m_staticPhyEntities.find (modulation) == m_staticPhyEntities.end (), "The PHY entity has already been added. The setting should only be done once per modulation class");
888  m_staticPhyEntities[modulation] = phyEntity;
889 }
890 
891 void
893 {
894  NS_LOG_FUNCTION (this << modulation);
895  NS_ABORT_MSG_IF (m_staticPhyEntities.find (modulation) == m_staticPhyEntities.end (), "Cannot add an unimplemented PHY to supported list. Update the former first.");
896  NS_ASSERT_MSG (m_phyEntities.find (modulation) == m_phyEntities.end (), "The PHY entity has already been added. The setting should only be done once per modulation class");
897  phyEntity->SetOwner (this);
898  m_phyEntities[modulation] = phyEntity;
899 }
900 
901 void
903 {
904  m_sifs = sifs;
905 }
906 
907 Time
908 WifiPhy::GetSifs (void) const
909 {
910  return m_sifs;
911 }
912 
913 void
915 {
916  m_slot = slot;
917 }
918 
919 Time
920 WifiPhy::GetSlot (void) const
921 {
922  return m_slot;
923 }
924 
925 void
927 {
928  m_pifs = pifs;
929 }
930 
931 Time
932 WifiPhy::GetPifs (void) const
933 {
934  return m_pifs;
935 }
936 
937 Time
939 {
940  return m_ackTxTime;
941 }
942 
943 Time
945 {
946  return m_blockAckTxTime;
947 }
948 
949 void
951 {
952  NS_LOG_FUNCTION (this);
953  AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create<OfdmPhy> ());
954 
955  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
956  SetSifs (MicroSeconds (16));
957  SetSlot (MicroSeconds (9));
958  SetPifs (GetSifs () + GetSlot ());
959  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
960  // of the PPDU causing the EIFS" of 802.11-2016
961  m_ackTxTime = MicroSeconds (44);
962 }
963 
964 void
966 {
967  NS_LOG_FUNCTION (this);
968  Ptr<DsssPhy> phyEntity = Create<DsssPhy> ();
970  AddPhyEntity (WIFI_MOD_CLASS_DSSS, phyEntity); //when plain DSSS modes are used
971 
972  // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
973  SetSifs (MicroSeconds (10));
974  SetSlot (MicroSeconds (20));
975  SetPifs (GetSifs () + GetSlot ());
976  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
977  // of the PPDU causing the EIFS" of 802.11-2016
978  m_ackTxTime = MicroSeconds (304);
979 }
980 
981 void
983 {
984  NS_LOG_FUNCTION (this);
985  // See Table 18-5 "ERP characteristics" of 802.11-2016
986  // Slot time defaults to the "long slot time" of 20 us in the standard
987  // according to mixed 802.11b/g deployments. Short slot time is enabled
988  // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
989  // consists of only ERP STAs capable of supporting this option.
990  Configure80211b ();
991  AddPhyEntity (WIFI_MOD_CLASS_ERP_OFDM, Create<ErpOfdmPhy> ());
992 }
993 
994 void
996 {
997  NS_LOG_FUNCTION (this);
998  if (GetChannelWidth () == 10)
999  {
1000  AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create<OfdmPhy> (OFDM_PHY_10_MHZ));
1001 
1002  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1003  SetSifs (MicroSeconds (32));
1004  SetSlot (MicroSeconds (13));
1005  SetPifs (GetSifs () + GetSlot ());
1006  m_ackTxTime = MicroSeconds (88);
1007  }
1008  else if (GetChannelWidth () == 5)
1009  {
1010  AddPhyEntity (WIFI_MOD_CLASS_OFDM, Create<OfdmPhy> (OFDM_PHY_5_MHZ));
1011 
1012  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1013  SetSifs (MicroSeconds (64));
1014  SetSlot (MicroSeconds (21));
1015  SetPifs (GetSifs () + GetSlot ());
1016  m_ackTxTime = MicroSeconds (176);
1017  }
1018  else
1019  {
1020  NS_FATAL_ERROR ("802.11p configured with a wrong channel width!");
1021  }
1022 }
1023 
1024 void
1026 {
1027  NS_LOG_FUNCTION (this);
1029  {
1030  Configure80211g ();
1031  }
1032  else
1033  {
1034  Configure80211a ();
1035  }
1037 
1038  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1039  // of the PPDU causing the EIFS" of 802.11-2016
1041 }
1042 
1043 void
1045 {
1046  NS_LOG_FUNCTION (this);
1047  Configure80211n ();
1048  AddPhyEntity (WIFI_MOD_CLASS_VHT, Create<VhtPhy> ());
1049 }
1050 
1051 void
1053 {
1054  NS_LOG_FUNCTION (this);
1056  {
1057  Configure80211n ();
1058  }
1059  else
1060  {
1061  Configure80211ac ();
1062  }
1063  AddPhyEntity (WIFI_MOD_CLASS_HE, Create<HePhy> ());
1064 }
1065 
1066 void
1068 {
1069  NS_LOG_FUNCTION (this << standard << band);
1070  m_standard = standard;
1071  m_band = band;
1072 
1073  if (m_initialFrequency == 0 && m_initialChannelNumber == 0)
1074  {
1075  // set a default channel if the user did not specify anything
1076  if (m_initialChannelWidth == 0)
1077  {
1078  // set a default channel width
1080  }
1081 
1083  }
1084  else
1085  {
1087  m_standard, m_band);
1088  }
1090 
1091  switch (standard)
1092  {
1094  Configure80211a ();
1095  break;
1097  Configure80211b ();
1098  break;
1100  Configure80211g ();
1101  break;
1103  Configure80211p ();
1104  break;
1106  Configure80211n ();
1107  break;
1109  Configure80211ac ();
1110  break;
1112  Configure80211ax ();
1113  break;
1115  default:
1116  NS_ASSERT_MSG (false, "Unsupported standard");
1117  break;
1118  }
1119 }
1120 
1123 {
1124  return m_band;
1125 }
1126 
1127 
1130 {
1131  return m_standard;
1132 }
1133 
1136 {
1137  return m_operatingChannel;
1138 }
1139 
1140 void
1141 WifiPhy::SetFrequency (uint16_t frequency)
1142 {
1143  NS_LOG_FUNCTION (this << frequency);
1144 
1145  if (!m_operatingChannel.IsSet ())
1146  {
1147  // ConfigureStandardAndBand has not been called yet, so store the frequency
1148  // into m_initialFrequency
1149  NS_LOG_DEBUG ("Saving frequency configuration for initialization");
1150  m_initialFrequency = frequency;
1151  return;
1152  }
1153 
1154  if (GetFrequency () == frequency)
1155  {
1156  NS_LOG_DEBUG ("No frequency change requested");
1157  return;
1158  }
1159 
1160  // if the frequency does not uniquely identify an operating channel,
1161  // the simulation aborts
1162  SetOperatingChannel (0, frequency, 0);
1163 }
1164 
1165 uint16_t
1167 {
1168  return m_operatingChannel.GetFrequency ();
1169 }
1170 
1171 void
1173 {
1174  NS_LOG_FUNCTION (this << +nch);
1175 
1176  if (!m_operatingChannel.IsSet ())
1177  {
1178  // ConfigureStandardAndBand has not been called yet, so store the channel
1179  // into m_initialChannelNumber
1180  NS_LOG_DEBUG ("Saving channel number configuration for initialization");
1181  m_initialChannelNumber = nch;
1182  return;
1183  }
1184 
1185  if (GetChannelNumber () == nch)
1186  {
1187  NS_LOG_DEBUG ("No channel change requested");
1188  return;
1189  }
1190 
1191  // if the channel number does not uniquely identify an operating channel,
1192  // the simulation aborts
1193  SetOperatingChannel (nch, 0, 0);
1194 }
1195 
1196 uint8_t
1198 {
1199  return m_operatingChannel.GetNumber ();
1200 }
1201 
1202 void
1203 WifiPhy::SetChannelWidth (uint16_t channelWidth)
1204 {
1205  NS_LOG_FUNCTION (this << channelWidth);
1206 
1207  if (channelWidth != 0)
1208  {
1209  AddSupportedChannelWidth (channelWidth);
1210  }
1211 
1212  if (!m_operatingChannel.IsSet ())
1213  {
1214  // ConfigureStandardAndBand has not been called yet, so store the channel width
1215  // into m_initialChannelWidth
1216  NS_LOG_DEBUG ("Saving channel width configuration for initialization");
1217  m_initialChannelWidth = channelWidth;
1218  return;
1219  }
1220 
1221  if (GetChannelWidth () == channelWidth)
1222  {
1223  NS_LOG_DEBUG ("No channel width change requested");
1224  return;
1225  }
1226 
1227  NS_ABORT_MSG ("The channel width does not uniquely identify an operating channel.");
1228 }
1229 
1230 uint16_t
1232 {
1233  return m_operatingChannel.GetWidth ();
1234 }
1235 
1236 void
1238 {
1239  NS_LOG_FUNCTION (this << +index);
1240 
1241  if (!m_operatingChannel.IsSet ())
1242  {
1243  // ConfigureStandardAndBand has not been called yet, so store the primary20
1244  // index into m_initialPrimary20Index
1245  NS_LOG_DEBUG ("Saving primary20 index configuration for initialization");
1246  m_initialPrimary20Index = index;
1247  return;
1248  }
1249 
1251 }
1252 
1253 void
1254 WifiPhy::SetOperatingChannel (uint8_t number, uint16_t frequency, uint16_t width)
1255 {
1256  Time delay = Seconds (0);
1257 
1258  if (IsInitialized ())
1259  {
1260  delay = DoChannelSwitch ();
1261  }
1262 
1263  if (delay.IsStrictlyNegative ())
1264  {
1265  // switching channel is not possible now
1266  return;
1267  }
1268  if (delay.IsStrictlyPositive ())
1269  {
1270  // switching channel has been postponed
1271  Simulator::Schedule (delay, &WifiPhy::SetOperatingChannel, this, number, frequency, width);
1272  return;
1273  }
1274 
1275  // channel can be switched now.
1276  uint16_t prevChannelWidth = 0;
1277  if (m_operatingChannel.IsSet ())
1278  {
1279  prevChannelWidth = GetChannelWidth ();
1280  }
1281 
1282  m_operatingChannel.Set (number, frequency, width, m_standard, m_band);
1283 
1284  if (GetChannelWidth () != prevChannelWidth)
1285  {
1287 
1288  // If channel width changed after initialization, invoke the capabilities changed callback
1290  {
1292  }
1293  }
1294 }
1295 
1296 Time
1298 {
1299  m_powerRestricted = false;
1300  m_channelAccessRequested = false;
1301  m_currentEvent = 0;
1302  m_currentPreambleEvents.clear ();
1303  if (!IsInitialized ())
1304  {
1305  //this is not channel switch, this is initialization
1306  NS_LOG_DEBUG ("Before initialization, nothing to do");
1307  return Seconds (0);
1308  }
1309 
1310  Time delay = Seconds (0);
1311 
1313  switch (m_state->GetState ())
1314  {
1315  case WifiPhyState::RX:
1316  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1318  for (auto & phyEntity : m_phyEntities)
1319  {
1320  phyEntity.second->CancelAllEvents ();
1321  }
1322  break;
1323  case WifiPhyState::TX:
1324  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1325  delay = GetDelayUntilIdle ();
1326  break;
1328  case WifiPhyState::IDLE:
1329  for (auto & phyEntity : m_phyEntities)
1330  {
1331  phyEntity.second->CancelAllEvents ();
1332  }
1333  break;
1334  case WifiPhyState::SLEEP:
1335  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1336  delay = Seconds (-1); // negative value to indicate switching not possible
1337  break;
1338  default:
1339  NS_ASSERT (false);
1340  break;
1341  }
1342 
1343  if (delay.IsZero ())
1344  {
1345  // channel switch can be done now
1346  NS_LOG_DEBUG ("switching channel");
1347  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1349  /*
1350  * Needed here to be able to correctly sensed the medium for the first
1351  * time after the switching. The actual switching is not performed until
1352  * after m_channelSwitchDelay. Packets received during the switching
1353  * state are added to the event list and are employed later to figure
1354  * out the state of the medium after the switching.
1355  */
1356  }
1357 
1358  return delay;
1359 }
1360 
1361 void
1363 {
1364  NS_ASSERT_MSG (antennas > 0 && antennas <= 4, "unsupported number of antennas");
1365  m_numberOfAntennas = antennas;
1367 }
1368 
1369 uint8_t
1371 {
1372  return m_numberOfAntennas;
1373 }
1374 
1375 void
1377 {
1378  NS_ASSERT (streams <= GetNumberOfAntennas ());
1379  bool changed = (m_txSpatialStreams != streams);
1380  m_txSpatialStreams = streams;
1381  if (changed)
1382  {
1383  auto phyEntity = m_phyEntities.find (WIFI_MOD_CLASS_HT);
1384  if (phyEntity != m_phyEntities.end ())
1385  {
1386  Ptr<HtPhy> htPhy = DynamicCast<HtPhy> (phyEntity->second);
1387  if (htPhy)
1388  {
1389  htPhy->SetMaxSupportedNss (m_txSpatialStreams); //this is essential to have the right MCSs configured
1390  }
1391 
1393  {
1395  }
1396  }
1397  }
1398 }
1399 
1400 uint8_t
1402 {
1403  return m_txSpatialStreams;
1404 }
1405 
1406 void
1408 {
1409  NS_ASSERT (streams <= GetNumberOfAntennas ());
1410  bool changed = (m_rxSpatialStreams != streams);
1411  m_rxSpatialStreams = streams;
1412  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1413  {
1415  }
1416 }
1417 
1418 uint8_t
1420 {
1421  return m_rxSpatialStreams;
1422 }
1423 
1424 std::list<uint8_t>
1426 {
1427  std::list<uint8_t> list;
1428  for (const auto & phyEntity : m_phyEntities)
1429  {
1430  Ptr<HtPhy> htPhy = DynamicCast<HtPhy> (phyEntity.second);
1431  if (htPhy)
1432  {
1433  list.emplace_back (htPhy->GetBssMembershipSelector ());
1434  }
1435  }
1436  return list;
1437 }
1438 
1439 void
1441 {
1442  NS_LOG_FUNCTION (this << width);
1443  for (std::vector<uint32_t>::size_type i = 0; i != m_supportedChannelWidthSet.size (); i++)
1444  {
1445  if (m_supportedChannelWidthSet[i] == width)
1446  {
1447  return;
1448  }
1449  }
1450  NS_LOG_FUNCTION ("Adding " << width << " to supported channel width set");
1451  m_supportedChannelWidthSet.push_back (width);
1452 }
1453 
1454 std::vector<uint16_t>
1456 {
1458 }
1459 
1460 void
1462 {
1463  NS_LOG_FUNCTION (this);
1464  m_powerRestricted = false;
1465  m_channelAccessRequested = false;
1466  switch (m_state->GetState ())
1467  {
1468  case WifiPhyState::TX:
1469  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1471  break;
1472  case WifiPhyState::RX:
1473  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1475  break;
1477  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1479  break;
1481  case WifiPhyState::IDLE:
1482  NS_LOG_DEBUG ("setting sleep mode");
1483  m_state->SwitchToSleep ();
1484  break;
1485  case WifiPhyState::SLEEP:
1486  NS_LOG_DEBUG ("already in sleep mode");
1487  break;
1488  default:
1489  NS_ASSERT (false);
1490  break;
1491  }
1492 }
1493 
1494 void
1496 {
1497  NS_LOG_FUNCTION (this);
1498  m_powerRestricted = false;
1499  m_channelAccessRequested = false;
1501  m_endTxEvent.Cancel ();
1502  for (auto & phyEntity : m_phyEntities)
1503  {
1504  phyEntity.second->CancelAllEvents ();
1505  }
1506  m_state->SwitchToOff ();
1507 }
1508 
1509 void
1511 {
1512  NS_LOG_FUNCTION (this);
1513  m_currentPreambleEvents.clear ();
1514  switch (m_state->GetState ())
1515  {
1516  case WifiPhyState::TX:
1517  case WifiPhyState::RX:
1518  case WifiPhyState::IDLE:
1521  {
1522  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1523  break;
1524  }
1525  case WifiPhyState::SLEEP:
1526  {
1527  NS_LOG_DEBUG ("resuming from sleep mode");
1529  m_state->SwitchFromSleep (delayUntilCcaEnd);
1530  break;
1531  }
1532  default:
1533  {
1534  NS_ASSERT (false);
1535  break;
1536  }
1537  }
1538 }
1539 
1540 void
1542 {
1543  NS_LOG_FUNCTION (this);
1544  switch (m_state->GetState ())
1545  {
1546  case WifiPhyState::TX:
1547  case WifiPhyState::RX:
1548  case WifiPhyState::IDLE:
1551  case WifiPhyState::SLEEP:
1552  {
1553  NS_LOG_DEBUG ("not in off mode, there is nothing to resume");
1554  break;
1555  }
1556  case WifiPhyState::OFF:
1557  {
1558  NS_LOG_DEBUG ("resuming from off mode");
1560  m_state->SwitchFromOff (delayUntilCcaEnd);
1561  break;
1562  }
1563  default:
1564  {
1565  NS_ASSERT (false);
1566  break;
1567  }
1568  }
1569 }
1570 
1571 Time
1573 {
1574  return MicroSeconds (4);
1575 }
1576 
1577 Time
1579 {
1580  return MicroSeconds (4);
1581 }
1582 
1583 Time
1584 WifiPhy::GetPayloadDuration (uint32_t size, const WifiTxVector& txVector, WifiPhyBand band, MpduType mpdutype, uint16_t staId)
1585 {
1586  uint32_t totalAmpduSize;
1587  double totalAmpduNumSymbols;
1588  return GetPayloadDuration (size, txVector, band, mpdutype, false, totalAmpduSize, totalAmpduNumSymbols, staId);
1589 }
1590 
1591 Time
1592 WifiPhy::GetPayloadDuration (uint32_t size, const WifiTxVector& txVector, WifiPhyBand band, MpduType mpdutype,
1593  bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols,
1594  uint16_t staId)
1595 {
1596  return GetStaticPhyEntity (txVector.GetModulationClass ())->GetPayloadDuration (size, txVector, band, mpdutype,
1597  incFlag, totalAmpduSize, totalAmpduNumSymbols,
1598  staId);
1599 }
1600 
1601 Time
1603 {
1605 }
1606 
1607 Time
1609 {
1610  return GetStaticPhyEntity (txVector.GetModulationClass ())->GetDuration (field, txVector);
1611 }
1612 
1613 Time
1614 WifiPhy::CalculateTxDuration (uint32_t size, const WifiTxVector& txVector, WifiPhyBand band, uint16_t staId)
1615 {
1616  Time duration = CalculatePhyPreambleAndHeaderDuration (txVector)
1617  + GetPayloadDuration (size, txVector, band, NORMAL_MPDU, staId);
1618  NS_ASSERT (duration.IsStrictlyPositive ());
1619  return duration;
1620 }
1621 
1622 Time
1624 {
1625  return CalculateTxDuration (GetWifiConstPsduMap (psdu, txVector), txVector, band);
1626 }
1627 
1628 Time
1630 {
1631  return GetStaticPhyEntity (txVector.GetModulationClass ())->CalculateTxDuration (psduMap, txVector, band);
1632 }
1633 
1634 uint32_t
1636 {
1637  return GetStaticPhyEntity (modulation)->GetMaxPsduSize ();
1638 }
1639 
1640 void
1642 {
1643  for (auto const& psdu : psdus)
1644  {
1645  for (auto& mpdu : *PeekPointer (psdu.second))
1646  {
1647  m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW);
1648  }
1649  }
1650 }
1651 
1652 void
1654 {
1655  for (auto const& psdu : psdus)
1656  {
1657  for (auto& mpdu : *PeekPointer (psdu.second))
1658  {
1659  m_phyTxEndTrace (mpdu->GetProtocolDataUnit ());
1660  }
1661  }
1662 }
1663 
1664 void
1666 {
1667  for (auto& mpdu : *PeekPointer (psdu))
1668  {
1669  m_phyTxDropTrace (mpdu->GetProtocolDataUnit ());
1670  }
1671 }
1672 
1673 void
1675 {
1676  if (psdu)
1677  {
1678  for (auto& mpdu : *PeekPointer (psdu))
1679  {
1680  m_phyRxBeginTrace (mpdu->GetProtocolDataUnit (), rxPowersW);
1681  }
1682  }
1683 }
1684 
1685 void
1687 {
1688  if (psdu)
1689  {
1690  for (auto& mpdu : *PeekPointer (psdu))
1691  {
1692  m_phyRxEndTrace (mpdu->GetProtocolDataUnit ());
1693  }
1694  }
1695 }
1696 
1697 void
1699 {
1700  if (psdu)
1701  {
1702  for (auto& mpdu : *PeekPointer (psdu))
1703  {
1704  m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason);
1705  }
1706  }
1707 }
1708 
1709 void
1710 WifiPhy::NotifyMonitorSniffRx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector,
1711  SignalNoiseDbm signalNoise, std::vector<bool> statusPerMpdu, uint16_t staId)
1712 {
1713  MpduInfo aMpdu;
1714  if (psdu->IsAggregate ())
1715  {
1716  //Expand A-MPDU
1717  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
1719  size_t nMpdus = psdu->GetNMpdus ();
1720  NS_ASSERT_MSG (statusPerMpdu.size () == nMpdus, "Should have one reception status per MPDU");
1721  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1722  for (size_t i = 0; i < nMpdus;)
1723  {
1724  if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer
1725  {
1726  m_phyMonitorSniffRxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, signalNoise, staId);
1727  }
1728  ++i;
1729  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1730  }
1731  }
1732  else
1733  {
1734  aMpdu.type = NORMAL_MPDU;
1735  NS_ASSERT_MSG (statusPerMpdu.size () == 1, "Should have one reception status for normal MPDU");
1736  m_phyMonitorSniffRxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, signalNoise, staId);
1737  }
1738 }
1739 
1740 void
1741 WifiPhy::NotifyMonitorSniffTx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector, uint16_t staId)
1742 {
1743  MpduInfo aMpdu;
1744  if (psdu->IsAggregate ())
1745  {
1746  //Expand A-MPDU
1747  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
1749  size_t nMpdus = psdu->GetNMpdus ();
1750  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
1751  for (size_t i = 0; i < nMpdus;)
1752  {
1753  m_phyMonitorSniffTxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, staId);
1754  ++i;
1755  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1756  }
1757  }
1758  else
1759  {
1760  aMpdu.type = NORMAL_MPDU;
1761  m_phyMonitorSniffTxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, staId);
1762  }
1763 }
1764 
1767 {
1768  return GetStaticPhyEntity (txVector.GetModulationClass ())->GetWifiConstPsduMap (psdu, txVector);
1769 }
1770 
1771 void
1773 {
1774  NS_LOG_FUNCTION (this << *psdu << txVector);
1775  Send (GetWifiConstPsduMap (psdu, txVector), txVector);
1776 }
1777 
1778 void
1780 {
1781  NS_LOG_FUNCTION (this << psdus << txVector);
1782  /* Transmission can happen if:
1783  * - we are syncing on a packet. It is the responsibility of the
1784  * MAC layer to avoid doing this but the PHY does nothing to
1785  * prevent it.
1786  * - we are idle
1787  */
1788  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
1790 
1791  if (txVector.GetNssMax () > GetMaxSupportedTxSpatialStreams ())
1792  {
1793  NS_FATAL_ERROR ("Unsupported number of spatial streams!");
1794  }
1795 
1796  if (m_state->IsStateSleep ())
1797  {
1798  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
1799  for (auto const& psdu : psdus)
1800  {
1801  NotifyTxDrop (psdu.second);
1802  }
1803  return;
1804  }
1805 
1806  Time txDuration = CalculateTxDuration (psdus, txVector, GetPhyBand ());
1807 
1808  bool noEndPreambleDetectionEvent = true;
1809  for (const auto & it : m_phyEntities)
1810  {
1811  noEndPreambleDetectionEvent &= it.second->NoEndPreambleDetectionEvents ();
1812  }
1813  if (!noEndPreambleDetectionEvent || ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))))
1814  {
1816  //that packet will be noise _after_ the transmission.
1818  }
1819 
1820  for (auto & it : m_phyEntities)
1821  {
1822  it.second->CancelRunningEndPreambleDetectionEvents ();
1823  }
1824  m_currentPreambleEvents.clear ();
1826 
1827  if (m_powerRestricted)
1828  {
1829  NS_LOG_DEBUG ("Transmitting with power restriction for " << txDuration.As (Time::NS));
1830  }
1831  else
1832  {
1833  NS_LOG_DEBUG ("Transmitting without power restriction for " << txDuration.As (Time::NS));
1834  }
1835 
1836  if (m_state->GetState () == WifiPhyState::OFF)
1837  {
1838  NS_LOG_DEBUG ("Transmission canceled because device is OFF");
1839  return;
1840  }
1841 
1842  Ptr<WifiPpdu> ppdu = GetPhyEntity (txVector.GetModulationClass ())->BuildPpdu (psdus, txVector, txDuration);
1843  m_previouslyRxPpduUid = UINT64_MAX; //reset (after creation of PPDU) to use it only once
1844 
1845  double txPowerW = DbmToW (GetTxPowerForTransmission (ppdu) + GetTxGain ());
1846  NotifyTxBegin (psdus, txPowerW);
1847  m_phyTxPsduBeginTrace (psdus, txVector, txPowerW);
1848  for (auto const& psdu : psdus)
1849  {
1850  NotifyMonitorSniffTx (psdu.second, GetFrequency (), txVector, psdu.first);
1851  }
1852  m_state->SwitchToTx (txDuration, psdus, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
1853 
1854  if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
1855  {
1856  ppdu->SetTruncatedTx ();
1857  }
1858 
1859  m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdus); //TODO: fix for MU
1860 
1861  StartTx (ppdu);
1862 
1863  m_channelAccessRequested = false;
1864  m_powerRestricted = false;
1865 
1866  Simulator::Schedule (txDuration, &WifiPhy::Reset, this);
1867 }
1868 
1869 uint64_t
1871 {
1872  return m_previouslyRxPpduUid;
1873 }
1874 
1875 void
1877 {
1878  NS_LOG_FUNCTION (this);
1879  m_currentPreambleEvents.clear ();
1880  m_currentEvent = 0;
1881  for (auto & phyEntity : m_phyEntities)
1882  {
1883  phyEntity.second->CancelAllEvents ();
1884  }
1885 }
1886 
1887 void
1889 {
1890  WifiModulationClass modulation = ppdu->GetTxVector ().GetModulationClass ();
1891  auto it = m_phyEntities.find (modulation);
1892  if (it != m_phyEntities.end ())
1893  {
1894  it->second->StartReceivePreamble (ppdu, rxPowersW, rxDuration);
1895  }
1896  else
1897  {
1898  //TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble structure)
1899  NS_LOG_DEBUG ("Unsupported modulation received (" << modulation << "), consider as noise");
1900  if (ppdu->GetTxDuration () > m_state->GetDelayUntilIdle ())
1901  {
1903  }
1904  }
1905 }
1906 
1907 void
1908 WifiPhy::MaybeCcaBusyDuration (uint16_t channelWidth)
1909 {
1910  //We are here because we have received the first bit of a packet and we are
1911  //not going to be able to synchronize on it
1912  //In this model, CCA becomes busy when the aggregation of all signals as
1913  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
1914  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetPrimaryBand (channelWidth));
1915  if (!delayUntilCcaEnd.IsZero ())
1916  {
1917  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
1918  }
1919 }
1920 
1922 WifiPhy::ConvertHeRuSubcarriers (uint16_t bandWidth, uint16_t guardBandwidth,
1923  HeRu::SubcarrierRange range, uint8_t bandIndex) const
1924 {
1925  NS_ASSERT_MSG (false, "802.11ax can only be used with SpectrumWifiPhy");
1926  WifiSpectrumBand convertedSubcarriers;
1927  return convertedSubcarriers;
1928 }
1929 
1930 void
1932 {
1933  NS_LOG_FUNCTION (this);
1935  {
1936  m_powerRestricted = false;
1937  }
1938 }
1939 
1940 void
1942 {
1943  NS_LOG_FUNCTION (this << *event);
1944  NS_ASSERT (!IsStateRx ());
1946  m_currentEvent = 0;
1947  m_currentPreambleEvents.clear ();
1948  MaybeCcaBusyDuration (GetMeasurementChannelWidth (event->GetPpdu ()));
1949 }
1950 
1951 void
1953 {
1954  NS_LOG_FUNCTION (this);
1955  m_channelAccessRequested = true;
1956 }
1957 
1958 bool
1960 {
1961  for (const auto & phyEntity : m_phyEntities)
1962  {
1963  if (phyEntity.second->IsModeSupported (mode))
1964  {
1965  return true;
1966  }
1967  }
1968  return false;
1969 }
1970 
1971 WifiMode
1973 {
1974  //Start from oldest standards and move up (guaranteed by fact that WifModulationClass is ordered)
1975  for (const auto & phyEntity : m_phyEntities)
1976  {
1977  for (const auto & mode : *(phyEntity.second))
1978  {
1979  return mode;
1980  }
1981  }
1982  NS_ASSERT_MSG (false, "Should have found at least one default mode");
1983  return WifiMode ();
1984 }
1985 
1986 bool
1987 WifiPhy::IsMcsSupported (WifiModulationClass modulation, uint8_t mcs) const
1988 {
1989  const auto phyEntity = m_phyEntities.find (modulation);
1990  if (phyEntity == m_phyEntities.end ())
1991  {
1992  return false;
1993  }
1994  return phyEntity->second->IsMcsSupported (mcs);
1995 }
1996 
1997 std::list<WifiMode>
1999 {
2000  std::list<WifiMode> list;
2001  for (const auto & phyEntity : m_phyEntities)
2002  {
2003  if (!phyEntity.second->HandlesMcsModes ()) //to exclude MCSs from search
2004  {
2005  for (const auto & mode : *(phyEntity.second))
2006  {
2007  list.emplace_back (mode);
2008  }
2009  }
2010  }
2011  return list;
2012 }
2013 
2014 std::list<WifiMode>
2016 {
2017  std::list<WifiMode> list;
2018  const auto phyEntity = m_phyEntities.find (modulation);
2019  if (phyEntity != m_phyEntities.end ())
2020  {
2021  if (!phyEntity->second->HandlesMcsModes ()) //to exclude MCSs from search
2022  {
2023  for (const auto & mode : *(phyEntity->second))
2024  {
2025  list.emplace_back (mode);
2026  }
2027  }
2028  }
2029  return list;
2030 }
2031 
2032 uint16_t
2033 WifiPhy::GetNMcs (void) const
2034 {
2035  uint16_t numMcs = 0;
2036  for (const auto & phyEntity : m_phyEntities)
2037  {
2038  if (phyEntity.second->HandlesMcsModes ()) //to exclude non-MCS modes from search
2039  {
2040  numMcs += phyEntity.second->GetNumModes ();
2041  }
2042  }
2043  return numMcs;
2044 }
2045 
2046 std::list<WifiMode>
2048 {
2049  std::list<WifiMode> list;
2050  for (const auto & phyEntity : m_phyEntities)
2051  {
2052  if (phyEntity.second->HandlesMcsModes ()) //to exclude non-MCS modes from search
2053  {
2054  for (const auto & mode : *(phyEntity.second))
2055  {
2056  list.emplace_back (mode);
2057  }
2058  }
2059  }
2060  return list;
2061 }
2062 
2063 std::list<WifiMode>
2065 {
2066  std::list<WifiMode> list;
2067  auto phyEntity = m_phyEntities.find (modulation);
2068  if (phyEntity != m_phyEntities.end ())
2069  {
2070  if (phyEntity->second->HandlesMcsModes ()) //to exclude non-MCS modes from search
2071  {
2072  for (const auto & mode : *(phyEntity->second))
2073  {
2074  list.emplace_back (mode);
2075  }
2076  }
2077  }
2078  return list;
2079 }
2080 
2081 WifiMode
2082 WifiPhy::GetMcs (WifiModulationClass modulation, uint8_t mcs) const
2083 {
2084  NS_ASSERT_MSG (IsMcsSupported (modulation, mcs), "Unsupported MCS");
2085  return m_phyEntities.at (modulation)->GetMcs (mcs);
2086 }
2087 
2088 bool
2090 {
2091  return m_state->IsStateCcaBusy ();
2092 }
2093 
2094 bool
2096 {
2097  return m_state->IsStateIdle ();
2098 }
2099 
2100 bool
2102 {
2103  return m_state->IsStateRx ();
2104 }
2105 
2106 bool
2108 {
2109  return m_state->IsStateTx ();
2110 }
2111 
2112 bool
2114 {
2115  return m_state->IsStateSwitching ();
2116 }
2117 
2118 bool
2120 {
2121  return m_state->IsStateSleep ();
2122 }
2123 
2124 bool
2126 {
2127  return m_state->IsStateOff ();
2128 }
2129 
2130 Time
2132 {
2133  return m_state->GetDelayUntilIdle ();
2134 }
2135 
2136 Time
2138 {
2139  return m_state->GetLastRxStartTime ();
2140 }
2141 
2142 Time
2144 {
2145  return m_state->GetLastRxEndTime ();
2146 }
2147 
2148 void
2149 WifiPhy::SwitchMaybeToCcaBusy (uint16_t channelWidth)
2150 {
2151  NS_LOG_FUNCTION (this << channelWidth);
2152  //We are here because we have received the first bit of a packet and we are
2153  //not going to be able to synchronize on it
2154  //In this model, CCA becomes busy when the aggregation of all signals as
2155  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2156  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetPrimaryBand (channelWidth));
2157  if (!delayUntilCcaEnd.IsZero ())
2158  {
2159  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
2160  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
2161  }
2162 }
2163 
2164 void
2166 {
2167  NS_LOG_FUNCTION (this << reason);
2168  if (reason != OBSS_PD_CCA_RESET || m_currentEvent) //Otherwise abort has already been called previously
2169  {
2170  for (auto & phyEntity : m_phyEntities)
2171  {
2172  phyEntity.second->CancelAllEvents ();
2173  }
2174  if (m_endPhyRxEvent.IsRunning ())
2175  {
2177  }
2179  if (!m_currentEvent)
2180  {
2181  return;
2182  }
2183  NotifyRxDrop (GetAddressedPsduInPpdu (m_currentEvent->GetPpdu ()), reason);
2184  if (reason == OBSS_PD_CCA_RESET)
2185  {
2186  m_state->SwitchFromRxAbort ();
2187  }
2188  for (auto it = m_currentPreambleEvents.begin (); it != m_currentPreambleEvents.end (); ++it)
2189  {
2190  if (it->second == m_currentEvent)
2191  {
2192  it = m_currentPreambleEvents.erase (it);
2193  break;
2194  }
2195  }
2196  m_currentEvent = 0;
2197  }
2198 }
2199 
2200 void
2201 WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
2202 {
2203  NS_LOG_FUNCTION (this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2204  // This method might be called multiple times when receiving TB PPDUs with a BSS color
2205  // different than the one of the receiver. The first time this method is called, the call
2206  // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2207  // m_currentEvent is not 0 before executing the instructions below.
2208  if (m_currentEvent != 0)
2209  {
2210  m_powerRestricted = powerRestricted;
2211  m_txPowerMaxSiso = txPowerMaxSiso;
2212  m_txPowerMaxMimo = txPowerMaxMimo;
2213  NS_ASSERT ((m_currentEvent->GetEndTime () - Simulator::Now ()).IsPositive ());
2215  Simulator::ScheduleNow (&WifiPhy::AbortCurrentReception, this, OBSS_PD_CCA_RESET); //finish processing field first
2216  }
2217 }
2218 
2219 double
2221 {
2222  NS_LOG_FUNCTION (this << m_powerRestricted << ppdu);
2223  const WifiTxVector& txVector = ppdu->GetTxVector ();
2224  // Get transmit power before antenna gain
2225  double txPowerDbm;
2226  if (!m_powerRestricted)
2227  {
2228  txPowerDbm = GetPowerDbm (txVector.GetTxPowerLevel ());
2229  }
2230  else
2231  {
2232  if (txVector.GetNssMax () > 1)
2233  {
2234  txPowerDbm = std::min (m_txPowerMaxMimo, GetPowerDbm (txVector.GetTxPowerLevel ()));
2235  }
2236  else
2237  {
2238  txPowerDbm = std::min (m_txPowerMaxSiso, GetPowerDbm (txVector.GetTxPowerLevel ()));
2239  }
2240  }
2241 
2242  //Apply power density constraint on EIRP
2243  uint16_t channelWidth = GetPhyEntity (txVector.GetModulationClass ())->GetTransmissionChannelWidth (ppdu);
2244  double txPowerDbmPerMhz = (txPowerDbm + GetTxGain ()) - RatioToDb (channelWidth); //account for antenna gain since EIRP
2245  NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz << " over " << channelWidth << " MHz");
2246  txPowerDbm = std::min (txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb (channelWidth);
2247  txPowerDbm -= GetTxGain (); //remove antenna gain since will be added right afterwards
2248  NS_LOG_INFO ("txPowerDbm=" << txPowerDbm << " after applying m_powerDensityLimit=" << m_powerDensityLimit);
2249  return txPowerDbm;
2250 }
2251 
2254 {
2255  //TODO: wrapper. See if still needed
2256  return GetPhyEntity (ppdu->GetModulation ())->GetAddressedPsduInPpdu (ppdu);
2257 }
2258 
2259 uint16_t
2261 {
2262  if (ppdu == nullptr)
2263  {
2264  // Here because PHY was not receiving anything (e.g. resuming from OFF) nor expecting anything (e.g. sleep)
2265  // nor processing a Wi-Fi signal.
2266  return GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
2267  }
2268  return GetPhyEntity (ppdu->GetModulation ())->GetMeasurementChannelWidth (ppdu);
2269 }
2270 
2272 WifiPhy::GetBand (uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
2273 {
2274  WifiSpectrumBand band;
2275  band.first = 0;
2276  band.second = 0;
2277  return band;
2278 }
2279 
2281 WifiPhy::GetPrimaryBand (uint16_t bandWidth)
2282 {
2283  if (GetChannelWidth () % 20 != 0)
2284  {
2285  return GetBand (bandWidth);
2286  }
2287 
2288  return GetBand (bandWidth, m_operatingChannel.GetPrimaryChannelIndex (bandWidth));
2289 }
2290 
2291 int64_t
2292 WifiPhy::AssignStreams (int64_t stream)
2293 {
2294  NS_LOG_FUNCTION (this << stream);
2295  m_random->SetStream (stream);
2296  return 1;
2297 }
2298 
2299 std::ostream& operator<< (std::ostream& os, RxSignalInfo rxSignalInfo)
2300 {
2301  os << "SNR:" << RatioToDb (rxSignalInfo.snr) << " dB"
2302  << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2303  return os;
2304 }
2305 
2306 } //namespace ns3
ERP-OFDM PHY (Clause 19, Section 19.5)
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802...
MpduInfo structure.
Definition: phy-entity.h:59
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1698
Ptr< NetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:1424
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
void NotifyRxEnd(Time endTime)
Notify that RX has ended.
uint8_t GetNTxPower(void) const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:730
bool IsStateSwitching(void) const
Definition: wifi-phy.cc:2113
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:926
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
bool IsStateOff(void) const
Definition: wifi-phy.cc:2125
TracedCallback< Ptr< const Packet >, RxPowerWattPerChannelBand > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: wifi-phy.h:1318
static Time GetStartOfPacketDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1578
nanosecond
Definition: nstime.h:118
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.
uint8_t GetNssMax(void) const
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
bool IsSingle(void) const
Return true if the PSDU is an S-MPDU.
Definition: wifi-psdu.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
void NotifyTxBegin(WifiConstPsduMap psdus, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:1641
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class, for the WifiPhy instance...
Definition: wifi-phy.cc:876
Ptr< Packet > GetAmpduSubframe(std::size_t i) const
Get a copy of the i-th A-MPDU subframe (includes subframe header, MPDU, and possibly padding) ...
Definition: wifi-psdu.cc:290
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
void SetNTxPower(uint8_t n)
Sets the number of transmission power levels available between the minimum level and the maximum leve...
Definition: wifi-phy.cc:723
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:1406
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
double GetRxGain(void) const
Return the reception gain (dB).
Definition: wifi-phy.cc:756
static std::map< WifiModulationClass, Ptr< PhyEntity > > m_staticPhyEntities
Map of implemented PHY entities.
Definition: wifi-phy.h:1385
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:1959
void AddSupportedChannelWidth(uint16_t width)
Definition: wifi-phy.cc:1440
double GetCcaEdThreshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:683
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
void NotifyTxEnd(WifiConstPsduMap psdus)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:1653
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:1405
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted...
Definition: wifi-phy.cc:2165
virtual ~WifiPhy()
Definition: wifi-phy.cc:588
Time DoChannelSwitch(void)
Perform any actions necessary when user changes operating channel after initialization.
Definition: wifi-phy.cc:1297
void ResumeFromOff(void)
Resume from off mode.
Definition: wifi-phy.cc:1541
Ptr< WifiPhyStateHelper > GetState(void) const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:627
void ResumeFromSleep(void)
Resume from sleep mode.
Definition: wifi-phy.cc:1510
#define min(a, b)
Definition: 80211b.c:42
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:1403
void SetOperatingChannel(uint8_t number, uint16_t frequency, uint16_t width)
Set the operating channel according to the specified parameters.
Definition: wifi-phy.cc:1254
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition: wifi-ppdu.h:38
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1122
Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: wifi-phy.cc:2253
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:736
void Configure80211ax(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard...
Definition: wifi-phy.cc:1052
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:663
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:85
virtual void ConfigureStandardAndBand(WifiPhyStandard standard, WifiPhyBand band)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1067
virtual void DoDispose(void)
Destructor implementation.
Definition: wifi-phy.cc:594
def start()
Definition: core.py:1855
double m_powerDensityLimit
the power density limit (dBm/MHz)
Definition: wifi-phy.h:1410
The PHY layer is sleeping.
std::list< WifiMode > GetModeList(void) const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1998
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1342
WifiSpectrumBand GetPrimaryBand(uint16_t bandWidth)
If the operating channel width is a multiple of 20 MHz, return the start band index and the stop band...
Definition: wifi-phy.cc:2281
bool IsStateCcaBusy(void) const
Definition: wifi-phy.cc:2089
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:639
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool IsInitialized(void) const
Check if the object has been initialized.
Definition: object.cc:208
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:411
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:914
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:762
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1334
uint16_t GetFrequency(void) const
Return the center frequency of the operating channel (in MHz).
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1180
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:787
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:651
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
void SetRxNoiseFigure(double noiseFigureDb)
Sets the RX loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
Definition: wifi-phy.cc:689
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
bool IsStateIdle(void) const
Definition: wifi-phy.cc:2095
Class that keeps track of all information about the current PHY operating channel.
void Reset(void)
Definition: wifi-phy.cc:1876
The 5 GHz band.
Definition: wifi-phy-band.h:37
TracedCallback< Ptr< const Packet >, WifiPhyRxfailureReason > m_phyRxDropTrace
The trace source fired when the PHY layer drops a packet it has received.
Definition: wifi-phy.h:1349
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1922
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:1409
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm, uint16_t > m_phyMonitorSniffRxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being received...
Definition: wifi-phy.h:1363
std::list< WifiMode > GetMcsList(void) const
The WifiPhy::GetMcsList() method is used (e.g., by a WifiRemoteStationManager) to determine the set o...
Definition: wifi-phy.cc:2047
virtual void SetFrequency(uint16_t freq)
If the operating channel for this object has not been set yet, the given center frequency is saved an...
Definition: wifi-phy.cc:1141
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition: wifi-phy.cc:862
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:820
void ResetCca(bool powerRestricted, double txPowerMaxSiso=0, double txPowerMaxMimo=0)
Reset PHY to IDLE, with some potential TX power restrictions for the next transmission.
Definition: wifi-phy.cc:2201
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:63
uint8_t m_initialChannelNumber
Store channel number until initialization.
Definition: wifi-phy.h:1390
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1686
bool IsStateSleep(void) const
Definition: wifi-phy.cc:2119
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
MpduType
The type of an MPDU.
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
Definition: he-ru.h:53
double GetRxSensitivity(void) const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:670
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
mobility
Definition: third.py:108
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:775
HR/DSSS (Clause 16)
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1231
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:1412
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1614
void SwitchMaybeToCcaBusy(uint16_t channelWidth)
Check if PHY state should move to CCA busy state based on current state of interference tracker...
Definition: wifi-phy.cc:2149
Keep track of the current position and velocity of an object.
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
The MPDU is not part of an A-MPDU.
Ptr< const Packet > GetPacket(void) const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:87
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:66
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate...
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:868
WifiMode GetMcs(WifiModulationClass modulation, uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the given modulation class.
Definition: wifi-phy.cc:2082
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:227
Time m_slot
Slot duration.
Definition: wifi-phy.h:1398
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:1425
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:588
AttributeValue implementation for Time.
Definition: nstime.h:1353
double rssi
RSSI in dBm.
Definition: phy-entity.h:69
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
Definition: wifi-phy.cc:1237
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:1401
receive notifications about PHY events.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the PHY layer drops a packet as it tries to transmit it.
Definition: wifi-phy.h:1310
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1414
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:1417
uint16_t GetWidth(void) const
Return the width of the whole operating channel (in MHz).
static WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
Definition: wifi-phy.cc:1766
Hold an unsigned integer type.
Definition: uinteger.h:44
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1181
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:1429
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:710
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:826
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate...
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1952
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1186
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
WifiPpduField
The type of PPDU field (grouped for convenience)
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const
Return the channel width used to measure the RSSI.
Definition: wifi-phy.cc:2260
The PHY layer has sense the medium busy through the CCA mechanism.
Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:2131
OFDM PHY (Clause 17 - amendment for 10 MHz and 5 MHz channels)
uint8_t m_initialPrimary20Index
Store the index of primary20 until initialization.
Definition: wifi-phy.h:1392
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1178
std::list< uint8_t > GetBssMembershipSelectorList(void) const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1425
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:657
void SetOffMode(void)
Put in off mode.
Definition: wifi-phy.cc:1495
void AddPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of supported PHY entities for the given modulation class for the WifiPh...
Definition: wifi-phy.cc:892
#define list
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1428
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:838
WifiPhyStandard GetPhyStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1129
Time GetBlockAckTxTime(void) const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:944
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:806
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
TracedCallback< WifiConstPsduMap, WifiTxVector, double > m_phyTxPsduBeginTrace
The trace source fired when a PSDU map begins the transmission process on the medium.
Definition: wifi-phy.h:1294
Ptr< MobilityModel > GetMobility(void) const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:793
static Time GetPreambleDetectionDuration(void)
Definition: wifi-phy.cc:1572
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:1399
void Set(uint8_t number, uint16_t frequency, uint16_t width, WifiPhyStandard standard, WifiPhyBand band)
Set the channel according to the specified parameters if a unique frequency channel matches the speci...
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:813
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-phy.cc:297
std::size_t GetNMpdus(void) const
Return the number of MPDUs constituting the PSDU.
Definition: wifi-psdu.cc:319
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:856
OFDM PHY (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:1388
Hold objects of type Ptr<T>.
Definition: pointer.h:36
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
Definition: wifi-phy.h:61
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:832
void EraseEvents(void)
Erase all events.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1166
The PHY layer is IDLE.
uint8_t GetNumberOfAntennas(void) const
Definition: wifi-phy.cc:1370
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1635
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:1665
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:1397
TracedCallback< Ptr< const Packet >, double > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
Definition: wifi-phy.h:1287
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
virtual void StartTx(Ptr< WifiPpdu > ppdu)=0
uint8_t GetNumber(void) const
Return the channel number identifying the whole operating channel.
void SetDefault(uint16_t width, WifiPhyStandard standard, WifiPhyBand band)
Set the default channel of the given width and for the given PHY standard and band.
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1888
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > m_currentPreambleEvents
store event associated to a PPDU (that has a unique ID and preamble combination) whose preamble is be...
Definition: wifi-phy.h:1184
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1407
bool GetShortPhyPreambleSupported(void) const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:769
double m_ccaEdThresholdW
Clear channel assessment (CCA) threshold in watts.
Definition: wifi-phy.h:1404
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1172
Time GetPifs(void) const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:932
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:938
void Configure80211ac(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard...
Definition: wifi-phy.cc:1044
WifiMode GetDefaultMode(void) const
Get the default WifiMode supported by the PHY.
Definition: wifi-phy.cc:1972
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1354
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:47
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class...
Definition: wifi-phy.cc:884
uint8_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:1197
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
WifiPhyStandard m_standard
WifiPhyStandard.
Definition: wifi-phy.h:1387
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:1415
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1174
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:35
uint64_t GetPreviouslyRxPpduUid(void) const
Definition: wifi-phy.cc:1870
bool IsSet(void) const
Return true if a valid channel has been set, false otherwise.
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:1419
double GetTxPowerStart(void) const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:704
Time m_ackTxTime
estimated Ack TX time
Definition: wifi-phy.h:1400
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1430
std::vector< uint16_t > GetSupportedChannelWidthSet(void) const
Definition: wifi-phy.cc:1455
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1427
#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:88
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
void SetRxGain(double gain)
Sets the reception gain (dB).
Definition: wifi-phy.cc:749
void Configure80211b(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard...
Definition: wifi-phy.cc:965
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:32
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:902
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:633
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:645
bool IsStateTx(void) const
Definition: wifi-phy.cc:2107
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, RxPowerWattPerChannelBand rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1674
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1376
The PHY layer is sending a packet.
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1175
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
void Configure80211n(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard...
Definition: wifi-phy.cc:1025
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:697
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:1407
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:908
uint16_t GetDefaultChannelWidth(WifiPhyStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
void SetNoiseFigure(double value)
Set the noise figure.
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the packet under reception after it has failed the PHY header.
Definition: wifi-phy.cc:1941
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2220
SignalNoiseDbm structure.
Definition: phy-entity.h:52
uint32_t mpduRefNumber
MPDU ref number.
Definition: phy-entity.h:62
InterferenceHelper m_interference
the class handling interference computations
Definition: wifi-phy.h:1173
double snr
SNR in linear scale.
Definition: phy-entity.h:68
virtual void SetChannelWidth(uint16_t channelWidth)
If the operating channel for this object has not been set yet, the given channel width is saved and w...
Definition: wifi-phy.cc:1203
bool IsStrictlyNegative(void) const
Exactly equivalent to t < 0.
Definition: nstime.h:325
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
The PHY layer is receiving a packet.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1394
static Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1584
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
double GetTxPowerEnd(void) const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:717
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:920
void EndReceiveInterBss(void)
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:1931
void NotifyMonitorSniffTx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being transmitted.
Definition: wifi-phy.cc:1741
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1602
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument...
Definition: wifi-phy.cc:1772
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
The PHY layer is switched off.
void Configure80211g(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard...
Definition: wifi-phy.cc:982
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:781
uint8_t GetTxPowerLevel(void) const
double GetTxGain(void) const
Return the transmission gain (dB).
Definition: wifi-phy.cc:743
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
The PHY layer is switching to other channel.
void SetSleepMode(void)
Put in sleep mode.
Definition: wifi-phy.cc:1461
void NotifyMonitorSniffRx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, SignalNoiseDbm signalNoise, std::vector< bool > statusPerMpdu, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being received. ...
Definition: wifi-phy.cc:1710
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
The 6 GHz band.
Definition: wifi-phy-band.h:39
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1362
uint16_t m_initialChannelWidth
Store channel width (MHz) until initialization.
Definition: wifi-phy.h:1391
const WifiPhyOperatingChannel & GetOperatingChannel(void) const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1135
second
Definition: nstime.h:115
A base class which provides memory management and object aggregation.
Definition: object.h:87
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:1408
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
void Configure80211p(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard...
Definition: wifi-phy.cc:995
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1205
The MPDU is a single MPDU.
MpduType type
type of MPDU
Definition: phy-entity.h:61
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:1422
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2143
void MaybeCcaBusyDuration(uint16_t channelWidth)
Eventually switch to CCA busy.
Definition: wifi-phy.cc:1908
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:45
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:1418
uint8_t GetMaxSupportedTxSpatialStreams(void) const
Definition: wifi-phy.cc:1401
a unique identifier for an interface.
Definition: type-id.h:58
uint16_t GetNMcs(void) const
Definition: wifi-phy.cc:2033
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1183
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
Definition: wifi-phy.cc:2137
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1413
bool IsStateRx(void) const
Definition: wifi-phy.cc:2101
bool IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
Check if the given MCS of the given modulation class is supported by the PHY.
Definition: wifi-phy.cc:1987
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:1420
std::vector< uint16_t > m_supportedChannelWidthSet
Supported channel width set (MHz)
Definition: wifi-phy.h:1395
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, uint16_t > m_phyMonitorSniffTxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being transmitted...
Definition: wifi-phy.h:1377
void SetCcaEdThreshold(double threshold)
Sets the CCA threshold (dBm).
Definition: wifi-phy.cc:676
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: wifi-phy.cc:2292
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
static Time GetPpduFieldDuration(WifiPpduField field, const WifiTxVector &txVector)
Get the duration of the PPDU field (or group of fields) for the given transmission parameters...
Definition: wifi-phy.cc:1608
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:1433
void Configure80211a(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard...
Definition: wifi-phy.cc:950
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1419
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
Definition: wifi-phy.h:1302
uint16_t m_initialFrequency
Store frequency until initialization (MHz)
Definition: wifi-phy.h:1389
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81
virtual WifiSpectrumBand GetBand(uint16_t bandWidth, uint8_t bandIndex=0)
Get the start band index and the stop band index for a given band.
Definition: wifi-phy.cc:2272