A Discrete-Event Network Simulator
API
tv-spectrum-transmitter-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Benjamin Cizdziel <ben.cizdziel@gmail.com>
18 */
19
21
22#include <ns3/double.h>
23#include <ns3/geographic-positions.h>
24#include <ns3/isotropic-antenna-model.h>
25#include <ns3/log.h>
26#include <ns3/mobility-helper.h>
27#include <ns3/position-allocator.h>
28#include <ns3/uinteger.h>
29
30#include <cmath>
31#include <list>
32#include <vector>
33
34namespace ns3
35{
36
37NS_LOG_COMPONENT_DEFINE("TvSpectrumTransmitterHelper");
38
42const double northAmericaStartFrequencies[84] = {
43 0, 0, 54e6, 60e6, 66e6, 76e6, 82e6, 174e6, 180e6, 186e6, 192e6, 198e6,
44 204e6, 210e6, 470e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6,
45 530e6, 536e6, 542e6, 548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6,
46 602e6, 608e6, 614e6, 620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6,
47 674e6, 680e6, 686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6,
48 746e6, 752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6,
49 818e6, 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6};
51const double northAmericaEndFrequencies[84] = {
52 0, 0, 60e6, 66e6, 72e6, 82e6, 88e6, 180e6, 186e6, 192e6, 198e6, 204e6,
53 210e6, 216e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6,
54 536e6, 542e6, 548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6,
55 608e6, 614e6, 620e6, 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6,
56 680e6, 686e6, 692e6, 698e6, 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6,
57 752e6, 758e6, 764e6, 770e6, 776e6, 782e6, 788e6, 794e6, 800e6, 806e6, 812e6, 818e6,
58 824e6, 830e6, 836e6, 842e6, 848e6, 854e6, 860e6, 866e6, 872e6, 878e6, 884e6, 890e6};
59
61const int europeArrayLength = 70;
63const double europeStartFrequencies[70] = {
64 0, 0, 0, 0, 0, 174e6, 181e6, 188e6, 195e6, 202e6, 209e6, 216e6,
65 223e6, 0, 0, 0, 0, 0, 0, 0, 0, 470e6, 478e6, 486e6,
66 494e6, 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6, 582e6,
67 590e6, 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6, 670e6, 678e6,
68 686e6, 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6, 758e6, 766e6, 774e6,
69 782e6, 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6, 846e6, 854e6};
71const double europeEndFrequencies[70] = {
72 0, 0, 0, 0, 0, 181e6, 188e6, 195e6, 202e6, 209e6, 216e6, 223e6,
73 230e6, 0, 0, 0, 0, 0, 0, 0, 0, 478e6, 486e6, 494e6,
74 502e6, 510e6, 518e6, 526e6, 534e6, 542e6, 550e6, 558e6, 566e6, 574e6, 582e6, 590e6,
75 598e6, 606e6, 614e6, 622e6, 630e6, 638e6, 646e6, 654e6, 662e6, 670e6, 678e6, 686e6,
76 694e6, 702e6, 710e6, 718e6, 726e6, 734e6, 742e6, 750e6, 758e6, 766e6, 774e6, 782e6,
77 790e6, 798e6, 806e6, 814e6, 822e6, 830e6, 838e6, 846e6, 854e6, 862e6};
78
80const int japanArrayLength = 63;
82const double japanStartFrequencies[63] = {
83 0, 90e6, 96e6, 102e6, 170e6, 176e6, 182e6, 188e6, 192e6, 198e6, 204e6, 210e6, 216e6,
84 470e6, 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6,
85 548e6, 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6,
86 626e6, 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6, 698e6,
87 704e6, 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6, 764e6};
89const double japanEndFrequencies[63] = {
90 0, 96e6, 102e6, 108e6, 176e6, 182e6, 188e6, 194e6, 198e6, 204e6, 210e6, 216e6, 222e6,
91 476e6, 482e6, 488e6, 494e6, 500e6, 506e6, 512e6, 518e6, 524e6, 530e6, 536e6, 542e6, 548e6,
92 554e6, 560e6, 566e6, 572e6, 578e6, 584e6, 590e6, 596e6, 602e6, 608e6, 614e6, 620e6, 626e6,
93 632e6, 638e6, 644e6, 650e6, 656e6, 662e6, 668e6, 674e6, 680e6, 686e6, 692e6, 698e6, 704e6,
94 710e6, 716e6, 722e6, 728e6, 734e6, 740e6, 746e6, 752e6, 758e6, 764e6, 770e6};
95
97 : m_channel(nullptr),
99{
100 NS_LOG_FUNCTION(this);
101 m_factory.SetTypeId("ns3::TvSpectrumTransmitter");
102}
103
105{
106 m_channel = nullptr;
107 m_uniRand = nullptr;
108 NS_LOG_FUNCTION(this);
109}
110
111void
113{
114 NS_LOG_FUNCTION(this << c);
115 m_channel = c;
116}
117
118void
120{
121 m_factory.Set(name, val);
122}
123
126{
127 NS_LOG_FUNCTION(this);
128 NetDeviceContainer devCont;
129 // iterate over node container to make one transmitter for each given node
130 for (NodeContainer::Iterator i = nodeCont.Begin(); i != nodeCont.End(); ++i)
131 {
132 Ptr<Node> node = *i;
134 phy->CreateTvPsd();
135 Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
136 NS_ASSERT(phy);
137 dev->SetPhy(phy);
138 NS_ASSERT(node);
139 phy->SetMobility(node->GetObject<MobilityModel>());
140 NS_ASSERT(dev);
141 phy->SetDevice(dev);
143 phy->SetChannel(m_channel);
144 dev->SetChannel(m_channel);
145 node->AddDevice(dev);
146 devCont.Add(dev);
147 phy->Start();
148 }
149 return devCont;
150}
151
153TvSpectrumTransmitterHelper::Install(NodeContainer nodeCont, Region region, uint16_t channelNumber)
154{
155 NS_LOG_FUNCTION(this);
156 NetDeviceContainer devCont;
157 double startFrequency;
158 double channelBandwidth;
159 if (region == REGION_NORTH_AMERICA)
160 {
162 "channel number " << channelNumber << " does not exist for this region");
164 "channel number " << channelNumber << " does not exist for this region");
165 startFrequency = northAmericaStartFrequencies[channelNumber];
166 channelBandwidth =
167 northAmericaEndFrequencies[channelNumber] - northAmericaStartFrequencies[channelNumber];
168 }
169 else if (region == REGION_EUROPE)
170 {
171 NS_ASSERT_MSG(channelNumber < europeArrayLength,
172 "channel number " << channelNumber << " does not exist for this region");
173 NS_ASSERT_MSG(europeStartFrequencies[channelNumber] != 0,
174 "channel number " << channelNumber << " does not exist for this region");
175 startFrequency = europeStartFrequencies[channelNumber];
176 channelBandwidth =
177 europeEndFrequencies[channelNumber] - europeStartFrequencies[channelNumber];
178 }
179 else if (region == REGION_JAPAN)
180 {
181 NS_ASSERT_MSG(channelNumber < japanArrayLength,
182 "channel number " << channelNumber << " does not exist for this region");
183 NS_ASSERT_MSG(japanStartFrequencies[channelNumber] != 0,
184 "channel number " << channelNumber << " does not exist for this region");
185 startFrequency = japanStartFrequencies[channelNumber];
186 channelBandwidth =
187 japanEndFrequencies[channelNumber] - japanStartFrequencies[channelNumber];
188 }
189 // iterate over node container to make one transmitter for each given node
190 for (NodeContainer::Iterator i = nodeCont.Begin(); i != nodeCont.End(); ++i)
191 {
192 Ptr<Node> node = *i;
194 phy->SetAttribute("StartFrequency", DoubleValue(startFrequency));
195 phy->SetAttribute("ChannelBandwidth", DoubleValue(channelBandwidth));
196 phy->CreateTvPsd();
197 Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
198 NS_ASSERT(phy);
199 dev->SetPhy(phy);
200 NS_ASSERT(node);
201 phy->SetMobility(node->GetObject<MobilityModel>());
202 NS_ASSERT(dev);
203 phy->SetDevice(dev);
205 phy->SetChannel(m_channel);
206 dev->SetChannel(m_channel);
207 node->AddDevice(dev);
208 devCont.Add(dev);
209 phy->Start();
210 }
211 return devCont;
212}
213
216{
217 NS_LOG_FUNCTION(this);
218 NetDeviceContainer devCont;
219 int index = 0;
220 DoubleValue startFrequency;
221 DoubleValue channelBandwidth;
222 // iterate over node container to make one transmitter for each given node
223 for (NodeContainer::Iterator i = nodeCont.Begin(); i != nodeCont.End(); ++i)
224 {
225 Ptr<Node> node = *i;
227 phy->GetAttribute("StartFrequency", startFrequency);
228 phy->GetAttribute("ChannelBandwidth", channelBandwidth);
229 phy->SetAttribute("StartFrequency",
230 DoubleValue(startFrequency.Get() + (index * channelBandwidth.Get())));
231 phy->CreateTvPsd();
232 Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
233 NS_ASSERT(phy);
234 dev->SetPhy(phy);
235 NS_ASSERT(node);
236 phy->SetMobility(node->GetObject<MobilityModel>());
237 NS_ASSERT(dev);
238 phy->SetDevice(dev);
240 phy->SetChannel(m_channel);
241 dev->SetChannel(m_channel);
242 node->AddDevice(dev);
243 devCont.Add(dev);
244 phy->Start();
245 index++;
246 }
247 return devCont;
248}
249
252 Region region,
253 uint16_t channelNumber)
254{
255 NS_LOG_FUNCTION(this);
256 NetDeviceContainer devCont;
257 double startFrequency;
258 double channelBandwidth;
259 uint16_t currChannelNumber;
260 int index = 0;
261 // iterate over node container to make one transmitter for each given node
262 for (NodeContainer::Iterator i = nodeCont.Begin(); i != nodeCont.End(); ++i)
263 {
264 currChannelNumber = channelNumber + index;
265 if (region == REGION_NORTH_AMERICA)
266 {
267 NS_ASSERT_MSG(currChannelNumber < northAmericaArrayLength,
268 "channel number " << currChannelNumber
269 << " does not exist for this region");
270 NS_ASSERT_MSG(northAmericaStartFrequencies[currChannelNumber] != 0,
271 "channel number " << currChannelNumber
272 << " does not exist for this region");
273 startFrequency = northAmericaStartFrequencies[currChannelNumber];
274 channelBandwidth = northAmericaEndFrequencies[currChannelNumber] -
275 northAmericaStartFrequencies[currChannelNumber];
276 }
277 else if (region == REGION_EUROPE)
278 {
279 NS_ASSERT_MSG(currChannelNumber < europeArrayLength,
280 "channel number " << currChannelNumber
281 << " does not exist for this region");
282 NS_ASSERT_MSG(europeStartFrequencies[currChannelNumber] != 0,
283 "channel number " << currChannelNumber
284 << " does not exist for this region");
285 startFrequency = europeStartFrequencies[currChannelNumber];
286 channelBandwidth =
287 europeEndFrequencies[currChannelNumber] - europeStartFrequencies[currChannelNumber];
288 }
289 else if (region == REGION_JAPAN)
290 {
291 NS_ASSERT_MSG(currChannelNumber < japanArrayLength,
292 "channel number " << currChannelNumber
293 << " does not exist for this region");
294 NS_ASSERT_MSG(japanStartFrequencies[currChannelNumber] != 0,
295 "channel number " << currChannelNumber
296 << " does not exist for this region");
297 startFrequency = japanStartFrequencies[currChannelNumber];
298 channelBandwidth =
299 japanEndFrequencies[currChannelNumber] - japanStartFrequencies[currChannelNumber];
300 }
301 Ptr<Node> node = *i;
303 phy->SetAttribute("StartFrequency", DoubleValue(startFrequency));
304 phy->SetAttribute("ChannelBandwidth", DoubleValue(channelBandwidth));
305 phy->CreateTvPsd();
306 Ptr<NonCommunicatingNetDevice> dev = CreateObject<NonCommunicatingNetDevice>();
307 NS_ASSERT(phy);
308 dev->SetPhy(phy);
309 NS_ASSERT(node);
310 phy->SetMobility(node->GetObject<MobilityModel>());
311 NS_ASSERT(dev);
312 phy->SetDevice(dev);
314 phy->SetChannel(m_channel);
315 dev->SetChannel(m_channel);
316 node->AddDevice(dev);
317 devCont.Add(dev);
318 phy->Start();
319 index++;
320 }
321 return devCont;
322}
323
324int64_t
326{
327 m_uniRand->SetStream(streamNum);
328 return 1;
329}
330
331void
333 Density density,
334 double originLatitude,
335 double originLongitude,
336 double maxAltitude,
337 double maxRadius)
338{
339 NS_LOG_FUNCTION(this);
340 std::list<int> transmitterIndicesToCreate;
341 if (region == REGION_NORTH_AMERICA)
342 {
343 transmitterIndicesToCreate =
346 density);
347 }
348 else if (region == REGION_EUROPE)
349 {
350 transmitterIndicesToCreate =
352 }
353 else if (region == REGION_JAPAN)
354 {
355 transmitterIndicesToCreate =
357 }
358 std::list<Vector> tvTransmitterLocations =
360 originLatitude,
361 originLongitude,
362 maxAltitude,
363 transmitterIndicesToCreate.size(),
364 maxRadius,
365 m_uniRand);
366 InstallRandomRegionalTransmitters(region, transmitterIndicesToCreate, tvTransmitterLocations);
367}
368
369std::list<int>
371 const int startFrequenciesLength,
372 Density density)
373{
374 std::vector<double> startFreqVector; // stores all non-zero start frequencies
375 for (int i = 0; i < startFrequenciesLength; i++)
376 {
377 double element = startFrequencies[i];
378 // add all non-zero frequencies to vector (0 means unused channel)
379 if (element != 0)
380 {
381 startFreqVector.push_back(element);
382 }
383 }
384
385 // randomly generate number of transmitters to create based on density
386 uint32_t freqVectorSize = startFreqVector.size();
387 int randNumTransmitters = GetRandomNumTransmitters(density, freqVectorSize);
388
389 // stores start frequencies that transmitters will be created to transmit
390 std::vector<double> transmitterStartFreqsToCreate;
391 for (int i = 0; i < randNumTransmitters; i++)
392 {
393 // get random index from start frequency vector
394 uint32_t randIndex = m_uniRand->GetInteger(0, startFreqVector.size() - 1);
395 // add start frequency corresponding to random index to vector
396 transmitterStartFreqsToCreate.push_back(startFreqVector[randIndex]);
397 // remove selected start frequency from vector so it is not selected again
398 startFreqVector.erase(startFreqVector.begin() + randIndex);
399 }
400
401 // find indices on startFrequencies[] containing each start frequency that is
402 // selected to be transmitted and add to list
403 std::list<int> transmitterIndicesToCreate;
404 for (int i = 0; i < (int)transmitterStartFreqsToCreate.size(); i++)
405 {
406 for (int channelNumberIndex = 0; channelNumberIndex < startFrequenciesLength;
407 channelNumberIndex++)
408 {
409 if (startFrequencies[channelNumberIndex] == transmitterStartFreqsToCreate[i])
410 {
411 transmitterIndicesToCreate.push_back(channelNumberIndex);
412 break;
413 }
414 }
415 }
416 return transmitterIndicesToCreate;
417}
418
419int
421{
422 int numTransmitters;
423 if (density == DENSITY_LOW)
424 {
425 numTransmitters = m_uniRand->GetInteger(1, ceil(0.33 * numChannels));
426 }
427 else if (density == DENSITY_MEDIUM)
428 {
429 numTransmitters =
430 m_uniRand->GetInteger(ceil(0.33 * numChannels) + 1, ceil(0.66 * numChannels));
431 }
432 else
433 {
434 numTransmitters = m_uniRand->GetInteger(ceil(0.66 * numChannels) + 1, numChannels);
435 }
436 return numTransmitters;
437}
438
439void
441 Region region,
442 std::list<int> transmitterIndicesToCreate,
443 std::list<Vector> transmitterLocations)
444{
445 int numTransmitters = (int)transmitterIndicesToCreate.size();
446 for (int transNum = 0; transNum < numTransmitters; transNum++)
447 {
448 Ptr<ListPositionAllocator> nodePosition = CreateObject<ListPositionAllocator>();
449 // add generated coordinate point to node position
450 nodePosition->Add(transmitterLocations.front());
452 mobility.SetPositionAllocator(nodePosition);
453 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
454 NodeContainer tvNode; // contains position of transmitter to be created
455 tvNode.Create(1);
456 mobility.Install(tvNode);
457 // set channel number for this transmitter
458 uint16_t channelNumber = (uint16_t)transmitterIndicesToCreate.front();
459 Install(tvNode, region, channelNumber); // install tv transmitter
460 transmitterLocations.pop_front(); // remove created transmitter location
461 transmitterIndicesToCreate.pop_front(); // remove created transmitter index
462 }
463}
464
465} // namespace ns3
Hold a value for an Attribute.
Definition: attribute.h:70
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
double Get() const
Definition: double.cc:37
static std::list< Vector > RandCartesianPointsAroundGeographicPoint(double originLatitude, double originLongitude, double maxAltitude, int numPoints, double maxDistFromOrigin, Ptr< UniformRandomVariable > uniRand)
Generates uniformly distributed random points (in ECEF Cartesian coordinates) within a given altitude...
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
keep track of a set of node pointers.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
std::list< int > GenerateRegionalTransmitterIndices(const double startFrequencies[], const int startFrequenciesLength, Density density)
Generates random indices of given region frequency array (ignoring indices referring to invalid chann...
void SetChannel(Ptr< SpectrumChannel > c)
Set the spectrum channel for the device(s) to transmit on.
NetDeviceContainer InstallAdjacent(NodeContainer nodes)
Set up and start the TV Transmitter's transmission on the spectrum channel.
Density
density of location that TV transmitters are being set up in
void InstallRandomRegionalTransmitters(Region region, std::list< int > transmitterIndicesToCreate, std::list< Vector > transmitterLocations)
Installs each randomly generated regional TV transmitter.
Region
geographical region that TV transmitters are being set up in
int GetRandomNumTransmitters(Density density, uint32_t numChannels)
Randomly generates the number of TV transmitters to be created based on given density and number of p...
Ptr< UniformRandomVariable > m_uniRand
Object to generate uniform random numbers.
int64_t AssignStreams(int64_t streamNum)
Assigns the stream number for the uniform random number generator to use.
ObjectFactory m_factory
Object factory for attribute setting.
void CreateRegionalTvTransmitters(Region region, Density density, double originLatitude, double originLongitude, double maxAltitude, double maxRadius)
Generates and installs (starts transmission on the spectrum channel) a random number of TV transmitte...
void SetAttribute(std::string name, const AttributeValue &val)
Set attribute for each TvSpectrumTransmitter instance to be created.
NetDeviceContainer Install(NodeContainer nodes)
Set up and start the TV Transmitter's transmission on the spectrum channel.
Ptr< SpectrumChannel > m_channel
Pointer to spectrum channel object.
SpectrumPhy implementation that creates a customizable TV transmitter which transmits a PSD spectrum ...
The uniform distribution Random Number Generator (RNG).
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition: object.h:579
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const double northAmericaEndFrequencies[84]
NORTH AMERICA end frequencies.
const int japanArrayLength
JAPAN: 63 elements (index 0 - 62); valid channels = 1 - 62.
const double europeEndFrequencies[70]
EUROPE end frequencies.
const int northAmericaArrayLength
NORTH AMERICA: 84 elements (index 0 - 83); valid channels = 2 - 83.
const double japanStartFrequencies[63]
JAPAN start frequencies.
const double europeStartFrequencies[70]
EUROPE start frequencies.
const double japanEndFrequencies[63]
JAPAN end frequencies.
const double northAmericaStartFrequencies[84]
NORTH AMERICA start frequencies.
const int europeArrayLength
EUROPE: 70 elements (index 0 - 69); valid channels = 5 - 12, 21 - 69.
mobility
Definition: third.py:96
phy
Definition: third.py:82