SoDaRadio-5.0.3-master:8901fb5
SoDaServer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (c) 2012,2013,2014,2015,2016,2017 Matthew H. Reilly (kb1vc)
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
108 // #include <uhd/usrp/multi_usrp.hpp>
109 #include <unistd.h>
110 #include <stdio.h>
111 #include <sys/time.h>
112 #include <sys/resource.h>
113 
114 #include <fstream>
115 
116 #include "SoDaBase.hxx"
117 #include "MultiMBox.hxx"
118 
119 #include "ProcInfo.hxx"
120 
121 // the radio parts.
122 #include "Params.hxx"
123 // For USRP devices
124 #if HAVE_UHD
125 # include "USRPCtrl.hxx"
126 # include "USRPRX.hxx"
127 # include "USRPTX.hxx"
128 #endif
129 
130 #include "BaseBandRX.hxx"
131 #include "BaseBandTX.hxx"
132 #include "CWTX.hxx"
133 #include "UI.hxx"
134 #include "GPSmon.hxx"
135 #include "AudioPA.hxx"
136 #include "AudioALSA.hxx"
137 #include "Command.hxx"
138 #include "Debug.hxx"
139 
140 void createLockFile(const std::string & lock_file_name)
141 {
142  std::ofstream lfile;
143  lfile.open(lock_file_name.c_str());
144  lfile << "If this file exists, there is likely an active SoDaServer process somewhere on this machine.\n";
145  lfile.close();
146 }
147 
148 void deleteLockFile(const std::string & lock_file_name)
149 {
150  remove(lock_file_name.c_str());
151 }
152 
156 int doWork(SoDa::Params & params)
157 {
159  SoDa::Debug d(params.getDebugLevel(), "SoDaServer");
160  d.setDefaultLevel(params.getDebugLevel());
161 
162  // These are the mailboxes that connect
163  // the various widgets
164  // the rx and tx streams are vectors of complex floats.
165  // we don't declare the extent here, as it will be set
166  // by a negotiation.
167  SoDa::DatMBox rx_stream, tx_stream, if_stream, cw_env_stream;
168  SoDa::CmdMBox cmd_stream(false);
169  // create a separate gps stream to avoid "leaks" and latency problems...
170  SoDa::CmdMBox gps_stream(false);
171  SoDa::CmdMBox cwtxt_stream(false);
172 
173  SoDa::SoDaThread * ctrl;
174  SoDa::SoDaThread * rx;
175  SoDa::SoDaThread * tx;
176 
177  if(params.isRadioType("USRP")) {
178 #if HAVE_UHD
179  ctrl = new SoDa::USRPCtrl(&params, &cmd_stream);
182  rx = new SoDa::USRPRX(&params, ((SoDa::USRPCtrl *)ctrl)->getUSRP(), &rx_stream, &if_stream, &cmd_stream);
183  tx = new SoDa::USRPTX(&params, ((SoDa::USRPCtrl *)ctrl)->getUSRP(), &tx_stream, &cw_env_stream, &cmd_stream);
184 #else
185  std::cerr << "lib UHD support not included in this build.\n^C to exit.\n";
186  exit(-1);
187 #endif
188  }
189  else {
190  std::cerr << boost::format("Radio type [%s] is not yet supported\nHit ^C to exit.\n") % params.getRadioType();
191  exit(-1);
192  }
193 
194 
198  SoDa::AudioALSA audio_ifc(params.getAudioSampleRate(),
200  params.getAFBufferSize(),
201  params.getAudioPortName());
205  SoDa::BaseBandRX bbrx(&params, &rx_stream, &cmd_stream, &audio_ifc);
206  SoDa::BaseBandTX bbtx(&params, &tx_stream, &cmd_stream, &audio_ifc);
207 
209  SoDa::CWTX cwtx(&params, &cwtxt_stream, &cw_env_stream, &cmd_stream);
210 
212  SoDa::UI ui(&params, &cwtxt_stream, &rx_stream, &if_stream, &cmd_stream, &gps_stream);
213 
214 #if HAVE_GPSLIB
215  SoDa::GPSmon gps(&params, &gps_stream);
216 #endif
217 
218  d.debugMsg("Created units.");
219 
220  // Now start each of the activities -- they may or may not
221  // implement the "start" method -- not all objects need to be threads.
222 
223  d.debugMsg("Starting UI");
224  // start the UI -- configure stuff and all that.
225  ui.start();
226  d.debugMsg("Starting radio units");
227  // start command consumers first.
228  ctrl->start();
229  rx->start();
230  tx->start();
231  bbrx.start();
232  bbtx.start();
233  cwtx.start();
234 
235  // now the gps...
236 #if HAVE_GPSLIB
237  d.debugMsg("Starting gps");
238  gps.start();
239 #endif
240 
241  if(params.reportMemInfo()) {
242  kb1vc::ProcInfo pi(params.getReportFileName(), "SoDaServer");
243 
244  // wait for the user interface to tell us that it is time to quit.
245  // do this in a loop so that we can check on VM status.
246  int watchdog_count = 0;
247  pi.reportInfo();
248  while(!ui.waitForJoin(1000)) {
249  watchdog_count++;
250  // do this check every 10 seconds
251  if(watchdog_count > 10) {
252  pi.reportInfo(true);
253  watchdog_count = 0;
254  }
255  }
256  }
257  else {
258  ui.join();
259  }
260 
261  ctrl->join();
262  rx->join();
263  tx->join();
264  bbrx.join();
265  bbtx.join();
266  cwtx.join();
267 #if HAVE_GPSLIB
268  gps.join();
269 #endif
270  d.debugMsg("Exit");
271 
272  // when we get here, we are done... (UI should not return until it gets an "exit/quit" command.)
273 
274  return 0;
275 }
276 
282 int main(int argc, char * argv[])
283 {
289  SoDa::Params params(argc, argv);
290 
292  createLockFile(params.getLockFileName());
293 
294  try {
295  doWork(params);
296  }
297  catch (SoDa::SoDaException * exc) {
298  std::cerr << "Exception caught at SoDa main: " << std::endl;
299  std::cerr << "\t" << exc->toString() << std::endl;
300  }
301 
302  deleteLockFile(params.getLockFileName());
303 }
bool isRadioType(const std::string &rtype)
Definition: Params.hxx:128
The Baseclass for all SoDa objects, and useful commonly used classes.
The Thread baseclass for all SoDa thread objects.
Definition: SoDaBase.hxx:284
std::string getLockFileName() const
Definition: Params.hxx:123
Definition: UI.hxx:40
Though libuhd is designed to be re-entrant, there are some indications that all control functions (se...
Definition: USRPCtrl.hxx:68
double getAudioSampleRate() const
Definition: Params.hxx:104
bool reportMemInfo() const
Definition: Params.hxx:125
This class handles command line parameters and built-ins.
Definition: Params.hxx:42
The SoDa Exception class.
Definition: SoDaBase.hxx:217
void start()
Execute the threads run loop.
Definition: SoDaBase.hxx:292
std::string toString()
Create a string that explains this exception.
Definition: SoDaBase.hxx:246
void join()
more properly "Wait for this thread to exit its run loop".
Definition: SoDaBase.hxx:301
The CW text-to-envelope converter run loop.
Definition: CWTX.hxx:48
The Receive RF Path.
Definition: USRPRX.hxx:46
unsigned int getDebugLevel() const
Definition: Params.hxx:115
int main(int argc, char *argv[])
main entrypoint
Definition: SoDaServer.cxx:282
unsigned int getAFBufferSize() const
Definition: Params.hxx:106
std::string getAudioPortName() const
Definition: Params.hxx:110
bool waitForJoin(unsigned int m)
wait for the thread to stop running, or the specified time to pass.
Definition: SoDaBase.hxx:313
A simple base class to provide debug messaging from any derived class.
Definition: Debug.hxx:42
ALSA audio interface class.
Definition: AudioALSA.hxx:63
static void setDefaultLevel(unsigned int v)
Definition: Debug.hxx:82
int doWork(SoDa::Params &params)
do the work of creating the SoDa threads
Definition: SoDaServer.cxx:156
void createLockFile(const std::string &lock_file_name)
Definition: SoDaServer.cxx:140
std::string getRadioType() const
Definition: Params.hxx:117
BaseBandRX – this is the audio processing chain for the recieve path.
Definition: BaseBandRX.hxx:75
The Transmit RF Path.
Definition: USRPTX.hxx:51
Thread class that owns the USRP control channel and functions.
std::string getReportFileName() const
Definition: Params.hxx:126
A simple base class to provide debug messaging from any derived class.
Definition: ProcInfo.hxx:41
void reportInfo(bool only_if_changed=false)
Definition: ProcInfo.hxx:60
void deleteLockFile(const std::string &lock_file_name)
Definition: SoDaServer.cxx:148