1 /* packet-ieee80211-radio.c
2 * Routines for pseudo 802.11 header dissection and radio packet timing calculation
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * Copyright 2012 Parc Inc and Samsung Electronics
9 * Copyright 2015, 2016 & 2017 Cisco Inc
11 * Copied from README.developer
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include <wiretap/wtap.h>
21 #include <epan/prefs.h>
22 #include <epan/proto_data.h>
25 #include <epan/unit_strings.h>
27 #include "packet-ieee80211.h"
28 #include "packet-ieee80211-radio.h"
29 #include "packet-ieee80211-radiotap-defs.h"
32 void proto_register_ieee80211_radio(void);
33 void proto_reg_handoff_ieee80211_radio(void);
35 static dissector_handle_t wlan_radio_handle
;
36 static dissector_handle_t wlan_noqos_radio_handle
;
37 static dissector_handle_t ieee80211_handle
;
38 static dissector_handle_t ieee80211_noqos_handle
;
40 static int proto_wlan_radio
;
42 /* ************************************************************************* */
43 /* Header field info values for radio information */
44 /* ************************************************************************* */
45 static int hf_wlan_radio_phy
;
46 static int hf_wlan_radio_11_fhss_hop_set
;
47 static int hf_wlan_radio_11_fhss_hop_pattern
;
48 static int hf_wlan_radio_11_fhss_hop_index
;
49 static int hf_wlan_radio_11a_channel_type
;
50 static int hf_wlan_radio_11a_turbo_type
;
51 static int hf_wlan_radio_11g_mode
;
52 static int hf_wlan_radio_11n_mcs_index
;
53 static int hf_wlan_radio_11n_bandwidth
;
54 static int hf_wlan_radio_11n_short_gi
;
55 static int hf_wlan_radio_11n_greenfield
;
56 static int hf_wlan_radio_11n_fec
;
57 static int hf_wlan_radio_11n_stbc_streams
;
58 static int hf_wlan_radio_11n_ness
;
59 static int hf_wlan_radio_11ac_stbc
;
60 static int hf_wlan_radio_11ac_txop_ps_not_allowed
;
61 static int hf_wlan_radio_11ac_short_gi
;
62 static int hf_wlan_radio_11ac_short_gi_nsym_disambig
;
63 static int hf_wlan_radio_11ac_ldpc_extra_ofdm_symbol
;
64 static int hf_wlan_radio_11ac_beamformed
;
65 static int hf_wlan_radio_11ac_bandwidth
;
66 static int hf_wlan_radio_11ac_user
;
67 static int hf_wlan_radio_11ac_nsts
;
68 static int hf_wlan_radio_11ac_mcs
;
69 static int hf_wlan_radio_11ac_nss
;
70 static int hf_wlan_radio_11ac_fec
;
71 static int hf_wlan_radio_11ac_gid
;
72 static int hf_wlan_radio_11ac_p_aid
;
73 static int hf_wlan_radio_data_rate
;
74 static int hf_wlan_radio_channel
;
75 static int hf_wlan_radio_frequency
;
76 static int hf_wlan_radio_short_preamble
;
77 static int hf_wlan_radio_signal_percent
;
78 static int hf_wlan_radio_signal_db
;
79 static int hf_wlan_radio_signal_dbm
;
80 static int hf_wlan_radio_noise_percent
;
81 static int hf_wlan_radio_noise_db
;
82 static int hf_wlan_radio_noise_dbm
;
83 static int hf_wlan_radio_snr
;
84 static int hf_wlan_radio_timestamp
;
85 static int hf_wlan_last_part_of_a_mpdu
;
86 static int hf_wlan_a_mpdu_delim_crc_error
;
87 static int hf_wlan_a_mpdu_aggregate_id
;
88 static int hf_wlan_radio_duration
;
89 static int hf_wlan_radio_preamble
;
90 static int hf_wlan_radio_aggregate
;
91 static int hf_wlan_radio_aggregate_duration
;
92 static int hf_wlan_radio_ifs
;
93 static int hf_wlan_radio_start_tsf
;
94 static int hf_wlan_radio_end_tsf
;
95 static int hf_wlan_zero_length_psdu_type
;
96 static int hf_wlan_radio_11be_user
;
97 static int hf_wlan_radio_11be_sta_id
;
98 static int hf_wlan_radio_11be_mcs
;
99 static int hf_wlan_radio_11be_nsts
;
102 static expert_field ei_wlan_radio_assumed_short_preamble
;
103 static expert_field ei_wlan_radio_assumed_non_greenfield
;
104 static expert_field ei_wlan_radio_assumed_no_stbc
;
105 static expert_field ei_wlan_radio_assumed_no_extension_streams
;
106 static expert_field ei_wlan_radio_assumed_bcc_fec
;
107 static expert_field ei_wlan_radio_11be_num_users
;
109 static int wlan_radio_tap
;
110 static int wlan_radio_timeline_tap
;
113 static bool wlan_radio_always_short_preamble
;
114 static bool wlan_radio_tsf_at_end
= true;
115 static bool wlan_radio_timeline_enabled
;
117 static const value_string phy_vals
[] = {
118 { PHDR_802_11_PHY_11_FHSS
, "802.11 FHSS" },
119 { PHDR_802_11_PHY_11_IR
, "802.11 IR" },
120 { PHDR_802_11_PHY_11_DSSS
, "802.11 DSSS" },
121 { PHDR_802_11_PHY_11B
, "802.11b (HR/DSSS)" },
122 { PHDR_802_11_PHY_11A
, "802.11a (OFDM)" },
123 { PHDR_802_11_PHY_11G
, "802.11g (ERP)" },
124 { PHDR_802_11_PHY_11N
, "802.11n (HT)" },
125 { PHDR_802_11_PHY_11AC
, "802.11ac (VHT)" },
126 { PHDR_802_11_PHY_11AD
, "802.11ad (DMG)" },
127 { PHDR_802_11_PHY_11AH
, "802.11ah (S1G)" },
128 { PHDR_802_11_PHY_11AX
, "802.11ax (HE)" },
129 { PHDR_802_11_PHY_11BE
, "802.11be (EHT)" },
133 static const value_string channel_type_11a_vals
[] = {
134 { PHDR_802_11A_CHANNEL_TYPE_NORMAL
, "Normal" },
135 { PHDR_802_11A_CHANNEL_TYPE_HALF_CLOCKED
, "Half-clocked" },
136 { PHDR_802_11A_CHANNEL_TYPE_QUARTER_CLOCKED
, "Quarter-clocked" },
140 static const value_string turbo_type_11a_vals
[] = {
141 { PHDR_802_11A_TURBO_TYPE_NORMAL
, "Non-turbo" },
142 { PHDR_802_11A_TURBO_TYPE_TURBO
, "Turbo" },
143 { PHDR_802_11A_TURBO_TYPE_DYNAMIC_TURBO
, "Dynamic turbo" },
144 { PHDR_802_11A_TURBO_TYPE_STATIC_TURBO
, "Static turbo" },
148 static const value_string mode_11g_vals
[] = {
149 { PHDR_802_11G_MODE_NORMAL
, "None" },
150 { PHDR_802_11G_MODE_SUPER_G
, "Super G" },
154 static const value_string bandwidth_vals
[] = {
155 { PHDR_802_11_BANDWIDTH_20_MHZ
, "20 MHz" },
156 { PHDR_802_11_BANDWIDTH_40_MHZ
, "40 MHz" },
157 { PHDR_802_11_BANDWIDTH_20_20L
, "20 MHz + 20 MHz lower" },
158 { PHDR_802_11_BANDWIDTH_20_20U
, "20 MHz + 20 MHz upper" },
159 { PHDR_802_11_BANDWIDTH_80_MHZ
, "80 MHz" },
160 { PHDR_802_11_BANDWIDTH_40_40L
, "40 MHz + 40 MHz lower" },
161 { PHDR_802_11_BANDWIDTH_40_40U
, "40 MHz + 40 MHz upper" },
162 { PHDR_802_11_BANDWIDTH_20LL
, "20 MHz, channel 1/4" },
163 { PHDR_802_11_BANDWIDTH_20LU
, "20 MHz, channel 2/4" },
164 { PHDR_802_11_BANDWIDTH_20UL
, "20 MHz, channel 3/4" },
165 { PHDR_802_11_BANDWIDTH_20UU
, "20 MHz, channel 4/4" },
166 { PHDR_802_11_BANDWIDTH_160_MHZ
, "160 MHz" },
167 { PHDR_802_11_BANDWIDTH_80_80L
, "80 MHz + 80 MHz lower" },
168 { PHDR_802_11_BANDWIDTH_80_80U
, "80 MHz + 80 MHz upper" },
169 { PHDR_802_11_BANDWIDTH_40LL
, "40 MHz, channel 1/4" },
170 { PHDR_802_11_BANDWIDTH_40LU
, "40 MHz, channel 2/4" },
171 { PHDR_802_11_BANDWIDTH_40UL
, "40 MHz, channel 3/4" },
172 { PHDR_802_11_BANDWIDTH_40UU
, "40 MHz, channel 4/4" },
173 { PHDR_802_11_BANDWIDTH_20LLL
, "20 MHz, channel 1/8" },
174 { PHDR_802_11_BANDWIDTH_20LLU
, "20 MHz, channel 2/8" },
175 { PHDR_802_11_BANDWIDTH_20LUL
, "20 MHz, channel 3/8" },
176 { PHDR_802_11_BANDWIDTH_20LUU
, "20 MHz, channel 4/8" },
177 { PHDR_802_11_BANDWIDTH_20ULL
, "20 MHz, channel 5/8" },
178 { PHDR_802_11_BANDWIDTH_20ULU
, "20 MHz, channel 6/8" },
179 { PHDR_802_11_BANDWIDTH_20UUL
, "20 MHz, channel 7/8" },
180 { PHDR_802_11_BANDWIDTH_20UUU
, "20 MHz, channel 8/8" },
184 static const value_string fec_vals
[] = {
190 static const value_string zero_length_psdu_vals
[] = {
191 { 0, "sounding PPDU" },
192 { 1, "data not captured" },
193 { 255, "vendor-specific" },
197 * Lookup for the MCS index (0-76)
198 * returning the number of data bits per symbol
199 * assumes 52 subcarriers (20MHz)
200 * symbols are 4us for long guard interval, 3.6us for short guard interval
201 * Note: MCS 32 is special - only valid for 40Mhz channel.
203 WS_DLL_PUBLIC_DEF
const uint16_t ieee80211_ht_Dbps
[MAX_MCS_INDEX
+1] = {
204 /* MCS 0 - 1 stream */
205 26, 52, 78, 104, 156, 208, 234, 260,
207 /* MCS 8 - 2 stream */
208 52, 104, 156, 208, 312, 416, 468, 520,
210 /* MCS 16 - 3 stream */
211 78, 156, 234, 312, 468, 624, 702, 780,
213 /* MCS 24 - 4 stream */
214 104, 208, 312, 416, 624, 832, 936, 1040,
216 /* MCS 32 - 1 stream */
217 12, /* only valid for 40Mhz - 11a/g DUP mode */
219 /* MCS 33 - 2 stream */
220 156, 208, 260, 234, 312, 390,
222 /* MCS 39 - 3 stream */
223 208, 260, 260, 312, 364, 364, 416, 312, 390, 390, 468, 546, 546, 624,
225 /* MCS 53 - 4 stream */
226 260, 312, 364, 312, 364, 416, 468, 416, 468, 520, 520, 572,
227 390, 468, 546, 468, 546, 624, 702, 624, 702, 780, 780, 858
231 * Calculates data rate corresponding to a given 802.11n MCS index,
232 * bandwidth, and guard interval.
234 float ieee80211_htrate(int mcs_index
, bool bandwidth
, bool short_gi
)
236 return (float)(ieee80211_ht_Dbps
[mcs_index
] * (bandwidth
? 108 : 52) / 52.0 / (short_gi
? 3.6 : 4.0));
239 static const uint8_t ieee80211_ht_streams
[MAX_MCS_INDEX
+1] = {
240 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,
241 1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,
242 4,4,4,4,4,4,4,4,4,4,4,4,4
245 static const uint8_t ieee80211_ht_Nes
[MAX_MCS_INDEX
+1] = {
246 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
247 1,1,1,1,1,2,2,2, 1,1,1,1,2,2,2,2,
250 1,1,1,1,1,1,1,1,1,1,1,1,1,1,
251 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2
254 #define MAX_MCS_VHT_INDEX 9
257 * Maps a VHT bandwidth index to ieee80211_vhtinfo.rates index.
259 static const int ieee80211_vht_bw2rate_index
[] = {
261 /* 40Mhz total */ 1, 0, 0,
262 /* 80Mhz total */ 2, 1, 1, 0, 0, 0, 0,
263 /* 160Mhz total */ 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
267 const char *modulation
;
268 const char *coding_rate
;
269 float data_bits_per_symbol
; /* assuming 20MHz / 52 subcarriers */
272 #define EHT_MAX_MCS 14
273 static const struct mcs_info ieee80211_mcsinfo
[EHT_MAX_MCS
] = {
275 { "BPSK", "1/2", 26 },
277 { "QPSK", "1/2", 52 },
279 { "QPSK", "3/4", 78 },
281 { "16-QAM", "1/2", 104 },
283 { "16-QAM", "3/4", 156 },
285 { "64-QAM", "2/3", 208 },
287 { "64-QAM", "3/4", 234 },
289 { "64-QAM", "5/6", 260 },
291 { "256-QAM", "3/4", 312 },
293 { "256-QAM", "5/6", (float)(1040/3.0) },
295 { "1024-QAM", "3/4", 390 },
297 { "1024-QAM", "5/6", (float)(1300/3.0) },
299 { "4096-QAM", "3/4", 468 },
301 { "4096-QAM", "5/6", 520 }
304 /* map a bandwidth index to the number of data subcarriers */
305 static const unsigned subcarriers
[4] = { 52, 108, 234, 468 };
307 #define MAX_VHT_NSS 8
309 struct mcs_vht_valid
{
310 bool valid
[4][MAX_VHT_NSS
]; /* indexed by bandwidth and NSS-1 */
313 static const struct mcs_vht_valid ieee80211_vhtvalid
[MAX_MCS_VHT_INDEX
+1] = {
316 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
317 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
318 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
319 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
324 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
325 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
326 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
327 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
332 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
333 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
334 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
335 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
340 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
341 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
342 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
343 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
348 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
349 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
350 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
351 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
356 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
357 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
358 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
359 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
364 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
365 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
366 /* 80 Mhz */ { true, true, false, true, true, true, false, true },
367 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
372 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
373 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
374 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
375 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
380 { /* 20 Mhz */ { true, true, true, true, true, true, true, true },
381 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
382 /* 80 Mhz */ { true, true, true, true, true, true, true, true },
383 /* 160 Mhz */ { true, true, true, true, true, true, true, true },
388 { /* 20 Mhz */ { false, false, true, false, false, true, false, false },
389 /* 40 Mhz */ { true, true, true, true, true, true, true, true },
390 /* 80 Mhz */ { true, true, true, true, true, false, true, true },
391 /* 160 Mhz */ { true, true, false, true, true, true, true, true },
397 * Calculates data rate corresponding to a given 802.11ac MCS index,
398 * bandwidth, and guard interval.
400 static float ieee80211_vhtrate(int mcs_index
, unsigned bandwidth_index
, bool short_gi
)
402 return (float)(ieee80211_mcsinfo
[mcs_index
].data_bits_per_symbol
* subcarriers
[bandwidth_index
] / (short_gi
? 3.6 : 4.0) / 52.0);
406 * HE SU OFDM MCS rate table converted from http://mcsindex.com/
407 * indexed by (NSTS,MCS,BW,GI)
409 #define HE_MAX_NSTS 8
410 #define HE_MAX_MCS 12
411 #define HE_SU_MAX_BW 4
413 static float he_ofdm_tab
[HE_MAX_NSTS
][HE_MAX_MCS
][HE_SU_MAX_BW
][HE_MAX_GI
] = {
415 {{ 8.6f
, 8.1f
, 7.3f
},{ 17.2f
, 16.3f
, 14.6f
},{ 36.0f
, 34.0f
, 30.6f
},{ 72.1f
, 68.1f
, 61.3f
}},
416 {{ 17.2f
, 16.3f
, 14.6f
},{ 34.4f
, 32.5f
, 29.3f
},{ 72.1f
, 68.1f
, 61.3f
},{ 144.1f
, 136.1f
, 122.5f
}},
417 {{ 25.8f
, 24.4f
, 21.9f
},{ 51.6f
, 48.8f
, 43.9f
},{ 108.1f
, 102.1f
, 91.9f
},{ 216.2f
, 204.2f
, 183.8f
}},
418 {{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
},{ 288.2f
, 272.2f
, 245.0f
}},
419 {{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
}},
420 {{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
421 {{ 77.4f
, 73.1f
, 65.8f
},{ 154.9f
, 146.3f
, 131.6f
},{ 324.3f
, 306.3f
, 275.6f
},{ 648.5f
, 612.5f
, 551.3f
}},
422 {{ 86.0f
, 81.3f
, 73.1f
},{ 172.1f
, 162.5f
, 146.3f
},{ 360.3f
, 340.3f
, 306.3f
},{ 720.6f
, 680.6f
, 612.5f
}},
423 {{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
424 {{ 114.7f
, 108.3f
, 97.5f
},{ 229.4f
, 216.7f
, 195.0f
},{ 480.4f
, 453.7f
, 408.3f
},{ 960.8f
, 907.4f
, 816.7f
}},
425 {{ 129.0f
, 121.9f
, 109.7f
},{ 258.1f
, 243.8f
, 219.4f
},{ 540.4f
, 510.4f
, 459.4f
},{ 1080.9f
, 1020.8f
, 918.8f
}},
426 {{ 143.4f
, 135.4f
, 121.9f
},{ 286.8f
, 270.8f
, 243.8f
},{ 600.5f
, 567.1f
, 510.4f
},{ 1201.0f
, 1134.3f
, 1020.8f
}}
428 {{ 17.2f
, 16.3f
, 14.6f
},{ 34.4f
, 32.5f
, 29.3f
},{ 72.1f
, 68.1f
, 61.3f
},{ 144.1f
, 136.1f
, 122.5f
}},
429 {{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
},{ 288.2f
, 272.2f
, 245.0f
}},
430 {{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
}},
431 {{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
432 {{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
433 {{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
434 {{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
435 {{ 172.1f
, 162.5f
, 146.3f
},{ 344.1f
, 325.0f
, 292.5f
},{ 720.6f
, 680.6f
, 612.5f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
436 {{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
437 {{ 229.4f
, 216.7f
, 195.0f
},{ 458.8f
, 433.3f
, 390.0f
},{ 960.8f
, 907.4f
, 816.7f
},{ 1921.6f
, 1814.8f
, 1633.3f
}},
438 {{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
439 {{ 286.8f
, 270.8f
, 243.8f
},{ 573.5f
, 541.7f
, 487.5f
},{ 1201.0f
, 1134.3f
, 1020.8f
},{ 2402.0f
, 2268.5f
, 2041.7f
}}
441 {{ 25.8f
, 24.4f
, 21.9f
},{ 51.6f
, 48.8f
, 43.9f
},{ 108.1f
, 102.1f
, 91.9f
},{ 216.2f
, 204.2f
, 183.8f
}},
442 {{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
}},
443 {{ 77.4f
, 73.1f
, 65.8f
},{ 154.9f
, 146.3f
, 131.6f
},{ 324.3f
, 306.3f
, 275.6f
},{ 648.5f
, 612.5f
, 551.3f
}},
444 {{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
445 {{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
446 {{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
447 {{ 232.3f
, 219.4f
, 197.4f
},{ 464.6f
, 438.8f
, 394.9f
},{ 972.8f
, 918.8f
, 826.9f
},{ 1945.6f
, 1837.5f
, 1653.8f
}},
448 {{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
449 {{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
450 {{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}},
451 {{ 387.1f
, 365.6f
, 329.1f
},{ 774.3f
, 731.3f
, 658.1f
},{ 1621.3f
, 1531.3f
, 1378.1f
},{ 3242.6f
, 3062.5f
, 2756.3f
}},
452 {{ 430.1f
, 406.3f
, 365.6f
},{ 860.3f
, 812.5f
, 731.3f
},{ 1801.5f
, 1701.4f
, 1531.3f
},{ 3602.9f
, 3402.8f
, 3062.5f
}}
454 {{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
},{ 288.2f
, 272.2f
, 245.0f
}},
455 {{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
456 {{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
457 {{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
458 {{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
459 {{ 275.3f
, 260.0f
, 234.0f
},{ 550.6f
, 520.0f
, 468.0f
},{ 1152.9f
, 1088.9f
, 980.0f
},{ 2305.9f
, 2177.8f
, 1960.0f
}},
460 {{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
461 {{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}},
462 {{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
},{ 3458.8f
, 3266.7f
, 2940.0f
}},
463 {{ 458.8f
, 433.3f
, 390.0f
},{ 917.6f
, 866.7f
, 780.0f
},{ 1921.6f
, 1814.8f
, 1633.3f
},{ 3843.1f
, 3629.6f
, 3266.7f
}},
464 {{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
},{ 4323.5f
, 4083.3f
, 3675.0f
}},
465 {{ 573.5f
, 541.7f
, 487.5f
},{ 1147.1f
, 1083.3f
, 975.0f
},{ 2402.0f
, 2268.5f
, 2041.7f
},{ 4803.9f
, 4537.0f
, 4083.3f
}}
467 {{ 43.0f
, 40.6f
, 36.6f
},{ 86.0f
, 81.3f
, 73.1f
},{ 180.1f
, 170.1f
, 153.1f
},{ 360.3f
, 340.3f
, 306.3f
}},
468 {{ 86.0f
, 81.3f
, 73.1f
},{ 172.1f
, 162.5f
, 146.3f
},{ 360.3f
, 340.3f
, 306.3f
},{ 720.6f
, 680.6f
, 612.5f
}},
469 {{ 129.0f
, 121.9f
, 109.7f
},{ 258.1f
, 243.8f
, 219.4f
},{ 540.4f
, 510.4f
, 459.4f
},{ 1080.9f
, 1020.8f
, 918.8f
}},
470 {{ 172.1f
, 162.5f
, 146.3f
},{ 344.1f
, 325.0f
, 292.5f
},{ 720.6f
, 680.6f
, 612.5f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
471 {{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
472 {{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}},
473 {{ 387.1f
, 365.6f
, 329.1f
},{ 774.3f
, 731.3f
, 658.1f
},{ 1621.3f
, 1531.3f
, 1378.1f
},{ 3242.6f
, 3062.5f
, 2756.3f
}},
474 {{ 430.1f
, 406.3f
, 365.6f
},{ 860.3f
, 812.5f
, 731.3f
},{ 1801.5f
, 1701.4f
, 1531.3f
},{ 3602.9f
, 3402.8f
, 3062.5f
}},
475 {{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
},{ 4323.5f
, 4083.3f
, 3675.0f
}},
476 {{ 573.5f
, 541.7f
, 487.5f
},{ 1147.1f
, 1083.3f
, 975.0f
},{ 2402.0f
, 2268.5f
, 2041.7f
},{ 4803.9f
, 4537.0f
, 4083.3f
}},
477 {{ 645.2f
, 609.4f
, 548.4f
},{ 1290.4f
, 1218.8f
, 1096.9f
},{ 2702.2f
, 2552.1f
, 2296.9f
},{ 5404.4f
, 5104.2f
, 4593.8f
}},
478 {{ 716.9f
, 677.1f
, 609.4f
},{ 1433.8f
, 1354.2f
, 1218.8f
},{ 3002.5f
, 2835.6f
, 2552.1f
},{ 6004.9f
, 5671.3f
, 5104.2f
}}
480 {{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
}},
481 {{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
482 {{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
483 {{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
484 {{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
485 {{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
},{ 3458.8f
, 3266.7f
, 2940.0f
}},
486 {{ 464.6f
, 438.8f
, 394.9f
},{ 929.1f
, 877.5f
, 789.8f
},{ 1945.6f
, 1837.5f
, 1653.8f
},{ 3891.2f
, 3675.0f
, 3307.5f
}},
487 {{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
},{ 4323.5f
, 4083.3f
, 3675.0f
}},
488 {{ 619.4f
, 585.0f
, 526.5f
},{ 1238.8f
, 1170.0f
, 1053.0f
},{ 2594.1f
, 2450.0f
, 2205.0f
},{ 5188.2f
, 4900.0f
, 4410.0f
}},
489 {{ 688.2f
, 650.0f
, 585.0f
},{ 1376.5f
, 1300.0f
, 1170.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
},{ 5764.7f
, 5444.4f
, 4900.0f
}},
490 {{ 774.3f
, 731.3f
, 658.1f
},{ 1548.5f
, 1462.5f
, 1316.3f
},{ 3242.6f
, 3062.5f
, 2756.3f
},{ 6485.3f
, 6125.0f
, 5512.5f
}},
491 {{ 860.3f
, 812.5f
, 731.3f
},{ 1720.6f
, 1625.0f
, 1462.5f
},{ 3602.9f
, 3402.8f
, 3062.5f
},{ 7205.9f
, 6805.6f
, 6125.0f
}}
493 {{ 60.2f
, 56.9f
, 51.2f
},{ 120.4f
, 113.8f
, 102.4f
},{ 252.2f
, 238.2f
, 214.4f
},{ 504.4f
, 476.4f
, 428.8f
}},
494 {{ 120.4f
, 113.8f
, 102.4f
},{ 240.9f
, 227.5f
, 204.8f
},{ 504.4f
, 476.4f
, 428.8f
},{ 1008.8f
, 952.8f
, 857.5f
}},
495 {{ 180.7f
, 170.6f
, 153.6f
},{ 361.3f
, 341.3f
, 307.1f
},{ 756.6f
, 714.6f
, 643.1f
},{ 1513.2f
, 1429.2f
, 1286.3f
}},
496 {{ 240.9f
, 227.5f
, 204.8f
},{ 481.8f
, 455.0f
, 409.5f
},{ 1008.8f
, 952.8f
, 857.5f
},{ 2017.6f
, 1905.6f
, 1715.0f
}},
497 {{ 361.3f
, 341.3f
, 307.1f
},{ 722.6f
, 682.5f
, 614.3f
},{ 1513.2f
, 1429.2f
, 1286.3f
},{ 3026.5f
, 2858.3f
, 2572.5f
}},
498 {{ 481.8f
, 455.0f
, 409.5f
},{ 963.5f
, 910.0f
, 819.0f
},{ 2017.6f
, 1905.6f
, 1715.0f
},{ 4035.3f
, 3811.1f
, 3430.0f
}},
499 {{ 542.0f
, 511.9f
, 460.7f
},{ 1084.0f
, 1023.8f
, 921.4f
},{ 2269.9f
, 2143.8f
, 1929.4f
},{ 4539.7f
, 4287.5f
, 3858.8f
}},
500 {{ 602.2f
, 568.8f
, 511.9f
},{ 1204.4f
, 1137.5f
, 1023.8f
},{ 2522.1f
, 2381.9f
, 2143.8f
},{ 5044.1f
, 4763.9f
, 4287.5f
}},
501 {{ 722.6f
, 682.5f
, 614.3f
},{ 1445.3f
, 1365.0f
, 1228.5f
},{ 3026.5f
, 2858.3f
, 2572.5f
},{ 6052.9f
, 5716.7f
, 5145.0f
}},
502 {{ 802.9f
, 758.3f
, 682.5f
},{ 1605.9f
, 1516.7f
, 1365.0f
},{ 3362.7f
, 3175.9f
, 2858.3f
},{ 6725.5f
, 6351.9f
, 5716.7f
}},
503 {{ 903.3f
, 853.1f
, 767.8f
},{ 1806.6f
, 1706.3f
, 1535.6f
},{ 3783.1f
, 3572.9f
, 3215.6f
},{ 7566.2f
, 7145.8f
, 6431.3f
}},
504 {{ 1003.7f
, 947.9f
, 853.1f
},{ 2007.4f
, 1895.8f
, 1706.3f
},{ 4203.4f
, 3969.9f
, 3572.9f
},{ 8406.9f
, 7939.8f
, 7145.8f
}}
506 {{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
507 {{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
508 {{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
509 {{ 275.3f
, 260.0f
, 234.0f
},{ 550.6f
, 520.0f
, 468.0f
},{ 1152.9f
, 1088.9f
, 980.0f
},{ 2305.9f
, 2177.8f
, 1960.0f
}},
510 {{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
},{ 3458.8f
, 3266.7f
, 2940.0f
}},
511 {{ 550.6f
, 520.0f
, 468.0f
},{ 1101.2f
, 1040.0f
, 936.0f
},{ 2305.9f
, 2177.8f
, 1960.0f
},{ 4611.8f
, 4355.6f
, 3920.0f
}},
512 {{ 619.4f
, 585.0f
, 526.5f
},{ 1238.8f
, 1170.0f
, 1053.0f
},{ 2594.1f
, 2450.0f
, 2205.0f
},{ 5188.2f
, 4900.0f
, 4410.0f
}},
513 {{ 688.2f
, 650.0f
, 585.0f
},{ 1376.5f
, 1300.0f
, 1170.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
},{ 5764.7f
, 5444.4f
, 4900.0f
}},
514 {{ 825.9f
, 780.0f
, 702.0f
},{ 1651.8f
, 1560.0f
, 1404.0f
},{ 3458.8f
, 3266.7f
, 2940.0f
},{ 6917.6f
, 6533.3f
, 5880.0f
}},
515 {{ 917.6f
, 866.7f
, 780.0f
},{ 1835.3f
, 1733.3f
, 1560.0f
},{ 3843.1f
, 3629.6f
, 3266.7f
},{ 7686.3f
, 7259.3f
, 6533.3f
}},
516 {{ 1032.4f
, 975.0f
, 877.5f
},{ 2064.7f
, 1950.0f
, 1755.0f
},{ 4323.5f
, 4083.3f
, 3675.0f
},{ 8647.1f
, 8166.7f
, 7350.0f
}},
517 {{ 1147.1f
, 1083.3f
, 975.0f
},{ 2294.1f
, 2166.7f
, 1950.0f
},{ 4803.9f
, 4537.0f
, 4083.3f
},{ 9607.8f
, 9074.1f
, 8166.7f
}}
522 * Calculates 802.11ax HE SU data rate corresponding to a given 802.11ax MCS index,
523 * bandwidth, and guard interval.
525 static float ieee80211_he_ofdm_rate(unsigned nsts
, unsigned mcs
, unsigned bw
, unsigned gi
)
528 if ( ((nsts
-1) < HE_MAX_NSTS
) && (mcs
< HE_MAX_MCS
) && ( bw
< HE_SU_MAX_BW
) && ( gi
< HE_MAX_GI
) ) {
529 rate
= he_ofdm_tab
[nsts
-1][mcs
][bw
][gi
];
536 * HE MU OFDMA MCS rate table converted from http://mcsindex.com/
537 * indexed by (NSTS,MCS,RU,GI)
539 #define HE_MU_MAX_RU 6
540 static float he_mu_ofdma_tab
[HE_MAX_NSTS
][HE_MAX_MCS
][HE_MU_MAX_RU
][HE_MAX_GI
] = {
542 {{ 0.9f
, 0.8f
, 0.8f
},{ 1.8f
, 1.7f
, 1.5f
},{ 3.8f
, 3.5f
, 3.2f
},{ 8.6f
, 8.1f
, 7.3f
},{ 17.2f
, 16.3f
, 14.6f
},{ 36.0f
, 34.0f
, 30.6f
}},
543 {{ 1.8f
, 1.7f
, 1.5f
},{ 3.5f
, 3.3f
, 3.0f
},{ 7.5f
, 7.1f
, 6.4f
},{ 17.2f
, 16.3f
, 14.6f
},{ 34.4f
, 32.5f
, 29.3f
},{ 72.1f
, 68.1f
, 61.3f
}},
544 {{ 2.6f
, 2.5f
, 2.3f
},{ 5.3f
, 5.0f
, 4.5f
},{ 11.3f
, 10.6f
, 9.6f
},{ 25.8f
, 24.4f
, 21.9f
},{ 51.6f
, 48.8f
, 43.9f
},{ 108.1f
, 102.1f
, 91.9f
}},
545 {{ 3.5f
, 3.3f
, 3.0f
},{ 7.1f
, 6.7f
, 6.0f
},{ 15.0f
, 14.2f
, 12.8f
},{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
}},
546 {{ 5.3f
, 5.0f
, 4.5f
},{ 10.6f
, 10.0f
, 9.0f
},{ 22.5f
, 21.3f
, 19.1f
},{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
}},
547 {{ 7.1f
, 6.7f
, 6.0f
},{ 14.1f
, 13.3f
, 12.0f
},{ 30.0f
, 28.3f
, 25.5f
},{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
}},
548 {{ 7.9f
, 7.5f
, 6.8f
},{ 15.9f
, 15.0f
, 13.5f
},{ 33.8f
, 31.9f
, 28.7f
},{ 77.4f
, 73.1f
, 65.8f
},{ 154.9f
, 146.3f
, 131.6f
},{ 324.3f
, 306.3f
, 275.6f
}},
549 {{ 8.8f
, 8.3f
, 7.5f
},{ 17.6f
, 16.7f
, 15.0f
},{ 37.5f
, 35.4f
, 31.9f
},{ 86.0f
, 81.3f
, 73.1f
},{ 172.1f
, 162.5f
, 146.3f
},{ 360.3f
, 340.3f
, 306.3f
}},
550 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
}},
551 {{ 11.8f
, 11.1f
, 10.0f
},{ 23.5f
, 22.2f
, 20.0f
},{ 50.0f
, 47.2f
, 42.5f
},{ 114.7f
, 108.3f
, 97.5f
},{ 229.4f
, 216.7f
, 195.0f
},{ 480.4f
, 453.7f
, 408.3f
}},
552 {{ 13.2f
, 12.5f
, 11.3f
},{ 26.5f
, 25.0f
, 22.5f
},{ 56.3f
, 53.1f
, 47.8f
},{ 129.0f
, 121.9f
, 109.7f
},{ 258.1f
, 243.8f
, 219.4f
},{ 540.4f
, 510.4f
, 459.4f
}},
553 {{ 14.7f
, 13.9f
, 12.5f
},{ 29.4f
, 27.8f
, 25.0f
},{ 62.5f
, 59.0f
, 53.1f
},{ 143.4f
, 135.4f
, 121.9f
},{ 286.8f
, 270.8f
, 243.8f
},{ 600.5f
, 567.1f
, 510.4f
}}
555 {{ 1.8f
, 1.7f
, 1.5f
},{ 3.5f
, 3.3f
, 3.0f
},{ 7.5f
, 7.1f
, 6.4f
},{ 17.2f
, 16.3f
, 14.6f
},{ 34.4f
, 32.5f
, 29.3f
},{ 72.1f
, 68.1f
, 61.3f
}},
556 {{ 3.5f
, 3.3f
, 3.0f
},{ 7.1f
, 6.7f
, 6.0f
},{ 15.0f
, 14.2f
, 12.8f
},{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
}},
557 {{ 5.3f
, 5.0f
, 4.5f
},{ 10.6f
, 10.0f
, 9.0f
},{ 22.5f
, 21.3f
, 19.1f
},{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
}},
558 {{ 7.1f
, 6.7f
, 6.0f
},{ 14.1f
, 13.3f
, 12.0f
},{ 30.0f
, 28.3f
, 25.5f
},{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
}},
559 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
}},
560 {{ 14.1f
, 13.3f
, 12.0f
},{ 28.2f
, 26.7f
, 24.0f
},{ 60.0f
, 56.7f
, 51.0f
},{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
561 {{ 15.9f
, 15.0f
, 13.5f
},{ 31.8f
, 30.0f
, 27.0f
},{ 67.5f
, 63.8f
, 57.4f
},{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
}},
562 {{ 17.6f
, 16.7f
, 15.0f
},{ 35.3f
, 33.3f
, 30.0f
},{ 75.0f
, 70.8f
, 63.8f
},{ 172.1f
, 162.5f
, 146.3f
},{ 344.1f
, 325.0f
, 292.5f
},{ 720.6f
, 680.6f
, 612.5f
}},
563 {{ 21.2f
, 20.0f
, 18.0f
},{ 42.4f
, 40.0f
, 36.0f
},{ 90.0f
, 85.0f
, 76.5f
},{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
}},
564 {{ 23.5f
, 22.2f
, 20.0f
},{ 47.1f
, 44.4f
, 40.0f
},{ 100.0f
, 94.4f
, 85.0f
},{ 229.4f
, 216.7f
, 195.0f
},{ 458.8f
, 433.3f
, 390.0f
},{ 960.8f
, 907.4f
, 816.7f
}},
565 {{ 26.5f
, 25.0f
, 22.5f
},{ 52.9f
, 50.0f
, 45.0f
},{ 112.5f
, 106.3f
, 95.6f
},{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
}},
566 {{ 29.4f
, 27.8f
, 25.0f
},{ 58.8f
, 55.6f
, 50.0f
},{ 125.0f
, 118.1f
, 106.3f
},{ 286.8f
, 270.8f
, 243.8f
},{ 573.5f
, 541.7f
, 487.5f
},{ 1201.0f
, 1134.3f
, 1020.8f
}}
568 {{ 2.6f
, 2.5f
, 2.3f
},{ 5.3f
, 5.0f
, 4.5f
},{ 11.3f
, 10.6f
, 9.6f
},{ 25.8f
, 24.4f
, 21.9f
},{ 51.6f
, 48.8f
, 43.9f
},{ 108.1f
, 102.1f
, 91.9f
}},
569 {{ 5.3f
, 5.0f
, 4.5f
},{ 10.6f
, 10.0f
, 9.0f
},{ 22.5f
, 21.3f
, 19.1f
},{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
}},
570 {{ 7.9f
, 7.5f
, 6.8f
},{ 15.9f
, 15.0f
, 13.5f
},{ 33.8f
, 31.9f
, 28.7f
},{ 77.4f
, 73.1f
, 65.8f
},{ 154.9f
, 146.3f
, 131.6f
},{ 324.3f
, 306.3f
, 275.6f
}},
571 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
}},
572 {{ 15.9f
, 15.0f
, 13.5f
},{ 31.8f
, 30.0f
, 27.0f
},{ 67.5f
, 63.8f
, 57.4f
},{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
}},
573 {{ 21.2f
, 20.0f
, 18.0f
},{ 42.4f
, 40.0f
, 36.0f
},{ 90.0f
, 85.0f
, 76.5f
},{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
}},
574 {{ 23.8f
, 22.5f
, 20.3f
},{ 47.6f
, 45.0f
, 40.5f
},{ 101.3f
, 95.6f
, 86.1f
},{ 232.3f
, 219.4f
, 197.4f
},{ 464.6f
, 438.8f
, 394.9f
},{ 972.8f
, 918.8f
, 826.9f
}},
575 {{ 26.5f
, 25.0f
, 22.5f
},{ 52.9f
, 50.0f
, 45.0f
},{ 112.5f
, 106.3f
, 95.6f
},{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
}},
576 {{ 31.8f
, 30.0f
, 27.0f
},{ 63.5f
, 60.0f
, 54.0f
},{ 135.0f
, 127.5f
, 114.8f
},{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
577 {{ 35.3f
, 33.3f
, 30.0f
},{ 70.6f
, 66.7f
, 60.0f
},{ 150.0f
, 141.7f
, 127.5f
},{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
578 {{ 39.7f
, 37.5f
, 33.8f
},{ 79.4f
, 75.0f
, 67.5f
},{ 168.8f
, 159.4f
, 143.4f
},{ 387.1f
, 365.6f
, 329.1f
},{ 774.3f
, 731.3f
, 658.1f
},{ 1621.3f
, 1531.3f
, 1378.1f
}},
579 {{ 44.1f
, 41.7f
, 37.5f
},{ 88.2f
, 83.3f
, 75.0f
},{ 187.5f
, 177.1f
, 159.4f
},{ 430.1f
, 406.3f
, 365.6f
},{ 860.3f
, 812.5f
, 731.3f
},{ 1801.5f
, 1701.4f
, 1531.3f
}}
581 {{ 3.5f
, 3.3f
, 3.0f
},{ 7.1f
, 6.7f
, 6.0f
},{ 15.0f
, 14.2f
, 12.8f
},{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
}},
582 {{ 7.1f
, 6.7f
, 6.0f
},{ 14.1f
, 13.3f
, 12.0f
},{ 30.0f
, 28.3f
, 25.5f
},{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
}},
583 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
}},
584 {{ 14.1f
, 13.3f
, 12.0f
},{ 28.2f
, 26.7f
, 24.0f
},{ 60.0f
, 56.7f
, 51.0f
},{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
585 {{ 21.2f
, 20.0f
, 18.0f
},{ 42.4f
, 40.0f
, 36.0f
},{ 90.0f
, 85.0f
, 76.5f
},{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
}},
586 {{ 28.2f
, 26.7f
, 24.0f
},{ 56.5f
, 53.3f
, 48.0f
},{ 120.0f
, 113.3f
, 102.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 550.6f
, 520.0f
, 468.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
587 {{ 31.8f
, 30.0f
, 27.0f
},{ 63.5f
, 60.0f
, 54.0f
},{ 135.0f
, 127.5f
, 114.8f
},{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
588 {{ 35.3f
, 33.3f
, 30.0f
},{ 70.6f
, 66.7f
, 60.0f
},{ 150.0f
, 141.7f
, 127.5f
},{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
589 {{ 42.4f
, 40.0f
, 36.0f
},{ 84.7f
, 80.0f
, 72.0f
},{ 180.0f
, 170.0f
, 153.0f
},{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
590 {{ 47.1f
, 44.4f
, 40.0f
},{ 94.1f
, 88.9f
, 80.0f
},{ 200.0f
, 188.9f
, 170.0f
},{ 458.8f
, 433.3f
, 390.0f
},{ 917.6f
, 866.7f
, 780.0f
},{ 1921.6f
, 1814.8f
, 1633.3f
}},
591 {{ 52.9f
, 50.0f
, 45.0f
},{ 105.9f
, 100.0f
, 90.0f
},{ 225.0f
, 212.5f
, 191.3f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
592 {{ 58.8f
, 55.6f
, 50.0f
},{ 117.6f
, 111.1f
, 100.0f
},{ 250.0f
, 236.1f
, 212.5f
},{ 573.5f
, 541.7f
, 487.5f
},{ 1147.1f
, 1083.3f
, 975.0f
},{ 2402.0f
, 2268.5f
, 2041.7f
}}
594 {{ 4.4f
, 4.2f
, 3.8f
},{ 8.8f
, 8.3f
, 7.5f
},{ 18.8f
, 17.7f
, 15.9f
},{ 43.0f
, 40.6f
, 36.6f
},{ 86.0f
, 81.3f
, 73.1f
},{ 180.1f
, 170.1f
, 153.1f
}},
595 {{ 8.8f
, 8.3f
, 7.5f
},{ 17.6f
, 16.7f
, 15.0f
},{ 37.5f
, 35.4f
, 31.9f
},{ 86.0f
, 81.3f
, 73.1f
},{ 172.1f
, 162.5f
, 146.3f
},{ 360.3f
, 340.3f
, 306.3f
}},
596 {{ 13.2f
, 12.5f
, 11.3f
},{ 26.5f
, 25.0f
, 22.5f
},{ 56.3f
, 53.1f
, 47.8f
},{ 129.0f
, 121.9f
, 109.7f
},{ 258.1f
, 243.8f
, 219.4f
},{ 540.4f
, 510.4f
, 459.4f
}},
597 {{ 17.6f
, 16.7f
, 15.0f
},{ 35.3f
, 33.3f
, 30.0f
},{ 75.0f
, 70.8f
, 63.8f
},{ 172.1f
, 162.5f
, 146.3f
},{ 344.1f
, 325.0f
, 292.5f
},{ 720.6f
, 680.6f
, 612.5f
}},
598 {{ 26.5f
, 25.0f
, 22.5f
},{ 52.9f
, 50.0f
, 45.0f
},{ 112.5f
, 106.3f
, 95.6f
},{ 258.1f
, 243.8f
, 219.4f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1080.9f
, 1020.8f
, 918.8f
}},
599 {{ 35.3f
, 33.3f
, 30.0f
},{ 70.6f
, 66.7f
, 60.0f
},{ 150.0f
, 141.7f
, 127.5f
},{ 344.1f
, 325.0f
, 292.5f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
600 {{ 39.7f
, 37.5f
, 33.8f
},{ 79.4f
, 75.0f
, 67.5f
},{ 168.8f
, 159.4f
, 143.4f
},{ 387.1f
, 365.6f
, 329.1f
},{ 774.3f
, 731.3f
, 658.1f
},{ 1621.3f
, 1531.3f
, 1378.1f
}},
601 {{ 44.1f
, 41.7f
, 37.5f
},{ 88.2f
, 83.3f
, 75.0f
},{ 187.5f
, 177.1f
, 159.4f
},{ 430.1f
, 406.3f
, 365.6f
},{ 860.3f
, 812.5f
, 731.3f
},{ 1801.5f
, 1701.4f
, 1531.3f
}},
602 {{ 52.9f
, 50.0f
, 45.0f
},{ 105.9f
, 100.0f
, 90.0f
},{ 225.0f
, 212.5f
, 191.3f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
603 {{ 58.8f
, 55.6f
, 50.0f
},{ 117.6f
, 111.1f
, 100.0f
},{ 250.0f
, 236.1f
, 212.5f
},{ 573.5f
, 541.7f
, 487.5f
},{ 1147.1f
, 1083.3f
, 975.0f
},{ 2402.0f
, 2268.5f
, 2041.7f
}},
604 {{ 66.2f
, 62.5f
, 56.3f
},{ 132.4f
, 125.0f
, 112.5f
},{ 281.3f
, 265.6f
, 239.1f
},{ 645.2f
, 609.4f
, 548.4f
},{ 1290.4f
, 1218.8f
, 1096.9f
},{ 2702.2f
, 2552.1f
, 2296.9f
}},
605 {{ 73.5f
, 69.4f
, 62.5f
},{ 147.1f
, 138.9f
, 125.0f
},{ 312.5f
, 295.1f
, 265.6f
},{ 716.9f
, 677.1f
, 609.4f
},{ 1433.8f
, 1354.2f
, 1218.8f
},{ 3002.5f
, 2835.6f
, 2552.1f
}}
607 {{ 5.3f
, 5.0f
, 4.5f
},{ 10.6f
, 10.0f
, 9.0f
},{ 22.5f
, 21.3f
, 19.1f
},{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
}},
608 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
}},
609 {{ 15.9f
, 15.0f
, 13.5f
},{ 31.8f
, 30.0f
, 27.0f
},{ 67.5f
, 63.8f
, 57.4f
},{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
}},
610 {{ 21.2f
, 20.0f
, 18.0f
},{ 42.4f
, 40.0f
, 36.0f
},{ 90.0f
, 85.0f
, 76.5f
},{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
}},
611 {{ 31.8f
, 30.0f
, 27.0f
},{ 63.5f
, 60.0f
, 54.0f
},{ 135.0f
, 127.5f
, 114.8f
},{ 309.7f
, 292.5f
, 263.3f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
612 {{ 42.4f
, 40.0f
, 36.0f
},{ 84.7f
, 80.0f
, 72.0f
},{ 180.0f
, 170.0f
, 153.0f
},{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
613 {{ 47.6f
, 45.0f
, 40.5f
},{ 95.3f
, 90.0f
, 81.0f
},{ 202.5f
, 191.3f
, 172.1f
},{ 464.6f
, 438.8f
, 394.9f
},{ 929.1f
, 877.5f
, 789.8f
},{ 1945.6f
, 1837.5f
, 1653.8f
}},
614 {{ 52.9f
, 50.0f
, 45.0f
},{ 105.9f
, 100.0f
, 90.0f
},{ 225.0f
, 212.5f
, 191.3f
},{ 516.2f
, 487.5f
, 438.8f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
615 {{ 63.5f
, 60.0f
, 54.0f
},{ 127.1f
, 120.0f
, 108.0f
},{ 270.0f
, 255.0f
, 229.5f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1238.8f
, 1170.0f
, 1053.0f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
616 {{ 70.6f
, 66.7f
, 60.0f
},{ 141.2f
, 133.3f
, 120.0f
},{ 300.0f
, 283.3f
, 255.0f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1376.5f
, 1300.0f
, 1170.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}},
617 {{ 79.4f
, 75.0f
, 67.5f
},{ 158.8f
, 150.0f
, 135.0f
},{ 337.5f
, 318.8f
, 286.9f
},{ 774.3f
, 731.3f
, 658.1f
},{ 1548.5f
, 1462.5f
, 1316.3f
},{ 3242.6f
, 3062.5f
, 2756.3f
}},
618 {{ 88.2f
, 83.3f
, 75.0f
},{ 176.5f
, 166.7f
, 150.0f
},{ 375.0f
, 354.2f
, 318.8f
},{ 860.3f
, 812.5f
, 731.3f
},{ 1720.6f
, 1625.0f
, 1462.5f
},{ 3602.9f
, 3402.8f
, 3062.5f
}}
620 {{ 6.2f
, 5.8f
, 5.3f
},{ 12.4f
, 11.7f
, 10.5f
},{ 26.3f
, 24.8f
, 22.3f
},{ 60.2f
, 56.9f
, 51.2f
},{ 120.4f
, 113.8f
, 102.4f
},{ 252.2f
, 238.2f
, 214.4f
}},
621 {{ 12.4f
, 11.7f
, 10.5f
},{ 24.7f
, 23.3f
, 21.0f
},{ 52.5f
, 49.6f
, 44.6f
},{ 120.4f
, 113.8f
, 102.4f
},{ 240.9f
, 227.5f
, 204.8f
},{ 504.4f
, 476.4f
, 428.8f
}},
622 {{ 18.5f
, 17.5f
, 15.8f
},{ 37.1f
, 35.0f
, 31.5f
},{ 78.8f
, 74.4f
, 66.9f
},{ 180.7f
, 170.6f
, 153.6f
},{ 361.3f
, 341.3f
, 307.1f
},{ 756.6f
, 714.6f
, 643.1f
}},
623 {{ 24.7f
, 23.3f
, 21.0f
},{ 49.4f
, 46.7f
, 42.0f
},{ 105.0f
, 99.2f
, 89.3f
},{ 240.9f
, 227.5f
, 204.8f
},{ 481.8f
, 455.0f
, 409.5f
},{ 1008.8f
, 952.8f
, 857.5f
}},
624 {{ 37.1f
, 35.0f
, 31.5f
},{ 74.1f
, 70.0f
, 63.0f
},{ 157.5f
, 148.8f
, 133.9f
},{ 361.3f
, 341.3f
, 307.1f
},{ 722.6f
, 682.5f
, 614.3f
},{ 1513.2f
, 1429.2f
, 1286.3f
}},
625 {{ 49.4f
, 46.7f
, 42.0f
},{ 98.8f
, 93.3f
, 84.0f
},{ 210.0f
, 198.3f
, 178.5f
},{ 481.8f
, 455.0f
, 409.5f
},{ 963.5f
, 910.0f
, 819.0f
},{ 2017.6f
, 1905.6f
, 1715.0f
}},
626 {{ 55.6f
, 52.5f
, 47.3f
},{ 111.2f
, 105.0f
, 94.5f
},{ 236.3f
, 223.1f
, 200.8f
},{ 542.0f
, 511.9f
, 460.7f
},{ 1084.0f
, 1023.8f
, 921.4f
},{ 2269.9f
, 2143.8f
, 1929.4f
}},
627 {{ 61.8f
, 58.3f
, 52.5f
},{ 123.5f
, 116.7f
, 105.0f
},{ 262.5f
, 247.9f
, 223.1f
},{ 602.2f
, 568.8f
, 511.9f
},{ 1204.4f
, 1137.5f
, 1023.8f
},{ 2522.1f
, 2381.9f
, 2143.8f
}},
628 {{ 74.1f
, 70.0f
, 63.0f
},{ 148.2f
, 140.0f
, 126.0f
},{ 315.0f
, 297.5f
, 267.8f
},{ 722.6f
, 682.5f
, 614.3f
},{ 1445.3f
, 1365.0f
, 1228.5f
},{ 3026.5f
, 2858.3f
, 2572.5f
}},
629 {{ 82.4f
, 77.8f
, 70.0f
},{ 164.7f
, 155.6f
, 140.0f
},{ 350.0f
, 330.6f
, 297.5f
},{ 802.9f
, 758.3f
, 682.5f
},{ 1605.9f
, 1516.7f
, 1365.0f
},{ 3362.7f
, 3175.9f
, 2858.3f
}},
630 {{ 92.6f
, 87.5f
, 78.8f
},{ 185.3f
, 175.0f
, 157.5f
},{ 393.8f
, 371.9f
, 334.7f
},{ 903.3f
, 853.1f
, 767.8f
},{ 1806.6f
, 1706.3f
, 1535.6f
},{ 3783.1f
, 3572.9f
, 3215.6f
}},
631 {{ 102.9f
, 97.2f
, 87.5f
},{ 205.9f
, 194.4f
, 175.0f
},{ 437.5f
, 413.2f
, 371.9f
},{ 1003.7f
, 947.9f
, 853.1f
},{ 2007.4f
, 1895.8f
, 1706.3f
},{ 4203.4f
, 3969.9f
, 3572.9f
}}
633 {{ 7.1f
, 6.7f
, 6.0f
},{ 14.1f
, 13.3f
, 12.0f
},{ 30.0f
, 28.3f
, 25.5f
},{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
}},
634 {{ 14.1f
, 13.3f
, 12.0f
},{ 28.2f
, 26.7f
, 24.0f
},{ 60.0f
, 56.7f
, 51.0f
},{ 137.6f
, 130.0f
, 117.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
635 {{ 21.2f
, 20.0f
, 18.0f
},{ 42.4f
, 40.0f
, 36.0f
},{ 90.0f
, 85.0f
, 76.5f
},{ 206.5f
, 195.0f
, 175.5f
},{ 412.9f
, 390.0f
, 351.0f
},{ 864.7f
, 816.7f
, 735.0f
}},
636 {{ 28.2f
, 26.7f
, 24.0f
},{ 56.5f
, 53.3f
, 48.0f
},{ 120.0f
, 113.3f
, 102.0f
},{ 275.3f
, 260.0f
, 234.0f
},{ 550.6f
, 520.0f
, 468.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
637 {{ 42.4f
, 40.0f
, 36.0f
},{ 84.7f
, 80.0f
, 72.0f
},{ 180.0f
, 170.0f
, 153.0f
},{ 412.9f
, 390.0f
, 351.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
638 {{ 56.5f
, 53.3f
, 48.0f
},{ 112.9f
, 106.7f
, 96.0f
},{ 240.0f
, 226.7f
, 204.0f
},{ 550.6f
, 520.0f
, 468.0f
},{ 1101.2f
, 1040.0f
, 936.0f
},{ 2305.9f
, 2177.8f
, 1960.0f
}},
639 {{ 63.5f
, 60.0f
, 54.0f
},{ 127.1f
, 120.0f
, 108.0f
},{ 270.0f
, 255.0f
, 229.5f
},{ 619.4f
, 585.0f
, 526.5f
},{ 1238.8f
, 1170.0f
, 1053.0f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
640 {{ 70.6f
, 66.7f
, 60.0f
},{ 141.2f
, 133.3f
, 120.0f
},{ 300.0f
, 283.3f
, 255.0f
},{ 688.2f
, 650.0f
, 585.0f
},{ 1376.5f
, 1300.0f
, 1170.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}},
641 {{ 84.7f
, 80.0f
, 72.0f
},{ 169.4f
, 160.0f
, 144.0f
},{ 360.0f
, 340.0f
, 306.0f
},{ 825.9f
, 780.0f
, 702.0f
},{ 1651.8f
, 1560.0f
, 1404.0f
},{ 3458.8f
, 3266.7f
, 2940.0f
}},
642 {{ 94.1f
, 88.9f
, 80.0f
},{ 188.2f
, 177.8f
, 160.0f
},{ 400.0f
, 377.8f
, 340.0f
},{ 917.6f
, 866.7f
, 780.0f
},{ 1835.3f
, 1733.3f
, 1560.0f
},{ 3843.1f
, 3629.6f
, 3266.7f
}},
643 {{ 105.9f
, 100.0f
, 90.0f
},{ 211.8f
, 200.0f
, 180.0f
},{ 450.0f
, 425.0f
, 382.5f
},{ 1032.4f
, 975.0f
, 877.5f
},{ 2064.7f
, 1950.0f
, 1755.0f
},{ 4323.5f
, 4083.3f
, 3675.0f
}},
644 {{ 117.6f
, 111.1f
, 100.0f
},{ 235.3f
, 222.2f
, 200.0f
},{ 500.0f
, 472.2f
, 425.0f
},{ 1147.1f
, 1083.3f
, 975.0f
},{ 2294.1f
, 2166.7f
, 1950.0f
},{ 4803.9f
, 4537.0f
, 4083.3f
}}
650 * Calculates 802.11ax HE SU data rate corresponding to a given 802.11ax MCS index,
651 * bandwidth, and guard interval.
653 static float ieee80211_he_mu_ofdma_rate(unsigned nsts
, unsigned mcs
, unsigned ru
, unsigned gi
)
656 if ( ((nsts
-1) < HE_MAX_NSTS
) && (mcs
< HE_MAX_MCS
) && ( (ru
-4) < HE_MU_MAX_RU
) && ( gi
< HE_MAX_GI
) ) {
657 rate
= he_mu_ofdma_tab
[nsts
-1][mcs
][ru
-4][gi
];
663 * EHT MCS rate table converted from http://mcsindex.net
664 * indexed by (MCS,BW,GI)
665 * Covering only upto 4x996-tone-RU/320MHz, Additional RUs and Punctured modes not added yet.
666 * For higher # of spatial streams, the rate will be computed based on the 1SS rates below.
667 * The resultant error in rate computation remains within a maximum of +/- 0.5 Mbps from corresponding static table rates.
669 #define EHT_MAX_NSTS 8
670 #define EHT_MAX_BW IEEE80211_RADIOTAP_EHT_RU_4_TIMES_994 + 1
672 static float eht_mcs_tab
[EHT_MAX_MCS
][EHT_MAX_BW
][EHT_MAX_GI
] = {
673 /* ru-26 | ru-52 | ru-106 | ru-242 / 20 MHz | ru-484 / 40 MHz | ru-996 / 80 MHz | 2 * ru-996 / 160 MHz | 4 * ru-996 / 320 MHz */
674 {{ 0.9f
, 0.8f
, 0.8f
},{ 1.8f
, 1.7f
, 1.5f
},{ 3.8f
, 3.5f
, 3.2f
},{ 8.6f
, 8.1f
, 7.3f
},{ 17.2f
, 16.3f
, 14.6f
},{ 36.0f
, 34.0f
, 30.6f
},{ 72.1f
, 68.1f
, 61.3f
},{ 144.1f
, 136.1f
, 122.5f
}},
675 {{ 1.8f
, 1.7f
, 1.5f
},{ 3.5f
, 3.3f
, 3.0f
},{ 7.5f
, 7.1f
, 6.4f
},{ 17.2f
, 16.3f
, 14.6f
},{ 34.4f
, 32.5f
, 29.3f
},{ 72.1f
, 68.1f
, 61.3f
},{ 144.1f
, 136.1f
, 122.5f
},{ 288.2f
, 272.2f
, 245.0f
}},
676 {{ 2.6f
, 2.5f
, 2.3f
},{ 5.3f
, 5.0f
, 4.5f
},{ 11.3f
, 10.6f
, 9.6f
},{ 25.8f
, 24.4f
, 21.9f
},{ 51.6f
, 48.8f
, 43.9f
},{ 108.1f
, 102.1f
, 91.9f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
}},
677 {{ 3.5f
, 3.3f
, 3.0f
},{ 7.1f
, 6.7f
, 6.0f
},{ 15.0f
, 14.2f
, 12.8f
},{ 34.4f
, 32.5f
, 29.3f
},{ 68.8f
, 65.0f
, 58.5f
},{ 144.1f
, 136.1f
, 122.5f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
}},
678 {{ 5.3f
, 5.0f
, 4.5f
},{ 10.6f
, 10.0f
, 9.0f
},{ 22.5f
, 21.3f
, 19.1f
},{ 51.6f
, 48.8f
, 43.9f
},{ 103.2f
, 97.5f
, 87.8f
},{ 216.2f
, 204.2f
, 183.8f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
}},
679 {{ 7.1f
, 6.7f
, 6.0f
},{ 14.1f
, 13.3f
, 12.0f
},{ 30.0f
, 28.3f
, 25.5f
},{ 68.8f
, 65.0f
, 58.5f
},{ 137.6f
, 130.0f
, 117.0f
},{ 288.2f
, 272.2f
, 245.0f
},{ 576.5f
, 544.4f
, 490.0f
},{ 1152.9f
, 1088.9f
, 980.0f
}},
680 {{ 7.9f
, 7.5f
, 6.8f
},{ 15.9f
, 15.0f
, 13.5f
},{ 33.8f
, 31.9f
, 28.7f
},{ 77.4f
, 73.1f
, 65.8f
},{ 154.9f
, 146.3f
, 131.6f
},{ 324.3f
, 306.3f
, 275.6f
},{ 648.5f
, 612.5f
, 551.3f
},{ 1297.1f
, 1225.0f
, 1102.5f
}},
681 {{ 8.8f
, 8.3f
, 7.5f
},{ 17.6f
, 16.7f
, 15.0f
},{ 37.5f
, 35.4f
, 31.9f
},{ 86.0f
, 81.3f
, 73.1f
},{ 172.1f
, 162.5f
, 146.3f
},{ 360.3f
, 340.3f
, 306.3f
},{ 720.6f
, 680.6f
, 612.5f
},{ 1441.2f
, 1361.1f
, 1225.0f
}},
682 {{ 10.6f
, 10.0f
, 9.0f
},{ 21.2f
, 20.0f
, 18.0f
},{ 45.0f
, 42.5f
, 38.3f
},{ 103.2f
, 97.5f
, 87.8f
},{ 206.5f
, 195.0f
, 175.5f
},{ 432.4f
, 408.3f
, 367.5f
},{ 864.7f
, 816.7f
, 735.0f
},{ 1729.4f
, 1633.3f
, 1470.0f
}},
683 {{ 11.8f
, 11.1f
, 10.0f
},{ 23.5f
, 22.2f
, 20.0f
},{ 50.0f
, 47.2f
, 42.5f
},{ 114.7f
, 108.3f
, 97.5f
},{ 229.4f
, 216.7f
, 195.0f
},{ 480.4f
, 453.7f
, 408.3f
},{ 960.8f
, 907.4f
, 816.7f
},{ 1921.6f
, 1814.8f
, 1633.3f
}},
684 {{ 13.2f
, 12.5f
, 11.3f
},{ 26.5f
, 25.0f
, 22.5f
},{ 56.3f
, 53.1f
, 47.8f
},{ 129.0f
, 121.9f
, 109.7f
},{ 258.1f
, 243.8f
, 219.4f
},{ 540.4f
, 510.4f
, 459.4f
},{ 1080.9f
, 1020.8f
, 918.8f
},{ 2161.8f
, 2041.7f
, 1837.5f
}},
685 {{ 14.7f
, 13.9f
, 12.5f
},{ 29.4f
, 27.8f
, 25.0f
},{ 62.5f
, 59.0f
, 53.1f
},{ 143.4f
, 135.4f
, 121.9f
},{ 286.8f
, 270.8f
, 243.8f
},{ 600.5f
, 567.1f
, 510.4f
},{ 1201.0f
, 1134.3f
, 1020.8f
},{ 2402.0f
, 2268.5f
, 2041.7f
}},
686 {{ 15.9f
, 15.0f
, 13.5f
},{ 31.8f
, 30.0f
, 27.0f
},{ 67.5f
, 63.8f
, 57.4f
},{ 154.9f
, 146.3f
, 131.6f
},{ 309.7f
, 292.5f
, 263.3f
},{ 648.5f
, 612.5f
, 551.3f
},{ 1297.1f
, 1225.0f
, 1102.5f
},{ 2594.1f
, 2450.0f
, 2205.0f
}},
687 {{ 17.6f
, 16.7f
, 15.0f
},{ 35.3f
, 33.3f
, 30.0f
},{ 75.0f
, 70.8f
, 63.8f
},{ 172.1f
, 162.5f
, 146.3f
},{ 344.1f
, 325.0f
, 292.5f
},{ 720.6f
, 680.6f
, 612.5f
},{ 1441.2f
, 1361.1f
, 1225.0f
},{ 2882.4f
, 2722.2f
, 2450.0f
}}
692 * Calculates 802.11be EHT data rate corresponding to a given 802.11be MCS index,
693 * ru-size/bandwidth, guard interval and number of spatial streams.
695 static float ieee80211_eht_rate(unsigned nsts
, unsigned mcs
, unsigned bw
, unsigned gi
)
698 if ( ((nsts
-1) < EHT_MAX_NSTS
) && (mcs
< EHT_MAX_MCS
) && (bw
< EHT_MAX_BW
) && (gi
< EHT_MAX_GI
) ) {
699 rate
= eht_mcs_tab
[mcs
][bw
][gi
] * nsts
;
704 static int ett_wlan_radio
;
705 static int ett_wlan_radio_11ac_user
;
706 static int ett_wlan_radio_duration
;
707 static int ett_wlan_radio_aggregate
;
708 static int ett_wlan_radio_11be_user
;
710 /* previous frame details, for aggregate detection */
711 struct previous_frame_info
{
712 bool has_tsf_timestamp
;
713 uint64_t tsf_timestamp
;
715 union ieee_802_11_phy_info phy_info
;
716 unsigned prev_length
;
717 struct wlan_radio
*radio_info
;
720 static struct previous_frame_info previous_frame
;
721 static struct aggregate
*current_aggregate
;
722 static wmem_list_t
*agg_tracker_list
;
724 static unsigned calculate_11n_duration(unsigned frame_length
,
725 struct ieee_802_11n
* info_n
,
729 unsigned bits_per_symbol
;
733 /* data field calculation */
735 /* see ieee80211n-2009 20.3.11 (20-32) - for BCC FEC */
736 bits
= 8 * frame_length
+ 16 + ieee80211_ht_Nes
[info_n
->mcs_index
] * 6;
737 Mstbc
= stbc_streams
? 2 : 1;
738 bits_per_symbol
= ieee80211_ht_Dbps
[info_n
->mcs_index
] *
739 (info_n
->bandwidth
== PHDR_802_11_BANDWIDTH_40_MHZ
? 2 : 1);
740 symbols
= bits
/ (bits_per_symbol
* Mstbc
);
742 /* TODO: handle LDPC FEC, it changes the rounding */
744 /* round up to whole symbols */
745 if ((bits
% (bits_per_symbol
* Mstbc
)) > 0)
749 return (symbols
* (info_n
->short_gi
? 36 : 40) + 5) / 10;
752 /* TODO: this is a crude quick hack, need proper calculation of bits/symbols/FEC/etc */
753 static unsigned calculate_11ac_duration(unsigned frame_length
, float data_rate
)
755 unsigned bits
= 8 * frame_length
+ 16;
756 return (unsigned) (bits
/ data_rate
);
759 static void adjust_agg_tsf(void *data
, void *user_data
)
761 struct wlan_radio
*wlan_radio_info
= (struct wlan_radio
*)data
;
762 uint64_t *ppdu_start
= (uint64_t *)user_data
;
764 wlan_radio_info
->start_tsf
+= (*ppdu_start
);
765 wlan_radio_info
->end_tsf
+= (*ppdu_start
);
766 if (wlan_radio_info
->prior_aggregate_data
== 0)
767 wlan_radio_info
->ifs
+= (*ppdu_start
);
771 * Dissect 802.11 pseudo-header containing radio information.
774 dissect_wlan_radio_phdr(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, struct ieee_802_11_phdr
*phdr
)
777 proto_tree
*radio_tree
;
778 float data_rate
= 0.0f
;
779 bool have_data_rate
= false;
780 bool has_short_preamble
= false;
781 bool short_preamble
= true;
782 unsigned bandwidth
= 0;
783 bool can_calculate_rate
= false;
786 unsigned frame_length
= tvb_reported_length(tvb
); /* length of 802.11 frame data */
788 /* durations in microseconds */
789 unsigned preamble
= 0, agg_preamble
= 0; /* duration of plcp */
790 bool have_duration
= false;
791 unsigned duration
= 0; /* duration of whole frame (plcp + mac data + any trailing parts) */
792 unsigned prior_duration
= 0; /* duration of previous part of aggregate */
794 struct wlan_radio
*wlan_radio_info
;
796 union ieee_802_11_phy_info
*phy_info
= &phdr
->phy_info
;
798 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Radio");
799 col_clear(pinfo
->cinfo
, COL_INFO
);
801 /* Calculate the data rate, if we have the necessary data */
802 if (phdr
->has_data_rate
) {
803 data_rate
= phdr
->data_rate
* 0.5f
;
804 have_data_rate
= true;
807 /* this is the first time we are looking at this frame during a
808 * capture dissection, so we know the dissection is done in
809 * frame order (subsequent dissections may be random access) */
810 if (!pinfo
->fd
->visited
) {
811 wlan_radio_info
= wmem_new0(wmem_file_scope(), struct wlan_radio
);
812 p_add_proto_data(wmem_file_scope(), pinfo
, proto_wlan_radio
, 0, wlan_radio_info
);
814 /* A-MPDU / aggregate detection
815 * Different generators need different detection algorithms
816 * One common pattern is to report all subframes in the aggregate with the same
817 * tsf, referenced to the start of the AMPDU (Broadcom). Another pattern is to
818 * report the tsf on the first subframe, then tsf=0 for the rest of the subframes
820 * Another pattern is to report TSF = -1 for all frames but the last, and the
821 * last has the tsf referenced to the end of the PPDU. (QCA)
823 /* TODO: add code to work around problem with captures from Macbooks where
824 * aggregate subframes frames with FCS errors sometimes have incorrect
827 if (pinfo
->fd
->num
> 1 &&
828 (phdr
->phy
== PHDR_802_11_PHY_11N
|| phdr
->phy
== PHDR_802_11_PHY_11AC
) &&
829 phdr
->phy
== previous_frame
.phy
&&
830 phdr
->has_tsf_timestamp
&& previous_frame
.has_tsf_timestamp
&&
831 (phdr
->tsf_timestamp
== previous_frame
.tsf_timestamp
|| /* find matching TSFs */
832 (!current_aggregate
&& previous_frame
.tsf_timestamp
&& phdr
->tsf_timestamp
== 0) || /* Intel detect second frame */
833 (previous_frame
.tsf_timestamp
== UINT64_MAX
) /* QCA, detect last frame */
835 /* we're in an aggregate */
836 if (!current_aggregate
) {
837 /* this is the second frame in an aggregate
838 * where we first detect the aggregate */
839 current_aggregate
= wmem_new0(wmem_file_scope(), struct aggregate
);
840 current_aggregate
->phy
= previous_frame
.phy
;
841 current_aggregate
->phy_info
= previous_frame
.phy_info
;
843 /* go back to the first frame in the aggregate,
844 * and mark it as part of this aggregate */
845 if (previous_frame
.radio_info
!= NULL
)
846 previous_frame
.radio_info
->aggregate
= current_aggregate
;
848 wlan_radio_info
->aggregate
= current_aggregate
;
850 /* accumulate the length of the prior subframes in the aggregate.
851 * Round up previous frame length (padding) */
852 if (previous_frame
.prev_length
% 4 != 0) {
853 previous_frame
.prev_length
= (previous_frame
.prev_length
| 3) + 1;
855 /* Also add the MPDU delimiter length */
856 previous_frame
.prev_length
+= 4;
857 /* TODO: add padding to meet minimum subframe timing constraint */
858 wlan_radio_info
->prior_aggregate_data
= previous_frame
.prev_length
;
859 previous_frame
.prev_length
+= frame_length
;
861 /* work around macbook/QCA FCS error frame PHY rate bug here
862 * Some Macbook generators and some QCA generators erroneously report
863 * low PHY rates for some subframes within an aggregate that have FCS errors.
864 * All subframes must have the same PHY rate.
865 * Here we take the highest reported rate for the aggregate. */
867 case PHDR_802_11_PHY_11N
:
869 struct ieee_802_11n
*info_n
= &phy_info
->info_11n
;
870 struct ieee_802_11n
*agg_info_n
= ¤t_aggregate
->phy_info
.info_11n
;
872 if (info_n
->has_mcs_index
&& agg_info_n
->has_mcs_index
&&
873 info_n
->mcs_index
> agg_info_n
->mcs_index
)
874 current_aggregate
->phy_info
= *phy_info
;
878 case PHDR_802_11_PHY_11AC
:
880 struct ieee_802_11ac
*info_ac
= &phy_info
->info_11ac
;
881 struct ieee_802_11ac
*agg_info_ac
= ¤t_aggregate
->phy_info
.info_11ac
;
883 if (info_ac
->mcs
[0] > agg_info_ac
->mcs
[0])
884 current_aggregate
->phy_info
= *phy_info
;
888 /* TODO record a warning if the PHY rate does not match the aggregate */
889 phy
= current_aggregate
->phy
;
890 phy_info
= ¤t_aggregate
->phy_info
;
892 current_aggregate
= NULL
;
893 previous_frame
.prev_length
= frame_length
;
895 previous_frame
.has_tsf_timestamp
= phdr
->has_tsf_timestamp
;
896 previous_frame
.tsf_timestamp
= phdr
->tsf_timestamp
;
897 previous_frame
.phy
= phdr
->phy
;
898 previous_frame
.phy_info
= phdr
->phy_info
;
900 /* this frame has already been seen, so get its info structure */
901 wlan_radio_info
= (struct wlan_radio
*) p_get_proto_data(wmem_file_scope(), pinfo
, proto_wlan_radio
, 0);
903 if (wlan_radio_info
&& wlan_radio_info
->aggregate
) {
904 phy
= wlan_radio_info
->aggregate
->phy
;
905 phy_info
= &wlan_radio_info
->aggregate
->phy_info
;
909 ti
= proto_tree_add_item(tree
, proto_wlan_radio
, tvb
, 0, 0, ENC_NA
);
910 radio_tree
= proto_item_add_subtree (ti
, ett_wlan_radio
);
912 if (phy
!= PHDR_802_11_PHY_UNKNOWN
) {
913 proto_tree_add_uint(radio_tree
, hf_wlan_radio_phy
, tvb
, 0, 0, phy
);
917 case PHDR_802_11_PHY_11_FHSS
:
919 struct ieee_802_11_fhss
*info_fhss
= &phy_info
->info_11_fhss
;
921 if (info_fhss
->has_hop_set
) {
922 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11_fhss_hop_set
, tvb
, 0, 0,
925 if (info_fhss
->has_hop_pattern
) {
926 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11_fhss_hop_pattern
, tvb
, 0, 0,
927 info_fhss
->hop_pattern
);
929 if (info_fhss
->has_hop_index
) {
930 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11_fhss_hop_index
, tvb
, 0, 0,
931 info_fhss
->hop_index
);
936 case PHDR_802_11_PHY_11B
:
938 struct ieee_802_11b
*info_b
= &phy_info
->info_11b
;
940 has_short_preamble
= info_b
->has_short_preamble
;
942 if (has_short_preamble
) {
943 short_preamble
= info_b
->short_preamble
;
944 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_short_preamble
, tvb
, 0, 0,
950 case PHDR_802_11_PHY_11A
:
952 struct ieee_802_11a
*info_a
= &phy_info
->info_11a
;
954 if (info_a
->has_channel_type
) {
955 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11a_channel_type
, tvb
, 0, 0,
956 info_a
->channel_type
);
958 if (info_a
->has_turbo_type
) {
959 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11a_turbo_type
, tvb
, 0, 0,
965 case PHDR_802_11_PHY_11G
:
967 struct ieee_802_11g
*info_g
= &phy_info
->info_11g
;
969 if (info_g
->has_mode
) {
970 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11g_mode
, tvb
, 0, 0,
976 case PHDR_802_11_PHY_11N
:
978 struct ieee_802_11n
*info_n
= &phy_info
->info_11n
;
979 unsigned bandwidth_40
;
982 * If we have all the fields needed to look up the data rate,
985 if (info_n
->has_mcs_index
&&
986 info_n
->has_bandwidth
&&
987 info_n
->has_short_gi
) {
988 bandwidth_40
= (info_n
->bandwidth
== PHDR_802_11_BANDWIDTH_40_MHZ
) ? 1 : 0;
989 if (info_n
->mcs_index
< MAX_MCS_INDEX
) {
990 data_rate
= ieee80211_htrate(info_n
->mcs_index
, bandwidth_40
, info_n
->short_gi
);
991 have_data_rate
= true;
995 if (info_n
->has_mcs_index
) {
996 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11n_mcs_index
, tvb
, 0, 0,
1000 if (info_n
->has_bandwidth
) {
1001 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11n_bandwidth
, tvb
, 0, 0,
1005 if (info_n
->has_short_gi
) {
1006 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11n_short_gi
, tvb
, 0, 0,
1010 if (info_n
->has_greenfield
) {
1011 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11n_greenfield
, tvb
, 0, 0,
1012 info_n
->greenfield
);
1015 if (info_n
->has_fec
) {
1016 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11n_fec
, tvb
, 0, 0,
1020 if (info_n
->has_stbc_streams
) {
1021 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11n_stbc_streams
, tvb
, 0, 0,
1022 info_n
->stbc_streams
);
1025 if (info_n
->has_ness
) {
1026 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11n_ness
, tvb
, 0, 0,
1032 case PHDR_802_11_PHY_11AC
:
1034 struct ieee_802_11ac
*info_ac
= &phy_info
->info_11ac
;
1037 if (info_ac
->has_short_gi
) {
1038 can_calculate_rate
= true; /* well, if we also have the bandwidth */
1039 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_short_gi
, tvb
, 0, 0, info_ac
->short_gi
);
1041 can_calculate_rate
= false; /* unknown GI length */
1044 if (info_ac
->has_bandwidth
) {
1045 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11ac_bandwidth
, tvb
, 0, 0, info_ac
->bandwidth
);
1046 if (info_ac
->bandwidth
< G_N_ELEMENTS(ieee80211_vht_bw2rate_index
))
1047 bandwidth
= ieee80211_vht_bw2rate_index
[info_ac
->bandwidth
];
1049 can_calculate_rate
= false; /* unknown bandwidth */
1051 can_calculate_rate
= false; /* no bandwidth */
1054 if (info_ac
->has_stbc
) {
1055 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_stbc
, tvb
, 0, 0,
1059 if (info_ac
->has_txop_ps_not_allowed
) {
1060 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_txop_ps_not_allowed
, tvb
, 0, 0,
1061 info_ac
->txop_ps_not_allowed
);
1064 if (info_ac
->has_short_gi_nsym_disambig
) {
1065 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_short_gi_nsym_disambig
, tvb
, 0, 0,
1066 info_ac
->short_gi_nsym_disambig
);
1069 if (info_ac
->has_ldpc_extra_ofdm_symbol
) {
1070 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_ldpc_extra_ofdm_symbol
, tvb
, 0, 0,
1071 info_ac
->ldpc_extra_ofdm_symbol
);
1074 if (info_ac
->has_beamformed
) {
1075 proto_tree_add_boolean(radio_tree
, hf_wlan_radio_11ac_beamformed
, tvb
, 0, 0,
1076 info_ac
->beamformed
);
1079 for (i
= 0; i
< 4; i
++) {
1081 if (info_ac
->nss
[i
] != 0) {
1083 proto_tree
*user_tree
;
1085 it
= proto_tree_add_item(radio_tree
, hf_wlan_radio_11ac_user
, tvb
, 0, 0, ENC_NA
);
1086 proto_item_append_text(it
, " %d: MCS %u", i
, info_ac
->mcs
[i
]);
1087 user_tree
= proto_item_add_subtree(it
, ett_wlan_radio_11ac_user
);
1089 it
= proto_tree_add_uint(user_tree
, hf_wlan_radio_11ac_mcs
, tvb
, 0, 0,
1091 if (info_ac
->mcs
[i
] > MAX_MCS_VHT_INDEX
) {
1092 proto_item_append_text(it
, " (invalid)");
1094 proto_item_append_text(it
, " (%s %s)",
1095 ieee80211_mcsinfo
[info_ac
->mcs
[i
]].modulation
,
1096 ieee80211_mcsinfo
[info_ac
->mcs
[i
]].coding_rate
);
1099 proto_tree_add_uint(user_tree
, hf_wlan_radio_11ac_nss
, tvb
, 0, 0, info_ac
->nss
[i
]);
1101 * If we don't know whether space-time block coding is being
1102 * used, we don't know the number of space-time streams.
1104 if (info_ac
->has_stbc
) {
1108 nsts
= 2 * info_ac
->nss
[i
];
1110 nsts
= info_ac
->nss
[i
];
1111 proto_tree_add_uint(user_tree
, hf_wlan_radio_11ac_nsts
, tvb
, 0, 0,
1114 if (info_ac
->has_fec
) {
1115 proto_tree_add_uint(user_tree
, hf_wlan_radio_11ac_fec
, tvb
, 0, 0,
1116 (info_ac
->fec
>> i
) & 0x01);
1120 * If we can calculate the data rate for this user, do so.
1122 if (can_calculate_rate
&& info_ac
->mcs
[i
] <= MAX_MCS_VHT_INDEX
&&
1123 info_ac
->nss
[i
] <= MAX_VHT_NSS
&&
1124 ieee80211_vhtvalid
[info_ac
->mcs
[i
]].valid
[bandwidth
][info_ac
->nss
[i
]-1]) {
1125 data_rate
= ieee80211_vhtrate(info_ac
->mcs
[i
], bandwidth
, info_ac
->short_gi
) * info_ac
->nss
[i
];
1126 if (data_rate
!= 0.0f
) {
1127 have_data_rate
= true;
1133 if (info_ac
->has_group_id
) {
1134 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11ac_gid
, tvb
, 0, 0, info_ac
->group_id
);
1137 if (info_ac
->has_partial_aid
) {
1138 proto_tree_add_uint(radio_tree
, hf_wlan_radio_11ac_p_aid
, tvb
, 0, 0, info_ac
->partial_aid
);
1142 case PHDR_802_11_PHY_11AX
:
1144 struct ieee_802_11ax
*info_ax
= &phy_info
->info_11ax
;
1145 if (info_ax
->has_gi
&& info_ax
->has_bwru
&& info_ax
->has_mcs_index
) {
1146 if (info_ax
->bwru
< HE_SU_MAX_BW
) {
1147 data_rate
= ieee80211_he_ofdm_rate(info_ax
->nsts
,info_ax
->mcs
,info_ax
->bwru
,info_ax
->gi
);
1149 data_rate
= ieee80211_he_mu_ofdma_rate(info_ax
->nsts
,info_ax
->mcs
,info_ax
->bwru
,info_ax
->gi
);
1151 if (data_rate
!= 0.0f
) {
1152 have_data_rate
= true;
1157 case PHDR_802_11_PHY_11BE
:
1159 struct ieee_802_11be
*info_11be
= &phy_info
->info_11be
;
1161 can_calculate_rate
= true;
1163 for (i
= 0; i
< info_11be
->num_users
; i
++) {
1164 if (i
>= PHDR_802_11BE_MAX_USERS
) {
1165 expert_add_info(pinfo
, radio_tree
, &ei_wlan_radio_11be_num_users
);
1168 unsigned nsts
= info_11be
->user
[i
].nsts
;
1169 unsigned bw_idx
= 0;
1170 /* Do we have all the fields needed to compute rate ?*/
1171 if (!info_11be
->has_gi
|| !info_11be
->user
[i
].nsts_known
|| !nsts
)
1173 can_calculate_rate
= false;
1175 if (!info_11be
->has_bandwidth
&& (!info_11be
->has_ru_mru_size
||
1176 info_11be
->ru_mru_size
> IEEE80211_RADIOTAP_EHT_RU_4_TIMES_994
)) {
1177 can_calculate_rate
= false;
1180 if (info_11be
->has_bandwidth
) {
1181 /* 20,40,80,160 and 320MHz overlap with mcs table index for ru-242 and above.
1182 * So add the offset.
1183 * Punctured modes not considered yet. */
1184 bw_idx
= info_11be
->bandwidth
+ IEEE80211_RADIOTAP_EHT_RU_242
;
1186 bw_idx
= info_11be
->ru_mru_size
;
1189 proto_tree
*user_tree
;
1191 it
= proto_tree_add_item(radio_tree
, hf_wlan_radio_11be_user
, tvb
, 0, 0, ENC_NA
);
1192 proto_item_append_text(it
, " %d: MCS %u", i
, info_11be
->user
[i
].mcs
);
1193 user_tree
= proto_item_add_subtree(it
, ett_wlan_radio_11be_user
);
1195 it
= proto_tree_add_uint(user_tree
, hf_wlan_radio_11be_mcs
, tvb
, 0, 0,
1196 info_11be
->user
[i
].mcs
);
1197 if (info_11be
->user
[i
].mcs
>= EHT_MAX_MCS
) {
1198 proto_item_append_text(it
, " (invalid)");
1200 proto_item_append_text(it
, " (%s %s)",
1201 ieee80211_mcsinfo
[info_11be
->user
[i
].mcs
].modulation
,
1202 ieee80211_mcsinfo
[info_11be
->user
[i
].mcs
].coding_rate
);
1205 proto_tree_add_uint(user_tree
, hf_wlan_radio_11be_nsts
, tvb
, 0, 0, nsts
);
1208 * If we can calculate the data rate for this user, do so.
1210 if (can_calculate_rate
&& info_11be
->user
[i
].mcs
< EHT_MAX_MCS
&&
1211 nsts
< EHT_MAX_NSTS
) {
1212 data_rate
= ieee80211_eht_rate(nsts
, info_11be
->user
[i
].mcs
, bw_idx
, info_11be
->gi
);
1213 if (data_rate
!= 0.0f
) {
1214 //have_data_rate = true;
1215 proto_tree_add_float_format_value(user_tree
, hf_wlan_radio_data_rate
, tvb
, 0, 0,
1221 } // for (i = 0; i < info_11be->num_users; i++)
1222 } // case PHDR_802_11_PHY_11BE:
1227 if (have_data_rate
) {
1228 col_add_fstr(pinfo
->cinfo
, COL_TX_RATE
, "%.1f", data_rate
);
1229 proto_tree_add_float_format_value(radio_tree
, hf_wlan_radio_data_rate
, tvb
, 0, 0,
1235 if (phdr
->has_channel
) {
1236 col_add_fstr(pinfo
->cinfo
, COL_FREQ_CHAN
, "%u", phdr
->channel
);
1237 proto_tree_add_uint(radio_tree
, hf_wlan_radio_channel
, tvb
, 0, 0, phdr
->channel
);
1240 if (phdr
->has_frequency
) {
1241 col_add_fstr(pinfo
->cinfo
, COL_FREQ_CHAN
, "%u MHz", phdr
->frequency
);
1242 proto_tree_add_uint(radio_tree
, hf_wlan_radio_frequency
, tvb
, 0, 0, phdr
->frequency
);
1245 if (phdr
->has_signal_percent
) {
1246 col_add_fstr(pinfo
->cinfo
, COL_RSSI
, "%u%%", phdr
->signal_percent
);
1247 proto_tree_add_uint(radio_tree
, hf_wlan_radio_signal_percent
, tvb
, 0, 0, phdr
->signal_percent
);
1250 if (phdr
->has_signal_db
) {
1251 col_add_fstr(pinfo
->cinfo
, COL_RSSI
, "%u dB", phdr
->signal_db
);
1252 proto_tree_add_uint(radio_tree
, hf_wlan_radio_signal_db
, tvb
, 0, 0, phdr
->signal_db
);
1255 if (phdr
->has_signal_dbm
) {
1256 col_add_fstr(pinfo
->cinfo
, COL_RSSI
, "%d dBm", phdr
->signal_dbm
);
1257 proto_tree_add_int(radio_tree
, hf_wlan_radio_signal_dbm
, tvb
, 0, 0, phdr
->signal_dbm
);
1260 if (phdr
->has_noise_percent
) {
1261 proto_tree_add_uint(radio_tree
, hf_wlan_radio_noise_percent
, tvb
, 0, 0, phdr
->noise_percent
);
1264 if (phdr
->has_noise_db
) {
1265 proto_tree_add_uint(radio_tree
, hf_wlan_radio_noise_db
, tvb
, 0, 0, phdr
->noise_db
);
1268 if (phdr
->has_noise_dbm
) {
1269 proto_tree_add_int(radio_tree
, hf_wlan_radio_noise_dbm
, tvb
, 0, 0, phdr
->noise_dbm
);
1272 if (phdr
->has_signal_dbm
&& phdr
->has_noise_dbm
) {
1273 proto_tree_add_int(radio_tree
, hf_wlan_radio_snr
, tvb
, 0, 0, phdr
->signal_dbm
- phdr
->noise_dbm
);
1276 * XXX - are the signal and noise in dB from a fixed reference point
1277 * guaranteed to use the *same* fixed reference point? If so, we could
1278 * calculate the SNR if they're both present, too.
1281 if (phdr
->has_tsf_timestamp
) {
1282 proto_tree_add_uint64(radio_tree
, hf_wlan_radio_timestamp
, tvb
, 0, 0, phdr
->tsf_timestamp
);
1284 if (phdr
->has_aggregate_info
) {
1285 proto_tree_add_boolean(radio_tree
, hf_wlan_last_part_of_a_mpdu
, tvb
, 0, 0, phdr
->aggregate_flags
);
1286 proto_tree_add_boolean(radio_tree
, hf_wlan_a_mpdu_delim_crc_error
, tvb
, 0, 0, phdr
->aggregate_flags
);
1287 proto_tree_add_uint(radio_tree
, hf_wlan_a_mpdu_aggregate_id
, tvb
, 0, 0, phdr
->aggregate_id
);
1290 /* make sure frame_length includes the FCS for accurate duration calculation */
1291 if (pinfo
->pseudo_header
->ieee_802_11
.fcs_len
== 0) {
1295 if (have_data_rate
&& data_rate
> 0) {
1296 /* duration calculations */
1297 bool assumed_short_preamble
= false;
1298 bool assumed_non_greenfield
= false;
1299 bool assumed_no_stbc
= false;
1300 bool assumed_no_extension_streams
= false;
1301 bool assumed_bcc_fec
= false;
1303 /* some generators report CCK frames as 'dynamic-cck-ofdm', which are converted
1304 * into the 11g PHY type, so we need to be smart and recognize which ones are
1305 * DSSS/CCK and which are OFDM. Use the data_rate to do this. */
1306 if (phy
== PHDR_802_11_PHY_11G
&&
1307 (data_rate
== 1.0f
|| data_rate
== 2.0f
||
1308 data_rate
== 5.5f
|| data_rate
== 11.0f
||
1309 data_rate
== 22.0f
|| data_rate
== 33.0f
)) {
1310 phy
= PHDR_802_11_PHY_11B
;
1311 } else if (phy
== PHDR_802_11_PHY_UNKNOWN
&&
1312 (data_rate
== 1.0f
|| data_rate
== 2.0f
||
1313 data_rate
== 5.5f
|| data_rate
== 11.0f
||
1314 data_rate
== 22.0f
|| data_rate
== 33.0f
)) {
1315 phy
= PHDR_802_11_PHY_11B
;
1316 } else if (phy
== PHDR_802_11_PHY_UNKNOWN
&&
1317 (data_rate
== 6.0f
|| data_rate
== 9.0f
||
1318 data_rate
== 12.0f
|| data_rate
== 18.0f
||
1319 data_rate
== 24.0f
|| data_rate
== 36.0f
||
1320 data_rate
== 48.0f
|| data_rate
== 54.0f
)) {
1321 phy
= PHDR_802_11_PHY_11A
;
1325 case PHDR_802_11_PHY_11_FHSS
:
1326 /* TODO: preamble/duration calc for FHSS */
1329 case PHDR_802_11_PHY_11B
:
1330 if (!has_short_preamble
|| wlan_radio_always_short_preamble
) {
1331 assumed_short_preamble
= true;
1332 short_preamble
= true;
1334 preamble
= short_preamble
? 72 + 24 : 144 + 48;
1336 /* calculation of frame duration
1337 * Things we need to know to calculate accurate duration
1338 * 802.11 / 802.11b (DSSS or CCK modulation)
1339 * - length of preamble
1342 /* round up to whole microseconds */
1343 have_duration
= true;
1344 duration
= (unsigned) ceil(preamble
+ frame_length
* 8 / data_rate
);
1347 case PHDR_802_11_PHY_11A
:
1348 case PHDR_802_11_PHY_11G
:
1351 /* calculation of frame duration
1352 * Things we need to know to calculate accurate duration
1353 * 802.11a / 802.11g (OFDM modulation)
1357 /* preamble + signal */
1360 /* 16 service bits, data and 6 tail bits */
1361 unsigned bits
= 16 + 8 * frame_length
+ 6;
1362 unsigned symbols
= (unsigned) ceil(bits
/ (data_rate
* 4));
1364 have_duration
= true;
1365 duration
= preamble
+ symbols
* 4;
1369 case PHDR_802_11_PHY_11N
:
1371 struct ieee_802_11n
*info_n
= &phy_info
->info_11n
;
1373 /* We have all the fields required to calculate the duration */
1374 static const unsigned Nhtdltf
[4] = {1, 2, 4, 4};
1375 static const unsigned Nhteltf
[4] = {0, 1, 2, 4};
1377 unsigned stbc_streams
;
1381 * If we don't have necessary fields, or if we have them but
1382 * they have invalid values, then bail.
1384 if (!info_n
->has_mcs_index
||
1385 info_n
->mcs_index
> MAX_MCS_INDEX
||
1386 !info_n
->has_bandwidth
||
1387 !info_n
->has_short_gi
)
1390 /* calculation of frame duration
1391 * Things we need to know to calculate accurate duration
1393 * - whether frame preamble is mixed or greenfield, (assume mixed)
1394 * - guard interval, 800ns or 400ns
1395 * - bandwidth, 20Mhz or 40Mhz
1396 * - MCS index - used with previous 2 to calculate rate
1397 * - how many additional STBC streams are used (assume 0)
1398 * - how many optional extension spatial streams are used (assume 0)
1399 * - whether BCC or LDCP coding is used (assume BCC)
1402 /* preamble duration
1403 * see ieee802.11n-2009 Figure 20-1 - PPDU format
1404 * for HT-mixed format
1405 * L-STF 8us, L-LTF 8us, L-SIG 4us, HT-SIG 8us, HT_STF 4us
1407 * HT-GF-STF 8us, HT-LTF1 8us, HT_SIG 8us
1409 if (info_n
->has_greenfield
) {
1410 preamble
= info_n
->greenfield
? 24 : 32;
1413 assumed_non_greenfield
= true;
1416 if (info_n
->has_stbc_streams
) {
1417 stbc_streams
= info_n
->stbc_streams
;
1420 assumed_no_stbc
= true;
1423 if (info_n
->has_ness
) {
1424 ness
= info_n
->ness
;
1425 if (ness
>= G_N_ELEMENTS(Nhteltf
)) {
1431 assumed_no_extension_streams
= true;
1434 /* calculate number of HT-LTF training symbols.
1435 * see ieee80211n-2009 20.3.9.4.6 table 20-11 */
1436 Nsts
= ieee80211_ht_streams
[info_n
->mcs_index
] + stbc_streams
;
1437 if (Nsts
== 0 || Nsts
- 1 >= G_N_ELEMENTS(Nhtdltf
)) {
1441 preamble
+= 4 * (Nhtdltf
[Nsts
-1] + Nhteltf
[ness
]);
1443 if (info_n
->has_stbc_streams
) {
1444 stbc_streams
= info_n
->stbc_streams
;
1447 assumed_no_stbc
= true;
1450 if (!info_n
->has_ness
) {
1451 assumed_no_extension_streams
= true;
1454 if (!info_n
->has_fec
) {
1455 assumed_bcc_fec
= true;
1458 /* data field calculation */
1459 if (wlan_radio_info
&& wlan_radio_info
->aggregate
) {
1460 agg_preamble
= preamble
;
1461 if (wlan_radio_info
->prior_aggregate_data
!= 0) {
1464 prior_duration
= calculate_11n_duration(wlan_radio_info
->prior_aggregate_data
, info_n
, stbc_streams
);
1465 have_duration
= true;
1466 duration
= preamble
+
1467 calculate_11n_duration(frame_length
+ wlan_radio_info
->prior_aggregate_data
, info_n
, stbc_streams
)
1470 have_duration
= true;
1471 duration
= preamble
+ calculate_11n_duration(frame_length
, info_n
, stbc_streams
);
1476 case PHDR_802_11_PHY_11AC
:
1478 struct ieee_802_11ac
*info_ac
= &phy_info
->info_11ac
;
1480 if (!info_ac
->has_stbc
) {
1481 assumed_no_stbc
= true;
1483 preamble
= 32 + 4 * info_ac
->nss
[0] * (info_ac
->has_stbc
? info_ac
->stbc
+1 : 1);
1485 if (wlan_radio_info
&& wlan_radio_info
->aggregate
) {
1486 agg_preamble
= preamble
;
1487 if (wlan_radio_info
->prior_aggregate_data
!= 0) {
1490 prior_duration
= calculate_11ac_duration(wlan_radio_info
->prior_aggregate_data
, data_rate
);
1491 have_duration
= true;
1492 duration
= preamble
+
1493 calculate_11ac_duration(wlan_radio_info
->prior_aggregate_data
+ frame_length
, data_rate
)
1496 have_duration
= true;
1497 duration
= preamble
+ calculate_11ac_duration(frame_length
, data_rate
);
1503 if (!pinfo
->fd
->visited
&& have_duration
&& phdr
->has_tsf_timestamp
) {
1504 if (current_aggregate
) {
1505 current_aggregate
->duration
= agg_preamble
+ prior_duration
+ duration
;
1506 if (previous_frame
.radio_info
&& previous_frame
.radio_info
->aggregate
== current_aggregate
)
1507 previous_frame
.radio_info
->nav
= 0; // don't display NAV except for last frame in an aggregate
1509 if (phdr
->tsf_timestamp
== UINT64_MAX
) {
1510 /* QCA aggregate, we don't know tsf yet */
1511 wlan_radio_info
->start_tsf
= prior_duration
+ (current_aggregate
? agg_preamble
: 0);
1512 wlan_radio_info
->end_tsf
= prior_duration
+ duration
+ (current_aggregate
? agg_preamble
: 0);
1513 if (agg_tracker_list
== NULL
) {
1514 agg_tracker_list
= wmem_list_new(NULL
);
1516 wmem_list_append(agg_tracker_list
, wlan_radio_info
);
1517 } else if (current_aggregate
&& wlan_radio_tsf_at_end
&& phdr
->tsf_timestamp
!= UINT64_MAX
) {
1518 /* QCA aggregate, last frame */
1519 wlan_radio_info
->start_tsf
= phdr
->tsf_timestamp
- duration
;
1520 wlan_radio_info
->end_tsf
= phdr
->tsf_timestamp
;
1521 /* fix up the tsfs for the prior MPDUs */
1522 if (agg_tracker_list
!= NULL
) {
1523 uint64_t ppdu_start
= phdr
->tsf_timestamp
- (prior_duration
+ duration
+ agg_preamble
);
1524 wmem_list_foreach(agg_tracker_list
, adjust_agg_tsf
, &ppdu_start
);
1525 wmem_destroy_list(agg_tracker_list
);
1526 agg_tracker_list
= NULL
;
1528 } else if (wlan_radio_tsf_at_end
) {
1529 wlan_radio_info
->start_tsf
= phdr
->tsf_timestamp
- duration
;
1530 wlan_radio_info
->end_tsf
= phdr
->tsf_timestamp
;
1532 wlan_radio_info
->start_tsf
= phdr
->tsf_timestamp
+ prior_duration
- preamble
;
1533 wlan_radio_info
->end_tsf
= phdr
->tsf_timestamp
+ prior_duration
+ duration
- preamble
;
1535 if ((pinfo
->fd
->num
> 1) && (previous_frame
.radio_info
!= NULL
)) {
1536 /* TODO handle intermediate packets without end_tsf correctly */
1537 wlan_radio_info
->ifs
= wlan_radio_info
->start_tsf
- previous_frame
.radio_info
->end_tsf
;
1539 if (tvb_captured_length(tvb
) >= 4) {
1541 * Duration/ID field.
1543 int nav
= tvb_get_letohs(tvb
, 2);
1544 if ((nav
& 0x8000) == 0) {
1546 wlan_radio_info
->nav
= nav
;
1549 if (phdr
->has_signal_dbm
) {
1550 wlan_radio_info
->rssi
= phdr
->signal_dbm
;
1551 if (current_aggregate
)
1552 current_aggregate
->rssi
= phdr
->signal_dbm
;
1556 if (have_duration
) {
1557 proto_item
*item
= proto_tree_add_uint(radio_tree
, hf_wlan_radio_duration
, tvb
, 0, 0, duration
);
1558 proto_tree
*d_tree
= proto_item_add_subtree(item
, ett_wlan_radio_duration
);
1559 proto_item_set_generated(item
);
1561 if (assumed_short_preamble
)
1562 expert_add_info(pinfo
, item
, &ei_wlan_radio_assumed_short_preamble
);
1563 if (assumed_non_greenfield
)
1564 expert_add_info(pinfo
, item
, &ei_wlan_radio_assumed_non_greenfield
);
1565 if (assumed_no_stbc
)
1566 expert_add_info(pinfo
, item
, &ei_wlan_radio_assumed_no_stbc
);
1567 if (assumed_no_extension_streams
)
1568 expert_add_info(pinfo
, item
, &ei_wlan_radio_assumed_no_extension_streams
);
1569 if (assumed_bcc_fec
)
1570 expert_add_info(pinfo
, item
, &ei_wlan_radio_assumed_bcc_fec
);
1573 p_item
= proto_tree_add_uint(d_tree
, hf_wlan_radio_preamble
, tvb
, 0, 0, preamble
);
1574 proto_item_set_generated(p_item
);
1576 if (wlan_radio_info
) {
1577 if (wlan_radio_info
->aggregate
) {
1578 proto_tree
*agg_tree
;
1580 p_item
= proto_tree_add_none_format(d_tree
, hf_wlan_radio_aggregate
, tvb
, 0, 0,
1581 "This MPDU is part of an A-MPDU");
1582 agg_tree
= proto_item_add_subtree(item
, ett_wlan_radio_aggregate
);
1583 proto_item_set_generated(p_item
);
1584 if (wlan_radio_info
->aggregate
->duration
) {
1585 proto_item
*aitem
= proto_tree_add_uint(agg_tree
, hf_wlan_radio_aggregate_duration
, tvb
, 0, 0,
1586 wlan_radio_info
->aggregate
->duration
);
1587 proto_item_set_generated(aitem
);
1590 if (wlan_radio_info
->ifs
) {
1591 p_item
= proto_tree_add_int64(d_tree
, hf_wlan_radio_ifs
, tvb
, 0, 0, wlan_radio_info
->ifs
);
1592 proto_item_set_generated(p_item
);
1593 /* TODO: warnings on unusual IFS values (too small or negative) */
1595 if (wlan_radio_info
->start_tsf
) {
1596 p_item
= proto_tree_add_uint64(d_tree
, hf_wlan_radio_start_tsf
, tvb
, 0, 0, wlan_radio_info
->start_tsf
);
1597 proto_item_set_generated(p_item
);
1599 if (wlan_radio_info
->end_tsf
) {
1600 p_item
= proto_tree_add_uint64(d_tree
, hf_wlan_radio_end_tsf
, tvb
, 0, 0, wlan_radio_info
->end_tsf
);
1601 proto_item_set_generated(p_item
);
1605 } /* if (have_data_rate) */
1606 if (phdr
->has_zero_length_psdu_type
)
1607 proto_tree_add_uint(radio_tree
, hf_wlan_zero_length_psdu_type
, tvb
, 0, 0, phdr
->zero_length_psdu_type
);
1609 tap_queue_packet(wlan_radio_tap
, pinfo
, phdr
);
1610 if (wlan_radio_timeline_enabled
) {
1611 tap_queue_packet(wlan_radio_timeline_tap
, pinfo
, wlan_radio_info
);
1614 if (!pinfo
->fd
->visited
) {
1615 previous_frame
.radio_info
= wlan_radio_info
;
1620 * Dissect 802.11 with a variable-length link-layer header and a pseudo-
1621 * header containing radio information.
1624 dissect_wlan_radio (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void *data
)
1626 struct ieee_802_11_phdr
*phdr
= (struct ieee_802_11_phdr
*)data
;
1628 dissect_wlan_radio_phdr(tvb
, pinfo
, tree
, phdr
);
1630 /* Is there anything there? A 0-length-psdu has no frame data. */
1631 if (phdr
->has_zero_length_psdu_type
)
1632 return tvb_captured_length(tvb
);
1634 /* dissect the 802.11 packet next */
1635 return call_dissector_with_data(ieee80211_handle
, tvb
, pinfo
, tree
, data
);
1639 * Dissect 802.11 with a variable-length link-layer header without qos elements and
1640 * a pseudo-header containing radio information.
1643 dissect_wlan_noqos_radio (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void *data
)
1645 struct ieee_802_11_phdr
*phdr
= (struct ieee_802_11_phdr
*)data
;
1647 dissect_wlan_radio_phdr(tvb
, pinfo
, tree
, phdr
);
1649 /* Is there anything there? A 0-length-psdu has no frame data. */
1650 if (phdr
->has_zero_length_psdu_type
)
1651 return tvb_captured_length(tvb
);
1653 /* dissect the 802.11 packet next */
1654 return call_dissector_with_data(ieee80211_noqos_handle
, tvb
, pinfo
, tree
, data
);
1658 setup_ieee80211_radio(void)
1660 /* start of a new dissection, initialize state variables */
1661 current_aggregate
= NULL
;
1662 agg_tracker_list
= NULL
;
1663 memset(&previous_frame
, 0, sizeof(previous_frame
));
1667 cleanup_ieee80211_radio(void)
1669 if (agg_tracker_list
!= NULL
) {
1670 wmem_destroy_list(agg_tracker_list
);
1671 agg_tracker_list
= NULL
;
1675 void proto_register_ieee80211_radio(void)
1677 static hf_register_info hf_wlan_radio
[] = {
1678 {&hf_wlan_radio_phy
,
1679 {"PHY type", "wlan_radio.phy", FT_UINT32
, BASE_DEC
, VALS(phy_vals
), 0,
1682 {&hf_wlan_radio_11_fhss_hop_set
,
1683 {"Hop set", "wlan_radio.fhss.hop_set", FT_UINT8
, BASE_HEX
, NULL
, 0,
1686 {&hf_wlan_radio_11_fhss_hop_pattern
,
1687 {"Hop pattern", "wlan_radio.fhss.hop_pattern", FT_UINT8
, BASE_HEX
, NULL
, 0,
1690 {&hf_wlan_radio_11_fhss_hop_index
,
1691 {"Hop index", "wlan_radio.fhss.hop_index", FT_UINT8
, BASE_HEX
, NULL
, 0,
1694 {&hf_wlan_radio_11a_channel_type
,
1695 {"Channel type", "wlan_radio.11a.channel_type", FT_UINT32
, BASE_DEC
, VALS(channel_type_11a_vals
), 0,
1698 {&hf_wlan_radio_11a_turbo_type
,
1699 {"Turbo type", "wlan_radio.11a.turbo_type", FT_UINT32
, BASE_DEC
, VALS(turbo_type_11a_vals
), 0,
1702 {&hf_wlan_radio_11g_mode
,
1703 {"Proprietary mode", "wlan_radio.11g.mode", FT_UINT32
, BASE_DEC
, VALS(mode_11g_vals
), 0,
1706 {&hf_wlan_radio_11n_mcs_index
,
1707 {"MCS index", "wlan_radio.11n.mcs_index", FT_UINT32
, BASE_DEC
, NULL
, 0,
1708 "Modulation and Coding Scheme index", HFILL
}},
1710 {&hf_wlan_radio_11n_bandwidth
,
1711 {"Bandwidth", "wlan_radio.11n.bandwidth", FT_UINT32
, BASE_DEC
, VALS(bandwidth_vals
), 0,
1714 {&hf_wlan_radio_11n_short_gi
,
1715 {"Short GI", "wlan_radio.11n.short_gi", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1718 {&hf_wlan_radio_11n_greenfield
,
1719 {"Greenfield", "wlan_radio.11n.greenfield", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1722 {&hf_wlan_radio_11n_fec
,
1723 {"FEC", "wlan_radio.11n.fec", FT_UINT32
, BASE_DEC
, VALS(fec_vals
), 0,
1726 {&hf_wlan_radio_11n_stbc_streams
,
1727 {"Number of STBC streams", "wlan_radio.11n.stbc_streams", FT_UINT32
, BASE_DEC
, NULL
, 0,
1730 {&hf_wlan_radio_11n_ness
,
1731 {"Number of extension spatial streams", "wlan_radio.11n.ness", FT_UINT32
, BASE_DEC
, NULL
, 0,
1734 {&hf_wlan_radio_11ac_stbc
,
1735 {"STBC", "wlan_radio.11ac.stbc", FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_on_off
), 0x0,
1736 "Space Time Block Coding flag", HFILL
}},
1738 {&hf_wlan_radio_11ac_txop_ps_not_allowed
,
1739 {"TXOP_PS_NOT_ALLOWED", "wlan_radio_11ac.txop_ps_not_allowed", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1740 "Flag indicating whether STAs may doze during TXOP", HFILL
}},
1742 {&hf_wlan_radio_11ac_short_gi
,
1743 {"Short GI", "wlan_radio.11ac.short_gi", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1746 {&hf_wlan_radio_11ac_short_gi_nsym_disambig
,
1747 {"Short GI Nsym disambiguation", "wlan_radio.11ac.short_gi_nsym_disambig", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1748 "Short Guard Interval Nsym disambiguation", HFILL
}},
1750 {&hf_wlan_radio_11ac_ldpc_extra_ofdm_symbol
,
1751 {"LDPC extra OFDM symbol", "wlan_radio.11ac.ldpc_extra_ofdm_symbol", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1754 {&hf_wlan_radio_11ac_beamformed
,
1755 {"Beamformed", "wlan_radio.11ac.beamformed", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1758 {&hf_wlan_radio_11ac_bandwidth
,
1759 {"Bandwidth", "wlan_radio.11ac.bandwidth", FT_UINT32
, BASE_DEC
, VALS(bandwidth_vals
), 0,
1762 {&hf_wlan_radio_11ac_user
,
1763 {"User", "wlan_radio.11ac.user", FT_NONE
, BASE_NONE
, NULL
, 0x0,
1766 {&hf_wlan_radio_11ac_nsts
,
1767 {"Space-time streams", "wlan_radio.11ac.nsts", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1768 "Number of Space-time streams", HFILL
}},
1770 {&hf_wlan_radio_11ac_mcs
,
1771 {"MCS index", "wlan_radio.11ac.mcs", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1772 "Modulation and Coding Scheme index", HFILL
}},
1774 {&hf_wlan_radio_11ac_nss
,
1775 {"Spatial streams", "wlan_radio.11ac.nss", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1776 "Number of spatial streams", HFILL
}},
1778 {&hf_wlan_radio_11ac_fec
,
1779 {"FEC", "wlan_radio.11ac.fec", FT_UINT32
, BASE_DEC
, VALS(fec_vals
), 0x0,
1780 "Type of FEC", HFILL
}},
1782 {&hf_wlan_radio_11ac_gid
,
1783 {"Group Id", "wlan_radio.11ac.gid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1786 {&hf_wlan_radio_11ac_p_aid
,
1787 {"Partial AID", "wlan_radio.11ac.paid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1790 {&hf_wlan_radio_11be_user
,
1791 {"User", "wlan_radio.11be.user", FT_NONE
, BASE_NONE
, NULL
, 0x0,
1794 {&hf_wlan_radio_11be_sta_id
,
1795 {"Sta ID", "wlan_radio.11be.sta_id", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1796 "Station ID", HFILL
}},
1798 {&hf_wlan_radio_11be_nsts
,
1799 {"Space-time streams", "wlan_radio.11be.nsts", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1800 "Number of Space-time streams", HFILL
}},
1802 {&hf_wlan_radio_11be_mcs
,
1803 {"MCS index", "wlan_radio.11be.mcs", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1804 "Modulation and Coding Scheme index", HFILL
}},
1806 {&hf_wlan_radio_data_rate
,
1807 {"Data rate", "wlan_radio.data_rate", FT_FLOAT
, BASE_NONE
, NULL
, 0,
1808 "Speed at which this frame was sent/received", HFILL
}},
1810 {&hf_wlan_radio_channel
,
1811 {"Channel", "wlan_radio.channel", FT_UINT32
, BASE_DEC
, NULL
, 0,
1812 "802.11 channel number that this frame was sent/received on", HFILL
}},
1814 {&hf_wlan_radio_frequency
,
1815 {"Frequency", "wlan_radio.frequency", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_mhz
), 0,
1816 "Center frequency of the 802.11 channel that this frame was sent/received on", HFILL
}},
1818 {&hf_wlan_radio_short_preamble
,
1819 {"Short preamble", "wlan_radio.short_preamble", FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
1822 {&hf_wlan_radio_signal_percent
,
1823 {"Signal strength (percentage)", "wlan_radio.signal_percentage", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_percent
), 0,
1824 "Signal strength, as percentage of maximum RSSI", HFILL
}},
1826 {&hf_wlan_radio_signal_db
,
1827 {"Signal strength (dB)", "wlan_radio.signal_db", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_decibels
), 0,
1830 {&hf_wlan_radio_signal_dbm
,
1831 {"Signal strength (dBm)", "wlan_radio.signal_dbm", FT_INT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_dbm
), 0,
1834 {&hf_wlan_radio_noise_percent
,
1835 {"Noise level (percentage)", "wlan_radio.noise_percentage", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_percent
), 0,
1838 {&hf_wlan_radio_noise_db
,
1839 {"Noise level (dB)", "wlan_radio.noise_db", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_decibels
), 0,
1842 {&hf_wlan_radio_noise_dbm
,
1843 {"Noise level (dBm)", "wlan_radio.noise_dbm", FT_INT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_dbm
), 0,
1846 {&hf_wlan_radio_snr
,
1847 {"Signal/noise ratio (dB)", "wlan_radio.snr", FT_INT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_decibels
), 0,
1850 {&hf_wlan_radio_timestamp
,
1851 {"TSF timestamp", "wlan_radio.timestamp", FT_UINT64
, BASE_DEC
, NULL
, 0,
1852 "Timing Synchronization Function timestamp", HFILL
}},
1854 {&hf_wlan_last_part_of_a_mpdu
,
1855 {"Last part of an A-MPDU", "wlan_radio.last_part_of_an_ampdu", FT_BOOLEAN
, 32, NULL
, PHDR_802_11_LAST_PART_OF_A_MPDU
,
1856 "This is the last part of an A-MPDU", HFILL
}},
1858 {&hf_wlan_a_mpdu_delim_crc_error
,
1859 {"A-MPDU delimiter CRC error", "wlan_radio.a_mpdu_delim_crc_error", FT_BOOLEAN
, 32, NULL
, PHDR_802_11_A_MPDU_DELIM_CRC_ERROR
,
1862 {&hf_wlan_a_mpdu_aggregate_id
,
1863 {"A-MPDU aggregate ID", "wlan_radio.a_mpdu_aggregate_id", FT_UINT32
, BASE_DEC
, NULL
, 0,
1866 {&hf_wlan_radio_duration
,
1867 {"Duration", "wlan_radio.duration", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1868 "Total duration of the frame in microseconds, including any preamble or plcp header. "
1869 "Calculated from the frame length, modulation and other phy data.", HFILL
}},
1871 {&hf_wlan_radio_preamble
,
1872 {"Preamble", "wlan_radio.preamble", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1873 "Duration of the PLCP or preamble in microseconds, calculated from PHY data", HFILL
}},
1875 {&hf_wlan_radio_aggregate
,
1876 {"A-MPDU", "wlan_radio.aggregate", FT_NONE
, BASE_NONE
, NULL
, 0,
1877 "MPDU is part of an A-MPDU", HFILL
}},
1879 {&hf_wlan_radio_ifs
,
1880 {"IFS", "wlan_radio.ifs", FT_INT64
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1881 "Inter Frame Space before this frame in microseconds, calculated from PHY data", HFILL
}},
1883 {&hf_wlan_radio_start_tsf
,
1884 {"Start", "wlan_radio.start_tsf", FT_UINT64
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1885 "Calculated start time of the frame", HFILL
}},
1887 {&hf_wlan_radio_end_tsf
,
1888 {"End", "wlan_radio.end_tsf", FT_UINT64
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1889 "Calculated end time of the frame", HFILL
}},
1891 {&hf_wlan_radio_aggregate_duration
,
1892 {"Aggregate Duration", "wlan_radio.aggregate.duration", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
1893 "Total duration of the aggregate in microseconds, including any preamble or plcp header and multiple MPDUs. "
1894 "Calculated from the total subframe lengths, modulation and other phy data, assumes no excess padding.", HFILL
}},
1896 {&hf_wlan_zero_length_psdu_type
,
1897 {"Zero-length PSDU Type", "wlan_radio.zero_len_psdu.type", FT_UINT8
, BASE_HEX
, VALS(zero_length_psdu_vals
), 0x0,
1898 "Type of zero-length PSDU", HFILL
}},
1901 static int *ett
[] = {
1903 &ett_wlan_radio_11ac_user
,
1904 &ett_wlan_radio_duration
,
1905 &ett_wlan_radio_aggregate
,
1906 &ett_wlan_radio_11be_user
,
1909 static ei_register_info ei
[] = {
1910 { &ei_wlan_radio_assumed_short_preamble
,
1911 { "wlan_radio.assumed.short_preamble", PI_ASSUMPTION
, PI_WARN
,
1912 "No preamble length information was available, assuming short preamble.", EXPFILL
}},
1914 { &ei_wlan_radio_assumed_non_greenfield
,
1915 { "wlan_radio.assumed.non_greenfield", PI_ASSUMPTION
, PI_WARN
,
1916 "No plcp type information was available, assuming non greenfield.", EXPFILL
}},
1918 { &ei_wlan_radio_assumed_no_stbc
,
1919 { "wlan_radio.assumed.no_stbc", PI_ASSUMPTION
, PI_WARN
,
1920 "No stbc information was available, assuming no stbc.", EXPFILL
}},
1922 { &ei_wlan_radio_assumed_no_extension_streams
,
1923 { "wlan_radio.assumed.no_extension_streams", PI_ASSUMPTION
, PI_WARN
,
1924 "No extension stream information was available, assuming no extension streams.", EXPFILL
}},
1926 { &ei_wlan_radio_assumed_bcc_fec
,
1927 { "wlan_radio.assumed.bcc_fec", PI_ASSUMPTION
, PI_WARN
,
1928 "No fec type information was available, assuming bcc fec.", EXPFILL
}},
1930 { &ei_wlan_radio_11be_num_users
,
1931 { "wlan_radio.11be_num_users", PI_MALFORMED
, PI_WARN
,
1932 "Number of users in the 802.11be header exceeds available slots.", EXPFILL
}},
1935 module_t
*wlan_radio_module
;
1936 expert_module_t
* expert_wlan_radio
;
1938 proto_wlan_radio
= proto_register_protocol("802.11 radio information", "802.11 Radio", "wlan_radio");
1939 proto_register_field_array(proto_wlan_radio
, hf_wlan_radio
, array_length(hf_wlan_radio
));
1940 proto_register_subtree_array(ett
, array_length(ett
));
1942 expert_wlan_radio
= expert_register_protocol(proto_wlan_radio
);
1943 expert_register_field_array(expert_wlan_radio
, ei
, array_length(ei
));
1945 wlan_radio_handle
= register_dissector("wlan_radio", dissect_wlan_radio
, proto_wlan_radio
);
1946 wlan_noqos_radio_handle
= register_dissector("wlan_noqos_radio", dissect_wlan_noqos_radio
, proto_wlan_radio
);
1948 wlan_radio_module
= prefs_register_protocol(proto_wlan_radio
, NULL
);
1949 prefs_register_bool_preference(wlan_radio_module
, "always_short_preamble",
1950 "802.11/11b preamble length is always short",
1951 "Some generators incorrectly indicate long preamble when the preamble was actually"
1952 "short. Always assume short preamble when calculating duration.",
1953 &wlan_radio_always_short_preamble
);
1954 prefs_register_bool_preference(wlan_radio_module
, "tsf_at_end",
1955 "TSF indicates the end of the PPDU",
1956 "Some generators timestamp the end of the PPDU rather than the start of the (A)MPDU.",
1957 &wlan_radio_tsf_at_end
);
1958 prefs_register_bool_preference(wlan_radio_module
, "timeline",
1959 "Enable Wireless Timeline (experimental)",
1960 "Enables an additional panel for navigating through packets",
1961 &wlan_radio_timeline_enabled
);
1963 register_init_routine( setup_ieee80211_radio
);
1964 register_cleanup_routine( cleanup_ieee80211_radio
);
1966 wlan_radio_tap
= register_tap("wlan_radio");
1967 wlan_radio_timeline_tap
= register_tap("wlan_radio_timeline");
1970 void proto_reg_handoff_ieee80211_radio(void)
1972 /* Register handoff to radio-header dissectors */
1973 dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO
,
1975 ieee80211_handle
= find_dissector_add_dependency("wlan", proto_wlan_radio
);
1976 ieee80211_noqos_handle
= find_dissector_add_dependency("wlan_noqos", proto_wlan_radio
);
1985 * indent-tabs-mode: nil
1988 * ex: set shiftwidth=2 tabstop=8 expandtab:
1989 * :indentSize=2:tabSize=8:noTabs=true: