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