Skip to content

Commit ae71853

Browse files
authored
Fix SDO writes of empty strings (#551)
Previously, when attempting a write of "" to a VISIBLE_STRING, the expedited SDO request would not be sent and the transaction would timeout. To resolve this, if the transaction size is known to be 0, a segmented transfer is used.
1 parent ffbd10f commit ae71853

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

canopen/sdo/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ def __init__(self, sdo_client, index, subindex=0, size=None, force_segment=False
353353
self._exp_header = None
354354
self._done = False
355355

356-
if size is None or size > 4 or force_segment:
356+
if size is None or size < 1 or size > 4 or force_segment:
357357
# Initiate segmented download
358358
request = bytearray(8)
359359
command = REQUEST_DOWNLOAD

test/test_sdo.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ def _send_message(self, can_id, data, remote=False):
6868
while self.data and self.data[0][0] == RX:
6969
self.network.notify(0x582, self.data.pop(0)[1], 0.0)
7070

71+
self.message_sent = True
72+
7173
def setUp(self):
7274
network = canopen.Network()
7375
network.NOTIFIER_SHUTDOWN_TIMEOUT = 0.0
@@ -76,6 +78,8 @@ def setUp(self):
7678
node.sdo.RESPONSE_TIMEOUT = 0.01
7779
self.network = network
7880

81+
self.message_sent = False
82+
7983
def test_expedited_upload(self):
8084
self.data = [
8185
(TX, b'\x40\x18\x10\x01\x00\x00\x00\x00'),
@@ -91,6 +95,7 @@ def test_expedited_upload(self):
9195
]
9296
trans_type = self.network[2].sdo[0x1400]['Transmission type RPDO 1'].raw
9397
self.assertEqual(trans_type, 254)
98+
self.assertTrue(self.message_sent)
9499

95100
def test_size_not_specified(self):
96101
self.data = [
@@ -100,13 +105,15 @@ def test_size_not_specified(self):
100105
# Make sure the size of the data is 1 byte
101106
data = self.network[2].sdo.upload(0x1400, 2)
102107
self.assertEqual(data, b'\xfe')
108+
self.assertTrue(self.message_sent)
103109

104110
def test_expedited_download(self):
105111
self.data = [
106112
(TX, b'\x2b\x17\x10\x00\xa0\x0f\x00\x00'),
107113
(RX, b'\x60\x17\x10\x00\x00\x00\x00\x00')
108114
]
109115
self.network[2].sdo[0x1017].raw = 4000
116+
self.assertTrue(self.message_sent)
110117

111118
def test_segmented_upload(self):
112119
self.data = [
@@ -153,6 +160,16 @@ def test_block_download(self):
153160
'wb', size=len(data), block_transfer=True) as fp:
154161
fp.write(data)
155162

163+
def test_segmented_download_zero_length(self):
164+
self.data = [
165+
(TX, b'\x21\x00\x20\x00\x00\x00\x00\x00'),
166+
(RX, b'\x60\x00\x20\x00\x00\x00\x00\x00'),
167+
(TX, b'\x0F\x00\x00\x00\x00\x00\x00\x00'),
168+
(RX, b'\x20\x00\x00\x00\x00\x00\x00\x00'),
169+
]
170+
self.network[2].sdo[0x2000].raw = ""
171+
self.assertTrue(self.message_sent)
172+
156173
def test_block_upload(self):
157174
self.data = [
158175
(TX, b'\xa4\x08\x10\x00\x7f\x00\x00\x00'),

0 commit comments

Comments
 (0)