blob: 260dcb6867d681010450e6e57969d21ce09defac [file] [log] [blame]
#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_lock(char *name)
{
int j;
int num;
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)
{
return num;
}
return -1;
}
int add_lock(char *name)
{
int ret;
int i = 0;
int num;
int check_flag;
LYINFLOG("name:%s\n", name);
ret = read_lock_table();
LYINFLOG("read_lock_table ret = %d\n", ret);
if(ret <0)
{
return ret;
}
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);
LYINFLOG("lock_name[%d] %s\n", i, lock_status.lock_name[i]);
break;
}
}
if(i == MAX_LOCK_NUM)
{
return E_TABLE_FULL;
}
else
{
num = i;
}
}
else
{
return E_LOCK_EXIST;
}
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]));
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