1 /*
2 * echo_ir_test.c -- Infrared ray test application
3 *
4 * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
5 * Author: chad.ma <chad.ma@rock-chips.com>
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include <assert.h>
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 "IR_test"
31 #include "common.h"
32
33 #define IR_INPUT_EVENT "/dev/input/event0"
34
35 #define IR_TIMEOUT_DOWN 60
36 #define IR_TIMEOUT_UP 5
37
38
39 /* TV Remote Controler
40 * here accord kernel ir drivers keymap,./driver/media/rc/keymaps/rc-360.c
41 * just defien 10 keys.
42 */
43 #define IR_VALID_NUM 10
44
45 typedef struct IR_CONTRALOR_st {
46 char *key_name;
47 int key_value;
48 int key_press_flag;
49 } IR_st;
50
51
52 IR_st gIR_test[IR_VALID_NUM] = {
53 {"NUM_0", KEY_0, 0},
54 {"NUM_1", KEY_1, 0},
55 {"NUM_2", KEY_2, 0},
56 {"NUM_3", KEY_3, 0},
57 {"NUM_4", KEY_4, 0},
58 {"NUM_5", KEY_5, 0},
59 {"NUM_6", KEY_6, 0},
60 {"NUM_7", KEY_7, 0},
61 {"NUM_8", KEY_8, 0},
62 {"NUM_9", KEY_9, 0},
63
64 };
isAllIRKeyPressed(IR_st * key_array)65 static int isAllIRKeyPressed(IR_st *key_array)
66 {
67 int i = 0;
68
69 if (key_array == NULL)
70 return 0;
71
72 for (i = 0; i < IR_VALID_NUM; i++) {
73 if (key_array[i].key_press_flag)
74 continue;
75 else
76 break;
77 }
78
79 if (i == IR_VALID_NUM) {
80 log_info("########### All IR key had pressed!!! ######### \n");
81 return 1;
82 } else
83 return 0;
84 }
85
dumpKeyPressInfo(IR_st * key_array)86 static void dumpKeyPressInfo(IR_st *key_array)
87 {
88 int i = 0;
89
90 if (key_array == NULL)
91 return;
92
93 for (i = 0; i < IR_VALID_NUM; i++) {
94 log_info("KEYNAME : %s: \t KEY_press: %d \n", key_array[i].key_name,
95 key_array[i].key_press_flag);
96 }
97 }
98
assemble_info(char * key_info_buf,int buf_size,int key_index)99 static char *assemble_info(char *key_info_buf, int buf_size, int key_index)
100 {
101 int error_code = 0;
102 char msg[32] = {0};
103
104 memset(msg, sizeof(msg), 0);
105
106 if (key_info_buf == NULL)
107 return NULL;
108
109 memset(key_info_buf, buf_size, 0);
110
111 snprintf(msg, sizeof(msg), "ir-key name:%s", gIR_test[key_index].key_name);
112 snprintf(key_info_buf, buf_size, "x<%s>,<%s>,<%d>", msg, RESULT_KEY_PRESS, error_code);
113
114 return key_info_buf;
115 }
save_scan_result(char * result_buf)116 static int save_scan_result(char *result_buf)
117 {
118 int fd = -1;
119 int ret = 0;
120 char *bin_name = "echo_ir_test";
121 char result_filename[COMMAND_VALUESIZE] = {0};
122
123 snprintf(result_filename, sizeof(result_filename),
124 "%s/%s_result",
125 TEST_RESULT_SAVE_PATH,
126 bin_name);
127
128 fd = open(result_filename, O_CREAT | O_WRONLY | O_TRUNC);
129
130 if (fd < 0) {
131 log_err("open %s fail, errno = %d\n", result_filename, errno);
132 ret = errno;
133 }
134
135 assert(strlen(result_buf) <= COMMAND_VALUESIZE);
136 int w_len = write(fd, result_buf, strlen(result_buf));
137
138 if (w_len <= 0) {
139 log_err("Write %s fail, errno = %d\n", result_filename, errno);
140 ret = errno;
141 }
142
143 log_info("\t -------IR_test_result: %s -------\n", result_buf);
144 log_info("########## write to %s len %d ##########\n", result_filename, w_len);
145
146 close(fd);
147
148 return ret;
149 }
150
151 static char result[COMMAND_VALUESIZE] = RESULT_FAIL;
152
ir_wait_event(int maxfd,fd_set * readfds,int time)153 static int ir_wait_event(int maxfd, fd_set *readfds, int time)
154 {
155 int ret;
156 struct timeval timeout;
157
158 FD_ZERO(readfds);
159 FD_SET(maxfd, readfds);
160 timeout.tv_sec = time;
161 timeout.tv_usec = 0;
162 ret = select(maxfd + 1, readfds, NULL, NULL, &timeout);
163
164 switch (ret) {
165 case -1:
166 return -1;
167
168 case 0:
169 log_err("select timeout(%ds)\n", time);
170 return 1;
171
172 default:
173 if (FD_ISSET(maxfd, readfds)) {
174 FD_CLR (maxfd, readfds);
175 return 0;
176 }
177
178 break;
179 }
180
181 return -1;
182 }
183
ir_event_read(int fd,struct input_event * buf)184 static int ir_event_read(int fd, struct input_event *buf)
185 {
186 int read_len = 0;
187
188 read_len = read(fd, buf, sizeof(*buf));
189
190 if (read_len < 0) {
191 if ((errno != EINTR) && (errno != EAGAIN))
192 return 0;
193
194 return -1;
195 }
196
197 if (buf->type)
198 return 1;
199
200 return 0;
201 }
202
203 //* 信号处理函数,在结束进程前,为按键测试返回一个结果;
ir_result_send(int sign_no)204 static int ir_result_send(int sign_no)
205 {
206 int err_code = 0;
207 printf("====================function : %s start =================\n", __func__);
208
209 if (!memcmp(result, RESULT_VERIFY, strlen(RESULT_VERIFY)))
210 err_code = IR_QUERY_FAIL;
211
212 send_msg_to_server("key_test", result, err_code);
213
214 printf("====================function : %s finished =================\n", __func__);
215 exit(0);
216 }
217
218 #define MAX_INPUT_COUNT (4)
main(int argc,char ** argv)219 int main(int argc, char **argv)
220 {
221 int fd;
222 int ret = 0;
223 int err_code = 0;
224 int time = IR_TIMEOUT_DOWN;
225 fd_set rdfds;
226 struct input_event key_event;
227 int modifier;
228 char buf[COMMAND_VALUESIZE] = "ir_test";
229 int idx = 0;
230 int fds[MAX_INPUT_COUNT] = {0};
231 char path[64];
232 int fdcount = 0;
233 int max_fd = 0;
234 int i, k;
235 struct timeval sel_timeout_tv;
236
237 log_info("key test process start...\n");
238 //* 注册信号处理函数
239 signal(SIGTERM, (__sighandler_t)ir_result_send);
240
241 for (i = 0; i < MAX_INPUT_COUNT; i++) {
242 sprintf(path, "/dev/input/event%d", i);
243 fd = open(path, O_RDONLY | O_NOCTTY);
244
245 if (fd < 0) {
246 log_err("open fail:%s\n", strerror(errno));
247 continue;
248 }
249
250 fds[fdcount++] = fd;
251 }
252
253 if (fdcount < 1) {
254 err_code = IR_OPEN_FAIL;
255 goto EXIT;
256 }
257
258 for (i = 0 ; i < fdcount; i++)
259 if (max_fd < fds[i])
260 max_fd = fds[i];
261
262 while (1) {
263 FD_ZERO(&rdfds);
264 sel_timeout_tv.tv_sec = time;
265 sel_timeout_tv.tv_usec = 0;
266
267 for (i = 0 ; i < fdcount; i++)
268 FD_SET(fds[i], &rdfds);
269
270 if (isAllIRKeyPressed(gIR_test))
271 break;
272
273 ret = select(max_fd + 1, &rdfds, NULL, NULL, &sel_timeout_tv);
274 if (ret > 0) {
275 k = 0;
276
277 while (k < fdcount) {
278 int fd = fds[k++];
279
280 if (FD_ISSET(fd, &rdfds)) {
281 ret = ir_event_read(fd, &key_event);
282
283 if (ret > 0) {
284 if (key_event.value) {
285 log_info("key(%d) is down\n", key_event.code);
286 time = IR_TIMEOUT_UP;
287 } else {
288 log_info("key(%d) is up\n", key_event.code);
289 time = IR_TIMEOUT_DOWN;
290
291 for (idx = 0; idx < IR_VALID_NUM; idx ++) {
292 if (key_event.code == gIR_test[idx].key_value) {
293 if (gIR_test[idx].key_press_flag == 0)
294 gIR_test[idx].key_press_flag = 1;
295
296 assemble_info(buf, COMMAND_VALUESIZE, idx);
297 save_scan_result(buf);
298 } else
299 continue;
300 }
301
302 if (isAllIRKeyPressed(gIR_test)) {
303 //int i =0;
304 log_info(" ======== key test is over ========= \n");
305 strcpy(result, RESULT_VERIFY);
306 break;
307 }
308 }
309 }
310 }
311 }
312 } else if (ret == 0) {
313 log_err("wait key event fail, errno=%d\n", errno);
314
315 if (idx != IR_VALID_NUM) {
316 int i = 0;
317
318 for (i = 0; i < IR_VALID_NUM; ++i) {
319 if (gIR_test[i].key_press_flag == 0) {
320 strcat(buf, gIR_test[i].key_name);
321 strcat(buf, " ");
322 }
323 }
324
325 strcat(buf, " NOT PRESS!");
326 }
327
328 err_code = IR_EVENT_TIMEOUT;
329 goto EXIT;
330 }
331 }
332
333 //snprintf(buf, sizeof(buf), "key_code:%d", key_event.code);
334 dumpKeyPressInfo(gIR_test);
335 EXIT:
336 sleep(1);
337 memset(buf, 0 , sizeof(buf));
338
339 if (!err_code)
340 strcpy(result, RESULT_VERIFY);
341
342 send_msg_to_server(buf, result, err_code);
343
344 return err_code;
345 }
346
347
348