Skip to content

Commit b01e942

Browse files
authored
Merge pull request #742 from gijzelaerr/fix-payload-sequence-number
fix: add SequenceNumber to Get/SetMultiVariables payloads
2 parents 6b37cf0 + 72e982d commit b01e942

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

s7/_s7commplus_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ def _build_read_payload(items: list[tuple[int, int, int]]) -> bytes:
488488
for addr in addresses:
489489
payload += addr
490490
payload += encode_object_qualifier()
491+
payload += encode_uint32_vlq(1)
491492
payload += struct.pack(">I", 0)
492493

493494
return bytes(payload)
@@ -580,6 +581,7 @@ def _build_write_payload(items: list[tuple[int, int, bytes]]) -> bytes:
580581
payload += encode_pvalue_blob(data)
581582
payload += bytes([0x00])
582583
payload += encode_object_qualifier()
584+
payload += encode_uint32_vlq(1)
583585
payload += struct.pack(">I", 0)
584586

585587
return bytes(payload)
@@ -632,6 +634,7 @@ def _build_area_read_payload(area_rid: int, start: int, size: int) -> bytes:
632634
payload += encode_uint32_vlq(field_count)
633635
payload += addr_bytes
634636
payload += encode_object_qualifier()
637+
payload += encode_uint32_vlq(1)
635638
payload += struct.pack(">I", 0)
636639
return bytes(payload)
637640

@@ -653,6 +656,7 @@ def _build_area_write_payload(area_rid: int, start: int, data: bytes) -> bytes:
653656
payload += encode_pvalue_blob(data)
654657
payload += bytes([0x00])
655658
payload += encode_object_qualifier()
659+
payload += encode_uint32_vlq(1)
656660
payload += struct.pack(">I", 0)
657661
return bytes(payload)
658662

@@ -685,6 +689,7 @@ def _build_symbolic_read_payload(access_area: int, lids: list[int], symbol_crc:
685689
payload += encode_uint32_vlq(field_count)
686690
payload += addr_bytes
687691
payload += encode_object_qualifier()
692+
payload += encode_uint32_vlq(1)
688693
payload += struct.pack(">I", 0)
689694
return bytes(payload)
690695

@@ -712,6 +717,7 @@ def _build_symbolic_write_payload(access_area: int, lids: list[int], data: bytes
712717
payload += encode_pvalue_blob(data)
713718
payload += bytes([0x00])
714719
payload += encode_object_qualifier()
720+
payload += encode_uint32_vlq(1)
715721
payload += struct.pack(">I", 0)
716722
return bytes(payload)
717723

tests/test_s7_unit.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,29 @@
99
_parse_read_response,
1010
_build_write_payload,
1111
_parse_write_response,
12+
<<<<<<< HEAD
1213
_build_explore_request,
1314
_parse_explore_datablocks,
15+
||||||| parent of 22a5c08 (fix: add SequenceNumber to Get/SetMultiVariables payloads (#738))
16+
=======
17+
_build_area_read_payload,
18+
_build_area_write_payload,
19+
_build_symbolic_read_payload,
20+
_build_symbolic_write_payload,
21+
>>>>>>> 22a5c08 (fix: add SequenceNumber to Get/SetMultiVariables payloads (#738))
1422
)
23+
<<<<<<< HEAD
1524
from s7.connection import S7CommPlusConnection
1625
from s7.codec import encode_pvalue_blob
1726
from s7.codec import _pvalue_element_size as _element_size
1827
from s7.codec import skip_typed_value, parse_server_session_version
28+
||||||| parent of 22a5c08 (fix: add SequenceNumber to Get/SetMultiVariables payloads (#738))
29+
from s7.codec import encode_pvalue_blob
30+
from s7.connection import S7CommPlusConnection, _element_size
31+
=======
32+
from s7.codec import encode_object_qualifier, encode_pvalue_blob
33+
from s7.connection import S7CommPlusConnection, _element_size
34+
>>>>>>> 22a5c08 (fix: add SequenceNumber to Get/SetMultiVariables payloads (#738))
1935
from s7.protocol import DataType, ElementID, ObjectId
2036
from s7.vlq import (
2137
encode_uint32_vlq,
@@ -194,6 +210,42 @@ def test_write_read_consistency(self) -> None:
194210
assert isinstance(write_payload, bytes)
195211

196212

213+
class TestSequenceNumber:
214+
"""Verify all payload builders include a SequenceNumber after ObjectQualifier."""
215+
216+
@staticmethod
217+
def _has_sequence_number(payload: bytes) -> bool:
218+
oq = encode_object_qualifier()
219+
idx = bytes(payload).find(oq)
220+
assert idx >= 0, "ObjectQualifier not found in payload"
221+
seq_offset = idx + len(oq)
222+
return payload[seq_offset : seq_offset + 1] == encode_uint32_vlq(1)
223+
224+
def test_read_payload_has_sequence_number(self) -> None:
225+
payload = _build_read_payload([(1, 0, 4)])
226+
assert self._has_sequence_number(payload)
227+
228+
def test_write_payload_has_sequence_number(self) -> None:
229+
payload = _build_write_payload([(1, 0, bytes([1, 2, 3, 4]))])
230+
assert self._has_sequence_number(payload)
231+
232+
def test_area_read_payload_has_sequence_number(self) -> None:
233+
payload = _build_area_read_payload(82, 0, 4)
234+
assert self._has_sequence_number(payload)
235+
236+
def test_area_write_payload_has_sequence_number(self) -> None:
237+
payload = _build_area_write_payload(82, 0, b"\x00\x00\x00\x00")
238+
assert self._has_sequence_number(payload)
239+
240+
def test_symbolic_read_payload_has_sequence_number(self) -> None:
241+
payload = _build_symbolic_read_payload(0x8A0E0001, [1, 4])
242+
assert self._has_sequence_number(payload)
243+
244+
def test_symbolic_write_payload_has_sequence_number(self) -> None:
245+
payload = _build_symbolic_write_payload(0x8A0E0001, [1, 4], b"\x01")
246+
assert self._has_sequence_number(payload)
247+
248+
197249
# -- Connection unit tests --
198250

199251

0 commit comments

Comments
 (0)