3 #include <linux/can/raw.h>
4 #include <linux/input.h>
5 #include <linux/uinput.h>
10 #include <sys/ioctl.h>
12 #include <sys/types.h>
16 #define MIN(x, y) ((x) < (y) ? (x) : (y))
17 #define MAX(x, y) ((x) > (y) ? (x) : (y))
20 static int init_can(char *ifname)
22 struct sockaddr_can addr;
27 fd_can = socket(PF_CAN, SOCK_RAW, CAN_RAW);
33 /* Get CAN interfaces's index by name */
34 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
35 if (ioctl(fd_can, SIOCGIFINDEX, &ifr) < 0) {
36 perror("SIOCGIFINDEX");
40 /* Bind CAN interface by index */
41 memset(&addr, 0, sizeof(addr));
42 addr.can_family = AF_CAN;
43 addr.can_ifindex = ifr.ifr_ifindex;
44 if (bind(fd_can, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
53 static int init_uinput()
55 struct uinput_user_dev uidev;
59 fd_uinput = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
61 perror("open (/dev/uinput)");
65 /* Register push buttons A, B */
66 ioctl(fd_uinput, UI_SET_EVBIT, EV_KEY);
67 ioctl(fd_uinput, UI_SET_KEYBIT, BTN_TRIGGER);
68 ioctl(fd_uinput, UI_SET_KEYBIT, BTN_THUMB);
70 /* Register absolute axes X, Y */
71 ioctl(fd_uinput, UI_SET_EVBIT, EV_ABS);
72 ioctl(fd_uinput, UI_SET_ABSBIT, ABS_X);
73 ioctl(fd_uinput, UI_SET_ABSBIT, ABS_Y);
75 /* Create a virtual input device ID */
76 memset(&uidev, 0, sizeof(uidev));
77 strncpy(uidev.name, "can2joy", UINPUT_MAX_NAME_SIZE);
78 uidev.id.bustype = BUS_USB;
79 uidev.id.vendor = 0x1234;
80 uidev.id.product = 0xfedc;
82 write(fd_uinput, &uidev, sizeof(uidev));
84 /* Set min/max values for axes */
85 uidev.absmin[ABS_X] = 255;
86 uidev.absmax[ABS_X] = -256;
87 uidev.absmin[ABS_Y] = -1;
88 uidev.absmax[ABS_Y] = 1;
89 write(fd_uinput, &uidev, sizeof(uidev));
92 ioctl(fd_uinput, UI_DEV_CREATE);
99 static void receive_one(int fd_can, int fd_uinput)
101 struct can_frame frm;
102 struct sockaddr_can addr;
105 struct input_event ev;
108 memset(&ev, 0, sizeof(ev));
110 ret = recvfrom(fd_can, &frm, sizeof(struct can_frame), 0,
111 (struct sockaddr *)&addr, &len);
119 /* Check clutch and brake pedal.
120 * We only read one bit for each, so don't expect fine
121 * control of your simulated Lamborghini!
124 ev.code = BTN_TRIGGER;
125 ev.value = !(!(frm.data[4] & 3));
126 write(fd_uinput, &ev, sizeof(ev));
129 ev.value = !(!(frm.data[6] & 4));
130 write(fd_uinput, &ev, sizeof(ev));
134 /* Translate absolute wheel position.
135 * It's a signed 16-bit integer in the first two bytes
136 * of a 0x3c3 frame, indicating how far it is turned.
137 * Zero means we're driving straight.
138 * The next two bytes are the angular speed of the wheel
139 * being turned, but we don't care about that here.
141 wheel_pos = *((short*)(&frm.data[0]));
142 printf("Wheel position: %i\n", wheel_pos);
144 /* Clamp the wheel position around the zero point.
145 * This is to avoid excessive wear of the wheels of the
146 * parked car as well as of the whole steering mechanism.
148 if (wheel_pos >= 0) {
149 wheel_pos = MIN(255, wheel_pos);
151 /* The first negative value next to zero is
152 * -32768. So we have to invert this to -1
153 * instead of -32768, -2 instead of -32767, etc.
155 wheel_pos = 0 - (wheel_pos + 32768);
156 wheel_pos = MAX(-256, wheel_pos);
158 printf("Wheel position (clamped): %i\n", wheel_pos);
160 /* Report the change in wheel position as the X axis */
163 ev.value = wheel_pos;
164 ret = write(fd_uinput, &ev, sizeof(ev));
166 /* Report a dummy Y axis for programs that expect it */
169 ret = write(fd_uinput, &ev, sizeof(ev));
173 /* Flush the uinput events we just generated */
175 ev.code = SYN_REPORT;
177 write(fd_uinput, &ev, sizeof(ev));
183 int main(int argc, char **argv)
189 printf("Usage: %s <can-interface>\n", argv[0]);
191 printf("Example: %s can0\n", argv[0]);
196 fd_can = init_can(argv[1]);
200 fd_uinput = init_uinput();
206 receive_one(fd_can, fd_uinput);
209 ioctl(fd_uinput, UI_DEV_DESTROY);