Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion bumble/transport/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,32 @@ async def dequeue(self):
return
if self.sink:
try:
self.sink.on_packet(packet)
packet_type = packet[0]
len_packet = len(packet)
# A single USB interrupt transfer may contain multiple HCI events concatenated.
# Go through the packet buffer and dispatch each complete event individually so
# that no packet is silently discarded due to being concatenated with another packet.
if (
packet_type == hci.HCI_EVENT_PACKET
and len_packet > 3 + packet[2]
):
offset = 1 # skip the prepended packet_type byte
hci_event_header_len = 2 # event_code (1) + param_len (1)
while offset < len_packet:
if (
offset + hci_event_header_len > len_packet
): # incomplete header
break
param_len = packet[offset + 1]
end = offset + hci_event_header_len + param_len
if end > len_packet: # incomplete packet
break
self.sink.on_packet(
bytes([packet_type]) + packet[offset:end]
)
offset = end
else:
self.sink.on_packet(packet)
except Exception:
logger.exception(
color('!!! Exception in sink.on_packet', 'red')
Expand Down
Loading