1976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda/*
2976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com>
3976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda *
4976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * This program is free software; you can redistribute it and/or
5976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * modify it under the terms of the GNU General Public License as
6976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * published by the Free Software Foundation; either version 2 of
7976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * the License, or (at your option) any later version.
8976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda *
9976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * This program is distributed in the hope that it would be useful,
10976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * but WITHOUT ANY WARRANTY; without even the implied warranty of
11976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * GNU General Public License for more details.
13976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda *
14976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * You should have received a copy of the GNU General Public License
15976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * along with this program; if not, write the Free Software Foundation,
16976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda */
18976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
19976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda /*
20976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda  *  Create a virtual device (mouse), send events to /dev/uinput
21976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda  *  and check that the events are well received in /dev/input/eventX
22976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda  */
23976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
24976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#include <linux/input.h>
25976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
26976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#include "input_helper.h"
27976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#include "test.h"
28976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#include "safe_macros.h"
29976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#include "lapi/fcntl.h"
30976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
31976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda#define NB_TEST 20
32976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
33976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void setup(void);
34976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void send_events(void);
35976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int verify_data(struct input_event *iev, int nb);
36976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int check_events(void);
37976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void cleanup(void);
38976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
39976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int fd;
40976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int fd2;
41976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
42976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydachar *TCID = "input01";
43976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
44976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydaint main(int ac, char **av)
45976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
46976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	int lc;
47976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	int pid;
48976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
49976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	tst_parse_opts(ac, av, NULL, NULL);
50976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
51976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	setup();
52976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
53976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	for (lc = 0; TEST_LOOPING(lc); ++lc) {
54976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		pid = tst_fork();
55976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
56976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		switch (pid) {
57976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		case 0:
58976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			send_events();
59976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			exit(0);
60976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		case -1:
61976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
62976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		default:
63976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			if (check_events())
64976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda				tst_resm(TFAIL, "Wrong data read from eventX");
65976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			else
66976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda				tst_resm(TPASS, "Data received from eventX");
67976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		break;
68976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
69976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
70976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		SAFE_WAITPID(NULL, pid, NULL, 0);
71976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
72976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
73976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	cleanup();
74976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	tst_exit();
75976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
76976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
77976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void setup(void)
78976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
79976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	tst_require_root();
80976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
81976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	fd = open_uinput();
82976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	setup_mouse_events(fd);
83976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	create_device(fd);
84976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
85976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	fd2 = open_device();
86976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
87976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
88976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void send_events(void)
89976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
90976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	int nb;
91976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
92976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	for (nb = 0; nb < NB_TEST; ++nb) {
93976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		send_rel_move(fd, 10, 1);
94976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		usleep(1000);
95976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
96976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
97976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
98976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int check_events(void)
99976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
100976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	int nb, rd;
101976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	unsigned int i;
102976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	struct input_event iev[64];
103976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
104976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	nb = 0;
105976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
106976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	while (nb < NB_TEST * 3) {
107976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		rd = read(fd2, iev, sizeof(iev));
108976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
109976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (rd < 0)
110976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_brkm(TBROK | TERRNO, cleanup, "read()");
111976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
112976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (rd == 0 || rd % sizeof(struct input_event)) {
113976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_resm(TINFO, "read() returned unexpected %i", rd);
114976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
115976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
116976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
117976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		for (i = 0; i < rd / sizeof(struct input_event); i++) {
118976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			if (verify_data(&iev[i], nb++))
119976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda				return 1;
120976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
121976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
122976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
123976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	return 0;
124976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
125976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
126976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic int verify_data(struct input_event *iev, int nb)
127976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
128976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	if (nb % 3 == 0) {
129976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->type != EV_REL) {
130976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_resm(TINFO,
131976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         "%i: Unexpected event type %i expected %i",
132976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         nb, iev->type, EV_REL);
133976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
134976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
135976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
136976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->code != REL_X)
137976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
138976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
139976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->value != 10)
140976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
141976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
142976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		return 0;
143976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
144976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
145976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	if (nb % 3 == 1) {
146976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->type != EV_REL) {
147976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_resm(TINFO,
148976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         "%i: Unexpected event type %i expected %i",
149976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         nb, iev->type, EV_REL);
150976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
151976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
152976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
153976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->code != REL_Y)
154976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
155976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
156976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->value != 1)
157976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
158976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
159976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		return 0;
160976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
161976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
162976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	if (nb % 3 == 2) {
163976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->type != EV_SYN) {
164976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			tst_resm(TINFO,
165976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         "%i: Unexpected event type %i expected %i",
166976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			         nb, iev->type, EV_SYN);
167976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
168976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		}
169976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
170976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->code != 0)
171976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
172976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
173976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		if (iev->value != 0)
174976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda			return 1;
175976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
176976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		return 0;
177976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	}
178976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	return 1;
179976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
180976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
181976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnydastatic void cleanup(void)
182976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda{
183976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	if (fd2 > 0 && close(fd2))
184976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda		tst_resm(TWARN | TERRNO, "close(fd2)");
185976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda
186976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda	destroy_device(fd);
187976c9c736c3afbbefe14930601aa5972da1709f9Cedric Hnyda}
188