diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index 008a387..42d3b6a 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -303,6 +303,14 @@ float AppConfig::getSpectrumAvgSpeed() { return spectrumAvgSpeed.load(); } +void AppConfig::setManualDevices(std::vector manuals) { + manualDevices = manuals; +} + +std::vector AppConfig::getManualDevices() { + return manualDevices; +} + void AppConfig::setConfigName(std::string configName) { this->configName = configName; } @@ -354,6 +362,15 @@ bool AppConfig::save() { device_config_i->second->save(device_node); } + if (manualDevices.size()) { + DataNode *manual_node = cfg.rootNode()->newChild("manual_devices"); + for (std::vector::const_iterator i = manualDevices.begin(); i != manualDevices.end(); i++) { + DataNode *rig_node = manual_node->newChild("device"); + *rig_node->newChild("factory") = i->factory; + *rig_node->newChild("params") = i->params; + } + } + #ifdef USE_HAMLIB DataNode *rig_node = cfg.rootNode()->newChild("rig"); *rig_node->newChild("model") = rigModel.load(); @@ -474,6 +491,22 @@ bool AppConfig::load() { } } + if (cfg.rootNode()->hasAnother("manual_devices")) { + DataNode *manuals_node = cfg.rootNode()->getNext("manual_devices"); + + while (manuals_node->hasAnother("device")) { + DataNode *manual_node = manuals_node->getNext("device"); + if (manual_node->hasAnother("factory") && manual_node->hasAnother("params")) { + SDRManualDef mdef; + + mdef.factory = manual_node->getNext("factory")->element()->toString(); + mdef.params = manual_node->getNext("params")->element()->toString(); + + manualDevices.push_back(mdef); + } + } + } + #ifdef USE_HAMLIB if (cfg.rootNode()->hasAnother("rig")) { DataNode *rig_node = cfg.rootNode()->getNext("rig"); diff --git a/src/AppConfig.h b/src/AppConfig.h index fc35f81..b40ec12 100644 --- a/src/AppConfig.h +++ b/src/AppConfig.h @@ -8,6 +8,8 @@ #include #include "DataTree.h" +#include "CubicSDRDefs.h" +#include "SDRDeviceInfo.h" typedef std::map ConfigSettings; @@ -40,7 +42,7 @@ public: void setRigIF(int rigType, long long freq); long long getRigIF(int rigType); - + void save(DataNode *node); void load(DataNode *node); @@ -83,6 +85,9 @@ public: void setSpectrumAvgSpeed(float avgSpeed); float getSpectrumAvgSpeed(); + void setManualDevices(std::vector manuals); + std::vector getManualDevices(); + #if USE_HAMLIB int getRigModel(); void setRigModel(int rigModel); @@ -110,6 +115,7 @@ private: std::atomic_llong centerFreq; std::atomic_int waterfallLinesPerSec; std::atomic spectrumAvgSpeed; + std::vector manualDevices; #if USE_HAMLIB std::atomic_int rigModel, rigRate; std::string rigPort; diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 121e3c8..b5598bd 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -680,22 +680,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) { "Frequency Offset", wxGetApp().getOffset(), -2000000000, 2000000000, this); if (ofs != -1) { wxGetApp().setOffset(ofs); - wxGetApp().saveConfig(); } - } else if (event.GetId() == wxID_SET_DS_OFF) { -// wxGetApp().setDirectSampling(0); -// wxGetApp().saveConfig(); - } else if (event.GetId() == wxID_SET_DS_I) { -// wxGetApp().setDirectSampling(1); -// wxGetApp().saveConfig(); - } else if (event.GetId() == wxID_SET_DS_Q) { -// wxGetApp().setDirectSampling(2); -// wxGetApp().saveConfig(); - } else if (event.GetId() == wxID_SET_SWAP_IQ) { -// bool swap_state = !wxGetApp().getSwapIQ(); -// wxGetApp().setSwapIQ(swap_state); -// wxGetApp().saveConfig(); -// iqSwapMenuItem->Check(swap_state); } else if (event.GetId() == wxID_AGC_CONTROL) { if (wxGetApp().getDevice() == NULL) { agcMenuItem->Check(true); @@ -722,7 +707,6 @@ void AppFrame::OnMenu(wxCommandEvent& event) { long ofs = wxGetNumberFromUser("Frequency correction for device in PPM.\ni.e. -51 for -51 PPM\n\nNote: you can adjust PPM interactively\nby holding ALT over the frequency tuning bar.\n", "Parts per million (PPM)", "Frequency Correction", wxGetApp().getPPM(), -1000, 1000, this); wxGetApp().setPPM(ofs); - wxGetApp().saveConfig(); } else if (event.GetId() == wxID_SAVE) { if (!currentSessionFile.empty()) { saveSession(currentSessionFile); @@ -1007,6 +991,7 @@ void AppFrame::OnClose(wxCloseEvent& event) { wxGetApp().getConfig()->setCenterFreq(wxGetApp().getFrequency()); wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcessor()->getFFTAverageRate()); wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond()); + wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals()); #ifdef USE_HAMLIB wxGetApp().getConfig()->setRigModel(rigModel); wxGetApp().getConfig()->setRigRate(rigSerialRate); diff --git a/src/AppFrame.h b/src/AppFrame.h index 3ebe09a..cfa549c 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -25,10 +25,6 @@ #define wxID_SET_FREQ_OFFSET 2001 #define wxID_RESET 2002 #define wxID_SET_PPM 2003 -#define wxID_SET_DS_OFF 2004 -#define wxID_SET_DS_I 2005 -#define wxID_SET_DS_Q 2006 -#define wxID_SET_SWAP_IQ 2007 #define wxID_SDR_DEVICES 2008 #define wxID_AGC_CONTROL 2009 diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index f1814e7..b381173 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -247,6 +247,8 @@ bool CubicSDR::OnInit() { t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread); sdrEnum = new SDREnumerator(); + + SDREnumerator::setManuals(config.getManualDevices()); appframe = new AppFrame(); t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum); diff --git a/src/forms/SDRDevices/SDRDevices.cpp b/src/forms/SDRDevices/SDRDevices.cpp index 242cf19..814ac92 100644 --- a/src/forms/SDRDevices/SDRDevices.cpp +++ b/src/forms/SDRDevices/SDRDevices.cpp @@ -14,6 +14,7 @@ SDRDevicesDialog::SDRDevicesDialog( wxWindow* parent ): devFrame( parent ) { m_deviceTimer.Start(250); selId = nullptr; editId = nullptr; + removeId = nullptr; devAddDialog = nullptr; } @@ -147,23 +148,50 @@ void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { } if (selDev->isManual()) { - // TODO: add remove button + m_addRemoteButton->SetLabel("Remove"); + removeId = selId; + } else { + m_addRemoteButton->SetLabel("Add"); + removeId = nullptr; } } else if (selDev && !selDev->isAvailable() && selDev->isManual()) { m_propertyGrid->Clear(); devSettings.erase(devSettings.begin(),devSettings.end()); props.erase(props.begin(), props.end()); + removeId = devTree->GetSelection(); dev = nullptr; selId = nullptr; editId = nullptr; - // TODO: add remove option + m_addRemoteButton->SetLabel("Remove"); + } else if (!selDev) { + m_addRemoteButton->SetLabel("Add"); + removeId = nullptr; } event.Skip(); } void SDRDevicesDialog::OnAddRemote( wxMouseEvent& event ) { + if (removeId != nullptr) { + SDRDeviceInfo *selDev = getSelectedDevice(removeId); + + if (selDev) { + SDREnumerator::removeManual(selDev->getDriver(),selDev->getManualParams()); + m_propertyGrid->Clear(); + devSettings.erase(devSettings.begin(),devSettings.end()); + props.erase(props.begin(), props.end()); + dev = nullptr; + selId = nullptr; + editId = nullptr; + devTree->Delete(removeId); + removeId = nullptr; + m_addRemoteButton->SetLabel("Add"); + } + + return; + } + devAddDialog = new SDRDeviceAddDialog(this); devAddDialog->ShowModal(); @@ -396,6 +424,8 @@ void SDRDevicesDialog::doRefreshDevices() { wxGetApp().reEnumerateDevices(); selId = nullptr; editId = nullptr; + removeId = nullptr; dev = nullptr; refresh = true; + m_addRemoteButton->SetLabel("Add"); } \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDevices.h b/src/forms/SDRDevices/SDRDevices.h index d8cedf0..fd29880 100644 --- a/src/forms/SDRDevices/SDRDevices.h +++ b/src/forms/SDRDevices/SDRDevices.h @@ -39,5 +39,6 @@ private: std::map devSettings; wxTreeItemId selId; wxTreeItemId editId; + wxTreeItemId removeId; SDRDeviceAddDialog *devAddDialog; }; \ No newline at end of file diff --git a/src/sdr/SDRDeviceInfo.h b/src/sdr/SDRDeviceInfo.h index 62bfb9b..bb9fd41 100644 --- a/src/sdr/SDRDeviceInfo.h +++ b/src/sdr/SDRDeviceInfo.h @@ -5,32 +5,10 @@ #include -/* - ---------------------------------------------------- - -- Device identification - ---------------------------------------------------- - driver=rtl - hardware=rtl - - ---------------------------------------------------- - -- Peripheral summary - ---------------------------------------------------- - Channels: 1 Rx, 0 Tx - Timestamps: NO - - ---------------------------------------------------- - -- RX Channel 0 - ---------------------------------------------------- - Full-duplex: YES - Antennas: RX - Full gain range: [0, 49.6] dB - LNA gain range: [0, 49.6] dB - Full freq range: [24, 1766] MHz - RF freq range: [24, 1766] MHz - CORR freq range: MHz - Sample rates: [0.25, 2.56] MHz - Filter bandwidths: [] MHz -*/ +typedef struct _SDRManualDef { + std::string factory; + std::string params; +} SDRManualDef; class SDRDeviceRange { public: diff --git a/src/sdr/SDREnumerator.cpp b/src/sdr/SDREnumerator.cpp index 89af6c7..75af11b 100644 --- a/src/sdr/SDREnumerator.cpp +++ b/src/sdr/SDREnumerator.cpp @@ -176,7 +176,7 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot std::string strDevArgs = "driver="+m_i->factory+","+m_i->params; - manualParams.push_back(strDevArgs); + manualParams.push_back(m_i->params); wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Enumerating manual device '") + strDevArgs + "'.."); @@ -406,6 +406,29 @@ void SDREnumerator::addManual(std::string factory, std::string params) { manuals.push_back(def); } +void SDREnumerator::removeManual(std::string factory, std::string params) { + for (std::vector::const_iterator i = manuals.begin(); i != manuals.end(); i++) { + if (i->factory == factory && i->params == params) { + manuals.erase(i); + for (std::vector::const_iterator subdevs_i = devs[""].begin(); subdevs_i != devs[""].end(); subdevs_i++) { + if ((*subdevs_i)->isManual() && (*subdevs_i)->getDriver() == factory && (*subdevs_i)->getManualParams() == params) { + devs[""].erase(subdevs_i); + break; + } + } + break; + } + } +} + +std::vector &SDREnumerator::getManuals() { + return SDREnumerator::manuals; +} + +void SDREnumerator::setManuals(std::vector manuals) { + SDREnumerator::manuals = manuals; +} + bool SDREnumerator::hasRemoteModule() { return SDREnumerator::has_remote; } diff --git a/src/sdr/SDREnumerator.h b/src/sdr/SDREnumerator.h index 9ad0464..384d003 100644 --- a/src/sdr/SDREnumerator.h +++ b/src/sdr/SDREnumerator.h @@ -12,11 +12,6 @@ #include #include -typedef struct _SDRManualDef { - std::string factory; - std::string params; -} SDRManualDef; - class SDREnumerator: public IOThread { private: @@ -36,7 +31,9 @@ public: static std::vector &getRemotes(); static bool hasRemoteModule(); static void addManual(std::string factory, std::string params); - // static void removeManual(std::string factory, std::string params); + static void removeManual(std::string factory, std::string params); + static std::vector &getManuals(); + static void setManuals(std::vector manuals); static void reset(); static std::vector &getFactories(); @@ -47,4 +44,5 @@ protected: static std::vector remotes; static std::map< std::string, std::vector > devs; static std::vector manuals; + static std::mutex devs_busy; };