blob: 0565bd2e5bdaed162a8c93ce4af37816366643b1 [file] [log] [blame]
xj4049f512022-04-02 15:41:13 +08001/* //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 <dlfcn.h>
21#include <string.h>
22#include <pthread.h>
23#include <stdint.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <errno.h>
27#include <liblog/lynq_deflog.h>
28#include <include/lynq_uci.h>
29#include <sys/socket.h>
30#include <sys/un.h>
31
32#define LOG_UCI_MODULE "lynq_autosuspend"
33#define LOG_UCI_FILE "lynq_uci"
34
35#define LOG_TAG "AUTOSUSPEND"
36
37#define USER_LOG_TAG "PMS"
38
39#define SOCK_PATH "/tmp/autosuspend.server" //不能在当前这个目录创建socket文件,否则报错找不到文件(可能是因为这是在共享文件夹下,不支持创建socket文件)
40
41// #define LYINFLOG(X...) lynq_log_global_output(LOG_INFO,X)
42
43#define TIME_OUT_TIME 30
44
45
46#include <log/log.h>
47
48
49#define MAX_LIB_ARGS 16
50
51int adb_debug_mode = 0;
52
53extern int autosuspend_enable(void);
54extern int autosuspend_disable(void);
55extern void init_wakelock_func(void);
56extern void init_sim_func();
57extern void init_network_func();
58
59
60static void usage(const char *argv0) {
61 fprintf(stderr, "Usage: %s -l <possible_max_sleep_time> [-- <args for Autosuspend Service>]\n", argv0);
62 exit(EXIT_FAILURE);
63}
64
65
66
67static int make_argv(char * args, char ** argv) {
68 // Note: reserve argv[0]
69 int count = 1;
70 char * tok;
71 char * s = args;
72
73 while ((tok = strtok(s, " \0"))) {
74 argv[count] = tok;
75 s = NULL;
76 count++;
77 }
78 return count;
79}
80
81static int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
82{
83 int n;
84
85 while((n = accept(fd, sa, salenptr)) < 0)
86 {
87 if((errno == ECONNABORTED) || (errno == EINTR))
88 continue;
89 else
90 {
91 ALOGI("accept error\n");
92 return -1;
93 }
94 }
95 return n;
96}
97
98static int Bind(int fd, const struct sockaddr *sa, socklen_t salen)
99{
100 if(bind(fd, sa, salen) < 0)
101 {
102 // ALOGI("bind error\n");
103 perror("bind error");
104 return -1;
105 }
106 return 0;
107}
108
109static int Connect(int fd, const struct sockaddr *sa, socklen_t salen)
110{
111 if(connect(fd, sa, salen) < 0)
112 {
113 ALOGI("connect error\n");
114 return -1;
115 }
116 return 0;
117}
118
119static int Socket(int family, int type, int protocol)
120{
121 int n;
122
123 if ( (n = socket(family, type, protocol)) < 0)
124 {
125 ALOGI("socket error\n");
126 return -1;
127 }
128 return n;
129}
130
131static int Listen(int fd, int backlog)
132{
133 if(listen(fd, backlog) < 0)
134 {
135 ALOGI("listen error\n");
136 return -1;
137 }
138 return 0;
139}
140
141static int connect_with_timeout(int sockfd, struct sockaddr *servaddr)
142{
143 int error = -1, len;
144 len = sizeof(int);
145 struct timeval tm;
146 fd_set set;
147 int flags;
148 flags = fcntl(sockfd, F_GETFL, 0);
149 fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
150 int ret = -1;
151 if(connect(sockfd, servaddr, sizeof(struct sockaddr)) == -1)
152 {
153 tm.tv_sec = TIME_OUT_TIME;
154 tm.tv_usec = 0;
155 FD_ZERO(&set);
156 FD_SET(sockfd, &set);
157 if(select(sockfd + 1, NULL, &set, NULL, &tm) > 0)
158 {
159 //���ص�ǰsockfd����״̬����SO_ERROR
160 getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
161 if(error == 0)
162 {
163 ret = 0;
164 }
165 else
166 {
167 ALOGI("connect error\n");
168 ret = -1;
169 }
170 }
171 else
172 {
173 ALOGI("connect time out\n");
174 ret = -1;
175 }
176 }
177 else
178 ret = 0;
179 fcntl(sockfd,F_SETFL,flags & ~O_NONBLOCK);
180 return ret;
181}
182
183
184static int listen_port(struct sockaddr_un *addr, char *sockpath)
185{
186 int listenfd;
187 listenfd = Socket(AF_UNIX,SOCK_STREAM,0);
188 if(listenfd == -1)
189 return -1;
190 memset(addr, 0, sizeof(struct sockaddr_un));
191 addr->sun_family = AF_UNIX;
192 strcpy(addr->sun_path,sockpath);
193 // int opt = 1;
194 // if(setsockopt(listenfd, SOL_SOCKET,SO_REUSEADDR, (const void *)&opt, sizeof(opt)) == -1)
195 // {
196 // perror("setsockopt error");
197 // return -1;
198 // }
199
200// 以上方法对非网络的本地socket无效,应该用unlink函数避免Address already in use的错误
201
202
203 unlink(sockpath);
204 if(Bind(listenfd,(struct sockaddr *)addr,sizeof(*addr)) == -1)
205 return -1;
206
207 if(Listen(listenfd,20) == -1)
208 return -1;
209
210 return listenfd;
211}
212
213static ssize_t Read(int fd, void *ptr, size_t nbytes)
214{
215 ssize_t n;
216
217 while((n = read(fd, ptr, nbytes)) == -1)
218 {
219 //printf("READ,%d\n",fd);
220 if (errno == EINTR)
221 {
222 ALOGI("read error eintr\n");
223 continue;
224 }
225 else if(errno == EAGAIN)
226 {
227 //PRINTF("read time out\n");
228 return -1;
229 }
230 else
231 {
232 ALOGI("read error\n");
233 return -1;
234 }
235 }
236 //sleep(2);
237 //printf("READ1,%d\n", fd);
238 return n;
239}
240
241static ssize_t Write(int fd, const void *ptr, size_t nbytes)
242{
243 ssize_t n;
244
245 while((n = write(fd, ptr, nbytes)) == -1)
246 {
247 if (errno == EINTR)
248 continue;
249 else if(errno == EPIPE)
250 {
251 ALOGI("write error epipe\n");
252 return -1;
253 }
254 else
255 return -1;
256 }
257 return n;
258}
259
260static int Close(int fd)
261{
262 if (close(fd) == -1)
263 {
264 ALOGI("close error");
265 return -1;
266 }
267 return 0;
268}
269
270void *deal_autosuspend(void *sockfd)
271{
272 int commfd = *((int *)sockfd);
273 char buf[256];
274
275 while(1)
276 {
277 memset(buf,0,sizeof(buf));
278 ALOGI("deal_autosuspend start to read.\n");
279 // 错误点:read函数在对端关闭后,也会直接返回0,不会阻塞,因此要判断是否返回0,返回0表示对端已经关闭,此时要跳出while循环不再监听
280 // 为什么对端会关闭?因为在客户端没有用nohup方式打开的情况下,系统睡眠后客户端进行会直接被杀死,对端会关闭,所以会导致read不阻塞,且总是返回0的现象
281 if(Read(commfd,buf,sizeof(buf)) == 0)
282 {
283 break;
284 }
285 if(strcmp(buf,"enable") == 0)
286 {
287 if(autosuspend_enable() < 0)
288 {
289 ALOGI("autosuspend_enable fail.\n");
290 }
291 else
292 {
293 ALOGI("autosuspend_enable success.\n");
294 }
295 }
296 else if(strcmp(buf,"disable") == 0)
297 {
298 if(autosuspend_disable() < 0)
299 {
300 ALOGI("autosuspend_disable fail.\n");
301 }
302 else
303 {
304 ALOGI("autosuspend_disable success.\n");
305 }
306 }
307 else
308 {
309 ALOGI("Unknown cmd.\n");
310 }
311 }
312
313
314
315}
316
317
318
319int main(int argc, char **argv) {
320
321
322 // int i = 0;
323 // RLOGD("**Autosuspend Service Daemon Started**");
324 // RLOGD("**Autosuspend Service param count=%d**", argc);
325 char tmp[20];
326 int server_sock, commfd, len;
327 struct sockaddr_un server_sockaddr;
328 struct sockaddr_un client_sockaddr;
329 len = sizeof(server_sockaddr);
330
331 pthread_t tid;
332
333 int auto_enable = 0;
334 LYLOGEINIT(USER_LOG_TAG);
335 LYLOGSET(LOG_DEBUG);
336 // LYLOGSET(LOG_ERROR);
337
338
339 lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "debug", tmp);
340 ALOGI("[1832]Autosuspend Service Daemon. debug %s\n",tmp);
341 adb_debug_mode=atoi(tmp);
342 lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "auto_enable", tmp);
343 auto_enable=atoi(tmp);
344 ALOGI("Autosuspend Service Daemon. auto_enable %s\n",tmp);
345 init_wakelock_func();
346 init_sim_func();
347 // init_network_func();
348 if(auto_enable==0)
349 {
350 if(autosuspend_disable() < 0)
351 {
352 ALOGI("autosuspend_disable fail.\n");
353 }
354 else
355 {
356 ALOGI("autosuspend_disable success.\n");
357 }
358 }
359 if(auto_enable==1)
360 {
361 if(autosuspend_enable() < 0)
362 {
363 ALOGI("autosuspend_enable fail.\n");
364 }
365 else
366 {
367 ALOGI("autosuspend_enable success.\n");
368 }
369 }
370
371
372 server_sock = listen_port(&server_sockaddr,SOCK_PATH);
373 if(server_sock == -1)
374 return -1;
375
376 while (1)
377 {
378 ALOGI("service socket listening...\n");
379 commfd = Accept(server_sock,(struct sockaddr *)&client_sockaddr,&len);
380 if(commfd == -1)
381 {
382 return -1;
383 }
384 if(getpeername(commfd, (struct sockaddr *)&client_sockaddr, &len) == -1)
385 {
386 ALOGI("GETPEERNAME ERROR.\n");
387 close(server_sock);
388 close(commfd);
389 continue;
390 }
391 else
392 {
393 ALOGI("Client socket filepath: %s\n", client_sockaddr.sun_path);
394 }
395 pthread_create(&tid,NULL,deal_autosuspend,(void*)&commfd);//这里很容易错,最后一个参数要取地址,这是一个指针
396 pthread_detach(tid);
397
398 }
399
400 /* for (i = 1; i < argc ;) {
401 if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
402 rilLibPath = argv[i + 1];
403 i += 2;
404 } else if (0 == strcmp(argv[i], "--")) {
405 i++;
406 hasLibArgs = 1;
407 break;
408 } else if (0 == strcmp(argv[i], "-c") && (argc - i > 1)) {
409 clientId = argv[i+1];
410 i += 2;
411 } else {
412 usage(argv[0]);
413 }
414 }
415
416 if (clientId == NULL) {
417 clientId = "0";
418 } else if (atoi(clientId) >= MAX_RILDS) {
419 RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
420 exit(0);
421 }
422 if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
423 strncpy(ril_service_name, ril_service_name_base, MAX_SERVICE_NAME_LENGTH);
424 strncat(ril_service_name, clientId, MAX_SERVICE_NAME_LENGTH);
425 }
426
427 if (rilLibPath == NULL) {
428 if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
429 // No lib sepcified on the command line, and nothing set in props.
430 // Assume "no-ril" case.
431 goto done;
432 } else {
433 rilLibPath = libPath;
434 }
435 }
436
437 dlHandle = dlopen(rilLibPath, RTLD_NOW);
438
439 if (dlHandle == NULL) {
440 RLOGE("dlopen failed: %s", dlerror());
441 exit(EXIT_FAILURE);
442 }
443
444 RIL_startEventLoop();
445
446 rilInit =
447 (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
448 dlsym(dlHandle, "RIL_Init");
449
450 if (rilInit == NULL) {
451 RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
452 exit(EXIT_FAILURE);
453 }
454
455 dlerror(); // Clear any previous dlerror
456 rilUimInit =
457 (RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
458 dlsym(dlHandle, "RIL_SAP_Init");
459 err_str = dlerror();
460 if (err_str) {
461 RLOGW("RIL_SAP_Init not defined or exported in %s: %s\n", rilLibPath, err_str);
462 } else if (!rilUimInit) {
463 RLOGW("RIL_SAP_Init defined as null in %s. SAP Not usable\n", rilLibPath);
464 }
465
466 if (hasLibArgs) {
467 rilArgv = argv + i - 1;
468 argc = argc -i + 1;
469 } else {
470 static char * newArgv[MAX_LIB_ARGS];
471 static char args[PROPERTY_VALUE_MAX];
472 rilArgv = newArgv;
473 property_get(LIB_ARGS_PROPERTY, args, "");
474 argc = make_argv(args, rilArgv);
475 }
476
477 rilArgv[argc++] = "-c";
478 rilArgv[argc++] = (char*)clientId;
479 RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);
480
481 // Make sure there's a reasonable argv[0]
482 rilArgv[0] = argv[0];
483
484 funcs = rilInit(&s_rilEnv, argc, rilArgv);
485 RLOGD("RIL_Init rilInit completed");
486
487 RIL_register(funcs);
488
489 RLOGD("RIL_Init RIL_register completed");
490
491 if (rilUimInit) {
492 RLOGD("RIL_register_socket started");
493 RIL_register_socket(rilUimInit, RIL_SAP_SOCKET, argc, rilArgv);
494 }
495
496 RLOGD("RIL_register_socket completed");
497
498done:
499
500 rilc_thread_pool();
501
502 RLOGD("RIL_Init starting sleep loop");*/
503 while (1) {
504 // ALOGI("start autosuspend_enable:%d\n",(i++));
505 sleep(5);
506
507 }
508}