@@ -1000,6 +1000,256 @@ static uint8_t safe_copy(UDSServer_t *srv, const void *src, uint16_t count) {
10001000 return UDS_NRC_ResponseTooLong ;
10011001}
10021002
1003+ static UDSErr_t Handle_0x19_ReadDTCInformation (UDSServer_t * srv , UDSReq_t * r ) {
1004+ UDSErr_t ret = UDS_PositiveResponse ;
1005+ uint8_t type = r -> recv_buf [1 ];
1006+
1007+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN ) {
1008+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1009+ }
1010+
1011+ /* Shared by all SubFunc */
1012+ r -> send_buf [0 ] = UDS_RESPONSE_SID_OF (kSID_READ_DTC_INFORMATION );
1013+ r -> send_buf [1 ] = type ;
1014+ r -> send_len = UDS_0X19_RESP_BASE_LEN ;
1015+
1016+ UDSRDTCIArgs_t args = {
1017+ .type = type ,
1018+ .copy = safe_copy ,
1019+ };
1020+
1021+ /* Before checks and emitting Request */
1022+ switch (type ) {
1023+ case 0x01 : /* reportNumberOfDTCByStatusMask */
1024+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 1 ) {
1025+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1026+ }
1027+
1028+ args .numOfDTCByStatusMaskArgs .mask = r -> recv_buf [2 ];
1029+ break ;
1030+ case 0x02 : /* reportDTCByStatusMask */
1031+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 1 ) {
1032+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1033+ }
1034+
1035+ args .dtcStatusByMaskArgs .mask = r -> recv_buf [2 ];
1036+ break ;
1037+ case 0x03 : /* reportDTCSnapshotIdentification */
1038+ case 0x0A : /* reportSupportedDTC */
1039+ case 0x0B : /* reportFirstTestFailedDTC */
1040+ case 0x0C : /* reportFirstConfirmedDTC */
1041+ case 0x0D : /* reportMostRecentTestFailedDTC */
1042+ case 0x0E : /* reportMostRecentConfirmedDTC */
1043+ case 0x14 : /* reportDTCFaultDetectionCounter */
1044+ case 0x15 : /* reportDTCWithPermanentStatus */
1045+ /* has no subfunction specific args */
1046+ break ;
1047+ case 0x04 : /* reportDTCSnapshotRecordByDTCNumber */
1048+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 4 ) {
1049+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1050+ }
1051+
1052+ args .dtcSnapshotRecordbyDTCNumArgs .dtc =
1053+ (r -> recv_buf [2 ] << 16 | r -> recv_buf [3 ] << 8 | r -> recv_buf [4 ]) & 0x00FFFFFF ;
1054+ args .dtcSnapshotRecordbyDTCNumArgs .snapshotNum = r -> recv_buf [5 ];
1055+ break ;
1056+ case 0x05 : /* reportDTCStoredDataByRecordNumber */
1057+ case 0x16 : /* reportDTCExtDataRecordByNumber */
1058+ case 0x1A : /* reportDTCExtendedDataRecordIdentification */
1059+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 1 ) {
1060+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1061+ }
1062+
1063+ args .dtcStoredDataByRecordNumArgs .recordNum = r -> recv_buf [2 ];
1064+ break ;
1065+ case 0x06 : /* reportDTCExtDataRecordByDTCNumber */
1066+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 4 ) {
1067+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1068+ }
1069+
1070+ args .dtcExtDtaRecordByDTCNumArgs .dtc =
1071+ (r -> recv_buf [2 ] << 16 | r -> recv_buf [3 ] << 8 | r -> recv_buf [4 ]) & 0x00FFFFFF ;
1072+ args .dtcExtDtaRecordByDTCNumArgs .extDataRecNum = r -> recv_buf [5 ];
1073+ break ;
1074+ case 0x07 : /* reportNumberOfDTCBySeverityMaskRecord */
1075+ case 0x08 : /* reportDTCBySeverityMaskRecord */
1076+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 2 ) {
1077+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1078+ }
1079+
1080+ args .numOfDTCBySeverityMaskArgs .severityMask = r -> recv_buf [2 ];
1081+ args .numOfDTCBySeverityMaskArgs .statusMask = r -> recv_buf [3 ];
1082+ break ;
1083+ case 0x09 : /* reportSeverityInformationOfDTC */
1084+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 1 ) {
1085+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1086+ }
1087+
1088+ args .severityInfoOfDTCArgs .dtc =
1089+ (r -> recv_buf [2 ] << 16 | r -> recv_buf [3 ] << 8 | r -> recv_buf [4 ]) & 0x00FFFFFF ;
1090+ break ;
1091+ case 0x17 : /* reportUserDefMemoryDTCByStatusMask */
1092+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 2 ) {
1093+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1094+ }
1095+
1096+ args .userDefMemoryDTCByStatusMaskArgs .mask = r -> recv_buf [2 ];
1097+ args .userDefMemoryDTCByStatusMaskArgs .memory = r -> recv_buf [3 ];
1098+ break ;
1099+ case 0x18 : /* reportUserDefMemoryDTCSnapshotRecordByDTCNumber */
1100+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 5 ) {
1101+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1102+ }
1103+
1104+ args .userDefMemDTCSnapshotRecordByDTCNumArgs .dtc =
1105+ (r -> recv_buf [2 ] << 16 | r -> recv_buf [3 ] << 8 | r -> recv_buf [4 ]) & 0x00FFFFFF ;
1106+ args .userDefMemDTCSnapshotRecordByDTCNumArgs .snapshotNum = r -> recv_buf [5 ];
1107+ args .userDefMemDTCSnapshotRecordByDTCNumArgs .memory = r -> recv_buf [6 ];
1108+ break ;
1109+ case 0x19 : /* reportUserDefMemoryDTCExtDataRecordByDTCNumber */
1110+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 5 ) {
1111+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1112+ }
1113+
1114+ args .userDefMemDTCExtDataRecordByDTCNumArgs .dtc =
1115+ (r -> recv_buf [2 ] << 16 | r -> recv_buf [3 ] << 8 | r -> recv_buf [4 ]) & 0x00FFFFFF ;
1116+ args .userDefMemDTCExtDataRecordByDTCNumArgs .extDataRecNum = r -> recv_buf [5 ];
1117+ args .userDefMemDTCExtDataRecordByDTCNumArgs .memory = r -> recv_buf [6 ];
1118+ break ;
1119+ case 0x42 : /* reportWWHOBDDTCByMaskRecord */
1120+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 3 ) {
1121+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1122+ }
1123+
1124+ args .wwhobdDTCByMaskArgs .functionalGroup = r -> recv_buf [2 ];
1125+ args .wwhobdDTCByMaskArgs .statusMask = r -> recv_buf [3 ];
1126+ args .wwhobdDTCByMaskArgs .severityMask = r -> recv_buf [4 ];
1127+ break ;
1128+ case 0x55 : /* reportWWHOBDDTCWithPermanentStatus */
1129+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 1 ) {
1130+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1131+ }
1132+
1133+ args .wwhobdDTCWithPermStatusArgs .functionalGroup = r -> recv_buf [2 ];
1134+ break ;
1135+ case 0x56 : /* reportDTCInformationByDTCReadinessGroupIdentifier */
1136+ if (r -> recv_len < UDS_0X19_REQ_MIN_LEN + 2 ) {
1137+ return NegativeResponse (r , UDS_NRC_IncorrectMessageLengthOrInvalidFormat );
1138+ }
1139+
1140+ args .dtcInfoByDTCReadinessGroupIdArgs .functionalGroup = r -> recv_buf [2 ];
1141+ args .dtcInfoByDTCReadinessGroupIdArgs .readinessGroup = r -> recv_buf [3 ];
1142+ break ;
1143+ default :
1144+ return NegativeResponse (r , UDS_NRC_SubFunctionNotSupported );
1145+ }
1146+
1147+ ret = EmitEvent (srv , UDS_EVT_ReadDTCInformation , & args );
1148+
1149+ if (UDS_PositiveResponse != ret ) {
1150+ return NegativeResponse (r , ret );
1151+ }
1152+
1153+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN ) {
1154+ return UDS_NRC_GeneralProgrammingFailure ;
1155+ }
1156+
1157+ /* subfunc specific reply len checks */
1158+ switch (type ) {
1159+ case 0x01 : /* reportNumberOfDTCByStatusMask */
1160+ case 0x07 : /* reportNumberOfDTCBySeverityMaskRecord */
1161+ if (r -> send_len != UDS_0X19_RESP_BASE_LEN + 4 ) {
1162+ return UDS_NRC_GeneralProgrammingFailure ;
1163+ }
1164+ break ;
1165+ case 0x02 : /* reportDTCByStatusMask */
1166+ case 0x0A : /* reportSupportedDTC */
1167+ case 0x0B : /* reportFirstTestFailedDTC */
1168+ case 0x0C : /* reportFirstConfirmedDTC */
1169+ case 0x0D : /* reportMostRecentTestFailedDTC */
1170+ case 0x0E : /* reportMostRecentConfirmedDTC */
1171+ case 0x15 : /* reportDTCWithPermanentStatus */
1172+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 1 ||
1173+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 1 ) &&
1174+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 1 )) % 4 != 0 ) {
1175+ return UDS_NRC_GeneralProgrammingFailure ;
1176+ }
1177+ break ;
1178+ case 0x03 : /* reportDTCSnapshotIdentification */
1179+ case 0x14 : /* reportDTCFaultDetectionCounter */
1180+ if ((r -> send_len - UDS_0X19_RESP_BASE_LEN ) % 4 != 0 ) {
1181+ return UDS_NRC_GeneralProgrammingFailure ;
1182+ }
1183+ break ;
1184+ case 0x04 : /* reportDTCSnapshotRecordByDTCNumber */
1185+ case 0x06 : /* reportDTCExtDataRecordByDTCNumber */
1186+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 4 ) {
1187+ return UDS_NRC_GeneralProgrammingFailure ;
1188+ }
1189+ break ;
1190+ case 0x05 : /* reportDTCStoredDataByRecordNumber */
1191+ case 0x16 : /* reportDTCExtDataRecordByNumber */
1192+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 1 ) {
1193+ return UDS_NRC_GeneralProgrammingFailure ;
1194+ }
1195+ break ;
1196+ case 0x08 : /* reportDTCBySeverityMaskRecord */
1197+ case 0x09 : /* reportSeverityInformationOfDTC */
1198+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 1 ||
1199+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 1 &&
1200+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 1 )) % 6 != 0 )) {
1201+ return UDS_NRC_GeneralProgrammingFailure ;
1202+ }
1203+ break ;
1204+ case 0x17 : /* reportUserDefMemoryDTCByStatusMask */
1205+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 2 ||
1206+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 2 &&
1207+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 2 )) % 4 != 0 )) {
1208+ return UDS_NRC_GeneralProgrammingFailure ;
1209+ }
1210+ break ;
1211+ case 0x18 : /* reportUserDefMemoryDTCSnapshotRecordByDTCNumber */
1212+ case 0x19 : /* reportUserDefMemoryDTCExtDataRecordByDTCNumber */
1213+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 5 ) {
1214+ return UDS_NRC_GeneralProgrammingFailure ;
1215+ }
1216+ break ;
1217+ case 0x1A : /* reportDTCExtendedDataRecordIdentification */
1218+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 1 ||
1219+ (r -> send_len != UDS_0X19_RESP_BASE_LEN + 5 ) ||
1220+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 5 &&
1221+ (r -> send_len - UDS_0X19_RESP_BASE_LEN + 5 ) % 4 != 0 )) {
1222+ return UDS_NRC_GeneralProgrammingFailure ;
1223+ }
1224+ break ;
1225+ case 0x42 : /* reportWWHOBDDTCByMaskRecord */
1226+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 4 ||
1227+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 4 &&
1228+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 4 )) % 5 != 0 )) {
1229+ return UDS_NRC_GeneralProgrammingFailure ;
1230+ }
1231+ break ;
1232+ case 0x55 : /* reportWWHOBDDTCWithPermanentStatus */
1233+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 3 ||
1234+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 3 &&
1235+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 3 )) % 4 != 0 )) {
1236+ return UDS_NRC_GeneralProgrammingFailure ;
1237+ }
1238+ break ;
1239+ case 0x56 : /* reportDTCInformationByDTCReadinessGroupIdentifier */
1240+ if (r -> send_len < UDS_0X19_RESP_BASE_LEN + 4 ||
1241+ (r -> send_len > UDS_0X19_RESP_BASE_LEN + 4 &&
1242+ (r -> send_len - (UDS_0X19_RESP_BASE_LEN + 4 )) % 4 != 0 )) {
1243+ return UDS_NRC_GeneralProgrammingFailure ;
1244+ }
1245+ break ;
1246+ default :
1247+ return UDS_NRC_SubFunctionNotSupported ;
1248+ }
1249+
1250+ return UDS_PositiveResponse ;
1251+ }
1252+
10031253static UDSErr_t Handle_0x22_ReadDataByIdentifier (UDSServer_t * srv , UDSReq_t * r ) {
10041254 uint8_t numDIDs ;
10051255 uint16_t dataId = 0 ;
@@ -1726,7 +1976,7 @@ static UDSService getServiceForSID(uint8_t sid) {
17261976 case kSID_CLEAR_DIAGNOSTIC_INFORMATION :
17271977 return NULL ;
17281978 case kSID_READ_DTC_INFORMATION :
1729- return NULL ;
1979+ return Handle_0x19_ReadDTCInformation ;
17301980 case kSID_READ_DATA_BY_IDENTIFIER :
17311981 return Handle_0x22_ReadDataByIdentifier ;
17321982 case kSID_READ_MEMORY_BY_ADDRESS :
0 commit comments