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 <stdint.h>
17 #include <stdbool.h>
18 #include <string.h>
19 #include <strings.h>
20 #include "common_def.h"
21 #include "ctype.h"
22 #include "securec.h"
23 #include "timer.h"
24 #ifdef CONFIG_TESTSUITE_SUPPORT_MULTI_CORE
25 #include "ipc.h"
26 #include "debug_print.h"
27 #include "osal_addr.h"
28 #endif
29 #include "test_suite_ipc.h"
30 #include "test_suite_errors.h"
31 #include "test_suite.h"
32 #include "test_suite_functions_processor.h"
33 #include "test_suite_log.h"
34 #include "test_suite_console.h"
35 #include "test_suite_commands_processor.h"
36
37 #define TEST_SUITE_COMMANDS_ARGUMENT_SIZE 16
38 #define TEST_SUITE_DEFAULT_TIMEOUT 15
39 #define TEST_SUITE_COMMAND_SEPARATOR "#\0"
40 #define TEST_SUITE_TIMEOUT_BASE 10
41
42 #define APPS_SHORT_PREFIX "a"
43 #define APPS_PREFIX "apps"
44 #define BT_SHORT_PREFIX "b"
45 #define BT_PREFIX "bt"
46
test_suite_commands_timeout_callback(uintptr_t data)47 void test_suite_commands_timeout_callback(uintptr_t data)
48 {
49 if (data != 0) {
50 (void) uapi_timer_delete((timer_handle_t)data);
51 }
52
53 test_suite_console_set_color(TERM_COLOR_RED);
54 test_suite_log_string("\r\n[TEST_FAILED : TIMED_OUT]");
55 test_suite_console_set_color(TERM_COLOR_WHITE);
56 #ifdef CONFIG_TESTSUITE_SUPPORT_MULTI_CORE
57 test_suite_ipc_clear_core_flag();
58 #endif
59 }
60
test_suite_commands_unknown_command_reply(void)61 static void test_suite_commands_unknown_command_reply(void)
62 {
63 test_suite_log_set_test_result(TEST_SUITE_UNKNOWN_FUNCTION);
64 test_suite_log_line("this is not a known command, try \"?\"");
65 }
66
test_suite_commands_unrecognized_reply(void)67 static void test_suite_commands_unrecognized_reply(void)
68 {
69 test_suite_log_set_test_result(TEST_SUITE_UNKNOWN_FUNCTION);
70 test_suite_log_line("Command separator or terminator not recognized, try \"?\"");
71 }
72
test_suite_cmd_argument_get(char * argument,const char * string,char split_char)73 static uint8_t test_suite_cmd_argument_get(char *argument, const char *string, char split_char)
74 {
75 uint8_t i = 0;
76 uint16_t index = 0;
77 while (string[index] != 0) {
78 if (string[index] == split_char || (i == TEST_SUITE_COMMANDS_ARGUMENT_SIZE - 1)) {
79 break; /* we have found the first element */
80 }
81 argument[index] = string[index];
82 i++;
83 index++;
84 }
85 argument[index] = '\0';
86 return i;
87 }
88
test_suite_commands_execute_in_this_core(char * command,uint32_t timeout)89 static void test_suite_commands_execute_in_this_core(char *command, uint32_t timeout)
90 {
91 static timer_handle_t timer = 0;
92 if (timeout != 0) {
93 uapi_timer_create(DEFAULT_TIMER, &timer);
94 uapi_timer_start(timer, timeout * TEST_SUITE_TIMER_S_TO_US, test_suite_commands_timeout_callback, 0);
95 }
96 test_suite_function_execute_command(command);
97 if (timeout != 0) {
98 uapi_timer_stop(timer);
99 uapi_timer_delete(timer);
100 }
101 }
102
103 /*
104 * -- Public function definitions
105 */
test_suite_commands_process_cmd(char * command,char * first_argument,uint32_t timeout)106 static void test_suite_commands_process_cmd(char *command, char *first_argument, uint32_t timeout)
107 {
108 if ((strcasecmp(first_argument, APPS_PREFIX) == 0) || (strcasecmp(first_argument, APPS_SHORT_PREFIX) == 0)) {
109 test_suite_commands_execute_in_this_core(command, timeout);
110 #ifdef CONFIG_TESTSUITE_SUPPORT_MULTI_CORE
111 } else if ((strcasecmp(first_argument, BT_PREFIX) == 0) || (strcasecmp(first_argument, BT_SHORT_PREFIX) == 0)) {
112 test_suite_commands_execute_in_external_core(CORES_BT_CORE, command, timeout);
113 #endif
114 } else if ((strcasecmp("help", first_argument) == 0) || (strcasecmp("?", first_argument) == 0)) {
115 test_suite_function_list_func();
116 #ifdef CONFIG_TESTSUITE_SUPPORT_MULTI_CORE
117 test_suite_commands_execute_in_external_core(CORES_BT_CORE, "list_functions", timeout);
118 #endif
119 } else {
120 /* any of the previous ones. Default reply. */
121 test_suite_commands_unknown_command_reply();
122 }
123 }
124
test_suite_utils_is_numeric(char * s)125 static bool test_suite_utils_is_numeric(char *s)
126 {
127 bool numeric = true;
128 char *string = s;
129
130 if (*string == 0) {
131 return false;
132 }
133
134 while (*string != 0) {
135 if (!isdigit((int32_t)*string)) {
136 numeric = false;
137 break;
138 }
139 string++;
140 }
141 return numeric;
142 }
143
test_suite_commands_prase(char * commands)144 void test_suite_commands_prase(char *commands)
145 {
146 char first_argument[TEST_SUITE_COMMANDS_ARGUMENT_SIZE] = { 0 };
147 char second_argument[TEST_SUITE_COMMANDS_ARGUMENT_SIZE] = { 0 };
148 uint8_t argument_length;
149 uint32_t timeout = TEST_SUITE_DEFAULT_TIMEOUT;
150 char *cmd_sep = TEST_SUITE_COMMAND_SEPARATOR;
151 char *current_cmd;
152 char *remain_cmd;
153
154 current_cmd = strtok_s(commands, cmd_sep, &remain_cmd);
155 if (current_cmd == NULL) {
156 test_suite_commands_unrecognized_reply();
157 return;
158 }
159 while (current_cmd != NULL) {
160 /* Get the first argument */
161 argument_length = test_suite_cmd_argument_get(first_argument, current_cmd, ' ');
162 /* if it is empty just return */
163 if (argument_length == 0) {
164 return; /* EARLY RETURN */
165 }
166
167 if ((uint8_t)strlen(current_cmd) >= argument_length + 1) {
168 current_cmd += argument_length + 1;
169 argument_length = test_suite_cmd_argument_get(second_argument, current_cmd, ' ');
170 if (argument_length == 0) {
171 return; /* EARLY RETURN */
172 }
173 }
174
175 if (test_suite_utils_is_numeric((char *)second_argument)) {
176 timeout = (uint32_t)strtol(second_argument, NULL, TEST_SUITE_TIMEOUT_BASE);
177 current_cmd += argument_length + 1;
178 }
179
180 test_suite_commands_process_cmd(current_cmd, (char *)first_argument, timeout);
181 current_cmd = strtok_s(remain_cmd, cmd_sep, &remain_cmd);
182 }
183 }
184