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 d03e76c77eb1c4bb0b3da54d2b099c3435868cfa Author: Christopher Collins <ccoll...@apache.org> AuthorDate: Thu Jan 4 13:24:35 2018 -0800 zephyr - fragmentation of overly long responses. --- smp/port/zephyr/include/zephyr_smp/zephyr_smp.h | 13 ++++- smp/port/zephyr/src/zephyr_smp.c | 72 +++++++++++++++---------- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/smp/port/zephyr/include/zephyr_smp/zephyr_smp.h b/smp/port/zephyr/include/zephyr_smp/zephyr_smp.h index d74e8c4..c05ef01 100644 --- a/smp/port/zephyr/include/zephyr_smp/zephyr_smp.h +++ b/smp/port/zephyr/include/zephyr_smp/zephyr_smp.h @@ -14,7 +14,18 @@ struct zephyr_nmgr_pkt; */ typedef int zephyr_smp_transport_out_fn(struct zephyr_smp_transport *zst, struct zephyr_nmgr_pkt *pkt); -typedef uint16_t zephyr_smp_transport_get_mtu_fn(void); + +/** + * MTU query function. The supplied packet should contain a request received + * from the peer whose MTU is being queried. This function takes a packet + * parameter because some transports store connection-specific information in + * the packet (e.g., the BLE transport stores the connection pointer). + * + * @return The transport's MTU; + * 0 if transmission is currently not possible. + */ +typedef uint16_t +zephyr_smp_transport_get_mtu_fn(const struct zephyr_nmgr_pkt *pkt); struct zephyr_smp_transport { /* Must be the first member. */ diff --git a/smp/port/zephyr/src/zephyr_smp.c b/smp/port/zephyr/src/zephyr_smp.c index 2262397..759006d 100644 --- a/smp/port/zephyr/src/zephyr_smp.c +++ b/smp/port/zephyr/src/zephyr_smp.c @@ -23,32 +23,6 @@ static const struct mgmt_streamer_cfg zephyr_smp_cbor_cfg = { .free_buf = zephyr_smp_free_buf, }; -#if 0 -/** - * Allocates an mbuf to contain an outgoing response fragment. - */ -static struct os_mbuf * -zephyr_smp_rsp_frag_alloc(uint16_t frag_size, void *arg) -{ - struct os_mbuf *src_rsp; - struct os_mbuf *frag; - - /* We need to duplicate the user header from the source response, as that - * is where transport-specific information is stored. - */ - src_rsp = arg; - - frag = os_msys_get_pkthdr(frag_size, OS_MBUF_USRHDR_LEN(src_rsp)); - if (frag != NULL) { - /* Copy the user header from the response into the fragment mbuf. */ - memcpy(OS_MBUF_USRHDR(frag), OS_MBUF_USRHDR(src_rsp), - OS_MBUF_USRHDR_LEN(src_rsp)); - } - - return frag; -} -#endif - static void * zephyr_smp_alloc_rsp(const void *req, void *arg) { @@ -68,6 +42,29 @@ zephyr_smp_alloc_rsp(const void *req, void *arg) return rsp_pkt; } +static struct zephyr_nmgr_pkt * +zephyr_smp_split_frag(struct zephyr_nmgr_pkt **pkt, uint16_t mtu) +{ + struct zephyr_nmgr_pkt *frag; + struct zephyr_nmgr_pkt *src; + + src = *pkt; + + if (src->len <= mtu) { + *pkt = NULL; + frag = src; + } else { + frag = zephyr_smp_alloc_rsp(src, NULL); + frag->len = mtu; + memcpy(frag->data, src->data, mtu); + + src->len -= mtu; + memmove(src->data, src->data + mtu, src->len); + } + + return frag; +} + static int zephyr_smp_trim_front(void *buf, int len, void *arg) { @@ -126,18 +123,35 @@ static int zephyr_smp_tx_rsp(struct smp_streamer *ns, void *rsp, void *arg) { struct zephyr_smp_transport *zst; + struct zephyr_nmgr_pkt *frag; struct zephyr_nmgr_pkt *pkt; + uint16_t mtu; int rc; + int i; zst = arg; pkt = rsp; - rc = zst->zst_output(zst, pkt); - if (rc != 0) { + mtu = zst->zst_get_mtu(rsp); + if (mtu == 0) { + /* The transport cannot support a transmission right now. */ return MGMT_ERR_EUNKNOWN; } - return MGMT_ERR_EOK; + i = 0; + while (pkt != NULL) { + frag = zephyr_smp_split_frag(&pkt, mtu); + if (frag == NULL) { + return MGMT_ERR_ENOMEM; + } + + rc = zst->zst_output(zst, frag); + if (rc != 0) { + return MGMT_ERR_EUNKNOWN; + } + } + + return 0; } static void -- To stop receiving notification emails like this one, please contact "commits@mynewt.apache.org" <commits@mynewt.apache.org>.