Initial commit of files
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user