| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2021 Jon Beniston, M7RCE                                        //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 <vector>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QRegExp>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							|  |  |  | #include "device/deviceset.h"
 | 
					
						
							|  |  |  | #include "channel/channelapi.h"
 | 
					
						
							|  |  |  | #include "feature/featureset.h"
 | 
					
						
							|  |  |  | #include "feature/feature.h"
 | 
					
						
							|  |  |  | #include "maincore.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "pipeendpoint.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(PipeEndPoint::MsgReportPipes, Message) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  | QList<PipeEndPoint::AvailablePipeSource> PipeEndPoint::updateAvailablePipeSources(QString pipeName, QStringList pipeTypes, QStringList pipeURIs, PipeEndPoint *destination) | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MainCore *mainCore = MainCore::instance(); | 
					
						
							|  |  |  |     MessagePipes& messagePipes = mainCore->getMessagePipes(); | 
					
						
							|  |  |  |     std::vector<DeviceSet*>& deviceSets = mainCore->getDeviceSets(); | 
					
						
							|  |  |  |     QHash<PipeEndPoint *, AvailablePipeSource> availablePipes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |     // Source is a channel
 | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |     int deviceIndex = 0; | 
					
						
							|  |  |  |     for (std::vector<DeviceSet*>::const_iterator it = deviceSets.begin(); it != deviceSets.end(); ++it, deviceIndex++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPDeviceSourceEngine *deviceSourceEngine =  (*it)->m_deviceSourceEngine; | 
					
						
							|  |  |  |         DSPDeviceSinkEngine *deviceSinkEngine =  (*it)->m_deviceSinkEngine; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (deviceSourceEngine || deviceSinkEngine) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (int chi = 0; chi < (*it)->getNumberOfChannels(); chi++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 ChannelAPI *channel = (*it)->getChannelAt(chi); | 
					
						
							|  |  |  |                 int i = pipeURIs.indexOf(channel->getURI()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (i >= 0) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     if (!availablePipes.contains(channel)) | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |                         MessageQueue *messageQueue = messagePipes.registerChannelToFeature(channel, destination, pipeName); | 
					
						
							|  |  |  |                         if (MainCore::instance()->existsFeature((const Feature *)destination)) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // Destination is feature
 | 
					
						
							|  |  |  |                             Feature *featureDest = (Feature *)destination; | 
					
						
							|  |  |  |                             QObject::connect( | 
					
						
							|  |  |  |                                 messageQueue, | 
					
						
							|  |  |  |                                 &MessageQueue::messageEnqueued, | 
					
						
							|  |  |  |                                 featureDest, | 
					
						
							|  |  |  |                                 [=](){ featureDest->handlePipeMessageQueue(messageQueue); }, | 
					
						
							|  |  |  |                                 Qt::QueuedConnection | 
					
						
							|  |  |  |                             ); | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // Destination is a channel
 | 
					
						
							|  |  |  |                             // Can't use Qt::QueuedConnection because ChannelAPI isn't a QObject
 | 
					
						
							|  |  |  |                             ChannelAPI *channelDest = (ChannelAPI *)destination; | 
					
						
							|  |  |  |                             QObject::connect( | 
					
						
							|  |  |  |                                 messageQueue, | 
					
						
							|  |  |  |                                 &MessageQueue::messageEnqueued, | 
					
						
							|  |  |  |                                 [=](){ channelDest->handlePipeMessageQueue(messageQueue); } | 
					
						
							|  |  |  |                             ); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     AvailablePipeSource availablePipe = | 
					
						
							|  |  |  |                         AvailablePipeSource{ | 
					
						
							|  |  |  |                             deviceSinkEngine != nullptr ? AvailablePipeSource::TX : AvailablePipeSource::RX, | 
					
						
							|  |  |  |                             deviceIndex, | 
					
						
							|  |  |  |                             chi, | 
					
						
							|  |  |  |                             channel, | 
					
						
							|  |  |  |                             pipeTypes.at(i) | 
					
						
							|  |  |  |                         }; | 
					
						
							|  |  |  |                     availablePipes[channel] = availablePipe; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |     // Source is a feature
 | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |     std::vector<FeatureSet*>& featureSets = mainCore->getFeatureeSets(); | 
					
						
							|  |  |  |     int featureIndex = 0; | 
					
						
							|  |  |  |     for (std::vector<FeatureSet*>::const_iterator it = featureSets.begin(); it != featureSets.end(); ++it, featureIndex++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         for (int fi = 0; fi < (*it)->getNumberOfFeatures(); fi++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             Feature *feature = (*it)->getFeatureAt(fi); | 
					
						
							|  |  |  |             int i = pipeURIs.indexOf(feature->getURI()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (i >= 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (!availablePipes.contains(feature)) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |                     MessageQueue *messageQueue = messagePipes.registerChannelToFeature(feature, destination, pipeName); | 
					
						
							|  |  |  |                     if (MainCore::instance()->existsFeature((const Feature *)destination)) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         // Destination is feature
 | 
					
						
							|  |  |  |                         Feature *featureDest = (Feature *)destination; | 
					
						
							|  |  |  |                         QObject::connect( | 
					
						
							|  |  |  |                             messageQueue, | 
					
						
							|  |  |  |                             &MessageQueue::messageEnqueued, | 
					
						
							|  |  |  |                             featureDest, | 
					
						
							|  |  |  |                             [=](){ featureDest->handlePipeMessageQueue(messageQueue); }, | 
					
						
							|  |  |  |                             Qt::QueuedConnection | 
					
						
							|  |  |  |                         ); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         // Destination is a channel
 | 
					
						
							|  |  |  |                         // Can't use Qt::QueuedConnection because ChannelAPI isn't a QObject
 | 
					
						
							|  |  |  |                         ChannelAPI *channelDest = (ChannelAPI *)destination; | 
					
						
							|  |  |  |                         QObject::connect( | 
					
						
							|  |  |  |                             messageQueue, | 
					
						
							|  |  |  |                             &MessageQueue::messageEnqueued, | 
					
						
							|  |  |  |                             [=](){ channelDest->handlePipeMessageQueue(messageQueue); } | 
					
						
							|  |  |  |                         ); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 AvailablePipeSource availablePipe = | 
					
						
							|  |  |  |                     AvailablePipeSource{ | 
					
						
							|  |  |  |                         AvailablePipeSource::Feature, | 
					
						
							|  |  |  |                         featureIndex, | 
					
						
							|  |  |  |                         fi, | 
					
						
							|  |  |  |                         feature, | 
					
						
							|  |  |  |                         pipeTypes.at(i) | 
					
						
							|  |  |  |                     }; | 
					
						
							|  |  |  |                 availablePipes[feature] = availablePipe; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QList<AvailablePipeSource> availablePipeList; | 
					
						
							|  |  |  |     QHash<PipeEndPoint*, AvailablePipeSource>::iterator it = availablePipes.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; it != availablePipes.end(); ++it) { | 
					
						
							|  |  |  |         availablePipeList.push_back(*it); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return availablePipeList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PipeEndPoint *PipeEndPoint::getPipeEndPoint(const QString name, const QList<AvailablePipeSource> &availablePipeSources) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QRegExp re("([TRF])([0-9]+):([0-9]+) ([a-zA-Z0-9]+)"); | 
					
						
							|  |  |  |     if (re.exactMatch(name)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString type = re.capturedTexts()[1]; | 
					
						
							|  |  |  |         int setIndex = re.capturedTexts()[2].toInt(); | 
					
						
							|  |  |  |         int index = re.capturedTexts()[3].toInt(); | 
					
						
							|  |  |  |         QString id = re.capturedTexts()[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QListIterator<AvailablePipeSource> itr(availablePipeSources); | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |         while (itr.hasNext()) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |             AvailablePipeSource p = itr.next(); | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |             if ((p.m_setIndex == setIndex) && (p.m_index == index) && (id == p.m_id)) { | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |                 return p.m_source; | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |         qDebug() << "PipeEndPoint::getPipeEndPoint: " << name << " is malformed"; | 
					
						
							| 
									
										
										
										
											2021-10-12 11:18:29 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-13 17:07:38 +00:00
										 |  |  |     return nullptr; | 
					
						
							|  |  |  | } |