Commit cfe3c253 authored by Isabella Skořepová's avatar Isabella Skořepová
Browse files

Merge commit 'f9843206' as 'dserial-server'

parents 17f04030 f9843206
# DSerial-Server
Server implementation of dserial D-Bus protocol.
## Building
This repository is ment to be built from dserial-project repo.
If you want to build it separately you have to have dserial-protocol in same directory as this one
and run following commands.
qmake
make
## Installing
Again, this is ment to be built and installed from dserial-project repo.
make install
## Running
Nothing here - it should be dbus activated
#include "controller.h"
#include <QDebug>
#include <QSerialPortInfo>
Controller::Controller(QObject *parent) : QObject(parent), connection(QDBusConnection::sessionBus())
{
Autodetect();
}
QStringList Controller::PortList() const
{
qDebug() << "PortList";
QStringList pl;
for(Port *port : ports) {
qDebug() << port->Name();
pl.append(port->Name());
}
qDebug() << pl;
return pl;
}
void Controller::CreateFakePort(QString)
{
qDebug() << "CreateFakePort not implemented";
}
void Controller::CreateFilePort(QString)
{
qDebug() << "CreateFilePort not implemented";
}
void Controller::Autodetect()
{
qDebug() << "Autodetect";
// Remove nonexistent
for(Port *port : ports) {
port->Exists();
}
// Detect new
for(QSerialPortInfo info: QSerialPortInfo::availablePorts()) {
qDebug() << info.portName();
bool isInList = false;
for(Port *port : ports) {
qDebug() << port->Name();
if(info.portName() == port->Name()) {
isInList = true;
break;
}
}
if(!isInList) {
Port *port = new Port(info.systemLocation());
new PortAdaptor(port);
port->dbusPath.setPath("/autodetected"+info.systemLocation());
connection.registerObject(port->dbusPath.path(), port);
connect(port,SIGNAL(removeMe(QDBusObjectPath)),
this,SLOT(removePort(QDBusObjectPath)));
ports.append(port);
}
}
qDebug() << "Autodetect done";
}
QDBusObjectPath Controller::GetPath(QString name)
{
for(Port *port : ports) {
if(port->Name() == name) return port->dbusPath;
}
return QDBusObjectPath("/");
}
void Controller::removePort(QDBusObjectPath id)
{
for(int i = 0; i < ports.length(); i++) {
if(ports.at(i)->dbusPath == id) {
connection.unregisterObject(ports.at(i)->dbusPath.path());
ports.at(i)->deleteLater();
ports.remove(i);
return;
}
}
}
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QObject>
#include <QDBusObjectPath>
#include <QtDBus>
#include "port.h"
#include "port_adaptor.h"
class Controller : public QObject
{
Q_OBJECT
QVector<Port*> ports;
public:
explicit Controller(QObject *parent = 0);
Q_PROPERTY(QStringList PortList READ PortList NOTIFY PortListChanged)
QStringList PortList() const;
public slots:
void CreateFakePort(QString);
void CreateFilePort(QString);
void Autodetect();
QDBusObjectPath GetPath(QString name);
signals:
void PortListChanged(QList<QDBusObjectPath> PortList);
private slots:
void removePort(QDBusObjectPath id);
public:
QDBusConnection connection;
};
#endif // CONTROLLER_H
#-------------------------------------------------
#
# Project created by QtCreator 2015-08-16T17:19:07
#
#-------------------------------------------------
QT += core dbus serialport
QT -= gui
TARGET = dserial-server
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
DBUS_ADAPTORS += ../dserial-protocol/port.xml ../dserial-protocol/controller.xml
SOURCES += main.cpp \
port.cpp \
controller.cpp
HEADERS += \
port.h \
controller.h
documentation.path = .
unix:target.path = /usr/local/bin
service.path = /usr/share/dbus-1/services/
service.files = info.skorepa.DSerial1.service
INSTALLS += documentation target service
CONFIG += c++14
[D-BUS Service]
Name=info.skorepa.DSerial1
Exec=/usr/local/bin/dserial-server
#include <QCoreApplication>
#include <QTime>
#include <iostream>
#include <QLoggingCategory>
#include "controller.h"
#include "controller_adaptor.h"
void msgHandler( QtMsgType type, const QMessageLogContext& context, const QString& msg )
{
QString symbols[] = { "Debug", "Warning", "Critical", "Fatal" };
QString output = QString("%4 [%1,%3] %2\n").arg( symbols[type] ).arg( msg ).arg(context.category).arg(QTime::currentTime().toString("hh:mm:ss.zzz"));
std::cout << output.toStdString();
std::cout.flush();
if( type == QtFatalMsg ) abort();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qInstallMessageHandler(msgHandler);
QLoggingCategory::setFilterRules("*default=true\n"
"qml=true\n"
"qt.widgets.gestures=false\n"
"qt.quick.*=false\n"
"fc.io.debug=false\n"
"qt.qpa.input=false");
Controller *controller = new Controller();
new ControllerAdaptor(controller);
controller->connection.registerObject("/controller", controller);
controller->connection.registerService("info.skorepa.DSerial1");
return a.exec();
}
#include "port.h"
#include <QDebug>
#include <QMetaObject>
#include <QMetaEnum>
#include <QSerialPortInfo>
Port::Port(QString name, QObject *parent) : QObject(parent), closeTimer(), autoCloseTimer(), readTimer(), serialPort(name)
{
closeTimer.setInterval(5000);
closeTimer.setSingleShot(true);
connect(&closeTimer,&QTimer::timeout,
this, &Port::doClose);
autoCloseTimer.setInterval(120'000);
autoCloseTimer.setSingleShot(true);
connect(&autoCloseTimer,&QTimer::timeout,
this, &Port::Close);
readTimer.setInterval(16);
connect(&readTimer, &QTimer::timeout,
this, &Port::read);
}
/****
* GETTERS
****/
QString Port::Name() const
{
if(!Exists()) return QString("REMOVED");
return serialPort.portName();
}
qint32 Port::Baudrate() const
{
if(!Exists()) return 0;
return serialPort.baudRate();
}
quint8 Port::DataBits() const
{
if(!Exists()) return 0;
return serialPort.dataBits();
}
quint8 Port::StopBits() const
{
if(!Exists()) return 0;
return serialPort.stopBits();
}
quint8 Port::Parity() const
{
if(!Exists()) return 0;
quint8 par = serialPort.parity();
if(par == 0) return 1;
else return par;
}
quint8 Port::Type() const
{
Exists();
return 0;
}
quint8 Port::FlowControl() const
{
if(!Exists()) return 0;
return serialPort.flowControl()+1;
}
/******
* METHODS
******/
void Port::Write(QByteArray data)
{
if(!Exists()) return;
QString debugWrite = "Trying to write";
for(int i = 0; i < data.size(); i++) {
debugWrite.append(" ");
quint8 byte = quint8(data.at(i));
debugWrite.append(QString::number(byte, 16));
}
qDebug().nospace().noquote() << debugWrite;
if(!serialPort.isOpen()) {
if(serialPort.open(QSerialPort::WriteOnly)) {
qDebug() << " Autoopened port";
qDebug() << " Wrote" << serialPort.write(data) << "bytes";
serialPort.flush();
serialPort.close();
qDebug() << " Port was closed";
} else {
qDebug().nospace().noquote() << " Port autoopen failed (" << errorString() << ") - no data written";
}
} else {
qDebug() << " Wrote" << serialPort.write(data) << "bytes";
}
emit DataSent(data);
}
void Port::FakeReception(QByteArray data)
{
if(!Exists()) return;
qDebug() << "Faking reception of" << data;
emit DataRecieved(data);
}
void Port::Open()
{
if(!Exists()) return;
readTimer.start();
if(closeTimer.isActive()) qDebug() << "Closing was cancelled by call to open";
closeTimer.stop();
autoCloseTimer.start();
if(!serialPort.isOpen()) {
if(serialPort.open(QSerialPort::ReadWrite))
qDebug() << "Port successfully opened";
else
qDebug() << "Port open failed -" << errorString();
}
}
void Port::Close()
{
if(!Exists()) return;
qDebug() << "Closing port in 5 seconds";
autoCloseTimer.stop();
closeTimer.start();
emit Closing();
}
bool Port::Exists() const
{
for(QSerialPortInfo info: QSerialPortInfo::availablePorts()) {
if(info.portName() == serialPort.portName()) return true;
}
qDebug() << "Port does not exist";
emit Disappeared();
emit removeMe(dbusPath);
return false;
}
/*******
* SETTERS
*******/
void Port::setFlowControl(quint8 flow_control)
{
if(!Exists()) return;
if(flow_control == serialPort.flowControl()) return;
if(flow_control >= 1 && flow_control <= 3) {
if(serialPort.setFlowControl(QSerialPort::FlowControl(flow_control-1))) {
qDebug() << "Setting flow control to" << flow_control << "succeeded";
emit flowControlChanged(flow_control);
} else {
qDebug() << "Setting flow control to" << flow_control << "failed - error" << errorString();
}
} else {
qDebug() << "Setting flow control to" << flow_control << "failed - invalid value";
}
}
void Port::setBaudrate(qint32 baudrate)
{
if(!Exists()) return;
if(baudrate == serialPort.baudRate()) return;
if(baudrate > 0) {
if(serialPort.setBaudRate(baudrate)) {
qDebug() << "Setting baudrate to" << baudrate << "succeeded";
emit baudrateChanged(baudrate);
} else {
qDebug() << "Setting baudrate to" << baudrate << "failed - error" << errorString();
}
} else {
qDebug() << "Setting baudrate to" << baudrate << "failed - invalid value";
}
}
void Port::setDataBits(quint8 dataBits)
{
if(!Exists()) return;
if(dataBits == serialPort.dataBits()) return;
if(dataBits >= 5 && dataBits <= 8) {
if(serialPort.setDataBits(QSerialPort::DataBits(dataBits))) {
qDebug() << "Setting data bits to" << dataBits << "succeeded";
emit dataBitsChanged(dataBits);
} else {
qDebug() << "Setting data bits to" << dataBits << "failed - error" << errorString();
}
} else {
qDebug() << "Setting data bits to" << dataBits << "failed - invalid value";
}
}
void Port::setStopBits(quint8 stopBits)
{
if(!Exists()) return;
if(stopBits == serialPort.stopBits()) return;
if(stopBits >= 1 && stopBits <= 2) {
if(serialPort.setStopBits(QSerialPort::StopBits(stopBits))) {
qDebug() << "Setting stop bits to" << stopBits << "succeeded";
emit stopBitsChanged(stopBits);
} else {
qDebug() << "Setting stop bits to" << stopBits << "failed - error" << errorString();
}
} else {
qDebug() << "Setting stop bits to" << stopBits << "failed - invalid value";
}
}
void Port::setParity(quint8 parity)
{
if(!Exists()) return;
if(parity == serialPort.parity()) return;
if(parity == 1) parity = 0;
if(parity <= 5) {
if(serialPort.setParity(QSerialPort::Parity(parity))) {
qDebug() << "Setting parity to" << parity << "succeeded";
emit parityChanged(parity);
} else {
qDebug() << "Setting parity to" << parity << "failed - error" << errorString();
}
} else {
qDebug() << "Setting parity to" << parity << "failed - invalid value";
}
}
/*****
* PRIVATE SLOTS
*****/
void Port::doClose()
{
if(!Exists()) return;
closeTimer.stop();
qDebug() << "Closing";
serialPort.close();
readTimer.stop();
}
QString Port::errorString()
{
const QMetaObject *mo = serialPort.metaObject();
int enum_index = mo->indexOfEnumerator("SerialPortError");
QMetaEnum metaEnum = mo->enumerator(enum_index);
return metaEnum.valueToKey(serialPort.error());
}
void Port::read()
{
if(serialPort.isOpen()) {
QByteArray data = serialPort.readAll();
if(data.size() > 0) {
emit DataRecieved(data);
}
} else {
readTimer.stop();
}
}
#ifndef PORT_H
#define PORT_H
#include <QObject>
#include <QVector>
#include <QTimer>
#include <QSerialPort>
#include <QDBusObjectPath>
class Port : public QObject
{
Q_OBJECT
public: // Interface from rest of program
explicit Port(QString name ,QObject *parent = 0);
QDBusObjectPath dbusPath;
signals:
void removeMe(QDBusObjectPath) const;
public slots: // METHODS
void Write(QByteArray data);
void FakeReception(QByteArray data);
void Open();
void Close();
bool Exists() const;
signals: // SIGNALS
void DataRecieved(QByteArray data);
void Closing();
void DataSent(QByteArray data);
void Disappeared() const;
public: // PROPERTIES
Q_PROPERTY(QString Name READ Name)
Q_PROPERTY(qint32 Baudrate READ Baudrate WRITE setBaudrate NOTIFY baudrateChanged)
Q_PROPERTY(quint8 DataBits READ DataBits WRITE setDataBits NOTIFY dataBitsChanged)
Q_PROPERTY(quint8 StopBits READ StopBits WRITE setStopBits NOTIFY stopBitsChanged)
Q_PROPERTY(quint8 Parity READ Parity WRITE setParity NOTIFY parityChanged)
Q_PROPERTY(quint8 Type READ Type)
Q_PROPERTY(quint8 FlowControl READ FlowControl WRITE setFlowControl NOTIFY flowControlChanged)
public slots: // PROPERTY setters
void setBaudrate(qint32 Baudrate);
void setDataBits(quint8 DataBits);
void setStopBits(quint8 StopBits);
void setParity(quint8 Parity);
void setFlowControl(quint8 FlowControl);
public: // PROPERTY getters
QString Name() const;
qint32 Baudrate() const;
quint8 DataBits() const;
quint8 StopBits() const;
quint8 Parity() const;
quint8 Type() const;
quint8 FlowControl() const;
signals: // PROPERTY notifiers
void baudrateChanged(qint32 Baudrate);
void dataBitsChanged(quint8 DataBits);
void stopBitsChanged(quint8 StopBits);
void parityChanged(quint8 Parity);
void flowControlChanged(quint8 FlowControl);
private slots:
void doClose();
QString errorString();
void read();
private:
QTimer closeTimer;
QTimer autoCloseTimer;
QTimer readTimer;
QSerialPort serialPort;
};
#endif // PORT_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment