libcyberradio  22.01.24
RadioHandler.cpp
1 /***************************************************************************
2  * \file RadioHandler.cpp
3  * \brief Defines the radio handler interface for the NDR308.
4  * \author DA
5  * \author NH
6  * \author MN
7  * \copyright (c) 2017 CyberRadio Solutions, Inc. All rights reserved.
8  *
9  ***************************************************************************/
10 
11 #include "LibCyberRadio/Driver/NDR308/RadioHandler.h"
12 #include "LibCyberRadio/Driver/NDR308/DataPort.h"
13 #include "LibCyberRadio/Driver/NDR308/NbddcComponent.h"
14 #include "LibCyberRadio/Driver/NDR308/TunerComponent.h"
15 #include "LibCyberRadio/Driver/NDR308/VitaIfSpec.h"
16 #include "LibCyberRadio/Driver/NDR308/WbddcComponent.h"
17 #include "LibCyberRadio/Driver/NDR308/WbddcGroupComponent.h"
18 #include "LibCyberRadio/Driver/NDR308/NbddcGroupComponent.h"
19 #include "LibCyberRadio/Common/Pythonesque.h"
20 #include <sstream>
21 #include <cstdio>
22 
23 
24 namespace LibCyberRadio
25 {
26 
27  namespace Driver
28  {
29 
30  namespace NDR308
31  {
32 
33  RadioHandler::RadioHandler(bool debug) :
34  ::LibCyberRadio::Driver::RadioHandler(
35  /* const std::string& name */ "NDR308",
36  /* int numTuner */ 8,
37  /* int tunerIndexBase */ 1,
38  /* int numWbddc */ 8,
39  /* int wbddcIndexBase */ 1,
40  /* int numNbddc */ 32,
41  /* int nbddcIndexBase */ 1,
42  /* int numTunerBoards */ 2,
43  /* int maxTunerBw */ 6000,
44  /* int numTransmitters */ 0,
45  /* int transmitterIndexBase */ 1,
46  /* int numDuc */ 0,
47  /* int ducIndexBase */ 1,
48  /* int numWbddcGroups */ 4,
49  /* int wbddcGroupIndexBase */ 1,
50  /* int numNbddcGroups */ 8,
51  /* int nbddcGroupIndexBase */ 1,
52  /* int numDdcGroups */ 0,
53  /* int ddcGroupIndexBase */ 1,
54  /* int numDataPorts */ 2,
55  /* int dataPortIndexBase */ 1,
56  /* int numSimpleIpSetups */ 0,
57  /* double adcRate */ 102.4e6,
58  /* VitaIfSpec ifSpec */ NDR308::VitaIfSpec(),
59  /* bool debug */ debug)
60  {
62  _connModesSupported.push_back("tcp");
63  _defaultDeviceInfo = 8617;
64  // Allocate tuner components
65  for (int tuner = _tunerIndexBase;
66  tuner < (_tunerIndexBase + _numTuner); tuner++)
67  {
68 
69  _tuners[tuner] = new NDR308::TunerComponent(
70  /* int index */ tuner,
71  /* RadioHandler* parent */ this,
72  /* bool debug */ _debug,
73  /* double frequency */ 800e6,
74  /* double attenuation */ 0.0,
75  /* int filter */ 0);
76  }
77  // Allocate WBDDC components
78  for (int wbddc = _wbddcIndexBase;
79  wbddc < (_wbddcIndexBase + _numWbddc); wbddc++)
80  {
81  _wbddcs[wbddc] = new NDR308::WbddcComponent(
82  /* int index */ wbddc,
83  /* RadioHandler* parent */ this,
84  /* bool debug */ _debug,
85  /* int dataPort */ 1,
86  /* int rateIndex */ 0,
87  /* int udpDestination */ 0,
88  /* int vitaEnable */ 0,
89  /* int streamId */ 0);
90  }
91  // Allocate NBDDC components
92  for (int nbddc = _nbddcIndexBase;
93  nbddc < (_nbddcIndexBase + _numNbddc); nbddc++)
94  {
95  _nbddcs[nbddc] = new NDR308::NbddcComponent(
96  /* int index */ nbddc,
97  /* RadioHandler* parent */ this,
98  /* bool debug */ _debug,
99  /* int dataPort */ 1,
100  /* int rateIndex */ 0,
101  /* int udpDestination */ 0,
102  /* int vitaEnable */ 0,
103  /* int streamId */ 0,
104  /* double frequency */ 0.0,
105  /* int source */ 1);
106  }
107  // Allocate WBDDC group components
108  for (int group = _wbddcGroupIndexBase;
109  group < (_wbddcGroupIndexBase + _numWbddcGroups); group++)
110  {
111  _wbddcGroups[group] = new NDR308::WbddcGroupComponent(
112  /* int index */ group,
113  /* RadioHandler* parent */ this,
114  /* bool debug */ _debug);
115  }
116  // Allocate NBDDC group components
117  for (int group = _nbddcGroupIndexBase;
118  group < (_nbddcGroupIndexBase + _numNbddcGroups); group++)
119  {
120  _nbddcGroups[group] = new NDR308::NbddcGroupComponent(
121  /* int index */ group,
122  /* RadioHandler* parent */ this,
123  /* bool debug */ _debug);
124  }
125  // Allocate data ports
126  for (int dataPort = _dataPortIndexBase;
127  dataPort < (_dataPortIndexBase + _numDataPorts); dataPort++)
128  {
129  _dataPorts[dataPort] = new NDR308::DataPort(
130  /* int index */ dataPort,
131  /* RadioHandler* parent */ this,
132  /* bool debug */ _debug,
133  /* const std::string& sourceIP */ "0.0.0.0");
134  }
135  }
136 
138  {
139  }
140 
141  RadioHandler::RadioHandler(const RadioHandler &other) :
142  ::LibCyberRadio::Driver::RadioHandler(other)
143  {
144  }
145 
146  RadioHandler& RadioHandler::operator=(const RadioHandler& other)
147  {
148  ::LibCyberRadio::Driver::RadioHandler::operator=(other);
149  // Block self-assignment
150  if (this != &other)
151  {
152  }
153  return *this;
154  }
155 
157  {
158  this->debug("[NDR308::RadioHandler::queryConfiguration] Called\n");
159  // Purge the banner sent over when a connection is made.
160  BasicStringList rsp = _transport.receive(_defaultTimeout);
161  // Call the base-class queryConfiguration() to retrieve identity info
162  // and query configuration for all components
164  this->debug("[NDR308::RadioHandler::queryConfiguration] Returning\n");
165  }
166 
167  bool RadioHandler::queryVersionInfo()
168  {
169  this->debug("[NDR308::RadioHandler::queryVersionInfo] Called\n");
170  // First, call the base-class version
171  bool ret = ::LibCyberRadio::Driver::RadioHandler::queryVersionInfo();
172  // Next, use the hardware version info string to determine
173  // -- unit revision
174  // -- number of tuner boards
175  // -- max tuner bandwidth
176  if ( ret )
177  {
178  // Set number of installed tuner boards to zero
179  _numTunerBoards = 0;
180  // Progress state tracker: 0=Unit, 1=Digital Board, 2+=Tuner Boards
181  int stateTracker = -1;
182  // Split the hardware version info string into separate lines
183  BasicStringList vec = Pythonesque::Split(_versionInfo["hardwareVersion"], "\n");
184  // Iterate over the list
185  for (BasicStringList::iterator it = vec.begin(); it != vec.end(); it++)
186  {
187  // First, determine if the current line indicates a change in progress state
188  if ( it->find("Unit") == 0 )
189  stateTracker = 0;
190  else if ( it->find("Digital Board") == 0 )
191  stateTracker = 1;
192  else if ( it->find("Tuner Quad") == 0 )
193  stateTracker = 2;
194  // Then use the current line to determine other quantities
195  switch( stateTracker )
196  {
197  case 0:
198  if ( it->find(" Revision: ") != std::string::npos )
199  _versionInfo["unitRevision"] = Pythonesque::Replace(*it, " Revision: ", "");
200  break;
201  case 1:
202  break;
203  case 2:
204  if ( ( it->find("Tuner Quad") == 0) && ( it->find("Not Installed") != std::string::npos) )
205  _numTunerBoards++;
206  else if ( it->find("Bandwidth: ") == 0 )
207  {
208  std::string tmp = Pythonesque::Replace(*it, "Bandwidth: ", "");
209  std::istringstream iss(tmp);
210  // Handle the corner case where the radio doesn't report its
211  // maximum tuner bandwidth properly (returning 0 for BW).
212  int value;
213  iss >> value;
214  if ( value != 0 )
215  _maxTunerBw = value;
216  }
217  break;
218  default:
219  break;
220  }
221 
222  }
223  }
224  // Calculate number of tuners/WBDDCs from tuner boards
225  _numTuner = std::min(_numTuner, _numTunerBoards * 4);
226  _numWbddc = _numTuner;
227  this->debug("[NDR308::RadioHandler::queryVersionInfo] Number of tuner boards=%d\n", _numTunerBoards);
228  this->debug("[NDR308::RadioHandler::queryVersionInfo] Number of tuners=%d\n", _numTuner);
229  // Deallocate any tuners and DDCs that don't have a tuner board
230  this->debug("[NDR308::RadioHandler::queryVersionInfo] Deallocating nonexistent tuners/WBDDCs\n");
231  TunerComponentDict::iterator it = _tuners.begin();
232  for (; it != _tuners.end(); )
233  {
234  if ( it->first >= (_tunerIndexBase + _numTuner) )
235  {
236  this->debug("[NDR308::RadioHandler::queryVersionInfo] -- Deallocating tuner=%d\n", it->first);
237  delete it->second;
238  _tuners.erase(it++);
239  }
240  else
241  {
242  this->debug("[NDR308::RadioHandler::queryVersionInfo] -- OK tuner=%d\n", it->first);
243  it++;
244  }
245  }
246  WbddcComponentDict::iterator it2 = _wbddcs.begin();
247  for (; it2 != _wbddcs.end(); )
248  {
249  if ( it2->first >= (_wbddcIndexBase + _numWbddc) )
250  {
251  this->debug("[NDR308::RadioHandler::queryVersionInfo] -- Deallocating WBDDC=%d\n", it2->first);
252  delete it2->second;
253  _wbddcs.erase(it2++);
254  }
255  else
256  {
257  this->debug("[NDR308::RadioHandler::queryVersionInfo] -- OK WBDDC=%d\n", it2->first);
258  it2++;
259  }
260  }
261  // Determine frequency range from max bandwidth
262  this->debug("[NDR308::RadioHandler::queryVersionInfo] Max tuner bandwidth=%d MHz\n", _maxTunerBw);
263  for (it = _tuners.begin(); it != _tuners.end(); it++)
264  {
265  it->second->setFrequencyRangeMax(_maxTunerBw * 1e6);
266  }
267  // Debug dump
268  if (ret)
269  {
270  for (BasicStringStringDict::iterator it = _versionInfo.begin(); it != _versionInfo.end(); it++)
271  {
272  this->debug("[NDR308::RadioHandler::queryVersionInfo] %s = \"%s\"\n", it->first.c_str(), it->second.c_str());
273  }
274  }
275  this->debug("[NDR308::RadioHandler::queryVersionInfo] Returning %s\n", debugBool(ret));
276  return ret;
277  }
278 
279  // NOTE: The default implementation is the NDR308 implementation,
280  // but this just makes it explicit in the code.
281  bool RadioHandler::executeQueryIDN(std::string& model,
282  std::string& serialNumber)
283  {
284  return ::LibCyberRadio::Driver::RadioHandler::executeQueryIDN(model, serialNumber);
285  }
286 
287  // NOTE: The default implementation is the NDR308 implementation,
288  // but this just makes it explicit in the code.
289  bool RadioHandler::executeQueryVER(std::string& softwareVersion,
290  std::string& firmwareVersion,
291  std::string& referenceVersion,
292  std::string& firmwareDate)
293  {
294 
295  return ::LibCyberRadio::Driver::RadioHandler::executeQueryVER(softwareVersion,
296  firmwareVersion,
297  referenceVersion,
298  firmwareDate);
299  }
300 
301  // NOTE: The default implementation is the NDR308 implementation,
302  // but this just makes it explicit in the code.
303  bool RadioHandler::executeQueryHREV(std::string& hardwareInfo)
304  {
305  return ::LibCyberRadio::Driver::RadioHandler::executeQueryHREV(hardwareInfo);
306  }
307 
308  } /* namespace NDR308 */
309 
310  } /* namespace Driver */
311 
312 } /* namespace LibCyberRadio */
virtual ~RadioHandler()
Destroys a RadioHandler object.
static std::string Replace(const std::string &str, const std::string &oldstr, const std::string &newstr, int count=INT_MAX)
Replaces occurrences of one substring with another within the given string.
Definition: Pythonesque.cpp:62
static BasicStringList Split(const std::string &str, const std::string &sep, int maxsplit=INT_MAX)
Splits the given string into a list of string tokens.
Definition: Pythonesque.cpp:77
Radio handler class for the NDR308.
Definition: RadioHandler.h:178
Generic radio handler class.
Definition: RadioHandler.h:54
virtual int debug(const char *format,...)
Outputs debug information.
Definition: Debuggable.cpp:95
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition: BasicList.h:25
Defines functionality for LibCyberRadio applications.
Definition: App.h:23
virtual const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
Definition: Debuggable.cpp:126
virtual BasicStringList receive(double timeout=-1)
Receives a command response from the radio.
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...