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
24namespace 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 {
61 initConfigurationDict();
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
140
141 RadioHandler::RadioHandler(const RadioHandler &other) :
143 {
144 }
145
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 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 NDR308-TS.
virtual void queryConfiguration()
Tells the radio to query its hardware configuration in order to create its configuration dictionary (...
virtual ~RadioHandler()
Destroys a RadioHandler object.
VITA interface specification for the NDR308-TS.
Definition VitaIfSpec.h:38
Generic radio handler class.
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 (...
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 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 NDR308-TS radios.
Definition DataPort.h:34
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