/** Callback for the firmware upload result */ void DeviceWidget::uploadFinished(OP_DFU::Status retstatus) { disconnect(m_dfu, SIGNAL(uploadFinished(OP_DFU::Status)), this, SLOT(uploadFinished(OP_DFU::Status))); disconnect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); disconnect(m_dfu, SIGNAL(operationProgress(QString)), this, SLOT(dfuStatus(QString))); if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); updateButtons(true); return; } else if (!descriptionArray.isEmpty()) { // We have a structured array to save status(QString("Updating description"), STATUSICON_RUNNING); repaint(); // Make sure the text above shows right away retstatus = m_dfu->UploadDescription(descriptionArray); if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); updateButtons(true); return; } } else if (!myDevice->description->text().isEmpty()) { // Fallback: we save the description field: status(QString("Updating description"), STATUSICON_RUNNING); repaint(); // Make sure the text above shows right away retstatus = m_dfu->UploadDescription(myDevice->description->text()); if (retstatus != OP_DFU::Last_operation_Success) { emit uploadEnded(false); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); updateButtons(true); return; } } populate(); emit uploadEnded(true); status("Upload successful", STATUSICON_OK); updateButtons(true); }
/** Sends a firmware to the device */ void deviceWidget::uploadFirmware() { myDevice->updateButton->setEnabled(false); if (!m_dfu->devices[deviceID].Writable) { status("Device not writable!", STATUSICON_FAIL); myDevice->updateButton->setEnabled(true); return; } bool verify = false; /* TODO: does not work properly on current Bootloader! if (m_dfu->devices[deviceID].Readable) verify = true; */ QByteArray desc = loadedFW.right(100); if (desc.startsWith("OpFw")) { descriptionArray = desc; // Now do sanity checking: // - Check whether board type matches firmware: int board = m_dfu->devices[deviceID].ID; int firmwareBoard = ((desc.at(12)&0xff)<<8) + (desc.at(13)&0xff); if((board == 0x401 && firmwareBoard == 0x402) || (board == 0x901 && firmwareBoard == 0x902) || // L3GD20 revo supports Revolution firmware (board == 0x902 && firmwareBoard == 0x903)) // RevoMini1 supporetd by RevoMini2 firmware { // These firmwares are designed to be backwards compatible } else if (firmwareBoard != board) { status("Error: firmware does not match board", STATUSICON_FAIL); myDevice->updateButton->setEnabled(true); return; } // Check the firmware embedded in the file: QByteArray firmwareHash = desc.mid(40,20); QByteArray fileHash = QCryptographicHash::hash(loadedFW.left(loadedFW.length()-100), QCryptographicHash::Sha1); if (firmwareHash != fileHash) { status("Error: firmware file corrupt", STATUSICON_FAIL); myDevice->updateButton->setEnabled(true); return; } } else { // The firmware is not packaged, just upload the text in the description field // if it is there. descriptionArray.clear(); } status("Starting firmware upload", STATUSICON_RUNNING); // We don't know which device was used previously, so we // are cautious and reenter DFU for this deviceID: emit uploadStarted(); if(!m_dfu->enterDFU(deviceID)) { status("Error:Could not enter DFU mode", STATUSICON_FAIL); myDevice->updateButton->setEnabled(true); emit uploadEnded(false); return; } OP_DFU::Status ret=m_dfu->StatusRequest(); qDebug() << m_dfu->StatusToString(ret); m_dfu->AbortOperation(); // Necessary, otherwise I get random failures. connect(m_dfu, SIGNAL(progressUpdated(int)), this, SLOT(setProgress(int))); connect(m_dfu, SIGNAL(operationProgress(QString)), this, SLOT(dfuStatus(QString))); connect(m_dfu, SIGNAL(uploadFinished(OP_DFU::Status)), this, SLOT(uploadFinished(OP_DFU::Status))); bool retstatus = m_dfu->UploadFirmware(filename,verify, deviceID); if(!retstatus ) { status("Could not start upload", STATUSICON_FAIL); myDevice->updateButton->setEnabled(true); emit uploadEnded(false); return; } status("Uploading, please wait...", STATUSICON_RUNNING); }