Files
gcs-nf/dlink/dlink.cpp
T
2026-05-05 17:08:24 +08:00

850 lines
23 KiB
C++

#include "dlink.h"
#include <string.h>
#include "QDateTime"
#include "QElapsedTimer"
DLink::DLink(QObject *parent) : QObject(parent)
{
qDebug() << "Dlink " << QThread::currentThreadId();
//采用插件导入的方式(plugin)
mavlinknode = new MavLinkNode();//不允许带参数,因为这是单独的线程
//在当前线程运行
connect(mavlinknode,SIGNAL(SendMessageTo(quint8,quint8*,quint16)),
this,SLOT(SendMessageTo(quint8,quint8*,quint16)), Qt::BlockingQueuedConnection);//BlockingQueuedConnection);//信号和槽必须在不同的线程中,否则就产生死锁
connect(mavlinknode,SIGNAL(SendMessageToExport(quint8,quint8*,quint16)),
this,SLOT(SendMessageToExport(quint8,quint8*,quint16)));//BlockingQueuedConnection);//信号和槽必须在不同的线程中,否则就产生死锁
//在当前线程运行
connect(mavlinknode,SIGNAL(showMessage(QString,int)),
this,SIGNAL(showMessage(QString,int)));
//在当前线程运行
connect(this,SIGNAL(recieveMessage(quint32,QByteArray)),
mavlinknode,SLOT(setbuff(quint32,QByteArray)),Qt::DirectConnection);
connect(this,SIGNAL(getRTK(quint32,QByteArray)),
mavlinknode->rtk,SLOT(setbuff(quint32,QByteArray)),Qt::DirectConnection);
Exportsock = new QUdpSocket(this);
int rst = Exportsock->bind(QHostAddress::AnyIPv4,10000);
if(rst)
{
if(Exportsock->open(QIODevice::ReadWrite))
{
qDebug() << "信息输出端口打开正常";
}
}
PPSTimer = new QTimer();
PPSTimer->setInterval(1000);
connect(PPSTimer,&QTimer::timeout,
this,&DLink::timeout);
PPSTimer->start();
bitTimer = new QTimer(this);
bitTimer->setInterval(1000);
connect(bitTimer,SIGNAL(timeout()),
this,SLOT(bitTimerout()));
bitTimer->start();
sendRTCM = false;
RecieveRTCMtime = QDateTime::currentMSecsSinceEpoch();
}
DLink::~DLink()
{
foreach (serialNode node, serials) {
if(node.port)
{
if(node.port->isOpen())
{
node.port->close();
}
delete node.port;
node.port = nullptr;
}
}
foreach(clientNode node,clientSockets)
{
if(node.sock)
{
node.sock->leaveMulticastGroup(node.addr);
node.sock->abort();
qWarning("leave multicast Group");
delete node.sock;
node.sock = nullptr;
}
}
delete mavlinknode;
mavlinknode = nullptr;
if(Exportsock)
{
Exportsock->abort();
delete Exportsock;
Exportsock = nullptr;
}
if(PPSTimer)
{
PPSTimer->stop();
delete PPSTimer;
}
}
void DLink::timeout()
{
static qint64 last = QDateTime::currentMSecsSinceEpoch();
qint64 time = QDateTime::currentMSecsSinceEpoch() - last;
if(time >= 2000)
{
Byte_Out_per = (double)Byte_Out_ALL / (time * 0.001);
Byte_Out_ALL = 0;
last = QDateTime::currentMSecsSinceEpoch();
emit byteCount(Byte_In_per,Byte_Out_per);
}
}
void DLink::bitTimerout()
{
static qint64 last = QDateTime::currentMSecsSinceEpoch();
qint64 time = QDateTime::currentMSecsSinceEpoch() - last;
if(time >= 2000)
{
last = QDateTime::currentMSecsSinceEpoch();
double RecieveRCByte = 0;
double RecieveRTCMByte = 0;
RecieveRTCMByte = (double)RecieveRTCMcount / (time * 0.001);
if((QDateTime::currentMSecsSinceEpoch() - RecieveRTCMtime) > 2000)
{
emit RTCM_Byte(0);
}
else
{
emit RTCM_Byte(RecieveRTCMByte);
}
RecieveRTCMcount = 0;
}
}
void DLink::setExportInfo(QVariant value,QVariant id, QHostAddress addr, qint32 port)
{
isExportInfo = value.toBool();
if(isExportInfo)
{
if(!Exportsock)
{
Exportsock = new QUdpSocket(this);
int rst = Exportsock->bind(QHostAddress::AnyIPv4,10000);
if(rst)
{
if(Exportsock->open(QIODevice::ReadWrite))
{
qDebug() << "信息输出端口打开正常";
}
}
}
}
else
{
if(Exportsock)
{
Exportsock->abort();
delete Exportsock;
Exportsock = nullptr;
}
}
if(mavlinknode)
{
mavlinknode->infoExportID = id.toInt();
}
Export_addr = addr;
Export_port = port;
/*
qDebug() << "isExportInfo" << value
<< id
<< addr
<< port;
*/
}
int DLink::SendMessageToExport(quint8 ch, quint8 *msg, quint16 len)
{
Q_UNUSED(ch)
if(isExportInfo)//使能输出再输出
{
if(Exportsock)
{
qint64 flag = Exportsock->writeDatagram((const char *)msg,len,Export_addr, Export_port);
if(flag != -1)
{
//qDebug() << "export Client Send Msg" << Export_addr <<Export_port << msg[0];
}
}
}
return len;
}
int DLink::SendMessageTo(quint8 ch, quint8 *msg, quint16 len)
{
//让这个函数在其他线程运行
/*
QString num;
for (int i = 0; i < len; ++i) {
num.append(QString::number(msg[i],16).toUpper());
num.append(" ");
}
qDebug() << num;
*/
//Q_UNUSED(ch);
Byte_Out_ALL += len;
foreach(clientNode node,clientSockets)
{
if(node.sock->isOpen()||node.sock->isWritable()||node.sock->isValid())
{
if(node.type == devtype::datalink)
{
qint64 flag = node.sock->writeDatagram((const char *)msg,len,node.addr, node.port);
if(flag != -1)
{
//qDebug() << "Client Send Msg";
}
else
{
qDebug() << tr("udp Send Msg failure");
}
}
}
}
foreach (serialNode node, serials) {
if(node.port)
{
if(node.port->isOpen()||node.port->isWritable())
{
if(node.type == devtype::datalink)
{
qint64 flag = node.port->write((const char *)msg,len);
if(flag != -1)
{
//qDebug() << "serialPort Send Msg";
}
else
{
qDebug() << tr("serialPort Send Msg failure");
}
}
}
}
}
return 0;
}
void DLink::readRTKPendingDatagrams()
{
QObject *obj = sender();
if(obj)
{
QSerialPort *serialport = qobject_cast<QSerialPort *>(obj);
if(serialport)
{
QByteArray datagram = serialport->readAll();
if(datagram.size() > 0)
{
//emit RTCM_Byte(datagram.size());
RecieveRTCMcount += datagram.size();
RecieveRTCMtime = QDateTime::currentMSecsSinceEpoch();
isRecieveRTCM = true;
if(sendRTCM == true)
{
emit getRTK(SourceType::s_port,datagram);
}
}
}
}
}
//这个函数就在本线程内运行
bool DLink::setupPort(const QString port, qint32 baudrate, QSerialPort::Parity parity)
{
bool isSuccess = false;
foreach (serialNode node, serials) {
if(node.port)
{
if(node.name == port)
{
if(node.port->isOpen())
{
node.port->close();
}
//断掉所有的连接
disconnect(node.port,nullptr,nullptr,nullptr);
delete node.port;
node.port = nullptr;
serials.removeAt(serials.indexOf(node));
}
}
}
QSerialPort *serialPort = new QSerialPort(port,this);
if (serialPort->open(QIODevice::ReadWrite))
{
serialPort->setBaudRate(baudrate);
serialPort->setParity(parity);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setStopBits(QSerialPort::OneStop);
isSuccess = true;
serialNode node;
node.port = serialPort;
node.baud = baudrate;
node.parity = parity;
node.name = port;
node.type = devtype::datalink;
serials.append(node);
connect(serialPort, SIGNAL(readyRead()),
this, SLOT(readPendingDatagramsSerialPort()));//本线程内调用
emit showMessage(tr("Serial Port Open Success"));
qWarning() << "Serial Port Open Success";
}
else
{
isSuccess = false;
emit showMessage(tr("Serial Port Open Fail"));
qWarning() << "Serial Port Open Fail";
delete serialPort;
serialPort = nullptr;
}
return isSuccess;
}
bool DLink::statesPort()
{
if(serialPort)
{
return (serialPort != nullptr)?(true):(false);
}
}
void DLink::stopPort()
{
if(serialPort)
{
emit showMessage(tr("Serial Port close"));
if(serialPort->isOpen())
{
serialPort->close();
}
delete serialPort;
serialPort = nullptr;
}
}
void DLink::connectSignal(QVariant m_state,
QVariant m_usrName,QVariant m_Type,
QVariant m_Param1,QVariant m_Param2,
QVariant m_Param3,QVariant m_Param4,
QVariant m_Param5)
{
qDebug() << m_Type.toString();
if(m_state.toBool() == true)
{
if(m_Type.toString() == "SerialPort")
{
QSerialPort::Parity parity;
if(m_Param4.toString() == "NONE")
{
parity = QSerialPort::Parity::NoParity;
}
if(m_Param4.toString() == "ODD")
{
parity = QSerialPort::Parity::OddParity;
}
if(m_Param4.toString() == "EVEN")
{
parity = QSerialPort::Parity::EvenParity;
}
qWarning() << m_Type << m_Param1 << m_Param2.toString().toInt() << parity;
if(m_usrName.toString() == "DataLink" )
{
if(setupPort(m_Param1.toString(),m_Param2.toString().toInt(),parity))
{
emit PortConnected(true,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else
{
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
}
else if(m_usrName.toString() == "RTK" )
{
if(setup_rtk(m_Param1.toString(),m_Param2.toString().toInt(),parity))
{
emit PortConnected(true,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else
{
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
}
}
else if(m_Type.toString() == "UDP")
{
qDebug() << "connet to udp socket";
if(setupClient(QHostAddress(m_Param1.toString()),m_Param2.toString().toInt(),QHostAddress(m_Param3.toString()),m_Param4.toString().toInt()))
{
emit PortConnected(true,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else
{
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
}
else if(m_Type.toString() == "Multicast")
{
qDebug() << "connet to multicast socket";
if(setup_multicast(m_Param1.toString(),m_Param2.toString().toInt(),m_Param3.toString(),m_Param4.toString().toInt()))
{
emit PortConnected(true,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else
{
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
}
}
else
{
qWarning() << "disconnect";
if(m_Type.toString() == "SerialPort")
{
foreach (serialNode node, serials) {
if(node.port)
{
if(node.name == m_Param1.toString())
{
if(node.port->isOpen())
{
emit showMessage(tr("%1 close").arg(node.name));
node.port->close();
}
//断掉所有的连接
disconnect(node.port,nullptr,nullptr,nullptr);
delete node.port;
node.port = nullptr;
serials.removeOne(node);
}
}
}
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else if(m_Type.toString() == "UDP")
{
//断开连接
for(int i = 0;i < clientSockets.count();i++)
{
if((clientSockets.at(i).addr == QHostAddress(m_Param3.toString()))&&(clientSockets.at(i).port == m_Param4.toInt()))
{
clientSockets.at(i).sock->leaveMulticastGroup(QHostAddress(m_Param3.toString()));
clientSockets.at(i).sock->close();
qWarning("leave multicast Group");
clientSockets.at(i).sock->deleteLater();
clientSockets.removeAt(i);
}
}
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
else if(m_Type.toString() == "Multicast")
{
//断开连接
for(int i = 0;i < clientSockets.count();i++)
{
if((clientSockets.at(i).addr == QHostAddress(m_Param3.toString()))&&(clientSockets.at(i).port == m_Param4.toInt()))
{
clientSockets.at(i).sock->leaveMulticastGroup(QHostAddress(m_Param3.toString()));
clientSockets.at(i).sock->close();
qWarning("leave multicast Group");
clientSockets.at(i).sock->deleteLater();
clientSockets.removeAt(i);
}
}
emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5);
}
}
}
bool DLink::setupClient(const QHostAddress &local_addr,int local_port,const QHostAddress &remote_addr,int remote_port)
{
bool isSuccess = false;
foreach (clientNode node, clientSockets) {
if(node.sock)
{
if((node.addr == remote_addr)&&(node.port == remote_port))
{
if(node.sock->isOpen())
{
node.sock->leaveMulticastGroup(node.addr);
node.sock->close();
}
//断掉所有的连接
disconnect(node.sock,nullptr,nullptr,nullptr);
node.sock->deleteLater();
//node.sock = nullptr;
clientSockets.removeAt(clientSockets.indexOf(node));
}
}
}
QUdpSocket *clientsock = new QUdpSocket(this);
int rst = clientsock->open(QIODevice::ReadWrite);
if(rst)
{
clientsock->setSocketOption(QAbstractSocket::MulticastLoopbackOption,1);
clientsock->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,1024*1024*8);
clientsock->setProxy(QNetworkProxy::NoProxy);
if(clientsock->bind(local_addr,local_port,QAbstractSocket::ShareAddress|QUdpSocket::ReuseAddressHint))
{
clientNode node;
node.sock = clientsock;
node.addr = remote_addr;
node.port = remote_port;
node.type = devtype::datalink;
clientSockets.append(node);
qWarning() << "UdpSocket open:"
<< remote_addr
<< local_port
<< remote_port;
isSuccess = true;
connect(clientsock, SIGNAL(readyRead()),
this, SLOT(readPendingDatagramsClient()));
emit showMessage(tr("UdpSocket open"));
}
else
{
clientsock->close();
isSuccess = false;
qWarning() << "sock open failure" << clientsock->state();
delete clientsock;
clientsock = nullptr;
}
}
else
{
isSuccess = false;
clientsock->close();
qWarning("sock is not binded.");
delete clientsock;
clientsock = nullptr;
}
return isSuccess;
}
bool DLink::setup_rtk(const QString port, qint32 baudrate, QSerialPort::Parity parity)
{
bool isSuccess = false;
foreach (serialNode node, serials) {
if(node.port)
{
if(node.name == port)
{
if(node.port->isOpen())
{
node.port->close();
}
//断掉所有的连接
disconnect(node.port,nullptr,nullptr,nullptr);
delete node.port;
node.port = nullptr;
serials.removeAt(serials.indexOf(node));
}
}
}
QSerialPort *serialPort = new QSerialPort(port, this);
if (serialPort->open(QIODevice::ReadWrite))
{
serialPort->setBaudRate(baudrate);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setParity(parity);
serialPort->setDataBits(QSerialPort::Data8);
connect(serialPort, &QSerialPort::readyRead, this, &DLink::readRTKPendingDatagrams);
isSuccess = true;
serialNode node;
node.port = serialPort;
node.baud = baudrate;
node.parity = parity;
node.name = port;
node.type = devtype::rtk;
serials.insert(serials.size(),node);
}
else
{
delete serialPort;
serialPort = NULL;
}
return isSuccess;
}
bool DLink::setup_multicast(const QString &recieveIP, qint32 recievePort,
const QString &transmitIP, qint32 transmitPort)
{
bool isSuccess = false;
foreach (clientNode node, clientSockets) {
if(node.sock)
{
if((node.addr == QHostAddress(recieveIP))&&(node.port == recievePort))
{
if(node.sock->isOpen())
{
node.sock->leaveMulticastGroup(node.addr);
node.sock->close();
}
//断掉所有的连接
disconnect(node.sock,nullptr,nullptr,nullptr);
node.sock->deleteLater();
//node.sock = nullptr;
clientSockets.removeAt(clientSockets.indexOf(node));
}
}
}
QUdpSocket *clientsock = new QUdpSocket(this);
if(clientsock->bind(QHostAddress::AnyIPv4,recievePort,QAbstractSocket::ShareAddress))
{
if (clientsock->joinMulticastGroup(QHostAddress(recieveIP)))
{
clientsock->setProxy(QNetworkProxy::NoProxy);
clientsock->setSocketOption(QAbstractSocket::MulticastTtlOption, 3);
clientNode node;
node.sock = clientsock;
node.addr = QHostAddress(transmitIP);
node.port = transmitPort;
node.type = devtype::datalink;
clientSockets.append(node);
qWarning() << "multicast open:"
<< node.addr
<< node.port;
isSuccess = true;
connect(clientsock, SIGNAL(readyRead()),
this, SLOT(processPendingMulticastDatagrams()));
emit showMessage(tr("Bind and join the multicast group"));
}
else
{
clientsock->close();
isSuccess = false;
qWarning() << "sock open failure" << clientsock->state();
delete clientsock;
clientsock = nullptr;
emit showMessage(tr("Fail to join multicast group."));
}
}
else
{
isSuccess = false;
clientsock->close();
qWarning("sock is not binded.");
delete clientsock;
clientsock = nullptr;
emit showMessage(tr("Fail to bind multicast socket."));
}
return isSuccess;
}
void DLink::readPendingDatagramsSerialPort(void)
{
QObject *obj = sender();
if(obj)
{
QSerialPort *serialport = qobject_cast<QSerialPort *>(obj);
if(serialport)
{
QByteArray datagram = serialport->readAll();
emit recieveMessage(SourceType::s_port,datagram);
}
}
}
void DLink::readPendingDatagramsClient(void)
{
QElapsedTimer time;
time.start();
//轮番查询
QObject *obj = sender();
if(obj)
{
QUdpSocket *clientsock = qobject_cast<QUdpSocket *>(obj);
if(clientsock)
{
while (clientsock->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(clientsock->pendingDatagramSize());
clientsock->readDatagram(datagram.data(), datagram.size());
emit recieveMessage(SourceType::c_sock,datagram);
}
}
}
int milsec = time.elapsed();
//qDebug() << "a loop using time:" << milsec << "ms";
}
void DLink::processPendingMulticastDatagrams(void)
{
QElapsedTimer time;
time.start();
//轮番查询
QObject *obj = sender();
if(obj)
{
QUdpSocket *clientsock = qobject_cast<QUdpSocket *>(obj);
if(clientsock)
{
while (clientsock->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(clientsock->pendingDatagramSize());
clientsock->readDatagram(datagram.data(), datagram.size());
emit recieveMessage(SourceType::c_sock,datagram);
}
}
}
int milsec = time.elapsed();
//qDebug() << "a loop using time:" << milsec << "ms";
}