Skip to content

Commit 086398d

Browse files
authored
Merge pull request #10 from dhalbert/robust-packet-reading
Robust packet reading
2 parents e130852 + 1347bbe commit 086398d

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

adafruit_bluefruit_connect/location_packet.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ class LocationPacket(Packet):
4040
PACKET_LENGTH = struct.calcsize(_FMT_PARSE)
4141
# _FMT_CONSTRUCT doesn't include the trailing checksum byte.
4242
_FMT_CONSTRUCT = '<2sfff'
43-
PACKET_LENGTH = struct.calcsize(_FMT_CONSTRUCT)
4443
_TYPE_HEADER = b'!L'
4544

4645
def __init__(self, latitude, longitude, altitude):

adafruit_bluefruit_connect/packet.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,9 @@ def from_bytes(cls, packet):
7373
"""
7474
if len(packet) < 3:
7575
raise ValueError("Packet too short")
76-
header = packet[0:2]
77-
packet_class = cls._type_to_class.get(header, None)
76+
packet_class = cls._type_to_class.get(packet[0:2], None)
7877
if not packet_class:
79-
raise ValueError("Unknown packet header '{}'".format(header))
78+
raise ValueError("Unregistered packet type {}".format(packet[0:2]))
8079

8180
# In case this was called from a subclass, make sure the parsed
8281
# type matches up with the current class.
@@ -103,14 +102,28 @@ def from_stream(cls, stream):
103102
:param stream stream: an input stream that provides standard stream read operations,
104103
such as ``ble.UARTServer`` or ``busio.UART``.
105104
"""
106-
header = stream.read(2)
107-
if len(header) != 2 or header[0] != ord(b'!'):
108-
# Remove any other junk already read.
109-
stream.reset_input_buffer()
110-
return None
105+
# Loop looking for a b'!' packet start. If the buffer has overflowed,
106+
# or there's been some other problem, we may need to skip some characters
107+
# to get to a packet start.
108+
while True:
109+
start = stream.read(1)
110+
if not start:
111+
# Timeout: nothing read.
112+
return None
113+
if start == b'!':
114+
# Found start of packet.
115+
packet_type = stream.read(1)
116+
if not packet_type:
117+
# Timeout: nothing more read.
118+
return None
119+
else:
120+
break
121+
# Didn't find a packet start. Loop and try again.
122+
123+
header = start + packet_type
111124
packet_class = cls._type_to_class.get(header, None)
112125
if not packet_class:
113-
raise ValueError("Unknown packet header {}".format(header))
126+
raise ValueError("Unregistered packet type {}".format(header))
114127
packet = header + stream.read(packet_class.PACKET_LENGTH - 2)
115128
return cls.from_bytes(packet)
116129

0 commit comments

Comments
 (0)