bool CDVRPTRControllerV2::setConfig() { unsigned char buffer[105U]; ::memset(buffer, 0x00U, 105U); buffer[0U] = 'H'; buffer[1U] = 'E'; buffer[2U] = 'A'; buffer[3U] = 'D'; buffer[4U] = 'X'; buffer[5U] = '9'; buffer[6U] = '0'; buffer[7U] = '0'; buffer[8U] = '1'; ::memset(buffer + 9U, ' ', LONG_CALLSIGN_LENGTH); for (unsigned int i = 0U; i < LONG_CALLSIGN_LENGTH && i < m_callsign.Len(); i++) buffer[9U + i] = m_callsign.GetChar(i); buffer[65U] = m_duplex ? 0x03U : 0x00U; buffer[66U] = m_txInvert ? 0x01U : 0x00U; buffer[73U] = (m_modLevel * 256U) / 100U; buffer[87U] = 0x01U; // CUtils::dump(wxT("Written"), buffer, 105U); int ret = m_serial.write(buffer, 105U); if (ret != 105) return false; unsigned int count = 0U; unsigned int length; RESP_TYPE_V2 resp; do { ::wxMilliSleep(10UL); resp = getResponse(m_buffer, length); if (resp != RT2_CONFIG) { count++; if (count >= MAX_RESPONSES) { wxLogError(wxT("The DV-RPTR modem is not responding to the configure command")); return false; } } } while (resp != RT2_CONFIG); // CUtils::dump(wxT("Response"), m_buffer, length); wxString firmware((char*)(m_buffer + 9U), wxConvLocal); wxLogInfo(wxT("DV-RPTR Modem Firmware version: %s"), firmware.c_str()); return true; }
void exit(int ispanic) { canlock(&active); active.machs &= ~(1<<m->machno); active.exiting = 1; unlock(&active); spllo(); print("cpu %d exiting\n", m->machno); do delay(100); while(consactive()); splhi(); delay(1000); /* give serial fifo time to finish flushing */ if (getconf("*debug") != nil) { USED(ispanic); delay(60*1000); /* give us time to read the screen */ } if(arch->coredetach) arch->coredetach(); setupboot(1); // set up to halt for (; ; ) firmware(); // on PC is just: //if (0) { // shutdown(ispanic); // arch->reset(); //} }
void FirmwareDownloader::systemMessageReceived(const QByteArray &data) { qDebug() << "system message" << data.toHex(); if (!m_upgradeInProgress) { return; } Bundle firmware(m_bundlePath); qDebug() << "** Uploading firmware resources..."; m_connection->uploadManager()->uploadFirmwareResources(firmware.file(Bundle::FileTypeResources), firmware.crc(Bundle::FileTypeResources), [this, firmware]() { qDebug() << "** Firmware resources uploaded. OK"; qDebug() << "** Uploading firmware binary..."; m_connection->uploadManager()->uploadFirmwareBinary(false, firmware.file(Bundle::FileTypeFirmware), firmware.crc(Bundle::FileTypeFirmware), [this]() { qDebug() << "** Firmware binary uploaded. OK"; m_connection->systemMessage(WatchConnection::SystemMessageFirmwareComplete); m_upgradeInProgress = false; emit upgradingChanged(); }, [this](int code) { qWarning() << "** ERROR uploading firmware binary" << code; m_connection->systemMessage(WatchConnection::SystemMessageFirmwareFail); m_upgradeInProgress = false; emit upgradingChanged(); }); }, [this](int code) { qWarning() << "** ERROR uploading firmware resources" << code; m_connection->systemMessage(WatchConnection::SystemMessageFirmwareFail); m_upgradeInProgress = false; emit upgradingChanged(); }); }
void GeneralUtils::configureFabric(std::vector<char> const &buffer) { if (GeneralUtils::fileExists("/dev/xdevcfg")) { //We are on Kernel 4.6 or lower FILE *fd = fopen("/dev/xdevcfg", "w"); if (fd == NULL) { throw std::runtime_error("Could not open /dev/xdevcfg device"); } size_t written = fwrite(buffer.data(), sizeof(char), buffer.size(), fd); if (written != buffer.size()) { throw std::runtime_error("Could not write complete bitstream to /dev/xdevcfg"); } fclose(fd); } else if (GeneralUtils::fileExists("/sys/class/fpga_manager/fpga0/firmware")) { const char bitstreamFile[] = "fabric_bitstream.bin"; std::ofstream bitstream(std::string("/lib/firmware/") + bitstreamFile, std::ios::out | std::ios::binary | std::ios::trunc); bitstream.write(buffer.data(), buffer.size()); bitstream.close(); std::ofstream firmware("/sys/class/fpga_manager/fpga0/firmware"); firmware << bitstreamFile; firmware.close(); if (!firmware.good()) { throw std::runtime_error("Fabric configuration through fpga_manager failed!"); } // Loading was successful, wait for half a second before using the fpga! // or else the board is gone... praise the fpga_manager std::this_thread::sleep_for(std::chrono::milliseconds(500)); } else { // TODO load AWS bitstream } }
static signed nvmimage2 (void const * memory, size_t extent, char const * filename, flag_t flags) { struct nvm_header1 * nvm_header; unsigned module = 0; uint32_t offset = 0; do { nvm_header = (struct nvm_header1 *)((char *)(memory) + offset); if (LE32TOH (nvm_header->HEADERVERSION) != 0x60000000) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_VERSION, filename, module); } return (-1); } if (checksum32 (nvm_header, sizeof (* nvm_header), 0)) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_CHECKSUM, filename, module); } return (-1); } offset += sizeof (* nvm_header); extent -= sizeof (* nvm_header); if (_anyset (flags, NVM_VERBOSE)) { printf ("------- %s (%d) -------\n", filename, module); nvmpeek1 (nvm_header); } if (LE32TOH (nvm_header->IMAGETYPE) == NVM_IMAGE_FIRMWARE) { firmware (filename, module, (char *)(memory) + offset, 0x70, flags); } if (checksum32 ((char *)(memory) + offset, LE32TOH (nvm_header->IMAGELENGTH), nvm_header->IMAGECHECKSUM)) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_IMG_CHECKSUM, filename, module); } return (-1); } offset += LE32TOH (nvm_header->IMAGELENGTH); extent -= LE32TOH (nvm_header->IMAGELENGTH); module++; } while (nvm_header->NEXTHEADER); if (extent) { if (_allclr (flags, NVM_SILENCE)) { error (0, errno, NVM_HDR_LINK, filename, module); } } return ((signed)(extent)); }
void FlashFirmwareDialog::updateUI() { ui->firmwareFilename->setText(fwName); ui->burnButton->setEnabled(QFile(fwName).exists()); FirmwareInterface firmware(fwName); if (firmware.isValid()) { ui->firmwareInfoFrame->show(); ui->date->setText(firmware.getDate() + " " + firmware.getTime()); ui->version->setText(firmware.getVersion()); ui->variant->setText(firmware.getEEpromId()); ui->date->setEnabled(true); ui->version->setEnabled(true); ui->variant->setEnabled(true); if (firmware.hasSplash()) { ui->splashFrame->show(); ui->splash->setFixedSize(firmware.getSplashWidth(), firmware.getSplashHeight()); } else { ui->splashFrame->hide(); } } else { imageSource = FIRMWARE; ui->firmwareInfoFrame->hide(); ui->splashFrame->hide(); } QImage image; switch(imageSource) { case FIRMWARE: ui->useFirmwareSplash->setChecked(true); image = firmware.getSplash(); break; case PROFILE: ui->useProfileSplash->setChecked(true); image.load(g.profile[g.id()].splashFile()); break; case LIBRARY: ui->useLibrarySplash->setChecked(true); image.load(imageFile); break; case EXTERNAL: ui->useExternalSplash->setChecked(true); image.load(imageFile); break; } if (!image.isNull()) { ui->splash->setPixmap(makePixMap(image, g.profile[g.id()].fwType())); } }
void FalconCLIBase::addOptions(int value) { if(value & COMM_OPTIONS) { po::options_description comm("Communication Options"); comm.add_options() #if defined(LIBUSB) ("libusb", "use libusb-1.0 based driver") #endif #if defined(LIBFTDI) ("libftdi", "use libftdi based driver") #elif defined(LIBFTD2XX) ("ftd2xx", "use ftd2xx based driver") #endif ; m_progOptions.add(comm); } if(value & DEVICE_OPTIONS) { po::options_description device("Device options"); device.add_options() ("device_count", "Print the number of devices currently connected and return") ("device_index", po::value<int>(), "Opens device of given index (starts at 0)") ; m_progOptions.add(device); } if(value & FIRMWARE_OPTIONS) { po::options_description firmware("Firmware Options"); firmware.add_options() ("nvent_firmware", "Use 'nVent' firmware (Recommended)") ("test_firmware", "Use test firmware") ("firmware_file", po::value<std::string>(), "Specify external firmware file (instead of nvent or test)") ("force_firmware", "Force firmware download, even if already loaded") ("skip_checksum", "Ignore checksum errors when loading firmware (useful for FTD2XX on non-windows platforms)") ; m_progOptions.add(firmware); } #ifdef ENABLE_LOGGING po::options_description debug("Debug Message Options"); debug.add_options() ("debug_level", po::value<std::string>(), "Level of debug messages to print (FATAL, ERROR, WARN, INFO, DEBUG) (Default: FATAL)") ; // ("output_file", po::value<std::string>(), "File to output debug messages to (outputs to stdout otherwise") m_progOptions.add(debug); #endif }
void FlashFirmwareDialog::on_useFirmwareSplash_clicked() { FirmwareInterface firmware(fwName); if (!firmware.isValid()) { QMessageBox::warning(this, tr("Error"), tr( "The firmware file is not valid." )); } else if (!firmware.hasSplash()) { QMessageBox::warning(this, tr("Error"), tr( "There is no start screen image in the firmware file." )); } else { imageSource = FIRMWARE; } updateUI(); }
void FlashFirmwareDialog::on_burnButton_clicked() { g.flashDir(QFileInfo(fwName).dir().absolutePath()); g.profile[g.id()].fwName(fwName); g.checkHardwareCompatibility(ui->checkHardwareCompatibility->isChecked()); g.backupOnFlash(ui->backupEEprom->isChecked()); qDebug() << "FlashFirmwareDialog: flashing" << fwName; if (imageSource != FIRMWARE) { // load the splash image const QPixmap * pixmap = ui->splash->pixmap(); QImage image; if (pixmap) { image = pixmap->toImage().scaled(ui->splash->width(), ui->splash->height()); } if (image.isNull()) { QMessageBox::critical(this, tr("Warning"), tr("Splash image not found")); return; } // write the customized firmware QString tempFile; if (getFileType(fwName) == FILE_TYPE_HEX) tempFile = generateProcessUniqueTempFileName("flash.hex"); else tempFile = generateProcessUniqueTempFileName("flash.bin"); qDebug() << "FlashFirmwareDialog: patching" << fwName << "with custom splash screen and saving to" << tempFile; FirmwareInterface firmware(fwName); firmware.setSplash(image); if (firmware.save(tempFile) <= 0) { QMessageBox::critical(this, tr("Warning"), tr("Cannot save customized firmware")); return; } startFlash(tempFile); } else { startFlash(fwName); } }
bool TellStick::isUpgradable() const { QString fw = firmware(); if (fw == "?") { return false; } int firmware = fw.toInt(); if (type() == 1) { //TellStick if (firmware <= 3) { return false; } if (firmware < 6) { return true; } } else if (type() == 2) { //TellStick Duo if (firmware < 10) { return true; } } return false; }
bool convertEEprom(const QString &sourceEEprom, const QString &destinationEEprom, const QString &firmwareFilename) { Firmware *currentFirmware = GetCurrentFirmware(); FirmwareInterface firmware(firmwareFilename); if (!firmware.isValid()) return false; unsigned int version = firmware.getEEpromVersion(); unsigned int variant = firmware.getEEpromVariant(); QFile sourceFile(sourceEEprom); int eeprom_size = sourceFile.size(); if (!eeprom_size) return false; if (!sourceFile.open(QIODevice::ReadOnly)) return false; QByteArray eeprom(eeprom_size, 0); long result = sourceFile.read(eeprom.data(), eeprom_size); sourceFile.close(); QSharedPointer<RadioData> radioData = QSharedPointer<RadioData>(new RadioData()); if (!loadEEprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size) || !currentFirmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version)) return false; QFile destinationFile(destinationEEprom); if (!destinationFile.open(QIODevice::WriteOnly)) return false; result = destinationFile.write(eeprom.constData(), eeprom_size); destinationFile.close(); if (result != eeprom_size) return false; return true; }
void KbFirmware::processDownload(QNetworkReply* reply){ if(reply->error() != QNetworkReply::NoError) return; // Update last check lastCheck = lastFinished = QDateTime::currentMSecsSinceEpoch(); QByteArray data = reply->readAll(); // Don't do anything if this is the same as the last version downloaded QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256); if(hash == fwTableHash) return; fwTableHash = hash; if(hasGPG == UNKNOWN){ // Check for a GPG installation QProcess gpg; gpg.start("gpg", QStringList("--version")); gpg.waitForFinished(); if(gpg.error() == QProcess::FailedToStart) // No GPG install hasGPG = NO; else { QString output = QString::fromUtf8(gpg.readAll()); // Must support RSA keys and SHA256 if(output.contains("RSA", Qt::CaseInsensitive) && output.contains("SHA256", Qt::CaseInsensitive)) hasGPG = YES; else hasGPG = NO; } if(!hasGPG) qDebug() << "No GPG detected, signature verification disabled"; } if(hasGPG){ // If GPG is available, check the signature on the file before proceeding. QDir tmp = QDir::temp(); // Save file to a temporary path. Include PID to avoid conflicts qint64 pid = QCoreApplication::applicationPid(); QString fwPath = tmp.absoluteFilePath(QString("ckb-%1-firmware").arg(pid)); QFile firmware(fwPath); if(!firmware.open(QIODevice::WriteOnly) || firmware.write(data) != data.length()){ qDebug() << "Failed to write firmware file to temporary location, aborting firmware check"; return; } firmware.close(); // Write GPG key QString keyPath = tmp.absoluteFilePath(QString("ckb-%1-key.gpg").arg(pid)); if(!QFile::copy(":/bin/msckey.gpg", keyPath)){ firmware.remove(); qDebug() << "Failed to write GPG key to temporary location, aborting firmware check"; return; } // Check signature QProcess gpg; gpg.start("gpg", QStringList("--no-default-keyring") << "--keyring" << keyPath << "--verify" << fwPath); gpg.waitForFinished(); // Clean up temp files tmp.remove(fwPath); tmp.remove(keyPath); if(gpg.error() != QProcess::UnknownError || gpg.exitCode() != 0){ qDebug() << "GPG couldn't verify firmware signature:"; qDebug() << gpg.readAllStandardOutput(); qDebug() << gpg.readAllStandardError(); return; } // Signature good, proceed to update database } fwTable.clear(); QStringList lines = QString::fromUtf8(data).split("\n"); bool scan = false; foreach(QString line, lines){ // Collapse whitespace line.replace(QRegExp("\\s+"), " ").remove(QRegExp("^\\s")).remove(QRegExp("\\s$")); // Skip empty or commented-out lines if(line.length() == 0 || line.at(0) == '#') continue; // Don't read anything until the entries begin and don't read anything after they end if(!scan){ if(line == "!BEGIN FW ENTRIES") scan = true; else continue; } if(line == "!END FW ENTRIES") break; QStringList components = line.split(" "); if(components.length() != 7) continue; // "VENDOR-PRODUCT" QString device = components[0].toUpper() + "-" + components[1].toUpper(); FW fw; fw.fwVersion = components[2].toFloat(); // Firmware blob version fw.url = QUrl::fromPercentEncoding(components[3].toLatin1()); // URL to zip file fw.ckbVersion = KbManager::parseVersionString(components[4]); // Minimum ckb version fw.fileName = QUrl::fromPercentEncoding(components[5].toLatin1()); // Name of file inside zip fw.hash = QByteArray::fromHex(components[6].toLatin1()); // SHA256 of file inside zip // Update entry fwTable[device] = fw; }
int main() { GPIO_InitTypeDef gpioInit = {0}; struct syslinkPacket slPacket; struct crtpPacket_s packet; unsigned int ledGreenTime=0; unsigned int ledRedTime = 0; unsigned int ledBlueTime = 0; /* Detecting if we need to boot firmware or DFU bootloader */ bootpinInit(); if (bootpinStartFirmware() == true) { if (*((uint32_t*)FIRMWARE_START) != 0xFFFFFFFFU) { void (*firmware)(void) __attribute__((noreturn)) = (void *)(*(uint32_t*)(FIRMWARE_START+4)); bootpinDeinit(); // Start firmware NVIC_SetVectorTable(FIRMWARE_START, 0); __set_MSP(*((uint32_t*)FIRMWARE_START)); firmware(); } } else if (bootpinNrfReset() == true) { void (*bootloader)(void) __attribute__((noreturn)) = (void *)(*(uint32_t*)(SYSTEM_BASE+4)); bootpinDeinit(); // Start bootloader NVIC_SetVectorTable(SYSTEM_BASE, 0); __set_MSP(*((uint32_t*)SYSTEM_BASE)); bootloader(); } bootpinDeinit(); /* Booting CRTP Bootloader! */ SystemInit(); uartInit(); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); gpioInit.GPIO_Pin = GPIO_Pin_2; gpioInit.GPIO_Mode = GPIO_Mode_OUT; GPIO_Init(GPIOD, &gpioInit); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); gpioInit.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0; gpioInit.GPIO_Mode = GPIO_Mode_OUT; GPIO_Init(GPIOC, &gpioInit); GPIO_WriteBit(GPIOC, GPIO_Pin_0, 1); GPIO_WriteBit(GPIOC, GPIO_Pin_1, 1); SysTick->LOAD = (SystemCoreClock/8)/1000; // Set systick to overflow every 1ms SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; NVIC_EnableIRQ(SysTick_IRQn); // Blue LED ON by default GPIO_WriteBit(GPIOD, GPIO_Pin_2, 1); while(1) { if (syslinkReceive(&slPacket)) { if (slPacket.type == SYSLINK_RADIO_RAW) { memcpy(packet.raw, slPacket.data, slPacket.length); packet.datalen = slPacket.length-1; ledGreenTime = tick; GPIO_WriteBit(GPIOC, GPIO_Pin_1, 0); if (bootloaderProcess(&packet)) { ledRedTime = tick; GPIO_WriteBit(GPIOC, GPIO_Pin_0, 0); memcpy(slPacket.data, packet.raw, packet.datalen+1); slPacket.length = packet.datalen+1; syslinkSend(&slPacket); } } } if (ledGreenTime!=0 && tick-ledGreenTime>10) { GPIO_WriteBit(GPIOC, GPIO_Pin_1, 1); ledGreenTime = 0; } if (ledRedTime!=0 && tick-ledRedTime>10) { GPIO_WriteBit(GPIOC, GPIO_Pin_0, 1); ledRedTime = 0; } if ((tick-ledBlueTime)>500) { if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_2)) { GPIO_WriteBit(GPIOD, GPIO_Pin_2, 0); } else { GPIO_WriteBit(GPIOD, GPIO_Pin_2, 1); } ledBlueTime = tick; } } return 0; }
/* Ma-ma-ma-main function! */ void main() { state_t state = LISTENING; command_t cmd = CMD_NO_CMD; firmware_start firmware; uint16_t channel_timer = 0, bootloader_timer = 0, connection_timer = 0; uint8_t ch_i = 0, firmware_number = 0; bool running; uint16_t bytes_received = 0; uint16_t bytes_total = 0; uint8_t ea_default, rf_default; // Disable RF interrupt rf_default = RF; RF = 0; // Disable global interrupt ea_default = EA; EA = 0; // Set up parameters for RF communication. configureRF(); #ifdef DEBUG_LED_ P0DIR = 0; P0 = 0x55; #endif running = true; // Boot loader loop. // Will terminate after a couple of seconds if firmware has been successfully // installed. while (running) { // Polls the RF-interrupt bit every iteration. if (RFF) { RFF = 0; nrf_irq(); if (packet_received) { packet_received = false; connection_timer = 0; cmd = MSG_CMD; switch (cmd) { // Host initiates contact with the device. case CMD_INIT: // Send ACK to host, go to CONNECTED state if successful. sendInitAck(&state); // Reset timers channel_timer = bootloader_timer = 0; break; // Host starts a firmware update. case CMD_UPDATE_START: if (state == CONNECTED) { // Initiate firmware updates, go to RECEIVING_FIRMWARE state // if successful. startFirmwareUpdate(&state, &bytes_total, &bytes_received, &firmware_number); } #ifdef DEBUG_LED_ P0 = state; #endif break; // Write message containing one hex record. case CMD_WRITE: if (state == RECEIVING_FIRMWARE) { writeHexRecord(&state, &bytes_received); } #ifdef DEBUG_LED_ P0 = 0x40; #endif break; // Firmware update has been completed. case CMD_UPDATE_COMPLETE: CE_LOW(); // Check that every byte is received. if (bytes_received == bytes_total) { // Mark firmware as successfully installed. hal_flash_byte_write(FW_INSTALLED, 0x01); hal_flash_byte_write(FW_NUMBER, firmware_number); state = CONNECTED; send(CMD_ACK); } else { send(CMD_NACK); } if (!send_success) { state = ERROR; } #ifdef DEBUG_LED_ P0 = 0x10; #endif break; // Host request data from flash at specified address. case CMD_READ: readHexRecord(); #ifdef DEBUG_LED_ P0 = 0x20; #endif break; // Host sends ping to check connections with device. case CMD_PING: if (state != LISTENING) { send(CMD_PONG); } #ifdef DEBUG_LED_ P0 = 0x80; #endif break; // Host sends disconnect case CMD_EXIT: state = LISTENING; break; // These commands should no be received. case CMD_NO_CMD: default: state = ERROR; break; } // Clear command cmd = CMD_NO_CMD; } // RF interrupt bit not set } else if (state == LISTENING) { // Will listen to one channel for 'a while' before changing. channel_timer++; if (channel_timer > CHANNEL_TIMEOUT) { channel_timer = 0; // Go to next channel ch_i = (ch_i+1)%3; hal_nrf_set_rf_channel(default_channels[ch_i]); #ifdef DEBUG_LED_ P0 = ch_i; #endif // After changing channels and being in the LISTENING state // for 'a while', boot loader loop will check if there is firmware // installed, and if so end the while(running) loop. bootloader_timer++; if (bootloader_timer > BOOTLOADER_TIMEOUT) { bootloader_timer = 0; running = (hal_flash_byte_read(FW_INSTALLED) == 0x01) ? false : true; } } // While connected must receive something or connection times out. // Connection timer reset when packet received. } else if (state == CONNECTED) { connection_timer++; if (connection_timer > CONNECTION_TIMEOUT) { state = LISTENING; } } } resetRF(); #ifdef DEBUG_LED_ // Default value for P0DIR P0 = 0x00; P0DIR = 0xFF; #endif EA = ea_default; RF = rf_default; // Reads address of firmware's reset vector. temp_data[0] = hal_flash_byte_read(FW_RESET_ADDR_H); temp_data[1] = hal_flash_byte_read(FW_RESET_ADDR_L); firmware = (firmware_start)(((uint16_t)temp_data[0]<<8) | (temp_data[1])); // Jump to firmware. Goodbye! firmware(); }
void FirmwareDownloader::performUpgrade() { if (!m_updateAvailable) { qWarning() << "No update available"; return; } if (m_upgradeInProgress) { qWarning() << "Upgrade already in progress. Won't start another one"; return; } m_upgradeInProgress = true; emit upgradingChanged(); QNetworkRequest request(m_url); QNetworkReply *reply = m_nam->get(request); connect(reply, &QNetworkReply::finished, [this, reply](){ reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) { qWarning() << "Erorr fetching firmware" << reply->errorString(); m_upgradeInProgress = false; emit upgradingChanged(); return; } QByteArray data = reply->readAll(); QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); if (hash != m_hash) { qWarning() << "Downloaded data hash doesn't match hash from target"; m_upgradeInProgress = false; emit upgradingChanged(); return; } QDir dir("/tmp/" + m_pebble->address().toString().replace(":", "_")); if (!dir.exists() && !dir.mkpath(dir.absolutePath())) { qWarning() << "Error saving file" << dir.absolutePath(); m_upgradeInProgress = false; emit upgradingChanged(); return; } QString path = "/tmp/" + m_pebble->address().toString().replace(":", "_"); QFile f(path + "/" + reply->request().url().fileName()); if (!f.open(QFile::WriteOnly | QFile::Truncate)) { qWarning() << "Cannot open tmp file for writing" << f.fileName(); m_upgradeInProgress = false; emit upgradingChanged(); return; } f.write(data); f.close(); if (!ZipHelper::unpackArchive(f.fileName(), path)) { qWarning() << "Error unpacking firmware archive"; m_upgradeInProgress = false; emit upgradingChanged(); return; } Bundle firmware(path); if (firmware.file(Bundle::FileTypeFirmware).isEmpty() || firmware.file(Bundle::FileTypeResources).isEmpty()) { qWarning() << "Firmware bundle file missing binary or resources"; m_upgradeInProgress = false; emit upgradingChanged(); return; } qDebug() << "** Starting firmware upgrade **"; m_bundlePath = path; m_connection->systemMessage(WatchConnection::SystemMessageFirmwareStart); }); }