1 /*
2  * Copyright 2022-2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "nxp_wifi.h"
8 
9 #if CONFIG_WIFI_SHELL
10 #include <zephyr/kernel.h>
11 #include <zephyr/shell/shell.h>
12 
13 #include "wifi_shell.h"
14 #include <wlan.h>
15 #include <wifi.h>
16 
17 static struct
18 {
19     const struct cli_command *commands[MAX_COMMANDS];
20     unsigned int num_commands;
21 } cli;
22 
cli_register_command(const struct cli_command * command)23 int cli_register_command(const struct cli_command *command)
24 {
25     unsigned int i;
26     if (command->name == NULL || command->function == NULL)
27     {
28         return 1;
29     }
30 
31     if (cli.num_commands < MAX_COMMANDS)
32     {
33         /* Check if the command has already been registered.
34          * Return 0, if it has been registered.
35          */
36         for (i = 0; i < cli.num_commands; i++)
37         {
38             if (cli.commands[i] == command)
39             {
40                 return 0;
41             }
42         }
43         cli.commands[cli.num_commands++] = command;
44         return 0;
45     }
46 
47     return 1;
48 }
49 
cli_unregister_command(const struct cli_command * command)50 int cli_unregister_command(const struct cli_command *command)
51 {
52     unsigned int i = 0;
53     if (command->name == NULL || command->function == NULL)
54     {
55         return 1;
56     }
57 
58     while (i < cli.num_commands)
59     {
60         if (cli.commands[i] == command)
61         {
62             cli.num_commands--;
63             unsigned int remaining_cmds = cli.num_commands - i;
64             if (remaining_cmds > 0U)
65             {
66                 (void)memmove(&cli.commands[i], &cli.commands[i + 1U], (remaining_cmds * sizeof(struct cli_command *)));
67             }
68             cli.commands[cli.num_commands] = NULL;
69             return 0;
70         }
71         i++;
72     }
73 
74     return 1;
75 }
76 
cli_register_commands(const struct cli_command * commands,int num_commands)77 int cli_register_commands(const struct cli_command *commands, int num_commands)
78 {
79     int i;
80     for (i = 0; i < num_commands; i++)
81     {
82         if (cli_register_command(commands++) != 0)
83         {
84             return 1;
85         }
86     }
87     return 0;
88 }
89 
cli_unregister_commands(const struct cli_command * commands,int num_commands)90 int cli_unregister_commands(const struct cli_command *commands, int num_commands)
91 {
92     int i;
93     for (i = 0; i < num_commands; i++)
94     {
95         if (cli_unregister_command(commands++) != 0)
96         {
97             return 1;
98         }
99     }
100 
101     return 0;
102 }
103 
lookup_command(char * name,int len)104 static const struct cli_command *lookup_command(char *name, int len)
105 {
106     unsigned int i = 0;
107     unsigned int n = 0;
108 
109     while (i < MAX_COMMANDS && n < cli.num_commands)
110     {
111         if (cli.commands[i]->name == NULL)
112         {
113             i++;
114             continue;
115         }
116         /* See if partial or full match is expected */
117         if (len != 0)
118         {
119             if (strncmp(cli.commands[i]->name, name, (size_t)len) == 0)
120             {
121                 return cli.commands[i];
122             }
123         }
124         else
125         {
126             if (strcmp(cli.commands[i]->name, name) == 0)
127             {
128                 return cli.commands[i];
129             }
130         }
131 
132         i++;
133         n++;
134     }
135 
136     return NULL;
137 }
138 
139 /* prints all registered commands and their help text string, if any. */
help_command(int argc,char ** argv)140 void help_command(int argc, char **argv)
141 {
142     unsigned int i = 0, n = 0;
143 
144     while (i < MAX_COMMANDS && n < cli.num_commands)
145     {
146         if (cli.commands[i]->name != NULL)
147         {
148             (void)PRINTF("%s %s\r\n", (char *)cli.commands[i]->name + 5,
149                          cli.commands[i]->help != NULL ? cli.commands[i]->help : "");
150             n++;
151         }
152         i++;
153     }
154 }
155 
156 static char nxp_wifi_cmd_name[32];
157 
158 /**
159  *  wlan shell entry
160  *  syntax: wlansh wlan-add ...
161  */
nxp_wifi_request(size_t argc,char ** argv)162 int nxp_wifi_request(size_t argc, char **argv)
163 {
164     const struct cli_command *command = NULL;
165 
166     if (argc < 2)
167     {
168         (void)PRINTF("nxp_wifi command too few arguments\r\n");
169         return -1;
170     }
171 
172     /* cmd name should be less than buff size */
173     if (strlen(argv[1]) >= sizeof(nxp_wifi_cmd_name) - strlen("wlan-"))
174     {
175         (void)PRINTF("nxp_wifi command name too long\r\n");
176         return -1;
177     }
178 
179     if (strcmp(argv[1], "help") == 0)
180     {
181         help_command(argc, argv);
182         return 0;
183     }
184 
185     strcpy(nxp_wifi_cmd_name, "wlan-");
186     strcat(nxp_wifi_cmd_name, argv[1]);
187 
188     command = lookup_command(nxp_wifi_cmd_name, strlen(nxp_wifi_cmd_name));
189     if (command != NULL)
190     {
191         command->function(argc - 1, &argv[1]);
192         (void)PRINTF("Command %s\r\n", command->name);
193     }
194     else
195     {
196         (void)PRINTF("Unknown comamnd %s\r\n", argv[1]);
197     }
198 
199     return 0;
200 }
201 #endif
202