blob: 5a88ef7fc5d2d81ddbc31dd54bb859c1eddb0fdb [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 <cutils/uevent.h>
#include <lynq_autosuspend.h>
#include "lynq-qser-autosuspend.h"
#include "liblog/lynq_deflog.h"
#include "sc_mnet_whitelist.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 UEVENT_MSG_LEN 128
struct dtr_uevent {
const char *action;
const char *path;
const char *subsystem;
const char *usbevent;
};
static void parse_event(const char *msg, struct dtr_uevent *dtr_uevent);
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;
}
static void parse_event(const char *msg, struct dtr_uevent *dtr_uevent)
{
dtr_uevent->action = "";
dtr_uevent->path = "";
dtr_uevent->subsystem = "";
dtr_uevent->usbevent = "";
while (*msg) {
if (!strncmp(msg, "ACTION=", 7))
{
msg += 7;
dtr_uevent->action = msg;
}
else if (!strncmp(msg, "DEVPATH=", 8))
{
msg += 8;
dtr_uevent->path = msg;
}
else if (!strncmp(msg, "SUBSYSTEM=", 10))
{
msg += 10;
dtr_uevent->subsystem = msg;
}
else if (!strncmp(msg, "USBEVENT=", 9)) {
msg += 9;
dtr_uevent->usbevent = msg;
}
while(*msg++);
}
LYINFLOG("event { '%s', '%s', '%s', '%s'}\n",
dtr_uevent->action, dtr_uevent->path, dtr_uevent->subsystem,dtr_uevent->usbevent);
}
void *check_dtr(void * arg)
{
int device_fd;
qser_lpm_edge_t lpm_edge;
char msg[UEVENT_MSG_LEN+2];
struct dtr_uevent dtr_uevent;
int n;
int i;
device_fd = uevent_open_socket(4*UEVENT_MSG_LEN, true);
if(device_fd < 0)
{
LYERRLOG("uevent_open_socket fail\n");
return -1;
}
while(1)
{
n = uevent_kernel_multicast_recv(device_fd, msg, UEVENT_MSG_LEN);
msg[n] = '\0';
msg[n+1] = '\0';
parse_event(msg, &dtr_uevent);
if((!strcmp(dtr_uevent.subsystem, "xp2xp")) && (!strcmp(dtr_uevent.action, "online")))
{
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;
g_lpm_handler = qser_lpm_handler;
ret = pthread_create(&thid,NULL,check_dtr,NULL);
if(ret != 0)
{
LYERRLOG("restart service fail");
}
return ret;
}
int qser_lpm_deinit(void)
{
int ret;
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_add(int id)
{
int ret;
if(sc_mnet_whitelist_init() != 0)
{
LYINFLOG("sc_mnet_whitelist_init failed.\n");
return -1;
}
ret = sc_mnet_whitelist_add(id);
LYINFLOG("sc_mnet_whitelist_add ret %d.\n", ret);
sc_mnet_whitelist_deinit();
return ret;
}
int qser_whitelist_del(int id)
{
int ret;
if(sc_mnet_whitelist_init() != 0)
{
LYINFLOG("sc_mnet_whitelist_init failed.\n");
return -1;
}
ret = sc_mnet_whitelist_del(id);
LYINFLOG("qser_whitelist_del ret %d.\n", ret);
sc_mnet_whitelist_deinit();
return ret;
}
int qser_whitelist_get(char* whitelist)
{
int ret;
if(sc_mnet_whitelist_init() != 0)
{
LYINFLOG("sc_mnet_whitelist_init failed.\n");
return -1;
}
whitelist = sc_mnet_whitelist_get();
if(NULL != whitelist)
{
LYINFLOG("sc_mnet_whitelist_get :%s\n",whitelist);
ret = 0;
}
else
{
LYINFLOG("sc_mnet_whitelist_get empty\n");
ret = -1;
}
sc_mnet_whitelist_deinit();
return ret;
}
int qser_whitelist_clear(void)
{
int ret;
if(sc_mnet_whitelist_init() != 0)
{
LYINFLOG("sc_mnet_whitelist_init failed.\n");
return -1;
}
ret = sc_mnet_whitelist_clear();
LYINFLOG("sc_mnet_whitelist_clear ret %d\n", ret);
sc_mnet_whitelist_deinit();
return ret;
}
DEFINE_LYNQ_LIB_LOG(LYNQ_QSER_AUTOSUSPEND)
#ifdef __cplusplus
}
#endif