libcyberradio 22.01.24
DataPort.cpp
1/***************************************************************************
2 * \file DataPort.cpp
3 * \brief Defines the basic 10GigE data port interface for an
4 * NDR-class radio.
5 * \author DA
6 * \author NH
7 * \author MN
8 * \copyright (c) 2017 CyberRadio Solutions, Inc. All rights reserved.
9 *
10 ***************************************************************************/
11
12#include "LibCyberRadio/Driver/DataPort.h"
13#include "LibCyberRadio/Driver/RadioHandler.h"
14#include "LibCyberRadio/Common/Pythonesque.h"
15#include <boost/lexical_cast.hpp>
16#include <sstream>
17
18
19namespace LibCyberRadio
20{
21
22 namespace Driver
23 {
24
25 DataPort::DataPort(const std::string& name,
26 int index,
27 RadioHandler* parent,
28 bool debug,
29 const std::string& sourceIP,
30 int numDataPortDipEntries,
31 int dataPortDipEntryIndexBase) :
32 Configurable(name, debug),
33 _index(index),
34 _parent(parent),
35 _sourceIP(sourceIP),
36 _numDipEntries(numDataPortDipEntries),
37 _dipEntryIndexBase(dataPortDipEntryIndexBase),
38 _errorsEnabled(true),
39 _flowControlEnabled(true)
40 {
42 }
43
47
49 Configurable(other),
50 _index(other._index),
51 _parent(other._parent),
52 _sourceIP(other._sourceIP),
53 _numDipEntries(other._numDipEntries),
54 _macAddresses(other._macAddresses),
55 _ipAddresses(other._ipAddresses),
56 _sourcePorts(other._sourcePorts),
57 _destPorts(other._destPorts),
58 _dipEntryIndexBase(other._dipEntryIndexBase),
59 _errorsEnabled(other._errorsEnabled),
60 _flowControlEnabled(other._flowControlEnabled)
61 {
62 }
63
65 {
67 if ( this != &other )
68 {
69 _index = other._index;
70 _parent = other._parent;
71 _sourceIP = other._sourceIP;
72 _numDipEntries = other._numDipEntries;
73 _macAddresses = other._macAddresses;
74 _ipAddresses = other._ipAddresses;
75 _sourcePorts = other._sourcePorts;
76 _destPorts = other._destPorts;
77 _dipEntryIndexBase = other._dipEntryIndexBase;
78 _errorsEnabled = other._errorsEnabled;
79 _flowControlEnabled = other._flowControlEnabled;
80 }
81 return *this;
82 }
83
85 {
86 this->debug("[DataPort::setConfiguration] Called\n");
87 // Call the base-class version to modify the configuration dictionary
88 bool ret = Configurable::setConfiguration(cfg);
89 // Use the keys provided in the *incoming* dictionary to determine
90 // what needs to be changed.
91 if ( cfg.hasKey("sourceIP") && _config.hasKey("sourceIP") )
92 {
93 ret &= setSourceIP(cfg["sourceIP"]);
94 }
95 if ( cfg.hasKey("errors") && _config.hasKey("errors") )
96 {
97 ret &= enableErrors( cfg["errors"].asBool() );
98 }
99 if ( cfg.hasKey("flowControl") && _config.hasKey("flowControl") )
100 {
101 ret &= enableFlowControl( cfg["flowControl"].asBool() );
102 }
103 this->debug("[DataPort::setConfiguration] Returning\n");
104 return ret;
105 }
106
108 {
109 this->debug("[DataPort::queryConfiguration] Called\n");
110 // Query source and destination information
111 if ( _config.hasKey("sourceIP") )
112 executeSourceIPQuery(_index, _sourceIP);
113 if ( _config.hasKey("errors") )
114 executeErrorEnabledQuery(_index, _errorsEnabled);
115 if ( _config.hasKey("flowControl") )
116 executeFlowControlEnabledQuery(_index, _flowControlEnabled);
117 for (int dipIndex = _dipEntryIndexBase;
118 dipIndex < _dipEntryIndexBase + _numDipEntries;
119 dipIndex++)
120 {
121 executeDestIPQuery(_index, dipIndex,
122 _macAddresses[dipIndex],
123 _ipAddresses[dipIndex],
124 _sourcePorts[dipIndex],
125 _destPorts[dipIndex]);
126 }
128 this->debug("[DataPort::queryConfiguration] Returning\n");
129 }
130
132 {
133 return _numDipEntries;
134 }
135
137 {
138 BasicIntList ret;
139 for (int dipIndex = _dipEntryIndexBase;
140 dipIndex < _dipEntryIndexBase + _numDipEntries;
141 dipIndex++)
142 {
143 ret.push_back(dipIndex);
144 }
145 return ret;
146 }
147
148 std::string DataPort::getSourceIP() const
149 {
150 return _sourceIP;
151 }
152
153 bool DataPort::setSourceIP(const std::string& ipAddr)
154 {
155 bool ret = false;
156 if ( _config.hasKey("sourceIP") )
157 {
158 std::string adjSourceIP = ipAddr;
159 ret = executeSourceIPCommand(_index, adjSourceIP);
160 if ( ret )
161 {
162 _sourceIP = adjSourceIP;
164 }
165 }
166 return ret;
167 }
168
169 std::string DataPort::getDestMACAddress(int dipIndex) const
170 {
171 std::string ret;
172 if ( _macAddresses.find(dipIndex) != _macAddresses.end() )
173 ret = _macAddresses.at(dipIndex);
174 return ret;
175 }
176
177 std::string DataPort::getDestIPAddress(int dipIndex) const
178 {
179 std::string ret;
180 if ( _ipAddresses.find(dipIndex) != _ipAddresses.end() )
181 ret = _ipAddresses.at(dipIndex);
182 return ret;
183 }
184
185 unsigned int DataPort::getDestSourcePort(int dipIndex) const
186 {
187 int ret = 0;
188 if ( _sourcePorts.find(dipIndex) != _sourcePorts.end() )
189 ret = _sourcePorts.at(dipIndex);
190 return ret;
191 }
192
193 unsigned int DataPort::getDestDestPort(int dipIndex) const
194 {
195 int ret = 0;
196 if ( _destPorts.find(dipIndex) != _destPorts.end() )
197 ret = _destPorts.at(dipIndex);
198 return ret;
199 }
200
201 bool DataPort::setDestInfo(int dipIndex,
202 const std::string& ipAddr,
203 const std::string& macAddr,
204 unsigned int sourcePort,
205 unsigned int destPort)
206 {
207 std::string adjIp = ipAddr;
208 std::string adjMac = macAddr;
209 unsigned int adjSrc = sourcePort;
210 unsigned int adjDst = destPort;
211 bool ret = executeDestIPCommand(_index, dipIndex, adjIp, adjMac,
212 adjSrc, adjDst);
213 if ( ret )
214 {
215 _macAddresses[dipIndex] = adjMac;
216 _ipAddresses[dipIndex] = adjIp;
217 _sourcePorts[dipIndex] = adjSrc;
218 _destPorts[dipIndex] = adjDst;
219 //updateConfigurationDict();
220 }
221 return ret;
222 }
223
224 bool DataPort::setDestMACAddress(int dipIndex, const std::string& macAddr)
225 {
226 return setDestInfo(dipIndex,
227 _ipAddresses[dipIndex],
228 macAddr,
229 _sourcePorts[dipIndex],
230 _destPorts[dipIndex]);
231 }
232
233 bool DataPort::setDestIPAddress(int dipIndex, const std::string& ipAddr)
234 {
235 return setDestInfo(dipIndex,
236 ipAddr,
237 _macAddresses[dipIndex],
238 _sourcePorts[dipIndex],
239 _destPorts[dipIndex]);
240 }
241
242 bool DataPort::setDestSourcePort(int dipIndex, unsigned int sourcePort)
243 {
244 return setDestInfo(dipIndex,
245 _ipAddresses[dipIndex],
246 _macAddresses[dipIndex],
247 sourcePort,
248 _destPorts[dipIndex]);
249 }
250
251 bool DataPort::setDestDestPort(int dipIndex, unsigned int destPort)
252 {
253 return setDestInfo(dipIndex,
254 _ipAddresses[dipIndex],
255 _macAddresses[dipIndex],
256 _sourcePorts[dipIndex],
257 destPort);
258 }
259
260 bool DataPort::enableErrors(bool enabled)
261 {
262 bool ret = false;
263 if ( _config.hasKey("errors") )
264 {
265 bool adjEn = enabled;
266 if ( executeErrorEnabledCommand(_index, adjEn) )
267 {
268 _errorsEnabled = enabled;
270 ret = true;
271 }
272 }
273 return ret;
274 }
275
277 {
278 return enableErrors(false);
279 }
280
282 {
283 bool ret = false;
284 if ( _config.hasKey("errors") )
285 {
286 bool adjEn = enabled;
287 if ( executeFlowControlEnabledCommand(_index, adjEn) )
288 {
289 _flowControlEnabled = enabled;
291 ret = true;
292 }
293 }
294 return ret;
295 }
296
298 {
299 return enableFlowControl(false);
300 }
301
303 {
304 _config.clear();
305 //this->debug("[DataPort::initConfigurationDict] Called\n");
306 _config["sourceIP"] = _sourceIP;
307 _config["errors"] = _errorsEnabled;
308 _config["flowControl"] = _flowControlEnabled;
309 //this->debug("[DataPort::initConfigurationDict] Returning\n");
310 }
311
313 {
314 this->debug("[DataPort::updateConfigurationDict] Called\n");
315 if ( _config.hasKey("sourceIP") )
316 setConfigurationValue("sourceIP", _sourceIP);
317 if ( _config.hasKey("errors") )
318 setConfigurationValueToBool("errors", _errorsEnabled);
319 if ( _config.hasKey("flowControl") )
320 setConfigurationValueToBool("flowControl", _flowControlEnabled);
321 this->debug("[DataPort::updateConfigurationDict] Returning\n");
322 }
323
324 // Default implementation uses the NDR308 pattern
325 bool DataPort::executeSourceIPQuery(int index, std::string& sourceIP)
326 {
327 bool ret = false;
328 if ( (_parent != NULL) && (_parent->isConnected()) )
329 {
330 std::ostringstream oss;
331 oss << "SIP? " << index << "\n";
332 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
333 if ( _parent->getLastCommandErrorInfo() == "" )
334 {
336 Pythonesque::Replace(rsp.front(), "SIP ", ""),
337 ", ");
338 // vec[0] = Index
339 // vec[1] = Source IP address
340 sourceIP = vec[1];
341 ret = true;
342 }
343 }
344 return ret;
345 }
346
347 // Default implementation uses the NDR308 pattern
348 bool DataPort::executeSourceIPCommand(int index, std::string& sourceIP)
349 {
350 bool ret = false;
351 if ( (_parent != NULL) && (_parent->isConnected()) )
352 {
353 std::ostringstream oss;
354 oss << "SIP " << index
355 << ", " << sourceIP
356 << "\n";
357 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
358 if ( _parent->getLastCommandErrorInfo() == "" )
359 {
360 ret = true;
361 }
362 }
363 return ret;
364 }
365
366 // Default implementation uses the NDR308 pattern
368 int dipIndex,
369 std::string& ipAddr,
370 std::string& macAddr,
371 unsigned int& sourcePort,
372 unsigned int& destPort)
373 {
374 bool ret = false;
375 ipAddr = "";
376 macAddr = "";
377 sourcePort = 0;
378 destPort = 0;
379 if ( (_parent != NULL) && (_parent->isConnected()) &&
380 ( _macAddresses.find(dipIndex) != _macAddresses.end()) )
381 {
382 std::ostringstream oss;
383 oss << "DIP? " << index << ", " << dipIndex << "\n";
384 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
385 if ( _parent->getLastCommandErrorInfo() == "" )
386 {
387 if ( Pythonesque::Startswith(rsp.front(), "DIP") )
388 {
390 Pythonesque::Replace(rsp.front(), "DIP ", ""),
391 ", ");
392 // vec[0] = Index
393 // vec[1] = Destination index
394 // vec[2] = IP address (with lots of leading spaces)
395 //this->debug("[DataPort::executeDestIPQuery] IP addr string=\"%s\"\n", vec[2].c_str());
396 ipAddr = Pythonesque::Strip(vec[2]);
397 //this->debug("[DataPort::executeDestIPQuery] -- converted=\"%s\"\n", ipAddr.c_str());
398 // vec[3] = MAC address
399 //this->debug("[DataPort::executeDestIPQuery] MAC addr string=\"%s\"\n", vec[3].c_str());
400 macAddr = Pythonesque::Strip(vec[3]);
401 //this->debug("[DataPort::executeDestIPQuery] -- converted=\"%s\"\n", macAddr.c_str());
402 // vec[4] = UDP port
403 //this->debug("[DataPort::executeDestIPQuery] Source UDP port string=\"%s\"\n", vec[4].c_str());
404 sourcePort = boost::lexical_cast<unsigned int>(Pythonesque::Strip(vec[4]));
405 //this->debug("[DataPort::executeDestIPQuery] -- converted=%u\n", udpPort);
406 // vec[5] = Stream ID
407 //this->debug("[DataPort::executeDestIPQuery] Destination UDP string=\"%s\"\n", vec[5].c_str());
408 destPort = boost::lexical_cast<unsigned int>(Pythonesque::Strip(vec[5]));
409 //this->debug("[DataPort::executeDestIPQuery] -- converted=%u\n", streamId);
410 ret = true;
411 }
412 }
413 }
414 return ret;
415 }
416
417 // Default implementation uses the NDR308 pattern
419 int dipIndex,
420 std::string& ipAddr,
421 std::string& macAddr,
422 unsigned int& sourcePort,
423 unsigned int& destPort)
424 {
425 bool ret = false;
426 if ( (_parent != NULL) && (_parent->isConnected()) )
427 {
428 std::ostringstream oss;
429 oss << "DIP " << index
430 << ", " << dipIndex
431 << ", " << ipAddr
432 << ", " << macAddr
433 << ", " << sourcePort
434 << ", " << destPort
435 << "\n";
436 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
437 if ( _parent->getLastCommandErrorInfo() == "" )
438 {
439 ret = true;
440 }
441 }
442 return ret;
443 }
444
445 // Default implementation uses the NDR308 pattern
446 bool DataPort::executeErrorEnabledQuery(int index, bool& enabled)
447 {
448 bool ret = false;
449 if ( (_parent != NULL) && (_parent->isConnected()) )
450 {
451 std::ostringstream oss;
452 oss << "TGBED? " << index << "\n";
453 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
454 if ( _parent->getLastCommandErrorInfo() == "" )
455 {
457 Pythonesque::Replace(rsp.front(), "TGBED ", ""),
458 ", ");
459 // vec[0] = Index
460 // vec[1] = Disabled indicator (1 = disabled, 0 = enabled)
461 int ind = boost::lexical_cast<int>(vec[1]);
462 enabled = (ind == 0);
463 ret = true;
464 }
465 }
466 return ret;
467 }
468
469 // Default implementation uses the NDR308 pattern
470 bool DataPort::executeErrorEnabledCommand(int index, bool& enabled)
471 {
472 bool ret = false;
473 if ( (_parent != NULL) && (_parent->isConnected()) )
474 {
475 std::ostringstream oss;
476 oss << "TGBED " << index
477 << ", " << (enabled ? 0 : 1)
478 << "\n";
479 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
480 if ( _parent->getLastCommandErrorInfo() == "" )
481 {
482 ret = true;
483 }
484 }
485 return ret;
486 }
487
488 // Default implementation uses the NDR308 pattern
489 bool DataPort::executeFlowControlEnabledQuery(int index, bool& enabled)
490 {
491 bool ret = false;
492 if ( (_parent != NULL) && (_parent->isConnected()) )
493 {
494 std::ostringstream oss;
495 oss << "TGFC? " << index << "\n";
496 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
497 if ( _parent->getLastCommandErrorInfo() == "" )
498 {
500 Pythonesque::Replace(rsp.front(), "TGFC ", ""),
501 ", ");
502 // vec[0] = Index
503 // vec[1] = Enabled indicator (1 = enabled, 0 = disabled)
504 int ind = boost::lexical_cast<int>(vec[1]);
505 enabled = (ind == 1);
506 ret = true;
507 }
508 }
509 return ret;
510 }
511
512 // Default implementation uses the NDR308 pattern
513 bool DataPort::executeFlowControlEnabledCommand(int index, bool& enabled)
514 {
515 bool ret = false;
516 if ( (_parent != NULL) && (_parent->isConnected()) )
517 {
518 std::ostringstream oss;
519 oss << "TGFC " << index
520 << ", " << (enabled ? 1 : 0)
521 << "\n";
522 BasicStringList rsp = _parent->sendCommand(oss.str(), 2.0);
523 if ( _parent->getLastCommandErrorInfo() == "" )
524 {
525 ret = true;
526 }
527 }
528 return ret;
529 }
530
531
532 } /* namespace Driver */
533
534} /* namespace LibCyberRadio */
535
virtual int debug(const char *format,...)
Outputs debug information.
virtual bool setConfiguration(ConfigurationDict &cfg)
Sets the configuration dictionary for this object.
virtual Configurable & operator=(const Configurable &other)
Assignment operator for Configurable objects.
virtual bool setConfigurationValue(const std::string &key, const std::string &value)
Sets a named configuration value to a string.
Configurable(const std::string &name="<unknown>", bool debug=false)
Constructs a Configurable object.
virtual bool setConfigurationValueToBool(const std::string &key, const bool value)
Sets a named configuration value to a Boolean.
A configuration dictionary.
virtual bool hasKey(const std::string &key) const
Determines if the dictionary has the given key.
virtual bool setConfiguration(ConfigurationDict &cfg)
Sets the configuration dictionary for this object.
Definition DataPort.cpp:84
virtual bool executeFlowControlEnabledCommand(int index, bool &enabled)
Executes the flow control enabled command.
Definition DataPort.cpp:513
virtual bool executeErrorEnabledQuery(int index, bool &enabled)
Executes the error enabled query.
Definition DataPort.cpp:446
virtual int getNumDestEntries() const
Gets the number of destination IP table entries.
Definition DataPort.cpp:131
virtual bool executeDestIPCommand(int index, int dipIndex, std::string &ipAddr, std::string &macAddr, unsigned int &sourcePort, unsigned int &destPort)
Executes the destination IP set command.
Definition DataPort.cpp:418
virtual bool executeDestIPQuery(int index, int dipIndex, std::string &ipAddr, std::string &macAddr, unsigned int &sourcePort, unsigned int &destPort)
Executes the destination IP query command.
Definition DataPort.cpp:367
virtual BasicIntList getDestEntryIndexRange() const
Gets the list of destination IP table entry indices.
Definition DataPort.cpp:136
virtual bool setDestInfo(int dipIndex, const std::string &ipAddr, const std::string &macAddr, unsigned int sourcePort, unsigned int destPort)
Sets the destination table information for a given entry in the DIP table.
Definition DataPort.cpp:201
virtual bool setSourceIP(const std::string &ipAddr)
Sets the source IP address.
Definition DataPort.cpp:153
DataPort(const std::string &name="DATAPORT", int index=0, RadioHandler *parent=NULL, bool debug=false, const std::string &sourceIP="0.0.0.0", int numDataPortDipEntries=0, int dataPortDipEntryIndexBase=0)
Constructs a DataPort object.
Definition DataPort.cpp:25
virtual bool setDestMACAddress(int dipIndex, const std::string &macAddr)
Sets the MAC address for a given entry in the destination IP table.
Definition DataPort.cpp:224
virtual DataPort & operator=(const DataPort &other)
Assignment operator for DataPort objects.
Definition DataPort.cpp:64
virtual std::string getSourceIP() const
Gets the source IP address.
Definition DataPort.cpp:148
virtual std::string getDestIPAddress(int dipIndex) const
Gets the IP address for a given entry in the destination IP table.
Definition DataPort.cpp:177
virtual std::string getDestMACAddress(int dipIndex) const
Gets the MAC address for a given entry in the destination IP table.
Definition DataPort.cpp:169
virtual ~DataPort()
Destroys a DataPort object.
Definition DataPort.cpp:44
virtual unsigned int getDestSourcePort(int dipIndex) const
Gets the source UDP port number for a given entry in the destination IP table.
Definition DataPort.cpp:185
virtual bool executeSourceIPCommand(int index, std::string &ipAddr)
Executes the source IP set command.
Definition DataPort.cpp:348
virtual bool disableErrors()
Disables errors on the data port.
Definition DataPort.cpp:276
virtual void queryConfiguration()
Tells the object to create its configuration dictionary.
Definition DataPort.cpp:107
virtual void updateConfigurationDict()
Updates the configuration dictionary from object settings.
Definition DataPort.cpp:312
virtual bool setDestIPAddress(int dipIndex, const std::string &ipAddr)
Sets the IP address for a given entry in the destination IP table.
Definition DataPort.cpp:233
virtual bool enableErrors(bool enabled=true)
Enables errors on the data port.
Definition DataPort.cpp:260
virtual bool executeSourceIPQuery(int index, std::string &ipAddr)
Executes the source IP query command.
Definition DataPort.cpp:325
virtual bool executeErrorEnabledCommand(int index, bool &enabled)
Executes the error enabled command.
Definition DataPort.cpp:470
virtual bool setDestDestPort(int dipIndex, unsigned int destPort)
Sets the destination UDP port number for a given entry in the destination IP table.
Definition DataPort.cpp:251
virtual bool disableFlowControl()
Disables flow control on the data port.
Definition DataPort.cpp:297
virtual void initConfigurationDict()
Initializes the configuration dictionary, defining the allowed keys.
Definition DataPort.cpp:302
virtual bool enableFlowControl(bool enabled=true)
Enables flow control on the data port.
Definition DataPort.cpp:281
virtual bool setDestSourcePort(int dipIndex, unsigned int sourcePort)
Sets the source UDP port number for a given entry in the destination IP table.
Definition DataPort.cpp:242
virtual unsigned int getDestDestPort(int dipIndex) const
Gets the destination UDP port number for a given entry in the destination IP table.
Definition DataPort.cpp:193
virtual bool executeFlowControlEnabledQuery(int index, bool &enabled)
Executes the flow control enabled query.
Definition DataPort.cpp:489
Generic radio handler class.
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 CRS NDR-class radios.
Defines functionality for LibCyberRadio applications.
Definition App.h:24
BASIC_LIST_CONTAINER< int > BasicIntList
Type representing a list of integers.
Definition BasicList.h:27
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Definition BasicList.h:25