/** * Connection Handler for the serial connection to the sfm * $Id$ * $HeadURL$ * $Author$ * Created by Philipp Dassow, NLST, 2018-01-29 */ #include "connection_handler_serial.h" #include #include namespace EffectShowClient { ConnectionHandlerSerial::ConnectionHandlerSerial(QObject *parent) : QObject(parent) , m_spQuerry(new LtsSerialPortQuerry::LtsSerialPortQuerry(this)) , m_serialPort(nullptr) , m_receiveTimeoutTimer(new QTimer(this)) , m_currentDataRead(QByteArray()) , m_portName(QStringLiteral("COM5")) , m_readBuffer(new QByteArray()) , m_logger(getLogger("ConnectionHandlerSerial")) { m_receiveTimeoutTimer->setInterval(1700); connect(m_spQuerry, &LtsSerialPortQuerry::LtsSerialPortQuerry::connectionEstablished, this, &ConnectionHandlerSerial::open); m_spQuerry->restartQuerry(); connect(m_receiveTimeoutTimer, &QTimer::timeout, m_spQuerry, &LtsSerialPortQuerry::LtsSerialPortQuerry::continueQuerry); connect(m_receiveTimeoutTimer, &QTimer::timeout, this, &ConnectionHandlerSerial::disconnectedFromSerialConverter); } ConnectionHandlerSerial::~ConnectionHandlerSerial() { DEBUG_LOG(m_logger) << "ConnectionHandlerSerial::~ConnectionHandlerSerial"; } bool ConnectionHandlerSerial::init() { return true; } bool ConnectionHandlerSerial::send(const QByteArray &binaryData) { // Checking port --------------------------------------------- if (!m_serialPort) { DEBUG_LOG(m_logger) << "Port is not initialized!"; return false; } if (!m_serialPort->isOpen()) { DEBUG_LOG(m_logger) << "Port is not opened!"; return false; } // Sending data --------------------------------------------- const QByteArray writeThis = LtsUtils::byteStreamFromEscMessage(binaryData); DEBUG_LOG(m_logger) << "Send HEX:" << writeThis.toHex(' '); qint64 byteswritten = m_serialPort->write(writeThis); DEBUG_LOG(m_logger) << "Binary data:" << binaryData.size(); DEBUG_LOG(m_logger) << "Try sending: " << writeThis.size(); // Check for errors --------------------------------------------- if (byteswritten == -1) { DEBUG_LOG(m_logger) << "Failed to write data to port " << m_serialPort->portName() << " error: " << m_serialPort->errorString(); return false; } else if (byteswritten != writeThis.size()) { DEBUG_LOG(m_logger) << "Failed to write all data to port " << m_serialPort->portName() << " error: " << m_serialPort->errorString(); return false; } return true; } bool ConnectionHandlerSerial::open() { m_serialPort = m_spQuerry->currentSerialPort(); connect(m_serialPort, &QSerialPort::readyRead, this, &ConnectionHandlerSerial::read); m_currentDataRead.clear(); m_receiveTimeoutTimer->start(); DEBUG_LOG(m_logger) << "(Re)openend serial port " << m_serialPort->portName() << " baudrate: " << m_serialPort->baudRate(); emit connectedToSerialConverter(); return true; } bool ConnectionHandlerSerial::isOpen() const { return m_serialPort->isOpen(); } void ConnectionHandlerSerial::read() { const QByteArray ba = m_serialPort->readAll(); m_currentDataRead.append(ba); //DEBUG_LOG(m_logger) << "Binary data from sfm: " << ba.toHex(' '); DEBUG_LOG(m_logger) << "Data size" << ba.size(); int idxStart = -1; int idxEnd = -1; while ((idxStart = m_currentDataRead.indexOf(0x02)) >= 0 && (idxEnd = m_currentDataRead.indexOf(0x03)) >= 0) // while complete message frame in buffer { //whatever happens: remove current frame from data //m_currentDataRead = m_currentDataRead.mid(idxEnd+1); QByteArray message = m_currentDataRead.mid(idxStart, (idxEnd - idxStart) + 1); m_currentDataRead = m_currentDataRead.mid(idxEnd + 1); DEBUG_LOG(m_logger) << "Data Message found: " << message.toHex(' '); message = LtsUtils::byteStreamToEscMessage(message); if (message.size() > 2) { ERROR_LOG(m_logger) << "Message to long: " << message.size(); continue; } DEBUG_LOG(m_logger) << "Frame from sfm as binary " << message.toHex(); //got message now remove frame unsigned int byte = 0; byte = message.at(0) & 0xFF; DEBUG_LOG(m_logger) << "ConnectionHandlerSerial::read var byte is" << byte; if (!isValidCommandByte(byte)) { ERROR_LOG(m_logger) << "ConnectionHandlerSerial::read Commandbyte is invalid. Returning"; return; } // If first byte is not between 43 and 91, then we need the second byte, because all other commands have payload. Just not this single piece of if (byte < 43 || byte > 91) { if (message.size() > 1 && !isValidPayloadByte(message.at(1))) { ERROR_LOG(m_logger) << "ConnectionHandlerSerial::read Payloadbyte is invalid. Returning"; continue; } } if (message.size() != 2) { ERROR_LOG(m_logger) << "ConnectionHandlerSerial::read No 2nd byte was appended (QByteArray has bad size). Returning."; continue; } DEBUG_LOG(m_logger) << "Binary data from serial port: " << message.toHex(' '); m_receiveTimeoutTimer->start(); emit received(message); } if (m_serialPort->bytesAvailable() > 0) DEBUG_LOG(m_logger) << "Still " << m_serialPort->bytesAvailable() << " available to be read"; } bool ConnectionHandlerSerial::isValidCommandByte(const unsigned char command) { DEBUG_LOG(m_logger) << "ConnectionHandlerSerial::isValidCommandByte" << command << (command == 192 || command == 240 || command == 244 || command == 255 || command == 144 || command == 202 || command == 224 || command == 213 || command == 15 || command == 42 || (command >= 43 && command <= 91)); return (command == 192 || command == 240 || command == 244 || command == 255 || command == 144 || command == 202 || command == 224 || command == 213 || command == 15 || command == 42 || (command >= 43 && command <= 91)); } bool ConnectionHandlerSerial::isValidPayloadByte(const unsigned char payload) { Q_UNUSED(payload); return true; } }