blob: f706c9f8205648a7c18faa3e62778b138057eb0e [file] [log] [blame]
xf.lia06dd222024-10-14 09:07:20 +00001/* //device/system/rild/rild.c
2**
3** Copyright 2006 The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <stdbool.h>
21#include <dlfcn.h>
22#include <string.h>
23#include <pthread.h>
24#include <stdint.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <errno.h>
28#include <log/log.h>
29#include <liblog/lynq_deflog.h>
30#include <include/lynq_uci.h>
31#include <sys/socket.h>
32#include <sys/un.h>
33#include <signal.h>
34
35
36#define LOG_UCI_MODULE "lynq_autosuspend"
37#define LOG_UCI_FILE "lynq_uci"
38
39#define LOG_TAG "AUTOSUSPEND"
40
41#define USER_LOG_TAG "PMS"
42
43#define SOCK_PATH "/tmp/autosuspend.cmd.server" //不能在当前这个目录创建socket文件,否则报错找不到文件(可能是因为这是在共享文件夹下,不支持创建socket文件)
44
45#define SOCK_DATA_PATH "/tmp/autosuspend.data.server"
46
47// #define LYINFLOG(X...) lynq_log_global_output(LOG_INFO,X)
48
49#define TIME_OUT_TIME 30
50
51
52#define MAX_LIB_ARGS 16
53
54int adb_debug_mode = 0;
55
56
57pthread_cond_t feedback_cond = PTHREAD_COND_INITIALIZER;
58pthread_mutex_t feedback_mutex = PTHREAD_MUTEX_INITIALIZER;
59pthread_mutex_t time_info_mutex = PTHREAD_MUTEX_INITIALIZER;
60
61extern int autosuspend_enable(void);
62extern int autosuspend_disable(void);
63extern void init_wakelock_func(void);
64extern void init_sim_func();
65extern void init_network_func();
66extern void set_wakeup_callback(void (*func)(bool success));
67extern void wakeup_feedback(bool success);
68extern int (*lynq_screen)(int num);
69
70struct time_info_t
71{
72 long sleep_start_time;
73 long wakeup_time;
74};
75
76struct time_info_t time_info;
77
78static void usage(const char *argv0) {
79 fprintf(stderr, "Usage: %s -l <possible_max_sleep_time> [-- <args for Autosuspend Service>]\n", argv0);
80 exit(EXIT_FAILURE);
81}
82
83
84
85static int make_argv(char * args, char ** argv) {
86 // Note: reserve argv[0]
87 int count = 1;
88 char * tok;
89 char * s = args;
90
91 while ((tok = strtok(s, " \0"))) {
92 argv[count] = tok;
93 s = NULL;
94 count++;
95 }
96 return count;
97}
98
99static int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
100{
101 int n;
102
103 while((n = accept(fd, sa, salenptr)) < 0)
104 {
105 if((errno == ECONNABORTED) || (errno == EINTR))
106 continue;
107 else
108 {
109 ALOGI("accept error\n");
110 return -1;
111 }
112 }
113 return n;
114}
115
116static int Bind(int fd, const struct sockaddr *sa, socklen_t salen)
117{
118 if(bind(fd, sa, salen) < 0)
119 {
120 // ALOGI("bind error\n");
121 perror("bind error");
122 return -1;
123 }
124 return 0;
125}
126
127
128static int Socket(int family, int type, int protocol)
129{
130 int n;
131
132 if ( (n = socket(family, type, protocol)) < 0)
133 {
134 ALOGI("socket error\n");
135 return -1;
136 }
137 return n;
138}
139
140static int Listen(int fd, int backlog)
141{
142 if(listen(fd, backlog) < 0)
143 {
144 ALOGI("listen error\n");
145 return -1;
146 }
147 return 0;
148}
149
150
151static int listen_port(struct sockaddr_un *addr, char *sockpath)
152{
153 int listenfd;
154 listenfd = Socket(AF_UNIX,SOCK_STREAM,0);
155 if(listenfd == -1)
156 return -1;
157 memset(addr, 0, sizeof(struct sockaddr_un));
158 addr->sun_family = AF_UNIX;
159 strcpy(addr->sun_path,sockpath);
160 // int opt = 1;
161 // if(setsockopt(listenfd, SOL_SOCKET,SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
162 // {
163 // perror("setsockopt error");
164 // return -1;
165 // }
166
167// 以上方法对非网络的本地socket无效,应该用unlink函数避免Address already in use的错误
168
169
170 unlink(sockpath);
171 if(Bind(listenfd,(struct sockaddr *)addr,sizeof(*addr)) == -1)
172 return -1;
173
174 if(Listen(listenfd,20) == -1)
175 return -1;
176
177 return listenfd;
178}
179
180static ssize_t Read(int fd, void *ptr, size_t nbytes)
181{
182 ssize_t n;
183
184 while((n = read(fd, ptr, nbytes)) == -1)
185 {
186 //printf("READ,%d\n",fd);
187 if (errno == EINTR)
188 {
189 ALOGI("read error eintr\n");
190 continue;
191 }
192 else if(errno == EAGAIN || errno == EWOULDBLOCK)
193 {
194 ALOGI("read time out\n");
195 return -1;
196 }
197 else
198 {
199 ALOGI("read error\n");
200 return -1;
201 }
202 }
203 //sleep(2);
204 //printf("READ1,%d\n", fd);
205 return n;
206}
207
208static ssize_t Write(int fd, const void *ptr, size_t nbytes)
209{
210 ssize_t n;
211
212 while((n = write(fd, ptr, nbytes)) == -1)
213 {
214 if (errno == EINTR)
215 continue;
216 else if(errno == EPIPE)
217 {
218 ALOGI("write error epipe\n");
219 return -1;
220 }
221 else
222 return -1;
223 }
224 return n;
225}
226
227static int Close(int fd)
228{
229 if (close(fd) == -1)
230 {
231 ALOGI("close error\n");
232 return -1;
233 }
234 return 0;
235}
236
237
238void *deal_autosuspend(void *sockfd)
239{
240 int commfd = *((int *)sockfd);
241 char buf[20];
242 char res[15];
243
244 while(1)
245 {
246 memset(buf,0,sizeof(buf));
247 ALOGI("deal_autosuspend start to read.\n");
248 // 错误点:read函数在对端关闭后,也会直接返回0,不会阻塞,因此要判断是否返回0,返回0表示对端已经关闭,此时要跳出while循环不再监听
249 // 为什么对端会关闭?因为在客户端没有用nohup方式打开的情况下,系统睡眠后客户端进行会直接被杀死,对端会关闭,所以会导致read不阻塞,且总是返回0的现象
250 if(Read(commfd,buf,sizeof(buf)) <= 0)
251 {
252 ALOGI("service receive suspend_cmd fail or client is closed.\n");
253 Close(commfd);
254 break;
255 }
256 if(strcmp(buf,"enable") == 0)
257 {
258 if(autosuspend_enable() < 0)
259 {
260 ALOGI("autosuspend_enable fail.\n");
261 }
262 else
263 {
264 ALOGI("autosuspend_enable success.\n");
265 }
266 }
267 else if(strcmp(buf,"disable") == 0)
268 {
269 if(autosuspend_disable() < 0)
270 {
271 ALOGI("autosuspend_disable fail.\n");
272 }
273 else
274 {
275 ALOGI("autosuspend_disable success.\n");
276
277 }
278 }
279
280 else
281 {
282 ALOGI("Unknown cmd : %s\n",buf);
283 }
284
285 }
286
287
288
289}
290
291#ifdef GSW_SUSPEND_CFG
292/*jb.qi add for service send when DTR is low on 20221111 start */
293void *dtr_wakeup()
294{
295 FILE *fp;
296 int ret;
297 bool success = true;
298 char buf[30];
299 char dtr_buffer[25];
300 RLOGD("dtr_wakeup start\n");
301 while(1)
302 {
303 fp = popen("cat /sys/devices/platform/10005000.pinctrl/mt_gpio |grep 006:","r");
304 fgets(dtr_buffer, sizeof(dtr_buffer), fp);
305 if(dtr_buffer[7] == '0')
306 {
307 time_info.sleep_start_time = 123;
308 time_info.wakeup_time = 123;
309 if (pthread_cond_broadcast(&feedback_cond) != 0)
310 {
311 strerror_r(errno, buf, sizeof(buf));
312 ALOGI("Error broadcast cond: %s\n", buf);
313 }
314 RLOGD("dtr_wakeup success!\n");
315 sleep(3);
316 }
317 usleep(500);
318 pclose(fp);
319 }
320}
321/*jb.qi add for service send when DTR is low on 20221111 end */
322#endif
323
324void *send_feedback(void *sockfd)
325{
326 int commfd = *((int *)sockfd);
327 char buf[80];
328
329 while (1)
330 {
331 memset(buf,0,sizeof(buf));
332 ALOGI("send_feedback thread wait to send.\n");
333 pthread_mutex_lock(&feedback_mutex);
334 pthread_cond_wait(&feedback_cond,&feedback_mutex);
335
336 ALOGI("send_feedback thread is now sending the feedback to client.\n");
337 pthread_mutex_lock(&time_info_mutex);
338 if(Write(commfd,&time_info,sizeof(struct time_info_t)) <= 0)
339 {
340 ALOGI("service send wakeup_feedback struct fail.\n");
341 Close(commfd);
342 pthread_mutex_unlock(&time_info_mutex);
343 pthread_mutex_unlock(&feedback_mutex);
344#ifdef GSW_SUSPEND_CFG
345 continue ;//jb.qi add for service send when DTR is low on 20221111
346#endif
347
348#ifdef MOBILETEK_SUSPEND_CFG
349 break ;
350#endif
351 }
352 pthread_mutex_unlock(&time_info_mutex);
353
354 pthread_mutex_unlock(&feedback_mutex);
355
356
357
358 }
359
360}
361
362
363int main(int argc, char **argv) {
364
365
366 // int i = 0;
367 // RLOGD("**Autosuspend Service Daemon Started**");
368 // RLOGD("**Autosuspend Service param count=%d**", argc);
369 char tmp[20];
370
371 int commfd, commfd_data, server_sock, server_data_sock,len, len_data;
372
373 struct sockaddr_un server_sockaddr;
374 struct sockaddr_un server_data_sockaddr;
375 struct sockaddr_un client_sockaddr;
376
377 len = sizeof(server_sockaddr);
378
379
380 pthread_t tid;
381#ifdef GSW_SUSPEND_CFG
382 pthread_t tid_1;//jb.qi add for service send when DTR is low on 20221111
383#endif
384
385 LYLOGEINIT(USER_LOG_TAG);
386 LYLOGSET(LOG_DEBUG);
387 // LYLOGSET(LOG_ERROR);
388
389 int auto_enable = 0;
390
391 lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "debug", tmp); // 即获取系统层面的环境变量
392 ALOGI("Autosuspend Service Daemon. debug %s\n",tmp);
393 adb_debug_mode=atoi(tmp);
394 lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "auto_enable", tmp);
395 auto_enable=atoi(tmp);
396 ALOGI("Autosuspend Service Daemon. auto_enable %s\n",tmp);
397#ifdef MOBILETEK_SUSPEND_CFG
398 init_wakelock_func();
399 init_sim_func();
400#endif
401 signal(SIGPIPE,SIG_IGN); // 忽略SIGPIPE信号,防止由于客户端关闭,继续往客户端write,会导致服务端收到SIGPIPE信号而Broken pipe
402
403
404 // init_network_func();
405
406 // if(pthread_cond_init(&feedback_cond,NULL) != 0)
407 // {
408 // strerror_r(errno, buf, sizeof(buf));
409 // ALOGI("Error creating cond: %s\n", buf);
410 // return -1;
411 // }
412
413 set_wakeup_callback(wakeup_feedback);
414 // 注册回调函数
415
416 if(auto_enable==0)
417 {
418 if(autosuspend_disable() < 0)
419 {
420 ALOGI("autosuspend_disable fail.\n");
421 }
422 else
423 {
424 ALOGI("autosuspend_disable success.\n");
425 }
426 }
427 if(auto_enable==1)
428 {
429 if(autosuspend_enable() < 0)
430 {
431 ALOGI("autosuspend_enable fail.\n");
432 }
433 else
434 {
435 ALOGI("autosuspend_enable success.\n");
436 }
437 }
438
439
440 server_sock = listen_port(&server_sockaddr,SOCK_PATH);
441 if(server_sock == -1)
442 return -1;
443
444 server_data_sock = listen_port(&server_data_sockaddr,SOCK_DATA_PATH);
445 if(server_data_sock == -1)
446 return -1;
447#ifdef GSW_SUSPEND_CFG
448 /*jb.qi add for service send when DTR is low on 20221111 start*/
449 pthread_create(&tid_1,NULL,dtr_wakeup,NULL);
450 pthread_detach(tid_1);
451 /*jb.qi add for service send when DTR is low on 20221111 end*/
452#endif
453
454 while (1)
455 {
456 ALOGI("service socket listening...\n");
457 commfd = Accept(server_sock,(struct sockaddr *)&client_sockaddr,&len);
458 if(commfd == -1)
459 {
460 return -1;
461 }
462 if(getpeername(commfd, (struct sockaddr *)&client_sockaddr, &len) == -1)
463 {
464 ALOGI("GETPEERNAME ERROR.\n");
465 // Close(server_sock);
466 Close(commfd);
467 continue;
468 }
469 else
470 {
471 ALOGI("Client socket filepath: %s\n", client_sockaddr.sun_path);
472 }
473
474 commfd_data = Accept(server_data_sock,NULL,NULL);
475 if(commfd_data == -1)
476 {
477 return -1;
478 }
479 ALOGI("data channel connected.\n");
480
481 pthread_create(&tid,NULL,deal_autosuspend,(void*)&commfd);//这里很容易错,最后一个参数要取地址,这是一个指针
482 pthread_detach(tid);
483
484 pthread_create(&tid,NULL,send_feedback,(void*)&commfd_data);
485 pthread_detach(tid);
486
487
488 }
489
490
491}
492
493DEFINE_LYNQ_LIB_LOG(LYNQ_AUTOSUSPEND)
494