]> rtime.felk.cvut.cz Git - arc.git/blob - communication/ComM/ComM.c
0d7c97ff150d1d2dfad2169a5d78ddc2906d5457
[arc.git] / communication / ComM / ComM.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 //lint -emacro(904,COMM_VALIDATE_INIT,COMM_VALIDATE_CHANNEL,COMM_VALIDATE_USER,COMM_VALIDATE_PARAMETER) //904 PC-Lint exception to MISRA 14.7 (validate macros).\r
17 \r
18 /* Globally fulfilled requirements */\r
19 /** @req COMM43 */\r
20 /** @req COMM38 */\r
21 /** @req COMM463.partially */\r
22 /** @req COMM686 */\r
23 /** @req COMM51 */\r
24 /** @req COMM191 */\r
25 /** @req COMM301 */\r
26 /** @req COMM488 */\r
27 /** @req COMM599 */\r
28 /** @req COMM509 */\r
29 /** @req COMM269 */\r
30 /** @req COMM458 */\r
31 /** @req COMM640 */\r
32 /** @req COMM459 */\r
33 /** @req COMM462 */\r
34 /** @req COMM457.bswbuilder */\r
35 /** @req COMM419.bswbuilder */\r
36 /** @req COMM460.bswbuilder */\r
37 /** @req COMM549.bswbuilder */\r
38 /** @req COMM464 */\r
39 \r
40 #include <string.h>\r
41 #include "ComM.h"\r
42 #include "ComM_Dcm.h"\r
43 #include "ComM_EcuM.h"\r
44 #if (COMM_DEV_ERROR_DETECT == STD_ON)\r
45 #include "Det.h"\r
46 #endif\r
47 \r
48 /** @req COMM507  @req COMM508 */\r
49 #if defined(USE_DEM)\r
50 #include "Dem.h"\r
51 #endif\r
52 \r
53 #include "ComM_BusSm.h"\r
54 #include "ComM_Internal.h"\r
55 \r
56 /** @req COMM506  @req COMM353 */\r
57 #include "CanSM.h"\r
58 \r
59 /** @req COMM347 */\r
60 #if defined(USE_NM) || defined(COMM_TESTS)\r
61 #include "Nm.h"\r
62 #endif\r
63 \r
64 static ComM_InternalType ComM_Internal = {\r
65                 .InitStatus = COMM_UNINIT,\r
66                 .InhibitCounter = 0,\r
67 #if (COMM_NO_COM == STD_ON)\r
68                 .NoCommunication = TRUE,\r
69 #else\r
70                 .NoCommunication = FALSE,\r
71 #endif\r
72 };\r
73 \r
74 static const ComM_ConfigType * ComM_Config;\r
75 \r
76 \r
77 void ComM_Init(const ComM_ConfigType * Config ){\r
78         COMM_VALIDATE_PARAMETER( (Config != NULL), COMM_SERVICEID_INIT);\r
79         COMM_VALIDATE_PARAMETER( (Config->Channels != NULL), COMM_SERVICEID_INIT);\r
80         COMM_VALIDATE_PARAMETER( (Config->Users != NULL), COMM_SERVICEID_INIT);\r
81 \r
82         ComM_Config = Config;\r
83 \r
84         for (uint8 i = 0; i < COMM_CHANNEL_COUNT; ++i) {\r
85                 ComM_Internal.Channels[i].Mode = COMM_NO_COMMUNICATION;  /**< @req COMM485 */\r
86                 ComM_Internal.Channels[i].SubMode = COMM_SUBMODE_NONE;\r
87                 ComM_Internal.Channels[i].UserRequestMask = 0;\r
88                 ComM_Internal.Channels[i].InhibitionStatus = COMM_INHIBITION_STATUS_NONE;\r
89                 ComM_Internal.Channels[i].NmIndicationMask = COMM_NM_INDICATION_NONE;\r
90         }\r
91 \r
92         for (uint8 i = 0; i < COMM_USER_COUNT; ++i) {\r
93                 ComM_Internal.Users[i].RequestedMode = COMM_NO_COMMUNICATION;\r
94         }\r
95 \r
96         ComM_Internal.InhibitCounter = 0;\r
97         ComM_Internal.InitStatus = COMM_INIT;\r
98         /** @req COMM313 */\r
99 }\r
100 \r
101 void ComM_DeInit(){\r
102         COMM_VALIDATE_INIT(COMM_SERVICEID_DEINIT);\r
103 \r
104         ComM_Internal.InitStatus = COMM_UNINIT;\r
105 }\r
106 \r
107 Std_ReturnType ComM_GetStatus( ComM_InitStatusType* Status ){\r
108         COMM_VALIDATE_PARAMETER( (Status != NULL), COMM_SERVICEID_GETSTATUS, E_NOT_OK);\r
109 \r
110         *Status = ComM_Internal.InitStatus;\r
111         return E_OK;\r
112 }\r
113 \r
114 Std_ReturnType ComM_GetInhibitionStatus( NetworkHandleType Channel, ComM_InhibitionStatusType* Status ){\r
115         COMM_VALIDATE_INIT(COMM_SERVICEID_GETINHIBITIONSTATUS, COMM_E_UNINIT);\r
116 \r
117         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
118         *Status = ChannelInternal->InhibitionStatus;\r
119         return E_OK;\r
120 }\r
121 \r
122 \r
123 Std_ReturnType ComM_RequestComMode( ComM_UserHandleType User, ComM_ModeType ComMode ){\r
124         COMM_VALIDATE_INIT(COMM_SERVICEID_REQUESTCOMMODE, COMM_E_UNINIT);\r
125         COMM_VALIDATE_USER(User, COMM_SERVICEID_REQUESTCOMMODE, E_NOT_OK);\r
126         /** @req COMM151 */\r
127         COMM_VALIDATE_PARAMETER((ComMode != COMM_SILENT_COMMUNICATION), COMM_SERVICEID_REQUESTCOMMODE, E_NOT_OK);\r
128 \r
129         return ComM_Internal_RequestComMode(User, ComMode);\r
130 }\r
131 \r
132 static Std_ReturnType ComM_Internal_RequestComMode(\r
133                                 ComM_UserHandleType User, ComM_ModeType ComMode ){\r
134 \r
135         const ComM_UserType* UserConfig = &ComM_Config->Users[User];\r
136         ComM_Internal_UserType* UserInternal = &ComM_Internal.Users[User];\r
137 \r
138         UserInternal->RequestedMode = ComMode;  /**< @req COMM471  @req COMM500  @req COMM92 */\r
139         uint32 userMask = (1LU << User);\r
140 \r
141         Std_ReturnType requestStatus = E_OK;\r
142 \r
143         /* Go through users channels. Relay to SMs. Collect overall success status */\r
144         for (uint8 i = 0; i < UserConfig->ChannelCount; ++i) {\r
145                 const ComM_ChannelType* Channel = UserConfig->ChannelList[i];\r
146                 ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel->Number];\r
147 \r
148                 /** @req COMM784.1  @req COMM304  @req COMM625 */\r
149                 // Put user request into mask\r
150                 if (ComMode == COMM_NO_COMMUNICATION) {\r
151                         ChannelInternal->UserRequestMask &= ~(userMask);\r
152                 } else if (ComMode == COMM_FULL_COMMUNICATION) {\r
153                         ChannelInternal->UserRequestMask |= userMask;\r
154                 } else {\r
155                         //Nothing to be done.\r
156                 }\r
157 \r
158                 // take request -> new state\r
159                 Std_ReturnType status = ComM_Internal_UpdateChannelState(Channel, TRUE);\r
160                 if (status > requestStatus){\r
161                         requestStatus = status;\r
162                 }\r
163 \r
164         }\r
165 \r
166         return requestStatus;\r
167 }\r
168 \r
169 Std_ReturnType ComM_GetMaxComMode( ComM_UserHandleType User, ComM_ModeType* ComMode ){\r
170         COMM_VALIDATE_INIT(COMM_SERVICEID_GETMAXCOMMODE, COMM_E_UNINIT);\r
171         COMM_VALIDATE_USER(User, COMM_SERVICEID_GETMAXCOMMODE, E_NOT_OK);\r
172         // Not implemented\r
173         (void)ComMode;\r
174         return E_NOT_OK;\r
175 }\r
176 \r
177 /** @req COMM80 */\r
178 Std_ReturnType ComM_GetRequestedComMode( ComM_UserHandleType User, ComM_ModeType* ComMode ){\r
179         COMM_VALIDATE_INIT(COMM_SERVICEID_GETREQUESTEDCOMMODE, COMM_E_UNINIT);\r
180         COMM_VALIDATE_USER(User, COMM_SERVICEID_GETREQUESTEDCOMMODE, E_NOT_OK);\r
181 \r
182         ComM_Internal_UserType* UserInternal = &ComM_Internal.Users[User];\r
183         *ComMode = UserInternal->RequestedMode;\r
184         return E_OK;\r
185 }\r
186 \r
187 /** @req COMM84 */\r
188 Std_ReturnType ComM_GetCurrentComMode( ComM_UserHandleType User, ComM_ModeType* ComMode ){\r
189         COMM_VALIDATE_INIT(COMM_SERVICEID_GETCURRENTCOMMODE, COMM_E_UNINIT);\r
190         COMM_VALIDATE_USER(User, COMM_SERVICEID_GETCURRENTCOMMODE, E_NOT_OK);\r
191 \r
192         return ComM_Internal_PropagateGetCurrentComMode(User, ComMode);\r
193 }\r
194 \r
195 Std_ReturnType ComM_PreventWakeUp( NetworkHandleType Channel, boolean Status ){\r
196         COMM_VALIDATE_INIT(COMM_SERVICEID_PREVENTWAKEUP, COMM_E_UNINIT);\r
197         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_PREVENTWAKEUP, E_NOT_OK);\r
198 #if (COMM_MODE_LIMITATION_ENABLED == STD_ON)\r
199         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
200         if (Status) {\r
201                 ChannelInternal->InhibitionStatus |=  (COMM_INHIBITION_STATUS_WAKE_UP);\r
202         } else {\r
203                 ChannelInternal->InhibitionStatus &= ~(COMM_INHIBITION_STATUS_WAKE_UP);\r
204         }\r
205         return E_OK;\r
206 #else\r
207         return E_NOT_OK;\r
208 #endif\r
209 }\r
210 \r
211 /** @req COMM361  @req COMM105.1  @req COMM800 */\r
212 Std_ReturnType ComM_LimitChannelToNoComMode( NetworkHandleType Channel, boolean Status ){\r
213         COMM_VALIDATE_INIT(COMM_SERVICEID_LIMITCHANNELTONOCOMMODE, COMM_E_UNINIT);\r
214         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_LIMITCHANNELTONOCOMMODE, E_NOT_OK);\r
215 #if (COMM_MODE_LIMITATION_ENABLED == STD_ON)\r
216         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
217         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
218         if (Status) {\r
219                 ChannelInternal->InhibitionStatus |=  (COMM_INHIBITION_STATUS_NO_COMMUNICATION);\r
220         } else {\r
221                 ChannelInternal->InhibitionStatus &= ~(COMM_INHIBITION_STATUS_NO_COMMUNICATION);\r
222         }\r
223         return ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
224 #else\r
225         return E_NOT_OK;\r
226 #endif\r
227 }\r
228 \r
229 /** @req COMM105.2  @req COMM801.partially */\r
230 Std_ReturnType ComM_LimitECUToNoComMode( boolean Status ){\r
231         COMM_VALIDATE_INIT(COMM_SERVICEID_LIMITECUTONOCOMMODE, COMM_E_UNINIT);\r
232 #if (COMM_MODE_LIMITATION_ENABLED == STD_ON)\r
233         ComM_Internal.NoCommunication = Status;\r
234         uint8 Channel;\r
235         Std_ReturnType totalStatus = E_OK;\r
236         for (Channel = 0; Channel < COMM_CHANNEL_COUNT; Channel++) {\r
237                 const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
238                 Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
239                 if (status > totalStatus) {\r
240                         totalStatus = status;\r
241                 }\r
242         }\r
243         return totalStatus;\r
244 #else\r
245         return E_NOT_OK;\r
246 #endif\r
247 }\r
248 \r
249 /** @req COMM143  @req COMM802 */\r
250 Std_ReturnType ComM_ReadInhibitCounter( uint16* CounterValue ){\r
251         COMM_VALIDATE_INIT(COMM_SERVICEID_READINHIBITCOUNTER, COMM_E_UNINIT);\r
252 #if (COMM_MODE_LIMITATION_ENABLED == STD_ON)\r
253         *CounterValue = ComM_Internal.InhibitCounter;\r
254         return E_OK;\r
255 #else\r
256         return E_NOT_OK;\r
257 #endif\r
258 }\r
259 \r
260 /** @req COMM803 */\r
261 Std_ReturnType ComM_ResetInhibitCounter(){\r
262         COMM_VALIDATE_INIT(COMM_SERVICEID_RESETINHIBITCOUNTER, COMM_E_UNINIT);\r
263 #if (COMM_MODE_LIMITATION_ENABLED == STD_ON)\r
264         ComM_Internal.InhibitCounter = 0;\r
265         return E_OK;\r
266 #else\r
267         return E_NOT_OK;\r
268 #endif\r
269 }\r
270 \r
271 Std_ReturnType ComM_SetECUGroupClassification( ComM_InhibitionStatusType Status ){\r
272         COMM_VALIDATE_INIT(COMM_SERVICEID_SETECUGROUPCLASSIFICATION, COMM_E_UNINIT);\r
273         // Not implemented\r
274         (void)Status;\r
275         return E_NOT_OK;\r
276 }\r
277 \r
278 \r
279 // Network Management Interface Callbacks\r
280 // --------------------------------------\r
281 /** @req COMM804 */\r
282 void ComM_Nm_NetworkStartIndication( NetworkHandleType Channel ){\r
283         COMM_VALIDATE_INIT(COMM_SERVICEID_NM_NETWORKSTARTINDICATION);\r
284         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_NM_NETWORKSTARTINDICATION);\r
285         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
286         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
287 \r
288         // Used to simulate Wake-up\r
289         ChannelInternal->NmIndicationMask |= COMM_NM_INDICATION_RESTART;\r
290         Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
291         if (status != E_OK) {\r
292                 // TODO: report error?\r
293         }\r
294 }\r
295 \r
296 /** @req COMM807 */\r
297 void ComM_Nm_NetworkMode( NetworkHandleType Channel ){\r
298         COMM_VALIDATE_INIT(COMM_SERVICEID_NM_NETWORKMODE);\r
299         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_NM_NETWORKMODE);\r
300         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
301         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
302 \r
303         ChannelInternal->NmIndicationMask |= COMM_NM_INDICATION_NETWORK_MODE;\r
304         Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
305         if (status != E_OK) {\r
306                 // TODO: report error?\r
307         }\r
308 }\r
309 \r
310 /** @req COMM809 */\r
311 void ComM_Nm_PrepareBusSleepMode( NetworkHandleType Channel ){\r
312         COMM_VALIDATE_INIT(COMM_SERVICEID_NM_PREPAREBUSSLEEPMODE);\r
313         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_NM_PREPAREBUSSLEEPMODE);\r
314         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
315         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
316 \r
317         ChannelInternal->NmIndicationMask |= COMM_NM_INDICATION_PREPARE_BUS_SLEEP;\r
318         Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
319         if (status != E_OK) {\r
320                 // TODO: report error?\r
321         }\r
322 }\r
323 \r
324 /** @req COMM811 */\r
325 void ComM_Nm_BusSleepMode( NetworkHandleType Channel ){\r
326         COMM_VALIDATE_INIT(COMM_SERVICEID_NM_BUSSLEEPMODE);\r
327         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_NM_BUSSLEEPMODE);\r
328         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
329         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
330 \r
331         ChannelInternal->NmIndicationMask |= COMM_NM_INDICATION_BUS_SLEEP;\r
332         Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
333         if (status != E_OK) {\r
334                 // TODO: report error?\r
335         }\r
336 }\r
337 \r
338 /** @req COMM813 */\r
339 void ComM_Nm_RestartIndication( NetworkHandleType Channel ){\r
340         COMM_VALIDATE_INIT(COMM_SERVICEID_NM_RESTARTINDICATION);\r
341         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_NM_RESTARTINDICATION);\r
342         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
343         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
344 \r
345         ChannelInternal->NmIndicationMask |= COMM_NM_INDICATION_RESTART;\r
346         Std_ReturnType status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
347         if (status != E_OK) {\r
348                 // TODO: report error?\r
349         }\r
350 \r
351 }\r
352 \r
353 \r
354 // ECU State Manager Callbacks\r
355 // ---------------------------\r
356 \r
357 void ComM_EcuM_RunModeIndication( NetworkHandleType Channel ){\r
358         COMM_VALIDATE_INIT(COMM_SERVICEID_ECUM_RUNMODEINDICATION);\r
359         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_ECUM_RUNMODEINDICATION);\r
360 }\r
361 \r
362 void ComM_EcuM_WakeUpIndication( NetworkHandleType Channel ){\r
363         COMM_VALIDATE_INIT(COMM_SERVICEID_ECUM_WAKEUPINDICATION);\r
364         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_ECUM_WAKEUPINDICATION);\r
365 }\r
366 \r
367 \r
368 // Diagnostic Communication Manager Callbacks\r
369 // ------------------------------------------\r
370 \r
371 void ComM_DCM_ActiveDiagnostic(void){\r
372         COMM_VALIDATE_INIT(COMM_SERVICEID_DCM_ACTIVEDIAGNOSTIC);\r
373 }\r
374 \r
375 void ComM_DCM_InactiveDiagnostic(void){\r
376         COMM_VALIDATE_INIT(COMM_SERVICEID_DCM_INACTIVEDIAGNOSTIC);\r
377 }\r
378 \r
379 \r
380 // Bus State Manager Callbacks\r
381 // ---------------------------\r
382 \r
383 void ComM_BusSM_ModeIndication( NetworkHandleType Channel, ComM_ModeType ComMode ){\r
384         COMM_VALIDATE_INIT(COMM_SERVICEID_BUSSM_MODEINDICATION);\r
385         COMM_VALIDATE_CHANNEL(Channel, COMM_SERVICEID_BUSSM_MODEINDICATION);\r
386         // Not implemented\r
387         (void)ComMode;\r
388 }\r
389 \r
390 \r
391 // Scheduled main function\r
392 // -----------------------\r
393 \r
394 // Prototype right here because this function should not be exposed\r
395 void ComM_MainFunction(NetworkHandleType Channel);\r
396 \r
397 /** @req COMM429 */\r
398 void ComM_MainFunction(NetworkHandleType Channel) {\r
399         const ComM_ChannelType* ChannelConf = &ComM_Config->Channels[Channel];\r
400         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[Channel];\r
401 \r
402         if ((ChannelConf->NmVariant == COMM_NM_VARIANT_NONE) ||\r
403                 (ChannelConf->NmVariant == COMM_NM_VARIANT_LIGHT)) {\r
404                 Std_ReturnType status = ComM_Internal_TickFullComMinTime(ChannelConf, ChannelInternal);\r
405                 if (status != E_OK) {\r
406                         // TODO: Report error?\r
407                 }\r
408         }\r
409         if (ChannelConf->NmVariant == COMM_NM_VARIANT_LIGHT) {\r
410                 Std_ReturnType status = ComM_Internal_TickLightTime(ChannelConf, ChannelInternal);\r
411                 if (status != E_OK) {\r
412                         // TODO: Report error?\r
413                 }\r
414         }\r
415 \r
416 }\r
417 \r
418 // ----------------------------------------------------------------------------\r
419 // Internal functions\r
420 // ----------------------------------------------------------------------------\r
421 \r
422 static inline Std_ReturnType ComM_Internal_TickFullComMinTime(const ComM_ChannelType* ChannelConf, ComM_Internal_ChannelType* ChannelInternal) {\r
423         Std_ReturnType status = E_OK;\r
424         if (ChannelInternal->Mode == COMM_FULL_COMMUNICATION) {\r
425                 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->FullComMinDurationTimeLeft) {\r
426                         ChannelInternal->FullComMinDurationTimeLeft = 0;\r
427                         status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
428                 } else {\r
429                         ChannelInternal->FullComMinDurationTimeLeft -= ChannelConf->MainFunctionPeriod;\r
430                 }\r
431         }\r
432         return status;\r
433 }\r
434 \r
435 static inline boolean ComM_Internal_FullComMinTime_AllowsExit(const ComM_ChannelType* ChannelConf, const ComM_Internal_ChannelType* ChannelInternal) {\r
436         boolean rv;\r
437         /** @req COMM311 */\r
438         if ((ChannelConf->NmVariant == COMM_NM_VARIANT_LIGHT) ||\r
439                 (ChannelConf->NmVariant == COMM_NM_VARIANT_NONE)){\r
440                 rv = (ChannelInternal->FullComMinDurationTimeLeft == 0);\r
441         } else {\r
442                 rv = TRUE;\r
443         }\r
444         return rv;\r
445 }\r
446 \r
447 static inline Std_ReturnType ComM_Internal_TickLightTime(const ComM_ChannelType* ChannelConf, ComM_Internal_ChannelType* ChannelInternal) {\r
448         Std_ReturnType status = E_OK;\r
449         if ((ChannelInternal->Mode == COMM_FULL_COMMUNICATION) &&\r
450                 (ChannelInternal->SubMode == COMM_SUBMODE_READY_SLEEP)) {\r
451                 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->LightTimeoutTimeLeft) {\r
452                         ChannelInternal->LightTimeoutTimeLeft = 0;\r
453                         status = ComM_Internal_UpdateChannelState(ChannelConf, FALSE);\r
454                 } else {\r
455                         ChannelInternal->LightTimeoutTimeLeft -= ChannelConf->MainFunctionPeriod;\r
456                 }\r
457         }\r
458         return status;\r
459 }\r
460 \r
461 /** @req COMM678.2 */\r
462 static Std_ReturnType ComM_Internal_PropagateGetCurrentComMode( ComM_UserHandleType User, ComM_ModeType* ComMode ){\r
463         const ComM_UserType* UserConfig = &ComM_Config->Users[User];\r
464 \r
465         ComM_ModeType requestMode = COMM_FULL_COMMUNICATION;\r
466         Std_ReturnType totalStatus = E_OK;\r
467         /* Go through users channels. Relay to SMs. Collect overall mode and success status */\r
468         for (uint8 i = 0; i < UserConfig->ChannelCount; ++i) {\r
469                 const ComM_ChannelType* Channel = UserConfig->ChannelList[i];\r
470                 Std_ReturnType status = E_OK;\r
471                 ComM_ModeType mode = COMM_FULL_COMMUNICATION;\r
472                 switch (Channel->BusType) {\r
473                         case COMM_BUS_TYPE_CAN:\r
474                                 status = CanSM_GetCurrentComMode(Channel->BusSMNetworkHandle, &mode);\r
475                                 break;\r
476                         default:\r
477                                 status = E_NOT_OK;\r
478                                 break;\r
479                 }\r
480                 if (status == E_OK) {\r
481                         if (mode < requestMode) {       /** @req ComM176 */\r
482                                 requestMode = mode;\r
483                         }\r
484                 } else {\r
485                         totalStatus = status;\r
486                 }\r
487         }\r
488         *ComMode = requestMode;\r
489         return totalStatus;\r
490 }\r
491 \r
492 /** @req COMM281.partially  @req COMM70  @req COMM73  @req COMM71  @req COMM72\r
493  *  @req COMM69  @req COMM402  @req COMM434  @req COMM678.1  @req COMM168  @req COMM676.partially */\r
494 static Std_ReturnType ComM_Internal_PropagateComMode( const ComM_ChannelType* ChannelConf ){\r
495         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[ChannelConf->Number];\r
496         ComM_ModeType ComMode = ChannelInternal->Mode;\r
497 \r
498         Std_ReturnType busSMStatus = E_OK;\r
499         switch (ChannelConf->BusType) {\r
500 #if defined(USE_CANSM) || defined(COMM_TESTS)\r
501                 case COMM_BUS_TYPE_CAN:\r
502                         busSMStatus = CanSM_RequestComMode(ChannelConf->BusSMNetworkHandle, ComMode);\r
503                         break;\r
504 #endif\r
505 #if defined(USE_LINSM)\r
506                 case COMM_BUS_TYPE_LIN:\r
507                         busSMStatus = LinSM_RequestComMode(ChannelConf->BusSMNetworkHandle, ComMode);\r
508                         break;\r
509 #endif\r
510                 default:\r
511                         busSMStatus = E_NOT_OK;\r
512         }\r
513 \r
514         return busSMStatus;\r
515 }\r
516 \r
517 /** @req COMM472  @req COMM602  @req COMM261 */\r
518 static Std_ReturnType ComM_Internal_NotifyNm( const ComM_ChannelType* ChannelConf){\r
519         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[ChannelConf->Number];\r
520 \r
521         Std_ReturnType globalStatus = E_OK;\r
522 \r
523         if ((ChannelConf->NmVariant == COMM_NM_VARIANT_FULL) ||\r
524                 (ChannelConf->NmVariant == COMM_NM_VARIANT_PASSIVE)) {\r
525 #if defined(USE_NM) || defined(COMM_TESTS)\r
526                 Nm_ReturnType nmStatus = NM_E_OK;\r
527                 if (ChannelInternal->Mode == COMM_FULL_COMMUNICATION) {\r
528                         if (ChannelInternal->SubMode == COMM_SUBMODE_NETWORK_REQUESTED) {\r
529                                 nmStatus = Nm_NetworkRequest(ChannelConf->NmChannelHandle);  /**< @req COMM129.1 */\r
530                         } else if (ChannelInternal->SubMode == COMM_SUBMODE_READY_SLEEP) {\r
531                                 nmStatus = Nm_NetworkRelease(ChannelConf->NmChannelHandle);  /**< @req COMM133.1 */\r
532                         } else {\r
533                                 //Nothing to be done.\r
534                         }\r
535                 }\r
536                 if (nmStatus != NM_E_OK) {\r
537                         globalStatus = E_NOT_OK;\r
538                 }\r
539 #else\r
540                 globalStatus = E_NOT_OK;\r
541 #endif\r
542         }\r
543 \r
544         return globalStatus;\r
545 }\r
546 \r
547 /* Processes all requests etc. and makes state machine transitions accordingly */\r
548 static Std_ReturnType ComM_Internal_UpdateChannelState( const ComM_ChannelType* ChannelConf, boolean isRequest ) {\r
549         ComM_Internal_ChannelType* ChannelInternal = &ComM_Internal.Channels[ChannelConf->Number];\r
550         Std_ReturnType status = E_OK;\r
551         switch (ChannelInternal->Mode) {\r
552                 case COMM_NO_COMMUNICATION:\r
553                         status = ComM_Internal_UpdateFromNoCom(ChannelConf, ChannelInternal, isRequest);\r
554                         break;\r
555                 case COMM_SILENT_COMMUNICATION:\r
556                         status = ComM_Internal_UpdateFromSilentCom(ChannelConf, ChannelInternal, isRequest);\r
557                         break;\r
558                 case COMM_FULL_COMMUNICATION:\r
559                         status = ComM_Internal_UpdateFromFullCom(ChannelConf, ChannelInternal, isRequest);\r
560                         break;\r
561                 default:\r
562                         status = E_NOT_OK;\r
563                         break;\r
564         }\r
565         return status;\r
566 }\r
567 \r
568 static inline Std_ReturnType ComM_Internal_UpdateFromNoCom(const ComM_ChannelType* ChannelConf,\r
569                                         ComM_Internal_ChannelType* ChannelInternal, boolean isRequest) {\r
570         Std_ReturnType status = E_OK;\r
571         if (ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_RESTART) {  /**< @req COMM207.partial */\r
572                 // "restart" indication\r
573                 status = ComM_Internal_Enter_NetworkRequested(ChannelConf, ChannelInternal);  /**< @req COMM583 */\r
574                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_RESTART);\r
575         } else {\r
576                 if ((ChannelInternal->InhibitionStatus & COMM_INHIBITION_STATUS_NO_COMMUNICATION) ||\r
577                         (ChannelInternal->InhibitionStatus & COMM_INHIBITION_STATUS_WAKE_UP) ||\r
578                         (ComM_Internal.NoCommunication == TRUE)) {\r
579                         // Inhibition is active\r
580                         /** @req COMM302  @req COMM218  @req COMM219  @req COMM215.3  @req COMM216.3 */\r
581                         if (isRequest){\r
582                                 ComM_Internal.InhibitCounter++;\r
583                         }\r
584                 } else {\r
585                         if (ChannelInternal->UserRequestMask != 0) {\r
586                                 // Channel is requested\r
587                                 status = ComM_Internal_Enter_NetworkRequested(ChannelConf, ChannelInternal);  /**< @req COMM784.2 */\r
588                         } else {\r
589                                 // Channel is not requested\r
590                         }\r
591                 }\r
592         }\r
593         return status;\r
594 }\r
595 \r
596 static inline Std_ReturnType ComM_Internal_UpdateFromSilentCom(const ComM_ChannelType* ChannelConf,\r
597                                         ComM_Internal_ChannelType* ChannelInternal,     boolean isRequest) {\r
598         Std_ReturnType status = E_OK;\r
599         if (ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_RESTART) {  /**< @req COMM207.partial */\r
600                 // "restart" indication\r
601                 status = ComM_Internal_Enter_ReadySleep(ChannelConf, ChannelInternal);  /**< @req COMM296.1 */\r
602                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_RESTART);\r
603         } else if (ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_BUS_SLEEP) {\r
604                 // "bus sleep" indication\r
605                 status = ComM_Internal_Enter_NoCom(ChannelConf, ChannelInternal);  /**< @req COMM295 */\r
606                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_BUS_SLEEP);\r
607         } else if (ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_NETWORK_MODE) {\r
608                 // "network mode" indication\r
609                 status = ComM_Internal_Enter_ReadySleep(ChannelConf, ChannelInternal);  /**< @req COMM296.2 */\r
610                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_NETWORK_MODE);\r
611         } else {\r
612                 if ((ChannelInternal->InhibitionStatus & COMM_INHIBITION_STATUS_NO_COMMUNICATION) ||\r
613                         (ComM_Internal.NoCommunication == TRUE)) {\r
614                         // Inhibition is active\r
615                         /** @req COMM215.2  @req COMM216.2 */\r
616                         if (isRequest) {\r
617                                 ComM_Internal.InhibitCounter++;\r
618                         }\r
619                 } else {\r
620                         if (ChannelInternal->UserRequestMask != 0) {\r
621                                 // Channel is requested\r
622                                 status = ComM_Internal_Enter_NetworkRequested(ChannelConf, ChannelInternal);  /**< @req COMM785 */\r
623                         } else {\r
624                                 // Stay in SILENT\r
625                         }\r
626                 }\r
627         }\r
628         return status;\r
629 }\r
630 \r
631 static inline Std_ReturnType ComM_Internal_UpdateFromFullCom(const ComM_ChannelType* ChannelConf,\r
632                                         ComM_Internal_ChannelType* ChannelInternal, boolean isRequest) {\r
633         Std_ReturnType status = E_OK;\r
634         if (ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_BUS_SLEEP) {\r
635                 // "bus sleep" indication\r
636                 status = ComM_Internal_Enter_NoCom(ChannelConf, ChannelInternal);  /**< @req COMM637 */\r
637                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_BUS_SLEEP);\r
638         } else if ((ChannelInternal->NmIndicationMask & COMM_NM_INDICATION_PREPARE_BUS_SLEEP) &&\r
639                                 (ChannelInternal->SubMode == COMM_SUBMODE_READY_SLEEP)) {\r
640                 // "prepare bus sleep" indication\r
641                 status = ComM_Internal_Enter_SilentCom(ChannelConf, ChannelInternal);  /**< @req COMM299 */\r
642                 ChannelInternal->NmIndicationMask &= ~(COMM_NM_INDICATION_PREPARE_BUS_SLEEP);\r
643         } else {\r
644                 if ((ChannelInternal->InhibitionStatus & COMM_INHIBITION_STATUS_NO_COMMUNICATION) ||\r
645                         (ComM_Internal.NoCommunication == TRUE)) {\r
646                         // Inhibition is active\r
647                         if (ComM_Internal_FullComMinTime_AllowsExit(ChannelConf, ChannelInternal)) {  /**< @req COMM205.1 */\r
648                                 if (ChannelInternal->SubMode == COMM_SUBMODE_READY_SLEEP) {\r
649                                         if ((ChannelConf->NmVariant == COMM_NM_VARIANT_LIGHT) &&\r
650                                                 (ChannelInternal->LightTimeoutTimeLeft == 0)) {\r
651                                                 status = ComM_Internal_Enter_NoCom(ChannelConf, ChannelInternal);  /**< @req COMM610.1 */\r
652                                         }\r
653                                 } else {\r
654                                         /** @req COMM478.seeAlsoCOMM52  @req COMM303  @req COMM215.1  @req COMM216.1 */\r
655                                         status = ComM_Internal_Enter_ReadySleep(ChannelConf, ChannelInternal);\r
656                                 }\r
657                         }\r
658                         if (isRequest){\r
659                                 ComM_Internal.InhibitCounter++;\r
660                         }\r
661                 } else {\r
662                         if (ChannelInternal->UserRequestMask == 0) {\r
663                                 // Channel no longer requested\r
664                                 if (ComM_Internal_FullComMinTime_AllowsExit(ChannelConf, ChannelInternal)) {  /**< @req COMM205.1 */\r
665                                         if (ChannelInternal->SubMode == COMM_SUBMODE_READY_SLEEP) {\r
666                                                 if ((ChannelConf->NmVariant == COMM_NM_VARIANT_LIGHT) &&\r
667                                                         (ChannelInternal->LightTimeoutTimeLeft == 0)) {\r
668                                                         status = ComM_Internal_Enter_NoCom(ChannelConf, ChannelInternal);  /**< @req COMM610.2 */\r
669                                                 }\r
670                                         } else {\r
671                                                 status = ComM_Internal_Enter_ReadySleep(ChannelConf, ChannelInternal);\r
672                                         }\r
673                                 }\r
674                         } else {\r
675                                 // Channel is requested\r
676                                 if (ChannelInternal->SubMode != COMM_SUBMODE_NETWORK_REQUESTED) {\r
677                                         status = ComM_Internal_Enter_NetworkRequested(ChannelConf, ChannelInternal);  /**< @req COMM479 */\r
678                                 }\r
679                         }\r
680                 }\r
681         }\r
682         return status;\r
683 }\r
684 \r
685 static inline Std_ReturnType ComM_Internal_Enter_NoCom(const ComM_ChannelType* ChannelConf,\r
686                                                                                                         ComM_Internal_ChannelType* ChannelInternal) {\r
687         ChannelInternal->Mode = COMM_NO_COMMUNICATION;\r
688         return ComM_Internal_PropagateComMode(ChannelConf);\r
689 }\r
690 \r
691 static inline Std_ReturnType ComM_Internal_Enter_SilentCom(const ComM_ChannelType* ChannelConf,\r
692                                                                                                                 ComM_Internal_ChannelType* ChannelInternal) {\r
693         ChannelInternal->Mode = COMM_SILENT_COMMUNICATION;\r
694         return ComM_Internal_PropagateComMode(ChannelConf);\r
695 }\r
696 \r
697 static inline Std_ReturnType ComM_Internal_Enter_NetworkRequested(const ComM_ChannelType* ChannelConf,\r
698                                                                                                                                 ComM_Internal_ChannelType* ChannelInternal) {\r
699         boolean propagateToBusSM = (ChannelInternal->Mode != COMM_FULL_COMMUNICATION);\r
700         ChannelInternal->FullComMinDurationTimeLeft = COMM_T_MIN_FULL_COM_MODE_DURATION;\r
701         ChannelInternal->Mode = COMM_FULL_COMMUNICATION;\r
702         ChannelInternal->SubMode = COMM_SUBMODE_NETWORK_REQUESTED;\r
703 \r
704         Std_ReturnType status, globalStatus = E_OK;\r
705         status = ComM_Internal_NotifyNm(ChannelConf);  /**< @req COMM129.2 */\r
706         if (status > globalStatus){\r
707                 globalStatus = status;\r
708         }\r
709         if (propagateToBusSM) {\r
710                 status = ComM_Internal_PropagateComMode(ChannelConf);\r
711                 if (status > globalStatus){\r
712                         globalStatus = status;\r
713                 }\r
714         }\r
715         return globalStatus;\r
716 }\r
717 \r
718 static inline Std_ReturnType ComM_Internal_Enter_ReadySleep(const ComM_ChannelType* ChannelConf,\r
719                                                                                                                         ComM_Internal_ChannelType* ChannelInternal) {\r
720         boolean propagateToBusSM = (ChannelInternal->Mode != COMM_FULL_COMMUNICATION);\r
721         ChannelInternal->LightTimeoutTimeLeft = ChannelConf->LightTimeout;\r
722         ChannelInternal->Mode = COMM_FULL_COMMUNICATION;\r
723         ChannelInternal->SubMode = COMM_SUBMODE_READY_SLEEP;\r
724 \r
725         Std_ReturnType status, globalStatus = E_OK;\r
726         status = ComM_Internal_NotifyNm(ChannelConf);  /**< @req COMM133.1 */\r
727         if (status > globalStatus){\r
728                 globalStatus = status;\r
729         }\r
730         if (propagateToBusSM) {\r
731                 status = ComM_Internal_PropagateComMode(ChannelConf);\r
732                 if (status > globalStatus){\r
733                         globalStatus = status;\r
734                 }\r
735         }\r
736         return globalStatus;\r
737 }\r