1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
19 #include "Dcm_Cfg.h"
\r
21 #include "Dcm_Internal.h"
\r
27 #define ZERO_SUB_FUNCTION 0x00
\r
32 #define BYTES_TO_DTC(hb, mb, lb) (((hb) << 16) | ((mb) << 8) | (lb))
\r
33 #define DTC_HIGH_BYTE(dtc) (((dtc)>> 16) & 0xFF)
\r
34 #define DTC_MID_BYTE(dtc) (((dtc)>> 8) & 0xFF)
\r
35 #define DTC_LOW_BYTE(dtc) ((dtc) & 0xFF)
\r
38 boolean resetPending;
\r
39 PduIdType resetPduId;
\r
40 } DspUdsEcuResetDataType;
\r
42 static DspUdsEcuResetDataType dspUdsEcuResetData;
\r
46 boolean reqInProgress;
\r
47 Dcm_SecLevelType reqSecLevel;
\r
48 const Dcm_DspSecurityRowType *reqSecLevelRef;
\r
49 } DspUdsSecurityAccessDataType;
\r
51 static DspUdsSecurityAccessDataType dspUdsSecurityAccesData;
\r
56 dspUdsSecurityAccesData.reqInProgress = FALSE;
\r
57 dspUdsEcuResetData.resetPending = FALSE;
\r
67 Std_ReturnType AskApplicationForSessionPermission(Dcm_SesCtrlType newSessionLevel)
\r
69 Std_ReturnType returnCode = E_OK;
\r
70 Dcm_SesCtrlType currentSessionLevel;
\r
71 Std_ReturnType result;
\r
74 for (i = 0; !DCM_Config.Dsl->DslSessionControl[i].Arc_EOL && (returnCode != E_SESSION_NOT_ALLOWED); i++) {
\r
75 if (DCM_Config.Dsl->DslSessionControl[i].GetSesChgPermission != NULL) {
\r
76 Dcm_GetSesCtrlType(¤tSessionLevel);
\r
77 result = DCM_Config.Dsl->DslSessionControl[i].GetSesChgPermission(currentSessionLevel ,newSessionLevel);
\r
78 if (result != E_OK) {
\r
79 returnCode = result;
\r
88 void DspUdsDiagnosticSessionControl(void)
\r
91 Dcm_SesCtrlType reqSessionType;
\r
92 Std_ReturnType result;
\r
95 if (dslMsgData.pduRxData->SduLength == 2) {
\r
96 reqSessionType = dslMsgData.pduRxData->SduDataPtr[1];
\r
97 // Check if type exist in session table
\r
98 for (i = 0; (DCM_Config.Dsp->DspSession->DspSessionRow[i].DspSessionLevel != reqSessionType) && !DCM_Config.Dsp->DspSession->DspSessionRow[i].Arc_EOL;i++);
\r
100 if (!DCM_Config.Dsp->DspSession->DspSessionRow[i].Arc_EOL) {
\r
101 result = AskApplicationForSessionPermission(reqSessionType);
\r
102 if (result == E_OK) {
\r
103 DslSetSesCtrlType(reqSessionType); /** @req DCM311 **/
\r
104 // Create positive response
\r
105 /** @req DCM039.2 **/
\r
106 dslMsgData.pduTxData->SduDataPtr[1] = reqSessionType;
\r
107 dslMsgData.pduTxData->SduLength = 2;
\r
108 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.2 **/
\r
111 // TODO: Add handling of special case of E_FORCE_RCRRP (Dcm138)
\r
112 DsdDspProcessingDone(DCM_E_CONDITIONSNOTCORRECT); /** @req DCM308 **/
\r
116 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED); /** @req DCM307 **/
\r
121 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT); /** @req DCM272.1 **/
\r
126 void DspUdsEcuReset(void)
\r
129 uint8 reqResetType;
\r
131 if (dslMsgData.pduRxData->SduLength == 2) {
\r
132 reqResetType = dslMsgData.pduRxData->SduDataPtr[1];
\r
134 switch (reqResetType)
\r
136 case 0x01: // Hard reset
\r
137 // TODO: Ask application for permission (Dcm373) (Dcm375) (Dcm377)
\r
139 // Schedule the reset
\r
140 dspUdsEcuResetData.resetPending = TRUE;
\r
141 dspUdsEcuResetData.resetPduId = DCM_PDU_ID_UDS_TX;
\r
143 // Create positive response
\r
144 /** @req DCM039.1 **/
\r
145 dslMsgData.pduTxData->SduDataPtr[1] = reqResetType;
\r
146 dslMsgData.pduTxData->SduLength = 2;
\r
147 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.3 **/
\r
151 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED); /** @req DCM273.3 **/
\r
157 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT); /** @req DCM272.3 **/
\r
162 void DspUdsClearDiagnosticInformation(void)
\r
165 Dem_ReturnClearDTCType result;
\r
167 if (dslMsgData.pduRxData->SduLength == 4) {
\r
168 dtc = BYTES_TO_DTC(dslMsgData.pduRxData->SduDataPtr[1], dslMsgData.pduRxData->SduDataPtr[2], dslMsgData.pduRxData->SduDataPtr[3]);
\r
170 result = Dem_ClearDTC(dtc, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY);
\r
175 // Create positive response
\r
176 /** @req DCM039.1 **/
\r
177 dslMsgData.pduTxData->SduLength = 1;
\r
178 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.4 **/
\r
182 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
188 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT); /** @req DCM272.1 **/
\r
193 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x01_0x07_0x11_0x12(void)
\r
198 uint8 dtcStatusAvailabilityMask;
\r
199 uint8 dtcFormatIdentifier;
\r
200 uint8 dtcCountHighByte;
\r
201 uint8 dtcCountLowByte;
\r
204 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
205 Dem_ReturnSetDTCFilterType setDtcFilterResult;
\r
207 // Setup the DTC filter
\r
208 switch (dslMsgData.pduRxData->SduDataPtr[1]) /** @reg DCM293 **/
\r
210 case 0x01: // reportNumberOfDTCByStatusMask
\r
211 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
214 case 0x07: // reportNumberOfDTCBySeverityMaskRecord
\r
215 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[3], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_YES, dslMsgData.pduRxData->SduDataPtr[2], DEM_FILTER_FOR_FDC_NO);
\r
218 case 0x11: // reportNumberOfMirrorMemoryDTCByStatusMask
\r
219 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_MIRROR_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
222 case 0x12: // reportNumberOfEmissionRelatedOBDDTCByStatusMask
\r
223 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSON_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
227 setDtcFilterResult = DEM_WRONG_FILTER;
\r
228 #if (DCM_DEV_ERROR_DETECT == STD_ON)
\r
229 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);
\r
234 if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {
\r
235 uint16 numberOfFilteredDtc;
\r
236 uint8 dtcStatusMask;
\r
237 TxDataType *txData = (TxDataType*)dslMsgData.pduTxData->SduDataPtr;
\r
239 /** @reg DCM376 **/
\r
240 Dem_GetNumberOfFilteredDtc(&numberOfFilteredDtc);
\r
241 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);
\r
243 // Create positive response (ISO 14229-1 table 251)
\r
244 /** @req DCM039.0x19 **/
\r
245 txData->reportType = dslMsgData.pduRxData->SduDataPtr[1]; // reportType
\r
246 txData->dtcStatusAvailabilityMask = dtcStatusMask; // DTCStatusAvailabilityMask
\r
247 txData->dtcFormatIdentifier = Dem_GetTranslationType(); // DTCFormatIdentifier
\r
248 txData->dtcCountHighByte = (numberOfFilteredDtc >> 8); // DTCCount high byte
\r
249 txData->dtcCountLowByte = (numberOfFilteredDtc & 0xFF); // DTCCount low byte
\r
250 dslMsgData.pduTxData->SduLength = 6;
\r
253 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
256 return responseCode;
\r
260 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(void)
\r
262 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
263 Dem_ReturnSetDTCFilterType setDtcFilterResult;
\r
267 uint8 dtcMiddleByte;
\r
270 } dtcAndStatusRecordType;
\r
275 uint8 dtcStatusAvailabilityMask;
\r
276 dtcAndStatusRecordType dtcAndStatusRecord[];
\r
279 // Setup the DTC filter
\r
280 switch (dslMsgData.pduRxData->SduDataPtr[1]) /** @reg DCM378 **/
\r
282 case 0x02: // reportDTCByStatusMask
\r
283 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
286 case 0x0A: // reportSupportedDTC
\r
287 setDtcFilterResult = Dem_SetDTCFilter(DEM_DTC_STATUS_MASK_ALL, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
290 case 0x0F: // reportMirrorMemoryDTCByStatusMask
\r
291 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_MIRROR_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
294 case 0x13: // reportEmissionRelatedOBDDTCByStatusMask
\r
295 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSON_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
298 case 0x15: // reportDTCWithPermanentStatus
\r
299 setDtcFilterResult = Dem_SetDTCFilter(DEM_DTC_STATUS_MASK_ALL, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PERMANENT_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
303 setDtcFilterResult = DEM_WRONG_FILTER;
\r
304 #if (DCM_DEV_ERROR_DETECT == STD_ON)
\r
305 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);
\r
310 if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {
\r
311 uint8 dtcStatusMask;
\r
312 TxDataType *txData = (TxDataType*)dslMsgData.pduTxData->SduDataPtr;
\r
313 Dem_ReturnGetNextFilteredDTCType getNextFilteredDtcResult;
\r
315 Dem_EventStatusExtendedType dtcStatus;
\r
316 uint16 nrOfDtcs = 0;
\r
318 /** @reg DCM377 **/
\r
319 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);
\r
321 // Create positive response (ISO 14229-1 table 252)
\r
322 /** @req DCM039.0x19 **/
\r
323 txData->reportType = dslMsgData.pduRxData->SduDataPtr[1];
\r
324 txData->dtcStatusAvailabilityMask = dtcStatusMask;
\r
326 if (dtcStatusMask != 0x00) { /** @req DCM008 **/
\r
327 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);
\r
328 while (getNextFilteredDtcResult == DEM_FILTERED_OK) {
\r
329 txData->dtcAndStatusRecord[nrOfDtcs].dtcHighByte = DTC_HIGH_BYTE(dtc);
\r
330 txData->dtcAndStatusRecord[nrOfDtcs].dtcMiddleByte = DTC_MID_BYTE(dtc);
\r
331 txData->dtcAndStatusRecord[nrOfDtcs].dtcLowByte = DTC_LOW_BYTE(dtc);
\r
332 txData->dtcAndStatusRecord[nrOfDtcs].statusOfDtc = dtcStatus;
\r
334 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);
\r
337 if (getNextFilteredDtcResult != DEM_FILTERED_NO_MATCHING_DTC) {
\r
338 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
341 dslMsgData.pduTxData->SduLength = 3 + nrOfDtcs * sizeof(dtcAndStatusRecordType);
\r
344 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
347 return responseCode;
\r
351 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x08(void)
\r
353 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
355 // TODO: Not supported yet, (DEM module does not currently support severity).
\r
356 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
358 return responseCode;
\r
362 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x09(void)
\r
364 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
366 // TODO: Not supported yet, (DEM module does not currently support severity).
\r
367 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
369 return responseCode;
\r
373 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x06_0x10(void)
\r
375 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
376 Dem_DTCOriginType dtcOrigin;
\r
380 // Switch on sub function
\r
381 switch (dslMsgData.pduRxData->SduDataPtr[1]) /** @reg DCM378 **/
\r
383 case 0x06: // reportDTCExtendedDataRecordByDTCNumber
\r
384 dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;
\r
387 case 0x10: // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber
\r
388 dtcOrigin = DEM_DTC_ORIGIN_MIRROR_MEMORY;
\r
392 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
393 #if (DCM_DEV_ERROR_DETECT == STD_ON)
\r
394 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);
\r
399 // Switch on record number
\r
400 switch (dslMsgData.pduRxData->SduDataPtr[5])
\r
402 case 0xFF: // Report all Extended Data Records for a particular DTC
\r
403 startRecNum = 0x00;
\r
407 case 0xFE: // Report all OBD Extended Data Records for a particular DTC
\r
408 startRecNum = 0x90;
\r
412 default: // Report one specific Extended Data Records for a particular DTC
\r
413 startRecNum = dslMsgData.pduRxData->SduDataPtr[5];
\r
414 endRecNum = startRecNum;
\r
418 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
419 Dem_ReturnGetStatusOfDTCType getStatusOfDtcResult;
\r
421 Dem_EventStatusExtendedType statusOfDtc;
\r
423 dtc = BYTES_TO_DTC(dslMsgData.pduRxData->SduDataPtr[2], dslMsgData.pduRxData->SduDataPtr[3], dslMsgData.pduRxData->SduDataPtr[4]);
\r
424 getStatusOfDtcResult = Dem_GetStatusOfDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, &statusOfDtc); /** @req DCM295 **/ /** @req DCM475 **/
\r
425 if (getStatusOfDtcResult == DEM_STATUS_OK) {
\r
426 Dem_ReturnGetExtendedDataRecordByDTCType getExtendedDataRecordByDtcResult;
\r
429 uint16 txIndex = 6;
\r
431 /** @req DCM297 **/ /** @req DCM474 **/ /** @req DCM386 **/
\r
432 dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1]; // Sub function
\r
433 dslMsgData.pduTxData->SduDataPtr[2] = DTC_HIGH_BYTE(dtc); // DTC high byte
\r
434 dslMsgData.pduTxData->SduDataPtr[3] = DTC_MID_BYTE(dtc); // DTC mid byte
\r
435 dslMsgData.pduTxData->SduDataPtr[4] = DTC_LOW_BYTE(dtc); // DTC low byte
\r
436 dslMsgData.pduTxData->SduDataPtr[5] = statusOfDtc; // DTC status
\r
437 for (recNum = startRecNum; recNum <= endRecNum; recNum++) {
\r
438 recLength = DCM_PHYS_BUFFER_SIZE - txIndex -1; // Calculate what's left in buffer
\r
439 /** @req DCM296 **/ /** @req DCM476 **/ /** @req DCM382 **/
\r
440 getExtendedDataRecordByDtcResult = Dem_GetExtendedDataRecordByDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, recNum, &dslMsgData.pduTxData->SduDataPtr[txIndex+1], &recLength);
\r
441 if (getExtendedDataRecordByDtcResult == DEM_RECORD_OK) {
\r
442 dslMsgData.pduTxData->SduDataPtr[txIndex++] = recNum;
\r
443 /* Instead of calling Dem_GetSizeOfExtendedDataRecordByDTC() the result from Dem_GetExtendedDataRecordByDTC() is used */
\r
444 /** @req DCM478 **/ /** @req DCM479 **/ /** @req DCM480 **/
\r
445 txIndex += recLength;
\r
448 // TODO: What to do here?
\r
451 dslMsgData.pduTxData->SduLength = txIndex;
\r
454 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
458 return responseCode;
\r
462 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x03(void)
\r
464 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
466 // TODO: Not supported yet
\r
467 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
469 return responseCode;
\r
473 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x04(void)
\r
475 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
477 // TODO: Not supported yet
\r
478 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
480 return responseCode;
\r
484 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x05(void)
\r
486 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
488 // TODO: Not supported yet
\r
489 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
491 return responseCode;
\r
495 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(void)
\r
497 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
499 // TODO: Not supported yet
\r
500 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
502 return responseCode;
\r
506 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x14(void)
\r
508 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
510 // TODO: Not supported yet
\r
511 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
513 return responseCode;
\r
517 void DspUdsReadDtcInformation(void)
\r
519 /** @reg DCM248 **/
\r
520 // Sub function number 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15
\r
521 const uint8 sduLength[0x16] = {0, 3, 3, 6, 6, 3, 6, 4, 4, 5, 2, 2, 2, 2, 2, 3, 6, 3, 3, 3, 2, 2};
\r
523 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
525 uint8 subFunctionNumber = dslMsgData.pduRxData->SduDataPtr[1];
\r
528 if (subFunctionNumber <= 0x15) {
\r
529 if (dslMsgData.pduRxData->SduLength == sduLength[subFunctionNumber]) {
\r
530 switch (subFunctionNumber)
\r
532 case 0x01: // reportNumberOfDTCByStatusMask
\r
533 case 0x07: // reportNumberOfDTCBySeverityMaskRecord
\r
534 case 0x11: // reportNumberOfMirrorMemoryDTCByStatusMask
\r
535 case 0x12: // reportNumberOfEmissionRelatedOBDDTCByStatusMask
\r
536 responseCode = DspUdsReadDtcInfoSub_0x01_0x07_0x11_0x12();
\r
539 case 0x02: // reportDTCByStatusMask
\r
540 case 0x0A: // reportSupportedDTC
\r
541 case 0x0F: // reportMirrorMemoryDTCByStatusMask
\r
542 case 0x13: // reportEmissionRelatedOBDDTCByStatusMask
\r
543 case 0x15: // reportDTCWithPermanentStatus
\r
544 responseCode = DspUdsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15();
\r
547 case 0x08: // reportDTCBySeverityMaskRecord
\r
548 responseCode = DspUdsReadDtcInfoSub_0x08();
\r
551 case 0x09: // reportSeverityInformationOfDTC
\r
552 responseCode = DspUdsReadDtcInfoSub_0x09();
\r
555 case 0x06: // reportDTCExtendedDataRecordByDTCNumber
\r
556 case 0x10: // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber
\r
557 responseCode = DspUdsReadDtcInfoSub_0x06_0x10();
\r
560 case 0x03: // reportDTCSnapshotIdentidication
\r
561 responseCode = DspUdsReadDtcInfoSub_0x03();
\r
564 case 0x04: // reportDTCSnapshotByDtcNumber
\r
565 responseCode = DspUdsReadDtcInfoSub_0x04();
\r
568 case 0x05: // reportDTCSnapshotRecordNumber
\r
569 responseCode = DspUdsReadDtcInfoSub_0x05();
\r
572 case 0x0B: // reportFirstTestFailedDTC
\r
573 case 0x0C: // reportFirstConfirmedDTC
\r
574 case 0x0D: // reportMostRecentTestFailedDTC
\r
575 case 0x0E: // reportMostRecentConfirmedDTC
\r
576 responseCode = DspUdsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E();
\r
579 case 0x14: // reportDTCFaultDetectionCounter
\r
580 responseCode = DspUdsReadDtcInfoSub_0x14();
\r
584 // Unknown sub function
\r
585 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
591 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT; /** @req DCM272.0x19 **/
\r
595 // Sub function out of range
\r
596 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
599 DsdDspProcessingDone(responseCode);
\r
603 void DspUdsSecurityAccess(void)
\r
605 /** @req DCM252 **/
\r
606 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
608 // Check sub function range (0x01 to 0x42)
\r
609 if ((dslMsgData.pduRxData->SduDataPtr[1] >= 0x01) && (dslMsgData.pduRxData->SduDataPtr[1] <= 0x42)) {
\r
610 boolean isRequestSeed = dslMsgData.pduRxData->SduDataPtr[1] & 0x01;
\r
611 Dcm_SecLevelType requestedSecurityLevel = (dslMsgData.pduRxData->SduDataPtr[1]-1)/2;
\r
612 Std_ReturnType getSeedResult;
\r
613 Dcm_NegativeResponseCodeType getSeedErrorCode;
\r
616 if (isRequestSeed) {
\r
617 // requestSeed message
\r
618 // Check if type exist in security table
\r
619 for (i = 0; (DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].DspSecurityLevel != requestedSecurityLevel) && !DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].Arc_EOL; i++);
\r
621 if (!DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].Arc_EOL) {
\r
622 const Dcm_DspSecurityRowType *requestedSecurity = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[i];
\r
624 if (dslMsgData.pduRxData->SduLength == (2 + requestedSecurity->DspSecurityADRSize)) { /** @req DCM321.1 **/
\r
625 Dcm_SecLevelType activeSecLevel;
\r
626 Dcm_GetSecurityLevel(&activeSecLevel);
\r
627 if (requestedSecurityLevel == activeSecLevel) { /** @req DCM323 **/
\r
628 // If same level set the seed to zeroes
\r
629 for (i = 0; i < requestedSecurity->DspSecuritySeedSize; i++) {
\r
630 dslMsgData.pduTxData->SduDataPtr[2+i] = 0;
\r
631 dslMsgData.pduTxData->SduLength = 2 + requestedSecurity->DspSecuritySeedSize;
\r
635 // New security level ask for seed
\r
636 getSeedResult = requestedSecurity->GetSeed(&dslMsgData.pduRxData->SduDataPtr[2], &dslMsgData.pduTxData->SduDataPtr[2], &getSeedErrorCode);
\r
637 if ((getSeedResult == E_OK) && (getSeedErrorCode == E_OK)) {
\r
638 // Everything ok add sub function to tx message and send it.
\r
639 dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1];
\r
640 dslMsgData.pduTxData->SduLength = 2 + requestedSecurity->DspSecuritySeedSize;
\r
642 dspUdsSecurityAccesData.reqSecLevel = requestedSecurityLevel;
\r
643 dspUdsSecurityAccesData.reqSecLevelRef = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[i];
\r
644 dspUdsSecurityAccesData.reqInProgress = TRUE;
\r
645 // TODO: Start security timeout
\r
648 // GetSeed returned not ok
\r
649 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
655 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
659 // Requested security level not configured
\r
660 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
665 if (dspUdsSecurityAccesData.reqInProgress) {
\r
666 if (dslMsgData.pduRxData->SduLength == (2 + dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityKeySize)) { /** @req DCM321 **/
\r
667 if (requestedSecurityLevel == dspUdsSecurityAccesData.reqSecLevel) {
\r
668 Std_ReturnType compareKeyResult;
\r
669 compareKeyResult = dspUdsSecurityAccesData.reqSecLevelRef->CompareKey(&dslMsgData.pduRxData->SduDataPtr[2]);
\r
670 if (compareKeyResult == E_OK) {
\r
671 // Request accepted
\r
673 DslSetSecurityLevel(dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityLevel);
\r
674 dspUdsSecurityAccesData.reqInProgress = FALSE;
\r
675 dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1];
\r
676 dslMsgData.pduTxData->SduLength = 2;
\r
679 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
683 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
688 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
692 // sendKey request without a preceding requestSeed
\r
693 responseCode = DCM_E_REQUESTSEQUENCEERROR;
\r
698 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
701 DsdDspProcessingDone(responseCode);
\r
705 void DspUdsTesterPresent(void)
\r
707 if (dslMsgData.pduRxData->SduLength == 2) {
\r
708 switch (dslMsgData.pduRxData->SduDataPtr[1])
\r
710 case ZERO_SUB_FUNCTION:
\r
711 DslResetSessionTimeoutTimer();
\r
712 // Create positive response
\r
713 /** @req DCM039.1 **/
\r
714 dslMsgData.pduTxData->SduDataPtr[1] = ZERO_SUB_FUNCTION;
\r
715 dslMsgData.pduTxData->SduLength = 2;
\r
716 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.1 **/
\r
720 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED); /** @req DCM273.1 **/
\r
726 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT); /** @req DCM272.1 **/
\r
731 void DspUdsControlDtcSetting(void)
\r
733 Dem_ReturnControlDTCStorageType resultCode;
\r
735 if (dslMsgData.pduRxData->SduLength == 2) {
\r
736 switch (dslMsgData.pduRxData->SduDataPtr[1])
\r
738 case 0x01: // ON /** @req DCM249.1 **/
\r
739 resultCode = Dem_EnableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS); /** @req DCM304 **/
\r
740 if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {
\r
741 dslMsgData.pduTxData->SduDataPtr[1] = 0x01;
\r
742 dslMsgData.pduTxData->SduLength = 2;
\r
743 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
746 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
750 case 0x02: // OFF /** @req DCM249.2 **/
\r
751 resultCode = Dem_DisableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS); /** @req DCM406 **/
\r
752 if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {
\r
753 dslMsgData.pduTxData->SduDataPtr[1] = 0x02;
\r
754 dslMsgData.pduTxData->SduLength = 2;
\r
755 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
758 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
763 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);
\r
769 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
774 void DspDcmConfirmation(PduIdType confirmPduId)
\r
776 if (dspUdsEcuResetData.resetPending) {
\r
777 if (confirmPduId == dspUdsEcuResetData.resetPduId) {
\r
778 dspUdsEcuResetData.resetPending = FALSE;
\r
779 Mcu_PerformReset();
\r