1 /*
2 * Copyright (C) 2021-2022 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 "serial.h"
17 #include <inttypes.h>
18 #include <securec.h>
19 #include <stdlib.h>
20 #include <sys/un.h>
21 #include "common.h"
22
23 #define TMP_CHAR_LEN 64
24
25 const int HIGH_TWO_BIT = 16;
26 const int ALPHA_NUM_MAX = 10;
27
WriteBegin(Context * context,int type)28 int WriteBegin(Context *context, int type)
29 {
30 if (context == NULL) {
31 return -1;
32 }
33
34 char szTmp[TMP_CHAR_LEN] = {0};
35 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%s%c", ((type == 0) ? "N" : "C"), context->cSplit) < 0) {
36 return -1;
37 }
38 int len = strlen(szTmp);
39 return ContextAppendWrite(context, szTmp, len);
40 }
41
WriteFunc(Context * context,const char * funcName)42 int WriteFunc(Context *context, const char *funcName)
43 {
44 if (context == NULL || funcName == NULL) {
45 return -1;
46 }
47
48 int len = (int)strlen(funcName) + 1;
49 if (len <= 0) {
50 return -1;
51 }
52 char *buf = (char *)calloc(len + 1, sizeof(char));
53 if (buf == NULL) {
54 return -1;
55 }
56 if (snprintf_s(buf, len + 1, len, "%s%c", funcName, context->cSplit) < 0) {
57 free(buf);
58 buf = NULL;
59 return -1;
60 }
61 int ret = ContextAppendWrite(context, buf, len);
62 free(buf);
63 buf = NULL;
64 return ret;
65 }
66
WriteInt(Context * context,int iData)67 int WriteInt(Context *context, int iData)
68 {
69 if (context == NULL) {
70 return -1;
71 }
72
73 char szTmp[TMP_CHAR_LEN] = {0};
74 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%d%c", iData, context->cSplit) < 0) {
75 return -1;
76 }
77 return ContextAppendWrite(context, szTmp, strlen(szTmp));
78 }
79
WriteLong(Context * context,long lData)80 int WriteLong(Context *context, long lData)
81 {
82 if (context == NULL) {
83 return -1;
84 }
85
86 char szTmp[TMP_CHAR_LEN] = {0};
87 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%ld%c", lData, context->cSplit) < 0) {
88 return -1;
89 }
90 return ContextAppendWrite(context, szTmp, strlen(szTmp));
91 }
92
WriteInt64(Context * context,int64_t iData)93 int WriteInt64(Context *context, int64_t iData)
94 {
95 if (context == NULL) {
96 return -1;
97 }
98
99 char szTmp[TMP_CHAR_LEN] = {0};
100 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%" PRId64 "%c", iData, context->cSplit) < 0) {
101 return -1;
102 }
103 return ContextAppendWrite(context, szTmp, strlen(szTmp));
104 }
105
WriteDouble(Context * context,double dData)106 int WriteDouble(Context *context, double dData)
107 {
108 if (context == NULL) {
109 return -1;
110 }
111
112 char szTmp[TMP_CHAR_LEN] = {0};
113 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%.6lf%c", dData, context->cSplit) < 0) {
114 return -1;
115 }
116 return ContextAppendWrite(context, szTmp, strlen(szTmp));
117 }
118
WriteChar(Context * context,char cData)119 int WriteChar(Context *context, char cData)
120 {
121 if (context == NULL) {
122 return -1;
123 }
124
125 char szTmp[TMP_CHAR_LEN] = {0};
126 if (snprintf_s(szTmp, sizeof(szTmp), sizeof(szTmp) - 1, "%c%c", cData, context->cSplit) < 0) {
127 return -1;
128 }
129 return ContextAppendWrite(context, szTmp, strlen(szTmp));
130 }
131
WriteStr(Context * context,const char * pStr)132 int WriteStr(Context *context, const char *pStr)
133 {
134 if (context == NULL || pStr == NULL) {
135 return -1;
136 }
137
138 int len = (int)strlen(pStr) + 1;
139 if (len <= 0) {
140 return -1;
141 }
142 char *buf = (char *)calloc(len + 1, sizeof(char));
143 if (buf == NULL) {
144 return -1;
145 }
146 if (snprintf_s(buf, len + 1, len, "%s%c", pStr, context->cSplit) < 0) {
147 free(buf);
148 buf = NULL;
149 return -1;
150 }
151 int ret = ContextAppendWrite(context, buf, len);
152 free(buf);
153 buf = NULL;
154 return ret;
155 }
156
WriteUStr(Context * context,const unsigned char * uStr,unsigned int len)157 int WriteUStr(Context *context, const unsigned char *uStr, unsigned int len)
158 {
159 if (context == NULL || uStr == NULL) {
160 return -1;
161 }
162
163 int inLen = (len << 1) + 1;
164 char *buf = (char *)calloc(inLen + 1, sizeof(char));
165 if (buf == NULL) {
166 return -1;
167 }
168 int pos = 0;
169 for (unsigned int i = 0; i < len; ++i) {
170 pos = (i << 1);
171 if (snprintf_s(buf + pos, inLen - pos, inLen - pos - 1, "%02x", uStr[i]) < 0) {
172 free(buf);
173 buf = NULL;
174 return -1;
175 }
176 }
177 buf[inLen - 1] = context->cSplit;
178 buf[inLen] = 0;
179 int ret = ContextAppendWrite(context, buf, inLen);
180 free(buf);
181 buf = NULL;
182 return ret;
183 }
184
WriteEnd(Context * context)185 int WriteEnd(Context *context)
186 {
187 if (context == NULL) {
188 return -1;
189 }
190
191 return ContextAppendWrite(context, context->cMsgEnd, strlen(context->cMsgEnd));
192 }
193
ReadNext(Context * context)194 static int ReadNext(Context *context)
195 {
196 if (context == NULL) {
197 return -1;
198 }
199
200 if (context->oneProcess == NULL || context->nPos >= context->nSize) {
201 return -1;
202 }
203 char *p = context->oneProcess + context->nPos;
204 char *q = p;
205 while (*p != context->cSplit && *p != '\0') {
206 ++p;
207 }
208 if (*p != context->cSplit) {
209 return -1;
210 }
211 return p - q;
212 }
213
ReadFunc(Context * context,char * funcName,int count)214 int ReadFunc(Context *context, char *funcName, int count)
215 {
216 if (context == NULL) {
217 return -1;
218 }
219
220 int len = ReadNext(context);
221 if (len < 0) {
222 return len;
223 }
224 if (len >= count) {
225 return len;
226 }
227 if (strncpy_s(funcName, count, context->oneProcess + context->nPos, len) != EOK) {
228 return -1;
229 }
230 context->nPos += (uint32_t)(len + 1);
231 return 0;
232 }
233
IsValidNumberChar(const char * szNum,int size)234 static int IsValidNumberChar(const char *szNum, int size)
235 {
236 int dotNum = 0; /* '.' num */
237 for (int i = 0; i < size; ++i) {
238 if (szNum[i] == '.') {
239 ++dotNum;
240 } else if ((szNum[i] < '0' || szNum[i] > '9') && szNum[i] != '+' && szNum[i] != '-') {
241 return -1;
242 }
243 }
244 if (dotNum > 1) {
245 return -1;
246 }
247 return 0;
248 }
249
ReadNextNum(Context * context,char * szNum,int size)250 static int ReadNextNum(Context *context, char *szNum, int size)
251 {
252 if (context == NULL) {
253 return -1;
254 }
255
256 int len = ReadNext(context);
257 if (len < 0) {
258 return len;
259 }
260 if (len >= size) {
261 return SERIAL_READ_TOO_LONG;
262 }
263 if (strncpy_s(szNum, size, context->oneProcess + context->nPos, len) != EOK) {
264 return -1;
265 }
266 if (IsValidNumberChar(szNum, len) != 0) {
267 return SERIAL_READ_INVALID_DIGIT;
268 }
269 return len;
270 }
271
ReadInt(Context * context,int * iData)272 int ReadInt(Context *context, int *iData)
273 {
274 if (context == NULL) {
275 return -1;
276 }
277
278 char szTmp[TMP_CHAR_LEN] = {0};
279 int len = ReadNextNum(context, szTmp, sizeof(szTmp));
280 if (len < 0) {
281 return len;
282 }
283 *iData = atoi(szTmp);
284 context->nPos += (uint32_t)(len + 1);
285 return 0;
286 }
287
ReadLong(Context * context,long * pLong)288 int ReadLong(Context *context, long *pLong)
289 {
290 if (context == NULL || pLong == NULL) {
291 return -1;
292 }
293
294 char szTmp[TMP_CHAR_LEN] = {0};
295 int len = ReadNextNum(context, szTmp, sizeof(szTmp));
296 if (len < 0) {
297 return len;
298 }
299 *pLong = atol(szTmp);
300 context->nPos += (uint32_t)(len + 1);
301 return 0;
302 }
303
ReadInt64(Context * context,int64_t * pInt64)304 int ReadInt64(Context *context, int64_t *pInt64)
305 {
306 if (context == NULL) {
307 return -1;
308 }
309
310 char szTmp[TMP_CHAR_LEN] = {0};
311 int len = ReadNextNum(context, szTmp, sizeof(szTmp));
312 if (len < 0) {
313 return len;
314 }
315 *pInt64 = atoll(szTmp);
316 context->nPos += (uint32_t)(len + 1);
317 return 0;
318 }
319
ReadDouble(Context * context,double * dData)320 int ReadDouble(Context *context, double *dData)
321 {
322 if (context == NULL || dData == NULL) {
323 return -1;
324 }
325
326 char szTmp[TMP_CHAR_LEN] = {0};
327 int len = ReadNextNum(context, szTmp, sizeof(szTmp));
328 if (len < 0) {
329 return len;
330 }
331 *dData = atof(szTmp);
332 context->nPos += (uint32_t)(len + 1);
333 return 0;
334 }
335
ReadChar(Context * context,char * cData)336 int ReadChar(Context *context, char *cData)
337 {
338 if (context == NULL) {
339 return -1;
340 }
341
342 int len = ReadNext(context);
343 if (len < 0) {
344 return len;
345 }
346 if (len != 1) {
347 return SERIAL_READ_TOO_LONG;
348 }
349 *cData = *(context->oneProcess + context->nPos);
350 context->nPos += (uint32_t)(len + 1);
351 return 0;
352 }
353
ReadStr(Context * context,char * str,int count)354 int ReadStr(Context *context, char *str, int count)
355 {
356 if (context == NULL) {
357 return -1;
358 }
359
360 int len = ReadNext(context);
361 if (len < 0) {
362 return len;
363 }
364 if (str == NULL || len >= count) {
365 return len;
366 }
367 if (strncpy_s(str, count, context->oneProcess + context->nPos, len) != EOK) {
368 return -1;
369 }
370 context->nPos += (uint32_t)(len + 1);
371 return 0;
372 }
373
ReadUStr(Context * context,unsigned char * uStr,int count)374 int ReadUStr(Context *context, unsigned char *uStr, int count)
375 {
376 if (context == NULL || uStr == NULL) {
377 return -1;
378 }
379
380 int len = ReadNext(context);
381 if (len < 0) {
382 return len;
383 }
384 if ((len & 1) != 0) { /* format invalid: uStr message len must be an even number */
385 return -1;
386 }
387 if ((len >> 1) >= count) {
388 return (len >> 1);
389 }
390 int i = 0;
391 int j = 0;
392 char *q = context->oneProcess + context->nPos;
393 for (; i < len; ++i) {
394 unsigned char byte = 0;
395 if (q[i] >= '0' && q[i] <= '9') {
396 byte += HIGH_TWO_BIT * (q[i] - '0');
397 } else {
398 byte += HIGH_TWO_BIT * (q[i] - 'a' + ALPHA_NUM_MAX); /* WriteUStr uses lowercase letter, so use 'a' */
399 }
400 ++i;
401 if (q[i] >= '0' && q[i] <= '9') {
402 byte += q[i] - '0';
403 } else {
404 byte += q[i] - 'a' + ALPHA_NUM_MAX;
405 }
406 uStr[j++] = byte;
407 }
408 uStr[j] = 0;
409 context->nPos += (uint32_t)(len + 1);
410 return 0;
411 }
412