#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(SendMessageToExport(quint8,quint8*,quint16)), this,SLOT(SendMessageToExport(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); 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(); } 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::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 <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; } //这个函数就在本线程内运行 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(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") { 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_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(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(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(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"; }