[Feature][T8TSK-100] RIL3.0 AT partial upgrade 2

Change-Id: I70c601f3cbc7e8b59aa5feaf2d4147727f227963
diff --git a/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp b/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp
old mode 100644
new mode 100755
index cdb1977..6d5ecf5
--- a/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/atci/ATCI.cpp
@@ -462,11 +462,11 @@
     memset(buf, 0, sizeof(buf));
     if(error_code != 0)
     {
-        sprintf(buf,"%s%d","\r\n+CME ERROR: ",error_code);
+        sprintf(buf,"%s%d\r\n","\r\n+CME ERROR: ",error_code);
     }
     else
     {
-        sprintf(buf,"%s","\r\nOK");
+        sprintf(buf,"%s","\r\nOK\r\n");
     }
     int len_s = send(atci_client_connect, buf, strlen(buf), 0);
     if(len_s != strlen(buf))
@@ -490,14 +490,14 @@
     else
     {
         data_len = strlen(data);
-        if(data_len > 124)// \r\r + \0
+        if(data_len > 122)// \r\n + \r\n\0
         {
             RLOGD("data too long");
-            snprintf(buf,127,"\r\n%s",data);
+            snprintf(buf,127,"\r\n%s\r\n",data);
         }
         else
         {
-            snprintf(buf,data_len+3,"\r\n%s",data);// \r\r + \0
+            snprintf(buf,data_len+5,"\r\n%s\r\n",data);// \r\n + \r\n\0
         }
         int len_s = send(atci_client_connect, buf, strlen(buf), 0);
         if(len_s != strlen(buf))
diff --git a/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp b/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
index 8561e58..38c62da 100755
--- a/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
@@ -66,7 +66,7 @@
 
             //wrire data to target
             atci_data_req_t req;
-            
+
             if(state==1)
             {
                 req.request_id = RIL_REQUEST_SETUP_DATA_CALL;
diff --git a/src/lynq/lib/liblynq-at-extension/include/lib_at/lynq_at.h b/src/lynq/lib/liblynq-at-extension/include/lib_at/lynq_at.h
index 1a17fe9..0049eb1 100755
--- a/src/lynq/lib/liblynq-at-extension/include/lib_at/lynq_at.h
+++ b/src/lynq/lib/liblynq-at-extension/include/lib_at/lynq_at.h
@@ -10,9 +10,9 @@
 
 #ifndef __LYNQ_AT__
 #define __LYNQ_AT__
-#ifdef __cplusplus
-extern "C" {
-#endif
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
 
 /**
  * @brief
@@ -31,8 +31,8 @@
  */
 int lynq_reg_third_at(const char *ext_at, LYNQ_AT_CALLBACK callback);
 
-#ifdef __cplusplus
-}
-#endif
+//#ifdef __cplusplus
+//}
+//#endif
 
 #endif
\ No newline at end of file
diff --git a/src/lynq/lib/liblynq-at-extension/lynq_at.cpp b/src/lynq/lib/liblynq-at-extension/lynq_at.cpp
index a7c6b2e..8785310 100755
--- a/src/lynq/lib/liblynq-at-extension/lynq_at.cpp
+++ b/src/lynq/lib/liblynq-at-extension/lynq_at.cpp
@@ -1,20 +1,25 @@
-#include<sys/types.h>
-#include<sys/socket.h>
-#include<unistd.h>
-#include<arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <arpa/inet.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <string.h>
 #include <log/log.h>
 #include <pthread.h>
+#include <errno.h>
 #include "liblog/lynq_deflog.h"
 #include "include/lib_at/lynq_at.h"
 
 #define LYNQ_AT_SERVICE_PORT 8087
 #define OUT_MAX_SIZE 1024
 #define USER_LOG_TAG "LYNQ_AT"
-
+#define AT_EXTERSION_SOCKET_NAME "/dev/socket/lynq_atsvc_socket_1"
+#define LINE __LINE__
+#define FUNC __FUNCTION__
+static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
 typedef enum
 {
     A_SUCCESS = 0,
@@ -28,8 +33,15 @@
 char *output = NULL;
 char buffer_at[OUT_MAX_SIZE] = {0};
 struct sockaddr_in addr_serv;
+struct sockaddr_un addr_server;
+
+
 socklen_t len;
 LYNQ_AT_CALLBACK tmp = NULL;
+bool connect_state = false;
+#define SOCKET_ZERO   0
+#define SOCKET_SUCC   1
+#define SOCKET_FAIL  -1
 
 /**
  * @brief Catch exceptions and free malloc's memory
@@ -66,6 +78,84 @@
     }
 }
 
+
+int socket_local_client (char* name) {
+    //struct sockaddr_un server;
+    //int fd = 0;
+    LYINFLOG("[%d][%s] enter",LINE,FUNC);
+    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (sockfd < 0)
+    {
+        LYDBGLOG("Can't open stream socket (%s)", name);
+        return -1;
+    }
+    addr_server.sun_family = AF_UNIX;
+    memset(addr_server.sun_path, '\0', sizeof(addr_server.sun_path));
+    strncpy(addr_server.sun_path, name, sizeof(addr_server.sun_path) - 1);
+    if (connect(sockfd, (struct sockaddr *) &addr_server, sizeof(struct sockaddr_un)) < 0)
+    {
+        close(sockfd);
+        LYDBGLOG("Can't connect to server side, path: %s, errno:%d", name, errno);
+        return -1;
+    }
+    LYINFLOG("[%d][%s] connect %s success",LINE,FUNC,name);
+    return sockfd;
+}
+bool send_msg_to_service(int fd,char *msg,int size)
+{
+    LYDBGLOG("[%d][%s] enter",LINE,FUNC);
+    if (fd < 0)
+    {
+        LYDBGLOG("fd invalid when send to atci service. errno = %d", errno);
+        return false;
+    }
+    if(NULL == msg)
+    {
+        LYDBGLOG("atcmd is null.");
+        return false;
+    }
+    int sendLen = send(fd, msg, size, 0);
+    if (sendLen != size)
+    {
+        LYDBGLOG("lose data when send to atci service. errno = %d", errno);
+        return false;
+    }
+    LYDBGLOG("send to app demo: %s", msg);
+    return true;
+}
+
+int atsvc_cmd_recv(int fd, char *buf, int len)
+{
+    int ret = 0;
+    fd_set rfds;
+    //FD_CLR(fd, &rfds);
+    FD_SET(fd, &rfds);
+    ret = select(fd + 1, &rfds, NULL, NULL, NULL);
+    if (ret <= 0)
+    {
+        LYDBGLOG("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+        return SOCKET_FAIL;
+    }
+    if (FD_ISSET(fd, &rfds))
+    {
+        ret = recv(fd, buf, len, 0);
+        if (ret < 0)
+        {
+            LYDBGLOG("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+            return SOCKET_FAIL;
+        }
+        else if(ret == 0)
+        {
+            LYDBGLOG("acti_cmd_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+            return SOCKET_ZERO;
+    }
+    else
+    {
+      //buf[ret] = '\0';
+    }
+  }
+  return SOCKET_SUCC;
+}
 /**
  * @brief send third cmd to service and receive input,then send output to service
  * 
@@ -74,53 +164,73 @@
  */
 void *thread_recv(void *parm)
 {
-    signal(SIGPIPE, signal_handler);
-    signal(SIGABRT, signal_handler);
-    signal(SIGBUS, signal_handler);
-    signal(SIGFPE, signal_handler);
-    signal(SIGILL, signal_handler);
-    signal(SIGSEGV, signal_handler);
+    //signal(SIGPIPE, signal_handler);
+    //signal(SIGABRT, signal_handler);
+    //signal(SIGBUS, signal_handler);
+    //signal(SIGFPE, signal_handler);
+    //signal(SIGILL, signal_handler);
+    //signal(SIGSEGV, signal_handler);
+    LYINFLOG("[%d][%s] enter",LINE,FUNC);
     int recv = 0;
     int send = 0;
     char at_cmd[100] = {0};
-    sockfd=socket(AF_INET,SOCK_DGRAM,0);
-    memset(&addr_serv, 0, sizeof(addr_serv));
-    addr_serv.sin_family =AF_INET;
-    addr_serv.sin_port =htons(LYNQ_AT_SERVICE_PORT);
-    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); 
-    len=sizeof(addr_serv);
-    int len_buf = strlen(buffer_at);
-    send = sendto(sockfd, buffer_at, len_buf,0,(struct sockaddr*)&addr_serv,len);
-    if(send < 0)
+    int fd = -1;
+    int ret = 0;
+    fd = socket_local_client(AT_EXTERSION_SOCKET_NAME);
+    if(fd <= 0)
     {
-        LYDBGLOG("thread_recv send fail\n");
-        result = send;
+        connect_state = false;
+        pthread_mutex_unlock(&s_startupMutex);
         return NULL;
     }
+    int len_buf = strlen(buffer_at);
+    if(!send_msg_to_service(fd,buffer_at,len_buf))
+    {
+        connect_state = false;
+        pthread_mutex_unlock(&s_startupMutex);
+        return NULL;
+    }
+    connect_state = true;
+    pthread_mutex_unlock(&s_startupMutex);
     char *input = NULL;
     output = (char *)malloc(sizeof(char)*OUT_MAX_SIZE);
     if(NULL == output)
     {
         LYDBGLOG("thread_recv malloc fail\n");
-        result = A_ERROR;
         return NULL;
     }
+    TryNewLink:
+    if(connect_state == false)
+    {
+        if (connect(fd, (struct sockaddr *) &addr_server, sizeof(struct sockaddr_un)) < 0)
+        {
+            close(fd);
+            LYDBGLOG("Can't connect to server side, path: %s, errno:%d", AT_EXTERSION_SOCKET_NAME, errno);
+            return NULL;
+        }
+        connect_state = true;
+    }
     while (1)
     {
         /*receive at cmd*/
-        LYDBGLOG("lynq_reg_third_at receive at cmd\n");
-        recv = recvfrom(sockfd,at_cmd,sizeof(at_cmd),0,(struct sockaddr*)&addr_serv,&len);
-        if(recv < 0)
+        memset(at_cmd, 0, sizeof(at_cmd));
+        ret = atsvc_cmd_recv(fd, at_cmd,sizeof(at_cmd));
+        if (ret < 0)
         {
-            LYDBGLOG("thread_recv recv fail\n");
+            LYDBGLOG("[%d][%s]receive CMD error",LINE,FUNC);
             continue;
         }
+        else if(ret == SOCKET_ZERO)
+        {
+            ALOGE("maybe client socket closed 1. retry new link!");
+            connect_state = false;
+            goto TryNewLink;
+        }
         input = at_cmd;
         //begin deal with callback
         tmp(input, output, OUT_MAX_SIZE);
         LYDBGLOG("lynq_reg_third_at send output to service\n");
-        send = sendto(sockfd, output, strlen(output),0,(struct sockaddr*)&addr_serv,len);
-        if(send < 0)
+        if(!send_msg_to_service(fd,output, strlen(output)))
         {
             LYDBGLOG("thread_recv send fail\n");
             continue;
@@ -128,9 +238,9 @@
     }
     free(output);
     output = NULL;
-    if(sockfd != 0)
+    if(fd != 0)
     {
-        close(sockfd);
+        close(fd);
     }
     return NULL;
 }
@@ -142,11 +252,15 @@
  */
 int lynq_connect_service_start(void)
 {
+    LYINFLOG("[%d][%s] enter",LINE,FUNC);
     pthread_t lynq_at_tid = -1;
     int rt = pthread_create(&lynq_at_tid, NULL, thread_recv, NULL);
-    if(rt < 0)
+    pthread_mutex_lock(&s_startupMutex);
+    LYINFLOG("[%d][%s] pthread mutex unlock",LINE,FUNC);
+    LYINFLOG(",rt:%d,connect state:%d\n",rt,connect_state);
+    if((connect_state != true) && rt < 0)
     {
-        LYERRLOG("urc loop failure!!!\n");
+        LYERRLOG("connect fail,rt:%d,connect state:%d\n",rt,connect_state);
         return -1;
     }
     return 0;
@@ -166,15 +280,17 @@
     }
     memcpy(buffer_at, ext_at, strlen(ext_at));
     tmp = callback;
-    LYLOGSET(LOG_INFO);
+    LYLOGSET(LOG_DEBUG);
     LYLOGEINIT(USER_LOG_TAG);
     LYDBGLOG("lynq_reg_third_at start\n");
     int ret = lynq_connect_service_start();
+    
     if(ret != 0)
     {
         LYDBGLOG("lynq_connect_service_start start failed\n");
         return A_ERROR;
     }
-    return result;
+    LYDBGLOG("lynq_connect_service_start success ret:%d\n",ret);
+    return A_SUCCESS;
 }
 
diff --git a/src/lynq/lib/liblynq-at-extension/makefile b/src/lynq/lib/liblynq-at-extension/makefile
index 0a6c2d3..257de29 100755
--- a/src/lynq/lib/liblynq-at-extension/makefile
+++ b/src/lynq/lib/liblynq-at-extension/makefile
@@ -6,10 +6,7 @@
                 -g -Os \
                 -flto \
                 -DRIL_SHLIB \
-                -DATCI_PARSE \
                 -fPIC \
-                -DKEEP_ALIVE \
-                -DECALL_SUPPORT \
                 -fpermissive \
 
 
@@ -19,6 +16,7 @@
 
 LOCAL_C_INCLUDES = \
   -I. \
+  -I$(ROOT)/usr/include/binder \
   -I$(LOCAL_PATH)/include/lib_at \
   -I$(ROOT)$(includedir)/logger \
   -I$(ROOT)$(includedir)/liblog \
@@ -31,6 +29,7 @@
     -llog \
     -lpthread \
     -llynq-log \
+    -lbinder \
 
 
 SOURCES = $(wildcard *.cpp)
diff --git a/src/telephonyware/3.0/atcid/atci/src/atcid.c b/src/telephonyware/3.0/atcid/atci/src/atcid.c
index d5ee767..0eaff4f 100755
--- a/src/telephonyware/3.0/atcid/atci/src/atcid.c
+++ b/src/telephonyware/3.0/atcid/atci/src/atcid.c
@@ -44,7 +44,7 @@
 
 #include <netinet/in.h>
 #include <sys/socket.h>
-#include "lynq_atsvc_controller.h"
+#include "lynq_atsvc_controller.h" /*warren add for lynq atsvc on 2022/12/06*/
 
 /*misc global vars */
 Serial serial;
diff --git a/src/telephonyware/3.0/atcid/atci/src/atcid_serial.c b/src/telephonyware/3.0/atcid/atci/src/atcid_serial.c
index 9ae9f21..577b3c1 100755
--- a/src/telephonyware/3.0/atcid/atci/src/atcid_serial.c
+++ b/src/telephonyware/3.0/atcid/atci/src/atcid_serial.c
@@ -68,7 +68,9 @@
 
 
 /*misc global vars */
-//extern Serial serial;
+#ifndef LYNQ_ATSVC
+extern Serial serial;
+#endif
 extern At_Ril_Mmi_t atRilMmi_info;
 
 #define CONN_VCOM 1
@@ -1269,6 +1271,17 @@
         LOGATCI(LOG_INFO, "Command:%s",line);
         /*warren add for lynq at svc on 2022/12/12 start*/
         #ifdef LYNQ_ATSVC
+        if(has_registe_cmd == true)
+        {
+            if(lynq_check_extension_atcmd(line) == 0)
+            {
+                if(send_msg_to_at_extension(line,strlen(line))!=0)
+                {
+                    ALOGD("send at fail,please try agin");
+                }
+                continue;
+            }
+        }
         plugin_count = -1;
         plugin_count = lynq_dispatch_atcmd(line);
         ALOGD("plugin count:%d",plugin_count);
@@ -1277,7 +1290,6 @@
             plugin_msg_array[plugin_count].atsvc_incb(line,strlen(line));
             continue;
         }
-//todo check whither plugin at cmd, if is plugin atcmd call cb and send msg to com,and continue
         #endif
         /*warren add for lynq at svc on 2022/12/12 end*/
         dataType = process_cmd_line(line);
diff --git a/src/telephonyware/3.0/atcid/atci/src/atcid_serial.h b/src/telephonyware/3.0/atcid/atci/src/atcid_serial.h
index 55d0868..3c0ed52 100755
--- a/src/telephonyware/3.0/atcid/atci/src/atcid_serial.h
+++ b/src/telephonyware/3.0/atcid/atci/src/atcid_serial.h
@@ -123,7 +123,9 @@
     int currDevice;
 } Serial;
 
