blob: 8c147935dfc7b124a0de5776319804ee42b378dd [file] [log] [blame]
b.liu1c74d692024-08-14 17:43:59 +08001#include "lynq-qser-autosuspend.h"
2
3#include <stdio.h>
4#include <unistd.h>
5#include <stddef.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <pthread.h>
10#include <string.h>
11#include <stdlib.h>
12#include <errno.h>
13#include <sys/epoll.h>
14#include <linux/input.h>
15
16#include "mbtk_type.h"
17#include "mbtk_log.h"
18#include "mbtk_info_api.h"
19#include "mbtk_power.h"
20
21/*
22This module is system sleep, the system cannot sleep when the lock exists
23To verify whether it is in sleep state, it is necessary to test the power consumption
24Power management principle, as long as a wakelock lock exists, the system will not enter the Suspend state
25So the name can be arbitrarily chosen to indicate that such a lock is needed so that the system does not sleep
26*/
27#if defined(MBTK_PLATFORM_KERNEL_5)
28#define MTBK_POWERIND "/system/etc/powerind" //1806
29#elif defined(MBTK_PLATFORM_KERNEL_3)
30#define MTBK_POWERIND "/etc/powerind" //1803
31#endif
32
33static bool call_Off = FALSE;
34static bool nw_off = FALSE;
35static bool sms_off = FALSE;
36static bool data_off = FALSE;
37
38static pthread_t lpm_t;
39static int edge_t = 0;
40static int epoll_fd_t = -1;
41static int fd_t = -1;
42static int socket_t[2];
43
44typedef struct{
45 qser_lpm_wakeupin_data_t wakeupin;
46 qser_lpm_wakeupout_data_t wakeupout;
47 qser_lpm_Handler_t wakehandle;
48}lynq_wake_t;
49
50static lynq_wake_t lpm_init;
51
52
53typedef struct
54{
55 int fd;
56 char name[64];
57} lock_name;
58
59#define LOCK_MAX_SIZE 129
60
61lock_name lynq_lock_name[LOCK_MAX_SIZE]={0};
62static bool autosleep_enable = FALSE;
63
64static mbtk_info_handle_t* whitelist_info_handle = NULL;
65
66static int powerrind_get()
67{
68 char buffer[4];
69 int ret = 0;
70
71 int fd = open(MTBK_POWERIND, O_RDWR | O_SYNC, 0662);
72 if (fd != -1)
73 {
74 read(fd, buffer, strlen(buffer)+1);
75 close(fd);
76 }
77
78 ret = atoi(buffer);
79
80 return ret;
81}
82
83#if 1
84static int sleep_epoll_deregister(int epoll_fd,int fd )
85{
86 int ret;
87 do {
88 ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
89 } while (ret < 0 && errno == EINTR);
90 return ret;
91}
92
93static int sleep_epoll_register(int epoll_fd, int fd)
94{
95 struct epoll_event ev;
96 int ret, flags;
97
98 /* important: make the fd non-blocking */
99 flags = fcntl(fd, F_GETFL);
100 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
101
102 ev.events = EPOLLIN;
103 ev.data.fd = fd;
104 do {
105 ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
106 } while (ret < 0 && errno == EINTR);
107
108 return ret;
109}
110#endif
111
112int qser_autosuspend_enable(char enable)
113{
114 //UNUSED(enable);
115
116 if((enable == 1) || enable == '1')
117 {
118 //if(!mbtk_system_sleep())
119 if(!access("/sys/power/autosleep", W_OK))
120 {
121 system("echo mem > /sys/power/autosleep");
122 autosleep_enable = TRUE;
123 return 0;
124 }
125 else
126 {
127 LOGE("/sys/power/autosleep can not write.");
128 return -1;
129 }
130 }
131 else if((enable == 0) || enable == '0')
132 {
133 if(!access("/sys/power/autosleep", W_OK))
134 {
135 system("echo off > /sys/power/autosleep");
136 autosleep_enable = FALSE;
137 return 0;
138 }
139 else
140 {
141 LOGE("/sys/power/autosleep can not write.");
142 return -1;
143 }
144 }
145 else
146 {
147 LOGE("qser_autosuspend_enablecan enable err.");
148 return -1;
149 }
150
151 return 0;
152}
153
154int qser_wakelock_create(const char* name , size_t len)
155{
156 //UNUSED(name);
157 //UNUSED(len);
158 int len_t;
159/*
160 if(!autosleep_enable) {
161 LOGE("Autosleep not enable.");
162 return -1;
163 }
164*/
165 len_t = strlen(name);
166
167 if((name != NULL) && (len < 33) && (len_t < 33))
168 {
169 int i;
170 //name
171 for(i=1 ;i<LOCK_MAX_SIZE;i++)
172 {
173 if(strcmp(lynq_lock_name[i].name, name) == 0)
174 {
175 LOGE("Repeated names.");
176 return -1;
177 }
178 }
179
180 for(i=1 ;i<LOCK_MAX_SIZE;i++)
181 {
182 if(lynq_lock_name[i].fd == 0)
183 break;
184 }
185
186 if (i >= LOCK_MAX_SIZE)
187 {
188 LOGE("Fd is full.");
189 return -1;
190 }
191
192 memcpy(lynq_lock_name[i].name, name, strlen(name)+1);
193 lynq_lock_name[i].fd = i;
194 return lynq_lock_name[i].fd -1;//Starting from scratch
195 }
196 else
197 return -1;
198
199 return -1;
200}
201
202int qser_wakelock_lock(int fd)
203{
204 //UNUSED(fd);
205/*
206 if(!autosleep_enable) {
207 LOGE("Autosleep not enable.");
208 return -1;
209 }
210*/
211 int i;
212 for(i=1;i<LOCK_MAX_SIZE;i++)
213 {
214 if(lynq_lock_name[i].fd -1 == fd)
215 break;
216 }
217 if(i == LOCK_MAX_SIZE)
218 {
219 LOGE("LOCK_MAX_SIZE is full\n");
220 return -1;
221 }
222
223 if(!access("/sys/power/wake_lock", W_OK))
224 {
225 char cmd[128]={0};
226 sprintf(cmd, "echo %s > /sys/power/wake_lock", lynq_lock_name[i].name);
227 system(cmd);
228 return 0;
229 }
230 else
231 {
232 LOGE("/sys/power/wake_lock can not write.");
233 return -1;
234 }
235
236 return 0;
237}
238
239int qser_wakelock_unlock(int fd)
240{
241 //UNUSED(fd);
242/*
243 if(!autosleep_enable) {
244 LOGE("Autosleep not enable.");
245 return -1;
246 }
247*/
248 int i;
249 for(i=1;i<LOCK_MAX_SIZE;i++)
250 {
251 if(lynq_lock_name[i].fd -1 == fd)
252 break;
253 }
254 if(i == LOCK_MAX_SIZE)
255 {
256 LOGE("LOCK_MAX_SIZE is full\n");
257 return -1;
258 }
259
260 if(!access("/sys/power/wake_unlock", W_OK))
261 {
262 char cmd[128]={0};
263 sprintf(cmd, "echo %s > /sys/power/wake_unlock", lynq_lock_name[i].name);
264 system(cmd);
265 return 0;
266 }
267 else
268 {
269 LOGE("/sys/power/wake_unlock can not write.");
270 return -1;
271 }
272
273 return 0;
274}
275
276int qser_wakelock_destroy(int fd)
277{
278 //UNUSED(fd);
279/*
280 if(!autosleep_enable) {
281 LOGE("Autosleep not enable.");
282 return -1;
283 }
284*/
285 int i;
286 for(i=1;i<LOCK_MAX_SIZE;i++)
287 {
288 if(lynq_lock_name[i].fd -1 == fd)
289 break;
290 }
291
292 if(i == LOCK_MAX_SIZE)
293 {
294 LOGE("LOCK_MAX_SIZE is full\n");
295 return -1;
296 }
297 else
298 {
299 lynq_lock_name[i].fd = 0;
300 memset(lynq_lock_name[i].name, 0, 64);
301 return 0;
302 }
303
304 return 0;
305}
306
307void *threadFunction(void *arg)
308{
309 int pinValue;
310 int i;
311 char buf[8] = {0};
312 struct input_event ev_input = { 0 };
313 const int size = sizeof(struct input_event);
314
315 epoll_fd_t = epoll_create(2);
316/*
317 struct epoll_event event;
318 memset(&event, 0, sizeof(struct epoll_event));
319 event.events = EPOLLIN | EPOLLET;
320 event.data.fd = open("/dev/input/event0", O_RDONLY); // 根据实际情况指定正确的GPIO设备文件名
321
322 fd_t = event.data.fd;
323 if (epoll_ctl(epoll_fd_t, EPOLL_CTL_ADD, event.data.fd, &event) == -1)
324 {
325 LOGE("Failed to add GPIO device file.");
326 return NULL;
327 }
328
329 memset(&event, 0, sizeof(struct epoll_event));
330 event.events = EPOLLIN | EPOLLET;
331 event.data.fd = socket_t[0];
332 LOGE("threadFunction event.data.fd =[%d] ", event.data.fd);
333
334 if (epoll_ctl(epoll_fd_t, EPOLL_CTL_ADD, event.data.fd, &event) == -1)
335 {
336 LOGE("Failed to add GPIO device file.");
337 return NULL;
338 }
339*/
340
341#if defined(MBTK_SG_SUPPORT)
342 fd_t = open("/dev/input/event1", O_RDONLY);
343 LOGI("init sg pthread_event");
344#else
345 fd_t = open("/dev/input/event0", O_RDONLY);
346#endif
347
348 sleep_epoll_register(epoll_fd_t, fd_t);
349 sleep_epoll_register(epoll_fd_t, socket_t[1]);
350
351 while (true)
352 {
353 struct epoll_event events[2];
354 struct epoll_event ev;
355 int cmd = 0;
356
357 int numEvents = epoll_wait(epoll_fd_t, events, 2, -1);
358
359 for (i = 0; i < numEvents; ++i)
360 {
361 if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP))
362 {
363 LOGE("Error on GPIO device.");
364 return NULL;
365 }
366 else if ((events[i].events & EPOLLIN) || (events[i].events & EPOLLET))
367 {
368 //handleInterrupt(events[i].data.fd);
369 if (events[i].data.fd == socket_t[1])
370 {
371 memset(buf, 0, sizeof(buf));
372 read(socket_t[1], buf, sizeof(buf));
373 if (1 == atoi(buf))
374 {
375 if(close(fd_t) == 0)
376 LOGI("close(fd_t)ing");
377
378 sleep_epoll_deregister(epoll_fd_t, socket_t[1]);
379 sleep_epoll_deregister(epoll_fd_t, fd_t);
380 /*
381 memset(&ev, 0, sizeof(struct epoll_event));
382 ev.events = EPOLLIN | EPOLLET;
383 ev.data.fd = socket_t[1];
384 epoll_ctl( epoll_fd_t, EPOLL_CTL_DEL, ev.data.fd, &ev);
385
386 memset(&ev, 0, sizeof(struct epoll_event));
387 ev.events = EPOLLIN | EPOLLET;
388 ev.data.fd = fd_t;
389 epoll_ctl( epoll_fd_t, EPOLL_CTL_DEL, ev.data.fd, &ev);
390 */
391 LOGI("do pthread_exit");
392 return NULL;
393 }
394 }
395 else if (events[i].data.fd == fd_t)
396 {
397 LOGI("go pthread_event");
398 memset(&ev_input, 0x00, size);
399 read(fd_t, &ev_input, size);
400 LOGI("ev_input type = %x, code = %x, value = %x", ev_input.type, ev_input.code,ev_input.value);
401 if (ev_input.code == 2)
402 {
403 LOGI(">>>>ev_input.value = [%d]",ev_input.value);
404 pinValue = (int)ev_input.value;
405 edge_t = pinValue;
406 lpm_init.wakehandle(edge_t);
407 }
408 }
409 else
410 {
411 LOGE("Unknown events[i].data.fd = %d", events[i].data.fd);
412 }
413 }
414 }
415 }
416 return NULL;
417}
418
419int qser_lpm_init(qser_lpm_Handler_t qser_lpm_handler, qser_pm_cfg_t *qser_lpm_cfg)
420{
421 //UNUSED(qser_lpm_handler);
422 //UNUSED(qser_lpm_cfg);
423 if (socketpair( AF_LOCAL, SOCK_STREAM, 0, socket_t ) < 0 )
424 {
425 LOGE("[qser_lpm_init] could not create thread control socket pair: %s", strerror(errno));
426
427 /*close the control socket pair && Retry again.*/
428 if(socket_t[0] > 0)
429 {
430 close(socket_t[0] );
431 socket_t[0] = -1;
432 }
433
434 if(socket_t[1] > 0)
435 {
436 close(socket_t[1] );
437 socket_t[1] = -1;
438 }
439 return -1;
440 }
441 lpm_init.wakeupin.wakeupin_pin = qser_lpm_cfg->wakeupin.wakeupin_pin;
442 LOGI(">>pin = %d",lpm_init.wakeupin.wakeupin_pin);
443 lpm_init.wakeupin.wakeupin_edge = qser_lpm_cfg->wakeupin.wakeupin_edge;
444 LOGI(">>edge = %d",lpm_init.wakeupin.wakeupin_edge);
445 edge_t = qser_lpm_cfg->wakeupin.wakeupin_edge;//保留原始状态值 0 or 1
446 lpm_init.wakehandle = qser_lpm_handler;
447
448 pthread_attr_t thread_attr;
449 pthread_attr_init(&thread_attr);
450
451 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
452 {
453 LOGE("pthread_attr_setdetachstate() fail");
454 return -1;
455 }
456
457 if(pthread_create(&lpm_t, &thread_attr, threadFunction, NULL))
458 //if(pthread_create(&lpm_t, NULL, threadFunction, NULL))
459 {
460 LOGE("qser_lpm_init can't create thread");
461 return -1;
462 }
463
464 pthread_attr_destroy(&thread_attr);
465
466 //if (edge_t != qser_lpm_cfg->wakeupin.wakeupin_edge)//说明有变化,并且和原来的值不相同
467 //qser_lpm_handler(edge_t);
468
469 return 0;
470}
471
472int qser_lpm_deinit(void)
473{
474 char buf[4]={0};
475
476 if (fd_t == -1)
477 return 0;
478
479 if (fd_t != -1)
480 {
481 //char cmd = 1;
482 strcpy(buf, "1");
483 void* dummy = NULL;
484 write( socket_t[0], buf, sizeof(buf) );
485 //pthread_join(lpm_t, &dummy);
486
487 sleep(1);
488 // close the control socket pair
489 if(socket_t[0] > 0)
490 {
491 close(socket_t[0] );
492 socket_t[0] = -1;
493 }
494 if(socket_t[1] > 0)
495 {
496 close(socket_t[1] );
497 socket_t[1] = -1;
498 }
499
500 //重置还原
501 fd_t = -1;
502
503 }
504
505 return 0;
506}
507
508/*
509例如AT*POWERIND=31,就相当于设置NETWORK、SIM、SMS、CS CALL、PS DATA变化时都不主动上报,
510其中PS DATA目前暂时不支持,只是保留了这个标志位;
511AP power state: 1~31 means suspend, bitmap: bit0 - NETWORK;bit1 - SIM;bit2 - SMS;bit3 - CS CALL;bit4 - PS DATA
5120 means resume all.
513目标文件"/system/etc/powerind"
514如果bit0-bit3都配置可以采用的值是1-15,如果是当前采用NETWORK SMS CALL 则值的取值是 1 4 8 5 9 12 13
515
516*/
517
518int qser_whitelist_set(char* whitelish)
519{
520 //UNUSED(whitelish);
521 uint32 on = 0;
522 int call_t, nw_t, data_t, sms_t, tmp;
523
524 int len = strlen(whitelish);
525
526 if (len != 4)
527 {
528 LOGE("whitelish num error num=[%d]",len);
529 return -1;
530 }
531
532 tmp = atoi(whitelish);
533
534 call_t = tmp/1000;
535 nw_t = tmp%1000/100;
536 data_t = tmp%1000%100/10;
537 sms_t = tmp%1000%100%10;
538
539 if (call_t == 1)
540 call_Off = TRUE;
541 else
542 call_Off = FALSE;
543
544 if (nw_t == 1)
545 nw_off = TRUE;
546 else
547 nw_off = FALSE;
548
549 if (data_t == 1)
550 data_off = TRUE;
551 else
552 data_off = FALSE;
553
554 if (sms_t == 1)
555 sms_off = TRUE;
556 else
557 sms_off = FALSE;
558
559 if (call_Off == FALSE && nw_off == FALSE && data_off == FALSE && sms_off == FALSE)
560 {
561 on = 29;//0000的情况,所有上报源都屏蔽,SIM的上报会一直被包含在内
562 }
563 else
564 {
565 if (call_Off == TRUE)
566 call_t = 8;
567 else
568 call_t = 0;
569
570 if (nw_off == TRUE)
571 nw_t = 1;
572 else
573 nw_t = 0;
574
575 if (data_off == TRUE)
576 data_t = 16;
577 else
578 data_t = 0;
579
580 if (sms_off == TRUE)
581 sms_t = 4;
582 else
583 sms_t = 0;
584
585 on = 29 - (call_t + nw_t + data_t + sms_t);//SIM的上报会一直被包含在内
586 }
587
588 if(whitelist_info_handle == NULL)
589 {
590 whitelist_info_handle = mbtk_info_handle_get();
591 if(whitelist_info_handle)
592 {
593 LOGI("creat whitelist_info_handle is success");
594 }
595 else
596 {
597 LOGE("creat whitelist_info_handle is fail");
598 return -1;
599 }
600 }
601
602 int err = mbtk_wakeup_state_set(whitelist_info_handle, on);
603 if(err)
604 {
605 LOGE("whitelist_info_handle Error : %d", err);
606 return -1;
607 }
608
609 return 0;
610}
611
612
613int qser_whitelist_get(char* whitelish)
614{
615 //UNUSED(whitelish);
616 char list[10]={0};
617 int call_t, nw_t, data_t, sms_t;
618 int get_tmp;
619
620 get_tmp = powerrind_get();
621 //LOGI(">>>get_tmp: %d",get_tmp);
622
623 //call 8 nw 1 data 16 sms 4 SIM的上报会一直被包含在内
624 switch(get_tmp)
625 {
626 case 0:
627 sprintf(list, "%d%d%d%d", 1, 1, 1, 1);
628 break;
629 case 8:
630 sprintf(list, "%d%d%d%d", 0, 1, 1, 1);
631 break;
632 case 1:
633 sprintf(list, "%d%d%d%d", 1, 0, 1, 1);
634 break;
635 case 16:
636 sprintf(list, "%d%d%d%d", 1, 1, 0, 1);
637 break;
638 case 4:
639 sprintf(list, "%d%d%d%d", 1, 1, 1, 0);
640 break;
641
642 case 9:
643 sprintf(list, "%d%d%d%d", 0, 0, 1, 1);
644 break;
645 case 24:
646 sprintf(list, "%d%d%d%d", 0, 1, 0, 1);
647 break;
648 case 12:
649 sprintf(list, "%d%d%d%d", 0, 1, 1, 0);
650 break;
651 case 17:
652 sprintf(list, "%d%d%d%d", 1, 0, 0, 1);
653 break;
654 case 5:
655 sprintf(list, "%d%d%d%d", 1, 0, 1, 0);
656 break;
657 case 20:
658 sprintf(list, "%d%d%d%d", 1, 1, 0, 0);
659 break;
660
661 case 25:
662 sprintf(list, "%d%d%d%d", 0, 0, 0, 1);
663 break;
664 case 13:
665 sprintf(list, "%d%d%d%d", 0, 0, 1, 0);
666 break;
667 case 28:
668 sprintf(list, "%d%d%d%d", 0, 1, 0, 0);
669 break;
670 case 21:
671 sprintf(list, "%d%d%d%d", 1, 0, 0, 0);
672 break;
673
674 case 29:
675 sprintf(list, "%d%d%d%d", 0, 0, 0, 0);
676 break;
677
678 default :
679 LOGE("qser_whitelist_get is error");
680 break;
681 }
682
683 //LOGI(">>>get list: %s",list);
684 strncpy(whitelish, list, strlen(list));
685
686 if(whitelist_info_handle != NULL)
687 {
688 mbtk_info_handle_free(&whitelist_info_handle);
689 LOGI("deinit whitelist_info_handle is succuess");
690 }
691
692 return 0;
693}
694