Initial commit of files

This commit is contained in:
2021-01-22 10:16:20 -05:00
parent 32d165ec8f
commit ed92211680
534 changed files with 68563 additions and 19 deletions

View 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
View 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
View 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

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

File diff suppressed because one or more lines are too long

139
daemons/cand/bsmpbeat.xml Normal file
View 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
View 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
View File

@ -0,0 +1,3 @@
#!/bin/sh
./cand -c can0 -d -m bsmpbeat.xml

3
daemons/cand/debug.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
./cand -d -f udp://192.168.1.10:2736 -m bsmpbeat.xml