-extern Serial serial;
+#ifdef LYNQ_ATSVC
+extern Serial serial;//warren add for atsvc on 20221214
+#endif
 
 static const char *s_MsgResponses[] = {
    "OK",
diff --git a/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.c b/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.c
index 0f32469..9042d35 100755
--- a/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.c
+++ b/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.c
@@ -6,6 +6,7 @@
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 #include <dlfcn.h>
+#include <pthread.h>
 #include "lynq_atsvc_controller.h"
 #include "atcid.h"
 #include "atcid_serial.h"
@@ -13,10 +14,19 @@
 #include "transfer_controller.h"
 #define FUNC __FUNCTION__
 #define LINE __LINE__
+
+#define SOCKET_ZERO   0
+#define SOCKET_SUCC   1
+#define SOCKET_FAIL  -1
+#define SOCKET_BUF_SIZE 512
+char register_atcmd_buff[SOCKET_BUF_SIZE] = {0};
+char *white_list[] = {"AT","ATD","ATV","ATA","ATE","ATH","ATL","ATI","ATP","ATO","ATQ",NULL};
 int g_atsvc_socket_fd = 0;
+int g_atsvc_client_connect = 0;
 //struct sockaddr_in server_addr;
 //struct sockaddr_in lynqClient_addr;
-
+static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
+int has_registe_cmd = 0;
 struct sockaddr_un g_remote_addr = {0};
 struct sockaddr_un g_local_addr = {0};
 
@@ -96,7 +106,6 @@
                     return -1;
                 }
             }
