| #include <pthread.h> |
| #include <sys/epoll.h> |
| #include <sys/timerfd.h> |
| |
| |
| |
| #include "mbtk_sleep.h" |
| #include "mbtk_log.h" |
| #include "mbtk_utils.h" |
| |
| static mbtk_lock_name_s mbtk_lock_name[LOCK_MAX_SIZE]={0}; |
| |
| #define EPOLL_SIZE_HINT 128 |
| int mEpollFd = -1; |
| mbtk_info_callback_func g_sleep_timer_cb; |
| int g_sleep_timer_fd = 0; |
| |
| |
| 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(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 { |
| |
| g_sleep_timer_cb(NULL, 0); |
| mbtk_autosuspend_enable(0); |
| g_sleep_timer_fd = 0; |
| LOGI("suspend_timer_success\n"); |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| |
| static int suspend_timer_timer_init(void) |
| { |
| pthread_attr_t thread_attr; |
| pthread_t net_led_thread_id; |
| 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(&net_led_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_info_callback_func cb) |
| { |
| if(0 < g_sleep_timer_fd) |
| { |
| LOGE("suspend timer has been init"); |
| return -1; |
| } |
| 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; |
| } |
| |
| struct itimerspec timerSet; |
| 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; |
| } |
| |
| struct epoll_event eventItem; |
| memset(&eventItem, 0, sizeof(eventItem)); |
| eventItem.events = EPOLLIN | EPOLLET; |
| eventItem.data.fd = g_sleep_timer_fd; |
| int result = epoll_ctl(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; |
| } |
| |
| |
| |
| |