| #include <termios.h> |
| #include <pthread.h> |
| #include <sys/un.h> |
| #include <stdio.h> |
| #include <sys/socket.h> |
| #include <errno.h> |
| #include <stdlib.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <sys/epoll.h> |
| #include <netinet/in.h> |
| #include <signal.h> |
| #include <unistd.h> |
| |
| #include "mbtk_log.h" |
| |
| #define MBTK_AT_SOCK "/tmp/atcmd_at" |
| #define TEMP_FAILURE_RETRY(exp) ({ \ |
| typeof (exp) _rc; \ |
| do { \ |
| _rc = (exp); \ |
| } while (_rc == -1 && errno == EINTR); \ |
| _rc; }) |
| |
| static char *at_rsp_complete_tag[] = { |
| "OK", |
| "ERROR", |
| "CONNECT", |
| "+CMS ERROR:", |
| "+CME ERROR:", |
| "NO ANSWER", |
| "NO DIALTONE", |
| NULL}; |
| static int at_fd = -1; |
| |
| static int openSocket(const char* sockname) |
| { |
| int sock = socket(AF_UNIX, SOCK_STREAM, 0); |
| if (sock < 0) { |
| LOGE("Error create socket: %s\n", strerror(errno)); |
| return -1; |
| } |
| struct sockaddr_un addr; |
| memset(&addr, 0, sizeof(addr)); |
| addr.sun_family = AF_UNIX; |
| strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); |
| while (TEMP_FAILURE_RETRY(connect(sock,(const struct sockaddr*)&addr, sizeof(addr))) != 0) { |
| LOGE("Error connect to socket %s: %s, try again", sockname, strerror(errno)); |
| sleep(1); |
| } |
| |
| #if 0 |
| int sk_flags = fcntl(sock, F_GETFL, 0); |
| fcntl(sock, F_SETFL, sk_flags | O_NONBLOCK); |
| #endif |
| |
| return sock; |
| } |
| |
| |
| static int at_complete(char *rsp) |
| { |
| #if 0 |
| char *ptr = at_rsp_complete_tag; |
| while(ptr) { |
| LOGD("ptr = %s", ptr); |
| if(strstr(rsp, ptr)) { |
| LOGD("%s , %s", rsp, ptr); |
| return 1; |
| } |
| ptr++; |
| } |
| #else |
| int i = 0; |
| while(at_rsp_complete_tag[i]) { |
| LOGD("ptr = %s", at_rsp_complete_tag[i]); |
| if(strstr(rsp, at_rsp_complete_tag[i])) { |
| LOGD("%s , %s", rsp, at_rsp_complete_tag[i]); |
| return 1; |
| } |
| i++; |
| } |
| |
| #endif |
| return 0; |
| } |
| |
| static int at_rsp_read(char* rsp, int rsp_len) |
| { |
| int len = 0; |
| int index = 0; |
| memset(rsp, 0x0, rsp_len); |
| while(1) { |
| if((len = read(at_fd, rsp + index, rsp_len - index)) > 0) { |
| if(at_complete(rsp)) { |
| LOGD("AT<%s", rsp); |
| return 0; |
| } else { |
| index += len; |
| |
| if(index >= rsp_len) { |
| LOGE("Buffer too small."); |
| return -1; |
| } |
| } |
| } else { |
| printf("Read error:%d\n",errno); |
| return -1; |
| } |
| } |
| } |
| |
| |
| /*=========================================================================== |
| FUNCTION mbtk_at_init |
| |
| DESCRIPTION: |
| Initial MBTK AT. |
| |
| PARAMETERS: |
| None. |
| |
| RETURN VALUE: |
| int : Return 0 if success,other for failure. |
| |
| ===========================================================================*/ |
| int mbtk_at_init() |
| { |
| if(at_fd > 0) { |
| LOGW("MBTK AT has inited."); |
| return 0; |
| } |
| |
| at_fd = openSocket(MBTK_AT_SOCK); |
| return at_fd > 0 ? 0 : -1; |
| } |
| |
| |
| /*=========================================================================== |
| FUNCTION mbtk_at_deinit |
| |
| DESCRIPTION: |
| Deinitial MBTK AT. |
| |
| PARAMETERS: |
| None. |
| |
| RETURN VALUE: |
| int : Return 0 if success,other for failure. |
| |
| ===========================================================================*/ |
| int mbtk_at_deinit() |
| { |
| if(at_fd < 0) { |
| LOGW("MBTK AT not inited."); |
| return 0; |
| } |
| |
| close(at_fd); |
| at_fd = -1; |
| return 0; |
| } |
| |
| /*=========================================================================== |
| FUNCTION mbtk_at_send |
| |
| DESCRIPTION: |
| Send AT command. |
| |
| PARAMETERS: |
| cmd [IN]: AT command. |
| rsp [OUT]: AT command response. |
| rsp_len[IN] : AT command response buffer size. |
| |
| RETURN VALUE: |
| int : Return 0 if success,other for failure. |
| |
| ===========================================================================*/ |
| int mbtk_at_send(char* cmd, char* rsp, int rsp_len) |
| { |
| if(cmd == NULL || strlen(cmd) == 0 || rsp == NULL || rsp_len <= 0) { |
| return -1; |
| } |
| char at_cmd[2048] = {0}; |
| memcpy(at_cmd, cmd, strlen(cmd)); |
| char *ptr = at_cmd + strlen(at_cmd) - 1; |
| while(ptr >= at_cmd && (*ptr == '\r' || *ptr == '\n')) |
| { |
| *ptr-- = '\0'; |
| } |
| if(!strncasecmp(at_cmd, "at", 2)) |
| { |
| LOGD("AT>%s", at_cmd); |
| *(++ptr) = '\r'; |
| *(++ptr) = '\n'; |
| if(write(at_fd, at_cmd, strlen(at_cmd)) != strlen(at_cmd)) { |
| LOGE("Write error:%d",errno); |
| return -1; |
| } |
| |
| return at_rsp_read(rsp, rsp_len); |
| } else { |
| LOGE("AT command error:%s",at_cmd); |
| return -1; |
| } |
| } |
| |