blob: a8a39404eb56da6172099770fe8ac392e0b31924 [file] [log] [blame]
xjd5ccac02022-04-02 15:41:13 +08001
2#include <stdio.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <sys/un.h>
9#include <unistd.h>
10#include <dlfcn.h>
xjac563942022-05-04 16:50:24 +080011#include <pthread.h>
12#include <stdbool.h>
13#include <time.h>
xjd5ccac02022-04-02 15:41:13 +080014
15#define LOG_TAG "libautosuspend"
16
17// #include <liblog/lynq_deflog.h>
18#include <log/log.h>
19
xjac563942022-05-04 16:50:24 +080020#define SERVER_CMD_PATH "/tmp/autosuspend.cmd.server"
21#define SERVER_DATA_PATH "/tmp/autosuspend.data.server"
xjd5ccac02022-04-02 15:41:13 +080022// #define CLIENT_PATH "/tmp/autosuspend.client"
23
24
xjac563942022-05-04 16:50:24 +080025static int client_sock_fd;
26
27static int client_data_sock_fd;
28
29static bool libautosuspend_inited;
30
31// static bool libautosuspend_enabled;
32
33// static pthread_mutex_t get_feedback_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35// static pthread_cond_t get_feedback_cond = PTHREAD_COND_INITIALIZER;
36
37static pthread_mutex_t client_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
38
39static pthread_mutex_t client_data_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
40
41static pthread_mutex_t feedback_got_mutex = PTHREAD_MUTEX_INITIALIZER;
42
43static pthread_cond_t feedback_got_cond = PTHREAD_COND_INITIALIZER;
44
45struct time_info_t
xjd5ccac02022-04-02 15:41:13 +080046{
xjac563942022-05-04 16:50:24 +080047 long sleep_start_time;
48 long wakeup_time;
49};
50
51static struct time_info_t time_info_client;
52
53static ssize_t Read(int fd, void *ptr, size_t nbytes)
54{
55 ssize_t n;
56
57 while((n = read(fd, ptr, nbytes)) == -1)
58 {
59 //printf("READ,%d\n",fd);
60 if (errno == EINTR)
61 {
62 ALOGI("read error eintr\n");
63 continue;
64 }
65 else if(errno == EAGAIN || errno == EWOULDBLOCK)
66 {
67 ALOGI("read time out\n");
68 return -2;
69 }
70 else
71 {
72 ALOGI("read error\n");
73 return -1;
74 }
75 }
76 //sleep(2);
77 //printf("READ1,%d\n", fd);
78 return n;
79}
80
81static ssize_t Write(int fd, const void *ptr, size_t nbytes)
82{
83 ssize_t n;
84
85 while((n = write(fd, ptr, nbytes)) == -1)
86 {
87 if (errno == EINTR)
88 continue;
89 else if(errno == EPIPE)
90 {
91 ALOGI("write error epipe\n");
92 return -1;
93 }
94 else
95 return -1;
96 }
97 return n;
98}
99
100static int Close(int fd)
101{
102 if (Close(fd) == -1)
103 {
104 ALOGI("Close error\n");
105 return -1;
106 }
107 return 0;
108}
109
110static int connect_to_server(int *cfd, char *client_path, char *server_path)
111{
112 int rc;
xjd5ccac02022-04-02 15:41:13 +0800113 struct sockaddr_un server_sockaddr;
114 struct sockaddr_un client_sockaddr;
115
116
xjac563942022-05-04 16:50:24 +0800117 ALOGI("Start bind and connect to the service.\n");
xjd5ccac02022-04-02 15:41:13 +0800118
119 /**************************************/
120 /* Create a UNIX domain stream socket */
121 /**************************************/
xjac563942022-05-04 16:50:24 +0800122 *cfd = socket(AF_UNIX, SOCK_STREAM, 0);
123 if (*cfd == -1) {
xjd5ccac02022-04-02 15:41:13 +0800124 ALOGI("SOCKET ERROR ");
xjac563942022-05-04 16:50:24 +0800125 return -1;
xjd5ccac02022-04-02 15:41:13 +0800126 }
127
128 /***************************************/
129 /* Set up the UNIX sockaddr structure */
130 /* by using AF_UNIX for the family and */
131 /* giving it a filepath to bind to. */
132 /* */
133 /* Unlink the file so the bind will */
134 /* succeed, then bind to that file. */
135 /***************************************/
xjac563942022-05-04 16:50:24 +0800136 client_sockaddr.sun_family = AF_UNIX;
137 strcpy(client_sockaddr.sun_path, client_path);
xjd5ccac02022-04-02 15:41:13 +0800138
139 unlink(client_sockaddr.sun_path);
xjac563942022-05-04 16:50:24 +0800140
141 rc = bind(*cfd, (struct sockaddr *) &client_sockaddr, sizeof(client_sockaddr));
xjd5ccac02022-04-02 15:41:13 +0800142 if (rc == -1){
143 ALOGI("BIND ERROR ");
xjac563942022-05-04 16:50:24 +0800144 Close(*cfd);
145 return -1;
xjd5ccac02022-04-02 15:41:13 +0800146 }
147
148 /***************************************/
149 /* Set up the UNIX sockaddr structure */
150 /* for the server socket and connect */
151 /* to it. */
152 /***************************************/
153 server_sockaddr.sun_family = AF_UNIX;
xjac563942022-05-04 16:50:24 +0800154
155 strcpy(server_sockaddr.sun_path, server_path);
156
157 rc = connect(*cfd, (struct sockaddr *) &server_sockaddr, sizeof(client_sockaddr));
xjd5ccac02022-04-02 15:41:13 +0800158 if(rc == -1){
159 ALOGI("CONNECT ERROR ");
xjac563942022-05-04 16:50:24 +0800160 Close(*cfd);
xjd5ccac02022-04-02 15:41:13 +0800161 return -3;
162 }
xjac563942022-05-04 16:50:24 +0800163
164 return 0;
165
166}
167
168static void *deal_get_feedback(void *sockfd)
169{
170 int rc;
171
172 int client_sock = *((int *)sockfd);
173
174 // pthread_mutex_lock(&feedback_got_mutex);
175
176 while (1)
177 {
178 // ALOGI("deal_get_feedback thread wait.\n");
179
180 // pthread_cond_wait(&get_feedback_cond,&get_feedback_mutex);
181
182 ALOGI("start get feedback from the service.\n");
183
184 pthread_mutex_lock(&feedback_got_mutex);
185
186 memset(&time_info_client,0,sizeof(struct time_info_t));
187
188 rc = Read(client_sock,&time_info_client,sizeof(struct time_info_t));
189 if(rc == -1)
190 {
191 ALOGI("client read wakeup_feedback struct fail.\n");
192 Close(client_sock);
193 pthread_mutex_unlock(&feedback_got_mutex);
194 break ;
195 }
196 else if(rc == -2)
197 {
198 ALOGI("client read wakeup_feedback struct timeout.\n");
199 pthread_mutex_unlock(&feedback_got_mutex);
200 continue;
201 }
202
203 ALOGI("system sleep_start timestamps : %ld ms\n",time_info_client.sleep_start_time);
204 ALOGI("system wakeup timestamps : %ld ms\n",time_info_client.wakeup_time);
205
206 // pthread_cond_broadcast(&feedback_got_cond);
207
208 pthread_mutex_unlock(&feedback_got_mutex);
209
210 sleep(1); //给libautosuspend_get_feedback函数时间进入wait
211
212 pthread_cond_broadcast(&feedback_got_cond);
213
214 sleep(1); //希望多给libautosuspend_get_feedback函数拿到锁的机会,保证他们先执行完
215
216 }
217
218}
219
220
221static int libautosuspend_init()
222{
223 if (libautosuspend_inited)
224 {
225 return 0;
226 }
227
228 ALOGI("Start libautosuspend_init.\n");
229
230 char client_cmd_path[40];
231 char client_data_path[40];
232
233
234 sprintf(client_cmd_path,"/tmp/autosuspend.%d.cmd.client",(int)getpid());
235 sprintf(client_data_path,"/tmp/autosuspend.%d.data.client",(int)getpid());
236
237 pthread_mutex_lock(&client_fd_mutex);
238
239 if(connect_to_server(&client_sock_fd,client_cmd_path,SERVER_CMD_PATH) < 0)
240 {
241 ALOGI("cmd channel connect error.\n");
242 pthread_mutex_unlock(&client_fd_mutex);
243 return -1;
244 }
245
246 if(connect_to_server(&client_data_sock_fd,client_data_path,SERVER_DATA_PATH) < 0)
247 {
248 ALOGI("data channel connect error.\n");
249 pthread_mutex_unlock(&client_fd_mutex);
250 return -1;
251 }
252
253 pthread_t feedback_tid;
254 pthread_create(&feedback_tid,NULL,deal_get_feedback,(void*)&client_data_sock_fd);
255 pthread_detach(feedback_tid);
256
257
258 libautosuspend_inited = true;
259
260 pthread_mutex_unlock(&client_fd_mutex);
261
262 return 0;
263
264}
265
266static int send_cmd(char * value,int len)
267{
268 int rc;
269
270 if(value == NULL)
271 {
272 return -1;
273 }
xjd5ccac02022-04-02 15:41:13 +0800274
275 /************************************/
276 /* Copy the data to the buffer and */
277 /* send it to the server socket. */
278 /************************************/
xjac563942022-05-04 16:50:24 +0800279 // strcpy(buf, DATA);
280
281 ALOGI("Sending data...\n");
282 rc = send(client_sock_fd, value, len, 0);
xjd5ccac02022-04-02 15:41:13 +0800283 if (rc == -1) {
284 ALOGI("SEND ERROR ");
xjac563942022-05-04 16:50:24 +0800285 Close(client_sock_fd);
xjd5ccac02022-04-02 15:41:13 +0800286 return -2;
287 }
288 else {
289 ALOGI("Data sent: %s\n",value);
290 }
291
xjac563942022-05-04 16:50:24 +0800292 // Close(client_sock);
xjd5ccac02022-04-02 15:41:13 +0800293
294 return rc;
295
296}
297
298int lynq_autosleep_enable(void)
299{
xjac563942022-05-04 16:50:24 +0800300 char value[15]="enable";
301 char res[15];
302
303 if(libautosuspend_init() != 0)
304 {
305 return -1;
306 }
307
308 // if(libautosuspend_enabled)
309 // {
310 // return 0;
311 // }
312
313 pthread_mutex_lock(&client_fd_mutex);
314
315 int rc = send_cmd(value,strlen(value));
316 if(rc < 0)
317 {
318 ALOGI("libautosuspend send enable cmd fail.\n");
319 pthread_mutex_unlock(&client_fd_mutex);
320 return -1;
321 }
322
xjda4933f2022-05-09 10:34:43 +0800323 // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
324 // {
325 // ALOGI("libautosuspend get respond fail.\n");
326 // pthread_mutex_unlock(&client_fd_mutex);
327 // return -1;
328 // }
xjac563942022-05-04 16:50:24 +0800329
xjda4933f2022-05-09 10:34:43 +0800330 // ALOGI("libautosuspend get respond : %s.\n",res);
xjac563942022-05-04 16:50:24 +0800331
xjda4933f2022-05-09 10:34:43 +0800332 // if(strcmp(res,"enabled") != 0)
333 // {
334 // pthread_mutex_unlock(&client_fd_mutex);
335 // return -1;
336 // }
xjac563942022-05-04 16:50:24 +0800337
338 // libautosuspend_enabled = true;
339
340 pthread_mutex_unlock(&client_fd_mutex);
341
xj0bb28dc2022-05-10 08:22:22 +0800342 return 1;
xjac563942022-05-04 16:50:24 +0800343
xjd5ccac02022-04-02 15:41:13 +0800344}
345
346int lynq_autosleep_disable(void)
347{
xjac563942022-05-04 16:50:24 +0800348 char value[15]="disable";
349 char res[15];
350
351 if(libautosuspend_init() != 0)
352 {
353 return -1;
354 }
355
356 // if(!libautosuspend_enabled)
357 // {
358 // return 0;
359 // }
360
361 pthread_mutex_lock(&client_fd_mutex);
362
363 int rc = send_cmd(value,strlen(value));
364 if(rc < 0)
365 {
366 ALOGI("libautosuspend send disable cmd fail.\n");
367 pthread_mutex_unlock(&client_fd_mutex);
368 return -1;
369 }
370
xjda4933f2022-05-09 10:34:43 +0800371 // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
372 // {
373 // ALOGI("libautosuspend get respond fail.\n");
374 // pthread_mutex_unlock(&client_fd_mutex);
375 // return -1;
376 // }
xjac563942022-05-04 16:50:24 +0800377
xjda4933f2022-05-09 10:34:43 +0800378 // ALOGI("libautosuspend get respond : %s.\n",res);
xjac563942022-05-04 16:50:24 +0800379
xjda4933f2022-05-09 10:34:43 +0800380 // if(strcmp(res,"disabled") != 0)
381 // {
382 // pthread_mutex_unlock(&client_fd_mutex);
383 // return -1;
384 // }
xjac563942022-05-04 16:50:24 +0800385
386 // libautosuspend_enabled = false;
387
388 pthread_mutex_unlock(&client_fd_mutex);
389
xj0bb28dc2022-05-10 08:22:22 +0800390 return 1;
xjd5ccac02022-04-02 15:41:13 +0800391
392}
393
394
xjac563942022-05-04 16:50:24 +0800395
xjda4933f2022-05-09 10:34:43 +0800396int libautosuspend_get_feedback(struct time_info_t *time_info)
xjac563942022-05-04 16:50:24 +0800397{
398 // char value[15]="feedback";
399 // char res[15];
400
401 // if(!libautosuspend_enabled)
402 // {
403 // ALOGI("system autosuspend disabled, can not get wakeup feedback.\n");
404 // return -1;
405 // }
406
407 ALOGI("start get feedback from the service.\n");
408
409 memset(time_info,0,sizeof(struct time_info_t));
410
xjda4933f2022-05-09 10:34:43 +0800411 // if(timeout == NULL)
412 // {
413 // ALOGI("client set timeout for receiving wakeup_feedback: NULL.\n");
414 // }
415 // else
416 // {
417 // struct timeval recv_timeout = {(*timeout),0};
418 // pthread_mutex_lock(&client_data_fd_mutex);
419 // if(setsockopt(client_data_sock_fd,SOL_SOCKET,SO_RCVTIMEO,(char*)&recv_timeout,sizeof(struct timeval)) == -1)
420 // {
421 // ALOGI("client set timeout for receiving wakeup_feedback: error.\n");
422 // pthread_mutex_unlock(&client_data_fd_mutex);
423 // return -1;
424 // }
xjac563942022-05-04 16:50:24 +0800425
xjda4933f2022-05-09 10:34:43 +0800426 // ALOGI("client set timeout for receiving wakeup_feedback: %d s.\n",(*timeout));
427 // pthread_mutex_unlock(&client_data_fd_mutex);
xjac563942022-05-04 16:50:24 +0800428
xjda4933f2022-05-09 10:34:43 +0800429 // }
xjac563942022-05-04 16:50:24 +0800430
431 // int rc = send_cmd(value,strlen(value));
432 // if(rc < 0)
433 // {
434 // ALOGI("libautosuspend send feedback cmd fail.\n");
435 // pthread_mutex_unlock(&client_fd_mutex);
436 // return -1;
437 // }
438
439 // if(Read(client_data_sock_fd,time_info,sizeof(struct time_info_t)) <= 0)
440 // {
441 // ALOGI("libautosuspend_get_feedback fail.\n");
442 // pthread_mutex_unlock(&client_fd_mutex);
443 // return -1;
444 // }
445
446
447 ALOGI("libautosuspend_get_feedback wait.\n");
448
449 pthread_mutex_lock(&feedback_got_mutex);
450
451 pthread_cond_wait(&feedback_got_cond,&feedback_got_mutex);
452
453 memcpy(time_info,&time_info_client,sizeof(struct time_info_t));
454
455 ALOGI("libautosuspend_get_feedback success.\n");
456
457 pthread_mutex_unlock(&feedback_got_mutex);
458 // ALOGI("[client] system sleep_start timestamps : %ld ms\n",time_info.sleep_start_time);
459 // ALOGI("[client] system wakeup timestamps : %ld ms\n",time_info.wakeup_time);
460
461 return 0;
462
463}
464
465
xjda4933f2022-05-09 10:34:43 +0800466int lynq_wait_wakeup_event(long *sleep_start_time, long * wakeup_time)
467{
468 int *socket_timeout = NULL;
469 struct time_info_t time_info;
470 int ret = 0;
471
472 memset(&time_info,0,sizeof(struct time_info_t));
473 if(sleep_start_time == NULL || wakeup_time == NULL )
474 {
475 ALOGI("lynq_wait_wakeup_event input errors.\n");
476 return -1;
477 }
478 ret=libautosuspend_get_feedback(&time_info);
479 if(ret == 0)
480 {
481 *sleep_start_time = time_info.sleep_start_time;
482 *wakeup_time = time_info.wakeup_time;
483 return 0;
484 }
485 else
486 {
487 return -1;
488 }
489
490
491}
xjac563942022-05-04 16:50:24 +0800492
493// static void libautosuspend_get_feedback()
494// {
495// pthread_t feedback_tid;
496// pthread_create(&feedback_tid,NULL,deal_get_feedback,(void*)&client_sock);
497// pthread_detach(&feedback_tid);
498
499// return ;
500
501// }
502
xjd5ccac02022-04-02 15:41:13 +0800503
504