OTA升级

#ifndef OTAUPDATE_H
#define OTAUPDATE_H

#include <QObject>
#include <QVariantMap>
#include <QCryptographicHash>
#include <QTimer>
#ifdef IS_REPORT_SPEED
#include <QElapsedTimer>
#endif

class OtaUpdate : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool upgrade READ upgrade WRITE setUpgrade NOTIFY upgradeChanged)
    Q_PROPERTY(int downloadPrg READ downloadPrg WRITE setDownloadPrg NOTIFY downloadPrgChanged)
    Q_PROPERTY(int status READ status WRITE setStatus NOTIFY statusChanged)
    Q_PROPERTY(QString speed READ speed WRITE setSpeed NOTIFY speedChanged)
    Q_PROPERTY(QString fileSize READ fileSize WRITE setFileSize NOTIFY fileSizeChanged)
    Q_PROPERTY(QString remainTime READ remainTime WRITE setRemainTime NOTIFY remainTimeChanged)
    Q_PROPERTY(int upgradePrg READ upgradePrg WRITE setUpgradePrg NOTIFY upgradePrgChanged)
    Q_PROPERTY(bool speedDisp READ speedDisp CONSTANT)
public:
    enum OtaType {
        FullPack = 1,
        AppFile,
        McuFile
    };

    enum UpgradeProgress {
        McuPermissionPrg = 2,
        McuMsgNotifyPrg = 10,
        McuDataSendPrg = 90,
        McuUpgradeResultPrg = 92,
        AppUpgradePrg = 94,
        FileSystemUpgradePrg = 98,
        UpgradeFinishPrg = 100
    };

    enum OtaStatus {
        Ready = 0,
        Downloading,
        DownloadFailed,
        Md5CheckFailed,
        DownloadFinish,
        Uncompressing,
        UncompressFailed,
        Updating,
        ForbidUpdate,
        UpdateFailed,
        UpdateFailedByLen,
        UpdateFailedByCheck,
        UpdateJsonNotExist,
        UpdateFinish,
        UpdateFinishRestart
    };

    Q_ENUM(OtaStatus)

    explicit OtaUpdate(QObject *parent = nullptr);

    static OtaUpdate* getInstance();

    bool upgrade() const;
    void setUpgrade(bool upgrade);

    int downloadPrg() const;
    void setDownloadPrg(int);

    int upgradePrg() const;
    void setUpgradePrg(int);

    int status() const;
    void setStatus(int);

    QString speed() const;
    void setSpeed(QString);

    QString fileSize() const;
    void setFileSize(QString);

    QString remainTime() const;
    void setRemainTime(QString);

    bool speedDisp() const;

    Q_INVOKABLE void startUpgrade();
    Q_INVOKABLE int getUpgradeVersion();
signals:
    void upgradeChanged(bool);
    void downloadPrgChanged(int);
    void statusChanged(int);
    void speedChanged(QString);
    void fileSizeChanged(QString);
    void remainTimeChanged(QString);
    void upgradePrgChanged(int);
public slots:
    // t-smart下发升级信息
    void downloadUpgradePack(QVariantMap vMap);
    // 下载文件
    void writeFile();
    // 下载文件结束
    void downloadFinished();

    void upgradeFlag(QVariantMap &vMap);
    void updatingFlag(QVariantMap &vMap);
    void upgradeResultFlag(QVariantMap &vMap);
    void otaPermissionFlag(QVariantMap &vMap);
private:
    QString getFileName(int type);
    void startDownload();
    void startUpdate();
    void uncompressUpgradeFile();
    void rebootOpe();
    bool parseUpgradeJson();
    void startMcuUpgrade();
    void startAppUpgrade();
    void startFileSystemUpgrade();
private:
    bool m_isHasUpgrade{false};     //  当前是否有升级
    int m_downloadPrg{0};           // 下载进度
    int m_upgradePrg{0};            // 升级进度
    int m_status{Ready};      // 升级状态
    QString m_speed;                // 下载速度
    QString m_fileSizeStr;          // 下载文件显示字符串
    QString m_remainTime;           // 剩余时间
    quint64 m_fileSize{0};          // 已接收文件大小
    QList<QVariantMap> m_otaList;   // 待升级列表
    QCryptographicHash m_cryHash{QCryptographicHash::Md5};
