]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - test/tst-bcm-filter.c
Fixed contradiction in Sourcecode discalimer.
[socketcan-devel.git] / test / tst-bcm-filter.c
1 /*
2  *  $Id$
3  */
4
5 /*
6  * tst-bcm-filter.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 and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of Volkswagen nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * Alternatively, provided that this notice is retained in full, this
24  * software may be distributed under the terms of the GNU General
25  * Public License ("GPL") version 2, in which case the provisions of the
26  * GPL apply INSTEAD OF those given above.
27  *
28  * The provided data structures and external interfaces from this code
29  * are not restricted to be used by modules with a GPL compatible license.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
42  * DAMAGE.
43  *
44  * Send feedback to <socketcan-users@lists.berlios.de>
45  *
46  */
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <string.h>
52
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 #include <sys/ioctl.h>
56 #include <sys/uio.h>
57 #include <net/if.h>
58
59 #include <linux/can.h>
60 #include <linux/can/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     /* test for RX_DELETE */
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 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     /* growing number of nframes => RX_DELETE instead of simple update */
180     txmsg.msg_head.opcode  = RX_DELETE;
181     txmsg.msg_head.can_id  = 0x042; /* everything we need for RX_DELETE */
182
183     printf("<*>Writing RX_DELETE for can_id <%03X>\n",
184            txmsg.msg_head.can_id);
185
186     if (write(s, &txmsg, sizeof(txmsg)) < 0)
187       perror("write");
188
189     txmsg.msg_head.opcode  = RX_SETUP;
190     txmsg.msg_head.can_id  = 0x042;
191     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
192     txmsg.msg_head.ival1.tv_sec = 1;
193     txmsg.msg_head.ival1.tv_usec = 0;
194     txmsg.msg_head.ival2.tv_sec = 0;
195     txmsg.msg_head.ival2.tv_usec = 0;
196     txmsg.msg_head.nframes = 1;
197     /* txmsg.frame[0].can_dlc   = 8; obsolete for RX_SETUP */
198     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
199
200     printf("<*>Writing simple RX_SETUP for can_id <%03X> with msgbits 0x%016llX\n",
201            txmsg.msg_head.can_id, U64_DATA(&txmsg.frame[0]));
202
203     if (write(s, &txmsg, sizeof(txmsg)) < 0)
204       perror("write");
205
206     txmsg.msg_head.opcode  = TX_SEND;
207     txmsg.msg_head.nframes = 1;
208     txmsg.frame[0].can_id    = 0x42;
209     txmsg.frame[0].can_dlc   = 8;
210     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
211
212     printf("<5>Writing TX_SEND with correct can_id <%03X>\n",
213            txmsg.frame[0].can_id);
214
215     if (write(s, &txmsg, sizeof(txmsg)) < 0)
216       perror("write");
217
218     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
219       perror("read");
220
221     ioctl(s, SIOCGSTAMP, &tv);
222     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
223
224     if (rxmsg.msg_head.opcode == RX_CHANGED &&
225         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
226         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
227       printf("<5>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
228              rxmsg.frame[0].can_id);
229     }
230
231     txmsg.msg_head.opcode  = TX_SEND;
232     txmsg.msg_head.nframes = 1;
233     txmsg.frame[0].can_id    = 0x42;
234     txmsg.frame[0].can_dlc   = 8;
235     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
236
237     printf("<6>Writing TX_SEND with correct can_id <%03X> ",
238            txmsg.frame[0].can_id);
239     printf("no changed data\n");
240
241     if (write(s, &txmsg, sizeof(txmsg)) < 0)
242       perror("write");
243
244     /* no change here */
245
246     txmsg.msg_head.opcode  = TX_SEND;
247     txmsg.msg_head.nframes = 1;
248     txmsg.frame[0].can_id    = 0x42;
249     txmsg.frame[0].can_dlc   = 8;
250     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
251
252     printf("<7>Writing TX_SEND with correct can_id <%03X> ",
253            txmsg.frame[0].can_id);
254     printf("changed relevant msgbits\n");
255
256     if (write(s, &txmsg, sizeof(txmsg)) < 0)
257       perror("write");
258
259     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
260       perror("read");
261
262     ioctl(s, SIOCGSTAMP, &tv);
263     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
264
265     if (rxmsg.msg_head.opcode == RX_CHANGED &&
266         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
267         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
268       printf("<7>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
269              rxmsg.frame[0].can_id);
270     }
271
272     txmsg.msg_head.opcode  = TX_SEND;
273     txmsg.msg_head.nframes = 1;
274     txmsg.frame[0].can_id    = 0x42;
275     txmsg.frame[0].can_dlc   = 8;
276     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
277
278     printf("<8>Writing TX_SEND with correct can_id <%03X> ",
279            txmsg.frame[0].can_id);
280     printf("changed irrelevant msgbits\n");
281
282     if (write(s, &txmsg, sizeof(txmsg)) < 0)
283       perror("write");
284
285     txmsg.msg_head.opcode  = TX_SEND;
286     txmsg.msg_head.nframes = 1;
287     txmsg.frame[0].can_id    = 0x42;
288     txmsg.frame[0].can_dlc   = 7;
289     U64_DATA(&txmsg.frame[0]) = (__u64) 0xdeadbeefdeadbeefULL;
290
291     printf("<9>Writing TX_SEND with correct can_id <%03X> ",
292            txmsg.frame[0].can_id);
293     printf("changed Data Length Code DLC\n");
294
295     if (write(s, &txmsg, sizeof(txmsg)) < 0)
296       perror("write");
297
298     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
299       perror("read");
300
301     ioctl(s, SIOCGSTAMP, &tv);
302     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
303
304     if (rxmsg.msg_head.opcode == RX_CHANGED &&
305         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
306         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
307       printf("<9>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
308              rxmsg.frame[0].can_id);
309     }
310
311     txmsg.msg_head.opcode  = RX_DELETE;
312     txmsg.msg_head.can_id  = 0x042; /* everything we need for RX_DELETE */
313
314     printf("<*>Writing RX_DELETE for can_id <%03X> for RX_SETUP with growing nframes\n",
315            txmsg.msg_head.can_id);
316
317     if (write(s, &txmsg, sizeof(txmsg)) < 0)
318       perror("write");
319
320     /* no problems ;-) but NOW we try MUX messages ... and timeouts */
321
322     txmsg.msg_head.opcode  = RX_SETUP;
323     txmsg.msg_head.can_id  = 0x042;
324     txmsg.msg_head.flags   = SETTIMER|RX_CHECK_DLC;
325     txmsg.msg_head.ival1.tv_sec = 1;
326     txmsg.msg_head.ival1.tv_usec = 0;
327     txmsg.msg_head.nframes = 3;
328     U64_DATA(&txmsg.frame[0]) = (__u64) 0xFF00000000000000ULL;
329     U64_DATA(&txmsg.frame[1]) = (__u64) 0x01000000000000FFULL;
330     U64_DATA(&txmsg.frame[2]) = (__u64) 0x02000000000000FFULL;
331
332     printf("<*>Writing multiplex RX_SETUP for can_id <%03X>\n",
333            txmsg.msg_head.can_id);
334
335     if (write(s, &txmsg, sizeof(txmsg)) < 0)
336       perror("write");
337
338
339     txmsg.msg_head.opcode  = TX_SEND;
340     txmsg.msg_head.nframes = 1;
341     txmsg.frame[0].can_id    = 0x42;
342     txmsg.frame[0].can_dlc   = 8;
343     U64_DATA(&txmsg.frame[0]) = (__u64) 0x4200000000000000ULL;
344
345     printf("<A>Writing TX_SEND with wrong MUX ID 42\n");
346
347     if (write(s, &txmsg, sizeof(txmsg)) < 0)
348       perror("write");
349
350     txmsg.msg_head.opcode  = TX_SEND;
351     txmsg.msg_head.nframes = 1;
352     txmsg.frame[0].can_id    = 0x42;
353     txmsg.frame[0].can_dlc   = 8;
354     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
355
356     printf("<B>Writing TX_SEND with correct MUX ID 01\n");
357
358     if (write(s, &txmsg, sizeof(txmsg)) < 0)
359       perror("write");
360
361     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
362       perror("read");
363
364     ioctl(s, SIOCGSTAMP, &tv);
365     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
366
367     if (rxmsg.msg_head.opcode == RX_CHANGED &&
368         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
369         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
370       printf("<B>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
371              rxmsg.frame[0].can_id);
372     }
373
374     txmsg.msg_head.opcode  = TX_SEND;
375     txmsg.msg_head.nframes = 1;
376     txmsg.frame[0].can_id    = 0x42;
377     txmsg.frame[0].can_dlc   = 8;
378     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100000000000000ULL;
379
380     printf("<C>Writing TX_SEND with correct MUX ID 01 but no data change\n");
381
382     if (write(s, &txmsg, sizeof(txmsg)) < 0)
383       perror("write");
384
385     txmsg.msg_head.opcode  = TX_SEND;
386     txmsg.msg_head.nframes = 1;
387     txmsg.frame[0].can_id    = 0x42;
388     txmsg.frame[0].can_dlc   = 8;
389     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567800ULL;
390
391     printf("<D>Writing TX_SEND with correct MUX ID 01 but no relevant data change\n");
392
393     if (write(s, &txmsg, sizeof(txmsg)) < 0)
394       perror("write");
395
396     txmsg.msg_head.opcode  = TX_SEND;
397     txmsg.msg_head.nframes = 1;
398     txmsg.frame[0].can_id    = 0x42;
399     txmsg.frame[0].can_dlc   = 8;
400     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0100001234567801ULL;
401
402     printf("<E>Writing TX_SEND with correct MUX ID 01 with relevant data change\n");
403
404     if (write(s, &txmsg, sizeof(txmsg)) < 0)
405       perror("write");
406
407     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
408       perror("read");
409
410     ioctl(s, SIOCGSTAMP, &tv);
411     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
412
413     if (rxmsg.msg_head.opcode == RX_CHANGED &&
414         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
415         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
416       printf("<E>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
417              rxmsg.frame[0].can_id);
418     }
419
420     txmsg.msg_head.opcode  = TX_SEND;
421     txmsg.msg_head.nframes = 1;
422     txmsg.frame[0].can_id    = 0x42;
423     txmsg.frame[0].can_dlc   = 8;
424     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000000ULL;
425
426     printf("<F>Writing TX_SEND with correct MUX ID 02\n");
427
428     if (write(s, &txmsg, sizeof(txmsg)) < 0)
429       perror("write");
430
431     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
432       perror("read");
433
434     ioctl(s, SIOCGSTAMP, &tv);
435     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
436
437     if (rxmsg.msg_head.opcode == RX_CHANGED &&
438         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
439         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
440       printf("<F>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
441              rxmsg.frame[0].can_id);
442     }
443
444     txmsg.msg_head.opcode  = TX_SEND;
445     txmsg.msg_head.nframes = 1;
446     txmsg.frame[0].can_id    = 0x42;
447     txmsg.frame[0].can_dlc   = 8;
448     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
449
450     printf("<10>Writing TX_SEND with correct MUX ID 02 with relevant data change\n");
451
452     if (write(s, &txmsg, sizeof(txmsg)) < 0)
453       perror("write");
454
455     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
456       perror("read");
457
458     ioctl(s, SIOCGSTAMP, &tv);
459     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
460
461     if (rxmsg.msg_head.opcode == RX_CHANGED &&
462         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
463         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
464       printf("<10>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
465              rxmsg.frame[0].can_id);
466     }
467
468     txmsg.msg_head.opcode  = TX_SEND;
469     txmsg.msg_head.nframes = 1;
470     txmsg.frame[0].can_id    = 0x42;
471     txmsg.frame[0].can_dlc   = 7;
472     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0200000000000001ULL;
473
474     printf("<11>Writing TX_SEND with correct MUX ID 02 no data change but DLC\n");
475
476     if (write(s, &txmsg, sizeof(txmsg)) < 0)
477       perror("write");
478
479     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
480       perror("read");
481
482     if (rxmsg.msg_head.opcode == RX_CHANGED &&
483         nbytes == sizeof(struct bcm_msg_head) + sizeof(struct can_frame) &&
484         rxmsg.msg_head.can_id == 0x42 && rxmsg.frame[0].can_id == 0x42) {
485       printf("<11>Received correct RX_CHANGED message for can_id <%03X> >> OK!\n",
486              rxmsg.frame[0].can_id);
487     }
488
489     txmsg.msg_head.opcode  = TX_SEND;
490     txmsg.msg_head.nframes = 1;
491     txmsg.frame[0].can_id    = 0x42;
492     txmsg.frame[0].can_dlc   = 7;
493     U64_DATA(&txmsg.frame[0]) = (__u64) 0x0300000000000001ULL;
494
495     printf("<12>Writing TX_SEND with wrong MUX ID 03\n");
496
497     if (write(s, &txmsg, sizeof(txmsg)) < 0)
498       perror("write");
499
500     if ((nbytes = read(s, &rxmsg, sizeof(rxmsg))) < 0)
501       perror("read");
502
503     ioctl(s, SIOCGSTAMP, &tv);
504     printf("(%ld.%06ld)   ", tv.tv_sec, tv.tv_usec);
505
506     if (rxmsg.msg_head.opcode == RX_TIMEOUT &&
507         nbytes == sizeof(struct bcm_msg_head) &&
508         rxmsg.msg_head.can_id == 0x42) {
509       printf("<-->Received correct RX_TIMEOUT message for can_id <%03X> >> OK!\n",
510              rxmsg.msg_head.can_id);
511     }
512
513     close(s);
514
515     return 0;
516 }