blob: 5dc3fe582923328e91c443980aeaef44608fe974 [file] [log] [blame]
jb.qi3a8298c2023-09-07 04:48:51 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <sys/un.h>
8#include <unistd.h>
9#include <dlfcn.h>
10#include <pthread.h>
11#include <stdbool.h>
12#include <time.h>
jb.qid70ee152023-10-17 04:52:42 -070013#include <liblog/lynq_deflog.h>
14
jb.qi3a8298c2023-09-07 04:48:51 -070015#include "include/libauto/lynq_autosuspend.h"
16#ifdef MOBILETEK_TARGET_PLATFORM_T106
17#include <sc_bsp.h>
18#endif
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
jb.qid70ee152023-10-17 04:52:42 -070024#define USER_LOG_TAG "LIBLYNQ_AUTOSUSPEND"
jb.qi3a8298c2023-09-07 04:48:51 -070025
jb.qid70ee152023-10-17 04:52:42 -070026
27
28
jb.qi3a8298c2023-09-07 04:48:51 -070029#define SERVER_CMD_PATH "/tmp/autosuspend.cmd.server"
30#define SERVER_DATA_PATH "/tmp/autosuspend.data.server"
31// #define CLIENT_PATH "/tmp/autosuspend.client"
32static int client_sock_fd;
33static int client_data_sock_fd;
34static bool libautosuspend_inited;
35bool feedback_flag = true; //add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time
36// static bool libautosuspend_enabled;
37// static pthread_mutex_t get_feedback_mutex = PTHREAD_MUTEX_INITIALIZER;
38// static pthread_cond_t get_feedback_cond = PTHREAD_COND_INITIALIZER;
39static pthread_mutex_t client_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
40static pthread_mutex_t client_data_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
41static pthread_mutex_t feedback_got_mutex = PTHREAD_MUTEX_INITIALIZER;
42static pthread_cond_t feedback_got_cond = PTHREAD_COND_INITIALIZER;
43
44static struct time_info_t time_info_client;
45static ssize_t Read(int fd, void *ptr, size_t nbytes)
46{
47 ssize_t n;
48
49 while((n = read(fd, ptr, nbytes)) == -1)
50 {
jb.qid70ee152023-10-17 04:52:42 -070051 //LYINFLOG("READ,%d\n",fd);
jb.qi3a8298c2023-09-07 04:48:51 -070052 if (errno == EINTR)
53 {
jb.qid70ee152023-10-17 04:52:42 -070054 LYINFLOG("read error eintr\n");
jb.qi3a8298c2023-09-07 04:48:51 -070055 continue;
56 }
57 else if(errno == EAGAIN || errno == EWOULDBLOCK)
58 {
jb.qid70ee152023-10-17 04:52:42 -070059 LYINFLOG("read time out\n");
jb.qi3a8298c2023-09-07 04:48:51 -070060 return -2;
61 }
62 else
63 {
jb.qid70ee152023-10-17 04:52:42 -070064 LYINFLOG("read error\n");
jb.qi3a8298c2023-09-07 04:48:51 -070065 return -1;
66 }
67 }
68 //sleep(2);
jb.qid70ee152023-10-17 04:52:42 -070069 //LYINFLOG("READ1,%d\n", fd);
jb.qi3a8298c2023-09-07 04:48:51 -070070 return n;
71}
72static ssize_t Write(int fd, const void *ptr, size_t nbytes)
73{
74 ssize_t n;
75 while((n = write(fd, ptr, nbytes)) == -1)
76 {
77 if (errno == EINTR)
78 continue;
79 else if(errno == EPIPE)
80 {
jb.qid70ee152023-10-17 04:52:42 -070081 LYINFLOG("write error epipe\n");
jb.qi3a8298c2023-09-07 04:48:51 -070082 return -1;
83 }
84 else
85 return -1;
86 }
87 return n;
88}
89static int Close(int fd)
90{
jb.qi6ae06882024-08-16 23:00:46 -070091 if (close(fd) == -1)
jb.qi3a8298c2023-09-07 04:48:51 -070092 {
jb.qid70ee152023-10-17 04:52:42 -070093 LYINFLOG("Close error\n");
jb.qi3a8298c2023-09-07 04:48:51 -070094 return -1;
95 }
96 return 0;
97}
98static int connect_to_server(int *cfd, char *client_path, char *server_path)
99{
100 int rc;
101 struct sockaddr_un server_sockaddr;
102 struct sockaddr_un client_sockaddr;
jb.qid70ee152023-10-17 04:52:42 -0700103 LYINFLOG("Start bind and connect to the service.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700104 /**************************************/
105 /* Create a UNIX domain stream socket */
106 /**************************************/
107 *cfd = socket(AF_UNIX, SOCK_STREAM, 0);
108 if (*cfd == -1) {
jb.qid70ee152023-10-17 04:52:42 -0700109 LYINFLOG("SOCKET ERROR ");
jb.qi3a8298c2023-09-07 04:48:51 -0700110 return -1;
111 }
112 /***************************************/
113 /* Set up the UNIX sockaddr structure */
114 /* by using AF_UNIX for the family and */
115 /* giving it a filepath to bind to. */
116 /* */
117 /* Unlink the file so the bind will */
118 /* succeed, then bind to that file. */
119 /***************************************/
120 client_sockaddr.sun_family = AF_UNIX;
121 strcpy(client_sockaddr.sun_path, client_path);
122
123 unlink(client_sockaddr.sun_path);
124 rc = bind(*cfd, (struct sockaddr *) &client_sockaddr, sizeof(client_sockaddr));
125 if (rc == -1){
jb.qid70ee152023-10-17 04:52:42 -0700126 LYINFLOG("BIND ERROR ");
jb.qi3a8298c2023-09-07 04:48:51 -0700127 Close(*cfd);
128 return -1;
129 }
130
131 /***************************************/
132 /* Set up the UNIX sockaddr structure */
133 /* for the server socket and connect */
134 /* to it. */
135 /***************************************/
136 server_sockaddr.sun_family = AF_UNIX;
137
138 strcpy(server_sockaddr.sun_path, server_path);
139 rc = connect(*cfd, (struct sockaddr *) &server_sockaddr, sizeof(client_sockaddr));
140 if(rc == -1){
jb.qid70ee152023-10-17 04:52:42 -0700141 LYINFLOG("CONNECT ERROR ");
jb.qi3a8298c2023-09-07 04:48:51 -0700142 Close(*cfd);
143 return -3;
144 }
145 return 0;
146
147}
148static void *deal_get_feedback(void *sockfd)
149{
150 int rc;
151 int client_sock = *((int *)sockfd);
152 // pthread_mutex_lock(&feedback_got_mutex);
153
154 while (1)
155 {
jb.qid70ee152023-10-17 04:52:42 -0700156 // LYINFLOG("deal_get_feedback thread wait.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700157 // pthread_cond_wait(&get_feedback_cond,&get_feedback_mutex);
jb.qid70ee152023-10-17 04:52:42 -0700158 LYINFLOG("start get feedback from the service.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700159 pthread_mutex_lock(&feedback_got_mutex);
160 memset(&time_info_client,0,sizeof(struct time_info_t));
161 rc = Read(client_sock,&time_info_client,sizeof(struct time_info_t));
162 if(rc == -1)
163 {
jb.qid70ee152023-10-17 04:52:42 -0700164 LYINFLOG("client read wakeup_feedback struct fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700165 Close(client_sock);
166 pthread_mutex_unlock(&feedback_got_mutex);
167 break ;
168 }
169 else if(rc == -2)
170 {
jb.qid70ee152023-10-17 04:52:42 -0700171 LYINFLOG("client read wakeup_feedback struct timeout.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700172 pthread_mutex_unlock(&feedback_got_mutex);
173 continue;
174 }
jb.qid70ee152023-10-17 04:52:42 -0700175 LYINFLOG("system sleep_start timestamps : %ld ms\n",time_info_client.sleep_start_time);
176 LYINFLOG("system wakeup timestamps : %ld ms\n",time_info_client.wakeup_time);
jb.qi3a8298c2023-09-07 04:48:51 -0700177 // pthread_cond_broadcast(&feedback_got_cond);
178 pthread_mutex_unlock(&feedback_got_mutex);
179 usleep(10000); //给libautosuspend_get_feedback函数时间进入wait,不可删除,但可以减少
180 pthread_cond_broadcast(&feedback_got_cond);
181 usleep(10000); //希望多给libautosuspend_get_feedback函数拿到锁的机会,不可删除,但可以减少
182
183 }
184
185}
186static int libautosuspend_init()
187{
188 if (libautosuspend_inited)
189 {
190 return 0;
191 }
jb.qid70ee152023-10-17 04:52:42 -0700192 LYINFLOG("Start libautosuspend_init.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700193 char client_cmd_path[40];
194 char client_data_path[40];
195 sprintf(client_cmd_path,"/tmp/autosuspend.%d.cmd.client",(int)getpid());
196 sprintf(client_data_path,"/tmp/autosuspend.%d.data.client",(int)getpid());
197 pthread_mutex_lock(&client_fd_mutex);
198 if(connect_to_server(&client_sock_fd,client_cmd_path,SERVER_CMD_PATH) < 0)
199 {
jb.qid70ee152023-10-17 04:52:42 -0700200 LYINFLOG("cmd channel connect error.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700201 pthread_mutex_unlock(&client_fd_mutex);
202 return -1;
203 }
204 if(connect_to_server(&client_data_sock_fd,client_data_path,SERVER_DATA_PATH) < 0)
205 {
jb.qid70ee152023-10-17 04:52:42 -0700206 LYINFLOG("data channel connect error.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700207 pthread_mutex_unlock(&client_fd_mutex);
208 return -1;
209 }
210 pthread_t feedback_tid;
211 pthread_create(&feedback_tid,NULL,deal_get_feedback,(void*)&client_data_sock_fd);
212 pthread_detach(feedback_tid);
213 libautosuspend_inited = true;
214 pthread_mutex_unlock(&client_fd_mutex);
215
216 return 0;
217
218}
219static int send_cmd(char * value,int len)
220{
221 int rc;
222 if(value == NULL)
223 {
224 return -1;
225 }
226
227 /************************************/
228 /* Copy the data to the buffer and */
229 /* send it to the server socket. */
230 /************************************/
231 // strcpy(buf, DATA);
jb.qid70ee152023-10-17 04:52:42 -0700232 LYINFLOG("Sending data...\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700233 rc = send(client_sock_fd, value, len, 0);
234 if (rc == -1) {
jb.qid70ee152023-10-17 04:52:42 -0700235 LYINFLOG("SEND ERROR ");
jb.qi3a8298c2023-09-07 04:48:51 -0700236 Close(client_sock_fd);
237 return -2;
238 }
239 else {
jb.qid70ee152023-10-17 04:52:42 -0700240 LYINFLOG("Data sent: %s\n",value);
jb.qi3a8298c2023-09-07 04:48:51 -0700241 }
242 // Close(client_sock);
243 return rc;
244}
245int lynq_autosleep_enable(void)
246{
247 char value[15]="enable";
248 char res[15];
jb.qid70ee152023-10-17 04:52:42 -0700249 LYLOGSET(LOG_INFO);
250 LYLOGEINIT(USER_LOG_TAG);
251
jb.qi3a8298c2023-09-07 04:48:51 -0700252 if(libautosuspend_init() != 0)
253 {
254 return -1;
255 }
256 // if(libautosuspend_enabled)
257 // {
258 // return 0;
259 // }
260 pthread_mutex_lock(&client_fd_mutex);
261 int rc = send_cmd(value,strlen(value));
262 if(rc < 0)
263 {
jb.qid70ee152023-10-17 04:52:42 -0700264 LYINFLOG("libautosuspend send enable cmd fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700265 pthread_mutex_unlock(&client_fd_mutex);
266 return -1;
267 }
268 // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
269 // {
jb.qid70ee152023-10-17 04:52:42 -0700270 // LYINFLOG("libautosuspend get respond fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700271 // pthread_mutex_unlock(&client_fd_mutex);
272 // return -1;
273 // }
jb.qid70ee152023-10-17 04:52:42 -0700274 // LYINFLOG("libautosuspend get respond : %s.\n",res);
jb.qi3a8298c2023-09-07 04:48:51 -0700275 // if(strcmp(res,"enabled") != 0)
276 // {
277 // pthread_mutex_unlock(&client_fd_mutex);
278 // return -1;
279 // }
280 // libautosuspend_enabled = true;
281 pthread_mutex_unlock(&client_fd_mutex);
282 return 1;
283
284}
285int lynq_autosleep_disable(void)
286{
287 char value[15]="disable";
288 char res[15];
289 if(libautosuspend_init() != 0)
290 {
291 return -1;
292 }
293 // if(!libautosuspend_enabled)
294 // {
295 // return 0;
296 // }
297 pthread_mutex_lock(&client_fd_mutex);
298 int rc = send_cmd(value,strlen(value));
299 if(rc < 0)
300 {
jb.qid70ee152023-10-17 04:52:42 -0700301 LYINFLOG("libautosuspend send disable cmd fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700302 pthread_mutex_unlock(&client_fd_mutex);
303 return -1;
304 }
305 // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
306 // {
jb.qid70ee152023-10-17 04:52:42 -0700307 // LYINFLOG("libautosuspend get respond fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700308 // pthread_mutex_unlock(&client_fd_mutex);
309 // return -1;
310 // }
jb.qid70ee152023-10-17 04:52:42 -0700311 // LYINFLOG("libautosuspend get respond : %s.\n",res);
jb.qi3a8298c2023-09-07 04:48:51 -0700312 // if(strcmp(res,"disabled") != 0)
313 // {
314 // pthread_mutex_unlock(&client_fd_mutex);
315 // return -1;
316 // }
317 // libautosuspend_enabled = false;
318 pthread_mutex_unlock(&client_fd_mutex);
319 return 1;
320}
321int libautosuspend_get_feedback(struct time_info_t *time_info)
322{
323 // char value[15]="feedback";
324 // char res[15];
325 // if(!libautosuspend_enabled)
326 // {
jb.qid70ee152023-10-17 04:52:42 -0700327 // LYINFLOG("system autosuspend disabled, can not get wakeup feedback.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700328 // return -1;
329 // }
jb.qid70ee152023-10-17 04:52:42 -0700330 LYINFLOG("start get feedback from the service.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700331 memset(time_info,0,sizeof(struct time_info_t));
332 // if(timeout == NULL)
333 // {
jb.qid70ee152023-10-17 04:52:42 -0700334 // LYINFLOG("client set timeout for receiving wakeup_feedback: NULL.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700335 // }
336 // else
337 // {
338 // struct timeval recv_timeout = {(*timeout),0};
339 // pthread_mutex_lock(&client_data_fd_mutex);
340 // if(setsockopt(client_data_sock_fd,SOL_SOCKET,SO_RCVTIMEO,(char*)&recv_timeout,sizeof(struct timeval)) == -1)
341 // {
jb.qid70ee152023-10-17 04:52:42 -0700342 // LYINFLOG("client set timeout for receiving wakeup_feedback: error.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700343 // pthread_mutex_unlock(&client_data_fd_mutex);
344 // return -1;
345 // }
346
jb.qid70ee152023-10-17 04:52:42 -0700347 // LYINFLOG("client set timeout for receiving wakeup_feedback: %d s.\n",(*timeout));
jb.qi3a8298c2023-09-07 04:48:51 -0700348 // pthread_mutex_unlock(&client_data_fd_mutex);
349
350 // }
351 // int rc = send_cmd(value,strlen(value));
352 // if(rc < 0)
353 // {
jb.qid70ee152023-10-17 04:52:42 -0700354 // LYINFLOG("libautosuspend send feedback cmd fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700355 // pthread_mutex_unlock(&client_fd_mutex);
356 // return -1;
357 // }
358 // if(Read(client_data_sock_fd,time_info,sizeof(struct time_info_t)) <= 0)
359 // {
jb.qid70ee152023-10-17 04:52:42 -0700360 // LYINFLOG("libautosuspend_get_feedback fail.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700361 // pthread_mutex_unlock(&client_fd_mutex);
362 // return -1;
363 // }
jb.qid70ee152023-10-17 04:52:42 -0700364 LYINFLOG("libautosuspend_get_feedback wait.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700365 pthread_mutex_lock(&feedback_got_mutex);
366 pthread_cond_wait(&feedback_got_cond,&feedback_got_mutex);
367 memcpy(time_info,&time_info_client,sizeof(struct time_info_t));
jb.qid70ee152023-10-17 04:52:42 -0700368 LYINFLOG("libautosuspend_get_feedback success.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700369 pthread_mutex_unlock(&feedback_got_mutex);
jb.qid70ee152023-10-17 04:52:42 -0700370 // LYINFLOG("[client] system sleep_start timestamps : %ld ms\n",time_info.sleep_start_time);
371 // LYINFLOG("[client] system wakeup timestamps : %ld ms\n",time_info.wakeup_time);
jb.qi3a8298c2023-09-07 04:48:51 -0700372 return 0;
373}
374int lynq_wait_wakeup_event(long *sleep_start_time, long * wakeup_time)
375{
376 int *socket_timeout = NULL;
377 struct time_info_t time_info;
378 int ret = 0;
379 /*add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time start*/
380 if(feedback_flag == true)
381 {
382 if(libautosuspend_init() != 0)
383 {
384 return -1;
385 }
386 }
387 feedback_flag = false;
388 /*add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time end*/
389 memset(&time_info,0,sizeof(struct time_info_t));
390 if(sleep_start_time == NULL || wakeup_time == NULL )
391 {
jb.qid70ee152023-10-17 04:52:42 -0700392 LYINFLOG("lynq_wait_wakeup_event input errors.\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700393 return -1;
394 }
395 ret=libautosuspend_get_feedback(&time_info);
396 if(ret == 0)
397 {
398 *sleep_start_time = time_info.sleep_start_time;
399 *wakeup_time = time_info.wakeup_time;
400 return 0;
401 }
402 else
403 {
404 return -1;
405 }
406
407}
408#ifdef MOBILETEK_TARGET_PLATFORM_T106
409int acquire_wake_lock(int lock, char *name)
410{
411 int ret;
jb.qid70ee152023-10-17 04:52:42 -0700412 LYLOGSET(LOG_INFO);
413 LYLOGEINIT(USER_LOG_TAG);
414
415 if(strlen(name) == 0)
416 {
417 return -1;
418 }
419 LYINFLOG("Get param:%s \n", name);
jb.qi3a8298c2023-09-07 04:48:51 -0700420 ret = sc_pm_wakelock_lock(name);
jb.qi68fe7782023-09-18 20:40:58 -0700421 if (ret != 0)
jb.qi3a8298c2023-09-07 04:48:51 -0700422 {
jb.qid70ee152023-10-17 04:52:42 -0700423 LYINFLOG("do_wakelock failed, err:%d", ret);
jb.qi68fe7782023-09-18 20:40:58 -0700424 return -1;
jb.qi3a8298c2023-09-07 04:48:51 -0700425 }
jb.qi68fe7782023-09-18 20:40:58 -0700426
jb.qid70ee152023-10-17 04:52:42 -0700427 LYINFLOG("do_wakelock succeed\n");
jb.qi68fe7782023-09-18 20:40:58 -0700428 return 1;
jb.qi3a8298c2023-09-07 04:48:51 -0700429}
430int release_wake_lock(char *name)
431{
432 int ret;
jb.qid70ee152023-10-17 04:52:42 -0700433
434 if(strlen(name) == 0)
435 {
436 return -1;
437 }
438 LYLOGSET(LOG_INFO);
439 LYLOGEINIT(USER_LOG_TAG);
440
441 LYINFLOG("Get param:%s \n", name);
jb.qi3a8298c2023-09-07 04:48:51 -0700442 ret = sc_pm_wakelock_unlock(name);
jb.qi68fe7782023-09-18 20:40:58 -0700443 if (ret != 0)
jb.qi3a8298c2023-09-07 04:48:51 -0700444 {
jb.qid70ee152023-10-17 04:52:42 -0700445 LYINFLOG("do_wakeunlock failed, err:%d", ret);
jb.qi68fe7782023-09-18 20:40:58 -0700446 return -1;
jb.qi3a8298c2023-09-07 04:48:51 -0700447 }
jb.qid70ee152023-10-17 04:52:42 -0700448 LYINFLOG("do_wakeunlock succeed\n");
jb.qi68fe7782023-09-18 20:40:58 -0700449 return 1;
jb.qi3a8298c2023-09-07 04:48:51 -0700450}
451int lynq_set_lpmode(int lp_mode)
452{
453 int ret;
jb.qid70ee152023-10-17 04:52:42 -0700454 LYLOGSET(LOG_INFO);
455 LYLOGEINIT(USER_LOG_TAG);
456
457 LYINFLOG("Get param:%d \n", lp_mode);
jb.qi3a8298c2023-09-07 04:48:51 -0700458 ret = sc_pm_set_lp_mode(lp_mode);
459 if (ret) {
jb.qid70ee152023-10-17 04:52:42 -0700460 LYINFLOG("do_set_lpmode failed, err:%d", ret);
jb.qi3a8298c2023-09-07 04:48:51 -0700461 exit(1);
462 }
jb.qid70ee152023-10-17 04:52:42 -0700463 LYINFLOG("do_set_lpmode succeed\n");
jb.qi3a8298c2023-09-07 04:48:51 -0700464 return ret;
465}
466#endif
467
jb.qid70ee152023-10-17 04:52:42 -0700468DEFINE_LYNQ_LIB_LOG(LIBLYNQ_AUTOSUSPEND)
469
jb.qi3a8298c2023-09-07 04:48:51 -0700470#ifdef __cplusplus
471}
472#endif