| #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 <pthread.h> | |
| #include <fcntl.h> | |
| #include <errno.h> | |
| #include <stdint.h> | |
| #include <dlfcn.h> | |
| #include <stdbool.h> | |
| #include "gsw_at_interface.h" | |
| #include "gsw_hal_errcode.h" | |
| #include "gsw_log_interface.h" | |
| #define OUT_MAX_SIZE 1024 | |
| #define LINE __LINE__ | |
| #define FUNC __FUNCTION__ | |
| #define AT_EXTERSION_SOCKET_NAME "/tmp/atcmdext" | |
| #define SOCKET_ZERO 0 | |
| #define SOCKET_SUCC 1 | |
| #define SOCKET_FAIL -1 | |
| #define GSW_AT "[HAL][GSW_AT]" | |
| //typedef void (*mbtk_log)(int level, const char *format,...); | |
| typedef enum | |
| { | |
| A_SUCCESS = 0, | |
| A_ERROR = -1 | |
| }LYNQ_AT_E; | |
| //static mbtk_log fun_ptr_log = NULL; | |
| static void *dlHandle_at = NULL; | |
| char *lynqLib_at = "/lib/libmbtk_lib.so"; | |
| char *output = NULL; | |
| int sockfd = 0; | |
| int result = A_SUCCESS; | |
| char buffer_at[OUT_MAX_SIZE] = {0}; | |
| struct sockaddr_in addr_serv; | |
| struct sockaddr_un addr_server; | |
| LYNQ_AT_CALLBACK tmp = NULL; | |
| static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER; | |
| socklen_t len; | |
| bool connect_state = false; | |
| int socket_local_client (char* name) { | |
| LOGD(GSW_AT,"[%d][%s] enter",LINE,FUNC); | |
| sockfd = socket(AF_UNIX, SOCK_STREAM, 0); | |
| if (sockfd < 0) | |
| { | |
| LOGD(GSW_AT,"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); | |
| LOGD(GSW_AT,"Can't connect to server side, path: %s, %s", name, strerror(errno)); | |
| return -1; | |
| } | |
| LOGD(GSW_AT,"[%d][%s] connect %s success",LINE,FUNC,name); | |
| return sockfd; | |
| } | |
| bool send_msg_to_service(int fd,char *msg,int size) | |
| { | |
| LOGD(GSW_AT,"[%d][%s] enter",LINE,FUNC); | |
| if (fd < 0) | |
| { | |
| LOGD(GSW_AT,"fd invalid when send to atci service. errno = %d", errno); | |
| return false; | |
| } | |
| if(NULL == msg) | |
| { | |
| LOGD(GSW_AT,"atcmd is null."); | |
| return false; | |
| } | |
| int sendLen = send(fd, msg, size, 0); | |
| if (sendLen != size) | |
| { | |
| LOGD(GSW_AT,"lose data when send to atci service. errno = %d", errno); | |
| return false; | |
| } | |
| LOGD(GSW_AT,"client send to app demo: %s", msg); | |
| return true; | |
| } | |
| int atsvc_cmd_recv(int fd, char *buf, int len) | |
| { | |
| int ret = 0; | |
| ret = recv(fd, buf, len, 0); | |
| LOGD(GSW_AT,"[%d][%s] recv after",LINE,FUNC); | |
| if (ret < 0) | |
| { | |
| LOGD(GSW_AT,"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) | |
| { | |
| LOGD(GSW_AT,"acti_cmd_recv client recv error, ret=%d, error=%s(%d),fd=%d", ret,strerror(errno), errno, fd); | |
| return SOCKET_ZERO; | |
| } | |
| 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) | |
| { | |
| LOGD(GSW_AT,"[%d][%s] enter",LINE,FUNC); | |
| char at_cmd[100] = {0}; | |
| int fd = -1; | |
| int ret = 0; | |
| fd = socket_local_client(AT_EXTERSION_SOCKET_NAME); | |
| if(fd <= 0) | |
| { | |
| LOGE(GSW_AT,"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)) | |
| { | |
| LOGE(GSW_AT,"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) | |
| { | |
| LOGE(GSW_AT,"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); | |
| LOGE(GSW_AT,"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) | |
| { | |
| LOGE(GSW_AT,"[%d][%s]receive CMD error",LINE,FUNC); | |
| continue; | |
| } | |
| else if(ret == SOCKET_ZERO) | |
| { | |
| LOGE(GSW_AT,"maybe client socket closed 1. retry new link!"); | |
| connect_state = false; | |
| goto TryNewLink; | |
| } | |
| input = at_cmd; | |
| int len = strlen(input); | |
| while (len > 0 && (input[len - 1] == '\r' || input[len - 1] == '\n')) | |
| { | |
| input[--len] = '\0'; | |
| } | |
| //begin deal with callback | |
| tmp(input, output, OUT_MAX_SIZE); | |
| LOGD(GSW_AT,"lynq_reg_third_at send output to service\n"); | |
| if(!send_msg_to_service(fd,output, strlen(output))) | |
| { | |
| LOGE(GSW_AT,"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) | |
| { | |
| LOGD(GSW_AT,"[%d][%s] enter",LINE,FUNC); | |
| pthread_t lynq_at_tid; | |
| int rt = pthread_create(&lynq_at_tid, NULL, thread_recv, NULL); | |
| pthread_mutex_lock(&s_startupMutex); | |
| LOGD(GSW_AT,"[%d][%s] pthread mutex unlock",LINE,FUNC); | |
| if((connect_state != true) && rt < 0) | |
| { | |
| LOGE(GSW_AT,"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 | |
| */ | |
| int32_t gsw_reg_atcmd(const char *atcmd,LYNQ_AT_CALLBACK func) | |
| { | |
| if(NULL == atcmd || NULL == func) | |
| { | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| memcpy(buffer_at, atcmd, strlen(atcmd)); | |
| tmp = func; | |
| LOGD(GSW_AT,"lynq_reg_third_at start\n"); | |
| int ret = lynq_connect_service_start(); | |
| if(ret != 0) | |
| { | |
| LOGE(GSW_AT,"lynq_connect_service_start start failed\n"); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| LOGD(GSW_AT,"lynq_connect_service_start success ret:%d\n",ret); | |
| return GSW_HAL_SUCCESS; | |
| } | |
| int32_t gsw_sdk_at_init(void) | |
| { | |
| dlHandle_at = dlopen(lynqLib_at, RTLD_NOW); | |
| //fun_ptr_log = (mbtk_log)dlsym(dlHandle_at, "mbtk_log"); | |
| if(dlHandle_at == NULL) | |
| { | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| return GSW_HAL_SUCCESS; | |
| } | |
| int gsw_get_modem_temperture(ZONE_NUM num,int *temp) | |
| { | |
| if (num != soc_max) | |
| { | |
| LOGE(GSW_AT,"temperture if not support,num is %d\n",num); | |
| return GSW_HAL_SUCCESS; | |
| } | |
| if (NULL == temp) | |
| { | |
| LOGE(GSW_AT,"temperture is null\n"); | |
| return GSW_HAL_ARG_INVALID; | |
| } | |
| char *cmd = "/sys/class/thermal/thermal_zone0/temp"; | |
| FILE *fp = NULL; | |
| char buf[128] = {0}; | |
| fp = fopen(cmd, "r"); | |
| if (fp == NULL) | |
| { | |
| LOGE(GSW_AT,"Unable to open file"); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| if (fgets(buf, sizeof(buf), fp) == NULL) | |
| { | |
| LOGE(GSW_AT,"fgets fail"); | |
| fclose(fp); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| if (strlen(buf) == 0) | |
| { | |
| LOGE(GSW_AT,"read len == 0\n"); | |
| fclose(fp); | |
| return GSW_HAL_NORMAL_FAIL; | |
| } | |
| *temp = atoi(buf) / 1000; | |
| fclose(fp); | |
| return GSW_HAL_SUCCESS; | |
| } |