[Feature][ZXW-68][AUTOSUSPEND]add wakelock api and autosuspend api

Only Configure:No
Affected branch:master
Affected module:autosuspend
Is it affected on both ZXIC and MTK: only ZXIC and MTK
Self-test: Yes
Doc Update:Yes

Change-Id: I389ac6629a628d3cf197bea5809882c25f408439
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
index 31697ed..8d07dc3 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
+++ b/cap/zx297520v3/sources/meta-zxic-custom/conf/distro/vehicle_dc_ref.conf
@@ -193,6 +193,8 @@
         liblynq-qser-fota \
         libpoweralarm \
         liblynq-systime \
+        liblynq-autosuspend \
+        liblynq-qser-autosuspend \
 	"
 
 zxic_lib += "${@bb.utils.contains('CONFIG_TEL_API_SUPPORT', 'RIL', 'libril', 'libtelsvr', d)}"
@@ -266,6 +268,7 @@
         lynq-qser-sim-demo \
         lynq-qser-sms-demo \
         lynq-qser-data-demo \
+        lynq-autosuspend \
         "
 
 zxic_app_open += "${@bb.utils.contains('CONFIG_TEL_API_SUPPORT', 'RIL', 'rild', '', d)}"
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-autosuspend/liblynq-autosuspend.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-autosuspend/liblynq-autosuspend.bb
new file mode 100644
index 0000000..fc81884
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-autosuspend/liblynq-autosuspend.bb
@@ -0,0 +1,53 @@
+#inherit externalsrc package
+
+DESCRIPTION = "liblynq-autosuspend"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b1e07e8d88e26263e71d3a9e2aa9a2ff"
+DEPENDS += "libbsp liblynq-log"
+#inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-autosuspend"
+FILESEXTRAPATHS_prepend :="${TOPDIR}/../src/lynq/lib/:"
+SRC_URI = " \
+          file://liblynq-autosuspend \
+          "
+
+SRC-DIR = "${S}/../liblynq-autosuspend"
+TARGET_CC_ARCH += "${LDFLAGS}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+#Parameters passed to do_compile()
+EXTRA_OEMAKE = "'TARGET_PLATFORM = ${TARGET_PLATFORM}'"
+
+FILES_${PN} = "${base_libdir}/*.so \
+               ${base_bindir}\
+               ${base_sbindir} \
+               /etc/dbus-1/system.d/"
+FILES_${PN}-dev = "/test \
+                   ${includedir}"
+FILES_${PN}-doc = "/doc"
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+                  ${base_libdir}/.debug \
+                  ${base_sbindir}/.debug"
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+	if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mfpu=neon-vfpv4 -mhard-float -Wl,--hash-style=gnu"
+	elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mfpu=neon-vfpv4 -mhard-float -Wl,--hash-style=gnu"
+	elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mfpu=neon-vfpv4 -mhard-float -Wl,--hash-style=gnu -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"
+	else
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"
+	fi
+}
+
+do_install() {
+    oe_runmake install -C ${SRC-DIR} ROOT=${D}
+    if [ -d "${WORKONSRC}" ] ; then
+        install -d ${D}${includedir}
+        cp -af ${SRC-DIR}/include/libauto/ ${D}${includedir}/libauto
+    fi
+}
+
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-autosuspend/liblynq-qser-autosuspend.bb b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-autosuspend/liblynq-qser-autosuspend.bb
new file mode 100644
index 0000000..375742d
--- /dev/null
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-lynq/liblynq-qser-autosuspend/liblynq-qser-autosuspend.bb
@@ -0,0 +1,52 @@
+#inherit externalsrc package
+
+DESCRIPTION = "liblynq-qser-autosuspend"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+
+DEPENDS += "${@bb.utils.contains('TARGET_PLATFORM', 'mt2735', 'audio-mixer-ctrl streamer1.0', '', d)}  liblynq-autosuspend liblynq-log"
+#inherit workonsrc
+WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-qser-autosuspend/"
+FILESEXTRAPATHS_prepend :="${TOPDIR}/../src/lynq/lib/:"
+SRC_URI = " \
+          file://liblynq-qser-autosuspend\
+          "
+
+SRC-DIR = "${S}/../liblynq-qser-autosuspend"
+TARGET_CC_ARCH += "${LDFLAGS}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+#Parameters passed to do_compile()
+FILES_${PN} = "${base_libdir}/*.so "
+
+FILES_${PN}-dev = "/test \
+                   ${includedir}"
+
+FILES_${PN}-doc = "/doc"
+
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+                  ${base_libdir}/.debug \
+                  ${base_sbindir}/.debug"
+
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+		oe_runmake all -C ${SRC-DIR} ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu"
+}
+
+do_install () {
+    oe_runmake install -C ${SRC-DIR} ROOT=${D}
+	
+    if [ -d "${WORKONSRC}" ] ; then
+        install -d ${D}${includedir}/
+        cp -af ${SRC-DIR}/include/ ${D}${includedir}/
+    fi 
+}
+
+addtask bachclean
+do_bachclean () {
+    oe_runmake clean
+}
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/LICENSE
new file mode 100644
index 0000000..605b7ea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MobileTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MobileTek Inc. and/or its licensors. Without
+the prior written permission of MobileTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MobileTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MobileTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MobileTek SOFTWARE")
+RECEIVED FROM MobileTek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MobileTek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MobileTek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MobileTek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MobileTek
+SOFTWARE. MobileTek SHALL ALSO NOT BE RESPONSIBLE FOR ANY MobileTek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MobileTek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MobileTek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MobileTek'S OPTION, TO REVISE OR REPLACE THE
+MobileTek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MobileTek FOR SUCH MobileTek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/include/libauto/lynq_autosuspend.h b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/include/libauto/lynq_autosuspend.h
new file mode 100644
index 0000000..efd1219
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/include/libauto/lynq_autosuspend.h
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct time_info_t
+{
+    long sleep_start_time;
+    long wakeup_time;
+};
+
+int lynq_autosleep_enable(void);
+int lynq_autosleep_disable(void);
+int lynq_wait_wakeup_event(long *sleep_start_time, long * wakeup_time);
+
+#ifdef MOBILETEK_TARGET_PLATFORM_T106
+int lynq_set_lpmode(int lp_mode);
+int release_wake_lock(char *name);
+int acquire_wake_lock(int lock, char *name);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq-autosuspend.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq-autosuspend.cpp
new file mode 100644
index 0000000..54c88fd
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq-autosuspend.cpp
@@ -0,0 +1,445 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <time.h>
+#include "include/libauto/lynq_autosuspend.h"
+#ifdef MOBILETEK_TARGET_PLATFORM_T106
+#include <sc_bsp.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define LOG_TAG "libautosuspend"
+// #include <liblog/lynq_deflog.h>
+#include <log/log.h>
+#define SERVER_CMD_PATH "/tmp/autosuspend.cmd.server"
+#define SERVER_DATA_PATH "/tmp/autosuspend.data.server"
+// #define CLIENT_PATH "/tmp/autosuspend.client"
+static int client_sock_fd;
+static int client_data_sock_fd;
+static bool libautosuspend_inited;
+bool feedback_flag = true; //add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time
+// 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;
+
+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)
+        {    
+            printf("read error eintr\n");
+            continue;
+        }
+        else if(errno == EAGAIN || errno == EWOULDBLOCK)
+        {
+            printf("read time out\n");
+            return -2;
+        }
+        else
+        {
+            printf("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)
+        {
+            printf("write error epipe\n");
+            return -1;
+        }  
+        else
+            return -1;
+    }
+    return n;
+}
+static int Close(int fd)
+{
+    if (Close(fd) == -1)
+    {
+        printf("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; 
+    printf("Start bind and connect to the service.\n");
+    /**************************************/
+    /* Create a UNIX domain stream socket */
+    /**************************************/
+    *cfd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (*cfd == -1) {
+        printf("SOCKET ERROR ");
+        return -1;
+    }
+    /***************************************/
+    /* Set up the UNIX sockaddr structure  */
+    /* by using AF_UNIX for the family and */
+    /* giving it a filepath to bind to.    */
+    /*                                     */
+    /* 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); 
+    
+    unlink(client_sockaddr.sun_path);
+    rc = bind(*cfd, (struct sockaddr *) &client_sockaddr, sizeof(client_sockaddr));
+    if (rc == -1){
+        printf("BIND ERROR ");
+        Close(*cfd);
+        return -1;
+    }
+        
+    /***************************************/
+    /* Set up the UNIX sockaddr structure  */
+    /* for the server socket and connect   */
+    /* to it.                              */
+    /***************************************/
+    server_sockaddr.sun_family = AF_UNIX;
+    
+    strcpy(server_sockaddr.sun_path, server_path);
+    rc = connect(*cfd, (struct sockaddr *) &server_sockaddr, sizeof(client_sockaddr));
+    if(rc == -1){
+        printf("CONNECT ERROR ");
+        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)
+    {
+        // printf("deal_get_feedback thread wait.\n");
+        // pthread_cond_wait(&get_feedback_cond,&get_feedback_mutex);
+        printf("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)
+        {           
+            printf("client read wakeup_feedback struct fail.\n");
+            Close(client_sock);
+            pthread_mutex_unlock(&feedback_got_mutex);
+            break ;
+        }
+        else if(rc == -2)
+        {
+            printf("client read wakeup_feedback struct timeout.\n");
+            pthread_mutex_unlock(&feedback_got_mutex);
+            continue;
+        }
+        printf("system sleep_start timestamps : %ld ms\n",time_info_client.sleep_start_time);
+        printf("system wakeup timestamps : %ld ms\n",time_info_client.wakeup_time);
+        // pthread_cond_broadcast(&feedback_got_cond);
+        pthread_mutex_unlock(&feedback_got_mutex);
+        usleep(10000);  //给libautosuspend_get_feedback函数时间进入wait,不可删除,但可以减少
+        pthread_cond_broadcast(&feedback_got_cond);
+        usleep(10000); //希望多给libautosuspend_get_feedback函数拿到锁的机会,不可删除,但可以减少
+        
+    }
+    
+}
+static int libautosuspend_init()
+{
+    if (libautosuspend_inited)
+    {
+        return 0;
+    }
+    printf("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)
+    {
+        printf("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)
+    {
+        printf("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_fd, value, len, 0);
+    if (rc == -1) {
+        printf("SEND ERROR ");
+        Close(client_sock_fd);
+        return -2;
+    }   
+    else {
+        printf("Data sent: %s\n",value);
+    }
+    // Close(client_sock);
+    return rc;
+}
+int lynq_autosleep_enable(void)
+{
+    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)
+    {
+        printf("libautosuspend send enable cmd fail.\n");
+        pthread_mutex_unlock(&client_fd_mutex);
+        return -1;
+    }
+    // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
+    // {
+    //     printf("libautosuspend get respond fail.\n");
+    //     pthread_mutex_unlock(&client_fd_mutex);
+    //     return -1;
+    // }
+    // printf("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 1;
+  
+}
+int lynq_autosleep_disable(void)
+{
+    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)
+    {
+        printf("libautosuspend send disable cmd fail.\n");
+        pthread_mutex_unlock(&client_fd_mutex);
+        return -1;
+    }
+    // if(Read(client_sock_fd,res,sizeof(res)) <= 0)
+    // {
+    //     printf("libautosuspend get respond fail.\n");
+    //     pthread_mutex_unlock(&client_fd_mutex);
+    //     return -1;
+    // }
+    // printf("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 1;
+}
+int libautosuspend_get_feedback(struct time_info_t *time_info)
+{
+    // char value[15]="feedback";
+    // char res[15];    
+    // if(!libautosuspend_enabled)
+    // {
+    //     printf("system autosuspend disabled, can not get wakeup feedback.\n");
+    //     return -1;
+    // }
+    printf("start get feedback from the service.\n");
+    memset(time_info,0,sizeof(struct time_info_t));
+    // if(timeout == NULL)
+    // {
+    //     printf("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)
+    //     {
+    //         printf("client set timeout for receiving wakeup_feedback: error.\n");
+    //         pthread_mutex_unlock(&client_data_fd_mutex);
+    //         return -1;
+    //     }
+            
+    //     printf("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)
+    // {
+    //     printf("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)
+    // {
+    //     printf("libautosuspend_get_feedback fail.\n");
+    //     pthread_mutex_unlock(&client_fd_mutex);
+    //     return -1;
+    // }
+    printf("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));
+    printf("libautosuspend_get_feedback success.\n");
+    pthread_mutex_unlock(&feedback_got_mutex);
+    // printf("[client] system sleep_start timestamps : %ld ms\n",time_info.sleep_start_time);
+    // printf("[client] system wakeup timestamps : %ld ms\n",time_info.wakeup_time);
+    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;
+   /*add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time start*/
+   if(feedback_flag == true)
+   {
+       if(libautosuspend_init() != 0)
+       {
+           return -1;
+       }
+   }
+   feedback_flag = false; 
+   /*add for after sleeping once calling lynq_wailt_wakeup_event does not return sleep time end*/
+   memset(&time_info,0,sizeof(struct time_info_t));
+   if(sleep_start_time == NULL || wakeup_time == NULL )
+   {
+      printf("lynq_wait_wakeup_event input errors.\n");
+      return -1;
+   }
+   ret=libautosuspend_get_feedback(&time_info);
+   if(ret == 0)
+   {
+     *sleep_start_time = time_info.sleep_start_time;
+     *wakeup_time = time_info.wakeup_time;
+     return 0;
+   }
+   else
+   {
+      return -1;
+   }
+   
+}
+#ifdef MOBILETEK_TARGET_PLATFORM_T106
+int acquire_wake_lock(int lock, char *name)
+{
+    int ret;
+    printf("Get param:%s \n", name);
+    ret = sc_pm_wakelock_lock(name);
+    if (ret)
+    {
+        printf("do_wakelock failed, err:%d", ret);
+        return ret;
+    }
+    printf("do_wakelock succeed\n");
+    return ret;
+}
+int release_wake_lock(char *name)
+{
+    int ret;
+    printf("Get param:%s \n", name);
+    ret = sc_pm_wakelock_unlock(name);
+    if (ret)
+    {
+        printf("do_wakeunlock failed, err:%d", ret);
+        return ret;
+    }
+    printf("do_wakeunlock succeed\n");
+    return ret;
+}
+int lynq_set_lpmode(int lp_mode)
+{
+    int ret;
+    printf("Get param:%d \n", lp_mode);
+    ret = sc_pm_set_lp_mode(lp_mode);
+    if (ret) {
+        printf("do_set_lpmode failed, err:%d", ret);
+        exit(1);
+    }
+    printf("do_set_lpmode succeed\n");
+    return ret;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq_autosuspend.h b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq_autosuspend.h
new file mode 100644
index 0000000..efd1219
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/lynq_autosuspend.h
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct time_info_t
+{
+    long sleep_start_time;
+    long wakeup_time;
+};
+
+int lynq_autosleep_enable(void);
+int lynq_autosleep_disable(void);
+int lynq_wait_wakeup_event(long *sleep_start_time, long * wakeup_time);
+
+#ifdef MOBILETEK_TARGET_PLATFORM_T106
+int lynq_set_lpmode(int lp_mode);
+int release_wake_lock(char *name);
+int acquire_wake_lock(int lock, char *name);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/makefile
new file mode 100644
index 0000000..b97b48c
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-autosuspend/makefile
@@ -0,0 +1,74 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=c++11 \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -fpermissive \
+
+
+ifeq ($(strip $(TARGET_PLATFORM)), T106)
+    LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1 -DHAVE_ENDIAN_H -DHAVE_PTHREADS -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP -DHAVE_STRLCPY -DHAVE_PRCTL -DHAVE_MEMSET16 -DHAVE_MEMSET32 -DANDROID_SMP=0
+endif
+
+ifeq ($(strip $(TARGET_PLATFORM)), T106)
+    LOCAL_CFLAGS += -DMOBILETEK_TARGET_PLATFORM_T106
+endif
+
+
+
+$(warning ################# lynq autosuspend API ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include/libauto \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+
+
+
+LOCAL_LIBS := \
+    -L. \
+    -ldl \
+    -lstdc++ \
+    -llog \
+    -lcutils \
+    -lpthread \
+    -llynq-log \
+    -lbsp \
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-autosuspend.so
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+pack_rootfs:
+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+	mkdir -p $(PACK_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
+	-find . -name "*.o" -delete
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/LICENSE b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/LICENSE
new file mode 100644
index 0000000..cb88533
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("Mobiletek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to Mobiletek Inc. and/or its licensors. Without
+the prior written permission of Mobiletek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of Mobiletek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+Mobiletek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("Mobiletek SOFTWARE")
+RECEIVED FROM Mobiletek AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. Mobiletek EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES Mobiletek PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE Mobiletek SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN Mobiletek
+SOFTWARE. Mobiletek SHALL ALSO NOT BE RESPONSIBLE FOR ANY Mobiletek SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND Mobiletek'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE Mobiletek SOFTWARE
+RELEASED HEREUNDER WILL BE, AT Mobiletek'S OPTION, TO REVISE OR REPLACE THE
+Mobiletek SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO Mobiletek FOR SUCH Mobiletek SOFTWARE AT ISSUE.
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/include/lynq-qser-autosuspend.h b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/include/lynq-qser-autosuspend.h
new file mode 100644
index 0000000..54b663f
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/include/lynq-qser-autosuspend.h
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_LOCK_NUM 128
+
+#define E_READ -2
+#define E_WRITE -3
+#define E_INIT -4
+
+typedef enum 
+{
+    E_QL_LPM_FALLING = 0, /* Falling, Means wakeupin falling to wakeup the module, or wakeupout falling to wakeup mcu
+. */
+    E_QL_LPM_RISING = 1, /* Rising, Means  wakeupin rising to wakeup the module,  or wakeupout rising to wakeup  mcu. 
+*/
+}qser_lpm_edge_t;
+
+typedef int qser_lpm_pin_t;
+
+
+typedef struct{
+    qser_lpm_pin_t wakeupin_pin;
+    qser_lpm_edge_t wakeupin_edge;
+}qser_lpm_wakeupin_data_t;
+
+typedef struct{
+    qser_lpm_pin_t wakeupout_pin;
+    qser_lpm_edge_t wakeupout_edge;
+}qser_lpm_wakeupout_data_t;
+
+
+typedef void (*qser_lpm_Handler_t)
+(
+    qser_lpm_edge_t lpm_edge
+);
+
+typedef struct{
+    qser_lpm_wakeupin_data_t wakeupin;
+    qser_lpm_wakeupout_data_t wakeupout;
+}qser_pm_cfg_t;
+
+
+typedef struct
+{
+    char lock_name[MAX_LOCK_NUM][64];
+} LOCK_TABLE;
+
+int read_lock_table(void);
+int qser_lpm_init(qser_lpm_Handler_t qser_lpm_handler, qser_pm_cfg_t *qser_lpm_cfg);
+int qser_lpm_deinit(void);
+int qser_autosuspend_enable(char enable);
+int qser_wakelock_create(const char *name, size_t len);
+int qser_wakelock_lock(int fd);
+int qser_wakelock_unlock(int fd);
+int qser_wakelock_destroy(int fd);
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/lynq-qser-autosuspend.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/lynq-qser-autosuspend.cpp
new file mode 100755
index 0000000..b6fcdea
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/lynq-qser-autosuspend.cpp
@@ -0,0 +1,337 @@
+#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"
+
+#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"
+
+
+LOCK_TABLE lock_status;
+
+
+int file_fd;
+int first_run = 0;
+
+
+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 -1;
+    }
+    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 -2;
+        }
+    }
+
+    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 -2;
+    }
+
+    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 -2;
+    }
+
+    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 -3;
+    }
+    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 -3;
+    }
+    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 -1;
+        }
+        else
+        {
+            num = i;
+        }
+    }
+    else
+    {
+        num = check_flag;
+    }
+
+    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;
+}
+
+int qser_lpm_init(qser_lpm_Handler_t qser_lpm_handler, qser_pm_cfg_t *qser_lpm_cfg)
+{
+    int ret;
+    ret = system("uci set lynq_uci.lynq_autosuspend.init='1'");
+    system("uci commit");
+    if(ret != 0)
+    {
+        LYINFLOG("uci set fail");
+    }
+    ret = system("./etc/init.d/lynq-autosuspend.sh restart");
+    if(ret != 0)
+    {
+        LYINFLOG("restart service fail");
+    }
+    return ret;
+}
+
+
+int qser_lpm_deinit(void)
+{
+    int ret;
+    system("uci set lynq_uci.lynq_autosuspend.init='0'");
+    system("uci commit");
+    if(ret != 0)
+    {
+        LYINFLOG("uci set fail");
+    }
+    system("./etc/init.d/lynq-autosuspend.sh restarts");
+    if(ret != 0)
+    {
+        LYINFLOG("restart service fail");
+    }
+    return 0;
+}
+
+int qser_autosuspend_enable(char enable)
+{
+    int ret;
+    if(enable == '0')
+    {
+        ret = lynq_autosleep_disable();
+
+    }
+    else if(enable == '1')
+    {
+        ret = lynq_autosleep_enable();
+    }
+    else
+    {
+        ret = -1;
+
+    }
+    return ret;
+
+}
+
+int qser_wakelock_create(const char *name, size_t len)
+{
+    int ret;
+    if(name == NULL)
+    {
+        return -1;
+    }
+    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 -4;
+    }
+    ret = read_lock_table();
+    ret = acquire_wake_lock( 0, lock_status.lock_name[fd]);
+    return ret;
+}
+
+int qser_wakelock_unlock(int fd)
+{
+    int ret;
+    if(fd < 0 || fd >= MAX_LOCK_NUM)
+    {
+        return -4;
+    }
+    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]);
+    return ret;
+}
+
+int qser_wakelock_destroy(int fd)
+{
+    int ret;
+    if(fd < 0 || fd >= MAX_LOCK_NUM)
+    {
+        return -4;
+    }
+    ret = delete_lock(fd);
+    return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/makefile b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/makefile
new file mode 100644
index 0000000..510b40e
--- /dev/null
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-autosuspend/makefile
@@ -0,0 +1,67 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+                -std=gnu++14 \
+                -g -Os \
+                -flto \
+                -fPIC \
+                -fpermissive \
+
+
+
+$(warning ################# lynq qser autosuspend API ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH   = .
+
+LOCAL_C_INCLUDES = \
+  -I. \
+  -I$(LOCAL_PATH)/include/ \
+  -I$(LOCAL_PATH)/ \
+  -I$(ROOT)$(includedir)/logger \
+  -I$(ROOT)$(includedir)/liblog \
+  -I$(ROOT)$(includedir)/libauto/ \
+
+  
+
+LOCAL_LIBS := \
+    -L. \
+    -lstdc++ \
+    -lcutils \
+    -lutils \
+    -lpthread \
+    -llynq-autosuspend \
+    -llynq-log \
+
+
+SOURCES = $(wildcard *.cpp)
+
+EXECUTABLE = liblynq-qser-autosuspend.so
+
+OBJECTS=$(SOURCES:.cpp=.o)
+
+
+.PHONY: build clean install pack_rootfs 
+all: build
+$(EXECUTABLE): $(OBJECTS)
+	$(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.cpp
+	$(CXX) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build:  $(EXECUTABLE)
+	$(warning ########## build $(EXECUTABLE)  ##########)
+install:
+	mkdir -p $(ROOT)$(base_libdir)/
+	install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+	mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+pack_rootfs:
+	mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+	mkdir -p $(PACK_TO)$(base_libdir)/
+	cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+	$(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
+	-find . -name "*.o" -delete