Skip to content

Commit 9b33a0d

Browse files
committed
add more precise parsing of DTCs
add more precise parsing of DTCs
1 parent e307445 commit 9b33a0d

File tree

2 files changed

+46
-68
lines changed

2 files changed

+46
-68
lines changed

scapy/contrib/automotive/uds.py

Lines changed: 33 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
BitEnumField, BitField, XByteField, FieldListField, \
1717
XShortField, X3BytesField, XIntField, ByteField, \
1818
ShortField, ObservableDict, XShortEnumField, XByteEnumField, StrLenField, \
19-
FieldLenField, XStrFixedLenField, XStrLenField, FlagsField, PacketListField, \
20-
PacketField
19+
FieldLenField, XStrFixedLenField, XStrLenField, FlagsField, PacketListField
2120
from scapy.packet import Packet, bind_layers, NoPayload
2221
from scapy.config import conf
2322
from scapy.error import log_loading
@@ -153,7 +152,7 @@ class UDS_DSCPR(Packet):
153152

154153
def answers(self, other):
155154
return isinstance(other, UDS_DSC) and \
156-
other.diagnosticSessionType == self.diagnosticSessionType
155+
other.diagnosticSessionType == self.diagnosticSessionType
157156

158157

159158
bind_layers(UDS, UDS_DSCPR, service=0x50)
@@ -219,7 +218,7 @@ class UDS_SAPR(Packet):
219218

220219
def answers(self, other):
221220
return isinstance(other, UDS_SA) \
222-
and other.securityAccessType == self.securityAccessType
221+
and other.securityAccessType == self.securityAccessType
223222

224223

225224
bind_layers(UDS, UDS_SAPR, service=0x67)
@@ -274,7 +273,7 @@ class UDS_CCPR(Packet):
274273

275274
def answers(self, other):
276275
return isinstance(other, UDS_CC) \
277-
and other.controlType == self.controlType
276+
and other.controlType == self.controlType
278277

279278

280279
bind_layers(UDS, UDS_CCPR, service=0x68)
@@ -430,7 +429,7 @@ class UDS_AUTHPR(Packet):
430429

431430
def answers(self, other):
432431
return isinstance(other, UDS_AUTH) \
433-
and other.subFunction == self.subFunction
432+
and other.subFunction == self.subFunction
434433

435434

436435
bind_layers(UDS, UDS_AUTHPR, service=0x69)
@@ -492,8 +491,8 @@ class UDS_ATPPR(Packet):
492491

493492
def answers(self, other):
494493
return isinstance(other, UDS_ATP) \
495-
and other.timingParameterAccessType == \
496-
self.timingParameterAccessType
494+
and other.timingParameterAccessType == \
495+
self.timingParameterAccessType
497496

498497

499498
bind_layers(UDS, UDS_ATPPR, service=0xC3)
@@ -606,7 +605,7 @@ class UDS_ROEPR(Packet):
606605

607606
def answers(self, other):
608607
return isinstance(other, UDS_ROE) \
609-
and other.eventType == self.eventType
608+
and other.eventType == self.eventType
610609

611610

612611
bind_layers(UDS, UDS_ROEPR, service=0xC6)
@@ -645,7 +644,7 @@ class UDS_LCPR(Packet):
645644

646645
def answers(self, other):
647646
return isinstance(other, UDS_LC) \
648-
and other.linkControlType == self.linkControlType
647+
and other.linkControlType == self.linkControlType
649648

650649

651650
bind_layers(UDS, UDS_LCPR, service=0xC7)
@@ -674,7 +673,7 @@ class UDS_RDBIPR(Packet):
674673

675674
def answers(self, other):
676675
return isinstance(other, UDS_RDBI) \
677-
and self.dataIdentifier in other.identifiers
676+
and self.dataIdentifier in other.identifiers
678677

679678

680679
bind_layers(UDS, UDS_RDBIPR, service=0x62)
@@ -744,7 +743,7 @@ class UDS_RSDBIPR(Packet):
744743

745744
def answers(self, other):
746745
return isinstance(other, UDS_RSDBI) \
747-
and other.dataIdentifier == self.dataIdentifier
746+
and other.dataIdentifier == self.dataIdentifier
748747

749748

750749
bind_layers(UDS, UDS_RSDBIPR, service=0x64)
@@ -781,7 +780,7 @@ class UDS_RDBPIPR(Packet):
781780

782781
def answers(self, other):
783782
return isinstance(other, UDS_RDBPI) \
784-
and other.periodicDataIdentifier == self.periodicDataIdentifier
783+
and other.periodicDataIdentifier == self.periodicDataIdentifier
785784

786785

787786
bind_layers(UDS, UDS_RDBPIPR, service=0x6A)
@@ -813,7 +812,7 @@ class UDS_DDDIPR(Packet):
813812

814813
def answers(self, other):
815814
return isinstance(other, UDS_DDDI) \
816-
and other.subFunction == self.subFunction
815+
and other.subFunction == self.subFunction
817816

818817

819818
bind_layers(UDS, UDS_DDDIPR, service=0x6C)
@@ -840,7 +839,7 @@ class UDS_WDBIPR(Packet):
840839