#ifdef IS_REPORT_SPEED
    QElapsedTimer m_elapsedTimer;   // 用于计算下载速度、剩余时间
#endif
    quint64 m_totalFileSize{0};     // 升级文件总大小
    QVariantMap m_currOtaMap;       // 当前升级版本信息
    QByteArray m_mcuByte;           // mcu文件大小
    QTimer m_timeoutTimer;          // 下载/升级过程中超时定时器
};

#endif // OTAUPDATE_H
#include "otaupdate.h"
#include "t_smartwrapper.h"
#include "globalsetting.h"
#include "cloudcomm.h"
#include <QNetworkReply>
#include <QFile>
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QtMath>
#include "serialportdataparse.h"
#include "crc32.h"

enum UpdateType {
    NoType = 0,
    McuType = 0x01,
    AppType = 0x02,
    FileSystemType = 0x04
};

#define MCU_VERIFY_HEAD_LEN 64              // MCU升级头文件封装长度
#define MCU_UPGRADE_FRAME_DATE_LEN 512      // MCU升级帧数据长度
static int updateType = NoType;             // 是否重启系统

OtaUpdate::OtaUpdate(QObject *parent)
    : QObject{parent}
{
    m_otaList.clear();
    m_timeoutTimer.setInterval(3*60*1000);
    connect(&m_timeoutTimer, &QTimer::timeout, this, [this](){
        if (m_status == Downloading) {
            setStatus(DownloadFailed);
        } else if (m_status == Updating) {
            setStatus(UpdateFailed);
        }

        m_timeoutTimer.stop();
    });

    // 下载进度变化重启超时定时器
    connect(this, &OtaUpdate::downloadPrgChanged, this, [this](){
        m_timeoutTimer.start();
    });

    // 升级进度变化重启超时定时器
    connect(this, &OtaUpdate::upgradePrgChanged, this, [this](){
        m_timeoutTimer.start();
    });

    connect(T_SmartWrapper::getInstance(), &T_SmartWrapper::otaUpgradeUrl, this, &OtaUpdate::downloadUpgradePack);
    connect(SerialPortDataParse::getInstance(), &SerialPortDataParse::sig_parseCmd0xA3Frame, this, &OtaUpdate::upgradeFlag);
    connect(SerialPortDataParse::getInstance(), &SerialPortDataParse::sig_parseCmd0xA4Frame, this, &OtaUpdate::updatingFlag);
    connect(SerialPortDataParse::getInstance(), &SerialPortDataParse::sig_parseCmd0xA5Frame, this, &OtaUpdate::upgradeResultFlag);
    connect(SerialPortDataParse::getInstance(), &SerialPortDataParse::sig_parseCmd0xA0Frame, this, &OtaUpdate::otaPermissionFlag);
}

OtaUpdate *OtaUpdate::getInstance()
{
    static OtaUpdate instance;
    return &instance;
}

bool OtaUpdate::upgrade() const
{
    return m_isHasUpgrade;
}

void OtaUpdate::setUpgrade(bool upgrade)
{
    m_isHasUpgrade = upgrade;
    emit upgradeChanged(upgrade);
}

int OtaUpdate::downloadPrg() const
{
    return m_downloadPrg;
}

void OtaUpdate::setDownloadPrg(int progress)
{
    m_downloadPrg = progress;
    emit downloadPrgChanged(progress);
}

int OtaUpdate::upgradePrg() const
{
    return m_upgradePrg;
}

void OtaUpdate::setUpgradePrg(int upgradePrg)
{
    m_upgradePrg = upgradePrg;
    emit upgradePrgChanged(upgradePrg);
}

int OtaUpdate::status() const
{
    return m_status;
}

void OtaUpdate::setStatus(int status)
{
    if (m_status != status) {
        m_status = status;
        emit statusChanged(status);
    }
}

QString OtaUpdate::speed() const
{
    return m_speed;
}

void OtaUpdate::setSpeed(QString speed)
{
    m_speed = speed;
    emit speedChanged(speed);
}

QString OtaUpdate::fileSize() const
{
    return m_fileSizeStr;
}

void OtaUpdate::setFileSize(QString fileSize)
{
    m_fileSizeStr = fileSize;
    emit fileSizeChanged(fileSize);
}

QString OtaUpdate::remainTime() const
{
    return m_remainTime;
}

void OtaUpdate::setRemainTime(QString remainTime)
{
    m_remainTime = remainTime;
    emit remainTimeChanged(remainTime);
}

