| #include <pthread.h> | 
 | #include <sys/epoll.h> | 
 | #include <sys/timerfd.h> | 
 |  | 
 | #include "mbtk_sleep.h" | 
 | #include "mbtk_log.h" | 
 | #include "mbtk_utils.h" | 
 |  | 
 | static bool autosleep_enable = FALSE; | 
 |  | 
 | static mbtk_lock_name_s mbtk_lock_name[LOCK_MAX_SIZE]={0}; | 
 |  | 
 | int g_mEpollFd = -1; | 
 | mbtk_sleep_callback_func g_sleep_timer_cb; | 
 | int g_sleep_timer_fd = 0; | 
 | pthread_t g_timer_thread_id; | 
 |  | 
 | int mbtk_powerrind_get() | 
 | { | 
 |     char buffer[4]; | 
 |     int ret = 0; | 
 |  | 
 |     int fd = open(MTBK_POWERIND, O_RDWR | O_SYNC, 0662); | 
 |     if (fd != -1) | 
 |     { | 
 |         mbtk_read(fd, buffer, strlen(buffer)+1); | 
 |         close(fd); | 
 |     } | 
 |  | 
 |     ret = atoi(buffer); | 
 |  | 
 |     return ret; | 
 | } | 
 |  | 
 |  | 
 | int mbtk_autosuspend_enable(char enable) | 
 | { | 
 |     if((enable == 1) || enable == '1') | 
 |     { | 
 |         if(!access("/sys/power/autosleep", W_OK)) | 
 |         { | 
 |             mbtk_system("echo mem > /sys/power/autosleep"); | 
 |             autosleep_enable = TRUE; | 
 |             return 0; | 
 |         } | 
 |         else | 
 |         { | 
 |             LOGE("/sys/power/autosleep can not write."); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |     else if((enable == 0) || enable == '0') | 
 |     { | 
 |         if(!access("/sys/power/autosleep", W_OK)) | 
 |         { | 
 |             mbtk_system("echo off > /sys/power/autosleep"); | 
 |             autosleep_enable = FALSE; | 
 |             return 0; | 
 |         } | 
 |         else | 
 |         { | 
 |             LOGE("/sys/power/autosleep can not write."); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGE("qser_autosuspend_enablecan enable err."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | int mbtk_wakelock_create(const char* name , size_t len) | 
 | { | 
 |     int len_t; | 
 |  | 
 |     len_t = strlen(name); | 
 |  | 
 |     if((name != NULL) && (len < 33) && (len_t < 33)) | 
 |     { | 
 |         int i; | 
 |         for(i=1 ;i<LOCK_MAX_SIZE;i++) | 
 |         { | 
 |             if(strcmp(mbtk_lock_name[i].name, name) == 0) | 
 |             { | 
 |                 LOGE("Repeated names."); | 
 |                 return -1; | 
 |             } | 
 |         } | 
 |  | 
 |         for(i=1 ;i<LOCK_MAX_SIZE;i++) | 
 |         { | 
 |             if(mbtk_lock_name[i].fd == 0) | 
 |                 break; | 
 |         } | 
 |  | 
 |         if (i >= LOCK_MAX_SIZE) | 
 |         { | 
 |             LOGE("Fd is full."); | 
 |             return -1; | 
 |         } | 
 |  | 
 |         memcpy(mbtk_lock_name[i].name, name, strlen(name)+1); | 
 |         mbtk_lock_name[i].fd = i; | 
 |         return mbtk_lock_name[i].fd -1;//Starting from scratch | 
 |     } | 
 |     else | 
 |         return -1; | 
 |  | 
 |     return -1; | 
 | } | 
 |  | 
 | int mbtk_wakelock_lock(int fd) | 
 | { | 
 |     int i; | 
 |     for(i=1;i<LOCK_MAX_SIZE;i++) | 
 |     { | 
 |         if(mbtk_lock_name[i].fd -1 == fd) | 
 |             break; | 
 |     } | 
 |     if(i == LOCK_MAX_SIZE) | 
 |     { | 
 |         LOGE("LOCK_MAX_SIZE is full\n"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     if(!access("/sys/power/wake_lock", W_OK)) | 
 |     { | 
 |         char cmd[128]={0}; | 
 |         sprintf(cmd, "echo %s > /sys/power/wake_lock", mbtk_lock_name[i].name); | 
 |         mbtk_system(cmd); | 
 |         return 0; | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGE("/sys/power/wake_lock can not write."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | int mbtk_wakelock_unlock(int fd) | 
 | { | 
 |     int i; | 
 |     for(i=1;i<LOCK_MAX_SIZE;i++) | 
 |     { | 
 |         if(mbtk_lock_name[i].fd -1 == fd) | 
 |             break; | 
 |     } | 
 |     if(i == LOCK_MAX_SIZE) | 
 |     { | 
 |         LOGE("LOCK_MAX_SIZE is full\n"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     if(!access("/sys/power/wake_unlock", W_OK)) | 
 |     { | 
 |         char cmd[128]={0}; | 
 |         sprintf(cmd, "echo %s > /sys/power/wake_unlock", mbtk_lock_name[i].name); | 
 |         mbtk_system(cmd); | 
 |         return 0; | 
 |     } | 
 |     else | 
 |     { | 
 |         LOGE("/sys/power/wake_unlock can not write."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | int mbtk_wakelock_destroy(int fd) | 
 | { | 
 |     int i; | 
 |     for(i=1;i<LOCK_MAX_SIZE;i++) | 
 |     { | 
 |         if(mbtk_lock_name[i].fd -1 == fd) | 
 |         break; | 
 |     } | 
 |  | 
 |     if(i == LOCK_MAX_SIZE) | 
 |     { | 
 |         LOGE("LOCK_MAX_SIZE is full\n"); | 
 |         return -1; | 
 |     } | 
 |     else | 
 |     { | 
 |         mbtk_lock_name[i].fd = 0; | 
 |         memset(mbtk_lock_name[i].name, 0, 64); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | static void* suspend_timer_thread_run(void* arg) | 
 | { | 
 |     struct epoll_event eventItems[EPOLL_SIZE_HINT]; | 
 |     int eventCount = epoll_wait(g_mEpollFd, eventItems, EPOLL_SIZE_HINT, -1); | 
 |  | 
 |     int timerFd = -1; | 
 |     int eventIndex = 0; | 
 |     uint64_t readCounter; | 
 |  | 
 |     if (eventCount < 0) { | 
 |         LOGE("Poll failed with an unexpected error: %s\n", strerror(errno)); | 
 |         return (void*)-1; | 
 |     } | 
 |  | 
 |     for (; eventIndex < eventCount; ++eventIndex)  | 
 |     { | 
 |         timerFd = eventItems[eventIndex].data.fd; | 
 |  | 
 |         int retRead = read(timerFd, &readCounter, sizeof(uint64_t)); | 
 |  | 
 |          | 
 |         if (retRead < 0)  | 
 |         { | 
 |             LOGE("read %d failed...\n", timerFd); | 
 |             continue; | 
 |         }  | 
 |         else  | 
 |         { | 
 |             mbtk_autosuspend_enable(0); | 
 |             g_sleep_timer_cb(NULL, 0); | 
 |             g_sleep_timer_fd = 0; | 
 |             LOGI("suspend_timer_success, retRead:%d\n", retRead); | 
 |         } | 
 |  | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 |  | 
 | static int suspend_timer_timer_init(void) | 
 | { | 
 |     pthread_attr_t thread_attr; | 
 |     pthread_attr_init(&thread_attr); | 
 |     if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED)) | 
 |     { | 
 |         LOGE("[suspend] pthread_attr_setdetachstate() fail."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     if(pthread_create(&g_timer_thread_id, &thread_attr, suspend_timer_thread_run, NULL)) | 
 |     { | 
 |         LOGE("[suspend] pthread_create() fail."); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     pthread_attr_destroy(&thread_attr); | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 |  | 
 |  | 
 | int mbtk_suspend_timer_set(int time, mbtk_sleep_callback_func cb) | 
 | { | 
 |     struct itimerspec timerSet; | 
 |     struct epoll_event eventItem; | 
 |     int result = 0; | 
 |  | 
 |     if(0 < g_sleep_timer_fd) | 
 |     { | 
 |         LOGE("suspend timer has been init, restart"); | 
 |         if(timerfd_settime(g_sleep_timer_fd, TFD_TIMER_CANCEL_ON_SET, &timerSet, NULL) != 0) | 
 |         { | 
 |             LOGE("suspend timer cancel fail"); | 
 |         } | 
 |  | 
 |         pthread_detach(g_timer_thread_id); | 
 |  | 
 |         pthread_cancel(g_timer_thread_id); | 
 |  | 
 |         result = epoll_ctl(g_mEpollFd, EPOLL_CTL_DEL, g_sleep_timer_fd, &eventItem); | 
 |         if (result != 0)  | 
 |         { | 
 |             LOGE("Could not del timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno)); | 
 |         } | 
 |          | 
 |         close(g_sleep_timer_fd);  | 
 |     } | 
 |      | 
 |     g_mEpollFd = epoll_create(EPOLL_SIZE_HINT); | 
 |  | 
 |     g_sleep_timer_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); | 
 |     if (g_sleep_timer_fd < 0) { | 
 |         LOGE("Could not create timer fd: %s\n", strerror(errno)); | 
 |         return 0; | 
 |     } | 
 |  | 
 |     timerSet.it_interval.tv_sec = 0; | 
 |     timerSet.it_interval.tv_nsec = 0; | 
 |     timerSet.it_value.tv_sec = time; | 
 |     timerSet.it_value.tv_nsec = 0; | 
 |     if (timerfd_settime(g_sleep_timer_fd, 0, &timerSet, NULL) != 0) { | 
 |         LOGE("timerfd_settime failed: %s\n", strerror(errno)); | 
 |         close(g_sleep_timer_fd); | 
 |         return 0; | 
 |     } | 
 |  | 
 |  | 
 |     memset(&eventItem, 0, sizeof(eventItem)); | 
 |     eventItem.events = EPOLLIN | EPOLLET; | 
 |     eventItem.data.fd = g_sleep_timer_fd; | 
 |     result = epoll_ctl(g_mEpollFd, EPOLL_CTL_ADD, g_sleep_timer_fd, &eventItem); | 
 |     if (result != 0) { | 
 |         LOGE("Could not add timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno)); | 
 |     } | 
 |  | 
 |     mbtk_autosuspend_enable(1); | 
 |     g_sleep_timer_cb = cb; | 
 |     suspend_timer_timer_init(); | 
 |  | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | int mbtk_suspend_timer_cancel(void) | 
 | { | 
 |     int ret = -1; | 
 |     struct itimerspec timerSet; | 
 |      | 
 |     if(0 < g_sleep_timer_fd) | 
 |     { | 
 |         LOGD("[%s] suspend timer deinit", __func__); | 
 |         memset(&timerSet, 0x0, sizeof(struct itimerspec)); | 
 |         if(timerfd_settime(g_sleep_timer_fd, TFD_TIMER_CANCEL_ON_SET, &timerSet, NULL) != 0) | 
 |         { | 
 |             LOGE("[%s] timerfd_settime fail", __func__); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |  | 
 |     if(0 < g_mEpollFd) | 
 |     { | 
 |         ret = epoll_ctl(g_mEpollFd, EPOLL_CTL_DEL, g_sleep_timer_fd, NULL); | 
 |         if (ret != 0)  | 
 |         { | 
 |             LOGE("[%s] epoll_ctl[%d] del g_sleep_timer_fd[%d] fail. [%s]\n", g_mEpollFd, g_sleep_timer_fd, strerror(errno)); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |  | 
 |     pthread_detach(g_timer_thread_id); | 
 |     pthread_cancel(g_timer_thread_id); | 
 |  | 
 |     g_timer_thread_id = 0; | 
 |     if(0 < g_sleep_timer_fd) | 
 |     { | 
 |         close(g_sleep_timer_fd);  | 
 |         g_sleep_timer_fd = -1; | 
 |     } | 
 |      | 
 |     if(0 < g_mEpollFd) | 
 |     { | 
 |         close(g_mEpollFd); | 
 |         g_mEpollFd = -1; | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  |