• 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 "errno.h"
22 #include "securec.h"
23 #include "string.h"
24 #include "telephony_log_c.h"
25 #include "unistd.h"
26 #include "vendor_util.h"
27 
28 static char g_buffer[MAX_RESPONSE_LEN + 1];
29 static char *g_bufferCur = g_buffer;
30 
FindEndOfLine(char * cur)31 static char *FindEndOfLine(char *cur)
32 {
33     char *endLine = cur;
34     int32_t count = 2;
35     if (endLine == NULL) {
36         return NULL;
37     }
38     if (endLine[0] == '>' && endLine[1] == ' ' && endLine[count] == '\0') {
39         return endLine + count;
40     }
41     while (*endLine != '\0' && *endLine != '\r' && *endLine != '\n') {
42         endLine++;
43     }
44     return (*endLine != '\0') ? endLine : NULL;
45 }
46 
SkipUnUseChar(void)47 static void SkipUnUseChar(void)
48 {
49     while (*g_bufferCur == '\r' || *g_bufferCur == '\n') {
50         g_bufferCur++;
51     }
52 }
53 
ClearCurBuffer(char ** processed)54 static void ClearCurBuffer(char **processed)
55 {
56     if (processed == NULL) {
57         return;
58     }
59     g_buffer[0] = '\0';
60     g_bufferCur = g_buffer;
61     *processed = g_bufferCur;
62 }
63 
ProcessLastResponse(char ** processed)64 static char *ProcessLastResponse(char **processed)
65 {
66     if (processed == NULL) {
67         return NULL;
68     }
69     char *endLine = NULL;
70     if (*g_bufferCur == '\0') {
71         ClearCurBuffer(processed);
72     } else {
73         SkipUnUseChar();
74         endLine = FindEndOfLine(g_bufferCur);
75         if (endLine == NULL) {
76             TELEPHONY_LOGE("g_bufferCur endLine is null\n");
77             size_t len;
78             len = strlen(g_bufferCur);
79             (void)memmove_s(g_buffer, MAX_RESPONSE_LEN + 1, g_bufferCur, len + 1);
80             *processed = g_buffer + len;
81             g_bufferCur = g_buffer;
82         }
83     }
84     return endLine;
85 }
86 
ReadResponse(int32_t atFd)87 const char *ReadResponse(int32_t atFd)
88 {
89     ssize_t size;
90     char *processed = NULL;
91     char *endEol = NULL;
92     char *ret = NULL;
93     // process last response data
94     endEol = ProcessLastResponse(&processed);
95     while (endEol == NULL) {
96         if (MAX_RESPONSE_LEN == (processed - &g_buffer[0])) {
97             ClearCurBuffer(&processed);
98         }
99         do {
100             size = read(atFd, processed, (MAX_RESPONSE_LEN - (processed - &g_buffer[0])));
101         } while (size < 0 && errno == EINTR);
102         if (size > 0) {
103             processed[size] = '\0';
104             SkipUnUseChar();
105             endEol = FindEndOfLine(g_bufferCur);
106             processed += size;
107         } else if (size == 0) {
108             TELEPHONY_LOGE("atchannel: EOF reached");
109             return NULL;
110         } else {
111             TELEPHONY_LOGE("read error %{public}s", strerror(errno));
112             return NULL;
113         }
114     }
115     *endEol = '\0';
116     ret = g_bufferCur;
117     g_bufferCur = endEol + 1;
118     return ret;
119 }
120 
WriteATCommand(const char * s,int32_t isPdu,int32_t atFd)121 int32_t WriteATCommand(const char *s, int32_t isPdu, int32_t atFd)
122 {
123     if (s == NULL) {
124         return AT_ERR_GENERIC;
125     }
126     ssize_t ret;
127     size_t i = 0;
128     size_t len = strlen(s);
129     if (atFd < 0) {
130         return AT_ERR_CHANNEL_CLOSED;
131     }
132 
133     while (i < len) {
134         do {
135             ret = write(atFd, s + i, len - i);
136         } while (ret < 0 && errno == EINTR);
137 
138         if (ret < 0) {
139             return AT_ERR_GENERIC;
140         }
141         i += ret;
142     }
143     if (isPdu != 0) {
144         do {
145             ret = write(atFd, "\x1A", 1);
146         } while ((ret < 0 && errno == EINTR) || (ret == 0));
147     } else {
148         do {
149             ret = write(atFd, "\r", 1);
150         } while ((ret < 0 && errno == EINTR) || (ret == 0));
151     }
152     if (ret < 0) {
153         return AT_ERR_GENERIC;
154     }
155     return VENDOR_SUCCESS;
156 }
157