[Bugfix] fix API-235,242
Change-Id: Ic63b8be16891b9597bb9b6473763351515a36d86
diff --git a/src/lynq/lib/libautosuspend/libautosuspend.c b/src/lynq/lib/libautosuspend/libautosuspend.c
index a933e9c..2588b04 100644
--- a/src/lynq/lib/libautosuspend/libautosuspend.c
+++ b/src/lynq/lib/libautosuspend/libautosuspend.c
@@ -8,36 +8,121 @@
#include <sys/un.h>
#include <unistd.h>
#include <dlfcn.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <time.h>
#define LOG_TAG "libautosuspend"
// #include <liblog/lynq_deflog.h>
#include <log/log.h>
-#define SERVER_PATH "/tmp/autosuspend.server"
+#define SERVER_CMD_PATH "/tmp/autosuspend.cmd.server"
+#define SERVER_DATA_PATH "/tmp/autosuspend.data.server"
// #define CLIENT_PATH "/tmp/autosuspend.client"
-static int send_cmd(char * value,int len)
+static int client_sock_fd;
+
+static int client_data_sock_fd;
+
+static bool libautosuspend_inited;
+
+// static bool libautosuspend_enabled;
+
+// static pthread_mutex_t get_feedback_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// static pthread_cond_t get_feedback_cond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t client_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t client_data_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t feedback_got_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t feedback_got_cond = PTHREAD_COND_INITIALIZER;
+
+struct time_info_t
{
- int client_sock, rc;
+ long sleep_start_time;
+ long wakeup_time;
+};
+
+static struct time_info_t time_info_client;
+
+static ssize_t Read(int fd, void *ptr, size_t nbytes)
+{
+ ssize_t n;
+
+ while((n = read(fd, ptr, nbytes)) == -1)
+ {
+ //printf("READ,%d\n",fd);
+ if (errno == EINTR)
+ {
+ ALOGI("read error eintr\n");
+ continue;
+ }
+ else if(errno == EAGAIN || errno == EWOULDBLOCK)
+ {
+ ALOGI("read time out\n");
+ return -2;
+ }
+ else
+ {
+ ALOGI("read error\n");
+ return -1;
+ }
+ }
+ //sleep(2);
+ //printf("READ1,%d\n", fd);
+ return n;
+}
+
+static ssize_t Write(int fd, const void *ptr, size_t nbytes)
+{
+ ssize_t n;
+
+ while((n = write(fd, ptr, nbytes)) == -1)
+ {
+ if (errno == EINTR)
+ continue;
+ else if(errno == EPIPE)
+ {
+ ALOGI("write error epipe\n");
+ return -1;
+ }
+ else
+ return -1;
+ }
+ return n;
+}
+
+static int Close(int fd)
+{
+ if (Close(fd) == -1)
+ {
+ ALOGI("Close error\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int connect_to_server(int *cfd, char *client_path, char *server_path)
+{
+ int rc;
struct sockaddr_un server_sockaddr;
struct sockaddr_un client_sockaddr;
-
- if(value == NULL)
- {
- return -1;
- }
+ ALOGI("Start bind and connect to the service.\n");
/**************************************/
/* Create a UNIX domain stream socket */
/**************************************/
- client_sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (client_sock == -1) {
+ *cfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (*cfd == -1) {
ALOGI("SOCKET ERROR ");
- return -5;
+ return -1;
}
/***************************************/
@@ -48,17 +133,16 @@
/* Unlink the file so the bind will */
/* succeed, then bind to that file. */
/***************************************/
- client_sockaddr.sun_family = AF_UNIX;
- // strcpy(client_sockaddr.sun_path, CLIENT_PATH);
- sprintf(client_sockaddr.sun_path,"/tmp/suspend.%d.client",(int)getpid());
- len = sizeof(client_sockaddr);
+ client_sockaddr.sun_family = AF_UNIX;
+ strcpy(client_sockaddr.sun_path, client_path);
unlink(client_sockaddr.sun_path);
- rc = bind(client_sock, (struct sockaddr *) &client_sockaddr, len);
+
+ rc = bind(*cfd, (struct sockaddr *) &client_sockaddr, sizeof(client_sockaddr));
if (rc == -1){
ALOGI("BIND ERROR ");
- close(client_sock);
- return -4;
+ Close(*cfd);
+ return -1;
}
/***************************************/
@@ -67,31 +151,145 @@
/* to it. */
/***************************************/
server_sockaddr.sun_family = AF_UNIX;
- strcpy(server_sockaddr.sun_path, SERVER_PATH);
- rc = connect(client_sock, (struct sockaddr *) &server_sockaddr, len);
+
+ strcpy(server_sockaddr.sun_path, server_path);
+
+ rc = connect(*cfd, (struct sockaddr *) &server_sockaddr, sizeof(client_sockaddr));
if(rc == -1){
ALOGI("CONNECT ERROR ");
- close(client_sock);
+ Close(*cfd);
return -3;
}
+
+ return 0;
+
+}
+
+static void *deal_get_feedback(void *sockfd)
+{
+ int rc;
+
+ int client_sock = *((int *)sockfd);
+
+ // pthread_mutex_lock(&feedback_got_mutex);
+
+ while (1)
+ {
+ // ALOGI("deal_get_feedback thread wait.\n");
+
+ // pthread_cond_wait(&get_feedback_cond,&get_feedback_mutex);
+
+ ALOGI("start get feedback from the service.\n");
+
+ pthread_mutex_lock(&feedback_got_mutex);
+
+ memset(&time_info_client,0,sizeof(struct time_info_t));
+
+ rc = Read(client_sock,&time_info_client,sizeof(struct time_info_t));
+ if(rc == -1)
+ {
+ ALOGI("client read wakeup_feedback struct fail.\n");
+ Close(client_sock);
+ pthread_mutex_unlock(&feedback_got_mutex);
+ break ;
+ }
+ else if(rc == -2)
+ {
+ ALOGI("client read wakeup_feedback struct timeout.\n");
+ pthread_mutex_unlock(&feedback_got_mutex);
+ continue;
+ }
+
+ ALOGI("system sleep_start timestamps : %ld ms\n",time_info_client.sleep_start_time);
+ ALOGI("system wakeup timestamps : %ld ms\n",time_info_client.wakeup_time);
+
+ // pthread_cond_broadcast(&feedback_got_cond);
+
+ pthread_mutex_unlock(&feedback_got_mutex);
+
+ sleep(1); //给libautosuspend_get_feedback函数时间进入wait
+
+ pthread_cond_broadcast(&feedback_got_cond);
+
+ sleep(1); //希望多给libautosuspend_get_feedback函数拿到锁的机会,保证他们先执行完
+
+ }
+
+}
+
+
+static int libautosuspend_init()
+{
+ if (libautosuspend_inited)
+ {
+ return 0;
+ }
+
+ ALOGI("Start libautosuspend_init.\n");
+
+ char client_cmd_path[40];
+ char client_data_path[40];
+
+
+ sprintf(client_cmd_path,"/tmp/autosuspend.%d.cmd.client",(int)getpid());
+ sprintf(client_data_path,"/tmp/autosuspend.%d.data.client",(int)getpid());
+
+ pthread_mutex_lock(&client_fd_mutex);
+
+ if(connect_to_server(&client_sock_fd,client_cmd_path,SERVER_CMD_PATH) < 0)
+ {
+ ALOGI("cmd channel connect error.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ if(connect_to_server(&client_data_sock_fd,client_data_path,SERVER_DATA_PATH) < 0)
+ {
+ ALOGI("data channel connect error.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ pthread_t feedback_tid;
+ pthread_create(&feedback_tid,NULL,deal_get_feedback,(void*)&client_data_sock_fd);
+ pthread_detach(feedback_tid);
+
+
+ libautosuspend_inited = true;
+
+ pthread_mutex_unlock(&client_fd_mutex);
+
+ return 0;
+
+}
+
+static int send_cmd(char * value,int len)
+{
+ int rc;
+
+ if(value == NULL)
+ {
+ return -1;
+ }
/************************************/
/* Copy the data to the buffer and */
/* send it to the server socket. */
/************************************/
- // strcpy(buf, DATA);
- printf("Sending data...\n");
- rc = send(client_sock, value, len, 0);
+ // strcpy(buf, DATA);
+
+ ALOGI("Sending data...\n");
+ rc = send(client_sock_fd, value, len, 0);
if (rc == -1) {
ALOGI("SEND ERROR ");
- close(client_sock);
+ Close(client_sock_fd);
return -2;
}
else {
ALOGI("Data sent: %s\n",value);
}
- close(client_sock);
+ // Close(client_sock);
return rc;
@@ -99,27 +297,208 @@
int lynq_autosleep_enable(void)
{
- char value[15]="enable";
- int rc = send_cmd(value,strlen(value));
- if(rc < 0)
- {
- ALOGI("libautosleep_enable ret %d\n",rc);
- }
- return rc;
+ char value[15]="enable";
+ char res[15];
+
+ if(libautosuspend_init() != 0)
+ {
+ return -1;
+ }
+
+ // if(libautosuspend_enabled)
+ // {
+ // return 0;
+ // }
+
+ pthread_mutex_lock(&client_fd_mutex);
+
+ int rc = send_cmd(value,strlen(value));
+ if(rc < 0)
+ {
+ ALOGI("libautosuspend send enable cmd fail.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ if(Read(client_sock_fd,res,sizeof(res)) <= 0)
+ {
+ ALOGI("libautosuspend get respond fail.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ ALOGI("libautosuspend get respond : %s.\n",res);
+
+ if(strcmp(res,"enabled") != 0)
+ {
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ // libautosuspend_enabled = true;
+
+ pthread_mutex_unlock(&client_fd_mutex);
+
+ return 0;
+
}
int lynq_autosleep_disable(void)
{
- char value[15]="disable";
- int rc = send_cmd(value,strlen(value));
- if(rc < 0)
- {
- ALOGI("libautosleep_disable ret %d\n",rc);
- }
- return rc;
+ char value[15]="disable";
+ char res[15];
+
+ if(libautosuspend_init() != 0)
+ {
+ return -1;
+ }
+
+ // if(!libautosuspend_enabled)
+ // {
+ // return 0;
+ // }
+
+ pthread_mutex_lock(&client_fd_mutex);
+
+ int rc = send_cmd(value,strlen(value));
+ if(rc < 0)
+ {
+ ALOGI("libautosuspend send disable cmd fail.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ if(Read(client_sock_fd,res,sizeof(res)) <= 0)
+ {
+ ALOGI("libautosuspend get respond fail.\n");
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ ALOGI("libautosuspend get respond : %s.\n",res);
+
+ if(strcmp(res,"disabled") != 0)
+ {
+ pthread_mutex_unlock(&client_fd_mutex);
+ return -1;
+ }
+
+ // libautosuspend_enabled = false;
+
+ pthread_mutex_unlock(&client_fd_mutex);
+
+ return 0;
}
+int lynq_wait_wakeup_event(long *sleep_start_time, long * wakeup_time)
+{
+ int *socket_timeout = NULL;
+ struct time_info_t time_info;
+ int ret = 0;
+
+ memset(&time_info,0,sizeof(struct time_info_t));
+ if(sleep_start_time == NULL || wakeup_time == NULL )
+ {
+ ALOGI("lynq_wait_wakeup_event input errors.\n");
+ return -1;
+ }
+ ret=libautosuspend_get_feedback(&time_info,socket_timeout);
+ if(ret == 0)
+ {
+ *sleep_start_time = time_info.sleep_start_time;
+ *wakeup_time = time_info.wakeup_time;
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+
+}
+
+int libautosuspend_get_feedback(struct time_info_t *time_info, int *timeout)
+{
+ // char value[15]="feedback";
+ // char res[15];
+
+ // if(!libautosuspend_enabled)
+ // {
+ // ALOGI("system autosuspend disabled, can not get wakeup feedback.\n");
+ // return -1;
+ // }
+
+ ALOGI("start get feedback from the service.\n");
+
+ memset(time_info,0,sizeof(struct time_info_t));
+
+ if(timeout == NULL)
+ {
+ ALOGI("client set timeout for receiving wakeup_feedback: NULL.\n");
+ }
+ else
+ {
+ struct timeval recv_timeout = {(*timeout),0};
+ pthread_mutex_lock(&client_data_fd_mutex);
+ if(setsockopt(client_data_sock_fd,SOL_SOCKET,SO_RCVTIMEO,(char*)&recv_timeout,sizeof(struct timeval)) == -1)
+ {
+ ALOGI("client set timeout for receiving wakeup_feedback: error.\n");
+ pthread_mutex_unlock(&client_data_fd_mutex);
+ return -1;
+ }
+
+ ALOGI("client set timeout for receiving wakeup_feedback: %d s.\n",(*timeout));
+ pthread_mutex_unlock(&client_data_fd_mutex);
+
+ }
+
+ // int rc = send_cmd(value,strlen(value));
+ // if(rc < 0)
+ // {
+ // ALOGI("libautosuspend send feedback cmd fail.\n");
+ // pthread_mutex_unlock(&client_fd_mutex);
+ // return -1;
+ // }
+
+ // if(Read(client_data_sock_fd,time_info,sizeof(struct time_info_t)) <= 0)
+ // {
+ // ALOGI("libautosuspend_get_feedback fail.\n");
+ // pthread_mutex_unlock(&client_fd_mutex);
+ // return -1;
+ // }
+
+
+ ALOGI("libautosuspend_get_feedback wait.\n");
+
+ pthread_mutex_lock(&feedback_got_mutex);
+
+ pthread_cond_wait(&feedback_got_cond,&feedback_got_mutex);
+
+ memcpy(time_info,&time_info_client,sizeof(struct time_info_t));
+
+ ALOGI("libautosuspend_get_feedback success.\n");
+
+ pthread_mutex_unlock(&feedback_got_mutex);
+ // ALOGI("[client] system sleep_start timestamps : %ld ms\n",time_info.sleep_start_time);
+ // ALOGI("[client] system wakeup timestamps : %ld ms\n",time_info.wakeup_time);
+
+ return 0;
+
+}
+
+
+
+// static void libautosuspend_get_feedback()
+// {
+// pthread_t feedback_tid;
+// pthread_create(&feedback_tid,NULL,deal_get_feedback,(void*)&client_sock);
+// pthread_detach(&feedback_tid);
+
+// return ;
+
+// }
+