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
16 //lint -esym(754, SID) //Structure member SID not used in udsReadDtcInfoSub_0x01_0x07_0x11_0x12() and udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15()
\r
20 * General requirements
\r
22 /** @req DCM273 */ /** @req DCM272 */
\r
23 /** @req DCM039 */ /** @req DCM038 */ /** @req DCM269 */
\r
24 /** @req DCM271 */ /** @req DCM274 */ /** @req DCM275 */ /** @req DCM424 */
\r
29 #include "Dcm_Internal.h"
\r
32 #if defined(USE_MCU)
\r
36 #define ZERO_SUB_FUNCTION 0x00
\r
41 #define BYTES_TO_DTC(hb, mb, lb) (((uint32)(hb) << 16) | ((uint32)(mb) << 8) | (uint32)(lb))
\r
42 #define DTC_HIGH_BYTE(dtc) (((uint32)(dtc) >> 16) & 0xFFu)
\r
43 #define DTC_MID_BYTE(dtc) (((uint32)(dtc) >> 8) & 0xFFu)
\r
44 #define DTC_LOW_BYTE(dtc) ((uint32)(dtc) & 0xFFu)
\r
48 boolean resetPending;
\r
49 PduIdType resetPduId;
\r
50 } DspUdsEcuResetDataType;
\r
52 static DspUdsEcuResetDataType dspUdsEcuResetData;
\r
56 boolean reqInProgress;
\r
57 Dcm_SecLevelType reqSecLevel;
\r
58 const Dcm_DspSecurityRowType *reqSecLevelRef;
\r
59 } DspUdsSecurityAccessDataType;
\r
61 static DspUdsSecurityAccessDataType dspUdsSecurityAccesData;
\r
66 dspUdsSecurityAccesData.reqInProgress = FALSE;
\r
67 dspUdsEcuResetData.resetPending = FALSE;
\r
77 boolean DspCheckSessionLevel(Dcm_DspSessionRowType const* const* sessionLevelRefTable)
\r
79 Std_ReturnType returnStatus;
\r
80 boolean levelFound = FALSE;
\r
81 Dcm_SesCtrlType currentSession;
\r
83 returnStatus = DslGetSesCtrlType(¤tSession);
\r
84 if (returnStatus == E_OK) {
\r
85 while ( ((*sessionLevelRefTable)->DspSessionLevel != currentSession) && (!(*sessionLevelRefTable)->Arc_EOL) ) {
\r
86 sessionLevelRefTable++;
\r
89 if (!(*sessionLevelRefTable)->Arc_EOL) {
\r
98 boolean DspCheckSecurityLevel(Dcm_DspSecurityRowType const* const* securityLevelRefTable)
\r
100 Std_ReturnType returnStatus;
\r
101 boolean levelFound = FALSE;
\r
102 Dcm_SecLevelType currentSecurityLevel;
\r
104 returnStatus = DslGetSecurityLevel(¤tSecurityLevel);
\r
105 if (returnStatus == E_OK) {
\r
106 while ( ((*securityLevelRefTable)->DspSecurityLevel != currentSecurityLevel) && (!(*securityLevelRefTable)->Arc_EOL) ) {
\r
107 securityLevelRefTable++;
\r
109 if (!(*securityLevelRefTable)->Arc_EOL) {
\r
118 static Std_ReturnType askApplicationForSessionPermission(Dcm_SesCtrlType newSessionLevel)
\r
120 Std_ReturnType returnCode = E_OK;
\r
121 const Dcm_DslSessionControlType *sesControl = DCM_Config.Dsl->DslSessionControl;
\r
122 Dcm_SesCtrlType currentSessionLevel;
\r
123 Std_ReturnType result;
\r
125 while ( (!sesControl->Arc_EOL) && (returnCode != E_SESSION_NOT_ALLOWED)) {
\r
126 if (sesControl->GetSesChgPermission != NULL) {
\r
127 result = Dcm_GetSesCtrlType(¤tSessionLevel);
\r
128 if (result == E_OK) {
\r
129 result = sesControl->GetSesChgPermission(currentSessionLevel ,newSessionLevel);
\r
130 if (result != E_OK) {
\r
131 returnCode = result;
\r
134 returnCode = E_NOT_OK;
\r
144 void DspUdsDiagnosticSessionControl(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
147 const Dcm_DspSessionRowType *sessionRow = DCM_Config.Dsp->DspSession->DspSessionRow;
\r
148 Dcm_SesCtrlType reqSessionType;
\r
149 Std_ReturnType result;
\r
151 if (pduRxData->SduLength == 2) {
\r
152 reqSessionType = pduRxData->SduDataPtr[1];
\r
153 // Check if type exist in session table
\r
154 while ((sessionRow->DspSessionLevel != reqSessionType) && (!sessionRow->Arc_EOL) ) {
\r
158 if (!sessionRow->Arc_EOL) {
\r
159 result = askApplicationForSessionPermission(reqSessionType);
\r
160 if (result == E_OK) {
\r
161 DslSetSesCtrlType(reqSessionType); /** @req DCM311 */
\r
162 // Create positive response
\r
163 pduTxData->SduDataPtr[1] = reqSessionType;
\r
164 pduTxData->SduLength = 2;
\r
165 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
168 // TODO: Add handling of special case of E_FORCE_RCRRP (Dcm138)
\r
169 DsdDspProcessingDone(DCM_E_CONDITIONSNOTCORRECT); /** @req DCM308 */
\r
173 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED); /** @req DCM307 */
\r
178 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
183 void DspUdsEcuReset(const PduInfoType *pduRxData, PduIdType txPduId, PduInfoType *pduTxData)
\r
186 uint8 reqResetType;
\r
188 if (pduRxData->SduLength == 2) {
\r
189 reqResetType = pduRxData->SduDataPtr[1];
\r
191 switch (reqResetType)
\r
193 case 0x01: // Hard reset
\r
194 // TODO: Ask application for permission (Dcm373) (Dcm375) (Dcm377)
\r
196 // Schedule the reset
\r
197 dspUdsEcuResetData.resetPending = TRUE;
\r
198 dspUdsEcuResetData.resetPduId = txPduId;
\r
200 // Create positive response
\r
201 pduTxData->SduDataPtr[1] = reqResetType;
\r
202 pduTxData->SduLength = 2;
\r
203 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
207 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);
\r
213 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
218 void DspUdsClearDiagnosticInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
222 Dem_ReturnClearDTCType result;
\r
224 if (pduRxData->SduLength == 4) {
\r
225 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[1], pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3]);
\r
227 result = Dem_ClearDTC(dtc, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY); /** @req DCM005 */
\r
232 // Create positive response
\r
233 pduTxData->SduLength = 1;
\r
234 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
238 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
244 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
249 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x01_0x07_0x11_0x12(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
254 uint8 dtcStatusAvailabilityMask;
\r
255 uint8 dtcFormatIdentifier;
\r
256 uint8 dtcCountHighByte;
\r
257 uint8 dtcCountLowByte;
\r
260 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
261 Dem_ReturnSetDTCFilterType setDtcFilterResult;
\r
263 // Setup the DTC filter
\r
264 switch (pduRxData->SduDataPtr[1]) /** @req DCM293 */
\r
266 case 0x01: // reportNumberOfDTCByStatusMask
\r
267 setDtcFilterResult = Dem_SetDTCFilter(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
270 case 0x07: // reportNumberOfDTCBySeverityMaskRecord
\r
271 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[3], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_YES, pduRxData->SduDataPtr[2], DEM_FILTER_FOR_FDC_NO);
\r
274 case 0x11: // reportNumberOfMirrorMemoryDTCByStatusMask
\r
275 setDtcFilterResult = Dem_SetDTCFilter(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
278 case 0x12: // reportNumberOfEmissionRelatedOBDDTCByStatusMask
\r
279 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSION_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
283 setDtcFilterResult = DEM_WRONG_FILTER;
\r
287 if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {
\r
288 Std_ReturnType result;
\r
289 Dem_ReturnGetNumberOfFilteredDTCType getNumerResult;
\r
290 uint16 numberOfFilteredDtc;
\r
291 uint8 dtcStatusMask;
\r
292 //lint --e(826) PC-Lint exception - Suspicious pointer conversion
\r
293 //lint --e(927) PC-Lint exception - Pointer to pointer cast
\r
294 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;
\r
297 getNumerResult = Dem_GetNumberOfFilteredDtc(&numberOfFilteredDtc);
\r
298 if (getNumerResult == DEM_NUMBER_OK) {
\r
299 result = Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);
\r
300 if (result != E_OK) {
\r
304 // Create positive response (ISO 14229-1 table 251)
\r
305 txData->reportType = pduRxData->SduDataPtr[1]; // reportType
\r
306 txData->dtcStatusAvailabilityMask = dtcStatusMask; // DTCStatusAvailabilityMask
\r
307 txData->dtcFormatIdentifier = Dem_GetTranslationType(); // DTCFormatIdentifier
\r
308 txData->dtcCountHighByte = (numberOfFilteredDtc >> 8); // DTCCount high byte
\r
309 txData->dtcCountLowByte = (numberOfFilteredDtc & 0xFFu); // DTCCount low byte
\r
310 pduTxData->SduLength = 6;
\r
312 // TODO: What to do?
\r
313 responseCode = DCM_E_GENERALREJECT;
\r
317 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
320 return responseCode;
\r
324 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
326 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
327 Dem_ReturnSetDTCFilterType setDtcFilterResult;
\r
331 uint8 dtcMiddleByte;
\r
334 } dtcAndStatusRecordType;
\r
339 uint8 dtcStatusAvailabilityMask;
\r
340 dtcAndStatusRecordType dtcAndStatusRecord[];
\r
343 // Setup the DTC filter
\r
344 switch (pduRxData->SduDataPtr[1]) /** @req DCM378 */
\r
346 case 0x02: // reportDTCByStatusMask
\r
347 setDtcFilterResult = Dem_SetDTCFilter(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
350 case 0x0A: // reportSupportedDTC
\r
351 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
354 case 0x0F: // reportMirrorMemoryDTCByStatusMask
\r
355 setDtcFilterResult = Dem_SetDTCFilter(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
358 case 0x13: // reportEmissionRelatedOBDDTCByStatusMask
\r
359 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSION_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);
\r
362 case 0x15: // reportDTCWithPermanentStatus
\r
363 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
367 setDtcFilterResult = DEM_WRONG_FILTER;
\r
371 if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {
\r
372 uint8 dtcStatusMask;
\r
373 //lint --e(826) PC-Lint exception - Suspicious pointer conversion
\r
374 //lint --e(927) PC-Lint exception - Pointer to pointer cast
\r
375 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;
\r
376 Dem_ReturnGetNextFilteredDTCType getNextFilteredDtcResult;
\r
378 Dem_EventStatusExtendedType dtcStatus;
\r
379 uint16 nrOfDtcs = 0;
\r
380 Std_ReturnType result;
\r
383 result = Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);
\r
384 if (result != E_OK) {
\r
388 // Create positive response (ISO 14229-1 table 252)
\r
389 txData->reportType = pduRxData->SduDataPtr[1];
\r
390 txData->dtcStatusAvailabilityMask = dtcStatusMask;
\r
392 if (dtcStatusMask != 0x00) { /** @req DCM008 */
\r
393 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);
\r
394 while (getNextFilteredDtcResult == DEM_FILTERED_OK) {
\r
395 txData->dtcAndStatusRecord[nrOfDtcs].dtcHighByte = DTC_HIGH_BYTE(dtc);
\r
396 txData->dtcAndStatusRecord[nrOfDtcs].dtcMiddleByte = DTC_MID_BYTE(dtc);
\r
397 txData->dtcAndStatusRecord[nrOfDtcs].dtcLowByte = DTC_LOW_BYTE(dtc);
\r
398 txData->dtcAndStatusRecord[nrOfDtcs].statusOfDtc = dtcStatus;
\r
400 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);
\r
403 if (getNextFilteredDtcResult != DEM_FILTERED_NO_MATCHING_DTC) {
\r
404 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
407 pduTxData->SduLength = (PduLengthType)(3 + (nrOfDtcs * sizeof(dtcAndStatusRecordType)));
\r
410 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
413 return responseCode;
\r
416 // PC-Lint (715 etc): Remove errors until function is filled.
\r
417 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
418 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x08(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
420 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
422 // TODO: Not supported yet, (DEM module does not currently support severity).
\r
423 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
425 return responseCode;
\r
429 // PC-Lint (715 etc): Remove errors until function is filled.
\r
430 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
431 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x09(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
433 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
435 // TODO: Not supported yet, (DEM module does not currently support severity).
\r
436 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
438 return responseCode;
\r
442 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x06_0x10(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
444 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
445 Dem_DTCOriginType dtcOrigin;
\r
449 // Switch on sub function
\r
450 switch (pduRxData->SduDataPtr[1]) /** @req DCM378 */
\r
452 case 0x06: // reportDTCExtendedDataRecordByDTCNumber
\r
453 dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;
\r
456 case 0x10: // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber
\r
457 dtcOrigin = DEM_DTC_ORIGIN_MIRROR_MEMORY;
\r
461 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
466 // Switch on record number
\r
467 switch (pduRxData->SduDataPtr[5])
\r
469 case 0xFF: // Report all Extended Data Records for a particular DTC
\r
470 startRecNum = 0x00;
\r
474 case 0xFE: // Report all OBD Extended Data Records for a particular DTC
\r
475 startRecNum = 0x90;
\r
479 default: // Report one specific Extended Data Records for a particular DTC
\r
480 startRecNum = pduRxData->SduDataPtr[5];
\r
481 endRecNum = startRecNum;
\r
485 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
486 Dem_ReturnGetStatusOfDTCType getStatusOfDtcResult;
\r
488 Dem_EventStatusExtendedType statusOfDtc;
\r
490 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3], pduRxData->SduDataPtr[4]);
\r
491 getStatusOfDtcResult = Dem_GetStatusOfDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, &statusOfDtc); /** @req DCM295 */ /** @req DCM475 */
\r
492 if (getStatusOfDtcResult == DEM_STATUS_OK) {
\r
493 Dem_ReturnGetExtendedDataRecordByDTCType getExtendedDataRecordByDtcResult;
\r
496 uint16 txIndex = 6;
\r
498 /** @req DCM297 */ /** @req DCM474 */ /** @req DCM386 */
\r
499 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1]; // Sub function
\r
500 pduTxData->SduDataPtr[2] = DTC_HIGH_BYTE(dtc); // DTC high byte
\r
501 pduTxData->SduDataPtr[3] = DTC_MID_BYTE(dtc); // DTC mid byte
\r
502 pduTxData->SduDataPtr[4] = DTC_LOW_BYTE(dtc); // DTC low byte
\r
503 pduTxData->SduDataPtr[5] = statusOfDtc; // DTC status
\r
504 for (recNum = startRecNum; recNum <= endRecNum; recNum++) {
\r
505 recLength = pduTxData->SduLength - (txIndex + 1); // Calculate what's left in buffer
\r
506 /** @req DCM296 */ /** @req DCM476 */ /** @req DCM382 */
\r
507 getExtendedDataRecordByDtcResult = Dem_GetExtendedDataRecordByDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, recNum, &pduTxData->SduDataPtr[txIndex+1], &recLength);
\r
508 if (getExtendedDataRecordByDtcResult == DEM_RECORD_OK) {
\r
509 pduTxData->SduDataPtr[txIndex++] = recNum;
\r
510 /* Instead of calling Dem_GetSizeOfExtendedDataRecordByDTC() the result from Dem_GetExtendedDataRecordByDTC() is used */
\r
511 /** @req DCM478 */ /** @req DCM479 */ /** @req DCM480 */
\r
512 txIndex += recLength;
\r
515 // TODO: What to do here?
\r
518 pduTxData->SduLength = txIndex;
\r
521 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
525 return responseCode;
\r
529 // PC-Lint (715 etc): Remove errors until function is filled.
\r
530 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
531 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x03(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
533 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
535 // TODO: Not supported yet
\r
536 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
538 return responseCode;
\r
542 // PC-Lint (715 etc): Remove errors until function is filled.
\r
543 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
544 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x04(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
546 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
548 // TODO: Not supported yet
\r
549 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
551 return responseCode;
\r
555 // PC-Lint (715 etc): Remove errors until function is filled.
\r
556 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
557 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x05(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
559 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
561 // TODO: Not supported yet
\r
562 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
564 return responseCode;
\r
568 // PC-Lint (715 etc): Remove errors until function is filled.
\r
569 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
570 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
572 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
574 // TODO: Not supported yet
\r
575 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
577 return responseCode;
\r
581 // PC-Lint (715 etc): Remove errors until function is filled.
\r
582 //lint -e{715, 838, 818} Symbol not referenced, responseCode not used, txData should be const
\r
583 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x14(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
585 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
587 // TODO: Not supported yet
\r
588 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
590 return responseCode;
\r
594 void DspUdsReadDtcInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
597 // 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
598 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
600 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
602 uint8 subFunctionNumber = pduRxData->SduDataPtr[1];
\r
605 if (subFunctionNumber <= 0x15) {
\r
606 if (pduRxData->SduLength == sduLength[subFunctionNumber]) {
\r
607 switch (subFunctionNumber)
\r
609 case 0x01: // reportNumberOfDTCByStatusMask
\r
610 case 0x07: // reportNumberOfDTCBySeverityMaskRecord
\r
611 case 0x11: // reportNumberOfMirrorMemoryDTCByStatusMask
\r
612 case 0x12: // reportNumberOfEmissionRelatedOBDDTCByStatusMask
\r
613 responseCode = udsReadDtcInfoSub_0x01_0x07_0x11_0x12(pduRxData, pduTxData);
\r
616 case 0x02: // reportDTCByStatusMask
\r
617 case 0x0A: // reportSupportedDTC
\r
618 case 0x0F: // reportMirrorMemoryDTCByStatusMask
\r
619 case 0x13: // reportEmissionRelatedOBDDTCByStatusMask
\r
620 case 0x15: // reportDTCWithPermanentStatus
\r
621 responseCode = udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(pduRxData, pduTxData);
\r
624 case 0x08: // reportDTCBySeverityMaskRecord
\r
625 responseCode = udsReadDtcInfoSub_0x08(pduRxData, pduTxData);
\r
628 case 0x09: // reportSeverityInformationOfDTC
\r
629 responseCode = udsReadDtcInfoSub_0x09(pduRxData, pduTxData);
\r
632 case 0x06: // reportDTCExtendedDataRecordByDTCNumber
\r
633 case 0x10: // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber
\r
634 responseCode = udsReadDtcInfoSub_0x06_0x10(pduRxData, pduTxData);
\r
637 case 0x03: // reportDTCSnapshotIdentidication
\r
638 responseCode = udsReadDtcInfoSub_0x03(pduRxData, pduTxData);
\r
641 case 0x04: // reportDTCSnapshotByDtcNumber
\r
642 responseCode = udsReadDtcInfoSub_0x04(pduRxData, pduTxData);
\r
645 case 0x05: // reportDTCSnapshotRecordNumber
\r
646 responseCode = udsReadDtcInfoSub_0x05(pduRxData, pduTxData);
\r
649 case 0x0B: // reportFirstTestFailedDTC
\r
650 case 0x0C: // reportFirstConfirmedDTC
\r
651 case 0x0D: // reportMostRecentTestFailedDTC
\r
652 case 0x0E: // reportMostRecentConfirmedDTC
\r
653 responseCode = udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(pduRxData, pduTxData);
\r
656 case 0x14: // reportDTCFaultDetectionCounter
\r
657 responseCode = udsReadDtcInfoSub_0x14(pduRxData, pduTxData);
\r
661 // Unknown sub function
\r
662 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
668 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
672 // Sub function out of range
\r
673 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
676 DsdDspProcessingDone(responseCode);
\r
680 static boolean lookupDid(uint16 didNr, const Dcm_DspDidType **didPtr)
\r
682 const Dcm_DspDidType *dspDid = DCM_Config.Dsp->DspDid;
\r
683 boolean didFound = FALSE;
\r
685 while ((dspDid->DspDidIdentifier != didNr) && (!dspDid->Arc_EOL)) {
\r
689 if (!dspDid->Arc_EOL) {
\r
698 static Dcm_NegativeResponseCodeType readDidData(const Dcm_DspDidType *didPtr, PduInfoType *pduTxData, uint16 *txPos)
\r
700 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
702 if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidRead != NULL) && (didPtr->DspDidConditionCheckReadFnc != NULL) && (didPtr->DspDidReadDataFnc != NULL)) { /** @req DCM433 */
\r
703 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef)) { /** @req DCM434 */
\r
704 if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef)) { /** @req DCM435 */
\r
705 Std_ReturnType result;
\r
706 Dcm_NegativeResponseCodeType errorCode;
\r
707 result = didPtr->DspDidConditionCheckReadFnc(&errorCode);
\r
708 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) { /** @req DCM439 */
\r
711 if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM436 */
\r
712 didLen = didPtr->DspDidSize;
\r
716 if (didPtr->DspDidReadDataLengthFnc != NULL) {
\r
717 result = didPtr->DspDidReadDataLengthFnc(&didLen);
\r
721 if (result == E_OK) {
\r
722 // Now ready for reading the data!
\r
723 if ((*txPos + didLen + 2) <= pduTxData->SduLength) {
\r
724 pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFFu;
\r
726 pduTxData->SduDataPtr[*txPos] = didPtr->DspDidIdentifier & 0xFFu;
\r
728 result = didPtr->DspDidReadDataFnc(&pduTxData->SduDataPtr[*txPos]); /** @req DCM437 */
\r
731 if (result != E_OK) {
\r
732 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
735 else { // tx buffer full
\r
736 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
739 else { // Not possible to obtain did length
\r
740 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
743 else { // CheckRead failed
\r
744 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
747 else { // Not allowed in current security level
\r
748 responseCode = DCM_E_SECUTITYACCESSDENIED;
\r
751 else { // Not allowed in current session
\r
752 responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
\r
755 else { // Read access not configured
\r
756 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
759 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
760 // Recurse trough the rest of the dids. /** @req DCM440 */
\r
762 for (i=0; (!didPtr->DspDidRef[i]->Arc_EOL) && (responseCode == DCM_E_POSITIVERESPONSE); i++) {
\r
763 responseCode = readDidData(didPtr->DspDidRef[i], pduTxData, txPos);
\r
767 return responseCode;
\r
770 void DspUdsReadDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
773 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
776 const Dcm_DspDidType *didPtr = NULL;
\r
781 if ( ((pduRxData->SduLength - 1) % 2) == 0 ) {
\r
782 nrOfDids = (pduRxData->SduLength - 1) / 2;
\r
784 for (i = 0; (i < nrOfDids) && (responseCode == DCM_E_POSITIVERESPONSE); i++) {
\r
785 didNr = (uint16)((uint16)pduRxData->SduDataPtr[1+(i*2)] << 8) + pduRxData->SduDataPtr[2+(i*2)];
\r
786 if (lookupDid(didNr, &didPtr)) { /** @req DCM438 */
\r
787 responseCode = readDidData(didPtr, pduTxData, &txPos);
\r
789 else { // DID not found
\r
790 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
795 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
798 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
799 pduTxData->SduLength = txPos;
\r
802 DsdDspProcessingDone(responseCode);
\r
806 static Dcm_NegativeResponseCodeType readDidScalingData(const Dcm_DspDidType *didPtr, const PduInfoType *pduTxData, uint16 *txPos)
\r
808 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
810 if (didPtr->DspDidGetScalingInfoFnc != NULL) {
\r
811 uint16 scalingInfoLen;
\r
813 scalingInfoLen = didPtr->DspDidInfoRef->DspDidScalingInfoSize;
\r
814 if ((*txPos + scalingInfoLen + 2) <= pduTxData->SduLength) {
\r
815 Std_ReturnType result;
\r
816 Dcm_NegativeResponseCodeType errorCode;
\r
818 pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFFu;
\r
820 pduTxData->SduDataPtr[*txPos] = didPtr->DspDidIdentifier & 0xFFu;
\r
822 result = didPtr->DspDidGetScalingInfoFnc(&pduTxData->SduDataPtr[*txPos], &errorCode); /** @req DCM394 */
\r
823 *txPos += scalingInfoLen;
\r
825 if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {
\r
826 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
829 else { // tx buffer full
\r
830 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
833 else { // DspDidGetScalingInfoFnc null pointer
\r
834 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
837 return responseCode;
\r
840 void DspUdsReadScalingDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
843 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
845 const Dcm_DspDidType *didPtr = NULL;
\r
849 if (pduRxData->SduLength == 3) {
\r
850 didNr = (uint16)((uint16)pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];
\r
851 if (lookupDid(didNr, &didPtr)) {
\r
852 responseCode = readDidScalingData(didPtr, pduTxData, &txPos);
\r
854 else { // DID not found
\r
855 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
858 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
859 pduTxData->SduLength = txPos;
\r
864 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
867 DsdDspProcessingDone(responseCode);
\r
871 static Dcm_NegativeResponseCodeType writeDidData(const Dcm_DspDidType *didPtr, const PduInfoType *pduRxData, uint16 writeDidLen)
\r
873 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
875 if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite != NULL) && (didPtr->DspDidConditionCheckWriteFnc != NULL) && (didPtr->DspDidWriteDataFnc != NULL)) { /** @req DCM468 */
\r
876 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSessionRef)) { /** @req DCM469 */
\r
877 if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSecurityLevelRef)) { /** @req DCM470 */
\r
878 Std_ReturnType result;
\r
879 Dcm_NegativeResponseCodeType errorCode;
\r
880 result = didPtr->DspDidConditionCheckWriteFnc(&errorCode); /** @req DCM471 */
\r
881 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {
\r
884 if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM472 */
\r
885 didLen = didPtr->DspDidSize;
\r
889 if (didPtr->DspDidReadDataLengthFnc != NULL) {
\r
890 result = didPtr->DspDidReadDataLengthFnc(&didLen);
\r
893 if (result == E_OK) {
\r
894 if (didLen == writeDidLen) { /** @req DCM473 */
\r
895 result = didPtr->DspDidWriteDataFnc(&pduRxData->SduDataPtr[3], (uint8)didLen, &errorCode); /** @req DCM395 */
\r
896 if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {
\r
897 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
901 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
904 else { // Not possible to obtain did length
\r
905 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
908 else { // CheckRead failed
\r
909 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
912 else { // Not allowed in current security level
\r
913 responseCode = DCM_E_SECUTITYACCESSDENIED;
\r
916 else { // Not allowed in current session
\r
917 responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
\r
920 else { // Read access not configured
\r
921 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
924 return responseCode;
\r
927 void DspUdsWriteDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
930 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
932 const Dcm_DspDidType *didPtr = NULL;
\r
934 uint16 didDataLength;
\r
936 didDataLength = pduRxData->SduLength - 3;
\r
937 didNr = (uint16)((uint16)pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];
\r
938 if (lookupDid(didNr, &didPtr)) { /** @req DCM467 */
\r
939 responseCode = writeDidData(didPtr, pduRxData, didDataLength);
\r
941 else { // DID not found
\r
942 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
945 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
946 pduTxData->SduLength = 3;
\r
947 pduTxData->SduDataPtr[1] = (didNr >> 8) & 0xFFu;
\r
948 pduTxData->SduDataPtr[2] = didNr & 0xFFu;
\r
951 DsdDspProcessingDone(responseCode);
\r
955 void DspUdsSecurityAccess(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
958 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
960 // Check sub function range (0x01 to 0x42)
\r
961 if ((pduRxData->SduDataPtr[1] >= 0x01) && (pduRxData->SduDataPtr[1] <= 0x42)) {
\r
962 boolean isRequestSeed = pduRxData->SduDataPtr[1] & 0x01u;
\r
963 Dcm_SecLevelType requestedSecurityLevel = (pduRxData->SduDataPtr[1]-1)/2;
\r
964 Dcm_NegativeResponseCodeType getSeedErrorCode;
\r
966 if (isRequestSeed) {
\r
967 // requestSeed message
\r
968 // Check if type exist in security table
\r
969 const Dcm_DspSecurityRowType *securityRow = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[0];
\r
970 while ((securityRow->DspSecurityLevel != requestedSecurityLevel) && (!securityRow->Arc_EOL)) {
\r
973 if (!securityRow->Arc_EOL) {
\r
975 if (pduRxData->SduLength == (2 + securityRow->DspSecurityADRSize)) { /** @req DCM321.RequestSeed */
\r
976 Dcm_SecLevelType activeSecLevel;
\r
977 Std_ReturnType result;
\r
978 result = Dcm_GetSecurityLevel(&activeSecLevel);
\r
979 if (result == E_OK) {
\r
980 if (requestedSecurityLevel == activeSecLevel) { /** @req DCM323 */
\r
981 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];
\r
982 // If same level set the seed to zeroes
\r
983 memset(&pduTxData->SduDataPtr[2], 0, securityRow->DspSecuritySeedSize);
\r
984 pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;
\r
986 // New security level ask for seed
\r
987 if (securityRow->GetSeed != NULL) {
\r
988 Std_ReturnType getSeedResult;
\r
989 getSeedResult = securityRow->GetSeed(&pduRxData->SduDataPtr[2], &pduTxData->SduDataPtr[2], &getSeedErrorCode); /** @req DCM324.RequestSeed */
\r
990 if ((getSeedResult == E_OK) && (getSeedErrorCode == E_OK)) {
\r
991 // Everything ok add sub function to tx message and send it.
\r
992 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];
\r
993 pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;
\r
995 dspUdsSecurityAccesData.reqSecLevel = requestedSecurityLevel;
\r
996 dspUdsSecurityAccesData.reqSecLevelRef = securityRow;
\r
997 dspUdsSecurityAccesData.reqInProgress = TRUE;
\r
1000 // GetSeed returned not ok
\r
1001 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1004 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1008 // TODO: What to do?
\r
1009 responseCode = DCM_E_GENERALREJECT;
\r
1015 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1019 // Requested security level not configured
\r
1020 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1024 // sendKey message
\r
1025 if (dspUdsSecurityAccesData.reqInProgress) {
\r
1026 if (pduRxData->SduLength == (2 + dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityKeySize)) { /** @req DCM321.SendKey */
\r
1027 if (requestedSecurityLevel == dspUdsSecurityAccesData.reqSecLevel) {
\r
1028 if (dspUdsSecurityAccesData.reqSecLevelRef->CompareKey != NULL) {
\r
1029 Std_ReturnType compareKeyResult;
\r
1030 compareKeyResult = dspUdsSecurityAccesData.reqSecLevelRef->CompareKey(&pduRxData->SduDataPtr[2]); /** @req DCM324.SendKey */
\r
1031 if (compareKeyResult == E_OK) {
\r
1032 // Request accepted
\r
1034 DslSetSecurityLevel(dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityLevel); /** @req DCM325 */
\r
1035 dspUdsSecurityAccesData.reqInProgress = FALSE;
\r
1036 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];
\r
1037 pduTxData->SduLength = 2;
\r
1040 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1043 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1047 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1052 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1056 // sendKey request without a preceding requestSeed
\r
1057 responseCode = DCM_E_REQUESTSEQUENCEERROR;
\r
1062 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
1065 DsdDspProcessingDone(responseCode);
\r
1069 static boolean lookupRoutine(uint16 routineId, const Dcm_DspRoutineType **routinePtr)
\r
1071 const Dcm_DspRoutineType *dspRoutine = DCM_Config.Dsp->DspRoutine;
\r
1072 boolean routineFound = FALSE;
\r
1074 while ((dspRoutine->DspRoutineIdentifier != routineId) && (!dspRoutine->Arc_EOL)) {
\r
1078 if (!dspRoutine->Arc_EOL) {
\r
1079 routineFound = TRUE;
\r
1080 *routinePtr = dspRoutine;
\r
1083 return routineFound;
\r
1087 static Dcm_NegativeResponseCodeType startRoutine(const Dcm_DspRoutineType *routinePtr, const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
1089 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
1090 Std_ReturnType routineResult;
\r
1093 if ((routinePtr->DspStartRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspStartRoutine != NULL)) {
\r
1094 if (((routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineCtrlOptRecSize + 4) == pduRxData->SduLength)
\r
1095 && ((routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineStsOptRecSize + 4) <= pduTxData->SduLength)) {
\r
1096 pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineStsOptRecSize + 4;
\r
1097 routineResult = routinePtr->DspStartRoutineFnc(&pduRxData->SduDataPtr[4], &pduTxData->SduDataPtr[4], &responseCode); /** @req DCM400 */ /** @req DCM401 */
\r
1098 if (routineResult != E_OK) {
\r
1099 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1103 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1107 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1110 return responseCode;
\r
1114 static Dcm_NegativeResponseCodeType stopRoutine(const Dcm_DspRoutineType *routinePtr, const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
1116 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
1117 Std_ReturnType routineResult;
\r
1120 if ((routinePtr->DspStopRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspRoutineStop != NULL)) {
\r
1121 if (((routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineCtrlOptRecSize + 4) == pduRxData->SduLength)
\r
1122 && ((routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineStsOptRecSize + 4) <= pduTxData->SduLength)) {
\r
1123 pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineStsOptRecSize + 4;
\r
1124 routineResult = routinePtr->DspStopRoutineFnc(&pduRxData->SduDataPtr[4], &pduTxData->SduDataPtr[4], &responseCode); /** @req DCM402 */ /** @req DCM403 */
\r
1125 if (routineResult != E_OK) {
\r
1126 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1130 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1134 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1137 return responseCode;
\r
1141 static Dcm_NegativeResponseCodeType requestRoutineResults(const Dcm_DspRoutineType *routinePtr, PduInfoType *pduTxData)
\r
1143 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
1144 Std_ReturnType routineResult;
\r
1146 // requestRoutineResults
\r
1147 if ((routinePtr->DspRequestResultRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspRoutineRequestRes != NULL)) {
\r
1148 if ((routinePtr->DspRoutineInfoRef->DspRoutineRequestRes->DspReqResRtnCtrlOptRecSize + 4) <= pduTxData->SduLength) {
\r
1149 pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspRoutineRequestRes->DspReqResRtnCtrlOptRecSize + 4;
\r
1150 routineResult = routinePtr->DspRequestResultRoutineFnc(&pduTxData->SduDataPtr[4], &responseCode); /** @req DCM404 */ /** @req DCM405 */
\r
1151 if (routineResult != E_OK) {
\r
1152 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1156 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1160 responseCode = DCM_E_CONDITIONSNOTCORRECT;
\r
1163 return responseCode;
\r
1167 void DspUdsRoutineControl(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
1169 /** @req DCM257 */
\r
1170 Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;
\r
1171 uint8 subFunctionNumber = 0;
\r
1172 uint16 routineId = 0;
\r
1173 const Dcm_DspRoutineType *routinePtr = NULL;
\r
1175 if (pduRxData->SduLength >= 4) {
\r
1176 subFunctionNumber = pduRxData->SduDataPtr[1];
\r
1177 if ((subFunctionNumber > 0) && (subFunctionNumber < 4)) {
\r
1178 routineId = (uint16)((uint16)pduRxData->SduDataPtr[2] << 8) + pduRxData->SduDataPtr[3];
\r
1179 if (lookupRoutine(routineId, &routinePtr)) {
\r
1180 if (DspCheckSessionLevel(routinePtr->DspRoutineInfoRef->DspRoutineAuthorization.DspRoutineSessionRef)) {
\r
1181 if (DspCheckSecurityLevel(routinePtr->DspRoutineInfoRef->DspRoutineAuthorization.DspRoutineSecurityLevelRef)) {
\r
1182 switch (subFunctionNumber) {
\r
1183 case 0x01: // startRoutine
\r
1184 responseCode = startRoutine(routinePtr, pduRxData, pduTxData);
\r
1187 case 0x02: // stopRoutine
\r
1188 responseCode = stopRoutine(routinePtr, pduRxData, pduTxData);
\r
1191 case 0x03: // requestRoutineResults
\r
1192 responseCode = requestRoutineResults(routinePtr, pduTxData);
\r
1195 default: // This shall never happen
\r
1196 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
1200 else { // Not allowed in current security level
\r
1201 responseCode = DCM_E_SECUTITYACCESSDENIED;
\r
1204 else { // Not allowed in current session
\r
1205 responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
\r
1208 else { // Unknown routine identifier
\r
1209 responseCode = DCM_E_REQUESTOUTOFRANGE;
\r
1212 else { // Sub function not supported
\r
1213 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;
\r
1218 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;
\r
1221 if (responseCode == DCM_E_POSITIVERESPONSE) {
\r
1222 // Add header to the positive response message
\r
1223 pduTxData->SduDataPtr[1] = subFunctionNumber;
\r
1224 pduTxData->SduDataPtr[2] = (routineId >> 8) & 0xFFu;
\r
1225 pduTxData->SduDataPtr[3] = routineId & 0xFFu;
\r
1228 DsdDspProcessingDone(responseCode);
\r
1232 void DspUdsTesterPresent(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
1234 /** @req DCM251 */
\r
1235 if (pduRxData->SduLength == 2) {
\r
1236 switch (pduRxData->SduDataPtr[1])
\r
1238 case ZERO_SUB_FUNCTION:
\r
1239 DslResetSessionTimeoutTimer();
\r
1240 // Create positive response
\r
1241 pduTxData->SduDataPtr[1] = ZERO_SUB_FUNCTION;
\r
1242 pduTxData->SduLength = 2;
\r
1243 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
1247 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);
\r
1253 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
1258 void DspUdsControlDtcSetting(const PduInfoType *pduRxData, PduInfoType *pduTxData)
\r
1260 /** @req DCM249 */
\r
1261 Dem_ReturnControlDTCStorageType resultCode;
\r
1263 if (pduRxData->SduLength == 2) {
\r
1264 switch (pduRxData->SduDataPtr[1])
\r
1267 resultCode = Dem_EnableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS); /** @req DCM304 */
\r
1268 if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {
\r
1269 pduTxData->SduDataPtr[1] = 0x01;
\r
1270 pduTxData->SduLength = 2;
\r
1271 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
1274 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
1279 resultCode = Dem_DisableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS); /** @req DCM406 */
\r
1280 if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {
\r
1281 pduTxData->SduDataPtr[1] = 0x02;
\r
1282 pduTxData->SduLength = 2;
\r
1283 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);
\r
1286 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);
\r
1291 DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);
\r
1297 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
\r
1302 void DspDcmConfirmation(PduIdType confirmPduId)
\r
1304 if (dspUdsEcuResetData.resetPending) {
\r
1305 if (confirmPduId == dspUdsEcuResetData.resetPduId) {
\r
1306 dspUdsEcuResetData.resetPending = FALSE;
\r
1307 #if defined(USE_MCU) && ( MCU_PERFORM_RESET_API == STD_ON )
\r
1308 Mcu_PerformReset();
\r
1310 DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_UDS_RESET_ID, DCM_E_NOT_SUPPORTED);
\r