/** * 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 "settings.h" namespace TrainingAreaBaseOC { ConnectionHandlerSerial::ConnectionHandlerSerial() : m_spQuerry(new LtsSerialPortQuerry::LtsSerialPortQuerry(this)) , m_receiveTimeoutTimer(new QTimer(this)) , m_logger(getLogger("ConnectionHandlerSerial")) { connect(m_spQuerry, &LtsSerialPortQuerry::LtsSerialPortQuerry::connectionEstablished, this, &ConnectionHandlerSerial::open); m_spQuerry->restartQuerry(); m_receiveTimeoutTimer->setInterval(5000); connect(m_receiveTimeoutTimer, &QTimer::timeout, m_spQuerry, &LtsSerialPortQuerry::LtsSerialPortQuerry::continueQuerry); connect(m_receiveTimeoutTimer, &QTimer::timeout, this, &ConnectionHandlerSerial::disconnectedFromEq); m_receiveTimeoutTimer->start(); } bool ConnectionHandlerSerial::init() { return true; } bool ConnectionHandlerSerial::send(const LtsUtils::SfmMessage &message) { if (!m_serialPort) return false; if (!m_serialPort->isOpen()) { ERROR_LOG(m_logger) << "Port is not opened!"; return false; } QByteArray data = LtsUtils::byteStreamFromSfmMessage(message); DEBUG_LOG(m_logger) << "Sending frame: " << data.toHex(' '); const qint64 byteswritten = m_serialPort->write(data); m_serialPort->flush(); if (byteswritten == -1) { ERROR_LOG(m_logger) << "Failed to write data to port " << m_serialPort->portName() << " error: " << m_serialPort->errorString(); return false; } else if (byteswritten != data.size()) { ERROR_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(); m_currentDataRead.clear(); NOTICE_LOG(m_logger) << "(Re)openend serial port " << m_serialPort->portName() << " baudrate: " << m_serialPort->baudRate(); connect(m_serialPort, &QSerialPort::readyRead, this, &ConnectionHandlerSerial::read); m_receiveTimeoutTimer->start(); return true; } bool ConnectionHandlerSerial::isOpen() const { return m_serialPort && m_serialPort->isOpen(); } void ConnectionHandlerSerial::read() { if (!m_serialPort) return; const QByteArray ba = m_serialPort->readAll(); m_currentDataRead.append(ba); DEBUG_LOG(m_logger) << "Binary data from sfm: " << ba.toHex(' '); 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 { QByteArray message = m_currentDataRead.mid(idxStart, (idxEnd - idxStart) + 1); LtsUtils::SfmMessage sfmMsg; DEBUG_LOG(m_logger) << "Frame from sfm as binary " << message.toHex(); try { sfmMsg = LtsUtils::byteStreamToSfmMessage(message); } catch (const LtsUtils::ConversionError &ex) { ERROR_LOG(m_logger) << "Error converting QByteArray into LtsUtils::SfmMessage: " << ex.what(); ERROR_LOG(m_logger) << "Faulty Data from sfm as binary " << message.toHex(); m_currentDataRead = m_currentDataRead.mid(idxEnd + 1); //we continue but dont restart the timer continue; } INFO_LOG(m_logger) << "Decoded message from sfm Id: " << sfmMsg.id() << " RTR: " << sfmMsg.rtr() << " Data: " << sfmMsg.payload().toHex(); // start new interval m_receiveTimeoutTimer->start(); m_currentDataRead = m_currentDataRead.mid(idxEnd + 1); emit received(sfmMsg); } if (m_serialPort->bytesAvailable() > 0) DEBUG_LOG(m_logger) << "Still " << m_serialPort->bytesAvailable() << " available to be read"; } } // namespace TrainingAreaBaseOC