8 * Copyright (c) 2008 Oliver Hartkopp
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the version 2 of the GNU General Public License
12 * as published by the Free Software Foundation
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Send feedback to <socketcan-users@lists.berlios.de>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/ioctl.h>
40 #include <linux/can.h>
41 #include <linux/can/bcm.h>
43 #define DEFAULT_IFACE "vcan0"
44 #define DEFAULT_CANID 0x42
46 void print_usage(char *prg)
48 fprintf(stderr, "\nUsage: %s [options]\n", prg);
49 fprintf(stderr, "Options: -i <interface> (CAN interface. Default: '%s')\n", DEFAULT_IFACE);
50 fprintf(stderr, " -c <can_id> (used CAN ID. Default: 0x%03X)\n", DEFAULT_CANID);
51 fprintf(stderr, " -o <timeout> (Timeout value in nsecs. Default: 0)\n");
52 fprintf(stderr, " -t <throttle> (Throttle value in nsecs. Default: 0)\n");
53 fprintf(stderr, " -q <msgs> (Quit after receiption of #msgs)\n");
54 fprintf(stderr, " -s (set STARTTIMER flag. Default: off)\n");
55 fprintf(stderr, "\n");
58 int main(int argc, char **argv)
61 struct sockaddr_can addr;
65 char *ifname = DEFAULT_IFACE;
66 canid_t canid = DEFAULT_CANID;
69 unsigned long starttimer = 0;
70 unsigned long long timeout = 0;
71 unsigned long long throttle = 0;
72 unsigned long msgs = 0;
74 struct bcm_msg_head msg_head;
75 struct can_frame frame;
78 while ((opt = getopt(argc, argv, "i:c:o:t:q:s")) != -1) {
86 canid = strtoul(optarg, (char **)NULL, 16);
90 timeout = strtoull(optarg, (char **)NULL, 10);
94 throttle = strtoull(optarg, (char **)NULL, 10);
98 msgs = strtoul(optarg, (char **)NULL, 10);
102 starttimer = STARTTIMER;
107 print_usage(basename(argv[0]));
114 if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) {
119 if (strcmp(ifname, "any") == 0)
120 addr.can_ifindex = 0;
122 strcpy(ifr.ifr_name, ifname);
123 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
124 perror("SIOCGIFINDEX");
127 addr.can_ifindex = ifr.ifr_ifindex;
130 addr.can_family = PF_CAN;
132 if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
137 msg.msg_head.opcode = RX_SETUP;
138 msg.msg_head.can_id = canid;
139 msg.msg_head.flags = SETTIMER|RX_FILTER_ID|starttimer;
140 msg.msg_head.ival1.tv_sec = timeout / 1000000;
141 msg.msg_head.ival1.tv_usec = timeout % 1000000;
142 msg.msg_head.ival2.tv_sec = throttle / 1000000;
143 msg.msg_head.ival2.tv_usec = throttle % 1000000;
144 msg.msg_head.nframes = 0;
146 gettimeofday(&tv, NULL);
147 printf("[%ld.%06ld] ", tv.tv_sec, tv.tv_usec);
148 printf("Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n",
149 msg.msg_head.can_id);
151 if (write(s, &msg, sizeof(msg)) < 0)
156 nbytes = read(s, &msg, sizeof(msg));
161 gettimeofday(&tv, NULL);
162 printf("[%ld.%06ld] ", tv.tv_sec, tv.tv_usec);
164 if (nbytes == sizeof(msg)) {
166 if (ioctl(s, SIOCGSTAMP, &tv) < 0)
167 perror("SIOCGSTAMP");
169 printf("(%ld.%06ld) ", tv.tv_sec, tv.tv_usec);
171 if (msg.msg_head.opcode != RX_CHANGED) {
172 printf("missing RX_CHANGED.\n");
176 printf("RX_CHANGED ");
178 for (i=0; i < msg.frame.can_dlc; i++)
179 printf("%02X ", msg.frame.data[i]);
183 if (msg.msg_head.opcode != RX_TIMEOUT) {
184 printf("missing RX_TIMEOUT.\n");
188 printf("RX_TIMEOUT");
194 if (msgs && !(--msgs))