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; } }