{
GpsDaemonApplication a(argc, argv, help);
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;
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;
ScreenClient * display=new ScreenClient(Address::me(), displayPort);
loop.addStream(display);
ScreenClient::write(0, 0, " ");
if(mode==Time || mode==Master) {
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();
}
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();
} 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;
}