blob: 38298499dbdcb44e199e05efd1d5fd818c92ab68 [file] [log] [blame]
b.liu68a94c92025-05-24 12:53:41 +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#include "mbtk_sleep.h"
21#include "mbtk_utils.h"
22
23/*
24This module is system sleep, the system cannot sleep when the lock exists
25To verify whether it is in sleep state, it is necessary to test the power consumption
26Power management principle, as long as a wakelock lock exists, the system will not enter the Suspend state
27So the name can be arbitrarily chosen to indicate that such a lock is needed so that the system does not sleep
28*/
29#define MTBK_POWERIND "/system/etc/powerind" //1806
30
31static bool call_Off = FALSE;
32static bool nw_off = FALSE;
33static bool sms_off = FALSE;
34static bool data_off = FALSE;
35
36static pthread_t lpm_t;
37static int edge_t = 0;
38static int epoll_fd_t = -1;
39static int fd_t = -1;
40static int socket_t[2];
41
42typedef struct{
43 qser_lpm_wakeupin_data_t wakeupin;
44 qser_lpm_wakeupout_data_t wakeupout;
45 qser_lpm_Handler_t wakehandle;
46}lynq_wake_t;
47
48static lynq_wake_t lpm_init;
49
50
51typedef struct
52{
53 int fd;
54 char name[64];
55} lock_name;
56
57#define LOCK_MAX_SIZE 129
58
59lock_name lynq_lock_name[LOCK_MAX_SIZE]={0};
60static bool autosleep_enable = FALSE;
61
62static mbtk_info_handle_t* whitelist_info_handle = NULL;
63
64
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 mbtk_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 mbtk_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 mbtk_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 mbtk_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 mbtk_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 pthread_event1");
344#else
345 fd_t = open("/dev/input/event2", O_RDONLY);
346 LOGI("init pthread_event2");
347#endif
348
349 sleep_epoll_register(epoll_fd_t, fd_t);
350 sleep_epoll_register(epoll_fd_t, socket_t[1]);
351
352 while (true)
353 {
354 struct epoll_event events[2];
355// struct epoll_event ev;
356// int cmd = 0;
357
358 int numEvents = epoll_wait(epoll_fd_t, events, 2, -1);
359
360 for (i = 0; i < numEvents; ++i)
361 {
362 if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP))
363 {
364 LOGE("Error on GPIO device.");
365 return NULL;
366 }
367 else if ((events[i].events & EPOLLIN) || (events[i].events & EPOLLET))
368 {
369 //handleInterrupt(events[i].data.fd);
370 if (events[i].data.fd == socket_t[1])
371 {
372 memset(buf, 0, sizeof(buf));
373 mbtk_read(socket_t[1], buf, sizeof(buf));
374 if (1 == atoi(buf))
375 {
376 if(close(fd_t) == 0)
377 LOGI("close(fd_t)ing");
378
379 sleep_epoll_deregister(epoll_fd_t, socket_t[1]);
380 sleep_epoll_deregister(epoll_fd_t, fd_t);
381 /*
382 memset(&ev, 0, sizeof(struct epoll_event));
383 ev.events = EPOLLIN | EPOLLET;
384 ev.data.fd = socket_t[1];
385 epoll_ctl( epoll_fd_t, EPOLL_CTL_DEL, ev.data.fd, &ev);
386
387 memset(&ev, 0, sizeof(struct epoll_event));
388 ev.events = EPOLLIN | EPOLLET;
389 ev.data.fd = fd_t;
390 epoll_ctl( epoll_fd_t, EPOLL_CTL_DEL, ev.data.fd, &ev);
391 */
392 LOGI("do pthread_exit");
393 return NULL;
394 }
395 }
396 else if (events[i].data.fd == fd_t)
397 {
398 LOGI("go pthread_event");
399 memset(&ev_input, 0x00, size);
400 mbtk_read(fd_t, &ev_input, size);
401 LOGI("ev_input type = %x, code = %x, value = %x", ev_input.type, ev_input.code,ev_input.value);
402#if defined(MBTK_SG_SUPPORT)
403 if (ev_input.code == 2)
404 {
405 LOGI(">>>>ev_input.value = [%d]",ev_input.value);
406 pinValue = (int)ev_input.value;
407 edge_t = pinValue;
408 lpm_init.wakehandle(edge_t);
409 }
410#else
411 if (ev_input.type == 4 && ev_input.code == 3)
412 {
413 LOGI(">>>>ev_input.value = [%d]",ev_input.value);
414 pinValue = (int)ev_input.value;
415 edge_t = pinValue;
416 lpm_init.wakehandle(edge_t);
417 }
418#endif
419
420 }
421 else
422 {
423 LOGE("Unknown events[i].data.fd = %d", events[i].data.fd);
424 }
425 }
426 }
427 }
428 return NULL;
429}
430
431int qser_lpm_init(qser_lpm_Handler_t qser_lpm_handler, qser_pm_cfg_t *qser_lpm_cfg)
432{
433 //UNUSED(qser_lpm_handler);
434 //UNUSED(qser_lpm_cfg);
435 if (socketpair( AF_LOCAL, SOCK_STREAM, 0, socket_t ) < 0 )
436 {
437 LOGE("[qser_lpm_init] could not create thread control socket pair: %s", strerror(errno));
438
439 /*close the control socket pair && Retry again.*/
440 if(socket_t[0] > 0)
441 {
442 close(socket_t[0] );
443 socket_t[0] = -1;
444 }
445
446 if(socket_t[1] > 0)
447 {
448 close(socket_t[1] );
449 socket_t[1] = -1;
450 }
451 return -1;
452 }
453 lpm_init.wakeupin.wakeupin_pin = qser_lpm_cfg->wakeupin.wakeupin_pin;
454 LOGI(">>pin = %d",lpm_init.wakeupin.wakeupin_pin);
455 lpm_init.wakeupin.wakeupin_edge = qser_lpm_cfg->wakeupin.wakeupin_edge;
456 LOGI(">>edge = %d",lpm_init.wakeupin.wakeupin_edge);
457 edge_t = qser_lpm_cfg->wakeupin.wakeupin_edge;//保留原始状态值 0 or 1
458 lpm_init.wakehandle = qser_lpm_handler;
459
460 pthread_attr_t thread_attr;
461 pthread_attr_init(&thread_attr);
462
463 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
464 {
465 LOGE("pthread_attr_setdetachstate() fail");
466 return -1;
467 }
468
469 if(pthread_create(&lpm_t, &thread_attr, threadFunction, NULL))
470 //if(pthread_create(&lpm_t, NULL, threadFunction, NULL))
471 {
472 LOGE("qser_lpm_init can't create thread");
473 return -1;
474 }
475
476 pthread_attr_destroy(&thread_attr);
477
478 //if (edge_t != qser_lpm_cfg->wakeupin.wakeupin_edge)//说明有变化,并且和原来的值不相同
479 //qser_lpm_handler(edge_t);
480
481 return 0;
482}
483
484int qser_lpm_deinit(void)
485{
486 char buf[4]={0};
487
488 if (fd_t == -1)
489 return 0;
490
491 if (fd_t != -1)
492 {
493 //char cmd = 1;
494 strcpy(buf, "1");
495// void* dummy = NULL;
496 mbtk_write( socket_t[0], buf, sizeof(buf) );
497 //pthread_join(lpm_t, &dummy);
498
499 sleep(1);
500 // close the control socket pair
501 if(socket_t[0] > 0)
502 {
503 close(socket_t[0] );
504 socket_t[0] = -1;
505 }
506 if(socket_t[1] > 0)
507 {
508 close(socket_t[1] );
509 socket_t[1] = -1;
510 }
511
512 //重置还原
513 fd_t = -1;
514
515 }
516
517 return 0;
518}
519
520/*
521例如AT*POWERIND=31,就相当于设置NETWORK、SIM、SMS、CS CALL、PS DATA变化时都不主动上报,
522其中PS DATA目前暂时不支持,只是保留了这个标志位;
523AP power state: 1~31 means suspend, bitmap: bit0 - NETWORK;bit1 - SIM;bit2 - SMS;bit3 - CS CALL;bit4 - PS DATA
5240 means resume all.
525目标文件"/system/etc/powerind"
526如果bit0-bit3都配置可以采用的值是1-15,如果是当前采用NETWORK SMS CALL 则值的取值是 1 4 8 5 9 12 13
527
528*/
529
530int qser_whitelist_set(char* whitelish)
531{
532 //UNUSED(whitelish);
533 uint32 on = 0;
534 int call_t, nw_t, data_t, sms_t, tmp;
535
536 int len = strlen(whitelish);
537
538 if (len != 4)
539 {
540 LOGE("whitelish num error num=[%d]",len);
541 return -1;
542 }
543
544 tmp = atoi(whitelish);
545
546 call_t = tmp/1000;
547 nw_t = tmp%1000/100;
548 data_t = tmp%1000%100/10;
549 sms_t = tmp%1000%100%10;
550
551 if (call_t == 1)
552 call_Off = TRUE;
553 else
554 call_Off = FALSE;
555
556 if (nw_t == 1)
557 nw_off = TRUE;
558 else
559 nw_off = FALSE;
560
561 if (data_t == 1)
562 data_off = TRUE;
563 else
564 data_off = FALSE;
565
566 if (sms_t == 1)
567 sms_off = TRUE;
568 else
569 sms_off = FALSE;
570
571 if (call_Off == FALSE && nw_off == FALSE && data_off == FALSE && sms_off == FALSE)
572 {
573 on = 29;//0000的情况,所有上报源都屏蔽,SIM的上报会一直被包含在内
574 }
575 else
576 {
577 if (call_Off == TRUE)
578 call_t = 8;
579 else
580 call_t = 0;
581
582 if (nw_off == TRUE)
583 nw_t = 1;
584 else
585 nw_t = 0;
586
587 if (data_off == TRUE)
588 data_t = 16;
589 else
590 data_t = 0;
591
592 if (sms_off == TRUE)
593 sms_t = 4;
594 else
595 sms_t = 0;
596
597 on = 29 - (call_t + nw_t + data_t + sms_t);//SIM的上报会一直被包含在内
598 }
599
600 if(whitelist_info_handle == NULL)
601 {
602 whitelist_info_handle = mbtk_info_handle_get();
603 if(whitelist_info_handle)
604 {
605 LOGI("creat whitelist_info_handle is success");
606 }
607 else
608 {
609 LOGE("creat whitelist_info_handle is fail");
610 return -1;
611 }
612 }
613
614 int err = mbtk_wakeup_state_set(whitelist_info_handle, on);
615 if(err)
616 {
617 LOGE("whitelist_info_handle Error : %d", err);
618 return -1;
619 }
620
621 return 0;
622}
623
624
625int qser_whitelist_get(char* whitelish)
626{
627 //UNUSED(whitelish);
628 char list[10]={0};
629// int call_t, nw_t, data_t, sms_t;
630 int get_tmp;
631
632 get_tmp = powerrind_get();
633 //LOGI(">>>get_tmp: %d",get_tmp);
634
635 //call 8 nw 1 data 16 sms 4 SIM的上报会一直被包含在内
636 switch(get_tmp)
637 {
638 case 0:
639 sprintf(list, "%d%d%d%d", 1, 1, 1, 1);
640 break;
641 case 8:
642 sprintf(list, "%d%d%d%d", 0, 1, 1, 1);
643 break;
644 case 1:
645 sprintf(list, "%d%d%d%d", 1, 0, 1, 1);
646 break;
647 case 16:
648 sprintf(list, "%d%d%d%d", 1, 1, 0, 1);
649 break;
650 case 4:
651 sprintf(list, "%d%d%d%d", 1, 1, 1, 0);
652 break;
653
654 case 9:
655 sprintf(list, "%d%d%d%d", 0, 0, 1, 1);
656 break;
657 case 24:
658 sprintf(list, "%d%d%d%d", 0, 1, 0, 1);
659 break;
660 case 12:
661 sprintf(list, "%d%d%d%d", 0, 1, 1, 0);
662 break;
663 case 17:
664 sprintf(list, "%d%d%d%d", 1, 0, 0, 1);
665 break;
666 case 5:
667 sprintf(list, "%d%d%d%d", 1, 0, 1, 0);
668 break;
669 case 20:
670 sprintf(list, "%d%d%d%d", 1, 1, 0, 0);
671 break;
672
673 case 25:
674 sprintf(list, "%d%d%d%d", 0, 0, 0, 1);
675 break;
676 case 13:
677 sprintf(list, "%d%d%d%d", 0, 0, 1, 0);
678 break;
679 case 28:
680 sprintf(list, "%d%d%d%d", 0, 1, 0, 0);
681 break;
682 case 21:
683 sprintf(list, "%d%d%d%d", 1, 0, 0, 0);
684 break;
685
686 case 29:
687 sprintf(list, "%d%d%d%d", 0, 0, 0, 0);
688 break;
689
690 default :
691 LOGE("qser_whitelist_get is error");
692 break;
693 }
694
695 //LOGI(">>>get list: %s",list);
696 strncpy(whitelish, list, strlen(list));
697
698 if(whitelist_info_handle != NULL)
699 {
700 mbtk_info_handle_free(&whitelist_info_handle);
701 LOGI("deinit whitelist_info_handle is succuess");
702 }
703
704 return 0;
705}
706
707
708int qser_suspend_timer_set(int time, mbtk_info_callback_func cb)
709{
710 int ret = 0;
711 ret = mbtk_suspend_timer_set(time, cb);
712 if(0 > ret)
713 {
714 LOGE("qser_suspend_timer_set failed");
715 }
716
717
718 return ret;
719}
720
721