]> rtime.felk.cvut.cz Git - sojka/can-syscalls-examples.git/blob - candump-recvmmsg.c
Add README
[sojka/can-syscalls-examples.git] / candump-recvmmsg.c
1 /**************************************************************/
2 /* CAN system calls example                                   */
3 /* Author: Michal Sojka, Czech Technical University in Prague */
4 /* License: Public domain                                     */
5 /**************************************************************/
6
7 #define _GNU_SOURCE
8
9 #include "common.h"
10
11 #include <linux/can.h>
12 #include <net/if.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <stdbool.h>
16 #include <string.h>
17 #include <sys/ioctl.h>
18 #include <sys/socket.h>
19
20 #define MMSG_MAX 64
21
22 struct mmsghdr msgs[MMSG_MAX];
23 struct iovec iovecs[MMSG_MAX];
24 struct can_frame cf[MMSG_MAX];
25
26 int init_recvmmsg(const char *dev)
27 {
28         int sock;
29         struct sockaddr_can addr;
30         struct ifreq ifr;
31         int i;
32
33         sock = CHECK(socket(PF_CAN, SOCK_RAW, CAN_RAW));
34
35         strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
36         if (-1 == ioctl(sock, SIOCGIFINDEX, &ifr)) {
37                 perror(dev);
38                 exit(1);
39         }
40
41         addr.can_family = AF_CAN;
42         addr.can_ifindex = ifr.ifr_ifindex;
43
44         CHECK(bind(sock, (struct sockaddr *)&addr, sizeof(addr)));
45
46         memset(msgs, 0, sizeof(msgs));
47         memset(iovecs, 0, sizeof(iovecs));
48         for (i = 0; i < MMSG_MAX; i++) {
49                 iovecs[i].iov_base         = &cf[i];
50                 iovecs[i].iov_len          = sizeof(cf[i]);
51                 msgs[i].msg_hdr.msg_iov    = &iovecs[i];
52                 msgs[i].msg_hdr.msg_iovlen = 1;
53         }
54
55         return sock;
56 }
57
58 void can_recvmmsg(int sock)
59 {
60         int i;
61         int received = CHECK(recvmmsg(sock, msgs, MMSG_MAX, MSG_WAITFORONE, NULL));
62
63         printf("Received %d CAN frames in one system call\n", received);
64         for (i = 0; i < received; i++)
65                 print_can_frame(&cf[i]);
66 }
67
68 int main(int argc, char *argv[])
69 {
70         const char *dev;
71         int sock;
72
73         dev = candump_parse_args(argc, argv);
74
75         sock = init_recvmmsg(dev);
76
77         while (1)
78                 can_recvmmsg(sock);
79 }