841840
def answers(self, other):
842841
return isinstance(other, UDS_WDBI) \
843-
and other.dataIdentifier == self.dataIdentifier
842+
and other.dataIdentifier == self.dataIdentifier
844843

845844

846845
bind_layers(UDS, UDS_WDBIPR, service=0x6E)
@@ -901,8 +900,8 @@ class UDS_WMBAPR(Packet):
901900

902901
def answers(self, other):
903902
return isinstance(other, UDS_WMBA) \
904-
and other.memorySizeLen == self.memorySizeLen \
905-
and other.memoryAddressLen == self.memoryAddressLen
903+
and other.memorySizeLen == self.memorySizeLen \
904+
and other.memoryAddressLen == self.memoryAddressLen
906905

907906

908907
bind_layers(UDS, UDS_WMBAPR, service=0x7D)
@@ -1012,30 +1011,12 @@ class UDS_RDTCI(Packet):
10121011

10131012

10141013
class DTC(Packet):
1015-
name = 'Diagnostic Trouble Code'
1014+
name = 'DTC and status record'
10161015
fields_desc = [
1017-
BitEnumField("system", 0, 2, {
1018-
0: "Powertrain",
1019-
1: "Chassis",
1020-
2: "Body",
1021-
3: "Network"}),
1022-
BitEnumField("type", 0, 2, {
1023-
0: "Generic",
1024-
1: "ManufacturerSpecific",
1025-
2: "Generic",
1026-
3: "Generic"}),
1016+
BitEnumField("system", 0, 2, {0: "Powertrain", 1: "Chassis", 2: "Body", 3: "Network"}),
1017+
BitEnumField("type", 0, 2, {0: "Generic", 1: "ManufacturerSpecific", 2: "Generic", 3: "Generic"}),
10271018
BitField("numeric_value_code", 0, 12),
10281019
ByteField("additional_information_code", 0),
1029-
]
1030-
1031-
def extract_padding(self, s):
1032-
return '', s
1033-
1034-
1035-
class DTC_Status(Packet):
1036-
name = 'DTC and status record'
1037-
fields_desc = [
1038-
PacketField("dtc", None, pkt_cls=DTC),
10391020
FlagsField("status", 0, 8, UDS_RDTCI.dtcStatus)
10401021
]
10411022

