85 lines
3.3 KiB
C++
85 lines
3.3 KiB
C++
// controllerlink.h - one controller for a GUI application: a RemoteClient in its own thread,
|
|
// the results as Qt signals (delivered in the thread of the ControllerLink object, normally
|
|
// the GUI thread). One ControllerLink per serial port.
|
|
//
|
|
// After open() the link detects the controller (PING, then ID), polls the keyboard leds
|
|
// (LEDS, 5 times a second) and executes the command lines given to send() one after the
|
|
// other (stop-and-wait). Link state:
|
|
// Closed - the port is closed
|
|
// NoLink - the port is open, the controller does not answer (detection repeated every 2 s)
|
|
// Link - connected
|
|
// 3 requests in a row without an answer = link lost: lost(), state NoLink, detection again.
|
|
// When the port fails (e.g. the USB adapter was unplugged) the link closes: error(), closed().
|
|
//
|
|
// Example
|
|
// auto *link = new AdvCtrl::ControllerLink(this);
|
|
// connect(link, &AdvCtrl::ControllerLink::stateChanged, this, &MyWidget::showLinkState);
|
|
// connect(link, &AdvCtrl::ControllerLink::reply, this,
|
|
// [](const QString &command, const QString &result) { qDebug() << command << result; });
|
|
// link->open("/dev/ttyUSB0");
|
|
// link->send("CAM 2");
|
|
// link->send("BR 12");
|
|
|
|
#ifndef ADVCTRL_CONTROLLERLINK_H
|
|
#define ADVCTRL_CONTROLLERLINK_H
|
|
|
|
#include "remoteclient.h"
|
|
|
|
#include <QObject>
|
|
#include <QString>
|
|
|
|
namespace AdvCtrl {
|
|
|
|
class LinkThread;
|
|
|
|
class ControllerLink : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum State { Closed, NoLink, Link };
|
|
Q_ENUM(State)
|
|
|
|
static constexpr int LedsPeriodMs = 200; // LEDS polling
|
|
static constexpr int DetectRetryMs = 2000; // detection retry while not detected
|
|
static constexpr int LostAfter = 3; // requests in a row without an answer -> link lost
|
|
|
|
explicit ControllerLink(QObject *parent = nullptr);
|
|
~ControllerLink() override; // stops the thread and closes the port
|
|
|
|
State state() const;
|
|
QString portName() const; // port of the running link, "" when closed
|
|
|
|
public slots:
|
|
void open(const QString &portName, int baudRate = RemoteClient::DefaultBaudRate);
|
|
void close(); // closed() follows when the port is released
|
|
void send(const QString &commandLine); // the result comes as reply(commandLine, result)
|
|
|
|
signals:
|
|
void stateChanged(AdvCtrl::ControllerLink::State state);
|
|
void detected(const QString &firmware, const QString &cameras, const QString &uid);
|
|
void notDetected(); // a detection attempt failed (retried every 2 s)
|
|
void lost(); // 3 requests in a row without an answer
|
|
void leds(quint32 mask); // keyboard leds, bit order = RemoteClient::LedNames
|
|
// result: "OK[ data]", "ERR <code> <text>" or "!! <why there is no reply>"
|
|
void reply(const QString &commandLine, const QString &result);
|
|
void error(const QString &message);
|
|
void closed();
|
|
|
|
private:
|
|
friend class LinkThread;
|
|
|
|
void setState(State state);
|
|
void handleDetected(const QString &firmware, const QString &cameras, const QString &uid);
|
|
void handleNotDetected();
|
|
void handleLost();
|
|
void handleClosed();
|
|
|
|
LinkThread *m_thread = nullptr;
|
|
State m_state = Closed;
|
|
QString m_portName;
|
|
};
|
|
|
|
} // namespace AdvCtrl
|
|
|
|
#endif // ADVCTRL_CONTROLLERLINK_H
|