diff --git a/canopen/sdo/client.py b/canopen/sdo/client.py index c08d92be..35a50cc0 100644 --- a/canopen/sdo/client.py +++ b/canopen/sdo/client.py @@ -530,6 +530,7 @@ def read(self, size=-1): if seqno == self._ackseq + 1: self._ackseq = seqno else: + logger.debug('Wrong seqno') # Wrong sequence number response = self._retransmit() res_command, = struct.unpack_from("B", response) diff --git a/canopen/sdo/constants.py b/canopen/sdo/constants.py index e8a07359..ec5c7bda 100644 --- a/canopen/sdo/constants.py +++ b/canopen/sdo/constants.py @@ -2,7 +2,12 @@ # Command, index, subindex SDO_STRUCT = struct.Struct(" %X', self.state, new_state) + if new_state >= self.state: + self.state = new_state + else: + raise SdoBlockException("Data can not be transferred or stored to the application " + "because of the present device state") + + def get_upload_blocks(self): + """ + Get the blocks of data to be sent to the client. The blocks are + created in a messages list of bytearrays. + """ + + msgs = [] + + # seq no 1 - 127, not 0 -.. + for seqno in range(1,self.req_blocksize+1): + logger.debug('SEQNO %d', seqno) + response = bytearray(8) + command = 0 + if self.size <= (self.data_uploaded + 7): + # no more segments after this + command |= NO_MORE_BLOCKS + + command |= seqno + response[0] = command + for i in range(7): + databyte = self.get_data_byte() + if databyte != None: + response[i+1] = databyte + else: + self.last_bytes = 7 - i + break + msgs.append(response) + self.last_seqno = seqno + + if self.size == self.data_uploaded: + break + logger.debug(msgs) + return msgs + + def get_data_byte(self): + """Get the next byte of data to be sent to the client.""" + if self.data_uploaded < self.size: + self.data_uploaded += 1 + return self.data[self.data_uploaded-1] + return None + diff --git a/test/test_local.py b/test/test_local.py index e184c040..bc195b2d 100644 --- a/test/test_local.py +++ b/test/test_local.py @@ -37,13 +37,14 @@ def test_expedited_upload(self): vendor_id = self.remote_node.sdo[0x1400][1].raw self.assertEqual(vendor_id, 0x99) - def test_block_upload_switch_to_expedite_upload(self): - with self.assertRaises(canopen.SdoCommunicationError) as context: - with self.remote_node.sdo[0x1008].open('r', block_transfer=True) as fp: - pass - # We get this since the sdo client don't support the switch - # from block upload to expedite upload - self.assertEqual("Unexpected response 0x41", str(context.exception)) + # Remove this test, as Block upload is now supported: + # def test_block_upload_switch_to_expedite_upload(self): + # with self.assertRaises(canopen.SdoCommunicationError) as context: + # with self.remote_node.sdo[0x1008].open('r', block_transfer=True) as fp: + # pass + # # We get this since the sdo client don't support the switch + # # from block upload to expedite upload + # self.assertEqual("Unexpected response 0x41", str(context.exception)) def test_block_download_not_supported(self): data = b"TEST DEVICE"