162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include "vmlinux.h" 462306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 562306a36Sopenharmony_ci#include <bpf/bpf_tracing.h> 662306a36Sopenharmony_ci#include "hid_bpf_helpers.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciSEC("fmod_ret/hid_bpf_device_event") 962306a36Sopenharmony_ciint BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci s16 y; 1262306a36Sopenharmony_ci __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci if (!data) 1562306a36Sopenharmony_ci return 0; /* EPERM check */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci bpf_printk("event: size: %d", hctx->size); 1862306a36Sopenharmony_ci bpf_printk("incoming event: %02x %02x %02x", 1962306a36Sopenharmony_ci data[0], 2062306a36Sopenharmony_ci data[1], 2162306a36Sopenharmony_ci data[2]); 2262306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x", 2362306a36Sopenharmony_ci data[3], 2462306a36Sopenharmony_ci data[4], 2562306a36Sopenharmony_ci data[5]); 2662306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x", 2762306a36Sopenharmony_ci data[6], 2862306a36Sopenharmony_ci data[7], 2962306a36Sopenharmony_ci data[8]); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci y = data[3] | (data[4] << 8); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci y = -y; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci data[3] = y & 0xFF; 3662306a36Sopenharmony_ci data[4] = (y >> 8) & 0xFF; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci bpf_printk("modified event: %02x %02x %02x", 3962306a36Sopenharmony_ci data[0], 4062306a36Sopenharmony_ci data[1], 4162306a36Sopenharmony_ci data[2]); 4262306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x", 4362306a36Sopenharmony_ci data[3], 4462306a36Sopenharmony_ci data[4], 4562306a36Sopenharmony_ci data[5]); 4662306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x", 4762306a36Sopenharmony_ci data[6], 4862306a36Sopenharmony_ci data[7], 4962306a36Sopenharmony_ci data[8]); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciSEC("fmod_ret/hid_bpf_device_event") 5562306a36Sopenharmony_ciint BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci s16 x; 5862306a36Sopenharmony_ci __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci if (!data) 6162306a36Sopenharmony_ci return 0; /* EPERM check */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci x = data[1] | (data[2] << 8); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci x = -x; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci data[1] = x & 0xFF; 6862306a36Sopenharmony_ci data[2] = (x >> 8) & 0xFF; 6962306a36Sopenharmony_ci return 0; 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciSEC("fmod_ret/hid_bpf_rdesc_fixup") 7362306a36Sopenharmony_ciint BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (!data) 7862306a36Sopenharmony_ci return 0; /* EPERM check */ 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci bpf_printk("rdesc: %02x %02x %02x", 8162306a36Sopenharmony_ci data[0], 8262306a36Sopenharmony_ci data[1], 8362306a36Sopenharmony_ci data[2]); 8462306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x", 8562306a36Sopenharmony_ci data[3], 8662306a36Sopenharmony_ci data[4], 8762306a36Sopenharmony_ci data[5]); 8862306a36Sopenharmony_ci bpf_printk(" %02x %02x %02x ...", 8962306a36Sopenharmony_ci data[6], 9062306a36Sopenharmony_ci data[7], 9162306a36Sopenharmony_ci data[8]); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /* 9462306a36Sopenharmony_ci * The original report descriptor contains: 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * 0x05, 0x01, // Usage Page (Generic Desktop) 30 9762306a36Sopenharmony_ci * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32 9862306a36Sopenharmony_ci * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35 9962306a36Sopenharmony_ci * 0x09, 0x30, // Usage (X) 38 10062306a36Sopenharmony_ci * 0x09, 0x31, // Usage (Y) 40 10162306a36Sopenharmony_ci * 10262306a36Sopenharmony_ci * So byte 39 contains Usage X and byte 41 Usage Y. 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * We simply swap the axes here. 10562306a36Sopenharmony_ci */ 10662306a36Sopenharmony_ci data[39] = 0x31; 10762306a36Sopenharmony_ci data[41] = 0x30; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return 0; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 113