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