bool OtaUpdate::speedDisp() const
{
#ifdef IS_REPORT_SPEED
    return true;
#else
    return false;
#endif
}

void OtaUpdate::startUpgrade()
{
    m_fileSize = 0;
    m_totalFileSize = 0;
    m_cryHash.reset();
    setDownloadPrg(0);
    setUpgradePrg(0);
    updateType = NoType;
    foreach (QVariantMap vMap, m_otaList) {
        m_totalFileSize += vMap.value("fw_sz").toInt();
    }

    // 移除已存在的升级包
    int type = m_otaList.first().value("fw_type").toInt();
    QString fileName = getFileName(type);
    QFile file(fileName);
    if (file.exists()) {
        file.remove();
    }

    startDownload();
#ifdef IS_REPORT_SPEED
    m_elapsedTimer.start();
#endif
}

int OtaUpdate::getUpgradeVersion()
{
    if (m_otaList.isEmpty()) {
        return m_currOtaMap.value("target_ver").toInt();
    } else {
        return m_otaList.first().value("target_ver").toInt();
    }
}

void OtaUpdate::downloadUpgradePack(QVariantMap vMap)
{
    if (m_otaList.isEmpty()) {
        m_otaList.append(vMap);
        setUpgrade(true);
    }
}

QString OtaUpdate::getFileName(int type) {
    switch (type) {
    case FullPack:
        return "upgrade.tar";
    case AppFile:
        return "app.tar";
    case McuFile:
        return "mcu.tar";
    default:
        return "unknown.tar";
    }
}

void OtaUpdate::startDownload()
{
    m_currOtaMap = m_otaList.first();
    QString url = m_otaList.first().value("uri").toString();
    CloudComm::getInstance()->downloadUpgradePack(url);
    // 开启超时定时器
    m_timeoutTimer.start();
}

void OtaUpdate::startUpdate()
{
    setStatus(Updating);

    QDir currDir = QDir::current();
    currDir.cd("ota");
    QStringList mcuList = currDir.entryList(QStringList("*.bin"), QDir::Files);
    if (!mcuList.isEmpty()) { // mcu文件存在
        QString fileName = QString(currDir.absolutePath()+"/%1").arg(mcuList.at(0));
        QFile mcuFile(fileName);    // Mcu执行文件
        if (mcuFile.exists()) {
            if (mcuFile.open(QIODevice::ReadOnly)) {
                updateType |= McuType;
                m_mcuByte = mcuFile.readAll();
                mcuFile.close();
                uint16_t data = 0x1003;
                SerialPortDataParse::getInstance()->otaPermissionSet(data);
            } else {
                setStatus(UpdateFailed);
                qDebug()<<"Mcu file open failed by: "<<mcuFile.errorString();
            }
        }
    } else { // 开始app升级
        startAppUpgrade();
    }
}

void OtaUpdate::startAppUpgrade()
{
    // 升级主控
    QDir currDir = QDir::current();
    QFile uiFile(currDir.absolutePath()+"/ota/WallManage");    // UI执行文件
    if (uiFile.exists()) {
        updateType |= AppType;
        QString mv = QString("mv %1 %2").arg(uiFile.fileName()).arg(currDir.absolutePath());
        system(mv.toUtf8().data());
    }

    QFile commFile(currDir.absolutePath()+"/ota/NetProcess");  // Comm执行文件
    if (commFile.exists()) {
        updateType |= AppType;
        QString mv = QString("mv %1 %2").arg(commFile.fileName()).arg(currDir.absolutePath());
        system(mv.toUtf8().data());
    }

    if (updateType & AppType) {
        // 解析app应用版本
        bool ret = parseUpgradeJson();
        if (!ret) {
            return;
        }
    }

    setUpgradePrg(AppUpgradePrg);

    startFileSystemUpgrade();

    // 设置升级成功标志,当前应用版本,更新到云端
#ifdef PLATFORM_ARM
#ifdef IS_SET_VERSION
    int ver = m_currOtaMap.value("target_ver").toInt();
    GlobalSetting::getInstance()->setVersion(ver);
#endif
#endif

    setUpgradePrg(UpgradeFinishPrg);
    // 升级主控
    if ((updateType & AppType) || (updateType & FileSystemType)) {
        setStatus(UpdateFinishRestart);
        system("sync"); // 将缓冲文件写到硬盘中
    } else {    // 升级mcu
        setStatus(UpdateFinish);
    }

    QTimer::singleShot(3000, this, &OtaUpdate::rebootOpe);
}

