2 * Copyright 2015 Max Staudt
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License 2 as published
6 * by the Free Software Foundation.
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <linux/can.h>
17 #include <linux/can/raw.h>
19 #include <sys/ioctl.h>
23 static int base_id = 0x420;
24 static int my_id = 0x1a;
25 static int next_id = 0x19; //myid
27 static int ignore_counter = 10;
29 static void on_nm_frame(int socket)
31 struct can_frame frame;
32 struct sockaddr_can addr;
36 ret = recvfrom(socket, &frame, sizeof(struct can_frame), 0,
37 (struct sockaddr *)&addr, &len);
43 if (frame.can_id >> 5 == 0x420 >> 5) {
44 printf("Received NM frame from %03x\n", frame.can_id);
47 if (frame.can_id == base_id + my_id) {
48 printf("Skipping my own NM frame.\n");
52 switch (frame.data[1]) {
54 if (frame.data[0] == my_id) {
55 struct can_frame txframe = {.can_id = base_id + next_id,
57 .data = {next_id, 01, 00, 00, 00, 00, 00, 00},
59 ssize_t tmp = write(socket, &txframe, sizeof(txframe));
60 if (tmp != sizeof(txframe)) {
61 perror("write socket");
67 if (ignore_counter > 0) {
72 ? frame.can_id - base_id < next_id
73 : next_id == my_id || frame.can_id - base_id < next_id) {
74 next_id = frame.can_id - base_id;
76 struct can_frame txframe = {.can_id = base_id + my_id,
78 .data = {my_id, 02, 01, 04, 00, 04, 00, 00},
80 ssize_t tmp = write(socket, &txframe, sizeof(txframe));
81 if (tmp != sizeof(txframe)) {
82 perror("write socket");
94 static int net_init(char *ifname)
98 struct sockaddr_can addr;
101 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
107 memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
108 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
109 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
110 perror("SIOCGIFINDEX");
114 memset(&addr, 0, sizeof(addr));
115 addr.can_family = AF_CAN;
116 addr.can_ifindex = ifr.ifr_ifindex;
117 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
122 recv_own_msgs = 0; /* 0 = disabled (default), 1 = enabled */
123 setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
124 &recv_own_msgs, sizeof(recv_own_msgs));
129 int main(int argc, char **argv)
135 printf("syntax: %s IFNAME\n", argv[0]);
139 s = net_init(argv[1]);
147 if (select(s+1, &rdfs, NULL, NULL, NULL) < 0) {
152 if (FD_ISSET(s, &rdfs)) {