You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/12/21 02:55:44 UTC

[mynewt-mcumgr] 02/02: Rename newtmgr -> smp (simple management protocol)

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-mcumgr.git

commit 9308d50cf57f97b2f57069133115b362fd4fdf53
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Dec 20 14:55:10 2017 -0800

    Rename newtmgr -> smp (simple management protocol)
    
    Also add some comments.
---
 mgmt/include/mgmt/mgmt.h                           |  18 +-
 mgmt/src/mgmt.c                                    |  14 +
 newtmgr/src/newtmgr.c                              | 354 ------------------
 .../newtmgr/newtmgr.h => smp/include/smp/smp.h     |  30 +-
 {newtmgr => smp}/pkg.yml                           |  12 +-
 .../port/mynewt/include/mynewt_smp/mynewt_smp.h    |  30 +-
 {newtmgr => smp}/port/mynewt/pkg.yml               |   5 +-
 .../port/mynewt/src/mynewt_smp.c                   | 130 +++----
 smp/src/smp.c                                      | 404 +++++++++++++++++++++
 9 files changed, 535 insertions(+), 462 deletions(-)

diff --git a/mgmt/include/mgmt/mgmt.h b/mgmt/include/mgmt/mgmt.h
index 5ed55d3..568d8b2 100644
--- a/mgmt/include/mgmt/mgmt.h
+++ b/mgmt/include/mgmt/mgmt.h
@@ -21,15 +21,14 @@
 #define H_MGMT_MGMT_
 
 #include <inttypes.h>
-
-#include "tinycbor/cbor.h"
+#include "cbor.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* MTU for newtmgr responses */
-#define MGMT_MAX_MTU 1024
+#define MGMT_MAX_MTU            (1024)
 
 #define MGMT_OP_READ            (0)
 #define MGMT_OP_READ_RSP        (1)
