1 /*
2  *    Copyright (C) 2018
3  *    Matthias P. Braendli (matthias.braendli@mpb.li)
4  *
5  *    Copyright (C) 2017
6  *    Albrecht Lohofener (albrechtloh@gmx.de)
7  *
8  *    This file is part of the welle.io.
9  *    Many of the ideas as implemented in welle.io are derived from
10  *    other work, made available through the GNU general Public License.
11  *    All copyrights of the original authors are recognized.
12  *
13  *    welle.io is free software; you can redistribute it and/or modify
14  *    it under the terms of the GNU General Public License as published by
15  *    the Free Software Foundation; either version 2 of the License, or
16  *    (at your option) any later version.
17  *
18  *    welle.io is distributed in the hope that it will be useful,
19  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *    GNU General Public License for more details.
22  *
23  *    You should have received a copy of the GNU General Public License
24  *    along with welle.io; if not, write to the Free Software
25  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  *
27  */
28 
29 #include <iostream>
30 
31 // For Qt translation if Qt is exisiting
32 #ifdef QT_CORE_LIB
33     #include <QtGlobal>
34 #else
35     #define QT_TRANSLATE_NOOP(x,y) (y)
36 #endif
37 
38 #include "input_factory.h"
39 #include "null_device.h"
40 #include "rtl_tcp.h"
41 #include "raw_file.h"
42 
43 #ifdef HAVE_RTLSDR
44 #include "rtl_sdr.h"
45 #endif
46 
47 #ifdef HAVE_AIRSPY
48 #include "airspy_sdr.h"
49 #endif
50 
51 #ifdef HAVE_SOAPYSDR
52 #include "soapy_sdr.h"
53 #endif
54 
55 #ifdef HAVE_LIMESDR
56 #include "limesdr.h"
57 #endif
58 
59 #ifdef __ANDROID__
60 #include "android_rtl_sdr.h"
61 #endif
62 
GetDevice(RadioControllerInterface & radioController,const std::string & device)63 CVirtualInput *CInputFactory::GetDevice(RadioControllerInterface& radioController, const std::string& device)
64 {
65     CVirtualInput *InputDevice = nullptr;
66 
67     std::clog << "InputFactory:" << "Input device:" << device << std::endl;
68 
69     if (device == "auto")
70         InputDevice = GetAutoDevice(radioController);
71     else
72         InputDevice = GetManualDevice(radioController, device);
73 
74     // Fallback if no device is found or an error occured
75     if (InputDevice == nullptr) {
76         std::string text;
77 
78         if (device == "auto")
79             text = QT_TRANSLATE_NOOP("CRadioController", "No valid device found use Null device instead.");
80         else
81             text = QT_TRANSLATE_NOOP("CRadioController", "Error while opening device");
82 
83         radioController.onMessage(message_level_t::Error, text);
84         InputDevice = new CNullDevice();
85     }
86 
87     return InputDevice;
88 }
89 
GetDevice(RadioControllerInterface & radioController,const CDeviceID deviceId)90 CVirtualInput *CInputFactory::GetDevice(RadioControllerInterface &radioController, const CDeviceID deviceId)
91 {
92     CVirtualInput *InputDevice = nullptr;
93 
94     try {
95         switch(deviceId) {
96 #ifdef HAVE_AIRSPY
97         case CDeviceID::AIRSPY: InputDevice = new CAirspy(radioController); break;
98 #endif
99         case CDeviceID::RTL_TCP: InputDevice = new CRTL_TCP_Client(radioController); break;
100 #ifdef HAVE_RTLSDR
101         case CDeviceID::RTL_SDR: InputDevice = new CRTL_SDR(radioController); break;
102 #endif
103         case CDeviceID::RAWFILE: InputDevice = new CRAWFile(radioController); break;
104 #ifdef HAVE_SOAPYSDR
105         case CDeviceID::SOAPYSDR: InputDevice = new CSoapySdr(radioController); break;
106 #endif
107 #ifdef HAVE_LIMESDR
108         case CDeviceID::LIMESDR: InputDevice = new CLimeSDR(radioController); break;
109 #endif
110 #ifdef __ANDROID__
111         case CDeviceID::ANDROID_RTL_SDR: InputDevice = new CAndroid_RTL_SDR(radioController); break;
112 #endif
113         case CDeviceID::NULLDEVICE: InputDevice = new CNullDevice(); break;
114         default: throw std::runtime_error("unknown device ID " + std::string(__FILE__) +":"+ std::to_string(__LINE__));
115         }
116     }
117     catch (...) {
118         std::clog << "InputFactory:"
119             "Error while opening device \"" << static_cast<int>(deviceId) << "\"." << std::endl;
120     }
121 
122     // Fallback if no device is found or an error occured
123     if (InputDevice == nullptr) {
124         std::string text = QT_TRANSLATE_NOOP("CRadioController", "Error while opening device");
125         radioController.onMessage(message_level_t::Error, text);
126         InputDevice = new CNullDevice();
127     }
128 
129     return InputDevice;
130 }
131 
GetAutoDevice(RadioControllerInterface & radioController)132 CVirtualInput* CInputFactory::GetAutoDevice(RadioControllerInterface& radioController)
133 {
134     (void)radioController;
135     CVirtualInput *inputDevice = nullptr;
136 
137     // Try to find a input device
138     for (int i = 0; i <= 3; i++) {
139         try {
140             switch(i) {
141 #ifdef HAVE_AIRSPY
142             case 0: inputDevice = new CAirspy(radioController); break;
143 #endif
144 #ifdef HAVE_RTLSDR
145             case 1: inputDevice = new CRTL_SDR(radioController); break;
146 #endif
147 #ifdef HAVE_SOAPYSDR
148             case 2: inputDevice = new CSoapySdr(radioController); break;
149 #endif
150 #ifdef __ANDROID__
151             case 3: inputDevice = new CAndroid_RTL_SDR(radioController); break;
152 #endif
153             }
154         }
155         catch (...) {
156             // An error occured. Maybe the device isn't present.
157             // Just try the next input device
158         }
159 
160         // Break loop if we found a device
161         if (inputDevice != nullptr)
162             break;
163     }
164 
165     return inputDevice;
166 }
167 
GetManualDevice(RadioControllerInterface & radioController,const std::string & device)168 CVirtualInput* CInputFactory::GetManualDevice(RadioControllerInterface& radioController, const std::string& device)
169 {
170     CVirtualInput *InputDevice = nullptr;
171 
172     try {
173 #ifdef HAVE_AIRSPY
174         if (device == "airspy")
175             InputDevice = new CAirspy(radioController);
176         else
177 #endif
178         if (device == "rtl_tcp")
179             InputDevice = new CRTL_TCP_Client(radioController);
180         else
181 #ifdef HAVE_RTLSDR
182         if (device == "rtl_sdr")
183             InputDevice = new CRTL_SDR(radioController);
184         else
185 #endif
186 #ifdef HAVE_SOAPYSDR
187         if (device == "soapysdr")
188             InputDevice = new CSoapySdr(radioController);
189         else
190 #endif
191 #ifdef HAVE_LIMESDR
192         if (device == "limesdr")
193             InputDevice = new CLimeSDR(radioController);
194         else
195 #endif
196 #ifdef __ANDROID__
197         if (device == "android_rtl_sdr")
198             InputDevice = new CAndroid_RTL_SDR(radioController);
199         else
200 #endif
201         if (device == "rawfile")
202             InputDevice = new CRAWFile(radioController);
203         else
204             std::clog << "InputFactory:"
205                 "Unknown device \"" << device << "\"." << std::endl;
206     }
207     catch (...) {
208         std::clog << "InputFactory:"
209             "Error while opening device \"" << device << "\"." << std::endl;
210     }
211 
212     return InputDevice;
213 }
214