Files
Cnomicon/daemons/cand/cand.cpp
2021-01-22 10:16:20 -05:00

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