ProtocolParser/app_source/source/serialportmanager.cpp

242 lines
7.0 KiB
C++

#include "serialportmanager.h"
#include <QSerialPortInfo>
#include <QMutex>
SerialPortManager::SerialPortManager(QObject *parent)
: QObject{parent}
{
_zigbee = zigbee_protocol::DLLN3X::instance();
_bus = EventsBus::instance();
ZigBeeParser::instance(); // 让ZigBeeParser在QML引擎中实例化
_event.type("serial_port");
_bus->reg_event(&_event);
closed(true);
opened(false);
handledBymanager(true);
recv_hex(false);
send_hex(false);
send_type(SendType::Blank);
_serial_port_scanner.setInterval(1000);
_serial_port_scanner.start();
connect(&_serial_port_scanner, &QTimer::timeout, this, [=](){
available_ports();
});
connect(this, &SerialPortManager::handledBymanagerChanged, this, [=](){
if (!_handledBymanager && _serial_port.isOpen())
{
_zigbee->init(&_serial_port, _serial_port.baudRate());
connect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
}
else
{
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
}
});
connect(&_event, &Event::triggered, this, [=](QJsonObject data){
write(data["text"].toString());
});
}
SerialPortManager::~SerialPortManager()
{
close();
_bus->unreg_event(&_event);
}
SerialPortManager* SerialPortManager::instance(){
static QMutex mutex;
QMutexLocker locker(&mutex);
static SerialPortManager *singleton = nullptr;
if (!singleton) {
singleton = new SerialPortManager();
}
return singleton;
}
QList<QString> SerialPortManager::available_ports(){
QList<QString> newPortStringList;
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
newPortStringList += info.portName();
if (_available_ports_count != newPortStringList.count())
{
available_ports_count(newPortStringList.count());
emit available_portsChanged(newPortStringList);
}
return newPortStringList;
}
bool SerialPortManager::open(QString port_name, QString baudrate, QString databits,
QString parity, QString stopbits)
{
_serial_port.setPortName(port_name);
if (_serial_port.isOpen())
{
close();
return false;
}
else
{
if (_serial_port.open(QIODevice::ReadWrite))
{
_serial_port.setBaudRate(baudrate.toInt());
switch (databits.toInt())
{
case 5:
_serial_port.setDataBits( QSerialPort::Data5 ); // 设置数据位(数据位为5位)
break;
case 6:
_serial_port.setDataBits( QSerialPort::Data6 ); // 设置数据位(数据位为6位)
break;
case 7:
_serial_port.setDataBits( QSerialPort::Data7 ); // 设置数据位(数据位为7位)
break;
case 8:
_serial_port.setDataBits( QSerialPort::Data8 ); // 设置数据位(数据位为8位)
break;
default:
return false;
}
if (parity=="NONE")
{
_serial_port.setParity( QSerialPort::NoParity ); // 设置校验位(无校验位)
}
else if (parity=="EVEN")
{
_serial_port.setParity( QSerialPort::EvenParity ); // 设置校验位(奇校验位)
}
else
{
_serial_port.setParity( QSerialPort::OddParity ); // 设置校验位(偶校验位)
}
if (stopbits=="1")
{
_serial_port.setStopBits( QSerialPort::OneStop ); // 设置停止位(停止位为1)
}
else if (stopbits=="1.5")
{
_serial_port.setStopBits( QSerialPort::OneAndHalfStop ); // 设置停止位(停止位为1.5)
}
else
{
_serial_port.setStopBits( QSerialPort::TwoStop ); // 设置停止位(停止位为2)
}
_serial_port.setFlowControl( QSerialPort::HardwareControl ); // 设置流控制(硬件数据流控制)
// 当下位机中有数据发送过来时就会响应这个槽函数
connect(&_serial_port,&QSerialPort::readyRead,this,&SerialPortManager::_ready_for_read);
connect(&_serial_port,&QSerialPort::aboutToClose,this,&SerialPortManager::close);
opened(true);
closed(false);
return true;
}
else
return false;
}
}
void SerialPortManager::close()
{
disconnect(&_serial_port,&QSerialPort::aboutToClose,this,&SerialPortManager::close);
disconnect(&_serial_port,&QSerialPort::readyRead,this,&SerialPortManager::_ready_for_read);
disconnect(_zigbee, &zigbee_protocol::DLLN3X::recved, this, &SerialPortManager::zigbee_callback);
if(_opened)
{
_serial_port.clear();
_serial_port.close();
}
readyRead(false);
closed(true);
opened(false);
}
QByteArray SerialPortManager::read()
{
QByteArray bdata;
if (_opened && _handledBymanager)
{
readyRead(false);
bdata = _serial_port.readAll();
if (_recv_hex)
{
return bdata.toHex(' ').toUpper();
}
else
return bdata;
}
else
return bdata;
}
void SerialPortManager::_ready_for_read()
{
if (_handledBymanager)
readyRead(true);
if (!_handledBymanager)
_zigbee->loop();
}
bool SerialPortManager::write(QString data)
{
if (_closed)
return false;
if ( !_handledBymanager)
{
QByteArray bdata;
QStringList td = data.split(' ');
for (auto item : td)
bdata += QByteArray::fromHex(item.toLatin1());
zigbee_protocol::ZigbeeFrame zf(bdata[2],bdata[3],(uint16_t)bdata[4] | bdata[5]<<8, bdata.data()+6,bdata.length()-7);
return _zigbee->send(zf);
}
QByteArray bdata;
if(_send_hex)
{
QStringList td = data.split(' ');
for (auto item : td)
bdata += QByteArray::fromHex(item.toLatin1());
}
else
bdata = data.toUtf8();
switch(_send_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;
}
return _serial_port.write(bdata);
}
void SerialPortManager::zigbee_callback(zigbee_protocol::ZigbeeFrame zframe)
{
QJsonObject object;
QByteArray zf = QByteArray((char *)zframe.data(),zframe.size());
QByteArray hex = zf.toHex(' ');
QByteArray data = hex.toUpper();
readyRead(false);
object.insert("data_hex", QJsonValue(QString(data)));
object.insert("type","zigbee_raw_data");
_bus->push_data("zigbee_parser", object);
}
QSerialPort* SerialPortManager::get_serial()
{
if (!_handledBymanager)
return &_serial_port;
else
return nullptr;
}