Add wpa_supplicant_fork command on RTEMS-libbsd

在将wpa_supplicant移植到RTEMS上后,我们能在shell command中使用该命令,但是存在一个BUG,当我们通过命令wpa_supplciant配置WPA时,我们不嫩使用其他命令,或者其他thread。因此我们要创建一个新的thread让wpa_supplicant运行。本文是从本人的英文博客中翻译过来,因此大部分是英文。


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.

posted on 2017-08-13 16:05  sichenzhao  阅读(136)  评论(0编辑  收藏  举报

导航