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