@ -25,6 +25,8 @@
# include <vector>
# include <vector>
# include <signal.h>
# include <signal.h>
# include <exception>
# include <exception>
# include <cassert>
# include <unistd.h>
# ifdef DEBUG_DSTARGW
# ifdef DEBUG_DSTARGW
# include <boost/stacktrace.hpp>
# include <boost/stacktrace.hpp>
# endif
# endif
@ -45,6 +47,7 @@
# include "LogConsoleTarget.h"
# include "LogConsoleTarget.h"
# include "APRSGPSDIdFrameProvider.h"
# include "APRSGPSDIdFrameProvider.h"
# include "APRSFixedIdFrameProvider.h"
# include "APRSFixedIdFrameProvider.h"
# include "Daemon.h"
CDStarGatewayApp * CDStarGatewayApp : : g_app = nullptr ;
CDStarGatewayApp * CDStarGatewayApp : : g_app = nullptr ;
@ -70,16 +73,52 @@ int main(int argc, char *argv[])
return 1 ;
return 1 ;
}
}
if ( ' - ' = = argv [ 1 ] [ 0 ] ) {
printf ( " \n %s Copyright (C) %s \n " , FULL_PRODUCT_NAME . c_str ( ) , VENDOR_NAME . c_str ( ) ) ;
printf ( " \n %s Copyright (C) %s \n " , FULL_PRODUCT_NAME . c_str ( ) , VENDOR_NAME . c_str ( ) ) ;
printf ( " DStarGateway comes with ABSOLUTELY NO WARRANTY; see the LICENSE for details. \n " ) ;
printf ( " DStarGateway comes with ABSOLUTELY NO WARRANTY; see the LICENSE for details. \n " ) ;
printf ( " This is free software, and you are welcome to distribute it \n under certain conditions that are discussed in the LICENSE file. \n \n " ) ;
printf ( " This is free software, and you are welcome to distribute it \n under certain conditions that are discussed in the LICENSE file. \n \n " ) ;
if ( ' - ' = = argv [ 1 ] [ 0 ] ) {
return 0 ;
return 0 ;
}
}
std : : string cfgFile ( argv [ 1 ] ) ;
CDStarGatewayConfig * config = new CDStarGatewayConfig ( std : : string ( ( argv [ 1 ] ) ) ) ;
if ( ! config - > load ( ) ) {
CLog : : logFatal ( " Invalid configuration, aborting " ) ;
return false ;
}
TDaemon daemon ;
config - > getGeneral ( daemon ) ;
if ( daemon . daemon ) {
CLog : : logInfo ( " Configured as a daemon, detaching ... " ) ;
auto res = CDaemon : : daemonize ( daemon . pidFile ) ;
switch ( res )
{
case DR_PARENT :
return 0 ;
case DR_CHILD :
break ;
case DR_PIDFILE_FAILED :
break ;
case DR_FAILURE :
[[fallthrough]] ;
default :
CLog : : logFatal ( " Fork failed, exiting " ) ;
delete config ;
return 1 ;
}
}
// Setup Log
TLog logConf ;
config - > getLog ( logConf ) ;
CLog : : finalise ( ) ;
if ( logConf . m_displayLevel ! = LOG_NONE & & ! daemon . daemon ) CLog : : addTarget ( new CLogConsoleTarget ( logConf . m_displayLevel ) ) ;
if ( logConf . m_fileLevel ! = LOG_NONE ) CLog : : addTarget ( new CLogFileTarget ( logConf . m_fileLevel , logConf . logDir , logConf . m_fileRotate ) ) ;
CDStarGatewayApp gateway ( cfgFile ) ;
CDStarGatewayApp gateway ( c on fi g) ;
if ( ! gateway . init ( ) ) {
if ( ! gateway . init ( ) ) {
return 1 ;
return 1 ;
@ -87,22 +126,30 @@ int main(int argc, char *argv[])
gateway . run ( ) ;
gateway . run ( ) ;
if ( daemon . daemon ) {
CDaemon : : finalize ( ) ;
}
return 0 ;
return 0 ;
}
}
CDStarGatewayApp : : CDStarGatewayApp ( const std : : string & configFile ) : m_configFile ( configFile ) , m_thread ( NULL )
CDStarGatewayApp : : CDStarGatewayApp ( CDStarGatewayConfig * config ) :
m_config ( config ) ,
m_thread ( NULL )
{
{
assert ( config ! = nullptr ) ;
g_app = this ;
g_app = this ;
}
}
CDStarGatewayApp : : ~ CDStarGatewayApp ( )
CDStarGatewayApp : : ~ CDStarGatewayApp ( )
{
{
delete m_config ;
delete m_thread ;
}
}
bool CDStarGatewayApp : : init ( )
bool CDStarGatewayApp : : init ( )
{
{
return createThread ( ) ;
return createThread ( ) ;
//2021-12-31 F4FXL This is ugly, if we failed to create the thread we do not clean up ... :(
}
}
void CDStarGatewayApp : : run ( )
void CDStarGatewayApp : : run ( )
@ -115,30 +162,18 @@ void CDStarGatewayApp::run()
bool CDStarGatewayApp : : createThread ( )
bool CDStarGatewayApp : : createThread ( )
{
{
printf ( " \n %s Copyright (C) %s \n " , FULL_PRODUCT_NAME . c_str ( ) , VENDOR_NAME . c_str ( ) ) ;
// Log
printf ( " DStarGateway comes with ABSOLUTELY NO WARRANTY; see the LICENSE for details. \n " ) ;
printf ( " This is free software, and you are welcome to distribute it \n under certain conditions that are discussed in the LICENSE file. \n \n " ) ;
CDStarGatewayConfig config ( m_configFile ) ;
if ( ! config . load ( ) ) {
CLog : : logFatal ( " Invalid configuration, aborting " ) ;
return false ;
}
// Setup Log
TLog log ;
TLog log ;
config . getLog ( log ) ;
m_config - > getLog ( log ) ;
CLog : : finalise ( ) ;
if ( log . m_displayLevel ! = LOG_NONE ) CLog : : addTarget ( new CLogConsoleTarget ( log . m_displayLevel ) ) ;
if ( log . m_fileLevel ! = LOG_NONE ) CLog : : addTarget ( new CLogFileTarget ( log . m_fileLevel , log . logDir , log . m_fileRotate ) ) ;
// Paths
Tpaths paths ;
Tpaths paths ;
config. getPaths ( paths ) ;
m_config - > getPaths ( paths ) ;
m_thread = new CDStarGatewayThread ( log . logDir , paths . dataDir , " " ) ;
m_thread = new CDStarGatewayThread ( log . logDir , paths . dataDir , " " ) ;
// Setup the gateway
// Setup the gateway
TGateway gatewayConfig ;
TGateway gatewayConfig ;
config. getGateway ( gatewayConfig ) ;
m_config- > getGateway ( gatewayConfig ) ;
m_thread - > setGateway ( gatewayConfig . type , gatewayConfig . callsign , gatewayConfig . address ) ;
m_thread - > setGateway ( gatewayConfig . type , gatewayConfig . callsign , gatewayConfig . address ) ;
m_thread - > setLanguage ( gatewayConfig . language ) ;
m_thread - > setLanguage ( gatewayConfig . language ) ;
m_thread - > setLocation ( gatewayConfig . latitude , gatewayConfig . longitude ) ;
m_thread - > setLocation ( gatewayConfig . latitude , gatewayConfig . longitude ) ;
@ -146,12 +181,12 @@ bool CDStarGatewayApp::createThread()
# ifdef USE_GPSD
# ifdef USE_GPSD
// Setup GPSD
// Setup GPSD
TGPSD gpsdConfig ;
TGPSD gpsdConfig ;
config. getGPSD ( gpsdConfig ) ;
m_config- > getGPSD ( gpsdConfig ) ;
# endif
# endif
// Setup APRS
// Setup APRS
TAPRS aprsConfig ;
TAPRS aprsConfig ;
config. getAPRS ( aprsConfig ) ;
m_config- > getAPRS ( aprsConfig ) ;
CAPRSHandler * aprsWriter = NULL ;
CAPRSHandler * aprsWriter = NULL ;
if ( aprsConfig . enabled & & ! aprsConfig . password . empty ( ) ) {
if ( aprsConfig . enabled & & ! aprsConfig . password . empty ( ) ) {
aprsWriter = new CAPRSHandler ( aprsConfig . hostname , aprsConfig . port , gatewayConfig . callsign , aprsConfig . password , gatewayConfig . address ) ;
aprsWriter = new CAPRSHandler ( aprsConfig . hostname , aprsConfig . port , gatewayConfig . callsign , aprsConfig . password , gatewayConfig . address ) ;
@ -176,9 +211,9 @@ bool CDStarGatewayApp::createThread()
bool ddEnabled = false ;
bool ddEnabled = false ;
bool atLeastOneRepeater = false ;
bool atLeastOneRepeater = false ;
CRepeaterProtocolHandlerFactory repeaterProtocolFactory ;
CRepeaterProtocolHandlerFactory repeaterProtocolFactory ;
for ( unsigned int i = 0U ; i < config. getRepeaterCount ( ) ; i + + ) {
for ( unsigned int i = 0U ; i < m_config- > getRepeaterCount ( ) ; i + + ) {
TRepeater rptrConfig ;
TRepeater rptrConfig ;
config. getRepeater ( i , rptrConfig ) ;
m_config- > getRepeater ( i , rptrConfig ) ;
auto repeaterProtocolHandler = repeaterProtocolFactory . getRepeaterProtocolHandler ( rptrConfig . hwType , gatewayConfig , rptrConfig . address , rptrConfig . port ) ;
auto repeaterProtocolHandler = repeaterProtocolFactory . getRepeaterProtocolHandler ( rptrConfig . hwType , gatewayConfig , rptrConfig . address , rptrConfig . port ) ;
if ( repeaterProtocolHandler = = nullptr )
if ( repeaterProtocolHandler = = nullptr )
continue ;
continue ;
@ -221,9 +256,9 @@ bool CDStarGatewayApp::createThread()
// Setup ircddb
// Setup ircddb
auto ircddbVersionInfo = " linux_ " + PRODUCT_NAME + " - " + VERSION ;
auto ircddbVersionInfo = " linux_ " + PRODUCT_NAME + " - " + VERSION ;
std : : vector < CIRCDDB * > clients ;
std : : vector < CIRCDDB * > clients ;
for ( unsigned int i = 0 ; i < config. getIrcDDBCount ( ) ; i + + ) {
for ( unsigned int i = 0 ; i < m_config- > getIrcDDBCount ( ) ; i + + ) {
TircDDB ircDDBConfig ;
TircDDB ircDDBConfig ;
config. getIrcDDB ( i , ircDDBConfig ) ;
m_config- > getIrcDDB ( i , ircDDBConfig ) ;
CLog : : logInfo ( " ircDDB Network %d set to %s user: %s, Quadnet %d " , i + 1 , ircDDBConfig . hostname . c_str ( ) , ircDDBConfig . username . c_str ( ) , ircDDBConfig . isQuadNet ) ;
CLog : : logInfo ( " ircDDB Network %d set to %s user: %s, Quadnet %d " , i + 1 , ircDDBConfig . hostname . c_str ( ) , ircDDBConfig . username . c_str ( ) , ircDDBConfig . isQuadNet ) ;
CIRCDDB * ircDDB = new CIRCDDBClient ( ircDDBConfig . hostname , 9007U , ircDDBConfig . username , ircDDBConfig . password , ircddbVersionInfo , gatewayConfig . address , ircDDBConfig . isQuadNet ) ;
CIRCDDB * ircDDB = new CIRCDDBClient ( ircDDBConfig . hostname , 9007U , ircDDBConfig . username , ircDDBConfig . password , ircddbVersionInfo , gatewayConfig . address , ircDDBConfig . isQuadNet ) ;
clients . push_back ( ircDDB ) ;
clients . push_back ( ircDDB ) ;
@ -240,31 +275,31 @@ bool CDStarGatewayApp::createThread()
// Setup Dextra
// Setup Dextra
TDextra dextraConfig ;
TDextra dextraConfig ;
config. getDExtra ( dextraConfig ) ;
m_config- > getDExtra ( dextraConfig ) ;
CLog : : logInfo ( " DExtra enabled: %d, max. dongles: %u " , int ( dextraConfig . enabled ) , dextraConfig . maxDongles ) ;
CLog : : logInfo ( " DExtra enabled: %d, max. dongles: %u " , int ( dextraConfig . enabled ) , dextraConfig . maxDongles ) ;
m_thread - > setDExtra ( dextraConfig . enabled , dextraConfig . maxDongles ) ;
m_thread - > setDExtra ( dextraConfig . enabled , dextraConfig . maxDongles ) ;
// Setup DCS
// Setup DCS
TDCS dcsConfig ;
TDCS dcsConfig ;
config. getDCS ( dcsConfig ) ;
m_config- > getDCS ( dcsConfig ) ;
CLog : : logInfo ( " DCS enabled: %d " , int ( dcsConfig . enabled ) ) ;
CLog : : logInfo ( " DCS enabled: %d " , int ( dcsConfig . enabled ) ) ;
m_thread - > setDCS ( dcsConfig . enabled ) ;
m_thread - > setDCS ( dcsConfig . enabled ) ;
// Setup DPlus
// Setup DPlus
TDplus dplusConfig ;
TDplus dplusConfig ;
config. getDPlus ( dplusConfig ) ;
m_config- > getDPlus ( dplusConfig ) ;
CLog : : logInfo ( " D-Plus enabled: %d, max. dongles: %u, login: %s " , int ( dplusConfig . enabled ) , dplusConfig . maxDongles , dplusConfig . login . c_str ( ) ) ;
CLog : : logInfo ( " D-Plus enabled: %d, max. dongles: %u, login: %s " , int ( dplusConfig . enabled ) , dplusConfig . maxDongles , dplusConfig . login . c_str ( ) ) ;
m_thread - > setDPlus ( dplusConfig . enabled , dplusConfig . maxDongles , dplusConfig . login ) ;
m_thread - > setDPlus ( dplusConfig . enabled , dplusConfig . maxDongles , dplusConfig . login ) ;
// Setup XLX
// Setup XLX
TXLX xlxConfig ;
TXLX xlxConfig ;
config. getXLX ( xlxConfig ) ;
m_config- > getXLX ( xlxConfig ) ;
CLog : : logInfo ( " XLX enabled: %d, Hosts file url: %s " , int ( xlxConfig . enabled ) , xlxConfig . url . c_str ( ) ) ;
CLog : : logInfo ( " XLX enabled: %d, Hosts file url: %s " , int ( xlxConfig . enabled ) , xlxConfig . url . c_str ( ) ) ;
m_thread - > setXLX ( xlxConfig . enabled , xlxConfig . enabled ? CXLXHostsFileDownloader : : download ( xlxConfig . url ) : " " ) ;
m_thread - > setXLX ( xlxConfig . enabled , xlxConfig . enabled ? CXLXHostsFileDownloader : : download ( xlxConfig . url ) : " " ) ;
// Setup Remote
// Setup Remote
TRemote remoteConfig ;
TRemote remoteConfig ;
config. getRemote ( remoteConfig ) ;
m_config- > getRemote ( remoteConfig ) ;
CLog : : logInfo ( " Remote enabled: %d, port %u " , int ( remoteConfig . enabled ) , remoteConfig . port ) ;
CLog : : logInfo ( " Remote enabled: %d, port %u " , int ( remoteConfig . enabled ) , remoteConfig . port ) ;
m_thread - > setRemote ( remoteConfig . enabled , remoteConfig . password , remoteConfig . port ) ;
m_thread - > setRemote ( remoteConfig . enabled , remoteConfig . password , remoteConfig . port ) ;
@ -287,6 +322,8 @@ void CDStarGatewayApp::sigHandler(int sig)
if ( g_app ! = nullptr & & g_app - > m_thread ! = nullptr ) {
if ( g_app ! = nullptr & & g_app - > m_thread ! = nullptr ) {
g_app - > m_thread - > kill ( ) ;
g_app - > m_thread - > kill ( ) ;
}
}
CDaemon : : finalize ( ) ;
}
}
void CDStarGatewayApp : : sigHandlerFatal ( int sig )
void CDStarGatewayApp : : sigHandlerFatal ( int sig )