1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2021
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "wifi-phy-common.h"
22 #include "wifi-mode.h"
23 #include "wifi-net-device.h"
24 #include "ns3/ht-configuration.h"
25 #include "ns3/he-configuration.h"
26 
27 namespace ns3 {
28 
29 uint16_t
ConvertGuardIntervalToNanoSeconds(WifiMode mode,const Ptr<WifiNetDevice> device)30 ConvertGuardIntervalToNanoSeconds (WifiMode mode, const Ptr<WifiNetDevice> device)
31 {
32   uint16_t gi = 800;
33   if (mode.GetModulationClass () == WIFI_MOD_CLASS_HE)
34     {
35       Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
36       NS_ASSERT (heConfiguration); //If HE modulation is used, we should have a HE configuration attached
37       gi = static_cast<uint16_t> (heConfiguration->GetGuardInterval ().GetNanoSeconds ());
38     }
39   else if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
40     {
41       Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
42       NS_ASSERT (htConfiguration); //If HT/VHT modulation is used, we should have a HT configuration attached
43       gi = htConfiguration->GetShortGuardIntervalSupported () ? 400 : 800;
44     }
45   return gi;
46 }
47 
48 uint16_t
ConvertGuardIntervalToNanoSeconds(WifiMode mode,bool htShortGuardInterval,Time heGuardInterval)49 ConvertGuardIntervalToNanoSeconds (WifiMode mode, bool htShortGuardInterval, Time heGuardInterval)
50 {
51   uint16_t gi;
52   if (mode.GetModulationClass () == WIFI_MOD_CLASS_HE)
53     {
54       gi = static_cast<uint16_t> (heGuardInterval.GetNanoSeconds ());
55     }
56   else if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
57     {
58       gi = htShortGuardInterval ? 400 : 800;
59     }
60   else
61     {
62       gi = 800;
63     }
64   return gi;
65 }
66 
67 uint16_t
GetChannelWidthForTransmission(WifiMode mode,uint16_t maxSupportedChannelWidth)68 GetChannelWidthForTransmission (WifiMode mode, uint16_t maxSupportedChannelWidth)
69 {
70   WifiModulationClass modulationClass = mode.GetModulationClass ();
71   if (maxSupportedChannelWidth > 20
72       && (modulationClass == WifiModulationClass::WIFI_MOD_CLASS_OFDM // all non-HT OFDM control and management frames
73           || modulationClass == WifiModulationClass::WIFI_MOD_CLASS_ERP_OFDM)) // special case of beacons at 2.4 GHz
74     {
75       return 20;
76     }
77   //at 2.4 GHz basic rate can be non-ERP DSSS
78   if (modulationClass == WifiModulationClass::WIFI_MOD_CLASS_DSSS
79       || modulationClass == WifiModulationClass::WIFI_MOD_CLASS_HR_DSSS)
80     {
81       return 22;
82     }
83   return maxSupportedChannelWidth;
84 }
85 
86 WifiPreamble
GetPreambleForTransmission(WifiModulationClass modulation,bool useShortPreamble)87 GetPreambleForTransmission (WifiModulationClass modulation, bool useShortPreamble)
88 {
89   if (modulation == WIFI_MOD_CLASS_HE)
90     {
91       return WIFI_PREAMBLE_HE_SU;
92     }
93   else if (modulation == WIFI_MOD_CLASS_VHT)
94     {
95       return WIFI_PREAMBLE_VHT_SU;
96     }
97   else if (modulation == WIFI_MOD_CLASS_HT)
98     {
99       return WIFI_PREAMBLE_HT_MF; // HT_GF has been removed
100     }
101   else if (modulation == WIFI_MOD_CLASS_HR_DSSS && useShortPreamble) //ERP_DSSS is modeled through HR_DSSS (since same preamble and modulation)
102     {
103       return WIFI_PREAMBLE_SHORT;
104     }
105   else
106     {
107       return WIFI_PREAMBLE_LONG;
108     }
109 }
110 
111 bool
IsAllowedControlAnswerModulationClass(WifiModulationClass modClassReq,WifiModulationClass modClassAnswer)112 IsAllowedControlAnswerModulationClass (WifiModulationClass modClassReq, WifiModulationClass modClassAnswer)
113 {
114   switch (modClassReq)
115     {
116     case WIFI_MOD_CLASS_DSSS:
117       return (modClassAnswer == WIFI_MOD_CLASS_DSSS);
118     case WIFI_MOD_CLASS_HR_DSSS:
119       return (modClassAnswer == WIFI_MOD_CLASS_DSSS || modClassAnswer == WIFI_MOD_CLASS_HR_DSSS);
120     case WIFI_MOD_CLASS_ERP_OFDM:
121       return (modClassAnswer == WIFI_MOD_CLASS_DSSS || modClassAnswer == WIFI_MOD_CLASS_HR_DSSS || modClassAnswer == WIFI_MOD_CLASS_ERP_OFDM);
122     case WIFI_MOD_CLASS_OFDM:
123       return (modClassAnswer == WIFI_MOD_CLASS_OFDM);
124     case WIFI_MOD_CLASS_HT:
125     case WIFI_MOD_CLASS_VHT:
126     case WIFI_MOD_CLASS_HE:
127       return true;
128     default:
129       NS_FATAL_ERROR ("Modulation class not defined");
130       return false;
131     }
132 }
133 
134 Time
GetPpduMaxTime(WifiPreamble preamble)135 GetPpduMaxTime (WifiPreamble preamble)
136 {
137   Time duration;
138 
139   switch (preamble)
140     {
141       case WIFI_PREAMBLE_HT_MF:
142       case WIFI_PREAMBLE_VHT_SU:
143       case WIFI_PREAMBLE_VHT_MU:
144       case WIFI_PREAMBLE_HE_SU:
145       case WIFI_PREAMBLE_HE_ER_SU:
146       case WIFI_PREAMBLE_HE_MU:
147       case WIFI_PREAMBLE_HE_TB:
148         duration = MicroSeconds (5484);
149         break;
150       default:
151         duration = MicroSeconds (0);
152         break;
153     }
154   return duration;
155 }
156 
157 bool
IsMu(WifiPreamble preamble)158 IsMu (WifiPreamble preamble)
159 {
160   return (IsDlMu (preamble) || IsUlMu (preamble));
161 }
162 
163 bool
IsDlMu(WifiPreamble preamble)164 IsDlMu (WifiPreamble preamble)
165 {
166   return (preamble == WIFI_PREAMBLE_HE_MU);
167 }
168 
169 bool
IsUlMu(WifiPreamble preamble)170 IsUlMu (WifiPreamble preamble)
171 {
172   return (preamble == WIFI_PREAMBLE_HE_TB);
173 }
174 
175 } //namespace ns3
176