libcyberradio  22.01.24
RadioHandler.cpp
1 /***************************************************************************
2  * \file RadioHandler.cpp
3  * \brief Defines the radio handler interface for the NDR551.
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/NDR358/RadioHandler.h"
12 #include "LibCyberRadio/Driver/NDR551/DataPort.h"
13 #include "LibCyberRadio/Driver/NDR551/NbddcComponent.h"
14 #include "LibCyberRadio/Driver/NDR551/TunerComponent.h"
15 #include "LibCyberRadio/Driver/NDR551/VitaIfSpec.h"
16 #include "LibCyberRadio/Driver/NDR551/WbddcComponent.h"
17 //#include "LibCyberRadio/Driver/NDR551/WbddcGroupComponent.h"
18 //#include "LibCyberRadio/Driver/NDR551/NbddcGroupComponent.h"
19 #include "LibCyberRadio/Common/Pythonesque.h"
20 #include <json/json.h>
21 #include <sstream>
22 #include <cstdio>
23 #include <iostream>
24 #include <cstring>
25 
26 static uint32_t msgCounter = 1;
27 
28 namespace LibCyberRadio
29 {
30 
31  namespace Driver
32  {
33  namespace NDR358
34  {
35 
36  RadioHandler::RadioHandler(bool debug) :
37  ::LibCyberRadio::Driver::RadioHandler(
38  /* const std::string& name */ "NDR358",
39  /* int numTuner */ 8,
40  /* int tunerIndexBase */ 0,
41  /* int numWbddc */ 8,
42  /* int wbddcIndexBase */ 0,
43  /* int numNbddc */ 64,
44  /* int nbddcIndexBase */ 0,
45  /* int numTunerBoards */ 1,
46  /* int maxTunerBw */ 6000,
47  /* int numTransmitters */ 0,
48  /* int transmitterIndexBase */ 0,
49  /* int numDuc */ 0,
50  /* int ducIndexBase */ 0,
51  /* int numWbddcGroups */ 4,
52  /* int wbddcGroupIndexBase */ 1,
53  /* int numNbddcGroups */ 8,
54  /* int nbddcGroupIndexBase */ 1,
55  /* int numDdcGroups */ 0,
56  /* int ddcGroupIndexBase */ 1,
57  /* int numDataPorts */ 4,
58  /* int dataPortIndexBase */ 0,
59  /* int numSimpleIpSetups */ 0,
60  /* double adcRate */ 128.036,
61  /* VitaIfSpec ifSpec */ NDR551::VitaIfSpec(),
62  /* bool debug */ debug)
63  {
65  _connModesSupported.push_back("udp");
66  _defaultDeviceInfo = 19091;
67  _transport.setJson(true);
68 
69 
70  // Allocate tuner components
71  for (int tuner = _tunerIndexBase;
72  tuner < (_tunerIndexBase + _numTuner); tuner++)
73  {
74 
75  _tuners[tuner] = new NDR551::TunerComponent(
76  /* int index */ tuner,
77  /* RadioHandler* parent */ this,
78  /* bool debug */ _debug,
79  /* double frequency */ 800e6,
80  /* double attenuation */ 0.0,
81  /* int filter */ 0);
82  }
83  // Allocate WBDDC components
84  for (int wbddc = _wbddcIndexBase;
85  wbddc < (_wbddcIndexBase + _numWbddc); wbddc++)
86  {
87  _wbddcs[wbddc] = new NDR551::WbddcComponent(
88  /* int index */ wbddc,
89  /* RadioHandler* parent */ this,
90  /* bool debug */ _debug,
91  /* int dataPort */ 1,
92  /* int rateIndex */ 0,
93  /* int udpDestination */ 0,
94  /* int vitaEnable */ 0,
95  /* int streamId */ 0);
96  }
97  // Allocate NBDDC components
98  for (int nbddc = _nbddcIndexBase;
99  nbddc < (_nbddcIndexBase + _numNbddc); nbddc++)
100  {
101  _nbddcs[nbddc] = new NDR551::NbddcComponent(
102  /* int index */ nbddc,
103  /* RadioHandler* parent */ this,
104  /* bool debug */ _debug,
105  /* int dataPort */ 1,
106  /* int rateIndex */ 0,
107  /* int udpDestination */ 0,
108  /* int vitaEnable */ 0,
109  /* int streamId */ 0,
110  /* double frequency */ 0.0,
111  /* int source */ 1);
112  }
113 #if 0
114  // Allocate WBDDC group components
115  for (int group = _wbddcGroupIndexBase;
116  group < (_wbddcGroupIndexBase + _numWbddcGroups); group++)
117  {
118  _wbddcGroups[group] = new NDR551::WbddcGroupComponent(
119  /* int index */ group,
120  /* RadioHandler* parent */ this,
121  /* bool debug */ _debug);
122  }
123  // Allocate NBDDC group components
124  for (int group = _nbddcGroupIndexBase;
125  group < (_nbddcGroupIndexBase + _numNbddcGroups); group++)
126  {
127  _nbddcGroups[group] = new NDR551::NbddcGroupComponent(
128  /* int index */ group,
129  /* RadioHandler* parent */ this,
130  /* bool debug */ _debug);
131  }
132 #endif
133  // Allocate data ports
134  for (int dataPort = _dataPortIndexBase;
135  dataPort < (_dataPortIndexBase + _numDataPorts); dataPort++)
136  {
137  _dataPorts[dataPort] = new NDR551::DataPort(
138  /* int index */ dataPort,
139  /* RadioHandler* parent */ this,
140  /* bool debug */ _debug,
141  /* const std::string& sourceIP */ "0.0.0.0");
142  }
143  }
144 
146  {
147  }
148 
149  RadioHandler::RadioHandler(const RadioHandler &other) :
150  ::LibCyberRadio::Driver::RadioHandler(other)
151  {
152  }
153  // Default implementation is the NDR308 pattern
155  {
156  //this->debug("[RadioHandler::initConfigurationDict] Called\n");
157  _config.clear();
158  _config["referenceMode"] = _referenceMode;
159  //this->debug("[RadioHandler::initConfigurationDict] Returning\n");
160  }
161 
162  RadioHandler& RadioHandler::operator=(const RadioHandler& other)
163  {
164  ::LibCyberRadio::Driver::RadioHandler::operator=(other);
165  // Block self-assignment
166  if (this != &other)
167  {
168  }
169  return *this;
170  }
171 
173  {
174  this->debug("[NDR358]::RadioHandler::queryConfiguration] Called\n");
175  // Purge the banner sent over when a connection is made.
176  //BasicStringList rsp = _transport.receive(_defaultTimeout);
177  // Call the base-class queryConfiguration() to retrieve identity info
178  // and query configuration for all components
179  Json::Value root(Json::objectValue);
180  root["msg"] = this->getMessageId();
181  root["cmd"] = "qstatus";
182  Json::Value params(Json::objectValue);
183  root["params"] = params;
184  Json::FastWriter fastWriter;
185  std::string output = fastWriter.write(root);
187  if ( _config.hasKey("referenceMode") )
188  {
189  this->executeReferenceModeQuery(_referenceMode);
190  }
191  this->debug("[NDR358::RadioHandler::queryConfiguration] Returning\n");
192 
193  for ( TunerComponentDict::iterator it = _tuners.begin();
194  it != _tuners.end(); it++)
195  {
196  it->second->queryConfiguration();
197  }
198  for ( WbddcComponentDict::iterator it = _wbddcs.begin();
199  it != _wbddcs.end(); it++)
200  {
201  it->second->queryConfiguration();
202  }
203  for ( DataPortDict::iterator it = _dataPorts.begin();
204  it != _dataPorts.end(); it++)
205  {
206  it->second->queryConfiguration();
207  }
208  this->queryVersionInfo();
209  }
210 
211  bool RadioHandler::query358Specifics()
212  {
213  Json::Value root(Json::objectValue);
214  root["msg"] = this->getMessageId();
215  root["cmd"] = "cli";
216  Json::Value params(Json::objectValue);
217  params["input"] = "version";
218  root["params"] = params;
219  Json::FastWriter fastWriter;
220  std::string output = fastWriter.write(root);
222  Json::Reader reader;
223  Json::Value returnVal;
224  std::string t = rsp.at(0);
225  bool parsingSuccessful = reader.parse( t.c_str(), returnVal ); //parse process
226  if( parsingSuccessful ){
227  if ( returnVal["result"].isString() ) {
228  std::string result = returnVal["result"].asString();
229  LibCyberRadio::BasicStringList l = Pythonesque::Split(Pythonesque::Lstrip(result), "\n"); //Pythonesque::Split(Pythonesque::Replace(result," ", ""), "\n");
230  for(int i = 0; i < l.size(); i++)
231  {
232  std::string temp = l.at(i);
233  temp = Pythonesque::Replace(temp," ", "").c_str();
234  BasicStringList J = Pythonesque::Split(temp, ":");
235  const char *unitsn = "UnitSN";
236  if ( std::strstr(temp.c_str(), unitsn) != nullptr )
237  {
238  _versionInfo["serialNumber"] = J.at(1).c_str();
239  }
240  }
241  } else {
242  _versionInfo["serialNumber"] = "SNxxxx";
243  }
244  }
245  return true;
246  }
247 
248  bool RadioHandler::queryVersionInfo()
249  {
250  this->debug("[RadioHandler::queryVersionInfo] Called\n");
251  // First, call the base-class version
252  bool ret = true;
253  Json::Value root(Json::objectValue);
254  root["msg"] = this->getMessageId();
255  root["cmd"] = "qstatus";
256  Json::Value params(Json::objectValue);
257  root["params"] = params;
258  Json::FastWriter fastWriter;
259  std::string output = fastWriter.write(root);
261  Json::Reader reader;
262  Json::Value returnVal;
263  std::string t = rsp.at(0);
264  bool parsingSuccessful = reader.parse( t.c_str(), returnVal ); //parse process
265  if( parsingSuccessful ){
266  _versionInfo["model"] = returnVal["result"]["model"].asString();
267  _versionInfo["softwareVersion"] = returnVal["result"]["sw"].asString();
268  _versionInfo["firmwareVersion"] = returnVal["result"]["fw"].asString();
269  _versionInfo["unitRevision"] = returnVal["result"]["unit"].asString();
270  _versionInfo["hardwareVersion"] = returnVal["result"]["unit"].asString();
271  }
272  this->query358Specifics();
273  this->debug("[NDR358::RadioHandler::queryVersionInfo] Returning %s\n", debugBool(ret));
274  return ret;
275  }
276 
277  // NOTE: The default implementation is the NDR358 implementation,
278  // but this just makes it explicit in the code.
279  bool RadioHandler::executeQueryIDN(std::string& model,
280  std::string& serialNumber)
281  {
282  return ::LibCyberRadio::Driver::RadioHandler::executeQueryIDN(model, serialNumber);
283  }
284 
285  // NOTE: The default implementation is the NDR358 implementation,
286  // but this just makes it explicit in the code.
287  bool RadioHandler::executeQueryVER(std::string& softwareVersion,
288  std::string& firmwareVersion,
289  std::string& referenceVersion,
290  std::string& firmwareDate)
291  {
292 
293  return ::LibCyberRadio::Driver::RadioHandler::executeQueryVER(softwareVersion,
294  firmwareVersion,
295  referenceVersion,
296  firmwareDate);
297  }
298 
299  // NOTE: The default implementation is the NDR358 implementation,
300  // but this just makes it explicit in the code.
301  bool RadioHandler::executeQueryHREV(std::string& hardwareInfo)
302  {
303  return ::LibCyberRadio::Driver::RadioHandler::executeQueryHREV(hardwareInfo);
304  }
305 
306  uint32_t RadioHandler::getMessageId( void )
307  {
308  return msgCounter++;
309  }
310 
311  bool RadioHandler::executeReferenceModeQuery(int& refMode)
312  {
313  this->debug("[NDR358::RadioHandler::queryVersionInfo] Called\n");
314  // First, call the base-class version
315  bool ret = false;
316  Json::Value root(Json::objectValue);
317  root["msg"] = this->getMessageId();
318  root["cmd"] = "qref";
319  Json::Value params(Json::objectValue);
320  root["params"] = params;
321  Json::FastWriter fastWriter;
322  std::string output = fastWriter.write(root);
323  BasicStringList rsp = this->sendCommand(output);
324  Json::Reader reader;
325  Json::Value returnVal;
326  std::string t = rsp.at(0);
327  bool parsingSuccessful = reader.parse( t.c_str(), returnVal ); //parse process
328  if( parsingSuccessful ){
329  refMode = boost::lexical_cast<int>(returnVal["result"]["cfg10m"].asInt());
330  ret = true;
331  }
332  return ret;
333  }
334 
335  bool RadioHandler::executeReferenceModeCommand(int& refMode)
336  {
337  this->debug("[NDR358::RadioHandler::queryVersionInfo] Called\n");
338  // First, call the base-class version
339  bool ret = false;
340  Json::Value root(Json::objectValue);
341  root["msg"] = this->getMessageId();
342  root["cmd"] = "ref";
343  Json::Value params(Json::objectValue);
344  params["cfg10m"] = refMode;
345  root["params"] = params;
346  Json::FastWriter fastWriter;
347  std::string output = fastWriter.write(root);
348  BasicStringList rsp = this->sendCommand(output);
349  Json::Reader reader;
350  Json::Value returnVal;
351  std::string t = rsp.at(0);
352  bool parsingSuccessful = reader.parse( t.c_str(), returnVal ); //parse process
353  if( parsingSuccessful ){
354  ret = boost::lexical_cast<bool>(returnVal["success"].asBool());
355  }
356  return ret;
357  }
358 
359 
360  } /* namespace NDR358 */
361 
362  } /* namespace Driver */
363 
364 } /* namespace LibCyberRadio */
virtual ~RadioHandler()
Destroys a RadioHandler object.
virtual bool hasKey(const std::string &key) const
Determines if the dictionary has the given key.
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
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
Radio handler class for the NDR551.
Definition: RadioHandler.h:180
Defines functionality for LibCyberRadio applications.
Definition: App.h:23
static std::string Lstrip(const std::string &str, const std::string &chars=" \\\)
Strips leading whitespace from the given string.
Definition: Pythonesque.cpp:25
virtual const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
Definition: Debuggable.cpp:126
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...
uint32_t getMessageId(void)
Returns a Time for the msg parameter.
virtual BasicStringList sendCommand(const std::string &cmdString, double timeout=-1)
Sends a command to the radio.
void setJson(bool json)
Allows user to set JSON.
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.