libcyberradio  22.01.24
TransmitPacketizer.cpp
1 /***************************************************************************
2  * \file TransmitPacketizer.cpp
3  *
4  * \brief NDR651 transmit packetizer class.
5  *
6  * \author NH
7  * \copyright Copyright (c) 2015-2021 CyberRadio Solutions, Inc.
8  *
9  */
10 
11 #include "LibCyberRadio/NDR651/TransmitPacketizer.h"
12 #include <boost/algorithm/string.hpp>
13 #include <boost/tokenizer.hpp>
14 #include <unistd.h>
15 
16 #define BOOL_DEBUG(x) (x ? "true" : "false")
17 
18 using namespace boost::algorithm;
19 
20 
21 static unsigned short compute_checksum(unsigned short *addr, unsigned int count) {
22  register unsigned long sum = 0;
23  while (count > 1) {
24  //std::cout << count << " | " << *addr << " | " << sum << std::endl;
25  sum += * addr++;
26  count -= 2;
27  }
28  //if any bytes left, pad the bytes and add
29  if(count > 0) {
30  sum += ((*addr)&htons(0xFF00));
31  }
32  //Fold sum to 16 bits: add carrier to result
33  while (sum>>16) {
34  sum = (sum & 0xffff) + (sum >> 16);
35  }
36  //one's complement
37  sum = ~sum;
38  return ((unsigned short)sum);
39 }
40 
41 bool setCpuAffinity(int cpu) {
42  cpu_set_t set;
43  CPU_ZERO(&set);
44  CPU_SET(cpu, &set);
45  if (sched_setaffinity(0, sizeof(set), &set)) {
46  return false;
47  } else {
48  return true;
49  }
50 }
51 
52 namespace LibCyberRadio
53 {
54  namespace NDR651
55  {
56 
57  TransmitPacketizer::TransmitPacketizer(
58  const std::string& radioHostName,
59  int radioTcpPort,
60  unsigned int ducChannel,
61  const std::string& ifname,
62  unsigned int tenGigIndex,
63  int dipIndex,
64  unsigned int ducRate,
65  unsigned int ducTxChannels,
66  float ducFreq,
67  float ducAtten,
68  double txFreq,
69  float txAtten,
70  unsigned int streamId,
71  bool config_tx,
72  bool debug):
73  Debuggable(debug, "TransmitPacketizer"),
74  _radioHostName(""),
75  _radioTcpPort(0),
76  _ducChannel(0),
77  _ifname(""),
78  _tenGigIndex(0),
79  _dipIndex(-1),
80  _ducRate(0),
81  _ducTxChannels(0),
82  _ducFreq(0),
83  _ducAtten(0),
84  _txFreq(0),
85  _txAtten(0),
86  _streamId(streamId),
87  _config_tx(config_tx),
88  _txSock(NULL),
89  _numSock(8),
90  _fcClient(NULL),
91  _frameStart((unsigned char*)(&_frame)),
92  _frameLength(sizeof(TxFrame)),
93  _samplesSent(0),
94  _sMac(""),
95  _dMac(""),
96  _sIp(""),
97  _dIp(""),
98  _sPort(0),
99  _dPort(0),
100  _updatePE(false),
101  _duchsPfThresh(61*(67108862/64)),
102  _duchsPeThresh(58*(67108862/64)),
103  _duchsPeriod(10),
104  _samplesPerFrame(SAMPLES_PER_FRAME),
105  //_waiting(false),
106  _firstFrame(true),
107  _running(false),
108  _constructing(true),
109  _frameCount(0),
110  _pauseCount(64)
111  {
112  this->debug("construction\n");
113  std::cout << "using local lib" << std::endl;
114  memset(&_frame, 0, sizeof(TxFrame));
115  _fcClient = new FlowControlClient(ducChannel, _config_tx, 4, _debug);
116  _statusRx = new UdpStatusReceiver(ifname, 65500+ducChannel, _debug, _updatePE);
117 
118  setRadioParameters(radioHostName, radioTcpPort);
119  setDucInterface(ifname, tenGigIndex);
120  setDucParameters(tenGigIndex, ducRate, ducTxChannels,
121  ducFreq, ducAtten, txFreq, txAtten,
122  streamId);
123  _constructing = false;
124  _delayTime.tv_sec = 0;
125  _delayTime.tv_nsec = 100;
126 
127  }
128 
130  {
131  // TODO Auto-generated destructor stub
132 
133  this->debug("destruction\n");
134  if ( _fcClient != NULL )
135  delete _fcClient;
136  if ( _txSock != NULL )
137  delete _txSock;
138  }
139 
140  bool TransmitPacketizer::setRadioHostName(const std::string& radioHostName)
141  {
142  return setRadioParameters(radioHostName, _radioTcpPort);
143  }
144 
145  bool TransmitPacketizer::setRadioTcpPort(int radioTcpPort)
146  {
147  return setRadioParameters(_radioHostName, radioTcpPort);
148  }
149 
150  bool TransmitPacketizer::setDucChannel(unsigned int ducChannel)
151  {
152  _configuring = true;
153  this->debug("setting duc channel = %d\n", ducChannel);
154  // Sanity check -- there is not much we can do if we
155  // failed to make our control objects!
156  if ( (_txSock != NULL) && (_fcClient != NULL) )
157  {
158  // Disable the DUC this object was talking to
159  _fcClient->disableDuc();
160  // Switch DUCs
161  _fcClient->setDucChannel(ducChannel);
162  this->debug("duc channel set ok\n");
163  }
164  else
165  {
166  this->debug("duc channel set skipped\n");
167  }
168  _configuring = false;
169  return true;
170  }
171 
172  bool TransmitPacketizer::setDucInterface(const std::string& ifname,
173  unsigned int tenGigIndex)
174  {
175  _configuring = true;
176  this->debug("setting duc interface = %s/%d\n", ifname.c_str(),
177  tenGigIndex);
178  // Create a new TransmitSocket object if the user wants to
179  // use a different interface.
180  if ( ifname != _ifname )
181  {
182  if ( _txSock != NULL ) {
183  delete _txSock;
184  _txSockVec.clear();
185  }
186  _ifname = ifname;
187  //~ _txSock = new TransmitSocket(_ifname, _streamId);
188  for (int i=0; i<_numSock; i++) {
189  _txSockVec.push_back(new TransmitSocket(_ifname, _streamId));
190  }
191  std::cout << "# sockets = " << _txSockVec.size() << std::endl;
192  _currentSockIndex = 0;
193  _txSock = _txSockVec[_currentSockIndex];
194  }
195  _tenGigIndex = tenGigIndex;
196  this->debug("duc interface set ok\n");
197  return setDucParameters(tenGigIndex, _ducRate, _ducTxChannels,
198  _ducFreq, _ducAtten, _txFreq,
199  _txAtten, _streamId);
200  }
201 
202  bool TransmitPacketizer::setDucRate(unsigned int ducRate)
203  {
204  bool ret = true;
205  _configuring = true;
206  _ducRate = ducRate;
207  if (_fcClient != NULL)
208  {
209  ret = _fcClient->setDucRateIndex(_ducRate, true);
210  }
211  _configuring = false;
212  return ret;
213  }
214 
215  bool TransmitPacketizer::setDucTxChannels(unsigned int ducTxChannels)
216  {
217  bool ret = true;
218  _configuring = true;
219  _ducTxChannels = ducTxChannels;
220  if (_fcClient != NULL)
221  {
222  ret = _fcClient->setDucTxChannel(_ducTxChannels, true);
223  }
224  _configuring = false;
225  return ret;
226  }
227 
228  bool TransmitPacketizer::setDucFreq(float ducFreq)
229  {
230  bool ret = true;
231  _configuring = true;
232  _ducFreq = ducFreq;
233  if (_fcClient != NULL)
234  {
235  ret = _fcClient->setDucFrequency((long)_ducFreq, true);
236  }
237  _configuring = false;
238  return ret;
239  }
240 
241  bool TransmitPacketizer::setDucTxinvMode(unsigned int txinvMode)
242  {
243  bool ret = true;
244  _configuring = true;
245  _txinvMode = txinvMode;
246  if (_fcClient != NULL)
247  {
248  ret = _fcClient->setDucTxinvMode(txinvMode, true);
249  }
250  _configuring = false;
251  return ret;
252  }
253 
254  bool TransmitPacketizer::setDucAtten(float ducAtten)
255  {
256  bool ret = true;
257  _configuring = true;
258  _ducAtten = ducAtten;
259  if (_fcClient != NULL)
260  {
261  ret = _fcClient->setDucAttenuation(_ducAtten, true);
262  }
263  _configuring = false;
264  return ret;
265  }
266 
267 
268  void TransmitPacketizer::setDuchsParameters(unsigned int duchsPfThresh, unsigned int duchsPeThresh, unsigned int duchsPeriod, bool updatePE) {
269  bool change = false;
270  if (_updatePE != updatePE) {
271  _updatePE = updatePE;
272  if (updatePE) {
273  std::cerr << "setDuchsParameters: Updating on PE packet" << std::endl;
274  } else {
275  std::cerr << "setDuchsParameters: Updating on periodic packet" << std::endl;
276  }
277  _statusRx->setUpdatePE(_updatePE);
278  }
279  if (_duchsPfThresh != duchsPfThresh) {
280  std::cerr << "setDuchsParameters: Modify duchsPfThresh " << _duchsPfThresh << "->" << duchsPfThresh << std::endl;
281  _duchsPfThresh = duchsPfThresh;
282  change = true;
283  }
284  if (_duchsPeThresh != duchsPeThresh) {
285  std::cerr << "setDuchsParameters: Modify duchsPeThresh " << _duchsPeThresh << "->" << duchsPeThresh << std::endl;
286  _duchsPeThresh = duchsPeThresh;
287  change = true;
288  }
289  if (_duchsPeriod != duchsPeriod) {
290  std::cerr << "setDuchsParameters: Modify duchsPeriod " << _duchsPeriod << "->" << duchsPeriod << std::endl;
291  _duchsPeriod = duchsPeriod;
292  change = true;
293  }
294  if (change && _running) {
295  _fcClient->setDuchsParameters(_duchsPfThresh, _duchsPeThresh, _duchsPeriod);
296  }
297  }
298 
299  bool TransmitPacketizer::setTxFreq(double txFreq)
300  {
301  bool ret = true;
302  bool shfChange = (_txFreq != txFreq) && (((_txFreq >= 200.0)&&(txFreq < 200.0))||((_txFreq < 200.0)&&(txFreq >= 200.0)));
303  _configuring = true;
304  _txFreq = txFreq;
305  if (_fcClient != NULL)
306  {
307  //~ if (shfChange) {
308  //~ ret = _fcClient->enableDuc(_ducRate, _ducTxChannels,
309  //~ _streamId, _tenGigIndex,
310  //~ _ducAtten, _txFreq,
311  //~ (long)_ducFreq,
312  //~ (unsigned int)_txAtten);
313  //~ } else {
314  ret = _fcClient->setTxFrequency(_txFreq, true); // Allow double input
315  //~ }
316  }
317  _configuring = false;
318  return ret;
319  }
320 
321  bool TransmitPacketizer::setTxAtten(float txAtten)
322  {
323  bool ret = true;
324  _configuring = true;
325  _txAtten = txAtten;
326  if (_fcClient != NULL)
327  {
328  ret = _fcClient->setTxAttenuation((int)_txAtten, true);
329  }
330  _configuring = false;
331  return ret;
332  }
333 
334  bool TransmitPacketizer::setStreamId(unsigned int streamId)
335  {
336  bool ret = true;
337  _configuring = true;
338  _streamId = streamId;
339  setUdpHeader(_streamId, _streamId);
340  setVitaHeader(_streamId);
341  if (_fcClient != NULL)
342  {
343  ret = _fcClient->setDucStreamId(_streamId, true);
344  }
345  _configuring = false;
346  return ret;
347  }
348 
350  {
351  _debug = debug;
352  return true;
353  }
354 
356  const std::string& radioHostName,
357  int radioTcpPort)
358  {
359  _configuring = true;
360  this->debug("setting radio parameters host=%s, port=%d\n",
361  radioHostName.c_str(), radioTcpPort);
362  // Sanity check -- there is not much we can do if we
363  // failed to make our control objects!
364  if ( _fcClient != NULL )
365  {
366  // If we are not in the middle of constructing, then
367  // we need to deal with the case where the user is
368  // trying to connect to a different radio and/or TCP
369  // port on the fly.
370  if ( !_constructing )
371  {
372  // If changing radio hosts, disable the DUC we are
373  // controlling first.
374  if ( radioHostName != _radioHostName )
375  {
376  _fcClient->disableDuc();
377  }
378  // If changing radio host or TCP port, disconnect
379  // first.
380  if ( (radioHostName != _radioHostName) ||
381  (radioTcpPort != _radioTcpPort) )
382  {
383  _fcClient->disconnect();
384  }
385  }
386  // Set the new host name and TCP port
387  _radioHostName = radioHostName;
388  _radioTcpPort = radioTcpPort;
389  // Connect to the radio if a hostname was given
390  if ( _radioHostName != "" )
391  _fcClient->connectToRadio(_radioHostName, _radioTcpPort);
392  this->debug("radio parameters set result = %s\n",
393  BOOL_DEBUG(_fcClient->isConnected()));
394  }
395  else
396  {
397  this->debug("radio parameters set skipped\n");
398  }
399  _configuring = false;
400  return true;
401  }
402 
403  bool TransmitPacketizer::setDucParameters(unsigned int tenGigIndex,
404  unsigned int ducRate,
405  unsigned int ducTxChannels,
406  float ducFreq,
407  float ducAtten,
408  double txFreq,
409  float txAtten,
410  unsigned int streamId)
411  {
412  _configuring = true;
413  bool ret = true;
414  this->debug("setting duc parameters index=%d\n", tenGigIndex);
415  _tenGigIndex = tenGigIndex;
416  _ducRate = ducRate;
417  _ducTxChannels = ducTxChannels;
418  _ducFreq = ducFreq;
419  _ducAtten = ducAtten;
420  _txFreq = txFreq;
421  _txAtten = txAtten;
422  _streamId = streamId;
423  this->debug("-- ducRate=%u ducTxChannels=%d ducFreq=%f "
424  "ducAtten=%f txFreq=%f txAtten=%f streamId=%u\n",
425  _ducRate, _ducTxChannels, _ducFreq, _ducAtten,
426  _txFreq, _txAtten, _streamId);
427  // Sanity check -- there is not much we can do if we
428  // failed to make our control objects!
429  if ( (_txSock != NULL) && (_fcClient != NULL) )
430  {
431  _sMac = _txSock->getMacAddress();
432  _sIp = _txSock->getIpAddress();
433  if (_txSock->isUsingRawSocket()) {
434  this->debug("-- source mac = %s\n", _sMac.c_str());
435  _dMac = _fcClient->getRadioMac(tenGigIndex);
436  this->debug("-- dest mac = %s\n", _dMac.c_str());
437  setEthernetHeader(_sMac, _dMac);
438  this->debug("-- source ip = %s\n", _sIp.c_str());
439  _dIp = _fcClient->getRadioIp(tenGigIndex);
440  this->debug("-- dest ip = %s\n", _dIp.c_str());
441  setIpHeader(_sIp, _dIp);
442  setUdpHeader(_streamId, _streamId);
443  } else {
444  _frameStart = (unsigned char*)(&_frame.v49.frameStart);
445  _frameLength = sizeof(TxFrame)-( sizeof(ethhdr) + sizeof(iphdr) + sizeof(udphdr) );
446  }
447  setVitaHeader(_streamId);
448  this->debug("-- enabling duc\n");
449  ret = _fcClient->enableDuc(_ducRate, _ducTxChannels,
450  _streamId, _tenGigIndex,
451  _ducAtten, _txFreq,
452  (long)_ducFreq,
453  (unsigned int)_txAtten);
454  this->debug("-- duc enable = %s\n", BOOL_DEBUG(ret));
455  }
456  else
457  {
458  this->debug("duc parameters set skipped\n");
459  }
460  this->debug("duc parameters set result = %s\n", BOOL_DEBUG(ret));
461  _configuring = false;
462  return ret;
463  }
464 
466  {
467  _running = true;
468  //~ if ( _fcClient != NULL )
469  //~ _fcClient->start();
470  _fcClient->setDucDipStatusEntry(-1, _sIp, _sMac, _statusRx->getUdpPort());
471  _statusRx->setUpdatePE(_updatePE);
472  _fcClient->setDuchsParameters(_duchsPfThresh, _duchsPeThresh, _duchsPeriod);
473  if ( _statusRx != NULL )
474  _statusRx->start();
475  }
476 
478  {
479  std::cerr << "Stopping flow control threads.\n";
480  this->setDuchsParameters(0, 0, 0, false);
481  if ( _fcClient != NULL ) {
482  //~ _fcClient->interrupt();
483  _fcClient->setDucTenGbePort(0, false);
484  _fcClient->setDucRateIndex(0, false);
485  _fcClient->setDucFrequency(0, false);
486  _fcClient->setDucStreamId(0, false);
487  _fcClient->setDucEnable(false, true);
488  delete _fcClient;
489  _fcClient = NULL;
490  }
491  if ( _statusRx != NULL ){
492  std::cerr << "_statusRx->interrupt()\n";
493  _statusRx->interrupt();
494  std::cerr << "delete _statusRx\n";
495  delete _statusRx;
496  _statusRx = NULL;
497  }
498  std::cerr << "Stopped flow control threads.\n";
499  }
500 
501  unsigned int TransmitPacketizer::sendFrame(short * samples)
502  {
503  _samplesSent = 0;
504  // Sanity check -- there is not much we can do if we
505  // failed to make our control objects!
506  if ( (_txSock != NULL) && (_fcClient != NULL) && (_statusRx != NULL) )
507  {
508  while (!_statusRx->okToSend(SAMPLES_PER_FRAME,false))
509  {
510  usleep(1000);
511  }
512  memcpy(&_frame.payload.samples, samples, 4*SAMPLES_PER_FRAME);
513  if (_txSock->sendFrame(_frameStart, _frameLength))
514  {
515  _samplesSent = SAMPLES_PER_FRAME;
516  _incrementVitaHeader();
517  if (_firstFrame) {
518  this->debug("1st frame sent!\n");
519  _firstFrame = false;
520  }
521 
522  }
523  _currentSockIndex = (_currentSockIndex+1)%_txSockVec.size();
524  _txSock = _txSockVec[_currentSockIndex];
525  _statusRx->sentNSamples(_samplesSent);
526  //~ _frameCount += 1;
527  //~ if (_frameCount==_pauseCount) {
528  //~ std::cout << "UNPAUSING\n";
529  //~ _fcClient->unpause();
530  //~ }
531  //~ usleep(1);
532  }
533  return _samplesSent;
534  }
535 
537  {
538  return ( (_fcClient != NULL) &&
539  _fcClient->isConnected() );
540  }
541 
543  {
544  return ( !_configuring && isConnected() );
545  }
546 
547  bool TransmitPacketizer::setEthernetHeader(const std::string& sourceMac,
548  const std::string& destMac)
549  {
550  std::vector<std::string> macVec;
551  int ind = 0;
552 
553  //Destination MAC address
554  split(macVec, destMac, is_any_of(":"));
555  //std::cout << "header dMAC = ";
556  ind = 0;
557  for (std::vector<std::string>::iterator i=macVec.begin(); i!=macVec.end(); i++) {
558  unsigned char val = strtol((*i).c_str(), NULL, 16);
559  //std::cout << " " << (*i) << " (" << (int)val << ")";
560  _frame.eth.h_dest[ind++] = val;
561  }
562  //std::cout << std::endl;
563 
564  //Source MAC address
565  split(macVec, sourceMac, is_any_of(":"));
566  //std::cout << "header sMAC = ";
567  ind = 0;
568  for (std::vector<std::string>::iterator i=macVec.begin(); i!=macVec.end(); i++) {
569  unsigned char val = strtol((*i).c_str(), NULL, 16);
570  //std::cout << " " << (*i) << " (" << (int)val << ")";
571  _frame.eth.h_source[ind++] = val;
572  }
573  //std::cout << std::endl;
574 
575  _frame.eth.h_proto = htons(ETH_P_IP);
576 
577  return true;
578  }
579 
580  bool TransmitPacketizer::setIpHeader(const std::string& sourceIp,
581  const std::string& destIp)
582  {
583  _frame.ip.version = 4;
584  _frame.ip.ihl = sizeof(iphdr)/4;
585  //_frame.ip.frag_off = htons(0x4000);
586  _frame.ip.protocol = 17;
587  _frame.ip.tot_len = htons(sizeof(TxFrame)-sizeof(ethhdr));
588  _frame.ip.ttl = 255;
589 
590  // Destination IP address
591  inet_pton(AF_INET, destIp.c_str(), &(_frame.ip.daddr));
592 
593  // Source IP address
594  inet_pton(AF_INET, sourceIp.c_str(), &(_frame.ip.saddr));
595 
596  // IP Header checksum
597  _frame.ip.check = 0;
598  _frame.ip.check = compute_checksum((unsigned short*)&(_frame.ip), _frame.ip.ihl<<2);
599 
600  return true;
601  }
602 
603  bool TransmitPacketizer::setUdpHeader(unsigned short sourcePort,
604  unsigned short destPort)
605  {
606  _frame.udp.source = htons(sourcePort);
607  _frame.udp.dest = htons(destPort);
608  _frame.udp.len = htons(sizeof(TxFrame)-sizeof(ethhdr)-sizeof(iphdr));
609  return true;
610  }
611 
612  bool TransmitPacketizer::setVitaHeader(unsigned int streamId)
613  {
614  //Vita49
615  _frame.v49.frameStart = VRLP;
616  //~ _frame.v49.frameSize = SAMPLES_PER_FRAME+10;
617  _frame.v49.frameSize = _samplesPerFrame+10;
618  _frame.v49.streamId = streamId;
619  _frame.v49.packetType = 0x1;
620  _frame.v49.TSF = 0x1;
621  _frame.v49.TSF = 0x1;
622  _frame.v49.T = 0;
623  _frame.v49.C = 1;
624  _frame.v49.classId1 = 0x00fffffa;
625  _frame.v49.classId2 = 0x00130000;
626  //~ _frame.v49.packetSize = SAMPLES_PER_FRAME+7;
627  _frame.v49.packetSize = _samplesPerFrame+7;
628  _frame.vend.frameEnd = VEND;
629  return true;
630  }
631 
632  //~ unsigned int TransmitPacketizer::setSamplesPerFrame(unsigned int samplesPerFrame) {
633  //~ _samplesPerFrame = samplesPerFrame;
634  //~ _frame.v49.packetSize = _samplesPerFrame+7;
635  //~ _frame.v49.frameSize = _samplesPerFrame+10;
636  //~ }
637 
638  void TransmitPacketizer::_incrementVitaHeader()
639  {
640  //if (_debug && (_frame.v49.frameCount==0)) {
641  //std::cout << "Frame 0 " << std::endl;
642  //}
643  _frame.v49.frameCount = (_frame.v49.frameCount + 1) % 4096;
644  _frame.v49.packetCount = (_frame.v49.packetCount + 1) % 16;
645  }
646 
647  } /* namespace NDR651 */
648 }
virtual ~TransmitPacketizer()
Destroys a TransmitPacketizer object.
uint16_t packetSize
Packet size, in 32-bit words.
Definition: PacketTypes.h:43
struct Payload payload
VITA 49 payload.
Definition: PacketTypes.h:92
bool setDucChannel(unsigned int ducChannel)
Sets the DUC channel number.
struct iphdr ip
IP header.
Definition: PacketTypes.h:89
bool setRadioHostName(const std::string &radioHostName)
Sets the radio host name.
bool isConnected(void)
Gets whether or not the client is connected.
uint16_t packetType
Packet type.
Definition: PacketTypes.h:50
bool okToSend(long int pendingSamples, bool lockIfOk)
Determines if it is OK to send data.
bool sentNSamples(long int samplesSent)
Updates status based on the number of samples sent.
virtual void interrupt()
Interrupts (stops) the thread.
Definition: Thread.cpp:60
std::string getRadioIp(unsigned int tenGbeIndex)
Gets the IP address of a 10GigE port on the radio.
VITA 49 transmit-over-UDP frame information.
Definition: PacketTypes.h:87
uint32_t frameCount
Frame Count.
Definition: PacketTypes.h:42
bool setTxFrequency(double txFreq, bool applySetting=true)
Sets the transmitter frequency.
bool setDucTxChannels(unsigned int ducTxChannels)
Sets the DUC transmit channel bitmap.
virtual void start()
Starts thread processing.
Definition: Thread.cpp:54
bool isConnected(void)
Gets whether or not the packetizer is connected.
bool setDucTxinvMode(unsigned int txinvMode)
Sets the DUC TX Inversion Mode.
bool enableDuc(unsigned int rateIndex, unsigned int txChannel, unsigned int streamId, unsigned int tenGbeIndex, float attenuation, double txFreq, long ducFreq, unsigned int txAtten, bool ducEnable=true)
Enables the DUC.
bool setRadioParameters(const std::string &radioHostName, int radioTcpPort)
Sets the radio parameters.
bool setDucRateIndex(unsigned int rateIndex, bool applySetting=true)
Sets the DUC rate index.
bool setDucStreamId(unsigned int streamId, bool applySetting=true)
Sets the Stream ID.
Class that supports debug output.
Definition: Debuggable.h:38
uint32_t classId1
Class ID Field Part 1.
Definition: PacketTypes.h:57
bool setTxAttenuation(unsigned int txAttenuation, bool applySetting=true)
Sets the transmitter attenuation.
bool sendFrame(unsigned char *frame, const int &frameLen)
Sends a frame of data.
bool setDucRate(unsigned int ducRate)
Sets the DUC rate index.
std::string getRadioMac(unsigned int tenGbeIndex)
Gets the MAC address of a 10GigE port on the radio.
uint16_t packetCount
Packet counter.
Definition: PacketTypes.h:44
bool setDucTxChannel(unsigned int txChannel, bool applySetting=true)
Sets the DUC transmitter bitmap.
bool setDucInterface(const std::string &ifname, unsigned int tenGigIndex)
Sets the DUC interface parameters.
struct Vita49Trailer vend
VITA 49 frame trailer.
Definition: PacketTypes.h:93
bool disconnect(void)
Disconnects the flow control client.
virtual int debug(const char *format,...)
Outputs debug information.
Definition: Debuggable.cpp:95
bool setDucEnable(bool ducEnable, bool applySetting=true)
Sets whether or not the DUC is enabled.
bool setTxFreq(double txFreq)
Sets the transmitter frequency.
uint16_t TSF
Timestamp fractional field format.
Definition: PacketTypes.h:45
bool setDebug(bool debug)
Sets whether or not to produce debug output.
bool setDucFrequency(long ducFreq, bool applySetting=true)
Sets the DUC frequency.
bool isReadyToReceive(void)
Gets whether or not the packetizer is ready to receive data.
Defines functionality for LibCyberRadio applications.
Definition: App.h:23
int16_t samples[2 *SAMPLES_PER_FRAME]
Interleaved I and Q samples.
Definition: PacketTypes.h:74
bool setDucFreq(float ducFreq)
Sets the DUC frequency.
bool connectToRadio(const std::string &hostname, unsigned int port)
Connects to the radio.
uint16_t C
Class ID field present indicator.
Definition: PacketTypes.h:49
uint32_t frameEnd
Frame end word (ASCII string "VEND")
Definition: PacketTypes.h:81
uint32_t frameSize
Frame size, in 32-bit words.
Definition: PacketTypes.h:41
bool setDucAttenuation(float attenuation, bool applySetting=true)
Sets the DUC attenuation.
uint32_t frameStart
Frame start word (ASCII string "VRLP")
Definition: PacketTypes.h:40
struct ethhdr eth
Ethernet header.
Definition: PacketTypes.h:88
bool setDucTxinvMode(unsigned int txinvMode, bool applySetting=true)
Sets the DUC TX Inversion Mode.
bool setDucParameters(unsigned int tenGigIndex, unsigned int ducRate, unsigned int ducTxChannels, float ducFreq, float ducAtten, double txFreq, float txAtten, unsigned int streamId)
Sets the DUC parameters.
bool setTxAtten(float txAtten)
Sets the transmitter attenuation.
bool setRadioTcpPort(int radioTcpPort)
Sets the radio TCP port.
bool setDucAtten(float ducAtten)
Sets the DUC attenuation.
void setDucChannel(unsigned int ducChannel)
Sets the DUC channel number.
struct Vita49Header v49
VITA 49 frame header.
Definition: PacketTypes.h:91
struct udphdr udp
UDP header.
Definition: PacketTypes.h:90
bool setStreamId(unsigned int streamId)
Sets the stream ID.
uint32_t classId2
Class ID Field Part 2.
Definition: PacketTypes.h:64
uint16_t T
Frame trailer present indicator.
Definition: PacketTypes.h:48
std::string getMacAddress()
Gets the MAC address.
std::string getIpAddress()
Gets the IP address.
bool setDucTenGbePort(unsigned int ducTenGbePort, bool applySetting=true)
Sets the 10GigE port used by the DUC.
unsigned int sendFrame(short *samples)
Sends a number of samples as a VITA 49 frame.