1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "vendor_channel.h"
17
18 #include <stddef.h>
19 #include <sys/types.h>
20
21 #include "bits/errno.h"
22 #include "errno.h"
23 #include "securec.h"
24 #include "string.h"
25 #include "telephony_log_c.h"
26 #include "unistd.h"
27 #include "vendor_util.h"
28
29 static char g_buffer[MAX_RESPONSE_LEN + 1];
30 static char *g_bufferCur = g_buffer;
31
FindEndOfLine(char * cur)32 static char *FindEndOfLine(char *cur)
33 {
34 char *endLine = cur;
35 int32_t count = 2;
36 if (endLine == NULL) {
37 return NULL;
38 }
39 if (endLine[0] == '>' && endLine[1] == ' ' && endLine[count] == '\0') {
40 return endLine + count;
41 }
42 while (*endLine != '\0' && *endLine != '\r' && *endLine != '\n') {
43 endLine++;
44 }
45 return (*endLine != '\0') ? endLine : NULL;
46 }
47
SkipUnUseChar(void)48 static void SkipUnUseChar(void)
49 {
50 while (*g_bufferCur == '\r' || *g_bufferCur == '\n') {
51 g_bufferCur++;
52 }
53 }
54
ClearCurBuffer(char ** processed)55 static void ClearCurBuffer(char **processed)
56 {
57 if (processed == NULL) {
58 return;
59 }
60 g_buffer[0] = '\0';
61 g_bufferCur = g_buffer;
62 *processed = g_bufferCur;
63 }
64
ProcessLastResponse(char ** processed)65 static char *ProcessLastResponse(char **processed)
66 {
67 if (processed == NULL) {
68 return NULL;
69 }
70 char *endLine = NULL;
71 if (*g_bufferCur == '\0') {
72 ClearCurBuffer(processed);
73 } else {
74 SkipUnUseChar();
75 endLine = FindEndOfLine(g_bufferCur);
76 if (endLine == NULL) {
77 TELEPHONY_LOGE("g_bufferCur endLine is null\n");
78 size_t len;
79 len = strlen(g_bufferCur);
80 (void)memmove_s(g_buffer, MAX_RESPONSE_LEN + 1, g_bufferCur, len + 1);
81 *processed = g_buffer + len;
82 g_bufferCur = g_buffer;
83 }
84 }
85 return endLine;
86 }
87
ReadResponse(int32_t atFd)88 const char *ReadResponse(int32_t atFd)
89 {
90 ssize_t size;
91 char *processed = NULL;
92 char *endEol = NULL;
93 char *ret = NULL;
94 // process last response data
95 endEol = ProcessLastResponse(&processed);
96 while (endEol == NULL) {
97 if (MAX_RESPONSE_LEN == (processed - &g_buffer[0])) {
98 ClearCurBuffer(&processed);
99 }
100 do {
101 size = read(atFd, processed, (MAX_RESPONSE_LEN - (processed - &g_buffer[0])));
102 } while (size < 0 && errno == EINTR);
103 if (size > 0) {
104 processed[size] = '\0';
105 SkipUnUseChar();
106 endEol = FindEndOfLine(g_bufferCur);
107 processed += size;
108 } else if (size == 0) {
109 TELEPHONY_LOGE("atchannel: EOF reached");
110 return NULL;
111 } else {
112 TELEPHONY_LOGE("read error %{public}s", strerror(errno));
113 return NULL;
114 }
115 }
116 *endEol = '\0';
117 ret = g_bufferCur;
118 g_bufferCur = endEol + 1;
119 return ret;
120 }
121
WriteATCommand(const char * s,int32_t isPdu,int32_t atFd)122 int32_t WriteATCommand(const char *s, int32_t isPdu, int32_t atFd)
123 {
124 if (s == NULL) {
125 return AT_ERR_GENERIC;
126 }
127 ssize_t ret;
128 size_t i = 0;
129 size_t len = strlen(s);
130 if (atFd < 0) {
131 return AT_ERR_CHANNEL_CLOSED;
132 }
133
134 while (i < len) {
135 do {
136 ret = write(atFd, s + i, len - i);
137 } while (ret < 0 && errno == EINTR);
138
139 if (ret < 0) {
140 return AT_ERR_GENERIC;
141 }
142 i += ret;
143 }
144 if (isPdu != 0) {
145 do {
146 ret = write(atFd, "\x1A", 1);
147 } while ((ret < 0 && errno == EINTR) || (ret == 0));
148 } else {
149 do {
150 ret = write(atFd, "\r", 1);
151 } while ((ret < 0 && errno == EINTR) || (ret == 0));
152 }
153 if (ret < 0) {
154 return AT_ERR_GENERIC;
155 }
156 return VENDOR_SUCCESS;
157 }
158