From 2132de6b77d2ff620a9b36f8710592332ca9645e Mon Sep 17 00:00:00 2001 From: ezratl Date: Sat, 5 Oct 2019 17:09:54 -0400 Subject: [PATCH] More scanner changes --- src/core/ScannerSM.cpp | 75 ++++++++++++++++++++++--------------- src/core/ScannerSM.h | 10 +++-- src/core/StateMachine.cpp | 4 +- src/scan/Entry.cpp | 2 +- src/scan/Entry.h | 19 ++++++---- src/scan/SystemList.cpp | 23 +++++++++++- src/scan/SystemList.h | 2 + src/server/Connection.cpp | 22 ++++++++++- src/server/DebugServer.cpp | 13 +++++-- src/server/SocketServer.cpp | 15 +++++--- src/server/connection.h | 13 ++++++- src/sigproc/Demodulator.cpp | 11 +++++- src/sigproc/Demodulator.h | 10 +++-- 13 files changed, 155 insertions(+), 64 deletions(-) diff --git a/src/core/ScannerSM.cpp b/src/core/ScannerSM.cpp index 9dea959..330f420 100644 --- a/src/core/ScannerSM.cpp +++ b/src/core/ScannerSM.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "ScannerSM.h" #include "ListGenerator.h" @@ -17,7 +18,7 @@ using namespace piscan; ScannerSM::ScannerSM(MessageReceiver& central, SystemList& dataSource) : - StateMachine(7), _centralQueue(central), _systems(dataSource) { + StateMachine(7), _centralQueue(central), _systems(dataSource), _externalHold(false), _manualMode(false) { } void ScannerSM::startScan(){ @@ -34,8 +35,12 @@ void ScannerSM::startScan(){ END_TRANSITION_MAP(NULL) } -void ScannerSM::holdScan(){ +void ScannerSM::holdScan(std::vector index){ _externalHold = true; + { + std::lock_guard lock(_holdMutex); + _holdIndex = index; + } LOG_F(1, "ExtEvent: holdScan"); BEGIN_TRANSITION_MAP TRANSITION_MAP_ENTRY(EVENT_IGNORED) @@ -96,8 +101,10 @@ void ScannerSM::ST_Load(EventData* data){ void ScannerSM::ST_Scan(EventData* data){ DLOG_F(9, "ST_Scan"); - if(currentState != lastState) + if(currentState != lastState){ + _squelchHits = 0; DLOG_F(6, "State change: %i -> %i", lastState, currentState); + } _enableAudioOut(false); _currentContext.state = ScannerContext::SCAN; @@ -106,40 +113,22 @@ void ScannerSM::ST_Scan(EventData* data){ if(currentState != lastState) _broadcastContextUpdate(); - // incremental scan pattern - if(!_squelchHits || (currentState != lastState)){ - //_entryCounter = (_entryCounter + 1) % _currentSystem->size(); + if (!_squelchHits || (currentState != lastState)) { - - -// if(_entryCounter == 0){ -// _sysCounter = (_sysCounter + 1) % _systems.size(); -// -// _currentSystem = _systems[_sysCounter]; -// assert(_currentSystem != nullptr); -// -// //_broadcastContextUpdate(); -// } - - //CHECK_F(_currentSystem->size() > 0); - //_currentEntry = _currentSystem->operator[](_entryCounter); - //CHECK_F(_currentEntry != NULL); - - _currentEntry = _systems.getNextEntry(); + + _currentEntry = _systems.getNextEntry(); } - if(_currentEntry->hasSignal()){ + if (_currentEntry->hasSignal()) { _squelchHits++; - if(_squelchHits >= SQUELCH_TRIGGER_HITS){ + if (_squelchHits >= SQUELCH_TRIGGER_HITS) { LOG_F(2, "Signal found: %s", _currentEntry->tag().c_str()); InternalEvent(ST_RECEIVE); - } - else{ + } else { InternalEvent(ST_SCAN); } - } - else{ + } else { _squelchHits = 0; InternalEvent(ST_SCAN); } @@ -151,9 +140,27 @@ void ScannerSM::ST_Hold(EventData* data){ if(currentState != lastState) DLOG_F(6, "State change: %i -> %i", lastState, currentState); + bool indexHold = false; + + { + std::lock_guard < std::mutex > lock(_holdMutex); + if (_externalHold && _holdIndex.size() > 0) { + _currentEntry = _systems.getEntryByIndex(_holdIndex); + LOG_F(1, "Index hold"); + _holdIndex.clear(); + indexHold = true; + } + } + + /* don't hold on dummy channels */ + while(_currentEntry->isDummy()){ + _currentEntry->hasSignal(); + _currentEntry = _systems.getNextEntry(); + } + _enableAudioOut(false); _currentContext.state = ScannerContext::HOLD; - if(currentState != lastState) + if(currentState != lastState || indexHold) _broadcastContextUpdate(); /* start receive if signal active */ @@ -249,7 +256,7 @@ void ScannerSM::ST_Stopped(EventData* data){ } void ScannerSM::_broadcastContextUpdate() { - DLOG_F(7, "Broadcasting context"); + DLOG_F(6, "Broadcasting context"); std::lock_guard lock(_contextMutex); if (_currentContext.state != ScannerContext::SCAN) { @@ -338,7 +345,13 @@ void ScannerSM::_handleRequest(ClientRequest& request) { startScan(); break; case SCANNER_STATE_HOLD: - holdScan(); + if(request.pData != nullptr){ + std::vector* indexData = reinterpret_cast*>(request.pData); + holdScan(*indexData); + delete indexData; + } + else + holdScan(); break; case SCANNER_STATE_MANUAL: manualEntry(reinterpret_cast(rq->pData)); diff --git a/src/core/ScannerSM.h b/src/core/ScannerSM.h index ef41f51..558aea4 100644 --- a/src/core/ScannerSM.h +++ b/src/core/ScannerSM.h @@ -16,7 +16,7 @@ #include "messages.h" #include "clientmessage.h" -#define SQUELCH_TRIGGER_HITS 10 +#define SQUELCH_TRIGGER_HITS 25 namespace piscan { @@ -26,7 +26,7 @@ public: ~ScannerSM() {}; void startScan(); - void holdScan(); + void holdScan(std::vector index = std::vector()); void stopScanner(); void manualEntry(uint32_t* freq); void giveMessage(std::shared_ptr message); @@ -72,8 +72,10 @@ private: ScannerContext _currentContext; std::mutex _contextMutex; - bool _externalHold = false; - bool _manualMode = false; + std::atomic_bool _externalHold; + std::atomic_bool _manualMode; + std::mutex _holdMutex; + std::vector _holdIndex; std::time_t timeoutStart = 0; int _squelchHits = 0; diff --git a/src/core/StateMachine.cpp b/src/core/StateMachine.cpp index a66c9bf..5cd6ff0 100644 --- a/src/core/StateMachine.cpp +++ b/src/core/StateMachine.cpp @@ -95,7 +95,9 @@ void StateMachine::StateEngine(void) //lock.unlock(); } - // TBD - unlock semaphore here + // yield to let waiting threads generate external events + lock.unlock(); + std::this_thread::yield(); } void StateMachine::StateThreadFunc(void){ diff --git a/src/scan/Entry.cpp b/src/scan/Entry.cpp index 8e00c6e..dcbf7e6 100644 --- a/src/scan/Entry.cpp +++ b/src/scan/Entry.cpp @@ -15,7 +15,7 @@ using namespace piscan; DemodInterface* Entry::demod = nullptr; bool DummyChannel::hasSignal(){ - if(!demod->setFrequency(this->frequency)) + if(!demod->setTunerFrequency(this->frequency)) return false; return false; diff --git a/src/scan/Entry.h b/src/scan/Entry.h index 04702d5..0572ca9 100644 --- a/src/scan/Entry.h +++ b/src/scan/Entry.h @@ -25,7 +25,8 @@ public: bool useDelay() { return _scanDelay; } void lockout(bool val = true) { _lockedOut = val; } virtual bool hasSignal() = 0; - virtual long freq() = 0; + virtual long long freq() = 0; + virtual bool isDummy() { return false; } size_t getSysIndex() { return _sysIndex; }; void setSysIndex(size_t index) { _sysIndex = index; }; @@ -47,27 +48,29 @@ class Channel: public Entry { public: Channel(long freq, std::string tag, bool lo, bool del) : Entry(tag, lo, del), frequency(freq){} virtual ~Channel() {}; - virtual long freq() { return frequency; }; + virtual long long freq() { return frequency; }; protected: - const long frequency; + const long long frequency; }; class DummyChannel: public Channel { public: - DummyChannel(long freq) : Channel(freq, "", false, false){ + DummyChannel(long long freq) : Channel(freq, "", false, false){ } ~DummyChannel(){}; std::string modulation() { return ""; }; + bool isDummy() { return true; } + bool hasSignal(); }; class FMChannel : public Channel { public: - FMChannel(long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){} + FMChannel(long long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){} ~FMChannel() {}; std::string modulation() { @@ -79,7 +82,7 @@ public: class PLChannel: public FMChannel { public: - PLChannel(long freq, float tn, std::string tag, bool lo, bool del) : + PLChannel(long long freq, float tn, std::string tag, bool lo, bool del) : FMChannel(freq, tag, lo, del), tone(tn) { } ~PLChannel() {}; @@ -91,7 +94,7 @@ protected: class DCChannel : public FMChannel { public: - DCChannel(long freq, unsigned int tn, std::string tag, bool lo, bool del) : + DCChannel(long long freq, unsigned int tn, std::string tag, bool lo, bool del) : FMChannel(freq, tag, lo, del), code(tn) { } ~DCChannel() {}; @@ -103,7 +106,7 @@ protected: class AMChannel : public Channel { public: - AMChannel(long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){} + AMChannel(long long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){} ~AMChannel() {}; bool hasSignal() { return false; }; diff --git a/src/scan/SystemList.cpp b/src/scan/SystemList.cpp index f9dabc0..540ce19 100644 --- a/src/scan/SystemList.cpp +++ b/src/scan/SystemList.cpp @@ -18,14 +18,21 @@ SystemList::~SystemList() { // TODO Auto-generated destructor stub } +std::shared_ptr SystemList::getEntryByIndex(std::vector index){ + if(index.size() < 2 || index[0] < 0 || index[1] < 0 || index[0] >= _systems.size() || index[1] >= _systems[index[0]]->size()) + return getNextEntry(); + + return _systems[index[0]]->operator [](index[1]); +} std::shared_ptr SystemList::getNextEntry(){ if(_entryNum == 0 && _retune){ _retune = false; - return std::make_shared(_bins[_binNum]->getCenterFreq()); + //if(_bins[_binNum]->size() > 1) + return std::make_shared(_bins[_binNum]->getCenterFreq()); } - auto entry = _bins[_binNum]->operator [](_entryNum); + auto entry = _bins[_binNum]->at(_entryNum); _entryNum = (_entryNum + 1) % _bins[_binNum]->size(); @@ -39,6 +46,8 @@ std::shared_ptr SystemList::getNextEntry(){ } void SystemList::sortBins(int bandwidth){ + LOG_F(1, "Sorting bandwidth chunks..."); + size_t numEntries = 0; for(size_t i = 0; i < _systems.size(); i++) for(size_t k = 0; k < _systems[i]->size(); k++) @@ -70,6 +79,16 @@ void SystemList::sortBins(int bandwidth){ lastFreq = entries[i]->freq(); newBin->push_back(entries[i]); } + + std::string binPrint = ""; + for(size_t i = 0; i < _bins.size(); i++){ + binPrint += (std::string("\tCenter: ") + std::to_string(_bins[i]->getCenterFreq()) + std::string(" | ")); + for(size_t j = 0; j < _bins[i]->size(); j++) + binPrint += (std::to_string(_bins[i]->at(j)->freq()) + std::string(" ")); + + RAW_LOG_F(1, binPrint.c_str()); + binPrint = ""; + } } void SystemList::merge(std::shared_ptr arr[], int l, int m, int r) diff --git a/src/scan/SystemList.h b/src/scan/SystemList.h index c76b550..b485800 100644 --- a/src/scan/SystemList.h +++ b/src/scan/SystemList.h @@ -27,6 +27,8 @@ public: _systems.push_back(system); } + std::shared_ptr getEntryByIndex(std::vector index); + std::shared_ptr getNextEntry(); void sortBins(int bandwidth); diff --git a/src/server/Connection.cpp b/src/server/Connection.cpp index a0b32b0..d015f3c 100644 --- a/src/server/Connection.cpp +++ b/src/server/Connection.cpp @@ -52,7 +52,7 @@ int Connection::systemFunction(SystemFunction function) { return issueRequest(params); } -int Connection::scannerFunction(ScannerFunction function, uint32_t freq) { +/*int Connection::scannerFunction(ScannerFunction function, uint32_t freq) { ClientRequest::RequestParams params = { .type = SCANNER_FUNCTION }; switch (function) { case SCAN: @@ -69,6 +69,26 @@ int Connection::scannerFunction(ScannerFunction function, uint32_t freq) { return -1; } return issueRequest(params); +}*/ + +int Connection::scanStart() { + ClientRequest::RequestParams params = { .type = SCANNER_FUNCTION, .subType = SCANNER_STATE_SCAN }; + return issueRequest(params); +} + +int Connection::scanHold() { + ClientRequest::RequestParams params = { .type = SCANNER_FUNCTION, .subType = SCANNER_STATE_HOLD }; + return issueRequest(params); +} + +int Connection::scanHoldEntry(std::vector index) { + ClientRequest::RequestParams params = { .type = SCANNER_FUNCTION, .subType = SCANNER_STATE_HOLD }; + return issueRequest(params, new std::vector(index)); +} + +int Connection::scanManualEntry(long freq, Modulation mode) { + ClientRequest::RequestParams params = { .type = SCANNER_FUNCTION, .subType = SCANNER_STATE_MANUAL }; + return issueRequest(params, new uint32_t(freq)); } int Connection::setDemodSquelch(int level) { diff --git a/src/server/DebugServer.cpp b/src/server/DebugServer.cpp index 3a60afd..7a8f4d3 100644 --- a/src/server/DebugServer.cpp +++ b/src/server/DebugServer.cpp @@ -72,9 +72,16 @@ void DebugConsole::_consoleInputFunc() { else getDemodContext(); } else if (!tokens[0].compare("scan")) - scannerFunction(ScannerFunction::SCAN); + scanStart(); else if (!tokens[0].compare("hold")) { - scannerFunction(ScannerFunction::HOLD); + if (tokens.size() > 2) { + std::vector entryIndex; + for(size_t i = 1; i < tokens.size(); i++) + entryIndex.push_back(std::stoi(tokens[i])); + scanHoldEntry(entryIndex); + } + else + scanHold(); } else if (!tokens[0].compare("gain")) { if (tokens.size() > 1) { int gain = 0; @@ -87,7 +94,7 @@ void DebugConsole::_consoleInputFunc() { else getDemodContext(); } else if (!tokens[0].compare("manual")) { - scannerFunction(ScannerFunction::MANUAL, std::stof(tokens[1])); + scanManualEntry(std::stof(tokens[1])); } else if (!tokens[0].compare("get")){ if(!tokens[1].compare("context")) diff --git a/src/server/SocketServer.cpp b/src/server/SocketServer.cpp index 90a8715..0e529e7 100644 --- a/src/server/SocketServer.cpp +++ b/src/server/SocketServer.cpp @@ -180,26 +180,29 @@ void SocketConnection::_handleGeneralRequest(const piscan_pb::GeneralRequest& rq void SocketConnection::_handleScanStateRequest( const piscan_pb::ScannerStateRequest& rq) { - ScannerFunction func; + //ScannerFunction func; uint32_t freq = 0; switch(rq.state()){ case piscan_pb::ScannerStateRequest_NewState_SCAN: - func = SCAN; + //func = SCAN; + scanStart(); break; case piscan_pb::ScannerStateRequest_NewState_HOLD: - func = HOLD; + //func = HOLD; + scanHold(); break; case piscan_pb::ScannerStateRequest_NewState_MANUAL: - func = MANUAL; - freq = static_cast(rq.manfreq()); + //func = MANUAL; + //freq = static_cast(rq.manfreq()); + scanManualEntry(rq.manfreq()); break; default: LOG_F(WARNING, "Invalid ScannerStateRequest from %s", _socket.local_endpoint().address().to_string().c_str()); break; } - scannerFunction(func, freq); + //scannerFunction(func, freq); } void SocketConnection::_handleDemodRequest(const piscan_pb::DemodRequest& rq) { diff --git a/src/server/connection.h b/src/server/connection.h index f1eab26..7f34bfa 100644 --- a/src/server/connection.h +++ b/src/server/connection.h @@ -10,6 +10,7 @@ #include #include +#include #include "constants.h" #include "clientmessage.h" @@ -97,7 +98,17 @@ protected: HOLD, MANUAL, }; - int scannerFunction(ScannerFunction function, uint32_t freq = 0); + + enum Modulation { + FM, + AM, + }; + + //int scannerFunction(ScannerFunction function, uint32_t freq = 0); + int scanStart(); + int scanHold(); + int scanHoldEntry(std::vector index); + int scanManualEntry(long freq, Modulation mode = FM); int setDemodSquelch(int level); int setDemodGain(int level); int getScannerContext(); diff --git a/src/sigproc/Demodulator.cpp b/src/sigproc/Demodulator.cpp index b637994..5e4f634 100644 --- a/src/sigproc/Demodulator.cpp +++ b/src/sigproc/Demodulator.cpp @@ -152,7 +152,7 @@ void Demodulator::stop(){ LOG_F(1, "Demodulator stopped"); } -bool Demodulator::setFrequency(uint32_t freq) { +bool Demodulator::setFrequency(long long freq) { /*if(freq == _demodMgr.getCurrentModem()->getFrequency()){ DLOG_F(9, "Frequency already set"); return true; @@ -169,7 +169,7 @@ bool Demodulator::setFrequency(uint32_t freq) { _demodMgr.getCurrentModem()->setFrequency(freq); //this is totally arbitrary - usleep(1000); + usleep(7000); _currentFreq = freq; @@ -178,6 +178,13 @@ bool Demodulator::setFrequency(uint32_t freq) { return true; } +bool Demodulator::setTunerFrequency(long long freq){ + _cubic->setFrequency(freq); + _demodMgr.getCurrentModem()->setFrequency(freq); + usleep(200000); + return true; +} + float Demodulator::getSignalLevel() { return _demodMgr.getActiveContextModem()->getSignalLevel(); } diff --git a/src/sigproc/Demodulator.h b/src/sigproc/Demodulator.h index fc649e7..1c3dab6 100644 --- a/src/sigproc/Demodulator.h +++ b/src/sigproc/Demodulator.h @@ -15,7 +15,7 @@ #include "DemodulatorMgr.h" #include "SDRDeviceInfo.h" -#define DEFAULT_SQUELCH -60 +#define DEFAULT_SQUELCH 0 namespace piscan { @@ -29,7 +29,8 @@ class DemodInterface { public: virtual ~DemodInterface() {}; - virtual bool setFrequency(uint32_t freq) = 0; + virtual bool setFrequency(long long freq) = 0; + virtual bool setTunerFrequency(long long freq) = 0; virtual float getSignalLevel() = 0; virtual float getDecodedPL() = 0; virtual unsigned int getDecodedDC() = 0; @@ -53,7 +54,7 @@ private: MessageReceiver& _centralQueue; Modulation _currentModem = NFM; float _squelchLevel = DEFAULT_SQUELCH; - uint32_t _currentFreq = 0; + long long _currentFreq = 0; float _gain = AUTO_GAIN; std::shared_ptr _cubic; @@ -62,7 +63,8 @@ private: std::map _demods; void giveMessage(std::shared_ptr message); - bool setFrequency(uint32_t freq); + bool setFrequency(long long freq); + bool setTunerFrequency(long long freq); float getSignalLevel(); float getDecodedPL(); unsigned int getDecodedDC();