| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2016 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                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 22:56:32 +01:00
										 |  |  | #include <QCoreApplication>
 | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | #include <QPluginLoader>
 | 
					
						
							| 
									
										
										
										
											2017-11-01 22:56:32 +01:00
										 |  |  | //#include <QComboBox>
 | 
					
						
							| 
									
										
										
										
											2017-10-24 14:15:08 +02:00
										 |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | #include <cstdio>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 14:15:08 +02:00
										 |  |  | #include <plugin/plugininstancegui.h>
 | 
					
						
							|  |  |  | #include "device/devicesourceapi.h"
 | 
					
						
							|  |  |  | #include "device/devicesinkapi.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-02 03:30:54 +01:00
										 |  |  | #include "device/deviceenumerator.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | #include "settings/preset.h"
 | 
					
						
							|  |  |  | #include "util/message.h"
 | 
					
						
							|  |  |  | #include "dsp/dspdevicesourceengine.h"
 | 
					
						
							|  |  |  | #include "dsp/dspdevicesinkengine.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 14:15:08 +02:00
										 |  |  | #include "plugin/pluginmanager.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 13:03:12 +01:00
										 |  |  | const QString PluginManager::m_sdrDaemonSourceHardwareID = "SDRdaemonSource"; | 
					
						
							|  |  |  | const QString PluginManager::m_sdrDaemonSourceDeviceTypeID = "sdrangel.samplesource.sdrdaemonsource"; | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | const QString PluginManager::m_fileSourceHardwareID = "FileSource"; | 
					
						
							|  |  |  | const QString PluginManager::m_fileSourceDeviceTypeID = "sdrangel.samplesource.filesource"; | 
					
						
							| 
									
										
										
										
											2017-11-01 13:03:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | const QString PluginManager::m_sdrDaemonSinkHardwareID = "SDRdaemonSink"; | 
					
						
							|  |  |  | const QString PluginManager::m_sdrDaemonSinkDeviceTypeID = "sdrangel.samplesink.sdrdaemonsink"; | 
					
						
							|  |  |  | const QString PluginManager::m_fileSinkHardwareID = "FileSink"; | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | const QString PluginManager::m_fileSinkDeviceTypeID = "sdrangel.samplesink.filesink"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-24 14:15:08 +02:00
										 |  |  | PluginManager::PluginManager(QObject* parent) : | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 	QObject(parent), | 
					
						
							| 
									
										
										
										
											2017-10-24 14:01:31 +02:00
										 |  |  |     m_pluginAPI(this) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PluginManager::~PluginManager() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | //	freeAll();
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 10:36:22 +01:00
										 |  |  | void PluginManager::loadPlugins(const QString& pluginsSubDir) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-01 22:56:32 +01:00
										 |  |  | 	QString applicationDirPath = QCoreApplication::instance()->applicationDirPath(); | 
					
						
							| 
									
										
										
										
											2017-12-17 10:36:22 +01:00
										 |  |  | 	QString applicationLibPath = applicationDirPath + "/../lib/" + pluginsSubDir; | 
					
						
							|  |  |  | 	QString applicationBuildPath = applicationDirPath + "/" + pluginsSubDir; | 
					
						
							| 
									
										
										
										
											2017-12-16 13:39:13 +01:00
										 |  |  |     qDebug() << "PluginManager::loadPlugins: " << qPrintable(applicationLibPath) << "," << qPrintable(applicationBuildPath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QDir pluginsLibDir = QDir(applicationLibPath); | 
					
						
							|  |  |  |     QDir pluginsBuildDir = QDir(applicationBuildPath); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 10:36:22 +01:00
										 |  |  |     loadPluginsDir(pluginsLibDir); | 
					
						
							|  |  |  |     loadPluginsDir(pluginsBuildDir); | 
					
						
							| 
									
										
										
										
											2017-12-16 13:39:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 	qSort(m_plugins); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		it->pluginInterface->initPlugin(&m_pluginAPI); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 03:30:54 +01:00
										 |  |  | 	DeviceEnumerator::instance()->enumerateRxDevices(this); | 
					
						
							|  |  |  | 	DeviceEnumerator::instance()->enumerateTxDevices(this); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  | void PluginManager::registerRxChannel(const QString& channelIdURI, const QString& channelId, PluginInterface* plugin) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     qDebug() << "PluginManager::registerRxChannel " | 
					
						
							|  |  |  |             << plugin->getPluginDescriptor().displayedName.toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  |             << " with channel name " << channelIdURI; | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  | 	m_rxChannelRegistrations.append(PluginAPI::ChannelRegistration(channelIdURI, channelId, plugin)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  | void PluginManager::registerTxChannel(const QString& channelIdURI, const QString& channelId, PluginInterface* plugin) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     qDebug() << "PluginManager::registerTxChannel " | 
					
						
							|  |  |  |             << plugin->getPluginDescriptor().displayedName.toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  |             << " with channel name " << channelIdURI; | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  | 	m_txChannelRegistrations.append(PluginAPI::ChannelRegistration(channelIdURI, channelId, plugin)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PluginManager::registerSampleSource(const QString& sourceName, PluginInterface* plugin) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "PluginManager::registerSampleSource " | 
					
						
							|  |  |  | 			<< plugin->getPluginDescriptor().displayedName.toStdString().c_str() | 
					
						
							|  |  |  | 			<< " with source name " << sourceName.toStdString().c_str(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 03:30:54 +01:00
										 |  |  | 	m_sampleSourceRegistrations.append(PluginAPI::SamplingDeviceRegistration(sourceName, plugin)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PluginManager::registerSampleSink(const QString& sinkName, PluginInterface* plugin) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "PluginManager::registerSampleSink " | 
					
						
							|  |  |  | 			<< plugin->getPluginDescriptor().displayedName.toStdString().c_str() | 
					
						
							|  |  |  | 			<< " with sink name " << sinkName.toStdString().c_str(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 03:30:54 +01:00
										 |  |  | 	m_sampleSinkRegistrations.append(PluginAPI::SamplingDeviceRegistration(sinkName, plugin)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 10:36:22 +01:00
										 |  |  | void PluginManager::loadPluginsDir(const QDir& dir) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	QDir pluginsDir(dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	foreach (QString fileName, pluginsDir.entryList(QDir::Files)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  |         if (fileName.endsWith(".so") || fileName.endsWith(".dll") || fileName.endsWith(".dylib")) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-02-08 18:37:34 +01:00
										 |  |  | 			qDebug() << "PluginManager::loadPluginsDir: fileName: " << qPrintable(fileName); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			QPluginLoader* loader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName)); | 
					
						
							|  |  |  | 			PluginInterface* plugin = qobject_cast<PluginInterface*>(loader->instance()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (loader->isLoaded()) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-02-08 18:37:34 +01:00
										 |  |  | 				qInfo("PluginManager::loadPluginsDir: loaded plugin %s", qPrintable(fileName)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-02-08 18:37:34 +01:00
										 |  |  | 				qWarning() << "PluginManager::loadPluginsDir: " << qPrintable(loader->errorString()); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (plugin != 0) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				m_plugins.append(Plugin(fileName, loader, plugin)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				loader->unload(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			delete loader; // Valgrind memcheck
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// recursive calls on subdirectories
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	foreach (QString dirName, pluginsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-12-17 10:36:22 +01:00
										 |  |  | 		loadPluginsDir(pluginsDir.absoluteFilePath(dirName)); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 08:32:44 +01:00
										 |  |  | void PluginManager::listTxChannels(QList<QString>& list) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-01 08:32:44 +01:00
										 |  |  |     list.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(PluginAPI::ChannelRegistrations::iterator it = m_txChannelRegistrations.begin(); it != m_txChannelRegistrations.end(); ++it) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         const PluginDescriptor& pluginDescipror = it->m_plugin->getPluginDescriptor(); | 
					
						
							| 
									
										
										
										
											2017-11-01 08:32:44 +01:00
										 |  |  |         list.append(pluginDescipror.displayedName); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 08:32:44 +01:00
										 |  |  | void PluginManager::listRxChannels(QList<QString>& list) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-01 08:32:44 +01:00
										 |  |  |     list.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(PluginAPI::ChannelRegistrations::iterator it = m_rxChannelRegistrations.begin(); it != m_rxChannelRegistrations.end(); ++it) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-23 01:19:32 +01:00
										 |  |  |         const PluginDescriptor& pluginDesciptor = it->m_plugin->getPluginDescriptor(); | 
					
						
							|  |  |  |         list.append(pluginDesciptor.displayedName); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-09 01:03:05 +01:00
										 |  |  | void PluginManager::createRxChannelInstance(int channelPluginIndex, DeviceUISet *deviceUISet, DeviceSourceAPI *deviceAPI) | 
					
						
							| 
									
										
										
										
											2017-10-31 00:07:55 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     if (channelPluginIndex < m_rxChannelRegistrations.size()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         PluginInterface *pluginInterface = m_rxChannelRegistrations[channelPluginIndex].m_plugin; | 
					
						
							| 
									
										
										
										
											2017-12-23 09:54:42 +01:00
										 |  |  |         BasebandSampleSink *rxChannel = pluginInterface->createRxChannelBS(deviceAPI); | 
					
						
							| 
									
										
										
										
											2017-12-23 10:32:02 +01:00
										 |  |  |         pluginInterface->createRxChannelGUI(deviceUISet, rxChannel); | 
					
						
							| 
									
										
										
										
											2017-10-31 00:07:55 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 22:54:58 +01:00
										 |  |  | void PluginManager::createTxChannelInstance(int channelPluginIndex, DeviceUISet *deviceUISet, DeviceSinkAPI *deviceAPI) | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (channelPluginIndex < m_txChannelRegistrations.size()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         PluginInterface *pluginInterface = m_txChannelRegistrations[channelPluginIndex].m_plugin; | 
					
						
							| 
									
										
										
										
											2017-12-23 10:16:27 +01:00
										 |  |  |         BasebandSampleSource *txChannel = pluginInterface->createTxChannelBS(deviceAPI); | 
					
						
							| 
									
										
										
										
											2017-12-23 10:38:45 +01:00
										 |  |  |         pluginInterface->createTxChannelGUI(deviceUISet, txChannel); | 
					
						
							| 
									
										
										
										
											2017-04-23 10:33:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } |