// // RTCM Daemon // Neal Probert // //**************************************************************************** // includes //***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "UriParse.h" #include "RtcmDaemon.h" #include "netlib.h" //**************************************************************************** // defines //***************************************************************************/ //**************************************************************************** // macros //***************************************************************************/ //**************************************************************************** // structs & typedefs //***************************************************************************/ //**************************************************************************** // global constants //***************************************************************************/ //**************************************************************************** // global variables //***************************************************************************/ //**************************************************************************** // static constants //***************************************************************************/ //**************************************************************************** // static variables //***************************************************************************/ //**************************************************************************** // static functions //***************************************************************************/ //**************************************************************************** // C++ functions //***************************************************************************/ RtcmDaemon::RtcmDaemon() { log_open( RTCMD_NAME ); strcpy( Uri, "" ); SerialIn = DgpsIn = NtripIn = DgramIn = -1; nClients = 0; SetClientTimeout(false); // don't reset timeout on client activity } RtcmDaemon::~RtcmDaemon() { } int RtcmDaemon::ServerTimeout(void) { // should not timeout, try reconnecting if ( nClients > 0 ) RtcmReconnect(); else RtcmDisconnect(); return 0; } int RtcmDaemon::ServerSocket(void) { char buf[2048]; int n = 0, xmit = 0; if ( IsSet( DgpsIn ) ) { // from RTCM server n = Dgps.DgpsRead( buf, sizeof(buf) ); // xmit if ( n > 0 ) xmit = n; else if ( n == 0 ) { log_error( "Remote RTCM server closed!" ); RtcmDisconnect(); } else { log_error( "Remote RTCM server read error!" ); n = 0; } ResetServerTimeout(); } else if ( IsSet( NtripIn ) ) { // from NTRIP server n = Ntrip.NtripRead( (unsigned char *)buf, sizeof(buf) ); // xmit if ( n > 0 ) xmit = n; else if ( n == 0 ) { log_error( "Remote NTRIP server closed us!" ); RtcmDisconnect(); } else { log_error( "Remote NTRIP server read error!" ); n = 0; } ResetServerTimeout(); } else if ( IsSet( SerialIn ) ) { // from base station n = Rtcm.RtcmRead( buf, sizeof(buf) ); // xmit if ( n > 0 ) xmit = n; } // pass on RTCM data if ( xmit > 0 ) { ClientCast( buf, xmit ); } return n; } void RtcmDaemon::ClientCast( const char *buf, int n ) { // broadcast it Bcast.SendTo( buf, n ); // send to clients TcpServer::ClientCast( buf, n ); } int RtcmDaemon::ClientIn( int sock, const char *buf, int n ) { if ( n <= 0 ) return 0; // log messages from client, no responses if ( *buf == '$' ) { // update to OpenGTS // logging char name[128]; char out[1024]; // need to add ip address SockName( sock, name, sizeof(name) ); n = snprintf( out, sizeof(out), "[%s] %s", name, buf ); Log.LogWrite( out, n ); } else if ( n > 0 ) log_write( buf ); return 0; } int RtcmDaemon::ClientUp( int sock ) { // connect source on demand if ( nClients++ == 0 ) { // re-connect RtcmConnect( (const char *)Uri ); } return 1; } void RtcmDaemon::ClientDown( int sock ) { // disconnect source if ( --nClients <= 0 ) { RtcmDisconnect(); nClients = 0; } } int RtcmDaemon::RtcmOpen( const char *uri ) { // already connected? if ( SerialIn >= 0 ) Rtcm.RtcmClose(); UriParse parsed; parsed.setRate( 38400 ); parsed.setUri( uri ); // serial device SerialIn = Rtcm.RtcmOpen( parsed.getPath(), parsed.getRate() ); // add listener if ( SerialIn >= 0 ) { strcpy( Uri, uri ); AddFd( SerialIn ); } return SerialIn; } int RtcmDaemon::RtcmConnect( const char *uri ) { // already connected? if ( DgpsIn >= 0 ) return DgpsIn; else if ( NtripIn >= 0 ) return NtripIn; UriParse parsed; parsed.setService( RTCMD_PORT ); parsed.setRate( 57600 ); parsed.setUri( uri ); const char *proto = parsed.getProto(); if ( strcmp( proto, "dgps" ) == 0 || strcmp( proto, "dgpsip" ) == 0 ) { // RTCM server (dgpsip) DgpsIn = Dgps.DgpsConnect( parsed.getHost(), parsed.getService() ); // add listener if ( DgpsIn >= 0 ) { strcpy( Uri, uri ); AddFd( DgpsIn ); } return DgpsIn; } else if ( strcmp( proto, "ntrip" ) == 0 ) { // NTRIP caster NtripIn = Ntrip.NtripConnect( uri ); // add listener if ( NtripIn >= 0 ) { strcpy( Uri, uri ); AddFd( NtripIn ); } return NtripIn; } return -1; } void RtcmDaemon::RtcmDisconnect( void ) { if ( DgpsIn >= 0 || NtripIn >= 0 ) log_printf( "Remote RTCM/NTRIP dis-connected, no clients listening" ); else return; Dgps.DgpsClose(); DelFd( DgpsIn ); Ntrip.NtripClose(); DelFd( NtripIn ); DgpsIn = NtripIn = -1; } void RtcmDaemon::RtcmReconnect( void ) { if ( nClients == 0 ) return; log_printf( "Remote RTCM/NTRIP timed out, reconnecting" ); Dgps.DgpsClose(); DelFd( DgpsIn ); Ntrip.NtripClose(); DelFd( NtripIn ); DgpsIn = NtripIn = -1; RtcmConnect( Uri ); } int RtcmDaemon::RtcmBroadcast( const char *host, const char *port ) { return Bcast.Caster( host, port ); }