]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsd.c
Merge branch 'mikulka' of git@rtime.felk.cvut.cz:arc into mikulka
[arc.git] / diagnostic / Dcm / Dcm_Dsd.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\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
9  *\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
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 \r
18 /*\r
19  *  General requirements\r
20  */\r
21 /** @req DCM600 */ // Generated by BSW builder\r
22 \r
23 \r
24 #include <string.h>\r
25 #include "Dcm.h"\r
26 #include "Dcm_Internal.h"\r
27 #include "MemMap.h"\r
28 \r
29 typedef struct {\r
30         const PduInfoType                               *pduRxData;\r
31         PduInfoType                                     *pduTxData;\r
32         const Dcm_DsdServiceTableType   *serviceTable;\r
33         Dcm_ProtocolAddrTypeType                addrType;\r
34         PduIdType                                               txPduId;\r
35         PduIdType                                               rxPduId;\r
36 } MsgDataType;\r
37 \r
38 // In "queue" to DSD\r
39 static boolean  dsdDslDataIndication = FALSE;\r
40 static MsgDataType msgData;\r
41 \r
42 static uint8    currentSid;\r
43 static boolean  suppressPosRspMsg;\r
44 \r
45 /*\r
46  * Local functions\r
47  */\r
48 \r
49 \r
50 static Std_ReturnType askApplicationForServicePermission(uint8 *requestData, uint16 dataSize)\r
51 {\r
52         Std_ReturnType returnCode = E_OK;\r
53         const Dcm_DslServiceRequestIndicationType *serviceRequestIndication = DCM_Config.Dsl->DslServiceRequestIndication;\r
54         Std_ReturnType result;\r
55 \r
56         while ((!serviceRequestIndication->Arc_EOL) && (returnCode != E_REQUEST_NOT_ACCEPTED)) {\r
57                 if (serviceRequestIndication->Indication != NULL) {\r
58                         result = serviceRequestIndication->Indication(requestData, dataSize);\r
59                         if (result != E_OK){\r
60                                 returnCode = result;\r
61                         }\r
62                 }\r
63                 serviceRequestIndication++;\r
64         }\r
65 \r
66         return returnCode;\r
67 }\r
68 \r
69 \r
70 static void createAndSendNcr(Dcm_NegativeResponseCodeType responseCode)\r
71 {\r
72         if (!((msgData.addrType == DCM_PROTOCOL_FUNCTIONAL_ADDR_TYPE)\r
73                   && ((responseCode == DCM_E_SERVICENOTSUPPORTED) || (responseCode == DCM_E_SUBFUNCTIONNOTSUPPORTED) || (responseCode == DCM_E_REQUESTOUTOFRANGE)))) {   /** @req DCM001 */\r
74                 msgData.pduTxData->SduDataPtr[0] = SID_NEGATIVE_RESPONSE;\r
75                 msgData.pduTxData->SduDataPtr[1] = currentSid;\r
76                 msgData.pduTxData->SduDataPtr[2] = responseCode;\r
77                 msgData.pduTxData->SduLength = 3;\r
78                 DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_READY);   /** @req DCM114 */ /** @req DCM232.Ncr */\r
79         }\r
80         else {\r
81                 DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_SUPPRESSED);\r
82         }\r
83 }\r
84 \r
85 \r
86 static void selectServiceFunction(uint8 sid)\r
87 {\r
88         /** @req DCM442.Partially */\r
89         switch (sid)     /** @req DCM221 */\r
90         {\r
91         case SID_DIAGNOSTIC_SESSION_CONTROL:\r
92                 DspUdsDiagnosticSessionControl(msgData.pduRxData, msgData.pduTxData);\r
93                 break;\r
94 \r
95         case SID_ECU_RESET:\r
96                 DspUdsEcuReset(msgData.pduRxData, msgData.txPduId, msgData.pduTxData);\r
97                 break;\r
98 \r
99         case SID_CLEAR_DIAGNOSTIC_INFORMATION:\r
100                 DspUdsClearDiagnosticInformation(msgData.pduRxData, msgData.pduTxData);\r
101                 break;\r
102 \r
103         case SID_READ_DTC_INFORMATION:\r
104                 DspUdsReadDtcInformation(msgData.pduRxData, msgData.pduTxData);\r
105                 break;\r
106 \r
107         case SID_READ_DATA_BY_IDENTIFIER:\r
108                 DspUdsReadDataByIdentifier(msgData.pduRxData, msgData.pduTxData);\r
109                 break;\r
110                 \r
111         case SID_READ_MEMORY_BY_ADDRESS:\r
112                 DspUdsReadMemoryByAddress(msgData.pduRxData, msgData.pduTxData);\r
113                 break;\r
114                 \r
115         case SID_WRITE_MEMORY_BY_ADDRESS:\r
116                 DspUdsWriteMemoryByAddress(msgData.pduRxData, msgData.pduTxData);\r
117                 break;\r
118                 \r
119         case SID_READ_SCALING_DATA_BY_IDENTIFIER:\r
120                 DspUdsReadScalingDataByIdentifier(msgData.pduRxData, msgData.pduTxData);\r
121                 break;\r
122 \r
123         case SID_SECURITY_ACCESS:\r
124                 DspUdsSecurityAccess(msgData.pduRxData, msgData.pduTxData);\r
125                 break;\r
126 \r
127         case SID_WRITE_DATA_BY_IDENTIFIER:\r
128                 DspUdsWriteDataByIdentifier(msgData.pduRxData, msgData.pduTxData);\r
129                 break;\r
130 \r
131         case SID_ROUTINE_CONTROL:\r
132                 DspUdsRoutineControl(msgData.pduRxData, msgData.pduTxData);\r
133                 break;\r
134 \r
135         case SID_TESTER_PRESENT:\r
136                 DspUdsTesterPresent(msgData.pduRxData, msgData.pduTxData);\r
137                 break;\r
138 \r
139         case SID_CONTROL_DTC_SETTING:\r
140                 DspUdsControlDtcSetting(msgData.pduRxData, msgData.pduTxData);\r
141                 break;\r
142 \r
143         case SID_READ_DATA_BY_PERIODIC_IDENTIFIER:\r
144                 DspReadDataByPeriodicIdentifier(msgData.pduRxData, msgData.pduTxData);\r
145                 break;\r
146                 \r
147         case SID_DYNAMICALLY_DEFINE_DATA_IDENTIFIER:\r
148                 DspDynamicallyDefineDataIdentifier(msgData.pduRxData, msgData.pduTxData);\r
149                 break;\r
150                 \r
151         case SID_INPUT_OUTPUT_CONTROL_BY_IDENTIFIER:\r
152                 DspIOControlByDataIdentifier(msgData.pduRxData, msgData.pduTxData);\r
153                 break;\r
154                 \r
155         default:\r
156                 /* Non implemented service */\r
157                 createAndSendNcr(DCM_E_SERVICENOTSUPPORTED);\r
158                 break;\r
159         }\r
160 }\r
161 \r
162 \r
163 static boolean lookupSid(uint8 sid, const Dcm_DsdServiceType **sidPtr)\r
164 {\r
165         boolean returnStatus = TRUE;\r
166         const Dcm_DsdServiceType *service = msgData.serviceTable->DsdService;\r
167 \r
168         while ((service->DsdSidTabServiceId != sid) && (!service->Arc_EOL)) {\r
169                 service++;\r
170         }\r
171 \r
172         if (!service->Arc_EOL) {\r
173                 *sidPtr = service;\r
174         }\r
175         else {\r
176                 returnStatus = FALSE;\r
177                 *sidPtr = NULL;\r
178         }\r
179 \r
180         return returnStatus;\r
181 }\r
182 \r
183 \r
184 /*\r
185  * Exported functions\r
186  */\r
187 \r
188 void DsdInit(void)\r
189 {\r
190 \r
191 }\r
192 \r
193 \r
194 void DsdMain(void)\r
195 {\r
196         if (dsdDslDataIndication) {\r
197                 dsdDslDataIndication = FALSE;\r
198                 DsdHandleRequest();\r
199         }\r
200 }\r
201 \r
202 \r
203 void DsdHandleRequest(void)\r
204 {\r
205         Std_ReturnType result;\r
206         const Dcm_DsdServiceType *sidConfPtr = NULL;\r
207 \r
208         currentSid = msgData.pduRxData->SduDataPtr[0];  /** @req DCM198 */\r
209 \r
210         /** @req DCM178 */\r
211         //lint --e(506, 774)    PC-Lint exception Misra 13.7, 14.1 Allow configuration variables in boolean expression\r
212         if ((DCM_RESPOND_ALL_REQUEST == STD_ON) || ((currentSid & 0x7Fu) < 0x40)) {             /** @req DCM084 */\r
213                 if (lookupSid(currentSid, &sidConfPtr)) {               /** @req DCM192 */ /** @req DCM193 */ /** @req DCM196 */\r
214                         // SID found!\r
215                         if (DspCheckSessionLevel(sidConfPtr->DsdSidTabSessionLevelRef)) {                /** @req DCM211 */\r
216                                 if (DspCheckSecurityLevel(sidConfPtr->DsdSidTabSecurityLevelRef)) {      /** @req DCM217 */\r
217                                         //lint --e(506, 774)    PC-Lint exception Misra 13.7, 14.1 Allow configuration variables in boolean expression\r
218                                         if (DCM_REQUEST_INDICATION_ENABLED == STD_ON) {  /** @req DCM218 */\r
219                                                  result = askApplicationForServicePermission(msgData.pduRxData->SduDataPtr, msgData.pduRxData->SduLength);\r
220                                         } else {\r
221                                                 result = E_OK;\r
222                                         }\r
223                                         //lint --e(506, 774)    PC-Lint exception Misra 13.7, 14.1 Allow configuration variables in boolean expression\r
224                                         if (result == E_OK) {\r
225                                                 // Yes! All conditions met!\r
226                                                 // Check if response shall be suppressed\r
227                                                 if ( (sidConfPtr->DsdSidTabSubfuncAvail) && (msgData.pduRxData->SduDataPtr[1] & SUPPRESS_POS_RESP_BIT) ) {      /** @req DCM204 */\r
228                                                         suppressPosRspMsg = TRUE;       /** @req DCM202 */\r
229                                                         msgData.pduRxData->SduDataPtr[1] &= ~SUPPRESS_POS_RESP_BIT;     /** @req DCM201 */\r
230                                                 }\r
231                                                 else\r
232                                                 {\r
233                                                         suppressPosRspMsg = FALSE;      /** @req DCM202 */\r
234                                                 }\r
235                                                 selectServiceFunction(currentSid);\r
236                                         }\r
237                                         else {\r
238                                                 if (result == E_REQUEST_ENV_NOK) {\r
239                                                         createAndSendNcr(DCM_E_CONDITIONSNOTCORRECT);   /** @req DCM463 */\r
240                                                 }\r
241                                                 else {\r
242                                                         // Do not send any response             /** @req DCM462 */\r
243                                                         DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_SUPPRESSED);\r
244                                                 }\r
245                                         }\r
246                                 }\r
247                                 else {\r
248                                         createAndSendNcr(DCM_E_SECUTITYACCESSDENIED);   /** @req DCM217 */\r
249                                 }\r
250                         }\r
251                         else {\r
252                                 createAndSendNcr(DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);     /** @req DCM211 */\r
253                         }\r
254                 }\r
255                 else {\r
256                         createAndSendNcr(DCM_E_SERVICENOTSUPPORTED);    /** @req DCM197 */\r
257                 }\r
258         }\r
259         else {\r
260                 // Inform DSL that message has been discard\r
261                 DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_SUPPRESSED);\r
262         }\r
263 }\r
264 \r
265 \r
266 \r
267 void DsdDspProcessingDone(Dcm_NegativeResponseCodeType responseCode)\r
268 {\r
269         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
270                 if (!suppressPosRspMsg) {       /** @req DCM200 */ /** @req DCM231 */\r
271                         /** @req DCM222 */\r
272                         msgData.pduTxData->SduDataPtr[0] = currentSid | SID_RESPONSE_BIT;       /** @req DCM223 */ /** @req DCM224 */\r
273                         DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_READY);   /** @req DCM114 */ /** @req DCM225 */ /** @req DCM232.Ok */\r
274                 }\r
275                 else {\r
276                         DspDcmConfirmation(msgData.txPduId);    /** @req DCM236 */ /** @req DCM240 */\r
277                         DslDsdProcessingDone(msgData.rxPduId, DSD_TX_RESPONSE_SUPPRESSED);\r
278                 }\r
279         }\r
280         else {\r
281                 createAndSendNcr(responseCode); /** @req DCM228 */\r
282         }\r
283 \r
284 }\r
285 \r
286 \r
287 void DsdDataConfirmation(PduIdType confirmPduId, NotifResultType result)\r
288 {\r
289         (void)result;   /* Currently not used */\r
290         DspDcmConfirmation(confirmPduId);       /** @req DCM236 */\r
291 }\r
292 \r
293 \r
294 void DsdDslDataIndication(const PduInfoType *pduRxData, const Dcm_DsdServiceTableType *protocolSIDTable, Dcm_ProtocolAddrTypeType addrType, PduIdType txPduId, PduInfoType *pduTxData, PduIdType rxContextPduId)\r
295 {\r
296         msgData.rxPduId = rxContextPduId;\r
297         msgData.txPduId = txPduId;\r
298         msgData.pduRxData = pduRxData;\r
299         msgData.pduTxData = pduTxData;\r
300         msgData.addrType = addrType;\r
301         msgData.serviceTable = protocolSIDTable;\r
302 \r
303         dsdDslDataIndication = TRUE;\r
304 }\r