• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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