• 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. \n
14  *
15  * Description: Provides AT command source \n
16  */
17 
18 #include "at_base.h"
19 #include "at_cmd.h"
20 
21 typedef struct at_cmd_list_t {
22     const at_cmd_entry_t  *table;
23     uint32_t              len;
24     struct at_cmd_list_t  *next;
25 } at_cmd_list_t;
26 
27 at_cmd_list_t *g_at_cmd_list = NULL;
28 uint32_t g_at_cmd_struct_max_size = 0;
29 
at_cmd_get_entry_total(void)30 uint32_t at_cmd_get_entry_total(void)
31 {
32     uint32_t nr_size = 0;
33     at_cmd_list_t *list = g_at_cmd_list;
34 
35     if (list == NULL) {
36         return 0;
37     }
38 
39     while (list != NULL) {
40         for (uint32_t index = 0; index < list->len; index++) {
41             nr_size++;
42         }
43         list = list->next;
44     }
45     return nr_size;
46 }
47 
at_cmd_get_all_entrys(const at_cmd_entry_t ** entrys,uint32_t cnt)48 uint32_t at_cmd_get_all_entrys(const at_cmd_entry_t **entrys, uint32_t cnt)
49 {
50     uint32_t total = 0;
51     at_cmd_list_t *list = g_at_cmd_list;
52 
53     if (list == NULL) {
54         return 0;
55     }
56 
57     while (list != NULL) {
58         for (uint32_t index = 0; index < list->len; index++) {
59             entrys[total] = &list->table[index];
60             total++;
61             if (total > cnt) {
62                 return total;
63             }
64         }
65         list = list->next;
66     }
67     return total;
68 }
69 
at_cmd_table_add(const at_cmd_entry_t * table,uint32_t length)70 static errcode_t at_cmd_table_add(const at_cmd_entry_t *table, uint32_t length)
71 {
72     at_cmd_list_t *tail = g_at_cmd_list;
73     at_cmd_list_t *new_node = at_malloc(sizeof(at_cmd_list_t));
74     if (new_node == NULL) {
75         return ERRCODE_MALLOC;
76     }
77     new_node->table = table;
78     new_node->len = length;
79     new_node->next = NULL;
80 
81     if (tail == NULL) {
82         g_at_cmd_list = new_node;
83         return ERRCODE_SUCC;
84     }
85 
86     while (tail->next != NULL) {
87         tail = tail->next;
88     }
89     tail->next = new_node;
90 
91     return ERRCODE_SUCC;
92 }
93 
at_cmd_get_name_length(const char * str)94 static uint16_t at_cmd_get_name_length(const char* str)
95 {
96     uint16_t len = 0;
97     const char* ch = str;
98 
99     while ((*ch >= 'A' && *ch <= 'Z') ||
100            (*ch >= 'a' && *ch <= 'z') ||
101            (*ch >= '0' && *ch <= '9')) {
102         len++;
103         ch++;
104     }
105 
106     return len;
107 }
108 
at_cmd_find_entry(char * str,uint16_t * offset)109 const at_cmd_entry_t* at_cmd_find_entry(char *str, uint16_t *offset)
110 {
111     at_cmd_list_t *list = g_at_cmd_list;
112     if (list == NULL || str == NULL) {
113         return NULL;
114     }
115 
116     char *name = str + *offset;
117     uint16_t name_len = at_cmd_get_name_length(name);
118     at_base_toupper(name, name_len);
119     while (list != NULL) {
120         for (uint32_t index = 0; index < list->len; index++) {
121             if (list->table[index].name == NULL) { return NULL; }
122             if ((strncmp(list->table[index].name, name, name_len) == 0) &&
123                 (name_len == strlen(list->table[index].name))) {
124                 *offset = *offset + name_len;
125                 return &list->table[index];
126             }
127         }
128         list = list->next;
129     }
130     return NULL;
131 }
132 
133 #ifdef CONFIG_AT_SUPPORT_CMD_TABLE_CHECK
at_cmd_find_entry_by_name(const char * name)134 const at_cmd_entry_t* at_cmd_find_entry_by_name(const char *name)
135 {
136     at_cmd_list_t *list = g_at_cmd_list;
137     if (list == NULL) {
138         return NULL;
139     }
140 
141     while (list != NULL) {
142         for (uint32_t index = 0; index < list->len; index++) {
143             if (strcmp((char*)list->table[index].name, name) == 0) {
144                 return &list->table[index];
145             }
146         }
147         list = list->next;
148     }
149     return NULL;
150 }
151 
at_cmd_entry_name_check(const char * name)152 static errcode_t at_cmd_entry_name_check(const char *name)
153 {
154     uint16_t name_len = (uint16_t)strlen(name);
155     if (name_len > AT_CMD_NAME_MAX_LENGTH) {
156         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
157     }
158 
159     for (uint16_t index = 0; index < name_len; index++) {
160         if (name[index] < 'A' || name[index] > 'Z') {
161             return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
162         }
163     }
164     return ERRCODE_SUCC;
165 }
166 
at_cmd_entry_syntax_int_check(const at_para_parse_syntax_t * syntax)167 static errcode_t at_cmd_entry_syntax_int_check(const at_para_parse_syntax_t *syntax)
168 {
169     if (((syntax->attribute & (AT_SYNTAX_ATTR_AT_MIN_VALUE | AT_SYNTAX_ATTR_AT_MAX_VALUE)) != 0) &&
170         ((syntax->attribute & AT_SYNTAX_ATTR_LIST_VALUE) != 0)) {
171         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
172     }
173     return ERRCODE_SUCC;
174 }
175 
at_cmd_entry_syntax_string_check(const at_para_parse_syntax_t * syntax)176 static errcode_t at_cmd_entry_syntax_string_check(const at_para_parse_syntax_t *syntax)
177 {
178     if (((syntax->attribute & AT_SYNTAX_ATTR_MAX_LENGTH) != 0) &&
179         ((syntax->attribute & AT_SYNTAX_ATTR_LIST_VALUE) != 0)) {
180         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
181     }
182     return ERRCODE_SUCC;
183 }
184 
at_cmd_entry_syntax_bit_string_check(const at_para_parse_syntax_t * syntax)185 static errcode_t at_cmd_entry_syntax_bit_string_check(const at_para_parse_syntax_t *syntax)
186 {
187     if (((syntax->attribute & AT_SYNTAX_ATTR_AT_MAX_VALUE) != 0) &&
188         ((syntax->attribute & AT_SYNTAX_ATTR_LIST_VALUE) != 0)) {
189         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
190     }
191     return ERRCODE_SUCC;
192 }
193 
at_cmd_entry_syntax_check(const at_para_parse_syntax_t * syntax)194 static errcode_t at_cmd_entry_syntax_check(const at_para_parse_syntax_t *syntax)
195 {
196     errcode_t err_ret = ERRCODE_SUCC;
197     switch (syntax->type) {
198         case AT_SYNTAX_TYPE_INT:
199             err_ret = at_cmd_entry_syntax_int_check(syntax);
200             break;
201         case AT_SYNTAX_TYPE_STRING:
202             err_ret = at_cmd_entry_syntax_string_check(syntax);
203             break;
204         case AT_SYNTAX_TYPE_BIT_STRING:
205             err_ret = at_cmd_entry_syntax_bit_string_check(syntax);
206             break;
207         default:
208             break;
209     }
210     return err_ret;
211 }
212 
at_cmd_entry_syntax_table_check(const at_para_parse_syntax_t * syntax)213 static errcode_t at_cmd_entry_syntax_table_check(const at_para_parse_syntax_t *syntax)
214 {
215     errcode_t err_ret;
216     if (syntax == NULL) {
217         return ERRCODE_SUCC;
218     }
219 
220     for (uint16_t index = 0; index < AT_PARA_MAX_NUM; index++) {
221         err_ret = at_cmd_entry_syntax_check(&syntax[index]);
222         if (err_ret != ERRCODE_SUCC) {
223             return err_ret;
224         }
225         if (syntax[index].last == true) {
226             break;
227         }
228     }
229 
230     return ERRCODE_SUCC;
231 }
232 
at_cmd_entry_table_check(const at_cmd_entry_t * table)233 static errcode_t at_cmd_entry_table_check(const at_cmd_entry_t *table)
234 {
235     if (table->cmd == NULL &&
236         table->set == NULL &&
237         table->read == NULL &&
238 #ifdef CONFIG_AT_SUPPORT_QUERY
239         table->query == NULL &&
240 #endif
241         table->test == NULL) {
242         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
243     }
244 
245     if (table->set != NULL && table->syntax == NULL) {
246         return ERRCODE_AT_CMD_TABLE_PARA_ERROR;
247     }
248 
249     return ERRCODE_SUCC;
250 }
251 
at_cmd_entry_check(const at_cmd_entry_t * table)252 static errcode_t at_cmd_entry_check(const at_cmd_entry_t *table)
253 {
254     errcode_t err_ret;
255     err_ret = at_cmd_entry_table_check(table);
256     if (err_ret != ERRCODE_SUCC) {
257         return err_ret;
258     }
259 
260     err_ret = at_cmd_entry_name_check(table->name);
261     if (err_ret != ERRCODE_SUCC) {
262         return err_ret;
263     }
264 
265     err_ret = at_cmd_entry_syntax_table_check(table->syntax);
266     if (err_ret != ERRCODE_SUCC) {
267         return err_ret;
268     }
269     return ERRCODE_SUCC;
270 }
271 
at_cmd_table_check(const at_cmd_entry_t * table,uint32_t length)272 static errcode_t at_cmd_table_check(const at_cmd_entry_t *table, uint32_t length)
273 {
274     errcode_t ret = ERRCODE_SUCC;
275     for (uint32_t index = 0; index < length; index++) {
276         if (at_cmd_find_entry_by_name(table[index].name) != NULL) {
277             return ERRCODE_AT_CMD_REPEAT;
278         }
279 
280         ret = at_cmd_entry_check(&table[index]);
281         if (ret != ERRCODE_SUCC) {
282             return ret;
283         }
284     }
285     return ERRCODE_SUCC;
286 }
287 #endif
288 
at_cmd_get_max_struct_size(void)289 uint32_t at_cmd_get_max_struct_size(void)
290 {
291     return g_at_cmd_struct_max_size;
292 }
293 
uapi_at_cmd_table_register(const at_cmd_entry_t * table,uint32_t len,uint32_t struct_max_size)294 errcode_t uapi_at_cmd_table_register(const at_cmd_entry_t *table, uint32_t len,
295                                      uint32_t struct_max_size)
296 {
297     errcode_t ret;
298     if (table == NULL || len == 0) {
299         return ERRCODE_INVALID_PARAM;
300     }
301 #ifdef CONFIG_AT_SUPPORT_CMD_TABLE_CHECK
302     ret = at_cmd_table_check(table, len);
303     if (ret != ERRCODE_SUCC) {
304         return ret;
305     }
306 #endif
307     ret = at_cmd_table_add(table, len);
308     if ((ret == ERRCODE_SUCC) && (g_at_cmd_struct_max_size < struct_max_size)) {
309         g_at_cmd_struct_max_size = struct_max_size;
310     }
311     return ret;
312 }
313