| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2020 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | // (at your option) any later version.                                           //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "SWGDeviceState.h"
 | 
					
						
							|  |  |  | #include "SWGSuccessResponse.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | #include "SWGDeviceSettings.h"
 | 
					
						
							|  |  |  | #include "SWGChannelSettings.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | #include "SWGErrorResponse.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "webapi/webapiadapterinterface.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | #include "webapi/webapiutils.h"
 | 
					
						
							|  |  |  | #include "device/deviceset.h"
 | 
					
						
							|  |  |  | #include "device/deviceapi.h"
 | 
					
						
							|  |  |  | #include "channel/channelapi.h"
 | 
					
						
							|  |  |  | #include "feature/feature.h"
 | 
					
						
							|  |  |  | #include "maincore.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "afcreport.h"
 | 
					
						
							|  |  |  | #include "afcworker.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(AFCWorker::MsgConfigureAFCWorker, Message) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(AFCWorker::MsgTrackedDeviceChange, Message) | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(AFCWorker::MsgDeviceTrack, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(AFCWorker::MsgDevicesApply, Message) | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | AFCWorker::AFCWorker(WebAPIAdapterInterface *webAPIAdapterInterface) : | 
					
						
							|  |  |  |     m_webAPIAdapterInterface(webAPIAdapterInterface), | 
					
						
							|  |  |  |     m_msgQueueToGUI(nullptr), | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     m_freqTracker(nullptr), | 
					
						
							|  |  |  |     m_trackerDeviceFrequency(0), | 
					
						
							|  |  |  |     m_trackerChannelOffset(0), | 
					
						
							| 
									
										
										
										
											2022-09-15 21:59:42 +02:00
										 |  |  |     m_updateTimer(this) | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     qDebug("AFCWorker::AFCWorker"); | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  | 	connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateTarget())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_settings.m_hasTargetFrequency) { | 
					
						
							|  |  |  |     	m_updateTimer.start(m_settings.m_trackerAdjustPeriod * 1000); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AFCWorker::~AFCWorker() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_inputMessageQueue.clear(); | 
					
						
							| 
									
										
										
										
											2022-09-21 06:01:45 +02:00
										 |  |  |     stopWork(); | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::reset() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     m_inputMessageQueue.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 06:01:45 +02:00
										 |  |  | void AFCWorker::startWork() | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::stopWork() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::handleInputMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((message = m_inputMessageQueue.pop()) != nullptr) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (handleMessage(*message)) { | 
					
						
							|  |  |  | 			delete message; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AFCWorker::handleMessage(const Message& cmd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (MsgConfigureAFCWorker::match(cmd)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         qDebug() << "AFCWorker::handleMessage: MsgConfigureAFCWorker"; | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  |         QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |         MsgConfigureAFCWorker& cfg = (MsgConfigureAFCWorker&) cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  |         applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce()); | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-13 13:04:36 +01:00
										 |  |  |     else if (MainCore::MsgChannelSettings::match(cmd)) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QMutexLocker mutexLocker(&m_mutex); | 
					
						
							| 
									
										
										
										
											2020-12-13 13:04:36 +01:00
										 |  |  |         MainCore::MsgChannelSettings& cfg = (MainCore::MsgChannelSettings&) cmd; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         SWGSDRangel::SWGChannelSettings *swgChannelSettings = cfg.getSWGSettings(); | 
					
						
							| 
									
										
										
										
											2020-12-13 13:04:36 +01:00
										 |  |  |         qDebug() << "AFCWorker::handleMessage: MainCore::MsgChannelSettings:" << *swgChannelSettings->getChannelType(); | 
					
						
							| 
									
										
										
										
											2020-11-14 11:13:32 +01:00
										 |  |  |         processChannelSettings(cfg.getChannelAPI(), swgChannelSettings); | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         delete swgChannelSettings; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |     else if (MsgDeviceTrack::match(cmd)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-26 21:39:34 +01:00
										 |  |  |         qDebug() << "AFCWorker::handleMessage: MsgDeviceTrack"; | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |         QMutexLocker mutexLocker(&m_mutex); | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |         updateTarget(); | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (MsgDevicesApply::match(cmd)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-26 21:39:34 +01:00
										 |  |  |         qDebug() << "AFCWorker::handleMessage: MsgDevicesApply"; | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |         QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |         initTrackerDeviceSet(m_settings.m_trackerDeviceSetIndex); | 
					
						
							|  |  |  |         initTrackedDeviceSet(m_settings.m_trackedDeviceSetIndex); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  | void AFCWorker::applySettings(const AFCSettings& settings, const QList<QString>& settingsKeys, bool force) | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  |     qDebug() << "AFCWorker::applySettings:" << settings.getDebugString(settingsKeys, force)  << " force: " << force; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (settingsKeys.contains("trackerDeviceSetIndex") || force) { | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         initTrackerDeviceSet(settings.m_trackerDeviceSetIndex); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  |     if (settingsKeys.contains("trackedDeviceSetIndex") || force) { | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         initTrackedDeviceSet(settings.m_trackedDeviceSetIndex); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  |     if (settingsKeys.contains("trackerAdjustPeriod") || force) { | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |         m_updateTimer.setInterval(settings.m_trackerAdjustPeriod * 1000); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-19 23:30:49 +01:00
										 |  |  |     if (settingsKeys.contains("hasTargetFrequency") || force) | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (settings.m_hasTargetFrequency) { | 
					
						
							|  |  |  |             m_updateTimer.start(m_settings.m_trackerAdjustPeriod * 1000); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             m_updateTimer.stop(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 00:19:12 +01:00
										 |  |  |     if (force) { | 
					
						
							|  |  |  |         m_settings = settings; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         m_settings.applySettings(settingsKeys, settings); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-16 19:20:55 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::initTrackerDeviceSet(int deviceSetIndex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-27 09:58:16 +01:00
										 |  |  |     if (deviceSetIndex < 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     MainCore *mainCore = MainCore::instance(); | 
					
						
							|  |  |  |     m_trackerDeviceSet = mainCore->getDeviceSets()[deviceSetIndex]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < m_trackerDeviceSet->getNumberOfChannels(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ChannelAPI *channel = m_trackerDeviceSet->getChannelAt(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (channel->getURI() == "sdrangel.channel.freqtracker") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_freqTracker = channel; | 
					
						
							|  |  |  |             SWGSDRangel::SWGDeviceSettings resDevice; | 
					
						
							|  |  |  |             SWGSDRangel::SWGChannelSettings resChannel; | 
					
						
							|  |  |  |             SWGSDRangel::SWGErrorResponse error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int rc = m_webAPIAdapterInterface->devicesetDeviceSettingsGet(deviceSetIndex, resDevice, error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (rc / 100 == 2) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QJsonObject *jsonObj = resDevice.asJsonObject(); | 
					
						
							|  |  |  |                 QJsonValue freqValue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (WebAPIUtils::extractValue(*jsonObj, "centerFrequency", freqValue)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     double freq = freqValue.toDouble(); | 
					
						
							|  |  |  |                     m_trackerDeviceFrequency = freq; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     qDebug() << "AFCWorker::initTrackerDeviceSet: cannot find device frequency"; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qDebug() << "AFCWorker::initTrackerDeviceSet: devicesetDeviceSettingsGet error" << rc << ":" << *error.getMessage(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             rc = m_webAPIAdapterInterface->devicesetChannelSettingsGet(deviceSetIndex, i, resChannel, error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (rc / 100 == 2) { | 
					
						
							|  |  |  |                 m_trackerChannelOffset = resChannel.getFreqTrackerSettings()->getInputFrequencyOffset(); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 qDebug() << "AFCWorker::initTrackerDeviceSet: devicesetChannelSettingsGet error" << rc << ":" << *error.getMessage(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::initTrackedDeviceSet(int deviceSetIndex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-27 09:58:16 +01:00
										 |  |  |     if (deviceSetIndex < 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     MainCore *mainCore = MainCore::instance(); | 
					
						
							|  |  |  |     m_trackedDeviceSet = mainCore->getDeviceSets()[deviceSetIndex]; | 
					
						
							|  |  |  |     m_channelsMap.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < m_trackedDeviceSet->getNumberOfChannels(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ChannelAPI *channel = m_trackedDeviceSet->getChannelAt(i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (channel->getURI() != "sdrangel.channel.freqtracker") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             SWGSDRangel::SWGChannelSettings resChannel; | 
					
						
							|  |  |  |             SWGSDRangel::SWGErrorResponse error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int rc = m_webAPIAdapterInterface->devicesetChannelSettingsGet(deviceSetIndex, i, resChannel, error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (rc / 100 == 2) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QJsonObject *jsonObj = resChannel.asJsonObject(); | 
					
						
							|  |  |  |                 QJsonValue directionValue; | 
					
						
							|  |  |  |                 QJsonValue channelOffsetValue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (WebAPIUtils::extractValue(*jsonObj, "direction", directionValue)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     int direction = directionValue.toInt(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (WebAPIUtils::extractValue(*jsonObj, "inputFrequencyOffset", channelOffsetValue)) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         int channelOffset = channelOffsetValue.toInt(); | 
					
						
							|  |  |  |                         m_channelsMap.insert(channel, ChannelTracking{channelOffset, m_trackerChannelOffset, direction}); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         qDebug() << "AFCWorker::initTrackedDeviceSet: cannot find channel offset frequency"; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     qDebug() << "AFCWorker::initTrackedDeviceSet: cannot find channel direction"; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qDebug() << "AFCWorker::initTrackedDeviceSet: devicesetChannelSettingsGet error" << rc << ":" << *error.getMessage(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::processChannelSettings( | 
					
						
							|  |  |  |     const ChannelAPI *channelAPI, | 
					
						
							|  |  |  |     SWGSDRangel::SWGChannelSettings *swgChannelSettings) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MainCore *mainCore = MainCore::instance(); | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |     QJsonObject *jsonObj = swgChannelSettings->asJsonObject(); | 
					
						
							|  |  |  |     QJsonValue channelOffsetValue; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |     if (WebAPIUtils::extractValue(*jsonObj, "inputFrequencyOffset", channelOffsetValue)) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |         if (*swgChannelSettings->getChannelType() == "FreqTracker") | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-10-26 00:39:25 +01:00
										 |  |  |             int trackerChannelOffset = channelOffsetValue.toInt(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (trackerChannelOffset != m_trackerChannelOffset) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2020-10-26 00:39:25 +01:00
										 |  |  |                 qDebug("AFCWorker::processChannelSettings: FreqTracker offset change: %d", trackerChannelOffset); | 
					
						
							| 
									
										
										
										
											2020-10-26 21:39:34 +01:00
										 |  |  |                 m_trackerChannelOffset = trackerChannelOffset; | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |                 QMap<ChannelAPI*, ChannelTracking>::iterator it = m_channelsMap.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for (; it != m_channelsMap.end(); ++it) | 
					
						
							| 
									
										
										
										
											2020-10-24 13:05:28 +02:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |                     if (mainCore->existsChannel(it.key())) | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2020-10-26 00:39:25 +01:00
										 |  |  |                         int channelOffset = it.value().m_channelOffset + trackerChannelOffset - it.value().m_trackerOffset; | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |                         updateChannelOffset(it.key(), it.value().m_channelDirection, channelOffset); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         m_channelsMap.erase(it); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-10-24 13:05:28 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |         else if (m_channelsMap.contains(const_cast<ChannelAPI*>(channelAPI))) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-10-26 00:39:25 +01:00
										 |  |  |             int channelOffset = channelOffsetValue.toInt(); | 
					
						
							|  |  |  |             m_channelsMap[const_cast<ChannelAPI*>(channelAPI)].m_channelOffset = channelOffset; | 
					
						
							|  |  |  |             m_channelsMap[const_cast<ChannelAPI*>(channelAPI)].m_trackerOffset = m_trackerChannelOffset; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 11:13:32 +01:00
										 |  |  | bool AFCWorker::updateChannelOffset(ChannelAPI *channelAPI, int direction, int offset) | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     SWGSDRangel::SWGChannelSettings swgChannelSettings; | 
					
						
							|  |  |  |     SWGSDRangel::SWGErrorResponse errorResponse; | 
					
						
							|  |  |  |     QString channelId; | 
					
						
							|  |  |  |     channelAPI->getIdentifier(channelId); | 
					
						
							|  |  |  |     swgChannelSettings.init(); | 
					
						
							|  |  |  |     qDebug() << "AFCWorker::updateChannelOffset:" << channelId << ":" << offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QStringList channelSettingsKeys; | 
					
						
							|  |  |  |     channelSettingsKeys.append("inputFrequencyOffset"); | 
					
						
							|  |  |  |     QString jsonSettingsStr = tr("\"inputFrequencyOffset\":%1").arg(offset); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString jsonStr = tr("{ \"channelType\": \"%1\", \"direction\": \"%2\", \"%3Settings\": {%4}}") | 
					
						
							|  |  |  |         .arg(QString(channelId)) | 
					
						
							|  |  |  |         .arg(direction) | 
					
						
							|  |  |  |         .arg(QString(channelId)) | 
					
						
							|  |  |  |         .arg(jsonSettingsStr); | 
					
						
							|  |  |  |     swgChannelSettings.fromJson(jsonStr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int httpRC = m_webAPIAdapterInterface->devicesetChannelSettingsPutPatch( | 
					
						
							|  |  |  |         m_trackedDeviceSet->getIndex(), | 
					
						
							|  |  |  |         channelAPI->getIndexInDeviceSet(), | 
					
						
							|  |  |  |         false, // PATCH
 | 
					
						
							|  |  |  |         channelSettingsKeys, | 
					
						
							|  |  |  |         swgChannelSettings, | 
					
						
							|  |  |  |         errorResponse | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  |     if (httpRC / 100 != 2) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         qDebug() << "AFCWorker::updateChannelOffset: error code" << httpRC << ":" << *errorResponse.getMessage(); | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  | void AFCWorker::updateTarget() | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     SWGSDRangel::SWGDeviceSettings resDevice; | 
					
						
							|  |  |  |     SWGSDRangel::SWGChannelSettings resChannel; | 
					
						
							|  |  |  |     SWGSDRangel::SWGErrorResponse error; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int rc = m_webAPIAdapterInterface->devicesetDeviceSettingsGet(m_settings.m_trackerDeviceSetIndex, resDevice, error); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rc / 100 == 2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QJsonObject *jsonObj = resDevice.asJsonObject(); | 
					
						
							|  |  |  |         QJsonValue freqValue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (WebAPIUtils::extractValue(*jsonObj, "centerFrequency", freqValue)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             double freq = freqValue.toDouble(); | 
					
						
							|  |  |  |             m_trackerDeviceFrequency = freq; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |             qDebug() << "AFCWorker::updateTarget: cannot find device frequency"; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |         qDebug() << "AFCWorker::updateTarget: devicesetDeviceSettingsGet error" << rc << ":" << *error.getMessage(); | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |     int64_t trackerFrequency = m_trackerDeviceFrequency + m_trackerChannelOffset; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     int64_t correction = m_settings.m_targetFrequency - trackerFrequency; | 
					
						
							|  |  |  |     int64_t tolerance = m_settings.m_freqTolerance; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 13:48:19 +01:00
										 |  |  |     if ((correction > -tolerance) && (correction < tolerance)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         reportUpdateTarget(correction, false); | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_settings.m_transverterTarget) // act on transverter
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QJsonObject *jsonObj = resDevice.asJsonObject(); | 
					
						
							|  |  |  |         QJsonValue xverterFrequencyValue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  |         // adjust transverter
 | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |         if (WebAPIUtils::extractValue(*jsonObj, "transverterDeltaFrequency", xverterFrequencyValue)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             double xverterFrequency = xverterFrequencyValue.toDouble(); | 
					
						
							|  |  |  |             updateDeviceFrequency(m_trackerDeviceSet, "transverterDeltaFrequency", xverterFrequency + correction); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |             qDebug() << "AFCWorker::updateTarget: cannot find device transverter frequency"; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // adjust tracker offset
 | 
					
						
							| 
									
										
										
										
											2020-11-14 11:13:32 +01:00
										 |  |  |         if (updateChannelOffset(m_freqTracker, 0, m_trackerChannelOffset + correction)) { | 
					
						
							| 
									
										
										
										
											2020-10-25 11:34:47 +01:00
										 |  |  |             m_trackerChannelOffset += correction; | 
					
						
							| 
									
										
										
										
											2020-10-23 08:32:26 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-26 13:48:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         reportUpdateTarget(correction, true); | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else // act on device
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QJsonObject *jsonObj = resDevice.asJsonObject(); | 
					
						
							|  |  |  |         QJsonValue deviceFrequencyValue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (WebAPIUtils::extractValue(*jsonObj, "centerFrequency", deviceFrequencyValue)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             double deviceFrequency = deviceFrequencyValue.toDouble(); | 
					
						
							|  |  |  |             updateDeviceFrequency(m_trackerDeviceSet, "centerFrequency", deviceFrequency + correction); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |             qDebug() << "AFCWorker::updateTarget: cannot find device transverter frequency"; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-26 13:48:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         reportUpdateTarget(correction, true); | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AFCWorker::updateDeviceFrequency(DeviceSet *deviceSet, const QString& key, int64_t frequency) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SWGSDRangel::SWGDeviceSettings swgDeviceSettings; | 
					
						
							|  |  |  |     SWGSDRangel::SWGErrorResponse errorResponse; | 
					
						
							|  |  |  |     QStringList deviceSettingsKeys; | 
					
						
							|  |  |  |     deviceSettingsKeys.append(key); | 
					
						
							|  |  |  |     int deviceIndex = deviceSet->getIndex(); | 
					
						
							|  |  |  |     DeviceAPI *deviceAPI = deviceSet->m_deviceAPI; | 
					
						
							|  |  |  |     swgDeviceSettings.init(); | 
					
						
							|  |  |  |     QString jsonSettingsStr = tr("\"%1\":%2").arg(key).arg(frequency); | 
					
						
							|  |  |  |     QString deviceSettingsKey; | 
					
						
							|  |  |  |     getDeviceSettingsKey(deviceAPI, deviceSettingsKey); | 
					
						
							| 
									
										
										
										
											2020-10-24 10:35:07 +02:00
										 |  |  |     qDebug() << "AFCWorker::updateDeviceFrequency:" | 
					
						
							|  |  |  |         << deviceAPI->getHardwareId() | 
					
						
							|  |  |  |         << ":" << key | 
					
						
							|  |  |  |         << ":" << frequency; | 
					
						
							| 
									
										
										
										
											2020-10-22 08:38:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QString jsonStr = tr("{ \"deviceHwType\": \"%1\", \"direction\": \"%2\", \"%3\": {%4}}") | 
					
						
							|  |  |  |         .arg(deviceAPI->getHardwareId()) | 
					
						
							|  |  |  |         .arg(getDeviceDirection(deviceAPI)) | 
					
						
							|  |  |  |         .arg(deviceSettingsKey) | 
					
						
							|  |  |  |         .arg(jsonSettingsStr); | 
					
						
							|  |  |  |     swgDeviceSettings.fromJson(jsonStr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int httpRC = m_webAPIAdapterInterface->devicesetDeviceSettingsPutPatch | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |         deviceIndex, | 
					
						
							|  |  |  |         false, // PATCH
 | 
					
						
							|  |  |  |         deviceSettingsKeys, | 
					
						
							|  |  |  |         swgDeviceSettings, | 
					
						
							|  |  |  |         errorResponse | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (httpRC / 100 != 2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("AFCWorker::updateDeviceFrequency: error %d: %s", httpRC, qPrintable(*errorResponse.getMessage())); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int AFCWorker::getDeviceDirection(DeviceAPI *deviceAPI) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (deviceAPI->getSampleSink()) { | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } else if (deviceAPI->getSampleMIMO()) { | 
					
						
							|  |  |  |         return 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::getDeviceSettingsKey(DeviceAPI *deviceAPI, QString& settingsKey) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const QString& deviceHwId = deviceAPI->getHardwareId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (deviceAPI->getSampleSink()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (WebAPIUtils::m_sinkDeviceHwIdToSettingsKey.contains(deviceHwId)) { | 
					
						
							|  |  |  |             settingsKey = WebAPIUtils::m_sinkDeviceHwIdToSettingsKey[deviceHwId]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (deviceAPI->getSampleMIMO()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (WebAPIUtils::m_mimoDeviceHwIdToSettingsKey.contains(deviceHwId)) { | 
					
						
							|  |  |  |             settingsKey = WebAPIUtils::m_mimoDeviceHwIdToSettingsKey[deviceHwId]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (WebAPIUtils::m_sourceDeviceHwIdToSettingsKey.contains(deviceHwId)) { | 
					
						
							|  |  |  |             settingsKey = WebAPIUtils::m_sourceDeviceHwIdToSettingsKey[deviceHwId]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-26 13:48:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void AFCWorker::reportUpdateTarget(int correction, bool done) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_msgQueueToGUI) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         AFCReport::MsgUpdateTarget *msg = AFCReport::MsgUpdateTarget::create(correction, done); | 
					
						
							|  |  |  |         m_msgQueueToGUI->push(msg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |