static void rx_thread(void *p1, void *p2, void *p3) { struct net_buf *buf; ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); BT_DBG("started"); while (1) { BT_DBG("rx.buf %p", rx.buf); /* We can only do the allocation if we know the initial * header, since Command Complete/Status events must use the * original command buffer (if available). */ if (rx.have_hdr && !rx.buf) { rx.buf = get_rx(K_FOREVER); BT_DBG("Got rx.buf %p", rx.buf); if (rx.remaining > net_buf_tailroom(rx.buf)) { BT_ERR("Not enough space in buffer"); rx.discard = rx.remaining; reset_rx(); } else { copy_hdr(rx.buf); } } /* Let the ISR continue receiving new packets */ uart_irq_rx_enable(h4_dev); buf = net_buf_get(&rx.fifo, K_FOREVER); do { uart_irq_rx_enable(h4_dev); BT_DBG("Calling bt_recv(%p)", buf); bt_recv(buf); /* Give other threads a chance to run if the ISR * is receiving data so fast that rx.fifo never * or very rarely goes empty. */ k_yield(); uart_irq_rx_disable(h4_dev); buf = net_buf_get(&rx.fifo, K_NO_WAIT); } while (buf); } }
/** * @fn static BOOL rcv_snd(void) * @brief Receive a data and send a data */ L1CODE static BOOL rcv_snd(void) { if ( mnTxCount <= 0 && mnRxCount <= 1 ) { /* transfer end */ /* CS disable */ if( mpCurConfig->mnCS >= 0 ) *pSPI0_FLG &= ~( 1 << ( mpCurConfig->mnCS ) ); /* SPI disable */ *pSPI0_CTL = 0; ssync(); /* Get rest of one rx message, if there is. */ get_rx(); /* Complete! */ mpCurConfig = 0; return FALSE; } else { /* transfer continue */ /* Send tx */ snd(); if (!get_rx() ) { /* get dummy data for trigger */ volatile UH dummy = *pSPI0_RDBR; } return TRUE; } }
static inline void read_payload(void) { struct net_buf *buf; bool prio; int read; if (!rx.buf) { rx.buf = get_rx(K_NO_WAIT); if (!rx.buf) { if (rx.discardable) { BT_WARN("Discarding event 0x%02x", rx.evt.evt); rx.discard = rx.remaining; reset_rx(); return; } BT_WARN("Failed to allocate, deferring to rx_thread"); uart_irq_rx_disable(h4_dev); return; } BT_DBG("Allocated rx.buf %p", rx.buf); if (rx.remaining > net_buf_tailroom(rx.buf)) { BT_ERR("Not enough space in buffer"); rx.discard = rx.remaining; reset_rx(); return; } copy_hdr(rx.buf); } read = uart_fifo_read(h4_dev, net_buf_tail(rx.buf), rx.remaining); net_buf_add(rx.buf, read); rx.remaining -= read; BT_DBG("got %d bytes, remaining %u", read, rx.remaining); BT_DBG("Payload (len %u): %s", rx.buf->len, bt_hex(rx.buf->data, rx.buf->len)); if (rx.remaining) { return; } prio = (rx.type == H4_EVT && bt_hci_evt_is_prio(rx.evt.evt)); buf = rx.buf; rx.buf = NULL; if (rx.type == H4_EVT) { bt_buf_set_type(buf, BT_BUF_EVT); } else { bt_buf_set_type(buf, BT_BUF_ACL_IN); } reset_rx(); if (prio) { BT_DBG("Calling bt_recv_prio(%p)", buf); bt_recv_prio(buf); } else { BT_DBG("Putting buf %p to rx fifo", buf); net_buf_put(&rx.fifo, buf); } }
void dispatcher(void) { struct pollfd fds[2]; unsigned int msglen; int rc, err; memset(fds, 0, sizeof(fds)); fds[0].fd = sockpkt; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = -1; fds[1].events = 0; fds[1].revents = 0; for (;;) { flog(LOG_WARNING, "poll continue"); rc = poll(fds, sizeof(fds)/sizeof(fds[0]), DISPATCH_TIMEOUT); if (rc > 0) { if ( fds[0].revents & (POLLERR | POLLHUP | POLLNVAL) || fds[1].revents & (POLLERR | POLLHUP | POLLNVAL) ) { flog(LOG_WARNING, "Major socket error on fds[0 or 1].fd"); // Try and recover close(sockpkt); close(sockicmp); // Allow a moment for things to maybe return to normal... sleep(1); err = init_sockets(); if (err) { flog(LOG_ERR, "init_sockets: failed to reinitialise one or both sockets."); exit(1); } memset(fds, 0, sizeof(fds)); fds[0].fd = sockpkt; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = -1; fds[1].events = 0; fds[1].revents = 0; continue; } else if (fds[0].revents & POLLIN) { msglen = get_rx(msgdata, sockpkt, 0); // msglen is checked for sanity already within get_rx() flog(LOG_DEBUG2, "get_rx() gave msg with len = %d", msglen); // Have processNS() do the rest of validation and work... if (0 < msglen) { flog(LOG_DEBUG2, "processNS begin"); processNS(msgdata, msglen); flog(LOG_DEBUG2, "processNS end"); } continue; } else if ( rc == 0 ) { flog(LOG_DEBUG, "Timer event"); // Timer fired? // One day. If we implement timers. } else if ( rc == -1 ) { flog(LOG_ERR, "Weird poll error: %s", strerror(errno)); continue; } flog(LOG_DEBUG, "Timed out of poll(). Timeout was %d ms", DISPATCH_TIMEOUT); } } }