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
std::set< FrequencyChannelInfo >::const_iterator ConstIterator
Typedef for a const iterator pointing to a channel in the set of available channels.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
802.11 PHY layer model
Definition: wifi-phy.h:48
def start()
Definition: core.py:1855
#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
uint16_t GetMaximumChannelWidth(WifiPhyStandard standard)
Get the maximum channel width in MHz allowed for the given PHY standard.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
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.
uint16_t GetFrequency(void) const
Return the center frequency of the operating channel (in MHz).
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
channel
Definition: third.py:92
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
ConstIterator m_channelIt
const iterator pointing to the configured frequency channel
std::tuple< uint8_t, uint16_t, uint16_t, FrequencyChannelType, WifiPhyBand > FrequencyChannelInfo
A tuple (number, frequency, width, type, band) identifying a frequency channel.
uint16_t GetWidth(void) const
Return the width of the whole operating channel (in MHz).
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
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...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
Definition: wifi-phy.h:61
uint8_t GetNumber(void) const
Return the channel number identifying the whole operating channel.
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.
bool IsSet(void) const
Return true if a valid channel has been set, false otherwise.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:32
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
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...
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
uint8_t m_primary20Index
index of the primary20 channel (0 indicates the 20 MHz subchannel with the lowest center frequency) ...
FrequencyChannelType GetFrequencyChannelType(WifiPhyStandard standard)
Get the type of the frequency channel for the given PHY standard.