Initial commit of files
This commit is contained in:
7
daemons/.gitignore
vendored
Normal file
7
daemons/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
cand/cand
|
||||
gpsd/gpsd
|
||||
logd/logd
|
||||
rtcmd/rtcmd
|
||||
seriald/seriald
|
||||
stdiod/stdiod
|
||||
trackd/trackd
|
||||
12
daemons/CMakeLists.txt
Normal file
12
daemons/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(Cnomicon)
|
||||
set(CMAKE_INSTALL_PREFIX ../bin)
|
||||
|
||||
# list of header files
|
||||
set(SUB_DIRS
|
||||
logd seriald stdiod cand gpsd rtcmd
|
||||
)
|
||||
|
||||
foreach(SUB_DIR ${SUB_DIRS})
|
||||
add_subdirectory(${SUB_DIR})
|
||||
endforeach()
|
||||
25
daemons/cand/CMakeLists.txt
Normal file
25
daemons/cand/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME cand)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libcan++ ../include/libgps++ ../include/libnet++ ../include)
|
||||
link_directories(../lib)
|
||||
link_libraries(can++ gps++ net++ net emb kmlbase kmldom kmlengine xml2 pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
CanDaemon.cpp
|
||||
CanListener.cpp
|
||||
CanRxListener.cpp
|
||||
CanTxGenerator.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
138
daemons/cand/CanDaemon.cpp
Normal file
138
daemons/cand/CanDaemon.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
//****************************************************************************
|
||||
// Copyright (C) 2007
|
||||
// Nissan North America
|
||||
// All Rights Reserved. Proprietary and Confidential.
|
||||
//============================================================================
|
||||
|
||||
//****************************************************************************
|
||||
// includes
|
||||
//***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "CanDaemon.h"
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
typedef struct _Can2DsrcMap {
|
||||
int Signal;
|
||||
double Scale;
|
||||
int Offset;
|
||||
} Can2DsrcMap;
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
CanDaemon::CanDaemon()
|
||||
{
|
||||
/* open a log file */
|
||||
log_open( CAND_NAME );
|
||||
SetTimeout( 1000000L );
|
||||
}
|
||||
|
||||
CanDaemon::~CanDaemon()
|
||||
{
|
||||
}
|
||||
|
||||
/* Server *******************************************************************/
|
||||
|
||||
void CanDaemon::DaemonStartup(void)
|
||||
{
|
||||
// start threads and detach
|
||||
Vehicle.Start( &Can, true ); // Receive CAN messages
|
||||
Generator.Start( NULL, true ); // Send TX packets
|
||||
|
||||
Receiver.Caster = this;
|
||||
Receiver.Start( NULL, true ); // Receive RX and TX Echo packets
|
||||
}
|
||||
|
||||
void CanDaemon::DaemonShutdown(void)
|
||||
{
|
||||
Receiver.Stop();
|
||||
Generator.Stop();
|
||||
Vehicle.Stop();
|
||||
}
|
||||
|
||||
int CanDaemon::ServerSocket(void)
|
||||
{
|
||||
int nrec=0;
|
||||
|
||||
return nrec;
|
||||
}
|
||||
|
||||
int CanDaemon::ServerTimeout(void)
|
||||
{
|
||||
if ( NumClients() )
|
||||
{
|
||||
// status
|
||||
// char str[128];
|
||||
// int n = snprintf( str, sizeof(str), "CANd: %ld sent, %ld recv\n",
|
||||
// Generator.SentCount(), Echo.RecvCount() );
|
||||
// ClientCast( str, n );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CanDaemon::ClientIn( int sock, const char *buf, int n )
|
||||
{
|
||||
// commands?
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CanDaemon::ClientCast( const char *buf, int n )
|
||||
{
|
||||
TcpServer::ClientCast( buf, n );
|
||||
}
|
||||
|
||||
/* other stuff **************************************************************/
|
||||
|
||||
int CanDaemon::CanOpen( const char *uri )
|
||||
{
|
||||
return Can.CanOpen( uri );
|
||||
}
|
||||
76
daemons/cand/CanDaemon.h
Normal file
76
daemons/cand/CanDaemon.h
Normal file
@ -0,0 +1,76 @@
|
||||
//****************************************************************************
|
||||
// Copyright (C) 2012
|
||||
// Nissan North America
|
||||
// All Rights Reserved. Proprietary and Confidential.
|
||||
//============================================================================
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __CanDaemon__
|
||||
#define __CanDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "TcpDaemon.h"
|
||||
|
||||
#include "CanDatabase.h"
|
||||
|
||||
#include "UdpCaster.h"
|
||||
|
||||
#include "CanListener.h"
|
||||
#include "CanTxGenerator.h"
|
||||
#include "CanRxListener.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* BSMPd */
|
||||
#define CAND_NAME "cand"
|
||||
#define CAND_SERVICE "cand"
|
||||
#define CAND_PORT "2946"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Uses the Peak Systems CAN Linux driver and Nissan CAN data
|
||||
//
|
||||
class CanDaemon : public TcpDaemon {
|
||||
// public data
|
||||
public:
|
||||
CanTxGenerator Generator;
|
||||
CanRxListener Receiver;
|
||||
CanListener Vehicle;
|
||||
|
||||
CanSocket Can;
|
||||
|
||||
// private data
|
||||
private:
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
CanDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~CanDaemon();
|
||||
|
||||
// virtual functions
|
||||
void DaemonStartup(void);
|
||||
void DaemonShutdown(void);
|
||||
int ClientIn( int sock, const char *buf, int n );
|
||||
void ClientCast( const char *buf, int n );
|
||||
int ServerSocket( void );
|
||||
int ServerTimeout( void );
|
||||
|
||||
// public methods
|
||||
int CanOpen( const char *can );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
321
daemons/cand/CanListener.cpp
Normal file
321
daemons/cand/CanListener.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
//****************************************************************************
|
||||
// includes
|
||||
//***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <regex.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "libxml/parser.h"
|
||||
#include "libxml/tree.h"
|
||||
|
||||
#include "CanSignal.h"
|
||||
#include "CanListener.h"
|
||||
#include "CanRxListener.h"
|
||||
#include "CanTxGenerator.h"
|
||||
|
||||
#include "CAN_Packet.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
#define MAX_DSRC_PARSERS 32
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
// write into the TX buffer
|
||||
CAN_Packet Can = {};
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
static int num_parsers = 0;
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
CanListener::CanListener()
|
||||
{
|
||||
m_accel_from_speed = false;
|
||||
m_debug = false;
|
||||
m_reverse = false;
|
||||
}
|
||||
|
||||
CanListener::~CanListener()
|
||||
{
|
||||
}
|
||||
|
||||
bool CanListener::CanParser( CanSignal *pSig, const unsigned char *data )
|
||||
{
|
||||
// successful and valid conversion with new data
|
||||
if (!pSig->isNew)
|
||||
return false;
|
||||
|
||||
// data has changed
|
||||
// if ( m_debug )
|
||||
// printf( "%s (%x) = %g (%ld)\n", pSig->Name.c_str(), pSig->Address, dValue, lValue );
|
||||
|
||||
// match CAN signal to CAN_Packet an copy
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CanListener::CanMapping( const char *file )
|
||||
{
|
||||
// parse XML
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlNodePtr root = NULL;
|
||||
|
||||
/*parse the file and get the DOM */
|
||||
if ( file )
|
||||
{
|
||||
if ( !(doc = xmlParseFile( file )) )
|
||||
{
|
||||
log_printf( "CANd: %s read error", file );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // m/s^2
|
||||
|
||||
log_printf( "CANd: %s file not found", file );
|
||||
return -1;
|
||||
}
|
||||
|
||||
xmlChar *dbc = NULL;
|
||||
int error = 0;
|
||||
|
||||
// Get the root element node
|
||||
root = xmlDocGetRootElement(doc);
|
||||
if ( !root )
|
||||
return -1;
|
||||
// <CANd> only
|
||||
if ( xmlStrcmp( root->name, (const xmlChar *)"HeartBeat" ) != 0 )
|
||||
return -1;
|
||||
|
||||
/* walk the tree */
|
||||
xmlNodePtr node = root->xmlChildrenNode;
|
||||
|
||||
while ( node )
|
||||
{
|
||||
if ( xmlStrcmp( node->name, (const xmlChar *)"text" ) == 0 )
|
||||
;
|
||||
else if ( xmlStrcmp( node->name, (const xmlChar *)"HeartBeat" ) == 0 )
|
||||
; // <!-- comment -->
|
||||
else if ( xmlStrcmp( node->name, (const xmlChar *)"Description" ) == 0 )
|
||||
;
|
||||
else if ( xmlStrcmp( node->name, (const xmlChar *)"Database" ) == 0 )
|
||||
{
|
||||
// database file name
|
||||
dbc = xmlNodeGetContent( node );
|
||||
}
|
||||
else if ( xmlStrcmp( node->name, (const xmlChar *)"CAN" ) == 0 )
|
||||
{
|
||||
xmlNodePtr item = node->xmlChildrenNode;
|
||||
|
||||
while ( item )
|
||||
{
|
||||
// CAN Signals
|
||||
if ( xmlStrcmp( item->name, (const xmlChar *)"text" ) == 0 )
|
||||
;
|
||||
else if ( xmlStrcmp( item->name, (const xmlChar *)"Message" ) == 0 )
|
||||
{
|
||||
// get name and address
|
||||
xmlNodePtr message = item->xmlChildrenNode;
|
||||
xmlChar *name = NULL;
|
||||
xmlChar *address = NULL;
|
||||
u_long addr = 0;
|
||||
|
||||
while ( message )
|
||||
{
|
||||
if ( xmlStrcmp( message->name, (const xmlChar *)"text" ) == 0 )
|
||||
;
|
||||
else if ( xmlStrcmp( message->name, (const xmlChar *)"Name" ) == 0 )
|
||||
name = xmlNodeGetContent( message );
|
||||
else if ( xmlStrcmp( message->name, (const xmlChar *)"Address" ) == 0 )
|
||||
address = xmlNodeGetContent( message );
|
||||
|
||||
message = message->next;
|
||||
}
|
||||
|
||||
// add filter by name and address
|
||||
if ( address )
|
||||
addr = strtol( (char *)address, NULL, 10 );
|
||||
if ( name )
|
||||
AddMsgFilter( (char *)name, addr, addr );
|
||||
}
|
||||
else if ( xmlStrcmp( item->name, (const xmlChar *)"Signal" ) == 0 )
|
||||
{
|
||||
// get name and address
|
||||
xmlNodePtr signal = item->xmlChildrenNode;
|
||||
xmlChar *name = NULL;
|
||||
xmlChar *address = NULL;
|
||||
u_long addr = 0;
|
||||
|
||||
while ( signal )
|
||||
{
|
||||
if ( xmlStrcmp( signal->name, (const xmlChar *)"text" ) == 0 )
|
||||
;
|
||||
else if ( xmlStrcmp( signal->name, (const xmlChar *)"Name" ) == 0 )
|
||||
name = xmlNodeGetContent( signal );
|
||||
else if ( xmlStrcmp( signal->name, (const xmlChar *)"Address" ) == 0 )
|
||||
address = xmlNodeGetContent( signal );
|
||||
|
||||
signal = signal->next;
|
||||
}
|
||||
|
||||
// add filter by name and address
|
||||
if ( address )
|
||||
addr = strtol( (char *)address, NULL, 10 );
|
||||
if ( name )
|
||||
AddSigFilter( (char *)name, addr, addr );
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
error++;
|
||||
break;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
// Load the database after the filters are loaded and parse everything!
|
||||
if ( dbc )
|
||||
{
|
||||
int n = LoadDatabase( (char*)dbc );
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
log_printf( "CANd: Database \"%s\" open failed!", (char*)dbc );
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_printf( "CANd: No database!" );
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* free the document */
|
||||
xmlFreeDoc(doc);
|
||||
xmlCleanupParser();
|
||||
|
||||
// errors parsing
|
||||
if ( error )
|
||||
return -1;
|
||||
|
||||
if ( num_parsers )
|
||||
{
|
||||
log_printf( "CANd: Parsers found = %d", num_parsers );
|
||||
}
|
||||
else
|
||||
{
|
||||
log_printf( "CANd: Errors found or no work to do (no CAN signals)!" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return num_parsers;
|
||||
}
|
||||
|
||||
void *CanListener::Run(void *arg)
|
||||
{
|
||||
pCan = (CanSocket*)arg;
|
||||
|
||||
// wait till other threads have time to start
|
||||
sleep(1);
|
||||
|
||||
// subscribed marked signals
|
||||
SubscribeCan( pCan );
|
||||
pCan->Blocking(0); // does this even work?
|
||||
|
||||
// setup for select()
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
int retval;
|
||||
FD_ZERO(&rfds);
|
||||
|
||||
// run forever
|
||||
while(1)
|
||||
{
|
||||
// select()
|
||||
FD_SET(pCan->m_sock, &rfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10000;
|
||||
retval = select(pCan->m_sock+1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
if (retval == -1)
|
||||
perror("select()");
|
||||
else if (retval)
|
||||
{
|
||||
CanFrame frame[20];
|
||||
int n, sigs = 0;
|
||||
|
||||
// frame from CAN device (will block on more than 1)
|
||||
if ( (n = pCan->CanRawRead( frame, sizeof(frame)/sizeof(CanFrame) )) > 0 )
|
||||
{
|
||||
for ( int i=0 ; i<n ; i++ )
|
||||
{
|
||||
// convert matching addresses (might be more than 1 signal)
|
||||
for ( u_int j=0 ; j<Messages.size() ; j++ )
|
||||
{
|
||||
if ( Messages[j]->Read(&frame[i]) )
|
||||
{
|
||||
for (u_int k=0 ; k<Messages[j]->Signals.size() ; k++)
|
||||
{
|
||||
if ( CanParser( Messages[j]->Signals[k], frame[i].data ) )
|
||||
sigs++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
70
daemons/cand/CanListener.h
Normal file
70
daemons/cand/CanListener.h
Normal file
@ -0,0 +1,70 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __CanListener__
|
||||
#define __CanListener__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <muParser.h>
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "UdpCaster.h"
|
||||
|
||||
#include "CanSocket.h"
|
||||
#include "CanDatabase.h"
|
||||
|
||||
#include "CanTxGenerator.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
class CanListener : public Thread, public CanDatabase {
|
||||
// public data
|
||||
public:
|
||||
bool m_accel_from_speed;
|
||||
bool m_debug;
|
||||
bool m_reverse;
|
||||
|
||||
// protected data
|
||||
protected:
|
||||
CanSocket *pCan;
|
||||
|
||||
// private data
|
||||
private:
|
||||
|
||||
// private methods
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
CanListener();
|
||||
|
||||
// destructor
|
||||
virtual ~CanListener();
|
||||
|
||||
// public methods
|
||||
bool CanParser( CanSignal *pSig, const unsigned char * );
|
||||
int CanMapping( const char *file );
|
||||
|
||||
// virtual overrides
|
||||
void *Run(void*);
|
||||
|
||||
private:
|
||||
// signal catchers (do not override)
|
||||
};
|
||||
|
||||
#endif
|
||||
107
daemons/cand/CanRxListener.cpp
Normal file
107
daemons/cand/CanRxListener.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
//****************************************************************************
|
||||
// includes
|
||||
//***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "ClockTimer.h"
|
||||
#include "CanRxListener.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
extern CAN_Packet Can;
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
CanRxListener::CanRxListener()
|
||||
{
|
||||
m_debug = false;
|
||||
nTxEcho = nRxBsm = nRxOem = 0;
|
||||
}
|
||||
|
||||
CanRxListener::~CanRxListener()
|
||||
{
|
||||
}
|
||||
|
||||
// listener hooks
|
||||
void *CanRxListener::Run(void *arg)
|
||||
{
|
||||
unsigned char buf[2048];
|
||||
|
||||
while(1)
|
||||
{
|
||||
// WSU RX or TX Echo packets
|
||||
int nread = Recv( buf, sizeof(buf) );
|
||||
|
||||
if ( nread == 0 )
|
||||
continue;
|
||||
|
||||
char timebuf[32];
|
||||
|
||||
if ( Logging.IsLogging() )
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
gettimeofday( &tv, NULL );
|
||||
gmtime_r( &tv.tv_sec, &tm );
|
||||
sprintf( timebuf, "%4d/%02d/%02d-%02d:%02d:%02d.%03ld",
|
||||
tm.tm_year+1900, tm.tm_mon, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tv.tv_usec / 1000L
|
||||
);
|
||||
}
|
||||
|
||||
// incoming
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
67
daemons/cand/CanRxListener.h
Normal file
67
daemons/cand/CanRxListener.h
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __CanRxListener__
|
||||
#define __CanRxListener__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include <pthread.h>
|
||||
#include "netlib.h"
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include "GpsPoint.h"
|
||||
#include "UdpThread.h"
|
||||
#include "TcpServer.h"
|
||||
#include "UdpCaster.h"
|
||||
#include "LogData.h"
|
||||
|
||||
#include "CAN_Packet.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
class CanRxListener : public UdpThread {
|
||||
// public data
|
||||
public:
|
||||
bool m_debug;
|
||||
TcpServer *Caster;
|
||||
UdpCaster Forward;
|
||||
LogData Logging;
|
||||
|
||||
// protected data
|
||||
protected:
|
||||
int nTxEcho;
|
||||
int nRxBsm;
|
||||
int nRxOem;
|
||||
|
||||
// private data
|
||||
private:
|
||||
|
||||
// private methods
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
CanRxListener();
|
||||
|
||||
// destructor
|
||||
virtual ~CanRxListener();
|
||||
|
||||
// virtual overrides
|
||||
void *Run(void*);
|
||||
|
||||
private:
|
||||
// signal catchers (do not override)
|
||||
};
|
||||
|
||||
#endif
|
||||
139
daemons/cand/CanTxGenerator.cpp
Normal file
139
daemons/cand/CanTxGenerator.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
//****************************************************************************
|
||||
// includes
|
||||
//***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "ClockTimer.h"
|
||||
#include "CanTxGenerator.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
#ifndef min
|
||||
#define min(A,B) ((A)<(B)?(A):(B))
|
||||
#endif
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
extern CAN_Packet Can;
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
static CanTxGenerator *Self = NULL;
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
CanTxGenerator::CanTxGenerator()
|
||||
{
|
||||
Self = this;
|
||||
m_period = 100;
|
||||
}
|
||||
|
||||
CanTxGenerator::~CanTxGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
// generator itself
|
||||
void *CanTxGenerator::Run(void *arg)
|
||||
{
|
||||
ClockTimer Loop;
|
||||
|
||||
Loop.Start( m_period * 1000 ); // usec
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
// send out
|
||||
SendTo( &Can, sizeof(Can) );
|
||||
|
||||
// log this message // log this message
|
||||
if ( Logging.IsLogging() )
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
gettimeofday( &tv, NULL );
|
||||
gmtime_r( &tv.tv_sec, &tm );
|
||||
char buf[32];
|
||||
sprintf( buf, "%4d/%2d/%2d-%2d:%2d:%2d.%03ld",
|
||||
tm.tm_year+1900, tm.tm_mon, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tv.tv_usec / 1000L
|
||||
);
|
||||
|
||||
Logging.LogPrintf( "%s,%s,%f,%f,%f,%f,%u,%f,%u,%f,%f,%f,%f,%f,%u,%u,%u,%f,%u,%f",
|
||||
buf,
|
||||
"TX",
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0,
|
||||
Can.fSpeed,
|
||||
Can.byTransmission,
|
||||
Can.fSteering,
|
||||
Can.fAccelLongitudinal,
|
||||
Can.fAccelLateral,
|
||||
Can.fAccelVertical,
|
||||
Can.fYawRate,
|
||||
Can.wBrakeSystemStatus,
|
||||
Can.wEventFlags,
|
||||
Can.byExteriorLights,
|
||||
Can.fThrottle,
|
||||
Can.byFrontWipers,
|
||||
0.0
|
||||
);
|
||||
}
|
||||
|
||||
// 100 msec, leave a little time to do the work
|
||||
Loop.Sync();
|
||||
// msleep( m_period - 10L );
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
60
daemons/cand/CanTxGenerator.h
Normal file
60
daemons/cand/CanTxGenerator.h
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// Linux Daemon
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __CanTxGenerator__
|
||||
#define __CanTxGenerator__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
#include "UdpCaster.h"
|
||||
#include "UdpThread.h"
|
||||
#include "LogData.h"
|
||||
|
||||
#include "CAN_Packet.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
class CanTxGenerator : public UdpThread {
|
||||
// public data
|
||||
public:
|
||||
LogData Logging;
|
||||
unsigned long m_period;
|
||||
|
||||
// protected data
|
||||
protected:
|
||||
UdpClient *pCan;
|
||||
|
||||
// private data
|
||||
private:
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
CanTxGenerator();
|
||||
|
||||
// destructor
|
||||
virtual ~CanTxGenerator();
|
||||
|
||||
// public methods
|
||||
void SetPeriod(unsigned long period) {m_period=period;};
|
||||
|
||||
// virtual overrides
|
||||
void *Run(void*);
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
18862
daemons/cand/Infiniti_M37_JX35_ADAS.dbc
Normal file
18862
daemons/cand/Infiniti_M37_JX35_ADAS.dbc
Normal file
File diff suppressed because one or more lines are too long
139
daemons/cand/bsmpbeat.xml
Normal file
139
daemons/cand/bsmpbeat.xml
Normal file
@ -0,0 +1,139 @@
|
||||
<HeartBeat>
|
||||
<Description>Nissan/Infiniti Gen3</Description>
|
||||
<Database>Infiniti_M37_JX35_ADAS.dbc</Database>
|
||||
<CAN>
|
||||
<!-- CAN Database Filter, messages to read
|
||||
Not needed if DBC is edited to CAN messages needed -->
|
||||
<Signal>
|
||||
<Name>CABRESW</Name>
|
||||
<Address>0x35D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>TURN_IND</Name>
|
||||
<Address>0x60D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>FR_WIP_REQ</Name>
|
||||
<Address>0x35D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>HL_HIGH_REQ</Name>
|
||||
<Address>0x60D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>HL_LOW_REQ</Name>
|
||||
<Address>0x60D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>TAIL_L_REQ</Name>
|
||||
<Address>0x60D</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>LONG_ACC_02</Name>
|
||||
<Address>0x292</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>TRANS_ACC_02</Name>
|
||||
<Address>0x292</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>YAW_RATE_02</Name>
|
||||
<Address>0x292</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>ABSACT</Name>
|
||||
<Address>0x354</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>V_APO</Name>
|
||||
<Address>0x182</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>VSO</Name>
|
||||
<Address>0x284</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>STRANGLE</Name>
|
||||
<Address>0x002</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>TCSACT</Name>
|
||||
<Address>0x245</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>VDCACT</Name>
|
||||
<Address>0x245</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>OFF_SW</Name>
|
||||
<Address>0x245</Address>
|
||||
</Signal>
|
||||
<Signal>
|
||||
<Name>CURGP</Name>
|
||||
<Address>0x174</Address>
|
||||
</Signal>
|
||||
</CAN>
|
||||
<DSRC>
|
||||
<!-- CAN Signal (real values) to DSRC Element conversion -->
|
||||
<Element>
|
||||
<Name>Speed</Name>
|
||||
<Expr>VSO*0.277777778</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>TransmissionState</Name>
|
||||
<Expr>CURGP</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>LateralAcceleration</Name>
|
||||
<Expr>TRANS_ACC_02*9.80665</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>LongitudinalAcceleration</Name>
|
||||
<Expr>LONG_ACC_02*9.80665</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>YawRate</Name>
|
||||
<Expr>YAW_RATE_02*0.1</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>BrakeAppliedStatus</Name>
|
||||
<Expr>CABRESW*15</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>TractionControlStatus</Name>
|
||||
<Expr>OFF_SW?0:TCSACT+1</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>AntilockBrakeStatus</Name>
|
||||
<Expr>ABSACT?ABSACT+1:0</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>StabilityControlStatus</Name>
|
||||
<Expr>OFF_SW?0:VDCACT+1</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>VehicleWidth</Name>
|
||||
<Expr>1.85</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>VehicleLength</Name>
|
||||
<Expr>4.95</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>SteeringWheelAngle</Name>
|
||||
<Expr>STRANGLE</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>AccelPedalPosition</Name>
|
||||
<Expr>V_APO*0.39216</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>ExteriorLights</Name>
|
||||
<Expr>HL_LOW_REQ*1+HL_HIGH_REQ*2+TURN_IND*4+TAIL_L_REQ*128</Expr>
|
||||
</Element>
|
||||
<Element>
|
||||
<Name>FrontWiperStatus</Name>
|
||||
<Expr>FR_WIP_REQ</Expr>
|
||||
</Element>
|
||||
</DSRC>
|
||||
</HeartBeat>
|
||||
204
daemons/cand/cand.cpp
Normal file
204
daemons/cand/cand.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// CAN Daemon (cand.cpp)
|
||||
//
|
||||
// Neal Probert
|
||||
//
|
||||
// IPv4 for now, since clients will be localhost anyways
|
||||
// IPv6 for testing
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "CanDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
/*
|
||||
* Note that we are doing a multi-client server so that it's possible to
|
||||
* have several applications listening to CAN
|
||||
*/
|
||||
|
||||
static const char *helptext =
|
||||
"cand -m map.txt [options]\n"
|
||||
"\t-a Acceleration calculated from speed\n"
|
||||
"\t-b uri CAN Packet broadcast\n"
|
||||
"\t-c can0 CAN Interface (default)\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-f uri forward udp port (usually to MABX2)\n"
|
||||
"\t-h help\n"
|
||||
"\t-l uri UDP for TX Echo Listener (WSU BSM Proxy)\n"
|
||||
"\t-m file.xml CAN to DSRC mapping file\n"
|
||||
"\t-t period HeartBeat period in msec (default=100)\n"
|
||||
"\t-v id Set Vehicle TempID (default=random)\n"
|
||||
"\t-w uri UDP for TX Generator (WSU BSM Proxy)\n"
|
||||
"\t-L logfile Message log file\n"
|
||||
"\t-S service TCP service (default=2949)\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
int n;
|
||||
|
||||
/* options */
|
||||
int debug = 0;
|
||||
|
||||
/* CAN */
|
||||
const char *can = NULL; // "can0"
|
||||
const char *mapping = NULL;
|
||||
|
||||
/* HB */
|
||||
const char *tx = "udp://192.168.1.2:2735"; // to WSU
|
||||
const char *rx = "udp://0.0.0.0:2736"; // from WSU
|
||||
const char *tcp = CAND_PORT;
|
||||
unsigned long period = 100UL;
|
||||
const char *fwd = NULL; // "udp://192.168.1.10:2736"; // mABx2
|
||||
|
||||
// if we're doing CAN, we must be doing TX as well
|
||||
if ( can )
|
||||
tx = "udp://192.168.1.2:2735";
|
||||
else
|
||||
tx = NULL; // if we want to use dummy TX for testing
|
||||
|
||||
/* init hardware interface and daemon */
|
||||
CanDaemon Can;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "ac:df:hl:m:tw:L:S:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'a':
|
||||
Can.Vehicle.m_accel_from_speed = false;
|
||||
break;
|
||||
case 'c':
|
||||
can = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
Can.Receiver.m_debug = Can.Vehicle.m_debug = true;
|
||||
break;
|
||||
case 'f':
|
||||
fwd = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
exit(0);
|
||||
break;
|
||||
case 'l':
|
||||
rx = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
mapping = optarg;
|
||||
break;
|
||||
case 't':
|
||||
period = strtoul( optarg, NULL, 10 );
|
||||
break;
|
||||
case 'w':
|
||||
if (strcmp(optarg, "-") == 0)
|
||||
tx = "udp://192.168.1.2:2735";
|
||||
else
|
||||
tx = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
// Open log file (must be to logd!)
|
||||
if ( Can.Receiver.Logging.LogOpen(optarg, 0) )
|
||||
{
|
||||
printf( "%s: Log file opened\n", optarg );
|
||||
Can.Receiver.Logging.LogPrintf( "logtime,timestamp,type,id,latitude,longitude,elevation,heading,"
|
||||
"speed,trans,steering,accel_long,accel_lat,accel_vert,yaw_rate,"
|
||||
"brakes,event,lights,throttle,wipers,pp_radius" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: log file open failed\n", optarg );
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
tcp = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// CAN Database and Parsing
|
||||
if ( mapping )
|
||||
{
|
||||
// Filter to reduce database
|
||||
if ( (n = Can.Vehicle.CanMapping( mapping )) <= 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to load CAN database and DSRC mapping!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if ( can )
|
||||
{
|
||||
fprintf( stderr, "CAN to DSRC Mapping file is required!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// CAN device, can run without CAN for testing
|
||||
if ( can )
|
||||
{
|
||||
if ( Can.Can.CanOpen( can ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open CAN device: %s!\n", can );
|
||||
exit(1);
|
||||
}
|
||||
// fprintf( stderr, "CAN Max Filter = %d\n", CAN_MAX_FILTER );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Running without CAN, setting fake values\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// TX sending
|
||||
if ( tx )
|
||||
{
|
||||
// UDP
|
||||
if ( Can.Generator.ConnectUri( tx ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to WSU BSM Proxy!\n" );
|
||||
exit(1);
|
||||
}
|
||||
Can.Generator.SetPeriod( period );
|
||||
}
|
||||
else
|
||||
fprintf( stderr, "Running without TX, RX listener only (TX Echo, RX Msg, OEM Echo)\n" );
|
||||
|
||||
// UDP broadcast
|
||||
if ( rx )
|
||||
Can.Receiver.ListenUri( rx );
|
||||
else
|
||||
fprintf( stderr, "Running with RX, sending TX only\n" );
|
||||
|
||||
// Forwarding to MABX2
|
||||
if ( fwd )
|
||||
{
|
||||
if ( Can.Receiver.Forward.CasterUri( fwd ) >= 0 )
|
||||
fprintf( stderr, "Forwarding packets to %s\n", fwd );
|
||||
else
|
||||
fprintf( stderr, "Forward open failed!\n" );
|
||||
}
|
||||
|
||||
/* TCP Server */
|
||||
if ( Can.StartService( CAND_NAME, NULL, tcp, debug ) >= 0 )
|
||||
return Can.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
3
daemons/cand/candebug.sh
Executable file
3
daemons/cand/candebug.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
./cand -c can0 -d -m bsmpbeat.xml
|
||||
3
daemons/cand/debug.sh
Executable file
3
daemons/cand/debug.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
./cand -d -f udp://192.168.1.10:2736 -m bsmpbeat.xml
|
||||
26
daemons/gpsd/CMakeLists.txt
Normal file
26
daemons/gpsd/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME gpsd)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libgps++
|
||||
../include/libnet++
|
||||
../include)
|
||||
|
||||
link_directories(../lib)
|
||||
|
||||
link_libraries(gps++ net++ net emb kmlbase kmldom kmlengine xml2 pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
GpsDaemon.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
384
daemons/gpsd/GpsDaemon.cpp
Normal file
384
daemons/gpsd/GpsDaemon.cpp
Normal file
@ -0,0 +1,384 @@
|
||||
//
|
||||
// GPS Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "UriParse.h"
|
||||
#include "GpsDaemon.h"
|
||||
|
||||
#include "NmeaParser.h"
|
||||
#include "ApplanixParser.h"
|
||||
#include "FastraxParser.h"
|
||||
#include "GarminParser.h"
|
||||
#include "SirfParser.h"
|
||||
#include "UbloxParser.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
GpsDaemon::GpsDaemon()
|
||||
{
|
||||
log_open( GPSD_NAME );
|
||||
|
||||
clockset = 0;
|
||||
msgcount = 0;
|
||||
|
||||
dgps_corr = true;
|
||||
|
||||
SourceIn = CorrIn = -1;
|
||||
|
||||
strcpy( Uri, "" );
|
||||
nClients = 0;
|
||||
|
||||
SetClientTimeout(false); // don't reset timeout on client activity
|
||||
}
|
||||
|
||||
GpsDaemon::~GpsDaemon()
|
||||
{
|
||||
Gps.GpsClose();
|
||||
Log.LogClose();
|
||||
}
|
||||
|
||||
/* NMEA **********************************************************************/
|
||||
|
||||
void GpsDaemon::PositionListener( const GpsPoint &Pos, const ErrorInfo &Err )
|
||||
{
|
||||
}
|
||||
|
||||
void GpsDaemon::TimeListener( const struct timeval &tv )
|
||||
{
|
||||
// good fix and time
|
||||
if ( clockset && tv.tv_sec )
|
||||
{
|
||||
if ( getuid() == 0 )
|
||||
settimeofday( &tv, NULL );
|
||||
clockset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* TCP ***********************************************************************/
|
||||
|
||||
int GpsDaemon::ServerTimeout(void)
|
||||
{
|
||||
// timeout (a bad thing)
|
||||
DgpsReconnect();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GpsDaemon::ServerSocket(void)
|
||||
{
|
||||
char buf[2048];
|
||||
int n = 0;
|
||||
|
||||
|
||||
if ( IsSet( CorrIn ) )
|
||||
{
|
||||
// corrections
|
||||
if ( dgps_corr )
|
||||
// from RTCM server (once a minute)
|
||||
n = Dgps.DgpsRead( buf, sizeof(buf) );
|
||||
else
|
||||
// from NTRIP server (once a minute)
|
||||
n = Ntrip.NtripRead( (unsigned char *)buf, sizeof(buf) );
|
||||
|
||||
// xmit
|
||||
if ( n > 0 )
|
||||
Gps.GpsWrite( buf, n );
|
||||
else if ( n == 0 )
|
||||
{
|
||||
if ( dgps_corr )
|
||||
log_error( "Remote RTCM server closed!" );
|
||||
else
|
||||
log_error( "Remote NTRIP server closed!" );
|
||||
DgpsReconnect();
|
||||
}
|
||||
ResetServerTimeout();
|
||||
}
|
||||
else if ( IsSet( SourceIn ) )
|
||||
{
|
||||
if ( gps_source )
|
||||
// packet from GPS device
|
||||
n = Gps.GpsRead( buf, sizeof(buf) );
|
||||
else
|
||||
// remote gpsd/glty
|
||||
n = Gpsd.Recv( buf, sizeof(buf) );
|
||||
|
||||
if ( n > 0 && Parser && Parser->GpsParse(buf, n) > 0 )
|
||||
{
|
||||
msgcount++;
|
||||
|
||||
// 'cast
|
||||
ClientCast( buf, n );
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int GpsDaemon::ClientIn( int sock, const char *buf, int n )
|
||||
{
|
||||
// allows for NMEA playback via netcat
|
||||
if ( *buf == '$' )
|
||||
{
|
||||
// broadcast it
|
||||
Bcast.SendTo( buf, n );
|
||||
|
||||
// send to clients
|
||||
TcpServer::ClientCast( buf, n );
|
||||
}
|
||||
else
|
||||
{
|
||||
// parse for commands?
|
||||
|
||||
// just log it
|
||||
log_write( buf );
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int GpsDaemon::ClientUp( int sock )
|
||||
{
|
||||
if ( nClients++ == 0 )
|
||||
;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GpsDaemon::ClientDown( int sock )
|
||||
{
|
||||
// disconnect source
|
||||
if ( --nClients <= 0 )
|
||||
nClients = 0;
|
||||
}
|
||||
|
||||
void GpsDaemon::ClientCast( const char *buf, int n )
|
||||
{
|
||||
// broadcast it
|
||||
Bcast.SendTo( buf, n );
|
||||
|
||||
// send to clients
|
||||
TcpServer::ClientCast( buf, n );
|
||||
|
||||
// log NMEA data with time stamp
|
||||
Log.LogWrite( buf, n );
|
||||
}
|
||||
|
||||
/* GPS ***********************************************************************/
|
||||
|
||||
int GpsDaemon::GpsOpen( const char *device, int baud )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setRate( baud );
|
||||
parsed.setUri( device );
|
||||
|
||||
const char *proto = parsed.getProto();
|
||||
|
||||
SourceIn = -1;
|
||||
|
||||
if ( !proto )
|
||||
proto = "nmea";
|
||||
|
||||
// connect to gpsd?
|
||||
if ( strcmp( proto, "gpsd" ) == 0 )
|
||||
{
|
||||
// does r mode for NMEA
|
||||
SourceIn = Gpsd.GpsdConnect( parsed.getHost() );
|
||||
proto = "nmea";
|
||||
}
|
||||
else if ( strcmp( proto, "glty" ) == 0 )
|
||||
{
|
||||
// put in NMEA mode
|
||||
SourceIn = Gpsd.GpsdConnect( parsed.getHost() );
|
||||
Gpsd.Send( "$PGLTY,NMEA\n", 12 );
|
||||
proto = "pvii";
|
||||
}
|
||||
else
|
||||
{
|
||||
// open device
|
||||
SourceIn = Gps.GpsOpen( parsed.getPath(), parsed.getRate() );
|
||||
gps_source = true;
|
||||
}
|
||||
|
||||
// check
|
||||
if ( SourceIn < 0 )
|
||||
return SourceIn;
|
||||
|
||||
bool binary = false;
|
||||
|
||||
// attach parser (should probably use a table)
|
||||
if ( strcasecmp( proto, "nmea") == 0 )
|
||||
{
|
||||
// ascii
|
||||
NmeaParser *parser = new NmeaParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else if ( strcasecmp( proto, "applanix") == 0 )
|
||||
{
|
||||
// binary
|
||||
binary = true;
|
||||
ApplanixParser *parser = new ApplanixParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else if ( strcasecmp( proto, "fastrax") == 0 )
|
||||
{
|
||||
// ascii
|
||||
FastraxParser *parser = new FastraxParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else if ( strcasecmp( proto, "garmin") == 0 )
|
||||
{
|
||||
// ascii/binary
|
||||
GarminParser *parser = new GarminParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else if ( strcasecmp( proto, "sirf") == 0 )
|
||||
{
|
||||
// binary
|
||||
SirfParser *parser = new SirfParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else if ( strcasecmp( proto, "ublox") == 0 )
|
||||
{
|
||||
// ascii/binary
|
||||
UbloxParser *parser = new UbloxParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ascii
|
||||
NmeaParser *parser = new NmeaParser();
|
||||
Parser = (GpsParser *)parser;
|
||||
}
|
||||
|
||||
// set mode
|
||||
if ( binary )
|
||||
Gps.SetCanonical( false, 0, 0 );
|
||||
|
||||
// subscribe
|
||||
Parser->Subscribe( (GpsListener*)this );
|
||||
|
||||
// add listener
|
||||
AddFd( SourceIn );
|
||||
|
||||
return SourceIn;
|
||||
}
|
||||
|
||||
int GpsDaemon::DgpsConnect( const char *uri )
|
||||
{
|
||||
if ( !uri )
|
||||
return -1;
|
||||
|
||||
// already connected?
|
||||
if ( CorrIn >= 0 )
|
||||
return CorrIn;
|
||||
|
||||
UriParse parsed;
|
||||
parsed.setService( "2101" );
|
||||
parsed.setUri( uri );
|
||||
|
||||
const char *proto = parsed.getProto();
|
||||
|
||||
if ( strcmp( proto, "dgps" ) == 0 || strcmp( proto, "dgpsip" ) == 0
|
||||
|| strcmp( proto, "rtcmd" ) == 0 )
|
||||
{
|
||||
// RTCM server (dgpsip)
|
||||
CorrIn = Dgps.DgpsConnect( parsed.getHost(), parsed.getService() );
|
||||
dgps_corr = true;
|
||||
}
|
||||
else if ( strcmp( proto, "ntrip" ) == 0 )
|
||||
{
|
||||
// NTRIP caster
|
||||
CorrIn = Ntrip.NtripConnect( uri );
|
||||
dgps_corr = false;
|
||||
}
|
||||
|
||||
// add listener
|
||||
if ( CorrIn >= 0 )
|
||||
{
|
||||
strcpy( Uri, uri );
|
||||
AddFd( CorrIn );
|
||||
}
|
||||
|
||||
return CorrIn;
|
||||
}
|
||||
|
||||
void GpsDaemon::DgpsDisconnect( void )
|
||||
{
|
||||
if ( CorrIn >= 0 )
|
||||
;
|
||||
else
|
||||
return;
|
||||
Dgps.DgpsClose();
|
||||
Ntrip.NtripClose();
|
||||
DelFd( CorrIn );
|
||||
CorrIn = -1;
|
||||
}
|
||||
|
||||
void GpsDaemon::DgpsReconnect( void )
|
||||
{
|
||||
if ( nClients == 0 || strlen(Uri) == 0 )
|
||||
return;
|
||||
log_printf( "Remote RTCM/NTRIP timed out, reconnecting" );
|
||||
Dgps.DgpsClose();
|
||||
Ntrip.NtripClose();
|
||||
DelFd( CorrIn );
|
||||
CorrIn = -1;
|
||||
|
||||
DgpsConnect( Uri );
|
||||
}
|
||||
|
||||
int GpsDaemon::GpsBroadcast( const char *host )
|
||||
{
|
||||
const char *port = GPSD_SERVICE;
|
||||
|
||||
int sock = Bcast.Caster( host, port );
|
||||
|
||||
return sock;
|
||||
}
|
||||
121
daemons/gpsd/GpsDaemon.h
Normal file
121
daemons/gpsd/GpsDaemon.h
Normal file
@ -0,0 +1,121 @@
|
||||
//
|
||||
// GPS Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __GpsDaemon__
|
||||
#define __GpsDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#include "TcpDaemon.h"
|
||||
#include "UdpClient.h"
|
||||
#include "UdpCaster.h"
|
||||
|
||||
#include "GpsDevice.h"
|
||||
#include "GpsdClient.h"
|
||||
#include "NmeaParser.h"
|
||||
#include "SirfParser.h"
|
||||
#include "ApplanixParser.h"
|
||||
#include "DgpsClient.h"
|
||||
#include "NtripClient.h"
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* software details */
|
||||
#define GPSD_NAME "gpsd"
|
||||
#define GPSD_VERSION "0.1"
|
||||
|
||||
/* default service and port */
|
||||
#define GPSD_SERVICE "gpsd"
|
||||
#define GPSD_PORT "2947"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Uses the Peak Systems CAN Linux driver and Nissan CAN data
|
||||
//
|
||||
class GpsDaemon : public TcpDaemon, public GpsListener, public Logging {
|
||||
// public data
|
||||
public:
|
||||
GpsdClient Gpsd;
|
||||
GpsDevice Gps;
|
||||
GpsParser *Parser;
|
||||
|
||||
DgpsClient Dgps;
|
||||
NtripClient Ntrip;
|
||||
|
||||
// TrackClient Track;
|
||||
|
||||
// for corrections reconnect
|
||||
char Uri[1024];
|
||||
int nClients;
|
||||
|
||||
// private data
|
||||
private:
|
||||
bool gps_source; // 1=gps, 0=gpsd
|
||||
bool dgps_corr; // 1=dpgs, 0=ntrip
|
||||
|
||||
// FDs
|
||||
int SourceIn; // GpsdClient or GpsDevice
|
||||
int CorrIn; // DpgsIn or NtripIn
|
||||
int TrackOut; //
|
||||
|
||||
// UDP broadcast (data)
|
||||
UdpCaster Bcast;
|
||||
|
||||
// misc
|
||||
int clockset; // set to set clock from GPS
|
||||
int msgcount;
|
||||
|
||||
// private methods
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
GpsDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~GpsDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ServerTimeout(void);
|
||||
int ServerSocket(void);
|
||||
int ClientIn( int sock, const char *buf, int n );
|
||||
int ClientUp( int sock );
|
||||
void ClientDown( int sock );
|
||||
void ClientCast( const char *buf, int n );
|
||||
|
||||
// parser notifications
|
||||
void PositionListener( const GpsPoint &Pos, const ErrorInfo &Err );
|
||||
void TimeListener( const struct timeval &Time );
|
||||
|
||||
// public methods
|
||||
void SetClock( void ) {clockset=1;};
|
||||
int GpsOpen( const char *dev, int baud=38400 );
|
||||
int GpsBroadcast( const char *host = NULL );
|
||||
|
||||
// corrections
|
||||
int DgpsConnect( const char *host );
|
||||
void DgpsDisconnect( void );
|
||||
void DgpsReconnect( void );
|
||||
int DgpsListen( const char *host = NULL );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
226
daemons/gpsd/gpsd.cpp
Normal file
226
daemons/gpsd/gpsd.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// GPS Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "GpsDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// Written because gpsd (http://gpsd.berlios.de/) is too fat
|
||||
//
|
||||
|
||||
//
|
||||
// GPS Server (port 2947 by default)
|
||||
// ----------
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"This is GPSd, not the open source software gpsd:\n"
|
||||
"gpsd -s /dev/ttyS0:57600 [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-h help\n"
|
||||
"\t-l UDP listen for RTCM corrections\n"
|
||||
"\t-m network broadcast GPS data\n"
|
||||
"\t-o outfile output message log\n"
|
||||
"\t-r uri dgpsip://host or ntrip://user@pw:host/ rtcm:/dev/ttyS1\n"
|
||||
"\t-s port nmea:/dev/ttyS0:baud or sirf:/dev/ttyS0:baud\n"
|
||||
"\t-t uri OpenGTS server\n"
|
||||
"\t-w WDM DSRC listen for RTCM corrections\n"
|
||||
"\t-S service TCP service (default=gpsd)\n"
|
||||
"\tUse OSS gpsd, gpspipe and gpsfake to create and replay NMEA log files!\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
GpsDaemon Gps;
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
int dsrc_wsm = 0;
|
||||
int timeout = 15;
|
||||
|
||||
/* dgpsip server */
|
||||
char *host = NULL;
|
||||
|
||||
/* service/port */
|
||||
char *service = (char *)"gpsd";
|
||||
|
||||
/* serial port */
|
||||
char *primary = NULL;
|
||||
char *secondary = NULL;
|
||||
int baud = 4800;
|
||||
|
||||
/* logging */
|
||||
char *outfile = NULL;
|
||||
|
||||
/* udp broadcast */
|
||||
char *mcast = NULL;
|
||||
|
||||
/* udp listener */
|
||||
int listen = 0;
|
||||
|
||||
/* data */
|
||||
char szBuf[1600];
|
||||
bzero( szBuf, sizeof(szBuf) );
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "cdhi:jlm:o:r:s:t:S:T:v" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'c': // clock set
|
||||
Gps.SetClock();
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'l': // udp/wdm listen
|
||||
listen = 1;
|
||||
break;
|
||||
case 'm': // udp broadcast
|
||||
mcast = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 'r': // rtcm-sc104 host
|
||||
host = optarg;
|
||||
break;
|
||||
case 's': // serial device
|
||||
if ( !primary )
|
||||
primary = optarg;
|
||||
else
|
||||
secondary = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
timeout = atoi(optarg);
|
||||
if ( timeout == 0 )
|
||||
timeout = 30;
|
||||
break;
|
||||
case 'w': // DSRC WSM
|
||||
fprintf( stderr, "DSRC WSM support not available!\n" );
|
||||
listen = 1;
|
||||
dsrc_wsm = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// check options
|
||||
if ( !primary )
|
||||
{
|
||||
fprintf( stderr, "Must have a GPS device to communicate with!\n" );
|
||||
exit(1);
|
||||
}
|
||||
if ( mcast && listen )
|
||||
{
|
||||
fprintf( stderr, "Cannot do both UDP broadcast/multicast and listening!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// input
|
||||
if ( primary )
|
||||
{
|
||||
// open GPS device on serial port
|
||||
int serial = Gps.GpsOpen( primary, baud );
|
||||
|
||||
if ( serial < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open primary serial device: %s @ %d !\n", primary, baud );
|
||||
|
||||
if ( secondary )
|
||||
{
|
||||
serial = Gps.GpsOpen( secondary, baud ); // won't open till primary dies
|
||||
|
||||
if ( serial < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open secondary serial device: %s @ %d !\n", secondary, baud );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "No task specified: use -l, -i <logfile> or -s <dev>!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// corrections
|
||||
if ( host )
|
||||
{
|
||||
// RTCM server
|
||||
int remote = Gps.DgpsConnect( host );
|
||||
|
||||
if ( remote < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to rtcm-sc104 source host: %s\n", host );
|
||||
// exit(1);
|
||||
}
|
||||
Gps.SetTimeout( timeout * 1000000L );
|
||||
}
|
||||
else if ( listen )
|
||||
{
|
||||
if ( dsrc_wsm )
|
||||
{
|
||||
// listen on WSM control channel for DSRC MSG_RTCM_Corrections
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
if ( mcast )
|
||||
{
|
||||
int bcast = Gps.GpsBroadcast( mcast );
|
||||
|
||||
if ( bcast < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to create UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// logging
|
||||
if ( outfile )
|
||||
Gps.LogOpen( outfile );
|
||||
|
||||
// TCP listener
|
||||
if ( Gps.StartService( GPSD_NAME, NULL, service, debug ) >= 0 )
|
||||
{
|
||||
return Gps.RunService();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
1
daemons/include
Symbolic link
1
daemons/include
Symbolic link
@ -0,0 +1 @@
|
||||
../include
|
||||
1
daemons/lib
Symbolic link
1
daemons/lib
Symbolic link
@ -0,0 +1 @@
|
||||
../lib
|
||||
22
daemons/logd/CMakeLists.txt
Normal file
22
daemons/logd/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME logd)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libnet++ ../include)
|
||||
link_directories(../lib)
|
||||
link_libraries(net++ net pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
LogDaemon.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
139
daemons/logd/LogDaemon.cpp
Normal file
139
daemons/logd/LogDaemon.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// Log Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "UriParse.h"
|
||||
#include "LogDaemon.h"
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
LogDaemon::LogDaemon()
|
||||
{
|
||||
// logging
|
||||
log_open( LOGD_NAME );
|
||||
}
|
||||
|
||||
LogDaemon::~LogDaemon()
|
||||
{
|
||||
}
|
||||
|
||||
/* UDP ***********************************************************************/
|
||||
|
||||
int LogDaemon::ClientInOut( char *buf, int n, int max )
|
||||
{
|
||||
if ( n > 0 )
|
||||
{
|
||||
Dprintf( "%s\n", buf );
|
||||
Log.LogWrite( buf, n );
|
||||
}
|
||||
|
||||
// no response
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* log ***********************************************************************/
|
||||
|
||||
int LogDaemon::LogOpen( const char *uri )
|
||||
{
|
||||
if ( Log.LogOpen( uri ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int LogDaemon::LogPlayback( void )
|
||||
{
|
||||
timeval tv;
|
||||
tv.tv_sec = 0L;
|
||||
tv.tv_usec = 0L;
|
||||
|
||||
// read log input
|
||||
// send message
|
||||
// if ( strlen( logbuf ) )
|
||||
// ClientCast( logbuf, strlen(logbuf) );
|
||||
|
||||
// read next message
|
||||
if ( Log.LogRead( &tv, logbuf, sizeof(logbuf) ) > 0 )
|
||||
{
|
||||
// is this first one?
|
||||
if ( logcount == 0 )
|
||||
{
|
||||
// fudge it so it kicks off 10 seconds later
|
||||
loglast.tv_sec = tv.tv_sec - 10;
|
||||
loglast.tv_usec = tv.tv_usec;
|
||||
}
|
||||
logcount++;
|
||||
|
||||
// diff between this one and last
|
||||
if ( loglast.tv_usec > tv.tv_usec )
|
||||
{
|
||||
// carry
|
||||
tv.tv_sec--;
|
||||
tv.tv_usec += 1000000L;
|
||||
}
|
||||
timeval sv = tv;
|
||||
|
||||
// diff is timeout period
|
||||
tv.tv_sec = tv.tv_sec - loglast.tv_sec;
|
||||
tv.tv_usec = tv.tv_usec - loglast.tv_usec;
|
||||
|
||||
// mark last log record
|
||||
loglast = sv;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
// set next timeout
|
||||
SetTimeout( tv );
|
||||
return 1;
|
||||
}
|
||||
74
daemons/logd/LogDaemon.h
Normal file
74
daemons/logd/LogDaemon.h
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// Log Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __LogDaemon__
|
||||
#define __LogDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "UdpDaemon.h"
|
||||
#include "LogData.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
#define LOGD_NAME "logd"
|
||||
#define LOGD_SERVICE "logd"
|
||||
#ifndef LOGD_PORT
|
||||
#define LOGD_PORT "2940"
|
||||
#endif
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Listens to OBE HeartBeat messages
|
||||
//
|
||||
class LogDaemon : public UdpDaemon {
|
||||
// public data
|
||||
public:
|
||||
|
||||
// private data
|
||||
private:
|
||||
// Logging output
|
||||
LogData Log;
|
||||
|
||||
// log playback
|
||||
char logbuf[512];
|
||||
timeval loglast;
|
||||
unsigned int logcount;
|
||||
|
||||
// private methods
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
LogDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~LogDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ClientInOut( char *buf, int n, int max );
|
||||
|
||||
// public methods
|
||||
int LogOpen( const char *uri );
|
||||
int LogWrite( const char *log ) { return Log.LogWrite(log,strlen(log)); };
|
||||
void SetBinary(void) { Log.SetBinary(); };
|
||||
|
||||
int LogPlayback( void );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
145
daemons/logd/logd.cpp
Normal file
145
daemons/logd/logd.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
//
|
||||
// Serial Daemon (similar to ser2net)
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "LogDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// any port
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"logd [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-h help\n"
|
||||
"\t-i infile input log format:/path/to/file.log\n"
|
||||
"\t-o logfile output log format:/path/to/file.log\n"
|
||||
"\t-S service UDP service\n";
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
LogDaemon Log;
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
|
||||
/* connections */
|
||||
const char *file = NULL;
|
||||
const char *log = NULL;
|
||||
const char *service = LOGD_PORT;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "bdhi:o:S:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'b':
|
||||
Log.SetBinary();
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'i':
|
||||
file = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
log = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( log )
|
||||
{
|
||||
if ( Log.LogOpen( log ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open log file: %s!\n", log );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Must specify a MySQL connection: mysql://user:pass@host/database/table\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( file )
|
||||
{
|
||||
char buf[4096];
|
||||
int n = 0;
|
||||
|
||||
if ( strcmp( file, "-") == 0 )
|
||||
{
|
||||
while ( fgets(buf, sizeof(buf), stdin) )
|
||||
{
|
||||
Log.LogWrite( buf );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// import
|
||||
FILE *import = fopen( file, "r" );
|
||||
if ( import )
|
||||
{
|
||||
// read into database
|
||||
while ( fgets( buf, sizeof(buf), import ) )
|
||||
{
|
||||
// check for header?
|
||||
|
||||
Log.LogWrite( buf );
|
||||
n++;
|
||||
}
|
||||
printf( "Imported %d lines into log\n", n );
|
||||
log_printf( "Imported %d lines into log\n", n );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "Unable to import log data: %s\n", file );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// UDP listener
|
||||
if ( Log.StartService( LOGD_NAME, "0.0.0.0", service, debug ) >= 0 )
|
||||
return Log.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
22
daemons/rtcmd/CMakeLists.txt
Normal file
22
daemons/rtcmd/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME rtcmd)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libgps++ ../include/libnet++ ../include)
|
||||
link_directories(../lib)
|
||||
link_libraries(gps++ net++ net emb pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
RtcmDaemon.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
307
daemons/rtcmd/RtcmDaemon.cpp
Normal file
307
daemons/rtcmd/RtcmDaemon.cpp
Normal file
@ -0,0 +1,307 @@
|
||||
//
|
||||
// RTCM Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
//****************************************************************************
|
||||
// includes
|
||||
//***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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 );
|
||||
}
|
||||
94
daemons/rtcmd/RtcmDaemon.h
Normal file
94
daemons/rtcmd/RtcmDaemon.h
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// RTCM Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __RtcmDaemon__
|
||||
#define __RtcmDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "TcpDaemon.h"
|
||||
#include "UdpClient.h"
|
||||
#include "UdpCaster.h"
|
||||
#include "GpsDevice.h"
|
||||
#include "RtcmDevice.h"
|
||||
#include "DgpsClient.h"
|
||||
#include "NtripClient.h"
|
||||
#include "Logging.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
/* software details */
|
||||
#define RTCMD_NAME "rtcmd"
|
||||
#define RTCMD_VERSION "0.1"
|
||||
|
||||
/* default service and port */
|
||||
#define RTCMD_SERVICE "rtcm-sc104"
|
||||
#define RTCMD_PORT "2101"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Uses the Peak Systems CAN Linux driver and Nissan CAN data
|
||||
//
|
||||
class RtcmDaemon : public TcpDaemon, public Logging {
|
||||
// public data
|
||||
public:
|
||||
DgpsClient Dgps;
|
||||
NtripClient Ntrip;
|
||||
RtcmDevice Rtcm;
|
||||
|
||||
// private data
|
||||
private:
|
||||
char Uri[1024];
|
||||
|
||||
// FDs
|
||||
int DgpsIn;
|
||||
int SerialIn;
|
||||
int DgramIn;
|
||||
int NtripIn;
|
||||
|
||||
// UDP broadcast
|
||||
UdpCaster Bcast;
|
||||
|
||||
int nClients;
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
RtcmDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~RtcmDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ServerTimeout(void);
|
||||
int ServerSocket(void);
|
||||
int ClientIn( int sock, const char *buf, int n );
|
||||
void ClientCast( const char *buf, int n );
|
||||
int ClientUp( int sock );
|
||||
void ClientDown( int sock );
|
||||
|
||||
// public methods
|
||||
int RtcmOpen( const char *uri ); // serial device
|
||||
|
||||
int RtcmConnect( const char *uri );
|
||||
void RtcmDisconnect( void );
|
||||
void RtcmReconnect( void );
|
||||
int RtcmBroadcast( const char *host = NULL, const char *port = RTCMD_SERVICE );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
145
daemons/rtcmd/rtcmd.cpp
Normal file
145
daemons/rtcmd/rtcmd.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
//
|
||||
// RTCM Daemon (rtcmd.cpp)
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "RtcmDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// This was written because gpsd didn't have working RTCM104_SERVICE
|
||||
// or the ability to do UDP broadcasts.
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"rtcm -r dgpsip://host [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-h help\n"
|
||||
"\t-m network UDP broadcast RTCM data\n"
|
||||
"\t-r uri dgpsip://host or ntrip://user@pass:host:port/mount\n"
|
||||
"\t-t uri OpenGTS server\n"
|
||||
"\t-w WDM DSRC broadcast RTCM corrections\n"
|
||||
"\t-S service TCP service (default=2101)\n"
|
||||
"\t-T timeout reconnect timeout in seconds (default=15)\n";
|
||||
|
||||
static RtcmDaemon Rtcm;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
int dsrc_wsm = 0;
|
||||
int timeout = 15;
|
||||
|
||||
/* dgpsip server */
|
||||
char *host = NULL;
|
||||
|
||||
/* service/port */
|
||||
char *service = (char *)"2101"; // "rtcm-sc104"
|
||||
|
||||
/* udp broadcast */
|
||||
char *mcast = NULL;
|
||||
|
||||
/* log */
|
||||
char *outfile = NULL;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "dhm:o:r:s:t:S:T:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'm': // udp broadcast
|
||||
mcast = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
break;
|
||||
case 'r': // rtcm-sc104 host
|
||||
host = optarg;
|
||||
break;
|
||||
case 't':
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
timeout = atoi(optarg);
|
||||
if ( timeout == 0 )
|
||||
timeout = 30;
|
||||
break;
|
||||
case 'w': // DSRC WSM broadcast or listen
|
||||
fprintf( stderr, "DSRC WSM support not yet available!\n" );
|
||||
// dsrc_wsm = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// input
|
||||
if ( host )
|
||||
{
|
||||
Rtcm.SetTimeout( timeout * 1000000L );
|
||||
|
||||
// RTCM server
|
||||
int remote = Rtcm.RtcmConnect( host );
|
||||
|
||||
if ( remote < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to rtcm-sc104 source host: %s\n", host );
|
||||
if ( debug )
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
if ( mcast )
|
||||
{
|
||||
int bcast = Rtcm.RtcmBroadcast( mcast );
|
||||
|
||||
if ( bcast < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to create UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if ( dsrc_wsm )
|
||||
{
|
||||
}
|
||||
|
||||
if ( outfile )
|
||||
Rtcm.LogOpen( outfile, 0 );
|
||||
|
||||
// TCP listener
|
||||
if ( Rtcm.StartService( RTCMD_NAME, NULL, service, debug ) >= 0 )
|
||||
return Rtcm.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
7
daemons/rtcmd/test-mili.sh
Executable file
7
daemons/rtcmd/test-mili.sh
Executable file
@ -0,0 +1,7 @@
|
||||
!/bin/sh
|
||||
|
||||
rm /var/log/cnomicon/rtcmd.log
|
||||
|
||||
../../build/daemons/rtcmd/rtcmd -d -r ntrip://nprobert:p3x-mdotcors@148.149.0.87:10002/LIVONIA_RTCM2.3GPS
|
||||
|
||||
more /var/log/cnomicon/rtcmd.log
|
||||
1
daemons/sbin
Symbolic link
1
daemons/sbin
Symbolic link
@ -0,0 +1 @@
|
||||
../sbin
|
||||
22
daemons/seriald/CMakeLists.txt
Normal file
22
daemons/seriald/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME seriald)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libnet++ ../include)
|
||||
link_directories(../lib)
|
||||
link_libraries(net++ net pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
SerialDaemon.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
235
daemons/seriald/SerialDaemon.cpp
Normal file
235
daemons/seriald/SerialDaemon.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
//
|
||||
// Serial Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "UriParse.h"
|
||||
#include "SerialDaemon.h"
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
SerialDaemon::SerialDaemon()
|
||||
{
|
||||
// logging
|
||||
log_open( SERIALD_NAME );
|
||||
|
||||
m_SerialIn = m_RemoteIn = m_DgramIn = -1;
|
||||
|
||||
m_framed = 0;
|
||||
bzero(m_Framing,sizeof(m_Framing));
|
||||
}
|
||||
|
||||
SerialDaemon::~SerialDaemon()
|
||||
{
|
||||
if ( m_SerialIn >= 0 )
|
||||
close( m_SerialIn );
|
||||
}
|
||||
|
||||
/* TCP ***********************************************************************/
|
||||
|
||||
int SerialDaemon::ServerSocket(void)
|
||||
{
|
||||
char buf[2048];
|
||||
int n = 0;
|
||||
|
||||
if ( IsSet( m_RemoteIn ) )
|
||||
{
|
||||
// from server
|
||||
n = Client.Recv( buf, sizeof(buf) );
|
||||
|
||||
if ( n > 0 )
|
||||
{
|
||||
// send frame
|
||||
if ( m_framed )
|
||||
{
|
||||
m_Framing[m_framed-2] = n >> 8;
|
||||
m_Framing[m_framed-1] = n;
|
||||
write( m_SerialIn, m_Framing, m_framed );
|
||||
}
|
||||
|
||||
// send data
|
||||
write( m_SerialIn, buf, n );
|
||||
}
|
||||
}
|
||||
else if ( IsSet( m_SerialIn ) )
|
||||
{
|
||||
// data from device
|
||||
n = read( m_SerialIn, buf, sizeof(buf) );
|
||||
|
||||
// parse data
|
||||
|
||||
if ( n>0 )
|
||||
ClientCast( buf, n );
|
||||
}
|
||||
else if ( IsSet( m_DgramIn ) )
|
||||
{
|
||||
// packet from UDP broadcast
|
||||
n = Dgram.RecvFrom( buf, sizeof(buf) );
|
||||
|
||||
// send to device
|
||||
if ( n > 0 )
|
||||
{
|
||||
// send frame
|
||||
if ( m_framed )
|
||||
{
|
||||
m_Framing[m_framed-2] = n >> 8;
|
||||
m_Framing[m_framed-1] = n;
|
||||
write( m_SerialIn, m_Framing, m_framed );
|
||||
}
|
||||
|
||||
// send data
|
||||
write( m_SerialIn, buf, n );
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int SerialDaemon::ClientIn( int sock, const char *buf, int n )
|
||||
{
|
||||
return write( m_SerialIn, buf, n );
|
||||
}
|
||||
|
||||
void SerialDaemon::ClientCast( const char *buf, int n )
|
||||
{
|
||||
// broadcast it
|
||||
Bcast.SendTo( buf, n );
|
||||
|
||||
// send to clients
|
||||
TcpServer::ClientCast( buf, n );
|
||||
}
|
||||
|
||||
/* GPS ***********************************************************************/
|
||||
|
||||
int SerialDaemon::SerialOpen( const char *device, int baud )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setRate( baud );
|
||||
parsed.setUri( device );
|
||||
|
||||
int binary = 0;
|
||||
|
||||
// parse type
|
||||
if ( strlen( parsed.getProto() ) )
|
||||
{
|
||||
if ( strcasecmp( parsed.getProto(), "binary" ) == 0 )
|
||||
binary = 1;
|
||||
}
|
||||
|
||||
// open device
|
||||
m_SerialIn = serial_open( (char*)parsed.getPath(), parsed.getRate(), binary, binary?1:0 );
|
||||
|
||||
// check
|
||||
if ( m_SerialIn < 0 )
|
||||
return m_SerialIn;
|
||||
|
||||
// add listener
|
||||
AddFd( m_SerialIn );
|
||||
|
||||
return m_SerialIn;
|
||||
}
|
||||
|
||||
int SerialDaemon::TcpConnect( const char *uri )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setUri( uri );
|
||||
|
||||
const char *proto = parsed.getProto();
|
||||
|
||||
if ( strcasecmp( proto, "http" ) == 0 ||
|
||||
strcasecmp( proto, "https" ) == 0 )
|
||||
{
|
||||
// web site
|
||||
}
|
||||
else if ( strcasecmp( proto, "telnet" ) == 0 ||
|
||||
strlen( proto ) == 0 )
|
||||
{
|
||||
// straight TCP client
|
||||
m_RemoteIn = Client.Connect( parsed.getHost(), parsed.getService() );
|
||||
}
|
||||
|
||||
return m_RemoteIn;
|
||||
}
|
||||
|
||||
int SerialDaemon::UdpListen( const char *uri )
|
||||
{
|
||||
m_DgramIn = Dgram.ListenUri( uri );
|
||||
|
||||
if ( m_DgramIn > 0 )
|
||||
AddFd( m_DgramIn );
|
||||
|
||||
return m_DgramIn;
|
||||
}
|
||||
|
||||
int SerialDaemon::UdpBroadcast( const char *uri )
|
||||
{
|
||||
return Bcast.CasterUri( uri );
|
||||
}
|
||||
|
||||
void SerialDaemon::SetFrame( const char *frame, int n )
|
||||
{
|
||||
if ( n )
|
||||
{
|
||||
// string
|
||||
strncpy( m_Framing, frame, sizeof(m_Framing)-2 );
|
||||
m_framed = strlen(m_Framing)+2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hex
|
||||
unsigned long value = atol( frame );
|
||||
|
||||
m_framed = 6;
|
||||
m_Framing[0] = value >> 24;
|
||||
m_Framing[1] = value >> 16;
|
||||
m_Framing[2] = value >> 8;
|
||||
m_Framing[3] = value;
|
||||
}
|
||||
}
|
||||
92
daemons/seriald/SerialDaemon.h
Normal file
92
daemons/seriald/SerialDaemon.h
Normal file
@ -0,0 +1,92 @@
|
||||
//
|
||||
// Serial Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __SerialDaemon__
|
||||
#define __SerialDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#include "TcpDaemon.h"
|
||||
#include "TcpClient.h"
|
||||
#include "UdpClient.h"
|
||||
#include "UdpCaster.h"
|
||||
|
||||
#include "LogData.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
#define SERIALD_NAME "seriald"
|
||||
#define SERIALD_SERVICE "seriald"
|
||||
#define SERIALD_PORT "2942"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Uses the Peak Systems CAN Linux driver and Nissan CAN data
|
||||
//
|
||||
class SerialDaemon : public TcpDaemon {
|
||||
// public data
|
||||
public:
|
||||
|
||||
// private data
|
||||
private:
|
||||
// FDs
|
||||
int m_SerialIn;
|
||||
int m_RemoteIn;
|
||||
int m_DgramIn;
|
||||
|
||||
// TCP client
|
||||
TcpClient Client;
|
||||
|
||||
// UDP listen
|
||||
UdpClient Dgram;
|
||||
|
||||
// UDP broadcast
|
||||
UdpCaster Bcast;
|
||||
|
||||
// misc
|
||||
int m_framed;
|
||||
char m_Framing[8];
|
||||
|
||||
// private methods
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
SerialDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~SerialDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ServerSocket(void);
|
||||
int ClientIn( int sock, const char *buf, int n );
|
||||
void ClientCast( const char *buf, int n );
|
||||
|
||||
// public methods
|
||||
int SerialOpen( const char *dev, int baud );
|
||||
int TcpConnect( const char *uri );
|
||||
|
||||
int UdpBroadcast( const char *uri );
|
||||
int UdpListen( const char *uri );
|
||||
|
||||
void SetFrame( const char *frame, int n=0 );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
175
daemons/seriald/seriald.cpp
Normal file
175
daemons/seriald/seriald.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
//
|
||||
// Serial Daemon (similar to ser2net)
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "SerialDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// port 2748
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"seriald -s /dev/ttyS0:57600 [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-h help\n"
|
||||
"\t-l UDP listen for data\n"
|
||||
"\t-m network broadcast data\n"
|
||||
"\t-o outfile output message log\n"
|
||||
"\t-r uri http://host.domain.com/\n"
|
||||
"\t-s port /dev/ttyS0:baud\n"
|
||||
"\t-S service TCP service\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
SerialDaemon Ser;
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
|
||||
/* dgpsip server */
|
||||
char *host = NULL;
|
||||
|
||||
/* service/port */
|
||||
char *service = (char *)SERIALD_PORT;
|
||||
|
||||
/* serial port */
|
||||
char *primary = NULL;
|
||||
int baud = 57600;
|
||||
|
||||
/* udp broadcast */
|
||||
char *mcast = NULL;
|
||||
|
||||
/* udp listener */
|
||||
int listen = 0;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "df:hm:lr:s:S:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'f':
|
||||
Ser.SetFrame( optarg );
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'l': // udp/wdm listen
|
||||
listen = 1;
|
||||
break;
|
||||
case 'm': // udp broadcast
|
||||
mcast = optarg;
|
||||
break;
|
||||
case 'r': // remote host
|
||||
host = optarg;
|
||||
break;
|
||||
case 's': // serial device
|
||||
primary = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// check options
|
||||
if ( !primary )
|
||||
{
|
||||
fprintf( stderr, "Must have a serial device to communicate with!\n" );
|
||||
exit(1);
|
||||
}
|
||||
if ( mcast && listen )
|
||||
{
|
||||
fprintf( stderr, "Cannot do both UDP broadcast/multicast and listening!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// input
|
||||
if ( primary )
|
||||
{
|
||||
// open GPS device on serial port
|
||||
int serial = Ser.SerialOpen( primary, baud );
|
||||
|
||||
if ( serial < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open primary serial device: %s @ %d !\n", primary, baud );
|
||||
exit(1);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "No task specified: use -l or -s <dev>!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// corrections
|
||||
if ( host )
|
||||
{
|
||||
// RTCM server
|
||||
int remote = Ser.TcpConnect( host );
|
||||
|
||||
if ( remote < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to remote host: %s\n", host );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if ( listen )
|
||||
{
|
||||
// listen on UDP broadcasts for RTCM corrrections
|
||||
int dgram = Ser.UdpListen( NULL );
|
||||
|
||||
if ( dgram < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to listen on UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
if ( mcast )
|
||||
{
|
||||
int bcast = Ser.UdpBroadcast( mcast );
|
||||
|
||||
if ( bcast < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to create UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// TCP listener
|
||||
if ( Ser.StartService( SERIALD_NAME, NULL, service, debug ) >= 0 )
|
||||
return Ser.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
22
daemons/stdiod/CMakeLists.txt
Normal file
22
daemons/stdiod/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
set(NAME stdiod)
|
||||
project(Cnomicon-Daemon)
|
||||
set(TARGET ${NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ..)
|
||||
|
||||
# includes
|
||||
include_directories(
|
||||
/usr/include/libxml2
|
||||
../include/libnet++ ../include)
|
||||
link_directories(../lib)
|
||||
link_libraries(net++ net pthread rt)
|
||||
|
||||
# sources
|
||||
set(SRCS
|
||||
StdioDaemon.cpp
|
||||
)
|
||||
|
||||
# executables
|
||||
add_executable(${TARGET} ${TARGET}.cpp ${SRCS})
|
||||
|
||||
install(TARGETS ${TARGET} DESTINATION sbin)
|
||||
162
daemons/stdiod/StdioDaemon.cpp
Normal file
162
daemons/stdiod/StdioDaemon.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
//
|
||||
// Stdio Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "UriParse.h"
|
||||
#include "StdioDaemon.h"
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
StdioDaemon::StdioDaemon()
|
||||
{
|
||||
// logging
|
||||
log_open( STDIOD_NAME );
|
||||
|
||||
m_RemoteIn = m_DgramIn = -1;
|
||||
m_Stdin = 0;
|
||||
AddFd( m_Stdin );
|
||||
}
|
||||
|
||||
StdioDaemon::~StdioDaemon()
|
||||
{
|
||||
}
|
||||
|
||||
/* TCP ***********************************************************************/
|
||||
|
||||
int StdioDaemon::ServerSocket(void)
|
||||
{
|
||||
char buf[2048];
|
||||
int n = 0;
|
||||
|
||||
if ( IsSet( m_RemoteIn ) )
|
||||
{
|
||||
// from server (tbd)
|
||||
int n = Client.Recv( buf, sizeof(buf) );
|
||||
|
||||
if ( n > 0 )
|
||||
fputs( buf, stdout );
|
||||
}
|
||||
else if ( IsSet( m_Stdin ) )
|
||||
{
|
||||
// packet from GPS device
|
||||
while ( fgets( buf, sizeof(buf), stdin ) )
|
||||
{
|
||||
int n = strlen( buf );
|
||||
|
||||
if ( n>0 )
|
||||
ClientCast( buf, n );
|
||||
}
|
||||
}
|
||||
else if ( IsSet( m_DgramIn ) )
|
||||
{
|
||||
// RTCM packet from UDP broadcast (once a minute)
|
||||
int n = Dgram.RecvFrom( buf, sizeof(buf) );
|
||||
|
||||
// send to GPS device
|
||||
if ( n > 0 )
|
||||
fputs( buf, stdout );
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int StdioDaemon::ClientIn( int sock, const char *buf, int n )
|
||||
{
|
||||
return fputs( buf, stdout );
|
||||
}
|
||||
|
||||
void StdioDaemon::ClientCast( const char *buf, int n )
|
||||
{
|
||||
// broadcast it
|
||||
Bcast.SendTo( buf, n );
|
||||
|
||||
// send to clients
|
||||
TcpServer::ClientCast( buf, n );
|
||||
}
|
||||
|
||||
/* GPS ***********************************************************************/
|
||||
|
||||
int StdioDaemon::TcpConnect( const char *uri )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setUri( uri );
|
||||
|
||||
const char *proto = parsed.getProto();
|
||||
|
||||
if ( strcasecmp( proto, "http" ) == 0 ||
|
||||
strcasecmp( proto, "https" ) == 0 )
|
||||
{
|
||||
// web site
|
||||
}
|
||||
else if ( strcasecmp( proto, "telnet" ) == 0 ||
|
||||
strlen( proto ) == 0 )
|
||||
{
|
||||
// straight TCP client
|
||||
m_RemoteIn = Client.Connect( parsed.getHost(), parsed.getService() );
|
||||
}
|
||||
|
||||
return m_RemoteIn;
|
||||
}
|
||||
|
||||
int StdioDaemon::UdpListen( const char *uri )
|
||||
{
|
||||
m_DgramIn = Dgram.ListenUri( uri );
|
||||
|
||||
if ( m_DgramIn > 0 )
|
||||
AddFd( m_DgramIn );
|
||||
|
||||
return m_DgramIn;
|
||||
}
|
||||
|
||||
int StdioDaemon::UdpBroadcast( const char *uri )
|
||||
{
|
||||
return Bcast.CasterUri( uri );
|
||||
}
|
||||
87
daemons/stdiod/StdioDaemon.h
Normal file
87
daemons/stdiod/StdioDaemon.h
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// Stdio Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __StdioDaemon__
|
||||
#define __StdioDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#include "TcpDaemon.h"
|
||||
#include "TcpClient.h"
|
||||
#include "UdpClient.h"
|
||||
#include "UdpCaster.h"
|
||||
|
||||
#include "LogData.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
#define STDIOD_NAME "stdiod"
|
||||
#define STDIOD_SERVICE "stdiod"
|
||||
#define STDIOD_PORT "2941"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Uses the Peak Systems CAN Linux driver and Nissan CAN data
|
||||
//
|
||||
class StdioDaemon : public TcpDaemon {
|
||||
// public data
|
||||
public:
|
||||
|
||||
// private data
|
||||
private:
|
||||
// FDs
|
||||
int m_Stdin;
|
||||
int m_RemoteIn;
|
||||
int m_DgramIn;
|
||||
|
||||
// TCP client
|
||||
TcpClient Client;
|
||||
|
||||
// UDP listen
|
||||
UdpClient Dgram;
|
||||
|
||||
// UDP broadcast
|
||||
UdpCaster Bcast;
|
||||
|
||||
// misc
|
||||
|
||||
// private methods
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
StdioDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~StdioDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ServerSocket(void);
|
||||
int ClientIn( int sock, const char *buf, int n );
|
||||
void ClientCast( const char *buf, int n );
|
||||
|
||||
// public methods
|
||||
int TcpConnect( const char *uri );
|
||||
|
||||
int UdpBroadcast( const char *uri );
|
||||
int UdpListen( const char *uri );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
140
daemons/stdiod/stdiod.cpp
Normal file
140
daemons/stdiod/stdiod.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// Stdio Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "StdioDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// any port
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"stdiod [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-h help\n"
|
||||
"\t-l UDP listen for data\n"
|
||||
"\t-m network broadcast data\n"
|
||||
"\t-S service TCP service\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
StdioDaemon Std;
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
|
||||
/* dgpsip server */
|
||||
char *host = NULL;
|
||||
|
||||
/* udp broadcast */
|
||||
char *mcast = NULL;
|
||||
|
||||
/* udp listener */
|
||||
char *listen = NULL;
|
||||
|
||||
/* server */
|
||||
char *service = (char *)STDIOD_PORT;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "dhm:l:r:S:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'l': // udp listen
|
||||
listen = optarg;
|
||||
break;
|
||||
case 'm': // udp broadcast
|
||||
mcast = optarg;
|
||||
break;
|
||||
case 'r': // remote host
|
||||
host = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// check options
|
||||
if ( mcast && listen )
|
||||
{
|
||||
fprintf( stderr, "Cannot do both UDP broadcast/multicast and listening!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// input
|
||||
|
||||
// corrections
|
||||
if ( host )
|
||||
{
|
||||
// RTCM server
|
||||
int remote = Std.TcpConnect( host );
|
||||
|
||||
if ( remote < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to remote host: %s\n", host );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if ( listen )
|
||||
{
|
||||
// listen on UDP broadcasts for RTCM corrrections
|
||||
int dgram = Std.UdpListen( listen );
|
||||
|
||||
if ( dgram < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to listen on UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
if ( mcast )
|
||||
{
|
||||
int bcast = Std.UdpBroadcast( mcast );
|
||||
|
||||
if ( bcast < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to create UDP broadcast!\n" );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// TCP listener
|
||||
if ( Std.StartService( STDIOD_NAME, NULL, service, debug ) >= 0 )
|
||||
return Std.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
194
daemons/trackd/TrackDaemon.cpp
Normal file
194
daemons/trackd/TrackDaemon.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
//
|
||||
// Track Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "NmeaParser.h"
|
||||
#include "UriParse.h"
|
||||
#include "TrackDaemon.h"
|
||||
#include "netlib.h"
|
||||
|
||||
//****************************************************************************
|
||||
// defines
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// macros
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// structs & typedefs
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// global variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static constants
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static variables
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// static functions
|
||||
//***************************************************************************/
|
||||
|
||||
//****************************************************************************
|
||||
// C++ functions
|
||||
//***************************************************************************/
|
||||
|
||||
TrackDaemon::TrackDaemon()
|
||||
{
|
||||
log_open( TRACKD_NAME );
|
||||
|
||||
gethostname( Id, sizeof(Id) );
|
||||
}
|
||||
|
||||
TrackDaemon::~TrackDaemon()
|
||||
{
|
||||
}
|
||||
|
||||
/* UDP ***********************************************************************/
|
||||
|
||||
void TrackDaemon::PositionListener( const PositionFix &Pos, const ErrorInfo &Err )
|
||||
{
|
||||
char buf[256];
|
||||
int n = 0;
|
||||
char datetime[40];
|
||||
|
||||
// convert date & time (MySQL friendly)
|
||||
struct tm *tmp = gmtime(&Pos.Time.tv_sec);
|
||||
strftime( datetime, sizeof(datetime), "%Y-%m-%d,%T", tmp );
|
||||
|
||||
// convert to unicsv
|
||||
n = snprintf( buf, sizeof(buf),
|
||||
"%s,%s,%lf,%lf,%lf,%lf,%lf\n",
|
||||
Id, // name
|
||||
datetime, // time
|
||||
Pos.Latitude, // lat
|
||||
Pos.Longitude, // long
|
||||
Pos.Altitude, // elev
|
||||
Pos.Speed, // speed (m/sec -> kph)
|
||||
Pos.Heading // heading
|
||||
);
|
||||
|
||||
// send upstream
|
||||
if ( TrackOut >= 0 )
|
||||
Track.SendTo( buf, n );
|
||||
|
||||
// log locally
|
||||
Log.LogWrite( buf, n );
|
||||
}
|
||||
|
||||
void TrackDaemon::TimeListener( const struct timeval &tv )
|
||||
{
|
||||
}
|
||||
|
||||
int TrackDaemon::ServerSocket(void)
|
||||
{
|
||||
char buf[2048];
|
||||
int n = 0;
|
||||
|
||||
if ( IsSet( GpsIn ) )
|
||||
{
|
||||
// Gpsd
|
||||
if ( (n = Gpsd.Recv( buf, sizeof(buf) )) > 0 )
|
||||
{
|
||||
// use NMEA parser (should trigger on RMC or GGA)
|
||||
Gps.Nmea.NmeaParse(buf);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int TrackDaemon::ClientInOut( char *buf, int n, int max )
|
||||
{
|
||||
// check
|
||||
if ( n <= 0 )
|
||||
return 0;
|
||||
|
||||
// parse $PVII
|
||||
if ( buf[0] == '$' )
|
||||
{
|
||||
// use NMEA parser (should trigger on RMC or GGA)
|
||||
Gps.Nmea.NmeaParse( buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward
|
||||
if ( TrackOut >= 0 )
|
||||
Track.SendTo( buf, n );
|
||||
|
||||
// log
|
||||
Log.LogWrite( buf , n );
|
||||
}
|
||||
|
||||
// no response
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* GPS ***********************************************************************/
|
||||
|
||||
int TrackDaemon::GpsdServer( const char *uri )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setProto( "gpsd" );
|
||||
parsed.setService( "gpsd" );
|
||||
parsed.setUri( uri );
|
||||
bGpsd = 0;
|
||||
|
||||
const char *proto = parsed.getProto();
|
||||
if ( !strlen(proto) )
|
||||
proto = "gpsd";
|
||||
GpsDeviceType type = Gps.Proto2Type( proto );
|
||||
|
||||
// open device
|
||||
if ( strcmp( proto, "gpsd" ) == 0 || type == GPS_TYPE_UNDEF )
|
||||
GpsIn = Gpsd.GpsdConnect( parsed.getHost() );
|
||||
else
|
||||
GpsIn = Gps.GpsOpen( parsed.getPath(), parsed.getRate(), type );
|
||||
|
||||
if ( GpsIn >= 0 )
|
||||
AddFd( GpsIn );
|
||||
return GpsIn;
|
||||
}
|
||||
|
||||
int TrackDaemon::TrackOpen( const char *uri )
|
||||
{
|
||||
UriParse parsed;
|
||||
parsed.setService( TRACKD_PORT );
|
||||
parsed.setUri( uri );
|
||||
|
||||
// connect to remote web server to upload data
|
||||
return TrackOut = Track.Connect( parsed.getHost(), TRACKD_PORT );
|
||||
}
|
||||
|
||||
int TrackDaemon::LogOpen( const char *uri )
|
||||
{
|
||||
if ( Log.LogOpen( uri ) )
|
||||
{
|
||||
Log.LogFields( "name,date,time,lat,long,ele,speed,head" );
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
89
daemons/trackd/TrackDaemon.h
Normal file
89
daemons/trackd/TrackDaemon.h
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// Track Daemon
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
/* prevent multiple inclusions */
|
||||
#ifndef __TrackDaemon__
|
||||
#define __TrackDaemon__
|
||||
|
||||
/* includes *****************************************************************/
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
#include "UdpDaemon.h"
|
||||
#include "TcpClient.h"
|
||||
#include "UdpClient.h"
|
||||
#include "Logging.h"
|
||||
|
||||
#include "GpsdClient.h"
|
||||
#include "GpsDevice.h"
|
||||
|
||||
/* defines ******************************************************************/
|
||||
|
||||
#define TRACKD_NAME "trackd"
|
||||
#define TRACKD_SERVICE "trackd"
|
||||
#define TRACKD_PORT "2948"
|
||||
|
||||
/* macros *******************************************************************/
|
||||
|
||||
/* structs & typedefs *******************************************************/
|
||||
|
||||
/* c class definitions ******************************************************/
|
||||
|
||||
//
|
||||
// Listens to OBE HeartBeat messages
|
||||
//
|
||||
class TrackDaemon : public UdpDaemon, public GpsListener, public Logging {
|
||||
// public data
|
||||
public:
|
||||
|
||||
// private data
|
||||
private:
|
||||
// my name
|
||||
char Id[32];
|
||||
|
||||
// Gpsd client
|
||||
GpsdClient Gpsd; // direct from GPSd
|
||||
GpsDevice Gps; // or from serial port
|
||||
bool bGpsd; // true for Gpsd
|
||||
int GpsIn; // Gpsd or Gps
|
||||
|
||||
// upstream trackd
|
||||
UdpClient Track; // listener
|
||||
int TrackOut;
|
||||
|
||||
// NMEA parsing
|
||||
|
||||
// private methods
|
||||
|
||||
// static data
|
||||
|
||||
// public methods
|
||||
public:
|
||||
// constructors
|
||||
TrackDaemon();
|
||||
|
||||
// destructor
|
||||
virtual ~TrackDaemon();
|
||||
|
||||
// virtual functions
|
||||
int ServerSocket(void);
|
||||
int ClientInOut( char *buf, int n, int max );
|
||||
|
||||
// public methods
|
||||
int GpsdServer( const char *uri );
|
||||
void PositionListener( const PositionFix &Pos, const ErrorInfo &Err );
|
||||
void TimeListener( const struct timeval &Time );
|
||||
|
||||
void SetId( const char *id ) { strncpy(Id,id,sizeof(Id)-1); };
|
||||
int TrackOpen( const char *uri );
|
||||
int LogOpen( const char *uri );
|
||||
|
||||
// static methods
|
||||
|
||||
// private methods
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
132
daemons/trackd/trackd.cpp
Normal file
132
daemons/trackd/trackd.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
//
|
||||
// Serial Daemon (similar to ser2net)
|
||||
// Neal Probert
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "TrackDaemon.h"
|
||||
|
||||
#include "netlib.h"
|
||||
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
//
|
||||
// any port
|
||||
//
|
||||
|
||||
static const char *helptext =
|
||||
"stdiod [options]\n"
|
||||
"\t-d debug (foreground with stdio)\n"
|
||||
"\t-g host gpsd\n"
|
||||
"\t-h help\n"
|
||||
"\t-i id set my id\n"
|
||||
"\t-c uri host:port source data (CardiacMonitor)\n"
|
||||
"\t-o logfile format:/path/to/file.log\n"
|
||||
"\t-r uri remote web host for upload\n"
|
||||
"\t-S service TCP service\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c; /* we have character */
|
||||
|
||||
TrackDaemon Track;
|
||||
|
||||
/* options */
|
||||
int debug = 0; // run in foreground, leaves stdio open
|
||||
|
||||
/* connections */
|
||||
char *gpsd = NULL; // "localhost";
|
||||
char *host = NULL;
|
||||
char *id = NULL;
|
||||
char *log = NULL;
|
||||
char *service = TRACKD_PORT;
|
||||
|
||||
// add command line args
|
||||
while ( (c = getopt( argc, argv, "dg:hi:o:r:S:" )) > 0 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'g':
|
||||
gpsd = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
puts( helptext );
|
||||
return 0;
|
||||
case 'i':
|
||||
id = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
log = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
service = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown option -%c\n", c );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// set my id (hostname by default)
|
||||
if ( id )
|
||||
Track.SetId( id );
|
||||
|
||||
// monitor
|
||||
if ( gpsd )
|
||||
{
|
||||
// GPSd
|
||||
int remote = Track.GpsdServer( gpsd );
|
||||
|
||||
if ( remote < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to connect to gpsd: %s\n", gpsd );
|
||||
// exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
if ( host )
|
||||
{
|
||||
if ( Track.TrackOpen( host ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "Unable to open vehicle location server: %s!\n", host );
|
||||
// exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( log )
|
||||
{
|
||||
if ( !Track.LogOpen( log ) )
|
||||
{
|
||||
fprintf( stderr, "Unable to open log file: %s!\n", log );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// TCP listener
|
||||
if ( Track.StartService( TRACKD_NAME, NULL, service, debug ) >= 0 )
|
||||
return Track.RunService();
|
||||
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user