@@ -63,7 +62,7 @@ extern "C" {
 #define MGMT_ERR_EMSGSIZE       (7)     /* Response too large. */
 #define MGMT_ERR_EPERUSER       (256)
 
-#define NMGR_HDR_SIZE           (8)
+#define MGMT_HDR_SIZE       (8)
 
 struct mgmt_hdr {
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ -102,7 +101,7 @@ struct mgmt_streamer_cfg {
     mgmt_free_buf_fn *free_buf;
 };
 
-/** Decodes requests and encodes responses. */
+/** Decodes requests and encodes responses for any mgmt protocol. */
 struct mgmt_streamer {
     const struct mgmt_streamer_cfg *cfg;
     void *cb_arg;
@@ -130,10 +129,15 @@ struct mgmt_handler {
 
 /** A collection of handlers for every command in a single group. */
 struct mgmt_group {
+    /** Points to the next group in the list. */
+    struct mgmt_group *mg_next;
+
+    /** Array of handlers; one entry per command ID. */
     const struct mgmt_handler *mg_handlers;
     uint16_t mg_handlers_count;
+
+    /* The numeric ID of this group. */
     uint16_t mg_group_id;
-    struct mgmt_group *mg_next;
 };
 
 #define MGMT_GROUP_SET_HANDLERS(group__, handlers__) do {   \
@@ -158,6 +162,8 @@ const struct mgmt_handler *mgmt_find_handler(uint16_t group_id,
                                              uint16_t command_id);
 int mgmt_err_from_cbor(int cbor_status);
 int mgmt_cbuf_init(struct mgmt_cbuf *cbuf, struct mgmt_streamer *streamer);
+void mgmt_ntoh_hdr(struct mgmt_hdr *hdr);
+void mgmt_hton_hdr(struct mgmt_hdr *hdr);
 
 #ifdef __cplusplus
 }
diff --git a/mgmt/src/mgmt.c b/mgmt/src/mgmt.c
index 1acb60f..f12fc98 100644
--- a/mgmt/src/mgmt.c
+++ b/mgmt/src/mgmt.c
@@ -154,3 +154,17 @@ mgmt_cbuf_init(struct mgmt_cbuf *cbuf, struct mgmt_streamer *streamer)
 
     return 0;
 }
+
+void
+mgmt_ntoh_hdr(struct mgmt_hdr *hdr)
+{
+    hdr->nh_len = ntohs(hdr->nh_len);
+    hdr->nh_group = ntohs(hdr->nh_group);
+}
+
+void
+mgmt_hton_hdr(struct mgmt_hdr *hdr)
+{
+    hdr->nh_len = htons(hdr->nh_len);
+    hdr->nh_group = htons(hdr->nh_group);
+}
diff --git a/newtmgr/src/newtmgr.c b/newtmgr/src/newtmgr.c
deleted file mode 100644
index 7f12f76..0000000
--- a/newtmgr/src/newtmgr.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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 <assert.h>
-#include <string.h>
-
-#include "mgmt/mgmt.h"
-#include "newtmgr/newtmgr.h"
-#include "tinycbor/cbor.h"
-#include "tinycbor/cbor_mbuf_writer.h"
-#include "tinycbor/cbor_mbuf_reader.h"
-
-#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-
-#ifndef ntohs
-#define ntohs(x) (x)
-#endif
-
-#ifndef htons
-#define htons(x) (x)
-#endif
-
-#else
-/* Little endian. */
-
-#ifndef ntohs
-#define ntohs(x)   ((uint16_t)  \
-    ((((x) & 0xff00) >> 8) |    \
-     (((x) & 0x00ff) << 8)))
-#endif
-
-#ifndef htons
-#define htons(x) (ntohs(x))
-#endif
-
-#endif
-
-static int
-nmgr_align4(int x)
-{
-    int rem;
-
-    rem = x % 4;
-    if (rem == 0) {
-        return x;
-    } else {
-        return x - rem + 4;
-    }
-}
-
-static uint8_t
-nmgr_rsp_op(uint8_t req_op)
-{
-    if (req_op == MGMT_OP_READ) {
-        return MGMT_OP_READ_RSP;
-    } else {
-        return MGMT_OP_WRITE_RSP;
-    }
-}
-
-void
-nmgr_ntoh_hdr(struct mgmt_hdr *hdr)
-{
-    hdr->nh_len = ntohs(hdr->nh_len);
-    hdr->nh_group = ntohs(hdr->nh_group);
-}
-
-static void
-nmgr_hton_hdr(struct mgmt_hdr *hdr)
-{
-    hdr->nh_len = htons(hdr->nh_len);
-    hdr->nh_group = htons(hdr->nh_group);
-}
-
-static void
-nmgr_init_rsp_hdr(const struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr)
-{
-    *rsp_hdr = (struct mgmt_hdr) {
-        .nh_len = 0,
-        .nh_flags = 0,
-        .nh_op = nmgr_rsp_op(req_hdr->nh_op),
-        .nh_group = req_hdr->nh_group,
-        .nh_seq = req_hdr->nh_seq,
-        .nh_id = req_hdr->nh_id,
-    };
-}
-
-static int
-nmgr_read_hdr(struct nmgr_streamer *streamer, struct mgmt_hdr *hdr)
-{
-    struct mgmt_streamer *base;
-
-    base = &streamer->ns_base;
-
-    if (base->reader->message_size < sizeof *hdr) {
-        return MGMT_ERR_EINVAL;
-    }
-
-    base->reader->cpy(base->reader, (char *)hdr, 0, sizeof *hdr);
-    return 0;
-}
-
-static int
-nmgr_write_hdr(struct nmgr_streamer *streamer, const struct mgmt_hdr *hdr)
-{
-    int rc;
-
-    rc = mgmt_streamer_write_at(&streamer->ns_base, 0, hdr, sizeof *hdr);
-    return mgmt_err_from_cbor(rc);
-}
-
-static int
-nmgr_build_err_rsp(struct nmgr_streamer *streamer,
-                   const struct mgmt_hdr *req_hdr,
-                   int status)
-{
-    struct CborEncoder map;
-    struct mgmt_cbuf cbuf;
-    struct mgmt_hdr rsp_hdr;
-    int rc;
-
-    rc = mgmt_cbuf_init(&cbuf, &streamer->ns_base);
-    if (rc != 0) {
-        return rc;
-    }
-
-    nmgr_init_rsp_hdr(req_hdr, &rsp_hdr);
-    rc = nmgr_write_hdr(streamer, &rsp_hdr);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = cbor_encoder_create_map(&cbuf.encoder, &map, CborIndefiniteLength);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = mgmt_cbuf_setoerr(&cbuf, status);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = cbor_encoder_close_container(&cbuf.encoder, &map);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rsp_hdr.nh_len = cbor_encode_bytes_written(&cbuf.encoder) - MGMT_HDR_SIZE;
-    nmgr_hton_hdr(&rsp_hdr);
-    rc = nmgr_write_hdr(streamer, &rsp_hdr);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-int
-nmgr_handle_single_payload(struct mgmt_cbuf *cbuf,
-                           const struct mgmt_hdr *req_hdr)
-{
-    const struct mgmt_handler *handler;
-    struct CborEncoder payload_encoder;
-    int rc;
-
-    handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id);
-    if (!handler) {
-        return MGMT_ERR_ENOENT;
-    }
-
-    /* Begin response payload.  Response fields are inserted into the root
-     * map as key value pairs.
-     */
-    rc = cbor_encoder_create_map(&cbuf->encoder, &payload_encoder,
-                                 CborIndefiniteLength);
-    rc = mgmt_err_from_cbor(rc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (req_hdr->nh_op == MGMT_OP_READ) {
-        if (handler->mh_read) {
-            rc = handler->mh_read(cbuf);
-        } else {
-            rc = MGMT_ERR_ENOENT;
-        }
-    } else if (req_hdr->nh_op == MGMT_OP_WRITE) {
-        if (handler->mh_write) {
-            rc = handler->mh_write(cbuf);
-        } else {
-            rc = MGMT_ERR_ENOENT;
-        }
-    } else {
-        rc = MGMT_ERR_EINVAL;
-    }
-    if (rc != 0) {
-        return rc;
-    }
-
-    /* End response payload. */
-    rc = cbor_encoder_close_container(&cbuf->encoder, &payload_encoder);
-    rc = mgmt_err_from_cbor(rc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-
-static int
-nmgr_handle_single_req(struct nmgr_streamer *streamer,
-                       const struct mgmt_hdr *req_hdr)
-{
-    struct mgmt_cbuf cbuf;
-    struct mgmt_hdr rsp_hdr;
-    int rc;
-
-    rc = mgmt_cbuf_init(&cbuf, &streamer->ns_base);
-    if (rc != 0) {
-        return rc;
-    }
-
-    /* Build response header a priori, then pass to the handlers to fill out
-     * the response data and adjust length and flags.
-     */
-    nmgr_init_rsp_hdr(req_hdr, &rsp_hdr);
-    rc = nmgr_write_hdr(streamer, &rsp_hdr);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = nmgr_handle_single_payload(&cbuf, req_hdr);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rsp_hdr.nh_len = cbor_encode_bytes_written(&cbuf.encoder) - MGMT_HDR_SIZE;
-    nmgr_hton_hdr(&rsp_hdr);
-    rc = nmgr_write_hdr(streamer, &rsp_hdr);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-nmgr_on_err(struct nmgr_streamer *streamer,
-            const struct mgmt_hdr *req_hdr,
-            void *req,
-            void *rsp,
-            int status)
-{
-    int rc;
-
-    if (rsp == NULL) {
-        rsp = req;
-        req = NULL;
-    }
-
-    mgmt_streamer_reset_buf(&streamer->ns_base, rsp);
-    mgmt_streamer_init_writer(&streamer->ns_base, rsp);
-
-    rc = nmgr_build_err_rsp(streamer, req_hdr, status);
-    if (rc == 0) {
-        streamer->ns_tx_rsp(streamer, rsp, streamer->ns_base.cb_arg);
-        rsp = NULL;
-    }
-
-    mgmt_streamer_free_buf(&streamer->ns_base, req);
-    mgmt_streamer_free_buf(&streamer->ns_base, rsp);
-}
-
-int
-nmgr_process_single_packet(struct nmgr_streamer *streamer, void *req)
-{
-    struct mgmt_hdr req_hdr;
-    void *rsp;
-    bool valid_hdr;
-    int rc;
-
-    rsp = NULL;
-    valid_hdr = true;
-
-    while (1) {
-        rc = mgmt_streamer_init_reader(&streamer->ns_base, req);
-        if (rc != 0) {
-            valid_hdr = false;
-            break;
-        }
-
-        rc = nmgr_read_hdr(streamer, &req_hdr);
-        if (rc != 0) {
-            valid_hdr = false;
-            break;
-        }
-        nmgr_ntoh_hdr(&req_hdr);
-        rc = mgmt_streamer_trim_front(&streamer->ns_base, req, MGMT_HDR_SIZE);
-        assert(rc == 0);
-
-        rsp = mgmt_streamer_alloc_rsp(&streamer->ns_base, req);
-        if (rsp == NULL) {
-            rc = MGMT_ERR_ENOMEM;
-            break;
-        }
-
-        rc = mgmt_streamer_init_writer(&streamer->ns_base, rsp);
-        if (rc != 0) {
-            break;
-        }
-
-        rc = nmgr_handle_single_req(streamer, &req_hdr);
-        if (rc != 0) {
-            break;
-        }
-
-        rc = streamer->ns_tx_rsp(streamer, rsp, streamer->ns_base.cb_arg);
-        rsp = NULL;
-        if (rc != 0) {
-            break;
-        }
-
-        /* Trim processed request to free up space for subsequent responses. */
-        rc = mgmt_streamer_trim_front(&streamer->ns_base, req,
-                                      nmgr_align4(req_hdr.nh_len));
-        assert(rc == 0);
-    }
-
-    if (rc != 0 && valid_hdr) {
-        nmgr_on_err(streamer, &req_hdr, req, rsp, rc);
-        return rc;
-    }
-
-    mgmt_streamer_free_buf(&streamer->ns_base, req);
-    mgmt_streamer_free_buf(&streamer->ns_base, rsp);
-    return 0;
-}
diff --git a/newtmgr/include/newtmgr/newtmgr.h b/smp/include/smp/smp.h
similarity index 61%
rename from newtmgr/include/newtmgr/newtmgr.h
rename to smp/include/smp/smp.h
index c6b3806..2feaa47 100644
--- a/newtmgr/include/newtmgr/newtmgr.h
+++ b/smp/include/smp/smp.h
@@ -17,8 +17,10 @@
  * under the License.
  */
 
-#ifndef _NEWTMGR_H_
-#define _NEWTMGR_H_
+/** SMP - Simple Management Protocol. */
+
+#ifndef H_SMP_
+#define H_SMP_
 
 #include "mgmt/mgmt.h"
 
@@ -26,23 +28,25 @@
 extern "C" {
 #endif
 
-struct mynewt_nmgr_transport;
-struct nmgr_streamer;
+struct mynewt_smp_transport;
+struct smp_streamer;
 struct mgmt_hdr;
-typedef int nmgr_tx_rsp_fn(struct nmgr_streamer *ns, void *buf, void *arg);
 
-struct nmgr_streamer {
-    struct mgmt_streamer ns_base;
-    nmgr_tx_rsp_fn *ns_tx_rsp;
+typedef int smp_tx_rsp_fn(struct smp_streamer *ss, void *buf, void *arg);
+
+/** Decodes, encodes, and transmits SMP packets. */
+struct smp_streamer {
+    struct mgmt_streamer ss_base;
+    smp_tx_rsp_fn *ss_tx_rsp;
 };
 
-void nmgr_ntoh_hdr(struct mgmt_hdr *hdr);
-int nmgr_handle_single_payload(struct mgmt_cbuf *cbuf,
-                               const struct mgmt_hdr *req_hdr);
-int nmgr_process_single_packet(struct nmgr_streamer *streamer, void *req);
+void smp_ntoh_hdr(struct mgmt_hdr *hdr);
+int smp_handle_single_payload(struct mgmt_cbuf *cbuf,
+                              const struct mgmt_hdr *req_hdr);
+int smp_process_single_packet(struct smp_streamer *streamer, void *req);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* _NETMGR_H */
+#endif /* H_SMP_ */
diff --git a/newtmgr/pkg.yml b/smp/pkg.yml
similarity index 86%
rename from newtmgr/pkg.yml
rename to smp/pkg.yml
index 2d48007..bf165cb 100644
--- a/newtmgr/pkg.yml
+++ b/smp/pkg.yml
@@ -17,8 +17,8 @@
 # under the License.
 #
 
-pkg.name: mgmt/newtmgr
-pkg.description: Server-side newtmgr functionality.
+pkg.name: smp
+pkg.description: Server-side simple management protocol (SMP) functionality.
 pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
@@ -26,16 +26,16 @@ pkg.keywords:
 pkg.deps:
     - encoding/cborattr
     - kernel/os
-    - mgmt/mgmt
-    - mgmt/newtmgr/nmgr_os
-    - mgmt/newtmgr/port/mynewt
+    - mgmt
+    - smp/port/mynewt
     - util/mem
 
 pkg.deps.NEWTMGR_BLE_HOST:
+    # XXX: Inaccurate path.
     - mgmt/newtmgr/transport/ble
 
 pkg.apis:
-    - newtmgr
+    - smp
 
 pkg.init:
     nmgr_pkg_init: 500
diff --git a/newtmgr/port/mynewt/include/mynewt_newtmgr/mynewt_newtmgr.h b/smp/port/mynewt/include/mynewt_smp/mynewt_smp.h
similarity index 65%
rename from newtmgr/port/mynewt/include/mynewt_newtmgr/mynewt_newtmgr.h
rename to smp/port/mynewt/include/mynewt_smp/mynewt_smp.h
index 0317ef5..02883c5 100644
--- a/newtmgr/port/mynewt/include/mynewt_newtmgr/mynewt_newtmgr.h
+++ b/smp/port/mynewt/include/mynewt_smp/mynewt_smp.h
@@ -17,13 +17,13 @@
  * under the License.
  */
 
-#ifndef H_MYNEWT_NEWTMGR_
-#define H_MYNEWT_NEWTMGR_
+#ifndef H_MYNEWT_SMP_
+#define H_MYNEWT_SMP_
 
 #include <inttypes.h>
 #include "mgmt/mgmt.h"
 #include "os/os_mbuf.h"
-struct mynewt_nmgr_transport;
+struct mynewt_smp_transport;
 
 #ifdef __cplusplus
 extern "C" {
@@ -33,8 +33,8 @@ extern "C" {
  * Transmit function.  The supplied mbuf is always consumed, regardless of
  * return code.
  */
-typedef int mynewt_nmgr_transport_out_fn(struct mynewt_nmgr_transport *mnt,
-                                         struct os_mbuf *m);
+typedef int mynewt_smp_transport_out_fn(struct mynewt_smp_transport *mnt,
+                                        struct os_mbuf *m);
 
 /**
  * MTU query function.  The supplied mbuf should contain a request received
@@ -45,22 +45,22 @@ typedef int mynewt_nmgr_transport_out_fn(struct mynewt_nmgr_transport *mnt,
  * @return                      The transport's MTU;
  *                              0 if transmission is currently not possible.
  */
-typedef uint16_t mynewt_nmgr_transport_get_mtu_fn(struct os_mbuf *m);
+typedef uint16_t mynewt_smp_transport_get_mtu_fn(struct os_mbuf *m);
 
-struct mynewt_nmgr_transport {
-    struct os_mqueue mnt_imq;
-    mynewt_nmgr_transport_out_fn *mnt_output;
-    mynewt_nmgr_transport_get_mtu_fn *mnt_get_mtu;
+struct mynewt_smp_transport {
+    struct os_mqueue msp_imq;
+    mynewt_smp_transport_out_fn *msp_output;
+    mynewt_smp_transport_get_mtu_fn *msp_get_mtu;
 };
 
-int mynewt_nmgr_transport_init(struct mynewt_nmgr_transport *mnt,
-                               mynewt_nmgr_transport_out_fn *output_func,
-                               mynewt_nmgr_transport_get_mtu_fn *get_mtu_func);
+int mynewt_smp_transport_init(struct mynewt_smp_transport *mnt,
+                               mynewt_smp_transport_out_fn *output_func,
+                               mynewt_smp_transport_get_mtu_fn *get_mtu_func);
 
-int mynewt_nmgr_rx_req(struct mynewt_nmgr_transport *mnt, struct os_mbuf *req);
+int mynewt_smp_rx_req(struct mynewt_smp_transport *mnt, struct os_mbuf *req);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* H_MYNEWT_NETMGR_ */
+#endif /* H_MYNEWT_SMP_ */
diff --git a/newtmgr/port/mynewt/pkg.yml b/smp/port/mynewt/pkg.yml
similarity index 93%
rename from newtmgr/port/mynewt/pkg.yml
rename to smp/port/mynewt/pkg.yml
index bb90250..ae71ebf 100644
--- a/newtmgr/port/mynewt/pkg.yml
+++ b/smp/port/mynewt/pkg.yml
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-pkg.name: mgmt/newtmgr/port/mynewt
+pkg.name: smp/port/mynewt
 pkg.description: Server-side newtmgr functionality.
 pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
@@ -25,6 +25,5 @@ pkg.keywords:
 
 pkg.deps:
     - kernel/os
-    - mgmt/mgmt
-    - mgmt/mgmt_os
+    - mgmt
     - util/mem
diff --git a/newtmgr/port/mynewt/src/mynewt_nmgr.c b/smp/port/mynewt/src/mynewt_smp.c
similarity index 54%
rename from newtmgr/port/mynewt/src/mynewt_nmgr.c
rename to smp/port/mynewt/src/mynewt_smp.c
index 0aa4c9b..f5f2950 100644
--- a/newtmgr/port/mynewt/src/mynewt_nmgr.c
+++ b/smp/port/mynewt/src/mynewt_smp.c
@@ -2,40 +2,40 @@
 
 #include "os/os.h"
 #include "mynewt_mgmt/mynewt_mgmt.h"
-#include "newtmgr/newtmgr.h"
+#include "smp/smp.h"
 #include "mgmt_os/mgmt_os.h"
 #include "mem/mem.h"
-#include "tinycbor/cbor_mbuf_reader.h"
-#include "tinycbor/cbor_mbuf_writer.h"
-#include "mynewt_newtmgr/mynewt_newtmgr.h"
-
-/* Shared queue that newtmgr uses for work items. */
-struct os_eventq *nmgr_evq;
-
-static mgmt_alloc_rsp_fn mynewt_nmgr_alloc_rsp;
-static mgmt_trim_front_fn mynewt_nmgr_trim_front;
-static mgmt_reset_buf_fn mynewt_nmgr_reset_buf;
-static mgmt_write_at_fn mynewt_nmgr_write_at;
-static mgmt_init_reader_fn mynewt_nmgr_init_reader;
-static mgmt_init_writer_fn mynewt_nmgr_init_writer;
-static mgmt_free_buf_fn mynewt_nmgr_free_buf;
-static nmgr_tx_rsp_fn mynewt_nmgr_tx_rsp;
-
-static const struct mgmt_streamer_cfg mynewt_nmgr_cbor_cfg = {
-    .alloc_rsp = mynewt_nmgr_alloc_rsp,
-    .trim_front = mynewt_nmgr_trim_front,
-    .reset_buf = mynewt_nmgr_reset_buf,
-    .write_at = mynewt_nmgr_write_at,
-    .init_reader = mynewt_nmgr_init_reader,
-    .init_writer = mynewt_nmgr_init_writer,
-    .free_buf = mynewt_nmgr_free_buf,
+#include "cbor_mbuf_reader.h"
+#include "cbor_mbuf_writer.h"
+#include "mynewt_smp/mynewt_smp.h"
+
+/* Shared queue that smp uses for work items. */
+struct os_eventq *smp_evq;
+
+static mgmt_alloc_rsp_fn mynewt_smp_alloc_rsp;
+static mgmt_trim_front_fn mynewt_smp_trim_front;
+static mgmt_reset_buf_fn mynewt_smp_reset_buf;
+static mgmt_write_at_fn mynewt_smp_write_at;
+static mgmt_init_reader_fn mynewt_smp_init_reader;
+static mgmt_init_writer_fn mynewt_smp_init_writer;
+static mgmt_free_buf_fn mynewt_smp_free_buf;
+static smp_tx_rsp_fn mynewt_smp_tx_rsp;
+
+static const struct mgmt_streamer_cfg mynewt_smp_cbor_cfg = {
+    .alloc_rsp = mynewt_smp_alloc_rsp,
+    .trim_front = mynewt_smp_trim_front,
+    .reset_buf = mynewt_smp_reset_buf,
+    .write_at = mynewt_smp_write_at,
+    .init_reader = mynewt_smp_init_reader,
+    .init_writer = mynewt_smp_init_writer,
+    .free_buf = mynewt_smp_free_buf,
 };
 
 /**
  * Allocates an mbuf to contain an outgoing response fragment.
  */
 static struct os_mbuf *
-mynewt_nmgr_rsp_frag_alloc(uint16_t frag_size, void *arg)
+mynewt_smp_rsp_frag_alloc(uint16_t frag_size, void *arg)
 {
     struct os_mbuf *src_rsp;
     struct os_mbuf *frag;
@@ -56,7 +56,7 @@ mynewt_nmgr_rsp_frag_alloc(uint16_t frag_size, void *arg)
 }
 
 static void *
-mynewt_nmgr_alloc_rsp(const void *req, void *arg)
+mynewt_smp_alloc_rsp(const void *req, void *arg)
 {
     const struct os_mbuf *om_req;
     struct os_mbuf *om_rsp;
@@ -76,7 +76,7 @@ mynewt_nmgr_alloc_rsp(const void *req, void *arg)
 }
 
 static int
-mynewt_nmgr_trim_front(void *buf, int len, void *arg)
+mynewt_smp_trim_front(void *buf, int len, void *arg)
 {
     struct os_mbuf *om;
 
@@ -86,7 +86,7 @@ mynewt_nmgr_trim_front(void *buf, int len, void *arg)
 }
 
 static void
-mynewt_nmgr_reset_buf(void *buf, void *arg)
+mynewt_smp_reset_buf(void *buf, void *arg)
 {
     struct os_mbuf *om;
 
@@ -95,8 +95,8 @@ mynewt_nmgr_reset_buf(void *buf, void *arg)
 }
 
 static int
-mynewt_nmgr_write_at(struct cbor_encoder_writer *writer, int offset,
-                     const void *data, int len, void *arg)
+mynewt_smp_write_at(struct cbor_encoder_writer *writer, int offset,
+                    const void *data, int len, void *arg)
 {
     struct cbor_mbuf_writer *mw;
     int rc;
@@ -113,8 +113,8 @@ mynewt_nmgr_write_at(struct cbor_encoder_writer *writer, int offset,
 }
 
 static int
-mynewt_nmgr_init_reader(struct cbor_decoder_reader *reader, void *buf,
-                        void *arg)
+mynewt_smp_init_reader(struct cbor_decoder_reader *reader, void *buf,
+                       void *arg)
 {
     struct cbor_mbuf_reader *mr;
 
@@ -125,8 +125,8 @@ mynewt_nmgr_init_reader(struct cbor_decoder_reader *reader, void *buf,
 }
 
 static int
-mynewt_nmgr_init_writer(struct cbor_encoder_writer *writer, void *buf,
-                        void *arg)
+mynewt_smp_init_writer(struct cbor_encoder_writer *writer, void *buf,
+                       void *arg)
 {
     struct cbor_mbuf_writer *mw;
 
@@ -137,31 +137,31 @@ mynewt_nmgr_init_writer(struct cbor_encoder_writer *writer, void *buf,
 }
 
 static int
-mynewt_nmgr_tx_rsp(struct nmgr_streamer *ns, void *rsp, void *arg)
+mynewt_smp_tx_rsp(struct smp_streamer *ss, void *rsp, void *arg)
 {
-    struct mynewt_nmgr_transport *mnt;
+    struct mynewt_smp_transport *msp;
     struct os_mbuf *om_rsp;
     struct os_mbuf *frag;
     uint16_t mtu;
     int rc;
 
-    mnt = arg;
+    msp = arg;
     om_rsp = rsp;
 
-    mtu = mnt->mnt_get_mtu(rsp);
+    mtu = msp->msp_get_mtu(rsp);
     if (mtu == 0) {
         /* The transport cannot support a transmission right now. */
         return MGMT_ERR_EUNKNOWN;
     }
 
     while (om_rsp != NULL) {
-        frag = mem_split_frag(&om_rsp, mtu, mynewt_nmgr_rsp_frag_alloc,
+        frag = mem_split_frag(&om_rsp, mtu, mynewt_smp_rsp_frag_alloc,
                               om_rsp);
         if (frag == NULL) {
             return MGMT_ERR_ENOMEM;
         }
 
-        rc = mnt->mnt_output(mnt, frag);
+        rc = msp->msp_output(msp, frag);
         if (rc != 0) {
             /* Output function already freed mbuf. */
             return MGMT_ERR_EUNKNOWN;
@@ -172,37 +172,37 @@ mynewt_nmgr_tx_rsp(struct nmgr_streamer *ns, void *rsp, void *arg)
 }
 
 static void
-mynewt_nmgr_free_buf(void *buf, void *arg)
+mynewt_smp_free_buf(void *buf, void *arg)
 {
     os_mbuf_free_chain(buf);
 }
 
 static void
-mynewt_nmgr_process(struct mynewt_nmgr_transport *mnt)
+mynewt_smp_process(struct mynewt_smp_transport *msp)
 {
     struct cbor_mbuf_reader reader;
     struct cbor_mbuf_writer writer;
-    struct nmgr_streamer streamer;
+    struct smp_streamer streamer;
     struct os_mbuf *req;
     int rc;
 
-    streamer = (struct nmgr_streamer) {
-        .ns_base = {
-            .cfg = &mynewt_nmgr_cbor_cfg,
+    streamer = (struct smp_streamer) {
+        .ss_base = {
+            .cfg = &mynewt_smp_cbor_cfg,
             .reader = &reader.r,
             .writer = &writer.enc,
-            .cb_arg = mnt,
+            .cb_arg = msp,
         },
-        .ns_tx_rsp = mynewt_nmgr_tx_rsp,
+        .ss_tx_rsp = mynewt_smp_tx_rsp,
     };
 
     while (1) {
-        req = os_mqueue_get(&mnt->mnt_imq);
+        req = os_mqueue_get(&msp->msp_imq);
         if (req == NULL) {
             break;
         }
 
-        rc = nmgr_process_single_packet(&streamer, req);
+        rc = smp_process_single_packet(&streamer, req);
         if (rc != 0) {
             break;
         }
@@ -210,24 +210,24 @@ mynewt_nmgr_process(struct mynewt_nmgr_transport *mnt)
 }
 
 static void
-mynewt_nmgr_event_data_in(struct os_event *ev)
+mynewt_smp_event_data_in(struct os_event *ev)
 {
-    mynewt_nmgr_process(ev->ev_arg);
+    mynewt_smp_process(ev->ev_arg);
 }
 
 int
-mynewt_nmgr_transport_init(struct mynewt_nmgr_transport *mnt,
-                           mynewt_nmgr_transport_out_fn *output_func,
-                           mynewt_nmgr_transport_get_mtu_fn *get_mtu_func)
+mynewt_smp_transport_init(struct mynewt_smp_transport *msp,
+                          mynewt_smp_transport_out_fn *output_func,
+                          mynewt_smp_transport_get_mtu_fn *get_mtu_func)
 {
     int rc;
 
-    *mnt = (struct mynewt_nmgr_transport) {
-        .mnt_output = output_func,
-        .mnt_get_mtu = get_mtu_func,
+    *msp = (struct mynewt_smp_transport) {
+        .msp_output = output_func,
+        .msp_get_mtu = get_mtu_func,
     };
 
-    rc = os_mqueue_init(&mnt->mnt_imq, mynewt_nmgr_event_data_in, mnt);
+    rc = os_mqueue_init(&msp->msp_imq, mynewt_smp_event_data_in, msp);
     if (rc != 0) {
         return rc;
     }
@@ -236,11 +236,11 @@ mynewt_nmgr_transport_init(struct mynewt_nmgr_transport *mnt,
 }
 
 int
-mynewt_nmgr_rx_req(struct mynewt_nmgr_transport *mnt, struct os_mbuf *req)
+mynewt_smp_rx_req(struct mynewt_smp_transport *msp, struct os_mbuf *req)
 {
     int rc;
 
-    rc = os_mqueue_put(&mnt->mnt_imq, mgmt_evq_get(), req);
+    rc = os_mqueue_put(&msp->msp_imq, mgmt_evq_get(), req);
     if (rc != 0) {
         os_mbuf_free_chain(req);
     }
@@ -251,17 +251,17 @@ mynewt_nmgr_rx_req(struct mynewt_nmgr_transport *mnt, struct os_mbuf *req)
 struct os_eventq *
 mgmt_evq_get(void)
 {
-    return nmgr_evq;
+    return smp_evq;
 }
 
 void
 mgmt_evq_set(struct os_eventq *evq)
 {
-    nmgr_evq = evq;
+    smp_evq = evq;
 }
 
 void
-nmgr_pkg_init(void)
+smp_pkg_init(void)
 {
     int rc;
 
diff --git a/smp/src/smp.c b/smp/src/smp.c
new file mode 100644
index 0000000..6caf653
--- /dev/null
+++ b/smp/src/smp.c
@@ -0,0 +1,404 @@
+/*
+ * 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.
+ */
+
+/** SMP - Simple Management Protocol. */
+
+#include <assert.h>
+#include <string.h>
+
+#include "mgmt/mgmt.h"
+#include "smp/smp.h"
+#include "tinycbor/cbor.h"
+#include "tinycbor/cbor_mbuf_writer.h"
+#include "tinycbor/cbor_mbuf_reader.h"
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+
+#ifndef ntohs
+#define ntohs(x) (x)
+#endif
+
+#ifndef htons
+#define htons(x) (x)
+#endif
+
+#else
+/* Little endian. */
+
+#ifndef ntohs
+#define ntohs(x)   ((uint16_t)  \
+    ((((x) & 0xff00) >> 8) |    \
+     (((x) & 0x00ff) << 8)))
+#endif
+
+#ifndef htons
+#define htons(x) (ntohs(x))
+#endif
+
+#endif
+
+static int
+smp_align4(int x)
+{
+    int rem;
+
+    rem = x % 4;
+    if (rem == 0) {
+        return x;
+    } else {
+        return x - rem + 4;
+    }
+}
+
+static uint8_t
+smp_rsp_op(uint8_t req_op)
+{
+    if (req_op == MGMT_OP_READ) {
+        return MGMT_OP_READ_RSP;
+    } else {
+        return MGMT_OP_WRITE_RSP;
+    }
+}
+
+static void
+smp_init_rsp_hdr(const struct mgmt_hdr *req_hdr, struct mgmt_hdr *rsp_hdr)
+{
+    *rsp_hdr = (struct mgmt_hdr) {
+        .nh_len = 0,
+        .nh_flags = 0,
+        .nh_op = smp_rsp_op(req_hdr->nh_op),
+        .nh_group = req_hdr->nh_group,
+        .nh_seq = req_hdr->nh_seq,
+        .nh_id = req_hdr->nh_id,
+    };
+}
+
+static int
+smp_read_hdr(struct smp_streamer *streamer, struct mgmt_hdr *dst_hdr)
+{
+    struct cbor_decoder_reader *reader;
+
+    reader = streamer->ss_base.reader;
+
+    if (reader->message_size < sizeof *hdr) {
+        return MGMT_ERR_EINVAL;
+    }
+
+    reader->cpy(reader, (char *)hdr, 0, sizeof *hdr);
+    return 0;
+}
+
+static int
+smp_write_hdr(struct smp_streamer *streamer, const struct mgmt_hdr *src_hdr)
+{
+    int rc;
+
+    rc = mgmt_streamer_write_at(&streamer->ss_base, 0, src_hdr,
+                                sizeof *src_hdr);
+    return mgmt_err_from_cbor(rc);
+}
+
+static int
+smp_build_err_rsp(struct smp_streamer *streamer,
+                  const struct mgmt_hdr *req_hdr,
+                  int status)
+{
+    struct CborEncoder map;
+    struct mgmt_cbuf cbuf;
+    struct mgmt_hdr rsp_hdr;
+    int rc;
+
+    rc = mgmt_cbuf_init(&cbuf, &streamer->ss_base);
+    if (rc != 0) {
+        return rc;
+    }
+
+    smp_init_rsp_hdr(req_hdr, &rsp_hdr);
+    rc = smp_write_hdr(streamer, &rsp_hdr);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = cbor_encoder_create_map(&cbuf.encoder, &map, CborIndefiniteLength);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = mgmt_cbuf_setoerr(&cbuf, status);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = cbor_encoder_close_container(&cbuf.encoder, &map);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rsp_hdr.nh_len = cbor_encode_bytes_written(&cbuf.encoder) - MGMT_HDR_SIZE;
+    mgmt_hton_hdr(&rsp_hdr);
+    rc = smp_write_hdr(streamer, &rsp_hdr);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+/**
+ * Processes a single SMP request and generates a response payload (i.e.,
+ * everything after the management header).  On success, the response payload
+ * is written to the supplied cbuf but not transmitted.  On failure, no error
+ * response gets written; the caller is expected to build an error response
+ * from the return code.
+ *
+ * @param cbuf                  A cbuf containing the request and response
+ *                                  buffer.
+ * @param req_hdr               The management header belonging to the incoming
+ *                                  request (host-byte order).
+ *
+ * @return                      A MGMT_ERR_[...] error code.
+ */
+int
+smp_handle_single_payload(struct mgmt_cbuf *cbuf,
+                          const struct mgmt_hdr *req_hdr)
+{
+    const struct mgmt_handler *handler;
+    struct CborEncoder payload_encoder;
+    int rc;
+
+    handler = mgmt_find_handler(req_hdr->nh_group, req_hdr->nh_id);
+    if (handler == NULL) {
+        return MGMT_ERR_ENOENT;
+    }
+
+    /* Begin response payload.  Response fields are inserted into the root
+     * map as key value pairs.
+     */
+    rc = cbor_encoder_create_map(&cbuf->encoder, &payload_encoder,
+                                 CborIndefiniteLength);
+    rc = mgmt_err_from_cbor(rc);
+    if (rc != 0) {
+        return rc;
+    }
+
+    switch (req_hdr->nh_op) {
+    case MGMT_OP_READ:
+        if (handler->mh_read != NULL) {
+            rc = handler->mh_read(cbuf);
+        } else {
+            rc = MGMT_ERR_ENOENT;
+        }
+        break;
+
+    case MGMT_OP_WRITE:
+        if (handler->mh_write != NULL) {
+            rc = handler->mh_write(cbuf);
+        } else {
+            rc = MGMT_ERR_ENOENT;
+        }
+        break;
+
+    default:
+        rc = MGMT_ERR_EINVAL;
+        break;
+    }
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* End response payload. */
+    rc = cbor_encoder_close_container(&cbuf->encoder, &payload_encoder);
+    return mgmt_err_from_cbor(rc);
+}
+
+/**
+ * Processes a single SMP request and generates a complete response (i.e.,
+ * header and payload).  On success, the response is written using the supplied
+ * streamer but not transmitted.  On failure, no error response gets written;
+ * the caller is expected to build an error response from the return code.
+ *
+ * @param streamer              The SMP streamer to use for reading the request
+ *                                  and writing the response.
+ * @param req_hdr               The management header belonging to the incoming
+ *                                  request (host-byte order).
+ *
+ * @return                      A MGMT_ERR_[...] error code.
+ */
+static int
+smp_handle_single_req(struct smp_streamer *streamer,
+                      const struct mgmt_hdr *req_hdr)
+{
+    struct mgmt_cbuf cbuf;
+    struct mgmt_hdr rsp_hdr;
+    int rc;
+
+    rc = mgmt_cbuf_init(&cbuf, &streamer->ss_base);
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Write a dummy header to the beginning of the response buffer.  Some
+     * fields will need to be fixed up later.
+     */
+    smp_init_rsp_hdr(req_hdr, &rsp_hdr);
+    rc = smp_write_hdr(streamer, &rsp_hdr);
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Process the request and write the response payload. */
+    rc = smp_handle_single_payload(&cbuf, req_hdr);
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Fix up the response header with the correct length. */
+    rsp_hdr.nh_len = cbor_encode_bytes_written(&cbuf.encoder) - MGMT_HDR_SIZE;
+    mgmt_hton_hdr(&rsp_hdr);
+    rc = smp_write_hdr(streamer, &rsp_hdr);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+/**
+ * Attempts to transmit an SMP error response.  This function consumes both
+ * supplied buffers.
+ *
+ * @param streamer              The SMP streamer for building and transmitting
+ *                                  the response.
+ * @param req_hdr               The header of the request which elicited the
+ *                                  error.
+ * @param req                   The buffer holding the request.
+ * @param rsp                   The buffer holding the response, or NULL if
+ *                                  none was allocated.
+ * @param status                The status to indicate in the error response.
+ */
+static void
+smp_on_err(struct smp_streamer *streamer, const struct mgmt_hdr *req_hdr,
+           void *req, void *rsp, int status)
+{
+    int rc;
+
+    /* Prefer the response buffer for holding the error response.  If no
+     * response buffer was allocated, use the request buffer instead.
+     */
+    if (rsp == NULL) {
+        rsp = req;
+        req = NULL;
+    }
+
+    /* Clear the partial response from the buffer, if any. */
+    mgmt_streamer_reset_buf(&streamer->ss_base, rsp);
+    mgmt_streamer_init_writer(&streamer->ss_base, rsp);
+
+    /* Build and transmit the error response. */
+    rc = smp_build_err_rsp(streamer, req_hdr, status);
+    if (rc == 0) {
+        streamer->ss_tx_rsp(streamer, rsp, streamer->ss_base.cb_arg);
+        rsp = NULL;
+    }
+
+    /* Free any extra buffers. */
+    mgmt_streamer_free_buf(&streamer->ss_base, req);
+    mgmt_streamer_free_buf(&streamer->ss_base, rsp);
+}
+
+/**
+ * Processes all SMP requests in an incoming packet.  Requests are processed
+ * sequentially from the start of the packet to the end.  Each response is sent
+ * individually in its own packet.  If a request elicits an error response,
+ * processing of the packet is aborted.  This function consumes the supplied
+ * request buffer regardless of the outcome.
+ *
+ * @param streamer              The streamer to use for reading, writing, and
+ *                                  transmitting.
+ * @param req                   A buffer containing the request packet.
+ *
+ * @return                      A MGMT_ERR_[...] error code.
+ */
+int
+smp_process_single_packet(struct smp_streamer *streamer, void *req)
+{
+    struct mgmt_hdr req_hdr;
+    void *rsp;
+    bool valid_hdr;
+    int rc;
+
+    rsp = NULL;
+    valid_hdr = true;
+
+    while (1) {
+        rc = mgmt_streamer_init_reader(&streamer->ss_base, req);
+        if (rc != 0) {
+            valid_hdr = false;
+            break;
+        }
+
+        /* Read the management header and strip it from the request. */
+        rc = smp_read_hdr(streamer, &req_hdr);
+        if (rc != 0) {
+            valid_hdr = false;
+            break;
+        }
+        mgmt_ntoh_hdr(&req_hdr);
+        rc = mgmt_streamer_trim_front(&streamer->ss_base, req, MGMT_HDR_SIZE);
+        assert(rc == 0);
+
+        rsp = mgmt_streamer_alloc_rsp(&streamer->ss_base, req);
+        if (rsp == NULL) {
+            rc = MGMT_ERR_ENOMEM;
+            break;
+        }
+
+        rc = mgmt_streamer_init_writer(&streamer->ss_base, rsp);
+        if (rc != 0) {
+            break;
+        }
+
+        /* Process the request payload and build the response. */
+        rc = smp_handle_single_req(streamer, &req_hdr);
+        if (rc != 0) {
+            break;
+        }
+
+        /* Send the response. */
+        rc = streamer->ss_tx_rsp(streamer, rsp, streamer->ss_base.cb_arg);
+        rsp = NULL;
+        if (rc != 0) {
+            break;
+        }
+
+        /* Trim processed request to free up space for subsequent responses. */
+        rc = mgmt_streamer_trim_front(&streamer->ss_base, req,
+                                      smp_align4(req_hdr.nh_len));
+        assert(rc == 0);
+    }
+
+    if (rc != 0 && valid_hdr) {
+        smp_on_err(streamer, &req_hdr, req, rsp, rc);
+        return rc;
+    }
+
+    mgmt_streamer_free_buf(&streamer->ss_base, req);
+    mgmt_streamer_free_buf(&streamer->ss_base, rsp);
+    return 0;
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@mynewt.apache.org" <co...@mynewt.apache.org>.