A Discrete-Event Network Simulator
API
wifi-phy-operating-channel.cc
Go to the documentation of this file.
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  * Authors: Stefano Avallone <stavallo@unina.it>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include "ns3/log.h"
23 #include "wifi-phy.h"
24 #include <algorithm>
25 
26 namespace ns3 {
27 
28 NS_LOG_COMPONENT_DEFINE ("WifiPhyOperatingChannel");
29 
31  : m_channelIt (WifiPhy::m_frequencyChannels.end ()),
32  m_primary20Index (0)
33 {
34  NS_LOG_FUNCTION (this);
35 }
36 
38 {
40 }
41 
42 bool
44 {
46 }
47 
48 void
49 WifiPhyOperatingChannel::Set (uint8_t number, uint16_t frequency, uint16_t width,
50  WifiPhyStandard standard, WifiPhyBand band)
51 {
52  NS_LOG_FUNCTION (this << +number << frequency << width << standard << band);
53 
54  auto channelIt = FindFirst (number, frequency, width, standard, band, WifiPhy::m_frequencyChannels.begin ());
55 
56  if (channelIt != WifiPhy::m_frequencyChannels.end ()
57  && FindFirst (number, frequency, width, standard, band, std::next (channelIt))
59  {
60  // a unique channel matches the specified criteria
61  m_channelIt = channelIt;
62  m_primary20Index = 0;
63  return;
64  }
65 
66  // if a unique channel was not found, throw an exception (mainly for unit testing this code)
67  throw std::runtime_error ("WifiPhyOperatingChannel: No unique channel found given the specified criteria");
68 }
69 
70 void
72 {
73  NS_LOG_FUNCTION (this << width << standard << band);
74 
75  auto channelIt = FindFirst (0, 0, width, standard, band, WifiPhy::m_frequencyChannels.begin ());
76 
77  if (channelIt != WifiPhy::m_frequencyChannels.end ())
78  {
79  // a channel matches the specified criteria
80  m_channelIt = channelIt;
81  m_primary20Index = 0;
82  return;
83  }
84 
85  // if a default channel was not found, throw an exception (mainly for unit testing this code)
86  throw std::runtime_error ("WifiPhyOperatingChannel: No default channel found of the given width and for the given PHY standard and band");
87 }
88 
90 WifiPhyOperatingChannel::FindFirst (uint8_t number, uint16_t frequency, uint16_t width,
91  WifiPhyStandard standard, WifiPhyBand band,
92  ConstIterator start) const
93 {
94  NS_LOG_FUNCTION (this << +number << frequency << width << standard << band);
95 
96  // lambda used to match channels against the specified criteria
97  auto predicate = [&](const FrequencyChannelInfo& channel)
98  {
99  if (number != 0 && std::get<0> (channel) != number)
100  {
101  return false;
102  }
103  if (frequency != 0 && std::get<1> (channel) != frequency)
104  {
105  return false;
106  }
107  if (width > GetMaximumChannelWidth (standard))
108  {
109  return false;
110  }
111  if (width != 0 && std::get<2> (channel) != width)
112  {
113  return false;
114  }
115  if (std::get<3> (channel) != GetFrequencyChannelType (standard))
116  {
117  return false;
118  }
119  if (std::get<4> (channel) != band)
120  {
121  return false;
122  }
123  return true;
124  };
125 
126  return std::find_if (start, WifiPhy::m_frequencyChannels.end (), predicate);
127 }
128 
129 uint8_t
131 {
132  NS_ASSERT (IsSet ());
133  return std::get<0> (*m_channelIt);
134 }
135 
136 uint16_t
138 {
139  NS_ASSERT (IsSet ());
140  return std::get<1> (*m_channelIt);
141 }
142 
143 uint16_t
145 {
146  NS_ASSERT (IsSet ());
147  return std::get<2> (*m_channelIt);
148 }
149 
150 uint8_t
151 WifiPhyOperatingChannel::GetPrimaryChannelIndex (uint16_t primaryChannelWidth) const
152 {
153  NS_LOG_FUNCTION (this << primaryChannelWidth);
154 
155  if (primaryChannelWidth % 20 != 0)
156  {
157  NS_LOG_DEBUG ("The operating channel width is not a multiple of 20 MHz; return 0");
158  return 0;
159  }
160 
161  NS_ASSERT (primaryChannelWidth <= GetWidth ());
162 
163  // the index of primary40 is half the index of primary20; the index of
164  // primary80 is half the index of primary40, ...
165  uint16_t width = 20;
166  uint8_t index = m_primary20Index;
167 
168  while (width < primaryChannelWidth)
169  {
170  index /= 2;
171  width *= 2;
172  }
173  NS_LOG_LOGIC ("Return " << +index);
174  return index;
175 }
176 
177 void
179 {
180  NS_LOG_FUNCTION (this << +index);
181 
182  NS_ABORT_MSG_IF (index > 0 && index >= GetWidth () / 20, "Primary20 index out of range");
183  m_primary20Index = index;
184 }
185 
186 uint16_t
188 {
189  uint16_t freq = GetFrequency () - GetWidth () / 2.
190  + (GetPrimaryChannelIndex (primaryChannelWidth) + 0.5) * primaryChannelWidth;
191 
192  NS_LOG_FUNCTION (this << primaryChannelWidth << freq);
193  return freq;
194 }
195 
196 } //namespace ns3
802.11 PHY layer model
Definition: wifi-phy.h:49
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
Definition: wifi-phy.h:61
WifiPhyOperatingChannel()
Create an uninitialized PHY operating channel.
void Set(uint8_t number, uint16_t frequency, uint16_t width, WifiPhyStandard standard, WifiPhyBand band)
Set the channel according to the specified parameters if a unique frequency channel matches the speci...
uint8_t GetNumber(void) const
Return the channel number identifying the whole operating channel.
bool IsSet(void) const
Return true if a valid channel has been set, false otherwise.
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
ConstIterator m_channelIt
const iterator pointing to the configured frequency channel
uint16_t GetWidth(void) const
Return the width of the whole operating channel (in MHz).
ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiPhyStandard standard, WifiPhyBand band, ConstIterator start) const
Find the first channel matching the specified parameters.
uint8_t m_primary20Index
index of the primary20 channel (0 indicates the 20 MHz subchannel with the lowest center frequency)
void SetDefault(uint16_t width, WifiPhyStandard standard, WifiPhyBand band)
Set the default channel of the given width and for the given PHY standard and band.
uint16_t GetFrequency(void) const
Return the center frequency of the operating channel (in MHz).
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
std::set< FrequencyChannelInfo >::const_iterator ConstIterator
Typedef for a const iterator pointing to a channel in the set of available channels.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::tuple< uint8_t, uint16_t, uint16_t, FrequencyChannelType, WifiPhyBand > FrequencyChannelInfo
A tuple (number, frequency, width, type, band) identifying a frequency channel.
FrequencyChannelType GetFrequencyChannelType(WifiPhyStandard standard)
Get the type of the frequency channel for the given PHY standard.
uint16_t GetMaximumChannelWidth(WifiPhyStandard standard)
Get the maximum channel width in MHz allowed for the given PHY standard.
channel
Definition: third.py:92
def start()
Definition: core.py:1855