evdev.c revision 14a810e6d87d03852b45bacf5d4444320d413b69
1/*
2 * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr>
3 * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "defs.h"
30
31#ifdef HAVE_LINUX_INPUT_H
32
33# include <linux/ioctl.h>
34# include <linux/input.h>
35# include "xlat/evdev_abs.h"
36# include "xlat/evdev_autorepeat.h"
37# include "xlat/evdev_ff_status.h"
38# include "xlat/evdev_ff_types.h"
39# include "xlat/evdev_keycode.h"
40# include "xlat/evdev_leds.h"
41# include "xlat/evdev_misc.h"
42# include "xlat/evdev_mtslots.h"
43# include "xlat/evdev_prop.h"
44# include "xlat/evdev_relative_axes.h"
45# include "xlat/evdev_snd.h"
46# include "xlat/evdev_switch.h"
47# include "xlat/evdev_sync.h"
48
49# ifndef SYN_MAX
50#  define SYN_MAX 0xf
51# endif
52
53static void
54decode_envelope(const struct ff_envelope *envelope)
55{
56	tprintf(", envelope={attack_length=%" PRIu16
57		", attack_level=%" PRIu16
58		", fade_length=%" PRIu16
59		", fade_level=%#x}",
60		envelope->attack_length,
61		envelope->attack_level,
62		envelope->fade_length,
63		envelope->fade_level);
64}
65
66static int
67ff_effect_ioctl(struct tcb *tcp, long arg)
68{
69	tprints(", ");
70
71	struct ff_effect ffe;
72
73	if (umove_or_printaddr(tcp, arg, &ffe))
74		return 1;
75
76	tprints("{type=");
77	printxval(evdev_ff_types, ffe.type, "FF_???");
78	tprintf(", id=%" PRIu16
79		", direction=%" PRIu16 ", ",
80		ffe.id,
81		ffe.direction);
82
83	if (abbrev(tcp)) {
84		tprints("...}");
85		return 1;
86	}
87
88	tprintf("trigger={button=%" PRIu16
89		", interval=%" PRIu16 "}"
90		", replay={length=%" PRIu16
91		", delay=%" PRIu16 "}",
92		ffe.trigger.button,
93		ffe.trigger.interval,
94		ffe.replay.length,
95		ffe.replay.delay);
96
97	switch (ffe.type) {
98		case FF_CONSTANT:
99			tprintf(", constant={level=%" PRId16,
100				ffe.u.constant.level);
101			decode_envelope(&ffe.u.constant.envelope);
102			tprints("}");
103			break;
104		case FF_RAMP:
105			tprintf(", ramp={start_level=%" PRId16
106				", end_level=%" PRId16,
107				ffe.u.ramp.start_level,
108				ffe.u.ramp.end_level);
109			decode_envelope(&ffe.u.ramp.envelope);
110			tprints("}");
111			break;
112		case FF_PERIODIC:
113			tprintf(", periodic={waveform=%" PRIu16
114				", period=%" PRIu16
115				", magnitude=%" PRId16
116				", offset=%" PRId16
117				", phase=%" PRIu16,
118				ffe.u.periodic.waveform,
119				ffe.u.periodic.period,
120				ffe.u.periodic.magnitude,
121				ffe.u.periodic.offset,
122				ffe.u.periodic.phase);
123			decode_envelope(&ffe.u.periodic.envelope);
124			tprintf(", custom_len=%u"
125				", custom_data=%#lx}",
126				ffe.u.periodic.custom_len,
127				(unsigned long) ffe.u.periodic.custom_data);
128			break;
129		case FF_RUMBLE:
130			tprintf(", rumble={strong_magnitude=%" PRIu16
131				", weak_magnitude=%" PRIu16 "}",
132				ffe.u.rumble.strong_magnitude,
133				ffe.u.rumble.weak_magnitude);
134			break;
135		default:
136			break;
137	}
138
139	tprints("}");
140
141	return 1;
142}
143
144static int
145abs_ioctl(struct tcb *tcp, long arg)
146{
147	tprints(", ");
148
149	struct input_absinfo absinfo;
150
151	if (!umove_or_printaddr(tcp, arg, &absinfo)) {
152		tprintf("{value=%u"
153			", minimum=%u, ",
154			absinfo.value,
155			absinfo.minimum);
156
157		if (!abbrev(tcp)) {
158			tprintf("maximum=%u"
159				", fuzz=%u"
160				", flat=%u",
161				absinfo.maximum,
162				absinfo.fuzz,
163				absinfo.flat);
164# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
165			tprintf(", resolution=%u",
166				absinfo.resolution);
167# endif
168		} else {
169			tprints("...");
170		}
171
172		tprints("}");
173	}
174
175	return 1;
176}
177
178static int
179keycode_ioctl(struct tcb *tcp, long arg)
180{
181	tprints(", ");
182
183	unsigned int keycode[2];
184
185	if (!umove_or_printaddr(tcp, arg, &keycode)) {
186		tprintf("[%u, ", keycode[0]);
187		printxval(evdev_keycode, keycode[1], "KEY_???");
188		tprints("]");
189	}
190
191	return 1;
192}
193
194# ifdef EVIOCGKEYCODE_V2
195static int
196keycode_V2_ioctl(struct tcb *tcp, long arg)
197{
198	tprints(", ");
199
200	struct input_keymap_entry ike;
201
202	if (umove_or_printaddr(tcp, arg, &ike))
203		return 1;
204
205	tprintf("{flags=%" PRIu8
206		", len=%" PRIu8 ", ",
207		ike.flags,
208		ike.len);
209
210	if (!abbrev(tcp)) {
211		unsigned int i;
212
213		tprintf("index=%" PRIu16 ", keycode=", ike.index);
214		printxval(evdev_keycode, ike.keycode, "KEY_???");
215		tprints(", scancode=[");
216		for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
217			if (i > 0)
218				tprints(", ");
219			tprintf("%" PRIx8, ike.scancode[i]);
220		}
221		tprints("]");
222	} else {
223		tprints("...");
224	}
225
226	tprints("}");
227
228	return 1;
229}
230# endif /* EVIOCGKEYCODE_V2 */
231
232static int
233getid_ioctl(struct tcb *tcp, long arg)
234{
235	tprints(", ");
236
237	struct input_id id;
238
239	if (!umove_or_printaddr(tcp, arg, &id))
240		tprintf("{ID_BUS=%" PRIu16
241			", ID_VENDOR=%" PRIu16
242			", ID_PRODUCT=%" PRIu16
243			", ID_VERSION=%" PRIu16 "}",
244			id.bustype,
245			id.vendor,
246			id.product,
247			id.version);
248
249	return 1;
250}
251
252static int
253decode_bitset(struct tcb *tcp, long arg, const struct xlat decode_nr[],
254	      const unsigned int max_nr, const char *dflt)
255{
256	tprints(", ");
257
258	unsigned int size;
259	if ((unsigned long) tcp->u_rval > max_nr)
260		size = max_nr;
261	else
262		size = tcp->u_rval;
263	char decoded_arg[size];
264
265	if (umove_or_printaddr(tcp, arg, &decoded_arg))
266		return 1;
267
268	tprints("[");
269
270	int bit_displayed = 0;
271	int i = next_set_bit(decoded_arg, 0, size);
272	if (i < 0) {
273		tprints(" 0 ");
274	} else {
275		printxval(decode_nr, i, dflt);
276
277		while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
278			if (abbrev(tcp) && bit_displayed >= 3) {
279				tprints(", ...");
280				break;
281			}
282			tprints(", ");
283			printxval(decode_nr, i, dflt);
284			bit_displayed++;
285		}
286	}
287
288	tprints("]");
289
290	return 1;
291}
292
293# ifdef EVIOCGMTSLOTS
294static int
295mtslots_ioctl(struct tcb *tcp, const unsigned int code, long arg)
296{
297	const size_t size = _IOC_SIZE(code) / sizeof(int32_t);
298	if (!size)
299		return 0;
300
301	int32_t buffer[size];
302
303	if (!verbose(tcp) || umove(tcp, arg, &buffer) < 0)
304		return 0;
305
306	tprints(", {code=");
307	printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
308
309	unsigned int i;
310	tprints(", values=[");
311
312	for (i = 1; i < ARRAY_SIZE(buffer); i++)
313		tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
314
315	tprints("]}");
316	return 1;
317}
318# endif /* EVIOCGMTSLOTS */
319
320# if defined EVIOCGREP || defined EVIOCSREP
321static int
322repeat_ioctl(struct tcb *tcp, long arg)
323{
324	tprints(", ");
325	printpair_int(tcp, arg, "%u");
326	return 1;
327}
328# endif /* EVIOCGREP || EVIOCSREP */
329
330static int
331bit_ioctl(struct tcb *tcp, const unsigned int ev_nr, const long arg)
332{
333	switch (ev_nr) {
334		case EV_SYN:
335			return decode_bitset(tcp, arg, evdev_sync,
336					SYN_MAX, "SYN_???");
337		case EV_KEY:
338			return decode_bitset(tcp, arg, evdev_keycode,
339					KEY_MAX, "KEY_???");
340		case EV_REL:
341			return decode_bitset(tcp, arg, evdev_relative_axes,
342					REL_MAX, "REL_???");
343		case EV_ABS:
344			return decode_bitset(tcp, arg,
345					evdev_abs, ABS_MAX, "ABS_???");
346		case EV_MSC:
347			return decode_bitset(tcp, arg,
348					evdev_misc, MSC_MAX, "MSC_???");
349# ifdef EV_SW
350		case EV_SW:
351			return decode_bitset(tcp, arg,
352					evdev_switch, SW_MAX, "SW_???");
353# endif
354		case EV_LED:
355			return decode_bitset(tcp, arg,
356					evdev_leds, LED_MAX, "LED_???");
357		case EV_SND:
358			return decode_bitset(tcp, arg,
359					evdev_snd, SND_MAX, "SND_???");
360		case EV_REP:
361			return decode_bitset(tcp, arg, evdev_autorepeat,
362					REP_MAX, "REP_???");
363		case EV_FF:
364			return decode_bitset(tcp, arg, evdev_ff_types,
365					FF_MAX, "FF_???");
366		case EV_PWR:
367			printnum_int(tcp, arg, "%d");
368			return 1;
369		case EV_FF_STATUS:
370			return decode_bitset(tcp, arg, evdev_ff_status,
371					FF_STATUS_MAX, "FF_STATUS_???");
372		default:
373			return 0;
374	}
375}
376
377static int
378evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
379{
380	if (syserror(tcp))
381		return 0;
382
383	/* fixed-number fixed-length commands */
384	switch (code) {
385		case EVIOCGVERSION:
386			tprints(", ");
387			printnum_int(tcp, arg, "%" PRIx32);
388			return 1;
389		case EVIOCGEFFECTS:
390			tprints(", ");
391			printnum_int(tcp, arg, "%" PRIu32);
392			return 1;
393		case EVIOCGID:
394			return getid_ioctl(tcp, arg);
395# ifdef EVIOCGREP
396		case EVIOCGREP:
397			return repeat_ioctl(tcp, arg);;
398# endif
399		case EVIOCGKEYCODE:
400			return keycode_ioctl(tcp, arg);
401# ifdef EVIOCGKEYCODE_V2
402		case EVIOCGKEYCODE_V2:
403			return keycode_V2_ioctl(tcp, arg);
404# endif
405	}
406
407	/* fixed-number variable-length commands */
408	switch (_IOC_NR(code)) {
409# ifdef EVIOCGMTSLOTS
410		case _IOC_NR(EVIOCGMTSLOTS(0)):
411			return mtslots_ioctl(tcp, code, arg);
412# endif
413		case _IOC_NR(EVIOCGNAME(0)):
414		case _IOC_NR(EVIOCGPHYS(0)):
415		case _IOC_NR(EVIOCGUNIQ(0)):
416			tprints(", ");
417			printstr(tcp, arg, tcp->u_rval - 1);
418			return 1;
419# ifdef EVIOCGPROP
420		case _IOC_NR(EVIOCGPROP(0)):
421			return decode_bitset(tcp, arg,
422					evdev_prop, INPUT_PROP_MAX, "PROP_???");
423# endif
424		case _IOC_NR(EVIOCGSND(0)):
425			return decode_bitset(tcp, arg,
426					evdev_snd, SND_MAX, "SND_???");
427# ifdef EVIOCGSW
428		case _IOC_NR(EVIOCGSW(0)):
429			return decode_bitset(tcp, arg,
430					evdev_switch, SW_MAX, "SW_???");
431# endif
432		case _IOC_NR(EVIOCGKEY(0)):
433			return decode_bitset(tcp, arg,
434					evdev_keycode, KEY_MAX, "KEY_???");
435		case _IOC_NR(EVIOCGLED(0)):
436			return decode_bitset(tcp, arg,
437					evdev_leds, LED_MAX, "LED_???");
438	}
439
440	/* multi-number fixed-length commands */
441	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
442		return abs_ioctl(tcp, arg);
443
444	/* multi-number variable-length commands */
445	if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
446		return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
447
448	return 0;
449}
450
451static int
452evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
453{
454	/* fixed-number fixed-length commands */
455	switch (code) {
456# ifdef EVIOCSREP
457		case EVIOCSREP:
458			return repeat_ioctl(tcp, arg);
459# endif
460		case EVIOCSKEYCODE:
461			return keycode_ioctl(tcp, arg);
462# ifdef EVIOCSKEYCODE_V2
463		case EVIOCSKEYCODE_V2:
464			return keycode_V2_ioctl(tcp, arg);
465# endif
466		case EVIOCSFF:
467			return ff_effect_ioctl(tcp, arg);
468		case EVIOCRMFF:
469			tprintf(", %d", (int) arg);
470			return 1;
471		case EVIOCGRAB:
472# ifdef EVIOCREVOKE
473		case EVIOCREVOKE:
474# endif
475			tprintf(", %lu", arg);
476			return 1;
477# ifdef EVIOCSCLOCKID
478		case EVIOCSCLOCKID:
479			tprints(", ");
480			printnum_int(tcp, arg, "%u");
481			return 1;
482# endif
483	}
484
485	/* multi-number fixed-length commands */
486	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
487		return abs_ioctl(tcp, arg);
488
489	return 0;
490}
491
492int
493evdev_ioctl(struct tcb *tcp, const unsigned int code, long arg)
494{
495	switch(_IOC_DIR(code)) {
496		case _IOC_READ:
497			if (entering(tcp))
498				return 0;
499			return evdev_read_ioctl(tcp, code, arg);
500		case _IOC_WRITE:
501			return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
502		default:
503			return RVAL_DECODED;
504	}
505}
506
507#endif /* HAVE_LINUX_INPUT_H */
508