@@ -1047,11 +1028,12 @@ class UDS_RDTCIPR(Packet):
10471028
name = 'ReadDTCInformationPositiveResponse'
10481029
fields_desc = [
10491030
ByteEnumField('reportType', 0, UDS_RDTCI.reportTypes),
1050-
ConditionalField(
1051-
FlagsField('DTCStatusAvailabilityMask', 0, 8, UDS_RDTCI.dtcStatus),
1052-
lambda pkt: pkt.reportType in [0x01, 0x07, 0x11, 0x12, 0x02, 0x0A,
1053-
0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x13,
1054-
0x15]),
1031+
ConditionalField(FlagsField('DTCStatusAvailabilityMask', 0, 8, UDS_RDTCI.dtcStatus),
1032+
lambda pkt: pkt.reportType in [0x01, 0x07, 0x11,
1033+
0x12, 0x02, 0x0A,
1034+
0x0B, 0x0C, 0x0D,
1035+
0x0E, 0x0F, 0x13,
1036+
0x15]),
10551037
ConditionalField(ByteEnumField('DTCFormatIdentifier', 0,
10561038
{0: 'ISO15031-6DTCFormat',
10571039
1: 'UDS-1DTCFormat',
@@ -1062,8 +1044,7 @@ class UDS_RDTCIPR(Packet):
10621044
ConditionalField(ShortField('DTCCount', 0),
10631045
lambda pkt: pkt.reportType in [0x01, 0x07,
10641046
0x11, 0x12]),
1065-
ConditionalField(PacketListField('DTCAndStatusRecord', None,
1066-
pkt_cls=DTC_Status),
1047+
ConditionalField(PacketListField('DTCAndStatusRecord', None, pkt_cls=DTC),
10671048
lambda pkt: pkt.reportType in [0x02, 0x0A, 0x0B,
10681049
0x0C, 0x0D, 0x0E,
10691050
0x0F, 0x13, 0x15]),
@@ -1075,7 +1056,7 @@ class UDS_RDTCIPR(Packet):
10751056

10761057
def answers(self, other):
10771058
return isinstance(other, UDS_RDTCI) \
1078-
and other.reportType == self.reportType
1059+
and other.reportType == self.reportType
10791060

10801061

10811062
bind_layers(UDS, UDS_RDTCIPR, service=0x59)
@@ -1110,8 +1091,8 @@ class UDS_RCPR(Packet):
11101091

11111092
def answers(self, other):
11121093
return isinstance(other, UDS_RC) \
1113-
and other.routineControlType == self.routineControlType \
1114-
and other.routineIdentifier == self.routineIdentifier
1094+
and other.routineControlType == self.routineControlType \
1095+
and other.routineIdentifier == self.routineIdentifier
11151096

11161097

11171098
bind_layers(UDS, UDS_RCPR, service=0x71)
@@ -1230,7 +1211,7 @@ class UDS_TDPR(Packet):
12301211

12311212
def answers(self, other):
12321213
return isinstance(other, UDS_TD) \
1233-
and other.blockSequenceCounter == self.blockSequenceCounter
1214+
and other.blockSequenceCounter == self.blockSequenceCounter
12341215

12351216

12361217
bind_layers(UDS, UDS_TDPR, service=0x76)
@@ -1370,7 +1351,7 @@ class UDS_IOCBIPR(Packet):
13701351

13711352
def answers(self, other):
13721353
return isinstance(other, UDS_IOCBI) \
1373-
and other.dataIdentifier == self.dataIdentifier
1354+
and other.dataIdentifier == self.dataIdentifier
13741355

13751356

13761357
bind_layers(UDS, UDS_IOCBIPR, service=0x6F)
@@ -1435,8 +1416,8 @@ class UDS_NR(Packet):
14351416

14361417
def answers(self, other):
14371418
return self.requestServiceId == other.service and \
1438-
(self.negativeResponseCode != 0x78 or
1439-
conf.contribs['UDS']['treat-response-pending-as-answer'])
1419+
(self.negativeResponseCode != 0x78 or
1420+
conf.contribs['UDS']['treat-response-pending-as-answer'])
14401421

14411422

14421423
bind_layers(UDS, UDS_NR, service=0x7f)

test/contrib/automotive/uds.uts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,18 +1047,16 @@ assert rdtcipr.DTCCount == 0xddaa
10471047
assert rdtcipr.answers(rdtci)
10481048

10491049
rdtcipr1 = UDS(b'\x59\x02\xff\x11\x07\x11\'\x022\x12\'\x01\x07\x11\'\x01\x18\x12\'\x01\x13\x12\'\x01"\x11\'\x06C\x00\'\x06S\x00\'\x161\x00\'\x14\x03\x12\'')
1050-
1050+
rdtcipr1.show()
10511051
assert len(rdtcipr1.DTCAndStatusRecord) == 10
1052-
assert rdtcipr1.DTCAndStatusRecord[0].dtc.system == 0
1053-
assert rdtcipr1.DTCAndStatusRecord[0].dtc.type == 1
1054-
assert rdtcipr1.DTCAndStatusRecord[0].dtc.numeric_value_code == 263
1055-
assert rdtcipr1.DTCAndStatusRecord[0].dtc.additional_information_code == 17
1056-
assert rdtcipr1.DTCAndStatusRecord[0].status == 0x27
1057-
assert rdtcipr1.DTCAndStatusRecord[-1].dtc.system == 0
1058-
assert rdtcipr1.DTCAndStatusRecord[-1].dtc.type == 1
1059-
assert rdtcipr1.DTCAndStatusRecord[-1].dtc.numeric_value_code == 1027
1060-
assert rdtcipr1.DTCAndStatusRecord[-1].dtc.additional_information_code == 18
1061-
assert rdtcipr1.DTCAndStatusRecord[-1].status == 0x27
1052+
assert rdtcipr1.DTCAndStatusRecord[0].system == 0
1053+
assert rdtcipr1.DTCAndStatusRecord[0].type == 1
1054+
assert rdtcipr1.DTCAndStatusRecord[0].numeric_value_code == 263
1055+
assert rdtcipr1.DTCAndStatusRecord[0].additional_information_code == 17
1056+
assert rdtcipr1.DTCAndStatusRecord[-1].system == 0
1057+
assert rdtcipr1.DTCAndStatusRecord[-1].type == 1
1058+
assert rdtcipr1.DTCAndStatusRecord[-1].numeric_value_code == 1027
1059+
assert rdtcipr1.DTCAndStatusRecord[-1].additional_information_code == 18
10621060

10631061
= Check UDS_RDTCI
10641062

@@ -1175,11 +1173,10 @@ rdtcipr.show()
11751173
assert rdtcipr.service == 0x59
11761174
assert rdtcipr.reportType == 2
11771175
assert rdtcipr.DTCStatusAvailabilityMask == 0xff
1178-
assert rdtcipr.DTCAndStatusRecord[0].dtc.system == 3
1179-
assert rdtcipr.DTCAndStatusRecord[0].dtc.type == 2
1180-
assert rdtcipr.DTCAndStatusRecord[0].dtc.numeric_value_code == 3805
1181-
assert rdtcipr.DTCAndStatusRecord[0].dtc.additional_information_code == 170
1182-
assert rdtcipr.DTCAndStatusRecord[0].status == 2
1176+
assert rdtcipr.DTCAndStatusRecord[0].system == 3
1177+
assert rdtcipr.DTCAndStatusRecord[0].type == 2
1178+
assert rdtcipr.DTCAndStatusRecord[0].numeric_value_code == 3805
1179+
assert rdtcipr.DTCAndStatusRecord[0].additional_information_code == 170
11831180

11841181
assert not rdtcipr.answers(rdtci)
11851182

0 commit comments

Comments
 (0)