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 "ht-configuration.h"
39 #include "he-configuration.h"
40 #include "mpdu-aggregator.h"
41 #include "wifi-psdu.h"
42 
43 namespace ns3 {
44 
45 NS_LOG_COMPONENT_DEFINE ("WifiPhy");
46 
47 /****************************************************************
48  * The actual WifiPhy class
49  ****************************************************************/
50 
52 
62 {
63  //2.4 GHz channels
64  // 802.11b uses width of 22, while OFDM modes use width of 20
65  { { {1, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2412, 22} },
66  { { {1, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2412, 20} },
67  { { {2, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2417, 22} },
68  { { {2, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2417, 20} },
69  { { {3, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2422, 22} },
70  { { {3, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2422, 20} },
71  { { {4, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2427, 22} },
72  { { {4, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2427, 20} },
73  { { {5, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2432, 22} },
74  { { {5, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2432, 20} },
75  { { {6, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2437, 22} },
76  { { {6, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2437, 20} },
77  { { {7, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2442, 22} },
78  { { {7, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2442, 20} },
79  { { {8, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2447, 22} },
80  { { {8, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2447, 20} },
81  { { {9, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2452, 22} },
82  { { {9, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2452, 20} },
83  { { {10, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2457, 22} },
84  { { {10, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2457, 20} },
85  { { {11, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2462, 22} },
86  { { {11, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2462, 20} },
87  { { {12, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2467, 22} },
88  { { {12, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2467, 20} },
89  { { {13, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2472, 22} },
90  { { {13, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {2472, 20} },
91  // Only defined for 802.11b
92  { { {14, WIFI_PHY_BAND_2_4GHZ}, WIFI_PHY_STANDARD_80211b}, {2484, 22} },
93 
94  // Now the 5 GHz channels; UNSPECIFIED for 802.11a/n/ac/ax channels
95  // 20 MHz channels
96  { { {36, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5180, 20} },
97  { { {40, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5200, 20} },
98  { { {44, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5220, 20} },
99  { { {48, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5240, 20} },
100  { { {52, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5260, 20} },
101  { { {56, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5280, 20} },
102  { { {60, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5300, 20} },
103  { { {64, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5320, 20} },
104  { { {100, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5500, 20} },
105  { { {104, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5520, 20} },
106  { { {108, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5540, 20} },
107  { { {112, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5560, 20} },
108  { { {116, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5580, 20} },
109  { { {120, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5600, 20} },
110  { { {124, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5620, 20} },
111  { { {128, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5640, 20} },
112  { { {132, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5660, 20} },
113  { { {136, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5680, 20} },
114  { { {140, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5700, 20} },
115  { { {144, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5720, 20} },
116  { { {149, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5745, 20} },
117  { { {153, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5765, 20} },
118  { { {157, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5785, 20} },
119  { { {161, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5805, 20} },
120  { { {165, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5825, 20} },
121  { { {169, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5845, 20} },
122  { { {173, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5865, 20} },
123  { { {177, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5885, 20} },
124  { { {181, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5905, 20} },
125  // 40 MHz channels
126  { { {38, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5190, 40} },
127  { { {46, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5230, 40} },
128  { { {54, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5270, 40} },
129  { { {62, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5310, 40} },
130  { { {102, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5510, 40} },
131  { { {110, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5550, 40} },
132  { { {118, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5590, 40} },
133  { { {126, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5630, 40} },
134  { { {134, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5670, 40} },
135  { { {142, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5710, 40} },
136  { { {151, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5755, 40} },
137  { { {159, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5795, 40} },
138  { { {167, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5835, 40} },
139  { { {175, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5875, 40} },
140  // 80 MHz channels
141  { { {42, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5210, 80} },
142  { { {58, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5290, 80} },
143  { { {106, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5530, 80} },
144  { { {122, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5610, 80} },
145  { { {138, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5690, 80} },
146  { { {155, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5775, 80} },
147  { { {171, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5855, 80} },
148  // 160 MHz channels
149  { { {50, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5250, 160} },
150  { { {114, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5570, 160} },
151  { { {163, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_UNSPECIFIED}, {5815, 160} },
152 
153  // 802.11p 10 MHz channels at the 5.855-5.925 band
154  { { {172, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5860, 10} },
155  { { {174, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5870, 10} },
156  { { {176, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5880, 10} },
157  { { {178, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5890, 10} },
158  { { {180, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5900, 10} },
159  { { {182, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5910, 10} },
160  { { {184, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5920, 10} },
161 
162  // 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)
163  { { {171, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5860, 5} },
164  { { {173, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5870, 5} },
165  { { {175, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5880, 5} },
166  { { {177, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5890, 5} },
167  { { {179, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5900, 5} },
168  { { {181, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5910, 5} },
169  { { {183, WIFI_PHY_BAND_5GHZ}, WIFI_PHY_STANDARD_80211p}, {5920, 5} },
170 
171  // Now the 6 GHz channels (802.11ax only)
172  // 20 MHz channels
173  { { {1, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5945, 20} },
174  { { {5, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5965, 20} },
175  { { {9, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5985, 20} },
176  { { {13, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6005, 20} },
177  { { {17, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6025, 20} },
178  { { {21, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6045, 20} },
179  { { {25, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6065, 20} },
180  { { {29, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6085, 20} },
181  { { {33, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6105, 20} },
182  { { {37, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6125, 20} },
183  { { {41, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6145, 20} },
184  { { {45, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6165, 20} },
185  { { {49, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6185, 20} },
186  { { {53, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6205, 20} },
187  { { {57, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6225, 20} },
188  { { {61, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6245, 20} },
189  { { {65, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6265, 20} },
190  { { {69, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6285, 20} },
191  { { {73, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6305, 20} },
192  { { {77, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6325, 20} },
193  { { {81, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6345, 20} },
194  { { {85, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6365, 20} },
195  { { {89, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6385, 20} },
196  { { {93, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6405, 20} },
197  { { {97, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6425, 20} },
198  { { {101, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6445, 20} },
199  { { {105, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6465, 20} },
200  { { {109, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6485, 20} },
201  { { {113, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6505, 20} },
202  { { {117, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6525, 20} },
203  { { {121, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6545, 20} },
204  { { {125, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6565, 20} },
205  { { {129, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6585, 20} },
206  { { {133, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6605, 20} },
207  { { {137, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6625, 20} },
208  { { {141, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6645, 20} },
209  { { {145, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6665, 20} },
210  { { {149, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6685, 20} },
211  { { {153, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6705, 20} },
212  { { {157, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6725, 20} },
213  { { {161, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6745, 20} },
214  { { {165, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6765, 20} },
215  { { {169, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6785, 20} },
216  { { {173, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6805, 20} },
217  { { {177, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6825, 20} },
218  { { {181, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6845, 20} },
219  { { {185, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6865, 20} },
220  { { {189, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6885, 20} },
221  { { {193, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6905, 20} },
222  { { {197, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6925, 20} },
223  { { {201, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6945, 20} },
224  { { {205, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6965, 20} },
225  { { {209, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6985, 20} },
226  { { {213, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7005, 20} },
227  { { {217, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7025, 20} },
228  { { {221, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7045, 20} },
229  { { {225, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7065, 20} },
230  { { {229, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7085, 20} },
231  { { {233, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7105, 20} },
232  // 40 MHz channels
233  { { {3, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5955, 40} },
234  { { {11, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5995, 40} },
235  { { {19, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6035, 40} },
236  { { {27, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6075, 40} },
237  { { {35, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6115, 40} },
238  { { {43, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6155, 40} },
239  { { {51, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6195, 40} },
240  { { {59, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6235, 40} },
241  { { {67, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6275, 40} },
242  { { {75, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6315, 40} },
243  { { {83, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6355, 40} },
244  { { {91, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6395, 40} },
245  { { {99, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6435, 40} },
246  { { {107, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6475, 40} },
247  { { {115, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6515, 40} },
248  { { {123, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6555, 40} },
249  { { {131, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6595, 40} },
250  { { {139, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6635, 40} },
251  { { {147, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6675, 40} },
252  { { {155, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6715, 40} },
253  { { {163, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6755, 40} },
254  { { {171, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6795, 40} },
255  { { {179, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6835, 40} },
256  { { {187, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6875, 40} },
257  { { {195, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6915, 40} },
258  { { {203, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6955, 40} },
259  { { {211, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6995, 40} },
260  { { {219, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7035, 40} },
261  { { {227, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7075, 40} },
262  // 80 MHz channels
263  { { {7, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {5975, 80} },
264  { { {23, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6055, 80} },
265  { { {39, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6135, 80} },
266  { { {55, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6215, 80} },
267  { { {71, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6295, 80} },
268  { { {87, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6375, 80} },
269  { { {103, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6455, 80} },
270  { { {119, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6535, 80} },
271  { { {135, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6615, 80} },
272  { { {151, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6695, 80} },
273  { { {167, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6775, 80} },
274  { { {183, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6855, 80} },
275  { { {199, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6935, 80} },
276  { { {215, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {7015, 80} },
277  // 160 MHz channels
278  { { {15, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6015, 160} },
279  { { {47, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6175, 160} },
280  { { {79, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6335, 160} },
281  { { {111, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6495, 160} },
282  { { {143, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6655, 160} },
283  { { {175, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6815, 160} },
284  { { {207, WIFI_PHY_BAND_6GHZ}, WIFI_PHY_STANDARD_80211ax}, {6975, 160} }
285 };
286 
287 TypeId
289 {
290  static TypeId tid = TypeId ("ns3::WifiPhy")
291  .SetParent<Object> ()
292  .SetGroupName ("Wifi")
293  .AddAttribute ("Frequency",
294  "The operating center frequency (MHz)",
295  UintegerValue (0),
298  MakeUintegerChecker<uint16_t> ())
299  .AddAttribute ("ChannelWidth",
300  "Whether 5MHz, 10MHz, 20MHz, 22MHz, 40MHz, 80 MHz or 160 MHz.",
301  UintegerValue (20),
304  MakeUintegerChecker<uint16_t> (5, 160))
305  .AddAttribute ("ChannelNumber",
306  "If set to non-zero defined value, will control Frequency and ChannelWidth assignment",
307  UintegerValue (0),
310  MakeUintegerChecker<uint8_t> (0, 233))
311  .AddAttribute ("RxSensitivity",
312  "The energy of a received signal should be higher than "
313  "this threshold (dBm) for the PHY to detect the signal.",
314  DoubleValue (-101.0),
317  MakeDoubleChecker<double> ())
318  .AddAttribute ("CcaEdThreshold",
319  "The energy of a non Wi-Fi received signal should be higher than "
320  "this threshold (dBm) to allow the PHY layer to declare CCA BUSY state. "
321  "This check is performed on the 20 MHz primary channel only.",
322  DoubleValue (-62.0),
325  MakeDoubleChecker<double> ())
326  .AddAttribute ("TxGain",
327  "Transmission gain (dB).",
328  DoubleValue (0.0),
331  MakeDoubleChecker<double> ())
332  .AddAttribute ("RxGain",
333  "Reception gain (dB).",
334  DoubleValue (0.0),
337  MakeDoubleChecker<double> ())
338  .AddAttribute ("TxPowerLevels",
339  "Number of transmission power levels available between "
340  "TxPowerStart and TxPowerEnd included.",
341  UintegerValue (1),
343  MakeUintegerChecker<uint8_t> ())
344  .AddAttribute ("TxPowerEnd",
345  "Maximum available transmission level (dBm).",
346  DoubleValue (16.0206),
349  MakeDoubleChecker<double> ())
350  .AddAttribute ("TxPowerStart",
351  "Minimum available transmission level (dBm).",
352  DoubleValue (16.0206),
355  MakeDoubleChecker<double> ())
356  .AddAttribute ("RxNoiseFigure",
357  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
358  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
359  "\"the difference in decibels (dB) between"
360  " the noise output of the actual receiver to the noise output of an "
361  " ideal receiver with the same overall gain and bandwidth when the receivers "
362  " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
363  DoubleValue (7),
365  MakeDoubleChecker<double> ())
366  .AddAttribute ("State",
367  "The state of the PHY layer.",
368  PointerValue (),
370  MakePointerChecker<WifiPhyStateHelper> ())
371  .AddAttribute ("ChannelSwitchDelay",
372  "Delay between two short frames transmitted on different frequencies.",
373  TimeValue (MicroSeconds (250)),
375  MakeTimeChecker ())
376  .AddAttribute ("Antennas",
377  "The number of antennas on the device.",
378  UintegerValue (1),
381  MakeUintegerChecker<uint8_t> (1, 8))
382  .AddAttribute ("MaxSupportedTxSpatialStreams",
383  "The maximum number of supported TX spatial streams."
384  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
385  UintegerValue (1),
388  MakeUintegerChecker<uint8_t> (1, 8))
389  .AddAttribute ("MaxSupportedRxSpatialStreams",
390  "The maximum number of supported RX spatial streams."
391  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
392  UintegerValue (1),
395  MakeUintegerChecker<uint8_t> (1, 8))
396  .AddAttribute ("ShortPlcpPreambleSupported",
397  "Whether or not short PHY preamble is supported."
398  "This parameter is only valuable for 802.11b STAs and APs."
399  "Note: 802.11g APs and STAs always support short PHY preamble.",
400  BooleanValue (false),
404  .AddAttribute ("FrameCaptureModel",
405  "Ptr to an object that implements the frame capture model",
406  PointerValue (),
408  MakePointerChecker <FrameCaptureModel> ())
409  .AddAttribute ("PreambleDetectionModel",
410  "Ptr to an object that implements the preamble detection model",
411  PointerValue (),
413  MakePointerChecker <PreambleDetectionModel> ())
414  .AddAttribute ("PostReceptionErrorModel",
415  "An optional packet error model can be added to the receive "
416  "packet process after any propagation-based (SNR-based) error "
417  "models have been applied. Typically this is used to force "
418  "specific packet drops, for testing purposes.",
419  PointerValue (),
421  MakePointerChecker<ErrorModel> ())
422  .AddAttribute ("Sifs",
423  "The duration of the Short Interframe Space. "
424  "NOTE that the default value is overwritten by the value defined "
425  "by the standard; if you want to set this attribute, you have to "
426  "do it after that the PHY object is initialized.",
427  TimeValue (MicroSeconds (0)),
429  MakeTimeChecker ())
430  .AddAttribute ("Slot",
431  "The duration of a slot. "
432  "NOTE that the default value is overwritten by the value defined "
433  "by the standard; if you want to set this attribute, you have to "
434  "do it after that the PHY object is initialized.",
435  TimeValue (MicroSeconds (0)),
437  MakeTimeChecker ())
438  .AddAttribute ("Pifs",
439  "The duration of the PCF Interframe Space. "
440  "NOTE that the default value is overwritten by the value defined "
441  "by the standard; if you want to set this attribute, you have to "
442  "do it after that the PHY object is initialized.",
443  TimeValue (MicroSeconds (0)),
445  MakeTimeChecker ())
446  .AddTraceSource ("PhyTxBegin",
447  "Trace source indicating a packet "
448  "has begun transmitting over the channel medium",
450  "ns3::Packet::TracedCallback")
451  .AddTraceSource ("PhyTxPsduBegin",
452  "Trace source indicating a PSDU "
453  "has begun transmitting over the channel medium",
455  "ns3::WifiPhy::PsduTxBeginCallback")
456  .AddTraceSource ("PhyTxEnd",
457  "Trace source indicating a packet "
458  "has been completely transmitted over the channel.",
460  "ns3::Packet::TracedCallback")
461  .AddTraceSource ("PhyTxDrop",
462  "Trace source indicating a packet "
463  "has been dropped by the device during transmission",
465  "ns3::Packet::TracedCallback")
466  .AddTraceSource ("PhyRxBegin",
467  "Trace source indicating a packet "
468  "has begun being received from the channel medium "
469  "by the device",
471  "ns3::Packet::TracedCallback")
472  .AddTraceSource ("PhyRxPayloadBegin",
473  "Trace source indicating the reception of the "
474  "payload of a PPDU has begun",
476  "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
477  .AddTraceSource ("PhyRxEnd",
478  "Trace source indicating a packet "
479  "has been completely received from the channel medium "
480  "by the device",
482  "ns3::Packet::TracedCallback")
483  .AddTraceSource ("PhyRxDrop",
484  "Trace source indicating a packet "
485  "has been dropped by the device during reception",
487  "ns3::Packet::TracedCallback")
488  .AddTraceSource ("MonitorSnifferRx",
489  "Trace source simulating a wifi device in monitor mode "
490  "sniffing all received frames",
492  "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
493  .AddTraceSource ("MonitorSnifferTx",
494  "Trace source simulating the capability of a wifi device "
495  "in monitor mode to sniff all frames being transmitted",
497  "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
498  .AddTraceSource ("EndOfHePreamble",
499  "Trace source indicating the end of the 802.11ax preamble (after training fields)",
501  "ns3::WifiPhy::EndOfHePreambleTracedCallback")
502  ;
503  return tid;
504 }
505 
507  : m_txMpduReferenceNumber (0xffffffff),
508  m_rxMpduReferenceNumber (0xffffffff),
509  m_endRxEvent (),
510  m_endPhyRxEvent (),
511  m_endPreambleDetectionEvent (),
512  m_endTxEvent (),
513  m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
514  m_band (WIFI_PHY_BAND_UNSPECIFIED),
515  m_isConstructed (false),
516  m_channelCenterFrequency (0),
517  m_initialFrequency (0),
518  m_frequencyChannelNumberInitialized (false),
519  m_channelWidth (0),
520  m_sifs (Seconds (0)),
521  m_slot (Seconds (0)),
522  m_pifs (Seconds (0)),
523  m_ackTxTime (Seconds (0)),
524  m_blockAckTxTime (Seconds (0)),
525  m_powerRestricted (false),
526  m_channelAccessRequested (false),
527  m_txSpatialStreams (0),
528  m_rxSpatialStreams (0),
529  m_channelNumber (0),
530  m_initialChannelNumber (0),
531  m_currentEvent (0),
532  m_wifiRadioEnergyModel (0),
533  m_timeLastPreambleDetected (Seconds (0))
534 {
535  NS_LOG_FUNCTION (this);
536  m_random = CreateObject<UniformRandomVariable> ();
537  m_state = CreateObject<WifiPhyStateHelper> ();
538 }
539 
541 {
542  NS_LOG_FUNCTION (this);
543 }
544 
545 void
547 {
548  NS_LOG_FUNCTION (this);
549  m_endTxEvent.Cancel ();
550  m_endRxEvent.Cancel ();
553  m_device = 0;
554  m_mobility = 0;
555  m_state = 0;
558  m_deviceRateSet.clear ();
559  m_deviceMcsSet.clear ();
560  m_mcsIndexMap.clear ();
561 }
562 
563 void
565 {
566  NS_LOG_FUNCTION (this);
567  m_isConstructed = true;
569  {
570  NS_LOG_DEBUG ("Frequency already initialized");
571  return;
572  }
574 }
575 
577 WifiPhy::GetState (void) const
578 {
579  return m_state;
580 }
581 
582 void
584 {
585  m_state->SetReceiveOkCallback (callback);
586 }
587 
588 void
590 {
591  m_state->SetReceiveErrorCallback (callback);
592 }
593 
594 void
596 {
597  m_state->RegisterListener (listener);
598 }
599 
600 void
602 {
603  m_state->UnregisterListener (listener);
604 }
605 
606 void
608 {
610 }
611 
612 void
614 {
615  NS_LOG_FUNCTION (this);
616 
617  NS_ASSERT_MSG (m_frequencyChannelNumberInitialized == false, "Initialization called twice");
618 
619  // If frequency has been set to a non-zero value during attribute
620  // construction phase, the frequency and channel width will drive the
621  // initial configuration. If frequency has not been set, but both
622  // standard and channel number have been set, that pair will instead
623  // drive the configuration, and frequency and channel number will be
624  // aligned
625  if (m_initialFrequency != 0)
626  {
628  }
630  {
632  }
634  {
635  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " was set by user, but neither a standard nor a frequency");
636  }
638 }
639 
640 void
641 WifiPhy::SetRxSensitivity (double threshold)
642 {
643  NS_LOG_FUNCTION (this << threshold);
644  m_rxSensitivityW = DbmToW (threshold);
645 }
646 
647 double
649 {
650  return WToDbm (m_rxSensitivityW);
651 }
652 
653 void
654 WifiPhy::SetCcaEdThreshold (double threshold)
655 {
656  NS_LOG_FUNCTION (this << threshold);
657  m_ccaEdThresholdW = DbmToW (threshold);
658 }
659 
660 double
662 {
663  return WToDbm (m_ccaEdThresholdW);
664 }
665 
666 void
667 WifiPhy::SetRxNoiseFigure (double noiseFigureDb)
668 {
669  NS_LOG_FUNCTION (this << noiseFigureDb);
670  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
672 }
673 
674 void
676 {
677  NS_LOG_FUNCTION (this << start);
679 }
680 
681 double
683 {
684  return m_txPowerBaseDbm;
685 }
686 
687 void
689 {
690  NS_LOG_FUNCTION (this << end);
691  m_txPowerEndDbm = end;
692 }
693 
694 double
696 {
697  return m_txPowerEndDbm;
698 }
699 
700 void
702 {
703  NS_LOG_FUNCTION (this << +n);
704  m_nTxPower = n;
705 }
706 
707 uint8_t
709 {
710  return m_nTxPower;
711 }
712 
713 void
714 WifiPhy::SetTxGain (double gain)
715 {
716  NS_LOG_FUNCTION (this << gain);
717  m_txGainDb = gain;
718 }
719 
720 double
721 WifiPhy::GetTxGain (void) const
722 {
723  return m_txGainDb;
724 }
725 
726 void
727 WifiPhy::SetRxGain (double gain)
728 {
729  NS_LOG_FUNCTION (this << gain);
730  m_rxGainDb = gain;
731 }
732 
733 double
734 WifiPhy::GetRxGain (void) const
735 {
736  return m_rxGainDb;
737 }
738 
739 void
741 {
742  NS_LOG_FUNCTION (this << enable);
743  m_shortPreamble = enable;
744 }
745 
746 bool
748 {
749  return m_shortPreamble;
750 }
751 
752 void
754 {
755  m_device = device;
756 }
757 
759 WifiPhy::GetDevice (void) const
760 {
761  return m_device;
762 }
763 
764 void
766 {
768 }
769 
772 {
773  if (m_mobility != 0)
774  {
775  return m_mobility;
776  }
777  else
778  {
779  return m_device->GetNode ()->GetObject<MobilityModel> ();
780  }
781 }
782 
783 void
785 {
788 }
789 
790 void
792 {
793  NS_LOG_FUNCTION (this << em);
795 }
796 
797 void
799 {
800  m_frameCaptureModel = model;
801 }
802 
803 void
805 {
806  m_preambleDetectionModel = model;
807 }
808 
809 void
811 {
812  m_wifiRadioEnergyModel = wifiRadioEnergyModel;
813 }
814 
815 double
816 WifiPhy::GetPowerDbm (uint8_t power) const
817 {
819  NS_ASSERT (m_nTxPower > 0);
820  double dbm;
821  if (m_nTxPower > 1)
822  {
823  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
824  }
825  else
826  {
827  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
828  dbm = m_txPowerBaseDbm;
829  }
830  return dbm;
831 }
832 
833 Time
835 {
836  return m_channelSwitchDelay;
837 }
838 
839 double
840 WifiPhy::CalculateSnr (WifiTxVector txVector, double ber) const
841 {
842  return m_interference.GetErrorRateModel ()->CalculateSnr (txVector, ber);
843 }
844 
845 void
847 {
848  NS_LOG_FUNCTION (this);
849  switch (m_standard)
850  {
852  SetChannelWidth (20);
853  SetFrequency (5180);
854  // Channel number should be aligned by SetFrequency () to 36
855  NS_ASSERT (GetChannelNumber () == 36);
856  break;
858  SetChannelWidth (22);
859  SetFrequency (2412);
860  // Channel number should be aligned by SetFrequency () to 1
861  NS_ASSERT (GetChannelNumber () == 1);
862  break;
864  SetChannelWidth (20);
865  SetFrequency (2412);
866  // Channel number should be aligned by SetFrequency () to 1
867  NS_ASSERT (GetChannelNumber () == 1);
868  break;
870  if (GetChannelWidth () > 10)
871  {
872  SetChannelWidth (10);
873  }
874  SetFrequency (5860);
875  // Channel number should be aligned by SetFrequency () to either 172 or 171
876  NS_ASSERT ((GetChannelWidth () == 10 && GetChannelNumber () == 172) || (GetChannelWidth () == 5 && GetChannelNumber () == 171)) ;
877  break;
879  SetChannelWidth (20);
880  SetFrequency (5180);
881  // Channel number should be aligned by SetFrequency () to 36
882  NS_ASSERT (GetChannelNumber () == 36);
883  break;
885  SetChannelWidth (20);
887  {
888  SetFrequency (2412);
889  // Channel number should be aligned by SetFrequency () to 1
890  NS_ASSERT (GetChannelNumber () == 1);
891  }
892  else if (m_band == WIFI_PHY_BAND_5GHZ)
893  {
894  SetFrequency (5180);
895  // Channel number should be aligned by SetFrequency () to 36
896  NS_ASSERT (GetChannelNumber () == 36);
897  }
898  else
899  {
900  NS_FATAL_ERROR ("Invalid band");
901  }
902  break;
904  SetChannelWidth (80);
905  SetFrequency (5210);
906  // Channel number should be aligned by SetFrequency () to 42
907  NS_ASSERT (GetChannelNumber () == 42);
908  break;
911  {
912  SetChannelWidth (20);
913  SetFrequency (2412);
914  // Channel number should be aligned by SetFrequency () to 1
915  NS_ASSERT (GetChannelNumber () == 1);
916  }
917  else if (m_band == WIFI_PHY_BAND_5GHZ)
918  {
919  SetChannelWidth (80);
920  SetFrequency (5210);
921  // Channel number should be aligned by SetFrequency () to 42
922  NS_ASSERT (GetChannelNumber () == 42);
923  }
924  else if (m_band == WIFI_PHY_BAND_6GHZ)
925  {
926  SetChannelWidth (80);
927  SetFrequency (5975);
928  // Channel number should be aligned by SetFrequency () to 7
929  NS_ASSERT (GetChannelNumber () == 7);
930  }
931  else
932  {
933  NS_FATAL_ERROR ("Invalid band");
934  }
935  break;
937  default:
938  NS_LOG_WARN ("Configuring unspecified standard; performing no action");
939  break;
940  }
941 }
942 
943 void
945 {
946  m_sifs = sifs;
947 }
948 
949 Time
950 WifiPhy::GetSifs (void) const
951 {
952  return m_sifs;
953 }
954 
955 void
957 {
958  m_slot = slot;
959 }
960 
961 Time
962 WifiPhy::GetSlot (void) const
963 {
964  return m_slot;
965 }
966 
967 void
969 {
970  m_pifs = pifs;
971 }
972 
973 Time
974 WifiPhy::GetPifs (void) const
975 {
976  return m_pifs;
977 }
978 
979 Time
981 {
982  return m_ackTxTime;
983 }
984 
985 Time
987 {
988  return m_blockAckTxTime;
989 }
990 
991 void
993 {
994  NS_LOG_FUNCTION (this);
995 
996  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
997  SetSifs (MicroSeconds (16));
998  SetSlot (MicroSeconds (9));
999  SetPifs (GetSifs () + GetSlot ());
1000  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1001  // of the PPDU causing the EIFS" of 802.11-2016
1002  m_ackTxTime = MicroSeconds (44);
1003 
1012 }
1013 
1014 void
1016 {
1017  NS_LOG_FUNCTION (this);
1018 
1019  // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
1020  SetSifs (MicroSeconds (10));
1021  SetSlot (MicroSeconds (20));
1022  SetPifs (GetSifs () + GetSlot ());
1023  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1024  // of the PPDU causing the EIFS" of 802.11-2016
1025  m_ackTxTime = MicroSeconds (304);
1026 
1031 }
1032 
1033 void
1035 {
1036  NS_LOG_FUNCTION (this);
1037  // See Table 18-5 "ERP characteristics" of 802.11-2016
1038  // Slot time defaults to the "long slot time" of 20 us in the standard
1039  // according to mixed 802.11b/g deployments. Short slot time is enabled
1040  // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
1041  // consists of only ERP STAs capable of supporting this option.
1042  Configure80211b ();
1043 
1052 }
1053 
1054 void
1056 {
1057  NS_LOG_FUNCTION (this);
1058  if (GetChannelWidth () == 10)
1059  {
1060  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1061  SetSifs (MicroSeconds (32));
1062  SetSlot (MicroSeconds (13));
1063  SetPifs (GetSifs () + GetSlot ());
1064  m_ackTxTime = MicroSeconds (88);
1065 
1074  }
1075  else if (GetChannelWidth () == 5)
1076  {
1077  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1078  SetSifs (MicroSeconds (64));
1079  SetSlot (MicroSeconds (21));
1080  SetPifs (GetSifs () + GetSlot ());
1081  m_ackTxTime = MicroSeconds (176);
1082 
1091  }
1092  else
1093  {
1094  NS_FATAL_ERROR ("802.11p configured with a wrong channel width!");
1095  }
1096 }
1097 
1098 void
1100 {
1101  NS_LOG_FUNCTION (this);
1102 
1103  SetSifs (MicroSeconds (16));
1104  SetSlot (MicroSeconds (9));
1105  SetPifs (GetSifs () + GetSlot ());
1106 
1112 }
1113 
1114 void
1116 {
1117  NS_LOG_FUNCTION (this << mode);
1118 
1119  WifiModulationClass modulation = mode.GetModulationClass ();
1120  NS_ASSERT (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
1121  || modulation == WIFI_MOD_CLASS_HE);
1122 
1123  m_mcsIndexMap[modulation][mode.GetMcsValue ()] = m_deviceMcsSet.size ();
1124  m_deviceMcsSet.push_back (mode);
1125 }
1126 
1127 void
1129 {
1130  NS_LOG_FUNCTION (this);
1131  m_mcsIndexMap.clear ();
1132  uint8_t index = 0;
1133  for (auto& mode : m_deviceMcsSet)
1134  {
1135  m_mcsIndexMap[mode.GetModulationClass ()][mode.GetMcsValue ()] = index++;
1136  }
1137 }
1138 
1139 void
1141 {
1142  NS_LOG_FUNCTION (this);
1143 
1144  bool htFound = false;
1145  for (std::vector<uint8_t>::size_type i = 0; i < m_bssMembershipSelectorSet.size (); i++)
1146  {
1148  {
1149  htFound = true;
1150  break;
1151  }
1152  }
1153  if (htFound)
1154  {
1155  // erase all HtMcs modes from deviceMcsSet
1156  std::size_t index = m_deviceMcsSet.size () - 1;
1157  for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend (); ++rit, --index)
1158  {
1159  if (m_deviceMcsSet[index].GetModulationClass () == WIFI_MOD_CLASS_HT)
1160  {
1161  m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
1162  }
1163  }
1164  RebuildMcsMap ();
1174  {
1183  }
1185  {
1194  }
1196  {
1205  }
1206  }
1207 }
1208 
1209 void
1211 {
1212  NS_LOG_FUNCTION (this);
1214  {
1215  Configure80211g ();
1216  }
1217  else
1218  {
1219  Configure80211a ();
1220  }
1221  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1222  // of the PPDU causing the EIFS" of 802.11-2016
1224  m_bssMembershipSelectorSet.push_back (HT_PHY);
1226 }
1227 
1228 void
1230 {
1231  NS_LOG_FUNCTION (this);
1232  Configure80211n ();
1233 
1244 
1245  m_bssMembershipSelectorSet.push_back (VHT_PHY);
1246 }
1247 
1248 void
1250 {
1251  NS_LOG_FUNCTION (this);
1253  {
1254  Configure80211n ();
1255  }
1256  else
1257  {
1258  Configure80211ac ();
1259  }
1260 
1273 
1274  m_bssMembershipSelectorSet.push_back (HE_PHY);
1275 }
1276 
1277 bool
1278 WifiPhy::DefineChannelNumber (uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
1279 {
1280  NS_LOG_FUNCTION (this << +channelNumber << band << standard << frequency << channelWidth);
1281  ChannelNumberStandardPair p = std::make_pair (std::make_pair (channelNumber, band), standard);
1282  ChannelToFrequencyWidthMap::const_iterator it;
1283  it = m_channelToFrequencyWidth.find (p);
1284  if (it != m_channelToFrequencyWidth.end ())
1285  {
1286  NS_LOG_DEBUG ("channel number/standard already defined; returning false");
1287  return false;
1288  }
1289  FrequencyWidthPair f = std::make_pair (frequency, channelWidth);
1291  return true;
1292 }
1293 
1294 uint8_t
1295 WifiPhy::FindChannelNumberForFrequencyWidth (uint16_t frequency, uint16_t width) const
1296 {
1297  NS_LOG_FUNCTION (this << frequency << width);
1298  bool found = false;
1299  FrequencyWidthPair f = std::make_pair (frequency, width);
1300  ChannelToFrequencyWidthMap::const_iterator it = m_channelToFrequencyWidth.begin ();
1301  while (it != m_channelToFrequencyWidth.end ())
1302  {
1303  if (it->second == f)
1304  {
1305  found = true;
1306  break;
1307  }
1308  ++it;
1309  }
1310  if (found)
1311  {
1312  NS_LOG_DEBUG ("Found, returning " << +it->first.first.first);
1313  return (it->first.first.first);
1314  }
1315  else
1316  {
1317  NS_LOG_DEBUG ("Not found, returning 0");
1318  return 0;
1319  }
1320 }
1321 
1322 void
1324 {
1325  NS_LOG_FUNCTION (this);
1326  // If the user has configured both Frequency and ChannelNumber, Frequency
1327  // takes precedence
1328  if (GetFrequency () != 0)
1329  {
1330  // If Frequency is already set, then see whether a ChannelNumber can
1331  // be found that matches Frequency and ChannelWidth. If so, configure
1332  // the ChannelNumber to that channel number. If not, set ChannelNumber to zero.
1333  NS_LOG_DEBUG ("Frequency set; checking whether a channel number corresponds");
1334  uint8_t channelNumberSearched = FindChannelNumberForFrequencyWidth (GetFrequency (), GetChannelWidth ());
1335  if (channelNumberSearched)
1336  {
1337  NS_LOG_DEBUG ("Channel number found; setting to " << +channelNumberSearched);
1338  SetChannelNumber (channelNumberSearched);
1339  }
1340  else
1341  {
1342  NS_LOG_DEBUG ("Channel number not found; setting to zero");
1343  SetChannelNumber (0);
1344  }
1345  }
1346  else if (GetChannelNumber () != 0)
1347  {
1348  // If the channel number is known for this particular standard or for
1349  // the unspecified standard, configure using the known values;
1350  // otherwise, this is a configuration error
1351  NS_LOG_DEBUG ("Configuring for channel number " << +GetChannelNumber ());
1353  if (f.first == 0)
1354  {
1355  // the specific pair of number/standard is not known
1356  NS_LOG_DEBUG ("Falling back to check WIFI_PHY_STANDARD_UNSPECIFIED");
1358  }
1359  if (f.first == 0)
1360  {
1361  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " is unknown for this standard");
1362  }
1363  else
1364  {
1365  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1366  SetFrequency (f.first);
1367  SetChannelWidth (f.second);
1368  }
1369  }
1370 }
1371 
1372 void
1374 {
1375  NS_LOG_FUNCTION (this << standard << band);
1376  m_standard = standard;
1377  m_band = band;
1378  m_isConstructed = true;
1380  {
1382  }
1383  if (GetFrequency () == 0 && GetChannelNumber () == 0)
1384  {
1386  }
1387  else
1388  {
1389  // The user has configured either (or both) Frequency or ChannelNumber
1391  }
1392  switch (standard)
1393  {
1395  Configure80211a ();
1396  break;
1398  Configure80211b ();
1399  break;
1401  Configure80211g ();
1402  break;
1404  Configure80211p ();
1405  break;
1407  ConfigureHolland ();
1408  break;
1410  Configure80211n ();
1411  break;
1413  Configure80211ac ();
1414  break;
1416  Configure80211ax ();
1417  break;
1419  default:
1420  NS_ASSERT (false);
1421  break;
1422  }
1423 }
1424 
1427 {
1428  return m_band;
1429 }
1430 
1431 
1434 {
1435  return m_standard;
1436 }
1437 
1438 void
1439 WifiPhy::SetFrequency (uint16_t frequency)
1440 {
1441  NS_LOG_FUNCTION (this << frequency);
1442  if (m_isConstructed == false)
1443  {
1444  NS_LOG_DEBUG ("Saving frequency configuration for initialization");
1445  m_initialFrequency = frequency;
1446  return;
1447  }
1448  if (GetFrequency () == frequency)
1449  {
1450  NS_LOG_DEBUG ("No frequency change requested");
1451  return;
1452  }
1453  if (frequency == 0)
1454  {
1455  DoFrequencySwitch (0);
1456  NS_LOG_DEBUG ("Setting frequency and channel number to zero");
1458  m_channelNumber = 0;
1459  return;
1460  }
1461  // If the user has configured both Frequency and ChannelNumber, Frequency
1462  // takes precedence. Lookup the channel number corresponding to the
1463  // requested frequency.
1464  uint8_t nch = FindChannelNumberForFrequencyWidth (frequency, GetChannelWidth ());
1465  if (nch != 0)
1466  {
1467  NS_LOG_DEBUG ("Setting frequency " << frequency << " corresponds to channel " << +nch);
1468  if (DoFrequencySwitch (frequency))
1469  {
1470  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << +nch);
1471  m_channelCenterFrequency = frequency;
1472  m_channelNumber = nch;
1473  }
1474  else
1475  {
1476  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1477  }
1478  }
1479  else
1480  {
1481  NS_LOG_DEBUG ("Channel number is unknown for frequency " << frequency);
1482  if (DoFrequencySwitch (frequency))
1483  {
1484  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << 0);
1485  m_channelCenterFrequency = frequency;
1486  m_channelNumber = 0;
1487  }
1488  else
1489  {
1490  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1491  }
1492  }
1493 }
1494 
1495 uint16_t
1497 {
1498  return m_channelCenterFrequency;
1499 }
1500 
1501 void
1502 WifiPhy::SetChannelWidth (uint16_t channelWidth)
1503 {
1504  NS_LOG_FUNCTION (this << channelWidth);
1505  NS_ASSERT_MSG (channelWidth == 5 || channelWidth == 10 || channelWidth == 20 || channelWidth == 22 || channelWidth == 40 || channelWidth == 80 || channelWidth == 160, "wrong channel width value");
1506  bool changed = (m_channelWidth != channelWidth);
1507  m_channelWidth = channelWidth;
1508  AddSupportedChannelWidth (channelWidth);
1509  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1510  {
1512  }
1513 }
1514 
1515 uint16_t
1517 {
1518  return m_channelWidth;
1519 }
1520 
1521 void
1523 {
1524  NS_ASSERT_MSG (antennas > 0 && antennas <= 4, "unsupported number of antennas");
1525  m_numberOfAntennas = antennas;
1527 }
1528 
1529 uint8_t
1531 {
1532  return m_numberOfAntennas;
1533 }
1534 
1535 void
1537 {
1538  NS_ASSERT (streams <= GetNumberOfAntennas ());
1539  bool changed = (m_txSpatialStreams != streams);
1540  m_txSpatialStreams = streams;
1542  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1543  {
1545  }
1546 }
1547 
1548 uint8_t
1550 {
1551  return m_txSpatialStreams;
1552 }
1553 
1554 void
1556 {
1557  NS_ASSERT (streams <= GetNumberOfAntennas ());
1558  bool changed = (m_rxSpatialStreams != streams);
1559  m_rxSpatialStreams = streams;
1560  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1561  {
1563  }
1564 }
1565 
1566 uint8_t
1568 {
1569  return m_rxSpatialStreams;
1570 }
1571 
1572 uint8_t
1574 {
1575  return static_cast<uint8_t> (m_bssMembershipSelectorSet.size ());
1576 }
1577 
1578 uint8_t
1579 WifiPhy::GetBssMembershipSelector (uint8_t selector) const
1580 {
1581  return m_bssMembershipSelectorSet[selector];
1582 }
1583 
1584 void
1586 {
1587  NS_LOG_FUNCTION (this << width);
1588  for (std::vector<uint32_t>::size_type i = 0; i != m_supportedChannelWidthSet.size (); i++)
1589  {
1590  if (m_supportedChannelWidthSet[i] == width)
1591  {
1592  return;
1593  }
1594  }
1595  NS_LOG_FUNCTION ("Adding " << width << " to supported channel width set");
1596  m_supportedChannelWidthSet.push_back (width);
1597 }
1598 
1599 std::vector<uint16_t>
1601 {
1603 }
1604 
1607 {
1608  ChannelNumberStandardPair p = std::make_pair (std::make_pair (channelNumber, band), standard);
1610  return f;
1611 }
1612 
1613 void
1615 {
1616  NS_LOG_FUNCTION (this << +nch);
1617  if (m_isConstructed == false)
1618  {
1619  NS_LOG_DEBUG ("Saving channel number configuration for initialization");
1620  m_initialChannelNumber = nch;
1621  return;
1622  }
1623  if (GetChannelNumber () == nch)
1624  {
1625  NS_LOG_DEBUG ("No channel change requested");
1626  return;
1627  }
1628  if (nch == 0)
1629  {
1630  // This case corresponds to when there is not a known channel
1631  // number for the requested frequency. There is no need to call
1632  // DoChannelSwitch () because DoFrequencySwitch () should have been
1633  // called by the client
1634  NS_LOG_DEBUG ("Setting channel number to zero");
1635  m_channelNumber = 0;
1636  return;
1637  }
1638 
1639  // First make sure that the channel number is defined for the standard in use
1641  if (f.first == 0)
1642  {
1644  }
1645  if (f.first != 0)
1646  {
1647  if (DoChannelSwitch (nch))
1648  {
1649  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1650  m_channelCenterFrequency = f.first;
1651  SetChannelWidth (f.second);
1652  m_channelNumber = nch;
1653  }
1654  else
1655  {
1656  // Subclass may have suppressed (e.g. waiting for state change)
1657  NS_LOG_DEBUG ("Channel switch suppressed");
1658  }
1659  }
1660  else
1661  {
1662  NS_FATAL_ERROR ("Frequency not found for channel number " << +nch);
1663  }
1664 }
1665 
1666 uint8_t
1668 {
1669  return m_channelNumber;
1670 }
1671 
1672 bool
1674 {
1675  m_powerRestricted = false;
1676  m_channelAccessRequested = false;
1677  if (!IsInitialized ())
1678  {
1679  //this is not channel switch, this is initialization
1680  NS_LOG_DEBUG ("initialize to channel " << +nch);
1681  return true;
1682  }
1683 
1685  switch (m_state->GetState ())
1686  {
1687  case WifiPhyState::RX:
1688  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1690  m_endRxEvent.Cancel ();
1692  goto switchChannel;
1693  break;
1694  case WifiPhyState::TX:
1695  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1697  break;
1699  case WifiPhyState::IDLE:
1701  {
1703  m_endRxEvent.Cancel ();
1704  }
1705  goto switchChannel;
1706  break;
1707  case WifiPhyState::SLEEP:
1708  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1709  break;
1710  default:
1711  NS_ASSERT (false);
1712  break;
1713  }
1714 
1715  return false;
1716 
1717 switchChannel:
1718 
1719  NS_LOG_DEBUG ("switching channel " << +GetChannelNumber () << " -> " << +nch);
1720  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1722  /*
1723  * Needed here to be able to correctly sensed the medium for the first
1724  * time after the switching. The actual switching is not performed until
1725  * after m_channelSwitchDelay. Packets received during the switching
1726  * state are added to the event list and are employed later to figure
1727  * out the state of the medium after the switching.
1728  */
1729  return true;
1730 }
1731 
1732 bool
1733 WifiPhy::DoFrequencySwitch (uint16_t frequency)
1734 {
1735  m_powerRestricted = false;
1736  m_channelAccessRequested = false;
1737  if (!IsInitialized ())
1738  {
1739  //this is not channel switch, this is initialization
1740  NS_LOG_DEBUG ("start at frequency " << frequency);
1741  return true;
1742  }
1743 
1745  switch (m_state->GetState ())
1746  {
1747  case WifiPhyState::RX:
1748  NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
1750  m_endRxEvent.Cancel ();
1752  goto switchFrequency;
1753  break;
1754  case WifiPhyState::TX:
1755  NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
1757  break;
1759  case WifiPhyState::IDLE:
1761  {
1763  m_endRxEvent.Cancel ();
1764  }
1765  goto switchFrequency;
1766  break;
1767  case WifiPhyState::SLEEP:
1768  NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
1769  break;
1770  default:
1771  NS_ASSERT (false);
1772  break;
1773  }
1774 
1775  return false;
1776 
1777 switchFrequency:
1778 
1779  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
1780  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1782  /*
1783  * Needed here to be able to correctly sensed the medium for the first
1784  * time after the switching. The actual switching is not performed until
1785  * after m_channelSwitchDelay. Packets received during the switching
1786  * state are added to the event list and are employed later to figure
1787  * out the state of the medium after the switching.
1788  */
1789  return true;
1790 }
1791 
1792 void
1794 {
1795  NS_LOG_FUNCTION (this);
1796  m_powerRestricted = false;
1797  m_channelAccessRequested = false;
1798  switch (m_state->GetState ())
1799  {
1800  case WifiPhyState::TX:
1801  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1803  break;
1804  case WifiPhyState::RX:
1805  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1807  break;
1809  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1811  break;
1813  case WifiPhyState::IDLE:
1814  NS_LOG_DEBUG ("setting sleep mode");
1815  m_state->SwitchToSleep ();
1816  break;
1817  case WifiPhyState::SLEEP:
1818  NS_LOG_DEBUG ("already in sleep mode");
1819  break;
1820  default:
1821  NS_ASSERT (false);
1822  break;
1823  }
1824 }
1825 
1826 void
1828 {
1829  NS_LOG_FUNCTION (this);
1830  m_powerRestricted = false;
1831  m_channelAccessRequested = false;
1833  m_endRxEvent.Cancel ();
1835  m_endTxEvent.Cancel ();
1836  m_state->SwitchToOff ();
1837 }
1838 
1839 void
1841 {
1842  NS_LOG_FUNCTION (this);
1843  switch (m_state->GetState ())
1844  {
1845  case WifiPhyState::TX:
1846  case WifiPhyState::RX:
1847  case WifiPhyState::IDLE:
1850  {
1851  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1852  break;
1853  }
1854  case WifiPhyState::SLEEP:
1855  {
1856  NS_LOG_DEBUG ("resuming from sleep mode");
1857  uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
1858  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
1859  m_state->SwitchFromSleep (delayUntilCcaEnd);
1860  break;
1861  }
1862  default:
1863  {
1864  NS_ASSERT (false);
1865  break;
1866  }
1867  }
1868 }
1869 
1870 void
1872 {
1873  NS_LOG_FUNCTION (this);
1874  switch (m_state->GetState ())
1875  {
1876  case WifiPhyState::TX:
1877  case WifiPhyState::RX:
1878  case WifiPhyState::IDLE:
1881  case WifiPhyState::SLEEP:
1882  {
1883  NS_LOG_DEBUG ("not in off mode, there is nothing to resume");
1884  break;
1885  }
1886  case WifiPhyState::OFF:
1887  {
1888  NS_LOG_DEBUG ("resuming from off mode");
1889  uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
1890  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
1891  m_state->SwitchFromOff (delayUntilCcaEnd);
1892  break;
1893  }
1894  default:
1895  {
1896  NS_ASSERT (false);
1897  break;
1898  }
1899  }
1900 }
1901 
1902 WifiMode
1904 {
1905  return WifiPhy::GetHtMcs0 ();
1906 }
1907 
1908 WifiMode
1910 {
1911  return WifiPhy::GetVhtMcs0 ();
1912 }
1913 
1914 WifiMode
1916 {
1917  return WifiPhy::GetHeMcs0 ();
1918 }
1919 
1920 Time
1922 {
1923  return MicroSeconds (4);
1924 }
1925 
1926 Time
1928 {
1929  uint8_t Ndltf, Neltf;
1930  //We suppose here that STBC = 0.
1931  //If STBC > 0, we need a different mapping between Nss and Nltf (IEEE 802.11n-2012 standard, page 1682).
1932  uint8_t nss = txVector.GetNssMax (); //so as to cover also HE MU case (see section 27.3.10.10 of IEEE P802.11ax/D4.0)
1933  if (nss < 3)
1934  {
1935  Ndltf = nss;
1936  }
1937  else if (nss < 5)
1938  {
1939  Ndltf = 4;
1940  }
1941  else if (nss < 7)
1942  {
1943  Ndltf = 6;
1944  }
1945  else
1946  {
1947  Ndltf = 8;
1948  }
1949 
1950  if (txVector.GetNess () < 3)
1951  {
1952  Neltf = txVector.GetNess ();
1953  }
1954  else
1955  {
1956  Neltf = 4;
1957  }
1958 
1959  switch (txVector.GetPreambleType ())
1960  {
1961  case WIFI_PREAMBLE_HT_MF:
1962  return MicroSeconds (4 + (4 * Ndltf) + (4 * Neltf));
1963  case WIFI_PREAMBLE_HT_GF:
1964  return MicroSeconds ((4 * Ndltf) + (4 * Neltf));
1965  case WIFI_PREAMBLE_VHT_SU:
1966  case WIFI_PREAMBLE_VHT_MU:
1967  return MicroSeconds (4 + (4 * Ndltf));
1968  case WIFI_PREAMBLE_HE_SU:
1969  case WIFI_PREAMBLE_HE_MU:
1970  case WIFI_PREAMBLE_HE_TB:
1971  return MicroSeconds (4 + (8 * Ndltf));
1972  default:
1973  return MicroSeconds (0);
1974  }
1975 }
1976 
1977 Time
1979 {
1980  switch (preamble)
1981  {
1982  case WIFI_PREAMBLE_HT_MF:
1983  case WIFI_PREAMBLE_HT_GF:
1984  //HT-SIG
1985  return MicroSeconds (8);
1986  default:
1987  //no HT-SIG for non HT
1988  return MicroSeconds (0);
1989  }
1990 }
1991 
1992 Time
1994 {
1995  switch (preamble)
1996  {
1997  case WIFI_PREAMBLE_VHT_SU:
1998  case WIFI_PREAMBLE_HE_SU:
1999  case WIFI_PREAMBLE_VHT_MU:
2000  case WIFI_PREAMBLE_HE_MU:
2001  case WIFI_PREAMBLE_HE_TB:
2002  //VHT-SIG-A1 and HE-SIG-A1
2003  return MicroSeconds (4);
2004  default:
2005  // no SIG-A1
2006  return MicroSeconds (0);
2007  }
2008 }
2009 
2010 Time
2012 {
2013  switch (preamble)
2014  {
2015  case WIFI_PREAMBLE_VHT_SU:
2016  case WIFI_PREAMBLE_HE_SU:
2017  case WIFI_PREAMBLE_VHT_MU:
2018  case WIFI_PREAMBLE_HE_MU:
2019  //VHT-SIG-A2 and HE-SIG-A2
2020  return MicroSeconds (4);
2021  default:
2022  // no SIG-A2
2023  return MicroSeconds (0);
2024  }
2025 }
2026 
2027 Time
2029 {
2030  switch (preamble)
2031  {
2032  case WIFI_PREAMBLE_VHT_MU:
2033  case WIFI_PREAMBLE_HE_MU:
2034  return MicroSeconds (4);
2035  default:
2036  // no SIG-B
2037  return MicroSeconds (0);
2038  }
2039 }
2040 
2041 WifiMode
2043 {
2044  WifiPreamble preamble = txVector.GetPreambleType ();
2045  switch (preamble)
2046  {
2047  case WIFI_PREAMBLE_LONG:
2048  case WIFI_PREAMBLE_SHORT:
2049  {
2050  switch (txVector.GetMode ().GetModulationClass ())
2051  {
2052  case WIFI_MOD_CLASS_OFDM:
2053  {
2054  switch (txVector.GetChannelWidth ())
2055  {
2056  case 5:
2058  case 10:
2060  case 20:
2061  default:
2062  //(Section 17.3.2 "PPDU frame format"; IEEE Std 802.11-2016)
2063  //actually this is only the first part of the PhyHeader,
2064  //because the last 16 bits of the PhyHeader are using the
2065  //same mode of the payload
2066  return WifiPhy::GetOfdmRate6Mbps ();
2067  }
2068  }
2070  return WifiPhy::GetErpOfdmRate6Mbps ();
2071  case WIFI_MOD_CLASS_DSSS:
2073  {
2074  if (preamble == WIFI_PREAMBLE_LONG || txVector.GetMode () == WifiPhy::GetDsssRate1Mbps ())
2075  {
2076  //(Section 16.2.3 "PPDU field definitions" and Section 16.2.2.2 "Long PPDU format"; IEEE Std 802.11-2016)
2077  return WifiPhy::GetDsssRate1Mbps ();
2078  }
2079  else
2080  {
2081  //(Section 16.2.2.3 "Short PPDU format"; IEEE Std 802.11-2016)
2082  return WifiPhy::GetDsssRate2Mbps ();
2083  }
2084  }
2085  default:
2086  NS_FATAL_ERROR ("unsupported modulation class");
2087  return WifiMode ();
2088  }
2089  }
2090  case WIFI_PREAMBLE_HT_MF:
2091  case WIFI_PREAMBLE_HT_GF:
2092  case WIFI_PREAMBLE_VHT_SU:
2093  case WIFI_PREAMBLE_VHT_MU:
2094  case WIFI_PREAMBLE_HE_SU:
2096  case WIFI_PREAMBLE_HE_MU:
2097  case WIFI_PREAMBLE_HE_TB:
2098  return WifiPhy::GetOfdmRate6Mbps ();
2099  default:
2100  NS_FATAL_ERROR ("unsupported preamble type");
2101  return WifiMode ();
2102  }
2103 }
2104 
2105 Time
2107 {
2108  WifiPreamble preamble = txVector.GetPreambleType ();
2109  switch (txVector.GetPreambleType ())
2110  {
2111  case WIFI_PREAMBLE_LONG:
2112  case WIFI_PREAMBLE_SHORT:
2113  {
2114  switch (txVector.GetMode ().GetModulationClass ())
2115  {
2116  case WIFI_MOD_CLASS_OFDM:
2117  {
2118  switch (txVector.GetChannelWidth ())
2119  {
2120  case 20:
2121  default:
2122  //(Section 17.3.3 "PHY preamble (SYNC))" and Figure 17-4 "OFDM training structure"; IEEE Std 802.11-2016)
2123  //also (Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2124  //We return the duration of the SIGNAL field only, since the
2125  //SERVICE field (which strictly speaking belongs to the PHY
2126  //header, see Section 17.3.2 and Figure 17-1) is sent using the
2127  //payload mode.
2128  return MicroSeconds (4);
2129  case 10:
2130  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2131  return MicroSeconds (8);
2132  case 5:
2133  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2134  return MicroSeconds (16);
2135  }
2136  }
2138  return MicroSeconds (4);
2139  case WIFI_MOD_CLASS_DSSS:
2141  {
2142  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2143  {
2144  //(Section 16.2.2.3 "Short PPDU format" and Figure 16-2 "Short PPDU format"; IEEE Std 802.11-2016)
2145  return MicroSeconds (24);
2146  }
2147  else
2148  {
2149  //(Section 16.2.2.2 "Long PPDU format" and Figure 16-1 "Short PPDU format"; IEEE Std 802.11-2016)
2150  return MicroSeconds (48);
2151  }
2152  }
2153  default:
2154  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2155  return MicroSeconds (0);
2156  }
2157  }
2158  case WIFI_PREAMBLE_HT_MF:
2159  case WIFI_PREAMBLE_VHT_SU:
2160  case WIFI_PREAMBLE_VHT_MU:
2161  //L-SIG
2162  return MicroSeconds (4);
2163  case WIFI_PREAMBLE_HE_SU:
2165  case WIFI_PREAMBLE_HE_MU:
2166  case WIFI_PREAMBLE_HE_TB:
2167  //LSIG + R-LSIG
2168  return MicroSeconds (8);
2169  case WIFI_PREAMBLE_HT_GF:
2170  return MicroSeconds (0);
2171  default:
2172  NS_FATAL_ERROR ("unsupported preamble type");
2173  return MicroSeconds (0);
2174  }
2175 }
2176 
2177 Time
2179 {
2180  return MicroSeconds (4);
2181 }
2182 
2183 Time
2185 {
2186  WifiPreamble preamble = txVector.GetPreambleType ();
2187  switch (txVector.GetPreambleType ())
2188  {
2189  case WIFI_PREAMBLE_LONG:
2190  case WIFI_PREAMBLE_SHORT:
2191  {
2192  switch (txVector.GetMode ().GetModulationClass ())
2193  {
2194  case WIFI_MOD_CLASS_OFDM:
2195  {
2196  switch (txVector.GetChannelWidth ())
2197  {
2198  case 20:
2199  default:
2200  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2201  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2202  return MicroSeconds (16);
2203  case 10:
2204  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2205  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2206  return MicroSeconds (32);
2207  case 5:
2208  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2209  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2210  return MicroSeconds (64);
2211  }
2212  }
2214  return MicroSeconds (16);
2215  case WIFI_MOD_CLASS_DSSS:
2217  {
2218  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2219  {
2220  //(Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
2221  return MicroSeconds (72);
2222  }
2223  else
2224  {
2225  //(Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012)
2226  return MicroSeconds (144);
2227  }
2228  }
2229  default:
2230  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2231  return MicroSeconds (0);
2232  }
2233  }
2234  case WIFI_PREAMBLE_HT_MF:
2235  case WIFI_PREAMBLE_VHT_SU:
2236  case WIFI_PREAMBLE_VHT_MU:
2237  case WIFI_PREAMBLE_HE_SU:
2239  case WIFI_PREAMBLE_HE_MU:
2240  case WIFI_PREAMBLE_HE_TB:
2241  //L-STF + L-LTF
2242  return MicroSeconds (16);
2243  case WIFI_PREAMBLE_HT_GF:
2244  //HT-GF-STF + HT-LTF1
2245  return MicroSeconds (16);
2246  default:
2247  NS_FATAL_ERROR ("unsupported preamble type");
2248  return MicroSeconds (0);
2249  }
2250 }
2251 
2252 Time
2253 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype, uint16_t staId)
2254 {
2255  uint32_t totalAmpduSize;
2256  double totalAmpduNumSymbols;
2257  return GetPayloadDuration (size, txVector, band, mpdutype, false, totalAmpduSize, totalAmpduNumSymbols, staId);
2258 }
2259 
2260 Time
2261 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype,
2262  bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols,
2263  uint16_t staId)
2264 {
2265  WifiMode payloadMode = txVector.GetMode (staId);
2266  NS_LOG_FUNCTION (size << payloadMode);
2267 
2268  double stbc = 1;
2269  if (txVector.IsStbc ()
2270  && (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
2271  || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
2272  {
2273  stbc = 2;
2274  }
2275 
2276  double Nes = 1;
2277  //todo: improve logic to reduce the number of if cases
2278  //todo: extend to NSS > 4 for VHT rates
2279  if (payloadMode == GetHtMcs21 ()
2280  || payloadMode == GetHtMcs22 ()
2281  || payloadMode == GetHtMcs23 ()
2282  || payloadMode == GetHtMcs28 ()
2283  || payloadMode == GetHtMcs29 ()
2284  || payloadMode == GetHtMcs30 ()
2285  || payloadMode == GetHtMcs31 ())
2286  {
2287  Nes = 2;
2288  }
2289  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
2290  {
2291  if (txVector.GetChannelWidth () == 40
2292  && txVector.GetNss (staId) == 3
2293  && payloadMode.GetMcsValue () >= 8)
2294  {
2295  Nes = 2;
2296  }
2297  if (txVector.GetChannelWidth () == 80
2298  && txVector.GetNss (staId) == 2
2299  && payloadMode.GetMcsValue () >= 7)
2300  {
2301  Nes = 2;
2302  }
2303  if (txVector.GetChannelWidth () == 80
2304  && txVector.GetNss (staId) == 3
2305  && payloadMode.GetMcsValue () >= 7)
2306  {
2307  Nes = 2;
2308  }
2309  if (txVector.GetChannelWidth () == 80
2310  && txVector.GetNss (staId) == 3
2311  && payloadMode.GetMcsValue () == 9)
2312  {
2313  Nes = 3;
2314  }
2315  if (txVector.GetChannelWidth () == 80
2316  && txVector.GetNss (staId) == 4
2317  && payloadMode.GetMcsValue () >= 4)
2318  {
2319  Nes = 2;
2320  }
2321  if (txVector.GetChannelWidth () == 80
2322  && txVector.GetNss (staId) == 4
2323  && payloadMode.GetMcsValue () >= 7)
2324  {
2325  Nes = 3;
2326  }
2327  if (txVector.GetChannelWidth () == 160
2328  && payloadMode.GetMcsValue () >= 7)
2329  {
2330  Nes = 2;
2331  }
2332  if (txVector.GetChannelWidth () == 160
2333  && txVector.GetNss (staId) == 2
2334  && payloadMode.GetMcsValue () >= 4)
2335  {
2336  Nes = 2;
2337  }
2338  if (txVector.GetChannelWidth () == 160
2339  && txVector.GetNss (staId) == 2
2340  && payloadMode.GetMcsValue () >= 7)
2341  {
2342  Nes = 3;
2343  }
2344  if (txVector.GetChannelWidth () == 160
2345  && txVector.GetNss (staId) == 3
2346  && payloadMode.GetMcsValue () >= 3)
2347  {
2348  Nes = 2;
2349  }
2350  if (txVector.GetChannelWidth () == 160
2351  && txVector.GetNss (staId) == 3
2352  && payloadMode.GetMcsValue () >= 5)
2353  {
2354  Nes = 3;
2355  }
2356  if (txVector.GetChannelWidth () == 160
2357  && txVector.GetNss (staId) == 3
2358  && payloadMode.GetMcsValue () >= 7)
2359  {
2360  Nes = 4;
2361  }
2362  if (txVector.GetChannelWidth () == 160
2363  && txVector.GetNss (staId) == 4
2364  && payloadMode.GetMcsValue () >= 2)
2365  {
2366  Nes = 2;
2367  }
2368  if (txVector.GetChannelWidth () == 160
2369  && txVector.GetNss (staId) == 4
2370  && payloadMode.GetMcsValue () >= 4)
2371  {
2372  Nes = 3;
2373  }
2374  if (txVector.GetChannelWidth () == 160
2375  && txVector.GetNss (staId) == 4
2376  && payloadMode.GetMcsValue () >= 5)
2377  {
2378  Nes = 4;
2379  }
2380  if (txVector.GetChannelWidth () == 160
2381  && txVector.GetNss (staId) == 4
2382  && payloadMode.GetMcsValue () >= 7)
2383  {
2384  Nes = 6;
2385  }
2386  }
2387 
2388  Time symbolDuration = Seconds (0);
2389  switch (payloadMode.GetModulationClass ())
2390  {
2391  case WIFI_MOD_CLASS_OFDM:
2393  {
2394  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012
2395  //corresponds to T_{SYM} in the table)
2396  switch (txVector.GetChannelWidth ())
2397  {
2398  case 20:
2399  default:
2400  symbolDuration = MicroSeconds (4);
2401  break;
2402  case 10:
2403  symbolDuration = MicroSeconds (8);
2404  break;
2405  case 5:
2406  symbolDuration = MicroSeconds (16);
2407  break;
2408  }
2409  break;
2410  }
2411  case WIFI_MOD_CLASS_HT:
2412  case WIFI_MOD_CLASS_VHT:
2413  {
2414  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2415  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2416  uint16_t gi = txVector.GetGuardInterval ();
2417  NS_ASSERT (gi == 400 || gi == 800);
2418  symbolDuration = NanoSeconds (3200 + gi);
2419  }
2420  break;
2421  case WIFI_MOD_CLASS_HE:
2422  {
2423  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2424  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2425  uint16_t gi = txVector.GetGuardInterval ();
2426  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
2427  symbolDuration = NanoSeconds (12800 + gi);
2428  }
2429  break;
2430  default:
2431  break;
2432  }
2433 
2434  double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector, staId) * symbolDuration.GetNanoSeconds () / 1e9;
2435 
2436  double numSymbols = 0;
2437  if (mpdutype == FIRST_MPDU_IN_AGGREGATE)
2438  {
2439  //First packet in an A-MPDU
2440  numSymbols = (stbc * (16 + size * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol));
2441  if (incFlag == 1)
2442  {
2443  totalAmpduSize += size;
2444  totalAmpduNumSymbols += numSymbols;
2445  }
2446  }
2447  else if (mpdutype == MIDDLE_MPDU_IN_AGGREGATE)
2448  {
2449  //consecutive packets in an A-MPDU
2450  numSymbols = (stbc * size * 8.0) / (stbc * numDataBitsPerSymbol);
2451  if (incFlag == 1)
2452  {
2453  totalAmpduSize += size;
2454  totalAmpduNumSymbols += numSymbols;
2455  }
2456  }
2457  else if (mpdutype == LAST_MPDU_IN_AGGREGATE)
2458  {
2459  //last packet in an A-MPDU
2460  uint32_t totalSize = totalAmpduSize + size;
2461  numSymbols = lrint (stbc * ceil ((16 + totalSize * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol)));
2462  NS_ASSERT (totalAmpduNumSymbols <= numSymbols);
2463  numSymbols -= totalAmpduNumSymbols;
2464  if (incFlag == 1)
2465  {
2466  totalAmpduSize = 0;
2467  totalAmpduNumSymbols = 0;
2468  }
2469  }
2470  else if (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU)
2471  {
2472  //Not an A-MPDU or single MPDU (i.e. the current payload contains both service and padding)
2473  //The number of OFDM symbols in the data field when BCC encoding
2474  //is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
2475  numSymbols = lrint (stbc * ceil ((16 + size * 8.0 + 6.0 * Nes) / (stbc * numDataBitsPerSymbol)));
2476  }
2477  else
2478  {
2479  NS_FATAL_ERROR ("Unknown MPDU type");
2480  }
2481 
2482  switch (payloadMode.GetModulationClass ())
2483  {
2484  case WIFI_MOD_CLASS_OFDM:
2486  {
2487  //Add signal extension for ERP PHY
2488  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
2489  {
2490  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2491  }
2492  else
2493  {
2494  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2495  }
2496  }
2497  case WIFI_MOD_CLASS_HT:
2498  case WIFI_MOD_CLASS_VHT:
2499  {
2500  if ((payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT) && (band == WIFI_PHY_BAND_2_4GHZ)
2501  && (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE)) //at 2.4 GHz
2502  {
2503  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2504  }
2505  else //at 5 GHz
2506  {
2507  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2508  }
2509  }
2510  case WIFI_MOD_CLASS_HE:
2511  {
2512  if ((band == WIFI_PHY_BAND_2_4GHZ)
2513  && ((mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE))) //at 2.4 GHz
2514  {
2515  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2516  }
2517  else //at 5 GHz or 6 GHz
2518  {
2519  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2520  }
2521  }
2522  case WIFI_MOD_CLASS_DSSS:
2524  return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate (22) / 1.0e6))));
2525  default:
2526  NS_FATAL_ERROR ("unsupported modulation class");
2527  return MicroSeconds (0);
2528  }
2529 }
2530 
2531 Time
2533 {
2534  WifiPreamble preamble = txVector.GetPreambleType ();
2535  Time duration = GetPhyPreambleDuration (txVector)
2536  + GetPhyHeaderDuration (txVector)
2537  + GetPhyHtSigHeaderDuration (preamble)
2538  + GetPhySigA1Duration (preamble)
2539  + GetPhySigA2Duration (preamble)
2540  + GetPhyTrainingSymbolDuration (txVector)
2541  + GetPhySigBDuration (preamble);
2542  return duration;
2543 }
2544 
2545 Time
2546 WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, uint16_t staId)
2547 {
2548  Time duration = CalculatePhyPreambleAndHeaderDuration (txVector)
2549  + GetPayloadDuration (size, txVector, band, NORMAL_MPDU, staId);
2550  NS_ASSERT (duration.IsStrictlyPositive ());
2551  return duration;
2552 }
2553 
2554 Time
2556 {
2557  Time maxDuration = Seconds (0);
2558  for (auto & staIdPsdu : psduMap)
2559  {
2560  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
2561  {
2562  WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap ();
2563  NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector");
2564  }
2565  Time current = CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band, staIdPsdu.first);
2566  if (current > maxDuration)
2567  {
2568  maxDuration = current;
2569  }
2570  }
2571  NS_ASSERT (maxDuration.IsStrictlyPositive ());
2572  return maxDuration;
2573 }
2574 
2575 void
2577 {
2578  for (auto const& psdu : psdus)
2579  {
2580  for (auto& mpdu : *PeekPointer (psdu.second))
2581  {
2582  m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW);
2583  }
2584  }
2585 }
2586 
2587 void
2589 {
2590  for (auto const& psdu : psdus)
2591  {
2592  for (auto& mpdu : *PeekPointer (psdu.second))
2593  {
2594  m_phyTxEndTrace (mpdu->GetProtocolDataUnit ());
2595  }
2596  }
2597 }
2598 
2599 void
2601 {
2602  for (auto& mpdu : *PeekPointer (psdu))
2603  {
2604  m_phyTxDropTrace (mpdu->GetProtocolDataUnit ());
2605  }
2606 }
2607 
2608 void
2610 {
2611  if (psdu)
2612  {
2613  for (auto& mpdu : *PeekPointer (psdu))
2614  {
2615  m_phyRxBeginTrace (mpdu->GetProtocolDataUnit (), rxPowersW);
2616  }
2617  }
2618 }
2619 
2620 void
2622 {
2623  if (psdu)
2624  {
2625  for (auto& mpdu : *PeekPointer (psdu))
2626  {
2627  m_phyRxEndTrace (mpdu->GetProtocolDataUnit ());
2628  }
2629  }
2630 }
2631 
2632 void
2634 {
2635  if (psdu)
2636  {
2637  for (auto& mpdu : *PeekPointer (psdu))
2638  {
2639  m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason);
2640  }
2641  }
2642 }
2643 
2644 void
2645 WifiPhy::NotifyMonitorSniffRx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector,
2646  SignalNoiseDbm signalNoise, std::vector<bool> statusPerMpdu, uint16_t staId)
2647 {
2648  MpduInfo aMpdu;
2649  if (psdu->IsAggregate ())
2650  {
2651  //Expand A-MPDU
2652  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2654  size_t nMpdus = psdu->GetNMpdus ();
2655  NS_ASSERT_MSG (statusPerMpdu.size () == nMpdus, "Should have one reception status per MPDU");
2656  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
2657  for (size_t i = 0; i < nMpdus;)
2658  {
2659  if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer
2660  {
2661  m_phyMonitorSniffRxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, signalNoise, staId);
2662  }
2663  ++i;
2664  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2665  }
2666  }
2667  else
2668  {
2669  aMpdu.type = NORMAL_MPDU;
2670  NS_ASSERT_MSG (statusPerMpdu.size () == 1, "Should have one reception status for normal MPDU");
2671  m_phyMonitorSniffRxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, signalNoise, staId);
2672  }
2673 }
2674 
2675 void
2676 WifiPhy::NotifyMonitorSniffTx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector, uint16_t staId)
2677 {
2678  MpduInfo aMpdu;
2679  if (psdu->IsAggregate ())
2680  {
2681  //Expand A-MPDU
2682  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2684  size_t nMpdus = psdu->GetNMpdus ();
2685  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2686  for (size_t i = 0; i < nMpdus;)
2687  {
2688  m_phyMonitorSniffTxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, staId);
2689  ++i;
2690  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2691  }
2692  }
2693  else
2694  {
2695  aMpdu.type = NORMAL_MPDU;
2696  m_phyMonitorSniffTxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, staId);
2697  }
2698 }
2699 
2700 void
2702 {
2703  m_phyEndOfHePreambleTrace (params);
2704 }
2705 
2706 void
2708 {
2709  NS_LOG_FUNCTION (this << *psdu << txVector);
2710  WifiConstPsduMap psdus;
2711  psdus.insert (std::make_pair (SU_STA_ID, psdu));
2712  Send (psdus, txVector);
2713 }
2714 
2715 void
2717 {
2718  NS_LOG_FUNCTION (this << psdus << txVector);
2719  /* Transmission can happen if:
2720  * - we are syncing on a packet. It is the responsibility of the
2721  * MAC layer to avoid doing this but the PHY does nothing to
2722  * prevent it.
2723  * - we are idle
2724  */
2725  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2727 
2728  if (txVector.GetNssMax () > GetMaxSupportedTxSpatialStreams ())
2729  {
2730  NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2731  }
2732 
2733  if (m_state->IsStateSleep ())
2734  {
2735  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
2736  for (auto const& psdu : psdus)
2737  {
2738  NotifyTxDrop (psdu.second);
2739  }
2740  return;
2741  }
2742 
2743  Time txDuration = CalculateTxDuration (psdus, txVector, GetPhyBand ());
2744 
2745  if ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())))
2746  {
2747  //that packet will be noise _after_ the transmission.
2749  }
2750 
2751  if (m_currentEvent != 0)
2752  {
2754  }
2755 
2756  if (m_powerRestricted)
2757  {
2758  NS_LOG_DEBUG ("Transmitting with power restriction");
2759  }
2760  else
2761  {
2762  NS_LOG_DEBUG ("Transmitting without power restriction");
2763  }
2764 
2765  if (m_state->GetState () == WifiPhyState::OFF)
2766  {
2767  NS_LOG_DEBUG ("Transmission canceled because device is OFF");
2768  return;
2769  }
2770 
2771  double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ());
2772  NotifyTxBegin (psdus, txPowerW);
2773  m_phyTxPsduBeginTrace (psdus, txVector, txPowerW);
2774  for (auto const& psdu : psdus)
2775  {
2776  NotifyMonitorSniffTx (psdu.second, GetFrequency (), txVector, psdu.first);
2777  }
2778  m_state->SwitchToTx (txDuration, psdus, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
2779 
2780  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdus, txVector, txDuration, GetPhyBand ());
2781 
2782  if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
2783  {
2784  ppdu->SetTruncatedTx ();
2785  }
2786 
2787  m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdus); //TODO: fix for MU
2788 
2789  StartTx (ppdu);
2790 
2791  m_channelAccessRequested = false;
2792  m_powerRestricted = false;
2793 }
2794 
2795 void
2797 {
2798  NS_LOG_FUNCTION (this << *event);
2799  NS_ASSERT (!IsStateRx ());
2801  NS_ASSERT (m_currentEvent != 0);
2802  NS_ASSERT (event->GetStartTime () == m_currentEvent->GetStartTime ());
2803  NS_ASSERT (event->GetEndTime () == m_currentEvent->GetEndTime ());
2804 
2805  uint16_t channelWidth;
2806  if (event->GetTxVector ().GetChannelWidth () >= 40)
2807  {
2808  channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
2809  }
2810  else
2811  {
2812  channelWidth = event->GetTxVector ().GetChannelWidth ();
2813  }
2814  auto band = GetBand (channelWidth);
2816  double snr = snrPer.snr;
2817  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2818 
2819  if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (band), snr, m_channelWidth)))
2820  {
2821  NotifyRxBegin (GetAddressedPsduInPpdu (event->GetPpdu ()), event->GetRxPowerWPerBand ());
2822 
2824  WifiTxVector txVector = event->GetTxVector ();
2825 
2826  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HT_GF)
2827  {
2828  //No non-HT PHY header for HT GF
2829  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2830  m_state->SwitchMaybeToCcaBusy (remainingPreambleHeaderDuration);
2831  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2832  }
2833  else
2834  {
2835  //Schedule end of non-HT PHY header
2836  Time remainingPreambleAndNonHtHeaderDuration = GetPhyPreambleDuration (txVector) + GetPhyHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2837  m_state->SwitchMaybeToCcaBusy (remainingPreambleAndNonHtHeaderDuration);
2838  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleAndNonHtHeaderDuration, &WifiPhy::ContinueReceiveHeader, this, event);
2839  }
2840  }
2841  else
2842  {
2843  NS_LOG_DEBUG ("Drop packet because PHY preamble detection failed");
2846  m_currentEvent = 0;
2847 
2848  // Like CCA-SD, CCA-ED is governed by the 4μs CCA window to flag CCA-BUSY
2849  // for any received signal greater than the CCA-ED threshold.
2850  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2851  {
2853  }
2854  }
2855 }
2856 
2857 void
2859 {
2860  NS_LOG_FUNCTION (this << *event);
2862 
2863  uint16_t channelWidth;
2864  if (event->GetTxVector ().GetChannelWidth () >= 40)
2865  {
2866  channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
2867  }
2868  else
2869  {
2870  channelWidth = event->GetTxVector ().GetChannelWidth ();
2871  }
2873 
2874  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2875  if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded
2876  {
2877  NS_LOG_DEBUG ("Received non-HT PHY header");
2878  WifiTxVector txVector = event->GetTxVector ();
2879  Time remainingRxDuration = event->GetEndTime () - Simulator::Now ();
2880  m_state->SwitchMaybeToCcaBusy (remainingRxDuration);
2881  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPhyPreambleDuration (txVector) - GetPhyHeaderDuration (txVector);
2882  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2883  }
2884  else //non-HT PHY header reception failed
2885  {
2886  NS_LOG_DEBUG ("Abort reception because non-HT PHY header reception failed");
2888  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2889  {
2891  }
2892  }
2893 }
2894 
2895 void
2897 {
2898  //The total RX power corresponds to the maximum over all the bands
2899  auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
2900  [] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
2901  return p1.second < p2.second;
2902  });
2903  NS_LOG_FUNCTION (this << *ppdu << it->second);
2904  WifiTxVector txVector = ppdu->GetTxVector ();
2905  Time rxDuration = ppdu->GetTxDuration ();
2906  Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
2907  Time endRx = Simulator::Now () + rxDuration;
2908 
2909  if (m_state->GetState () == WifiPhyState::OFF)
2910  {
2911  NS_LOG_DEBUG ("Cannot start RX because device is OFF");
2912  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2913  {
2915  }
2916  return;
2917  }
2918 
2919  if (ppdu->IsTruncatedTx ())
2920  {
2921  NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
2922  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2923  {
2925  }
2926  return;
2927  }
2928 
2929  if (!txVector.GetModeInitialized ())
2930  {
2931  //If SetRate method was not called above when filling in txVector, this means the PHY does support the rate indicated in PHY SIG headers
2932  NS_LOG_DEBUG ("drop packet because of unsupported RX mode");
2934  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2935  {
2937  }
2938  return;
2939  }
2940 
2941  switch (m_state->GetState ())
2942  {
2944  NS_LOG_DEBUG ("drop packet because of channel switching");
2946  /*
2947  * Packets received on the upcoming channel are added to the event list
2948  * during the switching state. This way the medium can be correctly sensed
2949  * when the device listens to the channel for the first time after the
2950  * switching e.g. after channel switching, the channel may be sensed as
2951  * busy due to other devices' transmissions started before the end of
2952  * the switching.
2953  */
2954  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2955  {
2956  //that packet will be noise _after_ the completion of the channel switching.
2958  }
2959  break;
2960  case WifiPhyState::RX:
2961  NS_ASSERT (m_currentEvent != 0);
2962  if (m_frameCaptureModel != 0
2963  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2964  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2965  {
2967  NS_LOG_DEBUG ("Switch to new packet");
2968  StartRx (event);
2969  }
2970  else
2971  {
2972  NS_LOG_DEBUG ("Drop packet because already in Rx");
2974  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2975  {
2976  //that packet will be noise _after_ the reception of the currently-received packet.
2978  }
2979  }
2980  break;
2981  case WifiPhyState::TX:
2982  NS_LOG_DEBUG ("Drop packet because already in Tx");
2984  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2985  {
2986  //that packet will be noise _after_ the transmission of the currently-transmitted packet.
2988  }
2989  break;
2991  if (m_currentEvent != 0)
2992  {
2993  if (m_frameCaptureModel != 0
2994  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2995  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2996  {
2998  NS_LOG_DEBUG ("Switch to new packet");
2999  StartRx (event);
3000  }
3001  else
3002  {
3003  NS_LOG_DEBUG ("Drop packet because already in Rx");
3004  NotifyRxDrop (ppdu->GetPsdu (), RXING);
3005  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
3006  {
3007  //that packet will be noise _after_ the reception of the currently-received packet.
3009  }
3010  }
3011  }
3012  else
3013  {
3014  StartRx (event);
3015  }
3016  break;
3017  case WifiPhyState::IDLE:
3018  StartRx (event);
3019  break;
3020  case WifiPhyState::SLEEP:
3021  NS_LOG_DEBUG ("Drop packet because in sleep mode");
3023  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
3024  {
3025  //that packet will be noise _after_ the sleep period.
3027  }
3028  break;
3029  default:
3030  NS_FATAL_ERROR ("Invalid WifiPhy state.");
3031  break;
3032  }
3033 }
3034 
3035 void
3037 {
3038  //We are here because we have received the first bit of a packet and we are
3039  //not going to be able to synchronize on it
3040  //In this model, CCA becomes busy when the aggregation of all signals as
3041  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
3042  uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
3043  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
3044  if (!delayUntilCcaEnd.IsZero ())
3045  {
3046  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
3047  }
3048 }
3049 
3050 void
3052 {
3053  NS_LOG_FUNCTION (this << *event);
3056  bool canReceivePayload = false;
3057  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
3058  WifiModulationClass modulation = ppdu->GetModulation ();
3059  //calculate PER on the primary 20 MHz channel for PHY headers
3060  uint16_t primaryChannelWidth = std::min (event->GetTxVector ().GetChannelWidth (), static_cast<uint16_t> (20));
3061  auto primaryBand = GetBand (primaryChannelWidth);
3062  if (modulation >= WIFI_MOD_CLASS_HT)
3063  {
3065  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
3066  canReceivePayload = (m_random->GetValue () > snrPer.per);
3067  }
3068  else
3069  {
3070  //If we are here, this means non-HT PHY header was already successfully received
3071  canReceivePayload = true;
3072  }
3073  WifiTxVector txVector = event->GetTxVector ();
3074  Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePhyPreambleAndHeaderDuration (txVector);
3075  bool success = false;
3076  if (canReceivePayload) //PHY reception succeeded
3077  {
3079  if (psdu)
3080  {
3081  WifiMode txMode = txVector.GetMode (GetStaId ());
3082  uint8_t nss = txVector.GetNssMax();
3083  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
3084  {
3085  uint16_t staId = GetStaId ();
3086  for (const auto & info : txVector.GetHeMuUserInfoMap ())
3087  {
3088  if (info.first == staId)
3089  {
3090  nss = info.second.nss; //no need to look at other PSDUs
3091  break;
3092  }
3093  }
3094  }
3095  if (nss > GetMaxSupportedRxSpatialStreams ())
3096  {
3097  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
3099  }
3100  else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ()))
3101  {
3102  NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width");
3104  }
3105  else if (IsModeSupported (txMode) || IsMcsSupported (txMode))
3106  {
3107  m_statusPerMpdu.clear();
3108  if (psdu->GetNMpdus () > 1)
3109  {
3110  ScheduleEndOfMpdus (event);
3111  }
3112  m_state->SwitchToRx (payloadDuration);
3113  m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is triggered only if headers have been correctly decoded and that the mode within is supported
3114  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
3115  success = true;
3116  NS_LOG_DEBUG ("Receiving PSDU");
3117  }
3118  else //mode is not allowed
3119  {
3120  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
3122  }
3123  }
3124  else
3125  {
3126  NS_ASSERT (ppdu->IsMu ());
3127  NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
3128  payloadDuration = NanoSeconds (0); //so as to call AbortCurrentReception below
3129  m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is also triggered for filtered PPDUs
3130  }
3131  if (modulation == WIFI_MOD_CLASS_HE)
3132  {
3133  HePreambleParameters params;
3134  params.rssiW = event->GetRxPowerW (primaryBand);
3135  params.bssColor = event->GetTxVector ().GetBssColor ();
3136  NotifyEndOfHePreamble (params);
3137  }
3138  }
3139  else //PHY reception failed
3140  {
3141  NS_LOG_DEBUG ("Drop packet because HT PHY header reception failed");
3143  }
3144  if (!success)
3145  {
3146  if (payloadDuration.IsStrictlyPositive ())
3147  {
3148  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event);
3149  }
3150  else
3151  {
3152  AbortCurrentReception (FILTERED); //immediately followed by PHY-RXEND (Filtered)
3153  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
3154  {
3156  }
3157  }
3158  }
3159 }
3160 
3161 void
3163 {
3164  NS_LOG_FUNCTION (this << *event);
3165  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
3166  WifiTxVector txVector = event->GetTxVector ();
3167  Time endOfMpduDuration = NanoSeconds (0);
3168  Time relativeStart = NanoSeconds (0);
3169  Time psduDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
3170  Time remainingAmpduDuration = psduDuration;
3171  MpduType mpdutype = FIRST_MPDU_IN_AGGREGATE;
3172  uint32_t totalAmpduSize = 0;
3173  double totalAmpduNumSymbols = 0.0;
3175  size_t nMpdus = psdu->GetNMpdus ();
3176  uint16_t staId = SU_STA_ID;
3177  auto mpdu = psdu->begin ();
3178  for (size_t i = 0; i < nMpdus && mpdu != psdu->end (); ++mpdu)
3179  {
3180  Time mpduDuration = GetPayloadDuration (psdu->GetAmpduSubframeSize (i), txVector,
3181  GetPhyBand (), mpdutype, true,
3182  totalAmpduSize, totalAmpduNumSymbols,
3183  staId);
3184 
3185  remainingAmpduDuration -= mpduDuration;
3186  if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDU coming
3187  {
3188  mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
3189  }
3190 
3191  endOfMpduDuration += mpduDuration;
3192  Simulator::Schedule (endOfMpduDuration, &WifiPhy::EndOfMpdu, this, event, Create<WifiPsdu> (*mpdu, false), i, relativeStart, mpduDuration);
3193 
3194  //Prepare next iteration
3195  ++i;
3196  relativeStart += mpduDuration;
3197  mpdutype = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
3198  }
3199 }
3200 
3201 void
3202 WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
3203 {
3204  NS_LOG_FUNCTION (this << *event << mpduIndex << relativeStart << mpduDuration);
3205  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
3206  uint16_t staId = GetStaId ();
3207  WifiTxVector txVector = event->GetTxVector ();
3208  uint16_t channelWidth = std::min (GetChannelWidth (), txVector.GetChannelWidth ());
3209  double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), GetBand (channelWidth));
3210 
3211  std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, relativeStart, mpduDuration);
3212  NS_LOG_DEBUG ("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
3213  ", correct reception: " << rxInfo.first << ", Signal/Noise: " << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
3214 
3215  m_signalNoise = rxInfo.second;
3216  m_statusPerMpdu.push_back (rxInfo.first);
3217 
3218  if (rxInfo.first)
3219  {
3220  m_state->ContinueRxNextMpdu (Copy (psdu), snr, event->GetTxVector ());
3221  }
3222 }
3223 
3224 void
3226 {
3227  Time psduDuration = event->GetEndTime () - event->GetStartTime ();
3228  NS_LOG_FUNCTION (this << *event << psduDuration);
3230  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3231 
3232  uint16_t staId = GetStaId ();
3233  Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (event->GetPpdu ());
3234  if (psdu->GetNMpdus () == 1)
3235  {
3236  //We do not enter here for A-MPDU since this is done in WifiPhy::EndOfMpdu
3237  std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, NanoSeconds (0), psduDuration);
3238  m_signalNoise = rxInfo.second;
3239  m_statusPerMpdu.push_back (rxInfo.first);
3240  }
3241 
3242  NotifyRxEnd (psdu);
3243  WifiTxVector txVector = event->GetTxVector ();
3244  uint16_t channelWidth = std::min (GetChannelWidth (), txVector.GetChannelWidth ());
3245  WifiSpectrumBand band;
3246  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
3247  {
3248  band = GetRuBand (txVector, staId);
3249  channelWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
3250  }
3251  else
3252  {
3253  band = GetBand (channelWidth);
3254  }
3255  double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), band);
3256  if (std::count (m_statusPerMpdu.begin (), m_statusPerMpdu.end (), true))
3257  {
3258  //At least one MPDU has been successfully received
3259  WifiTxVector txVector = event->GetTxVector ();
3260  NotifyMonitorSniffRx (psdu, GetFrequency (), txVector, m_signalNoise, m_statusPerMpdu, staId);
3261  m_state->SwitchFromRxEndOk (Copy (psdu), snr, txVector, staId, m_statusPerMpdu);
3262  }
3263  else
3264  {
3265  m_state->SwitchFromRxEndError (Copy (psdu), snr);
3266  }
3267 
3269  m_currentEvent = 0;
3271 }
3272 
3273 std::pair<bool, SignalNoiseDbm>
3275  Time relativeMpduStart, Time mpduDuration)
3276 {
3277  NS_LOG_FUNCTION (this << *psdu << *event << staId << relativeMpduStart << mpduDuration);
3278  uint16_t channelWidth = std::min (GetChannelWidth (), event->GetTxVector ().GetChannelWidth ());
3279  WifiTxVector txVector = event->GetTxVector ();
3280  WifiSpectrumBand band;
3281  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
3282  {
3283  band = GetRuBand (txVector, staId);
3284  channelWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
3285  }
3286  else
3287  {
3288  band = GetBand (channelWidth);
3289  }
3290  InterferenceHelper::SnrPer snrPer = m_interference.CalculatePayloadSnrPer (event, channelWidth, band, staId, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
3291 
3292  WifiMode mode = event->GetTxVector ().GetMode (staId);
3293  NS_LOG_DEBUG ("mode=" << (mode.GetDataRate (event->GetTxVector (), staId)) <<
3294  ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << psdu->GetSize () <<
3295  ", relativeStart = " << relativeMpduStart.As (Time::NS) << ", duration = " << mpduDuration.As (Time::NS));
3296 
3297  // There are two error checks: PER and receive error model check.
3298  // PER check models is typical for Wi-Fi and is based on signal modulation;
3299  // Receive error model is optional, if we have an error model and
3300  // it indicates that the packet is corrupt, drop the packet.
3301  SignalNoiseDbm signalNoise;
3302  signalNoise.signal = WToDbm (event->GetRxPowerW (band));
3303  signalNoise.noise = WToDbm (event->GetRxPowerW (band) / snrPer.snr);
3304  if (m_random->GetValue () > snrPer.per &&
3305  !(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (psdu->GetPacket ()->Copy ())))
3306  {
3307  NS_LOG_DEBUG ("Reception succeeded: " << psdu);
3308  return std::make_pair (true, signalNoise);
3309  }
3310  else
3311  {
3312  NS_LOG_DEBUG ("Reception failed: " << psdu);
3313  return std::make_pair (false, signalNoise);
3314  }
3315 }
3316 
3318 WifiPhy::GetRuBand (WifiTxVector txVector, uint16_t staId)
3319 {
3321  WifiSpectrumBand band;
3322  HeRu::RuSpec ru = txVector.GetRu (staId);
3323  uint16_t channelWidth = txVector.GetChannelWidth ();
3324  NS_ASSERT (channelWidth <= GetChannelWidth ());
3325  HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.ruType, ru.index);
3326  HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
3327  band = ConvertHeRuSubcarriers (channelWidth, range);
3328  return band;
3329 }
3330 
3332 WifiPhy::ConvertHeRuSubcarriers (uint16_t channelWidth, HeRu::SubcarrierRange range) const
3333 {
3334  NS_ASSERT_MSG (false, "802.11ax can only be used with SpectrumWifiPhy");
3335  WifiSpectrumBand convertedSubcarriers;
3336  return convertedSubcarriers;
3337 }
3338 
3339 void
3341 {
3342  NS_LOG_FUNCTION (this);
3344  {
3345  m_powerRestricted = false;
3346  }
3347 }
3348 
3349 void
3351 {
3352  NS_LOG_FUNCTION (this << *event);
3353  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3354  NS_ASSERT (!IsStateRx ());
3356  m_currentEvent = 0;
3358 }
3359 
3360 void
3362 {
3363  NS_LOG_FUNCTION (this);
3364  m_channelAccessRequested = true;
3365 }
3366 
3367 // Clause 15 rates (DSSS)
3368 
3369 WifiMode
3371 {
3372  static WifiMode mode =
3373  WifiModeFactory::CreateWifiMode ("DsssRate1Mbps",
3375  true,
3377  2);
3378  return mode;
3379 }
3380 
3381 WifiMode
3383 {
3384  static WifiMode mode =
3385  WifiModeFactory::CreateWifiMode ("DsssRate2Mbps",
3387  true,
3389  4);
3390  return mode;
3391 }
3392 
3393 
3394 // Clause 18 rates (HR/DSSS)
3395 
3396 WifiMode
3398 {
3399  static WifiMode mode =
3400  WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps",
3402  true,
3404  16);
3405  return mode;
3406 }
3407 
3408 WifiMode
3410 {
3411  static WifiMode mode =
3412  WifiModeFactory::CreateWifiMode ("DsssRate11Mbps",
3414  true,
3416  256);
3417  return mode;
3418 }
3419 
3420 
3421 // Clause 19.5 rates (ERP-OFDM)
3422 
3423 WifiMode
3425 {
3426  static WifiMode mode =
3427  WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps",
3429  true,
3431  2);
3432  return mode;
3433 }
3434 
3435 WifiMode
3437 {
3438  static WifiMode mode =
3439  WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps",
3441  false,
3443  2);
3444  return mode;
3445 }
3446 
3447 WifiMode
3449 {
3450  static WifiMode mode =
3451  WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps",
3453  true,
3455  4);
3456  return mode;
3457 }
3458 
3459 WifiMode
3461 {
3462  static WifiMode mode =
3463  WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps",
3465  false,
3467  4);
3468  return mode;
3469 }
3470 
3471 WifiMode
3473 {
3474  static WifiMode mode =
3475  WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps",
3477  true,
3479  16);
3480  return mode;
3481 }
3482 
3483 WifiMode
3485 {
3486  static WifiMode mode =
3487  WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps",
3489  false,
3491  16);
3492  return mode;
3493 }
3494 
3495 WifiMode
3497 {
3498  static WifiMode mode =
3499  WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps",
3501  false,
3503  64);
3504  return mode;
3505 }
3506 
3507 WifiMode
3509 {
3510  static WifiMode mode =
3511  WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps",
3513  false,
3515  64);
3516  return mode;
3517 }
3518 
3519 
3520 // Clause 17 rates (OFDM)
3521 
3522 WifiMode
3524 {
3525  static WifiMode mode =
3526  WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps",
3528  true,
3530  2);
3531  return mode;
3532 }
3533 
3534 WifiMode
3536 {
3537  static WifiMode mode =
3538  WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps",
3540  false,
3542  2);
3543  return mode;
3544 }
3545 
3546 WifiMode
3548 {
3549  static WifiMode mode =
3550  WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps",
3552  true,
3554  4);
3555  return mode;
3556 }
3557 
3558 WifiMode
3560 {
3561  static WifiMode mode =
3562  WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps",
3564  false,
3566  4);
3567  return mode;
3568 }
3569 
3570 WifiMode
3572 {
3573  static WifiMode mode =
3574  WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps",
3576  true,
3578  16);
3579  return mode;
3580 }
3581 
3582 WifiMode
3584 {
3585  static WifiMode mode =
3586  WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps",
3588  false,
3590  16);
3591  return mode;
3592 }
3593 
3594 WifiMode
3596 {
3597  static WifiMode mode =
3598  WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps",
3600  false,
3602  64);
3603  return mode;
3604 }
3605 
3606 WifiMode
3608 {
3609  static WifiMode mode =
3610  WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps",
3612  false,
3614  64);
3615  return mode;
3616 }
3617 
3618 
3619 // 10 MHz channel rates
3620 
3621 WifiMode
3623 {
3624  static WifiMode mode =
3625  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz",
3627  true,
3629  2);
3630  return mode;
3631 }
3632 
3633 WifiMode
3635 {
3636  static WifiMode mode =
3637  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz",
3639  false,
3641  2);
3642  return mode;
3643 }
3644 
3645 WifiMode
3647 {
3648  static WifiMode mode =
3649  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz",
3651  true,
3653  4);
3654  return mode;
3655 }
3656 
3657 WifiMode
3659 {
3660  static WifiMode mode =
3661  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz",
3663  false,
3665  4);
3666  return mode;
3667 }
3668 
3669 WifiMode
3671 {
3672  static WifiMode mode =
3673  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz",
3675  true,
3677  16);
3678  return mode;
3679 }
3680 
3681 WifiMode
3683 {
3684  static WifiMode mode =
3685  WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz",
3687  false,
3689  16);
3690  return mode;
3691 }
3692 
3693 WifiMode
3695 {
3696  static WifiMode mode =
3697  WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz",
3699  false,
3701  64);
3702  return mode;
3703 }
3704 
3705 WifiMode
3707 {
3708  static WifiMode mode =
3709  WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz",
3711  false,
3713  64);
3714  return mode;
3715 }
3716 
3717 
3718 // 5 MHz channel rates
3719 
3720 WifiMode
3722 {
3723  static WifiMode mode =
3724  WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz",
3726  true,
3728  2);
3729  return mode;
3730 }
3731 
3732 WifiMode
3734 {
3735  static WifiMode mode =
3736  WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz",
3738  false,
3740  2);
3741  return mode;
3742 }
3743 
3744 WifiMode
3746 {
3747  static WifiMode mode =
3748  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz",
3750  true,
3752  4);
3753  return mode;
3754 }
3755 
3756 WifiMode
3758 {
3759  static WifiMode mode =
3760  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz",
3762  false,
3764  4);
3765  return mode;
3766 }
3767 
3768 WifiMode
3770 {
3771  static WifiMode mode =
3772  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz",
3774  true,
3776  16);
3777  return mode;
3778 }
3779 
3780 WifiMode
3782 {
3783  static WifiMode mode =
3784  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz",
3786  false,
3788  16);
3789  return mode;
3790 }
3791 
3792 WifiMode
3794 {
3795  static WifiMode mode =
3796  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz",
3798  false,
3800  64);
3801  return mode;
3802 }
3803 
3804 WifiMode
3806 {
3807  static WifiMode mode =
3808  WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz",
3810  false,
3812  64);
3813  return mode;
3814 }
3815 
3816 
3817 // Clause 20
3818 
3819 WifiMode
3821 {
3822  static WifiMode mcs =
3824  return mcs;
3825 }
3826 
3827 WifiMode
3829 {
3830  static WifiMode mcs =
3832  return mcs;
3833 }
3834 
3835 WifiMode
3837 {
3838  static WifiMode mcs =
3840  return mcs;
3841 }
3842 
3843 WifiMode
3845 {
3846  static WifiMode mcs =
3848  return mcs;
3849 }
3850 
3851 WifiMode
3853 {
3854  static WifiMode mcs =
3856  return mcs;
3857 }
3858 
3859 WifiMode
3861 {
3862  static WifiMode mcs =
3864  return mcs;
3865 }
3866 
3867 WifiMode
3869 {
3870  static WifiMode mcs =
3872  return mcs;
3873 }
3874 
3875 WifiMode
3877 {
3878  static WifiMode mcs =
3880  return mcs;
3881 }
3882 
3883 WifiMode
3885 {
3886  static WifiMode mcs =
3888  return mcs;
3889 }
3890 
3891 WifiMode
3893 {
3894  static WifiMode mcs =
3896  return mcs;
3897 }
3898 
3899 WifiMode
3901 {
3902  static WifiMode mcs =
3904  return mcs;
3905 }
3906 
3907 WifiMode
3909 {
3910  static WifiMode mcs =
3912  return mcs;
3913 }
3914 
3915 WifiMode
3917 {
3918  static WifiMode mcs =
3920  return mcs;
3921 }
3922 
3923 WifiMode
3925 {
3926  static WifiMode mcs =
3928  return mcs;
3929 }
3930 
3931 WifiMode
3933 {
3934  static WifiMode mcs =
3936  return mcs;
3937 }
3938 
3939 WifiMode
3941 {
3942  static WifiMode mcs =
3944  return mcs;
3945 }
3946 
3947 WifiMode
3949 {
3950  static WifiMode mcs =
3952  return mcs;
3953 }
3954 
3955 WifiMode
3957 {
3958  static WifiMode mcs =
3960  return mcs;
3961 }
3962 
3963 WifiMode
3965 {
3966  static WifiMode mcs =
3968  return mcs;
3969 }
3970 
3971 WifiMode
3973 {
3974  static WifiMode mcs =
3976  return mcs;
3977 }
3978 
3979 WifiMode
3981 {
3982  static WifiMode mcs =
3984  return mcs;
3985 }
3986 
3987 WifiMode
3989 {
3990  static WifiMode mcs =
3992  return mcs;
3993 }
3994 
3995 WifiMode
3997 {
3998  static WifiMode mcs =
4000  return mcs;
4001 }
4002 
4003 WifiMode
4005 {
4006  static WifiMode mcs =
4008  return mcs;
4009 }
4010 
4011 WifiMode
4013 {
4014  static WifiMode mcs =
4016  return mcs;
4017 }
4018 
4019 WifiMode
4021 {
4022  static WifiMode mcs =
4024  return mcs;
4025 }
4026 
4027 WifiMode
4029 {
4030  static WifiMode mcs =
4032  return mcs;
4033 }
4034 
4035 WifiMode
4037 {
4038  static WifiMode mcs =
4040  return mcs;
4041 }
4042 
4043 WifiMode
4045 {
4046  static WifiMode mcs =
4048  return mcs;
4049 }
4050 
4051 WifiMode
4053 {
4054  static WifiMode mcs =
4056  return mcs;
4057 }
4058 
4059 WifiMode
4061 {
4062  static WifiMode mcs =
4064  return mcs;
4065 }
4066 
4067 WifiMode
4069 {
4070  static WifiMode mcs =
4072  return mcs;
4073 }
4074 
4075 
4076 // Clause 22
4077 
4078 WifiMode
4080 {
4081  static WifiMode mcs =
4083  return mcs;
4084 }
4085 
4086 WifiMode
4088 {
4089  static WifiMode mcs =
4091  return mcs;
4092 }
4093 
4094 WifiMode
4096 {
4097  static WifiMode mcs =
4099  return mcs;
4100 }
4101 
4102 WifiMode
4104 {
4105  static WifiMode mcs =
4107  return mcs;
4108 }
4109 
4110 WifiMode
4112 {
4113  static WifiMode mcs =
4115  return mcs;
4116 }
4117 
4118 WifiMode
4120 {
4121  static WifiMode mcs =
4123  return mcs;
4124 }
4125 
4126 WifiMode
4128 {
4129  static WifiMode mcs =
4131  return mcs;
4132 }
4133 
4134 WifiMode
4136 {
4137  static WifiMode mcs =
4139  return mcs;
4140 }
4141 
4142 WifiMode
4144 {
4145  static WifiMode mcs =
4147  return mcs;
4148 }
4149 
4150 WifiMode
4152 {
4153  static WifiMode mcs =
4155  return mcs;
4156 }
4157 
4158 // Clause 26
4159 
4160 WifiMode
4162 {
4163  static WifiMode mcs =
4165  return mcs;
4166 }
4167 
4168 WifiMode
4170 {
4171  static WifiMode mcs =
4173  return mcs;
4174 }
4175 
4176 WifiMode
4178 {
4179  static WifiMode mcs =
4181  return mcs;
4182 }
4183 
4184 WifiMode
4186 {
4187  static WifiMode mcs =
4189  return mcs;
4190 }
4191 
4192 WifiMode
4194 {
4195  static WifiMode mcs =
4197  return mcs;
4198 }
4199 
4200 WifiMode
4202 {
4203  static WifiMode mcs =
4205  return mcs;
4206 }
4207 
4208 WifiMode
4210 {
4211  static WifiMode mcs =
4213  return mcs;
4214 }
4215 
4216 WifiMode
4218 {
4219  static WifiMode mcs =
4221  return mcs;
4222 }
4223 
4224 WifiMode
4226 {
4227  static WifiMode mcs =
4229  return mcs;
4230 }
4231 
4232 WifiMode
4234 {
4235  static WifiMode mcs =
4237  return mcs;
4238 }
4239 
4240 WifiMode
4242 {
4243  static WifiMode mcs =
4245  return mcs;
4246 }
4247 
4248 WifiMode
4250 {
4251  static WifiMode mcs =
4253  return mcs;
4254 }
4255 
4256 bool
4258 {
4259  for (uint8_t i = 0; i < GetNModes (); i++)
4260  {
4261  if (mode == GetMode (i))
4262  {
4263  return true;
4264  }
4265  }
4266  return false;
4267 }
4268 
4269 bool
4271 {
4272  WifiModulationClass modulation = mcs.GetModulationClass ();
4273  if (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
4274  || modulation == WIFI_MOD_CLASS_HE)
4275  {
4276  return IsMcsSupported (modulation, mcs.GetMcsValue ());
4277  }
4278  return false;
4279 }
4280 
4281 bool
4283 {
4284  if (m_mcsIndexMap.find (mc) == m_mcsIndexMap.end ())
4285  {
4286  return false;
4287  }
4288  if (m_mcsIndexMap.at (mc).find (mcs) == m_mcsIndexMap.at (mc).end ())
4289  {
4290  return false;
4291  }
4292  return true;
4293 }
4294 
4295 uint8_t
4297 {
4298  return static_cast<uint8_t> (m_deviceRateSet.size ());
4299 }
4300 
4301 WifiMode
4302 WifiPhy::GetMode (uint8_t mode) const
4303 {
4304  return m_deviceRateSet[mode];
4305 }
4306 
4307 uint8_t
4308 WifiPhy::GetNMcs (void) const
4309 {
4310  return static_cast<uint8_t> (m_deviceMcsSet.size ());
4311 }
4312 
4313 WifiMode
4314 WifiPhy::GetMcs (uint8_t mcs) const
4315 {
4316  return m_deviceMcsSet[mcs];
4317 }
4318 
4319 WifiMode
4320 WifiPhy::GetMcs (WifiModulationClass modulation, uint8_t mcs) const
4321 {
4322  NS_ASSERT_MSG (IsMcsSupported (modulation, mcs), "Unsupported MCS");
4323  uint8_t index = m_mcsIndexMap.at (modulation).at (mcs);
4324  NS_ASSERT (index < m_deviceMcsSet.size ());
4325  WifiMode mode = m_deviceMcsSet[index];
4326  NS_ASSERT (mode.GetModulationClass () == modulation);
4327  NS_ASSERT (mode.GetMcsValue () == mcs);
4328  return mode;
4329 }
4330 
4331 WifiMode
4332 WifiPhy::GetHtMcs (uint8_t mcs)
4333 {
4334  WifiMode mode;
4335  switch (mcs)
4336  {
4337  case 0:
4338  mode = WifiPhy::GetHtMcs0 ();
4339  break;
4340  case 1:
4341  mode = WifiPhy::GetHtMcs1 ();
4342  break;
4343  case 2:
4344  mode = WifiPhy::GetHtMcs2 ();
4345  break;
4346  case 3:
4347  mode = WifiPhy::GetHtMcs3 ();
4348  break;
4349  case 4:
4350  mode = WifiPhy::GetHtMcs4 ();
4351  break;
4352  case 5:
4353  mode = WifiPhy::GetHtMcs5 ();
4354  break;
4355  case 6:
4356  mode = WifiPhy::GetHtMcs6 ();
4357  break;
4358  case 7:
4359  mode = WifiPhy::GetHtMcs7 ();
4360  break;
4361  case 8:
4362  mode = WifiPhy::GetHtMcs8 ();
4363  break;
4364  case 9:
4365  mode = WifiPhy::GetHtMcs9 ();
4366  break;
4367  case 10:
4368  mode = WifiPhy::GetHtMcs10 ();
4369  break;
4370  case 11:
4371  mode = WifiPhy::GetHtMcs11 ();
4372  break;
4373  case 12:
4374  mode = WifiPhy::GetHtMcs12 ();
4375  break;
4376  case 13:
4377  mode = WifiPhy::GetHtMcs13 ();
4378  break;
4379  case 14:
4380  mode = WifiPhy::GetHtMcs14 ();
4381  break;
4382  case 15:
4383  mode = WifiPhy::GetHtMcs15 ();
4384  break;
4385  case 16:
4386  mode = WifiPhy::GetHtMcs16 ();
4387  break;
4388  case 17:
4389  mode = WifiPhy::GetHtMcs17 ();
4390  break;
4391  case 18:
4392  mode = WifiPhy::GetHtMcs18 ();
4393  break;
4394  case 19:
4395  mode = WifiPhy::GetHtMcs19 ();
4396  break;
4397  case 20:
4398  mode = WifiPhy::GetHtMcs20 ();
4399  break;
4400  case 21:
4401  mode = WifiPhy::GetHtMcs21 ();
4402  break;
4403  case 22:
4404  mode = WifiPhy::GetHtMcs22 ();
4405  break;
4406  case 23:
4407  mode = WifiPhy::GetHtMcs23 ();
4408  break;
4409  case 24:
4410  mode = WifiPhy::GetHtMcs24 ();
4411  break;
4412  case 25:
4413  mode = WifiPhy::GetHtMcs25 ();
4414  break;
4415  case 26:
4416  mode = WifiPhy::GetHtMcs26 ();
4417  break;
4418  case 27:
4419  mode = WifiPhy::GetHtMcs27 ();
4420  break;
4421  case 28:
4422  mode = WifiPhy::GetHtMcs28 ();
4423  break;
4424  case 29:
4425  mode = WifiPhy::GetHtMcs29 ();
4426  break;
4427  case 30:
4428  mode = WifiPhy::GetHtMcs30 ();
4429  break;
4430  case 31:
4431  mode = WifiPhy::GetHtMcs31 ();
4432  break;
4433  default:
4434  NS_ABORT_MSG ("Invalid HT MCS");
4435  break;
4436  }
4437  return mode;
4438 }
4439 
4440 WifiMode
4441 WifiPhy::GetVhtMcs (uint8_t mcs)
4442 {
4443  WifiMode mode;
4444  switch (mcs)
4445  {
4446  case 0:
4447  mode = WifiPhy::GetVhtMcs0 ();
4448  break;
4449  case 1:
4450  mode = WifiPhy::GetVhtMcs1 ();
4451  break;
4452  case 2:
4453  mode = WifiPhy::GetVhtMcs2 ();
4454  break;
4455  case 3:
4456  mode = WifiPhy::GetVhtMcs3 ();
4457  break;
4458  case 4:
4459  mode = WifiPhy::GetVhtMcs4 ();
4460  break;
4461  case 5:
4462  mode = WifiPhy::GetVhtMcs5 ();
4463  break;
4464  case 6:
4465  mode = WifiPhy::GetVhtMcs6 ();
4466  break;
4467  case 7:
4468  mode = WifiPhy::GetVhtMcs7 ();
4469  break;
4470  case 8:
4471  mode = WifiPhy::GetVhtMcs8 ();
4472  break;
4473  case 9:
4474  mode = WifiPhy::GetVhtMcs9 ();
4475  break;
4476  default:
4477  NS_ABORT_MSG ("Invalid VHT MCS");
4478  break;
4479  }
4480  return mode;
4481 }
4482 
4483 WifiMode
4484 WifiPhy::GetHeMcs (uint8_t mcs)
4485 {
4486  WifiMode mode;
4487  switch (mcs)
4488  {
4489  case 0:
4490  mode = WifiPhy::GetHeMcs0 ();
4491  break;
4492  case 1:
4493  mode = WifiPhy::GetHeMcs1 ();
4494  break;
4495  case 2:
4496  mode = WifiPhy::GetHeMcs2 ();
4497  break;
4498  case 3:
4499  mode = WifiPhy::GetHeMcs3 ();
4500  break;
4501  case 4:
4502  mode = WifiPhy::GetHeMcs4 ();
4503  break;
4504  case 5:
4505  mode = WifiPhy::GetHeMcs5 ();
4506  break;
4507  case 6:
4508  mode = WifiPhy::GetHeMcs6 ();
4509  break;
4510  case 7:
4511  mode = WifiPhy::GetHeMcs7 ();
4512  break;
4513  case 8:
4514  mode = WifiPhy::GetHeMcs8 ();
4515  break;
4516  case 9:
4517  mode = WifiPhy::GetHeMcs9 ();
4518  break;
4519  case 10:
4520  mode = WifiPhy::GetHeMcs10 ();
4521  break;
4522  case 11:
4523  mode = WifiPhy::GetHeMcs11 ();
4524  break;
4525  default:
4526  NS_ABORT_MSG ("Invalid HE MCS");
4527  break;
4528  }
4529  return mode;
4530 }
4531 
4532 bool
4534 {
4535  return m_state->IsStateCcaBusy ();
4536 }
4537 
4538 bool
4540 {
4541  return m_state->IsStateIdle ();
4542 }
4543 
4544 bool
4546 {
4547  return m_state->IsStateRx ();
4548 }
4549 
4550 bool
4552 {
4553  return m_state->IsStateTx ();
4554 }
4555 
4556 bool
4558 {
4559  return m_state->IsStateSwitching ();
4560 }
4561 
4562 bool
4564 {
4565  return m_state->IsStateSleep ();
4566 }
4567 
4568 bool
4570 {
4571  return m_state->IsStateOff ();
4572 }
4573 
4574 Time
4576 {
4577  return m_state->GetDelayUntilIdle ();
4578 }
4579 
4580 Time
4582 {
4583  return m_state->GetLastRxStartTime ();
4584 }
4585 
4586 Time
4588 {
4589  return m_state->GetLastRxEndTime ();
4590 }
4591 
4592 void
4594 {
4595  NS_LOG_FUNCTION (this);
4596  //We are here because we have received the first bit of a packet and we are
4597  //not going to be able to synchronize on it
4598  //In this model, CCA becomes busy when the aggregation of all signals as
4599  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
4600 
4601  uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
4602  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
4603  if (!delayUntilCcaEnd.IsZero ())
4604  {
4605  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
4606  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
4607  }
4608 }
4609 
4610 void
4612 {
4613  NS_LOG_FUNCTION (this << reason);
4615  {
4617  }
4618  if (m_endPhyRxEvent.IsRunning ())
4619  {
4621  }
4622  if (m_endRxEvent.IsRunning ())
4623  {
4624  m_endRxEvent.Cancel ();
4625  }
4626  NotifyRxDrop (GetAddressedPsduInPpdu (m_currentEvent->GetPpdu ()), reason);
4628  if (reason == OBSS_PD_CCA_RESET)
4629  {
4630  m_state->SwitchFromRxAbort ();
4631  }
4632  m_currentEvent = 0;
4633 }
4634 
4635 void
4636 WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
4637 {
4638  NS_LOG_FUNCTION (this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
4639  m_powerRestricted = powerRestricted;
4640  m_txPowerMaxSiso = txPowerMaxSiso;
4641  m_txPowerMaxMimo = txPowerMaxMimo;
4642  NS_ASSERT ((m_currentEvent->GetEndTime () - Simulator::Now ()).IsPositive ());
4645 }
4646 
4647 double
4649 {
4651  if (!m_powerRestricted)
4652  {
4653  return GetPowerDbm (txVector.GetTxPowerLevel ());
4654  }
4655  else
4656  {
4657  if (txVector.GetNssMax () > 1)
4658  {
4659  return std::min (m_txPowerMaxMimo, GetPowerDbm (txVector.GetTxPowerLevel ()));
4660  }
4661  else
4662  {
4663  return std::min (m_txPowerMaxSiso, GetPowerDbm (txVector.GetTxPowerLevel ()));
4664  }
4665  }
4666 }
4667 
4668 void
4670 {
4671  uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
4672  auto primaryBand = GetBand (primaryChannelWidth);
4673  double rxPowerW = event->GetRxPowerW (primaryBand);
4674  NS_LOG_FUNCTION (this << *event << rxPowerW);
4675 
4676  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
4677  m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events
4678 
4680  {
4681  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4682  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4683  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4684  }
4685  else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW (primaryBand)))
4686  {
4687  NS_LOG_DEBUG ("Received a stronger signal during preamble detection: drop current packet and switch to new packet");
4692  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4693  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4694  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4695  }
4696  else
4697  {
4698  NS_LOG_DEBUG ("Drop packet because RX is already decoding preamble");
4700  return;
4701  }
4702  m_currentEvent = event;
4703 }
4704 
4707 {
4708  Ptr<const WifiPsdu> psdu;
4709  if (!ppdu->IsMu ())
4710  {
4711  psdu = ppdu->GetPsdu ();
4712  }
4713  else
4714  {
4715  uint8_t bssColor = 0;
4716  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
4717  if (device)
4718  {
4719  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
4720  if (heConfiguration)
4721  {
4722  UintegerValue bssColorAttribute;
4723  heConfiguration->GetAttribute ("BssColor", bssColorAttribute);
4724  bssColor = bssColorAttribute.Get ();
4725  }
4726  }
4727  uint16_t staId = GetStaId ();
4728  psdu = ppdu->GetPsdu (bssColor, staId);
4729  }
4730  return psdu;
4731 }
4732 
4733 uint16_t
4734 WifiPhy::GetStaId (void) const
4735 {
4736  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
4737  if (device)
4738  {
4739  Ptr<StaWifiMac> mac = DynamicCast<StaWifiMac> (device->GetMac ());
4740  if (mac && mac->IsAssociated ())
4741  {
4742  return mac->GetAssociationId ();
4743  }
4744  }
4745  return SU_STA_ID;
4746 }
4747 
4749 WifiPhy::GetBand (uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
4750 {
4751  WifiSpectrumBand band;
4752  band.first = 0;
4753  band.second = 0;
4754  return band;
4755 }
4756 
4757 int64_t
4758 WifiPhy::AssignStreams (int64_t stream)
4759 {
4760  NS_LOG_FUNCTION (this << stream);
4761  m_random->SetStream (stream);
4762  return 1;
4763 }
4764 
4765 } //namespace ns3
4766 
4767 namespace {
4768 
4772 static class Constructor
4773 {
4774 public:
4776  {
4867  }
4868 } g_constructor;
4869 
4870 }
static class anonymous_namespace{wifi-phy.cc}::Constructor g_constructor
the constructor
ERP-OFDM PHY (Clause 19, Section 19.5)
MpduInfo structure.
Definition: wifi-phy.h:126
static WifiMode GetVhtMcs6()
Return MCS 6 from VHT MCS values.
Definition: wifi-phy.cc:4127
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:2633
static WifiMode GetOfdmRate9MbpsBW5MHz()
Return a WifiMode for OFDM at 9Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3781
Ptr< NetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:2170
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static WifiMode GetErpOfdmRate24Mbps()
Return a WifiMode for ERP-OFDM at 24Mbps.
Definition: wifi-phy.cc:3472
uint8_t GetNTxPower(void) const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:708
bool IsStateSwitching(void) const
Definition: wifi-phy.cc:4557
static WifiMode GetDsssRate11Mbps()
Return a WifiMode for DSSS at 11Mbps.
Definition: wifi-phy.cc:3409
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:968
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:4569
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard(uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard) const
Lookup frequency/width pair for channelNumber/standard pair.
Definition: wifi-phy.cc:1606
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:2018
nanosecond
Definition: nstime.h:118
double signal
in dBm
Definition: wifi-phy.h:121
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
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
Definition: wifi-phy.cc:4217
void NotifyTxBegin(WifiConstPsduMap psdus, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:2576
RuType ruType
RU type.
Definition: he-ru.h:67
static WifiMode GetErpOfdmRate36Mbps()
Return a WifiMode for ERP-OFDM at 36Mbps.
Definition: wifi-phy.cc:3484
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:56
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:701
Time GetEnergyDuration(double energyW, WifiSpectrumBand band) const
uint8_t m_channelNumber
Operating channel number.
Definition: wifi-phy.h:2165
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:2146
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
Definition: wifi-phy.cc:4143
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:56
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.
Ptr< HeConfiguration > GetHeConfiguration(void) const
double GetRxGain(void) const
Return the reception gain (dB).
Definition: wifi-phy.cc:734
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:4257
void AddSupportedChannelWidth(uint16_t width)
Definition: wifi-phy.cc:1585
static WifiMode GetOfdmRate9Mbps()
Return a WifiMode for OFDM at 9Mbps.
Definition: wifi-phy.cc:3535
double GetCcaEdThreshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:661
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:2588
static WifiMode GetOfdmRate18MbpsBW10MHz()
Return a WifiMode for OFDM at 18Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3682
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static WifiMode GetOfdmRate27MbpsBW10MHz()
Return a WifiMode for OFDM at 27Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3706
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:2145
WifiMode GetMcs(uint8_t mcs) const
The WifiPhy::GetMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of tr...
Definition: wifi-phy.cc:4314
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
static WifiMode GetOfdmRate3MbpsBW5MHz()
Return a WifiMode for OFDM at 3Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3745
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Definition: wifi-phy.cc:4079
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted...
Definition: wifi-phy.cc:4611
void MaybeCcaBusyDuration(void)
Eventually switch to CCA busy.
Definition: wifi-phy.cc:3036
virtual ~WifiPhy()
Definition: wifi-phy.cc:540
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer(Ptr< Event > event, WifiSpectrumBand band) const
Calculate the SNIR at the start of the non-HT PHY header and accumulate all SNIR changes in the SNIR ...
static WifiMode GetDsssRate1Mbps()
Return a WifiMode for DSSS at 1Mbps.
Definition: wifi-phy.cc:3370
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:2896
void ResumeFromOff(void)
Resume from off mode.
Definition: wifi-phy.cc:1871
Ptr< WifiPhyStateHelper > GetState(void) const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:577
void ResumeFromSleep(void)
Resume from sleep mode.
Definition: wifi-phy.cc:1840
std::size_t GetAmpduSubframeSize(std::size_t i) const
Return the size of the i-th A-MPDU subframe.
Definition: wifi-psdu.cc:306
#define min(a, b)
Definition: 80211b.c:42
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:2143
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t channelWidth, HeRu::SubcarrierRange range) const
Definition: wifi-phy.cc:3332
void ConfigureDefaultsForStandard(void)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:846
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Definition: wifi-ppdu.h:33
virtual uint16_t GetStaId(void) const
Return the STA ID that has been assigned to the station this PHY belongs to.
Definition: wifi-phy.cc:4734
static WifiMode GetHeMcs5()
Return MCS 5 from HE MCS values.
Definition: wifi-phy.cc:4201
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1426
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:4706
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:2178
static WifiMode GetErpOfdmRate18Mbps()
Return a WifiMode for ERP-OFDM at 18Mbps.
Definition: wifi-phy.cc:3460
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:714
void Configure80211ax(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard...
Definition: wifi-phy.cc:1249
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info paramters indexed by STA-ID
static WifiMode GetHtMcs7()
Return MCS 7 from HT MCS values.
Definition: wifi-phy.cc:3876
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:641
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:1373
virtual void DoDispose(void)
Destructor implementation.
Definition: wifi-phy.cc:546
static WifiMode GetHePhyHeaderMode()
Definition: wifi-phy.cc:1915
def start()
Definition: core.py:1855
void RebuildMcsMap(void)
Rebuild the mapping of MCS values to indices in the device MCS set.
Definition: wifi-phy.cc:1128
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
Definition: wifi-phy.cc:4119
uint8_t GetNBssMembershipSelectors(void) const
The WifiPhy::NBssMembershipSelectors() method is used (e.g., by a WifiRemoteStationManager) to determ...
Definition: wifi-phy.cc:1573
The PHY layer is sleeping.
static WifiMode GetHtMcs22()
Return MCS 22 from HT MCS values.
Definition: wifi-phy.cc:3996
static WifiMode GetHtMcs14()
Return MCS 14 from HT MCS values.
Definition: wifi-phy.cc:3932
static WifiMode GetOfdmRate12Mbps()
Return a WifiMode for OFDM at 12Mbps.
Definition: wifi-phy.cc:3547
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:2042
#define HE_PHY
Definition: wifi-phy.h:35
bool IsStateCcaBusy(void) const
Definition: wifi-phy.cc:4533
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:589
void EndOfMpdu(Ptr< Event > event, Ptr< const WifiPsdu > psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
The last symbol of an MPDU in an A-MPDU has arrived.
Definition: wifi-phy.cc:3202
static WifiMode GetHtMcs31()
Return MCS 31 from HT MCS values.
Definition: wifi-phy.cc:4068
static WifiMode GetHtMcs21()
Return MCS 21 from HT MCS values.
Definition: wifi-phy.cc:3988
#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
static WifiMode GetHtMcs30()
Return MCS 30 from HT MCS values.
Definition: wifi-phy.cc:4060
#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:956
std::vector< uint8_t > m_bssMembershipSelectorSet
the BSS membership selector set
Definition: wifi-phy.h:2127
static WifiMode GetHtMcs10()
Return MCS 10 from HT MCS values.
Definition: wifi-phy.cc:3900
static Time GetPhyPreambleDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2184
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:740
static WifiMode GetHtMcs26()
Return MCS 26 from HT MCS values.
Definition: wifi-phy.cc:4028
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:2034
static WifiMode GetOfdmRate1_5MbpsBW5MHz()
Return a WifiMode for OFDM at 1.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3721
static WifiMode GetHtMcs17()
Return MCS 17 from HT MCS values.
Definition: wifi-phy.cc:3956
static WifiMode GetHtMcs24()
Return MCS 24 from HT MCS values.
Definition: wifi-phy.cc:4012
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1810
bool IsStbc(void) const
Check if STBC is used or not.
static WifiMode GetOfdmRate4_5MbpsBW10MHz()
Return a WifiMode for OFDM at 4.5Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3634
bool GetModeInitialized(void) const
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54Mbps.
Definition: wifi-phy.cc:3607
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:765
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:601
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:667
#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
static WifiMode GetHeMcs4()
Return MCS 4 from HE MCS values.
Definition: wifi-phy.cc:4193
uint8_t GetNess(void) const
void ConfigureHolland(void)
Configure WifiPhy with appropriate channel frequency and supported rates for Holland.
Definition: wifi-phy.cc:1099
bool IsStateIdle(void) const
Definition: wifi-phy.cc:4539
uint16_t GetGuardInterval(void) const
VHT PHY (Clause 22)
Definition: wifi-mode.h:62
The 5 GHz band.
Definition: wifi-phy-band.h:35
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
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:2049
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:50
std::pair< uint16_t, uint16_t > FrequencyWidthPair
A pair of a center frequency (MHz) and a channel width (MHz)
Definition: wifi-phy.h:167
static WifiMode GetHtMcs8()
Return MCS 8 from HT MCS values.
Definition: wifi-phy.cc:3884
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:2149
static WifiMode GetHtMcs18()
Return MCS 18 from HT MCS values.
Definition: wifi-phy.cc:3964
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:2063
double GetTxPowerForTransmission(WifiTxVector txVector) const
Compute the transmit power (in dBm) for the next transmission.
Definition: wifi-phy.cc:4648
virtual void SetFrequency(uint16_t freq)
Definition: wifi-phy.cc:1439
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
Definition: wifi-phy.cc:4111
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower)
Add the PPDU-related signal to interference helper.
static WifiMode GetHtMcs27()
Return MCS 27 from HT MCS values.
Definition: wifi-phy.cc:4036
WifiSpectrumBand GetRuBand(WifiTxVector txVector, uint16_t staId)
Get the RU band used to transmit a PSDU to a given STA in a HE MU PPDU.
Definition: wifi-phy.cc:3318
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:798
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:4636
std::vector< Ptr< WifiMacQueueItem > >::const_iterator end(void) const
Return a const iterator to past-the-last MPDU.
Definition: wifi-psdu.cc:337
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
static WifiMode GetOfdmRate36Mbps()
Return a WifiMode for OFDM at 36Mbps.
Definition: wifi-phy.cc:3583
uint8_t m_initialChannelNumber
Initial channel number.
Definition: wifi-phy.h:2166
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:2621
static WifiMode GetVhtMcs7()
Return MCS 7 from VHT MCS values.
Definition: wifi-phy.cc:4135
static WifiMode GetOfdmRate6MbpsBW5MHz()
Return a WifiMode for OFDM at 6Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3769
bool IsStateSleep(void) const
Definition: wifi-phy.cc:4563
void NotifyEndOfHePreamble(HePreambleParameters params)
Public method used to fire a EndOfHePreamble trace once both HE SIG fields have been received...
Definition: wifi-phy.cc:2701
double snr
SNR in linear scale.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
Definition: wifi-phy.cc:4103
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:648
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiModeList m_deviceMcsSet
the device MCS set
Definition: wifi-phy.h:2123
mobility
Definition: third.py:108
uint32_t GetSize(void) const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:260
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
uint16_t m_channelCenterFrequency
Center frequency in MHz.
Definition: wifi-phy.h:2132
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:753
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode...
static WifiMode GetHtMcs16()
Return MCS 16 from HT MCS values.
Definition: wifi-phy.cc:3948
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1516
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:2151
static WifiMode GetErpOfdmRate54Mbps()
Return a WifiMode for ERP-OFDM at 54Mbps.
Definition: wifi-phy.cc:3508
WifiPreamble GetPreambleType(void) const
static Time GetPhyHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1978
static WifiMode GetHtMcs29()
Return MCS 29 from HT MCS values.
Definition: wifi-phy.cc:4052
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: wifi-phy.cc:3162
static WifiMode GetHtMcs11()
Return MCS 11 from HT MCS values.
Definition: wifi-phy.cc:3908
uint8_t GetNMcs(void) const
The WifiPhy::GetNMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of t...
Definition: wifi-phy.cc:4308
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:32
Keep track of the current position and velocity of an object.
static ChannelToFrequencyWidthMap m_channelToFrequencyWidth
the channel to frequency width map
Definition: wifi-phy.h:2162
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
The MPDU is not part of an A-MPDU.
double rssiW
RSSI in W.
Definition: wifi-phy.h:135
Ptr< const Packet > GetPacket(void) const
Get the PSDU as a single packet.
Definition: wifi-psdu.cc:87
uint8_t bssColor
BSS color.
Definition: wifi-phy.h:136
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:299
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate...
bool DoFrequencySwitch(uint16_t frequency)
The default implementation does nothing and returns true.
Definition: wifi-phy.cc:1733
static WifiMode GetHtMcs2()
Return MCS 2 from HT MCS values.
Definition: wifi-phy.cc:3836
std::vector< bool > m_statusPerMpdu
current reception status per MPDU that is filled in as long as MPDUs are being processed by the PHY i...
Definition: wifi-phy.h:2180
void StartReceiveHeader(Ptr< Event > event)
Start receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2796
static WifiMode GetHtPhyHeaderMode()
Definition: wifi-phy.cc:1903
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:2138
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:2171
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
AttributeValue implementation for Time.
Definition: nstime.h:1353
RU Specification.
Definition: he-ru.h:64
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:2141
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
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:2010
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:2153
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:2156
static WifiMode GetHeMcs3()
Return MCS 3 from HE MCS values.
Definition: wifi-phy.cc:4185
Hold an unsigned integer type.
Definition: uinteger.h:44
static Time GetPayloadDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:2253
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, WifiCodeRate codingRate, uint16_t constellationSize)
Definition: wifi-mode.cc:674
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1813
static WifiMode GetHtMcs12()
Return MCS 12 from HT MCS values.
Definition: wifi-phy.cc:3916
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:2176
static WifiMode GetErpOfdmRate48Mbps()
Return a WifiMode for ERP-OFDM at 48Mbps.
Definition: wifi-phy.cc:3496
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:688
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:804
mac
Definition: third.py:99
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate...
std::pair< ChannelNumberBandPair, WifiPhyStandard > ChannelNumberStandardPair
A pair of a ChannelNumberBandPair and a WifiPhyStandard.
Definition: wifi-phy.h:163
static WifiMode GetOfdmRate12MbpsBW10MHz()
Return a WifiMode for OFDM at 12Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3670
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:3361
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
Definition: wifi-phy.cc:4249
The PHY layer has sense the medium busy through the CCA mechanism.
static WifiMode GetHeMcs(uint8_t mcs)
Get the WifiMode object corresponding to the given MCS of the HE modulation class.
Definition: wifi-phy.cc:4484
HT PHY (Clause 20)
Definition: wifi-mode.h:60
Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:4575
OFDM PHY (Clause 17 - amendment for 10 MHz and 5 MHz channels)
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1807
TracedCallback< HePreambleParameters > m_phyEndOfHePreambleTrace
A trace source that indicates the end of both HE SIG fields as well as training fields for received 8...
Definition: wifi-phy.h:2084
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
double CalculateSnr(WifiTxVector txVector, double ber) const
Definition: wifi-phy.cc:840
static WifiMode GetOfdmRate18Mbps()
Return a WifiMode for OFDM at 18Mbps.
Definition: wifi-phy.cc:3559
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:607
void SetOffMode(void)
Put in off mode.
Definition: wifi-phy.cc:1827
static WifiMode GetOfdmRate9MbpsBW10MHz()
Return a WifiMode for OFDM at 9Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3658
static WifiMode GetOfdmRate12MbpsBW5MHz()
Return a WifiMode for OFDM at 12Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3793
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:480
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:2175
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:816
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
Definition: wifi-phy.cc:4087
WifiPhyStandard GetPhyStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1433
EventId m_endPreambleDetectionEvent
the end of preamble detection event
Definition: wifi-phy.h:1811
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
static WifiMode GetOfdmRate48Mbps()
Return a WifiMode for OFDM at 48Mbps.
Definition: wifi-phy.cc:3595
Time GetBlockAckTxTime(void) const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:986
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:784
uint64_t Get(void) const
Definition: uinteger.cc:35
static WifiMode GetVhtPhyHeaderMode()
Definition: wifi-phy.cc:1909
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
Definition: wifi-phy.cc:4233
double f(double x, void *params)
Definition: 80211b.c:70
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
Definition: wifi-phy.cc:3820
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:1994
Ptr< MobilityModel > GetMobility(void) const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:771
static Time GetPreambleDetectionDuration(void)
Definition: wifi-phy.cc:1921
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:2139
static Time GetPhySigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1993
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:791
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-phy.cc:288
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:834
OFDM PHY (Clause 17)
void ContinueReceiveHeader(Ptr< Event > event)
Continue receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2858
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:2130
void NotifyRxStart()
Notify that RX has started.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:810
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
void EraseEvents(void)
Erase all events.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1496
The PHY layer is IDLE.
uint8_t GetNumberOfAntennas(void) const
Definition: wifi-phy.cc:1530
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24Mbps.
Definition: wifi-phy.cc:3571
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:2600
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:2137
static WifiMode GetHeMcs1()
Return MCS 1 from HE MCS values.
Definition: wifi-phy.cc:4169
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:1987
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
virtual void StartTx(Ptr< WifiPpdu > ppdu)=0
static WifiMode GetHtMcs13()
Return MCS 13 from HT MCS values.
Definition: wifi-phy.cc:3924
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
Definition: wifi-phy.cc:4161
std::map< ChannelNumberStandardPair, FrequencyWidthPair > ChannelToFrequencyWidthMap
channel to frequency width map typedef
Definition: wifi-phy.h:2161
static WifiMode GetHeMcs10()
Return MCS 10 from HE MCS values.
Definition: wifi-phy.cc:4241
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
static WifiMode GetHtMcs20()
Return MCS 20 from HT MCS values.
Definition: wifi-phy.cc:3980
static WifiMode GetHeMcs2()
Return MCS 2 from HE MCS values.
Definition: wifi-phy.cc:4177
static Time GetPhyTrainingSymbolDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1927
static WifiMode GetHtMcs5()
Return MCS 5 from HT MCS values.
Definition: wifi-phy.cc:3860
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1555
bool GetShortPhyPreambleSupported(void) const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:747
double m_ccaEdThresholdW
Clear channel assessment (CCA) threshold in watts.
Definition: wifi-phy.h:2144
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
Definition: wifi-phy.cc:4095
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1614
Time GetPifs(void) const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:974
static WifiMode GetDsssRate5_5Mbps()
Return a WifiMode for DSSS at 5.5Mbps.
Definition: wifi-phy.cc:3397
static SubcarrierGroup GetSubcarrierGroup(uint8_t bw, RuType ruType, std::size_t index)
Get the subcarrier group of the RU having the given index among all the RUs of the given type (number...
Definition: he-ru.cc:172
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:980
void Configure80211ac(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard...
Definition: wifi-phy.cc:1229
virtual void DoInitialize(void)
Initialize() implementation.
Definition: wifi-phy.cc:564
static WifiMode GetOfdmRate2_25MbpsBW5MHz()
Return a WifiMode for OFDM at 2.25Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3733
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
uint8_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:1667
The 2.4 GHz band.
Definition: wifi-phy-band.h:33
WifiPhyStandard m_standard
WifiPhyStandard.
Definition: wifi-phy.h:2129
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
uint8_t FindChannelNumberForFrequencyWidth(uint16_t frequency, uint16_t width) const
Look for channel number matching the frequency and width.
Definition: wifi-phy.cc:1295
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:2154
static WifiMode GetErpOfdmRate9Mbps()
Return a WifiMode for ERP-OFDM at 9Mbps.
Definition: wifi-phy.cc:3436
void EndReceive(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: wifi-phy.cc:3225
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1803
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:35
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:2158
double GetTxPowerStart(void) const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:682
Time m_ackTxTime
estimated Ack TX time
Definition: wifi-phy.h:2140
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:2177
static WifiMode GetPhyHeaderMode(WifiTxVector txVector)
Definition: wifi-phy.cc:2042
void InitializeFrequencyChannelNumber(void)
post-construction setting of frequency and/or channel number
Definition: wifi-phy.cc:613
std::vector< uint16_t > GetSupportedChannelWidthSet(void) const
Definition: wifi-phy.cc:1600
uint8_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4296
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:2174
#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:727
void Configure80211b(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard...
Definition: wifi-phy.cc:1015
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:30
No explicit coding (e.g., DSSS rates)
Definition: wifi-mode.h:77
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:944
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:583
WifiMode GetMode(uint8_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4302
uint16_t m_channelWidth
Channel width (MHz)
Definition: wifi-phy.h:2135
uint8_t GetBssMembershipSelector(uint8_t selector) const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1579
static WifiMode GetErpOfdmRate6Mbps()
Return a WifiMode for ERP-OFDM at 6Mbps.
Definition: wifi-phy.cc:3424
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:595
bool IsStateTx(void) const
Definition: wifi-phy.cc:4551
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< const WifiPsdu > psdu, Ptr< Event > event, uint16_t staId, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
Definition: wifi-phy.cc:3274
Ptr< WifiMac > GetMac(void) const
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, RxPowerWattPerChannelBand rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:2609
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1536
The PHY layer is sending a packet.
static WifiMode GetErpOfdmRate12Mbps()
Return a WifiMode for ERP-OFDM at 12Mbps.
Definition: wifi-phy.cc:3448
WifiModulationClass
This enumeration defines the modulation classes per (Table 9-4 "Modulation classes"; IEEE 802...
Definition: wifi-mode.h:38
EventId m_endRxEvent
the end of receive event
Definition: wifi-phy.h:1809
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1804
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
void Configure80211n(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard...
Definition: wifi-phy.cc:1210
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:675
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:2147
bool IsMcsSupported(WifiMode mcs) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:4270
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer(Ptr< Event > event, WifiSpectrumBand band) const
Calculate the SNIR at the start of the HT PHY header and accumulate all SNIR changes in the SNIR vect...
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:950
void NotifyRxEnd()
Notify that RX has ended.
void SetNoiseFigure(double value)
Set the noise figure.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
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:3350
SignalNoiseDbm structure.
Definition: wifi-phy.h:119
uint32_t mpduRefNumber
MPDU ref number.
Definition: wifi-phy.h:129
bool m_frequencyChannelNumberInitialized
Store initialization state.
Definition: wifi-phy.h:2134
static WifiMode GetHtMcs19()
Return MCS 19 from HT MCS values.
Definition: wifi-phy.cc:3972
InterferenceHelper m_interference
Pointer to InterferenceHelper.
Definition: wifi-phy.h:1802
virtual void SetChannelWidth(uint16_t channelWidth)
Definition: wifi-phy.cc:1502
static WifiMode GetHtMcs6()
Return MCS 6 from HT MCS values.
Definition: wifi-phy.cc:3868
bool m_isConstructed
true when ready to set frequency
Definition: wifi-phy.h:2131
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
void ConfigureHtDeviceMcsSet(void)
Configure the device MCS set with the appropriate HtMcs modes for the number of available transmit sp...
Definition: wifi-phy.cc:1140
void PushMcs(WifiMode mode)
Add the given MCS to the device MCS set.
Definition: wifi-phy.cc:1115
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:52
The PHY layer is receiving a packet.
OFDM PHY (Clause 17)
Definition: wifi-mode.h:58
SignalNoiseDbm m_signalNoise
latest signal power and noise power in dBm (noise power includes the noise figure) ...
Definition: wifi-phy.h:2181
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
static Time GetPhySigA2Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:2011
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
static WifiMode GetHtMcs28()
Return MCS 28 from HT MCS values.
Definition: wifi-phy.cc:4044
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:695
static WifiMode GetHtMcs9()
Return MCS 9 from HT MCS values.
Definition: wifi-phy.cc:3892
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:962
void EndReceiveInterBss(void)
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:3340
std::vector< Ptr< WifiMacQueueItem > >::const_iterator begin(void) const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:325
void StartRx(Ptr< Event > event)
Starting receiving the PPDU after having detected the medium is idle or after a reception switch...
Definition: wifi-phy.cc:4669
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:2676
static WifiMode GetHtMcs4()
Return MCS 4 from HT MCS values.
Definition: wifi-phy.cc:3852
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void StartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: wifi-phy.cc:3051
static WifiMode GetHtMcs25()
Return MCS 25 from HT MCS values.
Definition: wifi-phy.cc:4020
static WifiMode GetHeMcs8()
Return MCS 8 from HE MCS values.
Definition: wifi-phy.cc:4225
The PHY layer is switched off.
void Send(Ptr< const WifiPsdu > psdu, WifiTxVector txVector)
Definition: wifi-phy.cc:2707
void Configure80211g(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard...
Definition: wifi-phy.cc:1034
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:759
uint8_t GetTxPowerLevel(void) const
double GetTxGain(void) const
Return the transmission gain (dB).
Definition: wifi-phy.cc:721
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
struct InterferenceHelper::SnrPer CalculatePayloadSnrPer(Ptr< Event > event, uint16_t channelWidth, WifiSpectrumBand band, uint16_t staId, std::pair< Time, Time > relativeMpduStartStop) const
Calculate the SNIR at the start of the payload and accumulate all SNIR changes in the SNIR vector for...
The PHY layer is switching to other channel.
double CalculateSnr(Ptr< Event > event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
Calculate the SNIR for the event (starting from now until the event end).
void SetSleepMode(void)
Put in sleep mode.
Definition: wifi-phy.cc:1793
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:2645
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
WifiModeList m_deviceRateSet
This vector holds the set of transmission modes that this WifiPhy(-derived class) can support...
Definition: wifi-phy.h:2122
The 6 GHz band.
Definition: wifi-phy-band.h:37
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1522
uint16_t GetChannelWidth(void) const
second
Definition: nstime.h:115
static WifiMode GetHtMcs1()
Return MCS 1 from HT MCS values.
Definition: wifi-phy.cc:3828
std::map< WifiModulationClass, std::map< uint8_t, uint8_t > > m_mcsIndexMap
Maps MCS values to indices in m_deviceMcsSet, for HT, VHT and HE modulation classes.
Definition: wifi-phy.h:2125
static WifiMode GetHtMcs23()
Return MCS 23 from HT MCS values.
Definition: wifi-phy.cc:4004
static Time GetPhyHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2106
A base class which provides memory management and object aggregation.
Definition: object.h:87
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1329
static WifiMode GetDsssRate2Mbps()
Return a WifiMode for DSSS at 2Mbps.
Definition: wifi-phy.cc:3382
static WifiMode GetVhtMcs9()
Return MCS 9 from VHT MCS values.
Definition: wifi-phy.cc:4151
#define HT_PHY
Definition: wifi-phy.h:37
static Time GetStartOfPacketDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2178
static WifiMode GetOfdmRate6MbpsBW10MHz()
Return a WifiMode for OFDM at 6Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3646
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:400
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:2546
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:2148
#define VHT_PHY
Definition: wifi-phy.h:36
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get the map HE MU user-specific transmission information indexed by STA-ID.
void Configure80211p(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard...
Definition: wifi-phy.cc:1055
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
static WifiMode GetOfdmRate24MbpsBW10MHz()
Return a WifiMode for OFDM at 24Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3694
The MPDU is a single MPDU.
MpduType type
type
Definition: wifi-phy.h:128
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:2168
static WifiMode GetOfdmRate13_5MbpsBW5MHz()
Return a WifiMode for OFDM at 13.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3805
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:4587
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:458
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
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass)
Definition: wifi-mode.cc:712
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:2157
uint8_t GetMaxSupportedTxSpatialStreams(void) const
Definition: wifi-phy.cc:1549
a unique identifier for an interface.
Definition: type-id.h:58
void ConfigureChannelForStandard(void)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1323
static WifiMode GetHtMcs15()
Return MCS 15 from HT MCS values.
Definition: wifi-phy.cc:3940
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:2173
static Time GetPhySigBDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:2028
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:4581
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:2152
bool IsStateRx(void) const
Definition: wifi-phy.cc:4545
static WifiMode GetHtMcs3()
Return MCS 3 from HT MCS values.
Definition: wifi-phy.cc:3844
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:2159
#define SU_STA_ID
Definition: wifi-mode.h:30
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:536
std::vector< uint16_t > m_supportedChannelWidthSet
Supported channel width set (MHz)
Definition: wifi-phy.h:2164
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6Mbps.
Definition: wifi-phy.cc:3523
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:2077
void SwitchMaybeToCcaBusy(void)
Check if PHY state should move to CCA busy state based on current state of interference tracker...
Definition: wifi-phy.cc:4593
void SetCcaEdThreshold(double threshold)
Sets the CCA threshold (dBm).
Definition: wifi-phy.cc:654
HE PHY (Clause 26)
Definition: wifi-mode.h:64
static WifiMode GetVhtMcs(uint8_t mcs)
Get the WifiMode object corresponding to the given MCS of the VHT modulation class.
Definition: wifi-phy.cc:4441
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:127
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:4758
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
DSSS PHY (Clause 15)
Definition: wifi-mode.h:48
static WifiMode GetHeMcs6()
Return MCS 6 from HE MCS values.
Definition: wifi-phy.cc:4209
static WifiMode GetOfdmRate4_5MbpsBW5MHz()
Return a WifiMode for OFDM at 4.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3757
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:2183
void Configure80211a(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard...
Definition: wifi-phy.cc:992
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1567
static WifiMode GetHtMcs(uint8_t mcs)
Get the WifiMode object corresponding to the given MCS of the HT modulation class.
Definition: wifi-phy.cc:4332
static WifiMode GetOfdmRate3MbpsBW10MHz()
Return a WifiMode for OFDM at 3Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3622
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
Definition: wifi-phy.h:2002
uint16_t m_initialFrequency
Store frequency until initialization (MHz)
Definition: wifi-phy.h:2133
Parameters for receive HE preamble.
Definition: wifi-phy.h:133
bool DefineChannelNumber(uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
Add a channel definition to the WifiPhy.
Definition: wifi-phy.cc:1278
bool IsAggregate(void) const
Return true if the PSDU is an S-MPDU or A-MPDU.
Definition: wifi-psdu.cc:81
static Time CalculatePhyPreambleAndHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2532
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:4749
bool DoChannelSwitch(uint8_t id)
The default implementation does nothing and returns true.
Definition: wifi-phy.cc:1673