diff --git a/CMakeLists.txt b/CMakeLists.txt index f495585..5a402c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,6 +313,8 @@ SET (cubicsdr_sources src/ui/GLPanel.cpp src/forms/SDRDevices/SDRDevices.cpp src/forms/SDRDevices/SDRDevicesForm.cpp + src/forms/SDRDevices/SDRDeviceAdd.cpp + src/forms/SDRDevices/SDRDeviceAddForm.cpp external/rtaudio/RtAudio.cpp external/lodepng/lodepng.cpp external/tinyxml/tinyxml.cpp @@ -413,6 +415,8 @@ SET (cubicsdr_headers src/ui/UITestContext.h src/forms/SDRDevices/SDRDevices.h src/forms/SDRDevices/SDRDevicesForm.h + src/forms/SDRDevices/SDRDeviceAdd.h + src/forms/SDRDevices/SDRDeviceAddForm.h external/rtaudio/RtAudio.h external/lodepng/lodepng.h external/tinyxml/tinyxml.h diff --git a/src/forms/SDRDevices/SDRDeviceAdd.cpp b/src/forms/SDRDevices/SDRDeviceAdd.cpp new file mode 100644 index 0000000..2a2e808 --- /dev/null +++ b/src/forms/SDRDevices/SDRDeviceAdd.cpp @@ -0,0 +1,59 @@ +#include "SDRDeviceAdd.h" + +#include "SDREnumerator.h" + +SDRDeviceAddDialog::SDRDeviceAddDialog( wxWindow* parent ): SDRDeviceAddForm( parent ) { + okPressed = false; + selectedModule = ""; + moduleParam = ""; + selectedModule = "SoapyRemote"; + + m_soapyModule->Append("SoapyRemote"); + m_paramLabel->SetLabel("Remote Address (address[:port])"); + + std::vector &factories = SDREnumerator::getFactories(); + std::vector::iterator factory_i; + + for (factory_i = factories.begin(); factory_i != factories.end(); factory_i++) { + if (*factory_i != "remote" && *factory_i != "null") { + m_soapyModule->Append(*factory_i); + } + } +} + +void SDRDeviceAddDialog::OnSoapyModuleChanged( wxCommandEvent& event ) { + wxString strSel = m_soapyModule->GetStringSelection(); + + selectedModule = strSel.ToStdString(); + + if (selectedModule == "SoapyRemote") { + m_paramLabel->SetLabelText("Remote Address (address[:port])"); + } else { + m_paramLabel->SetLabel("SoapySDR Device Parameters, i.e. 'addr=192.168.1.105'"); + } +} + +void SDRDeviceAddDialog::OnCancelButton( wxCommandEvent& event ) { + okPressed = false; + Close(true); +} + +void SDRDeviceAddDialog::OnOkButton( wxCommandEvent& event ) { + wxString strSel = m_soapyModule->GetStringSelection(); + selectedModule = strSel.ToStdString(); + moduleParam = m_paramText->GetValue().ToStdString(); + okPressed = true; + Close(true); +} + +bool SDRDeviceAddDialog::wasOkPressed() { + return okPressed; +} + +std::string SDRDeviceAddDialog::getSelectedModule() { + return selectedModule; +} + +std::string SDRDeviceAddDialog::getModuleParam() { + return moduleParam; +} diff --git a/src/forms/SDRDevices/SDRDeviceAdd.fbp b/src/forms/SDRDevices/SDRDeviceAdd.fbp new file mode 100644 index 0000000..c89620a --- /dev/null +++ b/src/forms/SDRDevices/SDRDeviceAdd.fbp @@ -0,0 +1,681 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + SDRDeviceAddForm + 1000 + none + 0 + SDRDeviceAddForm + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + SDRDeviceAddForm + + 395,241 + wxDEFAULT_DIALOG_STYLE + + Add SoapySDR Device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer6 + wxVERTICAL + none + + 10 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Manually add a SoapyRemote or SoapySDR device. Useful for a device that is not detected automatically. + + 0 + + + 0 + + 1 + m_staticText4 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 10 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_soapyModule + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnSoapyModuleChanged + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 10 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + <Parameter> + + 0 + + + 0 + + 1 + m_paramLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_paramText + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_DONTWRAP + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + + bSizer7 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Cancel + + 0 + + + 0 + + 1 + m_cancelButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCancelButton + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Ok + + 0 + + + 0 + + 1 + m_OkButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOkButton + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + diff --git a/src/forms/SDRDevices/SDRDeviceAdd.h b/src/forms/SDRDevices/SDRDeviceAdd.h new file mode 100644 index 0000000..649d130 --- /dev/null +++ b/src/forms/SDRDevices/SDRDeviceAdd.h @@ -0,0 +1,21 @@ +#pragma once + +#include "SDRDeviceAddForm.h" + +class SDRDeviceAddDialog : public SDRDeviceAddForm { +public: + SDRDeviceAddDialog( wxWindow* parent ); + + void OnSoapyModuleChanged( wxCommandEvent& event ); + void OnCancelButton( wxCommandEvent& event ); + void OnOkButton( wxCommandEvent& event ); + + bool wasOkPressed(); + std::string getSelectedModule(); + std::string getModuleParam(); + +private: + bool okPressed; + std::string selectedModule; + std::string moduleParam; +}; \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDeviceAddForm.cpp b/src/forms/SDRDevices/SDRDeviceAddForm.cpp new file mode 100644 index 0000000..1903ae3 --- /dev/null +++ b/src/forms/SDRDevices/SDRDeviceAddForm.cpp @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Aug 23 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "SDRDeviceAddForm.h" + +/////////////////////////////////////////////////////////////////////////// + +SDRDeviceAddForm::SDRDeviceAddForm( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer6; + bSizer6 = new wxBoxSizer( wxVERTICAL ); + + m_staticText4 = new wxStaticText( this, wxID_ANY, wxT("Manually add a SoapyRemote or SoapySDR device. \n\nUseful for a device that is not detected automatically."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText4->Wrap( -1 ); + bSizer6->Add( m_staticText4, 0, wxALL, 10 ); + + + bSizer6->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxArrayString m_soapyModuleChoices; + m_soapyModule = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_soapyModuleChoices, 0 ); + m_soapyModule->SetSelection( 0 ); + bSizer6->Add( m_soapyModule, 0, wxALL, 10 ); + + + bSizer6->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_paramLabel = new wxStaticText( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ); + m_paramLabel->Wrap( -1 ); + bSizer6->Add( m_paramLabel, 0, wxALL, 10 ); + + m_paramText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_DONTWRAP ); + bSizer6->Add( m_paramText, 0, wxALL|wxEXPAND, 10 ); + + + bSizer6->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer7; + bSizer7 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer7->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_cancelButton = new wxButton( this, wxID_ANY, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer7->Add( m_cancelButton, 0, wxALL, 5 ); + + m_OkButton = new wxButton( this, wxID_ANY, wxT("Ok"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer7->Add( m_OkButton, 0, wxALL, 5 ); + + + bSizer6->Add( bSizer7, 1, wxEXPAND, 5 ); + + + bSizer6->Add( 0, 0, 1, wxEXPAND, 5 ); + + + this->SetSizer( bSizer6 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + m_soapyModule->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SDRDeviceAddForm::OnSoapyModuleChanged ), NULL, this ); + m_cancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SDRDeviceAddForm::OnCancelButton ), NULL, this ); + m_OkButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SDRDeviceAddForm::OnOkButton ), NULL, this ); +} + +SDRDeviceAddForm::~SDRDeviceAddForm() +{ + // Disconnect Events + m_soapyModule->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SDRDeviceAddForm::OnSoapyModuleChanged ), NULL, this ); + m_cancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SDRDeviceAddForm::OnCancelButton ), NULL, this ); + m_OkButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SDRDeviceAddForm::OnOkButton ), NULL, this ); + +} diff --git a/src/forms/SDRDevices/SDRDeviceAddForm.h b/src/forms/SDRDevices/SDRDeviceAddForm.h new file mode 100644 index 0000000..fd0bc73 --- /dev/null +++ b/src/forms/SDRDevices/SDRDeviceAddForm.h @@ -0,0 +1,56 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Aug 23 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __SDRDEVICEADDFORM_H__ +#define __SDRDEVICEADDFORM_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class SDRDeviceAddForm +/////////////////////////////////////////////////////////////////////////////// +class SDRDeviceAddForm : public wxDialog +{ + private: + + protected: + wxStaticText* m_staticText4; + wxChoice* m_soapyModule; + wxStaticText* m_paramLabel; + wxTextCtrl* m_paramText; + wxButton* m_cancelButton; + wxButton* m_OkButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnSoapyModuleChanged( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCancelButton( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOkButton( wxCommandEvent& event ) { event.Skip(); } + + + public: + + SDRDeviceAddForm( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Add SoapySDR Device"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 395,241 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~SDRDeviceAddForm(); + +}; + +#endif //__SDRDEVICEADDFORM_H__ diff --git a/src/forms/SDRDevices/SDRDevices.cpp b/src/forms/SDRDevices/SDRDevices.cpp index 0e27895..876171f 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; + devAddDialog = nullptr; } void SDRDevicesDialog::OnClose( wxCloseEvent& event ) { @@ -95,7 +96,7 @@ wxPGProperty *SDRDevicesDialog::addArgInfoProperty(wxPropertyGrid *pg, SoapySDR: void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection()); - if (selDev) { + if (selDev && selDev->isAvailable()) { dev = selDev; selId = devTree->GetSelection(); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getName()); @@ -109,7 +110,9 @@ void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { devSettings.erase(devSettings.begin(),devSettings.end()); devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) ); devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) ); - + + props.erase(props.begin(), props.end()); + if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings")); @@ -143,29 +146,54 @@ void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { } } + if (selDev->isManual()) { + // TODO: add remove button + } + + } else if (selDev && !selDev->isAvailable() && selDev->isManual()) { + m_propertyGrid->Clear(); + devSettings.erase(devSettings.begin(),devSettings.end()); + props.erase(props.begin(), props.end()); + dev = nullptr; + selId = nullptr; + editId = nullptr; + // TODO: add remove option + } event.Skip(); } void SDRDevicesDialog::OnAddRemote( wxMouseEvent& event ) { - if (!SDREnumerator::hasRemoteModule()) { - wxMessageDialog *info; - info = new wxMessageDialog(NULL, wxT("Install SoapyRemote module to add remote servers.\n\nhttps://github.com/pothosware/SoapyRemote"), wxT("SoapyRemote not found."), wxOK | wxICON_ERROR); - info->ShowModal(); - return; - } + devAddDialog = new SDRDeviceAddDialog(this); + devAddDialog->ShowModal(); - wxString remoteAddr = - wxGetTextFromUser("Remote Address (address[:port])\n\ni.e. 'raspberrypi.local', '192.168.1.103:1234'\n","SoapySDR Remote Address", "", this); + if (devAddDialog->wasOkPressed()) { + std::string module = devAddDialog->getSelectedModule(); + + if (module == "SoapyRemote") { + if (!SDREnumerator::hasRemoteModule()) { + wxMessageDialog *info; + info = new wxMessageDialog(NULL, wxT("Install SoapyRemote module to add remote servers.\n\nhttps://github.com/pothosware/SoapyRemote"), wxT("SoapyRemote not found."), wxOK | wxICON_ERROR); + info->ShowModal(); + return; + } - if (!remoteAddr.Trim().empty()) { - wxGetApp().addRemote(remoteAddr.Trim().ToStdString()); + wxString remoteAddr = devAddDialog->getModuleParam(); + + if (!remoteAddr.Trim().empty()) { + wxGetApp().addRemote(remoteAddr.Trim().ToStdString()); + } + devTree->Disable(); + m_addRemoteButton->Disable(); + m_useSelectedButton->Disable(); + refresh = true; + } else { + std::string mod = devAddDialog->getSelectedModule(); + std::string param = devAddDialog->getModuleParam(); + SDREnumerator::addManual(mod, param); + doRefreshDevices(); + } } - devTree->Disable(); - m_addRemoteButton->Disable(); - m_useSelectedButton->Disable(); - refresh = true; - } SDRDeviceInfo *SDRDevicesDialog::getSelectedDevice(wxTreeItemId selId) { @@ -263,12 +291,15 @@ void SDRDevicesDialog::OnDeviceTimer( wxTimerEvent& event ) { wxTreeItemId localBranch = devTree->AppendItem(devRoot, "Local"); wxTreeItemId dsBranch = devTree->AppendItem(devRoot, "Local Net"); wxTreeItemId remoteBranch = devTree->AppendItem(devRoot, "Remote"); + wxTreeItemId manualBranch = devTree->AppendItem(devRoot, "Manual"); devs[""] = SDREnumerator::enumerate_devices("",true); if (devs[""] != NULL) { for (devs_i = devs[""]->begin(); devs_i != devs[""]->end(); devs_i++) { DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice((*devs_i)->getDeviceId()); - if ((*devs_i)->isRemote()) { + if ((*devs_i)->isManual()) { + devItems[devTree->AppendItem(manualBranch, devConfig->getDeviceName())] = (*devs_i); + } else if ((*devs_i)->isRemote()) { devItems[devTree->AppendItem(dsBranch, devConfig->getDeviceName())] = (*devs_i); } else { devItems[devTree->AppendItem(localBranch, devConfig->getDeviceName())] = (*devs_i); @@ -308,20 +339,7 @@ void SDRDevicesDialog::OnDeviceTimer( wxTimerEvent& event ) { } void SDRDevicesDialog::OnRefreshDevices( wxMouseEvent& event ) { - wxGetApp().stopDevice(); - devTree->DeleteAllItems(); - devTree->Disable(); - m_propertyGrid->Clear(); - props.erase(props.begin(),props.end()); - devSettings.erase(devSettings.begin(), devSettings.end()); - m_refreshButton->Disable(); - m_addRemoteButton->Disable(); - m_useSelectedButton->Disable(); - wxGetApp().reEnumerateDevices(); - selId = nullptr; - editId = nullptr; - dev = nullptr; - refresh = true; + doRefreshDevices(); } void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) { @@ -354,3 +372,21 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) { void SDRDevicesDialog::OnPropGridFocus( wxFocusEvent& event ) { editId = selId; } + + +void SDRDevicesDialog::doRefreshDevices() { + wxGetApp().stopDevice(); + devTree->DeleteAllItems(); + devTree->Disable(); + m_propertyGrid->Clear(); + props.erase(props.begin(),props.end()); + devSettings.erase(devSettings.begin(), devSettings.end()); + m_refreshButton->Disable(); + m_addRemoteButton->Disable(); + m_useSelectedButton->Disable(); + wxGetApp().reEnumerateDevices(); + selId = nullptr; + editId = nullptr; + dev = nullptr; + refresh = true; +} \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDevices.fbp b/src/forms/SDRDevices/SDRDevices.fbp index 725a91a..daf4773 100644 --- a/src/forms/SDRDevices/SDRDevices.fbp +++ b/src/forms/SDRDevices/SDRDevices.fbp @@ -493,7 +493,7 @@ 5 wxALL - 0 + 1 1 1 @@ -611,7 +611,7 @@ 0 0 wxID_ANY - Add Remote + Add 0 @@ -699,7 +699,7 @@ 0 0 wxID_ANY - Use Selected + Start 0 diff --git a/src/forms/SDRDevices/SDRDevices.h b/src/forms/SDRDevices/SDRDevices.h index c47b06e..d8cedf0 100644 --- a/src/forms/SDRDevices/SDRDevices.h +++ b/src/forms/SDRDevices/SDRDevices.h @@ -6,6 +6,7 @@ #include "SDRDevicesForm.h" #include "SoapySDRThread.h" #include "SDREnumerator.h" +#include "SDRDeviceAdd.h" class SDRDevicesDialog: public devFrame { public: @@ -23,6 +24,8 @@ public: void OnPropGridFocus( wxFocusEvent& event ); private: + void doRefreshDevices(); + SDRDeviceInfo *getSelectedDevice(wxTreeItemId selId); wxPGProperty *addArgInfoProperty(wxPropertyGrid *pg, SoapySDR::ArgInfo arg); @@ -36,4 +39,5 @@ private: std::map devSettings; wxTreeItemId selId; wxTreeItemId editId; + SDRDeviceAddDialog *devAddDialog; }; \ No newline at end of file diff --git a/src/forms/SDRDevices/SDRDevicesForm.cpp b/src/forms/SDRDevices/SDRDevicesForm.cpp index 32def2f..b38a944 100644 --- a/src/forms/SDRDevices/SDRDevicesForm.cpp +++ b/src/forms/SDRDevices/SDRDevicesForm.cpp @@ -35,12 +35,12 @@ devFrame::devFrame( wxWindow* parent, wxWindowID id, const wxString& title, cons bSizer5 = new wxBoxSizer( wxHORIZONTAL ); m_refreshButton = new wxButton( m_panel4, wxID_ANY, wxT("Refresh"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer5->Add( m_refreshButton, 0, wxALL, 5 ); + bSizer5->Add( m_refreshButton, 1, wxALL, 5 ); - m_addRemoteButton = new wxButton( m_panel4, wxID_ANY, wxT("Add Remote"), wxDefaultPosition, wxDefaultSize, 0 ); + m_addRemoteButton = new wxButton( m_panel4, wxID_ANY, wxT("Add"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer5->Add( m_addRemoteButton, 1, wxALL, 5 ); - m_useSelectedButton = new wxButton( m_panel4, wxID_ANY, wxT("Use Selected"), wxDefaultPosition, wxDefaultSize, 0 ); + m_useSelectedButton = new wxButton( m_panel4, wxID_ANY, wxT("Start"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer5->Add( m_useSelectedButton, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); diff --git a/src/sdr/SDRDeviceInfo.cpp b/src/sdr/SDRDeviceInfo.cpp index 7805659..48f394a 100644 --- a/src/sdr/SDRDeviceInfo.cpp +++ b/src/sdr/SDRDeviceInfo.cpp @@ -160,7 +160,7 @@ std::vector SDRDeviceChannel::getStreamArgNames() { } -SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false), remote(false) { +SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false), remote(false), manual(false) { } @@ -262,6 +262,22 @@ void SDRDeviceInfo::setRemote(bool remote) { this->remote = remote; } +bool SDRDeviceInfo::isManual() const { + return manual; +} + +void SDRDeviceInfo::setManual(bool manual) { + this->manual = manual; +} + +void SDRDeviceInfo::setManualParams(std::string manualParams) { + this->manual_params = manualParams; +} + +std::string SDRDeviceInfo::getManualParams() { + return manual_params; +} + void SDRDeviceInfo::setDeviceArgs(SoapySDR::Kwargs deviceArgs) { this->deviceArgs = deviceArgs; } diff --git a/src/sdr/SDRDeviceInfo.h b/src/sdr/SDRDeviceInfo.h index 842d18d..62bfb9b 100644 --- a/src/sdr/SDRDeviceInfo.h +++ b/src/sdr/SDRDeviceInfo.h @@ -139,7 +139,13 @@ public: bool isRemote() const; void setRemote(bool remote); + + bool isManual() const; + void setManual(bool manual); + void setManualParams(std::string manualParams); + std::string getManualParams(); + void addChannel(SDRDeviceChannel *chan); std::vector &getChannels(); SDRDeviceChannel * getRxChannel(); @@ -159,8 +165,8 @@ public: private: int index; std::string name, serial, product, manufacturer, tuner; - std::string driver, hardware; - bool timestamps, available, remote; + std::string driver, hardware, manual_params; + bool timestamps, available, remote, manual; SoapySDR::Kwargs deviceArgs, streamArgs; SoapySDR::ArgInfoList settingInfo; diff --git a/src/sdr/SDREnumerator.cpp b/src/sdr/SDREnumerator.cpp index cf6c3d5..406c802 100644 --- a/src/sdr/SDREnumerator.cpp +++ b/src/sdr/SDREnumerator.cpp @@ -11,6 +11,7 @@ std::vector SDREnumerator::remotes; std::map< std::string, std::vector > SDREnumerator::devs; bool SDREnumerator::soapy_initialized = false; bool SDREnumerator::has_remote = false; +std::vector SDREnumerator::manuals; SDREnumerator::SDREnumerator() : IOThread() { @@ -20,6 +21,48 @@ SDREnumerator::~SDREnumerator() { } +// Some utility from SoapySDR :) +static std::string trim(const std::string &s) +{ + std::string out = s; + while (not out.empty() and std::isspace(out[0])) out = out.substr(1); + while (not out.empty() and std::isspace(out[out.size()-1])) out = out.substr(0, out.size()-1); + return out; +} + +SoapySDR::Kwargs SDREnumerator::argsStrToKwargs(const std::string &args) +{ + SoapySDR::Kwargs kwargs; + + bool inKey = true; + std::string key, val; + for (size_t i = 0; i < args.size(); i++) + { + const char ch = args[i]; + if (inKey) + { + if (ch == '=') inKey = false; + else if (ch == ',') inKey = true; + else key += ch; + } + else + { + if (ch == ',') inKey = true; + else val += ch; + } + if ((inKey and not val.empty()) or ((i+1) == args.size())) + { + key = trim(key); + val = trim(val); + if (not key.empty()) kwargs[key] = val; + key = ""; + val = ""; + } + } + + return kwargs; +} + std::vector *SDREnumerator::enumerate_devices(std::string remoteAddr, bool noInit) { @@ -77,14 +120,7 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot #endif } -// modules = SoapySDR::listModules(); -// for (size_t i = 0; i < modules.size(); i++) { -// std::cout << "\tModule found: " << modules[i] << std::endl; -// } -// if (modules.empty()) { -// std::cout << "No modules found!" << std::endl; -// } - + if (SDREnumerator::factories.size()) { SDREnumerator::factories.erase(SDREnumerator::factories.begin(), SDREnumerator::factories.end()); } @@ -113,6 +149,8 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot soapy_initialized = true; } + modules = SoapySDR::listModules(); + std::vector results; SoapySDR::Kwargs enumArgs; bool isRemote = false; @@ -128,6 +166,36 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot results = SoapySDR::Device::enumerate(); } + int manualsIdx = results.size(); + std::vector manualParams; + std::vector manualResult; + + if (manuals.size()) { + for (std::vector::const_iterator m_i = manuals.begin(); m_i != manuals.end(); m_i++) { + std::vector manual_result; + + std::string strDevArgs = "driver="+m_i->factory+","+m_i->params; + + manualParams.push_back(strDevArgs); + + wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Enumerating manual device '") + strDevArgs + "'.."); + + manual_result = SoapySDR::Device::enumerate(strDevArgs); + + if (manual_result.size()) { + for (std::vector::const_iterator i = manual_result.begin(); i != manual_result.end(); i++) { + results.push_back(*i); + manualResult.push_back(true); + } + } else { + SoapySDR::Kwargs failedEnum; + failedEnum = argsStrToKwargs(strDevArgs+",label=Not Found ("+m_i->factory+")"); + results.push_back(failedEnum); + manualResult.push_back(false); + } + } + } + if (isRemote) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Opening remote server ") + remoteAddr + ".."); } @@ -145,7 +213,6 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot } } - DeviceConfig *cfg = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); if (deviceArgs.count("remote")) { isRemote = true; @@ -154,9 +221,14 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot } dev->setRemote(isRemote); + dev->setManual(i>=manualsIdx); + if (i>=manualsIdx) { + dev->setManualParams(manualParams[i-manualsIdx]); + } std::cout << "Make device " << i << std::endl; - try { + if (igetDevice(dev->getDeviceId()); SoapySDR::Device *device = SoapySDR::Device::make(deviceArgs); SoapySDR::Kwargs info = device->getHardwareInfo(); for (SoapySDR::Kwargs::const_iterator it = info.begin(); it != info.end(); ++it) { @@ -253,6 +325,8 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot std::cerr << "Error making device: " << ex.what() << std::endl; wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Error querying device #") + std::to_string(i)); dev->setAvailable(false); + } else { + dev->setAvailable(false); } std::cout << std::endl; @@ -323,6 +397,13 @@ std::vector &SDREnumerator::getRemotes() { return remotes; } +void SDREnumerator::addManual(std::string factory, std::string params) { + SDRManualDef def; + def.factory = factory; + def.params = params; + manuals.push_back(def); +} + bool SDREnumerator::hasRemoteModule() { return SDREnumerator::has_remote; } @@ -333,3 +414,7 @@ void SDREnumerator::reset() { modules.erase(modules.begin(), modules.end()); devs.erase(devs.begin(), devs.end()); } + +std::vector &SDREnumerator::getFactories() { + return SDREnumerator::factories; +} diff --git a/src/sdr/SDREnumerator.h b/src/sdr/SDREnumerator.h index 5cefdc3..9ad0464 100644 --- a/src/sdr/SDREnumerator.h +++ b/src/sdr/SDREnumerator.h @@ -12,6 +12,11 @@ #include #include +typedef struct _SDRManualDef { + std::string factory; + std::string params; +} SDRManualDef; + class SDREnumerator: public IOThread { private: @@ -25,11 +30,15 @@ public: void run(); + static SoapySDR::Kwargs argsStrToKwargs(const std::string &args); static void addRemote(std::string remoteAddr); static void removeRemote(std::string remoteAddr); 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 reset(); + static std::vector &getFactories(); protected: static bool soapy_initialized, has_remote; @@ -37,4 +46,5 @@ protected: static std::vector modules; static std::vector remotes; static std::map< std::string, std::vector > devs; + static std::vector manuals; };