1 /*
2 * key_test.c -- key test application
3 *
4 * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
5 * Author: Bin Yang <yangbin@rock-chips.com>
6 * Author: Panzhenzhuan Wang <randy.wang@rock-chips.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <linux/input.h>
27 #include <signal.h>
28 #include <unistd.h>
29
30 #define LOG_TAG "key_test"
31 #include "common.h"
32
33 #define KEY_INPUT_EVENT "/dev/input/event0"
34
35 #define KEY_INPUT_EVENT0 "/dev/input/event0"
36 #define KEY_INPUT_EVENT1 "/dev/input/event1"
37 #define KEY_INPUT_EVENT2 "/dev/input/event2"
38
39 #define KEY_TIMEOUT_DOWN 60
40 #define KEY_TIMEOUT_UP 5
41
42 typedef struct KEY_BOARD_st {
43 char *key_name;
44 int key_value;
45 int key_press_flag;
46 int key_cnt;
47 } KEY_st;
48
49
50 #ifdef PCBA_PX3SE
51 #define KEY_VALID_NUM 5 //PX3SE V11
52
53 /* key code */
54 #define KEY_HOME_CODE 102
55 #define KEY_MENU_CODE 59
56 #define KEY_ESC_CODE 158
57 #define KEY_VOLUP_CODE 115
58 #define KEY_VOLDOWN_CODE 114
59
60 KEY_st gkey_test[KEY_VALID_NUM] = {
61
62 {"vol+", KEY_VOLUMEUP, 0, 0},
63 {"vol-", KEY_VOLUMEDOWN, 0, 0},
64 {"menu", KEY_MENU, 0, 0},
65 {"esc", KEY_F1, 0, 0},
66 {"home", KEY_HOME, 0, 0},
67 // {"resv", 212, 0},
68 };
69 #endif
70
71 #ifdef PCBA_3308
72 #define KEY_VALID_NUM 6 //3308 evb v11
73
74 /* key code */
75 #define KEY_VOLUP_CODE 115
76 #define KEY_VOLDN_CODE 114
77 #define KEY_MUTE_CODE 113
78 #define KEY_POWER 116
79 #define KEY_PLAY_CODE 207
80 #define KEY_MODE_CODE 373
81
82 KEY_st gkey_test[KEY_VALID_NUM] = {
83 {"VOL+", KEY_VOLUMEUP, 0},
84 {"VOL-", KEY_VOLUMEDOWN, 0},
85 {"MICMUTE", KEY_MICMUTE, 0},
86 {"PLAY", KEY_PLAY, 0},
87 {"MODE", KEY_MODE, 0},
88 {"POWER", KEY_POWER, 0},
89
90 };
91
92 #endif
93
94 #ifdef PCBA_3229GVA
95 //TODO: According to 3229 real board to add test code.
96
97 #endif
98
99 #ifdef PCBA_1808
100 //TODO:According to 1808 real board to add test code.
101 #define KEY_VALID_NUM 2 //RK_EVB_RK1808_LP3D8P132SD6_V11
102
103 /* key code */
104 #define KEY_VOLUP_CODE 115
105 #define KEY_VOLDN_CODE 114
106
107 KEY_st gkey_test[KEY_VALID_NUM] = {
108 {"VOL+", KEY_VOLUMEUP, 0},
109 {"VOL-", KEY_VOLUMEDOWN, 0},
110 };
111
112 #endif
113
114 #ifdef PCBA_PX30
115 //TODO:According to PX30 real board to add test code.
116 #define KEY_VALID_NUM 0
117
118 #endif
119
120 #ifdef PCBA_3288
121 //TODO:According to 3288 real board to add test code.
122 #define KEY_VALID_NUM 0
123
124 #endif
125
126 #ifdef PCBA_3328
127 //TODO:According to 3328 real board to add test code.
128 #define KEY_VALID_NUM 0
129
130 #endif
131
132 #ifdef PCBA_3326
133 //TODO:According to 3326 real board to add test code.
134 #define KEY_VALID_NUM 0
135 #endif
136
137 #ifdef PCBA_3399
138 //TODO:According to 3399 real board to add test code.
139 #define KEY_VALID_NUM 0
140 #endif
141
142 #ifdef PCBA_3399PRO
143 //TODO:According to 3399 PRO real board to add test code.
144 #define KEY_VALID_NUM 0
145 #endif
146
147 #ifdef PCBA_1126_1109
148 //TODO:According to RV1126 / RV1109 real board to add test code.
149 #define KEY_VALID_NUM 0
150 #endif
151
152 #ifdef PCBA_356X
153 //TODO:According to 356X board to add test code.
154 #define KEY_VALID_NUM 2
155
156 KEY_st gkey_test[KEY_VALID_NUM] = {
157 {"VOL+", KEY_VOLUMEUP, 0},
158 {"VOL-", KEY_VOLUMEDOWN, 0},
159 };
160 #endif
161
162 #ifdef PCBA_3588
163 //TODO:According to 3588 real board to add test code.
164 #define KEY_VALID_NUM 2
165
166 KEY_st gkey_test[KEY_VALID_NUM] = {
167 {"VOL+", KEY_VOLUMEUP, 0},
168 {"VOL-", KEY_VOLUMEDOWN, 0},
169 };
170 #endif
171
172 static char result[COMMAND_VALUESIZE] = RESULT_FAIL;
173
isAllKeyPressed(KEY_st * key_array)174 static int isAllKeyPressed(KEY_st *key_array)
175 {
176 int i = 0;
177
178 if (key_array == NULL)
179 return 0;
180
181 for (i = 0; i < KEY_VALID_NUM; i++) {
182 if (key_array[i].key_press_flag)
183 continue;
184 else
185 break;
186 }
187
188 if (i == KEY_VALID_NUM) {
189 log_info("########### All key had pressed!!! ######### \n");
190 return 1;
191 } else
192 return 0;
193 }
194
dumpKeyPressInfo(KEY_st * key_array)195 static void dumpKeyPressInfo(KEY_st *key_array)
196 {
197 int i = 0;
198
199 if (key_array == NULL)
200 return;
201
202 for (i = 0; i < KEY_VALID_NUM; i++) {
203 log_info("KEYNAME : %s: \t KEY_press: %d \n", key_array[i].key_name,
204 key_array[i].key_press_flag);
205 }
206 }
207
assemble_info(char * key_info_buf,int buf_size,int key_index)208 static char *assemble_info(char *key_info_buf, int buf_size, int key_index)
209 {
210 int error_code = 0;
211 char msg[32] = {0};
212
213 memset(msg, sizeof(msg), 0);
214
215 if (key_info_buf == NULL)
216 return NULL;
217
218 memset(key_info_buf, buf_size, 0);
219
220 snprintf(msg, sizeof(msg), "key name:%s", gkey_test[key_index].key_name);
221 #ifdef PCBA_PX3SE
222 snprintf(key_info_buf, buf_size, "x<%s>,<%s>,<%d>", msg, RESULT_KEY_PRESS, \
223 gkey_test[key_index].key_cnt);
224 #else
225 snprintf(key_info_buf, buf_size, "x<%s>,<%s>,<%d>", msg, RESULT_KEY_PRESS, error_code);
226 #endif
227
228 return key_info_buf;
229 }
230
save_scan_result(char * result_buf)231 static int save_scan_result(char *result_buf)
232 {
233 int fd = -1;
234 int ret = 0;
235 char *bin_name = "echo_key_test";
236 char result_filename[COMMAND_VALUESIZE] = {0};
237
238 snprintf(result_filename, sizeof(result_filename),
239 "%s/%s_result",
240 TEST_RESULT_SAVE_PATH,
241 bin_name);
242
243 fd = open(result_filename, O_CREAT | O_WRONLY | O_TRUNC);
244
245 if (fd < 0) {
246 log_err("open %s fail, errno = %d\n", result_filename, errno);
247 ret = errno;
248 }
249
250 //assert(strlen(result_buf) <= COMMAND_VALUESIZE);
251 int w_len = write(fd, result_buf, strlen(result_buf));
252
253 if (w_len <= 0) {
254 log_err("Write %s fail, errno = %d\n", result_filename, errno);
255 ret = errno;
256 }
257
258 log_info("\t -------key_test_result: %s -------\n", result_buf);
259 log_info("########## write to %s len %d ##########\n", result_filename, w_len);
260
261 close(fd);
262
263 return ret;
264 }
265
266
key_wait_event(int maxfd,fd_set * readfds,int time)267 static int key_wait_event(int maxfd, fd_set *readfds, int time)
268 {
269 int ret;
270 struct timeval timeout;
271
272 FD_ZERO(readfds);
273 FD_SET(maxfd, readfds);
274 timeout.tv_sec = time;
275 timeout.tv_usec = 0;
276 ret = select(maxfd + 1, readfds, NULL, NULL, &timeout);
277 switch (ret) {
278 case -1:
279 return -1;
280 case 0:
281 log_err("select timeout(%ds)\n", time);
282 return 1;
283 default:
284 if (FD_ISSET(maxfd, readfds)) {
285 FD_CLR (maxfd, readfds);
286 return 0;
287 }
288 break;
289 }
290
291 return -1;
292 }
293
key_event_read(int fd,struct input_event * buf)294 static int key_event_read(int fd, struct input_event *buf)
295 {
296 int read_len = 0;
297
298 read_len = read(fd, buf, sizeof(*buf));
299 if (read_len < 0) {
300 if ((errno != EINTR) && (errno != EAGAIN))
301 return 0;
302 return -1;
303 }
304
305 if (buf->type)
306 return 1;
307
308 return 0;
309 }
310
key_result_send(int sign_no)311 static int key_result_send(int sign_no)
312 {
313 int err_code =0;
314 printf("====================function : %s start =================\n",__func__);
315
316 // if (!memcmp(result, RESULT_PASS, strlen(RESULT_PASS)))
317 // err_code = KEY_PROC_ERR;
318
319 strcpy(result, RESULT_VERIFY);
320 send_msg_to_server("key_test", result, err_code);
321
322 printf("====================function : %s finished =================\n",__func__);
323 exit(0);
324 }
325
326 #define MAX_INPUT_COUNT (4)
327
main(int argc,char ** argv)328 int main(int argc, char **argv)
329 {
330 int fd;
331 int ret = 0;
332 int err_code = 0;
333 int time = KEY_TIMEOUT_DOWN;
334 fd_set rdfds;
335 struct input_event key_event;
336 int modifier;
337 char buf[COMMAND_VALUESIZE] = "key_test";
338 int idx = 0;
339 int fds[MAX_INPUT_COUNT] = {0};
340 char path[64];
341 int fdcount = 0;
342 int max_fd = 0;
343 int i, k;
344 struct timeval sel_timeout_tv;
345
346 log_info("key test process start...\n");
347 signal(SIGTERM, (__sighandler_t)key_result_send);
348
349 for (i = 0; i < MAX_INPUT_COUNT; i++) {
350 sprintf(path, "/dev/input/event%d", i);
351 fd = open(path, O_RDONLY | O_NOCTTY);
352
353 if (fd < 0) {
354 log_err("open fail:%s\n", strerror(errno));
355 continue;
356 }
357
358 fds[fdcount++] = fd;
359 }
360
361 if (fdcount < 1) {
362 err_code = KEY_OPEN_FAIL;
363 goto EXIT;
364 }
365
366 for (i = 0 ; i < fdcount; i++)
367 if (max_fd < fds[i])
368 max_fd = fds[i];
369
370 while (1) {
371 FD_ZERO(&rdfds);
372 sel_timeout_tv.tv_sec = time;
373 sel_timeout_tv.tv_usec = 0;
374
375 for (i = 0 ; i < fdcount; i++)
376 FD_SET(fds[i], &rdfds);
377
378 if (isAllKeyPressed(gkey_test))
379 break;
380
381 ret = select(max_fd + 1, &rdfds, NULL, NULL, &sel_timeout_tv);
382 if (ret > 0) {
383 k = 0;
384
385 while (k < fdcount) {
386 int fd = fds[k++];
387
388 if (FD_ISSET(fd, &rdfds)) {
389 ret = key_event_read(fd, &key_event);
390
391 if (ret > 0) {
392 if (key_event.value) {
393 log_info("key(%d) is down\n", key_event.code);
394 time = KEY_TIMEOUT_UP;
395 } else {
396 log_info("key(%d) is up\n", key_event.code);
397 time = KEY_TIMEOUT_DOWN;
398
399 for (idx = 0; idx < KEY_VALID_NUM; idx ++) {
400 if (key_event.code == gkey_test[idx].key_value) {
401 if (gkey_test[idx].key_press_flag == 0) {
402 gkey_test[idx].key_press_flag = 1;
403 #ifdef PCBA_PX3SE
404 gkey_test[idx].key_cnt = 1;
405 #endif
406 } else {
407 #ifdef PCBA_PX3SE
408 gkey_test[idx].key_cnt++;
409 printf("\t\t %s : %d \n\n", gkey_test[idx].key_name,gkey_test[idx].key_cnt);
410 #endif
411 }
412
413 assemble_info(buf, COMMAND_VALUESIZE, idx);
414 save_scan_result(buf);
415 } else
416 continue;
417 }
418 #ifndef PCBA_PX3SE
419 if (isAllKeyPressed(gkey_test)) {
420 log_info(" ======== key test is over ========= \n");
421 strcpy(result, RESULT_VERIFY);
422 break;
423 }
424 #endif
425 }
426 }
427 }
428 }
429 } else if (ret == 0) {
430 log_err("wait key event fail, errno=%d\n", errno);
431
432 if (idx != KEY_VALID_NUM) {
433 int i = 0;
434
435 for (i = 0; i < KEY_VALID_NUM; ++i) {
436 if (gkey_test[i].key_press_flag == 0) {
437 strcat(buf, gkey_test[i].key_name);
438 strcat(buf, " ");
439 }
440 }
441 strcat(buf, " NOT PRESS!");
442 }
443
444 err_code = KEY_EVENT_TIMEOUT;
445 goto EXIT;
446 }
447 }
448
449 //snprintf(buf, sizeof(buf), "key_code:%d", key_event.code);
450 dumpKeyPressInfo(gkey_test);
451 EXIT:
452 sleep(1);
453 memset(buf, 0 , sizeof(buf));
454
455 if (!err_code)
456 strcpy(result, RESULT_VERIFY);
457
458 send_msg_to_server(buf, result, err_code);
459
460 return err_code;
461 }
462
463