205 lines
4.9 KiB
C++
205 lines
4.9 KiB
C++
//
|
|
// 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;
|
|
}
|