static int h4_open(void) { BT_DBG(""); uart_irq_rx_disable(h4_dev); uart_irq_tx_disable(h4_dev); #if defined(CONFIG_BT_NRF51_PM) if (nrf51_init(h4_dev) < 0) { return -EIO; } #else h4_discard(h4_dev, 32); #endif uart_irq_callback_set(h4_dev, bt_uart_isr); k_thread_create(&rx_thread_data, rx_thread_stack, K_THREAD_STACK_SIZEOF(rx_thread_stack), rx_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT); return 0; }
static inline void process_rx(void) { BT_DBG("remaining %u discard %u have_hdr %u rx.buf %p len %u", rx.remaining, rx.discard, rx.have_hdr, rx.buf, rx.buf ? rx.buf->len : 0); if (rx.discard) { rx.discard -= h4_discard(h4_dev, rx.discard); return; } if (rx.have_hdr) { read_payload(); } else { read_header(); } }
static void bt_uart_isr(struct device *unused) { static struct net_buf *buf; static int remaining; ARG_UNUSED(unused); while (uart_irq_update(h4_dev) && uart_irq_is_pending(h4_dev)) { int read; if (!uart_irq_rx_ready(h4_dev)) { if (uart_irq_tx_ready(h4_dev)) { BT_DBG("transmit ready"); } else { BT_DBG("spurious interrupt"); } continue; } /* Beginning of a new packet */ if (!remaining) { uint8_t type; /* Get packet type */ read = h4_read(h4_dev, &type, sizeof(type), 0); if (read != sizeof(type)) { BT_WARN("Unable to read H4 packet type"); continue; } switch (type) { case H4_EVT: buf = h4_evt_recv(&remaining); break; case H4_ACL: buf = h4_acl_recv(&remaining); break; default: BT_ERR("Unknown H4 type %u", type); return; } BT_DBG("need to get %u bytes", remaining); if (buf && remaining > net_buf_tailroom(buf)) { BT_ERR("Not enough space in buffer"); net_buf_unref(buf); buf = NULL; } } if (!buf) { read = h4_discard(h4_dev, remaining); BT_WARN("Discarded %d bytes", read); remaining -= read; continue; } read = h4_read(h4_dev, net_buf_tail(buf), remaining, 0); buf->len += read; remaining -= read; BT_DBG("received %d bytes", read); if (!remaining) { BT_DBG("full packet received"); /* Pass buffer to the stack */ bt_recv(buf); buf = NULL; } } }