11 #include "LibCyberRadio/NDR651/TransmitPacketizer.h" 12 #include <boost/algorithm/string.hpp> 13 #include <boost/tokenizer.hpp> 16 #define BOOL_DEBUG(x) (x ? "true" : "false") 21 static unsigned short compute_checksum(
unsigned short *addr,
unsigned int count) {
22 register unsigned long sum = 0;
30 sum += ((*addr)&htons(0xFF00));
34 sum = (sum & 0xffff) + (sum >> 16);
38 return ((
unsigned short)sum);
41 bool setCpuAffinity(
int cpu) {
45 if (sched_setaffinity(0,
sizeof(
set), &
set)) {
57 TransmitPacketizer::TransmitPacketizer(
58 const std::string& radioHostName,
60 unsigned int ducChannel,
61 const std::string& ifname,
62 unsigned int tenGigIndex,
65 unsigned int ducTxChannels,
70 unsigned int streamId,
87 _config_tx(config_tx),
91 _frameStart((unsigned char*)(&_frame)),
101 _duchsPfThresh(61*(67108862/64)),
102 _duchsPeThresh(58*(67108862/64)),
104 _samplesPerFrame(SAMPLES_PER_FRAME),
112 this->
debug(
"construction\n");
113 std::cout <<
"using local lib" << std::endl;
114 memset(&_frame, 0,
sizeof(
TxFrame));
121 ducFreq, ducAtten, txFreq, txAtten,
123 _constructing =
false;
124 _delayTime.tv_sec = 0;
125 _delayTime.tv_nsec = 100;
133 this->
debug(
"destruction\n");
134 if ( _fcClient != NULL )
136 if ( _txSock != NULL )
153 this->
debug(
"setting duc channel = %d\n", ducChannel);
156 if ( (_txSock != NULL) && (_fcClient != NULL) )
162 this->
debug(
"duc channel set ok\n");
166 this->
debug(
"duc channel set skipped\n");
168 _configuring =
false;
173 unsigned int tenGigIndex)
176 this->
debug(
"setting duc interface = %s/%d\n", ifname.c_str(),
180 if ( ifname != _ifname )
182 if ( _txSock != NULL ) {
188 for (
int i=0; i<_numSock; i++) {
191 std::cout <<
"# sockets = " << _txSockVec.size() << std::endl;
192 _currentSockIndex = 0;
193 _txSock = _txSockVec[_currentSockIndex];
195 _tenGigIndex = tenGigIndex;
196 this->
debug(
"duc interface set ok\n");
198 _ducFreq, _ducAtten, _txFreq,
199 _txAtten, _streamId);
207 if (_fcClient != NULL)
211 _configuring =
false;
219 _ducTxChannels = ducTxChannels;
220 if (_fcClient != NULL)
224 _configuring =
false;
233 if (_fcClient != NULL)
237 _configuring =
false;
245 _txinvMode = txinvMode;
246 if (_fcClient != NULL)
250 _configuring =
false;
258 _ducAtten = ducAtten;
259 if (_fcClient != NULL)
263 _configuring =
false;
268 void TransmitPacketizer::setDuchsParameters(
unsigned int duchsPfThresh,
unsigned int duchsPeThresh,
unsigned int duchsPeriod,
bool updatePE) {
270 if (_updatePE != updatePE) {
271 _updatePE = updatePE;
273 std::cerr <<
"setDuchsParameters: Updating on PE packet" << std::endl;
275 std::cerr <<
"setDuchsParameters: Updating on periodic packet" << std::endl;
277 _statusRx->setUpdatePE(_updatePE);
279 if (_duchsPfThresh != duchsPfThresh) {
280 std::cerr <<
"setDuchsParameters: Modify duchsPfThresh " << _duchsPfThresh <<
"->" << duchsPfThresh << std::endl;
281 _duchsPfThresh = duchsPfThresh;
284 if (_duchsPeThresh != duchsPeThresh) {
285 std::cerr <<
"setDuchsParameters: Modify duchsPeThresh " << _duchsPeThresh <<
"->" << duchsPeThresh << std::endl;
286 _duchsPeThresh = duchsPeThresh;
289 if (_duchsPeriod != duchsPeriod) {
290 std::cerr <<
"setDuchsParameters: Modify duchsPeriod " << _duchsPeriod <<
"->" << duchsPeriod << std::endl;
291 _duchsPeriod = duchsPeriod;
294 if (change && _running) {
295 _fcClient->setDuchsParameters(_duchsPfThresh, _duchsPeThresh, _duchsPeriod);
302 bool shfChange = (_txFreq != txFreq) && (((_txFreq >= 200.0)&&(txFreq < 200.0))||((_txFreq < 200.0)&&(txFreq >= 200.0)));
305 if (_fcClient != NULL)
317 _configuring =
false;
326 if (_fcClient != NULL)
330 _configuring =
false;
338 _streamId = streamId;
339 setUdpHeader(_streamId, _streamId);
340 setVitaHeader(_streamId);
341 if (_fcClient != NULL)
345 _configuring =
false;
356 const std::string& radioHostName,
360 this->
debug(
"setting radio parameters host=%s, port=%d\n",
361 radioHostName.c_str(), radioTcpPort);
364 if ( _fcClient != NULL )
370 if ( !_constructing )
374 if ( radioHostName != _radioHostName )
380 if ( (radioHostName != _radioHostName) ||
381 (radioTcpPort != _radioTcpPort) )
387 _radioHostName = radioHostName;
388 _radioTcpPort = radioTcpPort;
390 if ( _radioHostName !=
"" )
392 this->
debug(
"radio parameters set result = %s\n",
397 this->
debug(
"radio parameters set skipped\n");
399 _configuring =
false;
404 unsigned int ducRate,
405 unsigned int ducTxChannels,
410 unsigned int streamId)
414 this->
debug(
"setting duc parameters index=%d\n", tenGigIndex);
415 _tenGigIndex = tenGigIndex;
417 _ducTxChannels = ducTxChannels;
419 _ducAtten = ducAtten;
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);
429 if ( (_txSock != NULL) && (_fcClient != NULL) )
433 if (_txSock->isUsingRawSocket()) {
434 this->
debug(
"-- source mac = %s\n", _sMac.c_str());
436 this->
debug(
"-- dest mac = %s\n", _dMac.c_str());
437 setEthernetHeader(_sMac, _dMac);
438 this->
debug(
"-- source ip = %s\n", _sIp.c_str());
440 this->
debug(
"-- dest ip = %s\n", _dIp.c_str());
441 setIpHeader(_sIp, _dIp);
442 setUdpHeader(_streamId, _streamId);
445 _frameLength =
sizeof(
TxFrame)-(
sizeof(ethhdr) +
sizeof(iphdr) +
sizeof(udphdr) );
447 setVitaHeader(_streamId);
448 this->
debug(
"-- enabling duc\n");
449 ret = _fcClient->
enableDuc(_ducRate, _ducTxChannels,
450 _streamId, _tenGigIndex,
453 (
unsigned int)_txAtten);
454 this->
debug(
"-- duc enable = %s\n", BOOL_DEBUG(ret));
458 this->
debug(
"duc parameters set skipped\n");
460 this->
debug(
"duc parameters set result = %s\n", BOOL_DEBUG(ret));
461 _configuring =
false;
470 _fcClient->setDucDipStatusEntry(-1, _sIp, _sMac, _statusRx->getUdpPort());
471 _statusRx->setUpdatePE(_updatePE);
472 _fcClient->setDuchsParameters(_duchsPfThresh, _duchsPeThresh, _duchsPeriod);
473 if ( _statusRx != NULL )
479 std::cerr <<
"Stopping flow control threads.\n";
480 this->setDuchsParameters(0, 0, 0,
false);
481 if ( _fcClient != NULL ) {
491 if ( _statusRx != NULL ){
492 std::cerr <<
"_statusRx->interrupt()\n";
494 std::cerr <<
"delete _statusRx\n";
498 std::cerr <<
"Stopped flow control threads.\n";
506 if ( (_txSock != NULL) && (_fcClient != NULL) && (_statusRx != NULL) )
508 while (!_statusRx->
okToSend(SAMPLES_PER_FRAME,
false))
513 if (_txSock->
sendFrame(_frameStart, _frameLength))
515 _samplesSent = SAMPLES_PER_FRAME;
516 _incrementVitaHeader();
518 this->
debug(
"1st frame sent!\n");
523 _currentSockIndex = (_currentSockIndex+1)%_txSockVec.size();
524 _txSock = _txSockVec[_currentSockIndex];
538 return ( (_fcClient != NULL) &&
547 bool TransmitPacketizer::setEthernetHeader(
const std::string& sourceMac,
548 const std::string& destMac)
550 std::vector<std::string> macVec;
554 split(macVec, destMac, is_any_of(
":"));
557 for (std::vector<std::string>::iterator i=macVec.begin(); i!=macVec.end(); i++) {
558 unsigned char val = strtol((*i).c_str(), NULL, 16);
560 _frame.
eth.h_dest[ind++] = val;
565 split(macVec, sourceMac, is_any_of(
":"));
568 for (std::vector<std::string>::iterator i=macVec.begin(); i!=macVec.end(); i++) {
569 unsigned char val = strtol((*i).c_str(), NULL, 16);
571 _frame.
eth.h_source[ind++] = val;
575 _frame.
eth.h_proto = htons(ETH_P_IP);
580 bool TransmitPacketizer::setIpHeader(
const std::string& sourceIp,
581 const std::string& destIp)
583 _frame.
ip.version = 4;
584 _frame.
ip.ihl =
sizeof(iphdr)/4;
586 _frame.
ip.protocol = 17;
587 _frame.
ip.tot_len = htons(
sizeof(TxFrame)-
sizeof(ethhdr));
591 inet_pton(AF_INET, destIp.c_str(), &(_frame.
ip.daddr));
594 inet_pton(AF_INET, sourceIp.c_str(), &(_frame.
ip.saddr));
598 _frame.
ip.check = compute_checksum((
unsigned short*)&(_frame.
ip), _frame.
ip.ihl<<2);
603 bool TransmitPacketizer::setUdpHeader(
unsigned short sourcePort,
604 unsigned short destPort)
606 _frame.
udp.source = htons(sourcePort);
607 _frame.
udp.dest = htons(destPort);
608 _frame.
udp.len = htons(
sizeof(TxFrame)-
sizeof(ethhdr)-
sizeof(iphdr));
612 bool TransmitPacketizer::setVitaHeader(
unsigned int streamId)
638 void TransmitPacketizer::_incrementVitaHeader()
virtual ~TransmitPacketizer()
Destroys a TransmitPacketizer object.
struct Payload payload
VITA 49 payload.
bool setDucChannel(unsigned int ducChannel)
Sets the DUC channel number.
void stop()
Stops the packetizer.
struct iphdr ip
IP header.
bool setRadioHostName(const std::string &radioHostName)
Sets the radio host name.
bool isConnected(void)
Gets whether or not the client is connected.
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.
Flow control client class.
std::string getRadioIp(unsigned int tenGbeIndex)
Gets the IP address of a 10GigE port on the radio.
VITA 49 transmit-over-UDP frame information.
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.
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.
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.
void start()
Starts the packetizer.
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.
bool disconnect(void)
Disconnects the flow control client.
virtual int debug(const char *format,...)
Outputs debug information.
bool setDucEnable(bool ducEnable, bool applySetting=true)
Sets whether or not the DUC is enabled.
bool setTxFreq(double txFreq)
Sets the transmitter frequency.
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.
int16_t samples[2 *SAMPLES_PER_FRAME]
Interleaved I and Q samples.
bool setDucFreq(float ducFreq)
Sets the DUC frequency.
bool connectToRadio(const std::string &hostname, unsigned int port)
Connects to the radio.
uint32_t frameEnd
Frame end word (ASCII string "VEND")
bool setDucAttenuation(float attenuation, bool applySetting=true)
Sets the DUC attenuation.
struct ethhdr eth
Ethernet header.
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.
struct udphdr udp
UDP header.
bool setStreamId(unsigned int streamId)
Sets the stream ID.
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.
bool disableDuc()
Disables the DUC.