Skip to content

Commit 9246f74

Browse files
committed
update test
1 parent d4af0e5 commit 9246f74

File tree

5 files changed

+104
-7
lines changed

5 files changed

+104
-7
lines changed

test_apps/test_common/mb_utest_lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ target_include_directories(mb_ut_lib PUBLIC
1111
"${dir}/modbus/mb_controller/common/include"
1212
"${dir}/modbus/mb_controller/serial"
1313
"${dir}/modbus/mb_controller/tcp"
14+
"${dir}/modbus/mb_objects/common"
1415
"${dir}/modbus/mb_objects/include"
1516
"${dir}/modbus/mb_ports/common"
1617
"${dir}/modbus/mb_ports/serial"

tools/robot/ModbusSupport.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class ModbusMBAP(Packet):
3636
name = "Modbus TCP"
3737
fields_desc = [ ShortField("transId", 0),
3838
ShortField("protoId", 0),
39-
ShortField("len", 6),
40-
XByteField("UnitId", 247),
39+
ShortField("len", 0),
40+
XByteField("unitId", 0),
4141
]
4242

4343
# Can be used to replace all Modbus read
@@ -252,10 +252,27 @@ class ModbusPDUXX_Custom_Request(Packet):
252252
FieldListField("customBytes", [0x00], XByteField("", 0x00))
253253
]
254254

255+
class ModbusPDUXX_Custom_Exception(Packet):
256+
name = "Custom Command Exception"
257+
fields_desc = [
258+
XByteField("funcCode", 0x00),
259+
ByteEnumField("exceptCode", 1, modbus_exceptions)
260+
]
261+
262+
# Custom command respond
263+
class ModbusPDUXX_Custom_Answer(Packet):
264+
name = "Custom Command Answer"
265+
fields_desc = [
266+
ConditionalField(XByteField("funcCode", 0x00), lambda pkt: (type(pkt.underlayer) is ModbusADU_Response)),
267+
ConditionalField(FieldListField("customBytes", [0x00], XByteField("", 0x00), count_from = lambda pkt: pkt.underlayer.len if pkt.underlayer is not None else 0), lambda pkt: type(pkt.underlayer) is ModbusADU_Response)
268+
]
269+
255270
# 0x11 - Report Slave Id
256271
class ModbusPDU11_Report_Slave_Id(Packet):
257272
name = "Report Slave Id"
258-
fields_desc = [ XByteField("funcCode", 0x11) ]
273+
fields_desc = [
274+
XByteField("funcCode", 0x11)
275+
]
259276

260277
class ModbusPDU11_Report_Slave_Id_Answer(Packet):
261278
name = "Report Slave Id Answer"
@@ -279,7 +296,8 @@ class ModbusADU_Request(ModbusMBAP):
279296
XShortField("transId", 0x0000), # needs to be unique
280297
XShortField("protoId", 0x0000), # needs to be zero (Modbus)
281298
XShortField("len", None), # is calculated with payload
282-
XByteField("unitId", 0x00)] # 0xFF or 0x00 should be used for Modbus over TCP/IP
299+
XByteField("unitId", 0x00) # 0xFF or 0x00 should be used for Modbus over TCP/IP
300+
]
283301

