Skip to content

Commit 447ea43

Browse files
committed
Add timeout and overflow check in RX buffer handling to prevent hang on disconnect
1 parent bc14d3e commit 447ea43

File tree

1 file changed

+4
-13
lines changed

1 file changed

+4
-13
lines changed

src/pio_usb.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)(
178178
bool crc_match = false;
179179
int16_t t = 240;
180180
uint16_t idx = 0;
181+
uint16_t nak_timeout = 10000;
182+
const uint16_t rx_buf_len = sizeof(pp->usb_rx_buffer) / sizeof(pp->usb_rx_buffer[0]);
181183

182184
while (t--) {
183185
if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) {
@@ -192,25 +194,18 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)(
192194
// timing critical start
193195
if (t > 0) {
194196
if (handshake == USB_PID_ACK) {
195-
uint32_t timeout = 240;
196-
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && timeout--) {
197+
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && idx < rx_buf_len - 1) {
197198
if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) {
198199
uint8_t data = pio_sm_get(pp->pio_usb_rx, pp->sm_rx) >> 24;
199200
crc_prev2 = crc_prev;
200201
crc_prev = crc;
201202
crc = update_usb_crc16(crc, data);
202-
if (idx > (sizeof(pp->usb_rx_buffer) / sizeof(pp->usb_rx_buffer[0]))) {
203-
return -1;
204-
}
205203
pp->usb_rx_buffer[idx++] = data;
206204
crc_receive = (crc_receive >> 8) | (data << 8);
207205
crc_receive_inverse = crc_receive ^ 0xffff;
208206
crc_match = (crc_receive_inverse == crc_prev2);
209207
}
210208
}
211-
if (timeout == 0) {
212-
return -1;
213-
}
214209

215210
if (idx >= 4 && crc_match) {
216211
pio_usb_bus_send_handshake(pp, USB_PID_ACK);
@@ -219,14 +214,10 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)(
219214
}
220215
} else {
221216
// just discard received data since we NAK/STALL anyway
222-
uint32_t timeout = 240;
223-
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && timeout--) {
217+
while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && nak_timeout--) {
224218
continue;
225219
}
226220
pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx);
227-
if (timeout == 0) {
228-
return -1;
229-
}
230221

231222
pio_usb_bus_send_handshake(pp, handshake);
232223
}

0 commit comments

Comments
 (0)