#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <getopt.h>
#include <sys/mman.h>
#include <rtdm/can.h>
static void print_usage(char *prg)
{
fprintf(stderr,
"Usage: %s <can-interface> [Options] [up|down|start|stop|sleep]\n"
"Options:\n"
" -v, --verbose be verbose\n"
" -h, --help this help\n"
" -c, --ctrlmode=CTRLMODE listenonly, loopback or none\n"
" -b, --baudrate=BPS baudrate in bits/sec\n"
" -B, --bittime=BTR0:BTR1 BTR or standard bit-time\n"
" -B, --bittime=BRP:PROP_SEG:PHASE_SEG1:PHASE_SEG2:SJW:SAM\n",
prg);
}
{
if (sscanf(str, "%i", &baudrate) != 1)
return -1;
return baudrate;
}
static int string_to_mode(char *str)
{
if ( !strcmp(str, "up") || !strcmp(str, "start") )
else if ( !strcmp(str, "down") || !strcmp(str, "stop") )
else if ( !strcmp(str, "sleep") )
return -EINVAL;
}
static int string_to_ctrlmode(char *str)
{
if ( !strcmp(str, "listenonly") )
else if ( !strcmp(str, "loopback") )
else if ( !strcmp(str, "none") )
return 0;
return -1;
}
int main(int argc, char *argv[])
{
char ifname[16];
int can_fd = -1;
int new_baudrate = -1;
int new_mode = -1;
int new_ctrlmode = 0, set_ctrlmode = 0;
int verbose = 0;
int bittime_count = 0, bittime_data[6];
int opt, ret;
char* ptr;
struct option long_options[] = {
{ "help", no_argument, 0, 'h' },
{ "verbose", no_argument, 0, 'v'},
{ "baudrate", required_argument, 0, 'b'},
{ "bittime", required_argument, 0, 'B'},
{ "ctrlmode", required_argument, 0, 'c'},
{ 0, 0, 0, 0},
};
while ((opt = getopt_long(argc, argv, "hvb:B:c:",
long_options, NULL)) != -1) {
switch (opt) {
case 'h':
print_usage(argv[0]);
exit(0);
case 'v':
verbose = 1;
break;
case 'b':
new_baudrate = string_to_baudrate(optarg);
if (new_baudrate == -1) {
print_usage(argv[0]);
exit(0);
}
break;
case 'B':
ptr = optarg;
while (1) {
bittime_data[bittime_count++] = strtoul(ptr, NULL, 0);
if (!(ptr = strchr(ptr, ':')))
break;
ptr++;
}
if (bittime_count != 2 && bittime_count != 6) {
print_usage(argv[0]);
exit(0);
}
break;
case 'c':
ret = string_to_ctrlmode(optarg);
if (ret == -1) {
print_usage(argv[0]);
exit(0);
}
new_ctrlmode |= ret;
set_ctrlmode = 1;
break;
break;
default:
fprintf(stderr, "Unknown option %c\n", opt);
break;
}
}
if (optind != argc - 1 && optind != argc - 2) {
print_usage(argv[0]);
return 0;
}
strncpy(ifname, argv[optind], IFNAMSIZ);
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (optind == argc - 2) {
new_mode = string_to_mode(argv[optind + 1]);
if (verbose)
printf("mode: %s (%#x)\n", argv[optind + 1], new_mode);
if (new_mode < 0) {
print_usage(argv[0]);
return 0;
}
}
if (can_fd < 0) {
fprintf(stderr, "Cannot open RTDM CAN socket. Maybe driver not loaded? \n");
return can_fd;
}
if (ret) {
fprintf(stderr,"Can't get interface index for %s, errno = %d\n", ifname, errno);
return ret;
}
if (new_baudrate != -1) {
if (verbose)
printf("baudrate: %d\n", new_baudrate);
ifr.
ifr_ifru.
baudrate = new_baudrate;
if (ret) {
goto abort;
}
}
if (bittime_count) {
bittime = &ifr.ifr_ifru.
bittime;
if (bittime_count == 2) {
bittime->
btr.
btr0 = bittime_data[0];
bittime->
btr.
btr1 = bittime_data[1];
if (verbose)
printf("bit-time: btr0=0x%02x btr1=0x%02x\n",
} else {
bittime->
std.
brp = bittime_data[0];
bittime->
std.
sjw = bittime_data[4];
bittime->
std.
sam = bittime_data[5];
if (verbose)
printf("bit-time: brp=%d prop_seg=%d phase_seg1=%d "
"phase_seg2=%d sjw=%d sam=%d\n",
}
if (ret) {
goto abort;
}
}
if (set_ctrlmode != 0) {
ifr.ifr_ifru.
ctrlmode = new_ctrlmode;
if (verbose)
printf("ctrlmode: %#x\n", new_ctrlmode);
if (ret) {
goto abort;
}
}
if (new_mode != -1) {
ifr.ifr_ifru.
mode = new_mode;
if (ret) {
goto abort;
}
}
close(can_fd);
return 0;
abort:
close(can_fd);
return ret;
}