From a31bd7bb0d54a462cf93bd2b18adbcd77030d62d Mon Sep 17 00:00:00 2001 From: Xiangyang Wu Date: Thu, 20 Jan 2022 08:12:04 +0800 Subject: [PATCH] DM: add command module for command monitor The command module provides interfaces to find a command intance, register handler for specified command, dispatch command and invoke related handler. find_command: find a command instance by name. register_command_handler: register the handler for one command instance. dispatch_command_handlers: dispatch the command and invoke registered handler. v1-->v2: Only support single handler for one command instance. v2-->v3: Remove command id. Add error check to avoid regiter handler to command instance which has handler. Update the second parameter type of register_command_handler to avoid unnecessary type conversion. Tracked-On: #5921 Signed-off-by: Xiangyang Wu Acked-by: Wang, Yu1 --- devicemodel/core/cmd_monitor/command.c | 88 ++++++++++++++++++++++++++ devicemodel/core/cmd_monitor/command.h | 61 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 devicemodel/core/cmd_monitor/command.c create mode 100644 devicemodel/core/cmd_monitor/command.h diff --git a/devicemodel/core/cmd_monitor/command.c b/devicemodel/core/cmd_monitor/command.c new file mode 100644 index 000000000..a8695ac0c --- /dev/null +++ b/devicemodel/core/cmd_monitor/command.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2022 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "command.h" +#include "vmmapi.h" +#include "log.h" + +#define GEN_CMD_OBJ(cmd_name) \ + {.name = cmd_name,} +#define CMD_OBJS \ + GEN_CMD_OBJ(DESTROY), \ + GEN_CMD_OBJ(BLKRESCAN), \ + +struct command dm_command_list[CMDS_NUM] = {CMD_OBJS}; + +int dispatch_command_handlers(void *arg) +{ + struct command *cmd = (struct command *)arg; + int ret = 0; + + pr_info("Handle command %s in command monitor.\n", cmd->name); + if (cmd->cmd_handler.fn) { + ret = cmd->cmd_handler.fn(cmd->cmd_handler.arg, &cmd->para); + pr_info("Command handler ret=%d.\n", ret); + } else { + pr_info("No handler for command: %s.\r\n", cmd->name); + } + + return 0; +} +struct command *find_command(const char *name) +{ + for (int i = 0; (i < CMDS_NUM) && (name != NULL); i++) { + if (strcmp(dm_command_list[i].name, name) == 0) + return &dm_command_list[i]; + } + return NULL; +} + +int register_command_handler(cmd_handler *fn, struct handler_args *arg, const char *cmd_name) +{ + struct command *cmd; + struct handler_args *handler_arg; + + if ((!fn) || (!arg) || (!cmd_name)) { + pr_err("%s : Failed to register command_handler.\n", __func__); + return -EINVAL; + } + + cmd = find_command(cmd_name); + if (cmd == NULL) { + pr_err("%s : invalid command name %s.\r\n", __func__, cmd_name); + return -EINVAL; + } + + if (cmd->cmd_handler.fn != NULL) { + pr_err("Failed to register command handler since the handler have already been registered.\n"); + return -EINVAL; + } + cmd->cmd_handler.fn = fn; + + handler_arg = calloc(1, sizeof(*handler_arg)); + if (!handler_arg) { + pr_err("Failed to allocate command handler argument.\r\n"); + return -ENOMEM; + } + cmd->cmd_handler.arg = handler_arg; + cmd->cmd_handler.arg->channel_arg = arg->channel_arg; + cmd->cmd_handler.arg->ctx_arg = arg->ctx_arg; + + return 0; +} diff --git a/devicemodel/core/cmd_monitor/command.h b/devicemodel/core/cmd_monitor/command.h new file mode 100644 index 000000000..4285d8a35 --- /dev/null +++ b/devicemodel/core/cmd_monitor/command.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _COMMAND_H_ +#define _COMMAND_H_ +#include +#include + + +#define DESTROY "destroy" +#define BLKRESCAN "blkrescan" + +#define CMDS_NUM 2U +#define CMD_NAME_MAX 32U +#define CMD_ARG_MAX 320U + +typedef int (cmd_handler)(void *arg, void *command_para); +struct handler_args { + void *channel_arg; + void *ctx_arg; +}; +struct command_handler { + struct handler_args *arg; + cmd_handler *fn; +}; +struct command_parameters { + int fd; + char option[CMD_ARG_MAX]; +}; +struct command { + const char name[CMD_NAME_MAX]; /**< command name */ + struct command_parameters para; + + /* command handler */ + struct command_handler cmd_handler; +}; +/** + * @brief register command handler, other module can use this interface to + * register multiple handler for one command. + * + * @param fn the command handler which will be registered + * @param arg the parameter which will be passed into hanlder + * @param cmd_name the command name + */ +int register_command_handler(cmd_handler *fn, struct handler_args *arg, const char *cmd_name); +/** + * @brief find a command instance by name + * + * @param name the command name + * @return command instance + */ +struct command *find_command(const char *name); +/** + * @brief dispatch the command and invoke registered handler. + * + * @param arg command instance + * @return the flag indicates the state of command handler execution + */ +int dispatch_command_handlers(void *arg); +#endif