| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <pthread.h> |
| #include <unistd.h> |
| |
| #include <lynq_autosuspend.h> |
| #include "lynq-qser-autosuspend.h" |
| #include "liblog/lynq_deflog.h" |
| #include <include/lynq_uci.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| |
| extern int lynq_autosleep_enable(void); |
| extern int lynq_autosleep_disable(void); |
| extern int release_wake_lock(char *name); |
| extern int acquire_wake_lock(int lock, char *name); |
| |
| #define USER_LOG_TAG "LYNQ_QSER_AUTOSUSPEND" |
| #define FILE_LOCK_TABLE "/tmp/.lock_table" |
| #define LOG_UCI_MODULE "lynq_autosuspend" |
| #define LOG_UCI_FILE "lynq_uci" |
| |
| #define UEVENT_MSG_LEN 128 |
| |
| int g_init_flag = 0; |
| |
| |
| qser_lpm_Handler_t g_lpm_handler = NULL; |
| |
| |
| LOCK_TABLE lock_status; |
| |
| |
| int file_fd; |
| int first_run = 0; |
| pthread_t thid; |
| |
| |
| int lock_table_init(void) |
| { |
| int ret; |
| int err; |
| |
| file_fd = open(FILE_LOCK_TABLE, O_RDWR| O_CREAT,0777); |
| if(file_fd < 0) |
| { |
| err = errno; |
| LYINFLOG("Error open lock_table file:%s\n", strerror(errno)); |
| return -err; |
| } |
| memset(&lock_status, 0, sizeof(lock_status)); |
| ret = write(file_fd, (char*)&lock_status, sizeof(lock_status)); |
| if(ret <= 0) |
| { |
| LYINFLOG("write fail\n"); |
| close(file_fd); |
| return E_WRITE; |
| } |
| sync(); |
| close(file_fd); |
| return 0; |
| } |
| |
| |
| int read_lock_table(void) |
| { |
| int err; |
| int ret; |
| int i; |
| LYLOGSET(LOG_INFO); |
| LYLOGEINIT(USER_LOG_TAG); |
| |
| if(access(FILE_LOCK_TABLE,0) < 0) |
| { |
| ret = lock_table_init(); |
| if(ret < 0) |
| { |
| return E_READ; |
| } |
| } |
| |
| file_fd = open(FILE_LOCK_TABLE,O_RDWR); |
| if(file_fd < 0) |
| { |
| err = errno; |
| LYINFLOG("Error open lock_table file:%s\n", strerror(errno)); |
| return E_READ; |
| } |
| |
| memset(&lock_status, 0, sizeof(lock_status)); |
| lseek(file_fd,0,SEEK_SET); |
| ret = read(file_fd,(unsigned char *)&lock_status,sizeof(lock_status)); |
| LYINFLOG("read ret=%d\n", ret); |
| if(ret <= 0) |
| { |
| close(file_fd); |
| return E_READ; |
| } |
| |
| for(i=0;i<MAX_LOCK_NUM;i++) |
| { |
| if(strlen(lock_status.lock_name[i]) != 0) |
| { |
| LYINFLOG("fd: %d lock_name:%s strlen:%d\n", i, lock_status.lock_name[i], strlen(lock_status.lock_name[i])); |
| } |
| } |
| |
| close(file_fd); |
| return 0; |
| } |
| |
| |
| int save_lock_table(void) |
| { |
| int err; |
| int ret; |
| file_fd = open(FILE_LOCK_TABLE,O_RDWR); |
| if(file_fd < 0) |
| { |
| err = errno; |
| LYINFLOG("Error open lock_table file:%s\n", strerror(errno)); |
| return E_WRITE; |
| } |
| LYINFLOG("write lock_name[0]: %s\n", lock_status.lock_name[0]); |
| ret = write(file_fd, (unsigned char *)&lock_status, sizeof(lock_status)); |
| LYINFLOG("write ret=%d\n", ret); |
| if(ret <= 0) |
| { |
| LYINFLOG("write fail\n"); |
| close(file_fd); |
| return E_WRITE; |
| } |
| sync(); |
| close(file_fd); |
| |
| return 0; |
| } |
| |
| int check_pid(int pid) |
| { |
| char cmd1[64]; |
| int ret = -1; |
| sprintf(cmd1, "ps -ef |awk '{print $1}'|grep \"^%d$\"", pid); |
| ret = system(cmd1); |
| return ret; |
| } |
| |
| int check_lock(char *name) |
| { |
| int j; |
| int num; |
| int ret=-1; |
| for(j=0;j<MAX_LOCK_NUM;j++) |
| { |
| if(strcmp(lock_status.lock_name[j], name) == 0) |
| { |
| num = j; |
| break; |
| } |
| } |
| |
| if(j < MAX_LOCK_NUM) |
| { |
| ret = check_pid(lock_status.lock_pid[j]); |
| if(!ret) |
| { |
| LYINFLOG("the pid is exist\n"); |
| num = MAX_LOCK_NUM+1; |
| return num; |
| } |
| else |
| { |
| LYINFLOG("the pid is not exist\n"); |
| return num; |
| } |
| } |
| |
| return -1; |
| } |
| |
| |
| int add_lock(char *name) |
| { |
| int ret; |
| int i = 0; |
| int num; |
| int check_flag; |
| int pid; |
| |
| ret = read_lock_table(); |
| LYINFLOG("read_lock_table ret = %d\n", ret); |
| if(ret <0) |
| { |
| return ret; |
| } |
| pid = getpid(); |
| check_flag = check_lock(name); |
| |
| if(check_flag < 0) |
| { |
| for(i=0;i<MAX_LOCK_NUM;i++) |
| { |
| if(strlen(lock_status.lock_name[i]) == 0) |
| { |
| strcpy(lock_status.lock_name[i], name); |
| lock_status.lock_pid[i] = pid; |
| LYINFLOG("lock_name[%d] %s, lock_pid = %d\n", i, lock_status.lock_name[i], pid); |
| break; |
| } |
| } |
| if(i == MAX_LOCK_NUM) |
| { |
| return E_TABLE_FULL; |
| } |
| else |
| { |
| num = i; |
| } |
| } |
| else if(check_flag > MAX_LOCK_NUM) |
| { |
| return E_LOCK_EXIST; |
| } |
| else |
| { |
| num = check_flag; |
| lock_status.lock_pid[num] = pid; |
| } |
| |
| LYINFLOG("num = %d\n", num); |
| ret = save_lock_table(); |
| if(ret < 0) |
| { |
| return ret; |
| } |
| return num; |
| } |
| |
| int delete_lock(int fd) |
| { |
| int ret; |
| int i; |
| ret = read_lock_table(); |
| memset(lock_status.lock_name[fd], 0, sizeof(lock_status.lock_name[fd])); |
| lock_status.lock_pid[fd] = -1; |
| ret = save_lock_table(); |
| return ret; |
| } |
| |
| |
| void *check_dtr(void * arg) |
| { |
| qser_lpm_edge_t lpm_edge; |
| char msg[16]; |
| int fd=0; |
| int ret=0; |
| |
| while(1) |
| { |
| fd = open("/sys/xp2xp/xp2xp_notify/xp2xp_state", O_RDONLY); |
| ret=read(fd, &msg,15); |
| LYERRLOG("xp2xp_state ret = %d\n", ret); |
| close(fd); |
| |
| if(ret == 5) |
| { |
| lpm_edge =E_QL_LPM_FALLING; |
| } |
| else if(ret == 6) |
| { |
| lpm_edge =E_QL_LPM_RISING; |
| } |
| else |
| { |
| continue; |
| } |
| g_lpm_handler(lpm_edge); |
| |
| } |
| |
| return 0; |
| } |
| |
| |
| int qser_lpm_init(qser_lpm_Handler_t qser_lpm_handler, qser_pm_cfg_t *qser_lpm_cfg) |
| { |
| int ret; |
| int num; |
| if(g_init_flag != 0) |
| { |
| LYERRLOG("g_init_flag is error\n"); |
| return -1; |
| } |
| g_init_flag = 1; |
| g_lpm_handler = qser_lpm_handler; |
| ret = pthread_create(&thid,NULL,check_dtr,NULL); |
| if(ret != 0) |
| { |
| LYERRLOG("pthread create fail, qser_lpm_init fail\n"); |
| } |
| return ret; |
| } |
| |
| |
| int qser_lpm_deinit(void) |
| { |
| int ret; |
| if(g_init_flag != 1) |
| { |
| LYERRLOG("g_init_flag is error"); |
| return -1; |
| } |
| g_init_flag = 0; |
| ret = pthread_cancel(thid); |
| if(!ret) |
| { |
| LYERRLOG("pthread cancel success, lpm deinit success\n"); |
| } |
| else |
| { |
| LYERRLOG("pthread cancel fail, lpm deinit fail\n"); |
| } |
| return ret; |
| |
| } |
| |
| |
| int qser_autosuspend_enable(char enable) |
| { |
| int ret; |
| if(enable == '0') |
| { |
| ret = lynq_autosleep_disable(); |
| |
| } |
| else if(enable == '1') |
| { |
| ret = lynq_autosleep_enable(); |
| } |
| else |
| { |
| return E_INPUT_ERROR; |
| |
| } |
| if(ret >= 0) |
| { |
| ret = 0; |
| } |
| return ret; |
| |
| } |
| |
| |
| int qser_wakelock_create(const char *name, size_t len) |
| { |
| int ret; |
| if(name == NULL) |
| { |
| return E_INPUT_ERROR; |
| } |
| LYINFLOG("%s\n", name); |
| ret = add_lock(name); |
| return ret; |
| } |
| |
| int qser_wakelock_lock(int fd) |
| { |
| |
| int ret; |
| if(fd < 0 || fd >= MAX_LOCK_NUM) |
| { |
| return E_INPUT_ERROR; |
| } |
| ret = read_lock_table(); |
| ret = acquire_wake_lock( 0, lock_status.lock_name[fd]); |
| if(ret > 0) |
| { |
| ret = 0; |
| } |
| else |
| { |
| ret = -1; |
| } |
| return ret; |
| } |
| |
| int qser_wakelock_unlock(int fd) |
| { |
| int ret; |
| if(fd < 0 || fd >= MAX_LOCK_NUM) |
| { |
| return E_INPUT_ERROR; |
| } |
| ret = read_lock_table(); |
| if(strlen(lock_status.lock_name[fd]) == 0) |
| { |
| LYINFLOG("%d is null\n", fd); |
| return -1; |
| } |
| ret = release_wake_lock(lock_status.lock_name[fd]); |
| if(ret > 0) |
| { |
| ret = 0; |
| } |
| else |
| { |
| ret = -1; |
| } |
| return ret; |
| } |
| |
| int qser_wakelock_destroy(int fd) |
| { |
| int ret; |
| if(fd < 0 || fd >= MAX_LOCK_NUM) |
| { |
| return E_INPUT_ERROR; |
| } |
| ret = qser_wakelock_unlock(fd); |
| if(ret) |
| { |
| LYINFLOG("unlock is fail\n"); |
| return ret; |
| } |
| |
| ret = delete_lock(fd); |
| return ret; |
| } |
| |
| int qser_whitelist_set(char *whitelist) |
| { |
| int ret; |
| char cmd[64]; |
| if(strlen(whitelist) != 4) |
| { |
| LYINFLOG("string len is error\n"); |
| return -1; |
| } |
| sprintf(cmd, "uci set lynq_uci.lynq_autosuspend.whitelist_state='%s'", whitelist); |
| ret = system(cmd); |
| system("uci commit"); |
| if(ret != 0) |
| { |
| LYINFLOG("qser_whitlist_set fail"); |
| } |
| return ret; |
| |
| } |
| |
| int qser_whitelist_get(char *whitelist) |
| { |
| int ret; |
| ret = lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "whitelist_state", whitelist); |
| LYERRLOG("ret =%d, whitelist_state is %s\n", ret, whitelist); |
| return ret; |
| |
| } |
| |
| DEFINE_LYNQ_LIB_LOG(LYNQ_QSER_AUTOSUSPEND) |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| |
| |