Squashed 'LYNQ_PUBLIC/' content from commit 79d8f932f
git-subtree-dir: LYNQ_PUBLIC
git-subtree-split: 79d8f932fb4ebc4b5aec6c5ace97634912394272
Change-Id: If2527ba937f56fe989487bf71e996f7cfd9fbe61
diff --git a/common_src/lib/liblynq-at-extension/lynq_at.cpp b/common_src/lib/liblynq-at-extension/lynq_at.cpp
new file mode 100755
index 0000000..80c6588
--- /dev/null
+++ b/common_src/lib/liblynq-at-extension/lynq_at.cpp
@@ -0,0 +1,301 @@
+#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,
+ A_ERROR = -1
+}LYNQ_AT_E;
+
+/*lei add : maybe sento/revc error*/
+int result = A_SUCCESS;
+/*lei add : maybe sento/revc error*/
+int sockfd = 0;
+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
+ *
+ * @param signum Type:[IN] signal
+ */
+static void signal_handler(int signum)
+{
+ 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;
+ }
+}
+
+
+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, %s", name, strerror(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("client send to app demo: %s", msg);
+ return true;
+}
+
+int atsvc_cmd_recv(int fd, char *buf, int len)
+{
+ LYINFLOG("[%d][%s] enter",LINE,FUNC);
+ 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 client select error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd);
+ // return SOCKET_FAIL;
+ // }
+ // if (FD_ISSET(fd, &rfds))
+ // {
+ LYDBGLOG("[%d][%s] recv before",LINE,FUNC);
+ ret = recv(fd, buf, len, 0);
+ LYDBGLOG("[%d][%s] recv after",LINE,FUNC);
+ if (ret < 0)
+ {
+ LYDBGLOG("acti_cmd_recv client 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 client 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
+ *
+ * @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);
+ LYINFLOG("[%d][%s] enter",LINE,FUNC);
+ int recv = 0;
+ int send = 0;
+ char at_cmd[100] = {0};
+ int fd = -1;
+ int ret = 0;
+ fd = socket_local_client(AT_EXTERSION_SOCKET_NAME);
+ if(fd <= 0)
+ {
+ LYDBGLOG("socket_local_client fail\n");
+ 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))
+ {
+ LYDBGLOG("send_msg_to_service fail\n");
+ 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");
+ 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*/
+ memset(at_cmd, 0, sizeof(at_cmd));
+ ret = atsvc_cmd_recv(fd, at_cmd,sizeof(at_cmd));
+ if (ret < 0)
+ {
+ 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");
+ if(!send_msg_to_service(fd,output, strlen(output)))
+ {
+ LYDBGLOG("thread_recv send fail\n");
+ continue;
+ }
+ }
+ free(output);
+ output = NULL;
+ if(fd != 0)
+ {
+ close(fd);
+ }
+ return NULL;
+}
+
+/**
+ * @brief Threads are created to communicate with the server
+ *
+ * @return int
+ */
+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);
+ 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("connect fail,rt:%d,connect state:%d\n",rt,connect_state);
+ 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 A_ERROR;
+ }
+ memcpy(buffer_at, ext_at, strlen(ext_at));
+ tmp = callback;
+ 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;
+ }
+ LYDBGLOG("lynq_connect_service_start success ret:%d\n",ret);
+ return A_SUCCESS;
+}
+