[bugfix]liblynq-at-extension

Change-Id: Ib79b387ae820b9f4aae32f0a426ada3c3d9a1453
diff --git a/lib/liblynq-at-extension/lynq_at.cpp b/lib/liblynq-at-extension/lynq_at.cpp
index 7440c99..7af2ae3 100755
--- a/lib/liblynq-at-extension/lynq_at.cpp
+++ b/lib/liblynq-at-extension/lynq_at.cpp
@@ -7,6 +7,7 @@
 #include <signal.h>
 #include <string.h>
 #include <log/log.h>
+#include <pthread.h>
 #include "liblog/lynq_deflog.h"
 #include "include/lib_at/lynq_at.h"
 
@@ -16,73 +17,154 @@
 
 int sockfd = 0;
 char *output = NULL;
+char buffer_at[OUT_MAX_SIZE] = {0};
 struct sockaddr_in addr_serv;
 socklen_t len;
+LYNQ_AT_CALLBACK tmp = NULL;
 
 /**
- * @brief type:in send third at cmd to service
- * @param ext_at type:in input at cmd
- * @param callback type:in
- * @return int 
+ * @brief Catch exceptions and free malloc's memory
+ * 
+ * @param signum Type:[IN] signal
  */
-int lynq_reg_third_at(const char *ext_at, LYNQ_AT_CALLBACK callback)
+static void signal_handler(int signum)
 {
-    LYDBGLOG("lynq_reg_third_at start\n");
+    switch(signum)
+    {
+         case SIGABRT:
+            LYDBGLOG("recv SIGABRT\n");
+            break;
+         case SIGBUS:
+            LYDBGLOG("recv SIGBUS\n");
+            break;
+         case SIGFPE:
+            LYDBGLOG("recv SIGFPE\n");
+            break;
+         case SIGILL:
+            LYDBGLOG("recv SIGILL\n");
+            break;
+         case SIGSEGV:
+            LYDBGLOG("recv SIGSEGV\n");
+            break;
+         default:
+            LYDBGLOG("recv unknown signal\n");
+            break;
+    }
+    if(NULL != output)
+    {
+        free(output);
+        output = NULL;
+    }
+}
+
+/**
+ * @brief send third cmd to service and receive input,then send output to service
+ * 
+ * @param parm 
+ * @return void* 
+ */
+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);
+    int recv = 0;
+    int send = 0;
+    int result = 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(ext_at);
-    int send = sendto(sockfd, ext_at, len_buf,0,(struct sockaddr*)&addr_serv,len);
+    int len_buf = strlen(buffer_at);
+    send = sendto(sockfd, buffer_at, len_buf,0,(struct sockaddr*)&addr_serv,len);
     if(send < 0)
     {
-        LYDBGLOG("send fail\n");
-        return -1;
+        LYDBGLOG("thread_recv send fail\n");
+        return NULL;
     }
     char *input = NULL;
     output = (char *)malloc(sizeof(char)*OUT_MAX_SIZE);
     if(NULL == output)
     {
-        LYDBGLOG("malloc fail\n");
-        return -1;
+        LYDBGLOG("thread_recv malloc fail\n");
+        return NULL;
     }
     while (1)
     {
         /*receive at cmd*/
         LYDBGLOG("lynq_reg_third_at receive at cmd\n");
-        char at_cmd[100] = {0};
-        int recv = recvfrom(sockfd,at_cmd,sizeof(at_cmd),0,(struct sockaddr*)&addr_serv,&len);
+        recv = recvfrom(sockfd,at_cmd,sizeof(at_cmd),0,(struct sockaddr*)&addr_serv,&len);
         if(recv < 0)
         {
-            LYDBGLOG("recv fail\n");
-            return -1;
+            LYDBGLOG("thread_recv recv fail\n");
+            continue;
         }
         input = at_cmd;
-        callback(input, output, OUT_MAX_SIZE);
-        if(NULL == output)
-        {
-            LYDBGLOG("output = null\n");
-            return -1;
-        }
+        //begin deal with callback
+        tmp(input, output, OUT_MAX_SIZE);
         LYDBGLOG("lynq_reg_third_at send output to service\n");
-        int send = sendto(sockfd, output, strlen(output),0,(struct sockaddr*)&addr_serv,len);
+        send = sendto(sockfd, output, strlen(output),0,(struct sockaddr*)&addr_serv,len);
         if(send < 0)
         {
-            LYDBGLOG("send fail\n");
+            LYDBGLOG("thread_recv send fail\n");
             continue;
         }
     }
-    if(output != NULL)
-    {
-        free(output);
-        output = NULL;
-    }
+    free(output);
+    output = NULL;
     if(sockfd != 0)
     {
         close(sockfd);
     }
+    return NULL;
+}
+
+/**
+ * @brief Threads are created to communicate with the server
+ * 
+ * @return int 
+ */
+int lynq_connect_service_start(void)
+{
+    pthread_t lynq_at_tid = -1;
+    int rt = pthread_create(&lynq_at_tid, NULL, thread_recv, NULL);
+    if(rt < 0)
+    {
+        LYERRLOG("urc loop failure!!!\n");
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * @brief Type:[IN] send third at cmd to service
+ * @param ext_at Type:[IN] input at cmd
+ * @param callback Type:[IN]
+ * @return int 
+ */
+int lynq_reg_third_at(const char *ext_at, LYNQ_AT_CALLBACK callback)
+{
+    if(NULL == ext_at || NULL == callback)
+    {
+        return -1;
+    }
+    memcpy(buffer_at, ext_at, strlen(ext_at));
+    tmp = callback;
+    LYLOGSET(LOG_INFO);
+    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 -1;
+    }
     return 0;
 }