ProtocolParser/app_source/source/serialdataresolver.cpp

250 lines
7.1 KiB
C++

#include "serialdataresolver.h"
#include "protocol.h"
#include <QThread>
SerialDataResolver::SerialDataResolver(QObject *parent)
: QObject{parent}
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
_serial = new QSerialPort(this);
_zigbee = zigbee_protocol::DLLN3X::instance();
recv_hex(false);
handled_by_manager(true);
connect(this, &SerialDataResolver::handled_by_managerChanged, this, [=](){
if (!_handled_by_manager && _serial->isOpen())
{
_zigbee->init(_serial, _serial->baudRate());
zigbee_protocol::Protocol::getInstance()->self_addr = _zigbee->read_addr();
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback,
Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection));
}
else
{
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
}
});
}
SerialDataResolver::~SerialDataResolver()
{
close();
delete _serial;
}
SerialDataResolver* SerialDataResolver::instance()
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
static QMutex mutex;
QMutexLocker locker(&mutex);
static SerialDataResolver *singleton = nullptr;
if (!singleton) {
singleton = new SerialDataResolver();
}
return singleton;
}
void SerialDataResolver::open(QString port_name, QString baudrate, QString databits,
QString parity, QString stopbits)
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
QMutex mutex;
const QMutexLocker locker(&mutex);
_serial->setPortName(port_name);
if (!_serial->open(QIODevice::ReadWrite))
{
emit error(tr("串口%1打开失败, 错误代码:%2")
.arg(port_name).arg(_serial->error()));
return;
}
else
{
serial_opened(true);
_serial->setBaudRate(baudrate.toInt());
switch (databits.toInt())
{
case 5:
_serial->setDataBits( QSerialPort::Data5 ); // 设置数据位(数据位为5位)
break;
case 6:
_serial->setDataBits( QSerialPort::Data6 ); // 设置数据位(数据位为6位)
break;
case 7:
_serial->setDataBits( QSerialPort::Data7 ); // 设置数据位(数据位为7位)
break;
case 8:
_serial->setDataBits( QSerialPort::Data8 ); // 设置数据位(数据位为8位)
break;
default:
break;
}
if (parity=="NONE")
{
_serial->setParity( QSerialPort::NoParity ); // 设置校验位(无校验位)
}
else if (parity=="EVEN")
{
_serial->setParity( QSerialPort::EvenParity ); // 设置校验位(奇校验位)
}
else
{
_serial->setParity( QSerialPort::OddParity ); // 设置校验位(偶校验位)
}
if (stopbits=="1")
{
_serial->setStopBits( QSerialPort::OneStop ); // 设置停止位(停止位为1)
}
else if (stopbits=="1.5")
{
_serial->setStopBits( QSerialPort::OneAndHalfStop ); // 设置停止位(停止位为1.5)
}
else
{
_serial->setStopBits( QSerialPort::TwoStop ); // 设置停止位(停止位为2)
}
_serial->setFlowControl( QSerialPort::NoFlowControl ); // 设置流控制(无数据流控制)
connect(_serial,&QSerialPort::aboutToClose, this, &SerialDataResolver::close);
connect(_serial,&QSerialPort::readyRead, this, &SerialDataResolver::readHandler);
if (!_handled_by_manager)
{
_zigbee->init(_serial, _serial->baudRate());
zigbee_protocol::Protocol::getInstance()->self_addr = _zigbee->read_addr();
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback,
Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection));
}
}
}
bool SerialDataResolver::handled_by_manager()
{
return _handled_by_manager;
}
void SerialDataResolver::handled_by_manager(bool handled_by_manager)
{
QMutex mutex;
const QMutexLocker locker(&mutex);
_handled_by_manager = handled_by_manager;
emit handled_by_managerChanged();
}
bool SerialDataResolver::recv_hex()
{
return _recv_hex;
}
void SerialDataResolver::recv_hex(bool recv_hex)
{
QMutex mutex;
const QMutexLocker locker(&mutex);
_recv_hex = recv_hex;
emit recv_hexChanged();
}
bool SerialDataResolver::serial_opened()
{
return _serial_opened;
}
void SerialDataResolver::serial_opened(bool serial_opened)
{
QMutex mutex;
const QMutexLocker locker(&mutex);
_serial_opened = serial_opened;
emit serial_openedChanged();
}
void SerialDataResolver::readHandler()
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
if (_handled_by_manager)
{
QByteArray bdata;
if (_serial->isOpen() && _handled_by_manager)
{
while(true){
bdata += _serial->readAll();
if (!_serial->waitForReadyRead(20))
break;
}
if (_recv_hex)
{
emit recved(bdata.toHex(' ').toUpper());
}
else
emit recved(bdata);
}
else
emit recved(bdata);
}
else
_zigbee->loop();
}
void SerialDataResolver::close()
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
serial_opened(false);
disconnect(_serial,&QSerialPort::aboutToClose,this,&SerialDataResolver::close);
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialDataResolver::zigbee_callback);
if(_serial->isOpen())
{
_serial->clear();
_serial->close();
}
}
void SerialDataResolver::write_data(QString data, SendType type, bool send_hex)
{
//qDebug()<<__FUNCTION__<<"Thread: "<<QThread::currentThread();
QByteArray bdata;
if (!_serial->isOpen())
return;
if (!_handled_by_manager)
{
QStringList td = data.split(' ');
for (auto item : td)
bdata += QByteArray::fromHex(item.toLatin1());
zigbee_protocol::ZigbeeFrame zf;
zf.load_package((uint8_t*)bdata.data(),bdata.length());
_zigbee->send(zf);
return;
}
if(send_hex)
{
QStringList td = data.split(' ');
for (auto item : td)
bdata += QByteArray::fromHex(item.toLatin1());
}
else
bdata = data.toUtf8();
switch(type)
{
case SendType::WithCarriageEnter:
bdata += "\n";
break;
case SendType::WithLineFeed:
bdata += "\r";
break;
case SendType::WithCarriageEnterAndLineFeed:
bdata += "\r\n";
break;
case SendType::Blank:
default:
break;
}
_serial->write(bdata);
_serial->flush();
return;
}
void SerialDataResolver::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
{
emit recved_zframe(zframe);
}