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

Change-Id: I70c601f3cbc7e8b59aa5feaf2d4147727f227963
diff --git a/lib/liblynq-at-extension/lynq_at.cpp b/lib/liblynq-at-extension/lynq_at.cpp
index a7c6b2e..8785310 100755
--- a/lib/liblynq-at-extension/lynq_at.cpp
+++ b/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;
 }