150 lines
4.8 KiB
C++
150 lines
4.8 KiB
C++
#ifndef DEVICECONNECTION_H
|
||
#define DEVICECONNECTION_H
|
||
|
||
#include "DataStructure.h"
|
||
#include <QFuture>
|
||
#include <QFutureInterface>
|
||
#include <QObject>
|
||
#include <QQmlEngine>
|
||
#include <QTcpSocket>
|
||
#include <queue>
|
||
#include <string_view>
|
||
|
||
class NetworkInfomation;
|
||
|
||
class DeviceConnection : public QObject {
|
||
Q_OBJECT
|
||
QML_ELEMENT
|
||
QML_UNCREATABLE("Only created in C++...")
|
||
|
||
public:
|
||
constexpr static auto WirelessAddress = "192.168.10.2";
|
||
constexpr static auto HeartbeatInterval = std::chrono::milliseconds(2500);
|
||
enum Resolution {
|
||
Video_360P = 0,
|
||
Video_720P,
|
||
};
|
||
enum AreaWay {
|
||
Diabled = 0,
|
||
FullArea,
|
||
Quadrangle, // 四边形
|
||
};
|
||
class Infomation {
|
||
public:
|
||
QString deviceId;
|
||
QString softwareVersion;
|
||
QString firmwareVersion;
|
||
QString ip;
|
||
|
||
int rotation = 0;
|
||
bool flip = false;
|
||
|
||
QList<QPointF> openDoorArea;
|
||
AreaWay openDoorAreaWay;
|
||
|
||
QList<QPointF> shieldedArea;
|
||
bool shieldedAreaEnabled;
|
||
|
||
QList<QPointF> antiClipArea;
|
||
bool antiClipAreaEnabled;
|
||
int antiClipSensitivity = 1;
|
||
};
|
||
Q_ENUM(AreaWay)
|
||
|
||
using H264FrameCallback = std::function<void(const char *data, uint32_t size)>;
|
||
DeviceConnection(QObject *parent = nullptr);
|
||
~DeviceConnection();
|
||
Infomation infomation() const;
|
||
bool isConnected() const;
|
||
void setH264FrameCallback(H264FrameCallback &&callback);
|
||
void connect(const Infomation &infomation);
|
||
|
||
void setLiveStreamEnabled(bool enabled);
|
||
|
||
NetworkInfomation networkInfomation() const;
|
||
|
||
void requestOpenDoorArea();
|
||
QFuture<bool> updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points);
|
||
void requestShieldedArea();
|
||
void updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points);
|
||
void requestAntiClipArea();
|
||
void updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points, int sensitivity);
|
||
void requestResolution(Resolution resolution);
|
||
void requestNetworkInfomation();
|
||
QFuture<bool> updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
|
||
const QString &dns);
|
||
void requestVersion();
|
||
void requestVideoInformation();
|
||
void updateRotation(int rotation);
|
||
void updateFlip(bool flip);
|
||
|
||
/**
|
||
* @brief 对设备升级OTA,主要有几个步骤
|
||
* 1. 对设备发起OTA请求,等待设备回复 1
|
||
* 2. 发送二进制文件至设备 2-98
|
||
* 3. 对设备发起包检查结果,等待设备回复 99
|
||
* 4. 设备会重启,一直尝试连接设置,直至连接成功 100
|
||
*
|
||
* @param file
|
||
*/
|
||
void requestOta(const QString &firmware, const QString &file);
|
||
void requestReset();
|
||
|
||
signals:
|
||
void connected();
|
||
void disconnected();
|
||
void openDoorAreaChanged(AreaWay way, const QList<QPointF> &points);
|
||
void shieldedAreaChanged(bool enabled, const QList<QPointF> &points);
|
||
void antiClipAreaChanged(bool enabled, const QList<QPointF> &points, int sensitivity);
|
||
void rotationChanged(int rotation);
|
||
void flipChanged(bool flip);
|
||
void networkInfomationChanged(const NetworkInfomation &info);
|
||
void firmwareChanged(const QString &firmware);
|
||
void otaProgressChanged(bool status, int progress, const QString &message);
|
||
|
||
protected:
|
||
class Task {
|
||
public:
|
||
QString command;
|
||
std::chrono::system_clock::time_point time = std::chrono::system_clock::now();
|
||
std::function<void()> task;
|
||
std::shared_ptr<QTimer> timeoutTimer = nullptr;
|
||
std::shared_ptr<QFutureInterface<bool>> future;
|
||
};
|
||
void close();
|
||
void onConnected();
|
||
void onDisconnected();
|
||
void onH264ReadyRead();
|
||
void onCommandReadyRead();
|
||
QString handleCommand(const std::string_view &replyText, const Task *task);
|
||
void onErrorOccurred(QAbstractSocket::SocketError socketError);
|
||
void timerEvent(QTimerEvent *event) final;
|
||
void transferBinContent();
|
||
|
||
private:
|
||
Infomation m_infomation;
|
||
QTcpSocket *m_commandSocket = nullptr;
|
||
|
||
QTcpSocket *m_h264Socket = nullptr;
|
||
bool m_videoEnabled = false;
|
||
bool m_receivedFirstJsonReply = false;
|
||
|
||
QByteArray m_commandBuffer;
|
||
QByteArray m_h264Buffer;
|
||
|
||
int m_otaProgress = -1;
|
||
std::vector<uint8_t> m_uploadBuffer;
|
||
int m_sendedSize = 0;
|
||
QTimer *m_otaTimer = nullptr; // 检测OTA超时
|
||
|
||
H264FrameCallback m_frameCallback;
|
||
std::queue<Task> m_requests;
|
||
int m_requestTimerId = -1;
|
||
int m_heartbeatTimerId = -1;
|
||
int heartbeats = 0;
|
||
NetworkInfomation m_networkInfomation;
|
||
QString m_firmware;
|
||
};
|
||
|
||
#endif // DEVICECONNECTION_H
|