/**
  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);
}
Exemple #2
0
/**
  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);
}