int nm_chr_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, union ble_gatt_access_ctxt *ctxt, void *arg) { struct nmgr_transport *nt; struct os_mbuf *om; int rc; assert(attr_handle == nm_attr_val_handle); om = NULL; if (op != BLE_GATT_ACCESS_OP_WRITE_CHR) { rc = BLE_ATT_ERR_WRITE_NOT_PERMITTED; goto err; } om = os_msys_get_pkthdr(ctxt->chr_access.len, 2); if (om == NULL) { rc = 1; goto err; } /* Put the connection handle in the request packet header. */ memcpy(OS_MBUF_USRHDR(om), &conn_handle, sizeof conn_handle); rc = os_mbuf_append(om, ctxt->chr_access.data, ctxt->chr_access.len); if (rc != 0) { goto err; } nt = arg; rc = nmgr_rx_req(nt, om); return rc; err: os_mbuf_free_chain(om); 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; } }
static int nmgr_shell_in(struct os_mbuf *m, void *arg) { return nmgr_rx_req(&nmgr_shell_transport, m); }
/* * Check for full packet. If frame is not right, free the mbuf. */ static void nmgr_uart_rx_pkt(struct nmgr_uart_state *nus, struct os_mbuf_pkthdr *rxm) { struct os_mbuf *m; struct nmgr_ser_hdr *nsh; uint16_t crc; int rc; m = OS_MBUF_PKTHDR_TO_MBUF(rxm); if (rxm->omp_len <= sizeof(uint16_t) + sizeof(crc)) { goto err; } nsh = (struct nmgr_ser_hdr *)m->om_data; switch (nsh->nsh_seq) { case htons(SHELL_NLIP_PKT): if (nus->nus_rx_pkt) { os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt)); nus->nus_rx_pkt = NULL; } break; case htons(SHELL_NLIP_DATA): if (!nus->nus_rx_pkt) { goto err; } break; default: goto err; } if (os_mbuf_append(m, "\0", 1)) { /* * Null-terminate the line for base64_decode's sake. */ goto err; } m = os_mbuf_pullup(m, rxm->omp_len); if (!m) { /* * Make data contiguous for base64_decode's sake. */ goto err; } rxm = OS_MBUF_PKTHDR(m); rc = base64_decode((char *)m->om_data + 2, (char *)m->om_data + 2); if (rc < 0) { goto err; } rxm->omp_len = m->om_len = rc + 2; if (nus->nus_rx_pkt) { os_mbuf_adj(m, 2); os_mbuf_concat(OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt), m); } else { nus->nus_rx_pkt = rxm; } m = OS_MBUF_PKTHDR_TO_MBUF(nus->nus_rx_pkt); nsh = (struct nmgr_ser_hdr *)m->om_data; if (nus->nus_rx_pkt->omp_len - sizeof(*nsh) == ntohs(nsh->nsh_len)) { os_mbuf_adj(m, 4); os_mbuf_adj(m, -2); nmgr_rx_req(&nus->nus_transport, m); nus->nus_rx_pkt = NULL; } return; err: os_mbuf_free_chain(m); }