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 "frame-capture-model.h"
35 #include "error-rate-model.h"
36 #include "wifi-net-device.h"
37 #include "ht-configuration.h"
38 #include "he-configuration.h"
39 #include "mpdu-aggregator.h"
40 #include "wifi-psdu.h"
41 #include "wifi-ppdu.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, 196))
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_isConstructed (false),
515  m_channelCenterFrequency (0),
516  m_initialFrequency (0),
517  m_frequencyChannelNumberInitialized (false),
518  m_channelWidth (0),
519  m_sifs (Seconds (0)),
520  m_slot (Seconds (0)),
521  m_pifs (Seconds (0)),
522  m_ackTxTime (Seconds (0)),
523  m_blockAckTxTime (Seconds (0)),
524  m_powerRestricted (false),
525  m_channelAccessRequested (false),
526  m_txSpatialStreams (0),
527  m_rxSpatialStreams (0),
528  m_channelNumber (0),
529  m_initialChannelNumber (0),
530  m_currentEvent (0),
531  m_wifiRadioEnergyModel (0),
532  m_timeLastPreambleDetected (Seconds (0))
533 {
534  NS_LOG_FUNCTION (this);
535  m_random = CreateObject<UniformRandomVariable> ();
536  m_state = CreateObject<WifiPhyStateHelper> ();
537 }
538 
540 {
541  NS_LOG_FUNCTION (this);
542 }
543 
544 void
546 {
547  NS_LOG_FUNCTION (this);
548  m_endTxEvent.Cancel ();
549  m_endRxEvent.Cancel ();
552  m_device = 0;
553  m_mobility = 0;
554  m_state = 0;
557  m_deviceRateSet.clear ();
558  m_deviceMcsSet.clear ();
559  m_mcsIndexMap.clear ();
560 }
561 
562 void
564 {
565  NS_LOG_FUNCTION (this);
566  m_isConstructed = true;
568  {
569  NS_LOG_DEBUG ("Frequency already initialized");
570  return;
571  }
573 }
574 
576 WifiPhy::GetState (void) const
577 {
578  return m_state;
579 }
580 
581 void
583 {
584  m_state->SetReceiveOkCallback (callback);
585 }
586 
587 void
589 {
590  m_state->SetReceiveErrorCallback (callback);
591 }
592 
593 void
595 {
596  m_state->RegisterListener (listener);
597 }
598 
599 void
601 {
602  m_state->UnregisterListener (listener);
603 }
604 
605 void
607 {
609 }
610 
611 void
613 {
614  NS_LOG_FUNCTION (this);
615 
616  NS_ASSERT_MSG (m_frequencyChannelNumberInitialized == false, "Initialization called twice");
617 
618  // If frequency has been set to a non-zero value during attribute
619  // construction phase, the frequency and channel width will drive the
620  // initial configuration. If frequency has not been set, but both
621  // standard and channel number have been set, that pair will instead
622  // drive the configuration, and frequency and channel number will be
623  // aligned
624  if (m_initialFrequency != 0)
625  {
627  }
629  {
631  }
633  {
634  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " was set by user, but neither a standard nor a frequency");
635  }
637 }
638 
639 void
640 WifiPhy::SetRxSensitivity (double threshold)
641 {
642  NS_LOG_FUNCTION (this << threshold);
643  m_rxSensitivityW = DbmToW (threshold);
644 }
645 
646 double
648 {
649  return WToDbm (m_rxSensitivityW);
650 }
651 
652 void
653 WifiPhy::SetCcaEdThreshold (double threshold)
654 {
655  NS_LOG_FUNCTION (this << threshold);
656  m_ccaEdThresholdW = DbmToW (threshold);
657 }
658 
659 double
661 {
662  return WToDbm (m_ccaEdThresholdW);
663 }
664 
665 void
666 WifiPhy::SetRxNoiseFigure (double noiseFigureDb)
667 {
668  NS_LOG_FUNCTION (this << noiseFigureDb);
669  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
671 }
672 
673 void
675 {
676  NS_LOG_FUNCTION (this << start);
678 }
679 
680 double
682 {
683  return m_txPowerBaseDbm;
684 }
685 
686 void
688 {
689  NS_LOG_FUNCTION (this << end);
690  m_txPowerEndDbm = end;
691 }
692 
693 double
695 {
696  return m_txPowerEndDbm;
697 }
698 
699 void
701 {
702  NS_LOG_FUNCTION (this << +n);
703  m_nTxPower = n;
704 }
705 
706 uint8_t
708 {
709  return m_nTxPower;
710 }
711 
712 void
713 WifiPhy::SetTxGain (double gain)
714 {
715  NS_LOG_FUNCTION (this << gain);
716  m_txGainDb = gain;
717 }
718 
719 double
720 WifiPhy::GetTxGain (void) const
721 {
722  return m_txGainDb;
723 }
724 
725 void
726 WifiPhy::SetRxGain (double gain)
727 {
728  NS_LOG_FUNCTION (this << gain);
729  m_rxGainDb = gain;
730 }
731 
732 double
733 WifiPhy::GetRxGain (void) const
734 {
735  return m_rxGainDb;
736 }
737 
738 void
740 {
741  NS_LOG_FUNCTION (this << enable);
742  m_shortPreamble = enable;
743 }
744 
745 bool
747 {
748  return m_shortPreamble;
749 }
750 
751 void
753 {
754  m_device = device;
755 }
756 
758 WifiPhy::GetDevice (void) const
759 {
760  return m_device;
761 }
762 
763 void
765 {
767 }
768 
771 {
772  if (m_mobility != 0)
773  {
774  return m_mobility;
775  }
776  else
777  {
778  return m_device->GetNode ()->GetObject<MobilityModel> ();
779  }
780 }
781 
782 void
784 {
787 }
788 
789 void
791 {
792  NS_LOG_FUNCTION (this << em);
794 }
795 
796 void
798 {
799  m_frameCaptureModel = model;
800 }
801 
802 void
804 {
805  m_preambleDetectionModel = model;
806 }
807 
808 void
810 {
811  m_wifiRadioEnergyModel = wifiRadioEnergyModel;
812 }
813 
814 double
815 WifiPhy::GetPowerDbm (uint8_t power) const
816 {
818  NS_ASSERT (m_nTxPower > 0);
819  double dbm;
820  if (m_nTxPower > 1)
821  {
822  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
823  }
824  else
825  {
826  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
827  dbm = m_txPowerBaseDbm;
828  }
829  return dbm;
830 }
831 
832 Time
834 {
835  return m_channelSwitchDelay;
836 }
837 
838 double
839 WifiPhy::CalculateSnr (WifiTxVector txVector, double ber) const
840 {
841  return m_interference.GetErrorRateModel ()->CalculateSnr (txVector, ber);
842 }
843 
844 void
846 {
847  NS_LOG_FUNCTION (this);
848  switch (m_standard)
849  {
851  SetChannelWidth (20);
852  SetFrequency (5180);
853  // Channel number should be aligned by SetFrequency () to 36
854  NS_ASSERT (GetChannelNumber () == 36);
855  break;
857  SetChannelWidth (22);
858  SetFrequency (2412);
859  // Channel number should be aligned by SetFrequency () to 1
860  NS_ASSERT (GetChannelNumber () == 1);
861  break;
863  SetChannelWidth (20);
864  SetFrequency (2412);
865  // Channel number should be aligned by SetFrequency () to 1
866  NS_ASSERT (GetChannelNumber () == 1);
867  break;
869  if (GetChannelWidth () > 10)
870  {
871  SetChannelWidth (10);
872  }
873  SetFrequency (5860);
874  // Channel number should be aligned by SetFrequency () to either 172 or 171
875  NS_ASSERT ((GetChannelWidth () == 10 && GetChannelNumber () == 172) || (GetChannelWidth () == 5 && GetChannelNumber () == 171)) ;
876  break;
878  SetChannelWidth (20);
879  SetFrequency (5180);
880  // Channel number should be aligned by SetFrequency () to 36
881  NS_ASSERT (GetChannelNumber () == 36);
882  break;
884  SetChannelWidth (20);
886  {
887  SetFrequency (2412);
888  // Channel number should be aligned by SetFrequency () to 1
889  NS_ASSERT (GetChannelNumber () == 1);
890  }
891  else if (m_band == WIFI_PHY_BAND_5GHZ)
892  {
893  SetFrequency (5180);
894  // Channel number should be aligned by SetFrequency () to 36
895  NS_ASSERT (GetChannelNumber () == 36);
896  }
897  else
898  {
899  NS_FATAL_ERROR ("Invalid band");
900  }
901  break;
903  SetChannelWidth (80);
904  SetFrequency (5210);
905  // Channel number should be aligned by SetFrequency () to 42
906  NS_ASSERT (GetChannelNumber () == 42);
907  break;
910  {
911  SetChannelWidth (20);
912  SetFrequency (2412);
913  // Channel number should be aligned by SetFrequency () to 1
914  NS_ASSERT (GetChannelNumber () == 1);
915  }
916  else if (m_band == WIFI_PHY_BAND_5GHZ)
917  {
918  SetChannelWidth (80);
919  SetFrequency (5210);
920  // Channel number should be aligned by SetFrequency () to 42
921  NS_ASSERT (GetChannelNumber () == 42);
922  }
923  else if (m_band == WIFI_PHY_BAND_6GHZ)
924  {
925  SetChannelWidth (80);
926  SetFrequency (5975);
927  // Channel number should be aligned by SetFrequency () to 7
928  NS_ASSERT (GetChannelNumber () == 7);
929  }
930  else
931  {
932  NS_FATAL_ERROR ("Invalid band");
933  }
934  break;
936  default:
937  NS_LOG_WARN ("Configuring unspecified standard; performing no action");
938  break;
939  }
940 }
941 
942 void
944 {
945  m_sifs = sifs;
946 }
947 
948 Time
949 WifiPhy::GetSifs (void) const
950 {
951  return m_sifs;
952 }
953 
954 void
956 {
957  m_slot = slot;
958 }
959 
960 Time
961 WifiPhy::GetSlot (void) const
962 {
963  return m_slot;
964 }
965 
966 void
968 {
969  m_pifs = pifs;
970 }
971 
972 Time
973 WifiPhy::GetPifs (void) const
974 {
975  return m_pifs;
976 }
977 
978 Time
980 {
981  return m_ackTxTime;
982 }
983 
984 Time
986 {
987  return m_blockAckTxTime;
988 }
989 
990 void
992 {
993  NS_LOG_FUNCTION (this);
994 
995  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
996  SetSifs (MicroSeconds (16));
997  SetSlot (MicroSeconds (9));
998  SetPifs (GetSifs () + GetSlot ());
999  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1000  // of the PPDU causing the EIFS" of 802.11-2016
1001  m_ackTxTime = MicroSeconds (44);
1002 
1011 }
1012 
1013 void
1015 {
1016  NS_LOG_FUNCTION (this);
1017 
1018  // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
1019  SetSifs (MicroSeconds (10));
1020  SetSlot (MicroSeconds (20));
1021  SetPifs (GetSifs () + GetSlot ());
1022  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1023  // of the PPDU causing the EIFS" of 802.11-2016
1024  m_ackTxTime = MicroSeconds (304);
1025 
1030 }
1031 
1032 void
1034 {
1035  NS_LOG_FUNCTION (this);
1036  // See Table 18-5 "ERP characteristics" of 802.11-2016
1037  // Slot time defaults to the "long slot time" of 20 us in the standard
1038  // according to mixed 802.11b/g deployments. Short slot time is enabled
1039  // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
1040  // consists of only ERP STAs capable of supporting this option.
1041  Configure80211b ();
1042 
1051 }
1052 
1053 void
1055 {
1056  NS_LOG_FUNCTION (this);
1057  if (GetChannelWidth () == 10)
1058  {
1059  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1060  SetSifs (MicroSeconds (32));
1061  SetSlot (MicroSeconds (13));
1062  SetPifs (GetSifs () + GetSlot ());
1063  m_ackTxTime = MicroSeconds (88);
1064 
1073  }
1074  else if (GetChannelWidth () == 5)
1075  {
1076  // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
1077  SetSifs (MicroSeconds (64));
1078  SetSlot (MicroSeconds (21));
1079  SetPifs (GetSifs () + GetSlot ());
1080  m_ackTxTime = MicroSeconds (176);
1081 
1090  }
1091  else
1092  {
1093  NS_FATAL_ERROR ("802.11p configured with a wrong channel width!");
1094  }
1095 }
1096 
1097 void
1099 {
1100  NS_LOG_FUNCTION (this);
1101 
1102  SetSifs (MicroSeconds (16));
1103  SetSlot (MicroSeconds (9));
1104  SetPifs (GetSifs () + GetSlot ());
1105 
1111 }
1112 
1113 void
1115 {
1116  NS_LOG_FUNCTION (this << mode);
1117 
1118  WifiModulationClass modulation = mode.GetModulationClass ();
1119  NS_ASSERT (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
1120  || modulation == WIFI_MOD_CLASS_HE);
1121 
1122  m_mcsIndexMap[modulation][mode.GetMcsValue ()] = m_deviceMcsSet.size ();
1123  m_deviceMcsSet.push_back (mode);
1124 }
1125 
1126 void
1128 {
1129  NS_LOG_FUNCTION (this);
1130  m_mcsIndexMap.clear ();
1131  uint8_t index = 0;
1132  for (auto& mode : m_deviceMcsSet)
1133  {
1134  m_mcsIndexMap[mode.GetModulationClass ()][mode.GetMcsValue ()] = index++;
1135  }
1136 }
1137 
1138 void
1140 {
1141  NS_LOG_FUNCTION (this);
1142 
1143  bool htFound = false;
1144  for (std::vector<uint8_t>::size_type i = 0; i < m_bssMembershipSelectorSet.size (); i++)
1145  {
1147  {
1148  htFound = true;
1149  break;
1150  }
1151  }
1152  if (htFound)
1153  {
1154  // erase all HtMcs modes from deviceMcsSet
1155  std::size_t index = m_deviceMcsSet.size () - 1;
1156  for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend (); ++rit, --index)
1157  {
1158  if (m_deviceMcsSet[index].GetModulationClass () == WIFI_MOD_CLASS_HT)
1159  {
1160  m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
1161  }
1162  }
1163  RebuildMcsMap ();
1173  {
1182  }
1184  {
1193  }
1195  {
1204  }
1205  }
1206 }
1207 
1208 void
1210 {
1211  NS_LOG_FUNCTION (this);
1213  {
1214  Configure80211g ();
1215  }
1216  else
1217  {
1218  Configure80211a ();
1219  }
1220  // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
1221  // of the PPDU causing the EIFS" of 802.11-2016
1223  m_bssMembershipSelectorSet.push_back (HT_PHY);
1225 }
1226 
1227 void
1229 {
1230  NS_LOG_FUNCTION (this);
1231  Configure80211n ();
1232 
1243 
1244  m_bssMembershipSelectorSet.push_back (VHT_PHY);
1245 }
1246 
1247 void
1249 {
1250  NS_LOG_FUNCTION (this);
1252  {
1253  Configure80211n ();
1254  }
1255  else
1256  {
1257  Configure80211ac ();
1258  }
1259 
1272 
1273  m_bssMembershipSelectorSet.push_back (HE_PHY);
1274 }
1275 
1276 bool
1277 WifiPhy::DefineChannelNumber (uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
1278 {
1279  NS_LOG_FUNCTION (this << +channelNumber << band << standard << frequency << channelWidth);
1280  ChannelNumberStandardPair p = std::make_pair (std::make_pair (channelNumber, band), standard);
1281  ChannelToFrequencyWidthMap::const_iterator it;
1282  it = m_channelToFrequencyWidth.find (p);
1283  if (it != m_channelToFrequencyWidth.end ())
1284  {
1285  NS_LOG_DEBUG ("channel number/standard already defined; returning false");
1286  return false;
1287  }
1288  FrequencyWidthPair f = std::make_pair (frequency, channelWidth);
1290  return true;
1291 }
1292 
1293 uint8_t
1294 WifiPhy::FindChannelNumberForFrequencyWidth (uint16_t frequency, uint16_t width) const
1295 {
1296  NS_LOG_FUNCTION (this << frequency << width);
1297  bool found = false;
1298  FrequencyWidthPair f = std::make_pair (frequency, width);
1299  ChannelToFrequencyWidthMap::const_iterator it = m_channelToFrequencyWidth.begin ();
1300  while (it != m_channelToFrequencyWidth.end ())
1301  {
1302  if (it->second == f)
1303  {
1304  found = true;
1305  break;
1306  }
1307  ++it;
1308  }
1309  if (found)
1310  {
1311  NS_LOG_DEBUG ("Found, returning " << +it->first.first.first);
1312  return (it->first.first.first);
1313  }
1314  else
1315  {
1316  NS_LOG_DEBUG ("Not found, returning 0");
1317  return 0;
1318  }
1319 }
1320 
1321 void
1323 {
1324  NS_LOG_FUNCTION (this);
1325  // If the user has configured both Frequency and ChannelNumber, Frequency
1326  // takes precedence
1327  if (GetFrequency () != 0)
1328  {
1329  // If Frequency is already set, then see whether a ChannelNumber can
1330  // be found that matches Frequency and ChannelWidth. If so, configure
1331  // the ChannelNumber to that channel number. If not, set ChannelNumber to zero.
1332  NS_LOG_DEBUG ("Frequency set; checking whether a channel number corresponds");
1333  uint8_t channelNumberSearched = FindChannelNumberForFrequencyWidth (GetFrequency (), GetChannelWidth ());
1334  if (channelNumberSearched)
1335  {
1336  NS_LOG_DEBUG ("Channel number found; setting to " << +channelNumberSearched);
1337  SetChannelNumber (channelNumberSearched);
1338  }
1339  else
1340  {
1341  NS_LOG_DEBUG ("Channel number not found; setting to zero");
1342  SetChannelNumber (0);
1343  }
1344  }
1345  else if (GetChannelNumber () != 0)
1346  {
1347  // If the channel number is known for this particular standard or for
1348  // the unspecified standard, configure using the known values;
1349  // otherwise, this is a configuration error
1350  NS_LOG_DEBUG ("Configuring for channel number " << +GetChannelNumber ());
1352  if (f.first == 0)
1353  {
1354  // the specific pair of number/standard is not known
1355  NS_LOG_DEBUG ("Falling back to check WIFI_PHY_STANDARD_UNSPECIFIED");
1357  }
1358  if (f.first == 0)
1359  {
1360  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " is unknown for this standard");
1361  }
1362  else
1363  {
1364  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1365  SetFrequency (f.first);
1366  SetChannelWidth (f.second);
1367  }
1368  }
1369 }
1370 
1371 void
1373 {
1374  NS_LOG_FUNCTION (this << standard << band);
1375  m_standard = standard;
1376  m_band = band;
1377  m_isConstructed = true;
1379  {
1381  }
1382  if (GetFrequency () == 0 && GetChannelNumber () == 0)
1383  {
1385  }
1386  else
1387  {
1388  // The user has configured either (or both) Frequency or ChannelNumber
1390  }
1391  switch (standard)
1392  {
1394  Configure80211a ();
1395  break;
1397  Configure80211b ();
1398  break;
1400  Configure80211g ();
1401  break;
1403  Configure80211p ();
1404  break;
1406  ConfigureHolland ();
1407  break;
1409  Configure80211n ();
1410  break;
1412  Configure80211ac ();
1413  break;
1415  Configure80211ax ();
1416  break;
1418  default:
1419  NS_ASSERT (false);
1420  break;
1421  }
1422 }
1423 
1426 {
1427  return m_band;
1428 }
1429 
1430 
1433 {
1434  return m_standard;
1435 }
1436 
1437 void
1438 WifiPhy::SetFrequency (uint16_t frequency)
1439 {
1440  NS_LOG_FUNCTION (this << frequency);
1441  if (m_isConstructed == false)
1442  {
1443  NS_LOG_DEBUG ("Saving frequency configuration for initialization");
1444  m_initialFrequency = frequency;
1445  return;
1446  }
1447  if (GetFrequency () == frequency)
1448  {
1449  NS_LOG_DEBUG ("No frequency change requested");
1450  return;
1451  }
1452  if (frequency == 0)
1453  {
1454  DoFrequencySwitch (0);
1455  NS_LOG_DEBUG ("Setting frequency and channel number to zero");
1457  m_channelNumber = 0;
1458  return;
1459  }
1460  // If the user has configured both Frequency and ChannelNumber, Frequency
1461  // takes precedence. Lookup the channel number corresponding to the
1462  // requested frequency.
1463  uint8_t nch = FindChannelNumberForFrequencyWidth (frequency, GetChannelWidth ());
1464  if (nch != 0)
1465  {
1466  NS_LOG_DEBUG ("Setting frequency " << frequency << " corresponds to channel " << +nch);
1467  if (DoFrequencySwitch (frequency))
1468  {
1469  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << +nch);
1470  m_channelCenterFrequency = frequency;
1471  m_channelNumber = nch;
1472  }
1473  else
1474  {
1475  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1476  }
1477  }
1478  else
1479  {
1480  NS_LOG_DEBUG ("Channel number is unknown for frequency " << frequency);
1481  if (DoFrequencySwitch (frequency))
1482  {
1483  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << 0);
1484  m_channelCenterFrequency = frequency;
1485  m_channelNumber = 0;
1486  }
1487  else
1488  {
1489  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1490  }
1491  }
1492 }
1493 
1494 uint16_t
1496 {
1497  return m_channelCenterFrequency;
1498 }
1499 
1500 void
1501 WifiPhy::SetChannelWidth (uint16_t channelWidth)
1502 {
1503  NS_LOG_FUNCTION (this << channelWidth);
1504  NS_ASSERT_MSG (channelWidth == 5 || channelWidth == 10 || channelWidth == 20 || channelWidth == 22 || channelWidth == 40 || channelWidth == 80 || channelWidth == 160, "wrong channel width value");
1505  bool changed = (m_channelWidth != channelWidth);
1506  m_channelWidth = channelWidth;
1507  AddSupportedChannelWidth (channelWidth);
1508  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1509  {
1511  }
1512 }
1513 
1514 uint16_t
1516 {
1517  return m_channelWidth;
1518 }
1519 
1520 void
1522 {
1523  NS_ASSERT_MSG (antennas > 0 && antennas <= 4, "unsupported number of antennas");
1524  m_numberOfAntennas = antennas;
1526 }
1527 
1528 uint8_t
1530 {
1531  return m_numberOfAntennas;
1532 }
1533 
1534 void
1536 {
1537  NS_ASSERT (streams <= GetNumberOfAntennas ());
1538  bool changed = (m_txSpatialStreams != streams);
1539  m_txSpatialStreams = streams;
1541  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1542  {
1544  }
1545 }
1546 
1547 uint8_t
1549 {
1550  return m_txSpatialStreams;
1551 }
1552 
1553 void
1555 {
1556  NS_ASSERT (streams <= GetNumberOfAntennas ());
1557  bool changed = (m_rxSpatialStreams != streams);
1558  m_rxSpatialStreams = streams;
1559  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1560  {
1562  }
1563 }
1564 
1565 uint8_t
1567 {
1568  return m_rxSpatialStreams;
1569 }
1570 
1571 uint8_t
1573 {
1574  return static_cast<uint8_t> (m_bssMembershipSelectorSet.size ());
1575 }
1576 
1577 uint8_t
1578 WifiPhy::GetBssMembershipSelector (uint8_t selector) const
1579 {
1580  return m_bssMembershipSelectorSet[selector];
1581 }
1582 
1583 void
1585 {
1586  NS_LOG_FUNCTION (this << width);
1587  for (std::vector<uint32_t>::size_type i = 0; i != m_supportedChannelWidthSet.size (); i++)
1588  {
1589  if (m_supportedChannelWidthSet[i] == width)
1590  {
1591  return;
1592  }
1593  }
1594  NS_LOG_FUNCTION ("Adding " << width << " to supported channel width set");
1595  m_supportedChannelWidthSet.push_back (width);
1596 }
1597 
1598 std::vector<uint16_t>
1600 {
1602 }
1603 
1606 {
1607  ChannelNumberStandardPair p = std::make_pair (std::make_pair (channelNumber, band), standard);
1609  return f;
1610 }
1611 
1612 void
1614 {
1615  NS_LOG_FUNCTION (this << +nch);
1616  if (m_isConstructed == false)
1617  {
1618  NS_LOG_DEBUG ("Saving channel number configuration for initialization");
1619  m_initialChannelNumber = nch;
1620  return;
1621  }
1622  if (GetChannelNumber () == nch)
1623  {
1624  NS_LOG_DEBUG ("No channel change requested");
1625  return;
1626  }
1627  if (nch == 0)
1628  {
1629  // This case corresponds to when there is not a known channel
1630  // number for the requested frequency. There is no need to call
1631  // DoChannelSwitch () because DoFrequencySwitch () should have been
1632  // called by the client
1633  NS_LOG_DEBUG ("Setting channel number to zero");
1634  m_channelNumber = 0;
1635  return;
1636  }
1637 
1638  // First make sure that the channel number is defined for the standard in use
1640  if (f.first == 0)
1641  {
1643  }
1644  if (f.first != 0)
1645  {
1646  if (DoChannelSwitch (nch))
1647  {
1648  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1649  m_channelCenterFrequency = f.first;
1650  SetChannelWidth (f.second);
1651  m_channelNumber = nch;
1652  }
1653  else
1654  {
1655  // Subclass may have suppressed (e.g. waiting for state change)
1656  NS_LOG_DEBUG ("Channel switch suppressed");
1657  }
1658  }
1659  else
1660  {
1661  NS_FATAL_ERROR ("Frequency not found for channel number " << +nch);
1662  }
1663 }
1664 
1665 uint8_t
1667 {
1668  return m_channelNumber;
1669 }
1670 
1671 bool
1673 {
1674  m_powerRestricted = false;
1675  m_channelAccessRequested = false;
1676  if (!IsInitialized ())
1677  {
1678  //this is not channel switch, this is initialization
1679  NS_LOG_DEBUG ("initialize to channel " << +nch);
1680  return true;
1681  }
1682 
1684  switch (m_state->GetState ())
1685  {
1686  case WifiPhyState::RX:
1687  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1689  m_endRxEvent.Cancel ();
1691  goto switchChannel;
1692  break;
1693  case WifiPhyState::TX:
1694  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1696  break;
1698  case WifiPhyState::IDLE:
1700  {
1702  m_endRxEvent.Cancel ();
1703  }
1704  goto switchChannel;
1705  break;
1706  case WifiPhyState::SLEEP:
1707  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1708  break;
1709  default:
1710  NS_ASSERT (false);
1711  break;
1712  }
1713 
1714  return false;
1715 
1716 switchChannel:
1717 
1718  NS_LOG_DEBUG ("switching channel " << +GetChannelNumber () << " -> " << +nch);
1719  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1721  /*
1722  * Needed here to be able to correctly sensed the medium for the first
1723  * time after the switching. The actual switching is not performed until
1724  * after m_channelSwitchDelay. Packets received during the switching
1725  * state are added to the event list and are employed later to figure
1726  * out the state of the medium after the switching.
1727  */
1728  return true;
1729 }
1730 
1731 bool
1732 WifiPhy::DoFrequencySwitch (uint16_t frequency)
1733 {
1734  m_powerRestricted = false;
1735  m_channelAccessRequested = false;
1736  if (!IsInitialized ())
1737  {
1738  //this is not channel switch, this is initialization
1739  NS_LOG_DEBUG ("start at frequency " << frequency);
1740  return true;
1741  }
1742 
1744  switch (m_state->GetState ())
1745  {
1746  case WifiPhyState::RX:
1747  NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
1749  m_endRxEvent.Cancel ();
1751  goto switchFrequency;
1752  break;
1753  case WifiPhyState::TX:
1754  NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
1756  break;
1758  case WifiPhyState::IDLE:
1760  {
1762  m_endRxEvent.Cancel ();
1763  }
1764  goto switchFrequency;
1765  break;
1766  case WifiPhyState::SLEEP:
1767  NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
1768  break;
1769  default:
1770  NS_ASSERT (false);
1771  break;
1772  }
1773 
1774  return false;
1775 
1776 switchFrequency:
1777 
1778  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
1779  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1781  /*
1782  * Needed here to be able to correctly sensed the medium for the first
1783  * time after the switching. The actual switching is not performed until
1784  * after m_channelSwitchDelay. Packets received during the switching
1785  * state are added to the event list and are employed later to figure
1786  * out the state of the medium after the switching.
1787  */
1788  return true;
1789 }
1790 
1791 void
1793 {
1794  NS_LOG_FUNCTION (this);
1795  m_powerRestricted = false;
1796  m_channelAccessRequested = false;
1797  switch (m_state->GetState ())
1798  {
1799  case WifiPhyState::TX:
1800  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1802  break;
1803  case WifiPhyState::RX:
1804  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1806  break;
1808  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1810  break;
1812  case WifiPhyState::IDLE:
1813  NS_LOG_DEBUG ("setting sleep mode");
1814  m_state->SwitchToSleep ();
1815  break;
1816  case WifiPhyState::SLEEP:
1817  NS_LOG_DEBUG ("already in sleep mode");
1818  break;
1819  default:
1820  NS_ASSERT (false);
1821  break;
1822  }
1823 }
1824 
1825 void
1827 {
1828  NS_LOG_FUNCTION (this);
1829  m_powerRestricted = false;
1830  m_channelAccessRequested = false;
1832  m_endRxEvent.Cancel ();
1834  m_endTxEvent.Cancel ();
1835  m_state->SwitchToOff ();
1836 }
1837 
1838 void
1840 {
1841  NS_LOG_FUNCTION (this);
1842  switch (m_state->GetState ())
1843  {
1844  case WifiPhyState::TX:
1845  case WifiPhyState::RX:
1846  case WifiPhyState::IDLE:
1849  {
1850  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1851  break;
1852  }
1853  case WifiPhyState::SLEEP:
1854  {
1855  NS_LOG_DEBUG ("resuming from sleep mode");
1857  m_state->SwitchFromSleep (delayUntilCcaEnd);
1858  break;
1859  }
1860  default:
1861  {
1862  NS_ASSERT (false);
1863  break;
1864  }
1865  }
1866 }
1867 
1868 void
1870 {
1871  NS_LOG_FUNCTION (this);
1872  switch (m_state->GetState ())
1873  {
1874  case WifiPhyState::TX:
1875  case WifiPhyState::RX:
1876  case WifiPhyState::IDLE:
1879  case WifiPhyState::SLEEP:
1880  {
1881  NS_LOG_DEBUG ("not in off mode, there is nothing to resume");
1882  break;
1883  }
1884  case WifiPhyState::OFF:
1885  {
1886  NS_LOG_DEBUG ("resuming from off mode");
1888  m_state->SwitchFromOff (delayUntilCcaEnd);
1889  break;
1890  }
1891  default:
1892  {
1893  NS_ASSERT (false);
1894  break;
1895  }
1896  }
1897 }
1898 
1899 WifiMode
1901 {
1902  return WifiPhy::GetHtMcs0 ();
1903 }
1904 
1905 WifiMode
1907 {
1908  return WifiPhy::GetVhtMcs0 ();
1909 }
1910 
1911 WifiMode
1913 {
1914  return WifiPhy::GetHeMcs0 ();
1915 }
1916 
1917 Time
1919 {
1920  return MicroSeconds (4);
1921 }
1922 
1923 Time
1925 {
1926  uint8_t Ndltf, Neltf;
1927  //We suppose here that STBC = 0.
1928  //If STBC > 0, we need a different mapping between Nss and Nltf (IEEE 802.11n-2012 standard, page 1682).
1929  if (txVector.GetNss () < 3)
1930  {
1931  Ndltf = txVector.GetNss ();
1932  }
1933  else if (txVector.GetNss () < 5)
1934  {
1935  Ndltf = 4;
1936  }
1937  else if (txVector.GetNss () < 7)
1938  {
1939  Ndltf = 6;
1940  }
1941  else
1942  {
1943  Ndltf = 8;
1944  }
1945 
1946  if (txVector.GetNess () < 3)
1947  {
1948  Neltf = txVector.GetNess ();
1949  }
1950  else
1951  {
1952  Neltf = 4;
1953  }
1954 
1955  switch (txVector.GetPreambleType ())
1956  {
1957  case WIFI_PREAMBLE_HT_MF:
1958  return MicroSeconds (4 + (4 * Ndltf) + (4 * Neltf));
1959  case WIFI_PREAMBLE_HT_GF:
1960  return MicroSeconds ((4 * Ndltf) + (4 * Neltf));
1961  case WIFI_PREAMBLE_VHT_SU:
1962  case WIFI_PREAMBLE_VHT_MU:
1963  return MicroSeconds (4 + (4 * Ndltf));
1964  case WIFI_PREAMBLE_HE_SU:
1965  case WIFI_PREAMBLE_HE_MU:
1966  return MicroSeconds (4 + (8 * Ndltf));
1967  default:
1968  return MicroSeconds (0);
1969  }
1970 }
1971 
1972 Time
1974 {
1975  switch (preamble)
1976  {
1977  case WIFI_PREAMBLE_HT_MF:
1978  case WIFI_PREAMBLE_HT_GF:
1979  //HT-SIG
1980  return MicroSeconds (8);
1981  default:
1982  //no HT-SIG for non HT
1983  return MicroSeconds (0);
1984  }
1985 }
1986 
1987 Time
1989 {
1990  switch (preamble)
1991  {
1992  case WIFI_PREAMBLE_VHT_SU:
1993  case WIFI_PREAMBLE_HE_SU:
1994  case WIFI_PREAMBLE_VHT_MU:
1995  case WIFI_PREAMBLE_HE_MU:
1996  //VHT-SIG-A1 and HE-SIG-A1
1997  return MicroSeconds (4);
1998  default:
1999  // no SIG-A1
2000  return MicroSeconds (0);
2001  }
2002 }
2003 
2004 Time
2006 {
2007  switch (preamble)
2008  {
2009  case WIFI_PREAMBLE_VHT_SU:
2010  case WIFI_PREAMBLE_HE_SU:
2011  case WIFI_PREAMBLE_VHT_MU:
2012  case WIFI_PREAMBLE_HE_MU:
2013  //VHT-SIG-A2 and HE-SIG-A2
2014  return MicroSeconds (4);
2015  default:
2016  // no SIG-A2
2017  return MicroSeconds (0);
2018  }
2019 }
2020 
2021 Time
2023 {
2024  switch (preamble)
2025  {
2026  case WIFI_PREAMBLE_VHT_MU:
2027  case WIFI_PREAMBLE_HE_MU:
2028  return MicroSeconds (4);
2029  default:
2030  // no SIG-B
2031  return MicroSeconds (0);
2032  }
2033 }
2034 
2035 WifiMode
2037 {
2038  WifiPreamble preamble = txVector.GetPreambleType ();
2039  switch (preamble)
2040  {
2041  case WIFI_PREAMBLE_LONG:
2042  case WIFI_PREAMBLE_SHORT:
2043  {
2044  switch (txVector.GetMode ().GetModulationClass ())
2045  {
2046  case WIFI_MOD_CLASS_OFDM:
2047  {
2048  switch (txVector.GetChannelWidth ())
2049  {
2050  case 5:
2052  case 10:
2054  case 20:
2055  default:
2056  //(Section 17.3.2 "PPDU frame format"; IEEE Std 802.11-2016)
2057  //actually this is only the first part of the PhyHeader,
2058  //because the last 16 bits of the PhyHeader are using the
2059  //same mode of the payload
2060  return WifiPhy::GetOfdmRate6Mbps ();
2061  }
2062  }
2064  return WifiPhy::GetErpOfdmRate6Mbps ();
2065  case WIFI_MOD_CLASS_DSSS:
2067  {
2068  if (preamble == WIFI_PREAMBLE_LONG || txVector.GetMode () == WifiPhy::GetDsssRate1Mbps ())
2069  {
2070  //(Section 16.2.3 "PPDU field definitions" and Section 16.2.2.2 "Long PPDU format"; IEEE Std 802.11-2016)
2071  return WifiPhy::GetDsssRate1Mbps ();
2072  }
2073  else
2074  {
2075  //(Section 16.2.2.3 "Short PPDU format"; IEEE Std 802.11-2016)
2076  return WifiPhy::GetDsssRate2Mbps ();
2077  }
2078  }
2079  default:
2080  NS_FATAL_ERROR ("unsupported modulation class");
2081  return WifiMode ();
2082  }
2083  }
2084  case WIFI_PREAMBLE_HT_MF:
2085  case WIFI_PREAMBLE_HT_GF:
2086  case WIFI_PREAMBLE_VHT_SU:
2087  case WIFI_PREAMBLE_VHT_MU:
2088  case WIFI_PREAMBLE_HE_SU:
2090  case WIFI_PREAMBLE_HE_MU:
2091  case WIFI_PREAMBLE_HE_TB:
2092  return WifiPhy::GetOfdmRate6Mbps ();
2093  default:
2094  NS_FATAL_ERROR ("unsupported preamble type");
2095  return WifiMode ();
2096  }
2097 }
2098 
2099 Time
2101 {
2102  WifiPreamble preamble = txVector.GetPreambleType ();
2103  switch (txVector.GetPreambleType ())
2104  {
2105  case WIFI_PREAMBLE_LONG:
2106  case WIFI_PREAMBLE_SHORT:
2107  {
2108  switch (txVector.GetMode ().GetModulationClass ())
2109  {
2110  case WIFI_MOD_CLASS_OFDM:
2111  {
2112  switch (txVector.GetChannelWidth ())
2113  {
2114  case 20:
2115  default:
2116  //(Section 17.3.3 "PHY preamble (SYNC))" and Figure 17-4 "OFDM training structure"; IEEE Std 802.11-2016)
2117  //also (Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2118  //We return the duration of the SIGNAL field only, since the
2119  //SERVICE field (which strictly speaking belongs to the PHY
2120  //header, see Section 17.3.2 and Figure 17-1) is sent using the
2121  //payload mode.
2122  return MicroSeconds (4);
2123  case 10:
2124  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2125  return MicroSeconds (8);
2126  case 5:
2127  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2128  return MicroSeconds (16);
2129  }
2130  }
2132  return MicroSeconds (4);
2133  case WIFI_MOD_CLASS_DSSS:
2135  {
2136  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2137  {
2138  //(Section 16.2.2.3 "Short PPDU format" and Figure 16-2 "Short PPDU format"; IEEE Std 802.11-2016)
2139  return MicroSeconds (24);
2140  }
2141  else
2142  {
2143  //(Section 16.2.2.2 "Long PPDU format" and Figure 16-1 "Short PPDU format"; IEEE Std 802.11-2016)
2144  return MicroSeconds (48);
2145  }
2146  }
2147  default:
2148  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2149  return MicroSeconds (0);
2150  }
2151  }
2152  case WIFI_PREAMBLE_HT_MF:
2153  case WIFI_PREAMBLE_VHT_SU:
2154  case WIFI_PREAMBLE_VHT_MU:
2155  //L-SIG
2156  return MicroSeconds (4);
2157  case WIFI_PREAMBLE_HE_SU:
2159  case WIFI_PREAMBLE_HE_MU:
2160  case WIFI_PREAMBLE_HE_TB:
2161  //LSIG + R-LSIG
2162  return MicroSeconds (8);
2163  case WIFI_PREAMBLE_HT_GF:
2164  return MicroSeconds (0);
2165  default:
2166  NS_FATAL_ERROR ("unsupported preamble type");
2167  return MicroSeconds (0);
2168  }
2169 }
2170 
2171 Time
2173 {
2174  return MicroSeconds (4);
2175 }
2176 
2177 Time
2179 {
2180  WifiPreamble preamble = txVector.GetPreambleType ();
2181  switch (txVector.GetPreambleType ())
2182  {
2183  case WIFI_PREAMBLE_LONG:
2184  case WIFI_PREAMBLE_SHORT:
2185  {
2186  switch (txVector.GetMode ().GetModulationClass ())
2187  {
2188  case WIFI_MOD_CLASS_OFDM:
2189  {
2190  switch (txVector.GetChannelWidth ())
2191  {
2192  case 20:
2193  default:
2194  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2195  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2196  return MicroSeconds (16);
2197  case 10:
2198  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2199  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2200  return MicroSeconds (32);
2201  case 5:
2202  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2203  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2204  return MicroSeconds (64);
2205  }
2206  }
2208  return MicroSeconds (16);
2209  case WIFI_MOD_CLASS_DSSS:
2211  {
2212  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2213  {
2214  //(Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
2215  return MicroSeconds (72);
2216  }
2217  else
2218  {
2219  //(Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012)
2220  return MicroSeconds (144);
2221  }
2222  }
2223  default:
2224  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2225  return MicroSeconds (0);
2226  }
2227  }
2228  case WIFI_PREAMBLE_HT_MF:
2229  case WIFI_PREAMBLE_VHT_SU:
2230  case WIFI_PREAMBLE_VHT_MU:
2231  case WIFI_PREAMBLE_HE_SU:
2233  case WIFI_PREAMBLE_HE_MU:
2234  case WIFI_PREAMBLE_HE_TB:
2235  //L-STF + L-LTF
2236  return MicroSeconds (16);
2237  case WIFI_PREAMBLE_HT_GF:
2238  //HT-GF-STF + HT-LTF1
2239  return MicroSeconds (16);
2240  default:
2241  NS_FATAL_ERROR ("unsupported preamble type");
2242  return MicroSeconds (0);
2243  }
2244 }
2245 
2246 Time
2247 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype)
2248 {
2249  uint32_t totalAmpduSize;
2250  double totalAmpduNumSymbols;
2251  return GetPayloadDuration (size, txVector, band, mpdutype, false, totalAmpduSize, totalAmpduNumSymbols);
2252 }
2253 
2254 Time
2255 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype,
2256  bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols)
2257 {
2258  WifiMode payloadMode = txVector.GetMode ();
2259  NS_LOG_FUNCTION (size << payloadMode);
2260 
2261  double stbc = 1;
2262  if (txVector.IsStbc ()
2263  && (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
2264  || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
2265  {
2266  stbc = 2;
2267  }
2268 
2269  double Nes = 1;
2270  //todo: improve logic to reduce the number of if cases
2271  //todo: extend to NSS > 4 for VHT rates
2272  if (payloadMode == GetHtMcs21 ()
2273  || payloadMode == GetHtMcs22 ()
2274  || payloadMode == GetHtMcs23 ()
2275  || payloadMode == GetHtMcs28 ()
2276  || payloadMode == GetHtMcs29 ()
2277  || payloadMode == GetHtMcs30 ()
2278  || payloadMode == GetHtMcs31 ())
2279  {
2280  Nes = 2;
2281  }
2282  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
2283  {
2284  if (txVector.GetChannelWidth () == 40
2285  && txVector.GetNss () == 3
2286  && payloadMode.GetMcsValue () >= 8)
2287  {
2288  Nes = 2;
2289  }
2290  if (txVector.GetChannelWidth () == 80
2291  && txVector.GetNss () == 2
2292  && payloadMode.GetMcsValue () >= 7)
2293  {
2294  Nes = 2;
2295  }
2296  if (txVector.GetChannelWidth () == 80
2297  && txVector.GetNss () == 3
2298  && payloadMode.GetMcsValue () >= 7)
2299  {
2300  Nes = 2;
2301  }
2302  if (txVector.GetChannelWidth () == 80
2303  && txVector.GetNss () == 3
2304  && payloadMode.GetMcsValue () == 9)
2305  {
2306  Nes = 3;
2307  }
2308  if (txVector.GetChannelWidth () == 80
2309  && txVector.GetNss () == 4
2310  && payloadMode.GetMcsValue () >= 4)
2311  {
2312  Nes = 2;
2313  }
2314  if (txVector.GetChannelWidth () == 80
2315  && txVector.GetNss () == 4
2316  && payloadMode.GetMcsValue () >= 7)
2317  {
2318  Nes = 3;
2319  }
2320  if (txVector.GetChannelWidth () == 160
2321  && payloadMode.GetMcsValue () >= 7)
2322  {
2323  Nes = 2;
2324  }
2325  if (txVector.GetChannelWidth () == 160
2326  && txVector.GetNss () == 2
2327  && payloadMode.GetMcsValue () >= 4)
2328  {
2329  Nes = 2;
2330  }
2331  if (txVector.GetChannelWidth () == 160
2332  && txVector.GetNss () == 2
2333  && payloadMode.GetMcsValue () >= 7)
2334  {
2335  Nes = 3;
2336  }
2337  if (txVector.GetChannelWidth () == 160
2338  && txVector.GetNss () == 3
2339  && payloadMode.GetMcsValue () >= 3)
2340  {
2341  Nes = 2;
2342  }
2343  if (txVector.GetChannelWidth () == 160
2344  && txVector.GetNss () == 3
2345  && payloadMode.GetMcsValue () >= 5)
2346  {
2347  Nes = 3;
2348  }
2349  if (txVector.GetChannelWidth () == 160
2350  && txVector.GetNss () == 3
2351  && payloadMode.GetMcsValue () >= 7)
2352  {
2353  Nes = 4;
2354  }
2355  if (txVector.GetChannelWidth () == 160
2356  && txVector.GetNss () == 4
2357  && payloadMode.GetMcsValue () >= 2)
2358  {
2359  Nes = 2;
2360  }
2361  if (txVector.GetChannelWidth () == 160
2362  && txVector.GetNss () == 4
2363  && payloadMode.GetMcsValue () >= 4)
2364  {
2365  Nes = 3;
2366  }
2367  if (txVector.GetChannelWidth () == 160
2368  && txVector.GetNss () == 4
2369  && payloadMode.GetMcsValue () >= 5)
2370  {
2371  Nes = 4;
2372  }
2373  if (txVector.GetChannelWidth () == 160
2374  && txVector.GetNss () == 4
2375  && payloadMode.GetMcsValue () >= 7)
2376  {
2377  Nes = 6;
2378  }
2379  }
2380 
2381  Time symbolDuration = Seconds (0);
2382  switch (payloadMode.GetModulationClass ())
2383  {
2384  case WIFI_MOD_CLASS_OFDM:
2386  {
2387  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012
2388  //corresponds to T_{SYM} in the table)
2389  switch (txVector.GetChannelWidth ())
2390  {
2391  case 20:
2392  default:
2393  symbolDuration = MicroSeconds (4);
2394  break;
2395  case 10:
2396  symbolDuration = MicroSeconds (8);
2397  break;
2398  case 5:
2399  symbolDuration = MicroSeconds (16);
2400  break;
2401  }
2402  break;
2403  }
2404  case WIFI_MOD_CLASS_HT:
2405  case WIFI_MOD_CLASS_VHT:
2406  {
2407  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2408  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2409  uint16_t gi = txVector.GetGuardInterval ();
2410  NS_ASSERT (gi == 400 || gi == 800);
2411  symbolDuration = NanoSeconds (3200 + gi);
2412  }
2413  break;
2414  case WIFI_MOD_CLASS_HE:
2415  {
2416  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2417  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2418  uint16_t gi = txVector.GetGuardInterval ();
2419  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
2420  symbolDuration = NanoSeconds (12800 + gi);
2421  }
2422  break;
2423  default:
2424  break;
2425  }
2426 
2427  double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector) * symbolDuration.GetNanoSeconds () / 1e9;
2428 
2429  double numSymbols = 0;
2430  if (mpdutype == FIRST_MPDU_IN_AGGREGATE)
2431  {
2432  //First packet in an A-MPDU
2433  numSymbols = (stbc * (16 + size * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol));
2434  if (incFlag == 1)
2435  {
2436  totalAmpduSize += size;
2437  totalAmpduNumSymbols += numSymbols;
2438  }
2439  }
2440  else if (mpdutype == MIDDLE_MPDU_IN_AGGREGATE)
2441  {
2442  //consecutive packets in an A-MPDU
2443  numSymbols = (stbc * size * 8.0) / (stbc * numDataBitsPerSymbol);
2444  if (incFlag == 1)
2445  {
2446  totalAmpduSize += size;
2447  totalAmpduNumSymbols += numSymbols;
2448  }
2449  }
2450  else if (mpdutype == LAST_MPDU_IN_AGGREGATE)
2451  {
2452  //last packet in an A-MPDU
2453  uint32_t totalSize = totalAmpduSize + size;
2454  numSymbols = lrint (stbc * ceil ((16 + totalSize * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol)));
2455  NS_ASSERT (totalAmpduNumSymbols <= numSymbols);
2456  numSymbols -= totalAmpduNumSymbols;
2457  if (incFlag == 1)
2458  {
2459  totalAmpduSize = 0;
2460  totalAmpduNumSymbols = 0;
2461  }
2462  }
2463  else if (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU)
2464  {
2465  //Not an A-MPDU or single MPDU (i.e. the current payload contains both service and padding)
2466  //The number of OFDM symbols in the data field when BCC encoding
2467  //is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
2468  numSymbols = lrint (stbc * ceil ((16 + size * 8.0 + 6.0 * Nes) / (stbc * numDataBitsPerSymbol)));
2469  }
2470  else
2471  {
2472  NS_FATAL_ERROR ("Unknown MPDU type");
2473  }
2474 
2475  switch (payloadMode.GetModulationClass ())
2476  {
2477  case WIFI_MOD_CLASS_OFDM:
2479  {
2480  //Add signal extension for ERP PHY
2481  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
2482  {
2483  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2484  }
2485  else
2486  {
2487  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2488  }
2489  }
2490  case WIFI_MOD_CLASS_HT:
2491  case WIFI_MOD_CLASS_VHT:
2492  {
2493  if ((payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT) && (band == WIFI_PHY_BAND_2_4GHZ)
2494  && (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE)) //at 2.4 GHz
2495  {
2496  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2497  }
2498  else //at 5 GHz
2499  {
2500  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2501  }
2502  }
2503  case WIFI_MOD_CLASS_HE:
2504  {
2505  if ((band == WIFI_PHY_BAND_2_4GHZ)
2506  && ((mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE))) //at 2.4 GHz
2507  {
2508  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2509  }
2510  else //at 5 GHz or 6 GHz
2511  {
2512  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2513  }
2514  }
2515  case WIFI_MOD_CLASS_DSSS:
2517  return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate (22) / 1.0e6))));
2518  default:
2519  NS_FATAL_ERROR ("unsupported modulation class");
2520  return MicroSeconds (0);
2521  }
2522 }
2523 
2524 Time
2526 {
2527  WifiPreamble preamble = txVector.GetPreambleType ();
2528  Time duration = GetPhyPreambleDuration (txVector)
2529  + GetPhyHeaderDuration (txVector)
2530  + GetPhyHtSigHeaderDuration (preamble)
2531  + GetPhySigA1Duration (preamble)
2532  + GetPhySigA2Duration (preamble)
2533  + GetPhyTrainingSymbolDuration (txVector)
2534  + GetPhySigBDuration (preamble);
2535  return duration;
2536 }
2537 
2538 Time
2540 {
2541  Time duration = CalculatePhyPreambleAndHeaderDuration (txVector)
2542  + GetPayloadDuration (size, txVector, band);
2543  return duration;
2544 }
2545 
2546 void
2548 {
2549  for (auto& mpdu : *PeekPointer (psdu))
2550  {
2551  m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW);
2552  }
2553 }
2554 
2555 void
2557 {
2558  for (auto& mpdu : *PeekPointer (psdu))
2559  {
2560  m_phyTxEndTrace (mpdu->GetProtocolDataUnit ());
2561  }
2562 }
2563 
2564 void
2566 {
2567  for (auto& mpdu : *PeekPointer (psdu))
2568  {
2569  m_phyTxDropTrace (mpdu->GetProtocolDataUnit ());
2570  }
2571 }
2572 
2573 void
2575 {
2576  for (auto& mpdu : *PeekPointer (psdu))
2577  {
2578  m_phyRxBeginTrace (mpdu->GetProtocolDataUnit ());
2579  }
2580 }
2581 
2582 void
2584 {
2585  for (auto& mpdu : *PeekPointer (psdu))
2586  {
2587  m_phyRxEndTrace (mpdu->GetProtocolDataUnit ());
2588  }
2589 }
2590 
2591 void
2593 {
2594  for (auto& mpdu : *PeekPointer (psdu))
2595  {
2596  m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason);
2597  }
2598 }
2599 
2600 void
2601 WifiPhy::NotifyMonitorSniffRx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector,
2602  SignalNoiseDbm signalNoise, std::vector<bool> statusPerMpdu)
2603 {
2604  MpduInfo aMpdu;
2605  if (psdu->IsAggregate ())
2606  {
2607  //Expand A-MPDU
2608  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2610  size_t nMpdus = psdu->GetNMpdus ();
2611  NS_ASSERT_MSG (statusPerMpdu.size () == nMpdus, "Should have one reception status per MPDU");
2612  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2613  for (size_t i = 0; i < nMpdus;)
2614  {
2615  if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer
2616  {
2617  m_phyMonitorSniffRxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, signalNoise);
2618  }
2619  ++i;
2620  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2621  }
2622  }
2623  else
2624  {
2625  aMpdu.type = NORMAL_MPDU;
2626  NS_ASSERT_MSG (statusPerMpdu.size () == 1, "Should have one reception status for normal MPDU");
2627  m_phyMonitorSniffRxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, signalNoise);
2628  }
2629 }
2630 
2631 void
2632 WifiPhy::NotifyMonitorSniffTx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector)
2633 {
2634  MpduInfo aMpdu;
2635  if (psdu->IsAggregate ())
2636  {
2637  //Expand A-MPDU
2638  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2640  size_t nMpdus = psdu->GetNMpdus ();
2641  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2642  for (size_t i = 0; i < nMpdus;)
2643  {
2644  m_phyMonitorSniffTxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu);
2645  ++i;
2646  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2647  }
2648  }
2649  else
2650  {
2651  aMpdu.type = NORMAL_MPDU;
2652  m_phyMonitorSniffTxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu);
2653  }
2654 }
2655 
2656 void
2658 {
2659  m_phyEndOfHePreambleTrace (params);
2660 }
2661 
2662 void
2664 {
2665  NS_LOG_FUNCTION (this << *psdu << txVector);
2666  /* Transmission can happen if:
2667  * - we are syncing on a packet. It is the responsibility of the
2668  * MAC layer to avoid doing this but the PHY does nothing to
2669  * prevent it.
2670  * - we are idle
2671  */
2672  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2674 
2675  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2676  {
2677  NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2678  }
2679 
2680  if (m_state->IsStateSleep ())
2681  {
2682  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
2683  NotifyTxDrop (psdu);
2684  return;
2685  }
2686 
2687  Time txDuration = CalculateTxDuration (psdu->GetSize (), txVector, GetPhyBand ());
2688  NS_ASSERT (txDuration.IsStrictlyPositive ());
2689 
2690  if ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())))
2691  {
2692  //that packet will be noise _after_ the transmission.
2694  }
2695 
2696  if (m_currentEvent != 0)
2697  {
2699  }
2700 
2701  if (m_powerRestricted)
2702  {
2703  NS_LOG_DEBUG ("Transmitting with power restriction");
2704  }
2705  else
2706  {
2707  NS_LOG_DEBUG ("Transmitting without power restriction");
2708  }
2709 
2710  if (m_state->GetState () == WifiPhyState::OFF)
2711  {
2712  NS_LOG_DEBUG ("Transmission canceled because device is OFF");
2713  return;
2714  }
2715 
2716  double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ());
2717  NotifyTxBegin (psdu, txPowerW);
2718  m_phyTxPsduBeginTrace (psdu, txVector, txPowerW);
2719  NotifyMonitorSniffTx (psdu, GetFrequency (), txVector);
2720  m_state->SwitchToTx (txDuration, psdu->GetPacket (), GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
2721 
2722  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, GetPhyBand ());
2723 
2724  if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
2725  {
2726  ppdu->SetTruncatedTx ();
2727  }
2728 
2729  m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdu);
2730 
2731  StartTx (ppdu);
2732 
2733  m_channelAccessRequested = false;
2734  m_powerRestricted = false;
2735 }
2736 
2737 void
2739 {
2740  NS_LOG_FUNCTION (this << *event);
2741  NS_ASSERT (!IsStateRx ());
2743  NS_ASSERT (m_currentEvent != 0);
2744  NS_ASSERT (event->GetStartTime () == m_currentEvent->GetStartTime ());
2745  NS_ASSERT (event->GetEndTime () == m_currentEvent->GetEndTime ());
2746 
2748  double snr = snrPer.snr;
2749  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2750 
2751  if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (), snr, m_channelWidth)))
2752  {
2753  NotifyRxBegin (event->GetPsdu ());
2754 
2756  WifiTxVector txVector = event->GetTxVector ();
2757 
2758  if ((txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT) && (txVector.GetPreambleType () == WIFI_PREAMBLE_HT_GF))
2759  {
2760  //No non-HT PHY header for HT GF
2761  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2762  m_state->SwitchMaybeToCcaBusy (remainingPreambleHeaderDuration);
2763  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2764  }
2765  else
2766  {
2767  //Schedule end of non-HT PHY header
2768  Time remainingPreambleAndNonHtHeaderDuration = GetPhyPreambleDuration (txVector) + GetPhyHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2769  m_state->SwitchMaybeToCcaBusy (remainingPreambleAndNonHtHeaderDuration);
2770  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleAndNonHtHeaderDuration, &WifiPhy::ContinueReceiveHeader, this, event);
2771  }
2772  }
2773  else
2774  {
2775  NS_LOG_DEBUG ("Drop packet because PHY preamble detection failed");
2776  NotifyRxDrop (event->GetPsdu (), PREAMBLE_DETECT_FAILURE);
2778  m_currentEvent = 0;
2779 
2780  // Like CCA-SD, CCA-ED is governed by the 4μs CCA window to flag CCA-BUSY
2781  // for any received signal greater than the CCA-ED threshold.
2782  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2783  {
2785  }
2786  }
2787 }
2788 
2789 void
2791 {
2792  NS_LOG_FUNCTION (this << *event);
2794 
2797 
2798  if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded
2799  {
2800  NS_LOG_DEBUG ("Received non-HT PHY header");
2801  WifiTxVector txVector = event->GetTxVector ();
2802  Time remainingRxDuration = event->GetEndTime () - Simulator::Now ();
2803  m_state->SwitchMaybeToCcaBusy (remainingRxDuration);
2804  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPhyPreambleDuration (txVector) - GetPhyHeaderDuration (txVector);
2805  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2806  }
2807  else //non-HT PHY header reception failed
2808  {
2809  NS_LOG_DEBUG ("Abort reception because non-HT PHY header reception failed");
2811  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2812  {
2814  }
2815  }
2816 }
2817 
2818 void
2820 {
2821  NS_LOG_FUNCTION (this << *ppdu << rxPowerW);
2822  WifiTxVector txVector = ppdu->GetTxVector ();
2823  Time rxDuration = ppdu->GetTxDuration ();
2824  Ptr<const WifiPsdu> psdu = ppdu->GetPsdu ();
2825  Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW);
2826  Time endRx = Simulator::Now () + rxDuration;
2827 
2828  if (m_state->GetState () == WifiPhyState::OFF)
2829  {
2830  NS_LOG_DEBUG ("Cannot start RX because device is OFF");
2831  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2832  {
2834  }
2835  return;
2836  }
2837 
2838  if (ppdu->IsTruncatedTx ())
2839  {
2840  NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
2841  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2842  {
2844  }
2845  return;
2846  }
2847 
2848  if (!txVector.GetModeInitialized ())
2849  {
2850  //If SetRate method was not called above when filling in txVector, this means the PHY does support the rate indicated in PHY SIG headers
2851  NS_LOG_DEBUG ("drop packet because of unsupported RX mode");
2853  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2854  {
2856  }
2857  return;
2858  }
2859 
2860  switch (m_state->GetState ())
2861  {
2863  NS_LOG_DEBUG ("drop packet because of channel switching");
2865  /*
2866  * Packets received on the upcoming channel are added to the event list
2867  * during the switching state. This way the medium can be correctly sensed
2868  * when the device listens to the channel for the first time after the
2869  * switching e.g. after channel switching, the channel may be sensed as
2870  * busy due to other devices' transmissions started before the end of
2871  * the switching.
2872  */
2873  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2874  {
2875  //that packet will be noise _after_ the completion of the channel switching.
2877  }
2878  break;
2879  case WifiPhyState::RX:
2880  NS_ASSERT (m_currentEvent != 0);
2881  if (m_frameCaptureModel != 0
2882  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2883  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2884  {
2886  NS_LOG_DEBUG ("Switch to new packet");
2887  StartRx (event, rxPowerW);
2888  }
2889  else
2890  {
2891  NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
2892  rxPowerW << "W)");
2893  NotifyRxDrop (psdu, RXING);
2894  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2895  {
2896  //that packet will be noise _after_ the reception of the currently-received packet.
2898  }
2899  }
2900  break;
2901  case WifiPhyState::TX:
2902  NS_LOG_DEBUG ("Drop packet because already in Tx (power=" <<
2903  rxPowerW << "W)");
2904  NotifyRxDrop (psdu, TXING);
2905  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2906  {
2907  //that packet will be noise _after_ the transmission of the currently-transmitted packet.
2909  }
2910  break;
2912  if (m_currentEvent != 0)
2913  {
2914  if (m_frameCaptureModel != 0
2915  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2916  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2917  {
2919  NS_LOG_DEBUG ("Switch to new packet");
2920  StartRx (event, rxPowerW);
2921  }
2922  else
2923  {
2924  NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
2925  rxPowerW << "W)");
2926  NotifyRxDrop (psdu, RXING);
2927  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2928  {
2929  //that packet will be noise _after_ the reception of the currently-received packet.
2931  }
2932  }
2933  }
2934  else
2935  {
2936  StartRx (event, rxPowerW);
2937  }
2938  break;
2939  case WifiPhyState::IDLE:
2940  StartRx (event, rxPowerW);
2941  break;
2942  case WifiPhyState::SLEEP:
2943  NS_LOG_DEBUG ("Drop packet because in sleep mode");
2944  NotifyRxDrop (psdu, SLEEPING);
2945  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2946  {
2947  //that packet will be noise _after_ the sleep period.
2949  }
2950  break;
2951  default:
2952  NS_FATAL_ERROR ("Invalid WifiPhy state.");
2953  break;
2954  }
2955 }
2956 
2957 void
2959 {
2960  //We are here because we have received the first bit of a packet and we are
2961  //not going to be able to synchronize on it
2962  //In this model, CCA becomes busy when the aggregation of all signals as
2963  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2964 
2966  if (!delayUntilCcaEnd.IsZero ())
2967  {
2968  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
2969  }
2970 }
2971 
2972 void
2974 {
2975  NS_LOG_FUNCTION (this << *event);
2978  WifiTxVector txVector = event->GetTxVector ();
2979  WifiMode txMode = txVector.GetMode ();
2980  bool canReceivePayload;
2981  if (txMode.GetModulationClass () >= WIFI_MOD_CLASS_HT)
2982  {
2984  snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event);
2985  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2986  canReceivePayload = (m_random->GetValue () > snrPer.per);
2987  }
2988  else
2989  {
2990  //If we are here, this means non-HT PHY header was already successfully received
2991  canReceivePayload = true;
2992  }
2993  Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePhyPreambleAndHeaderDuration (txVector);
2994  if (canReceivePayload) //PHY reception succeeded
2995  {
2996  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2997  {
2998  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
2999  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
3000  }
3001  else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ()))
3002  {
3003  NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width");
3004  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
3005  }
3006  else if (!IsModeSupported (txMode) && !IsMcsSupported (txMode))
3007  {
3008  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
3009  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
3010  }
3011  else
3012  {
3013  m_statusPerMpdu.clear();
3014  if (event->GetPsdu ()->GetNMpdus () > 1)
3015  {
3016  ScheduleEndOfMpdus (event);
3017  }
3018  m_state->SwitchToRx (payloadDuration);
3019  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
3020  NS_LOG_DEBUG ("Receiving PSDU");
3021  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
3022  if (txMode.GetModulationClass () == WIFI_MOD_CLASS_HE)
3023  {
3024  HePreambleParameters params;
3025  params.rssiW = event->GetRxPowerW ();
3026  params.bssColor = event->GetTxVector ().GetBssColor ();
3027  NotifyEndOfHePreamble (params);
3028  }
3029  return;
3030  }
3031  }
3032  else //PHY reception failed
3033  {
3034  NS_LOG_DEBUG ("Drop packet because HT PHY header reception failed");
3035  NotifyRxDrop (event->GetPsdu (), SIG_A_FAILURE);
3036  }
3037  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event);
3038 }
3039 
3040 void
3042 {
3043  NS_LOG_FUNCTION (this << *event);
3044  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
3045  WifiTxVector txVector = event->GetTxVector ();
3046  Time endOfMpduDuration = NanoSeconds (0);
3047  Time relativeStart = NanoSeconds (0);
3048  Time psduDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
3049  Time remainingAmpduDuration = psduDuration;
3050  MpduType mpdutype = FIRST_MPDU_IN_AGGREGATE;
3051  uint32_t totalAmpduSize = 0;
3052  double totalAmpduNumSymbols = 0.0;
3053  Ptr<const WifiPsdu> psdu = event->GetPsdu ();
3054  size_t nMpdus = psdu->GetNMpdus ();
3055  auto mpdu = psdu->begin ();
3056  for (size_t i = 0; i < nMpdus && mpdu != psdu->end (); ++mpdu)
3057  {
3058  Time mpduDuration = GetPayloadDuration (psdu->GetAmpduSubframeSize (i), txVector,
3059  GetPhyBand (), mpdutype, true, totalAmpduSize, totalAmpduNumSymbols);
3060 
3061  remainingAmpduDuration -= mpduDuration;
3062  if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDU coming
3063  {
3064  mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
3065  }
3066 
3067  endOfMpduDuration += mpduDuration;
3068  m_endOfMpduEvents.push_back (Simulator::Schedule (endOfMpduDuration, &WifiPhy::EndOfMpdu, this, event, Create<WifiPsdu> (*mpdu, false), i, relativeStart, mpduDuration));
3069 
3070  //Prepare next iteration
3071  ++i;
3072  relativeStart += mpduDuration;
3073  mpdutype = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
3074  }
3075 }
3076 
3077 void
3078 WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex, Time relativeStart, Time mpduDuration)
3079 {
3080  NS_LOG_FUNCTION (this << *event << mpduIndex << relativeStart << mpduDuration);
3081  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
3082 
3083  std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, relativeStart, mpduDuration);
3084  NS_LOG_DEBUG ("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
3085  ", correct reception: " << rxInfo.first << ", Signal/Noise: " << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
3086 
3087  m_signalNoise = rxInfo.second;
3088  m_statusPerMpdu.push_back (rxInfo.first);
3089 
3090  if (rxInfo.first)
3091  {
3092  m_state->ContinueRxNextMpdu (Copy (psdu), m_interference.CalculateSnr (event), event->GetTxVector ());
3093  }
3094 }
3095 
3096 void
3098 {
3099  Time psduDuration = event->GetEndTime () - event->GetStartTime ();
3100  NS_LOG_FUNCTION (this << *event << psduDuration);
3102  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3103 
3104  Ptr<const WifiPsdu> psdu = event->GetPsdu ();
3105  if (psdu->GetNMpdus () == 1)
3106  {
3107  //We do not enter here for A-MPDU since this is done in WifiPhy::EndOfMpdu
3108  std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, NanoSeconds (0), psduDuration);
3109  m_signalNoise = rxInfo.second;
3110  m_statusPerMpdu.push_back (rxInfo.first);
3111  }
3112 
3113  NotifyRxEnd (psdu);
3114  double snr = m_interference.CalculateSnr (event);
3115  if (std::count (m_statusPerMpdu.begin (), m_statusPerMpdu.end (), true))
3116  {
3117  //At least one MPDU has been successfully received
3118  WifiTxVector txVector = event->GetTxVector ();
3120  m_state->SwitchFromRxEndOk (Copy (psdu), snr, txVector, m_statusPerMpdu);
3121  }
3122  else
3123  {
3124  m_state->SwitchFromRxEndError (Copy (psdu), snr);
3125  }
3126 
3128  m_currentEvent = 0;
3130 }
3131 
3132 std::pair<bool, SignalNoiseDbm>
3133 WifiPhy::GetReceptionStatus (Ptr<const WifiPsdu> psdu, Ptr<Event> event, Time relativeMpduStart, Time mpduDuration)
3134 {
3135  NS_LOG_FUNCTION (this << *psdu << *event << relativeMpduStart << mpduDuration);
3137  snrPer = m_interference.CalculatePayloadSnrPer (event, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
3138 
3139  NS_LOG_DEBUG ("mode=" << (event->GetTxVector ().GetMode ().GetDataRate (event->GetTxVector ())) <<
3140  ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << psdu->GetSize () <<
3141  ", relativeStart = " << relativeMpduStart.GetNanoSeconds () << "ns, duration = " << mpduDuration.GetNanoSeconds () << "ns");
3142 
3143  // There are two error checks: PER and receive error model check.
3144  // PER check models is typical for Wi-Fi and is based on signal modulation;
3145  // Receive error model is optional, if we have an error model and
3146  // it indicates that the packet is corrupt, drop the packet.
3147  SignalNoiseDbm signalNoise;
3148  signalNoise.signal = WToDbm (event->GetRxPowerW ());
3149  signalNoise.noise = WToDbm (event->GetRxPowerW () / snrPer.snr);
3150  if (m_random->GetValue () > snrPer.per &&
3151  !(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (psdu->GetPacket ()->Copy ())))
3152  {
3153  NS_LOG_DEBUG ("Reception succeeded: " << psdu);
3154  return std::make_pair (true, signalNoise);
3155  }
3156  else
3157  {
3158  NS_LOG_DEBUG ("Reception failed: " << psdu);
3159  return std::make_pair (false, signalNoise);
3160  }
3161 }
3162 
3163 void
3165 {
3166  NS_LOG_FUNCTION (this);
3168  {
3169  m_powerRestricted = false;
3170  }
3171 }
3172 
3173 void
3175 {
3176  NS_LOG_FUNCTION (this << *event);
3177  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3178  NS_ASSERT (!IsStateRx ());
3180  m_currentEvent = 0;
3182 }
3183 
3184 void
3186 {
3187  NS_LOG_FUNCTION (this);
3188  m_channelAccessRequested = true;
3189 }
3190 
3191 // Clause 15 rates (DSSS)
3192 
3193 WifiMode
3195 {
3196  static WifiMode mode =
3197  WifiModeFactory::CreateWifiMode ("DsssRate1Mbps",
3199  true,
3201  2);
3202  return mode;
3203 }
3204 
3205 WifiMode
3207 {
3208  static WifiMode mode =
3209  WifiModeFactory::CreateWifiMode ("DsssRate2Mbps",
3211  true,
3213  4);
3214  return mode;
3215 }
3216 
3217 
3218 // Clause 18 rates (HR/DSSS)
3219 
3220 WifiMode
3222 {
3223  static WifiMode mode =
3224  WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps",
3226  true,
3228  16);
3229  return mode;
3230 }
3231 
3232 WifiMode
3234 {
3235  static WifiMode mode =
3236  WifiModeFactory::CreateWifiMode ("DsssRate11Mbps",
3238  true,
3240  256);
3241  return mode;
3242 }
3243 
3244 
3245 // Clause 19.5 rates (ERP-OFDM)
3246 
3247 WifiMode
3249 {
3250  static WifiMode mode =
3251  WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps",
3253  true,
3255  2);
3256  return mode;
3257 }
3258 
3259 WifiMode
3261 {
3262  static WifiMode mode =
3263  WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps",
3265  false,
3267  2);
3268  return mode;
3269 }
3270 
3271 WifiMode
3273 {
3274  static WifiMode mode =
3275  WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps",
3277  true,
3279  4);
3280  return mode;
3281 }
3282 
3283 WifiMode
3285 {
3286  static WifiMode mode =
3287  WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps",
3289  false,
3291  4);
3292  return mode;
3293 }
3294 
3295 WifiMode
3297 {
3298  static WifiMode mode =
3299  WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps",
3301  true,
3303  16);
3304  return mode;
3305 }
3306 
3307 WifiMode
3309 {
3310  static WifiMode mode =
3311  WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps",
3313  false,
3315  16);
3316  return mode;
3317 }
3318 
3319 WifiMode
3321 {
3322  static WifiMode mode =
3323  WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps",
3325  false,
3327  64);
3328  return mode;
3329 }
3330 
3331 WifiMode
3333 {
3334  static WifiMode mode =
3335  WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps",
3337  false,
3339  64);
3340  return mode;
3341 }
3342 
3343 
3344 // Clause 17 rates (OFDM)
3345 
3346 WifiMode
3348 {
3349  static WifiMode mode =
3350  WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps",
3352  true,
3354  2);
3355  return mode;
3356 }
3357 
3358 WifiMode
3360 {
3361  static WifiMode mode =
3362  WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps",
3364  false,
3366  2);
3367  return mode;
3368 }
3369 
3370 WifiMode
3372 {
3373  static WifiMode mode =
3374  WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps",
3376  true,
3378  4);
3379  return mode;
3380 }
3381 
3382 WifiMode
3384 {
3385  static WifiMode mode =
3386  WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps",
3388  false,
3390  4);
3391  return mode;
3392 }
3393 
3394 WifiMode
3396 {
3397  static WifiMode mode =
3398  WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps",
3400  true,
3402  16);
3403  return mode;
3404 }
3405 
3406 WifiMode
3408 {
3409  static WifiMode mode =
3410  WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps",
3412  false,
3414  16);
3415  return mode;
3416 }
3417 
3418 WifiMode
3420 {
3421  static WifiMode mode =
3422  WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps",
3424  false,
3426  64);
3427  return mode;
3428 }
3429 
3430 WifiMode
3432 {
3433  static WifiMode mode =
3434  WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps",
3436  false,
3438  64);
3439  return mode;
3440 }
3441 
3442 
3443 // 10 MHz channel rates
3444 
3445 WifiMode
3447 {
3448  static WifiMode mode =
3449  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz",
3451  true,
3453  2);
3454  return mode;
3455 }
3456 
3457 WifiMode
3459 {
3460  static WifiMode mode =
3461  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz",
3463  false,
3465  2);
3466  return mode;
3467 }
3468 
3469 WifiMode
3471 {
3472  static WifiMode mode =
3473  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz",
3475  true,
3477  4);
3478  return mode;
3479 }
3480 
3481 WifiMode
3483 {
3484  static WifiMode mode =
3485  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz",
3487  false,
3489  4);
3490  return mode;
3491 }
3492 
3493 WifiMode
3495 {
3496  static WifiMode mode =
3497  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz",
3499  true,
3501  16);
3502  return mode;
3503 }
3504 
3505 WifiMode
3507 {
3508  static WifiMode mode =
3509  WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz",
3511  false,
3513  16);
3514  return mode;
3515 }
3516 
3517 WifiMode
3519 {
3520  static WifiMode mode =
3521  WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz",
3523  false,
3525  64);
3526  return mode;
3527 }
3528 
3529 WifiMode
3531 {
3532  static WifiMode mode =
3533  WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz",
3535  false,
3537  64);
3538  return mode;
3539 }
3540 
3541 
3542 // 5 MHz channel rates
3543 
3544 WifiMode
3546 {
3547  static WifiMode mode =
3548  WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz",
3550  true,
3552  2);
3553  return mode;
3554 }
3555 
3556 WifiMode
3558 {
3559  static WifiMode mode =
3560  WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz",
3562  false,
3564  2);
3565  return mode;
3566 }
3567 
3568 WifiMode
3570 {
3571  static WifiMode mode =
3572  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz",
3574  true,
3576  4);
3577  return mode;
3578 }
3579 
3580 WifiMode
3582 {
3583  static WifiMode mode =
3584  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz",
3586  false,
3588  4);
3589  return mode;
3590 }
3591 
3592 WifiMode
3594 {
3595  static WifiMode mode =
3596  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz",
3598  true,
3600  16);
3601  return mode;
3602 }
3603 
3604 WifiMode
3606 {
3607  static WifiMode mode =
3608  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz",
3610  false,
3612  16);
3613  return mode;
3614 }
3615 
3616 WifiMode
3618 {
3619  static WifiMode mode =
3620  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz",
3622  false,
3624  64);
3625  return mode;
3626 }
3627 
3628 WifiMode
3630 {
3631  static WifiMode mode =
3632  WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz",
3634  false,
3636  64);
3637  return mode;
3638 }
3639 
3640 
3641 // Clause 20
3642 
3643 WifiMode
3645 {
3646  static WifiMode mcs =
3648  return mcs;
3649 }
3650 
3651 WifiMode
3653 {
3654  static WifiMode mcs =
3656  return mcs;
3657 }
3658 
3659 WifiMode
3661 {
3662  static WifiMode mcs =
3664  return mcs;
3665 }
3666 
3667 WifiMode
3669 {
3670  static WifiMode mcs =
3672  return mcs;
3673 }
3674 
3675 WifiMode
3677 {
3678  static WifiMode mcs =
3680  return mcs;
3681 }
3682 
3683 WifiMode
3685 {
3686  static WifiMode mcs =
3688  return mcs;
3689 }
3690 
3691 WifiMode
3693 {
3694  static WifiMode mcs =
3696  return mcs;
3697 }
3698 
3699 WifiMode
3701 {
3702  static WifiMode mcs =
3704  return mcs;
3705 }
3706 
3707 WifiMode
3709 {
3710  static WifiMode mcs =
3712  return mcs;
3713 }
3714 
3715 WifiMode
3717 {
3718  static WifiMode mcs =
3720  return mcs;
3721 }
3722 
3723 WifiMode
3725 {
3726  static WifiMode mcs =
3728  return mcs;
3729 }
3730 
3731 WifiMode
3733 {
3734  static WifiMode mcs =
3736  return mcs;
3737 }
3738 
3739 WifiMode
3741 {
3742  static WifiMode mcs =
3744  return mcs;
3745 }
3746 
3747 WifiMode
3749 {
3750  static WifiMode mcs =
3752  return mcs;
3753 }
3754 
3755 WifiMode
3757 {
3758  static WifiMode mcs =
3760  return mcs;
3761 }
3762 
3763 WifiMode
3765 {
3766  static WifiMode mcs =
3768  return mcs;
3769 }
3770 
3771 WifiMode
3773 {
3774  static WifiMode mcs =
3776  return mcs;
3777 }
3778 
3779 WifiMode
3781 {
3782  static WifiMode mcs =
3784  return mcs;
3785 }
3786 
3787 WifiMode
3789 {
3790  static WifiMode mcs =
3792  return mcs;
3793 }
3794 
3795 WifiMode
3797 {
3798  static WifiMode mcs =
3800  return mcs;
3801 }
3802 
3803 WifiMode
3805 {
3806  static WifiMode mcs =
3808  return mcs;
3809 }
3810 
3811 WifiMode
3813 {
3814  static WifiMode mcs =
3816  return mcs;
3817 }
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 
3900 // Clause 22
3901 
3902 WifiMode
3904 {
3905  static WifiMode mcs =
3907  return mcs;
3908 }
3909 
3910 WifiMode
3912 {
3913  static WifiMode mcs =
3915  return mcs;
3916 }
3917 
3918 WifiMode
3920 {
3921  static WifiMode mcs =
3923  return mcs;
3924 }
3925 
3926 WifiMode
3928 {
3929  static WifiMode mcs =
3931  return mcs;
3932 }
3933 
3934 WifiMode
3936 {
3937  static WifiMode mcs =
3939  return mcs;
3940 }
3941 
3942 WifiMode
3944 {
3945  static WifiMode mcs =
3947  return mcs;
3948 }
3949 
3950 WifiMode
3952 {
3953  static WifiMode mcs =
3955  return mcs;
3956 }
3957 
3958 WifiMode
3960 {
3961  static WifiMode mcs =
3963  return mcs;
3964 }
3965 
3966 WifiMode
3968 {
3969  static WifiMode mcs =
3971  return mcs;
3972 }
3973 
3974 WifiMode
3976 {
3977  static WifiMode mcs =
3979  return mcs;
3980 }
3981 
3982 // Clause 26
3983 
3984 WifiMode
3986 {
3987  static WifiMode mcs =
3989  return mcs;
3990 }
3991 
3992 WifiMode
3994 {
3995  static WifiMode mcs =
3997  return mcs;
3998 }
3999 
4000 WifiMode
4002 {
4003  static WifiMode mcs =
4005  return mcs;
4006 }
4007 
4008 WifiMode
4010 {
4011  static WifiMode mcs =
4013  return mcs;
4014 }
4015 
4016 WifiMode
4018 {
4019  static WifiMode mcs =
4021  return mcs;
4022 }
4023 
4024 WifiMode
4026 {
4027  static WifiMode mcs =
4029  return mcs;
4030 }
4031 
4032 WifiMode
4034 {
4035  static WifiMode mcs =
4037  return mcs;
4038 }
4039 
4040 WifiMode
4042 {
4043  static WifiMode mcs =
4045  return mcs;
4046 }
4047 
4048 WifiMode
4050 {
4051  static WifiMode mcs =
4053  return mcs;
4054 }
4055 
4056 WifiMode
4058 {
4059  static WifiMode mcs =
4061  return mcs;
4062 }
4063 
4064 WifiMode
4066 {
4067  static WifiMode mcs =
4069  return mcs;
4070 }
4071 
4072 WifiMode
4074 {
4075  static WifiMode mcs =
4077  return mcs;
4078 }
4079 
4080 bool
4082 {
4083  for (uint8_t i = 0; i < GetNModes (); i++)
4084  {
4085  if (mode == GetMode (i))
4086  {
4087  return true;
4088  }
4089  }
4090  return false;
4091 }
4092 
4093 bool
4095 {
4096  WifiModulationClass modulation = mcs.GetModulationClass ();
4097  if (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
4098  || modulation == WIFI_MOD_CLASS_HE)
4099  {
4100  return IsMcsSupported (modulation, mcs.GetMcsValue ());
4101  }
4102  return false;
4103 }
4104 
4105 bool
4107 {
4108  if (m_mcsIndexMap.find (mc) == m_mcsIndexMap.end ())
4109  {
4110  return false;
4111  }
4112  if (m_mcsIndexMap.at (mc).find (mcs) == m_mcsIndexMap.at (mc).end ())
4113  {
4114  return false;
4115  }
4116  return true;
4117 }
4118 
4119 uint8_t
4121 {
4122  return static_cast<uint8_t> (m_deviceRateSet.size ());
4123 }
4124 
4125 WifiMode
4126 WifiPhy::GetMode (uint8_t mode) const
4127 {
4128  return m_deviceRateSet[mode];
4129 }
4130 
4131 uint8_t
4132 WifiPhy::GetNMcs (void) const
4133 {
4134  return static_cast<uint8_t> (m_deviceMcsSet.size ());
4135 }
4136 
4137 WifiMode
4138 WifiPhy::GetMcs (uint8_t mcs) const
4139 {
4140  return m_deviceMcsSet[mcs];
4141 }
4142 
4143 WifiMode
4144 WifiPhy::GetMcs (WifiModulationClass modulation, uint8_t mcs) const
4145 {
4146  NS_ASSERT_MSG (IsMcsSupported (modulation, mcs), "Unsupported MCS");
4147  uint8_t index = m_mcsIndexMap.at (modulation).at (mcs);
4148  NS_ASSERT (index < m_deviceMcsSet.size ());
4149  WifiMode mode = m_deviceMcsSet[index];
4150  NS_ASSERT (mode.GetModulationClass () == modulation);
4151  NS_ASSERT (mode.GetMcsValue () == mcs);
4152  return mode;
4153 }
4154 
4155 WifiMode
4156 WifiPhy::GetHtMcs (uint8_t mcs)
4157 {
4158  WifiMode mode;
4159  switch (mcs)
4160  {
4161  case 0:
4162  mode = WifiPhy::GetHtMcs0 ();
4163  break;
4164  case 1:
4165  mode = WifiPhy::GetHtMcs1 ();
4166  break;
4167  case 2:
4168  mode = WifiPhy::GetHtMcs2 ();
4169  break;
4170  case 3:
4171  mode = WifiPhy::GetHtMcs3 ();
4172  break;
4173  case 4:
4174  mode = WifiPhy::GetHtMcs4 ();
4175  break;
4176  case 5:
4177  mode = WifiPhy::GetHtMcs5 ();
4178  break;
4179  case 6:
4180  mode = WifiPhy::GetHtMcs6 ();
4181  break;
4182  case 7:
4183  mode = WifiPhy::GetHtMcs7 ();
4184  break;
4185  case 8:
4186  mode = WifiPhy::GetHtMcs8 ();
4187  break;
4188  case 9:
4189  mode = WifiPhy::GetHtMcs9 ();
4190  break;
4191  case 10:
4192  mode = WifiPhy::GetHtMcs10 ();
4193  break;
4194  case 11:
4195  mode = WifiPhy::GetHtMcs11 ();
4196  break;
4197  case 12:
4198  mode = WifiPhy::GetHtMcs12 ();
4199  break;
4200  case 13:
4201  mode = WifiPhy::GetHtMcs13 ();
4202  break;
4203  case 14:
4204  mode = WifiPhy::GetHtMcs14 ();
4205  break;
4206  case 15:
4207  mode = WifiPhy::GetHtMcs15 ();
4208  break;
4209  case 16:
4210  mode = WifiPhy::GetHtMcs16 ();
4211  break;
4212  case 17:
4213  mode = WifiPhy::GetHtMcs17 ();
4214  break;
4215  case 18:
4216  mode = WifiPhy::GetHtMcs18 ();
4217  break;
4218  case 19:
4219  mode = WifiPhy::GetHtMcs19 ();
4220  break;
4221  case 20:
4222  mode = WifiPhy::GetHtMcs20 ();
4223  break;
4224  case 21:
4225  mode = WifiPhy::GetHtMcs21 ();
4226  break;
4227  case 22:
4228  mode = WifiPhy::GetHtMcs22 ();
4229  break;
4230  case 23:
4231  mode = WifiPhy::GetHtMcs23 ();
4232  break;
4233  case 24:
4234  mode = WifiPhy::GetHtMcs24 ();
4235  break;
4236  case 25:
4237  mode = WifiPhy::GetHtMcs25 ();
4238  break;
4239  case 26:
4240  mode = WifiPhy::GetHtMcs26 ();
4241  break;
4242  case 27:
4243  mode = WifiPhy::GetHtMcs27 ();
4244  break;
4245  case 28:
4246  mode = WifiPhy::GetHtMcs28 ();
4247  break;
4248  case 29:
4249  mode = WifiPhy::GetHtMcs29 ();
4250  break;
4251  case 30:
4252  mode = WifiPhy::GetHtMcs30 ();
4253  break;
4254  case 31:
4255  mode = WifiPhy::GetHtMcs31 ();
4256  break;
4257  default:
4258  NS_ABORT_MSG ("Invalid HT MCS");
4259  break;
4260  }
4261  return mode;
4262 }
4263 
4264 WifiMode
4265 WifiPhy::GetVhtMcs (uint8_t mcs)
4266 {
4267  WifiMode mode;
4268  switch (mcs)
4269  {
4270  case 0:
4271  mode = WifiPhy::GetVhtMcs0 ();
4272  break;
4273  case 1:
4274  mode = WifiPhy::GetVhtMcs1 ();
4275  break;
4276  case 2:
4277  mode = WifiPhy::GetVhtMcs2 ();
4278  break;
4279  case 3:
4280  mode = WifiPhy::GetVhtMcs3 ();
4281  break;
4282  case 4:
4283  mode = WifiPhy::GetVhtMcs4 ();
4284  break;
4285  case 5:
4286  mode = WifiPhy::GetVhtMcs5 ();
4287  break;
4288  case 6:
4289  mode = WifiPhy::GetVhtMcs6 ();
4290  break;
4291  case 7:
4292  mode = WifiPhy::GetVhtMcs7 ();
4293  break;
4294  case 8:
4295  mode = WifiPhy::GetVhtMcs8 ();
4296  break;
4297  case 9:
4298  mode = WifiPhy::GetVhtMcs9 ();
4299  break;
4300  default:
4301  NS_ABORT_MSG ("Invalid VHT MCS");
4302  break;
4303  }
4304  return mode;
4305 }
4306 
4307 WifiMode
4308 WifiPhy::GetHeMcs (uint8_t mcs)
4309 {
4310  WifiMode mode;
4311  switch (mcs)
4312  {
4313  case 0:
4314  mode = WifiPhy::GetHeMcs0 ();
4315  break;
4316  case 1:
4317  mode = WifiPhy::GetHeMcs1 ();
4318  break;
4319  case 2:
4320  mode = WifiPhy::GetHeMcs2 ();
4321  break;
4322  case 3:
4323  mode = WifiPhy::GetHeMcs3 ();
4324  break;
4325  case 4:
4326  mode = WifiPhy::GetHeMcs4 ();
4327  break;
4328  case 5:
4329  mode = WifiPhy::GetHeMcs5 ();
4330  break;
4331  case 6:
4332  mode = WifiPhy::GetHeMcs6 ();
4333  break;
4334  case 7:
4335  mode = WifiPhy::GetHeMcs7 ();
4336  break;
4337  case 8:
4338  mode = WifiPhy::GetHeMcs8 ();
4339  break;
4340  case 9:
4341  mode = WifiPhy::GetHeMcs9 ();
4342  break;
4343  case 10:
4344  mode = WifiPhy::GetHeMcs10 ();
4345  break;
4346  case 11:
4347  mode = WifiPhy::GetHeMcs11 ();
4348  break;
4349  default:
4350  NS_ABORT_MSG ("Invalid HE MCS");
4351  break;
4352  }
4353  return mode;
4354 }
4355 
4356 bool
4358 {
4359  return m_state->IsStateCcaBusy ();
4360 }
4361 
4362 bool
4364 {
4365  return m_state->IsStateIdle ();
4366 }
4367 
4368 bool
4370 {
4371  return m_state->IsStateRx ();
4372 }
4373 
4374 bool
4376 {
4377  return m_state->IsStateTx ();
4378 }
4379 
4380 bool
4382 {
4383  return m_state->IsStateSwitching ();
4384 }
4385 
4386 bool
4388 {
4389  return m_state->IsStateSleep ();
4390 }
4391 
4392 bool
4394 {
4395  return m_state->IsStateOff ();
4396 }
4397 
4398 Time
4400 {
4401  return m_state->GetDelayUntilIdle ();
4402 }
4403 
4404 Time
4406 {
4407  return m_state->GetLastRxStartTime ();
4408 }
4409 
4410 Time
4412 {
4413  return m_state->GetLastRxEndTime ();
4414 }
4415 
4416 void
4418 {
4419  NS_LOG_FUNCTION (this);
4420  //We are here because we have received the first bit of a packet and we are
4421  //not going to be able to synchronize on it
4422  //In this model, CCA becomes busy when the aggregation of all signals as
4423  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
4424 
4426  if (!delayUntilCcaEnd.IsZero ())
4427  {
4428  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
4429  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
4430  }
4431 }
4432 
4433 void
4435 {
4436  NS_LOG_FUNCTION (this << reason);
4438  {
4440  }
4441  if (m_endPhyRxEvent.IsRunning ())
4442  {
4444  }
4445  if (m_endRxEvent.IsRunning ())
4446  {
4447  m_endRxEvent.Cancel ();
4448  }
4449  NotifyRxDrop (m_currentEvent->GetPsdu (), reason);
4451  if (reason == OBSS_PD_CCA_RESET)
4452  {
4453  m_state->SwitchFromRxAbort ();
4454  }
4455  m_currentEvent = 0;
4456 }
4457 
4458 void
4459 WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
4460 {
4461  NS_LOG_FUNCTION (this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
4462  m_powerRestricted = powerRestricted;
4463  m_txPowerMaxSiso = txPowerMaxSiso;
4464  m_txPowerMaxMimo = txPowerMaxMimo;
4465  NS_ASSERT ((m_currentEvent->GetEndTime () - Simulator::Now ()).IsPositive ());
4468 }
4469 
4470 double
4472 {
4474  if (!m_powerRestricted)
4475  {
4476  return GetPowerDbm (txVector.GetTxPowerLevel ());
4477  }
4478  else
4479  {
4480  if (txVector.GetNss () > 1)
4481  {
4482  return std::min (m_txPowerMaxMimo, GetPowerDbm (txVector.GetTxPowerLevel ()));
4483  }
4484  else
4485  {
4486  return std::min (m_txPowerMaxSiso, GetPowerDbm (txVector.GetTxPowerLevel ()));
4487  }
4488  }
4489 }
4490 
4491 void
4492 WifiPhy::StartRx (Ptr<Event> event, double rxPowerW)
4493 {
4494  NS_LOG_FUNCTION (this << *event << rxPowerW);
4495 
4496  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
4497  m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events
4498 
4500  {
4501  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4502  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4503  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4504  }
4505  else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW ()))
4506  {
4507  NS_LOG_DEBUG ("Received a stronger signal during preamble detection: drop current packet and switch to new packet");
4512  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4513  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4514  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4515  }
4516  else
4517  {
4518  NS_LOG_DEBUG ("Drop packet because RX is already decoding preamble");
4519  NotifyRxDrop (event->GetPsdu (), BUSY_DECODING_PREAMBLE);
4520  return;
4521  }
4522  m_currentEvent = event;
4523 }
4524 
4525 int64_t
4526 WifiPhy::AssignStreams (int64_t stream)
4527 {
4528  NS_LOG_FUNCTION (this << stream);
4529  m_random->SetStream (stream);
4530  return 1;
4531 }
4532 
4533 } //namespace ns3
4534 
4535 namespace {
4536 
4540 static class Constructor
4541 {
4542 public:
4544  {
4635  }
4636 } g_constructor;
4637 
4638 }
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:123
static WifiMode GetVhtMcs6()
Return MCS 6 from VHT MCS values.
Definition: wifi-phy.cc:3951
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:2592
static WifiMode GetOfdmRate9MbpsBW5MHz()
Return a WifiMode for OFDM at 9Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3605
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: wifi-phy.h:1939
Ptr< NetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:2091
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:3296
uint8_t GetNTxPower(void) const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:707
bool IsStateSwitching(void) const
Definition: wifi-phy.cc:4381
static WifiMode GetDsssRate11Mbps()
Return a WifiMode for DSSS at 11Mbps.
Definition: wifi-phy.cc:3233
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:967
bool IsStateOff(void) const
Definition: wifi-phy.cc:4393
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard(uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard) const
Lookup frequency/width pair for channelNumber/standard pair.
Definition: wifi-phy.cc:1605
double signal
in dBm
Definition: wifi-phy.h:118
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
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:4041
static WifiMode GetErpOfdmRate36Mbps()
Return a WifiMode for ERP-OFDM at 36Mbps.
Definition: wifi-phy.cc:3308
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:700
uint8_t m_channelNumber
Operating channel number.
Definition: wifi-phy.h:2086
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:2067
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
Definition: wifi-phy.cc:3967
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:54
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
double GetRxGain(void) const
Return the reception gain (dB).
Definition: wifi-phy.cc:733
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:4081
void AddSupportedChannelWidth(uint16_t width)
Definition: wifi-phy.cc:1584
static WifiMode GetOfdmRate9Mbps()
Return a WifiMode for OFDM at 9Mbps.
Definition: wifi-phy.cc:3359
double GetCcaEdThreshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:660
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
static WifiMode GetOfdmRate18MbpsBW10MHz()
Return a WifiMode for OFDM at 18Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3506
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:3530
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm > m_phyMonitorSniffRxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being received...
Definition: wifi-phy.h:1984
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:2066
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:4138
#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:3569
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Definition: wifi-phy.cc:3903
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted...
Definition: wifi-phy.cc:4434
void MaybeCcaBusyDuration(void)
Eventually switch to CCA busy.
Definition: wifi-phy.cc:2958
virtual ~WifiPhy()
Definition: wifi-phy.cc:539
static WifiMode GetDsssRate1Mbps()
Return a WifiMode for DSSS at 1Mbps.
Definition: wifi-phy.cc:3194
void ResumeFromOff(void)
Resume from off mode.
Definition: wifi-phy.cc:1869
Ptr< WifiPhyStateHelper > GetState(void) const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:576
void ResumeFromSleep(void)
Resume from sleep mode.
Definition: wifi-phy.cc:1839
#define min(a, b)
Definition: 80211b.c:42
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:2064
void ConfigureDefaultsForStandard(void)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:845
static WifiMode GetHeMcs5()
Return MCS 5 from HE MCS values.
Definition: wifi-phy.cc:4025
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1425
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:2099
static WifiMode GetErpOfdmRate18Mbps()
Return a WifiMode for ERP-OFDM at 18Mbps.
Definition: wifi-phy.cc:3284
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:713
void Configure80211ax(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard...
Definition: wifi-phy.cc:1248
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
static WifiMode GetHtMcs7()
Return MCS 7 from HT MCS values.
Definition: wifi-phy.cc:3700
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:640
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:1372
virtual void DoDispose(void)
Destructor implementation.
Definition: wifi-phy.cc:545
static WifiMode GetHePhyHeaderMode()
Definition: wifi-phy.cc:1912
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:1127
TracedCallback< Ptr< const WifiPsdu >, WifiTxVector, double > m_phyTxPsduBeginTrace
The trace source fired when a PSDU begins the transmission process on the medium. ...
Definition: wifi-phy.h:1915
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
Definition: wifi-phy.cc:3943
uint8_t GetNBssMembershipSelectors(void) const
The WifiPhy::NBssMembershipSelectors() method is used (e.g., by a WifiRemoteStationManager) to determ...
Definition: wifi-phy.cc:1572
The PHY layer is sleeping.
static WifiMode GetHtMcs22()
Return MCS 22 from HT MCS values.
Definition: wifi-phy.cc:3820
static WifiMode GetHtMcs14()
Return MCS 14 from HT MCS values.
Definition: wifi-phy.cc:3756
static WifiMode GetOfdmRate12Mbps()
Return a WifiMode for OFDM at 12Mbps.
Definition: wifi-phy.cc:3371
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1963
#define HE_PHY
Definition: wifi-phy.h:34
bool IsStateCcaBusy(void) const
Definition: wifi-phy.cc:4357
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:588
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:3078
static WifiMode GetHtMcs31()
Return MCS 31 from HT MCS values.
Definition: wifi-phy.cc:3892
static WifiMode GetHtMcs21()
Return MCS 21 from HT MCS values.
Definition: wifi-phy.cc:3812
#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:3884
#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:955
std::vector< uint8_t > m_bssMembershipSelectorSet
the BSS membership selector set
Definition: wifi-phy.h:2048
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< const WifiPsdu > psdu, Ptr< Event > event, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
Definition: wifi-phy.cc:3133
static WifiMode GetHtMcs10()
Return MCS 10 from HT MCS values.
Definition: wifi-phy.cc:3724
static Time GetPhyPreambleDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2178
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:739
static WifiMode GetHtMcs26()
Return MCS 26 from HT MCS values.
Definition: wifi-phy.cc:3852
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1955
static WifiMode GetOfdmRate1_5MbpsBW5MHz()
Return a WifiMode for OFDM at 1.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3545
static WifiMode GetHtMcs17()
Return MCS 17 from HT MCS values.
Definition: wifi-phy.cc:3780
static WifiMode GetHtMcs24()
Return MCS 24 from HT MCS values.
Definition: wifi-phy.cc:3836
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1749
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:3458
bool GetModeInitialized(void) const
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54Mbps.
Definition: wifi-phy.cc:3431
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:764
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: wifi-phy.h:2101
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:600
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:666
#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:332
static WifiMode GetHeMcs4()
Return MCS 4 from HE MCS values.
Definition: wifi-phy.cc:4017
uint8_t GetNess(void) const
void ConfigureHolland(void)
Configure WifiPhy with appropriate channel frequency and supported rates for Holland.
Definition: wifi-phy.cc:1098
bool IsStateIdle(void) const
Definition: wifi-phy.cc:4363
uint16_t GetGuardInterval(void) const
VHT PHY (Clause 22)
Definition: wifi-mode.h:60
The 5 GHz band.
Definition: wifi-phy-band.h:35
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
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:1970
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:48
std::pair< uint16_t, uint16_t > FrequencyWidthPair
A pair of a center frequency (MHz) and a channel width (MHz)
Definition: wifi-phy.h:719
static WifiMode GetHtMcs8()
Return MCS 8 from HT MCS values.
Definition: wifi-phy.cc:3708
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:2070
static WifiMode GetHtMcs18()
Return MCS 18 from HT MCS values.
Definition: wifi-phy.cc:3788
double GetTxPowerForTransmission(WifiTxVector txVector) const
Compute the transmit power (in dBm) for the next transmission.
Definition: wifi-phy.cc:4471
virtual void SetFrequency(uint16_t freq)
Definition: wifi-phy.cc:1438
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
Definition: wifi-phy.cc:3935
static WifiMode GetHtMcs27()
Return MCS 27 from HT MCS values.
Definition: wifi-phy.cc:3860
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:797
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:4459
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo > m_phyMonitorSniffTxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being transmitted...
Definition: wifi-phy.h:1998
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
static WifiMode GetOfdmRate36Mbps()
Return a WifiMode for OFDM at 36Mbps.
Definition: wifi-phy.cc:3407
uint8_t m_initialChannelNumber
Initial channel number.
Definition: wifi-phy.h:2087
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:2583
static WifiMode GetVhtMcs7()
Return MCS 7 from VHT MCS values.
Definition: wifi-phy.cc:3959
static WifiMode GetOfdmRate6MbpsBW5MHz()
Return a WifiMode for OFDM at 6Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3593
bool IsStateSleep(void) const
Definition: wifi-phy.cc:4387
void NotifyEndOfHePreamble(HePreambleParameters params)
Public method used to fire a EndOfHePreamble trace once both HE SIG fields have been received...
Definition: wifi-phy.cc:2657
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:3927
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the non-HT PHY header and accumulate all SNIR changes in the SNIR ...
MpduType
The type of an MPDU.
double GetRxSensitivity(void) const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:647
void NotifyTxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:2556
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:2044
mobility
Definition: third.py:108
uint16_t m_channelCenterFrequency
Center frequency in MHz.
Definition: wifi-phy.h:2053
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:752
static WifiMode GetHtMcs16()
Return MCS 16 from HT MCS values.
Definition: wifi-phy.cc:3772
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1515
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:2072
static WifiMode GetErpOfdmRate54Mbps()
Return a WifiMode for ERP-OFDM at 54Mbps.
Definition: wifi-phy.cc:3332
WifiPreamble GetPreambleType(void) const
static Time GetPhyHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1973
static WifiMode GetHtMcs29()
Return MCS 29 from HT MCS values.
Definition: wifi-phy.cc:3876
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: wifi-phy.cc:3041
static WifiMode GetHtMcs11()
Return MCS 11 from HT MCS values.
Definition: wifi-phy.cc:3732
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:4132
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:2083
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:132
uint8_t bssColor
BSS color.
Definition: wifi-phy.h:133
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:1732
static WifiMode GetHtMcs2()
Return MCS 2 from HT MCS values.
Definition: wifi-phy.cc:3660
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:2103
void StartReceiveHeader(Ptr< Event > event)
Start receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2738
static WifiMode GetHtPhyHeaderMode()
Definition: wifi-phy.cc:1900
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:2059
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band)
Definition: wifi-phy.cc:2539
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:2092
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:300
AttributeValue implementation for Time.
Definition: nstime.h:1342
void StartRx(Ptr< Event > event, double rxPowerW)
Starting receiving the PPDU after having detected the medium is idle or after a reception switch...
Definition: wifi-phy.cc:4492
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:2062
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1302
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:1931
Time GetEnergyDuration(double energyW) const
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:2074
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:2077
static WifiMode GetHeMcs3()
Return MCS 3 from HE MCS values.
Definition: wifi-phy.cc:4009
Hold an unsigned integer type.
Definition: uinteger.h:44
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, WifiCodeRate codingRate, uint16_t constellationSize)
Definition: wifi-mode.cc:657
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1752
static WifiMode GetHtMcs12()
Return MCS 12 from HT MCS values.
Definition: wifi-phy.cc:3740
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:2097
static WifiMode GetErpOfdmRate48Mbps()
Return a WifiMode for ERP-OFDM at 48Mbps.
Definition: wifi-phy.cc:3320
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:687
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:803
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:715
static WifiMode GetOfdmRate12MbpsBW10MHz()
Return a WifiMode for OFDM at 12Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3494
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:3185
WifiMode GetMode(void) const
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
Definition: wifi-phy.cc:4073
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:4308
HT PHY (Clause 20)
Definition: wifi-mode.h:58
Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:4399
static Time GetPayloadDuration(uint32_t size, WifiTxVector txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU)
Definition: wifi-phy.cc:2247
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:1746
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:2005
double CalculateSnr(WifiTxVector txVector, double ber) const
Definition: wifi-phy.cc:839
static WifiMode GetOfdmRate18Mbps()
Return a WifiMode for OFDM at 18Mbps.
Definition: wifi-phy.cc:3383
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:606
void SetOffMode(void)
Put in off mode.
Definition: wifi-phy.cc:1826
static WifiMode GetOfdmRate9MbpsBW10MHz()
Return a WifiMode for OFDM at 9Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3482
static WifiMode GetOfdmRate12MbpsBW5MHz()
Return a WifiMode for OFDM at 12Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3617
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:463
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:2096
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:815
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
Definition: wifi-phy.cc:3911
WifiPhyStandard GetPhyStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1432
EventId m_endPreambleDetectionEvent
the end of preamble detection event
Definition: wifi-phy.h:1750
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:3419
void NotifyRxBegin(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:2574
Time GetBlockAckTxTime(void) const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:985
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:783
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, double rxPowerW)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:2819
static WifiMode GetVhtPhyHeaderMode()
Definition: wifi-phy.cc:1906
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
Definition: wifi-phy.cc:4057
double f(double x, void *params)
Definition: 80211b.c:70
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
Definition: wifi-phy.cc:3644
Ptr< MobilityModel > GetMobility(void) const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:770
static Time GetPreambleDetectionDuration(void)
Definition: wifi-phy.cc:1918
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:2060
static Time GetPhySigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1988
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:790
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-phy.cc:288
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:833
OFDM PHY (Clause 17)
void ContinueReceiveHeader(Ptr< Event > event)
Continue receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2790
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:2051
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:809
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:391
void EraseEvents(void)
Erase all events.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1495
The PHY layer is IDLE.
uint8_t GetNumberOfAntennas(void) const
Definition: wifi-phy.cc:1529
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24Mbps.
Definition: wifi-phy.cc:3395
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:2565
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:2058
static WifiMode GetHeMcs1()
Return MCS 1 from HE MCS values.
Definition: wifi-phy.cc:3993
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:1908
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:3748
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
Definition: wifi-phy.cc:3985
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the HT PHY header and accumulate all SNIR changes in the SNIR vect...
std::map< ChannelNumberStandardPair, FrequencyWidthPair > ChannelToFrequencyWidthMap
channel to frequency width map typedef
Definition: wifi-phy.h:2082
static WifiMode GetHeMcs10()
Return MCS 10 from HE MCS values.
Definition: wifi-phy.cc:4065
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:3804
static WifiMode GetHeMcs2()
Return MCS 2 from HE MCS values.
Definition: wifi-phy.cc:4001
static Time GetPhyTrainingSymbolDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1924
static WifiMode GetHtMcs5()
Return MCS 5 from HT MCS values.
Definition: wifi-phy.cc:3684
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1554
bool GetShortPhyPreambleSupported(void) const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:746
double CalculateSnr(Ptr< Event > event) const
Calculate the SNIR for the event (starting from now until the event end).
double m_ccaEdThresholdW
Clear channel assessment (CCA) threshold in watts.
Definition: wifi-phy.h:2065
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
Definition: wifi-phy.cc:3919
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1613
Time GetPifs(void) const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:973
static WifiMode GetDsssRate5_5Mbps()
Return a WifiMode for DSSS at 5.5Mbps.
Definition: wifi-phy.cc:3221
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:979
void Configure80211ac(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard...
Definition: wifi-phy.cc:1228
virtual void DoInitialize(void)
Initialize() implementation.