// // CAN Daemon (cand.cpp) // // Neal Probert // // IPv4 for now, since clients will be localhost anyways // IPv6 for testing // #include #include #include #include #include #include #include #include #include #include #include #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; }