libcyberradio 22.01.24
WbddcComponent.cpp
1/***************************************************************************
2 * \file WbddcComponent.cpp
3 * \brief Defines the basic WBDDC interface for an NDR-class radio.
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/RadioHandler.h"
12#include "LibCyberRadio/Driver/WbddcComponent.h"
13#include "LibCyberRadio/Common/Pythonesque.h"
14#include <boost/lexical_cast.hpp>
15#include <sstream>
16#include <iomanip>
17
18
19namespace LibCyberRadio
20{
21 namespace Driver
22 {
23
25 const std::string& name,
26 int index,
27 RadioHandler* parent,
28 bool debug,
29 bool tunable,
30 bool selectableSource,
31 bool selectableDataPort,
32 bool agc,
33 double freqRangeMin,
34 double freqRangeMax,
35 double freqRes,
36 double freqUnits,
37 int source,
38 int dataPort,
39 double frequency,
40 int rateIndex,
41 int udpDestination,
42 int vitaEnable,
43 unsigned int streamId) :
44 RadioComponent(name, index, parent, debug),
45 _tunable(tunable),
46 _selectableSource(selectableSource),
47 _selectableDataPort(selectableDataPort),
48 _agc(agc),
49 _freqRangeMin(freqRangeMin),
50 _freqRangeMax(freqRangeMax),
51 _freqRes(freqRes),
52 _freqUnits(freqUnits),
53 _source(source),
54 _dataPort(dataPort),
55 _frequency(frequency),
56 _rateIndex(rateIndex),
57 _udpDestination(udpDestination),
58 _vitaEnable(vitaEnable),
59 _streamId(streamId)
60 {
62 }
63
67
69 RadioComponent(other),
70 _tunable(other._tunable),
71 _selectableSource(other._selectableSource),
72 _selectableDataPort(other._selectableDataPort),
73 _agc(other._agc),
74 _freqRangeMin(other._freqRangeMin),
75 _freqRangeMax(other._freqRangeMax),
76 _freqRes(other._freqRes),
77 _freqUnits(other._freqUnits),
78 _source(other._source),
79 _dataPort(other._dataPort),
80 _frequency(other._frequency),
81 _rateIndex(other._rateIndex),
82 _udpDestination(other._udpDestination),
83 _vitaEnable(other._vitaEnable),
84 _streamId(other._streamId)
85 {
86 }
87
89 {
91 if ( this != &other )
92 {
93 _tunable = other._tunable;
94 _selectableSource = other._selectableSource;
95 _selectableDataPort = other._selectableDataPort;
96 _agc = other._agc;
97 _freqRangeMin = other._freqRangeMin;
98 _freqRangeMax = other._freqRangeMax;
99 _freqRes = other._freqRes;
100 _freqUnits = other._freqUnits;
101 _source = other._source;
102 _dataPort = other._dataPort;
103 _frequency = other._frequency;
104 _rateIndex = other._rateIndex;
105 _udpDestination = other._udpDestination;
106 _vitaEnable = other._vitaEnable;
107 _streamId = other._streamId;
108 }
109 return *this;
110 }
111
112 bool WbddcComponent::enable(bool enabled)
113 {
114 bool ret = false;
115 if ( _config.hasKey("enable") )
116 {
117 int adjRateIndex = _rateIndex;
118 int adjUdpDest = _udpDestination;
119 int adjVita = _vitaEnable;
120 unsigned int adjStream = _streamId;
121 bool adjEnabled = enabled;
122 ret = executeWbddcCommand(_index, adjRateIndex, adjUdpDest, adjEnabled, adjVita, adjStream);
123 if ( ret )
124 {
125 _enabled = adjEnabled;
127 }
128 }
129 return ret;
130 }
131
133 {
134 this->debug("[WbddcComponent::setConfiguration] Called\n");
135 // Call the "grandparent" version of this method instead of the
136 // parent version. We want the normalization, but not the
137 // automatic enabling.
138 bool ret = Configurable::setConfiguration(cfg);
139 // Use the keys provided in the *incoming* dictionary to determine
140 // what needs to be changed via hardware calls.
141 int adjRateIndex = _rateIndex;
142 int adjUdpDest = _udpDestination;
143 int adjVita = _vitaEnable;
144 unsigned int adjStream = _streamId;
145 bool adjEnabled = _enabled;
146 double adjFreq = _frequency;
147 int adjSource = _source;
148 int adjDataPort = _dataPort;
149 bool ddcCmdNeedsExecuting = false;
150 bool freqCmdNeedsExecuting = false;
151 bool srcCmdNeedsExecuting = false;
152 bool dpCmdNeedsExecuting = false;
153 if ( cfg.hasKey("enable") && _config.hasKey("enable") )
154 {
155 adjEnabled = getConfigurationValueAsBool("enable");
156 ddcCmdNeedsExecuting = true;
157 }
158 if ( cfg.hasKey("rateIndex") && _config.hasKey("rateIndex") )
159 {
160 adjRateIndex = getConfigurationValueAsInt("rateIndex");
161 ddcCmdNeedsExecuting = true;
162 }
163 if ( cfg.hasKey("udpDestination") && _config.hasKey("udpDestination") )
164 {
165 adjUdpDest = getConfigurationValueAsInt("udpDestination");
166 ddcCmdNeedsExecuting = true;
167 }
168 if ( cfg.hasKey("vitaEnable") && _config.hasKey("vitaEnable") )
169 {
170 adjVita = getConfigurationValueAsInt("vitaEnable");
171 ddcCmdNeedsExecuting = true;
172 }
173 if ( cfg.hasKey("streamId") && _config.hasKey("streamId") )
174 {
175 adjStream = getConfigurationValueAsUInt("streamId");
176 ddcCmdNeedsExecuting = true;
177 }
178 if ( _tunable )
179 {
180 if ( cfg.hasKey("frequency") && _config.hasKey("frequency") )
181 {
182 adjFreq = getConfigurationValueAsDbl("frequency");
183 freqCmdNeedsExecuting = true;
184 }
185 }
186 if ( _selectableSource )
187 {
188 if ( cfg.hasKey("source") && _config.hasKey("source") )
189 {
190 adjSource = getConfigurationValueAsInt("source");
191 srcCmdNeedsExecuting = true;
192 }
193 }
194 if ( _selectableDataPort )
195 {
196 if ( cfg.hasKey("dataPort") && _config.hasKey("dataPort") )
197 {
198 adjDataPort = getConfigurationValueAsInt("dataPort");
199 dpCmdNeedsExecuting = true;
200 }
201 }
202 if ( ddcCmdNeedsExecuting )
203 {
204 ret &= executeWbddcCommand(_index, adjRateIndex, adjUdpDest,
205 adjEnabled, adjVita, adjStream);
206 }
207 if ( freqCmdNeedsExecuting )
208 {
209 ret &= executeFreqCommand(_index, adjFreq);
210 }
211 if ( srcCmdNeedsExecuting )
212 {
213 ret &= executeSourceCommand(_index, adjSource);
214 }
215 if ( dpCmdNeedsExecuting )
216 {
217 ret &= executeDataPortCommand(_index, adjDataPort);
218 }
219 if ( ret )
220 {
221 _rateIndex = adjRateIndex;
222 _udpDestination = adjUdpDest;
223 _vitaEnable = adjVita;
224 _streamId = adjStream;
225 _enabled = adjEnabled;
226 _frequency = adjFreq;
227 _source = adjSource;
228 _dataPort = adjDataPort;
230 }
231 this->debug("[WbddcComponent::setConfiguration] Returning\n");
232 return ret;
233 }
234
236 {
237 this->debug("[WbddcComponent::queryConfiguration] Called\n");
238 if ( _config.hasKey("enable") &&
239 _config.hasKey("rateIndex") &&
240 _config.hasKey("udpDestination") &&
241 _config.hasKey("vitaEnable") &&
242 _config.hasKey("streamId") )
243 {
244 executeWbddcQuery(_index, _rateIndex, _udpDestination, _enabled,
245 _vitaEnable, _streamId);
246 }
247 if ( _tunable && _config.hasKey("frequency") )
248 {
249 executeFreqQuery(_index, _frequency);
250 }
251 if ( _selectableSource && _config.hasKey("source") )
252 {
253 executeSourceQuery(_index, _source);
254 }
255 if ( _selectableDataPort && _config.hasKey("dataPort") )
256 {
257 executeDataPortQuery(_index, _dataPort);
258 }
260 this->debug("[WbddcComponent::queryConfiguration] Returning\n");
261 }
262
264 {
265 return _frequency;
266 }
267
269 {
270 bool ret = false;
271 if ( _tunable && _config.hasKey("frequency") )
272 {
273 double adjFreq = _frequency;
274 ret = executeFreqCommand(_index, adjFreq);
275 if ( ret )
276 {
277 _frequency = adjFreq;
279 }
280 }
281 return ret;
282 }
283
285 {
286 BasicDoubleList ret;
287 ret.push_back(_freqRangeMin);
288 ret.push_back(_freqRangeMax);
289 return ret;
290 }
291
293 {
294 return _freqRes;
295 }
296
298 {
299 return _freqUnits;
300 }
301
303 {
304 return _agc;
305 }
306
308 {
309 return _tunable;
310 }
311
313 {
314 return _selectableSource;
315 }
316
318 {
319 return _source;
320 }
321
323 {
324 bool ret = false;
325 if ( _selectableSource && _config.hasKey("source") )
326 {
327 int adjSource = source;
328 ret = executeSourceCommand(_index, adjSource);
329 if ( ret )
330 {
331 _source = adjSource;
333 }
334 }
335 return ret;
336 }
337
339 {
340 return _rateIndex;
341 }
342
344 {
345 bool ret = false;
346 if ( _config.hasKey("rateIndex") )
347 {
348 int adjRateIndex = index;
349 int adjUdpDest = _udpDestination;
350 int adjVita = _vitaEnable;
351 unsigned int adjStream = _streamId;
352 bool adjEnabled = _enabled;
353 ret = executeWbddcCommand(_index, adjRateIndex, adjUdpDest, adjEnabled, adjVita, adjStream);
354 if ( ret )
355 {
356 _rateIndex = adjRateIndex;
358 }
359 }
360 return ret;
361 }
362
364 {
365 return _udpDestination;
366 }
367
369 {
370 bool ret = false;
371 if ( _config.hasKey("udpDestination") )
372 {
373 int adjRateIndex = _rateIndex;
374 int adjUdpDest = dest;
375 int adjVita = _vitaEnable;
376 unsigned int adjStream = _streamId;
377 bool adjEnabled = _enabled;
378 ret = executeWbddcCommand(_index, adjRateIndex, adjUdpDest, adjEnabled, adjVita, adjStream);
379 if ( ret )
380 {
381 _udpDestination = adjUdpDest;
383 }
384 }
385 return ret;
386 }
387
389 {
390 return _vitaEnable;
391 }
392
394 {
395 bool ret = false;
396 if ( _config.hasKey("vitaEnable") )
397 {
398 int adjRateIndex = _rateIndex;
399 int adjUdpDest = _udpDestination;
400 int adjVita = enable;
401 unsigned int adjStream = _streamId;
402 bool adjEnabled = _enabled;
403 ret = executeWbddcCommand(_index, adjRateIndex, adjUdpDest, adjEnabled, adjVita, adjStream);
404 if ( ret )
405 {
406 _vitaEnable = adjVita;
408 }
409 }
410 return ret;
411 }
412
413 unsigned int WbddcComponent::getStreamId() const
414 {
415 return _streamId;
416 }
417
418 bool WbddcComponent::setStreamId(unsigned int sid)
419 {
420 bool ret = false;
421 if ( _config.hasKey("streamId") )
422 {
423 int adjRateIndex = _rateIndex;
424 int adjUdpDest = _udpDestination;
425 int adjVita = _vitaEnable;
426 unsigned int adjStream = sid;
427 bool adjEnabled = _enabled;
428 ret = executeWbddcCommand(_index, adjRateIndex, adjUdpDest, adjEnabled, adjVita, adjStream);
429 if ( ret )
430 {
431 _streamId = adjStream;
433 }
434 }
435 return ret;
436 }
437
439 {
440 return _dataPort;
441 }
442
444 {
445 bool ret = false;
446 if ( _selectableDataPort && _config.hasKey("dataPort") )
447 {
448 int adjDataPort = port;
449 ret = executeDataPortCommand(_index, adjDataPort);
450 if ( ret )
451 {
452 _dataPort = adjDataPort;
454 }
455 }
456 return ret;
457 }
458
460 {
461 return _rateSet;
462 }
463
465 {
466 _rateSet = set;
467 return true;
468 }
469
471 {
472 BasicDoubleList ret;
473 for (WbddcRateSet::const_iterator it = _rateSet.begin(); it != _rateSet.end(); it++)
474 {
475 ret.push_back(it->second);
476 }
477 return ret;
478 }
479
481 {
482 //this->debug("[WbddcComponent::initConfigurationDict] Called\n");
483 _config.clear();
484 // Call the base-class version
486 // Define tuner-specific keys
487 _config["rateIndex"] = "";
488 _config["udpDestination"] = "";
489 _config["vitaEnable"] = "";
490 _config["streamId"] = "";
491 if ( _tunable )
492 {
493 _config["frequency"] = "";
494 }
495 if ( _selectableSource )
496 {
497 _config["source"] = "";
498 }
499 if ( _selectableDataPort )
500 {
501 _config["dataPort"] = "";
502 }
503 //this->debug("[WbddcComponent::initConfigurationDict] Returning\n");
504 }
505
507 {
508 this->debug("[WbddcComponent::updateConfigurationDict] Called\n");
510 if ( _config.hasKey("rateIndex") )
511 setConfigurationValueToInt("rateIndex", _rateIndex);
512 if ( _config.hasKey("udpDestination") )
513 setConfigurationValueToInt("udpDestination", _udpDestination);
514 if ( _config.hasKey("vitaEnable") )
515 setConfigurationValueToInt("vitaEnable", _vitaEnable);
516 if ( _config.hasKey("streamId") )
517 setConfigurationValueToUInt("streamId", _streamId);
518 if ( _tunable && _config.hasKey("frequency") )
519 {
520 setConfigurationValueToDbl("frequency", _frequency);
521 }
522 if ( _selectableSource && _config.hasKey("source") )
523 {
524 setConfigurationValueToInt("source", _source);
525 }
526 if ( _selectableDataPort && _config.hasKey("dataPort") )
527 {
528 setConfigurationValueToInt("dataPort", _dataPort);
529 }
530 this->debug("[WbddcComponent::updateConfigurationDict] Returning\n");
531 }
532
533 // Default implementation uses the NDR308 syntax.
534 // WBDDC? <index>
535 bool WbddcComponent::executeWbddcQuery(int index, int& rateIndex,
536 int& udpDestination, bool& enabled, int& vitaEnable,
537 unsigned int& streamId)
538 {
539 bool ret = false;
540 if ( (_parent != NULL) && (_parent->isConnected()) )
541 {
542 std::ostringstream oss;
543 oss << "WBDDC? " << index << "\n";
544 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
545 if ( _parent->getLastCommandErrorInfo() == "" )
546 {
548 Pythonesque::Replace(rsp.front(), "WBDDC ", ""),
549 ", ");
550 // vec[0] = Index
551 // vec[1] = Rate index
552 rateIndex = boost::lexical_cast<int>(vec[1]);
553 udpDestination = boost::lexical_cast<int>(vec[2]);
554 enabled = (boost::lexical_cast<int>(vec[3]) == 1);
555 vitaEnable = boost::lexical_cast<int>(vec[4]);
556 streamId = boost::lexical_cast<unsigned int>(vec[5]);
557 ret = true;
558 }
559 }
560 return ret;
561 }
562
563 // Default implementation uses the NDR308 syntax.
564 // WBDDC <index>, <rate index>, <udp dest>, <enable>, <vita enable>, <stream id>
565 bool WbddcComponent::executeWbddcCommand(int index, int& rateIndex,
566 int& udpDestination, bool& enabled, int& vitaEnable,
567 unsigned int& streamId)
568 {
569 bool ret = false;
570 if ( (_parent != NULL) && (_parent->isConnected()) )
571 {
572 std::ostringstream oss;
573 oss << "WBDDC " << index
574 << ", " << rateIndex
575 << ", " << udpDestination
576 << ", " << (enabled ? 1 : 0)
577 << ", " << vitaEnable
578 << ", " << streamId
579 << "\n";
580 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
581 if ( _parent->getLastCommandErrorInfo() == "" )
582 {
583 ret = true;
584 }
585 }
586 return ret;
587 }
588
589 // Default implementation returns false, since it is based on
590 // the NDR308, which does not support tunable WBDDCs.
591 bool WbddcComponent::executeFreqQuery(int index, double& freq)
592 {
593 return false;
594 }
595
596 // Default implementation returns false, since it is based on
597 // the NDR308, which does not support tunable WBDDCs.
598 bool WbddcComponent::executeFreqCommand(int index, double& freq)
599 {
600 return false;
601 }
602
603 // Default implementation returns false, since it is based on
604 // the NDR308, which does not support selectable-source WBDDCs.
605 bool WbddcComponent::executeSourceQuery(int index, int& source)
606 {
607 return false;
608 }
609 // Default implementation uses the NDR308 syntax.
610
611 // Default implementation returns false, since it is based on
612 // the NDR308, which does not support selectable-source WBDDCs.
613 bool WbddcComponent::executeSourceCommand(int index, int& source)
614 {
615 return false;
616 }
617
618 // Default implementation uses the NDR308 syntax.
619 // WBDP? <index>
620 bool WbddcComponent::executeDataPortQuery(int index, int& dataPort)
621 {
622 bool ret = false;
623 if ( (_parent != NULL) && (_parent->isConnected()) )
624 {
625 std::ostringstream oss;
626 oss << "WBDP? " << index << "\n";
627 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
628 if ( _parent->getLastCommandErrorInfo() == "" )
629 {
631 Pythonesque::Replace(rsp.front(), "WBDP ", ""),
632 ", ");
633 // vec[0] = Index
634 // vec[1] = Data Port
635 dataPort = boost::lexical_cast<int>(vec[1]);
636 ret = true;
637 }
638 }
639 return ret;
640 }
641
642 // Default implementation uses the NDR308 syntax.
643 // WBDP <index>, <data port>
644 bool WbddcComponent::executeDataPortCommand(int index, int& dataPort)
645 {
646 bool ret = false;
647 if ( (_parent != NULL) && (_parent->isConnected()) )
648 {
649 std::ostringstream oss;
650 oss << "WBDP " << index
651 << ", " << dataPort
652 << "\n";
653 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
654 if ( _parent->getLastCommandErrorInfo() == "" )
655 {
656 ret = true;
657 }
658 }
659 return ret;
660 }
661
662 } // namespace Driver
663
664} // namespace LibCyberRadio
665
virtual int debug(const char *format,...)
Outputs debug information.
virtual bool setConfiguration(ConfigurationDict &cfg)
Sets the configuration dictionary for this object.
virtual int getConfigurationValueAsInt(const std::string &key) const
Gets a named configuration value as an integer value.
virtual double getConfigurationValueAsDbl(const std::string &key) const
Gets a named configuration value as a double value.
virtual bool getConfigurationValueAsBool(const std::string &key) const
Gets a named configuration value as a Boolean.
virtual unsigned int getConfigurationValueAsUInt(const std::string &key) const
Gets a named configuration value as an unsigned integer value.
virtual bool setConfigurationValueToUInt(const std::string &key, const unsigned int value)
Sets a named configuration value to an unsigned integer value.
virtual bool setConfigurationValueToInt(const std::string &key, const int value)
Sets a named configuration value to an integer value.
virtual bool setConfigurationValueToDbl(const std::string &key, const double value)
Sets a named configuration value to a double value.
A configuration dictionary.
virtual bool hasKey(const std::string &key) const
Determines if the dictionary has the given key.
virtual void updateConfigurationDict()
Updates the configuration dictionary from component settings.
virtual RadioComponent & operator=(const RadioComponent &other)
Assignment operator for RadioComponent objects.
RadioComponent(const std::string &name="<unknown>", int index=0, RadioHandler *parent=NULL, bool debug=false)
Constructs a RadioComponent object.
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
Generic radio handler class.
virtual bool enable(bool enabled=true)
Enables this component.
virtual bool setConfiguration(ConfigurationDict &cfg)
Sets the configuration dictionary for this component.
virtual int getSource() const
Gets the WBDDC's source (which tuner is supplying the signal).
virtual bool executeSourceQuery(int index, int &source)
Executes the WBDDC source query command.
virtual WbddcComponent & operator=(const WbddcComponent &other)
Assignment operator for WbddcComponent objects.
virtual int getUdpDestination() const
Gets the WBDDC's UDP destination.
virtual BasicDoubleList getFrequencyRange() const
Gets the tunable frequency range.
virtual bool setVitaEnable(int enable)
Sets the WBDDC's VITA 49 setting.
virtual bool executeWbddcCommand(int index, int &rateIndex, int &udpDestination, bool &enabled, int &vitaEnable, unsigned int &streamId)
Executes the WBDDC configuration set command.
virtual bool setFrequency(double freq)
Sets the WBDDC tuned frequency.
virtual bool executeSourceCommand(int index, int &source)
Executes the WBDDC source set command.
virtual bool isAgcSupported() const
Gets whether or not the WBDDC supports AGC.
virtual int getDataPort() const
Gets the WBDDC's data port.
virtual double getFrequency() const
Gets the tuned frequency.
virtual BasicDoubleList getRateList() const
Gets the list of allowed sample rates, based on the rate set.
virtual bool executeWbddcQuery(int index, int &rateIndex, int &udpDestination, bool &enabled, int &vitaEnable, unsigned int &streamId)
Executes the WBDDC configuration query command.
virtual bool executeFreqCommand(int index, double &freq)
Executes the WBDDC frequency set command.
virtual unsigned int getStreamId() const
Gets the WBDDC's VITA 49 stream ID.
virtual bool isSourceSelectable() const
Gets whether or not the WBDDC supports selectable source.
virtual int getRateIndex() const
Gets the WBDDC's rate index.
virtual bool setUdpDestination(int dest)
Sets the WBDDC's UDP destination.
virtual bool setRateSet(const WbddcRateSet &set)
Sets the WBDDC rate set.
virtual void queryConfiguration()
Tells the component to query its hardware configuration in order to create its configuration dictiona...
virtual bool setDataPort(int port)
Sets the WBDDC's data port.
virtual bool executeFreqQuery(int index, double &freq)
Executes the WBDDC frequency query command.
virtual bool setStreamId(unsigned int sid)
Sets the WBDDC's VITA 49 stream ID.
virtual WbddcRateSet getRateSet() const
Gets the WBDDC's rate set.
virtual void updateConfigurationDict()
Updates the configuration dictionary from component settings.
WbddcComponent(const std::string &name="WBDDC", int index=1, RadioHandler *parent=NULL, bool debug=false, bool tunable=false, bool selectableSource=false, bool selectableDataPort=false, bool agc=false, double freqRangeMin=0.0, double freqRangeMax=0.0, double freqRes=1.0, double freqUnits=1.0, int source=1, int dataPort=1, double frequency=0.0, int rateIndex=0, int udpDestination=0, int vitaEnable=0, unsigned int streamId=0)
Constructs a WbddcComponent object.
virtual bool isTunable() const
Gets whether or not the WBDDC is tunable.
virtual ~WbddcComponent()
Destroys a WbddcComponent object.
virtual bool setRateIndex(int index)
Sets the WBDDC's rate index.
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
virtual bool executeDataPortQuery(int index, int &dataPort)
Executes the WBDDC data port query command.
virtual double getFrequencyUnit() const
Gets the tuned frequency units.
virtual int getVitaEnable() const
Gets the WBDDC's VITA 49 setting.
virtual bool setSource(int source)
Sets the WBDDC's source (which tuner is supplying the signal).
virtual bool executeDataPortCommand(int index, int &dataPort)
Executes the WBDDC data port set command.
virtual double getFrequencyRes() const
Gets the tuned frequency resolution.
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 CRS NDR-class radios.
BASIC_DICT_CONTAINER< int, double > WbddcRateSet
A rate set for a WBDDC.
Defines functionality for LibCyberRadio applications.
Definition App.h:24
BASIC_LIST_CONTAINER< double > BasicDoubleList
Type representing a list of doubles.
Definition BasicList.h:29
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition BasicList.h:25