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