#include "dlink.h" #include #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(showMessage(QString,int)), this,SIGNAL(showMessage(QString,int))); //在当前线程运行 connect(this,SIGNAL(recieveMessage(quint32,QByteArray)), mavlinknode,SLOT(setbuff(quint32,QByteArray)),Qt::DirectConnection); PPSTimer = new QTimer(); PPSTimer->setInterval(1000); connect(PPSTimer,&QTimer::timeout, this,&DLink::timeout); PPSTimer->start(); } DLink::~DLink() { stopPort(); delete mavlinknode; mavlinknode = nullptr; if(PPSTimer) { PPSTimer->stop(); delete PPSTimer; } } void DLink::timeout() { static qint64 last = QDateTime::currentMSecsSinceEpoch(); qint64 time = QDateTime::currentMSecsSinceEpoch() - last; if(time >= 3000) { 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); } } 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; //更加ch选择 if (DLink::Clientsock) { foreach(Node node,clientSockets) { qint64 flag = DLink::Clientsock->writeDatagram((const char *)msg,len,node.addr, node.port); if(flag != -1) { //qDebug() << "send"; } } } if (DLink::serialPort) { qint64 flag = DLink::serialPort->write((const char *)msg,len); if(flag != -1) { //Byte_Out_ALL += flag; } } if (multicast_sock) { qint64 flag = multicast_sock->writeDatagram((const char *)msg, len,multicast_transmit_addr, multicast_transmit_port); if(flag != -1) { //Byte_Out_ALL += flag; } } return 0; } //这个函数就在本线程内运行 bool DLink::setupPort(const QString port, qint32 baudrate, QSerialPort::Parity parity) { qWarning() << port << baudrate << parity; bool isSuccess = false; if (serialPort)//多串口接入 { serialPort->close(); delete serialPort; } serialPort = new QSerialPort(this); serialPort->setPortName(port); if (serialPort->open(QIODevice::ReadWrite)) { serialPort->setBaudRate(baudrate); serialPort->setParity(parity); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); DLink::serialPort->write("serial connet ok",16); connect(serialPort, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsSerialPort()));//本线程内调用 isSuccess = true; 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(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_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") { stopPort(); emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5); } else if(m_Type.toString() == "UDP") { //断开连接 if(Clientsock) { for(int i = 0;i < clientSockets.count();i++) { qDebug() << clientSockets.at(i).addr; if(clientSockets.at(i).addr == QHostAddress(m_Param3.toString())) { clientSockets.removeAt(i); } } Clientsock->leaveMulticastGroup(QHostAddress(m_Param3.toString())); Clientsock->close(); qWarning("leave multicast Group"); delete Clientsock; Clientsock = nullptr; } emit PortConnected(false,m_usrName,m_Type,m_Param1,m_Param2,m_Param3,m_Param4,m_Param5); } else if(m_Type.toString() == "Multicast") { //断开连接 if(multicast_sock) { qWarning("leave multicast Group"); delete multicast_sock; multicast_sock = nullptr; } 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) { if(Clientsock) { Clientsock->disconnect(); delete Clientsock; Clientsock = nullptr; } qDebug() << "sock connect"; bool isSuccess = false; Clientsock = new QUdpSocket(this); Clientsock->setSocketOption(QAbstractSocket::MulticastLoopbackOption,1); Clientsock->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption,1024*1024*8); //QHostAddress::AnyIPv4 int rst = Clientsock->bind(QHostAddress::AnyIPv4,local_port, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint); qDebug() << "rst" << rst; if(rst) { Clientsock->joinMulticastGroup(remote_addr); if(Clientsock->open(QIODevice::ReadWrite)) //if(Clientsock->joinMulticastGroup(remote_addr)) { connect(Clientsock, SIGNAL(readyRead()), this, SLOT(readPendingDatagramsClient())); Node node; node.sock = Clientsock; node.addr = remote_addr; node.port = remote_port; clientSockets.append(node); qWarning() << "UdpSocket open:" << remote_addr << local_port << remote_port; isSuccess = true; emit showMessage(tr("UdpSocket open")); } else { //Clientsock->leaveMulticastGroup(remote_addr); Clientsock->close(); isSuccess = false; qWarning() << "sock not open"; delete Clientsock; Clientsock = nullptr; } } else { isSuccess = false; //Clientsock->leaveMulticastGroup(remote_addr); Clientsock->close(); qWarning("sock is not binded."); delete Clientsock; Clientsock = nullptr; } return isSuccess; } bool DLink::setup_multicast(const QString &recieveIP, qint32 recievePort, const QString &transmitIP, qint32 transmitPort) { bool isSuccess = false; multicast_transmit_port = transmitPort; multicast_transmit_addr.setAddress(transmitIP); if (multicast_sock) delete multicast_sock; multicast_recieve_addr.setAddress(recieveIP); multicast_sock = new QUdpSocket(this); if (multicast_sock->bind(QHostAddress::AnyIPv4, recievePort, QUdpSocket::ShareAddress)) { if (multicast_sock->joinMulticastGroup(multicast_recieve_addr)) { connect(multicast_sock, SIGNAL(readyRead()), this, SLOT(processPendingMulticastDatagrams())); multicast_recieve_port = recievePort; multicast_sock->setSocketOption(QAbstractSocket::MulticastTtlOption, 3); isSuccess = true; emit showMessage(tr("Bind and join the gdt multicast group")); } else { isSuccess = false; delete multicast_sock; multicast_sock = NULL; emit showMessage(tr("Fail to join gdt multicast group.")); } } else { isSuccess = false; emit showMessage(tr("Fail to bind gdt multicast socket.")); delete multicast_sock; multicast_sock = NULL; } return isSuccess; } void DLink::readPendingDatagramsSerialPort(void) { if(serialPort) { QByteArray datagram = serialPort->readAll(); emit recieveMessage(SourceType::s_port,datagram); } } void DLink::readPendingDatagramsClient(void) { QElapsedTimer time; time.start(); //轮番查询 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) { if(multicast_sock) { while (multicast_sock->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(multicast_sock->pendingDatagramSize()); multicast_sock->readDatagram(datagram.data(), datagram.size()); emit recieveMessage(SourceType::c_sock,datagram); } } }