16
16
BitEnumField , BitField , XByteField , FieldListField , \
17
17
XShortField , X3BytesField , XIntField , ByteField , \
18
18
ShortField , ObservableDict , XShortEnumField , XByteEnumField , StrLenField , \
19
- FieldLenField , XStrFixedLenField , XStrLenField
19
+ FieldLenField , XStrFixedLenField , XStrLenField , FlagsField , PacketListField , \
20
+ PacketField
20
21
from scapy .packet import Packet , bind_layers , NoPayload
21
22
from scapy .config import conf
22
23
from scapy .error import log_loading
@@ -956,12 +957,39 @@ class UDS_RDTCI(Packet):
956
957
20 : 'reportDTCFaultDetectionCounter' ,
957
958
21 : 'reportDTCWithPermanentStatus'
958
959
}
960
+ dtcStatus = {
961
+ 1 : 'TestFailed' ,
962
+ 2 : 'TestFailedThisOperationCycle' ,
963
+ 4 : 'PendingDTC' ,
964
+ 8 : 'ConfirmedDTC' ,
965
+ 16 : 'TestNotCompletedSinceLastClear' ,
966
+ 32 : 'TestFailedSinceLastClear' ,
967
+ 64 : 'TestNotCompletedThisOperationCycle' ,
968
+ 128 : 'WarningIndicatorRequested'
969
+ }
970
+ dtcStatusMask = {
971
+ 1 : 'ActiveDTCs' ,
972
+ 4 : 'PendingDTCs' ,
973
+ 8 : 'ConfirmedOrStoredDTCs' ,
974
+ 255 : 'AllRecordDTCs'
975
+ }
976
+ dtcSeverityMask = {
977
+ # 0: 'NoSeverityInformation',
978
+ 1 : 'NoClassInformation' ,
979
+ 2 : 'WWH-OBDClassA' ,
980
+ 4 : 'WWH-OBDClassB1' ,
981
+ 8 : 'WWH-OBDClassB2' ,
982
+ 16 : 'WWH-OBDClassC' ,
983
+ 32 : 'MaintenanceRequired' ,
984
+ 64 : 'CheckAtNextHalt' ,
985
+ 128 : 'CheckImmediately'
986
+ }
959
987
name = 'ReadDTCInformation'
960
988
fields_desc = [
961
989
ByteEnumField ('reportType' , 0 , reportTypes ),
962
- ConditionalField (ByteField ('DTCSeverityMask' , 0 ),
990
+ ConditionalField (FlagsField ('DTCSeverityMask' , 0 , 8 , dtcSeverityMask ),
963
991
lambda pkt : pkt .reportType in [0x07 , 0x08 ]),
964
- ConditionalField (XByteField ('DTCStatusMask' , 0 ),
992
+ ConditionalField (FlagsField ('DTCStatusMask' , 0 , 8 , dtcStatusMask ),
965
993
lambda pkt : pkt .reportType in [
966
994
0x01 , 0x02 , 0x07 , 0x08 , 0x0f , 0x11 , 0x12 , 0x13 ]),
967
995
ConditionalField (ByteField ('DTCHighByte' , 0 ),
@@ -983,16 +1011,47 @@ class UDS_RDTCI(Packet):
983
1011
bind_layers (UDS , UDS_RDTCI , service = 0x19 )
984
1012
985
1013
1014
+ class DTC (Packet ):
1015
+ name = 'Diagnostic Trouble Code'
1016
+ 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" }),
1027
+ BitField ("numeric_value_code" , 0 , 12 ),
1028
+ 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 ),
1039
+ FlagsField ("status" , 0 , 8 , UDS_RDTCI .dtcStatus )
1040
+ ]
1041
+
1042
+ def extract_padding (self , s ):
1043
+ return '' , s
1044
+
1045
+
986
1046
class UDS_RDTCIPR (Packet ):
987
1047
name = 'ReadDTCInformationPositiveResponse'
988
1048
fields_desc = [
989
1049
ByteEnumField ('reportType' , 0 , UDS_RDTCI .reportTypes ),
990
- ConditionalField (XByteField ('DTCStatusAvailabilityMask' , 0 ),
991
- lambda pkt : pkt .reportType in [0x01 , 0x07 , 0x11 ,
992
- 0x12 , 0x02 , 0x0A ,
993
- 0x0B , 0x0C , 0x0D ,
994
- 0x0E , 0x0F , 0x13 ,
995
- 0x15 ]),
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 ]),
996
1055
ConditionalField (ByteEnumField ('DTCFormatIdentifier' , 0 ,
997
1056
{0 : 'ISO15031-6DTCFormat' ,
998
1057
1 : 'UDS-1DTCFormat' ,
@@ -1003,7 +1062,8 @@ class UDS_RDTCIPR(Packet):
1003
1062
ConditionalField (ShortField ('DTCCount' , 0 ),
1004
1063
lambda pkt : pkt .reportType in [0x01 , 0x07 ,
1005
1064
0x11 , 0x12 ]),
1006
- ConditionalField (StrField ('DTCAndStatusRecord' , b"" ),
1065
+ ConditionalField (PacketListField ('DTCAndStatusRecord' , None ,
1066
+ pkt_cls = DTC_Status ),
1007
1067
lambda pkt : pkt .reportType in [0x02 , 0x0A , 0x0B ,
1008
1068
0x0C , 0x0D , 0x0E ,
1009
1069
0x0F , 0x13 , 0x15 ]),
@@ -1259,24 +1319,24 @@ def _contains_data_format_identifier(packet):
1259
1319
fmt = 'B' ),
1260
1320
lambda p : p .modeOfOperation != 2 ),
1261
1321
ConditionalField (StrLenField ('maxNumberOfBlockLength' , b"" ,
1262
- length_from = lambda p : p .lengthFormatIdentifier ),
1322
+ length_from = lambda p : p .lengthFormatIdentifier ),
1263
1323
lambda p : p .modeOfOperation != 2 ),
1264
1324
ConditionalField (BitField ('compressionMethod' , 0 , 4 ),
1265
1325
lambda p : p .modeOfOperation != 0x02 ),
1266
1326
ConditionalField (BitField ('encryptingMethod' , 0 , 4 ),
1267
1327
lambda p : p .modeOfOperation != 0x02 ),
1268
1328
ConditionalField (FieldLenField ('fileSizeOrDirInfoParameterLength' ,
1269
- None ,
1270
- length_of = 'fileSizeUncompressedOrDirInfoLength' ),
1329
+ None ,
1330
+ length_of = 'fileSizeUncompressedOrDirInfoLength' ),
1271
1331
lambda p : p .modeOfOperation not in [1 , 2 , 3 ]),
1272
1332
ConditionalField (StrLenField ('fileSizeUncompressedOrDirInfoLength' ,
1273
1333
b"" ,
1274
1334
length_from = lambda p :
1275
1335
p .fileSizeOrDirInfoParameterLength ),
1276
1336
lambda p : p .modeOfOperation not in [1 , 2 , 3 ]),
1277
1337
ConditionalField (StrLenField ('fileSizeCompressed' , b"" ,
1278
- length_from = lambda p :
1279
- p .fileSizeOrDirInfoParameterLength ),
1338
+ length_from = lambda p :
1339
+ p .fileSizeOrDirInfoParameterLength ),
1280
1340
lambda p : p .modeOfOperation not in [1 , 2 , 3 , 5 ]),
1281
1341
]
1282
1342
0 commit comments