99
1010
1111class SdoBlockException (SdoAbortedError ):
12- def __init__ (self , code : int ):
13- super .__init__ (self , code )
12+ """ Dedicated SDO Block exception. """
1413
1514class SdoServer (SdoBase ):
1615 """Creates an SDO server."""
@@ -68,6 +67,14 @@ def on_request(self, can_id, data, timestamp):
6867 logger .exception (exc )
6968
7069 def process_block (self , request ):
70+ """
71+ Process a block request, using a state mechanisme from SdoBlock class
72+ to handle the different states of the block transfer.
73+
74+ :param request:
75+ CAN message containing EMCY or SDO request.
76+ """
77+
7178 logger .debug ('process_block' )
7279 command , _ , _ , code = SDO_ABORT_STRUCT .unpack_from (request )
7380 if command == 0x80 :
@@ -84,14 +91,12 @@ def process_block(self, request):
8491 logger .debug ('BLOCK_STATE_UP_INIT_RESP' )
8592 #init response was sent, client required to send new request
8693 if (command & REQUEST_BLOCK_UPLOAD ) != REQUEST_BLOCK_UPLOAD :
87- raise SdoBlockException (0x05040001 )
94+ raise SdoBlockException ("Unknown SDO command specified" )
8895 if (command & START_BLOCK_UPLOAD ) != START_BLOCK_UPLOAD :
89- raise SdoBlockException (0x05040001 )
90- # self.sdo_block.update_state(BLOCK_STATE_UP_DATA)
96+ raise SdoBlockException ("Unknown SDO command specified" )
9197
9298 # now start blasting data to client from server
9399 self .sdo_block .update_state (BLOCK_STATE_UP_DATA )
94- #self.data_succesfull_upload = self.data_uploaded
95100
96101 blocks = self .sdo_block .get_upload_blocks ()
97102 for block in blocks :
@@ -101,13 +106,12 @@ def process_block(self, request):
101106 logger .debug ('BLOCK_STATE_UP_DATA' )
102107 command , ackseq , newblk = SDO_BLOCKACK_STRUCT .unpack_from (request )
103108 if (command & REQUEST_BLOCK_UPLOAD ) != REQUEST_BLOCK_UPLOAD :
104- raise SdoBlockException (0x05040001 )
109+ raise SdoBlockException ("Unknown SDO command specified" )
105110 elif (command & BLOCK_TRANSFER_RESPONSE ) != BLOCK_TRANSFER_RESPONSE :
106- raise SdoBlockException (0x05040001 )
111+ raise SdoBlockException ("Unknown SDO command specified" )
107112 elif (ackseq != self .sdo_block .last_seqno ):
108113 self .sdo_block .data_uploaded = self .sdo_block .data_succesfull_upload
109114
110-
111115 if self .sdo_block .size == self .sdo_block .data_uploaded :
112116 logger .debug ('BLOCK_STATE_UP_DATA last data' )
113117 self .sdo_block .update_state (BLOCK_STATE_UP_END )
@@ -131,12 +135,12 @@ def process_block(self, request):
131135 self .sdo_block = None
132136
133137 elif BLOCK_STATE_DOWNLOAD < self .sdo_block .state :
134- logger .debug ('BLOCK_STATE_DOWNLOAD' )
135138 # in download state
136- pass
139+ logger . debug ( 'BLOCK_STATE_DOWNLOAD' )
137140 else :
138141 # in neither
139- raise SdoBlockException (0x08000022 )
142+ raise SdoBlockException ("Data can not be transferred or stored to the application "
143+ "because of the present device state" )
140144
141145 def init_upload (self , request ):
142146 _ , index , subindex = SDO_STRUCT .unpack_from (request )
@@ -188,6 +192,13 @@ def segmented_upload(self, command):
188192 self .send_response (response )
189193
190194 def block_upload (self , request ):
195+ """
196+ Process an initial block upload request.
197+ Create a CAN response message and update the state of the SDO block.
198+
199+ :param request:
200+ CAN message containing SDO request.
201+ """
191202 logging .debug ('Enter server block upload' )
192203 self .sdo_block = SdoBlock (self ._node , request )
193204
@@ -314,6 +325,10 @@ def download(
314325 return self ._node .set_data (index , subindex , data )
315326
316327class SdoBlock ():
328+ """
329+ SdoBlock class to handle block transfer. It keeps track of the
330+ current state and the prepares data to be transferred.
331+ """
317332 state = BLOCK_STATE_NONE
318333 crc = False
319334 data_uploaded = 0
@@ -323,41 +338,57 @@ class SdoBlock():
323338 last_seqno = 0
324339
325340 def __init__ (self , node , request , docrc = False ):
326-
341+ """
342+ :param node:
343+ Node object owning the server
344+ :param request:
345+ CAN message containing SDO request.
346+ :param docrc:
347+ If True, CRC is calculated and checked.
348+ """
327349 command , index , subindex = SDO_STRUCT .unpack_from (request )
328350 # only do crc if crccheck lib is available _and_ if requested
329351 _req_crc = (command & CRC_SUPPORTED ) == CRC_SUPPORTED
330352
331353 if (command & SUB_COMMAND_MASK ) == INITIATE_BLOCK_TRANSFER :
332354 self .state = BLOCK_STATE_INIT
333355 else :
334- raise SdoBlockException (SdoAbortedError . from_string ( "Unknown SDO command specified" ) )
356+ raise SdoBlockException ("Unknown SDO command specified" )
335357
358+ # TODO: CRC of data if requested
336359 self .crc = CRC_SUPPORTED if (docrc & _req_crc ) else 0
337360 self ._node = node
338361 self .index = index
339362 self .subindex = subindex
340363 self .req_blocksize = request [4 ]
341364 self .seqno = 0
342365 if not 1 <= self .req_blocksize <= 127 :
343- raise SdoBlockException (SdoAbortedError . from_string ( "Invalid block size" ) )
366+ raise SdoBlockException ("Invalid block size" )
344367
345368 self .data = self ._node .get_data (index ,
346369 subindex ,
347370 check_readable = True )
348371 self .size = len (self .data )
349372
350- # TODO: add PST if needed
351- # self.pst = data[5]
352-
353373 def update_state (self , new_state ):
374+ """
375+ Update the state of the SDO block transfer. The state is
376+ updated only if the new state is higher than the current
377+ state. Otherwise an exception is raised.
378+ """
354379 logging .debug ('update_state %X -> %X' , self .state , new_state )
355380 if new_state >= self .state :
356381 self .state = new_state
357382 else :
358- raise SdoBlockException (0x08000022 )
383+ raise SdoBlockException ("Data can not be transferred or stored to the application "
384+ "because of the present device state" )
359385
360386 def get_upload_blocks (self ):
387+ """
388+ Get the blocks of data to be sent to the client. The blocks are
389+ created in a messages list of bytearrays.
390+ """
391+
361392 msgs = []
362393
363394 # seq no 1 - 127, not 0 -..
@@ -387,6 +418,7 @@ def get_upload_blocks(self):
387418 return msgs
388419
389420 def get_data_byte (self ):
421+ """Get the next byte of data to be sent to the client."""
390422 if self .data_uploaded < self .size :
391423 self .data_uploaded += 1
392424 return self .data [self .data_uploaded - 1 ]
0 commit comments