void OtaUpdate::startFileSystemUpgrade()
{
    QDir currDir = QDir::current();
    QFile fileSystemFile(currDir.absolutePath()+"/ota/update.img");
    if (fileSystemFile.exists()) {
        updateType |= FileSystemType;
//        QString mv = QString("mv %1 %2").arg(fileSystemFile.fileName()).arg(currDir.absolutePath());
//        system(mv.toUtf8().data());
    }

    setUpgradePrg(FileSystemUpgradePrg);
}

void OtaUpdate::uncompressUpgradeFile()
{
    setStatus(Uncompressing);
    QDir home = QDir::current();
    const QString otaDir = "ota";
    // 创建ota目录
    if (!home.exists(otaDir)) {
        if(!home.mkdir(otaDir)) {
            setStatus(UncompressFailed);
            return;
        }
    }

    QString otaName = getFileName(FullPack);
    QFile file(otaName);
    // 进入ota目录
    if (!home.cd(otaDir)) {
        setStatus(UncompressFailed);
        return;
    } else {
        // 移除ota内所有文件
        QStringList fileList = home.entryList(QDir::Files|QDir::NoDotAndDotDot);
        foreach(QString fileName, fileList) {
            home.remove(fileName);
        }

        if (home.isEmpty(QDir::Files | QDir::NoDotAndDotDot)) {
            // 将upgrade.tar移动到ota目录
            otaName = home.path()+"/"+otaName;
            if (!file.rename(otaName)) {
                setStatus(UncompressFailed);
                return;
            }
        }
    }

    // 解压
    QString str = QString("tar -xf %1 -C %2").arg(otaName).arg(home.absolutePath());
    system(str.toUtf8().data());
    // 存在升级文件,进入升级流程
    if (home.isEmpty(QDir::Files | QDir::NoDotAndDotDot)) {
        setStatus(UncompressFailed);
    } else {
        startUpdate();
    }
}

void OtaUpdate::startMcuUpgrade()
{
    if (m_mcuByte.size() >= MCU_VERIFY_HEAD_LEN) {
        QVariantMap vMap;
        vMap.insert("location", 0x01);
        // 标识符
        uint identify = (m_mcuByte[0] << 24) + (m_mcuByte[1] << 16) + (m_mcuByte[2] << 8) + m_mcuByte[3];
        vMap.insert("identify", identify);
        // md5
        QByteArray md5Bin = m_mcuByte.mid(4, 32);
        vMap.insert("md5", md5Bin);
        // crc32
        uint32_t crc32Bin = (m_mcuByte[36] << 24) + (m_mcuByte[37] << 16) + (m_mcuByte[38] << 8) + m_mcuByte[39];
        vMap.insert("crc32", crc32Bin);
        // 代码文件大小
        uint fileSize = (m_mcuByte[40] << 24) + (m_mcuByte[41] << 16) + (m_mcuByte[42] << 8) + m_mcuByte[43];
        vMap.insert("fileSize", fileSize);
        // 软件版本号
        uint32_t mcuVer = (m_mcuByte[44] << 24) + (m_mcuByte[45] << 16) + (m_mcuByte[46] << 8) + m_mcuByte[47];
        vMap.insert("version", mcuVer);
        // 通知mcu升级
        SerialPortDataParse::getInstance()->startSlaveUpgrade(vMap);
    } else {
        setStatus(UpdateFailed);
        QString err = QString("Mcu file size less than %1, size: %2").arg(MCU_VERIFY_HEAD_LEN).arg(m_mcuByte.size());
        qDebug()<<err;
    }
}

void OtaUpdate::rebootOpe()
{
#ifdef PLATFORM_ARM
    if (updateType & FileSystemType) {
        QDir currDir = QDir::current();
        QString fileSystemPath = currDir.absolutePath()+"/ota/update.img";
        QString cmd = QString("update ota %1").arg(fileSystemPath);
        system(cmd.toUtf8().data());
    } else if (updateType & AppType) {
        system("reboot");
    } else if (updateType & McuType) {
        setUpgrade(false);
        setStatus(Ready);
    }
#endif
    if (!m_otaList.isEmpty()) {
        m_otaList.removeFirst();
    }
}

