Skip to content

Commit 3a092bc

Browse files
christiansandberghardbyte
authored andcommitted
Fix slcan message handling (#462)
Fixes #444
1 parent 43763ed commit 3a092bc

File tree

1 file changed

+49
-46
lines changed

1 file changed

+49
-46
lines changed

can/interfaces/slcan.py

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -112,53 +112,56 @@ def _recv_internal(self, timeout):
112112
extended = False
113113
frame = []
114114

115-
# Read everything that is already available
116-
waiting = self.serialPortOrig.read(self.serialPortOrig.in_waiting)
117-
self._buffer += waiting
118-
119-
# Check if a complete message has been received
120-
pos = self._buffer.find(self.LINE_TERMINATOR)
121-
if pos == -1:
122-
# Keep reading...
115+
# First read what is already in the receive buffer
116+
while (self.serialPortOrig.in_waiting and
117+
self.LINE_TERMINATOR not in self._buffer):
118+
self._buffer += self.serialPortOrig.read(1)
119+
120+
# If we still don't have a complete message, do a blocking read
121+
if self.LINE_TERMINATOR not in self._buffer:
123122
self._buffer += self.serialPortOrig.read_until(self.LINE_TERMINATOR)
124-
pos = self._buffer.find(self.LINE_TERMINATOR)
125-
126-
if pos != -1:
127-
readStr = self._buffer[0:pos].decode()
128-
del self._buffer[0:pos+1]
129-
if readStr[0] == 'T':
130-
# extended frame
131-
canId = int(readStr[1:9], 16)
132-
dlc = int(readStr[9])
133-
extended = True
134-
for i in range(0, dlc):
135-
frame.append(int(readStr[10 + i * 2:12 + i * 2], 16))
136-
elif readStr[0] == 't':
137-
# normal frame
138-
canId = int(readStr[1:4], 16)
139-
dlc = int(readStr[4])
140-
for i in range(0, dlc):
141-
frame.append(int(readStr[5 + i * 2:7 + i * 2], 16))
142-
elif readStr[0] == 'r':
143-
# remote frame
144-
canId = int(readStr[1:4], 16)
145-
dlc = int(readStr[4])
146-
remote = True
147-
elif readStr[0] == 'R':
148-
# remote extended frame
149-
canId = int(readStr[1:9], 16)
150-
dlc = int(readStr[9])
151-
extended = True
152-
remote = True
153-
154-
if canId is not None:
155-
msg = Message(arbitration_id=canId,
156-
is_extended_id=extended,
157-
timestamp=time.time(), # Better than nothing...
158-
is_remote_frame=remote,
159-
dlc=dlc,
160-
data=frame)
161-
return msg, False
123+
124+
if self.LINE_TERMINATOR not in self._buffer:
125+
# Timed out
126+
return None, False
127+
128+
readStr = self._buffer.decode()
129+
del self._buffer[:]
130+
if not readStr:
131+
pass
132+
elif readStr[0] == 'T':
133+
# extended frame
134+
canId = int(readStr[1:9], 16)
135+
dlc = int(readStr[9])
136+
extended = True
137+
for i in range(0, dlc):
138+
frame.append(int(readStr[10 + i * 2:12 + i * 2], 16))
139+
elif readStr[0] == 't':
140+
# normal frame
141+
canId = int(readStr[1:4], 16)
142+
dlc = int(readStr[4])
143+
for i in range(0, dlc):
144+
frame.append(int(readStr[5 + i * 2:7 + i * 2], 16))
145+
elif readStr[0] == 'r':
146+
# remote frame
147+
canId = int(readStr[1:4], 16)
148+
dlc = int(readStr[4])
149+
remote = True
150+
elif readStr[0] == 'R':
151+
# remote extended frame
152+
canId = int(readStr[1:9], 16)
153+
dlc = int(readStr[9])
154+
extended = True
155+
remote = True
156+
157+
if canId is not None:
158+
msg = Message(arbitration_id=canId,
159+
is_extended_id=extended,
160+
timestamp=time.time(), # Better than nothing...
161+
is_remote_frame=remote,
162+
dlc=dlc,
163+
data=frame)
164+
return msg, False
162165
return None, False
163166

164167
def send(self, msg, timeout=None):

0 commit comments

Comments
 (0)