Skip to content

Commit b0f2eb0

Browse files
committed
chore: update iso14229.c/h files
Signed-off-by: Tim Schrader <tim.schrader@frickly.systems>
1 parent 1ec2b31 commit b0f2eb0

File tree

2 files changed

+298
-2
lines changed

2 files changed

+298
-2
lines changed

iso14229.c

Lines changed: 251 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
10031253
static 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:

iso14229.h

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ typedef enum UDSEvent {
301301
// Server Event ----------------- Argument Type
302302
UDS_EVT_DiagSessCtrl, // UDSDiagSessCtrlArgs_t *
303303
UDS_EVT_EcuReset, // UDSECUResetArgs_t *
304+
UDS_EVT_ReadDTCInformation, // UDSRDTCIArgs_t *
304305
UDS_EVT_ReadDataByIdent, // UDSRDBIArgs_t *
305306
UDS_EVT_ReadMemByAddr, // UDSReadMemByAddrArgs_t *
306307
UDS_EVT_CommCtrl, // UDSCommCtrlArgs_t *
@@ -487,13 +488,15 @@ typedef enum {
487488
#define UDS_MAX_DIAGNOSTIC_SERVICES 0x7F
488489

489490
#define UDS_RESPONSE_SID_OF(request_sid) ((request_sid) + 0x40)
490-
#define UDS_REQUEST_SID_OF(response_sid) ((response_sid)-0x40)
491+
#define UDS_REQUEST_SID_OF(response_sid) ((response_sid) - 0x40)
491492

492493
#define UDS_NEG_RESP_LEN 3U
493494
#define UDS_0X10_REQ_LEN 2U
494495
#define UDS_0X10_RESP_LEN 6U
495496
#define UDS_0X11_REQ_MIN_LEN 2U
496497
#define UDS_0X11_RESP_BASE_LEN 2U
498+
#define UDS_0X19_REQ_MIN_LEN 2U
499+
#define UDS_0X19_RESP_BASE_LEN 2U
497500
#define UDS_0X23_REQ_MIN_LEN 4U
498501
#define UDS_0X23_RESP_BASE_LEN 1U
499502
#define UDS_0X22_RESP_BASE_LEN 1U
@@ -882,6 +885,49 @@ typedef struct {
882885
a UDS_EVT_DoScheduledReset will be issued */
883886
} UDSECUResetArgs_t;
884887

888+
typedef struct {
889+
const uint8_t type; /*! invoked subfunction */
890+
uint8_t (*copy)(UDSServer_t *srv, const void *src,
891+
uint16_t count); /*! function for copying data */
892+
893+
union {
894+
struct {
895+
uint8_t mask; /*! DTC status mask */
896+
} numOfDTCByStatusMaskArgs, dtcStatusByMaskArgs;
897+
struct {
898+
uint32_t dtc; /*! DTC Mask Record */
899+
uint8_t snapshotNum; /*! DTC Snaphot Record Number */
900+
uint8_t memory; /*! Memory Selection (only used when type == 0x18) */
901+
} dtcSnapshotRecordbyDTCNumArgs, userDefMemDTCSnapshotRecordByDTCNumArgs;
902+
struct {
903+
uint8_t recordNum; /*! DTC Data Record Number */
904+
} dtcStoredDataByRecordNumArgs, dtcExtDataRecordByRecordNumArgs, dtcExtDataRecordIdArgs;
905+
struct {
906+
uint32_t dtc; /*! DTC Mask Record */
907+
uint8_t extDataRecNum; /*! DTC Extended Data Record Number */
908+
uint8_t memory; /*! Memory Selection (only used when type == 0x19) */
909+
} dtcExtDtaRecordByDTCNumArgs, userDefMemDTCExtDataRecordByDTCNumArgs;
910+
struct {
911+
uint8_t
912+
functionalGroup; /*! Functional Group Identifier (only used when type == 0x42) */
913+
uint8_t severityMask; /*! DTC Severity Mask */
914+
uint8_t statusMask; /*! DTC Status Mask */
915+
} numOfDTCBySeverityMaskArgs, dtcBySeverityMaskArgs, wwhobdDTCByMaskArgs;
916+
struct {
917+
uint32_t dtc; /*! DTC Mask Record */
918+
} severityInfoOfDTCArgs;
919+
struct {
920+
uint8_t mask; /*! DTC status mask */
921+
uint8_t memory; /*! Memory Selection */
922+
} userDefMemoryDTCByStatusMaskArgs;
923+
struct {
924+
uint8_t functionalGroup; /*! Functional Group Identifier */
925+
uint8_t
926+
readinessGroup; /*! DTC Readiness Group Identifier (only used when type == 0x56) */
927+
} wwhobdDTCWithPermStatusArgs, dtcInfoByDTCReadinessGroupIdArgs;
928+
};
929+
} UDSRDTCIArgs_t;
930+
885931
typedef struct {
886932
const uint16_t dataId; /*! RDBI Data Identifier */
887933
uint8_t (*copy)(UDSServer_t *srv, const void *src,

0 commit comments

Comments
 (0)