bool OtaUpdate::parseUpgradeJson()
{
    bool ret = false;
    QString json = QDir::currentPath()+"/ota/upgrade.json";
    QFile file(json);
    if (file.exists()) {
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray data = file.readAll();
            QJsonDocument doc = QJsonDocument::fromJson(data);
            if (doc.isObject()) {
                QJsonObject obj = doc.object();
                int app_version = obj.value("app_version").toInt();
                GlobalSetting::getInstance()->setAppVer(app_version);
                ret = true;
            }
        } else {
            setStatus(UpdateFailed);
        }
    } else {
        setStatus(UpdateJsonNotExist);
    }

    return ret;
}

void OtaUpdate::upgradeFlag(QVariantMap &vMap)
{
    uint8_t flag = vMap.value("flag").toUInt();
    if (flag == 0) {
        setStatus(ForbidUpdate);
    } else { // 开始升级
        QByteArray sendData = m_mcuByte.mid(MCU_VERIFY_HEAD_LEN, MCU_UPGRADE_FRAME_DATE_LEN);
        SerialPortDataParse::getInstance()->sendUpgradeData(1, sendData);
    }

    setUpgradePrg(McuMsgNotifyPrg);
}

void OtaUpdate::updatingFlag(QVariantMap &vMap)
{
    static int cnt = 0;
    uint8_t flag = vMap.value("flag").toUInt();
    uint16_t frameNo = vMap.value("frameNo").toUInt();

    // 判断是否是最后一帧
    uint16_t totalFrame = 0;
    uint64_t fileSize = m_mcuByte.size()-MCU_VERIFY_HEAD_LEN;
    if (fileSize % MCU_UPGRADE_FRAME_DATE_LEN == 0) {
        totalFrame = fileSize / MCU_UPGRADE_FRAME_DATE_LEN;
    } else {
        totalFrame = qFloor(fileSize/MCU_UPGRADE_FRAME_DATE_LEN)+1;
    }

    QByteArray sendData;
    if (flag == 0) {
        if (cnt < 2) {
            cnt++;
            if (frameNo == totalFrame) { // 最后一帧
                sendData = m_mcuByte.mid(MCU_VERIFY_HEAD_LEN+(frameNo-1)*MCU_UPGRADE_FRAME_DATE_LEN);
            } else {
                sendData = m_mcuByte.mid(MCU_VERIFY_HEAD_LEN+(frameNo-1)*MCU_UPGRADE_FRAME_DATE_LEN, MCU_UPGRADE_FRAME_DATE_LEN);
            }

            SerialPortDataParse::getInstance()->sendUpgradeData(frameNo, sendData);
        } else {
            setStatus(UpdateFailed);
        }
    } else {
        cnt = 0;
        if (frameNo == totalFrame) { // 最后一帧
            // 请求升级结果
            SerialPortDataParse::getInstance()->getUpgradeResult();
        } else {
            sendData = m_mcuByte.mid(MCU_VERIFY_HEAD_LEN+frameNo*MCU_UPGRADE_FRAME_DATE_LEN, MCU_UPGRADE_FRAME_DATE_LEN);
            SerialPortDataParse::getInstance()->sendUpgradeData(frameNo+1, sendData);
        }
    }

    int prg = McuMsgNotifyPrg+qRound((McuDataSendPrg-McuMsgNotifyPrg)*1.0/totalFrame*frameNo);
    setUpgradePrg(prg);
}

void OtaUpdate::upgradeResultFlag(QVariantMap &vMap)
{
    setUpgradePrg(McuUpgradeResultPrg);
    uint8_t flag = vMap.value("flag").toUInt();
    if (flag == 0) {
        startAppUpgrade();
    } else if (flag == 1) {
        setStatus(UpdateFailedByLen);
    } else if (flag == 2) {
        setStatus(UpdateFailedByCheck);
    } else {
        setStatus(UpdateFailed);
    }
}

void OtaUpdate::otaPermissionFlag(QVariantMap &vMap)
{
    uint16_t permission = vMap.value("permission").toUInt();
    if (permission == 0x5003) {
        startMcuUpgrade();
    } else {
        setStatus(UpdateFailed);
        QString err = QString("Mcu permission error By: 0x%1").arg(QString::number(permission, 16));
        qDebug()<<err;
    }

    setUpgradePrg(McuPermissionPrg);
}

