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 */
15
16 #include <hi_stdlib.h>
17 #include <at.h>
18 #include <at_parse.h>
19 #include "hi_config.h"
20
21 #ifdef __cplusplus
22 #if __cplusplus
23 extern "C" {
24 #endif
25 #endif
26
at_param_shift(const hi_char * cmd_in,hi_char * cmd_out,hi_u32 size)27 hi_u32 at_param_shift(const hi_char *cmd_in, hi_char *cmd_out, hi_u32 size)
28 {
29 hi_char *output = (hi_char *)NULL;
30 hi_char *out_bak = (hi_char *)NULL;
31 hi_u32 len = size;
32 hi_s32 ret;
33
34 if ((cmd_in == NULL) || (cmd_out == NULL)) {
35 at_printf("cmd_in and cmd_out = NULL in %s[%d]", __FUNCTION__, __LINE__);
36 return HI_ERR_FAILURE;
37 }
38
39 output = (hi_char *)hi_malloc(HI_MOD_ID_SAL_DFX, len);
40 if (output == NULL) {
41 at_printf("malloc failure in %s[%d]", __FUNCTION__, __LINE__);
42 return HI_ERR_FAILURE;
43 }
44 /* Backup the 'output' start address */
45 out_bak = output;
46 /* Scan each charactor in 'cmd_in',and squeeze the overmuch space and ignore invaild charactor */
47 for (; *cmd_in != '\0'; cmd_in++) {
48 if ((*cmd_in == '\\') && ((*(cmd_in + 1) == '\"') || (*(cmd_in + 1) == ','))) {
49 continue;
50 }
51 *output = *cmd_in;
52 output++;
53 }
54 *output = '\0';
55 /* Restore the 'pscOutput' start address */
56 output = out_bak;
57 len = strlen(output);
58
59 /* Copy out the buffer which is been operated already */
60 ret = strncpy_s(cmd_out, size, output, len);
61 if (ret != EOK) {
62 at_printf("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
63 hi_free(HI_MOD_ID_SAL_DFX, out_bak);
64 return HI_ERR_FAILURE;
65 }
66 cmd_out[len] = '\0';
67
68 hi_free(HI_MOD_ID_SAL_DFX, out_bak);
69
70 return HI_ERR_SUCCESS;
71 }
72
cmd_parse_para_get(hi_u32 * value,hi_char * para_token_str)73 hi_u32 cmd_parse_para_get(hi_u32 *value, hi_char *para_token_str)
74 {
75 if ((para_token_str == NULL) || (value == NULL)) {
76 return HI_ERR_FAILURE;
77 }
78 hi_u32 ret;
79 hi_u32 value_in_len;
80 hi_char *value_in = HI_NULL;
81
82 value_in_len = strlen(para_token_str) + 1;
83 value_in = (hi_char *)hi_malloc(HI_MOD_ID_SAL_DFX, value_in_len);
84 if (value_in == HI_NULL) {
85 at_printf("%s,%d hi_malloc failed!\n", __FUNCTION__, __LINE__);
86 return HI_ERR_FAILURE;
87 }
88
89 memset_s(value_in, value_in_len, 0, value_in_len);
90
91 ret = (hi_u32)strncpy_s(value_in, value_in_len, para_token_str, strlen(para_token_str));
92 if (ret != EOK) {
93 at_printf("%s,%d strncpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
94 hi_free(HI_MOD_ID_SAL_DFX, value_in);
95 return HI_ERR_FAILURE;
96 }
97
98 ret = at_param_shift(value_in, para_token_str, value_in_len);
99 if (ret != HI_ERR_SUCCESS) {
100 at_printf("%s,%d at_param_shift failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
101 hi_free(HI_MOD_ID_SAL_DFX, value_in);
102 return HI_ERR_FAILURE;
103 }
104 *value = (hi_u32)(uintptr_t)para_token_str;
105
106 hi_free(HI_MOD_ID_SAL_DFX, value_in);
107 return HI_ERR_SUCCESS;
108 }
109
cmd_parse_one_token(at_cmd_attr * cmd_parsed,hi_u32 index,hi_char * token)110 hi_u32 cmd_parse_one_token(at_cmd_attr *cmd_parsed, hi_u32 index, hi_char *token)
111 {
112 hi_u32 ret = HI_ERR_SUCCESS;
113
114 if (cmd_parsed == NULL) {
115 return HI_ERR_FAILURE;
116 }
117
118 if (index == 0) {
119 if (cmd_parsed->at_cmd_type != AT_CMD_TYPE_SETUP) {
120 return ret;
121 }
122 }
123
124 if (index >= AT_CMD_MAX_PARAS) {
125 return HI_ERR_FAILURE;
126 }
127
128 if (token[0] == '\0') {
129 hi_u32 len = cmd_parsed->at_param_cnt;
130 cmd_parsed->param_array[len] = NULL;
131 cmd_parsed->at_param_cnt++;
132 return ret;
133 }
134
135 if (cmd_parsed->at_param_cnt < AT_CMD_MAX_PARAS) {
136 hi_u32 len = cmd_parsed->at_param_cnt;
137 ret = cmd_parse_para_get(&(cmd_parsed->param_array[len]), token);
138 if (ret != HI_ERR_SUCCESS) {
139 return ret;
140 }
141 cmd_parsed->at_param_cnt++;
142 }
143
144 return ret;
145 }
146
at_cmd_token_split(hi_char * cmd,hi_char split,at_cmd_attr * cmd_parsed)147 hi_u32 at_cmd_token_split(hi_char *cmd, hi_char split, at_cmd_attr *cmd_parsed)
148 {
149 enum {
150 STAT_INIT,
151 STAT_TOKEN_IN,
152 STAT_TOKEN_OUT
153 } state = STAT_INIT;
154
155 hi_char *token = NULL;
156 hi_char *p = NULL;
157 hi_u32 count = 0;
158 hi_u32 ret = HI_ERR_SUCCESS;
159
160 if (cmd == NULL) {
161 return HI_ERR_FAILURE;
162 }
163
164 token = cmd;
165
166 for (p = cmd; (*p != '\0') && (ret == HI_ERR_SUCCESS); p++) {
167 if (state == STAT_TOKEN_OUT) {
168 token = p;
169 state = STAT_TOKEN_IN;
170 }
171
172 if (state == STAT_INIT || state == STAT_TOKEN_IN) {
173 if ((*p == split) && (*(p - 1) != '\\')) {
174 *p = '\0';
175 ret = cmd_parse_one_token(cmd_parsed, count++, token);
176 state = STAT_TOKEN_OUT;
177 }
178 }
179 }
180
181 if (*(p - 1) == '\0') {
182 token = p;
183 }
184 if ((ret == HI_ERR_SUCCESS) || (state == STAT_INIT)) {
185 ret = cmd_parse_one_token(cmd_parsed, count, token);
186 }
187
188 return ret;
189 }
190
at_para_parse(hi_char * cmd_line,at_cmd_attr * cmd_parsed)191 hi_u32 at_para_parse(hi_char *cmd_line, at_cmd_attr *cmd_parsed)
192 {
193 if ((cmd_line == NULL) || (cmd_parsed == NULL) || (strlen(cmd_line) == 0)) {
194 return HI_ERR_FAILURE;
195 }
196
197 return at_cmd_token_split(cmd_line, ',', cmd_parsed);
198 }
199
at_cmd_parse(hi_char * cmd_line,at_cmd_attr * cmd_parsed)200 hi_u32 at_cmd_parse(hi_char *cmd_line, at_cmd_attr *cmd_parsed)
201 {
202 hi_u32 ret;
203 if (cmd_line == HI_NULL || cmd_parsed == HI_NULL) {
204 return HI_ERR_FAILURE;
205 }
206
207 cmd_line += cmd_parsed->at_cmd_len;
208 at_printf("at_cmd_parse line %d: cmd_line = %s\n", __LINE__, cmd_line);
209 if (*cmd_line == '\0') {
210 cmd_parsed->at_cmd_type = AT_CMD_TYPE_EXE;
211 } else if (*cmd_line == '?' && (cmd_line[1] == '\0')) {
212 cmd_parsed->at_cmd_type = AT_CMD_TYPE_QUERY;
213 } else if ((*cmd_line == '=') && (cmd_line[1] == '?') && (cmd_line[2] == '\0')) { /* 2: the third character */
214 cmd_parsed->at_cmd_type = AT_CMD_TYPE_TEST;
215 } else if ((*cmd_line == '=') && (cmd_line[1] != '?')) {
216 cmd_parsed->at_cmd_type = AT_CMD_TYPE_SETUP;
217
218 if (cmd_line[1] != '\0') {
219 ret = at_para_parse(cmd_line + 1, cmd_parsed);
220 if (ret != HI_ERR_SUCCESS) {
221 return ret;
222 }
223 }
224 }
225
226 return HI_ERR_SUCCESS;
227 }
228
229 #ifdef __cplusplus
230 #if __cplusplus
231 }
232 #endif
233 #endif