@@ -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 )
@@ -89,11 +96,11 @@ def request_response(self, sdo_request):
8996 except SdoCommunicationError as e :
9097 retries_left -= 1
9198 if not retries_left :
92- self .abort (0x5040000 )
99+ self .abort (0x0504_0000 )
93100 raise
94101 logger .warning (str (e ))
95102
96- def abort (self , abort_code = 0x08000000 ):
103+ def abort (self , abort_code = 0x0800_0000 ):
97104 """Abort current transfer."""
98105 request = bytearray (8 )
99106 request [0 ] = REQUEST_ABORTED
@@ -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 (0x0504_0001 )
305313 raise SdoCommunicationError (f"Unexpected response 0x{ res_command :02X} " )
306314 if res_command & TOGGLE_BIT != self ._toggle :
315+ self .sdo_client .abort (0x0503_0000 )
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 (0x0504_0001 )
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 (0x0504_0001 )
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 (0x0504_0001 )
417429 raise SdoCommunicationError (
418430 f"Unexpected response 0x{ res_command :02X} "
419431 f"(expected 0x{ RESPONSE_SEGMENT_DOWNLOAD :02X} )" )
@@ -487,7 +499,7 @@ def __init__(self, sdo_client, index, subindex=0, request_crc_support=True):
487499 res_command , res_index , res_subindex = SDO_STRUCT .unpack_from (response )
488500 if res_command & 0xE0 != RESPONSE_BLOCK_UPLOAD :
489501 self ._error = True
490- self .sdo_client .abort (0x05040001 )
502+ self .sdo_client .abort (0x0504_0001 )
491503 raise SdoCommunicationError (f"Unexpected response 0x{ res_command :02X} " )
492504 # Check that the message is for us
493505 if res_index != index or res_subindex != subindex :
@@ -544,7 +556,7 @@ def read(self, size=-1):
544556 if self ._done :
545557 if self ._server_crc != self ._crc .final ():
546558 self ._error = True
547- self .sdo_client .abort (0x05040004 )
559+ self .sdo_client .abort (0x0504_0004 )
548560 raise SdoCommunicationError ("CRC is not OK" )
549561 logger .info ("CRC is OK" )
550562 self .pos += len (data )
@@ -564,8 +576,8 @@ def _retransmit(self):
564576 self ._ackseq = seqno
565577 return response
566578 self ._error = True
567- self .sdo_client .abort (0x05040000 )
568- raise SdoCommunicationError ("Some data were lost and could not be retransmitted" )
579+ self .sdo_client .abort (0x0504_0000 )
580+ raise SdoCommunicationError ("Some data was lost and could not be retransmitted" )
569581
570582 def _ack_block (self ):
571583 request = bytearray (8 )
@@ -576,15 +588,19 @@ 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 (0x0504_0000 )
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
583- self .sdo_client .abort (0x05040001 )
599+ self .sdo_client .abort (0x0504_0001 )
584600 raise SdoCommunicationError (f"Unexpected response 0x{ res_command :02X} " )
585601 if res_command & 0x3 != END_BLOCK_TRANSFER :
586602 self ._error = True
587- self .sdo_client .abort (0x05040001 )
603+ self .sdo_client .abort (0x0504_0001 )
588604 raise SdoCommunicationError ("Server did not end transfer as expected" )
589605 # Return number of bytes not used in last message
590606 return (res_command >> 2 ) & 0x7
@@ -654,7 +670,7 @@ def __init__(self, sdo_client, index, subindex=0, size=None, request_crc_support
654670 response = sdo_client .request_response (request )
655671 res_command , res_index , res_subindex = SDO_STRUCT .unpack_from (response )
656672 if res_command & 0xE0 != RESPONSE_BLOCK_DOWNLOAD :
657- self .sdo_client .abort (0x05040001 )
673+ self .sdo_client .abort (0x0504_0001 )
658674 raise SdoCommunicationError (
659675 f"Unexpected response 0x{ res_command :02X} " )
660676 # Check that the message is for us
@@ -736,14 +752,18 @@ 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 (0x0504_0000 )
759+ raise
740760 res_command , ackseq , blksize = struct .unpack_from ("BBB" , response )
741761 if res_command & 0xE0 != RESPONSE_BLOCK_DOWNLOAD :
742- self .sdo_client .abort (0x05040001 )
762+ self .sdo_client .abort (0x0504_0001 )
743763 raise SdoCommunicationError (
744764 f"Unexpected response 0x{ res_command :02X} " )
745765 if res_command & 0x3 != BLOCK_TRANSFER_RESPONSE :
746- self .sdo_client .abort (0x05040001 )
766+ self .sdo_client .abort (0x0504_0001 )
747767 raise SdoCommunicationError ("Server did not respond with a "
748768 "block download response" )
749769 if ackseq != self ._blksize :
0 commit comments