libcyberradio  22.01.24
RadioHandler.cpp
1 /***************************************************************************
2  * \file RadioHandler.cpp
3  * \brief Defines the radio handler interface for the NDR308-TS.
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/NDR308TS/RadioHandler.h"
12 #include "LibCyberRadio/Driver/NDR308TS/DataPort.h"
13 #include "LibCyberRadio/Driver/NDR308TS/NbddcComponent.h"
14 #include "LibCyberRadio/Driver/NDR308TS/TunerComponent.h"
15 #include "LibCyberRadio/Driver/NDR308TS/VitaIfSpec.h"
16 #include "LibCyberRadio/Driver/NDR308TS/WbddcComponent.h"
17 #include "LibCyberRadio/Driver/NDR308TS/WbddcGroupComponent.h"
18 #include "LibCyberRadio/Driver/NDR308TS/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 NDR308TS
31  {
32 
33  RadioHandler::RadioHandler(bool debug) :
34  ::LibCyberRadio::Driver::RadioHandler(
35  /* const std::string& name */ "NDR308TS",
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 */ 122.88e6,
58  /* VitaIfSpec ifSpec */ NDR308TS::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 NDR308TS::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 NDR308TS::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 NDR308TS::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 NDR308TS::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 NDR308TS::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 NDR308TS::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("[NDR308TS::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("[NDR308TS::RadioHandler::queryConfiguration] Returning\n");
165  }
166 
167  bool RadioHandler::queryVersionInfo()
168  {
169  this->debug("[NDR308TS::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("[NDR308TS::RadioHandler::queryVersionInfo] Number of tuner boards=%d\n", _numTunerBoards);
228  this->debug("[NDR308TS::RadioHandler::queryVersionInfo] Number of tuners=%d\n", _numTuner);
229  // Deallocate any tuners and DDCs that don't have a tuner board
230  this->debug("[NDR308TS::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("[NDR308TS::RadioHandler::queryVersionInfo] -- Deallocating tuner=%d\n", it->first);
237  delete it->second;
238  _tuners.erase(it++);
239  }
240  else
241  {
242  this->debug("[NDR308TS::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("[NDR308TS::RadioHandler::queryVersionInfo] -- Deallocating WBDDC=%d\n", it2->first);
252  delete it2->second;
253  _wbddcs.erase(it2++);
254  }
255  else
256  {
257  this->debug("[NDR308TS::RadioHandler::queryVersionInfo] -- OK WBDDC=%d\n", it2->first);
258  it2++;
259  }
260  }
261  // Determine frequency range from max bandwidth
262  this->debug("[NDR308TS::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("[NDR308TS::RadioHandler::queryVersionInfo] %s = \"%s\"\n", it->first.c_str(), it->second.c_str());
273  }
274  }
275  this->debug("[NDR308TS::RadioHandler::queryVersionInfo] Returning %s\n", debugBool(ret));
276  return ret;
277  }
278 
279  // NOTE: The default implementation is the NDR308TS 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 NDR308TS 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 NDR308TS 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 NDR308TS */
309 
310  } /* namespace Driver */
311 
312 } /* namespace LibCyberRadio */
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...
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 initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
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
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.
Radio handler class for the NDR308-TS.
Definition: RadioHandler.h:174
virtual ~RadioHandler()
Destroys a RadioHandler object.
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...