]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - test/tst-bcm-filter.c
changed user space programs to use new include files.
[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 <socketcan-users@lists.berlios.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 #include <net/if.h>
59
60 #include <linux/can.h>
61 #include <linux/can/bcm.h>
62
63 #define U64_DATA(p) (*(unsigned long long*)(p)->data)
64
65 int main(int argc, char **argv)
66 {
67     int s,nbytes;
68     struct sockaddr_can addr;
69     struct ifreq ifr;
70
71     struct timeval tv;
72
73     struct {
74       struct bcm_msg_head msg_head;
75       struct can_frame frame[4];
76     } txmsg, rxmsg;
77
78     if ((s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) {
79         perror("socket");
80         return 1;
81     }
82
83     addr.can_family = PF_CAN;
84     strcpy(ifr.ifr_name, "vcan2");
85     ioctl(s, SIOCGIFINDEX, &ifr);
86     addr.can_ifindex = ifr.ifr_ifindex;
87
88     if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
89         perror("connect");
90         return 1;
91     }
92
93     txmsg.msg_head.opcode  = RX_SETUP;
94     txmsg.msg_head.can_id  = 0x042;
95     txmsg.msg_head.flags   = SETTIMER|RX_FILTER_ID;
96     txmsg.msg_head.ival1.tv_sec = 1;
97     txmsg.msg_head.ival1.tv_usec = 0;
98     txmsg.msg_head.ival2.tv_sec = 0;
99     txmsg.msg_head.ival2.tv_usec = 0;
100     txmsg.msg_head.nframes = 0;
101
102     printf("<*>Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n",
103            txmsg.msg_head.can_id);
104
105     if (write(s, &txmsg, sizeof(txmsg)) < 0)
106       perror("write");
107
108     txmsg.msg_head.opcode  = RX_DELETE;
109     txmsg.msg_head.can_id  = 0x042; /* everything we need for RX_DELETE */
110
111     printf("<*>Writing RX_DELETE with RX_FILTER_ID for can_id <%03X>\n",
112            txmsg.msg_head.can_id);
113
114     if (write(s, &txmsg, sizeof(txmsg)) < 0)
115       perror("write");
116
117     txmsg.msg_head.opcode  = RX_SETUP;
118     txmsg.msg_head.can_id  = 0x042;
119     txmsg.msg_head.flags   = SETTIMER|RX_FILTER_ID;
120     txmsg.msg_head.ival1.tv_sec = 1;
121     txmsg.msg_head.ival1.tv_usec = 0;
122     txmsg.msg_head.ival2.tv_sec = 0;
123     txmsg.msg_head.ival2.tv_usec = 0;
124     txmsg.msg_head.nframes = 0;
125
126     printf("<*>Writing RX_SETUP with RX_FILTER_ID for can_id <%03X>\n",
127            txmsg.msg_head.can_id);
128
129     if (write(s, &txmsg, sizeof(txmsg)) < 0)
130       perror("write");
131
132     txmsg.msg_head.opcode  = TX_SEND;
133     txmsg.msg_head.nframes = 1;
134     /* obsolete for TX_SEND ... */
135 #if 0
136     txmsg.msg_head.can_id  = 0x43;
137     txmsg.msg_head.flags   = SETTIMER|STARTTIMER|TX_CP_CAN_ID;
138     txmsg.msg_head.count = 0;
139     txmsg.msg_head.ival1.tv_sec = 0;
140     txmsg.msg_head.ival1.tv_usec = 0;
141     txmsg.msg_head.ival2.tv_sec = 0;
142     txmsg.msg_head.ival2.tv_usec = 0;
143 #endif
144     txmsg.frame[0].can_id    = 0x43;
145     txmsg.frame[0].can_dlc   = 8;
146     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
147
148     printf("<2>Writing TX_SEND with wrong can_id <%03X>\n",
149            txmsg.frame[0].can_id);
150
151     if (write(s, &txmsg, sizeof(txmsg)) < 0)
152       perror("write");
153
154     txmsg.msg_head.opcode  = TX_SEND;
155     txmsg.msg_head.nframes = 1;
156     txmsg.frame[0].can_id    = 0x42;
157     txmsg.frame[0].can_dlc   = 8;
158     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
159
160     printf("<3>Writing TX_SEND with correct can_id <%03X>\n",
161            txmsg.frame[0].can_id);
162
163     if (write(s, &txmsg, sizeof(txmsg)) < 0)
164       perror("write");
165
166     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
167       perror("read");
168     
169     ioctl(s, SIOCGSTAMP, &tv);
170     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
171
172     if (rxmsg.msg_head.opcode == RX_CHANGED &&
173         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
174         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
175       printf("<3>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
176              rxmsg.frame[0].can_id);
177     }
178
179     txmsg.msg_head.opcode  = RX_SETUP;
180     txmsg.msg_head.can_id  = 0x042;
181     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
182     txmsg.msg_head.ival1.tv_sec = 1;
183     txmsg.msg_head.ival1.tv_usec = 0;
184     txmsg.msg_head.ival2.tv_sec = 0;
185     txmsg.msg_head.ival2.tv_usec = 0;
186     txmsg.msg_head.nframes = 1;
187     /* txmsg.frame[0].can_dlc   = 8; obsolete for RX_SETUP */
188     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
189
190     printf("<*>Writing simple RX_SETUP for can_id <%03X> with msgbits 0x%016llX\n",
191            txmsg.msg_head.can_id, U64_DATA(&txmsg.frame[0]));
192
193     if (write(s, &txmsg, sizeof(txmsg)) < 0)
194       perror("write");
195
196     txmsg.msg_head.opcode  = TX_SEND;
197     txmsg.msg_head.nframes = 1;
198     txmsg.frame[0].can_id    = 0x42;
199     txmsg.frame[0].can_dlc   = 8;
200     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
201
202     printf("<5>Writing TX_SEND with correct can_id <%03X>\n",
203            txmsg.frame[0].can_id);
204
205     if (write(s, &txmsg, sizeof(txmsg)) < 0)
206       perror("write");
207
208     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
209       perror("read");
210
211     ioctl(s, SIOCGSTAMP, &tv);
212     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
213
214     if (rxmsg.msg_head.opcode == RX_CHANGED &&
215         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
216         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
217       printf("<5>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
218              rxmsg.frame[0].can_id);
219     }
220
221     txmsg.msg_head.opcode  = TX_SEND;
222     txmsg.msg_head.nframes = 1;
223     txmsg.frame[0].can_id    = 0x42;
224     txmsg.frame[0].can_dlc   = 8;
225     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
226
227     printf("<6>Writing TX_SEND with correct can_id <%03X> ",
228            txmsg.frame[0].can_id);
229     printf("no changed data\n");
230
231     if (write(s, &txmsg, sizeof(txmsg)) < 0)
232       perror("write");
233
234     /* no change here */
235
236     txmsg.msg_head.opcode  = TX_SEND;
237     txmsg.msg_head.nframes = 1;
238     txmsg.frame[0].can_id    = 0x42;
239     txmsg.frame[0].can_dlc   = 8;
240     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
241
242     printf("<7>Writing TX_SEND with correct can_id <%03X> ",
243            txmsg.frame[0].can_id);
244     printf("changed relevant msgbits\n");
245
246     if (write(s, &txmsg, sizeof(txmsg)) < 0)
247       perror("write");
248
249     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
250       perror("read");
251
252     ioctl(s, SIOCGSTAMP, &tv);
253     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
254
255     if (rxmsg.msg_head.opcode == RX_CHANGED &&
256         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
257         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
258       printf("<7>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
259              rxmsg.frame[0].can_id);
260     }
261
262     txmsg.msg_head.opcode  = TX_SEND;
263     txmsg.msg_head.nframes = 1;
264     txmsg.frame[0].can_id    = 0x42;
265     txmsg.frame[0].can_dlc   = 8;
266     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
267
268     printf("<8>Writing TX_SEND with correct can_id <%03X> ",
269            txmsg.frame[0].can_id);
270     printf("changed irrelevant msgbits\n");
271
272     if (write(s, &txmsg, sizeof(txmsg)) < 0)
273       perror("write");
274
275     txmsg.msg_head.opcode  = TX_SEND;
276     txmsg.msg_head.nframes = 1;
277     txmsg.frame[0].can_id    = 0x42;
278     txmsg.frame[0].can_dlc   = 7;
279     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
280
281     printf("<9>Writing TX_SEND with correct can_id <%03X> ",
282            txmsg.frame[0].can_id);
283     printf("changed Data Length Code DLC\n");
284
285     if (write(s, &txmsg, sizeof(txmsg)) < 0)
286       perror("write");
287
288     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
289       perror("read");
290
291     ioctl(s, SIOCGSTAMP, &tv);
292     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
293
294     if (rxmsg.msg_head.opcode == RX_CHANGED &&
295         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
296         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
297       printf("<9>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
298              rxmsg.frame[0].can_id);
299     }
300
301     /* no problems ;-) but NOW we try MUX messages ... and timeouts */
302
303     txmsg.msg_head.opcode  = RX_SETUP;
304     txmsg.msg_head.can_id  = 0x042;
305     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
306     txmsg.msg_head.ival1.tv_sec = 1;
307     txmsg.msg_head.ival1.tv_usec = 0;
308     txmsg.msg_head.nframes = 3;
309     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
310     U64_DATA(&txmsg.frame[1]) = (__u64) 0x01000000000000FFULL;
311     U64_DATA(&txmsg.frame[2]) = (__u64) 0x02000000000000FFULL;
312
313     printf("<*>Writing multiplex RX_SETUP for can_id <%03X>\n",
314            txmsg.msg_head.can_id);
315
316     if (write(s, &txmsg, sizeof(txmsg)) < 0)
317       perror("write");
318
319
320     txmsg.msg_head.opcode  = TX_SEND;
321     txmsg.msg_head.nframes = 1;
322     txmsg.frame[0].can_id    = 0x42;
323     txmsg.frame[0].can_dlc   = 8;
324     U64_DATA(&txmsg.frame[0]) = (__u64) 0x4200000000000000ULL;
325
326     printf("<A>Writing TX_SEND with wrong MUX ID 42\n");
327
328     if (write(s, &txmsg, sizeof(txmsg)) < 0)
329       perror("write");
330
331     txmsg.msg_head.opcode  = TX_SEND;
332     txmsg.msg_head.nframes = 1;
333     txmsg.frame[0].can_id    = 0x42;
334     txmsg.frame[0].can_dlc   = 8;
335     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
336
337     printf("<B>Writing TX_SEND with correct MUX ID 01\n");
338
339     if (write(s, &txmsg, sizeof(txmsg)) < 0)
340       perror("write");
341
342     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
343       perror("read");
344
345     ioctl(s, SIOCGSTAMP, &tv);
346     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
347
348     if (rxmsg.msg_head.opcode == RX_CHANGED &&
349         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
350         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
351       printf("<B>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
352              rxmsg.frame[0].can_id);
353     }
354
355     txmsg.msg_head.opcode  = TX_SEND;
356     txmsg.msg_head.nframes = 1;
357     txmsg.frame[0].can_id    = 0x42;
358     txmsg.frame[0].can_dlc   = 8;
359     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
360
361     printf("<C>Writing TX_SEND with correct MUX ID 01 but no data change\n");
362
363     if (write(s, &txmsg, sizeof(txmsg)) < 0)
364       perror("write");
365
366     txmsg.msg_head.opcode  = TX_SEND;
367     txmsg.msg_head.nframes = 1;
368     txmsg.frame[0].can_id    = 0x42;
369     txmsg.frame[0].can_dlc   = 8;
370     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567800ULL;
371
372     printf("<D>Writing TX_SEND with correct MUX ID 01 but no relevant data change\n");
373
374     if (write(s, &txmsg, sizeof(txmsg)) < 0)
375       perror("write");
376
377     txmsg.msg_head.opcode  = TX_SEND;
378     txmsg.msg_head.nframes = 1;
379     txmsg.frame[0].can_id    = 0x42;
380     txmsg.frame[0].can_dlc   = 8;
381     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567801ULL;
382
383     printf("<E>Writing TX_SEND with correct MUX ID 01 with relevant data change\n");
384
385     if (write(s, &txmsg, sizeof(txmsg)) < 0)
386       perror("write");
387
388     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
389       perror("read");
390
391     ioctl(s, SIOCGSTAMP, &tv);
392     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
393
394     if (rxmsg.msg_head.opcode == RX_CHANGED &&
395         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
396         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
397       printf("<E>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
398              rxmsg.frame[0].can_id);
399     }
400
401     txmsg.msg_head.opcode  = TX_SEND;
402     txmsg.msg_head.nframes = 1;
403     txmsg.frame[0].can_id    = 0x42;
404     txmsg.frame[0].can_dlc   = 8;
405     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000000ULL;
406
407     printf("<F>Writing TX_SEND with correct MUX ID 02\n");
408
409     if (write(s, &txmsg, sizeof(txmsg)) < 0)
410       perror("write");
411
412     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
413       perror("read");
414
415     ioctl(s, SIOCGSTAMP, &tv);
416     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
417
418     if (rxmsg.msg_head.opcode == RX_CHANGED &&
419         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
420         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
421       printf("<F>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
422              rxmsg.frame[0].can_id);
423     }
424
425     txmsg.msg_head.opcode  = TX_SEND;
426     txmsg.msg_head.nframes = 1;
427     txmsg.frame[0].can_id    = 0x42;
428     txmsg.frame[0].can_dlc   = 8;
429     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
430
431     printf("<10>Writing TX_SEND with correct MUX ID 02 with relevant data change\n");
432
433     if (write(s, &txmsg, sizeof(txmsg)) < 0)
434       perror("write");
435
436     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
437       perror("read");
438
439     ioctl(s, SIOCGSTAMP, &tv);
440     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
441
442     if (rxmsg.msg_head.opcode == RX_CHANGED &&
443         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
444         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
445       printf("<10>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
446              rxmsg.frame[0].can_id);
447     }
448
449     txmsg.msg_head.opcode  = TX_SEND;
450     txmsg.msg_head.nframes = 1;
451     txmsg.frame[0].can_id    = 0x42;
452     txmsg.frame[0].can_dlc   = 7;
453     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
454
455     printf("<11>Writing TX_SEND with correct MUX ID 02 no data change but DLC\n");
456
457     if (write(s, &txmsg, sizeof(txmsg)) < 0)
458       perror("write");
459
460     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
461       perror("read");
462
463     if (rxmsg.msg_head.opcode == RX_CHANGED &&
464         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
465         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
466       printf("<11>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
467              rxmsg.frame[0].can_id);
468     }
469
470     txmsg.msg_head.opcode  = TX_SEND;
471     txmsg.msg_head.nframes = 1;
472     txmsg.frame[0].can_id    = 0x42;
473     txmsg.frame[0].can_dlc   = 7;
474     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0300000000000001ULL;
475
476     printf("<12>Writing TX_SEND with wrong MUX ID 03\n");
477
478     if (write(s, &txmsg, sizeof(txmsg)) < 0)
479       perror("write");
480
481     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
482       perror("read");
483
484     ioctl(s, SIOCGSTAMP, &tv);
485     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
486
487     if (rxmsg.msg_head.opcode == RX_TIMEOUT &&
488         nbytes == sizeof(struct bcm_msg_head) &&
489         rxmsg.msg_head.can_id == 0x42) {
490       printf("<-->Received correct RX_TIMEOUT message for can_id <%03X> >> OK!\n",
491              rxmsg.msg_head.can_id);
492     }
493
494     close(s);
495
496     return 0;
497 }