Structured comments updated.
[lincan.git] / lincan / utils / readburst.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <signal.h>
6 #include <getopt.h>
7 #include <fcntl.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/time.h>
11 #include <sys/ioctl.h>
12
13 #include "../include/can.h"
14
15 int fd;
16
17 struct canfilt_t canfilt = {
18         .flags = 0,
19         .queid = 0,
20         .cob = 0,
21         .id = 0,
22         .mask = 0
23 };
24
25 int canfilt_fl;
26
27 int query_fl;
28
29 int can_wait_sec = 5;
30
31 char *can_dev_name = "/dev/can0";
32
33 #define PRT_PREFIX_SIZE 40
34 char prt_prefix[PRT_PREFIX_SIZE];
35
36 char *prt_prefix_in = "CAN %s : ";
37
38 int can_fd_wait(int fd, int wait_sec)
39 {
40         int ret;
41         struct timeval timeout;
42         fd_set set;
43
44         FD_ZERO (&set);
45         FD_SET (fd, &set);
46         timeout.tv_sec = wait_sec;
47         timeout.tv_usec = 0;
48         while ((ret=select(FD_SETSIZE,&set, NULL, NULL,&timeout))==-1
49           &&errno==-EINTR);
50         return ret;
51 }
52
53
54 /*--- handler on SIGINT signal : the program quit with CTL-C ---*/
55 void sortie(int sig)
56 {
57         close(fd);
58         printf("Terminated by user\n");
59         exit(0);
60 }
61
62 static void
63 usage(void)
64 {
65   printf("usage: readburst\n");
66   printf("  -d, --device  <name>     name of CAN device [/dev/can0]\n");
67   printf("  -m, --mask  <num>        CAN filter mask\n");
68   printf("  -i, --id  <num>          CAN filter message ID\n");
69   printf("  -f, --flags <num>        CAN filter flags\n");
70   printf("  -w, --wait <num>         number of seconds to wait in select call\n");
71   printf("  -p, --prefix <str>       string prefix for output\n");
72   printf("  -q, --query              query driver features\n");
73   printf("  -V, --version            show version\n");
74   printf("  -h, --help               this usage screen\n");
75 }
76
77
78 int main(int argc, char *argv[])
79 {
80         static struct option long_opts[] = {
81                 { "uldev", 1, 0, 'd' },
82                 { "mask",  1, 0, 'm' },
83                 { "id",    1, 0, 'i' },
84                 { "flags", 1, 0, 'f' },
85                 { "wait",  1, 0, 'w' },
86                 { "prefix",1, 0, 'p' },
87                 { "query" ,0 ,0, 'q' },
88                 { "version",0,0, 'V' },
89                 { "help",  0, 0, 'h' },
90                 { 0, 0, 0, 0}
91         };
92         int opt;
93
94         int n,ret;
95         unsigned long i=0;
96        #ifdef CAN_MSG_VERSION_2
97         struct canmsg_t readmsg={0,0,5,{0,0},0,{0,}};
98        #else /* CAN_MSG_VERSION_2 */
99         struct canmsg_t readmsg={0,0,5,0,0,{0,}};
100        #endif /* CAN_MSG_VERSION_2 */
101         struct sigaction act;
102
103
104         while ((opt = getopt_long(argc, argv, "d:m:i:f:w:p:qVh",
105                             &long_opts[0], NULL)) != EOF) switch (opt) {
106                 case 'd':
107                         can_dev_name=optarg;
108                         break;
109                 case 'm':
110                         canfilt_fl=1;
111                         canfilt.mask = strtol(optarg,NULL,0);
112                         break;
113                 case 'i':
114                         canfilt_fl=1;
115                         canfilt.id = strtol(optarg,NULL,0);
116                         break;
117                 case 'f':
118                         canfilt_fl=1;
119                         canfilt.flags = strtol(optarg,NULL,0);
120                         break;
121                 case 'w':
122                         can_wait_sec = strtol(optarg,NULL,0);
123                         break;
124                 case 'p':
125                         prt_prefix_in = optarg;
126                         break;
127                 case 'q':
128                         query_fl=1;
129                         break;
130                 case 'V':
131                         fputs("LinCAN utilities v0.2\n", stdout);
132                         exit(0);
133                 case 'h':
134                 default:
135                         usage();
136                         exit(opt == 'h' ? 0 : 1);
137         }
138
139
140         /*------- register handler on SIGINT signal -------*/
141         act.sa_handler=sortie;
142         sigemptyset(&act.sa_mask);
143         act.sa_flags=0;
144         sigaction(SIGINT,&act,0);
145         /*---------------------------------------*/     
146
147         if ((fd=open(can_dev_name, O_RDWR)) < 0) {
148                 perror("open");
149                 printf("Error opening %s\n", can_dev_name);
150                 exit(1);        
151         }
152         
153         if (query_fl) {
154                 n=ioctl(fd, CAN_DRV_QUERY, CAN_DRV_QRY_BRANCH);
155                 printf("CAN driver branch:  %c%c%c%c\n",(n>>24)&0xff,(n>>16)&0xff,(n>>8)&0xff,n&0xff);
156                 n=ioctl(fd, CAN_DRV_QUERY, CAN_DRV_QRY_VERSION);
157                 printf("CAN driver version: %d.%d.%d\n",(n>>16)&0xff,(n>>8)&0xff,n&0xff);
158                 n=ioctl(fd, CAN_DRV_QUERY, CAN_DRV_QRY_MSGFORMAT);
159                 printf("CAN message format: %08x\n",n);
160                 close(fd);
161                 return 0;
162         }
163
164         if (canfilt_fl) {
165                 ret = ioctl(fd, CANQUE_FILTER, &canfilt);
166                 if(ret<0) {
167                         perror("ioctl FILTER_QUE");
168                 }
169         }
170
171         snprintf(prt_prefix, PRT_PREFIX_SIZE, prt_prefix_in, can_dev_name);
172         
173         while (1) {
174                 readmsg.flags=0;
175                 readmsg.cob=0;
176             #if 1
177                 ret=can_fd_wait(fd, can_wait_sec);
178                 printf("%scan_fd_wait returned %d\n", prt_prefix, ret);
179             #endif
180                 ret=read(fd,&readmsg,sizeof(struct canmsg_t));
181                 if(ret <0) {
182                         printf("%sError reading message\n", prt_prefix);
183                 }
184                 else if(ret == 0) {
185                         printf("%sNo message arrived\n", prt_prefix);
186                 } else {
187                         printf("%sRx msg #%lu: id=%lX dlc=%u flg=0x%02x",
188                                 prt_prefix,i,readmsg.id,readmsg.length,readmsg.flags);
189                         for(n=0 ; n<readmsg.length ; n++)
190                                 printf(" %.2X",(unsigned char)readmsg.data[n]);
191                         printf("\n");
192                         i++;
193                 }
194         }
195         return 0;
196 }