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