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 USB support for BBB document

RTEMS Network Transplantation - rtems system initialization process analysis

Work Product Submission