blob: 407b906734c95ef219e42745b279e134b2c8821f [file] [log] [blame]
liuyang34770f82024-11-14 17:26:24 +08001#include <pthread.h>
2#include <sys/epoll.h>
3#include <sys/timerfd.h>
4
r.xiao27072552024-10-24 01:02:48 -07005#include "mbtk_sleep.h"
6#include "mbtk_log.h"
b.liu9e8584b2024-11-06 19:21:28 +08007#include "mbtk_utils.h"
r.xiao27072552024-10-24 01:02:48 -07008
b.liuacb8b4a2024-11-19 15:50:11 +08009static bool autosleep_enable = FALSE;
10
r.xiao72f92372024-10-28 04:00:43 -070011static mbtk_lock_name_s mbtk_lock_name[LOCK_MAX_SIZE]={0};
r.xiao27072552024-10-24 01:02:48 -070012
liuyang83375062024-11-22 17:49:49 +080013int g_mEpollFd = -1;
b.liu670a7892024-11-21 18:38:54 +080014mbtk_sleep_callback_func g_sleep_timer_cb;
liuyang34770f82024-11-14 17:26:24 +080015int g_sleep_timer_fd = 0;
liuyang83375062024-11-22 17:49:49 +080016pthread_t g_timer_thread_id;
17
r.xiaofa03d832024-12-17 21:44:22 -080018int mbtk_powerrind_get()
19{
20 char buffer[4];
21 int ret = 0;
liuyang83375062024-11-22 17:49:49 +080022
r.xiaofa03d832024-12-17 21:44:22 -080023 int fd = open(MTBK_POWERIND, O_RDWR | O_SYNC, 0662);
24 if (fd != -1)
25 {
26 mbtk_read(fd, buffer, strlen(buffer)+1);
27 close(fd);
28 }
29
30 ret = atoi(buffer);
31
32 return ret;
33}
liuyang34770f82024-11-14 17:26:24 +080034
r.xiao27072552024-10-24 01:02:48 -070035
36int mbtk_autosuspend_enable(char enable)
37{
38 if((enable == 1) || enable == '1')
39 {
40 if(!access("/sys/power/autosleep", W_OK))
41 {
b.liu9e8584b2024-11-06 19:21:28 +080042 mbtk_system("echo mem > /sys/power/autosleep");
r.xiao27072552024-10-24 01:02:48 -070043 autosleep_enable = TRUE;
44 return 0;
45 }
46 else
47 {
48 LOGE("/sys/power/autosleep can not write.");
49 return -1;
50 }
51 }
52 else if((enable == 0) || enable == '0')
53 {
54 if(!access("/sys/power/autosleep", W_OK))
55 {
b.liu9e8584b2024-11-06 19:21:28 +080056 mbtk_system("echo off > /sys/power/autosleep");
r.xiao27072552024-10-24 01:02:48 -070057 autosleep_enable = FALSE;
58 return 0;
59 }
60 else
61 {
62 LOGE("/sys/power/autosleep can not write.");
63 return -1;
64 }
65 }
66 else
67 {
68 LOGE("qser_autosuspend_enablecan enable err.");
69 return -1;
70 }
71
72 return 0;
73}
74
75int mbtk_wakelock_create(const char* name , size_t len)
76{
77 int len_t;
78
79 len_t = strlen(name);
80
81 if((name != NULL) && (len < 33) && (len_t < 33))
82 {
83 int i;
84 for(i=1 ;i<LOCK_MAX_SIZE;i++)
85 {
86 if(strcmp(mbtk_lock_name[i].name, name) == 0)
87 {
88 LOGE("Repeated names.");
89 return -1;
90 }
91 }
92
93 for(i=1 ;i<LOCK_MAX_SIZE;i++)
94 {
95 if(mbtk_lock_name[i].fd == 0)
96 break;
97 }
b.liu9e8584b2024-11-06 19:21:28 +080098
r.xiao27072552024-10-24 01:02:48 -070099 if (i >= LOCK_MAX_SIZE)
100 {
101 LOGE("Fd is full.");
102 return -1;
103 }
104
105 memcpy(mbtk_lock_name[i].name, name, strlen(name)+1);
106 mbtk_lock_name[i].fd = i;
107 return mbtk_lock_name[i].fd -1;//Starting from scratch
108 }
109 else
110 return -1;
111
112 return -1;
113}
114
115int mbtk_wakelock_lock(int fd)
116{
117 int i;
118 for(i=1;i<LOCK_MAX_SIZE;i++)
119 {
120 if(mbtk_lock_name[i].fd -1 == fd)
121 break;
122 }
123 if(i == LOCK_MAX_SIZE)
124 {
125 LOGE("LOCK_MAX_SIZE is full\n");
126 return -1;
127 }
128
129 if(!access("/sys/power/wake_lock", W_OK))
130 {
131 char cmd[128]={0};
132 sprintf(cmd, "echo %s > /sys/power/wake_lock", mbtk_lock_name[i].name);
b.liu9e8584b2024-11-06 19:21:28 +0800133 mbtk_system(cmd);
r.xiao27072552024-10-24 01:02:48 -0700134 return 0;
135 }
136 else
137 {
138 LOGE("/sys/power/wake_lock can not write.");
139 return -1;
140 }
141
142 return 0;
143}
144
145int mbtk_wakelock_unlock(int fd)
146{
147 int i;
148 for(i=1;i<LOCK_MAX_SIZE;i++)
149 {
150 if(mbtk_lock_name[i].fd -1 == fd)
151 break;
152 }
153 if(i == LOCK_MAX_SIZE)
154 {
155 LOGE("LOCK_MAX_SIZE is full\n");
156 return -1;
157 }
158
159 if(!access("/sys/power/wake_unlock", W_OK))
160 {
161 char cmd[128]={0};
162 sprintf(cmd, "echo %s > /sys/power/wake_unlock", mbtk_lock_name[i].name);
b.liu9e8584b2024-11-06 19:21:28 +0800163 mbtk_system(cmd);
r.xiao27072552024-10-24 01:02:48 -0700164 return 0;
165 }
166 else
167 {
168 LOGE("/sys/power/wake_unlock can not write.");
169 return -1;
170 }
171
172 return 0;
173}
174
175int mbtk_wakelock_destroy(int fd)
176{
177 int i;
178 for(i=1;i<LOCK_MAX_SIZE;i++)
179 {
180 if(mbtk_lock_name[i].fd -1 == fd)
181 break;
182 }
183
184 if(i == LOCK_MAX_SIZE)
185 {
186 LOGE("LOCK_MAX_SIZE is full\n");
187 return -1;
188 }
189 else
190 {
191 mbtk_lock_name[i].fd = 0;
192 memset(mbtk_lock_name[i].name, 0, 64);
193 return 0;
194 }
195
196 return 0;
197}
198
liuyang34770f82024-11-14 17:26:24 +0800199static void* suspend_timer_thread_run(void* arg)
200{
201 struct epoll_event eventItems[EPOLL_SIZE_HINT];
liuyang83375062024-11-22 17:49:49 +0800202 int eventCount = epoll_wait(g_mEpollFd, eventItems, EPOLL_SIZE_HINT, -1);
b.liuacb8b4a2024-11-19 15:50:11 +0800203
liuyang34770f82024-11-14 17:26:24 +0800204 int timerFd = -1;
205 int eventIndex = 0;
206 uint64_t readCounter;
b.liuacb8b4a2024-11-19 15:50:11 +0800207
liuyang34770f82024-11-14 17:26:24 +0800208 if (eventCount < 0) {
209 LOGE("Poll failed with an unexpected error: %s\n", strerror(errno));
210 return (void*)-1;
211 }
b.liuacb8b4a2024-11-19 15:50:11 +0800212
liuyang83375062024-11-22 17:49:49 +0800213 for (; eventIndex < eventCount; ++eventIndex)
214 {
liuyang34770f82024-11-14 17:26:24 +0800215 timerFd = eventItems[eventIndex].data.fd;
b.liuacb8b4a2024-11-19 15:50:11 +0800216
liuyang34770f82024-11-14 17:26:24 +0800217 int retRead = read(timerFd, &readCounter, sizeof(uint64_t));
liuyang83375062024-11-22 17:49:49 +0800218
219
220 if (retRead < 0)
221 {
liuyang34770f82024-11-14 17:26:24 +0800222 LOGE("read %d failed...\n", timerFd);
liuyang34770f82024-11-14 17:26:24 +0800223 continue;
liuyang83375062024-11-22 17:49:49 +0800224 }
225 else
226 {
liuyang34770f82024-11-14 17:26:24 +0800227 mbtk_autosuspend_enable(0);
yq.wangb4e1b672025-02-12 11:11:31 +0800228 g_sleep_timer_cb(NULL, 0);
liuyang34770f82024-11-14 17:26:24 +0800229 g_sleep_timer_fd = 0;
liuyang83375062024-11-22 17:49:49 +0800230 LOGI("suspend_timer_success, retRead:%d\n", retRead);
liuyang34770f82024-11-14 17:26:24 +0800231 }
liuyang83375062024-11-22 17:49:49 +0800232
liuyang34770f82024-11-14 17:26:24 +0800233 }
b.liuacb8b4a2024-11-19 15:50:11 +0800234
liuyang34770f82024-11-14 17:26:24 +0800235 return 0;
236}
237
238
239
240static int suspend_timer_timer_init(void)
241{
242 pthread_attr_t thread_attr;
liuyang34770f82024-11-14 17:26:24 +0800243 pthread_attr_init(&thread_attr);
244 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
245 {
246 LOGE("[suspend] pthread_attr_setdetachstate() fail.");
247 return -1;
248 }
249
liuyang83375062024-11-22 17:49:49 +0800250 if(pthread_create(&g_timer_thread_id, &thread_attr, suspend_timer_thread_run, NULL))
liuyang34770f82024-11-14 17:26:24 +0800251 {
252 LOGE("[suspend] pthread_create() fail.");
253 return -1;
254 }
255
256 pthread_attr_destroy(&thread_attr);
257 return 0;
258}
259
260
liuyang83375062024-11-22 17:49:49 +0800261
262
b.liu670a7892024-11-21 18:38:54 +0800263int mbtk_suspend_timer_set(int time, mbtk_sleep_callback_func cb)
liuyang34770f82024-11-14 17:26:24 +0800264{
liuyang83375062024-11-22 17:49:49 +0800265 struct itimerspec timerSet;
266 struct epoll_event eventItem;
267 int result = 0;
268
liuyang34770f82024-11-14 17:26:24 +0800269 if(0 < g_sleep_timer_fd)
270 {
liuyang83375062024-11-22 17:49:49 +0800271 LOGE("suspend timer has been init, restart");
272 if(timerfd_settime(g_sleep_timer_fd, TFD_TIMER_CANCEL_ON_SET, &timerSet, NULL) != 0)
273 {
274 LOGE("suspend timer cancel fail");
275 }
276
277 pthread_detach(g_timer_thread_id);
278
279 pthread_cancel(g_timer_thread_id);
280
281 result = epoll_ctl(g_mEpollFd, EPOLL_CTL_DEL, g_sleep_timer_fd, &eventItem);
282 if (result != 0)
283 {
284 LOGE("Could not del timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno));
285 }
286
287 close(g_sleep_timer_fd);
liuyang34770f82024-11-14 17:26:24 +0800288 }
liuyang83375062024-11-22 17:49:49 +0800289
290 g_mEpollFd = epoll_create(EPOLL_SIZE_HINT);
b.liuacb8b4a2024-11-19 15:50:11 +0800291
liuyang34770f82024-11-14 17:26:24 +0800292 g_sleep_timer_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0);
293 if (g_sleep_timer_fd < 0) {
294 LOGE("Could not create timer fd: %s\n", strerror(errno));
295 return 0;
296 }
b.liuacb8b4a2024-11-19 15:50:11 +0800297
liuyang34770f82024-11-14 17:26:24 +0800298 timerSet.it_interval.tv_sec = 0;
299 timerSet.it_interval.tv_nsec = 0;
300 timerSet.it_value.tv_sec = time;
301 timerSet.it_value.tv_nsec = 0;
302 if (timerfd_settime(g_sleep_timer_fd, 0, &timerSet, NULL) != 0) {
303 LOGE("timerfd_settime failed: %s\n", strerror(errno));
304 close(g_sleep_timer_fd);
305 return 0;
306 }
b.liuacb8b4a2024-11-19 15:50:11 +0800307
liuyang83375062024-11-22 17:49:49 +0800308
liuyang34770f82024-11-14 17:26:24 +0800309 memset(&eventItem, 0, sizeof(eventItem));
310 eventItem.events = EPOLLIN | EPOLLET;
311 eventItem.data.fd = g_sleep_timer_fd;
liuyang83375062024-11-22 17:49:49 +0800312 result = epoll_ctl(g_mEpollFd, EPOLL_CTL_ADD, g_sleep_timer_fd, &eventItem);
liuyang34770f82024-11-14 17:26:24 +0800313 if (result != 0) {
314 LOGE("Could not add timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno));
315 }
316
317 mbtk_autosuspend_enable(1);
318 g_sleep_timer_cb = cb;
319 suspend_timer_timer_init();
320
321
322 return 0;
323}
324
yq.wangb4e1b672025-02-12 11:11:31 +0800325int mbtk_suspend_timer_cancel(void)
326{
327 int ret = -1;
328 struct itimerspec timerSet;
329
330 if(0 < g_sleep_timer_fd)
331 {
332 LOGD("[%s] suspend timer deinit", __func__);
333 memset(&timerSet, 0x0, sizeof(struct itimerspec));
334 if(timerfd_settime(g_sleep_timer_fd, TFD_TIMER_CANCEL_ON_SET, &timerSet, NULL) != 0)
335 {
336 LOGE("[%s] timerfd_settime fail", __func__);
337 return -1;
338 }
339 }
liuyang34770f82024-11-14 17:26:24 +0800340
yq.wangb4e1b672025-02-12 11:11:31 +0800341 if(0 < g_mEpollFd)
342 {
343 ret = epoll_ctl(g_mEpollFd, EPOLL_CTL_DEL, g_sleep_timer_fd, NULL);
344 if (ret != 0)
345 {
346 LOGE("[%s] epoll_ctl[%d] del g_sleep_timer_fd[%d] fail. [%s]\n", g_mEpollFd, g_sleep_timer_fd, strerror(errno));
347 return -1;
348 }
349 }
r.xiao27072552024-10-24 01:02:48 -0700350
yq.wangb4e1b672025-02-12 11:11:31 +0800351 pthread_detach(g_timer_thread_id);
352 pthread_cancel(g_timer_thread_id);
353
354 g_timer_thread_id = 0;
355 if(0 < g_sleep_timer_fd)
356 {
357 close(g_sleep_timer_fd);
358 g_sleep_timer_fd = -1;
359 }
360
361 if(0 < g_mEpollFd)
362 {
363 close(g_mEpollFd);
364 g_mEpollFd = -1;
365 }
366
367 return 0;
368}
r.xiao27072552024-10-24 01:02:48 -0700369