#include "dataserialport.h"
#include <QThread>
#ifdef QT_DEBUG
#include <QDebug>
#include <QDateTime>
#endif
//QSemaphore m_semEcho(1);
DataSerialPort::DataSerialPort() : QObject(),
m_strComName(""),
m_pThread(new QThread()),
m_pCom(new QSerialPort()),
m_iLen(-1),
m_bOpen(false),
m_bEchoFlag(false)
{
qRegisterMetaType<tagSerialPortInfo>("tagSerialPortInfo");
m_pCom->moveToThread(m_pThread);
this->moveToThread(m_pThread);
m_pThread->start();
connect(m_pCom, &QSerialPort::readyRead, this, &DataSerialPort::slotDataReady, Qt::DirectConnection);
connect(this, &DataSerialPort::sigSetCOM, this, &DataSerialPort::slotSetCOM);
connect(this, &DataSerialPort::sigClose, this, &DataSerialPort::slotClose);
connect(this, &DataSerialPort::sigClear, this, &DataSerialPort::slotClear);
connect(this, &DataSerialPort::sigWrite, this, &DataSerialPort::slotWrite);
}
DataSerialPort::~DataSerialPort()
{
#ifdef QT_DEBUG
qDebug() << "~DataSerialPort:" << QThread::currentThreadId() << "\n";
#endif
close();
m_pThread->quit();
m_pThread->wait();
delete m_pCom;
m_pCom = 0;
delete m_pThread;
m_pThread = 0;
}
bool DataSerialPort::isOpen() const
{
return m_bOpen;
}
qint64 DataSerialPort::write(const QByteArray &byteArray)
{
return write(byteArray.data(), byteArray.size());
}
qint64 DataSerialPort::write(const char *data, qint64 maxSize/* = -1*/)
{
if(!m_bOpen) return -1;
m_lockWrite.lock();
const int nAvlb = m_semWrite.available();
if(nAvlb > 0)
{
m_semWrite.tryAcquire(nAvlb);
}
emit sigWrite(data, maxSize);
const bool bWait = m_semWrite.tryAcquire(1, 5000);
m_lockWrite.unlock();
QMutexLocker lk(&m_lockWriteLen);
qint64 iRet = bWait ? m_iLen : 0;
return iRet;
}
void DataSerialPort::close()
{
m_lockClose.lock();
const int nAvlb = m_semClose.available();
if(nAvlb > 0)
{
m_semClose.tryAcquire(nAvlb);
}
emit sigClose();
m_semClose.tryAcquire(1, 5000);
m_lockClose.unlock();
}
void DataSerialPort::clear()
{
m_lockClear.lock();
const int nAvlb = m_semClear.available();
if(nAvlb > 0)
{
m_semClear.tryAcquire(nAvlb);
}
emit sigClear();
m_semClear.tryAcquire(1, 5000);
m_lockClear.unlock();
}
bool DataSerialPort::sendReciveData(const char * strCmd, qint64 leng, QByteArray& pstrReply)
{
clear();
setEchoFlag(true);
const int nAvlb = m_semEcho.available();
if(nAvlb > 0)
{
m_semEcho.tryAcquire(nAvlb);
}
pstrReply.clear();
if(write(strCmd,leng) < leng)
{
setEchoFlag(false);
return false;
}
bool bRet = m_semEcho.tryAcquire(1, 10000);
#ifdef QT_DEBUG
qDebug() << QDateTime::currentDateTime().toString("HH:mm:ss.zzz") << "EchoCommand wait " << bRet << " " << m_strReply << " |\n";
#endif
setEchoFlag(false);
if(false == bRet)
{
if(m_strReply.endsWith('\n'))
{
bRet = true;
}
}
pstrReply = m_strReply.toLatin1();
return bRet;
}
bool DataSerialPort::openPort(tagSerialPortInfo& cfg)
{
m_lockSetCOM.lock();
const int nAvlb = m_semSetCOM.available();
if(nAvlb > 0)
{
m_semSetCOM.tryAcquire(nAvlb);
}
emit sigSetCOM(cfg);
const bool bWait = m_semSetCOM.tryAcquire(1, 5000);
m_lockSetCOM.unlock();
return bWait ? m_bOpen : false;
}
void DataSerialPort::slotSetCOM(tagSerialPortInfo cfg)
{
qDebug()<<"slotSetCOM thread id = "<<QThread::currentThreadId()<<"==============================";
m_pCom->close();
m_bOpen = false;
if (cfg.portName.length() < 1)
return;
m_pCom->setPortName(cfg.portName);
if(!m_pCom->setBaudRate(cfg.baudRate, cfg.directions)) return ;
if(!m_pCom->setDataBits(cfg.dataBits)) return ;
if(!m_pCom->setFlowControl(cfg.flowControl)) return;
if(!m_pCom->setParity(cfg.parity)) return;
if(!m_pCom->setStopBits(cfg.stopBits)) return;
if(!m_pCom->open(QIODevice::ReadWrite))
{
emit sigCatchException("serialport open failture" + m_pCom->errorString());
qDebug() << "serialport open failture" << m_pCom->errorString();
m_semSetCOM.release();
return ;
}
m_pCom->clear();
m_bOpen = true;
m_semSetCOM.release();
}
void DataSerialPort::slotWrite(const char *pch, qint64 maxSize)
{
//qDebug() << QDateTime::currentDateTime().toString("HH:mm:ss.zzz") << " write begin\n";
m_lockWriteLen.lock();
m_iLen = -1;
if(m_pCom->isOpen())
{
m_iLen = (maxSize < 0) ? m_pCom->write(pch) : m_pCom->write(pch, maxSize);
}
m_lockWriteLen.unlock();
m_semWrite.release();
//qDebug() << QDateTime::currentDateTime().toString("HH:mm:ss.zzz") << " write OK\n";
}
void DataSerialPort::slotClose()
{
//qDebug() << "slotClose:" << QThread::currentThreadId() <<"\n";
m_pCom->close();
m_bOpen = false;
m_semClose.release();
}
void DataSerialPort::slotClear()
{
m_pCom->clear();
m_lockInBuffer.lock();
m_strInBuffer.clear();
m_strReply.clear();
m_lockInBuffer.unlock();
m_semClear.release();
}
void DataSerialPort::slotDataReady()
{
qDebug()<<"slotDataReady thread id = "<<QThread::currentThreadId()<<"==============================";
QSerialPort *const pCom = m_pCom;
if(getEchoFlag())
{
m_strInBuffer.push_back(pCom->readAll());
m_strReply = m_strInBuffer;
setEchoFlag(false);
m_semEcho.release();
}
else
{
emit sigDataReady(pCom->readAll());
}
}