@@ -65,6 +65,13 @@ def send_request(self, request):
6565 break
6666
6767 def read_response (self ):
68+ """Wait for an SDO response and handle timeout or remote abort.
69+
70+ :raises canopen.SdoAbortedError:
71+ When receiving an SDO abort response from the server.
72+ :raises canopen.SdoCommunicationError:
73+ After timeout with no response received.
74+ """
6875 try :
6976 response = self .responses .get (
7077 block = True , timeout = self .RESPONSE_TIMEOUT )
@@ -302,8 +309,10 @@ def read(self, size=-1):
302309 response = self .sdo_client .request_response (request )
303310 res_command , = struct .unpack_from ("B" , response )
304311 if res_command & 0xE0 != RESPONSE_SEGMENT_UPLOAD :
312+ self .sdo_client .abort (ABORT_INVALID_COMMAND_SPECIFIER )
305313 raise SdoCommunicationError (f"Unexpected response 0x{ res_command :02X} " )
306314 if res_command & TOGGLE_BIT != self ._toggle :
315+ self .sdo_client .abort (ABORT_TOGGLE_NOT_ALTERNATED )
307316 raise SdoCommunicationError ("Toggle bit mismatch" )
308317 length = 7 - ((res_command >> 1 ) & 0x7 )
309318 if res_command & NO_MORE_DATA :
@@ -362,6 +371,7 @@ def __init__(self, sdo_client, index, subindex=0, size=None, force_segment=False
362371 response = sdo_client .request_response (request )
363372 res_command , = struct .unpack_from ("B" , response )
364373 if res_command != RESPONSE_DOWNLOAD :
374+ self .sdo_client .abort (ABORT_INVALID_COMMAND_SPECIFIER )
365375 raise SdoCommunicationError (
366376 f"Unexpected response 0x{ res_command :02X} " )
367377 else :
@@ -390,6 +400,7 @@ def write(self, b):
390400 response = self .sdo_client .request_response (request )
391401 res_command , = struct .unpack_from ("B" , response )
392402 if res_command & 0xE0 != RESPONSE_DOWNLOAD :
403+ self .sdo_client .abort (ABORT_INVALID_COMMAND_SPECIFIER )
393404 raise SdoCommunicationError (
394405 f"Unexpected response 0x{ res_command :02X} " )
395406 bytes_sent = len (b )
@@ -414,6 +425,7 @@ def write(self, b):
414425 response = self .sdo_client .request_response (request )
415426 res_command , = struct .unpack ("B" , response [0 :1 ])
416427 if res_command & 0xE0 != RESPONSE_SEGMENT_DOWNLOAD :
428+ self .sdo_client .abort (ABORT_INVALID_COMMAND_SPECIFIER )
417429 raise SdoCommunicationError (
418430 f"Unexpected response 0x{ res_command :02X} "
419431 f"(expected 0x{ RESPONSE_SEGMENT_DOWNLOAD :02X} )" )
@@ -565,7 +577,7 @@ def _retransmit(self):
565577 return response
566578 self ._error = True
567579 self .sdo_client .abort (ABORT_TIMED_OUT )
568- raise SdoCommunicationError ("Some data were lost and could not be retransmitted" )
580+ raise SdoCommunicationError ("Some data was lost and could not be retransmitted" )
569581
570582 def _ack_block (self ):
571583 request = bytearray (8 )
@@ -576,7 +588,11 @@ def _ack_block(self):
576588 self ._ackseq = 0
577589
578590 def _end_upload (self ):
579- response = self .sdo_client .read_response ()
591+ try :
592+ response = self .sdo_client .read_response ()
593+ except SdoCommunicationError :
594+ self .abort (ABORT_TIMED_OUT )
595+ raise
580596 res_command , self ._server_crc = struct .unpack_from ("<BH" , response )
581597 if res_command & 0xE0 != RESPONSE_BLOCK_UPLOAD :
582598 self ._error = True
@@ -736,7 +752,11 @@ def tell(self):
736752
737753 def _block_ack (self ):
738754 logger .debug ("Waiting for acknowledgement of last block..." )
739- response = self .sdo_client .read_response ()
755+ try :
756+ response = self .sdo_client .read_response ()
757+ except SdoCommunicationError :
758+ self .sdo_client .abort (ABORT_TIMED_OUT )
759+ raise
740760 res_command , ackseq , blksize = struct .unpack_from ("BBB" , response )
741761 if res_command & 0xE0 != RESPONSE_BLOCK_DOWNLOAD :
742762 self .sdo_client .abort (ABORT_INVALID_COMMAND_SPECIFIER )
0 commit comments