mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
GCS-side implementation: if a firmware is package with description 100 byte bin blob at the end, it will use it, and parse it back
if description is structured the same way.
This commit is contained in:
parent
b61bd5bf31
commit
4af0c562e3
@ -117,9 +117,16 @@ void deviceWidget::populate()
|
||||
|
||||
int size=((OP_DFU::device)m_dfu->devices[deviceID]).SizeOfDesc;
|
||||
m_dfu->enterDFU(deviceID);
|
||||
QByteArray desc = m_dfu->DownloadDescriptionAsBA(size);
|
||||
if (! populateStructuredDescription(desc)) {
|
||||
// desc was not a structured description
|
||||
QString str = m_dfu->DownloadDescription(size);
|
||||
myDevice->description->setMaxLength(size);
|
||||
myDevice->description->setText(str.left(str.indexOf(QChar(255))));
|
||||
myDevice->buildDate->setText("Warning: development firmware");
|
||||
myDevice->commitTag->setText("");
|
||||
}
|
||||
|
||||
|
||||
status("Ready...", STATUSICON_INFO);
|
||||
|
||||
@ -137,6 +144,51 @@ void deviceWidget::freeze()
|
||||
myDevice->retrieveButton->setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Populates the widget field with the description in case
|
||||
it is structured properly
|
||||
*/
|
||||
bool deviceWidget::populateStructuredDescription(QByteArray desc)
|
||||
{
|
||||
if (desc.startsWith("OpFw")) {
|
||||
// This looks like a binary with a description at the end
|
||||
/*
|
||||
# 4 bytes: header: "OpFw"
|
||||
# 4 bytes: GIT commit tag (short version of SHA1)
|
||||
# 4 bytes: Unix timestamp of compile time
|
||||
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
|
||||
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded
|
||||
# ---- 40 bytes limit ---
|
||||
# 20 bytes: SHA1 sum of the firmware.
|
||||
# 40 bytes: free for now.
|
||||
*/
|
||||
// I don't want to use structs, ok ?
|
||||
quint32 gitCommitTag = desc.at(4)&0xFF;
|
||||
for (int i=1;i<4;i++) {
|
||||
gitCommitTag = gitCommitTag<<8;
|
||||
gitCommitTag += desc.at(4+i) & 0xFF;
|
||||
}
|
||||
myDevice->commitTag->setText("GIT tag 0x" + QString::number(gitCommitTag,16));
|
||||
quint32 buildDate = desc.at(8)&0xFF;
|
||||
for (int i=1;i<4;i++) {
|
||||
buildDate = buildDate<<8;
|
||||
buildDate += desc.at(8+i) & 0xFF;
|
||||
}
|
||||
|
||||
myDevice->buildDate->setText(QString("Build time: ") + QDateTime::fromTime_t(buildDate).toString());
|
||||
QByteArray targetPlatform = desc.mid(12,2);
|
||||
// TODO: check platform compatibility
|
||||
QString dscText = QString(desc.mid(14,26));
|
||||
myDevice->description->setText(dscText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Updates status message for messages coming from DFU
|
||||
*/
|
||||
@ -199,8 +251,6 @@ void deviceWidget::uploadFirmware()
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO : parse the firmware last 100 bytes and see whether it is
|
||||
// packaged:
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
status("Can't open file", STATUSICON_FAIL);
|
||||
@ -209,36 +259,11 @@ void deviceWidget::uploadFirmware()
|
||||
|
||||
QByteArray arr = file.readAll();
|
||||
QByteArray desc = arr.right(100);
|
||||
if (desc.startsWith("OpFw")) {
|
||||
// This looks like a binary with a description at the end
|
||||
/*
|
||||
# 4 bytes: header: "OpFw"
|
||||
# 4 bytes: GIT commit tag (short version of SHA1)
|
||||
# 4 bytes: Unix timestamp of compile time
|
||||
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
|
||||
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded
|
||||
# ---- 40 bytes limit ---
|
||||
# 20 bytes: SHA1 sum of the firmware.
|
||||
# 40 bytes: free for now.
|
||||
*/
|
||||
// I don't want to use structs, ok ?
|
||||
QByteArray gitCommitTag = desc.mid(4,4);
|
||||
quint32 buildDate = desc.at(8)&0xFF;
|
||||
for (int i=1;i<4;i++) {
|
||||
buildDate = buildDate<<8;
|
||||
buildDate += desc.at(8+i) & 0xFF;
|
||||
}
|
||||
|
||||
myDevice->buildDate->setText(QDateTime::fromTime_t(buildDate).toString());
|
||||
QByteArray targetPlatform = desc.mid(12,2);
|
||||
// TODO: check platform compatibility
|
||||
QString dscText = QString(desc.mid(14,26));
|
||||
myDevice->description->setText(dscText);
|
||||
|
||||
return;
|
||||
|
||||
if (populateStructuredDescription(desc)) {
|
||||
descriptionArray = desc;
|
||||
} else {
|
||||
// TODO : tell the user that the firmware is not packaged.
|
||||
descriptionArray.clear();
|
||||
}
|
||||
|
||||
|
||||
@ -320,7 +345,18 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus)
|
||||
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
|
||||
return;
|
||||
} else
|
||||
if(!myDevice->description->text().isEmpty()) {
|
||||
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) {
|
||||
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
|
||||
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());
|
||||
@ -329,6 +365,7 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status("Upload successful", STATUSICON_OK);
|
||||
|
||||
}
|
||||
|
@ -59,7 +59,9 @@ private:
|
||||
QByteArray downloadedFirmware;
|
||||
QString filename;
|
||||
QGraphicsSvgItem *devicePic;
|
||||
QByteArray descriptionArray;
|
||||
void status(QString str, StatusIcon ic);
|
||||
bool populateStructuredDescription(QByteArray arr);
|
||||
|
||||
|
||||
signals:
|
||||
|
@ -137,17 +137,17 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="buildDate">
|
||||
<property name="text">
|
||||
<string>Compile Date</string>
|
||||
<string>Build Date</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="commitTag">
|
||||
<property name="text">
|
||||
<string>Commit tag:</string>
|
||||
<string>Commit tag</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -276,9 +276,13 @@ bool DFUObject::UploadData(qint32 const & numberOfBytes, QByteArray & data)
|
||||
/**
|
||||
Sends the firmware description to the device
|
||||
*/
|
||||
OP_DFU::Status DFUObject::UploadDescription(QString description)
|
||||
OP_DFU::Status DFUObject::UploadDescription(QVariant desc)
|
||||
{
|
||||
cout<<"Starting uploading description\n";
|
||||
QByteArray array;
|
||||
|
||||
if (desc.type() == QMetaType::QString) {
|
||||
QString description = desc.toString();
|
||||
if(description.length()%4!=0)
|
||||
{
|
||||
int pad=description.length()/4;
|
||||
@ -288,10 +292,15 @@ OP_DFU::Status DFUObject::UploadDescription(QString description)
|
||||
padding.fill(' ',pad);
|
||||
description.append(padding);
|
||||
}
|
||||
if(!StartUpload(description.length(),OP_DFU::Descript,0))
|
||||
array=description.toAscii();
|
||||
|
||||
} else if (desc.type() == QMetaType::QByteArray) {
|
||||
array = desc.toByteArray();
|
||||
}
|
||||
|
||||
if(!StartUpload(array.length(),OP_DFU::Descript,0))
|
||||
return OP_DFU::abort;
|
||||
QByteArray array=description.toAscii();
|
||||
if(!UploadData(description.length(),array))
|
||||
if(!UploadData(array.length(),array))
|
||||
{
|
||||
return OP_DFU::abort;
|
||||
}
|
||||
@ -301,6 +310,7 @@ OP_DFU::Status DFUObject::UploadDescription(QString description)
|
||||
}
|
||||
OP_DFU::Status ret = StatusRequest();
|
||||
|
||||
|
||||
if(debug)
|
||||
qDebug() << "Upload description Status=" << StatusToString(ret);
|
||||
return ret;
|
||||
@ -321,6 +331,15 @@ QString DFUObject::DownloadDescription(int const & numberOfChars)
|
||||
|
||||
}
|
||||
|
||||
QByteArray DFUObject::DownloadDescriptionAsBA(int const & numberOfChars)
|
||||
{
|
||||
|
||||
QByteArray arr;
|
||||
StartDownloadT(&arr, numberOfChars,OP_DFU::Descript);
|
||||
return arr;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Starts a firmware download
|
||||
@param firmwareArray: pointer to the location where we should store the firmware
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <QMetaType>
|
||||
#include <QCryptographicHash>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <iostream>
|
||||
#include "delay.h"
|
||||
#include <qextserialport/src/qextserialport.h>
|
||||
@ -124,12 +125,13 @@ namespace OP_DFU {
|
||||
bool ready() { return mready; }
|
||||
|
||||
// Upload (send to device) commands
|
||||
OP_DFU::Status UploadDescription(QString description);
|
||||
OP_DFU::Status UploadDescription(QVariant description);
|
||||
bool UploadFirmware(const QString &sfile, const bool &verify,int device);
|
||||
|
||||
// Download (get from device) commands:
|
||||
// DownloadDescription is synchronous
|
||||
QString DownloadDescription(int const & numberOfChars);
|
||||
QByteArray DownloadDescriptionAsBA(int const & numberOfChars);
|
||||
// Asynchronous firmware download: initiates fw download,
|
||||
// and a downloadFinished signal is emitted when download
|
||||
// if finished:
|
||||
|
Loading…
Reference in New Issue
Block a user