Implement shell management command handlers.

Only zephyr is supported here.

Signed-off-by: Brian Bradley <brian.bradley.p@gmail.com>
diff --git a/cmd/CMakeLists.txt b/cmd/CMakeLists.txt
index b527aa8..3c62484 100644
--- a/cmd/CMakeLists.txt
+++ b/cmd/CMakeLists.txt
@@ -19,3 +19,4 @@
 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 0000000..1130be6
--- /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 0000000..3f3bf16
--- /dev/null
+++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt.h
@@ -0,0 +1,43 @@
+/*
+ * 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 0000000..60206d7
--- /dev/null
+++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_config.h
@@ -0,0 +1,43 @@
+/*
+ * 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_CONFIG_
+#define H_SHELL_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 0000000..716ed0a
--- /dev/null
+++ b/cmd/shell_mgmt/include/shell_mgmt/shell_mgmt_impl.h
@@ -0,0 +1,57 @@
+/*
+ * 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_SHELL_MGMT_IMPL_
+#define H_SHELL_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 0000000..077cd96
--- /dev/null
+++ b/cmd/shell_mgmt/port/zephyr/src/zephyr_shell_mgmt.c
@@ -0,0 +1,41 @@
+/*
+ * 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 <sys/util.h>
+#include <shell/shell.h>
+#include <mgmt/mgmt.h>
+#include <shell_mgmt/shell_mgmt.h>
+#include <shell/shell_dummy.h>
+
+int
+shell_mgmt_impl_exec(const char *line)
+{
+    const struct shell * shell = shell_backend_dummy_get_ptr();
+    shell_backend_dummy_clear_output(shell);
+    return shell_execute_cmd(shell, line);
+}
+
+const char *
+shell_mgmt_impl_get_output(){
+    size_t len;
+    return shell_backend_dummy_get_output(
+        shell_backend_dummy_get_ptr(),
+        &len
+    );
+}
diff --git a/cmd/shell_mgmt/src/shell_mgmt.c b/cmd/shell_mgmt/src/shell_mgmt.c
new file mode 100644
index 0000000..8e169a5
--- /dev/null
+++ b/cmd/shell_mgmt/src/shell_mgmt.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <string.h>
+#include <stdio.h>
+#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=<command-output> */
+    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=<status> */
+    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 0000000..0e375f3
--- /dev/null
+++ b/cmd/shell_mgmt/src/stubs.c
@@ -0,0 +1,38 @@
+/*
+ * 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 "";
+}