MCSInfo.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 #include "MCSInfo.hh"
15 
16 // Custom includes
17 #include <senf/Utils/senfassert.hh>
18 #include <senf/Utils/senflikely.hh>
19 
20 #define prefix_
21 //-/////////////////////////////////////////////////////////////////////////////////////////////////
22 
23 namespace {
24 
25 // http://mcsindex.com/
26 static senf::WLAN_MCSInfo::Info mcsInfos[] = {
27 // bandwidth: 20 MHz 40 MHz 80 MHz 160 MHz 20 40 80 160 I S
28 // GI: 800 ns 400 ns 800 ns 400 ns 800 ns 400 ns 800 ns 400 ns
29  { "BPSK_1/2", { 6500, 7200, 13500, 15000, 29300, 32500, 58500, 65000 }, { -82, -79, -76, -73 }, 0, 1 },
30  { "QPSK_1/2", { 13000, 14400, 27000, 30000, 58500, 65000, 117000, 130000 }, { -79, -76, -73, -70 }, 1, 1 },
31  { "QPSK_3/4", { 19500, 21700, 40500, 45000, 87800, 97500, 175500, 195000 }, { -77, -74, -71, -68 }, 2, 1 },
32  { "16QAM_1/2", { 26000, 28900, 54000, 60000, 117000, 130000, 234000, 260000 }, { -74, -71, -71, -68 }, 3, 1 },
33  { "16QAM_3/4", { 39000, 43300, 81000, 90000, 175500, 195300, 351000, 390000 }, { -70, -67, -64, -61 }, 4, 1 },
34  { "64QAM_2/3", { 52000, 57800, 108000, 120000, 234000, 260000, 468000, 520000 }, { -66, -63, -60, -57 }, 5, 1 },
35  { "64QAM_3/4", { 58500, 65000, 121500, 135000, 263300, 292500, 526500, 585000 }, { -65, -62, -59, -56 }, 6, 1 },
36  { "64QAM_5/6", { 65000, 72200, 135000, 150000, 292500, 325000, 585000, 650000 }, { -64, -61, -58, -55 }, 7, 1 },
37  { "256QAM_3/4", { 78500, 86700, 162000, 180000, 351000, 390000, 702000, 780000 }, { -62, -59, -56, -53 }, 8, 1 },
38  { "256QAM_5/6", { 0, 0, 180000, 200000, 390000, 433300, 780000, 866700 }, { -60, -57, -54, -51 }, 9, 1 },
39  { "1024QAM_3/4", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -57, -54, -51, -48 }, 10, 1 },
40  { "1024QAM_5/6", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -55, -52, -49, -46 }, 11, 1 },
41 
42  { "BPSK_1/2", { 13000, 14400, 27000, 30000, 58500, 65000, 117000, 130000 }, { -82, -79, -76, -73 }, 0, 2 },
43  { "QPSK_1/2", { 26000, 28900, 54000, 60000, 117000, 130000, 234000, 260000 }, { -79, -76, -73, -70 }, 1, 2 },
44  { "QPSK_3/4", { 39000, 43300, 81000, 90000, 175500, 195000, 351000, 390000 }, { -77, -74, -71, -68 }, 2, 2 },
45  { "16QAM_1/2", { 52000, 57800, 108000, 120000, 234000, 260000, 468000, 520000 }, { -74, -71, -71, -68 }, 3, 2 },
46  { "16QAM_3/4", { 78000, 86700, 162000, 180000, 351000, 390000, 702000, 780000 }, { -70, -67, -64, -61 }, 4, 2 },
47  { "64QAM_2/3", { 104000, 115600, 216000, 240000, 468000, 520000, 936000, 1040000 }, { -66, -63, -60, -57 }, 5, 2 },
48  { "64QAM_3/4", { 117000, 130000, 243000, 270000, 526500, 585000, 1053000, 1170000 }, { -65, -62, -59, -56 }, 6, 2 },
49  { "64QAM_5/6", { 130000, 144400, 270000, 300000, 585000, 650000, 1170000, 1300000 }, { -64, -61, -58, -55 }, 7, 2 },
50  { "256QAM_3/4", { 156000, 173300, 324000, 360000, 702000, 780000, 1404000, 1560000 }, { -62, -59, -56, -53 }, 8, 2 },
51  { "256QAM_5/6", { 0, 0, 360000, 400000, 780000, 866700, 1560000, 1733400 }, { -60, -57, -54, -51 }, 9, 2 },
52  { "1024QAM_3/4", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -57, -54, -51, -48 }, 10, 2 },
53  { "1024QAM_5/6", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -55, -52, -49, -46 }, 11, 2 },
54 
55  { "BPSK_1/2", { 19500, 21700, 40500, 45000, 87800, 97500, 175500, 195000 }, { -82, -79, -76, -73 }, 0, 3 },
56  { "QPSK_1/2", { 39000, 43300, 81000, 90000, 175500, 195000, 351000, 390000 }, { -79, -76, -73, -70 }, 1, 3 },
57  { "QPSK_3/4", { 58500, 65000, 121500, 135000, 263300, 292500, 526500, 585000 }, { -77, -74, -71, -68 }, 2, 3 },
58  { "16QAM_1/2", { 78000, 86700, 162000, 180000, 351000, 390000, 702000, 780000 }, { -74, -71, -71, -68 }, 3, 3 },
59  { "16QAM_3/4", { 117000, 130700, 243000, 270000, 526500, 585000, 1053000, 1170000 }, { -70, -67, -64, -61 }, 4, 3 },
60  { "64QAM_2/3", { 156000, 173300, 324000, 360000, 702000, 780000, 1404000, 1560000 }, { -66, -63, -60, -57 }, 5, 3 },
61  { "64QAM_3/4", { 175500, 195000, 364500, 405000, 0, 0, 1579500, 1755000 }, { -65, -62, -59, -56 }, 6, 3 },
62  { "64QAM_5/6", { 195000, 216700, 405000, 450000, 877500, 975000, 1755000, 1950000 }, { -64, -61, -58, -55 }, 7, 3 },
63  { "256QAM_3/4", { 234000, 260000, 486000, 540000, 1053000, 117000, 2106000, 2340000 }, { -62, -59, -56, -53 }, 8, 3 },
64  { "256QAM_5/6", { 260000, 288900, 540000, 600000, 1170000, 130000, 0, 0 }, { -60, -57, -54, -51 }, 9, 3 },
65  { "1024QAM_3/4", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -57, -54, -51, -48 }, 10, 3 },
66  { "1024QAM_5/6", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -55, -52, -49, -46 }, 11, 3 },
67 
68  { "BPSK_1/2", { 26000, 28800, 54000, 60000, 117000, 130000, 234000, 260000 }, { -82, -79, -76, -73 }, 0, 4 },
69  { "QPSK_1/2", { 52000, 57600, 108000, 120000, 234000, 260000, 468000, 520000 }, { -79, -76, -73, -70 }, 1, 4 },
70  { "QPSK_3/4", { 78000, 86800, 162000, 180000, 351000, 390000, 702000, 780000 }, { -77, -74, -71, -68 }, 2, 4 },
71  { "16QAM_1/2", { 104000, 115600, 216000, 240000, 468000, 520000, 936000, 1040000 }, { -74, -71, -71, -68 }, 3, 4 },
72  { "16QAM_3/4", { 156000, 173200, 324000, 360000, 702000, 780000, 1404000, 1560000 }, { -70, -67, -64, -61 }, 4, 4 },
73  { "64QAM_2/3", { 208000, 231200, 432000, 480000, 936000, 1040000, 1872000, 2080000 }, { -66, -63, -60, -57 }, 5, 4 },
74  { "64QAM_3/4", { 234000, 260000, 486000, 540000, 1053000, 1170000, 2106000, 2340000 }, { -65, -62, -59, -56 }, 6, 4 },
75  { "64QAM_5/6", { 260000, 288800, 540000, 600000, 1170000, 1300000, 2340000, 2600000 }, { -64, -61, -58, -55 }, 7, 4 },
76  { "256QAM_3/4", { 312000, 346700, 648000, 720000, 1404000, 1560000, 2808000, 3120000 }, { -62, -59, -56, -53 }, 8, 4 },
77  { "256QAM_5/6", { 0, 0, 720000, 800000, 1560000, 1733300, 3120000, 3466700 }, { -60, -57, -54, -51 }, 9, 4 },
78  { "1024QAM_3/4", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -57, -54, -51, -48 }, 10, 4 },
79  { "1024QAM_5/6", { 0, 0, 0, 0, 0, 0, 0, 0 }, { -55, -52, -49, -46 }, 11, 4 }
80 };
81 
82 }
83 
84 prefix_ std::vector<senf::WLAN_MCSInfo::Info> senf::WLAN_MCSInfo::getInfos()
85 {
86  return std::vector<Info>(mcsInfos, mcsInfos + sizeof(mcsInfos) / sizeof(Info));
87 }
88 
89 prefix_ unsigned senf::WLAN_MCSInfo::getRate(std::uint8_t mcsIndex, unsigned bandwidth, bool shortGI)
90 {
91  if (SENF_UNLIKELY(mcsIndex >= (NUM_STREAMS * NUM_HT_INDEX) or bandwidth > 40))
92  return 0;
93  auto tmp (fromHTIndex(mcsIndex));
94  return getRate(tmp.first, tmp.second, bandwidth, shortGI);
95 }
96 
97 prefix_ unsigned senf::WLAN_MCSInfo::getRate(std::uint8_t index, std::uint8_t streams, unsigned bandwidth, bool shortGI)
98 {
99  if (SENF_UNLIKELY(index >= MAX_INDEX or streams == 0 or streams > NUM_STREAMS))
100  return 0;
101  return mcsInfos[(streams-1) * MAX_INDEX + index].rate[toBandwidthIndex(bandwidth, shortGI)];
102 }
103 
104 prefix_ std::uint8_t senf::WLAN_MCSInfo::toHTIndex(std::uint8_t index, std::uint8_t streams)
105 {
106  if (SENF_UNLIKELY(index >= NUM_HT_INDEX or streams == 0 or streams > NUM_STREAMS))
107  return 0;
108  return (streams-1) * NUM_HT_INDEX + index;
109 }
110 
111 prefix_ std::pair<std::uint8_t,std::uint8_t> senf::WLAN_MCSInfo::fromHTIndex(std::uint8_t mcsIndex)
112 {
113  return std::make_pair(mcsIndex % NUM_HT_INDEX, (mcsIndex / NUM_HT_INDEX) + 1);
114 }
115 
116 prefix_ std::uint8_t senf::WLAN_MCSInfo::toBandwidthIndex(unsigned bandwidth, bool shortGI)
117 {
118  switch (bandwidth) {
119  case 20000:
120  return 0 + shortGI;
121  case 40000:
122  return 2 + shortGI;
123  case 80000:
124  return 4 + shortGI;
125  case 160000:
126  return 6 + shortGI;
127  default:
128  return 0;
129  }
130 }
131 
132 prefix_ unsigned senf::WLAN_MCSInfo::fromBandwidthIndex(std::uint8_t bandwidthIndex)
133 {
134  switch (bandwidthIndex) {
135  case 0:
136  case 1:
137  return 20000;
138  case 2:
139  case 3:
140  return 40000;
141  case 4:
142  case 5:
143  return 80000;
144  case 6:
145  case 7:
146  return 160000;
147  default:
148  return 0;
149  }
150 }
151 
152 
153 //-/////////////////////////////////////////////////////////////////////////////////////////////////
154 #undef prefix_
static unsigned getRate(std::uint8_t mcsIndex, unsigned bandwidth, bool shortGI)
Definition: MCSInfo.cc:89
#define prefix_
Definition: MCSInfo.cc:20
static constexpr unsigned NUM_HT_INDEX
Definition: MCSInfo.hh:29
static std::pair< std::uint8_t, std::uint8_t > fromHTIndex(std::uint8_t mcsIndex)
Definition: MCSInfo.cc:111
static constexpr unsigned MAX_INDEX
Definition: MCSInfo.hh:31
static constexpr unsigned NUM_STREAMS
Definition: MCSInfo.hh:28
static std::uint8_t toHTIndex(std::uint8_t index, std::uint8_t streams)
Definition: MCSInfo.cc:104
static std::vector< Info > getInfos()
Definition: MCSInfo.cc:84
static std::uint8_t toBandwidthIndex(unsigned bandwidth, bool shortGI=false)
Definition: MCSInfo.cc:116
#define SENF_UNLIKELY(x)
static unsigned fromBandwidthIndex(std::uint8_t bandwidthIndex)
Definition: MCSInfo.cc:132