1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-11-15 20:54:19 -05:00

SigMF file input: REST API: implemented actions and fixes

This commit is contained in:
f4exb 2020-06-17 01:39:10 +02:00
parent c75e4ec64b
commit 3fc326d7ed
2 changed files with 198 additions and 59 deletions

View File

@ -30,9 +30,10 @@
#include "libsigmf/sigmf.h" #include "libsigmf/sigmf.h"
#include "SWGDeviceSettings.h" #include "SWGDeviceSettings.h"
#include "SWGFileInputSettings.h" #include "SWGSigMFFileInputSettings.h"
#include "SWGDeviceState.h" #include "SWGDeviceState.h"
#include "SWGDeviceReport.h" #include "SWGDeviceReport.h"
#include "SWGDeviceActions.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "dsp/dspdevicesourceengine.h" #include "dsp/dspdevicesourceengine.h"
@ -65,6 +66,9 @@ SigMFFileInput::SigMFFileInput(DeviceAPI *deviceAPI) :
m_trackMode(false), m_trackMode(false),
m_currentTrackIndex(0), m_currentTrackIndex(0),
m_recordOpen(false), m_recordOpen(false),
m_crcAvailable(false),
m_crcOK(false),
m_recordLengthOK(false),
m_fileInputThread(nullptr), m_fileInputThread(nullptr),
m_deviceDescription(), m_deviceDescription(),
m_sampleRate(48000), m_sampleRate(48000),
@ -154,10 +158,11 @@ bool SigMFFileInput::openFileStreams(const QString& fileName)
if (m_metaInfo.m_sha512.size() != 0) if (m_metaInfo.m_sha512.size() != 0)
{ {
qDebug("SigMFFileInput::openFileStreams: compute SHA512"); qDebug("SigMFFileInput::openFileStreams: compute SHA512");
m_crcAvailable = true;
std::string sha512 = sw::sha512::file(dataFileName.toStdString()); std::string sha512 = sw::sha512::file(dataFileName.toStdString());
bool crcOK = m_metaInfo.m_sha512 == QString::fromStdString(sha512); m_crcOK = m_metaInfo.m_sha512 == QString::fromStdString(sha512);
if (crcOK) { if (m_crcOK) {
qDebug("SigMFFileInput::openFileStreams: SHA512 OK: %s", sha512.c_str()); qDebug("SigMFFileInput::openFileStreams: SHA512 OK: %s", sha512.c_str());
} else { } else {
qCritical("SigMFFileInput::openFileStreams: bad SHA512: %s expected: %s", sha512.c_str(), qPrintable(m_metaInfo.m_sha512)); qCritical("SigMFFileInput::openFileStreams: bad SHA512: %s expected: %s", sha512.c_str(), qPrintable(m_metaInfo.m_sha512));
@ -165,18 +170,23 @@ bool SigMFFileInput::openFileStreams(const QString& fileName)
if (getMessageQueueToGUI()) if (getMessageQueueToGUI())
{ {
MsgReportCRC *report = MsgReportCRC::create(crcOK); MsgReportCRC *report = MsgReportCRC::create(m_crcOK);
getMessageQueueToGUI()->push(report); getMessageQueueToGUI()->push(report);
} }
if (!crcOK) { if (!m_crcOK) {
return false; return false;
} }
} }
else
{
m_crcAvailable = false;
}
bool totalSamplesCheck = (m_metaInfo.m_totalSamples == m_captures.back().m_sampleStart + m_captures.back().m_length);
if (totalSamplesCheck) { m_recordLengthOK = (m_metaInfo.m_totalSamples == m_captures.back().m_sampleStart + m_captures.back().m_length);
if (m_recordLengthOK) {
qDebug("SigMFFileInput::openFileStreams: total samples OK"); qDebug("SigMFFileInput::openFileStreams: total samples OK");
} else { } else {
qCritical("SigMFFileInput::openFileStreams: invalid total samples: meta: %lu data: %lu", qCritical("SigMFFileInput::openFileStreams: invalid total samples: meta: %lu data: %lu",
@ -185,7 +195,7 @@ bool SigMFFileInput::openFileStreams(const QString& fileName)
if (getMessageQueueToGUI()) if (getMessageQueueToGUI())
{ {
MsgReportTotalSamplesCheck *report = MsgReportTotalSamplesCheck::create(totalSamplesCheck); MsgReportTotalSamplesCheck *report = MsgReportTotalSamplesCheck::create(m_recordLengthOK);
getMessageQueueToGUI()->push(report); getMessageQueueToGUI()->push(report);
} }
@ -798,6 +808,9 @@ bool SigMFFileInput::applySettings(const SigMFFileInputSettings& settings, bool
if ((m_settings.m_trackLoop != settings.m_trackLoop)) { if ((m_settings.m_trackLoop != settings.m_trackLoop)) {
reverseAPIKeys.append("trackLoop"); reverseAPIKeys.append("trackLoop");
} }
if ((m_settings.m_trackLoop != settings.m_fullLoop)) {
reverseAPIKeys.append("fullLoop");
}
if ((m_settings.m_fileName != settings.m_fileName)) if ((m_settings.m_fileName != settings.m_fileName))
{ {
@ -823,8 +836,8 @@ int SigMFFileInput::webapiSettingsGet(
QString& errorMessage) QString& errorMessage)
{ {
(void) errorMessage; (void) errorMessage;
response.setFileInputSettings(new SWGSDRangel::SWGFileInputSettings()); response.setSigMfFileInputSettings(new SWGSDRangel::SWGSigMFFileInputSettings());
response.getFileInputSettings()->init(); response.getSigMfFileInputSettings()->init();
webapiFormatDeviceSettings(response, m_settings); webapiFormatDeviceSettings(response, m_settings);
return 200; return 200;
} }
@ -858,25 +871,28 @@ void SigMFFileInput::webapiUpdateDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response) SWGSDRangel::SWGDeviceSettings& response)
{ {
if (deviceSettingsKeys.contains("fileName")) { if (deviceSettingsKeys.contains("fileName")) {
settings.m_fileName = *response.getFileInputSettings()->getFileName(); settings.m_fileName = *response.getSigMfFileInputSettings()->getFileName();
} }
if (deviceSettingsKeys.contains("accelerationFactor")) { if (deviceSettingsKeys.contains("accelerationFactor")) {
settings.m_accelerationFactor = response.getFileInputSettings()->getAccelerationFactor(); settings.m_accelerationFactor = response.getSigMfFileInputSettings()->getAccelerationFactor();
} }
if (deviceSettingsKeys.contains("trackLoop")) { if (deviceSettingsKeys.contains("trackLoop")) {
settings.m_trackLoop = response.getFileInputSettings()->getLoop() != 0; settings.m_trackLoop = response.getSigMfFileInputSettings()->getTrackLoop() != 0;
}
if (deviceSettingsKeys.contains("fullLoop")) {
settings.m_trackLoop = response.getSigMfFileInputSettings()->getFullLoop() != 0;
} }
if (deviceSettingsKeys.contains("useReverseAPI")) { if (deviceSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getFileInputSettings()->getUseReverseApi() != 0; settings.m_useReverseAPI = response.getSigMfFileInputSettings()->getUseReverseApi() != 0;
} }
if (deviceSettingsKeys.contains("reverseAPIAddress")) { if (deviceSettingsKeys.contains("reverseAPIAddress")) {
settings.m_reverseAPIAddress = *response.getFileInputSettings()->getReverseApiAddress(); settings.m_reverseAPIAddress = *response.getSigMfFileInputSettings()->getReverseApiAddress();
} }
if (deviceSettingsKeys.contains("reverseAPIPort")) { if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getFileInputSettings()->getReverseApiPort(); settings.m_reverseAPIPort = response.getSigMfFileInputSettings()->getReverseApiPort();
} }
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) { if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getFileInputSettings()->getReverseApiDeviceIndex(); settings.m_reverseAPIDeviceIndex = response.getSigMfFileInputSettings()->getReverseApiDeviceIndex();
} }
} }
@ -913,63 +929,175 @@ int SigMFFileInput::webapiReportGet(
QString& errorMessage) QString& errorMessage)
{ {
(void) errorMessage; (void) errorMessage;
response.setFileInputReport(new SWGSDRangel::SWGFileInputReport()); response.setSigMfFileInputReport(new SWGSDRangel::SWGSigMFFileInputReport());
response.getFileInputReport()->init(); response.getSigMfFileInputReport()->init();
webapiFormatDeviceReport(response); webapiFormatDeviceReport(response);
return 200; return 200;
} }
int SigMFFileInput::webapiActionsPost(
const QStringList& deviceActionsKeys,
SWGSDRangel::SWGDeviceActions& query,
QString& errorMessage)
{
SWGSDRangel::SWGSigMFFileInputActions *swgSigMFFileInputActions = query.getSigMfFileInputActions();
if (swgSigMFFileInputActions)
{
if (deviceActionsKeys.contains("playTrack"))
{
bool play = swgSigMFFileInputActions->getPlayTrack() != 0;
MsgConfigureTrackWork * msg = MsgConfigureTrackWork::create(play);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgConfigureTrackWork *msgToGUI = MsgConfigureTrackWork::create(play);
getMessageQueueToGUI()->push(msgToGUI);
}
}
else if (deviceActionsKeys.contains("playRecord"))
{
bool play = swgSigMFFileInputActions->getPlayRecord() != 0;
MsgConfigureFileWork * msg = MsgConfigureFileWork::create(play);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgConfigureFileWork *msgToGUI = MsgConfigureFileWork::create(play);
getMessageQueueToGUI()->push(msgToGUI);
}
}
else if (deviceActionsKeys.contains("seekTrack"))
{
int trackIndex = swgSigMFFileInputActions->getSeekTrack();
MsgConfigureTrackIndex *msg = MsgConfigureTrackIndex::create(trackIndex);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgConfigureTrackIndex *msgToGUI = MsgConfigureTrackIndex::create(trackIndex);
getMessageQueueToGUI()->push(msgToGUI);
}
}
else if (deviceActionsKeys.contains("seekTrackMillis"))
{
int trackMillis = swgSigMFFileInputActions->getSeekTrackMillis();
MsgConfigureTrackSeek *msg = MsgConfigureTrackSeek::create(trackMillis);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgConfigureTrackSeek *msgToGUI = MsgConfigureTrackSeek::create(trackMillis);
getMessageQueueToGUI()->push(msgToGUI);
}
}
else if (deviceActionsKeys.contains("seekRecordMillis"))
{
int recordMillis = swgSigMFFileInputActions->getSeekRecordMillis();
MsgConfigureFileSeek *msg = MsgConfigureFileSeek::create(recordMillis);
getInputMessageQueue()->push(msg);
if (getMessageQueueToGUI())
{
MsgConfigureFileSeek *msgToGUI = MsgConfigureFileSeek::create(recordMillis);
getMessageQueueToGUI()->push(msgToGUI);
}
}
return 202;
}
else
{
errorMessage = "Missing AirspyActions in query";
return 400;
}
}
void SigMFFileInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SigMFFileInputSettings& settings) void SigMFFileInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SigMFFileInputSettings& settings)
{ {
response.getFileInputSettings()->setFileName(new QString(settings.m_fileName)); response.getSigMfFileInputSettings()->setFileName(new QString(settings.m_fileName));
response.getFileInputSettings()->setAccelerationFactor(settings.m_accelerationFactor); response.getSigMfFileInputSettings()->setAccelerationFactor(settings.m_accelerationFactor);
response.getFileInputSettings()->setLoop(settings.m_trackLoop ? 1 : 0); response.getSigMfFileInputSettings()->setTrackLoop(settings.m_trackLoop ? 1 : 0);
response.getSigMfFileInputSettings()->setFullLoop(settings.m_fullLoop ? 1 : 0);
response.getFileInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); response.getSigMfFileInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getFileInputSettings()->getReverseApiAddress()) { if (response.getSigMfFileInputSettings()->getReverseApiAddress()) {
*response.getFileInputSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; *response.getSigMfFileInputSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else { } else {
response.getFileInputSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); response.getSigMfFileInputSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
} }
response.getFileInputSettings()->setReverseApiPort(settings.m_reverseAPIPort); response.getSigMfFileInputSettings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getFileInputSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); response.getSigMfFileInputSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
} }
void SigMFFileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) void SigMFFileInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response)
{ {
qint64 t_sec = 0; if (!m_metaStream.is_open()) {
qint64 t_msec = 0; return;
quint64 samplesCount = 0; }
response.getSigMfFileInputReport()->setSampleSize(m_metaInfo.m_dataType.m_sampleBits);
response.getSigMfFileInputReport()->setSampleBytes(m_sampleBytes);
response.getSigMfFileInputReport()->setSampleFormat(m_metaInfo.m_dataType.m_floatingPoint ? 1 : 0);
response.getSigMfFileInputReport()->setSampleSigned(m_metaInfo.m_dataType.m_signed ? 1 : 0);
response.getSigMfFileInputReport()->setSampleSwapIq(m_metaInfo.m_dataType.m_swapIQ ? 1 : 0);
response.getSigMfFileInputReport()->setCrcStatus(!m_crcAvailable ? 0 : m_crcOK ? 1 : 2);
response.getSigMfFileInputReport()->setTotalBytesStatus(m_recordLengthOK);
response.getSigMfFileInputReport()->setTrackNumber(m_currentTrackIndex);
QList<SigMFFileCapture>::const_iterator it = m_captures.begin();
if (response.getSigMfFileInputReport()->getCaptures()) {
response.getSigMfFileInputReport()->getCaptures()->clear();
} else {
response.getSigMfFileInputReport()->setCaptures(new QList<SWGSDRangel::SWGCapture*>);
}
for (; it != m_captures.end(); ++it)
{
response.getSigMfFileInputReport()->getCaptures()->append(new SWGSDRangel::SWGCapture);
response.getSigMfFileInputReport()->getCaptures()->back()->setTsms(it->m_tsms);
response.getSigMfFileInputReport()->getCaptures()->back()->setCenterFrequency(it->m_centerFrequency);
response.getSigMfFileInputReport()->getCaptures()->back()->setSampleRate(it->m_sampleRate);
response.getSigMfFileInputReport()->getCaptures()->back()->setSampleStart(it->m_sampleStart);
response.getSigMfFileInputReport()->getCaptures()->back()->setLength(it->m_length);
response.getSigMfFileInputReport()->getCaptures()->back()->setCumulativeTime(it->m_cumulativeTime);
}
uint64_t totalSamplesCount = 0;
if (m_fileInputThread) { if (m_fileInputThread) {
samplesCount = m_fileInputThread->getSamplesCount(); totalSamplesCount = m_fileInputThread->getSamplesCount();
} }
if (m_sampleRate > 0) unsigned int sampleRate = m_captures[m_currentTrackIndex].m_sampleRate;
uint64_t trackSamplesCount = totalSamplesCount - m_captures[m_currentTrackIndex].m_sampleStart;
uint64_t trackCumulativeTime = m_captures[m_currentTrackIndex].m_cumulativeTime;
uint64_t startingTimeStampMs = m_captures[m_currentTrackIndex].m_tsms;
uint64_t t = (trackSamplesCount*1000)/sampleRate;
response.getSigMfFileInputReport()->setElapsedTrackimeMs(t);
t += m_captures[m_currentTrackIndex].m_cumulativeTime;
response.getSigMfFileInputReport()->setElapsedRecordTimeMs(t);
response.getSigMfFileInputReport()->setAbsoluteTimeMs(startingTimeStampMs + ((trackSamplesCount*1000)/sampleRate));
float posRatio = (float) trackSamplesCount / (float) m_captures[m_currentTrackIndex].m_length;
response.getSigMfFileInputReport()->setTrackSamplesRatio(posRatio);
posRatio = (float) totalSamplesCount / (float) m_metaInfo.m_totalSamples;
response.getSigMfFileInputReport()->setRecordSamplesRatio(posRatio);
if (m_captures.size() > 0 )
{ {
t_sec = samplesCount / m_sampleRate; uint64_t totalTimeMs = m_captures.back().m_cumulativeTime + ((m_captures.back().m_length * 1000) / m_captures.back().m_sampleRate);
t_msec = (samplesCount - (t_sec * m_sampleRate)) * 1000 / m_sampleRate; response.getSigMfFileInputReport()->setRecordDurationMs(totalTimeMs);
}
else
{
response.getSigMfFileInputReport()->setRecordDurationMs(0);
} }
QTime t(0, 0, 0, 0);
t = t.addSecs(t_sec);
t = t.addMSecs(t_msec);
response.getFileInputReport()->setElapsedTime(new QString(t.toString("HH:mm:ss.zzz")));
qint64 startingTimeStampMsec = m_startingTimeStamp * 1000LL;
QDateTime dt = QDateTime::fromMSecsSinceEpoch(startingTimeStampMsec);
dt = dt.addSecs(t_sec);
dt = dt.addMSecs(t_msec);
response.getFileInputReport()->setAbsoluteTime(new QString(dt.toString("yyyy-MM-dd HH:mm:ss.zzz")));
QTime recordLength(0, 0, 0, 0);
recordLength = recordLength.addSecs(m_recordLength);
response.getFileInputReport()->setDurationTime(new QString(recordLength.toString("HH:mm:ss")));
response.getFileInputReport()->setSampleRate(m_sampleRate);
response.getFileInputReport()->setSampleSize(m_sampleBytes);
} }
void SigMFFileInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const SigMFFileInputSettings& settings, bool force) void SigMFFileInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const SigMFFileInputSettings& settings, bool force)
@ -978,19 +1106,22 @@ void SigMFFileInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKey
swgDeviceSettings->setDirection(0); // single Rx swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex()); swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("SigMFFileInput")); swgDeviceSettings->setDeviceHwType(new QString("SigMFFileInput"));
swgDeviceSettings->setFileInputSettings(new SWGSDRangel::SWGFileInputSettings()); swgDeviceSettings->setSigMfFileInputSettings(new SWGSDRangel::SWGSigMFFileInputSettings());
SWGSDRangel::SWGFileInputSettings *swgFileInputSettings = swgDeviceSettings->getFileInputSettings(); SWGSDRangel::SWGSigMFFileInputSettings *swgSigMFFileInputSettings = swgDeviceSettings->getSigMfFileInputSettings();
// transfer data that has been modified. When force is on transfer all data except reverse API data // transfer data that has been modified. When force is on transfer all data except reverse API data
if (deviceSettingsKeys.contains("accelerationFactor") || force) { if (deviceSettingsKeys.contains("accelerationFactor") || force) {
swgFileInputSettings->setAccelerationFactor(settings.m_accelerationFactor); swgSigMFFileInputSettings->setAccelerationFactor(settings.m_accelerationFactor);
} }
if (deviceSettingsKeys.contains("loop") || force) { if (deviceSettingsKeys.contains("trackLoop") || force) {
swgFileInputSettings->setLoop(settings.m_trackLoop); swgSigMFFileInputSettings->setTrackLoop(settings.m_trackLoop);
}
if (deviceSettingsKeys.contains("fullLoop") || force) {
swgSigMFFileInputSettings->setFullLoop(settings.m_fullLoop);
} }
if (deviceSettingsKeys.contains("fileName") || force) { if (deviceSettingsKeys.contains("fileName") || force) {
swgFileInputSettings->setFileName(new QString(settings.m_fileName)); swgSigMFFileInputSettings->setFileName(new QString(settings.m_fileName));
} }
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")

View File

@ -417,6 +417,11 @@ public:
SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGDeviceState& response,
QString& errorMessage); QString& errorMessage);
virtual int webapiActionsPost(
const QStringList& deviceActionsKeys,
SWGSDRangel::SWGDeviceActions& query,
QString& errorMessage);
virtual int webapiRun( virtual int webapiRun(
bool run, bool run,
SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGDeviceState& response,
@ -447,6 +452,9 @@ private:
bool m_trackMode; bool m_trackMode;
int m_currentTrackIndex; int m_currentTrackIndex;
bool m_recordOpen; bool m_recordOpen;
bool m_crcAvailable;
bool m_crcOK;
bool m_recordLengthOK;
QString m_recordSummary; QString m_recordSummary;
SigMFFileInputThread* m_fileInputThread; SigMFFileInputThread* m_fileInputThread;
QString m_deviceDescription; QString m_deviceDescription;