static void
ble_att_clt_test_misc_verify_tx_write(uint16_t handle_id, void *value,
                                      int value_len, int is_req)
{
    struct ble_att_write_req req;
    struct os_mbuf *om;
    int rc;

    TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx != NULL);

    om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
                        OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx));
    TEST_ASSERT_FATAL(om != NULL);

    if (is_req) {
        rc = ble_att_write_req_parse(om->om_data, om->om_len, &req);
    } else {
        rc = ble_att_write_cmd_parse(om->om_data, om->om_len, &req);
    }
    TEST_ASSERT_FATAL(rc == 0);

    TEST_ASSERT(req.bawq_handle == handle_id);
    TEST_ASSERT(om->om_len == BLE_ATT_WRITE_REQ_BASE_SZ + value_len);
    TEST_ASSERT(memcmp(om->om_data + BLE_ATT_WRITE_REQ_BASE_SZ, value,
                       value_len) == 0);
}
static void
ble_att_clt_test_misc_exec_good(uint8_t flags)
{
    struct ble_att_exec_write_req req;
    struct ble_l2cap_chan *chan;
    struct ble_hs_conn *conn;
    struct os_mbuf *om;
    int rc;

    ble_att_clt_test_misc_init(&conn, &chan);

    req.baeq_flags = flags;
    rc = ble_att_clt_tx_exec_write(conn->bhc_handle, &req);
    TEST_ASSERT(rc == 0);

    ble_hs_test_util_tx_all();
    TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx != NULL);

    om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
                        OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx));
    TEST_ASSERT_FATAL(om != NULL);
    TEST_ASSERT(om->om_len == BLE_ATT_EXEC_WRITE_REQ_SZ);

    ble_att_exec_write_req_parse(om->om_data, om->om_len, &req);
    TEST_ASSERT(req.baeq_flags == flags);
}
static void
ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset,
                                uint8_t *attr_data, uint16_t attr_data_len)
{
    struct ble_att_prep_write_cmd req;
    struct ble_l2cap_chan *chan;
    struct ble_hs_conn *conn;
    struct os_mbuf *om;
    int rc;
    int i;

    ble_att_clt_test_misc_init(&conn, &chan);

    req.bapc_handle = handle;
    req.bapc_offset = offset;
    rc = ble_att_clt_tx_prep_write(conn->bhc_handle, &req, attr_data,
                                   attr_data_len);
    TEST_ASSERT(rc == 0);

    ble_hs_test_util_tx_all();
    TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx != NULL);

    om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
                        OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx));
    TEST_ASSERT_FATAL(om != NULL);
    TEST_ASSERT(om->om_len == BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len);

    ble_att_prep_write_req_parse(om->om_data, om->om_len, &req);
    TEST_ASSERT(req.bapc_handle == handle);
    TEST_ASSERT(req.bapc_offset == offset);
    for (i = 0; i < attr_data_len; i++) {
        TEST_ASSERT(om->om_data[BLE_ATT_PREP_WRITE_CMD_BASE_SZ + i] ==
                    attr_data[i]);
    }
}
static void
ble_gatt_find_s_test_misc_verify_tx_read_type(uint16_t start_handle,
                                              uint16_t end_handle)
{
    struct ble_att_read_type_req req;
    struct os_mbuf *om;
    uint16_t uuid16;
    int rc;

    ble_hs_test_util_tx_all();

    TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx != NULL);

    om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
                        OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx));
    TEST_ASSERT_FATAL(om != NULL);

    rc = ble_att_read_type_req_parse(om->om_data, om->om_len, &req);
    TEST_ASSERT(rc == 0);

    TEST_ASSERT(req.batq_start_handle == start_handle);
    TEST_ASSERT(req.batq_end_handle == end_handle);
    TEST_ASSERT(om->om_len == BLE_ATT_READ_TYPE_REQ_BASE_SZ + 2);
    uuid16 = le16toh(om->om_data + BLE_ATT_READ_TYPE_REQ_BASE_SZ);
    TEST_ASSERT(uuid16 == BLE_ATT_UUID_INCLUDE);
}
static void
ble_gatt_find_s_test_misc_verify_tx_read(uint16_t handle)
{
    struct ble_att_read_req req;
    struct os_mbuf *om;
    int rc;

    ble_hs_test_util_tx_all();

    TEST_ASSERT_FATAL(ble_hs_test_util_prev_tx != NULL);

    om = os_mbuf_pullup(ble_hs_test_util_prev_tx,
                        OS_MBUF_PKTLEN(ble_hs_test_util_prev_tx));
    TEST_ASSERT_FATAL(om != NULL);

    rc = ble_att_read_req_parse(om->om_data, om->om_len, &req);
    TEST_ASSERT(rc == 0);

    TEST_ASSERT(req.barq_handle == handle);
    TEST_ASSERT(om->om_len == BLE_ATT_READ_REQ_SZ);
}
/*
 * 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);
}