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