Add wpa_supplicant_fork command on RTEMS-libbsd

After port the WPA on RTEMS-libbsd. We can use wpa_supplicant in RTEMS shell, but there is a bug, but when config WPA via "wpa_supplicant", we can't use shell command and other thread.
So we need create a command (such as wpa_supplicant_forking) to start wpa_supplicant in a new thread.




1. Add wpa_supplicant_fork command file which define the wpa_supplicant_fork command struct.


rtems-bsd-shell-wpa_supplicant_fork.c

+/*
+ * Copyright (c) 2017 Sichen Zhao.  All rights reserved.
+ *
+ *  <zsc19940506@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <rtems/netcmds-config.h>
+#include <machine/rtems-bsd-commands.h>
+
+rtems_shell_cmd_t rtems_shell_WPA_SUPPLICANT_FORK_Command = {
+  .name = "wpa_supplicant_fork",
+  .usage = "wpa_supplicant_fork [args]",
+  .topic = "net",
+  .command = rtems_bsd_command_wpa_supplicant_fork
+};

We can see from this file that the command function is rtems_bsd_command_wpa_supplicant_fork.
It is define in wpa supplicant main.c





2. Add rtems_bsd_command_wpa_supplicant_fork function in wpa supplicant main.c


We need create a new task to start the wpa supplicant, so in the rtems_bsd_command_wpa_supplicant_fork function, we need add the task create function:


+int rtems_bsd_command_wpa_supplicant_fork(int argc, char **argv)
+{
+    rtems_status_code sc;
+ rtems_id id;
+    int i;
+
+    struct myparams *params = malloc(sizeof(struct myparams));
+    if (params == NULL)
+ return NULL;
+
+ params->argc = argc;
+ params->argv = malloc((argc + 1) * sizeof(argv[0]));
+ if (params->argv == NULL)
+ return NULL;
+
+ for (i = 0; i < argc; i++) {
+ params->argv[i] = strdup(argv[i]);
+ if (params->argv[i] == NULL)
+ return NULL;
+ }
+    params->argv[argc] = NULL;
+
+ sc = rtems_task_create(
+ rtems_build_name('W', 'P', 'A', 'S'),
+ RTEMS_MAXIMUM_PRIORITY - 1,
+ 8 * RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &id
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+    sc = rtems_task_start(id, new_wpa_supplicant_task, params);
+ assert(sc == RTEMS_SUCCESSFUL);
+}

We create a new task via rtems_task_create function, and the stack size is 8 * RTEMS_MINIMUM_STACK_SIZE, this size is very important, for the reason of the scan ssid table is large. We need a large space to store it.
And then start the task via rtems_task_start function, and the 3rd params of this function is the argv of this command, so we need pack argv and argc as one struct, in my case, i create a struct named myparams:


+struct myparams {
+   int argc;
+   char ** argv;
+};

In the rtems_bsd_command_wpa_supplicant_fork function, i use this struct struct:

myparams *params = malloc(sizeof(struct myparams));

Then i pack argc and argv in this struct:

+ params->argc = argc;
+ params->argv = malloc((argc + 1) * sizeof(argv[0]));
+ if (params->argv == NULL)
+ return NULL;
+
+ for (i = 0; i < argc; i++) {
+ params->argv[i] = strdup(argv[i]);
+ if (params->argv[i] == NULL)
+ return NULL;
+ }



3. Create new_wpa_supplicant_task in wpa supplicant main.c file


In the function of rtems_bsd_command_wpa_supplicant_fork in main.c, we create a new task and start it via rtems_task_start(id, new_wpa_supplicant_task, params). In this funcion, the second params is the function of new task. So we need implement this function in main.c.


+static void
+new_wpa_supplicant_task(rtems_task_argument arg)
+{
+   int argc;
+   char ** argv;
+   int i;
+
+   struct myparams *params = (struct myparams *)arg;
+   argc = params->argc;
+   argv = params->argv;
+
+   rtems_bsd_command_wpa_supplicant(argc, argv);
+
+   for (i = 0; i < params->argc; i++) {
+ free(params->argv[i]);
+ }
+ free(params->argv);
+ free(params);
+
+ rtems_task_delete( RTEMS_SELF );
+}
+

In this function, we need unpack the params struct, and pass the argc and argv to rtems_bsd_command_wpa_supplicant function, which is the wpa_supplicant command implementation.
After pass the params, we need free these params space, and in the last, delete the task.






评论

此博客中的热门博文

RTEMS-libbsd generates drive device firmware

RTEMS Network Transplantation - rtems system initialization process analysis