284302
def mb_get_last_exception(self):
285303
return _mb_exception
@@ -372,7 +390,8 @@ def my_show(self, p):
372390
class ModbusADU_Response(ModbusMBAP):
373391
name = "ModbusADU Response"
374392
_mb_exception: modbus_exceptions = 0
375-
393+
_current_main_packet: Packet = None
394+
_modbus_pdu: Packet = None
376395
fields_desc = [
377396
XShortField("transId", 0x0000), # needs to be unique
378397
XShortField("protoId", 0x0000), # needs to be zero (Modbus)
@@ -381,6 +400,15 @@ class ModbusADU_Response(ModbusMBAP):
381400

382401
def mb_get_last_exception(self):
383402
return _mb_exception
403+
404+
# def extract_padding(self, s):
405+
# print(f'Extract pedding: {self, s, self.len, self.underlayer}')
406+
# return self.guess_payload_class( s) #, s #self.extract_pedding(self, s)
407+
408+
def pre_dissect(self, s):
409+
print(f'Pre desect: {self, s, self.len, self.underlayer}')
410+
_current_main_packet = self
411+
return s
384412

385413
# Dissects packets
386414
def guess_payload_class(self, payload):
@@ -443,11 +471,14 @@ def guess_payload_class(self, payload):
443471
return ModbusPDU10_Write_Multiple_Registers_Exception
444472

445473
elif funcCode == 0x11:
446-
print(f'Packet answer: {payload}, func: {funcCode}')
447474
return ModbusPDU11_Report_Slave_Id_Answer
448475
elif funcCode == 0x91:
449476
self._mb_exception = int(payload[1])
450477
return ModbusPDU11_Report_Slave_Id_Exception
451478

452479
else:
453-
return Packet.guess_payload_class(self, payload)
480+
if (funcCode & 0x80):
481+
self._mb_exception = int(payload[1])
482+
return ModbusPDUXX_Custom_Exception
483+
return ModbusPDUXX_Custom_Answer
484+
#return Packet.guess_payload_class(self, payload)

tools/robot/ModbusTestLib.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
# The constructed packets for self testing
4444

45+
TEST_PACKET_REPORT_CUSTOM_0X41 = 'ModbusADU_Request(transId=MB_DEF_TRANS_ID, unitId=0x01, protoId=0)/\
46+
ModbusPDUXX_Custom_Request(customBytes=[0x41])'
4547
TEST_PACKET_REPORT_SLAVE_ID_CUSTOM = 'ModbusADU_Request(transId=MB_DEF_TRANS_ID, unitId=0x01, protoId=0)/\
4648
ModbusPDUXX_Custom_Request(customBytes=[0x11])'
4749
TEST_PACKET_REPORT_SLAVE_ID = 'ModbusADU_Request(transId=MB_DEF_TRANS_ID, unitId=0x01, protoId=0)/\
@@ -431,6 +433,15 @@ def get_bits_from_pdu(self, pdu):
431433
def self_test(self) -> None:
432434
# type: () -> None
433435
self.connect(ip_addr=MB_DEF_SERVER_IP, port=MB_DEF_PORT)
436+
packet = self.create_request(TEST_PACKET_REPORT_CUSTOM_0X41)
437+
print(f"Test: 0x41 <Custom command> packet: {packet}")
438+
response = self.send_packet_and_get_response(packet, timeout=1, verbose=0)
439+
assert response and len(response) > 1, "No response from slave"
440+
print(f"Test: received: {bytes(response)}")
441+
pdu = self.translate_response(response)
442+
if pdu is not None:
443+
print(f"Received: {pdu}")
444+
#print(f"PDU Exception: {self.check_response(pdu, packet.customBytes[0])}")
434445
packet = self.create_request(TEST_PACKET_REPORT_SLAVE_ID_CUSTOM)
435446
print(f"Test: 0x11 <Report Slave ID> packet: {packet}")
436447
response = self.send_packet_and_get_response(packet, timeout=1, verbose=0)

tools/robot/ModbusTestSuite.resource

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ Library Collections
1818
Library ModbusTestLib.py WITH NAME ModbusTestLib
1919

2020
*** Keywords ***
21+
Create Custom Command Request
22+
[Arguments] ${uid} ${customData}
23+
${packet} = Create Request ModbusADU_Request(unitId=${uid}, protoId=0)/ModbusPDUXX_Custom_Request(customBytes=${customData})
24+
RETURN ${packet}
25+
2126
Create Report Slave Id Request
2227
[Arguments] ${uid} ${customData}
2328
#${packet} = Create Request ModbusADU_Request(unitId=${uid}, protoId=0)/ModbusPDU11_Report_Slave_Id(funcCode=${FUNC_REPORT_SLAVE_ID})
@@ -64,6 +69,48 @@ Create Discrete Read Request
6469
Log Packet: ${packet}
6570
RETURN ${packet}
6671

72+
Lists Should Be Equal
73+
[Arguments] ${get_list} ${exp_list}
74+
Should Not Be Empty ${get_list}
75+
Should Not Be Empty ${exp_list}
76+
${get_length} = Get length ${get_list}
77+
${exp_length} = Get length ${exp_list}
78+
Should Be Equal As Integers ${get_length} ${exp_length}
79+
FOR ${i} IN RANGE ${exp_length}
80+
${get_item} = Get From List ${get_list} ${i}
81+
${exp_item} = Get From List ${exp_list} ${i}
82+
Should Be Equal As Integers ${get_item} ${exp_item}
83+
END
84+
85+
Custom Command
86+
[Arguments] ${uid} ${customData} ${exception_expected} ${expected_list}
87+
${classId} = Get Class Id
88+
Log Library ClassId: ${classId}
89+
Log Get Slave Identificator UID:${uid}, Custom bytes: ${customData}
90+
${req} = Create Custom Command Request ${uid} ${customData}
91+
#Create Connection ${server} ${port}
92+
${response_frame} = Send Packet And Get Response ${req}
93+
Should Not Be Empty ${response_frame}
94+
${packet} = Translate Response ${response_frame}
95+
Should Be Equal As Integers ${req.transId} ${packet.transId}
96+
${exception} ${exp_message} = Check Response ${packet} ${req.customBytes[0]}
97+
Should Be Equal As Integers ${exception} ${exception_expected}
98+
Log exception: (${exception}: ${exp_message}), expected: ${exception_expected}
99+
IF ${exception} == ${0}
100+
Log SlaveUID:${uid}, Custom_data received:${packet.customBytes}
101+
IF ${expected_list} != ${None}
102+
Log ${expected_list}
103+
Log ${packet.customBytes}
104+
${get_list} = Convert To List ${packet.customBytes}
105+
${exp_list} = Evaluate ${expected_list}
106+
Lists Should Be Equal ${get_list} ${exp_list}
107+
ELSE
108+
Log "Skip comparison with expected list"
109+
END
110+
ELSE
111+
Log "Exception is evaluated correctly (${exception}: ${exp_message}) == ${exception_expected}"
112+
END
113+
67114
Report Slave Id
68115
[Arguments] ${uid} ${customData} ${exception_expected}
69116
${classId} = Get Class Id

tools/robot/ModbusTestSuite.robot

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ Suite Teardown Disconnect
1111
${suiteConnection} None
1212

1313
*** Test Cases ***
14+
Test Cusom Command Request
15+
[Documentation] Test reading slave UID, running status, identificator structure (use custom frame template)
16+
[Template] Custom Command
17+
0x01 [0x41] 0 ${None} # Try o send shortest request for custom command, do not check the buffer
18+
0x01 [0x41, 0x11, 0x22, 0x33, 0x44] 0 ${None} # Send custom data, do not compare the response buffer
19+
0x01 [0x41, 0x11, 0x22, 0x33] 0 [17, 34, 51, 0x3A, 83, 108, 97, 118, 101] # Send the custom command and compare expected response (can use hex or dec values)
20+
1421
Test Report Slave Id
1522
[Documentation] Test reading slave UID, running status, identificator structure (use custom frame template)
1623
[Template] Report Slave Id

0 commit comments

Comments
 (0)