static int
nmgr_send_rspfrag(struct nmgr_transport *nt, struct os_mbuf *rsp,
                  struct os_mbuf *req, uint16_t len)
{
    struct os_mbuf *rspfrag;
    int rc;

    rspfrag = NULL;

    rspfrag = os_msys_get_pkthdr(len, OS_MBUF_USRHDR_LEN(req));
    if (!rspfrag) {
        rc = MGMT_ERR_ENOMEM;
        goto err;
    }

    /* Copy the request packet header into the response. */
    memcpy(OS_MBUF_USRHDR(rspfrag), OS_MBUF_USRHDR(req),
           OS_MBUF_USRHDR_LEN(req));

    if (os_mbuf_appendfrom(rspfrag, rsp, 0, len)) {
        rc = MGMT_ERR_ENOMEM;
        goto err;
    }

    nt->nt_output(nt, rspfrag);

    return MGMT_ERR_EOK;
err:
    if (rspfrag) {
        os_mbuf_free_chain(rspfrag);
    }
    return rc;
}
static int
gatt_svr_chr_access_newtmgr(uint16_t conn_handle, uint16_t attr_handle,
                            struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    int rc;
    struct os_mbuf *m_req;

    switch (ctxt->op) {
        case BLE_GATT_ACCESS_OP_WRITE_CHR:
            /* Try to reuse the BLE packet mbuf as the newtmgr request.  This
             * requires a two-byte usrhdr to hold the BLE connection handle so
             * that the newtmgr response can be sent to the correct peer.  If
             * it is not possible to reuse the mbuf, then allocate a new one
             * and copy the request contents.
             */
            if (OS_MBUF_USRHDR_LEN(ctxt->om) >= sizeof (conn_handle)) {
                /* Sufficient usrhdr space already present. */
                m_req = ctxt->om;
                ctxt->om = NULL;
            } else if (OS_MBUF_LEADINGSPACE(ctxt->om) >=
                       sizeof (conn_handle)) {

                /* Usrhdr isn't present, but there is enough leading space to
                 * add one.
                 */
                m_req = ctxt->om;
                ctxt->om = NULL;

                m_req->om_pkthdr_len += sizeof (conn_handle);
            } else {
                /* The mbuf can't be reused.  Allocate a new one and perform a
                 * copy.  Don't set ctxt->om to NULL; let the NimBLE host free
                 * it.
                 */
                m_req = os_msys_get_pkthdr(OS_MBUF_PKTLEN(ctxt->om),
                                           sizeof (conn_handle));
                if (!m_req) {
                    return BLE_ATT_ERR_INSUFFICIENT_RES;
                }
                rc = os_mbuf_appendfrom(m_req, ctxt->om, 0,
                                        OS_MBUF_PKTLEN(ctxt->om));
                if (rc) {
                    return BLE_ATT_ERR_INSUFFICIENT_RES;
                }
            }

            /* Write the connection handle to the newtmgr request usrhdr.  This
             * is necessary so that we later know who to send the newtmgr
             * response to.
             */
            memcpy(OS_MBUF_USRHDR(m_req), &conn_handle, sizeof(conn_handle));

            rc = nmgr_rx_req(&ble_nt, m_req);
            if (rc != 0) {
                return BLE_ATT_ERR_UNLIKELY;
            }
            return 0;

        default:
            assert(0);
            return BLE_ATT_ERR_UNLIKELY;
    }
}