2015-04-13 19:58:34 -04:00
|
|
|
#include "AppConfig.h"
|
2015-07-08 01:07:39 -04:00
|
|
|
#include "CubicSDR.h"
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2015-07-14 20:27:32 -04:00
|
|
|
DeviceConfig::DeviceConfig() : deviceId("") {
|
2015-08-25 21:26:32 -04:00
|
|
|
iqSwap.store(0);
|
2015-07-14 20:27:32 -04:00
|
|
|
ppm.store(0);
|
|
|
|
directSampling.store(false);
|
|
|
|
offset.store(0);
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
2015-07-14 20:27:32 -04:00
|
|
|
DeviceConfig::DeviceConfig(std::string deviceId) : DeviceConfig() {
|
2015-04-21 23:19:45 -04:00
|
|
|
this->deviceId = deviceId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceConfig::setPPM(int ppm) {
|
2015-07-08 18:54:52 -04:00
|
|
|
this->ppm.store(ppm);
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int DeviceConfig::getPPM() {
|
2015-07-08 18:54:52 -04:00
|
|
|
return ppm.load();
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
2015-07-08 01:07:39 -04:00
|
|
|
void DeviceConfig::setDirectSampling(int mode) {
|
2015-07-08 18:54:52 -04:00
|
|
|
directSampling.store(mode);
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int DeviceConfig::getDirectSampling() {
|
2015-07-08 18:54:52 -04:00
|
|
|
return directSampling.load();
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceConfig::setOffset(long long offset) {
|
2015-07-08 18:54:52 -04:00
|
|
|
this->offset.store(offset);
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
long long DeviceConfig::getOffset() {
|
2015-07-08 18:54:52 -04:00
|
|
|
return offset.load();
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceConfig::setIQSwap(bool iqSwap) {
|
2015-07-08 18:54:52 -04:00
|
|
|
this->iqSwap.store(iqSwap);
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DeviceConfig::getIQSwap() {
|
2015-07-08 18:54:52 -04:00
|
|
|
return iqSwap.load();
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
void DeviceConfig::setDeviceId(std::string deviceId) {
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.lock();
|
2015-04-21 23:19:45 -04:00
|
|
|
this->deviceId = deviceId;
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.unlock();
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string DeviceConfig::getDeviceId() {
|
2015-07-08 18:54:52 -04:00
|
|
|
std::string tmp;
|
|
|
|
|
|
|
|
busy_lock.lock();
|
|
|
|
tmp = deviceId;
|
|
|
|
busy_lock.unlock();
|
|
|
|
|
|
|
|
return tmp;
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void DeviceConfig::save(DataNode *node) {
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.lock();
|
2015-07-08 01:07:39 -04:00
|
|
|
*node->newChild("id") = deviceId;
|
|
|
|
*node->newChild("ppm") = (int)ppm;
|
|
|
|
*node->newChild("iq_swap") = iqSwap;
|
|
|
|
*node->newChild("direct_sampling") = directSampling;
|
|
|
|
*node->newChild("offset") = offset;
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.unlock();
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
void DeviceConfig::load(DataNode *node) {
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.lock();
|
2015-04-21 23:19:45 -04:00
|
|
|
if (node->hasAnother("ppm")) {
|
|
|
|
DataNode *ppm_node = node->getNext("ppm");
|
|
|
|
int ppmValue = 0;
|
|
|
|
ppm_node->element()->get(ppmValue);
|
|
|
|
setPPM(ppmValue);
|
|
|
|
std::cout << "Loaded PPM for device '" << deviceId << "' at " << ppmValue << "ppm" << std::endl;
|
|
|
|
}
|
2015-07-08 01:07:39 -04:00
|
|
|
if (node->hasAnother("iq_swap")) {
|
|
|
|
DataNode *iq_swap_node = node->getNext("iq_swap");
|
|
|
|
int iqSwapValue = 0;
|
|
|
|
iq_swap_node->element()->get(iqSwapValue);
|
|
|
|
setIQSwap(iqSwapValue?true:false);
|
|
|
|
std::cout << "Loaded I/Q Swap for device '" << deviceId << "' as " << (iqSwapValue?"swapped":"not swapped") << std::endl;
|
|
|
|
}
|
|
|
|
if (node->hasAnother("direct_sampling")) {
|
|
|
|
DataNode *direct_sampling_node = node->getNext("direct_sampling");
|
|
|
|
int directSamplingValue = 0;
|
|
|
|
direct_sampling_node->element()->get(directSamplingValue);
|
|
|
|
setDirectSampling(directSamplingValue);
|
|
|
|
std::cout << "Loaded Direct Sampling Mode for device '" << deviceId << "': ";
|
|
|
|
switch (directSamplingValue) {
|
|
|
|
case 0:
|
|
|
|
std::cout << "off" << std::endl;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
std::cout << "I-ADC" << std::endl;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
std::cout << "Q-ADC" << std::endl;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (node->hasAnother("offset")) {
|
|
|
|
DataNode *offset_node = node->getNext("offset");
|
|
|
|
long long offsetValue = 0;
|
|
|
|
offset_node->element()->get(offsetValue);
|
|
|
|
setOffset(offsetValue);
|
2015-07-08 18:54:52 -04:00
|
|
|
std::cout << "Loaded offset for device '" << deviceId << "' at " << offsetValue << "Hz" << std::endl;
|
2015-07-08 01:07:39 -04:00
|
|
|
}
|
2015-07-08 18:54:52 -04:00
|
|
|
busy_lock.unlock();
|
2015-04-21 23:19:45 -04:00
|
|
|
}
|
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
AppConfig::AppConfig() : configName("") {
|
2015-07-16 18:57:03 -04:00
|
|
|
winX.store(0);
|
|
|
|
winY.store(0);
|
|
|
|
winW.store(0);
|
|
|
|
winH.store(0);
|
|
|
|
winMax.store(false);
|
|
|
|
themeId.store(0);
|
2015-07-18 21:49:53 -04:00
|
|
|
snap.store(1);
|
2015-07-20 22:51:19 -04:00
|
|
|
centerFreq.store(100000000);
|
2015-08-13 22:00:05 -04:00
|
|
|
waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
|
|
|
|
spectrumAvgSpeed.store(0.65f);
|
2015-07-16 18:57:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
|
|
|
|
DeviceConfig *AppConfig::getDevice(std::string deviceId) {
|
2015-07-14 19:44:19 -04:00
|
|
|
if (deviceConfig.find(deviceId) == deviceConfig.end()) {
|
|
|
|
deviceConfig[deviceId] = new DeviceConfig();
|
|
|
|
}
|
|
|
|
DeviceConfig *conf = deviceConfig[deviceId];
|
2015-04-21 23:19:45 -04:00
|
|
|
conf->setDeviceId(deviceId);
|
|
|
|
return conf;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string AppConfig::getConfigDir() {
|
2015-04-13 19:58:34 -04:00
|
|
|
std::string dataDir = wxStandardPaths::Get().GetUserDataDir().ToStdString();
|
|
|
|
|
|
|
|
bool mkStatus = false;
|
|
|
|
|
|
|
|
if (!wxDir::Exists(dataDir)) {
|
|
|
|
mkStatus = wxDir::Make(dataDir);
|
|
|
|
} else {
|
|
|
|
mkStatus = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mkStatus) {
|
|
|
|
std::cout << "Warning, unable to initialize user data directory." << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dataDir;
|
|
|
|
}
|
|
|
|
|
2015-07-15 00:32:36 -04:00
|
|
|
|
|
|
|
void AppConfig::setWindow(wxPoint winXY, wxSize winWH) {
|
|
|
|
winX.store(winXY.x);
|
|
|
|
winY.store(winXY.y);
|
|
|
|
winW.store(winWH.x);
|
|
|
|
winH.store(winWH.y);
|
|
|
|
}
|
|
|
|
|
2015-07-16 18:57:03 -04:00
|
|
|
void AppConfig::setWindowMaximized(bool max) {
|
|
|
|
winMax.store(max);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AppConfig::getWindowMaximized() {
|
|
|
|
return winMax.load();
|
|
|
|
}
|
|
|
|
|
2015-07-15 00:32:36 -04:00
|
|
|
wxRect *AppConfig::getWindow() {
|
|
|
|
wxRect *r = NULL;
|
|
|
|
if (winH.load() && winW.load()) {
|
|
|
|
r = new wxRect(winX.load(),winY.load(),winW.load(),winH.load());
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AppConfig::setTheme(int themeId) {
|
|
|
|
this->themeId.store(themeId);
|
|
|
|
}
|
|
|
|
|
|
|
|
int AppConfig::getTheme() {
|
|
|
|
return themeId.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-18 21:49:53 -04:00
|
|
|
void AppConfig::setSnap(long long snapVal) {
|
|
|
|
this->snap.store(snapVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
long long AppConfig::getSnap() {
|
|
|
|
return snap.load();
|
|
|
|
}
|
|
|
|
|
2015-07-20 22:51:19 -04:00
|
|
|
void AppConfig::setCenterFreq(long long freqVal) {
|
|
|
|
centerFreq.store(freqVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
long long AppConfig::getCenterFreq() {
|
|
|
|
return centerFreq.load();
|
|
|
|
}
|
|
|
|
|
2015-08-13 22:00:05 -04:00
|
|
|
|
|
|
|
void AppConfig::setWaterfallLinesPerSec(int lps) {
|
|
|
|
waterfallLinesPerSec.store(lps);
|
|
|
|
}
|
|
|
|
|
|
|
|
int AppConfig::getWaterfallLinesPerSec() {
|
|
|
|
return waterfallLinesPerSec.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AppConfig::setSpectrumAvgSpeed(float avgSpeed) {
|
|
|
|
spectrumAvgSpeed.store(avgSpeed);
|
|
|
|
}
|
|
|
|
|
|
|
|
float AppConfig::getSpectrumAvgSpeed() {
|
|
|
|
return spectrumAvgSpeed.load();
|
|
|
|
}
|
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
void AppConfig::setConfigName(std::string configName) {
|
|
|
|
this->configName = configName;
|
|
|
|
}
|
|
|
|
|
2015-07-20 22:09:36 -04:00
|
|
|
std::string AppConfig::getConfigFileName(bool ignoreName) {
|
2015-07-20 18:39:45 -04:00
|
|
|
std::string cfgFileDir = getConfigDir();
|
|
|
|
|
|
|
|
wxFileName cfgFile;
|
2015-07-20 22:09:36 -04:00
|
|
|
if (configName.length() && !ignoreName) {
|
2015-07-20 18:39:45 -04:00
|
|
|
std::string tempFn("config-");
|
|
|
|
tempFn.append(configName);
|
|
|
|
tempFn.append(".xml");
|
|
|
|
cfgFile = wxFileName(cfgFileDir, tempFn);
|
|
|
|
} else {
|
|
|
|
cfgFile = wxFileName(cfgFileDir, "config.xml");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string cfgFileName = cfgFile.GetFullPath(wxPATH_NATIVE).ToStdString();
|
|
|
|
|
|
|
|
return cfgFileName;
|
|
|
|
}
|
2015-07-18 21:49:53 -04:00
|
|
|
|
2015-04-13 19:58:34 -04:00
|
|
|
bool AppConfig::save() {
|
|
|
|
DataTree cfg;
|
|
|
|
|
|
|
|
cfg.rootNode()->setName("cubicsdr_config");
|
2015-07-15 00:32:36 -04:00
|
|
|
|
|
|
|
if (winW.load() && winH.load()) {
|
|
|
|
DataNode *window_node = cfg.rootNode()->newChild("window");
|
|
|
|
|
|
|
|
*window_node->newChild("x") = winX.load();
|
|
|
|
*window_node->newChild("y") = winY.load();
|
|
|
|
*window_node->newChild("w") = winW.load();
|
|
|
|
*window_node->newChild("h") = winH.load();
|
|
|
|
|
2015-07-16 18:57:03 -04:00
|
|
|
*window_node->newChild("max") = winMax.load();
|
2015-07-15 00:32:36 -04:00
|
|
|
*window_node->newChild("theme") = themeId.load();
|
2015-07-18 21:49:53 -04:00
|
|
|
*window_node->newChild("snap") = snap.load();
|
2015-07-20 22:51:19 -04:00
|
|
|
*window_node->newChild("center_freq") = centerFreq.load();
|
2015-08-13 22:00:05 -04:00
|
|
|
*window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
|
|
|
|
*window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load();
|
2015-07-15 00:32:36 -04:00
|
|
|
}
|
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
DataNode *devices_node = cfg.rootNode()->newChild("devices");
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2015-07-14 19:44:19 -04:00
|
|
|
std::map<std::string, DeviceConfig *>::iterator device_config_i;
|
2015-04-21 23:19:45 -04:00
|
|
|
for (device_config_i = deviceConfig.begin(); device_config_i != deviceConfig.end(); device_config_i++) {
|
|
|
|
DataNode *device_node = devices_node->newChild("device");
|
2015-07-14 19:44:19 -04:00
|
|
|
device_config_i->second->save(device_node);
|
2015-04-13 19:58:34 -04:00
|
|
|
}
|
2015-07-15 00:32:36 -04:00
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
std::string cfgFileName = getConfigFileName();
|
|
|
|
|
2015-04-13 19:58:34 -04:00
|
|
|
if (!cfg.SaveToFileXML(cfgFileName)) {
|
|
|
|
std::cout << "Error saving :: configuration file '" << cfgFileName << "' is not writable!" << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AppConfig::load() {
|
|
|
|
DataTree cfg;
|
|
|
|
std::string cfgFileDir = getConfigDir();
|
|
|
|
|
2015-07-20 18:39:45 -04:00
|
|
|
std::string cfgFileName = getConfigFileName();
|
|
|
|
wxFileName cfgFile = wxFileName(cfgFileName);
|
2015-04-13 19:58:34 -04:00
|
|
|
|
|
|
|
if (!cfgFile.Exists()) {
|
2015-07-20 22:09:36 -04:00
|
|
|
if (configName.length()) {
|
|
|
|
wxFileName baseConfig = wxFileName(getConfigFileName(true));
|
|
|
|
if (baseConfig.Exists()) {
|
|
|
|
std::string baseConfigFileName = baseConfig.GetFullPath(wxPATH_NATIVE).ToStdString();
|
|
|
|
std::cout << "Creating new configuration file '" << cfgFileName << "' by copying '" << baseConfigFileName << "'..";
|
|
|
|
wxCopyFile(baseConfigFileName, cfgFileName);
|
|
|
|
if (!cfgFile.Exists()) {
|
|
|
|
std::cout << "failed." << std::endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
std::cout << "ok." << std::endl;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
2015-04-13 19:58:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (cfgFile.IsFileReadable()) {
|
2015-04-21 23:19:45 -04:00
|
|
|
std::cout << "Loading:: configuration file '" << cfgFileName << "'" << std::endl;
|
|
|
|
|
2015-04-13 19:58:34 -04:00
|
|
|
cfg.LoadFromFileXML(cfgFileName);
|
|
|
|
} else {
|
|
|
|
std::cout << "Error loading:: configuration file '" << cfgFileName << "' is not readable!" << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-15 00:32:36 -04:00
|
|
|
if (cfg.rootNode()->hasAnother("window")) {
|
|
|
|
int x,y,w,h;
|
2015-07-16 18:57:03 -04:00
|
|
|
int max;
|
2015-07-15 00:32:36 -04:00
|
|
|
|
|
|
|
DataNode *win_node = cfg.rootNode()->getNext("window");
|
|
|
|
|
|
|
|
if (win_node->hasAnother("w") && win_node->hasAnother("h") && win_node->hasAnother("x") && win_node->hasAnother("y")) {
|
|
|
|
win_node->getNext("x")->element()->get(x);
|
|
|
|
win_node->getNext("y")->element()->get(y);
|
|
|
|
win_node->getNext("w")->element()->get(w);
|
|
|
|
win_node->getNext("h")->element()->get(h);
|
|
|
|
|
|
|
|
winX.store(x);
|
|
|
|
winY.store(y);
|
|
|
|
winW.store(w);
|
|
|
|
winH.store(h);
|
|
|
|
}
|
|
|
|
|
2015-07-16 18:57:03 -04:00
|
|
|
if (win_node->hasAnother("max")) {
|
|
|
|
win_node->getNext("max")->element()->get(max);
|
|
|
|
winMax.store(max?true:false);
|
|
|
|
}
|
|
|
|
|
2015-07-15 00:32:36 -04:00
|
|
|
if (win_node->hasAnother("theme")) {
|
|
|
|
int theme;
|
|
|
|
win_node->getNext("theme")->element()->get(theme);
|
|
|
|
themeId.store(theme);
|
|
|
|
}
|
|
|
|
|
2015-07-18 21:49:53 -04:00
|
|
|
if (win_node->hasAnother("snap")) {
|
|
|
|
long long snapVal;
|
|
|
|
win_node->getNext("snap")->element()->get(snapVal);
|
|
|
|
snap.store(snapVal);
|
|
|
|
}
|
2015-07-20 22:51:19 -04:00
|
|
|
|
|
|
|
if (win_node->hasAnother("center_freq")) {
|
|
|
|
long long freqVal;
|
|
|
|
win_node->getNext("center_freq")->element()->get(freqVal);
|
|
|
|
centerFreq.store(freqVal);
|
|
|
|
}
|
2015-08-13 22:00:05 -04:00
|
|
|
|
|
|
|
if (win_node->hasAnother("waterfall_lps")) {
|
|
|
|
int lpsVal;
|
|
|
|
win_node->getNext("waterfall_lps")->element()->get(lpsVal);
|
|
|
|
waterfallLinesPerSec.store(lpsVal);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (win_node->hasAnother("spectrum_avg")) {
|
|
|
|
float avgVal;
|
|
|
|
win_node->getNext("spectrum_avg")->element()->get(avgVal);
|
|
|
|
spectrumAvgSpeed.store(avgVal);
|
|
|
|
}
|
|
|
|
}
|
2015-07-15 00:32:36 -04:00
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
if (cfg.rootNode()->hasAnother("devices")) {
|
|
|
|
DataNode *devices_node = cfg.rootNode()->getNext("devices");
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
while (devices_node->hasAnother("device")) {
|
|
|
|
DataNode *device_node = devices_node->getNext("device");
|
|
|
|
if (device_node->hasAnother("id")) {
|
|
|
|
std::string deviceId;
|
|
|
|
device_node->getNext("id")->element()->get(deviceId);
|
2015-04-13 19:58:34 -04:00
|
|
|
|
2015-04-21 23:19:45 -04:00
|
|
|
getDevice(deviceId)->load(device_node);
|
2015-04-13 19:58:34 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AppConfig::reset() {
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|