-           
             break;
         }
         case AF_INET:
@@ -139,7 +148,8 @@
     char* line_cut = cut_cmd_line(atcmd);
     if (line_cut == NULL)
     {
-        return 0;
+        ALOGD("[%d][%s]line_cut is null",LINE,FUNC);
+        return -1;
     }
     for(int i = 0;i < PLUGINE_MAX_COUNT;i++)
     {
@@ -250,16 +260,197 @@
     return 0;
 }
 
+
+int lynq_check_extension_atcmd(char * atcmd)
+{
+    ALOGD("[%d][%s] enter",LINE,FUNC);
+    char *needleP = NULL;
+    if(NULL == atcmd)
+    {
+        ALOGD("[%d][%s] atcmd is null",LINE,FUNC);
+        return -1;
+    }
+    ALOGD("[%d][%s]atcmd:%s",LINE,FUNC,atcmd);
+    char* line_cut = cut_cmd_line(atcmd);
+    if (line_cut == NULL)
+    {
+        ALOGD("[%d][%s]line_cut is null",LINE,FUNC);
+        return -1;
+    }
+    for(int i = 0;white_list[i];i++)
+    {
+        if(strcmp(line_cut,white_list[i]) == 0)
+        {
+            ALOGD("[%d][%s]count %d,pass atcmd:%s",LINE,FUNC,i,line_cut);
+            return -1;
+        }
+    }
+    needleP =strstr(register_atcmd_buff,line_cut);
+    if(NULL != needleP)
+    {
+        ALOGD("[%d][%s] find atcmd:%s",LINE,FUNC,line_cut);
+        free(line_cut);
+        return 0;
+    }
+    free(line_cut);
+    return -1;
+}
+int send_msg_to_at_extension(char *atcmd,int size)
+{
+    LOGATCI(LOG_ERR,"[%d][%s] enter",LINE,FUNC);
+    if (g_atsvc_client_connect < 0)
+    {
+        LOGATCI(LOG_ERR, "fd invalid when send to atci service. errno = %d", errno);
+        return -1;
+    }
+    if(NULL == atcmd)
+    {
+        LOGATCI(LOG_ERR, "atcmd is null.");
+        return -1;
+    }
+    int sendLen = send(g_atsvc_client_connect, atcmd, size, 0);
+    if (sendLen != size)
+    {
+        LOGATCI(LOG_ERR, "lose data when send to atci service. errno = %d", errno);
+        return -1;
+    }
+    LOGATCI(LOG_DEBUG, "send to app demo: %s", atcmd);
+    return 0;
+}
+int actsvc_cmd_recv(int fd, char *buf, int len)
+{
+    int ret = 0;
+    fd_set rfds;
+    //FD_CLR(fd, &rfds);
+    FD_SET(fd, &rfds);
+    ret = select(fd + 1, &rfds, NULL, NULL, NULL);
+    if (ret <= 0)
+    {
+        ALOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+        return SOCKET_FAIL;
+    }
+    if (FD_ISSET(fd, &rfds))
+    {
+        ret = recv(fd, buf, len, 0);
+        if (ret < 0)
+        {
+            ALOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+            return SOCKET_FAIL;
+        }
+        else if(ret == 0)
+        {
+            ALOGE("acti_cmd_recv recv error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+            return SOCKET_ZERO;
+        }
+        else
+        {
+            ALOGD("[%d][%s] buf is:%s",LINE,FUNC,buf);
+        }
+    }
+    return SOCKET_SUCC;
+}
+
+void *start_at_extension_Socket(void * param)
+{
+    ALOGD("[%d][%s]enter",LINE,FUNC);
+    socklen_t client_len;
+    int ret;
+    char parser_buf[SOCKET_BUF_SIZE];
+    g_atsvc_socket_fd = create_socket(AF_UNIX, SOCK_STREAM,0, 0, NULL,RIL_SOCKET_NAME, (void *)&g_local_addr, 2);
+    if(0 > g_atsvc_socket_fd)
+    {
+        ALOGD("init socket fail and fd:%d",g_atsvc_socket_fd);
+        return NULL;
+    }
+    TryNewLink:
+    client_len = sizeof(g_local_addr);
+    int conn = accept(g_atsvc_socket_fd,(struct sockaddr *) &g_local_addr, &client_len);
+    if (conn <= 0)
+    {
+        ALOGE("[%d][%s] accept error!",LINE,FUNC);
+        close(conn);
+        return NULL;
+    }
+    ALOGD("Accept a client , fd is %d", conn);
+    if(g_atsvc_client_connect >= 0)
+    {
+        ALOGE("g_atsvc_client_connect need close!");
+        close(g_atsvc_client_connect);
+        g_atsvc_client_connect = -1;
+    }
+    g_atsvc_client_connect = conn;
+    /* tranlate data */
+    while (true)
+    {
+        memset(parser_buf, 0, sizeof(parser_buf));
+        if(has_registe_cmd == 0)
+        {
+            memset(register_atcmd_buff, 0, sizeof(register_atcmd_buff));
+            ret = actsvc_cmd_recv(conn, register_atcmd_buff, SOCKET_BUF_SIZE);
+            if (ret < 0)
+            {
+                ALOGE("[%d][%s]receive CMD error",LINE,FUNC);
+                continue;
+            }
+            else if(ret == SOCKET_ZERO)
+            {
+                ALOGE("maybe client socket closed 1. retry new link!");
+              goto TryNewLink;
+            }
+            has_registe_cmd = 1;
+        }
+        else
+        {
+            ret = actsvc_cmd_recv(conn, parser_buf, SOCKET_BUF_SIZE);
+            if (ret < 0)
+            {
+                ALOGE("[%d][%s]receive CMD error",LINE,FUNC);
+                continue;
+            }
+            else if(ret == SOCKET_ZERO)
+            {
+                ALOGE("maybe client socket closed 1. retry new link!");
+              goto TryNewLink;
+            }
+            lynq_write_data_to_serail(parser_buf,strlen(parser_buf),0);
+        }
+    }
+    return NULL;
+}
+
+void start_at_extension_loop(void)
+{
+    pthread_t at_extension_socket_thread;
+    ALOGD("[%d][%s]enter",LINE,FUNC);
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&at_extension_socket_thread, &attr, start_at_extension_Socket, NULL);
+    if (result != 0)
+    {
+        ALOGE("Failed to create ATCI thread: %s", strerror(result));
+        goto done;
+    }
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
 int lynq_atsvc_init(int count,const char * plugin_conf_path)
 {
     ALOGD("start [%d][%s]",LINE,FUNC);
     int res = 0;
+    /*
     g_atsvc_socket_fd = create_socket(AF_UNIX, SOCK_STREAM,0, 0, NULL,RIL_SOCKET_NAME, (void *)&g_local_addr, 2);
     if(0 > g_atsvc_socket_fd)
     {
         ALOGD("init socket fail and fd:%d",g_atsvc_socket_fd);
         //return INIT_SOCKET_FAIL;
     }
+    */
+    start_at_extension_loop();
     res = load_pulgin(PLUGIN_CONF_PATH);
     if(0 > res)
     {
@@ -285,6 +476,7 @@
     {
         ALOGD("init pseudo terminal fail");
     }
+    //todo at liblynq-at-extension
     /*create thread for reacive ril msg*/
     /*load pulgin from plugin config*/
     return 0;
diff --git a/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.h b/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.h
index a49400cf..549f6a7 100755
--- a/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.h
+++ b/src/telephonyware/3.0/atcid/atci/src/lynq-private/lynq_atsvc_controller.h
@@ -19,24 +19,35 @@
 #define PLUGIN_CONF_PATH "/data/atsvc/lynq_atsvc_plugin.xml"
 #define RIL_SOCKET_NAME "/dev/socket/lynq_atsvc_socket_1"
 #define PLUGINE_MAX_COUNT 16
+
+
+
 /**********************************************************************************************
-/**函数列表是第六部分
-* @brief initalize lynq atsvc,it will load plugin and create socket process
-* @param plugin_conf_path [IN] plugin config file path
-* @param sum [OUT](OUT 表示出参) 参数b 说明
-* @return 
-*     0:success
-*     1:load pugin config file fail
-*     2:create socket fail
-*     3:create thread fail
+* @brief this is a callback function,atsvc will call this function if the at command is this \
+**module command
+* @param input [IN] at command
+* @param length [IN] at command length
+* @return NULL
 ************************************************************************************************/
 typedef void ( *lynq_atsvc_incb )(const char *input,const int length);
-/*type:
+
+/**********************************************************************************************
+* @brief this is a callback function,plugin will call this function when the plugin needs to \
+**return the response or urc
+* @param input [IN] response or urc
+* @param length [IN] response or urc length
+* @param type 
 ** 0:response 
 ** 1:unsolictedresponse
-*/
+* @return NULL
+************************************************************************************************/
 typedef void ( *lynq_atsvc_outcb )(char *output,int out_size,int type);
 
+/**********************************************************************************************
+* @brief this is a register function, atsvc will call this function when a plugin register in atsvc.
+* @param lynq_atsvc_outcb [IN]
+* @return lynq_atsvc_incb
+************************************************************************************************/
 typedef lynq_atsvc_incb (*lynq_register_module)(lynq_atsvc_outcb out_cb);
 
 
@@ -50,9 +61,19 @@
 }plugin_msg_t;
 
 extern plugin_msg_t plugin_msg_array[PLUGINE_MAX_COUNT];
-
+extern int has_registe_cmd;
+/**********************************************************************************************
+* @brief initalize lynq atsvc,it will load plugin and create socket process
+* @param plugin_conf_path [IN] plugin config file path
+* @return 
+*     0:success
+*     1:load pugin config file fail
+*     2:create socket fail
+*     3:create thread fail
+************************************************************************************************/
 int lynq_atsvc_init(int count,const char * plugin_conf_path);
-
+int lynq_check_extension_atcmd(char * atcmd);
+int send_msg_to_at_extension(char *atcmd,int size);
 int create_socket(const int domain, const int type, const int protocol,const int port,const char *IP,const char *socket_name,void * addr,int backlog);
 int send_msg(int socket_fd,const struct sockaddr *dest_addr,const char *msg);
 int lynq_dispatch_atcmd(char* atcmd);