| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2023-11-18 13:12:18 +01:00
										 |  |  | // Copyright (C) 2019-2020, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com>    //
 | 
					
						
							|  |  |  | // Copyright (C) 2020 Vort <vvort@yandex.ru>                                     //
 | 
					
						
							|  |  |  | // Copyright (C) 2021-2022 Jon Beniston, M7RCE <jon@beniston.com>                //
 | 
					
						
							|  |  |  | // Copyright (C) 2022 Jiří Pinkava <jiri.pinkava@rossum.ai>                      //
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef INCLUDE_FEATURE_VORLOCALIZERWORKER_H_
 | 
					
						
							|  |  |  | #define INCLUDE_FEATURE_VORLOCALIZERWORKER_H_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QObject>
 | 
					
						
							|  |  |  | #include <QTimer>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "util/message.h"
 | 
					
						
							|  |  |  | #include "util/messagequeue.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "vorlocalizersettings.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WebAPIAdapterInterface; | 
					
						
							|  |  |  | class ChannelAPI; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | class Feature; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class VorLocalizerWorker : public QObject | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_OBJECT | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     class MsgConfigureVORLocalizerWorker : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         const VORLocalizerSettings& getSettings() const { return m_settings; } | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |         const QList<QString>& getSettingsKeys() const { return m_settingsKeys; } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         bool getForce() const { return m_force; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |         static MsgConfigureVORLocalizerWorker* create(const VORLocalizerSettings& settings, const QList<QString>& settingsKeys, bool force) | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |             return new MsgConfigureVORLocalizerWorker(settings, settingsKeys, force); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         VORLocalizerSettings m_settings; | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |         QList<QString> m_settingsKeys; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |         bool m_force; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |         MsgConfigureVORLocalizerWorker(const VORLocalizerSettings& settings, const QList<QString>& settingsKeys, bool force) : | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             Message(), | 
					
						
							|  |  |  |             m_settings(settings), | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |             m_settingsKeys(settingsKeys), | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |             m_force(force) | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MsgRefreshChannels : public Message { | 
					
						
							|  |  |  |         MESSAGE_CLASS_DECLARATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         static MsgRefreshChannels* create() { | 
					
						
							|  |  |  |             return new MsgRefreshChannels(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected: | 
					
						
							|  |  |  |         MsgRefreshChannels() : | 
					
						
							|  |  |  |             Message() | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VorLocalizerWorker(WebAPIAdapterInterface *webAPIAdapterInterface); | 
					
						
							|  |  |  |     ~VorLocalizerWorker(); | 
					
						
							|  |  |  |     void reset(); | 
					
						
							| 
									
										
										
										
											2022-09-24 12:41:05 +02:00
										 |  |  |     void startWork(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     void stopWork(); | 
					
						
							|  |  |  |     MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     void setMessageQueueToFeature(MessageQueue *messageQueue) { m_msgQueueToFeature = messageQueue; } | 
					
						
							|  |  |  |     void setAvailableChannels(QHash<ChannelAPI*, VORLocalizerSettings::AvailableChannel> *avaialbleChannels) { | 
					
						
							|  |  |  |         m_availableChannels = avaialbleChannels; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     struct VORRange | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         std::vector<int> m_vorIndices; | 
					
						
							|  |  |  |         int m_frequencyRange; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         VORRange() = default; | 
					
						
							|  |  |  |         VORRange(const VORRange&) = default; | 
					
						
							|  |  |  |         VORRange& operator=(const VORRange&) = default; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     struct RRDevice | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int m_deviceIndex; | 
					
						
							|  |  |  |         int m_frequency; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RRDevice() = default; | 
					
						
							|  |  |  |         RRDevice(const RRDevice&) = default; | 
					
						
							|  |  |  |         RRDevice& operator=(const RRDevice&) = default; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct RRChannel | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         ChannelAPI *m_channelAPI; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |         int m_channelIndex; | 
					
						
							|  |  |  |         int m_frequencyShift; | 
					
						
							|  |  |  |         int m_navId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         RRChannel() = default; | 
					
						
							|  |  |  |         RRChannel(const RRChannel&) = default; | 
					
						
							|  |  |  |         RRChannel& operator=(const RRChannel&) = default; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct RRTurnPlan | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RRDevice m_device; | 
					
						
							|  |  |  |         int m_bandwidth; | 
					
						
							|  |  |  |         std::vector<RRChannel> m_channels; | 
					
						
							| 
									
										
										
										
											2022-05-04 08:27:25 +01:00
										 |  |  |         bool m_fixedCenterFrequency;    // Devices such as FileInput that can't have center freq changed
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         RRTurnPlan() = default; | 
					
						
							|  |  |  |         RRTurnPlan(const RRTurnPlan&) = default; | 
					
						
							|  |  |  |         RRTurnPlan& operator=(const RRTurnPlan&) = default; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct ChannelAllocation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int m_navId; | 
					
						
							|  |  |  |         int m_deviceIndex; | 
					
						
							|  |  |  |         int m_channelIndex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ChannelAllocation() = default; | 
					
						
							|  |  |  |         ChannelAllocation(const ChannelAllocation&) = default; | 
					
						
							|  |  |  |         ChannelAllocation& operator=(const ChannelAllocation&) = default; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WebAPIAdapterInterface *m_webAPIAdapterInterface; | 
					
						
							|  |  |  | 	MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     MessageQueue *m_msgQueueToFeature; //!< Queue to report state to GUI
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     VORLocalizerSettings m_settings; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     QList<VORLocalizerSettings::VORChannel> m_vorChannels; | 
					
						
							|  |  |  |     QHash<int, ChannelAllocation> m_channelAllocations; | 
					
						
							|  |  |  |     QHash<ChannelAPI*, VORLocalizerSettings::AvailableChannel> *m_availableChannels; | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 	QTimer m_updateTimer; | 
					
						
							| 
									
										
										
										
											2022-09-15 21:59:42 +02:00
										 |  |  |     QRecursiveMutex m_mutex; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     QTimer m_rrTimer; | 
					
						
							|  |  |  |     std::vector<std::vector<RRTurnPlan>> m_rrPlans; //!< Round robin plans for each device
 | 
					
						
							|  |  |  |     std::vector<int> m_rrTurnCounters; //!< Round robin turn count for each device
 | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bool handleMessage(const Message& cmd); | 
					
						
							| 
									
										
										
										
											2022-11-30 22:00:26 +01:00
										 |  |  |     void applySettings(const VORLocalizerSettings& settings, const QList<QString>& settingsKeys, bool force = false); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     void removeVORChannel(int navId); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     void addVORChannel(const VORLocalizerSubChannelSettings& subChannelSettings); | 
					
						
							|  |  |  |     void updateChannels(); //!< (re)allocate channels to service VORs
 | 
					
						
							|  |  |  |     void setChannelShift(int deviceIndex, int channelIndex, double targetOffset, int vorNavId); | 
					
						
							|  |  |  |     void setAudioMute(int vorNavId, bool audioMute); | 
					
						
							| 
									
										
										
										
											2022-05-04 08:27:25 +01:00
										 |  |  |     static quint64 getDeviceCenterFrequency(int deviceIndex); | 
					
						
							|  |  |  |     static int getDeviceSampleRate(int deviceIndex); | 
					
						
							|  |  |  |     static bool hasCenterFrequencySetting(int deviceIndex); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     static void generateIndexCombinations(int length, int subLength, std::vector<std::vector<int>>& indexCombinations); | 
					
						
							|  |  |  |     static void getVORRanges(const QList<VORLocalizerSettings::VORChannel>& vors, int subLength, std::vector<VORRange>& vorRanges); | 
					
						
							|  |  |  |     static void filterVORRanges(std::vector<VORRange>& vorRanges, int thresholdBW); | 
					
						
							|  |  |  |     static void getChannelsByDevice(const QHash<ChannelAPI*, VORLocalizerSettings::AvailableChannel> *availableChannels, std::vector<RRTurnPlan>& m_deviceChannels); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | private slots: | 
					
						
							| 
									
										
										
										
											2021-11-25 09:28:59 +00:00
										 |  |  |     void started(); | 
					
						
							|  |  |  |     void finished(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  |     void handleInputMessages(); | 
					
						
							|  |  |  | 	void updateHardware(); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:32:43 +01:00
										 |  |  |     void rrNextTurn(); | 
					
						
							| 
									
										
										
										
											2020-11-30 01:30:18 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // INCLUDE_FEATURE_VORLOCALIZERWORKER_H_
 |