void OtaUpdate::writeFile()
{
    QNetworkReply *reply = static_cast<QNetworkReply*>(sender());
    QString fileName;
    foreach (QVariantMap vMap, m_otaList) {
        if (vMap.value("uri").toString() == reply->url().toString()) {
            fileName = getFileName(vMap.value("fw_type").toInt());
            break;
        }
    }

    if (reply->error() == QNetworkReply::NoError) {
        if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly|QIODevice::Append)) {
                setStatus(Downloading);
                QByteArray byte = reply->readAll();
                file.write(byte);
                m_cryHash.addData(byte);

                quint64 size = byte.size();
                m_fileSize += size;
                // 设置升级进度
                setDownloadPrg(qRound(m_fileSize*100.0/m_totalFileSize));

                // 设置文件大小
                QString total = QString::number(m_totalFileSize*1.0/(1024*1024), 'f', 2);
                if (m_fileSize >= 1024*1024) {
                    QString MB = QString::number(m_fileSize*1.0/(1024*1024), 'f', 2);
                    setFileSize(QString("<font color='yellow'>%1 MB</font>/%2 MB").arg(MB).arg(total));
                } else {
                    if (m_totalFileSize >= 1024*1024) {
                        setFileSize(QString("<font color='yellow'>%1 KB</font>/%2 MB").arg(qRound(m_fileSize*1.0/1024)).arg(total));
                    } else {
                        setFileSize(QString("<font color='yellow'>%1 KB</font>/%2 KB").arg(qRound(m_fileSize*1.0/1024)).arg(qRound(m_totalFileSize*1.0/1024)));
                    }
                }
#ifdef IS_REPORT_SPEED
                qint64 elapsed = m_elapsedTimer.elapsed();
                if (elapsed > 0) {
                    // 设置下载速度  KB/s
                    qreal KB_s = size/elapsed*1000.0/1024;
                    if (KB_s >= 1024) {
                        QString MB_s = QString::number(KB_s/1024, 'f', 1);
                        setSpeed(QString("%1 MB/s").arg(MB_s));
                    } else {
                        QString KB_Str = QString::number(KB_s, 'f', 1);
                        setSpeed(QString("%1 KB/s").arg(KB_Str));
                    }

                    // 设置剩余时间
                    if (KB_s > 0) {
                        qreal remain = (m_totalFileSize-m_fileSize)/KB_s/1024;
                        if (remain >= 60) {
                            setRemainTime(QString("%1 Min").arg(qRound(remain/60)));
                        } else {
                            setRemainTime(QString("%1 s").arg(qRound(remain)));
                        }
                    }
                }
#endif
            } else {
                setStatus(DownloadFailed);
            }
        } else {
            setStatus(DownloadFailed);
        }
    } else {
        setStatus(DownloadFailed);
    }
#ifdef IS_REPORT_SPEED
    m_elapsedTimer.start();
#endif
}

void OtaUpdate::downloadFinished()
{
    QString fileName;
    QString md5;
    QNetworkReply *reply = static_cast<QNetworkReply*>(sender());
    foreach (QVariantMap vMap, m_otaList) {
        if (vMap.value("uri").toString() == reply->url().toString()) {
            fileName = getFileName(vMap.value("fw_type").toInt());
            md5 = vMap.value("md5").toString();
            break;
        }
    }

    QFile file(fileName);
    if (file.isOpen()) {
        file.close();
    }

    if (reply->error() == QNetworkReply::NoError) {
        if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
            qDebug()<<"_________md5__________"<<m_cryHash.result().toHex()<<md5.toLower();
            if (m_cryHash.result().toHex() != md5.toLower()) {
                setStatus(Md5CheckFailed);
            } else {
                setStatus(DownloadFinish);
                QTimer::singleShot(1000, this, &OtaUpdate::uncompressUpgradeFile);
//                m_otaList.removeFirst();
//                if (!m_otaList.isEmpty()) {
//                    // 下载下一个升级文件
//                    startDownload();
//                } else {
//                    setStatus(DownloadFinish);
//                    QTimer::singleShot(1000, this, &OtaUpdate::uncompressUpgradeFile);
//                }
            }
        } else {
            setStatus(DownloadFailed);
        }
    } else {
        setStatus(DownloadFailed);
    }

    reply->deleteLater();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值