1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-30 15:52:12 +01:00

LP-597 Progress bar for GCS log replay - ensure the index vectors are emptied before adding elements to them. Caused problem when replaying multiple logfiles successively.

- Bugfix: ensure the index vectors are emptied before adding elements to them. Caused problem when replaying multiple logfiles successively.
- extra validations while indexing the logfile
- Define TIMESTAMP_SIZE_BYTES and use that instead of the hardcoded timestamp size of 4 bytes.
- modify variable case: updateBeginAndEndtimes -> updateBeginAndEndTimes
- improve qWarning messages for logfile.cpp: add the name of the function because we read the logfile in two separate functions.
This commit is contained in:
Jan NIJS 2018-04-29 16:27:51 +02:00
parent ef3cb8bf46
commit d540c2a043
4 changed files with 58 additions and 31 deletions

View File

@ -29,6 +29,8 @@
#include <QDataStream> #include <QDataStream>
#include <QThread> // DEBUG: to display the thread ID #include <QThread> // DEBUG: to display the thread ID
#define TIMESTAMP_SIZE_BYTES 4
LogFile::LogFile(QObject *parent) : QIODevice(parent), LogFile::LogFile(QObject *parent) : QIODevice(parent),
m_timer(this), m_timer(this),
m_previousTimeStamp(0), m_previousTimeStamp(0),
@ -156,7 +158,7 @@ void LogFile::timerFired()
} }
m_timer_tick++; m_timer_tick++;
if (m_file.bytesAvailable() > 4) { if (m_file.bytesAvailable() > TIMESTAMP_SIZE_BYTES) {
int time; int time;
time = m_myTime.elapsed(); time = m_myTime.elapsed();
@ -182,7 +184,7 @@ void LogFile::timerFired()
// read data size // read data size
qint64 dataSize; qint64 dataSize;
if (m_file.bytesAvailable() < (qint64)sizeof(dataSize)) { if (m_file.bytesAvailable() < (qint64)sizeof(dataSize)) {
qDebug() << "LogFile - end of log file reached"; qDebug() << "LogFile replay - end of log file reached";
stopReplay(); stopReplay();
return; return;
} }
@ -190,14 +192,14 @@ void LogFile::timerFired()
// check size consistency // check size consistency
if (dataSize < 1 || dataSize > (1024 * 1024)) { if (dataSize < 1 || dataSize > (1024 * 1024)) {
qWarning() << "LogFile - corrupted log file! Unlikely packet size:" << dataSize; qWarning() << "LogFile replay - corrupted log file! Unlikely packet size:" << dataSize;
stopReplay(); stopReplay();
return; return;
} }
// read data // read data
if (m_file.bytesAvailable() < dataSize) { if (m_file.bytesAvailable() < dataSize) {
qDebug() << "LogFile - end of log file reached"; qDebug() << "LogFile replay - end of log file reached";
stopReplay(); stopReplay();
return; return;
} }
@ -216,7 +218,7 @@ void LogFile::timerFired()
} }
// read next timestamp // read next timestamp
if (m_file.bytesAvailable() < (qint64)sizeof(m_nextTimeStamp)) { if (m_file.bytesAvailable() < (qint64)sizeof(m_nextTimeStamp)) {
qDebug() << "LogFile - end of log file reached"; qDebug() << "LogFile replay - end of log file reached";
stopReplay(); stopReplay();
return; return;
} }
@ -226,7 +228,7 @@ void LogFile::timerFired()
// some validity checks // some validity checks
if ((m_nextTimeStamp < m_previousTimeStamp) // logfile goes back in time if ((m_nextTimeStamp < m_previousTimeStamp) // logfile goes back in time
|| ((m_nextTimeStamp - m_previousTimeStamp) > 60 * 60 * 1000)) { // gap of more than 60 minutes || ((m_nextTimeStamp - m_previousTimeStamp) > 60 * 60 * 1000)) { // gap of more than 60 minutes
qWarning() << "LogFile - corrupted log file! Unlikely timestamp:" << m_nextTimeStamp << "after" << m_previousTimeStamp; qWarning() << "LogFile replay - corrupted log file! Unlikely timestamp:" << m_nextTimeStamp << "after" << m_previousTimeStamp;
stopReplay(); stopReplay();
return; return;
} }
@ -235,7 +237,7 @@ void LogFile::timerFired()
time = m_myTime.elapsed(); // number of milliseconds since start of playback time = m_myTime.elapsed(); // number of milliseconds since start of playback
} }
} else { } else {
qDebug() << "LogFile - end of log file reached"; qDebug() << "LogFile replay - end of log file reached";
stopReplay(); stopReplay();
} }
} }
@ -324,12 +326,12 @@ bool LogFile::stopReplay()
* If no position is given, resumes from the last position * If no position is given, resumes from the last position
* *
*/ */
bool LogFile::resumeReplay(quint32 desiredPosition) bool LogFile::resumeReplay(quint32 desiredPosition)
{ {
if (m_timer.isActive()) { if (m_timer.isActive()) {
return false; return false;
} }
qDebug() << "LogFile - resumeReplay";
// Clear the playout buffer: // Clear the playout buffer:
m_mutex.lock(); m_mutex.lock();
@ -346,7 +348,11 @@ bool LogFile::resumeReplay(quint32 desiredPosition)
for (int i = 0; i < m_timeStamps.size(); i++) { for (int i = 0; i < m_timeStamps.size(); i++) {
if (m_timeStamps.at(i) >= desiredPosition) { if (m_timeStamps.at(i) >= desiredPosition) {
m_file.seek(m_timeStampPositions.at(i)); int bytesToSkip = m_timeStampPositions.at(i);
bool seek_ok = m_file.seek(bytesToSkip);
if (!seek_ok) {
qWarning() << "LogFile resumeReplay - an error occurred while seeking through the logfile.";
}
m_lastPlayed = m_timeStamps.at(i); m_lastPlayed = m_timeStamps.at(i);
break; break;
} }
@ -401,6 +407,7 @@ bool LogFile::pauseAndResetPosition()
if (!m_file.isOpen() || !m_timer.isActive()) { if (!m_file.isOpen() || !m_timer.isActive()) {
return false; return false;
} }
qDebug() << "LogFile - pauseAndResetPosition";
m_timer.stop(); m_timer.stop();
m_replayStatus = STOPPED; m_replayStatus = STOPPED;
@ -426,11 +433,11 @@ ReplayState LogFile::getReplayStatus()
/** /**
* FUNCTION: buildIndex() * FUNCTION: buildIndex()
* *
* Walk through the opened logfile and sets the start and end position timestamps * Walk through the opened logfile and stores the first and last position timestamps.
* Also builds an index for quickly skipping to a specific position in the logfile. * Also builds an index for quickly skipping to a specific position in the logfile.
* *
* returns true when indexing has completed successfully * Returns true when indexing has completed successfully.
* returns false when a problem was encountered * Returns false when a problem was encountered.
* *
*/ */
bool LogFile::buildIndex() bool LogFile::buildIndex()
@ -439,18 +446,28 @@ bool LogFile::buildIndex()
qint64 totalSize; qint64 totalSize;
qint64 readPointer = 0; qint64 readPointer = 0;
quint64 index = 0; quint64 index = 0;
int bytesRead = 0;
qDebug() << "LogFile - buildIndex";
// Ensure empty vectors:
m_timeStampPositions.clear();
m_timeStamps.clear();
QByteArray arr = m_file.readAll(); QByteArray arr = m_file.readAll();
totalSize = arr.size(); totalSize = arr.size();
QDataStream dataStream(&arr, QIODevice::ReadOnly); QDataStream dataStream(&arr, QIODevice::ReadOnly);
// set the start timestamp // set the first timestamp
if (totalSize - readPointer >= 4) { if (totalSize - readPointer >= TIMESTAMP_SIZE_BYTES) {
dataStream.readRawData((char *)&timeStamp, 4); bytesRead = dataStream.readRawData((char *)&timeStamp, TIMESTAMP_SIZE_BYTES);
if (bytesRead != TIMESTAMP_SIZE_BYTES) {
qWarning() << "LogFile buildIndex - read first timeStamp: readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false;
}
m_timeStamps.append(timeStamp); m_timeStamps.append(timeStamp);
m_timeStampPositions.append(readPointer); m_timeStampPositions.append(readPointer);
readPointer += 4; readPointer += TIMESTAMP_SIZE_BYTES;
index++; index++;
m_beginTimeStamp = timeStamp; m_beginTimeStamp = timeStamp;
m_endTimeStamp = timeStamp; m_endTimeStamp = timeStamp;
@ -461,22 +478,27 @@ bool LogFile::buildIndex()
// Check if there are enough bytes remaining for a correct "dataSize" field // Check if there are enough bytes remaining for a correct "dataSize" field
if (totalSize - readPointer < (qint64)sizeof(dataSize)) { if (totalSize - readPointer < (qint64)sizeof(dataSize)) {
qDebug() << "Error: Logfile corrupted! Unexpected end of file"; qWarning() << "LogFile buildIndex - logfile corrupted! Unexpected end of file";
return false;
}
// Read the dataSize field and check for I/O errors
bytesRead = dataStream.readRawData((char *)&dataSize, sizeof(dataSize));
if (bytesRead != sizeof(dataSize)) {
qWarning() << "LogFile buildIndex - read dataSize: readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false; return false;
} }
// Read the dataSize field
dataStream.readRawData((char *)&dataSize, sizeof(dataSize));
readPointer += sizeof(dataSize); readPointer += sizeof(dataSize);
if (dataSize < 1 || dataSize > (1024 * 1024)) { if (dataSize < 1 || dataSize > (1024 * 1024)) {
qDebug() << "Error: Logfile corrupted! Unlikely packet size: " << dataSize << "\n"; qWarning() << "LogFile buildIndex - logfile corrupted! Unlikely packet size: " << dataSize << "\n";
return false; return false;
} }
// Check if there are enough bytes remaining // Check if there are enough bytes remaining
if (totalSize - readPointer < dataSize) { if (totalSize - readPointer < dataSize) {
qDebug() << "Error: Logfile corrupted! Unexpected end of file"; qWarning() << "LogFile buildIndex - logfile corrupted! Unexpected end of file";
return false; return false;
} }
@ -484,18 +506,23 @@ bool LogFile::buildIndex()
readPointer += dataStream.skipRawData(dataSize); readPointer += dataStream.skipRawData(dataSize);
// read the next timestamp // read the next timestamp
if (totalSize - readPointer >= 4) { if (totalSize - readPointer >= TIMESTAMP_SIZE_BYTES) {
dataStream.readRawData((char *)&timeStamp, 4); bytesRead = dataStream.readRawData((char *)&timeStamp, TIMESTAMP_SIZE_BYTES);
if (bytesRead != TIMESTAMP_SIZE_BYTES) {
qWarning() << "LogFile buildIndex - read timeStamp, readRawData returned unexpected number of bytes:" << bytesRead << "at position" << readPointer << "\n";
return false;
}
// some validity checks // some validity checks
if (timeStamp < m_endTimeStamp // logfile goes back in time if (timeStamp < m_endTimeStamp // logfile goes back in time
|| (timeStamp - m_endTimeStamp) > (60 * 60 * 1000)) { // gap of more than 60 minutes) || (timeStamp - m_endTimeStamp) > (60 * 60 * 1000)) { // gap of more than 60 minutes)
qDebug() << "Error: Logfile corrupted! Unlikely timestamp " << timeStamp << " after " << m_endTimeStamp; qWarning() << "LogFile buildIndex - logfile corrupted! Unlikely timestamp " << timeStamp << " after " << m_endTimeStamp;
return false;
} }
m_timeStamps.append(timeStamp); m_timeStamps.append(timeStamp);
m_timeStampPositions.append(readPointer); m_timeStampPositions.append(readPointer);
readPointer += 4; readPointer += TIMESTAMP_SIZE_BYTES;
index++; index++;
m_endTimeStamp = timeStamp; m_endTimeStamp = timeStamp;
} else { } else {
@ -504,7 +531,7 @@ bool LogFile::buildIndex()
} }
} }
emit updateBeginAndEndtimes(m_beginTimeStamp, m_endTimeStamp); emit updateBeginAndEndTimes(m_beginTimeStamp, m_endTimeStamp);
// reset the read pointer to the start of the file // reset the read pointer to the start of the file
m_file.seek(0); m_file.seek(0);

View File

@ -100,7 +100,7 @@ signals:
void replayStarted(); void replayStarted();
void replayFinished(); void replayFinished();
void playbackPosition(quint32); void playbackPosition(quint32);
void updateBeginAndEndtimes(quint32, quint32); void updateBeginAndEndTimes(quint32, quint32);
protected: protected:
QByteArray m_dataBuffer; QByteArray m_dataBuffer;

View File

@ -79,7 +79,7 @@ void LoggingGadgetWidget::setPlugin(LoggingPlugin *p)
// Feedback from logfile to GUI // Feedback from logfile to GUI
connect(loggingPlugin, &LoggingPlugin::stateChanged, this, &LoggingGadgetWidget::stateChanged); connect(loggingPlugin, &LoggingPlugin::stateChanged, this, &LoggingGadgetWidget::stateChanged);
connect(logFile, &LogFile::updateBeginAndEndtimes, this, &LoggingGadgetWidget::updateBeginAndEndtimes); connect(logFile, &LogFile::updateBeginAndEndTimes, this, &LoggingGadgetWidget::updateBeginAndEndTimes);
connect(logFile, &LogFile::playbackPosition, this, &LoggingGadgetWidget::playbackPosition); connect(logFile, &LogFile::playbackPosition, this, &LoggingGadgetWidget::playbackPosition);
connect(logFile, &LogFile::replayStarted, this, &LoggingGadgetWidget::enableButtons); connect(logFile, &LogFile::replayStarted, this, &LoggingGadgetWidget::enableButtons);
connect(logFile, &LogFile::replayFinished, this, &LoggingGadgetWidget::disableButtons); connect(logFile, &LogFile::replayFinished, this, &LoggingGadgetWidget::disableButtons);
@ -174,7 +174,7 @@ void LoggingGadgetWidget::stateChanged(LoggingPlugin::State state)
} }
} }
void LoggingGadgetWidget::updateBeginAndEndtimes(quint32 startTimeStamp, quint32 endTimeStamp) void LoggingGadgetWidget::updateBeginAndEndTimes(quint32 startTimeStamp, quint32 endTimeStamp)
{ {
int startSec, startMin, endSec, endMin; int startSec, startMin, endSec, endMin;

View File

@ -49,7 +49,7 @@ public:
protected slots: protected slots:
void stateChanged(LoggingPlugin::State state); void stateChanged(LoggingPlugin::State state);
void updateBeginAndEndtimes(quint32 startTimeStamp, quint32 endTimeStamp); void updateBeginAndEndTimes(quint32 startTimeStamp, quint32 endTimeStamp);
void playbackPosition(quint32 positionTimeStamp); void playbackPosition(quint32 positionTimeStamp);
void playPauseButtonAction(); void playPauseButtonAction();
void stopButtonAction(); void stopButtonAction();