• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  *     http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  */
26 #include "at_utils.h"
27 
28 #include <td_base.h>
29 #include <securec.h>
30 #include <string.h>
31 #include <soc_osal.h>
32 #include <stdarg.h>
33 
34 #include "at.h"
35 
36 #ifdef __cplusplus
37 #if __cplusplus
38 extern "C" {
39 #endif
40 #endif
41 
42 #define EXT_AT_SSID_MAX_LEN 32
43 #define EXT_AT_CUSTOM_PKT_MAX_LEN 2800
44 
at_param_null_check(td_s32 argc,TD_CONST td_char ** argv)45 td_u32 at_param_null_check(td_s32 argc, TD_CONST td_char **argv)
46 {
47     for (td_s32 i = 0; i < argc; i++) {
48         if (argv[i] == TD_NULL) {
49             return EXT_ERR_FAILURE;
50         }
51     }
52     return EXT_ERR_SUCCESS;
53 }
54 
integer_check(TD_CONST td_char * val)55 td_u32 integer_check(TD_CONST td_char *val)
56 {
57     td_u32 len;
58     td_u32 i;
59     td_char *buf = (td_char *)val;
60     if (buf == TD_NULL) {
61         return EXT_ERR_FAILURE;
62     }
63     len = strlen(buf);
64     if ((*buf == '0') && (len != 1)) {
65         return EXT_ERR_FAILURE;
66     }
67     for (i = 0; i < len; i++) {
68         if ((*buf < '0') || (*buf > '9')) {
69             return EXT_ERR_FAILURE;
70         }
71         buf++;
72     }
73     return EXT_ERR_SUCCESS;
74 }
75 
alnum_check(TD_CONST td_char * val)76 td_u32 alnum_check(TD_CONST td_char *val)
77 {
78     td_u32 i;
79     td_u32 len;
80     td_char *buf = (td_char *)val;
81     if (buf == TD_NULL) {
82         return EXT_ERR_FAILURE;
83     }
84     len = strlen(buf);
85     if ((*buf == '0') && (len != 1)) {
86         return EXT_ERR_FAILURE;
87     }
88     for (i = 0; i < len; i++) {
89         if (((*buf >= '0') && (*buf <= '9')) || ((*buf >= 'a') && (*buf <= 'f')) ||
90             ((*buf >= 'A') && (*buf <= 'F'))) {
91             buf++;
92         } else {
93             return EXT_ERR_FAILURE;
94         }
95     }
96     return EXT_ERR_SUCCESS;
97 }
98 
at_check_mac_elem(TD_CONST td_char elem)99 TD_PRV td_u32 at_check_mac_elem(TD_CONST td_char elem)
100 {
101     if (elem >= '0' && elem <= '9') {
102         return EXT_ERR_SUCCESS;
103     } else if (elem >= 'A' && elem <= 'F') {
104         return EXT_ERR_SUCCESS;
105     } else if (elem >= 'a' && elem <= 'f') {
106         return EXT_ERR_SUCCESS;
107     } else if (elem == ':') {
108         return EXT_ERR_SUCCESS;
109     }
110 
111     return EXT_ERR_FAILURE;
112 }
113 
cmd_strtoaddr(TD_CONST td_char * param,td_uchar * mac_addr,td_u32 addr_len)114 td_u32 cmd_strtoaddr(TD_CONST td_char *param, td_uchar *mac_addr, td_u32 addr_len)
115 {
116     td_u32 cnt;
117     td_char *tmp1 = (td_char *)param;
118     td_char *tmp2 = TD_NULL;
119     td_char *tmp3 = TD_NULL;
120 
121     for (cnt = 0; cnt < 17; cnt++) {    /* 17 */
122         if (at_check_mac_elem(param[cnt]) != EXT_ERR_SUCCESS) {
123             return EXT_ERR_FAILURE;
124         }
125     }
126 
127     for (cnt = 0; cnt < (addr_len - 1); cnt++) {
128         tmp2 = (char*)strsep(&tmp1, ":");
129         if (tmp2 == TD_NULL) {
130             return EXT_ERR_AT_INVALID_PARAMETER;
131         }
132         mac_addr[cnt] = (td_uchar)strtoul(tmp2, &tmp3, 16); /* 16 */
133     }
134 
135     if (tmp1 == TD_NULL) {
136         return EXT_ERR_AT_INVALID_PARAMETER;
137     }
138     mac_addr[cnt] = (td_uchar)strtoul(tmp1, &tmp3, 16); /* 16 */
139     return EXT_ERR_SUCCESS;
140 }
141 
at_strrchr(TD_CONST char * src,int c)142 TD_PRV char *at_strrchr(TD_CONST char *src, int c)
143 {
144     return strrchr(src, c);
145 }
146 
at_strlen(TD_CONST char * src)147 TD_PRV td_u32 at_strlen(TD_CONST char *src)
148 {
149     return strlen(src);
150 }
151 
at_dup_binstr(TD_CONST char * src,td_u32 len)152 TD_PRV char *at_dup_binstr(TD_CONST char *src, td_u32 len)
153 {
154     char *res = TD_NULL;
155     int ret;
156 
157     if (src == TD_NULL) {
158         return TD_NULL;
159     }
160     res = osal_kmalloc((td_ulong)(len + 1), OSAL_GFP_KERNEL);
161     if (res == TD_NULL) {
162         return TD_NULL;
163     }
164     ret = memcpy_s(res, len, src, len);
165     if (ret != EOK) {
166         osal_kfree(res);
167         res = TD_NULL;
168         return TD_NULL;
169     }
170     res[len] = '\0';
171 
172     return res;
173 }
174 
at_hex2num(char c)175 TD_PRV int at_hex2num(char c)
176 {
177     if (c >= '0' && c <= '9') {
178         return c - '0';
179     }
180     if (c >= 'a' && c <= 'f') {
181         return c - 'a' + 10;    /* add 10 */
182     }
183     if (c >= 'A' && c <= 'F') {
184         return c - 'A' + 10;    /* add 10 */
185     }
186     return -1;
187 }
188 
at_hex2byte(TD_CONST char * hex)189 TD_PRV int at_hex2byte(TD_CONST char *hex)
190 {
191     int a, b;
192     TD_CONST char *tmp_hex = hex;
193     a = at_hex2num(*tmp_hex++);
194     if (a < 0) {
195         return -1;
196     }
197     b = at_hex2num(*tmp_hex++);
198     if (b < 0) {
199         return -1;
200     }
201     return ((td_u32)a << 4) | (td_u32)b;    /* 4 */
202 }
203 
204 /**
205  * at_hexstr2bin - Convert ASCII hex string into binary data
206  * @hex: ASCII hex string (e.g., "01ab")
207  * @buf: Buffer for the binary data
208  * @len: Length of the text to convert in bytes (of buf); hex will be double
209  * this size
210  * Returns: 0 on success, -1 on failure (invalid hex string)
211  */
at_hexstr2bin(TD_CONST char * hex,td_u8 * buf,td_u32 len)212 TD_PRV int at_hexstr2bin(TD_CONST char *hex, td_u8 *buf, td_u32 len)
213 {
214     td_u32 i;
215     TD_CONST char *ipos = hex;
216     td_u8 *opos = buf;
217 
218     for (i = 0; i < len; i++) {
219         int a = at_hex2byte(ipos);
220         if (a < 0) {
221             return -1;
222         }
223         *opos++ = a;
224         ipos += 2;  /* add 2 */
225     }
226     return 0;
227 }
228 
at_printf_decode_slash(td_u8 * buf,TD_CONST char ** str_pos,td_u32 * str_len)229 TD_PRV td_void at_printf_decode_slash(td_u8 *buf, TD_CONST char **str_pos, td_u32 *str_len)
230 {
231     TD_CONST char *pos = *str_pos;
232     td_u32 len = *str_len;
233     int val;
234 
235     pos++;
236     switch (*pos) {
237         case '\\':
238         case '"':
239             buf[len++] = *pos;
240             pos++;
241             break;
242         case 'n':
243             buf[len++] = '\n';
244             pos++;
245             break;
246         case 'r':
247             buf[len++] = '\r';
248             pos++;
249             break;
250         case 't':
251             buf[len++] = '\t';
252             pos++;
253             break;
254         case 'e':
255             buf[len++] = '\033';
256             pos++;
257             break;
258         case 'x':
259             pos++;
260             val = at_hex2byte(pos);
261             if (val < 0) {
262                 val = at_hex2num(*pos);
263                 if (val < 0) {
264                     break;
265                 }
266                 buf[len++] = val;
267                 pos++;
268             } else {
269                 buf[len++] = val;
270                 pos += 2;   /* add 2 */
271             }
272             break;
273         case '0':
274         case '1':
275         case '2':
276         case '3':
277         case '4':
278         case '5':
279         case '6':
280         case '7':
281             val = *pos++ - '0';
282             if (*pos >= '0' && *pos <= '7') {
283                 val = val * 8 + (*pos++ - '0'); /* 8 */
284             }
285             if (*pos >= '0' && *pos <= '7') {
286                 val = val * 8 + (*pos++ - '0'); /* 8 */
287             }
288             buf[len++] = val;
289             break;
290         default:
291             break;
292     }
293 
294     *str_pos = pos;
295     *str_len = len;
296 }
297 
at_printf_decode(td_u8 * buf,td_u32 maxlen,TD_CONST char * str)298 TD_PRV td_u32 at_printf_decode(td_u8 *buf, td_u32 maxlen, TD_CONST char *str)
299 {
300     TD_CONST char *pos = str;
301     td_u32 len = 0;
302 
303     while (*pos) {
304         if (len + 1 >= maxlen) {
305             break;
306         }
307         switch (*pos) {
308             case '\\':
309                 at_printf_decode_slash(buf, &pos, &len);
310                 break;
311             default:
312                 buf[len++] = *pos++;
313                 break;
314         }
315     }
316     if (maxlen > len) {
317         buf[len] = '\0';
318     }
319 
320     return len;
321 }
322 
at_parse_string_normal(TD_CONST char * value,td_u32 * len)323 TD_PRV char *at_parse_string_normal(TD_CONST char *value, td_u32 *len)
324 {
325     TD_CONST char *pos = TD_NULL;
326     TD_CONST char *src = value;
327     char *str = TD_NULL;
328 
329     src++;
330     pos = at_strrchr(src, '"');
331     if (pos == TD_NULL || pos[1] != '\0') {
332         return TD_NULL;
333     }
334     *len = pos - src;
335     str = at_dup_binstr(src, *len);
336     if (str == TD_NULL) {
337         return TD_NULL;
338     }
339     return str;
340 }
341 
at_parse_string_with_p(TD_CONST char * value,td_u32 * len)342 TD_PRV char *at_parse_string_with_p(TD_CONST char *value, td_u32 *len)
343 {
344     TD_CONST char *pos = TD_NULL;
345     TD_CONST char *src = value;
346     char *tstr = TD_NULL;
347     char *str = TD_NULL;
348     td_u32 tlen;
349 
350     src += 2;     /* add 2 */
351     pos = at_strrchr(src, '"');
352     if (pos == TD_NULL || pos[1] != '\0') {
353         return TD_NULL;
354     }
355     tlen = pos - src;
356     tstr = at_dup_binstr(src, tlen);
357     if (tstr == TD_NULL) {
358         return TD_NULL;
359     }
360 
361     str = osal_kmalloc((td_ulong)(tlen + 1), OSAL_GFP_KERNEL);
362     if (str == TD_NULL) {
363         osal_kfree(tstr);
364         return TD_NULL;
365     }
366 
367     *len = at_printf_decode((td_u8 *)str, tlen + 1, tstr);
368     osal_kfree(tstr);
369     return str;
370 }
371 
at_parse_string_other(TD_CONST char * value,td_u32 * len)372 TD_PRV char *at_parse_string_other(TD_CONST char *value, td_u32 *len)
373 {
374     td_u8 *str = TD_NULL;
375     td_u32 tlen;
376     td_u32 hlen = at_strlen(value);
377     if (hlen & 1) {
378         return TD_NULL;
379     }
380     tlen = hlen / 2;    /* 2 */
381     str = osal_kmalloc((td_ulong)(tlen + 1), OSAL_GFP_KERNEL);
382     if (str == TD_NULL) {
383         return TD_NULL;
384     }
385     if (at_hexstr2bin(value, str, tlen)) {
386         osal_kfree((char*)str);
387         return TD_NULL;
388     }
389     str[tlen] = '\0';
390     *len = tlen;
391     return (char *)str;
392 }
393 
at_parse_string(TD_CONST char * value,td_u32 * len)394 char *at_parse_string(TD_CONST char *value, td_u32 *len)
395 {
396     if (len == TD_NULL) {
397         return TD_NULL;
398     }
399     if (*value == '"') {
400         return at_parse_string_normal(value, len);
401     } else if (*value == 'P' && value[1] == '"') {
402         return at_parse_string_with_p(value, len);
403     } else {
404         return at_parse_string_other(value, len);
405     }
406 }
407 
convert_bin_to_dec(td_s32 pbin)408 td_s32 convert_bin_to_dec(td_s32 pbin)
409 {
410     td_s32 result = 0;
411 
412     while (pbin)
413     {
414       result += pbin % 2;
415       pbin /= 2;
416     }
417 
418     return result;
419 }
420 
421 /*****************************************************************************
422  函 数 名  : at_str_to_hex
423  功能描述  : 字符串转16进制
424 *****************************************************************************/
at_str_to_hex(TD_CONST td_char * param,td_u32 len,unsigned char * value)425 td_void at_str_to_hex(TD_CONST td_char *param, td_u32 len, unsigned char *value)
426 {
427     td_u16 index;
428     if (param == TD_NULL || len > EXT_AT_CUSTOM_PKT_MAX_LEN) {
429         return;
430     }
431     for (index = 0; index < len; index++) {
432         /* 每2位字符转为一个十六进制,第一位乘以16 */
433         value[index / 2] = (unsigned char)(value[index / 2] * 16 * (index % 2) + at_hex2num(*param));
434         param++;
435     }
436 }
437 
438 #ifdef __cplusplus
439 #if __cplusplus
440     }
441 #endif
442 #endif
443