This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 4d37e68313f9dbae9f5abd6cc695372b57f58fdc
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Fri May 10 18:59:39 2019 -0700

    sys/shell: shell-newtmgr bridge
    
    Implement a new newtmgr command: `shell exec`.  This command allows
    shell commands to be executed via newtmgr.
---
 mgmt/mgmt/include/mgmt/mgmt.h         |   1 +
 sys/shell/pkg.yml                     |   3 +
 sys/shell/src/shell_bridge.c          | 109 ++++++++++++++++++++++++++++++++++
 sys/shell/src/shell_bridge_streamer.c |  81 +++++++++++++++++++++++++
 sys/shell/syscfg.yml                  |  16 +++++
 5 files changed, 210 insertions(+)

diff --git a/mgmt/mgmt/include/mgmt/mgmt.h b/mgmt/mgmt/include/mgmt/mgmt.h
index 427be1d..179d67f 100644
--- a/mgmt/mgmt/include/mgmt/mgmt.h
+++ b/mgmt/mgmt/include/mgmt/mgmt.h
@@ -58,6 +58,7 @@ extern "C" {
 #define MGMT_GROUP_ID_SPLIT     (6)
 #define MGMT_GROUP_ID_RUN       (7)
 #define MGMT_GROUP_ID_FS        (8)
+#define MGMT_GROUP_ID_SHELL     (9)
 #define MGMT_GROUP_ID_PERUSER   (64)
 
 /**
diff --git a/sys/shell/pkg.yml b/sys/shell/pkg.yml
index cf009a8..dee374f 100644
--- a/sys/shell/pkg.yml
+++ b/sys/shell/pkg.yml
@@ -33,6 +33,9 @@ pkg.deps.SHELL_NEWTMGR:
     - "@apache-mynewt-core/encoding/base64"
     - "@apache-mynewt-core/util/crc"
 
+pkg.deps.SHELL_BRIDGE:
+    - "@apache-mynewt-core/encoding/tinycbor"
+
 pkg.req_apis:
     - console
 
diff --git a/sys/shell/src/shell_bridge.c b/sys/shell/src/shell_bridge.c
new file mode 100644
index 0000000..f1ca335
--- /dev/null
+++ b/sys/shell/src/shell_bridge.c
@@ -0,0 +1,109 @@
+/*
+ * 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 "os/mynewt.h"
+
+#if MYNEWT_VAL(SHELL_BRIDGE)
+
+#include "mgmt/mgmt.h"
+#include "cborattr/cborattr.h"
+#include "streamer/streamer.h"
+#include "tinycbor/cbor_mbuf_writer.h"
+#include "shell_priv.h"
+
+static struct mgmt_group shell_bridge_group;
+
+static int shell_bridge_exec(struct mgmt_cbuf *cb);
+
+static struct mgmt_handler shell_bridge_group_handlers[] = {
+    [SHELL_NMGR_OP_EXEC] = { NULL, shell_bridge_exec },
+};
+
+/**
+ * Handler for the `shell exec` newtmgr command.
+ */
+static int
+shell_bridge_exec(struct mgmt_cbuf *cb)
+{
+    char line[MYNEWT_VAL(SHELL_BRIDGE_MAX_IN_LEN)];
+    char *argv[MYNEWT_VAL(SHELL_CMD_ARGC_MAX)];
+    struct shell_bridge_streamer sbs;
+    CborEncoder str_encoder;
+    CborError err;
+    int argc;
+    int rc;
+
+    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);
+
+    shell_bridge_streamer_new(&sbs, &str_encoder);
+    rc = shell_exec(argc, argv, &sbs.streamer);
+
+    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;
+}
+
+int
+shell_bridge_init(void)
+{
+    int rc;
+
+    MGMT_GROUP_SET_HANDLERS(&shell_bridge_group, shell_bridge_group_handlers);
+    shell_bridge_group.mg_group_id = MGMT_GROUP_ID_SHELL;
+
+    rc = mgmt_group_register(&shell_bridge_group);
+    if (rc) {
+        return rc;
+    }
+
+    return 0;
+}
+
+#endif
diff --git a/sys/shell/src/shell_bridge_streamer.c 
b/sys/shell/src/shell_bridge_streamer.c
new file mode 100644
index 0000000..d9df4dd
--- /dev/null
+++ b/sys/shell/src/shell_bridge_streamer.c
@@ -0,0 +1,81 @@
+/*
+ * 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 "os/mynewt.h"
+
+#if MYNEWT_VAL(SHELL_BRIDGE)
+
+#include "tinycbor/cbor.h"
+#include "shell_priv.h"
+
+static int
+shell_bridge_streamer_write(struct streamer *streamer,
+                            const void *src, size_t len)
+{
+    struct shell_bridge_streamer *sbs;
+    int err;
+
+    sbs = (struct shell_bridge_streamer *)streamer;
+
+    /* Encode the data as a CBOR text string. */
+    err = cbor_encode_text_string(sbs->str_encoder, src, len);
+    if (err != 0) {
+        return SYS_ENOMEM;
+    }
+
+    return 0;
+}
+
+static int
+shell_bridge_streamer_vprintf(struct streamer *streamer,
+                              const char *fmt, va_list ap)
+{
+    char buf[MYNEWT_VAL(SHELL_BRIDGE_PRINTF_LEN)];
+    int num_chars;
+    int rc;
+
+    num_chars = vsnprintf(buf, sizeof buf, fmt, ap);
+    if (num_chars > sizeof buf - 1) {
+        num_chars = sizeof buf - 1;
+    }
+
+    rc = shell_bridge_streamer_write(streamer, buf, num_chars);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return num_chars;
+}
+
+static const struct streamer_cfg shell_bridge_streamer_cfg = {
+    .write_cb = shell_bridge_streamer_write,
+    .vprintf_cb = shell_bridge_streamer_vprintf,
+};
+
+void
+shell_bridge_streamer_new(struct shell_bridge_streamer *sbs,
+                          struct CborEncoder *str_encoder)
+{
+    *sbs = (struct shell_bridge_streamer) {
+        .streamer.cfg = &shell_bridge_streamer_cfg,
+        .str_encoder = str_encoder,
+    };
+}
+
+#endif
diff --git a/sys/shell/syscfg.yml b/sys/shell/syscfg.yml
index 1f416bc..638f968 100644
--- a/sys/shell/syscfg.yml
+++ b/sys/shell/syscfg.yml
@@ -74,6 +74,22 @@ syscfg.defs:
             write 2, read/write 3 (default)
         value: 3 
 
+    SHELL_BRIDGE:
+        description: >
+            Enables the `shell exec` newtmgr command; executes shell commands
+            via newtmgr.
+        value: 0
+    SHELL_BRIDGE_MAX_IN_LEN:
+        description: >
+            Maximum combined length of arguments passed to the `shell exec`
+            newtmgr command.
+        value: 128
+    SHELL_BRIDGE_PRINTF_LEN:
+        description: >
+            Maximum number of characters that can be streamed by a single
+            printf call during processing of the `shell exec` newtmgr command.
+        value: 128
+
 ## duplicated from boot/boot_serial
     BOOT_SERIAL_NVREG_MAGIC:
         description: >

Reply via email to