libcyberradio  22.01.24
RadioHandler.cpp
1 /***************************************************************************
2  * \file RadioHandler.cpp
3  * \brief Defines the radio handler interface for the NDR472.
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/NDR472/RadioHandler.h"
12 #include "LibCyberRadio/Driver/NDR472/SimpleIpSetup.h"
13 #include "LibCyberRadio/Driver/NDR472/TunerComponent.h"
14 #include "LibCyberRadio/Driver/NDR472/VitaIfSpec.h"
15 #include "LibCyberRadio/Driver/NDR472/WbddcComponent.h"
16 #include "LibCyberRadio/Driver/NDR472/WbddcGroupComponent.h"
17 #include "LibCyberRadio/Common/Pythonesque.h"
18 #include <boost/lexical_cast.hpp>
19 #include <sstream>
20 #include <cstdio>
21 
22 
23 namespace LibCyberRadio
24 {
25 
26  namespace Driver
27  {
28 
29  namespace NDR472
30  {
31 
32  RadioHandler::RadioHandler(bool debug) :
33  ::LibCyberRadio::Driver::RadioHandler(
34  /* const std::string& name */ "NDR472",
35  /* int numTuner */ 2,
36  /* int tunerIndexBase */ 1,
37  /* int numWbddc */ 2,
38  /* int wbddcIndexBase */ 1,
39  /* int numNbddc */ 0,
40  /* int nbddcIndexBase */ 1,
41  /* int numTunerBoards */ 1,
42  /* int maxTunerBw */ 3000,
43  /* int numTransmitters */ 0,
44  /* int transmitterIndexBase */ 1,
45  /* int numDuc */ 0,
46  /* int ducIndexBase */ 1,
47  /* int numWbddcGroups */ 2,
48  /* int wbddcGroupIndexBase */ 1,
49  /* int numNbddcGroups */ 0,
50  /* int nbddcGroupIndexBase */ 1,
51  /* int numDdcGroups */ 0,
52  /* int ddcGroupIndexBase */ 1,
53  /* int numDataPorts */ 0,
54  /* int dataPortIndexBase */ 1,
55  /* int numSimpleIpSetups */ 1,
56  /* double adcRate */ 128e6,
57  /* VitaIfSpec ifSpec */ NDR472::VitaIfSpec(),
58  /* bool debug */ debug)
59  {
61  _connModesSupported.push_back("tty");
62  _defaultDeviceInfo = 921600;
63  // Allocate tuner components
64  for (int tuner = _tunerIndexBase;
65  tuner < (_tunerIndexBase + _numTuner); tuner++)
66  {
67 
68  _tuners[tuner] = new NDR472::TunerComponent(
69  /* int index */ tuner,
70  /* RadioHandler* parent */ this,
71  /* bool debug */ _debug,
72  /* double frequency */ 800e6,
73  /* double attenuation */ 0.0,
74  /* int filter */ 0);
75  }
76  // Allocate WBDDC components
77  for (int wbddc = _wbddcIndexBase;
78  wbddc < (_wbddcIndexBase + _numWbddc); wbddc++)
79  {
80  _wbddcs[wbddc] = new NDR472::WbddcComponent(
81  /* int index */ wbddc,
82  /* RadioHandler* parent */ this,
83  /* bool debug */ _debug,
84  /* int dataPort */ 1,
85  /* int rateIndex */ 0,
86  /* int udpDestination */ 0,
87  /* int vitaEnable */ 0,
88  /* int streamId */ 0);
89  }
90  // This radio has no NBDDC components
91  // Allocate WBDDC group components
92  for (int group = _wbddcGroupIndexBase;
93  group < (_wbddcGroupIndexBase + _numWbddcGroups); group++)
94  {
95  _wbddcGroups[group] = new NDR472::WbddcGroupComponent(
96  /* int index */ group,
97  /* RadioHandler* parent */ this,
98  /* bool debug */ _debug);
99  }
100  // This radio has no NBDDC group components
101  // This radio has no 10-Gig data ports
102  // Allocate a simple IP setup object
103  _simpleIpSetups[0] = new NDR472::SimpleIpSetup(
104  /* RadioHandler* parent */ this,
105  /* bool debug */ _debug,
106  /* const std::string& sourceIP */ "0.0.0.0",
107  /* const std::string& destIP */ "0.0.0.0",
108  /* const std::string& destMAC */ "00:00:00:00:00:00");
109  }
110 
112  {
113  }
114 
115  RadioHandler::RadioHandler(const RadioHandler &other) :
116  ::LibCyberRadio::Driver::RadioHandler(other)
117  {
118  }
119 
120  RadioHandler& RadioHandler::operator=(const RadioHandler& other)
121  {
122  ::LibCyberRadio::Driver::RadioHandler::operator=(other);
123  // Block self-assignment
124  if (this != &other)
125  {
126  }
127  return *this;
128  }
129 
130  // OVERRIDE
132  {
133  //this->debug("[NDR472::RadioHandler::initConfigurationDict] Called\n");
134  _config.clear();
135  _config["configMode"] = _configMode;
136  _config["referenceMode"] = _referenceMode;
137  _config["freqNormalization"] = _freqNormalization;
138  _config["gpsEnable"] = _gpsEnabled;
139  _config["referenceTuningVoltage"] = _referenceTuningVoltage;
140  //this->debug("[NDR472::RadioHandler::initConfigurationDict] Returning\n");
141  }
142 
143  // OVERRIDE
145  {
146  this->debug("[NDR472::RadioHandler::queryConfiguration] Called\n");
147  // Call the base-class queryConfiguration() to retrieve identity info
148  // and query configuration for all components
150  this->debug("[NDR472::RadioHandler::queryConfiguration] Returning\n");
151  }
152 
153  // OVERRIDE
154  bool RadioHandler::queryVersionInfo()
155  {
156  this->debug("[NDR472::RadioHandler::queryVersionInfo] Called\n");
157  // First, call the base-class version
158  bool ret = ::LibCyberRadio::Driver::RadioHandler::queryVersionInfo();
159  // Next, use the hardware version info string to determine
160  // -- unit revision (N/A for this radio)
161  // -- number of tuner boards (always 1)
162  // -- max tuner bandwidth (always 3000)
163  // Debug dump
164  if (ret)
165  {
166  for (BasicStringStringDict::iterator it = _versionInfo.begin(); it != _versionInfo.end(); it++)
167  {
168  this->debug("[NDR472::RadioHandler::queryVersionInfo] %s = \"%s\"\n", it->first.c_str(), it->second.c_str());
169  }
170  }
171  this->debug("[NDR472::RadioHandler::queryVersionInfo] Returning %s\n",
172  this->debugBool(ret));
173  return ret;
174  }
175 
176  // OVERRIDE
177  // NDR472 response:
178  // NDR472
179  // S/N 01004
180  // OK
181  bool RadioHandler::executeQueryIDN(std::string& model,
182  std::string& serialNumber)
183  {
184  bool ret = false;
185  // Issue the identity query to get model and serial number
186  BasicStringList rsp = sendCommand("*IDN?\n", _defaultTimeout);
187  if ( getLastCommandErrorInfo() == "" )
188  {
189  BasicStringList::iterator it;
190  for (it = rsp.begin(); it != rsp.end(); it++)
191  {
192  if ( it->find("NDR") != std::string::npos )
193  model = *it;
194  if ( it->find("S/N ") != std::string::npos )
195  serialNumber = Pythonesque::Replace(*it, "S/N ", "");
196  }
197  ret = true;
198  }
199  return ret;
200  }
201 
202  // OVERRIDE
203  // NDR472 response:
204  // NDR472 Application code:
205  // REV: 14.05.30
206  // FPGA
207  // Loaded Image: 0 Rev: 14.05.28 Date:00.00.00
208  // *FLASH Image 0: 00 FF
209  // FLASH Image 1: 01 FF
210  // OK
211  bool RadioHandler::executeQueryVER(std::string& softwareVersion,
212  std::string& firmwareVersion,
213  std::string& referenceVersion,
214  std::string& firmwareDate)
215  {
216  bool ret = true;
217  // Query the version command to get software versioning info
218  BasicStringList rsp = sendCommand("VER?\n", _defaultTimeout);
219  if ( getLastCommandErrorInfo() == "" )
220  {
221  BasicStringList::iterator it;
222  bool parsingAppCode = false;
223  bool parsingFpga = false;
224  for (it = rsp.begin(); it != rsp.end(); it++)
225  {
226  if ( it->find("Application code") != std::string::npos )
227  {
228  parsingAppCode = true;
229  parsingFpga = false;
230  }
231  if ( it->find("FPGA") != std::string::npos )
232  {
233  parsingAppCode = false;
234  parsingFpga = true;
235  }
236  if ( parsingAppCode )
237  {
238  if ( it->find(" REV: ") != std::string::npos )
239  softwareVersion = Pythonesque::Replace(*it, " REV: ", "");
240  }
241  else if ( parsingFpga )
242  {
243  if ( it->find("Loaded Image") != std::string::npos )
244  {
245  std::string tmp = Pythonesque::Strip(*it);
246  BasicStringList vec = Pythonesque::Split(tmp, " ");
247  // vec[0] = FPGA image that is loaded
248  // vec[1] = Firmware version
249  firmwareVersion = Pythonesque::Replace(vec[1], "Rev: ", "");
250  // vec[2] = Firmware date
251  firmwareDate = Pythonesque::Replace(vec[2], "Date:", "");
252 
253  }
254  }
255  }
256  ret = true;
257  }
258  return ret;
259  }
260 
261  // OVERRIDE
262  // NDR472 response:
263  // Unit Model: NDR472
264  // S/N: 01004
265  // Digital Board Model: 602863
266  // S/N: 00007
267  // Rev: 01.00 05/03/2013
268  // Tuner Board Model: 601987-02
269  // S/N 1: 00005
270  // Rev: 03.00 05/03/2013
271  // OK
272  bool RadioHandler::executeQueryHREV(std::string& hardwareInfo)
273  {
274  bool ret = true;
275  // Query the hardware revision command to get other stuff
276  BasicStringList rsp = sendCommand("HREV?\n", _defaultTimeout);
277  if ( getLastCommandErrorInfo() == "" )
278  {
279  std::ostringstream oss;
280  BasicStringList::iterator it;
281  bool parsingUnitModel = false;
282  for (it = rsp.begin(); it != rsp.end(); it++)
283  {
284  if ( (*it != "OK") && (*it != "HREV?") )
285  {
286  if ( Pythonesque::Startswith(*it, "Unit Model") )
287  {
288  parsingUnitModel = true;
289  }
290  if ( Pythonesque::Startswith(*it, "Digital Board Model") ||
291  Pythonesque::Startswith(*it, "Tuner Board Model") )
292  {
293  parsingUnitModel = false;
294  }
295  if ( !parsingUnitModel )
296  {
297  if ( oss.str() != "" )
298  oss << "\n";
299  //oss << Pythonesque::Strip(*it);
300  oss << *it;
301  }
302  }
303  }
304  hardwareInfo = oss.str();
305  ret = true;
306  }
307  return ret;
308  }
309 
310  } /* namespace NDR472 */
311 
312  } /* namespace Driver */
313 
314 } /* namespace LibCyberRadio */
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
static std::string Strip(const std::string &str, const std::string &chars=" \\\)
Strips both leading and trailing whitespace from the given string.
Definition: Pythonesque.cpp:57
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
Radio handler class for the NDR472.
Definition: RadioHandler.h:133
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
static bool Startswith(const std::string &str, const std::string &prefix, int start=0, int end=INT_MAX)
Determines if the given string starts with the specified prefix.
Defines functionality for LibCyberRadio applications.
Definition: App.h:23
virtual std::string getLastCommandErrorInfo() const
Gets the error message from the last command attempted.
virtual const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
Definition: Debuggable.cpp:126
virtual ~RadioHandler()
Destroys a RadioHandler object.
virtual BasicStringList sendCommand(const std::string &cmdString, double timeout=-1)
Sends a command to 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 (...