diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index a49f5b029ff8a478e8b7357b2b5843796e3bf3ec..dd8a36f7eab065a6a8e312f0264de233aa389cf8 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -108,6 +108,14 @@ SOURCES += \ libs/shapelib/shpopen.c \ libs/shapelib/safileio.c +# +# [REQUIRED] zlib library +Windows { + INCLUDEPATH += $$SOURCE_DIR/libszlib/windows/include + LIBS += -L$$SOURCE_DIR/libszlib/windows/lib +} +LIBS += -lz + # # [REQUIRED] SDL dependency. Provides joystick/gamepad support. # The SDL is packaged with QGC for the Mac and Windows. Linux support requires installing the SDL @@ -143,7 +151,7 @@ contains(DEFINES, QGC_ENABLE_PAIRING) { exists(/usr/local/Cellar/openssl/1.0.2t/include) { INCLUDEPATH += /usr/local/Cellar/openssl/1.0.2t/include LIBS += -L/usr/local/Cellar/openssl/1.0.2t/lib - LIBS += -lcrypto -lz + LIBS += -lcrypto } else { # There is some circular reference settings going on between QGCExternalLibs.pri and gqgroundcontrol.pro. # So this duplicates some of the enable/disable logic which would normally be in qgroundcontrol.pro. @@ -153,7 +161,7 @@ contains(DEFINES, QGC_ENABLE_PAIRING) { #- Pairing is not supported on Windows DEFINES -= QGC_ENABLE_PAIRING } else { - LIBS += -lcrypto -lz + LIBS += -lcrypto AndroidBuild { contains(QT_ARCH, arm) { LIBS += $$ANDROID_EXTRA_LIBS diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index 7ce4935ac1bea12a50440e468e3396941efc457d..149c7248f4600044de857ceae81aedac7577230e 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -9,13 +9,13 @@ #include "FirmwareUpgradeController.h" #include "Bootloader.h" -//-- TODO: #include "QGCQFileDialog.h" #include "QGCApplication.h" #include "QGCFileDownload.h" #include "QGCOptions.h" #include "QGCCorePlugin.h" #include "FirmwareUpgradeSettings.h" #include "SettingsManager.h" +#include "QGCTemporaryFile.h" #include #include @@ -24,6 +24,8 @@ #include #include +#include "zlib.h" + const char* FirmwareUpgradeController::_manifestFirmwareJsonKey = "firmware"; const char* FirmwareUpgradeController::_manifestBoardIdJsonKey = "board_id"; const char* FirmwareUpgradeController::_manifestMavTypeJsonKey = "mav-type"; @@ -878,11 +880,7 @@ void FirmwareUpgradeController::_downloadArduPilotManifest(void) QGCFileDownload* downloader = new QGCFileDownload(this); connect(downloader, &QGCFileDownload::downloadFinished, this, &FirmwareUpgradeController::_ardupilotManifestDownloadFinished); connect(downloader, &QGCFileDownload::error, this, &FirmwareUpgradeController::_ardupilotManifestDownloadError); -#if 0 downloader->download(QStringLiteral("http://firmware.ardupilot.org/manifest.json.gz")); -#else - downloader->download(QStringLiteral("http://firmware.ardupilot.org/manifest.json")); -#endif } void FirmwareUpgradeController::_ardupilotManifestDownloadFinished(QString remoteFile, QString localFile) @@ -892,49 +890,70 @@ void FirmwareUpgradeController::_ardupilotManifestDownloadFinished(QString remot // Delete the QGCFileDownload object sender()->deleteLater(); - qDebug() << "_ardupilotManifestDownloadFinished" << remoteFile << localFile; + qCDebug(FirmwareUpgradeLog) << "_ardupilotManifestDownloadFinished" << remoteFile << localFile; -#if 0 - QFile gzipFile(localFile); - if (!gzipFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot firmware manifest file" << localFile << gzipFile.errorString(); + QFile inputFile(localFile); + if (!inputFile.open(QIODevice::ReadOnly)) { + qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot firmware manifest file for reading" << localFile << inputFile.errorString(); QFile::remove(localFile); return; } - // Store decompressed size as first four bytes. This is required by qUncompress routine. - QByteArray raw; - int decompressedSize = 3073444; - raw.append((unsigned char)((decompressedSize >> 24) & 0xFF)); - raw.append((unsigned char)((decompressedSize >> 16) & 0xFF)); - raw.append((unsigned char)((decompressedSize >> 8) & 0xFF)); - raw.append((unsigned char)((decompressedSize >> 0) & 0xFF)); - - raw.append(gzipFile.readAll()); - QByteArray bytes = qUncompress(raw); -#else - - - QFile jsonFile(localFile); - if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot firmware manifest file" << localFile << jsonFile.errorString(); + int ret; + const int cBuffer = 1024 * 5; + unsigned char inputBuffer[cBuffer]; + unsigned char outputBuffer[cBuffer]; + z_stream strm; + QByteArray jsonBytes; + + strm.zalloc = nullptr; + strm.zfree = nullptr; + strm.opaque = nullptr; + strm.avail_in = 0; + strm.next_in = nullptr; + + ret = inflateInit2(&strm, 16+MAX_WBITS); + if (ret != Z_OK) { + qCWarning(FirmwareUpgradeLog) << "inflateInit2 failed:" << ret; QFile::remove(localFile); return; } - QByteArray bytes = jsonFile.readAll(); - jsonFile.close(); -#endif + + do { + strm.avail_in = static_cast(inputFile.read((char*)inputBuffer, cBuffer)); + if (strm.avail_in == 0) { + break; + } + strm.next_in = inputBuffer; + + do { + strm.avail_out = cBuffer; + strm.next_out = outputBuffer; + + ret = inflate(&strm, Z_NO_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) { + qCWarning(FirmwareUpgradeLog) << "Inflate failed" << ret; + inflateEnd(&strm); + QFile::remove(localFile); + return; + } + + unsigned cBytesInflated = cBuffer - strm.avail_out; + jsonBytes.append((char*)outputBuffer, static_cast(cBytesInflated)); + } while (strm.avail_out == 0); + } while (ret != Z_STREAM_END); + + inflateEnd(&strm); + inputFile.close(); QFile::remove(localFile); QJsonParseError jsonParseError; - QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError); + QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &jsonParseError); if (jsonParseError.error != QJsonParseError::NoError) { qCWarning(FirmwareUpgradeLog) << "Unable to open ArduPilot manifest json document" << localFile << jsonParseError.errorString(); } - - QJsonObject json = doc.object(); QJsonArray rgFirmware = json[_manifestFirmwareJsonKey].toArray();