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
23namespace 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 {
60 initConfigurationDict();
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
114
115 RadioHandler::RadioHandler(const RadioHandler &other) :
117 {
118 }
119
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 const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
virtual int debug(const char *format,...)
Outputs debug information.
Radio handler class for the NDR472.
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 ~RadioHandler()
Destroys a RadioHandler object.
VITA interface specification for the NDR472.
Definition VitaIfSpec.h:38
Generic radio handler class.
virtual std::string getLastCommandErrorInfo() const
Gets the error message from the last command attempted.
virtual RadioHandler & operator=(const RadioHandler &other)
Assignment operator for RadioHandler objects.
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...
virtual BasicStringList sendCommand(const std::string &cmdString, double timeout=-1)
Sends a command to the radio.
static std::string Strip(const std::string &str, const std::string &chars=" \r\n\t\v\f")
Strips both leading and trailing whitespace from the given string.
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.
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.
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.
Provides programming elements for driving NDR472 radios.
Provides programming elements for driving CRS NDR-class radios.
Defines functionality for LibCyberRadio applications.
Definition App.h:24
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition BasicList.h:25