• 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  */
15 
16 #include "hi_at.h"
17 
18 #include <at.h>
19 #include <at_cmd.h>
20 #include <hi_stdlib.h>
21 #include <hi_watchdog.h>
22 #include <hi_event.h>
23 #include <hi_lowpower.h>
24 #include <hi_timer.h>
25 #include <hi_cpu.h>
26 #include <sal_inf.h>
27 
28 #include "at_hipriv.h"
29 #include "at_general.h"
30 #include "at_wifi.h"
31 #include "at_io.h"
32 #include "at_lowpower.h"
33 #include "at_printf.h"
34 #include "hi_uart.h"
35 #include "hi_task.h"
36 #include "serial_dw.h"
37 #include "securec.h"
38 #include "unistd.h"
39 
40 #ifdef __cplusplus
41 #if __cplusplus
42 extern "C" {
43 #endif
44 #endif
45 
46 #define CMD_MAX_LEN                 256
47 #define AT_DEFAULT_UART_TASK_SIZE   0x600
48 #define AT_DEFAULT_PROC_TASK_SIZE   0xC00 /* 0x800:softap start would fail. */
49 #define AT_UART_TASK_PRIO           9
50 #define AT_PROC_TASK_PRIO           10
51 #define AT_CMD_HEADER               "AT"
52 #define AT_UART_SLEEP               1000
53 #define AT_DATA_MAX_LEN             1024
54 
55 #define RECV_DATA_NORMAL_CHAR       0
56 #define RECV_DATA_END_CHAR          1
57 #define RECV_DATA_END_CHAR_REPEAT   2
58 
59 #define STAT_NOMAL_KEY              0
60 #define STAT_ESC_KEY                1
61 #define STAT_MULTI_KEY              2
62 
63 /* AT��������busy��������20����ϵͳ��λ */
64 /* If the AT returns the busy message for more than 20 times, system soft reboot. */
65 #define SOFT_REBOOT_MAX_BUSY_CNT    20
66 
67 hi_u32 g_at_event = 0;
68 hi_uart_idx g_at_uart_port = HI_UART_IDX_1;
69 const hi_uart_attribute g_at_uart_cfg  = {115200, 8, 1, 0, 0};
70 static hi_char g_at_buf[CMD_MAX_LEN];
71 hi_char *g_at_data = HI_NULL;
72 
73 hi_at_input_func g_at_input_func  = HI_NULL;
74 static hi_at_output_func g_at_output_func = HI_NULL;
75 
76 hi_u16 g_at_uart_task_size = AT_DEFAULT_UART_TASK_SIZE;
77 hi_u16 g_at_proc_task_size = AT_DEFAULT_PROC_TASK_SIZE;
78 
79 hi_bool g_at_init = HI_FALSE;
80 /* AT��������busy�������� */
81 /* Busy message count */
82 hi_u8 g_busy_count = 0;
83 
hi_at_get_register_output_func(hi_void)84 hi_at_output_func hi_at_get_register_output_func(hi_void)
85 {
86     return g_at_output_func;
87 }
88 
at_monitor_input_func(hi_u8 * data,hi_u32 data_len)89 hi_s32 at_monitor_input_func(hi_u8 *data, hi_u32 data_len)
90 {
91     (hi_void)data;
92     (hi_void)data_len;
93 
94     return 0;
95 }
96 
at_monitor_output_func(const hi_u8 * data,hi_u32 data_len)97 hi_s32 at_monitor_output_func(const hi_u8 *data, hi_u32 data_len)
98 {
99     (hi_void)data;
100     (hi_void)data_len;
101 
102     return 0;
103 }
104 
hi_at_register_input_func(hi_at_input_func at_input_func)105 hi_u32 hi_at_register_input_func(hi_at_input_func at_input_func)
106 {
107     hi_u32 ret = HI_ERR_SUCCESS;
108 
109     hi_task_lock();
110     if (at_input_func != HI_NULL) {
111         hi_bool last_uart_input = HI_FALSE;
112         if (g_at_input_func == HI_NULL && g_at_uart_port != 0xFF) {
113             last_uart_input = HI_TRUE;
114         }
115 
116         g_at_input_func = at_input_func;
117 
118         if (last_uart_input == HI_TRUE) {
119             ret = hi_uart_quit_read(g_at_uart_port);
120             ret |= hi_uart_deinit(g_at_uart_port);
121         }
122     } else {
123         if (g_at_uart_port == 0xFF) {
124             g_at_input_func = at_monitor_input_func;
125         } else {
126             g_at_input_func = HI_NULL;
127             ret = hi_uart_deinit(g_at_uart_port);
128             ret |= hi_uart_init(g_at_uart_port, &g_at_uart_cfg, HI_NULL);
129         }
130     }
131     hi_task_unlock();
132 
133     return ret;
134 }
135 
hi_at_register_output_func(hi_at_output_func at_output_func)136 hi_void hi_at_register_output_func(hi_at_output_func at_output_func)
137 {
138     hi_task_lock();
139     if (at_output_func != HI_NULL) {
140         g_at_output_func = at_output_func;
141     } else {
142         if (g_at_uart_port == 0xFF) {
143             g_at_output_func = at_monitor_output_func;
144         } else {
145             g_at_output_func = HI_NULL;
146         }
147     }
148     hi_task_unlock();
149 
150     return;
151 }
152 
at_get_buf(hi_void)153 hi_char* at_get_buf(hi_void)
154 {
155     hi_char *buf = NULL;
156     hi_u32 buf_len;
157 
158     if (g_at_ctrl.at_state == AT_CMD_PROCESS) {
159         buf_len = strlen(g_at_buf) + 1;
160         buf = hi_malloc(HI_MOD_ID_APP_AT, buf_len);
161         if (buf != NULL) {
162             memset_s(buf, buf_len, 0, buf_len);
163             if (memcpy_s(buf, buf_len, g_at_buf, strlen(g_at_buf)) != EOK) {
164                 hi_at_printf("buf copy fail in %s[%d]", __FUNCTION__, __LINE__);
165                 hi_free(HI_MOD_ID_APP_AT, buf);
166                 buf = NULL;
167             }
168         }
169     } else if (g_at_ctrl.at_state == AT_DATA_SENDING) {
170         buf_len = g_at_ctrl.send_len + 1;
171         buf = hi_malloc(HI_MOD_ID_APP_AT, buf_len);
172         if (buf != NULL) {
173             memset_s(buf, buf_len, 0, buf_len);
174             if (memcpy_s(buf, buf_len, g_at_data, g_at_ctrl.send_len) != EOK) {
175                 hi_at_printf("buf copy fail in %s[%d]", __FUNCTION__, __LINE__);
176                 hi_free(HI_MOD_ID_APP_AT, buf);
177                 buf = NULL;
178             }
179         }
180     }
181     hi_event_send(g_at_event, 0x1000);
182     return buf;
183 }
184 
at_notify(hi_void)185 static hi_void at_notify(hi_void)
186 {
187     hi_u32 event_bit = 0;
188     hi_u32 ret;
189     hi_watchdog_feed();
190     hi_event_send(g_at_event, 0x111);
191     ret = hi_event_wait(g_at_event, 0x1000, &event_bit, HI_SYS_WAIT_FOREVER,
192         HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
193     if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
194         hi_at_printf("wait event timeout");
195     }
196 }
197 
at_put_c(hi_char ch)198 hi_void at_put_c(hi_char ch)
199 {
200     if (g_at_output_func == HI_NULL) {
201         (hi_void)serial_putc_at(ch);
202     } else {
203         g_at_output_func((const hi_u8*)&ch, 1);
204     }
205 }
206 
at_key_filter(hi_char ch,hi_u32 * index,hi_s32 * key_value)207 hi_u32 at_key_filter(hi_char ch, hi_u32 *index, hi_s32 *key_value)
208 {
209     if (ch == '\b') { /* backspace */
210         if (((*index) > 0) && ((*index) < (CMD_MAX_LEN - 1))) {
211             g_at_buf[(*index) - 1] = '\0';
212             (*index)--;
213             at_put_c('\b');
214             at_put_c(' ');
215             at_put_c('\b');
216         }
217         return HI_ERR_FAILURE;
218     } else if (ch == 0x1b) {
219         *key_value = STAT_ESC_KEY;
220         return HI_ERR_FAILURE;
221     } else if (ch == 0x5b) {
222         if (*key_value == STAT_ESC_KEY) {
223             *key_value = STAT_MULTI_KEY;
224             return HI_ERR_FAILURE;
225         }
226     } else if (ch == 0x41) { /* up */
227         if (*key_value == STAT_MULTI_KEY) {
228             *key_value = STAT_NOMAL_KEY;
229             return HI_ERR_FAILURE;
230         }
231     } else if (ch == 0x42) { /* down */
232         if (*key_value == STAT_MULTI_KEY) {
233             *key_value = STAT_NOMAL_KEY;
234             return HI_ERR_FAILURE;
235         }
236     } else if ((ch == 0x43) || (ch == 0x44)) { /* right */
237         if (*key_value == STAT_MULTI_KEY) {
238             *key_value = STAT_NOMAL_KEY;
239             return HI_ERR_FAILURE;
240         }
241     }
242 
243     return HI_ERR_SUCCESS;
244 }
245 
246 
at_cmd_print_back(hi_u32 i,hi_char ch)247 hi_void at_cmd_print_back(hi_u32 i, hi_char ch)
248 {
249     if (i < (CMD_MAX_LEN - 1)) {
250         g_at_buf[i] = ch;
251     } else {
252         g_at_buf[CMD_MAX_LEN - 1] = '\0';
253     }
254 
255     at_put_c(ch);
256 }
257 
at_cmd_line_parse(hi_char c)258 hi_void at_cmd_line_parse(hi_char c)
259 {
260     hi_char ch = c;
261     static hi_u32 i = 0;
262     static hi_s32 key_value = 0;
263     static hi_u32 enter_flag = 0;
264 
265     if ((i == 0) && (ch != '\n')) {
266         (hi_void)memset_s(g_at_buf, CMD_MAX_LEN, 0, CMD_MAX_LEN);
267     }
268 
269     if (ch == '\n') {
270         if (i == 0) {
271             hi_at_printf("\r\nERROR\r\n");
272             g_at_ctrl.at_state = AT_IDLE;
273             return;
274         }
275 
276         if (enter_flag == (i - 1)) {
277             i = 0;
278             g_at_ctrl.at_state = AT_CMD_PROCESS;
279             at_notify();
280         }
281         return;
282     }
283 
284     enter_flag = 0;
285 
286     if (ch == '\r') {
287         if (i == 0) {
288             hi_at_printf("\r\nERROR\r\n");
289             g_at_ctrl.at_state = AT_IDLE;
290             return;
291         }
292         if (i < (CMD_MAX_LEN - 1)) {
293             g_at_buf[i] = '\0';
294         }
295         enter_flag = i;
296         i++;
297         return;
298     }
299 
300     if (at_key_filter(ch, &i, &key_value) != HI_ERR_SUCCESS) {
301         return;
302     }
303 
304     if (ch != '\n') {
305         at_cmd_print_back(i, ch);
306         i++;
307     }
308 
309     key_value = STAT_NOMAL_KEY;
310 }
311 
at_get_send_data(hi_char c)312 hi_void at_get_send_data(hi_char c)
313 {
314     static hi_u16 i = 0;
315 
316     g_at_data[i] = c;
317     if ((g_at_ctrl.is_recv_end_char_flag == RECV_DATA_END_CHAR_REPEAT) && (c == '0')) {
318         g_at_data[i - 2] = g_at_data[i - 1]; /* 2:delete '\' */
319         g_at_data[i - 1] = g_at_data[i];
320         i -= 1;
321     }
322     if ((i >= (g_at_ctrl.send_len - 1)) || (i >= (AT_DATA_MAX_LEN - 1)) ||
323         ((g_at_ctrl.is_recv_end_char_flag == RECV_DATA_END_CHAR) && (c == '0'))) {
324         g_at_ctrl.at_state = AT_DATA_SENDING;
325         g_at_ctrl.is_first_recv_data = HI_TRUE;
326         g_at_ctrl.send_len = i + 1;
327         if ((g_at_ctrl.is_recv_end_char_flag == RECV_DATA_END_CHAR) && c == '0') {
328             g_at_ctrl.is_recv_end_char_flag = RECV_DATA_NORMAL_CHAR;
329             g_at_ctrl.send_len = i - 1;
330         }
331 
332         i = 0;
333         at_notify();
334         hi_free(HI_MOD_ID_APP_AT, g_at_data);
335         g_at_data = HI_NULL;
336     } else {
337         if (c == '\\') {
338             if (g_at_ctrl.is_recv_end_char_flag == RECV_DATA_NORMAL_CHAR) {
339                 g_at_ctrl.is_recv_end_char_flag = RECV_DATA_END_CHAR;
340             } else if (g_at_ctrl.is_recv_end_char_flag == RECV_DATA_END_CHAR) {
341                 g_at_ctrl.is_recv_end_char_flag = RECV_DATA_END_CHAR_REPEAT;
342             }
343         } else {
344             g_at_ctrl.is_recv_end_char_flag = RECV_DATA_NORMAL_CHAR;
345         }
346         i++;
347     }
348 }
349 
at_data_recving(hi_void)350 hi_u32 at_data_recving(hi_void)
351 {
352     if (g_at_ctrl.is_first_recv_data) {
353         g_at_data = hi_malloc(HI_MOD_ID_APP_AT, AT_DATA_MAX_LEN);
354         if (g_at_data == HI_NULL) {
355             printf("Malloc fail!\r\n");
356             return HI_ERR_FAILURE;
357         }
358         memset_s(g_at_data, AT_DATA_MAX_LEN, 0, AT_DATA_MAX_LEN);
359         g_at_ctrl.is_first_recv_data = HI_FALSE;
360     }
361     return HI_ERR_SUCCESS;
362 }
363 
364 hi_u32 g_at_uart_timer_handle;
365 volatile hi_bool g_at_have_uart_data;
366 hi_bool g_at_check_empty = HI_TRUE;
367 
368 #define AT_WAIT_TIME 10000         /* wait 10 seconds */
369 
timer_handle(hi_u32 data)370 static hi_void timer_handle(hi_u32 data)
371 {
372     hi_unref_param(data);
373     g_at_have_uart_data = HI_FALSE;
374 }
375 
hi_at_set_check_uart_busy(hi_bool enable)376 hi_void hi_at_set_check_uart_busy(hi_bool enable)
377 {
378     g_at_check_empty = enable;
379 }
380 
lp_at_uart_vote(hi_void)381 BSP_RAM_TEXT_SECTION hi_u32 lp_at_uart_vote(hi_void)
382 {
383     hi_bool val;
384 
385     if (g_at_check_empty) {
386         if (g_at_have_uart_data) {
387             return HI_NO_SLEEP;
388         }
389         hi_u32 ret = hi_uart_is_busy(g_at_uart_port, &val);
390         if ((ret == HI_ERR_SUCCESS) && (val == HI_TRUE)) {
391             return HI_NO_SLEEP;
392         }
393         val = HI_FALSE;
394         ret = hi_uart_is_buf_empty(g_at_uart_port, &val);
395         if (ret == HI_ERR_SUCCESS && val == HI_FALSE) {
396             return HI_NO_SLEEP;
397         }
398     }
399     return HI_DEEP_SLEEP;
400 }
401 
at_parse_uart_char(hi_char ch)402 hi_void at_parse_uart_char(hi_char ch)
403 {
404     switch (g_at_ctrl.at_state) {
405         case AT_IDLE:
406             g_busy_count = 0;
407             at_cmd_line_parse(ch);
408             break;
409         case AT_CMD_PROCESS:
410             hi_cpup_load_check_proc(hi_task_get_current_id(), LOAD_SLEEP_TIME_DEFAULT);
411 
412             if (ch == '\n') {
413                 if (g_busy_count >= SOFT_REBOOT_MAX_BUSY_CNT) {
414                     g_busy_count = 0;
415                     hi_soft_reboot(HI_SYS_REBOOT_CAUSE_AT_BUSY);
416                 }
417                 hi_at_printf("busy!\r\n");
418                 g_busy_count++;
419             }
420             break;
421         case AT_DATA_RECVING:
422             g_busy_count = 0;
423             if (at_data_recving() != HI_ERR_SUCCESS) {
424                 break;
425             }
426             at_get_send_data(ch);
427             break;
428         case AT_DATA_SENDING:
429             hi_cpup_load_check_proc(hi_task_get_current_id(), LOAD_SLEEP_TIME_DEFAULT);
430             if (g_at_ctrl.is_first_over_data) {
431                 g_at_ctrl.is_first_over_data = HI_FALSE;
432                 hi_at_printf("busy!\r\n");
433             }
434             break;
435         case AT_TRANSPARENT:
436             hi_at_printf("==TBD==\r\n");
437             break;
438         default:
439             break;
440     }
441 }
442 
at_uart_task_body(hi_void * param)443 hi_void *at_uart_task_body(hi_void* param)
444 {
445     hi_unref_param(param);
446     hi_char ch;
447     hi_s32 n;
448     for (;;) {
449         if (g_at_input_func == NULL) {
450             n = hi_uart_read(g_at_uart_port, (hi_u8 *)&ch, 1);
451         } else {
452             n = g_at_input_func((UINT8 *)&ch, 1);
453         }
454         if (n != 1) {
455             (hi_void)hi_sleep(AT_UART_SLEEP);
456             continue;
457         }
458         if ((hi_lpc_get_type() != HI_NO_SLEEP) && (g_at_check_empty == HI_TRUE)) {
459             g_at_have_uart_data = HI_TRUE;
460             hi_timer_start(g_at_uart_timer_handle, HI_TIMER_TYPE_ONCE, AT_WAIT_TIME, timer_handle, 0);
461         }
462 
463         at_parse_uart_char(ch);
464     }
465 }
466 
at_cmd_execute(hi_char * buf)467 hi_void at_cmd_execute(hi_char *buf)
468 {
469     hi_u32 ret;
470     if (memcmp(buf, AT_CMD_HEADER, strlen(AT_CMD_HEADER)) == EOK) {
471         hi_char *at_buf = buf + strlen(AT_CMD_HEADER);
472 
473         ret = at_cmd_process(at_buf);
474         if ((ret != HI_ERR_SUCCESS) && (ret != HI_ERR_RECVING)) {
475             g_at_ctrl.at_state = AT_IDLE;
476         }
477     } else {
478         AT_ENTER;
479         AT_RESPONSE_ERROR;
480         g_at_ctrl.at_state = AT_IDLE;
481     }
482 }
483 
at_proc_task_body(hi_void * param)484 hi_void *at_proc_task_body(hi_void* param)
485 {
486     hi_unref_param(param);
487     hi_u32 ret;
488     hi_u32 event_bit;
489     hi_char   *buf = NULL;
490     for (;;) {
491         if (g_at_ctrl.at_state != AT_DATA_RECVING) {
492             hi_at_printf("\r\n");
493         }
494         event_bit = 0;
495         ret = hi_event_wait(g_at_event, 0xFFF, &event_bit, HI_SYS_WAIT_FOREVER,
496             HI_EVENT_WAITMODE_OR | HI_EVENT_WAITMODE_CLR);
497         if (ret == HI_ERR_EVENT_WAIT_TIME_OUT) {
498             hi_at_printf("get event timeout\r\n");
499             continue;
500         }
501         if (event_bit == 0x111) {
502             buf = at_get_buf();
503             if (buf == NULL) {
504                 g_at_ctrl.at_state = AT_IDLE;
505                 continue;
506             }
507             if (g_at_ctrl.at_state == AT_CMD_PROCESS) {
508                 at_cmd_execute(buf);
509             } else if (g_at_ctrl.at_state == AT_DATA_SENDING) {
510 #ifndef CONFIG_FACTORY_TEST_MODE
511                 at_send_serial_data(buf);
512                 g_at_ctrl.at_state = AT_IDLE;
513                 g_at_ctrl.is_first_over_data = HI_TRUE;
514 #endif
515             }
516             hi_free(HI_MOD_ID_APP_AT, buf);
517         }
518     }
519 }
520 
at_uart_init(hi_void)521 hi_u32 at_uart_init(hi_void)
522 {
523     hi_u32 ret;
524 #ifndef CONFIG_QUICK_SEND_MODE
525     hi_u8 uart_port = 0;
526     ret = sal_uart_port_allocation(UART_FUNC_AT, &uart_port);
527     if (ret != HI_ERR_SUCCESS) {
528         hi_at_printf("Get at uart port fail, use default port.\r\n");
529     }
530 
531     g_at_uart_port = uart_port;
532 #endif
533 
534     if (g_at_uart_port == 0xFF) {
535         if (g_at_input_func == HI_NULL || g_at_output_func == HI_NULL) {
536             g_at_input_func = at_monitor_input_func;
537             g_at_output_func = at_monitor_output_func;
538         }
539         return HI_ERR_SUCCESS;
540     }
541 
542     (hi_void)hi_uart_deinit(g_at_uart_port);
543     ret = hi_uart_init(g_at_uart_port, &g_at_uart_cfg, HI_NULL);
544     if (ret != HI_ERR_SUCCESS) {
545         hi_at_printf("open uart%d failed.\r\n", (hi_u32)g_at_uart_port);
546         return HI_ERR_FAILURE;
547     }
548     if (g_at_uart_port == HI_UART_IDX_0) {
549         g_at_uart_baseaddr = HI_UART0_REG_BASE;
550     } else if (g_at_uart_port == HI_UART_IDX_1) {
551         g_at_uart_baseaddr = HI_UART1_REG_BASE;
552     } else if (g_at_uart_port == HI_UART_IDX_2) {
553         g_at_uart_baseaddr = HI_UART2_REG_BASE;
554     }
555     return HI_ERR_SUCCESS;
556 }
557 
check_name_and_callback(const at_cmd_func_list * ctx,hi_u8 tbl_index,HI_CONST at_cmd_func * cmd_tbl,hi_u16 cmd_num)558 static hi_u32 check_name_and_callback(const at_cmd_func_list *ctx, hi_u8 tbl_index, HI_CONST at_cmd_func *cmd_tbl,
559                                       hi_u16 cmd_num)
560 {
561     hi_u32 ret = HI_ERR_SUCCESS;
562     hi_u16 i;
563     hi_u16 j;
564 
565     for (i = 0; i < ctx->at_cmd_num[tbl_index]; i++) {
566         HI_CONST at_cmd_func *cmd_func = (at_cmd_func *)((ctx->at_cmd_list[tbl_index] + i));
567 
568         for (j = 0; j < cmd_num; j++) {
569             if (((cmd_func->at_cmd_len == cmd_tbl[j].at_cmd_len) &&
570                 (strcmp(cmd_func->at_cmd_name, cmd_tbl[j].at_cmd_name) == 0)) ||
571                 ((cmd_tbl[j].at_test_cmd != HI_NULL) && (cmd_func->at_test_cmd == cmd_tbl[j].at_test_cmd)) ||
572                 ((cmd_tbl[j].at_query_cmd != HI_NULL) && (cmd_func->at_query_cmd == cmd_tbl[j].at_query_cmd)) ||
573                 ((cmd_tbl[j].at_setup_cmd != HI_NULL) && (cmd_func->at_setup_cmd == cmd_tbl[j].at_setup_cmd)) ||
574                 ((cmd_tbl[j].at_exe_cmd != HI_NULL) && (cmd_func->at_exe_cmd == cmd_tbl[j].at_exe_cmd))) {
575                 return HI_ERR_AT_NAME_OR_FUNC_REPEAT_REGISTERED;
576             }
577         }
578     }
579 
580     return ret;
581 }
582 
check_cmd_tbl(HI_CONST at_cmd_func * cmd_tbl,hi_u16 cmd_num)583 static hi_u32 check_cmd_tbl(HI_CONST at_cmd_func *cmd_tbl, hi_u16 cmd_num)
584 {
585     hi_u16 i;
586     hi_u16 j;
587 
588     for (i = 0; i < cmd_num; i++) {
589         if (cmd_tbl[i].at_cmd_len != (hi_s8)strlen(cmd_tbl[i].at_cmd_name)) {
590             return HI_ERR_AT_INVALID_PARAMETER;
591         }
592 
593         for (j = 0; j < cmd_num; j++) {
594             if (i == j) {
595                 continue;
596             }
597 
598             if (((cmd_tbl[j].at_cmd_len == cmd_tbl[i].at_cmd_len) &&
599                 (strcmp(cmd_tbl[j].at_cmd_name, cmd_tbl[i].at_cmd_name) == 0)) ||
600                 ((cmd_tbl[j].at_test_cmd != HI_NULL) && (cmd_tbl[j].at_test_cmd == cmd_tbl[i].at_test_cmd)) ||
601                 ((cmd_tbl[j].at_query_cmd != HI_NULL) && (cmd_tbl[j].at_query_cmd == cmd_tbl[i].at_query_cmd)) ||
602                 ((cmd_tbl[j].at_setup_cmd != HI_NULL) && (cmd_tbl[j].at_setup_cmd == cmd_tbl[i].at_setup_cmd)) ||
603                 ((cmd_tbl[j].at_exe_cmd != HI_NULL) && (cmd_tbl[j].at_exe_cmd == cmd_tbl[i].at_exe_cmd))) {
604                 return HI_ERR_AT_NAME_OR_FUNC_REPEAT_REGISTERED;
605             }
606         }
607     }
608 
609     return HI_ERR_SUCCESS;
610 }
611 
hi_at_register_cmd(HI_CONST at_cmd_func * cmd_tbl,hi_u16 cmd_num)612 hi_u32 hi_at_register_cmd(HI_CONST at_cmd_func *cmd_tbl, hi_u16 cmd_num)
613 {
614     hi_u32 ret = HI_ERR_FAILURE;
615     hi_u8 i;
616 
617     if (cmd_tbl == HI_NULL || cmd_num == 0) {
618         return HI_ERR_FAILURE;
619     }
620 
621     ret = check_cmd_tbl(cmd_tbl, cmd_num);
622     if (ret != HI_ERR_SUCCESS) {
623         return ret;
624     }
625 
626     at_cmd_func_list *cmd_list = at_get_list();
627     for (i = 0; i < AT_CMD_LIST_NUM; i++) {
628         if ((cmd_list->at_cmd_list[i] == HI_NULL) || (cmd_list->at_cmd_num[i] == 0)) {
629             cmd_list->at_cmd_list[i] = cmd_tbl;
630             cmd_list->at_cmd_num[i] = cmd_num;
631             ret = HI_ERR_SUCCESS;
632             break;
633         }
634 
635         ret = check_name_and_callback(cmd_list, i, cmd_tbl, cmd_num);
636         if (ret != HI_ERR_SUCCESS) {
637             break;
638         }
639     }
640 
641     return ret;
642 }
643 
hi_at_sys_cmd_register(hi_void)644 hi_void hi_at_sys_cmd_register(hi_void)
645 {
646     hi_at_general_cmd_register();
647 #ifndef CONFIG_FACTORY_TEST_MODE
648     hi_at_sta_cmd_register();
649     hi_at_softap_cmd_register();
650 #endif
651     hi_at_hipriv_cmd_register();
652 #ifndef CONFIG_FACTORY_TEST_MODE
653 #ifdef LOSCFG_APP_MESH
654     hi_at_mesh_cmd_register();
655 #endif
656     hi_at_lowpower_cmd_register();
657 #endif
658     hi_at_general_factory_test_cmd_register();
659     hi_at_sta_factory_test_cmd_register();
660     hi_at_hipriv_factory_test_cmd_register();
661     hi_at_io_cmd_register();
662 }
663 
hi_at_init(hi_void)664 hi_u32 hi_at_init(hi_void)
665 {
666     hi_u32 ret;
667     hi_u32 at_uart_task, at_proc_task;
668 
669     if (g_at_init == HI_TRUE) {
670         return HI_ERR_SUCCESS;
671     }
672 
673     ret = at_uart_init();
674     if (ret != HI_ERR_SUCCESS) {
675         return ret;
676     }
677     hi_event_create(&g_at_event);
678 
679     hi_task_attr attr = {0};
680 
681     attr.stack_size  = g_at_proc_task_size;
682     attr.task_prio   = AT_PROC_TASK_PRIO;
683     attr.task_name   = (hi_char*)"at_proc";
684     ret = hi_task_create(&at_proc_task, &attr, at_proc_task_body, 0);
685     if (ret != HI_ERR_SUCCESS) {
686         hi_at_printf("AT_PROC_TSK init fail\r\n");
687         return ret;
688     }
689 
690     attr.stack_size  = g_at_uart_task_size;
691     attr.task_prio   = AT_UART_TASK_PRIO;
692     attr.task_name   = (hi_char*)"at_uart";
693     ret = hi_task_create(&at_uart_task, &attr, at_uart_task_body, 0);
694     if (ret != HI_ERR_SUCCESS) {
695         hi_at_printf("AT_UART_TSK init fail\r\n");
696         return ret;
697     }
698     hi_timer_create(&g_at_uart_timer_handle);
699     hi_lpc_register_check_handler((hi_u32_void_callback) lp_at_uart_vote);
700 
701     g_at_init = HI_TRUE;
702 
703     return HI_ERR_SUCCESS;
704 }
705 
hi_at_set_task_size(hi_u16 uart_task_size,hi_u16 process_task_size)706 hi_void hi_at_set_task_size(hi_u16 uart_task_size, hi_u16 process_task_size)
707 {
708     if (uart_task_size < AT_DEFAULT_UART_TASK_SIZE) {
709         g_at_uart_task_size = AT_DEFAULT_UART_TASK_SIZE;
710     } else {
711         g_at_uart_task_size = uart_task_size;
712     }
713 
714     if (process_task_size < AT_DEFAULT_PROC_TASK_SIZE) {
715         g_at_proc_task_size = AT_DEFAULT_PROC_TASK_SIZE;
716     } else {
717         g_at_proc_task_size = process_task_size;
718     }
719 }
720 
721 #ifdef __cplusplus
722 #if __cplusplus
723     }
724 #endif
725 #endif
726