From 2e0165acc02920571f8b6cafe14e7803acb2cfcd Mon Sep 17 00:00:00 2001 From: Brian Bradley Date: Wed, 21 Oct 2020 11:26:11 -0400 Subject: [PATCH] Implement shell management command handlers. Only zephyr is supported here. Signed-off-by: Brian Bradley --- cmd/CMakeLists.txt | 2 + cmd/shell_mgmt/CMakeLists.txt | 26 +++++ .../include/shell_mgmt/shell_mgmt.h | 42 +++++++ .../include/shell_mgmt/shell_mgmt_config.h | 44 ++++++++ .../include/shell_mgmt/shell_mgmt_impl.h | 56 ++++++++++ .../port/zephyr/src/zephyr_shell_mgmt.c | 60 ++++++++++ cmd/shell_mgmt/src/shell_mgmt.c | 105 ++++++++++++++++++ cmd/shell_mgmt/src/stubs.c | 39 +++++++ 8 files changed, 374 insertions(+) create mode 100644 cmd/shell_mgmt/CMakeLists.txt create mode 100644 cmd/shell_mgmt/include/shell_mgmt/shell_mgmt.h create mode 100644 cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_config.h create mode 100644 cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_impl.h create mode 100644 cmd/shell_mgmt/port/zephyr/src/zephyr_shell_mgmt.c create mode 100644 cmd/shell_mgmt/src/shell_mgmt.c create mode 100644 cmd/shell_mgmt/src/stubs.c diff --git a/cmd/CMakeLists.txt b/cmd/CMakeLists.txt index b527aa83..fcfa8e83 100644 --- a/cmd/CMakeLists.txt +++ b/cmd/CMakeLists.txt @@ -19,3 +19,5 @@ add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_FS_MGMT fs_mgmt) add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_IMG_MGMT img_mgmt) add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_OS_MGMT os_mgmt) add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_STAT_MGMT stat_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_CMD_SHELL_MGMT shell_mgmt) + diff --git a/cmd/shell_mgmt/CMakeLists.txt b/cmd/shell_mgmt/CMakeLists.txt new file mode 100644 index 00000000..1130be69 --- /dev/null +++ b/cmd/shell_mgmt/CMakeLists.txt @@ -0,0 +1,26 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +target_include_directories(MCUMGR INTERFACE + include +) + +zephyr_library_sources( + port/zephyr/src/zephyr_shell_mgmt.c + src/shell_mgmt.c + src/stubs.c +) diff --git a/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt.h b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt.h new file mode 100644 index 00000000..6b4e0e3d --- /dev/null +++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt.h @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_SHELL_MGMT_ +#define H_SHELL_MGMT_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Command IDs for shell management group. + */ +#define SHELL_MGMT_ID_EXEC 0 + +/** + * @brief Registers the shell management command handler group. + */ +void shell_mgmt_register_group(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_SHELL_MGMT_ */ + diff --git a/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_config.h b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_config.h new file mode 100644 index 00000000..f585447a --- /dev/null +++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_config.h @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_STAT_MGMT_CONFIG_ +#define H_STAT_MGMT_CONFIG_ + +#if defined MYNEWT + +#include "syscfg/syscfg.h" + +#define SHELL_MGMT_MAX_LINE_LEN MYNEWT_VAL(SHELL_BRIDGE_MAX_IN_LEN) +#define SHELL_MGMT_MAX_ARGC MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + +#elif defined __ZEPHYR__ + +#define SHELL_MGMT_MAX_LINE_LEN CONFIG_SHELL_CMD_BUFF_SIZE +#define SHELL_MGMT_MAX_ARGC CONFIG_SHELL_ARGC_MAX + +#else + +/* No direct support for this OS. The application needs to define the above + * settings itself. + */ + +#endif + +#endif + diff --git a/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_impl.h b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_impl.h new file mode 100644 index 00000000..01a39e39 --- /dev/null +++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_impl.h @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * @file + * @brief Declares implementation-specific functions required by shell + * management. The default stubs can be overridden with functions that + * are compatible with the host OS. + */ + +#ifndef H_STAT_MGMT_IMPL_ +#define H_STAT_MGMT_IMPL_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Execute `line` as a shell command + * + * @param line : shell command to be executed + * @return int : 0 on success, -errno otherwire + */ +int shell_mgmt_impl_exec(const char *line); + +/** + * @brief Capture the output of the shell + * + * @return const char* : shell output. This is not the return code, it is + * the string output of the shell command if it exists. If the shell provided no + * output, this will be an empty string + */ +const char * shell_mgmt_impl_get_output(); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/cmd/shell_mgmt/port/zephyr/src/zephyr_shell_mgmt.c b/cmd/shell_mgmt/port/zephyr/src/zephyr_shell_mgmt.c new file mode 100644 index 00000000..eb1a8b23 --- /dev/null +++ b/cmd/shell_mgmt/port/zephyr/src/zephyr_shell_mgmt.c @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include +#include +#if defined(CONFIG_SHELL_BACKEND_SERIAL) +#include +#elif defined(CONFIG_SHELL_BACKEND_DUMMY) +#include +#endif + + +int +shell_mgmt_impl_exec(const char *line) +{ + int rc; + + #if defined(CONFIG_SHELL_BACKEND_SERIAL) + rc = shell_execute_cmd(shell_backend_uart_get_ptr(), line); + #elif defined(CONFIG_SHELL_BACKEND_DUMMY) + const struct shell * shell = shell_backend_dummy_get_ptr(); + shell_backend_dummy_clear_output(shell); + rc = shell_execute_cmd(shell, line); + #else + rc = -ENOENT; + #endif + + return rc; +} + +const char * +shell_mgmt_impl_get_output(){ + #ifdef CONFIG_SHELL_BACKEND_DUMMY + size_t len; + return shell_backend_dummy_get_output( + shell_backend_dummy_get_ptr(), + &len + ); + #endif + return ""; +} + diff --git a/cmd/shell_mgmt/src/shell_mgmt.c b/cmd/shell_mgmt/src/shell_mgmt.c new file mode 100644 index 00000000..35577734 --- /dev/null +++ b/cmd/shell_mgmt/src/shell_mgmt.c @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +#include "mgmt/mgmt.h" +#include "cborattr/cborattr.h" +#include "shell_mgmt/shell_mgmt.h" +#include "shell_mgmt/shell_mgmt_impl.h" +#include "shell_mgmt/shell_mgmt_config.h" + +static mgmt_handler_fn shell_mgmt_exec; + +static struct mgmt_handler shell_mgmt_handlers[] = { + [SHELL_MGMT_ID_EXEC] = { NULL, shell_mgmt_exec }, +}; + +#define SHELL_MGMT_HANDLER_CNT \ + sizeof shell_mgmt_handlers / sizeof shell_mgmt_handlers[0] + +static struct mgmt_group shell_mgmt_group = { + .mg_handlers = shell_mgmt_handlers, + .mg_handlers_count = SHELL_MGMT_HANDLER_CNT, + .mg_group_id = MGMT_GROUP_ID_SHELL, +}; + +/** + * Command handler: shell exec + */ +static int +shell_mgmt_exec(struct mgmt_ctxt *cb) +{ + static char line[SHELL_MGMT_MAX_LINE_LEN + 1] = {0}; + CborEncoder str_encoder; + CborError err; + int rc; + char *argv[SHELL_MGMT_MAX_ARGC]; + int argc; + + + const struct cbor_attr_t attrs[] = { + { + .attribute = "argv", + .type = CborAttrArrayType, + .addr.array = { + .element_type = CborAttrTextStringType, + .arr.strings.ptrs = argv, + .arr.strings.store = line, + .arr.strings.storelen = sizeof line, + .count = &argc, + .maxlen = sizeof argv / sizeof argv[0], + }, + }, + { 0 }, + }; + + err = cbor_read_object(&cb->it, attrs); + if (err != 0) { + return MGMT_ERR_EINVAL; + } + + /* Key="o"; value= */ + err |= cbor_encode_text_stringz(&cb->encoder, "o"); + err |= cbor_encoder_create_indef_text_string(&cb->encoder, &str_encoder); + + rc = shell_mgmt_impl_exec(line); + + err |= cbor_encode_text_stringz(&str_encoder, + shell_mgmt_impl_get_output()); + + err |= cbor_encoder_close_container(&cb->encoder, &str_encoder); + + /* Key="rc"; value= */ + err |= cbor_encode_text_stringz(&cb->encoder, "rc"); + err |= cbor_encode_int(&cb->encoder, rc); + + if (err != 0) { + return MGMT_ERR_ENOMEM; + } + + return 0; +} + +void +shell_mgmt_register_group(void) +{ + mgmt_register_group(&shell_mgmt_group); +} + diff --git a/cmd/shell_mgmt/src/stubs.c b/cmd/shell_mgmt/src/stubs.c new file mode 100644 index 00000000..6fa965de --- /dev/null +++ b/cmd/shell_mgmt/src/stubs.c @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License") you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * These stubs get linked in when there is no equivalent OS-specific + * implementation. + */ + +#include "mgmt/mgmt.h" +#include "shell_mgmt/shell_mgmt_impl.h" + +int __attribute__((weak)) +shell_mgmt_impl_exec(const char *line) +{ + return MGMT_ERR_ENOTSUP; +} + +const char * __attribute__((weak)) +shell_mgmt_impl_get_output() +{ + return ""; +} +