Functions
warangpsd/main.cpp File Reference
#include <GpCoreTools.h>
#include "GpsDaemonApplication.h"
#include "warangpsdVersion.h"
#include "warangpsdInstallPath.h"
#include "UbxDevice.h"
#include "PPSDevice.h"
#include "GpsServer.h"
#include "TimeRequest.h"
#include "TimeMasterServer.h"
#include "MasterServer.h"

Functions

ApplicationHelphelp ()
int main (int argc, char **argv)
 PACKAGE_INFO (warangpsd, WARANGPSD)

Function Documentation

int main ( int  argc,
char **  argv 
)

References GpCoreTools::EventLoop::addStream(), GpCoreTools::CoreApplication::applicationName(), GpCoreTools::DaemonApplication::basePath(), GpsDaemonApplication::close(), GpCoreTools::EventLoop::exec(), GpCoreTools::DaemonApplication::fork(), GpsDaemonApplication::gpsThread(), help(), GpCoreTools::TcpServerStream::listen(), mode, GpsDaemonApplication::ppsThread(), GpsDaemonApplication::setGPSThread(), UbxDevice::setMonitorDriftMode(), GpsDaemonApplication::setPPSThread(), GpCoreTools::Timer::start(), GpCoreTools::DaemonApplication::start(), and GpCoreTools::PThread::start().

{
  GpsDaemonApplication a(argc, argv, help);

  // Options
  std::string gpsDevicePath, ppsDevicePath;
  std::string stationName("unamed");
  std::string interface("wlan0");
  enum Mode {GPS, Master, Time};
  Mode mode=GPS;
#ifdef MONITOR_DRIFT_MODE
  bool monitorDrift=false;
#endif
  uint16_t port=2974;
  uint16_t timePort=2975;
  uint16_t displayPort=2977;
  // Check arguments
  int i, j=1;
  for(i=1; i<argc; i++) {
    const char * arg=argv[i];
    if(arg[0]=='-') {
      if(strcmp(arg, "-p")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        port=atoi(argv[i]);
      } else if(strcmp(arg, "-tp")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        timePort=atoi(argv[i]);
      } else if(strcmp(arg, "-dp")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        displayPort=atoi(argv[i]);
      } else if(strcmp(arg, "-d")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        gpsDevicePath=argv[i];
      } else if(strcmp(arg, "-ppsd")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        ppsDevicePath=argv[i];
      } else if(strcmp(arg, "-s")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        stationName=argv[i];
      } else if(strcmp(arg, "-i")==0) {
        CoreApplication::checkOptionArg(i, argc, argv, true);
        interface=argv[i];
      } else if(strcmp(arg, "-gps")==0) {
        mode=GPS;
      } else if(strcmp(arg, "-master")==0) {
        mode=Master;
      } else if(strcmp(arg, "-time")==0) {
        mode=Time;
#ifdef MONITOR_DRIFT_MODE
      } else if(strcmp(arg, "-drift")==0) {
        if(mode!=GPS) {
          fprintf(stderr, "%s: option '-drift' is valid only in GPS mode.\n", a.applicationName());
          CoreApplication::exit(2);
        }
        monitorDrift=true;
#endif
      } else {
        fprintf(stderr, "%s: bad option %s, see -help\n", a.applicationName(), argv[i]);
        CoreApplication::exit(2);
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j<argc) {
    argv[j]=0;
    argc=j;
  }
  if(argc>1) {
    fprintf(stderr, "%s: bad option %s, see -help\n", a.applicationName(), argv[1]);
    CoreApplication::exit(2);
  }

  a.fork();
  a.start();

  EventLoop loop;

  // Use external LCD to show status
  ScreenClient * display=new ScreenClient(Address::me(), displayPort);
  loop.addStream(display);
  ScreenClient::write(0, 0, "                    ");

  if(mode==Time || mode==Master) {
    // Sub net mask required for time request broadcast
    Address::setMaskSize(24);
    Address::identifyMe(interface.data());
    if(!Address::me().isValid()) {
       Log::write(1, "cannot get host address, check interface (option -i).\n");
       return 2;
    }

    TimeRequest request(timePort, 5000);
    request.start();
    loop.exec();
    // server automatically deleted by event loop
  }

  if(mode==Master) {
    MasterServer * server=new MasterServer;
    while(!server->listen(port, 50)) {
      Log::write(1, "cannot listen to port %hu, retry in 10 seconds\n", port);
      sleep(10);
    }
    loop.addStream(server);
    loop.exec();
    // server automatically deleted by event loop
  } else if(mode==GPS) {

    if(gpsDevicePath.size()==0) {
      ScreenClient::write(0, 0, "Missing option -d!  ");
      Log::write(0, "missing gps device path, see -help\n");
      CoreApplication::exit(2);
    }
    std::vector<std::string> * devicePaths=File::complete(gpsDevicePath);
    switch(devicePaths->size()) {
    case 0:
      ScreenClient::write(0, 0, "No GPS connected!   ");
      Log::write(0, "no gps device named %s\n", gpsDevicePath.data());
      delete devicePaths;
      CoreApplication::exit(2);
    case 1:
      gpsDevicePath=devicePaths->front();
      delete devicePaths;
      break;
    default:
      ScreenClient::write(0, 0, "Two GPS connected!  ");
      Log::write(0, "more than one gps device named %s\n", gpsDevicePath.data());
      delete devicePaths;
      CoreApplication::exit(2);
    }
    if(ppsDevicePath.size()>0) {
      std::vector<std::string> * devicePaths=File::complete(ppsDevicePath);
      switch(devicePaths->size()) {
      case 0:
        ScreenClient::write(0, 0, "Two PPS connected!  ");
        Log::write(0, "no pps device named %s\n", ppsDevicePath.data());
        delete devicePaths;
        CoreApplication::exit(2);
      case 1:
        ppsDevicePath=devicePaths->front();
        delete devicePaths;
        break;
      default:
        ScreenClient::write(0, 0, "Two PPS connected!  ");
        Log::write(0, "more than one pps device named %s\n", ppsDevicePath.data());
        delete devicePaths;
        CoreApplication::exit(2);
      }
    }

    GpsServer * server=new GpsServer;
    while(!server->listen(port, 50)) {
      Log::write(1, "cannot listen to port %hu, retry in 10 seconds\n", port);
      sleep(10);
    }
    loop.addStream(server);

    a.setGPSThread(new UbxDevice(stationName, a.basePath(), gpsDevicePath, server));
#ifdef MONITOR_DRIFT_MODE
    if(monitorDrift) {
      a.gpsThread()->setMonitorDriftMode(true);
    }
#endif
    if(ppsDevicePath.size()>0) {
      a.setPPSThread(new PPSDevice(ppsDevicePath, a.gpsThread()));
    }

    TimeMasterServer * timeServer=new TimeMasterServer(timePort, a.gpsThread());
    while(!timeServer->listen(timePort, 50)) {
      Log::write(1, "cannot listen to port %hu, retry in 10 seconds\n", timePort);
      sleep(10);
    }
    loop.addStream(timeServer);

    a.gpsThread()->start();
    if(a.ppsThread()) {
      a.ppsThread()->start();
    }
    loop.exec();
  }
  ScreenClient::write(0, 0, "                    ");
  a.close();
  return 0;
}
PACKAGE_INFO ( warangpsd  ,
WARANGPSD   
)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines