#ifndef DEVICECONNECTION_H #define DEVICECONNECTION_H #include "DataStructure.h" #include #include #include #include #include #include #include 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 openDoorArea; AreaWay openDoorAreaWay; QList shieldedArea; bool shieldedAreaEnabled; QList antiClipArea; bool antiClipAreaEnabled; }; Q_ENUM(AreaWay) using H264FrameCallback = std::function; 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 updateOpenDoorAreaPoints(AreaWay way, const QList &points); void requestShieldedArea(); void updateShieldedAreaPoints(bool enabled, const QList &points); void requestAntiClipArea(); void updateAntiClipAreaPoints(bool enabled, const QList &points); void requestResolution(Resolution resolution); void requestNetworkInfomation(); QFuture 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); signals: void connected(); void disconnected(); void openDoorAreaChanged(AreaWay way, const QList &points); void shieldedAreaChanged(bool enabled, const QList &points); void antiClipAreaChanged(bool enabled, const QList &points); 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 task; std::shared_ptr timeoutTimer = nullptr; std::shared_ptr> 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 m_uploadBuffer; int m_sendedSize = 0; QTimer *m_otaTimer = nullptr; // 检测OTA超时 H264FrameCallback m_frameCallback; std::queue m_requests; int m_requestTimerId = -1; int m_heartbeatTimerId = -1; int heartbeats = 0; NetworkInfomation m_networkInfomation; QString m_firmware; }; #endif // DEVICECONNECTION_H