0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <linux/bpf.h>
0031 #include <linux/input.h>
0032 #include <errno.h>
0033 #include <stdio.h>
0034 #include <stdlib.h>
0035 #include <string.h>
0036 #include <unistd.h>
0037 #include <poll.h>
0038 #include <sys/types.h>
0039 #include <sys/ioctl.h>
0040 #include <sys/stat.h>
0041 #include <fcntl.h>
0042
0043 #include "bpf_util.h"
0044 #include <bpf/bpf.h>
0045 #include <bpf/libbpf.h>
0046
0047 #include "testing_helpers.h"
0048
0049 int main(int argc, char **argv)
0050 {
0051 struct bpf_object *obj;
0052 int ret, lircfd, progfd, inputfd;
0053 int testir1 = 0x1dead;
0054 int testir2 = 0x20101;
0055 u32 prog_ids[10], prog_flags[10], prog_cnt;
0056
0057 if (argc != 3) {
0058 printf("Usage: %s /dev/lircN /dev/input/eventM\n", argv[0]);
0059 return 2;
0060 }
0061
0062 ret = bpf_prog_test_load("test_lirc_mode2_kern.o",
0063 BPF_PROG_TYPE_LIRC_MODE2, &obj, &progfd);
0064 if (ret) {
0065 printf("Failed to load bpf program\n");
0066 return 1;
0067 }
0068
0069 lircfd = open(argv[1], O_RDWR | O_NONBLOCK);
0070 if (lircfd == -1) {
0071 printf("failed to open lirc device %s: %m\n", argv[1]);
0072 return 1;
0073 }
0074
0075
0076 ret = bpf_prog_detach2(progfd, lircfd, BPF_LIRC_MODE2);
0077 if (ret != -1 || errno != ENOENT) {
0078 printf("bpf_prog_detach2 not attached should fail: %m\n");
0079 return 1;
0080 }
0081
0082 inputfd = open(argv[2], O_RDONLY | O_NONBLOCK);
0083 if (inputfd == -1) {
0084 printf("failed to open input device %s: %m\n", argv[1]);
0085 return 1;
0086 }
0087
0088 prog_cnt = 10;
0089 ret = bpf_prog_query(lircfd, BPF_LIRC_MODE2, 0, prog_flags, prog_ids,
0090 &prog_cnt);
0091 if (ret) {
0092 printf("Failed to query bpf programs on lirc device: %m\n");
0093 return 1;
0094 }
0095
0096 if (prog_cnt != 0) {
0097 printf("Expected nothing to be attached\n");
0098 return 1;
0099 }
0100
0101 ret = bpf_prog_attach(progfd, lircfd, BPF_LIRC_MODE2, 0);
0102 if (ret) {
0103 printf("Failed to attach bpf to lirc device: %m\n");
0104 return 1;
0105 }
0106
0107
0108 ret = write(lircfd, &testir1, sizeof(testir1));
0109 if (ret != sizeof(testir1)) {
0110 printf("Failed to send test IR message: %m\n");
0111 return 1;
0112 }
0113
0114 struct pollfd pfd = { .fd = inputfd, .events = POLLIN };
0115 struct input_event event;
0116
0117 for (;;) {
0118 poll(&pfd, 1, 100);
0119
0120
0121 ret = read(inputfd, &event, sizeof(event));
0122 if (ret != sizeof(event)) {
0123 printf("Failed to read decoded IR: %m\n");
0124 return 1;
0125 }
0126
0127 if (event.type == EV_MSC && event.code == MSC_SCAN &&
0128 event.value == 0xdead) {
0129 break;
0130 }
0131 }
0132
0133
0134 ret = write(lircfd, &testir2, sizeof(testir2));
0135 if (ret != sizeof(testir2)) {
0136 printf("Failed to send test IR message: %m\n");
0137 return 1;
0138 }
0139
0140 for (;;) {
0141 poll(&pfd, 1, 100);
0142
0143
0144 ret = read(inputfd, &event, sizeof(event));
0145 if (ret != sizeof(event)) {
0146 printf("Failed to read decoded IR: %m\n");
0147 return 1;
0148 }
0149
0150 if (event.type == EV_REL && event.code == REL_Y &&
0151 event.value == 1 ) {
0152 break;
0153 }
0154 }
0155
0156 prog_cnt = 10;
0157 ret = bpf_prog_query(lircfd, BPF_LIRC_MODE2, 0, prog_flags, prog_ids,
0158 &prog_cnt);
0159 if (ret) {
0160 printf("Failed to query bpf programs on lirc device: %m\n");
0161 return 1;
0162 }
0163
0164 if (prog_cnt != 1) {
0165 printf("Expected one program to be attached\n");
0166 return 1;
0167 }
0168
0169
0170 ret = bpf_prog_detach2(progfd, lircfd, BPF_LIRC_MODE2);
0171 if (ret) {
0172 printf("bpf_prog_detach2: returned %m\n");
0173 return 1;
0174 }
0175
0176 return 0;
0177 }