]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - test/tst-bcm-filter.c
added CAN error frame support.
[socketcan-devel.git] / test / tst-bcm-filter.c
1 /*
2  *  $Id$
3  */
4
5 /*
6  * tst-bcm-filter.c
7  *
8  * Copyright (c) 2002-2005 Volkswagen Group Electronic Research
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, the following disclaimer and
16  *    the referenced file 'COPYING'.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of Volkswagen nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * Alternatively, provided that this notice is retained in full, this
25  * software may be distributed under the terms of the GNU General
26  * Public License ("GPL") version 2 as distributed in the 'COPYING'
27  * file from the main directory of the linux kernel source.
28  *
29  * The provided data structures and external interfaces from this code
30  * are not restricted to be used by modules with a GPL compatible license.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
43  * DAMAGE.
44  *
45  * Send feedback to <llcf@volkswagen.de>
46  *
47  */
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <unistd.h>
52 #include <string.h>
53
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/ioctl.h>
57 #include <sys/uio.h>
58
59 #include "af_can.h"
60 #include "bcm.h"
61
62 #define U64_DATA(p) (*(unsigned long long*)(p)->data)
63
64 int main(int argc, char **argv)
65 {
66     int s,nbytes;
67     struct sockaddr_can addr;
68     struct ifreq ifr;
69
70     struct timeval tv;
71
72     struct {
73       struct bcm_msg_head msg_head;
74       struct can_frame frame[4];
75     } txmsg, rxmsg;
76
77     if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) {
78         perror("socket");
79         return 1;
80     }
81
82     addr.can_family = PF_CAN;
83     strcpy(ifr.ifr_name, "vcan2");
84     ioctl(s, SIOCGIFINDEX, &ifr);
85     addr.can_ifindex = ifr.ifr_ifindex;
86
87     if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
88         perror("connect");
89         return 1;
90     }
91
92     txmsg.msg_head.opcode  = RX_SETUP;
93     txmsg.msg_head.can_id  = 0x042;
94     txmsg.msg_head.flags   = SETTIMER|RX_FILTER_ID;
95     txmsg.msg_head.ival1.tv_sec = 1;
96     txmsg.msg_head.ival1.tv_usec = 0;
97     txmsg.msg_head.ival2.tv_sec = 0;
98     txmsg.msg_head.ival2.tv_usec = 0;
99     txmsg.msg_head.nframes = 0;
100
101     printf("<*>Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n",
102            txmsg.msg_head.can_id);
103
104     if (write(s, &txmsg, sizeof(txmsg)) < 0)
105       perror("write");
106
107     txmsg.msg_head.opcode  = RX_DELETE;
108     txmsg.msg_head.can_id  = 0x042; /* everything we need for RX_DELETE */
109
110     printf("<*>Writing RX_DELETE with RX_FILTER_ID for can_id <%03X>\n",
111            txmsg.msg_head.can_id);
112
113     if (write(s, &txmsg, sizeof(txmsg)) < 0)
114       perror("write");
115
116     txmsg.msg_head.opcode  = RX_SETUP;
117     txmsg.msg_head.can_id  = 0x042;
118     txmsg.msg_head.flags   = SETTIMER|RX_FILTER_ID;
119     txmsg.msg_head.ival1.tv_sec = 1;
120     txmsg.msg_head.ival1.tv_usec = 0;
121     txmsg.msg_head.ival2.tv_sec = 0;
122     txmsg.msg_head.ival2.tv_usec = 0;
123     txmsg.msg_head.nframes = 0;
124
125     printf("<*>Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n",
126            txmsg.msg_head.can_id);
127
128     if (write(s, &txmsg, sizeof(txmsg)) < 0)
129       perror("write");
130
131     txmsg.msg_head.opcode  = TX_SEND;
132     txmsg.msg_head.nframes = 1;
133     /* obsolete for TX_SEND ... */
134 #if 0
135     txmsg.msg_head.can_id  = 0x43;
136     txmsg.msg_head.flags   = SETTIMER|STARTTIMER|TX_CP_CAN_ID;
137     txmsg.msg_head.count = 0;
138     txmsg.msg_head.ival1.tv_sec = 0;
139     txmsg.msg_head.ival1.tv_usec = 0;
140     txmsg.msg_head.ival2.tv_sec = 0;
141     txmsg.msg_head.ival2.tv_usec = 0;
142 #endif
143     txmsg.frame[0].can_id    = 0x43;
144     txmsg.frame[0].can_dlc   = 8;
145     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
146
147     printf("<2>Writing TX_SEND with wrong can_id <%03X>\n",
148            txmsg.frame[0].can_id);
149
150     if (write(s, &txmsg, sizeof(txmsg)) < 0)
151       perror("write");
152
153     txmsg.msg_head.opcode  = TX_SEND;
154     txmsg.msg_head.nframes = 1;
155     txmsg.frame[0].can_id    = 0x42;
156     txmsg.frame[0].can_dlc   = 8;
157     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
158
159     printf("<3>Writing TX_SEND with correct can_id <%03X>\n",
160            txmsg.frame[0].can_id);
161
162     if (write(s, &txmsg, sizeof(txmsg)) < 0)
163       perror("write");
164
165     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
166       perror("read");
167     
168     ioctl(s, SIOCGSTAMP, &tv);
169     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
170
171     if (rxmsg.msg_head.opcode == RX_CHANGED &&
172         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
173         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
174       printf("<3>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
175              rxmsg.frame[0].can_id);
176     }
177
178     txmsg.msg_head.opcode  = RX_SETUP;
179     txmsg.msg_head.can_id  = 0x042;
180     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
181     txmsg.msg_head.ival1.tv_sec = 1;
182     txmsg.msg_head.ival1.tv_usec = 0;
183     txmsg.msg_head.ival2.tv_sec = 0;
184     txmsg.msg_head.ival2.tv_usec = 0;
185     txmsg.msg_head.nframes = 1;
186     /* txmsg.frame[0].can_dlc   = 8; obsolete for RX_SETUP */
187     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
188
189     printf("<*>Writing simple RX_SETUP for can_id <%03X> with msgbits 0x%016llX\n",
190            txmsg.msg_head.can_id, U64_DATA(&txmsg.frame[0]));
191
192     if (write(s, &txmsg, sizeof(txmsg)) < 0)
193       perror("write");
194
195     txmsg.msg_head.opcode  = TX_SEND;
196     txmsg.msg_head.nframes = 1;
197     txmsg.frame[0].can_id    = 0x42;
198     txmsg.frame[0].can_dlc   = 8;
199     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
200
201     printf("<5>Writing TX_SEND with correct can_id <%03X>\n",
202            txmsg.frame[0].can_id);
203
204     if (write(s, &txmsg, sizeof(txmsg)) < 0)
205       perror("write");
206
207     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
208       perror("read");
209
210     ioctl(s, SIOCGSTAMP, &tv);
211     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
212
213     if (rxmsg.msg_head.opcode == RX_CHANGED &&
214         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
215         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
216       printf("<5>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
217              rxmsg.frame[0].can_id);
218     }
219
220     txmsg.msg_head.opcode  = TX_SEND;
221     txmsg.msg_head.nframes = 1;
222     txmsg.frame[0].can_id    = 0x42;
223     txmsg.frame[0].can_dlc   = 8;
224     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
225
226     printf("<6>Writing TX_SEND with correct can_id <%03X> ",
227            txmsg.frame[0].can_id);
228     printf("no changed data\n");
229
230     if (write(s, &txmsg, sizeof(txmsg)) < 0)
231       perror("write");
232
233     /* no change here */
234
235     txmsg.msg_head.opcode  = TX_SEND;
236     txmsg.msg_head.nframes = 1;
237     txmsg.frame[0].can_id    = 0x42;
238     txmsg.frame[0].can_dlc   = 8;
239     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
240
241     printf("<7>Writing TX_SEND with correct can_id <%03X> ",
242            txmsg.frame[0].can_id);
243     printf("changed relevant msgbits\n");
244
245     if (write(s, &txmsg, sizeof(txmsg)) < 0)
246       perror("write");
247
248     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
249       perror("read");
250
251     ioctl(s, SIOCGSTAMP, &tv);
252     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
253
254     if (rxmsg.msg_head.opcode == RX_CHANGED &&
255         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
256         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
257       printf("<7>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
258              rxmsg.frame[0].can_id);
259     }
260
261     txmsg.msg_head.opcode  = TX_SEND;
262     txmsg.msg_head.nframes = 1;
263     txmsg.frame[0].can_id    = 0x42;
264     txmsg.frame[0].can_dlc   = 8;
265     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
266
267     printf("<8>Writing TX_SEND with correct can_id <%03X> ",
268            txmsg.frame[0].can_id);
269     printf("changed irrelevant msgbits\n");
270
271     if (write(s, &txmsg, sizeof(txmsg)) < 0)
272       perror("write");
273
274     txmsg.msg_head.opcode  = TX_SEND;
275     txmsg.msg_head.nframes = 1;
276     txmsg.frame[0].can_id    = 0x42;
277     txmsg.frame[0].can_dlc   = 7;
278     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
279
280     printf("<9>Writing TX_SEND with correct can_id <%03X> ",
281            txmsg.frame[0].can_id);
282     printf("changed Data Length Code DLC\n");
283
284     if (write(s, &txmsg, sizeof(txmsg)) < 0)
285       perror("write");
286
287     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
288       perror("read");
289
290     ioctl(s, SIOCGSTAMP, &tv);
291     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
292
293     if (rxmsg.msg_head.opcode == RX_CHANGED &&
294         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
295         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
296       printf("<9>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
297              rxmsg.frame[0].can_id);
298     }
299
300     /* no problems ;-) but NOW we try MUX messages ... and timeouts */
301
302     txmsg.msg_head.opcode  = RX_SETUP;
303     txmsg.msg_head.can_id  = 0x042;
304     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
305     txmsg.msg_head.ival1.tv_sec = 1;
306     txmsg.msg_head.ival1.tv_usec = 0;
307     txmsg.msg_head.nframes = 3;
308     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
309     U64_DATA(&txmsg.frame[1]) = (__u64) 0x01000000000000FFULL;
310     U64_DATA(&txmsg.frame[2]) = (__u64) 0x02000000000000FFULL;
311
312     printf("<*>Writing multiplex RX_SETUP for can_id <%03X>\n",
313            txmsg.msg_head.can_id);
314
315     if (write(s, &txmsg, sizeof(txmsg)) < 0)
316       perror("write");
317
318
319     txmsg.msg_head.opcode  = TX_SEND;
320     txmsg.msg_head.nframes = 1;
321     txmsg.frame[0].can_id    = 0x42;
322     txmsg.frame[0].can_dlc   = 8;
323     U64_DATA(&txmsg.frame[0]) = (__u64) 0x4200000000000000ULL;
324
325     printf("<A>Writing TX_SEND with wrong MUX ID 42\n");
326
327     if (write(s, &txmsg, sizeof(txmsg)) < 0)
328       perror("write");
329
330     txmsg.msg_head.opcode  = TX_SEND;
331     txmsg.msg_head.nframes = 1;
332     txmsg.frame[0].can_id    = 0x42;
333     txmsg.frame[0].can_dlc   = 8;
334     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
335
336     printf("<B>Writing TX_SEND with correct MUX ID 01\n");
337
338     if (write(s, &txmsg, sizeof(txmsg)) < 0)
339       perror("write");
340
341     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
342       perror("read");
343
344     ioctl(s, SIOCGSTAMP, &tv);
345     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
346
347     if (rxmsg.msg_head.opcode == RX_CHANGED &&
348         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
349         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
350       printf("<B>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
351              rxmsg.frame[0].can_id);
352     }
353
354     txmsg.msg_head.opcode  = TX_SEND;
355     txmsg.msg_head.nframes = 1;
356     txmsg.frame[0].can_id    = 0x42;
357     txmsg.frame[0].can_dlc   = 8;
358     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
359
360     printf("<C>Writing TX_SEND with correct MUX ID 01 but no data change\n");
361
362     if (write(s, &txmsg, sizeof(txmsg)) < 0)
363       perror("write");
364
365     txmsg.msg_head.opcode  = TX_SEND;
366     txmsg.msg_head.nframes = 1;
367     txmsg.frame[0].can_id    = 0x42;
368     txmsg.frame[0].can_dlc   = 8;
369     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567800ULL;
370
371     printf("<D>Writing TX_SEND with correct MUX ID 01 but no relevant data change\n");
372
373     if (write(s, &txmsg, sizeof(txmsg)) < 0)
374       perror("write");
375
376     txmsg.msg_head.opcode  = TX_SEND;
377     txmsg.msg_head.nframes = 1;
378     txmsg.frame[0].can_id    = 0x42;
379     txmsg.frame[0].can_dlc   = 8;
380     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567801ULL;
381
382     printf("<E>Writing TX_SEND with correct MUX ID 01 with relevant data change\n");
383
384     if (write(s, &txmsg, sizeof(txmsg)) < 0)
385       perror("write");
386
387     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
388       perror("read");
389
390     ioctl(s, SIOCGSTAMP, &tv);
391     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
392
393     if (rxmsg.msg_head.opcode == RX_CHANGED &&
394         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
395         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
396       printf("<E>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
397              rxmsg.frame[0].can_id);
398     }
399
400     txmsg.msg_head.opcode  = TX_SEND;
401     txmsg.msg_head.nframes = 1;
402     txmsg.frame[0].can_id    = 0x42;
403     txmsg.frame[0].can_dlc   = 8;
404     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000000ULL;
405
406     printf("<F>Writing TX_SEND with correct MUX ID 02\n");
407
408     if (write(s, &txmsg, sizeof(txmsg)) < 0)
409       perror("write");
410
411     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
412       perror("read");
413
414     ioctl(s, SIOCGSTAMP, &tv);
415     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
416
417     if (rxmsg.msg_head.opcode == RX_CHANGED &&
418         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
419         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
420       printf("<F>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
421              rxmsg.frame[0].can_id);
422     }
423
424     txmsg.msg_head.opcode  = TX_SEND;
425     txmsg.msg_head.nframes = 1;
426     txmsg.frame[0].can_id    = 0x42;
427     txmsg.frame[0].can_dlc   = 8;
428     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
429
430     printf("<10>Writing TX_SEND with correct MUX ID 02 with relevant data change\n");
431
432     if (write(s, &txmsg, sizeof(txmsg)) < 0)
433       perror("write");
434
435     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
436       perror("read");
437
438     ioctl(s, SIOCGSTAMP, &tv);
439     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
440
441     if (rxmsg.msg_head.opcode == RX_CHANGED &&
442         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
443         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
444       printf("<10>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
445              rxmsg.frame[0].can_id);
446     }
447
448     txmsg.msg_head.opcode  = TX_SEND;
449     txmsg.msg_head.nframes = 1;
450     txmsg.frame[0].can_id    = 0x42;
451     txmsg.frame[0].can_dlc   = 7;
452     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
453
454     printf("<11>Writing TX_SEND with correct MUX ID 02 no data change but DLC\n");
455
456     if (write(s, &txmsg, sizeof(txmsg)) < 0)
457       perror("write");
458
459     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
460       perror("read");
461
462     if (rxmsg.msg_head.opcode == RX_CHANGED &&
463         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
464         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
465       printf("<11>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
466              rxmsg.frame[0].can_id);
467     }
468
469     txmsg.msg_head.opcode  = TX_SEND;
470     txmsg.msg_head.nframes = 1;
471     txmsg.frame[0].can_id    = 0x42;
472     txmsg.frame[0].can_dlc   = 7;
473     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0300000000000001ULL;
474
475     printf("<12>Writing TX_SEND with wrong MUX ID 03\n");
476
477     if (write(s, &txmsg, sizeof(txmsg)) < 0)
478       perror("write");
479
480     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
481       perror("read");
482
483     ioctl(s, SIOCGSTAMP, &tv);
484     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
485
486     if (rxmsg.msg_head.opcode == RX_TIMEOUT &&
487         nbytes == sizeof(struct bcm_msg_head) &&
488         rxmsg.msg_head.can_id == 0x42) {
489       printf("<-->Received correct RX_TIMEOUT message for can_id <%03X> >> OK!\n",
490              rxmsg.msg_head.can_id);
491     }
492
493     close(s);
494
495     return 0;
496 }